Search in sources :

Example 1 with EffectiveNodeType

use of org.apache.jackrabbit.jcr2spi.nodetype.EffectiveNodeType in project jackrabbit by apache.

the class SessionImporter method checkIncludesMixReferenceable.

/**
 * Validate the given <code>NodeInfo</code>: make sure, that if a uuid is
 * defined, the primary or the mixin types include mix:referenceable.
 *
 * @param nodeInfo
 * @throws RepositoryException
 */
private void checkIncludesMixReferenceable(Importer.NodeInfo nodeInfo) throws RepositoryException {
    List<Name> l = new ArrayList<Name>();
    l.add(nodeInfo.getNodeTypeName());
    Name[] mixinNames = nodeInfo.getMixinNames();
    if (mixinNames != null && mixinNames.length > 0) {
        l.addAll(Arrays.asList(nodeInfo.getMixinNames()));
    }
    if (l.contains(NameConstants.MIX_REFERENCEABLE)) {
        // shortcut
        return;
    }
    Name[] ntNames = l.toArray(new Name[l.size()]);
    EffectiveNodeType ent = session.getEffectiveNodeTypeProvider().getEffectiveNodeType(ntNames);
    if (!ent.includesNodeType(NameConstants.MIX_REFERENCEABLE)) {
        throw new ConstraintViolationException("XML defines jcr:uuid without defining import node to be referenceable.");
    }
}
Also used : EffectiveNodeType(org.apache.jackrabbit.jcr2spi.nodetype.EffectiveNodeType) ArrayList(java.util.ArrayList) ConstraintViolationException(javax.jcr.nodetype.ConstraintViolationException) Name(org.apache.jackrabbit.spi.Name)

Example 2 with EffectiveNodeType

use of org.apache.jackrabbit.jcr2spi.nodetype.EffectiveNodeType in project jackrabbit by apache.

the class SessionItemStateManager method addNodeState.

private List<ItemState> addNodeState(NodeState parent, Name nodeName, Name nodeTypeName, String uuid, QNodeDefinition definition, int options) throws RepositoryException, ConstraintViolationException, AccessDeniedException, UnsupportedRepositoryOperationException, NoSuchNodeTypeException, ItemExistsException, VersionException {
    // check if add node is possible. note, that the options differ if
    // the 'addNode' is called from inside a regular add-node to create
    // autocreated child nodes that may be 'protected'.
    validator.checkAddNode(parent, nodeName, nodeTypeName, options);
    // a new NodeState doesn't have mixins defined yet -> ent is ent of primarytype
    EffectiveNodeType ent = mgrProvider.getEffectiveNodeTypeProvider().getEffectiveNodeType(nodeTypeName);
    if (nodeTypeName == null) {
        // no primary node type specified,
        // try default primary type from definition
        nodeTypeName = definition.getDefaultPrimaryType();
        if (nodeTypeName == null) {
            String msg = "No applicable node type could be determined for " + nodeName;
            log.debug(msg);
            throw new ConstraintViolationException(msg);
        }
    }
    List<ItemState> addedStates = new ArrayList<ItemState>();
    // create new nodeState. NOTE, that the uniqueID is not added to the
    // state for consistency between 'addNode' and importXML
    NodeState nodeState = transientStateMgr.createNewNodeState(nodeName, null, nodeTypeName, definition, parent);
    addedStates.add(nodeState);
    if (uuid != null) {
        QValue[] value = getQValues(uuid, qValueFactory);
        ItemDefinitionProvider defProvider = mgrProvider.getItemDefinitionProvider();
        QPropertyDefinition pDef = defProvider.getQPropertyDefinition(NameConstants.MIX_REFERENCEABLE, NameConstants.JCR_UUID, PropertyType.STRING, false);
        addedStates.add(addPropertyState(nodeState, NameConstants.JCR_UUID, PropertyType.STRING, value, pDef, 0));
    }
    // add 'auto-create' properties defined in node type
    for (QPropertyDefinition pd : ent.getAutoCreateQPropertyDefinitions()) {
        if (!nodeState.hasPropertyName(pd.getName())) {
            QValue[] autoValue = computeSystemGeneratedPropertyValues(nodeState, pd);
            if (autoValue != null) {
                int propOptions = ItemStateValidator.CHECK_NONE;
                // execute 'addProperty' without adding operation.
                addedStates.add(addPropertyState(nodeState, pd.getName(), pd.getRequiredType(), autoValue, pd, propOptions));
            }
        }
    }
    // recursively add 'auto-create' child nodes defined in node type
    for (QNodeDefinition nd : ent.getAutoCreateQNodeDefinitions()) {
        // execute 'addNode' without adding the operation.
        int opt = ItemStateValidator.CHECK_LOCK | ItemStateValidator.CHECK_COLLISION;
        addedStates.addAll(addNodeState(nodeState, nd.getName(), nd.getDefaultPrimaryType(), null, nd, opt));
    }
    return addedStates;
}
Also used : QValue(org.apache.jackrabbit.spi.QValue) ArrayList(java.util.ArrayList) QNodeDefinition(org.apache.jackrabbit.spi.QNodeDefinition) EffectiveNodeType(org.apache.jackrabbit.jcr2spi.nodetype.EffectiveNodeType) QPropertyDefinition(org.apache.jackrabbit.spi.QPropertyDefinition) ConstraintViolationException(javax.jcr.nodetype.ConstraintViolationException) ItemDefinitionProvider(org.apache.jackrabbit.jcr2spi.nodetype.ItemDefinitionProvider)

Example 3 with EffectiveNodeType

use of org.apache.jackrabbit.jcr2spi.nodetype.EffectiveNodeType in project jackrabbit by apache.

the class NodeImpl method canAddMixin.

/**
 * @param mixinName
 * @return
 * @throws NoSuchNodeTypeException
 * @throws ConstraintViolationException
 */
private boolean canAddMixin(Name mixinName) throws NoSuchNodeTypeException, ConstraintViolationException {
    NodeTypeManagerImpl ntMgr = session.getNodeTypeManager();
    // first check characteristics of each mixin
    NodeType mixin = ntMgr.getNodeType(mixinName);
    if (!mixin.isMixin()) {
        log.error(mixin.getName() + ": not a mixin node type");
        return false;
    }
    // get list of existing nodetypes
    Name[] existingNts = getNodeState().getNodeTypeNames();
    // build effective node type representing primary type including existing mixins
    EffectiveNodeType entExisting = session.getEffectiveNodeTypeProvider().getEffectiveNodeType(existingNts);
    // check if the base type supports adding this mixin
    if (!entExisting.supportsMixin(mixinName)) {
        log.debug(mixin.getName() + ": not supported on node type " + getPrimaryNodeTypeName());
        return false;
    }
    // second, build new effective node type for nts including the new mixin
    // types, detecting eventual incompatibilities
    Name[] resultingNts = new Name[existingNts.length + 1];
    System.arraycopy(existingNts, 0, resultingNts, 0, existingNts.length);
    resultingNts[existingNts.length] = mixinName;
    session.getEffectiveNodeTypeProvider().getEffectiveNodeType(resultingNts);
    // all validations succeeded: return true
    return true;
}
Also used : EffectiveNodeType(org.apache.jackrabbit.jcr2spi.nodetype.EffectiveNodeType) NodeType(javax.jcr.nodetype.NodeType) EffectiveNodeType(org.apache.jackrabbit.jcr2spi.nodetype.EffectiveNodeType) NodeTypeManagerImpl(org.apache.jackrabbit.jcr2spi.nodetype.NodeTypeManagerImpl) Name(org.apache.jackrabbit.spi.Name)

Example 4 with EffectiveNodeType

use of org.apache.jackrabbit.jcr2spi.nodetype.EffectiveNodeType in project jackrabbit by apache.

the class NodeImpl method removeMixin.

/**
 * @see Node#removeMixin(String)
 */
public void removeMixin(String mixinName) throws NoSuchNodeTypeException, VersionException, ConstraintViolationException, LockException, RepositoryException {
    checkIsWritable();
    Name ntName = getQName(mixinName);
    List<Name> mixinValue = getMixinTypes();
    // remove name of target mixin
    if (!mixinValue.remove(ntName)) {
        throw new NoSuchNodeTypeException("Cannot remove mixin '" + mixinName + "': Nodetype is not present on this node.");
    }
    // mix:referenceable needs additional assertion: the mixin cannot be
    // removed, if any references are left to this node.
    NodeTypeImpl mixin = session.getNodeTypeManager().getNodeType(ntName);
    if (mixin.isNodeType(NameConstants.MIX_REFERENCEABLE)) {
        EffectiveNodeType entRemaining = getRemainingENT(mixinValue);
        if (!entRemaining.includesNodeType(NameConstants.MIX_REFERENCEABLE)) {
            PropertyIterator iter = getReferences();
            if (iter.hasNext()) {
                throw new ConstraintViolationException("Mixin type " + mixinName + " can not be removed: the node is being referenced through at least one property of type REFERENCE");
            }
        }
    }
    /*
         * mix:lockable: the mixin cannot be removed if the node is currently
         * locked even if the editing session is the lock holder.
         */
    if (mixin.isNodeType((NameConstants.MIX_LOCKABLE))) {
        EffectiveNodeType entRemaining = getRemainingENT(mixinValue);
        if (!entRemaining.includesNodeType(NameConstants.MIX_LOCKABLE) && isLocked()) {
            throw new ConstraintViolationException(mixinName + " can not be removed: the node is locked.");
        }
    }
    // delegate to operation
    Name[] mixins = mixinValue.toArray(new Name[mixinValue.size()]);
    Operation op = SetMixin.create(getNodeState(), mixins);
    session.getSessionItemStateManager().execute(op);
}
Also used : EffectiveNodeType(org.apache.jackrabbit.jcr2spi.nodetype.EffectiveNodeType) NodeTypeImpl(org.apache.jackrabbit.jcr2spi.nodetype.NodeTypeImpl) PropertyIterator(javax.jcr.PropertyIterator) ConstraintViolationException(javax.jcr.nodetype.ConstraintViolationException) Operation(org.apache.jackrabbit.jcr2spi.operation.Operation) Name(org.apache.jackrabbit.spi.Name) NoSuchNodeTypeException(javax.jcr.nodetype.NoSuchNodeTypeException)

Example 5 with EffectiveNodeType

use of org.apache.jackrabbit.jcr2spi.nodetype.EffectiveNodeType in project jackrabbit by apache.

the class SessionImporter method startNode.

/**
 * {@inheritDoc}
 */
public void startNode(NodeInfo nodeInfo, List<PropInfo> propInfos, NamePathResolver resolver) throws RepositoryException {
    if (isClosed()) {
        // workspace-importer only: ignore if import has been aborted before.
        return;
    }
    checkSession();
    NodeState parent = parents.peek();
    if (parent == null) {
        // parent node was skipped, skip this child node also
        // push null onto stack for skipped node
        parents.push(null);
        log.debug("Skipping node '" + nodeInfo.getName() + "'.");
        return;
    }
    NodeEntry parentEntry = (NodeEntry) parent.getHierarchyEntry();
    NodeState nodeState = null;
    if (parentEntry.hasNodeEntry(nodeInfo.getName())) {
        try {
            // a valid child node with that name already exists
            NodeEntry entry = parentEntry.getNodeEntry(nodeInfo.getName(), Path.INDEX_DEFAULT);
            NodeState existing = entry.getNodeState();
            QNodeDefinition def = existing.getDefinition();
            if (!def.allowsSameNameSiblings()) {
                // existing doesn't allow same-name siblings, check for conflicts
                EffectiveNodeTypeProvider provider = session.getEffectiveNodeTypeProvider();
                Name[] ntNames = existing.getAllNodeTypeNames();
                EffectiveNodeType entExisting = provider.getEffectiveNodeType(ntNames);
                if (def.isProtected() && entExisting.includesNodeType(nodeInfo.getNodeTypeName())) {
                    // skip protected node
                    // push null onto stack for skipped node
                    parents.push(null);
                    log.debug("skipping protected node " + LogUtil.safeGetJCRPath(existing, session.getPathResolver()));
                    return;
                }
                if (def.isAutoCreated() && entExisting.includesNodeType(nodeInfo.getNodeTypeName())) {
                    // this node has already been auto-created, no need to create it
                    nodeState = existing;
                } else {
                    throw new ItemExistsException(LogUtil.safeGetJCRPath(existing, session.getPathResolver()));
                }
            }
        } catch (ItemNotFoundException e) {
        // 'existing' doesn't exist any more -> ignore
        }
    }
    if (nodeState == null) {
        // node does not exist -> create new one
        if (nodeInfo.getUUID() == null) {
            // no potential uuid conflict, add new node from given info
            nodeState = importNode(nodeInfo, parent);
        } else {
            // make sure the import does not define a uuid without having
            // a primaryType or mixin that makes the new node referenceable
            checkIncludesMixReferenceable(nodeInfo);
            // potential uuid conflict
            try {
                NodeId conflictingId = session.getIdFactory().createNodeId(nodeInfo.getUUID());
                NodeEntry conflicting = session.getHierarchyManager().getNodeEntry(conflictingId);
                // assert that the entry is available
                conflicting.getItemState();
                nodeState = resolveUUIDConflict(parent, conflicting, nodeInfo);
            } catch (ItemNotFoundException e) {
                // no conflict: create new with given uuid
                nodeState = importNode(nodeInfo, parent);
            }
        }
    }
    // node state may be 'null' if applicable def is protected
    if (nodeState != null) {
        // process properties
        for (PropInfo pi : propInfos) {
            importProperty(pi, nodeState, resolver);
        }
    }
    // push current nodeState onto stack of parents
    parents.push(nodeState);
}
Also used : EffectiveNodeTypeProvider(org.apache.jackrabbit.jcr2spi.nodetype.EffectiveNodeTypeProvider) EffectiveNodeType(org.apache.jackrabbit.jcr2spi.nodetype.EffectiveNodeType) NodeState(org.apache.jackrabbit.jcr2spi.state.NodeState) NodeEntry(org.apache.jackrabbit.jcr2spi.hierarchy.NodeEntry) ItemExistsException(javax.jcr.ItemExistsException) NodeId(org.apache.jackrabbit.spi.NodeId) QNodeDefinition(org.apache.jackrabbit.spi.QNodeDefinition) Name(org.apache.jackrabbit.spi.Name) ItemNotFoundException(javax.jcr.ItemNotFoundException)

Aggregations

EffectiveNodeType (org.apache.jackrabbit.jcr2spi.nodetype.EffectiveNodeType)7 Name (org.apache.jackrabbit.spi.Name)6 ConstraintViolationException (javax.jcr.nodetype.ConstraintViolationException)4 QNodeDefinition (org.apache.jackrabbit.spi.QNodeDefinition)3 ArrayList (java.util.ArrayList)2 QPropertyDefinition (org.apache.jackrabbit.spi.QPropertyDefinition)2 AccessDeniedException (javax.jcr.AccessDeniedException)1 ItemExistsException (javax.jcr.ItemExistsException)1 ItemNotFoundException (javax.jcr.ItemNotFoundException)1 PropertyIterator (javax.jcr.PropertyIterator)1 NoSuchNodeTypeException (javax.jcr.nodetype.NoSuchNodeTypeException)1 NodeType (javax.jcr.nodetype.NodeType)1 NodeEntry (org.apache.jackrabbit.jcr2spi.hierarchy.NodeEntry)1 EffectiveNodeTypeProvider (org.apache.jackrabbit.jcr2spi.nodetype.EffectiveNodeTypeProvider)1 ItemDefinitionProvider (org.apache.jackrabbit.jcr2spi.nodetype.ItemDefinitionProvider)1 NodeTypeImpl (org.apache.jackrabbit.jcr2spi.nodetype.NodeTypeImpl)1 NodeTypeManagerImpl (org.apache.jackrabbit.jcr2spi.nodetype.NodeTypeManagerImpl)1 Operation (org.apache.jackrabbit.jcr2spi.operation.Operation)1 NodeState (org.apache.jackrabbit.jcr2spi.state.NodeState)1 NodeId (org.apache.jackrabbit.spi.NodeId)1