org.jahia.services.content.JCRPropertyWrapperImpl.java Source code

Java tutorial

Introduction

Here is the source code for org.jahia.services.content.JCRPropertyWrapperImpl.java

Source

/**
 * ==========================================================================================
 * =                   JAHIA'S DUAL LICENSING - IMPORTANT INFORMATION                       =
 * ==========================================================================================
 *
 *                                 http://www.jahia.com
 *
 *     Copyright (C) 2002-2017 Jahia Solutions Group SA. All rights reserved.
 *
 *     THIS FILE IS AVAILABLE UNDER TWO DIFFERENT LICENSES:
 *     1/GPL OR 2/JSEL
 *
 *     1/ GPL
 *     ==================================================================================
 *
 *     IF YOU DECIDE TO CHOOSE THE GPL LICENSE, YOU MUST COMPLY WITH THE FOLLOWING TERMS:
 *
 *     This program is free software: you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation, either version 3 of the License, or
 *     (at your option) any later version.
 *
 *     This program is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *     GNU General Public License for more details.
 *
 *     You should have received a copy of the GNU General Public License
 *     along with this program. If not, see <http://www.gnu.org/licenses/>.
 *
 *
 *     2/ JSEL - Commercial and Supported Versions of the program
 *     ===================================================================================
 *
 *     IF YOU DECIDE TO CHOOSE THE JSEL LICENSE, YOU MUST COMPLY WITH THE FOLLOWING TERMS:
 *
 *     Alternatively, commercial and supported versions of the program - also known as
 *     Enterprise Distributions - must be used in accordance with the terms and conditions
 *     contained in a separate written agreement between you and Jahia Solutions Group SA.
 *
 *     If you are unsure which license is appropriate for your use,
 *     please contact the sales department at sales@jahia.com.
 */
package org.jahia.services.content;

import org.apache.commons.lang.StringUtils;
import org.apache.jackrabbit.value.ValueHelper;
import org.jahia.api.Constants;
import org.jahia.services.content.decorator.JCRNodeDecorator;
import org.jahia.services.content.nodetypes.ExtendedPropertyDefinition;
import org.slf4j.Logger;

import javax.jcr.*;
import javax.jcr.lock.LockException;
import javax.jcr.nodetype.ConstraintViolationException;
import javax.jcr.nodetype.NoSuchNodeTypeException;
import javax.jcr.version.VersionException;

import java.io.InputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;

/**
 * Wrapper for {@link javax.jcr.Property} to allow more data format.
 *
 * @author toto
 */
public class JCRPropertyWrapperImpl extends JCRItemWrapperImpl implements JCRPropertyWrapper {
    private static final Logger logger = org.slf4j.LoggerFactory.getLogger(JCRPropertyWrapperImpl.class);

    private JCRNodeWrapper node;
    private Property property;
    private String name;
    private ExtendedPropertyDefinition def;

    /**
     * Constructor
     * 
     * @param objectNode JCRNodeWrapper of the node holding this property
     * @param property wrapped property object
     * @param session wrapped session which loaded this property
     * @param provider JCR store provider for this property
     * @param def definition of this property
     */
    public JCRPropertyWrapperImpl(JCRNodeWrapper objectNode, Property property, JCRSessionWrapper session,
            JCRStoreProvider provider, ExtendedPropertyDefinition def) {
        super(session, provider);
        this.node = objectNode;
        this.property = property;
        this.item = property;
        if (property != null) {
            try {
                this.localPath = property.getPath();
                this.localPathInProvider = localPath;
                this.name = property.getName();
                this.def = def;
            } catch (RepositoryException e) {
                logger.error(e.getMessage(), e);
            }
        }
    }

    /**
     * Constructor
     * 
     * @param objectNode JCRNodeWrapper of the node holding this property
     * @param property wrapped property object
     * @param session wrapped session which loaded this property
     * @param provider JCR store provider for this property
     * @param def definition of this property
     * @param name name of this property
     */
    public JCRPropertyWrapperImpl(JCRNodeWrapper objectNode, Property property, JCRSessionWrapper session,
            JCRStoreProvider provider, ExtendedPropertyDefinition def, String name) {
        super(session, provider);
        this.node = objectNode;
        this.property = property;
        this.item = property;
        this.name = name;
        this.localPath = node.getPath() + "/" + name; // todo : node.getPath() returns the global path, not local path - should use node.getRealNode()
        this.localPathInProvider = localPath;
        this.def = def;
    }

    public void setValue(Value value) throws ValueFormatException, VersionException, LockException,
            ConstraintViolationException, RepositoryException {
        node.checkLock();
        Value modifiedValue = JCRStoreService.getInstance().getInterceptorChain().beforeSetValue(node, name, def,
                value);
        property.setValue(modifiedValue);
    }

    public void setValue(Value[] values) throws ValueFormatException, VersionException, LockException,
            ConstraintViolationException, RepositoryException {
        node.checkLock();
        Value[] modifiedValues = JCRStoreService.getInstance().getInterceptorChain().beforeSetValues(node, name,
                def, values);
        property.setValue(modifiedValues);
    }

    public void setValue(String value) throws ValueFormatException, VersionException, LockException,
            ConstraintViolationException, RepositoryException {
        if (value != null) {
            setValue(getSession().getValueFactory().createValue(value));
        } else {
            remove();
        }
    }

    public void setValue(String[] values) throws ValueFormatException, VersionException, LockException,
            ConstraintViolationException, RepositoryException {
        if (values != null) {
            Value[] v = new Value[values.length];
            for (int i = 0; i < values.length; i++) {
                if (values[i] != null) {
                    v[i] = getSession().getValueFactory().createValue(values[i]);
                } else {
                    v[i] = null;
                }
            }
            setValue(v);
        } else {
            remove();
        }
    }

    /**
     * @deprecated As of JCR 2.0, {@link #setValue(Binary)} should be used instead.
     */
    public void setValue(InputStream value) throws ValueFormatException, VersionException, LockException,
            ConstraintViolationException, RepositoryException {
        if (value != null) {
            setValue(getSession().getValueFactory().createValue(value));
        } else {
            remove();
        }
    }

    public void setValue(long value) throws ValueFormatException, VersionException, LockException,
            ConstraintViolationException, RepositoryException {
        setValue(getSession().getValueFactory().createValue(value));
    }

    public void setValue(double value) throws ValueFormatException, VersionException, LockException,
            ConstraintViolationException, RepositoryException {
        setValue(getSession().getValueFactory().createValue(value));
    }

    public void setValue(Calendar value) throws ValueFormatException, VersionException, LockException,
            ConstraintViolationException, RepositoryException {
        if (value != null) {
            setValue(getSession().getValueFactory().createValue(value));
        } else {
            remove();
        }
    }

    public void setValue(boolean value) throws ValueFormatException, VersionException, LockException,
            ConstraintViolationException, RepositoryException {
        setValue(getSession().getValueFactory().createValue(value));
    }

    public void setValue(Node value) throws ValueFormatException, VersionException, LockException,
            ConstraintViolationException, RepositoryException {
        if (value != null) {
            setValue(getSession().getValueFactory().createValue(
                    value instanceof JCRNodeWrapper ? ((JCRNodeWrapper) value).getRealNode() : value,
                    def.getRequiredType() == PropertyType.WEAKREFERENCE));
        } else {
            remove();
        }
    }

    public void setValue(Binary value) throws ValueFormatException, VersionException, LockException,
            ConstraintViolationException, RepositoryException {
        if (value != null) {
            setValue(getSession().getValueFactory().createValue(value));
        } else {
            remove();
        }
    }

    public void setValue(BigDecimal value) throws ValueFormatException, VersionException, LockException,
            ConstraintViolationException, RepositoryException {
        if (value != null) {
            setValue(getSession().getValueFactory().createValue(value));
        } else {
            remove();
        }
    }

    @Override
    public void addValue(String value) throws ValueFormatException, VersionException, LockException,
            ConstraintViolationException, RepositoryException {
        addValue(getSession().getValueFactory().createValue(value));
    }

    @Override
    public void addValue(InputStream value) throws ValueFormatException, VersionException, LockException,
            ConstraintViolationException, RepositoryException {
        addValue(getSession().getValueFactory().createValue(value));
    }

    @Override
    public void addValue(long value) throws ValueFormatException, VersionException, LockException,
            ConstraintViolationException, RepositoryException {
        addValue(getSession().getValueFactory().createValue(value));
    }

    @Override
    public void addValue(double value) throws ValueFormatException, VersionException, LockException,
            ConstraintViolationException, RepositoryException {
        addValue(getSession().getValueFactory().createValue(value));
    }

    @Override
    public void addValue(Calendar value) throws ValueFormatException, VersionException, LockException,
            ConstraintViolationException, RepositoryException {
        addValue(getSession().getValueFactory().createValue(value));
    }

    @Override
    public void addValue(boolean value) throws ValueFormatException, VersionException, LockException,
            ConstraintViolationException, RepositoryException {
        addValue(getSession().getValueFactory().createValue(value));
    }

    @Override
    public void addValue(Node value) throws ValueFormatException, VersionException, LockException,
            ConstraintViolationException, RepositoryException {
        addValue(value, true);
    }

    @Override
    public void addValue(Node value, boolean weak) throws ValueFormatException, VersionException, LockException,
            ConstraintViolationException, RepositoryException {
        addValue(getSession().getValueFactory().createValue(value, weak));
    }

    @Override
    public void addValue(Binary value) throws ValueFormatException, VersionException, LockException,
            ConstraintViolationException, RepositoryException {
        addValue(getSession().getValueFactory().createValue(value));
    }

    @Override
    public void addValue(BigDecimal value) throws ValueFormatException, VersionException, LockException,
            ConstraintViolationException, RepositoryException {
        addValue(getSession().getValueFactory().createValue(value));
    }

    @Override
    public void addValue(Value value) throws ValueFormatException, VersionException, LockException,
            ConstraintViolationException, RepositoryException {
        addValues(new Value[] { value });
    }

    @Override
    public void addValues(Value[] values) throws ValueFormatException, VersionException, LockException,
            ConstraintViolationException, RepositoryException {
        List<Value> newValues = new ArrayList<Value>(Arrays.asList(getValues()));
        boolean updated = false;
        for (Value value : values) {
            if (!newValues.contains(value)) {
                newValues.add(value);
                updated = true;
            }
        }
        if (updated) {
            setValue(newValues.toArray(new Value[newValues.size()]));
        }
    }

    public String getString() throws ValueFormatException, RepositoryException {
        return getValue().getString();
    }

    /**
     * @deprecated As of JCR 2.0, {@link #getBinary()} should be used instead.
     */
    public InputStream getStream() throws ValueFormatException, RepositoryException {
        return getValue().getStream();
    }

    public long getLong() throws ValueFormatException, RepositoryException {
        return getValue().getLong();
    }

    public double getDouble() throws ValueFormatException, RepositoryException {
        return getValue().getDouble();
    }

    public Calendar getDate() throws ValueFormatException, RepositoryException {
        return getValue().getDate();
    }

    public boolean getBoolean() throws ValueFormatException, RepositoryException {
        return getValue().getBoolean();
    }

    public JCRNodeWrapper getNode() throws ValueFormatException, RepositoryException {
        Value value = getValue();
        int type = value.getType();
        switch (type) {
        case PropertyType.REFERENCE:
        case PropertyType.WEAKREFERENCE:
            return session.getNodeByUUID(value.getString());

        case PropertyType.PATH:
        case PropertyType.NAME:
            String path = value.getString();
            boolean absolute = StringUtils.startsWith(path, "/");
            return (absolute) ? session.getNode(path) : getParent().getNode(path);

        case PropertyType.STRING:
            try {
                Value refValue = ValueHelper.convert(value, PropertyType.REFERENCE, session.getValueFactory());
                return session.getNodeByUUID(refValue.getString());
            } catch (RepositoryException e) {
                // try if STRING value can be interpreted as PATH value
                Value pathValue = ValueHelper.convert(value, PropertyType.PATH, session.getValueFactory());
                absolute = StringUtils.startsWith(pathValue.getString(), "/");
                return (absolute) ? session.getNode(pathValue.getString())
                        : getParent().getNode(pathValue.getString());
            }

        default:
            throw new ValueFormatException(
                    "Property value cannot be converted to a PATH, REFERENCE or WEAKREFERENCE");
        }
    }

    public JCRNodeWrapper getContextualizedNode() throws ValueFormatException, RepositoryException {
        JCRNodeWrapper ref = getNode();
        try {
            return session.getNode(
                    getParent().getPath() + JCRSessionWrapper.DEREF_SEPARATOR + ref.getRealNode().getName());
        } catch (PathNotFoundException e) {
            throw new ItemNotFoundException(e.getMessage(), e);
        }
    }

    public JCRNodeWrapper getReferencedNode() throws ValueFormatException, RepositoryException {
        return getNode();
    }

    public Binary getBinary() throws ValueFormatException, RepositoryException {
        return getValue().getBinary();
    }

    public BigDecimal getDecimal() throws ValueFormatException, RepositoryException {
        return getValue().getDecimal();
    }

    public Property getProperty() throws ItemNotFoundException, ValueFormatException, RepositoryException {
        Value value = getValue();
        Value pathValue = ValueHelper.convert(value, PropertyType.PATH, session.getValueFactory());
        String path = pathValue.getString();
        boolean absolute = StringUtils.startsWith(path, "/");
        return (absolute) ? session.getProperty(path) : getParent().getProperty(path);
    }

    public long getLength() throws ValueFormatException, RepositoryException {
        return property.getLength();
    }

    public long[] getLengths() throws ValueFormatException, RepositoryException {
        return property.getLengths();
    }

    public ExtendedPropertyDefinition getDefinition() throws RepositoryException {
        return def;
    }

    public int getType() throws RepositoryException {
        return def.getRequiredType();
    }

    public String getName() throws RepositoryException {
        return name;
    }

    @Override
    public JCRItemWrapper getAncestor(int i)
            throws ItemNotFoundException, AccessDeniedException, RepositoryException {
        return provider.getItemWrapper(property.getAncestor(i), session);
    }

    public JCRNodeWrapper getParent() throws ItemNotFoundException, AccessDeniedException, RepositoryException {
        return node;
    }

    public int getDepth() throws RepositoryException {
        return property.getDepth();
    }

    public boolean isNode() {
        return property.isNode();
    }

    public boolean isNew() {
        return property.isNew();
    }

    public boolean isModified() {
        return property.isModified();
    }

    @Override
    public boolean isSame(Item item) throws RepositoryException {
        return property.isSame(item) || (item instanceof JCRItemWrapperImpl && item.isSame(property));
    }

    @Override
    public void accept(ItemVisitor itemVisitor) throws RepositoryException {
        property.accept(itemVisitor);
    }

    /**
     * @deprecated As of JCR 2.0, {@link Session#save()} should
     *             be used instead.
     */
    public void save() throws AccessDeniedException, ItemExistsException, ConstraintViolationException,
            InvalidItemStateException, ReferentialIntegrityException, VersionException, LockException,
            NoSuchNodeTypeException, RepositoryException {
        property.save();
    }

    @Override
    public void refresh(boolean b) throws InvalidItemStateException, RepositoryException {
        property.refresh(b);
    }

    @Override
    public void remove() throws VersionException, LockException, ConstraintViolationException, RepositoryException {
        node.checkLock();
        JCRStoreService.getInstance().getInterceptorChain().beforeRemove(node, name, def);
        property.remove();
        JCRNodeWrapper n = node;
        if (n instanceof JCRNodeDecorator) {
            n = ((JCRNodeDecorator) n).getDecoratedNode();
        }
        if (n instanceof JCRNodeWrapperImpl) {
            ((JCRNodeWrapperImpl) n).flushLocalCaches();
        }
    }

    public boolean isMultiple() throws RepositoryException {
        return property.isMultiple();
    }

    public JCRValueWrapper getValue() throws ValueFormatException, RepositoryException {
        Value value = JCRStoreService.getInstance().getInterceptorChain().afterGetValue(this, property.getValue());
        return wrap(value);
    }

    public JCRValueWrapper getRealValue() throws ValueFormatException, RepositoryException {
        return wrap(property.getValue());
    }

    private JCRValueWrapper wrap(Value value) throws RepositoryException {
        return new JCRValueWrapperImpl(value, getDefinition(), getSession());
    }

    public JCRValueWrapper[] getValues() throws ValueFormatException, RepositoryException {
        Value[] values = JCRStoreService.getInstance().getInterceptorChain().afterGetValues(this,
                property.getValues());

        return wrap(values);
    }

    public JCRValueWrapper[] getRealValues() throws ValueFormatException, RepositoryException {
        return wrap(property.getValues());
    }

    private JCRValueWrapper[] wrap(Value[] values) throws RepositoryException {
        JCRValueWrapper[] wrappedValues = new JCRValueWrapper[values.length];
        for (int i = 0; i < values.length; i++) {
            Value value = values[i];
            wrappedValues[i] = new JCRValueWrapperImpl(value, getDefinition(), getSession());
        }
        return wrappedValues;
    }

    public String getLocale() throws RepositoryException {
        if (def.isInternationalized()) {
            Node parent = property.getParent();
            String parentName = parent.getName();
            if ("jcr:frozenNode".equals(parentName)) {
                // we have a property of a version node -> get the locale as property
                try {
                    return parent.getProperty(Constants.JCR_LANGUAGE).getString();
                } catch (PathNotFoundException e) {
                    return null;
                }
            }
            return StringUtils.substringAfter(parentName, "j:translation_");
        }
        return null;
    }

    @Override
    public boolean removeValue(Value value) throws ValueFormatException, VersionException, LockException,
            ConstraintViolationException, RepositoryException {
        return removeValues(new Value[] { value });
    }

    @Override
    public boolean removeValues(Value[] values) throws ValueFormatException, VersionException, LockException,
            ConstraintViolationException, RepositoryException {
        Value[] valueArray = getValues();
        if (valueArray == null || valueArray.length == 0) {
            return false;
        }

        List<Value> newValues = new ArrayList<Value>(Arrays.asList(valueArray));
        boolean updated = false;
        for (Value value : values) {
            if (newValues.contains(value)) {
                newValues.remove(value);
                updated = true;
            }
        }
        if (updated) {
            setValue(newValues.toArray(new Value[newValues.size()]));
        }

        return updated;
    }

    @Override
    public Property getRealProperty() {
        return property;
    }

}