Search in sources :

Example 6 with ChildNodeEntry

use of org.apache.jackrabbit.core.state.ChildNodeEntry in project jackrabbit by apache.

the class NodeStateEx method removeNode.

/**
     * removes recursively the node with the given id
     *
     * @param id node id
     * @throws ItemStateException if an error occurs
     */
private void removeNode(NodeId id) throws ItemStateException {
    NodeState state = (NodeState) stateMgr.getItemState(id);
    // remove properties
    for (Name name : state.getPropertyNames()) {
        PropertyId propId = new PropertyId(id, name);
        PropertyState propState = (PropertyState) stateMgr.getItemState(propId);
        stateMgr.destroy(propState);
    }
    state.removeAllPropertyNames();
    // remove child nodes
    for (ChildNodeEntry entry : state.getChildNodeEntries()) {
        removeNode(entry.getId());
    }
    state.removeAllChildNodeEntries();
    // destroy the state itself
    stateMgr.destroy(state);
}
Also used : NodeState(org.apache.jackrabbit.core.state.NodeState) ChildNodeEntry(org.apache.jackrabbit.core.state.ChildNodeEntry) Name(org.apache.jackrabbit.spi.Name) PropertyId(org.apache.jackrabbit.core.id.PropertyId) PropertyState(org.apache.jackrabbit.core.state.PropertyState)

Example 7 with ChildNodeEntry

use of org.apache.jackrabbit.core.state.ChildNodeEntry in project jackrabbit by apache.

the class VersionManagerImplMerge method getCorrespondingNode.

/**
     * Returns the corresponding node in the workspace of the given session.
     * <p>
     * Given a node N1 in workspace W1, its corresponding node N2 in workspace
     * W2 is defined as follows:
     * <ul>
     * <li>If N1 is the root node of W1 then N2 is the root node of W2.
     * <li>If N1 is referenceable (has a UUID) then N2 is the node in W2 with
     * the same UUID.
     * <li>If N1 is not referenceable (does not have a UUID) then there is some
     * node M1 which is either the nearest ancestor of N1 that is
     * referenceable, or is the root node of W1. If the corresponding node
     * of M1 is M2 in W2, then N2 is the node with the same relative path
     * from M2 as N1 has from M1.
     * </ul>
     *
     * @param state N1
     * @param srcRoot the root node state of W2
     * @return the corresponding node or <code>null</code> if no corresponding
     *         node exists.
     * @throws RepositoryException If another error occurs.
     */
private NodeStateEx getCorrespondingNode(NodeStateEx state, NodeStateEx srcRoot) throws RepositoryException {
    // search nearest ancestor that is referenceable
    NodeStateEx m1 = state;
    LinkedList<ChildNodeEntry> elements = new LinkedList<ChildNodeEntry>();
    while (m1.getParentId() != null && !m1.getEffectiveNodeType().includesNodeType(NameConstants.MIX_REFERENCEABLE)) {
        NodeStateEx parent = m1.getParent();
        elements.addFirst(parent.getState().getChildNodeEntry(m1.getNodeId()));
        m1 = parent;
    }
    // check if corresponding ancestor exists
    if (srcRoot.hasNode(m1.getNodeId())) {
        NodeStateEx m2 = srcRoot.getNode(m1.getNodeId());
        Iterator<ChildNodeEntry> iter = elements.iterator();
        while (iter.hasNext() && m2 != null) {
            ChildNodeEntry e = iter.next();
            m2 = m2.getNode(e.getName(), e.getIndex());
        }
        return m2;
    } else {
        return null;
    }
}
Also used : ChildNodeEntry(org.apache.jackrabbit.core.state.ChildNodeEntry) LinkedList(java.util.LinkedList)

Example 8 with ChildNodeEntry

use of org.apache.jackrabbit.core.state.ChildNodeEntry in project jackrabbit by apache.

the class VersionManagerImplMerge method internalMerge.

/**
     * Merges/Updates this node with its corresponding ones
     *
     * @param state state to merge or update
     * @param srcRoot src workspace root node
     * @param failedIds list of failed ids
     * @param bestEffort best effort flag
     * @param shallow is shallow flag
     * @throws RepositoryException if an error occurs
     * @throws ItemStateException if an error occurs
     */
private void internalMerge(NodeStateEx state, NodeStateEx srcRoot, List<ItemId> failedIds, boolean bestEffort, boolean shallow) throws RepositoryException, ItemStateException {
    NodeStateEx srcNode = doMergeTest(state, srcRoot, failedIds, bestEffort);
    if (srcNode == null) {
        if (!shallow) {
            // nodes (see JCR-1046)
            for (NodeStateEx n : state.getChildNodes()) {
                if (n.getEffectiveNodeType().includesNodeType(NameConstants.MIX_VERSIONABLE)) {
                    internalMerge(n, srcRoot, failedIds, bestEffort, shallow);
                }
            }
        }
        return;
    }
    // check lock and hold status if node exists
    checkModify(state, ItemValidator.CHECK_LOCK | ItemValidator.CHECK_HOLD, Permission.NONE);
    // remove all properties that are not present in srcNode
    for (PropertyState prop : state.getProperties()) {
        if (!srcNode.hasProperty(prop.getName())) {
            state.removeProperty(prop.getName());
        }
    }
    // update all properties from the src node
    for (PropertyState prop : srcNode.getProperties()) {
        Name propName = prop.getName();
        // ignore system types
        if (propName.equals(NameConstants.JCR_PRIMARYTYPE) || propName.equals(NameConstants.JCR_MIXINTYPES) || propName.equals(NameConstants.JCR_UUID)) {
            continue;
        }
        state.copyFrom(prop);
    }
    // update the mixin types
    state.setMixins(srcNode.getState().getMixinTypeNames());
    // remove the child nodes in N but not in N'
    LinkedList<ChildNodeEntry> toDelete = new LinkedList<ChildNodeEntry>();
    for (ChildNodeEntry entry : state.getState().getChildNodeEntries()) {
        if (!srcNode.getState().hasChildNodeEntry(entry.getName(), entry.getIndex())) {
            toDelete.add(entry);
        }
    }
    for (ChildNodeEntry entry : toDelete) {
        state.removeNode(entry.getName(), entry.getIndex());
    }
    state.store();
    // add source ones
    for (ChildNodeEntry entry : srcNode.getState().getChildNodeEntries()) {
        NodeStateEx child = state.getNode(entry.getName(), entry.getIndex());
        if (child == null) {
            // if destination workspace already has such an node, remove it
            if (state.hasNode(entry.getId())) {
                child = state.getNode(entry.getId());
                NodeStateEx parent = child.getParent();
                parent.removeNode(child);
                parent.store();
            }
            // create new child
            NodeStateEx srcChild = srcNode.getNode(entry.getId());
            child = state.addNode(entry.getName(), srcChild.getState().getNodeTypeName(), srcChild.getNodeId());
            child.setMixins(srcChild.getState().getMixinTypeNames());
            // copy src child
            state.store();
            internalMerge(child, srcRoot, null, bestEffort, false);
        } else if (!shallow) {
            // recursively merge
            internalMerge(child, srcRoot, failedIds, bestEffort, false);
        }
    }
}
Also used : ChildNodeEntry(org.apache.jackrabbit.core.state.ChildNodeEntry) LinkedList(java.util.LinkedList) PropertyState(org.apache.jackrabbit.core.state.PropertyState) Name(org.apache.jackrabbit.spi.Name)

Example 9 with ChildNodeEntry

use of org.apache.jackrabbit.core.state.ChildNodeEntry in project jackrabbit by apache.

the class WorkspaceImporter method resolveUUIDConflict.

/**
     * @param parent parent node state
     * @param conflicting conflicting node state
     * @param nodeInfo the node info
     * @return the resolved node state
     * @throws RepositoryException if an error occurs
     */
protected NodeState resolveUUIDConflict(NodeState parent, NodeState conflicting, NodeInfo nodeInfo) throws RepositoryException {
    NodeState node;
    if (uuidBehavior == ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW) {
        // create new with new uuid:
        // 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, nodeInfo.getName(), nodeInfo.getNodeTypeName(), BatchedItemOperations.CHECK_ACCESS | BatchedItemOperations.CHECK_CONSTRAINTS);
        node = itemOps.createNodeState(parent, nodeInfo.getName(), nodeInfo.getNodeTypeName(), nodeInfo.getMixinNames(), null);
        // remember uuid mapping
        EffectiveNodeType ent = itemOps.getEffectiveNodeType(node);
        if (ent.includesNodeType(NameConstants.MIX_REFERENCEABLE)) {
            refTracker.mappedId(nodeInfo.getId(), node.getNodeId());
        }
    } else if (uuidBehavior == ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW) {
        // new node and share with existing
        if (conflicting.isShareable()) {
            itemOps.clone(conflicting, parent, nodeInfo.getName());
            return null;
        }
        String msg = "a node with uuid " + nodeInfo.getId() + " already exists!";
        log.debug(msg);
        throw new ItemExistsException(msg);
    } else if (uuidBehavior == ImportUUIDBehavior.IMPORT_UUID_COLLISION_REMOVE_EXISTING) {
        // make sure conflicting node is not importTarget or an ancestor thereof
        Path p0 = hierMgr.getPath(importTarget.getNodeId());
        Path p1 = hierMgr.getPath(conflicting.getNodeId());
        try {
            if (p1.equals(p0) || p1.isAncestorOf(p0)) {
                String msg = "cannot remove ancestor node";
                log.debug(msg);
                throw new ConstraintViolationException(msg);
            }
        } catch (MalformedPathException mpe) {
            // should never get here...
            String msg = "internal error: failed to determine degree of relationship";
            log.error(msg, mpe);
            throw new RepositoryException(msg, mpe);
        }
        // remove conflicting:
        // check if conflicting can be removed
        // (access rights, node type constraints, locking & versioning status)
        itemOps.checkRemoveNode(conflicting, BatchedItemOperations.CHECK_ACCESS | BatchedItemOperations.CHECK_LOCK | BatchedItemOperations.CHECK_CHECKED_OUT | BatchedItemOperations.CHECK_CONSTRAINTS | BatchedItemOperations.CHECK_HOLD | BatchedItemOperations.CHECK_RETENTION);
        // do remove conflicting (recursive)
        itemOps.removeNodeState(conflicting);
        // create new with given uuid:
        // 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, nodeInfo.getName(), nodeInfo.getNodeTypeName(), BatchedItemOperations.CHECK_ACCESS | BatchedItemOperations.CHECK_CONSTRAINTS);
        // do create new node
        node = itemOps.createNodeState(parent, nodeInfo.getName(), nodeInfo.getNodeTypeName(), nodeInfo.getMixinNames(), nodeInfo.getId());
    } else if (uuidBehavior == ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING) {
        NodeId parentId = conflicting.getParentId();
        if (parentId == null) {
            String msg = "root node cannot be replaced";
            log.debug(msg);
            throw new RepositoryException(msg);
        }
        // 'replace' current parent with parent of conflicting
        try {
            parent = itemOps.getNodeState(parentId);
        } catch (ItemNotFoundException infe) {
            // should never get here...
            String msg = "internal error: failed to retrieve parent state";
            log.error(msg, infe);
            throw new RepositoryException(msg, infe);
        }
        // remove conflicting:
        // check if conflicting can be removed
        // (access rights, node type constraints, locking & versioning status)
        itemOps.checkRemoveNode(conflicting, BatchedItemOperations.CHECK_ACCESS | BatchedItemOperations.CHECK_LOCK | BatchedItemOperations.CHECK_CHECKED_OUT | BatchedItemOperations.CHECK_CONSTRAINTS | BatchedItemOperations.CHECK_HOLD | BatchedItemOperations.CHECK_RETENTION);
        // 'replace' is actually a 'remove existing/add new' operation;
        // this unfortunately changes the order of the parent's
        // child node entries (JCR-1055);
        // => backup list of child node entries beforehand in order
        // to restore it afterwards
        ChildNodeEntry cneConflicting = parent.getChildNodeEntry(nodeInfo.getId());
        List<ChildNodeEntry> cneList = new ArrayList<ChildNodeEntry>(parent.getChildNodeEntries());
        // do remove conflicting (recursive)
        itemOps.removeNodeState(conflicting);
        // create new with given uuid at same location as conflicting:
        // check if new node can be added at other location
        // (access rights, node type constraints, locking & versioning
        // status and retention/hold)
        itemOps.checkAddNode(parent, nodeInfo.getName(), nodeInfo.getNodeTypeName(), BatchedItemOperations.CHECK_ACCESS | BatchedItemOperations.CHECK_LOCK | BatchedItemOperations.CHECK_CHECKED_OUT | BatchedItemOperations.CHECK_CONSTRAINTS | BatchedItemOperations.CHECK_HOLD | BatchedItemOperations.CHECK_RETENTION);
        // do create new node
        node = itemOps.createNodeState(parent, nodeInfo.getName(), nodeInfo.getNodeTypeName(), nodeInfo.getMixinNames(), nodeInfo.getId());
        // restore list of child node entries (JCR-1055)
        if (cneConflicting.getName().equals(nodeInfo.getName())) {
            // restore original child node list
            parent.setChildNodeEntries(cneList);
        } else {
            // replace child node entry with different name
            // but preserving original position
            parent.removeAllChildNodeEntries();
            for (ChildNodeEntry cne : cneList) {
                if (cne.getId().equals(nodeInfo.getId())) {
                    // replace entry with different name
                    parent.addChildNodeEntry(nodeInfo.getName(), nodeInfo.getId());
                } else {
                    parent.addChildNodeEntry(cne.getName(), cne.getId());
                }
            }
        }
    } else {
        String msg = "unknown uuidBehavior: " + uuidBehavior;
        log.debug(msg);
        throw new RepositoryException(msg);
    }
    return node;
}
Also used : Path(org.apache.jackrabbit.spi.Path) NodeState(org.apache.jackrabbit.core.state.NodeState) ChildNodeEntry(org.apache.jackrabbit.core.state.ChildNodeEntry) MalformedPathException(org.apache.jackrabbit.spi.commons.conversion.MalformedPathException) RepositoryException(javax.jcr.RepositoryException) EffectiveNodeType(org.apache.jackrabbit.core.nodetype.EffectiveNodeType) ItemExistsException(javax.jcr.ItemExistsException) NodeId(org.apache.jackrabbit.core.id.NodeId) ConstraintViolationException(javax.jcr.nodetype.ConstraintViolationException) ArrayList(java.util.ArrayList) List(java.util.List) ItemNotFoundException(javax.jcr.ItemNotFoundException)

Example 10 with ChildNodeEntry

use of org.apache.jackrabbit.core.state.ChildNodeEntry in project jackrabbit by apache.

the class ItemSaveOperation method validateTransientItems.

/**
     * the following validations/checks are performed on transient items:
     *
     * for every transient item:
     * - if it is 'modified' or 'new' check the corresponding write permission.
     * - if it is 'removed' check the REMOVE permission
     *
     * for every transient node:
     * - if it is 'new' check that its node type satisfies the
     *   'required node type' constraint specified in its definition
     * - check if 'mandatory' child items exist
     *
     * for every transient property:
     * - check if the property value satisfies the value constraints
     *   specified in the property's definition
     *
     * note that the protected flag is checked in Node.addNode/Node.remove
     * (for adding/removing child entries of a node), in
     * Node.addMixin/removeMixin/setPrimaryType (for type changes on nodes)
     * and in Property.setValue (for properties to be modified).
     */
private void validateTransientItems(SessionContext context, Iterable<ItemState> dirty, Iterable<ItemState> removed) throws RepositoryException {
    SessionImpl session = context.getSessionImpl();
    ItemManager itemMgr = context.getItemManager();
    SessionItemStateManager stateMgr = context.getItemStateManager();
    AccessManager accessMgr = context.getAccessManager();
    NodeTypeManagerImpl ntMgr = context.getNodeTypeManager();
    // walk through list of dirty transient items and validate each
    for (ItemState itemState : dirty) {
        ItemDefinition def;
        if (itemState.isNode()) {
            def = itemMgr.getDefinition((NodeState) itemState);
        } else {
            def = itemMgr.getDefinition((PropertyState) itemState);
        }
        /* check permissions for non-protected items. protected items are
               only added through API methods which need to assert that
               permissions are not violated.
             */
        if (!def.isProtected()) {
            /* detect the effective set of modification:
                   - new added node -> add_node perm on the child
                   - new property added -> set_property permission
                   - property modified -> set_property permission
                   - modified nodes can be ignored for changes only included
                     child-item addition or removal or changes of protected
                     properties such as mixin-types which are covered separately
                   note: removed items are checked later on.
                   note: reordering of child nodes has been covered upfront as
                         this information isn't available here.
                */
            Path path = stateMgr.getHierarchyMgr().getPath(itemState.getId());
            boolean isGranted = true;
            if (itemState.isNode()) {
                if (itemState.getStatus() == ItemState.STATUS_NEW) {
                    isGranted = accessMgr.isGranted(path, Permission.ADD_NODE);
                }
            // else: modified node (see comment above)
            } else {
                // modified or new property: set_property permission
                isGranted = accessMgr.isGranted(path, Permission.SET_PROPERTY);
            }
            if (!isGranted) {
                String msg = itemMgr.safeGetJCRPath(path) + ": not allowed to add or modify item";
                log.debug(msg);
                throw new AccessDeniedException(msg);
            }
        }
        if (itemState.isNode()) {
            // the transient item is a node
            NodeState nodeState = (NodeState) itemState;
            ItemId id = nodeState.getNodeId();
            NodeDefinition nodeDef = (NodeDefinition) def;
            // primary type
            NodeTypeImpl pnt = ntMgr.getNodeType(nodeState.getNodeTypeName());
            // effective node type (primary type incl. mixins)
            EffectiveNodeType ent = getEffectiveNodeType(context.getRepositoryContext().getNodeTypeRegistry(), nodeState);
            /**
                 * if the transient node was added (i.e. if it is 'new') or if
                 * its primary type has changed, check its node type against the
                 * required node type in its definition
                 */
            boolean primaryTypeChanged = nodeState.getStatus() == ItemState.STATUS_NEW;
            if (!primaryTypeChanged) {
                NodeState overlaid = (NodeState) nodeState.getOverlayedState();
                if (overlaid != null) {
                    Name newName = nodeState.getNodeTypeName();
                    Name oldName = overlaid.getNodeTypeName();
                    primaryTypeChanged = !newName.equals(oldName);
                }
            }
            if (primaryTypeChanged) {
                for (NodeType ntReq : nodeDef.getRequiredPrimaryTypes()) {
                    Name ntName = ((NodeTypeImpl) ntReq).getQName();
                    if (!(pnt.getQName().equals(ntName) || pnt.isDerivedFrom(ntName))) {
                        /**
                             * the transient node's primary node type does not
                             * satisfy the 'required primary types' constraint
                             */
                        String msg = itemMgr.safeGetJCRPath(id) + " must be of node type " + ntReq.getName();
                        log.debug(msg);
                        throw new ConstraintViolationException(msg);
                    }
                }
            }
            // mandatory child properties
            for (QPropertyDefinition pd : ent.getMandatoryPropDefs()) {
                if (pd.getDeclaringNodeType().equals(NameConstants.MIX_VERSIONABLE) || pd.getDeclaringNodeType().equals(NameConstants.MIX_SIMPLE_VERSIONABLE)) {
                    /**
                         * todo FIXME workaround for mix:versionable:
                         * the mandatory properties are initialized at a
                         * later stage and might not exist yet
                         */
                    continue;
                }
                String msg = itemMgr.safeGetJCRPath(id) + ": mandatory property " + pd.getName() + " does not exist";
                if (!nodeState.hasPropertyName(pd.getName())) {
                    log.debug(msg);
                    throw new ConstraintViolationException(msg);
                } else {
                    /*
                        there exists a property with the mandatory-name.
                        make sure the property really has the expected mandatory
                        property definition (and not another non-mandatory def,
                        such as e.g. multivalued residual instead of single-value
                        mandatory, named def).
                        */
                    PropertyId pi = new PropertyId(nodeState.getNodeId(), pd.getName());
                    ItemData childData = itemMgr.getItemData(pi, null, false);
                    if (!childData.getDefinition().isMandatory()) {
                        throw new ConstraintViolationException(msg);
                    }
                }
            }
            // mandatory child nodes
            for (QItemDefinition cnd : ent.getMandatoryNodeDefs()) {
                String msg = itemMgr.safeGetJCRPath(id) + ": mandatory child node " + cnd.getName() + " does not exist";
                if (!nodeState.hasChildNodeEntry(cnd.getName())) {
                    log.debug(msg);
                    throw new ConstraintViolationException(msg);
                } else {
                    /*
                        there exists a child node with the mandatory-name.
                        make sure the node really has the expected mandatory
                        node definition.
                        */
                    boolean hasMandatoryChild = false;
                    for (ChildNodeEntry cne : nodeState.getChildNodeEntries(cnd.getName())) {
                        ItemData childData = itemMgr.getItemData(cne.getId(), null, false);
                        if (childData.getDefinition().isMandatory()) {
                            hasMandatoryChild = true;
                            break;
                        }
                    }
                    if (!hasMandatoryChild) {
                        throw new ConstraintViolationException(msg);
                    }
                }
            }
        } else {
            // the transient item is a property
            PropertyState propState = (PropertyState) itemState;
            ItemId propId = propState.getPropertyId();
            org.apache.jackrabbit.spi.commons.nodetype.PropertyDefinitionImpl propDef = (org.apache.jackrabbit.spi.commons.nodetype.PropertyDefinitionImpl) def;
            /**
                 * check value constraints
                 * (no need to check value constraints of protected properties
                 * as those are set by the implementation only, i.e. they
                 * cannot be set by the user through the api)
                 */
            if (!def.isProtected()) {
                String[] constraints = propDef.getValueConstraints();
                if (constraints != null) {
                    InternalValue[] values = propState.getValues();
                    try {
                        EffectiveNodeType.checkSetPropertyValueConstraints(propDef.unwrap(), values);
                    } catch (RepositoryException e) {
                        // repack exception for providing more verbose error message
                        String msg = itemMgr.safeGetJCRPath(propId) + ": " + e.getMessage();
                        log.debug(msg);
                        throw new ConstraintViolationException(msg);
                    }
                    /**
                         * need to manually check REFERENCE value constraints
                         * as this requires a session (target node needs to
                         * be checked)
                         */
                    if (constraints.length > 0 && (propDef.getRequiredType() == PropertyType.REFERENCE || propDef.getRequiredType() == PropertyType.WEAKREFERENCE)) {
                        for (InternalValue internalV : values) {
                            boolean satisfied = false;
                            String constraintViolationMsg = null;
                            try {
                                NodeId targetId = internalV.getNodeId();
                                if (propDef.getRequiredType() == PropertyType.WEAKREFERENCE && !itemMgr.itemExists(targetId)) {
                                    // target of weakref doesn;t exist, skip
                                    continue;
                                }
                                Node targetNode = session.getNodeById(targetId);
                                /**
                                     * constraints are OR-ed, i.e. at least one
                                     * has to be satisfied
                                     */
                                for (String constrNtName : constraints) {
                                    /**
                                         * a [WEAK]REFERENCE value constraint specifies
                                         * the name of the required node type of
                                         * the target node
                                         */
                                    if (targetNode.isNodeType(constrNtName)) {
                                        satisfied = true;
                                        break;
                                    }
                                }
                                if (!satisfied) {
                                    NodeType[] mixinNodeTypes = targetNode.getMixinNodeTypes();
                                    String[] targetMixins = new String[mixinNodeTypes.length];
                                    for (int j = 0; j < mixinNodeTypes.length; j++) {
                                        targetMixins[j] = mixinNodeTypes[j].getName();
                                    }
                                    String targetMixinsString = Text.implode(targetMixins, ", ");
                                    String constraintsString = Text.implode(constraints, ", ");
                                    constraintViolationMsg = itemMgr.safeGetJCRPath(propId) + ": is constraint to [" + constraintsString + "] but references [primaryType=" + targetNode.getPrimaryNodeType().getName() + ", mixins=" + targetMixinsString + "]";
                                }
                            } catch (RepositoryException re) {
                                String msg = itemMgr.safeGetJCRPath(propId) + ": failed to check " + ((propDef.getRequiredType() == PropertyType.REFERENCE) ? "REFERENCE" : "WEAKREFERENCE") + " value constraint";
                                log.debug(msg);
                                throw new ConstraintViolationException(msg, re);
                            }
                            if (!satisfied) {
                                log.debug(constraintViolationMsg);
                                throw new ConstraintViolationException(constraintViolationMsg);
                            }
                        }
                    }
                }
            }
        /**
                 * no need to check the protected flag as this is checked
                 * in PropertyImpl.setValue(Value)
                 */
        }
    }
    // walk through list of removed transient items and check REMOVE permission
    for (ItemState itemState : removed) {
        QItemDefinition def;
        try {
            if (itemState.isNode()) {
                def = itemMgr.getDefinition((NodeState) itemState).unwrap();
            } else {
                def = itemMgr.getDefinition((PropertyState) itemState).unwrap();
            }
        } catch (ConstraintViolationException e) {
            // of a mixin (see also JCR-2130 & JCR-2408)
            continue;
        }
        if (!def.isProtected()) {
            Path path = stateMgr.getAtticAwareHierarchyMgr().getPath(itemState.getId());
            // check REMOVE permission
            int permission = (itemState.isNode()) ? Permission.REMOVE_NODE : Permission.REMOVE_PROPERTY;
            if (!accessMgr.isGranted(path, permission)) {
                String msg = itemMgr.safeGetJCRPath(path) + ": not allowed to remove item";
                log.debug(msg);
                throw new AccessDeniedException(msg);
            }
        }
    }
}
Also used : AccessManager(org.apache.jackrabbit.core.security.AccessManager) AccessDeniedException(javax.jcr.AccessDeniedException) NodeState(org.apache.jackrabbit.core.state.NodeState) NodeTypeImpl(org.apache.jackrabbit.core.nodetype.NodeTypeImpl) Node(javax.jcr.Node) QItemDefinition(org.apache.jackrabbit.spi.QItemDefinition) ItemDefinition(javax.jcr.nodetype.ItemDefinition) NodeDefinition(javax.jcr.nodetype.NodeDefinition) ItemId(org.apache.jackrabbit.core.id.ItemId) Name(org.apache.jackrabbit.spi.Name) QPropertyDefinition(org.apache.jackrabbit.spi.QPropertyDefinition) ConstraintViolationException(javax.jcr.nodetype.ConstraintViolationException) NodeTypeManagerImpl(org.apache.jackrabbit.core.nodetype.NodeTypeManagerImpl) Path(org.apache.jackrabbit.spi.Path) ChildNodeEntry(org.apache.jackrabbit.core.state.ChildNodeEntry) RepositoryException(javax.jcr.RepositoryException) QItemDefinition(org.apache.jackrabbit.spi.QItemDefinition) InternalValue(org.apache.jackrabbit.core.value.InternalValue) PropertyState(org.apache.jackrabbit.core.state.PropertyState) PropertyId(org.apache.jackrabbit.core.id.PropertyId) EffectiveNodeType(org.apache.jackrabbit.core.nodetype.EffectiveNodeType) ItemState(org.apache.jackrabbit.core.state.ItemState) NodeType(javax.jcr.nodetype.NodeType) EffectiveNodeType(org.apache.jackrabbit.core.nodetype.EffectiveNodeType) NodeId(org.apache.jackrabbit.core.id.NodeId) SessionItemStateManager(org.apache.jackrabbit.core.state.SessionItemStateManager)

Aggregations

ChildNodeEntry (org.apache.jackrabbit.core.state.ChildNodeEntry)44 NodeState (org.apache.jackrabbit.core.state.NodeState)34 RepositoryException (javax.jcr.RepositoryException)25 NodeId (org.apache.jackrabbit.core.id.NodeId)23 Name (org.apache.jackrabbit.spi.Name)22 ItemStateException (org.apache.jackrabbit.core.state.ItemStateException)19 PropertyState (org.apache.jackrabbit.core.state.PropertyState)13 Path (org.apache.jackrabbit.spi.Path)12 ItemNotFoundException (javax.jcr.ItemNotFoundException)11 ConstraintViolationException (javax.jcr.nodetype.ConstraintViolationException)11 PropertyId (org.apache.jackrabbit.core.id.PropertyId)11 EffectiveNodeType (org.apache.jackrabbit.core.nodetype.EffectiveNodeType)10 ArrayList (java.util.ArrayList)9 ItemExistsException (javax.jcr.ItemExistsException)9 NoSuchItemStateException (org.apache.jackrabbit.core.state.NoSuchItemStateException)9 InvalidItemStateException (javax.jcr.InvalidItemStateException)7 HashSet (java.util.HashSet)6 NodeTypeImpl (org.apache.jackrabbit.core.nodetype.NodeTypeImpl)5 InternalValue (org.apache.jackrabbit.core.value.InternalValue)5 QNodeDefinition (org.apache.jackrabbit.spi.QNodeDefinition)5