Search in sources :

Example 1 with PropertyDefinition

use of javax.jcr.nodetype.PropertyDefinition in project jackrabbit by apache.

the class RemoveMixinOperation method perform.

public Object perform(SessionContext context) throws RepositoryException {
    SessionImpl session = context.getSessionImpl();
    ItemManager itemMgr = context.getItemManager();
    SessionItemStateManager stateMgr = context.getItemStateManager();
    context.getItemValidator().checkModify(node, CHECK_LOCK | CHECK_CHECKED_OUT | CHECK_CONSTRAINTS | CHECK_HOLD, Permission.NODE_TYPE_MNGMT);
    // check if mixin is assigned
    NodeState state = node.getNodeState();
    if (!state.getMixinTypeNames().contains(mixinName)) {
        throw new NoSuchNodeTypeException("Mixin " + context.getJCRName(mixinName) + " not included in " + node);
    }
    NodeTypeManagerImpl ntMgr = context.getNodeTypeManager();
    NodeTypeRegistry ntReg = context.getNodeTypeRegistry();
    // build effective node type of remaining mixin's & primary type
    Set<Name> remainingMixins = new HashSet<Name>(state.getMixinTypeNames());
    // remove name of target mixin
    remainingMixins.remove(mixinName);
    EffectiveNodeType entResulting;
    try {
        // build effective node type representing primary type
        // including remaining mixin's
        entResulting = ntReg.getEffectiveNodeType(state.getNodeTypeName(), remainingMixins);
    } catch (NodeTypeConflictException e) {
        throw new ConstraintViolationException(e.getMessage(), e);
    }
    // mix:referenceable needs special handling because it has
    // special semantics:
    // it can only be removed if there no more references to this node
    NodeTypeImpl mixin = ntMgr.getNodeType(mixinName);
    if (isReferenceable(mixin) && !entResulting.includesNodeType(MIX_REFERENCEABLE)) {
        if (node.getReferences().hasNext()) {
            throw new ConstraintViolationException(mixinName + " can not be removed:" + " the node is being referenced through at least" + " one property of type REFERENCE");
        }
    }
    // currently locked even if the editing session is the lock holder.
    if ((NameConstants.MIX_LOCKABLE.equals(mixinName) || mixin.isDerivedFrom(NameConstants.MIX_LOCKABLE)) && !entResulting.includesNodeType(NameConstants.MIX_LOCKABLE) && node.isLocked()) {
        throw new ConstraintViolationException(mixinName + " can not be removed: the node is locked.");
    }
    NodeState thisState = (NodeState) node.getOrCreateTransientItemState();
    // collect information about properties and nodes which require further
    // action as a result of the mixin removal; we need to do this *before*
    // actually changing the assigned mixin types, otherwise we wouldn't
    // be able to retrieve the current definition of an item.
    Map<PropertyId, PropertyDefinition> affectedProps = new HashMap<PropertyId, PropertyDefinition>();
    Map<ChildNodeEntry, NodeDefinition> affectedNodes = new HashMap<ChildNodeEntry, NodeDefinition>();
    try {
        Set<Name> names = thisState.getPropertyNames();
        for (Name propName : names) {
            PropertyId propId = new PropertyId(thisState.getNodeId(), propName);
            PropertyState propState = (PropertyState) stateMgr.getItemState(propId);
            PropertyDefinition oldDef = itemMgr.getDefinition(propState);
            // check if property has been defined by mixin type
            // (or one of its supertypes)
            NodeTypeImpl declaringNT = (NodeTypeImpl) oldDef.getDeclaringNodeType();
            if (!entResulting.includesNodeType(declaringNT.getQName())) {
                // the resulting effective node type doesn't include the
                // node type that declared this property
                affectedProps.put(propId, oldDef);
            }
        }
        List<ChildNodeEntry> entries = thisState.getChildNodeEntries();
        for (ChildNodeEntry entry : entries) {
            NodeState nodeState = (NodeState) stateMgr.getItemState(entry.getId());
            NodeDefinition oldDef = itemMgr.getDefinition(nodeState);
            // check if node has been defined by mixin type
            // (or one of its supertypes)
            NodeTypeImpl declaringNT = (NodeTypeImpl) oldDef.getDeclaringNodeType();
            if (!entResulting.includesNodeType(declaringNT.getQName())) {
                // the resulting effective node type doesn't include the
                // node type that declared this child node
                affectedNodes.put(entry, oldDef);
            }
        }
    } catch (ItemStateException e) {
        throw new RepositoryException("Failed to determine effect of removing mixin " + context.getJCRName(mixinName), e);
    }
    // modify the state of this node
    thisState.setMixinTypeNames(remainingMixins);
    // set jcr:mixinTypes property
    node.setMixinTypesProperty(remainingMixins);
    // process affected nodes & properties:
    // 1. try to redefine item based on the resulting
    //    new effective node type (see JCR-2130)
    // 2. remove item if 1. fails
    boolean success = false;
    try {
        for (Map.Entry<PropertyId, PropertyDefinition> entry : affectedProps.entrySet()) {
            PropertyId id = entry.getKey();
            PropertyImpl prop = (PropertyImpl) itemMgr.getItem(id);
            PropertyDefinition oldDef = entry.getValue();
            if (oldDef.isProtected()) {
                // remove 'orphaned' protected properties immediately
                node.removeChildProperty(id.getName());
                continue;
            }
            // redefine property if possible (JCR-2130)
            try {
                PropertyDefinitionImpl newDef = node.getApplicablePropertyDefinition(id.getName(), prop.getType(), oldDef.isMultiple(), false);
                if (newDef.getRequiredType() != PropertyType.UNDEFINED && newDef.getRequiredType() != prop.getType()) {
                    // value conversion required
                    if (oldDef.isMultiple()) {
                        // convert value
                        Value[] values = ValueHelper.convert(prop.getValues(), newDef.getRequiredType(), session.getValueFactory());
                        // redefine property
                        prop.onRedefine(newDef.unwrap());
                        // set converted values
                        prop.setValue(values);
                    } else {
                        // convert value
                        Value value = ValueHelper.convert(prop.getValue(), newDef.getRequiredType(), session.getValueFactory());
                        // redefine property
                        prop.onRedefine(newDef.unwrap());
                        // set converted values
                        prop.setValue(value);
                    }
                } else {
                    // redefine property
                    prop.onRedefine(newDef.unwrap());
                }
            } catch (ValueFormatException vfe) {
                // value conversion failed, remove it
                node.removeChildProperty(id.getName());
            } catch (ConstraintViolationException cve) {
                // no suitable definition found for this property,
                // remove it
                node.removeChildProperty(id.getName());
            }
        }
        for (ChildNodeEntry entry : affectedNodes.keySet()) {
            NodeState nodeState = (NodeState) stateMgr.getItemState(entry.getId());
            NodeImpl childNode = (NodeImpl) itemMgr.getItem(entry.getId());
            NodeDefinition oldDef = affectedNodes.get(entry);
            if (oldDef.isProtected()) {
                // remove 'orphaned' protected child node immediately
                node.removeChildNode(entry.getId());
                continue;
            }
            // redefine node if possible (JCR-2130)
            try {
                NodeDefinitionImpl newDef = node.getApplicableChildNodeDefinition(entry.getName(), nodeState.getNodeTypeName());
                // redefine node
                childNode.onRedefine(newDef.unwrap());
            } catch (ConstraintViolationException cve) {
                // no suitable definition found for this child node,
                // remove it
                node.removeChildNode(entry.getId());
            }
        }
        success = true;
    } catch (ItemStateException e) {
        throw new RepositoryException("Failed to clean up child items defined by removed mixin " + context.getJCRName(mixinName), e);
    } finally {
        if (!success) {
        // TODO JCR-1914: revert any changes made so far
        }
    }
    return this;
}
Also used : NodeState(org.apache.jackrabbit.core.state.NodeState) NodeTypeImpl(org.apache.jackrabbit.core.nodetype.NodeTypeImpl) HashMap(java.util.HashMap) NodeTypeConflictException(org.apache.jackrabbit.core.nodetype.NodeTypeConflictException) NodeDefinition(javax.jcr.nodetype.NodeDefinition) Name(org.apache.jackrabbit.spi.Name) NodeDefinitionImpl(org.apache.jackrabbit.spi.commons.nodetype.NodeDefinitionImpl) ConstraintViolationException(javax.jcr.nodetype.ConstraintViolationException) NodeTypeManagerImpl(org.apache.jackrabbit.core.nodetype.NodeTypeManagerImpl) HashSet(java.util.HashSet) ChildNodeEntry(org.apache.jackrabbit.core.state.ChildNodeEntry) PropertyDefinitionImpl(org.apache.jackrabbit.spi.commons.nodetype.PropertyDefinitionImpl) RepositoryException(javax.jcr.RepositoryException) PropertyDefinition(javax.jcr.nodetype.PropertyDefinition) NoSuchNodeTypeException(javax.jcr.nodetype.NoSuchNodeTypeException) PropertyId(org.apache.jackrabbit.core.id.PropertyId) PropertyState(org.apache.jackrabbit.core.state.PropertyState) ItemStateException(org.apache.jackrabbit.core.state.ItemStateException) EffectiveNodeType(org.apache.jackrabbit.core.nodetype.EffectiveNodeType) Value(javax.jcr.Value) ValueFormatException(javax.jcr.ValueFormatException) NodeTypeRegistry(org.apache.jackrabbit.core.nodetype.NodeTypeRegistry) SessionItemStateManager(org.apache.jackrabbit.core.state.SessionItemStateManager) HashMap(java.util.HashMap) Map(java.util.Map)

Example 2 with PropertyDefinition

use of javax.jcr.nodetype.PropertyDefinition in project jackrabbit by apache.

the class DefaultHandler method exportProperties.

public boolean exportProperties(PropertyExportContext exportContext, boolean isCollection) throws RepositoryException {
    if (!canExport(exportContext, isCollection)) {
        throw new RepositoryException("PropertyHandler " + getName() + " failed to export properties.");
    }
    Node cn = getContentNode(exportContext, isCollection);
    try {
        // export the properties common with normal I/O handling
        exportProperties(exportContext, isCollection, cn);
        // export all other properties as well
        PropertyIterator it = cn.getProperties();
        while (it.hasNext()) {
            Property p = it.nextProperty();
            String name = p.getName();
            PropertyDefinition def = p.getDefinition();
            if (def.isMultiple() || isDefinedByFilteredNodeType(def)) {
                log.debug("Skip property '" + name + "': not added to webdav property set.");
                continue;
            }
            if (JcrConstants.JCR_DATA.equals(name) || JcrConstants.JCR_MIMETYPE.equals(name) || JcrConstants.JCR_ENCODING.equals(name) || JcrConstants.JCR_LASTMODIFIED.equals(name)) {
                continue;
            }
            DavPropertyName davName = getDavName(name, p.getSession());
            exportContext.setProperty(davName, p.getValue().getString());
        }
        return true;
    } catch (IOException e) {
        // should not occur (log output see 'exportProperties')
        return false;
    }
}
Also used : Node(javax.jcr.Node) PropertyIterator(javax.jcr.PropertyIterator) RepositoryException(javax.jcr.RepositoryException) IOException(java.io.IOException) Property(javax.jcr.Property) DavProperty(org.apache.jackrabbit.webdav.property.DavProperty) PropertyDefinition(javax.jcr.nodetype.PropertyDefinition) DavPropertyName(org.apache.jackrabbit.webdav.property.DavPropertyName)

Example 3 with PropertyDefinition

use of javax.jcr.nodetype.PropertyDefinition in project jackrabbit by apache.

the class MandatoryItemTest method setUp.

@Override
protected void setUp() throws Exception {
    super.setUp();
    NodeType nt = superuser.getWorkspace().getNodeTypeManager().getNodeType(testNodeType);
    NodeDefinition[] ndefs = nt.getChildNodeDefinitions();
    for (int i = 0; i < ndefs.length; i++) {
        if (ndefs[i].isMandatory() && !ndefs[i].isProtected() && !ndefs[i].isAutoCreated()) {
            childNodeDef = ndefs[i];
            break;
        }
    }
    PropertyDefinition[] pdefs = nt.getPropertyDefinitions();
    for (int i = 0; i < pdefs.length; i++) {
        if (pdefs[i].isMandatory() && !pdefs[i].isProtected() && !pdefs[i].isAutoCreated()) {
            childPropDef = pdefs[i];
            break;
        }
    }
    if (childPropDef == null && childNodeDef == null) {
        cleanUp();
        throw new NotExecutableException();
    }
}
Also used : NotExecutableException(org.apache.jackrabbit.test.NotExecutableException) NodeType(javax.jcr.nodetype.NodeType) NodeDefinition(javax.jcr.nodetype.NodeDefinition) PropertyDefinition(javax.jcr.nodetype.PropertyDefinition)

Example 4 with PropertyDefinition

use of javax.jcr.nodetype.PropertyDefinition in project jackrabbit by apache.

the class CanSetPropertyTest method testReturnFalseBecauseIsMultiple.

/**
     * Tests if NodeType.canSetProperty(String propertyName, Value value)
     * returns false if the property is multiple
     */
public void testReturnFalseBecauseIsMultiple() throws NotExecutableException, RepositoryException {
    PropertyDefinition propDef = NodeTypeUtil.locatePropertyDef(session, NodeTypeUtil.ANY_PROPERTY_TYPE, true, false, false, false);
    if (propDef == null) {
        throw new NotExecutableException("No multiple, not protected property def found.");
    }
    NodeType nodeType = propDef.getDeclaringNodeType();
    Value value = NodeTypeUtil.getValueOfType(superuser, propDef.getRequiredType());
    assertFalse("canSetProperty(String propertyName, Value value) must " + "return false if the property is multiple.", nodeType.canSetProperty(propDef.getName(), value));
}
Also used : NotExecutableException(org.apache.jackrabbit.test.NotExecutableException) NodeType(javax.jcr.nodetype.NodeType) Value(javax.jcr.Value) PropertyDefinition(javax.jcr.nodetype.PropertyDefinition)

Example 5 with PropertyDefinition

use of javax.jcr.nodetype.PropertyDefinition in project jackrabbit by apache.

the class NodeTypeTest method testGetDeclaredPropertyDefs.

/**
     * Test if all property defs returned by getDeclatedPropertyDefs() are also
     * returned by getPropertyDefs(). All existing node types are tested.
     */
public void testGetDeclaredPropertyDefs() throws RepositoryException {
    NodeTypeIterator types = manager.getAllNodeTypes();
    while (types.hasNext()) {
        NodeType type = types.nextNodeType();
        PropertyDefinition[] declaredDefs = type.getDeclaredPropertyDefinitions();
        PropertyDefinition[] defs = type.getPropertyDefinitions();
        try {
            for (int i = 0; i < declaredDefs.length; i++) {
                boolean exists = false;
                for (int j = 0; j < defs.length; j++) {
                    if (defs[j].getName().equals(declaredDefs[i].getName())) {
                        exists = true;
                        break;
                    }
                }
                assertTrue("All property defs returned by " + "getDeclaredPropertyDefs() must also be " + "returned by getPropertyDefs()", exists);
            }
        } catch (ArrayIndexOutOfBoundsException e) {
            fail("The array returned by " + "getDeclaredPropertyDefs() must not exceed " + "the one returned by getPropertyDefs()");
        }
    }
}
Also used : NodeType(javax.jcr.nodetype.NodeType) NodeTypeIterator(javax.jcr.nodetype.NodeTypeIterator) PropertyDefinition(javax.jcr.nodetype.PropertyDefinition)

Aggregations

PropertyDefinition (javax.jcr.nodetype.PropertyDefinition)141 NodeType (javax.jcr.nodetype.NodeType)79 Value (javax.jcr.Value)70 NotExecutableException (org.apache.jackrabbit.test.NotExecutableException)61 Node (javax.jcr.Node)27 ConstraintViolationException (javax.jcr.nodetype.ConstraintViolationException)22 Property (javax.jcr.Property)20 NodeTypeIterator (javax.jcr.nodetype.NodeTypeIterator)15 NodeTypeManager (javax.jcr.nodetype.NodeTypeManager)14 RepositoryException (javax.jcr.RepositoryException)13 NodeDefinition (javax.jcr.nodetype.NodeDefinition)13 QPropertyDefinition (org.apache.jackrabbit.spi.QPropertyDefinition)11 Test (org.junit.Test)11 InputStream (java.io.InputStream)5 Session (javax.jcr.Session)5 ValueFormatException (javax.jcr.ValueFormatException)5 PropertyDefinitionImpl (org.apache.jackrabbit.spi.commons.nodetype.PropertyDefinitionImpl)5 ByteArrayInputStream (java.io.ByteArrayInputStream)4 IOException (java.io.IOException)4 Name (org.apache.jackrabbit.spi.Name)4