Search in sources :

Example 16 with EffectiveNodeType

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

the class WorkspaceImporter method startNode.

/**
     * {@inheritDoc}
     */
public void startNode(NodeInfo nodeInfo, List<PropInfo> propInfos) throws RepositoryException {
    if (aborted) {
        // the import has been aborted, get outta here...
        return;
    }
    boolean succeeded = false;
    NodeState parent;
    try {
        // check sanity of workspace/session first
        wsp.sanityCheck();
        parent = parents.peek();
        // process node
        NodeState node = null;
        NodeId id = nodeInfo.getId();
        Name nodeName = nodeInfo.getName();
        Name ntName = nodeInfo.getNodeTypeName();
        Name[] mixins = nodeInfo.getMixinNames();
        if (parent == null) {
            // parent node was skipped, skip this child node too
            // push null onto stack for skipped node
            parents.push(null);
            succeeded = true;
            log.debug("skipping node " + nodeName);
            return;
        }
        if (parent.hasChildNodeEntry(nodeName)) {
            // a node with that name already exists...
            ChildNodeEntry entry = parent.getChildNodeEntry(nodeName, 1);
            NodeId idExisting = entry.getId();
            NodeState existing = (NodeState) itemOps.getItemState(idExisting);
            QNodeDefinition def = itemOps.findApplicableNodeDefinition(nodeName, existing.getNodeTypeName(), parent);
            if (!def.allowsSameNameSiblings()) {
                // existing doesn't allow same-name siblings,
                // check for potential conflicts
                EffectiveNodeType entExisting = itemOps.getEffectiveNodeType(existing);
                if (def.isProtected() && entExisting.includesNodeType(ntName)) {
                    // skip protected node
                    // push null onto stack for skipped node
                    parents.push(null);
                    succeeded = true;
                    log.debug("skipping protected node " + itemOps.safeGetJCRPath(existing.getNodeId()));
                    return;
                }
                if (def.isAutoCreated() && entExisting.includesNodeType(ntName)) {
                    // this node has already been auto-created,
                    // no need to create it
                    node = existing;
                } else {
                    // (see http://issues.apache.org/jira/browse/JCR-1128)
                    if (!(idExisting.equals(id) && (uuidBehavior == ImportUUIDBehavior.IMPORT_UUID_COLLISION_REMOVE_EXISTING || uuidBehavior == ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING))) {
                        throw new ItemExistsException(itemOps.safeGetJCRPath(existing.getNodeId()));
                    }
                // fall through
                }
            }
        }
        if (node == null) {
            // there's no node with that name...
            if (id == null) {
                // no potential uuid conflict, always create new node
                QNodeDefinition def = itemOps.findApplicableNodeDefinition(nodeName, ntName, parent);
                if (def.isProtected()) {
                    // skip protected node
                    // push null onto stack for skipped node
                    parents.push(null);
                    succeeded = true;
                    log.debug("skipping protected node " + nodeName);
                    return;
                }
                // check if new node can be added (check access rights &
                // node type constraints only, assume locking & versioning status
                // and retention/hold has already been checked on ancestor)
                itemOps.checkAddNode(parent, nodeName, ntName, BatchedItemOperations.CHECK_ACCESS | BatchedItemOperations.CHECK_CONSTRAINTS);
                // do create new node
                node = itemOps.createNodeState(parent, nodeName, ntName, mixins, null, def);
            } else {
                // potential uuid conflict
                try {
                    NodeState conflicting = itemOps.getNodeState(id);
                    // resolve uuid conflict
                    node = resolveUUIDConflict(parent, conflicting, nodeInfo);
                    if (node == null) {
                        // no new node has been created, so skip this node
                        // push null onto stack for skipped node
                        parents.push(null);
                        succeeded = true;
                        log.debug("skipping existing node: " + nodeName);
                        return;
                    }
                } catch (ItemNotFoundException e) {
                    // create new with given uuid
                    QNodeDefinition def = itemOps.findApplicableNodeDefinition(nodeName, ntName, parent);
                    if (def.isProtected()) {
                        // skip protected node
                        // push null onto stack for skipped node
                        parents.push(null);
                        succeeded = true;
                        log.debug("skipping protected node " + nodeName);
                        return;
                    }
                    // check if new node can be added (check access rights &
                    // node type constraints only, assume locking & versioning status
                    // and retention/hold has already been checked on ancestor)
                    itemOps.checkAddNode(parent, nodeName, ntName, BatchedItemOperations.CHECK_ACCESS | BatchedItemOperations.CHECK_CONSTRAINTS);
                    // do create new node
                    node = itemOps.createNodeState(parent, nodeName, ntName, mixins, id, def);
                }
            }
        }
        // process properties
        for (PropInfo propInfo : propInfos) {
            processProperty(node, propInfo);
        }
        // store affected nodes
        itemOps.store(node);
        itemOps.store(parent);
        // push current node onto stack of parents
        parents.push(node);
        succeeded = true;
    } finally {
        if (!succeeded) {
            // update operation failed, cancel all modifications
            aborted = true;
            itemOps.cancel();
        }
    }
}
Also used : EffectiveNodeType(org.apache.jackrabbit.core.nodetype.EffectiveNodeType) NodeState(org.apache.jackrabbit.core.state.NodeState) ItemExistsException(javax.jcr.ItemExistsException) ChildNodeEntry(org.apache.jackrabbit.core.state.ChildNodeEntry) NodeId(org.apache.jackrabbit.core.id.NodeId) QNodeDefinition(org.apache.jackrabbit.spi.QNodeDefinition) Name(org.apache.jackrabbit.spi.Name) ItemNotFoundException(javax.jcr.ItemNotFoundException)

Example 17 with EffectiveNodeType

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

the class NodeStateEx method getDefinition.

/**
     * Returns the QNodeDefinition for this state
     * @return the node def
     * @throws RepositoryException if an error occurs
     */
public QNodeDefinition getDefinition() throws RepositoryException {
    if (def == null) {
        EffectiveNodeType ent = getParent().getEffectiveNodeType();
        def = ent.getApplicableChildNodeDef(getName(), nodeState.getNodeTypeName(), ntReg);
    }
    return def;
}
Also used : EffectiveNodeType(org.apache.jackrabbit.core.nodetype.EffectiveNodeType)

Example 18 with EffectiveNodeType

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

the class BatchedItemOperations method checkAddNode.

//--------------------------------------< misc. high-level helper methods >
/**
     * Checks if adding a child node called <code>nodeName</code> of node type
     * <code>nodeTypeName</code> to the given parent node is allowed in the
     * current context.
     *
     * @param parentState
     * @param nodeName
     * @param nodeTypeName
     * @param options      bit-wise OR'ed flags specifying the checks that should be
     *                     performed; any combination of the following constants:
     *                     <ul>
     *                     <li><code>{@link #CHECK_ACCESS}</code>: make sure
     *                     current session is granted read &amp; write access on
     *                     parent node</li>
     *                     <li><code>{@link #CHECK_LOCK}</code>: make sure
     *                     there's no foreign lock on parent node</li>
     *                     <li><code>{@link #CHECK_CHECKED_OUT}</code>: make sure
     *                     parent node is checked-out</li>
     *                     <li><code>{@link #CHECK_CONSTRAINTS}</code>:
     *                     make sure no node type constraints would be violated</li>
     *                     <li><code>{@link #CHECK_HOLD}</code>: check for effective holds preventing the add operation</li>
     *                     <li><code>{@link #CHECK_RETENTION}</code>: check for effective retention policy preventing the add operation</li>
     *                     </ul>
     * @throws ConstraintViolationException
     * @throws AccessDeniedException
     * @throws VersionException
     * @throws LockException
     * @throws ItemNotFoundException
     * @throws ItemExistsException
     * @throws RepositoryException
     */
public void checkAddNode(NodeState parentState, Name nodeName, Name nodeTypeName, int options) throws ConstraintViolationException, AccessDeniedException, VersionException, LockException, ItemNotFoundException, ItemExistsException, RepositoryException {
    Path parentPath = hierMgr.getPath(parentState.getNodeId());
    if ((options & CHECK_LOCK) == CHECK_LOCK) {
        // make sure there's no foreign lock on parent node
        verifyUnlocked(parentPath);
    }
    if ((options & CHECK_CHECKED_OUT) == CHECK_CHECKED_OUT) {
        // make sure parent node is checked-out
        verifyCheckedOut(parentPath);
    }
    if ((options & CHECK_ACCESS) == CHECK_ACCESS) {
        AccessManager accessMgr = context.getAccessManager();
        // make sure current session is granted read access on parent node
        if (!accessMgr.isGranted(parentPath, Permission.READ)) {
            throw new ItemNotFoundException(safeGetJCRPath(parentState.getNodeId()));
        }
        // make sure current session is granted write access on parent node
        if (!accessMgr.isGranted(parentPath, nodeName, Permission.ADD_NODE)) {
            throw new AccessDeniedException(safeGetJCRPath(parentState.getNodeId()) + ": not allowed to add child node");
        }
        // specified node type (and ev. mixins)
        if (!accessMgr.isGranted(parentPath, nodeName, Permission.NODE_TYPE_MNGMT)) {
            throw new AccessDeniedException(safeGetJCRPath(parentState.getNodeId()) + ": not allowed to add child node");
        }
    }
    if ((options & CHECK_CONSTRAINTS) == CHECK_CONSTRAINTS) {
        QItemDefinition parentDef = context.getItemManager().getDefinition(parentState).unwrap();
        // make sure parent node is not protected
        if (parentDef.isProtected()) {
            throw new ConstraintViolationException(safeGetJCRPath(parentState.getNodeId()) + ": cannot add child node to protected parent node");
        }
        // make sure there's an applicable definition for new child node
        EffectiveNodeType entParent = getEffectiveNodeType(parentState);
        entParent.checkAddNodeConstraints(nodeName, nodeTypeName, context.getNodeTypeRegistry());
        QNodeDefinition newNodeDef = findApplicableNodeDefinition(nodeName, nodeTypeName, parentState);
        // check for name collisions
        if (parentState.hasChildNodeEntry(nodeName)) {
            // there's already a node with that name...
            // get definition of existing conflicting node
            ChildNodeEntry entry = parentState.getChildNodeEntry(nodeName, 1);
            NodeState conflictingState;
            NodeId conflictingId = entry.getId();
            try {
                conflictingState = (NodeState) stateMgr.getItemState(conflictingId);
            } catch (ItemStateException ise) {
                String msg = "internal error: failed to retrieve state of " + safeGetJCRPath(conflictingId);
                log.debug(msg);
                throw new RepositoryException(msg, ise);
            }
            QNodeDefinition conflictingTargetDef = context.getItemManager().getDefinition(conflictingState).unwrap();
            // check same-name sibling setting of both target and existing node
            if (!conflictingTargetDef.allowsSameNameSiblings() || !newNodeDef.allowsSameNameSiblings()) {
                throw new ItemExistsException("cannot add child node '" + nodeName.getLocalName() + "' to " + safeGetJCRPath(parentState.getNodeId()) + ": colliding with same-named existing node");
            }
        }
    }
    RetentionRegistry retentionReg = context.getSessionImpl().getRetentionRegistry();
    if ((options & CHECK_HOLD) == CHECK_HOLD) {
        if (retentionReg.hasEffectiveHold(parentPath, false)) {
            throw new RepositoryException("Unable to add node. Parent is affected by a hold.");
        }
    }
    if ((options & CHECK_RETENTION) == CHECK_RETENTION) {
        if (retentionReg.hasEffectiveRetention(parentPath, false)) {
            throw new RepositoryException("Unable to add node. Parent is affected by a retention.");
        }
    }
}
Also used : Path(org.apache.jackrabbit.spi.Path) AccessManager(org.apache.jackrabbit.core.security.AccessManager) AccessDeniedException(javax.jcr.AccessDeniedException) NodeState(org.apache.jackrabbit.core.state.NodeState) ChildNodeEntry(org.apache.jackrabbit.core.state.ChildNodeEntry) RepositoryException(javax.jcr.RepositoryException) RetentionRegistry(org.apache.jackrabbit.core.retention.RetentionRegistry) QItemDefinition(org.apache.jackrabbit.spi.QItemDefinition) QNodeDefinition(org.apache.jackrabbit.spi.QNodeDefinition) NoSuchItemStateException(org.apache.jackrabbit.core.state.NoSuchItemStateException) ItemStateException(org.apache.jackrabbit.core.state.ItemStateException) EffectiveNodeType(org.apache.jackrabbit.core.nodetype.EffectiveNodeType) ItemExistsException(javax.jcr.ItemExistsException) NodeId(org.apache.jackrabbit.core.id.NodeId) ConstraintViolationException(javax.jcr.nodetype.ConstraintViolationException) ItemNotFoundException(javax.jcr.ItemNotFoundException)

Example 19 with EffectiveNodeType

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

the class BatchedItemOperations method checkRemoveNode.

/**
     * Checks if removing the given target node from the specifed parent
     * is allowed in the current context.
     *
     * @param targetState
     * @param parentId
     * @param options     bit-wise OR'ed flags specifying the checks that should be
     *                    performed; any combination of the following constants:
     *                    <ul>
     *                    <li><code>{@link #CHECK_ACCESS}</code>: make sure
     *                    current session is granted read access on parent
     *                    and remove privilege on target node</li>
     *                    <li><code>{@link #CHECK_LOCK}</code>: make sure
     *                    there's no foreign lock on parent node</li>
     *                    <li><code>{@link #CHECK_CHECKED_OUT}</code>: make sure
     *                    parent node is checked-out</li>
     *                    <li><code>{@link #CHECK_CONSTRAINTS}</code>:
     *                    make sure no node type constraints would be violated</li>
     *                    <li><code>{@link #CHECK_REFERENCES}</code>:
     *                    make sure no references exist on target node</li>
     *                    <li><code>{@link #CHECK_HOLD}</code>: check for effective holds preventing the add operation</li>
     *                    <li><code>{@link #CHECK_RETENTION}</code>: check for effective retention policy preventing the add operation</li>
     *                    </ul>
     * @throws ConstraintViolationException
     * @throws AccessDeniedException
     * @throws VersionException
     * @throws LockException
     * @throws ItemNotFoundException
     * @throws ReferentialIntegrityException
     * @throws RepositoryException
     */
public void checkRemoveNode(NodeState targetState, NodeId parentId, int options) throws ConstraintViolationException, AccessDeniedException, VersionException, LockException, ItemNotFoundException, ReferentialIntegrityException, RepositoryException {
    if (targetState.getParentId() == null) {
        // root or orphaned node
        throw new ConstraintViolationException("cannot remove root node");
    }
    Path targetPath = hierMgr.getPath(targetState.getNodeId());
    NodeState parentState = getNodeState(parentId);
    Path parentPath = hierMgr.getPath(parentId);
    if ((options & CHECK_LOCK) == CHECK_LOCK) {
        // make sure there's no foreign lock on parent node
        verifyUnlocked(parentPath);
    }
    if ((options & CHECK_CHECKED_OUT) == CHECK_CHECKED_OUT) {
        // make sure parent node is checked-out
        verifyCheckedOut(parentPath);
    }
    if ((options & CHECK_ACCESS) == CHECK_ACCESS) {
        try {
            AccessManager accessMgr = context.getAccessManager();
            // make sure current session is granted read access on parent node
            if (!accessMgr.isGranted(targetPath, Permission.READ)) {
                throw new PathNotFoundException(safeGetJCRPath(targetPath));
            }
            // make sure current session is allowed to remove target node
            if (!accessMgr.isGranted(targetPath, Permission.REMOVE_NODE)) {
                throw new AccessDeniedException(safeGetJCRPath(targetPath) + ": not allowed to remove node");
            }
        } catch (ItemNotFoundException infe) {
            String msg = "internal error: failed to check access rights for " + safeGetJCRPath(targetPath);
            log.debug(msg);
            throw new RepositoryException(msg, infe);
        }
    }
    if ((options & CHECK_CONSTRAINTS) == CHECK_CONSTRAINTS) {
        QItemDefinition parentDef = context.getItemManager().getDefinition(parentState).unwrap();
        if (parentDef.isProtected()) {
            throw new ConstraintViolationException(safeGetJCRPath(parentId) + ": cannot remove child node of protected parent node");
        }
        QItemDefinition targetDef = context.getItemManager().getDefinition(targetState).unwrap();
        if (targetDef.isMandatory()) {
            throw new ConstraintViolationException(safeGetJCRPath(targetPath) + ": cannot remove mandatory node");
        }
        if (targetDef.isProtected()) {
            throw new ConstraintViolationException(safeGetJCRPath(targetPath) + ": cannot remove protected node");
        }
    }
    if ((options & CHECK_REFERENCES) == CHECK_REFERENCES) {
        EffectiveNodeType ent = getEffectiveNodeType(targetState);
        if (ent.includesNodeType(NameConstants.MIX_REFERENCEABLE)) {
            NodeId targetId = targetState.getNodeId();
            if (stateMgr.hasNodeReferences(targetId)) {
                try {
                    NodeReferences refs = stateMgr.getNodeReferences(targetId);
                    if (refs.hasReferences()) {
                        throw new ReferentialIntegrityException(safeGetJCRPath(targetPath) + ": cannot remove node with references");
                    }
                } catch (ItemStateException ise) {
                    String msg = "internal error: failed to check references on " + safeGetJCRPath(targetPath);
                    log.error(msg, ise);
                    throw new RepositoryException(msg, ise);
                }
            }
        }
    }
    RetentionRegistry retentionReg = context.getSessionImpl().getRetentionRegistry();
    if ((options & CHECK_HOLD) == CHECK_HOLD) {
        if (retentionReg.hasEffectiveHold(targetPath, true)) {
            throw new RepositoryException("Unable to perform removal. Node is affected by a hold.");
        }
    }
    if ((options & CHECK_RETENTION) == CHECK_RETENTION) {
        if (retentionReg.hasEffectiveRetention(targetPath, true)) {
            throw new RepositoryException("Unable to perform removal. Node is affected by a retention.");
        }
    }
}
Also used : Path(org.apache.jackrabbit.spi.Path) AccessManager(org.apache.jackrabbit.core.security.AccessManager) AccessDeniedException(javax.jcr.AccessDeniedException) NodeState(org.apache.jackrabbit.core.state.NodeState) RepositoryException(javax.jcr.RepositoryException) NodeReferences(org.apache.jackrabbit.core.state.NodeReferences) RetentionRegistry(org.apache.jackrabbit.core.retention.RetentionRegistry) QItemDefinition(org.apache.jackrabbit.spi.QItemDefinition) NoSuchItemStateException(org.apache.jackrabbit.core.state.NoSuchItemStateException) ItemStateException(org.apache.jackrabbit.core.state.ItemStateException) EffectiveNodeType(org.apache.jackrabbit.core.nodetype.EffectiveNodeType) ReferentialIntegrityException(javax.jcr.ReferentialIntegrityException) NodeId(org.apache.jackrabbit.core.id.NodeId) ConstraintViolationException(javax.jcr.nodetype.ConstraintViolationException) PathNotFoundException(javax.jcr.PathNotFoundException) ItemNotFoundException(javax.jcr.ItemNotFoundException)

Example 20 with EffectiveNodeType

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

the class ItemSaveOperation method processShareableNodes.

/**
     * Process all items given in iterator and check whether <code>mix:shareable</code>
     * or (some derived node type) has been added or removed:
     * <ul>
     * <li>If the mixin <code>mix:shareable</code> (or some derived node type),
     * then initialize the shared set inside the state.</li>
     * <li>If the mixin <code>mix:shareable</code> (or some derived node type)
     * has been removed, throw.</li>
     * </ul>
     */
private void processShareableNodes(NodeTypeRegistry registry, Iterable<ItemState> states) throws RepositoryException {
    for (ItemState is : states) {
        if (is.isNode()) {
            NodeState ns = (NodeState) is;
            boolean wasShareable = false;
            if (ns.hasOverlayedState()) {
                NodeState old = (NodeState) ns.getOverlayedState();
                EffectiveNodeType ntOld = getEffectiveNodeType(registry, old);
                wasShareable = ntOld.includesNodeType(NameConstants.MIX_SHAREABLE);
            }
            EffectiveNodeType ntNew = getEffectiveNodeType(registry, ns);
            boolean isShareable = ntNew.includesNodeType(NameConstants.MIX_SHAREABLE);
            if (!wasShareable && isShareable) {
                // mix:shareable has been added
                ns.addShare(ns.getParentId());
            } else if (wasShareable && !isShareable) {
                // mix:shareable has been removed: not supported
                String msg = "Removing mix:shareable is not supported.";
                log.debug(msg);
                throw new UnsupportedRepositoryOperationException(msg);
            }
        }
    }
}
Also used : UnsupportedRepositoryOperationException(javax.jcr.UnsupportedRepositoryOperationException) EffectiveNodeType(org.apache.jackrabbit.core.nodetype.EffectiveNodeType) NodeState(org.apache.jackrabbit.core.state.NodeState) ItemState(org.apache.jackrabbit.core.state.ItemState)

Aggregations

EffectiveNodeType (org.apache.jackrabbit.core.nodetype.EffectiveNodeType)24 NodeState (org.apache.jackrabbit.core.state.NodeState)16 RepositoryException (javax.jcr.RepositoryException)15 Name (org.apache.jackrabbit.spi.Name)14 ConstraintViolationException (javax.jcr.nodetype.ConstraintViolationException)13 NodeTypeConflictException (org.apache.jackrabbit.core.nodetype.NodeTypeConflictException)10 NodeTypeRegistry (org.apache.jackrabbit.core.nodetype.NodeTypeRegistry)10 ChildNodeEntry (org.apache.jackrabbit.core.state.ChildNodeEntry)10 NodeId (org.apache.jackrabbit.core.id.NodeId)9 ItemStateException (org.apache.jackrabbit.core.state.ItemStateException)9 QNodeDefinition (org.apache.jackrabbit.spi.QNodeDefinition)7 ItemExistsException (javax.jcr.ItemExistsException)6 PropertyId (org.apache.jackrabbit.core.id.PropertyId)6 NodeTypeManagerImpl (org.apache.jackrabbit.core.nodetype.NodeTypeManagerImpl)6 InternalValue (org.apache.jackrabbit.core.value.InternalValue)6 QItemDefinition (org.apache.jackrabbit.spi.QItemDefinition)6 HashSet (java.util.HashSet)5 ItemNotFoundException (javax.jcr.ItemNotFoundException)5 PropertyState (org.apache.jackrabbit.core.state.PropertyState)5 Path (org.apache.jackrabbit.spi.Path)5