Search in sources :

Example 16 with ItemExistsException

use of javax.jcr.ItemExistsException in project jackrabbit by apache.

the class NodeImpl method rename.

//-------------------------------------------------------< JackrabbitNode >
/**
     * {@inheritDoc}
     */
public void rename(String newName) throws RepositoryException {
    // check if this is the root node
    if (getDepth() == 0) {
        throw new RepositoryException("Cannot rename the root node");
    }
    Name qName;
    try {
        qName = sessionContext.getQName(newName);
    } catch (NameException e) {
        throw new RepositoryException("invalid node name: " + newName, e);
    }
    NodeImpl parent = (NodeImpl) getParent();
    // check for name collisions
    NodeImpl existing = null;
    try {
        existing = parent.getNode(qName);
        // check same-name sibling setting of existing node
        if (!existing.getDefinition().allowsSameNameSiblings()) {
            throw new ItemExistsException("Same name siblings are not allowed: " + existing);
        }
    } catch (AccessDeniedException ade) {
        // FIXME by throwing ItemExistsException we're disclosing too much information
        throw new ItemExistsException();
    } catch (ItemNotFoundException infe) {
    // no name collision, fall through
    }
    // verify that parent node
    // - is checked-out
    // - is not protected neither by node type constraints nor by retention/hold
    int options = ItemValidator.CHECK_CHECKED_OUT | ItemValidator.CHECK_LOCK | ItemValidator.CHECK_CONSTRAINTS | ItemValidator.CHECK_HOLD | ItemValidator.CHECK_RETENTION;
    sessionContext.getItemValidator().checkRemove(parent, options, Permission.NONE);
    sessionContext.getItemValidator().checkModify(parent, options, Permission.NONE);
    // check constraints
    // get applicable definition of renamed target node
    NodeTypeImpl nt = (NodeTypeImpl) getPrimaryNodeType();
    org.apache.jackrabbit.spi.commons.nodetype.NodeDefinitionImpl newTargetDef;
    try {
        newTargetDef = parent.getApplicableChildNodeDefinition(qName, nt.getQName());
    } catch (RepositoryException re) {
        String msg = safeGetJCRPath() + ": no definition found in parent node's node type for renamed node";
        log.debug(msg);
        throw new ConstraintViolationException(msg, re);
    }
    // necessarily have identical definitions
    if (existing != null && !newTargetDef.allowsSameNameSiblings()) {
        throw new ItemExistsException("Same name siblings not allowed: " + existing);
    }
    // check permissions:
    // 1. on the parent node the session must have permission to manipulate the child-entries
    AccessManager acMgr = sessionContext.getAccessManager();
    if (!acMgr.isGranted(parent.getPrimaryPath(), qName, Permission.MODIFY_CHILD_NODE_COLLECTION)) {
        String msg = "Not allowed to rename node " + safeGetJCRPath() + " to " + newName;
        log.debug(msg);
        throw new AccessDeniedException(msg);
    }
    //    the primary node type on this node itself.
    if (!nt.getName().equals(newTargetDef.getName()) && !(acMgr.isGranted(getPrimaryPath(), Permission.NODE_TYPE_MNGMT))) {
        String msg = "Not allowed to rename node " + safeGetJCRPath() + " to " + newName;
        log.debug(msg);
        throw new AccessDeniedException(msg);
    }
    // change definition
    onRedefine(newTargetDef.unwrap());
    // delegate to parent
    parent.renameChildNode(getNodeId(), qName, true);
}
Also used : AccessManager(org.apache.jackrabbit.core.security.AccessManager) AccessDeniedException(javax.jcr.AccessDeniedException) NodeDefinitionImpl(org.apache.jackrabbit.spi.commons.nodetype.NodeDefinitionImpl) NodeTypeImpl(org.apache.jackrabbit.core.nodetype.NodeTypeImpl) RepositoryException(javax.jcr.RepositoryException) Name(org.apache.jackrabbit.spi.Name) NameException(org.apache.jackrabbit.spi.commons.conversion.NameException) ItemExistsException(javax.jcr.ItemExistsException) ConstraintViolationException(javax.jcr.nodetype.ConstraintViolationException) ItemNotFoundException(javax.jcr.ItemNotFoundException)

Example 17 with ItemExistsException

use of javax.jcr.ItemExistsException in project jackrabbit by apache.

the class ProtectedItemModifier method addNode.

protected NodeImpl addNode(NodeImpl parentImpl, Name name, Name ntName, NodeId nodeId) throws RepositoryException {
    checkPermission(parentImpl, name, getPermission(true, false));
    // validation: make sure Node is not locked or checked-in.
    parentImpl.checkSetProperty();
    NodeTypeImpl nodeType = parentImpl.sessionContext.getNodeTypeManager().getNodeType(ntName);
    org.apache.jackrabbit.spi.commons.nodetype.NodeDefinitionImpl def = parentImpl.getApplicableChildNodeDefinition(name, ntName);
    // check for name collisions
    // TODO: improve. copied from NodeImpl
    NodeState thisState = parentImpl.getNodeState();
    ChildNodeEntry cne = thisState.getChildNodeEntry(name, 1);
    if (cne != null) {
        // check same-name sibling setting of new node
        if (!def.allowsSameNameSiblings()) {
            throw new ItemExistsException();
        }
        // check same-name sibling setting of existing node
        NodeId newId = cne.getId();
        NodeImpl n = (NodeImpl) parentImpl.sessionContext.getItemManager().getItem(newId);
        if (!n.getDefinition().allowsSameNameSiblings()) {
            throw new ItemExistsException();
        }
    }
    return parentImpl.createChildNode(name, nodeType, nodeId);
}
Also used : NodeTypeImpl(org.apache.jackrabbit.core.nodetype.NodeTypeImpl) 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)

Example 18 with ItemExistsException

use of javax.jcr.ItemExistsException in project jackrabbit by apache.

the class SessionImporter method resolveUUIDConflict.

//----------------------------------------------------< Private methods >---
/**
     * @param parent
     * @param conflicting
     * @param nodeInfo
     * @return
     * @throws RepositoryException
     */
NodeState resolveUUIDConflict(NodeState parent, NodeEntry conflicting, NodeInfo nodeInfo) throws ItemExistsException, RepositoryException {
    NodeState nodeState;
    switch(uuidBehavior) {
        case ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW:
            String originalUUID = nodeInfo.getUUID();
            String newUUID = UUID.randomUUID().toString();
            // reset id on nodeInfo to force creation with new uuid:
            nodeInfo.setUUID(newUUID);
            nodeState = importNode(nodeInfo, parent);
            if (nodeState != null) {
                // remember uuid mapping
                refTracker.mappedUUIDs(originalUUID, newUUID);
            }
            break;
        case ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW:
            String msg = "a node with uuid " + nodeInfo.getUUID() + " already exists!";
            log.debug(msg);
            throw new ItemExistsException(msg);
        case ImportUUIDBehavior.IMPORT_UUID_COLLISION_REMOVE_EXISTING:
            // make sure conflicting node is not importTarget or an ancestor thereof
            Path p0 = importTarget.getPath();
            Path p1 = conflicting.getPath();
            if (p1.equals(p0) || p1.isAncestorOf(p0)) {
                msg = "cannot remove ancestor node";
                log.debug(msg);
                throw new ConstraintViolationException(msg);
            }
            // do remove conflicting (recursive) including validation check
            try {
                Operation op = Remove.create(conflicting.getNodeState());
                stateMgr.execute(op);
            } catch (ItemNotFoundException e) {
            // conflicting does not exist any more. no need for a removal
            }
            // create new with given uuid:
            nodeState = importNode(nodeInfo, parent);
            break;
        case ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING:
            if (conflicting.getNodeState().isRoot()) {
                msg = "Root node cannot be replaced";
                log.debug(msg);
                throw new RepositoryException(msg);
            }
            // 'replace' current parent with parent of conflicting
            parent = conflicting.getParent().getNodeState();
            // do remove conflicting (recursive), including validation checks
            Operation op = Remove.create(conflicting.getNodeState());
            stateMgr.execute(op);
            // create new with given uuid at same location as conflicting
            nodeState = importNode(nodeInfo, parent);
            break;
        default:
            msg = "Unknown uuidBehavior: " + uuidBehavior;
            log.debug(msg);
            throw new RepositoryException(msg);
    }
    return nodeState;
}
Also used : Path(org.apache.jackrabbit.spi.Path) NodeState(org.apache.jackrabbit.jcr2spi.state.NodeState) ItemExistsException(javax.jcr.ItemExistsException) ConstraintViolationException(javax.jcr.nodetype.ConstraintViolationException) RepositoryException(javax.jcr.RepositoryException) Operation(org.apache.jackrabbit.jcr2spi.operation.Operation) ItemNotFoundException(javax.jcr.ItemNotFoundException)

Example 19 with ItemExistsException

use of javax.jcr.ItemExistsException in project jackrabbit by apache.

the class BatchedItemOperations method copyNodeState.

/**
     * Recursively copies the specified node state including its properties and
     * child nodes.
     *
     * @param srcState
     * @param srcPath
     * @param srcStateMgr
     * @param srcAccessMgr
     * @param destParentId
     * @param flag           one of
     *                       <ul>
     *                       <li><code>COPY</code></li>
     *                       <li><code>CLONE</code></li>
     *                       <li><code>CLONE_REMOVE_EXISTING</code></li>
     *                       </ul>
     * @param refTracker     tracks uuid mappings and processed reference properties
     * @return a deep copy of the given node state and its children
     * @throws RepositoryException if an error occurs
     */
private NodeState copyNodeState(NodeState srcState, Path srcPath, ItemStateManager srcStateMgr, AccessManager srcAccessMgr, NodeId destParentId, int flag, ReferenceChangeTracker refTracker) throws RepositoryException {
    NodeState newState;
    try {
        NodeId id = null;
        EffectiveNodeType ent = getEffectiveNodeType(srcState);
        boolean referenceable = ent.includesNodeType(NameConstants.MIX_REFERENCEABLE);
        boolean versionable = ent.includesNodeType(NameConstants.MIX_SIMPLE_VERSIONABLE);
        boolean fullVersionable = ent.includesNodeType(NameConstants.MIX_VERSIONABLE);
        boolean shareable = ent.includesNodeType(NameConstants.MIX_SHAREABLE);
        switch(flag) {
            case COPY:
                /* if this node is shareable and another node in the same shared set
                     * has been already been copied and given a new uuid, use this one
                     * (see section 14.5 of the specification)
                     */
                if (shareable && refTracker.getMappedId(srcState.getNodeId()) != null) {
                    NodeId newId = refTracker.getMappedId(srcState.getNodeId());
                    NodeState sharedState = (NodeState) stateMgr.getItemState(newId);
                    sharedState.addShare(destParentId);
                    return sharedState;
                }
                break;
            case CLONE:
                if (!referenceable) {
                    // non-referenceable node: always create new node id
                    break;
                }
                // use same uuid as source node
                id = srcState.getNodeId();
                if (stateMgr.hasItemState(id)) {
                    if (shareable) {
                        NodeState sharedState = (NodeState) stateMgr.getItemState(id);
                        sharedState.addShare(destParentId);
                        return sharedState;
                    }
                    // node with this uuid already exists
                    throw new ItemExistsException(safeGetJCRPath(id));
                }
                break;
            case CLONE_REMOVE_EXISTING:
                if (!referenceable) {
                    // non-referenceable node: always create new node id
                    break;
                }
                // use same uuid as source node
                id = srcState.getNodeId();
                if (stateMgr.hasItemState(id)) {
                    NodeState existingState = (NodeState) stateMgr.getItemState(id);
                    // or an ancestor thereof
                    if (id.equals(destParentId) || hierMgr.isAncestor(id, destParentId)) {
                        String msg = "cannot remove node " + safeGetJCRPath(srcPath) + " because it is an ancestor of the destination";
                        log.debug(msg);
                        throw new RepositoryException(msg);
                    }
                    // check if existing can be removed
                    // (access rights, locking & versioning status,
                    // node type constraints and retention/hold)
                    checkRemoveNode(existingState, CHECK_ACCESS | CHECK_LOCK | CHECK_CHECKED_OUT | CHECK_CONSTRAINTS | CHECK_HOLD | CHECK_RETENTION);
                    // do remove existing
                    removeNodeState(existingState);
                }
                break;
            default:
                throw new IllegalArgumentException("unknown flag for copying node state: " + flag);
        }
        newState = stateMgr.createNew(id, srcState.getNodeTypeName(), destParentId);
        id = newState.getNodeId();
        if (flag == COPY && referenceable) {
            // remember uuid mapping
            refTracker.mappedId(srcState.getNodeId(), id);
        }
        // copy node state
        newState.setMixinTypeNames(srcState.getMixinTypeNames());
        if (shareable) {
            // initialize shared set
            newState.addShare(destParentId);
        }
        // copy child nodes
        for (ChildNodeEntry entry : srcState.getChildNodeEntries()) {
            Path srcChildPath = PathFactoryImpl.getInstance().create(srcPath, entry.getName(), true);
            if (!srcAccessMgr.isGranted(srcChildPath, Permission.READ)) {
                continue;
            }
            NodeId nodeId = entry.getId();
            NodeState srcChildState = (NodeState) srcStateMgr.getItemState(nodeId);
            /**
                 * If child is shareble and its UUID has already been remapped,
                 * then simply add a reference to the state with that remapped
                 * UUID instead of copying the whole subtree.
                 */
            if (srcChildState.isShareable()) {
                NodeId mappedId = refTracker.getMappedId(srcChildState.getNodeId());
                if (mappedId != null) {
                    if (stateMgr.hasItemState(mappedId)) {
                        NodeState destState = (NodeState) stateMgr.getItemState(mappedId);
                        if (!destState.isShareable()) {
                            String msg = "Remapped child (" + safeGetJCRPath(srcPath) + ") is not shareable.";
                            throw new ItemStateException(msg);
                        }
                        if (!destState.addShare(id)) {
                            String msg = "Unable to add share to node: " + id;
                            throw new ItemStateException(msg);
                        }
                        stateMgr.store(destState);
                        newState.addChildNodeEntry(entry.getName(), mappedId);
                        continue;
                    }
                }
            }
            // recursive copying of child node
            NodeState newChildState = copyNodeState(srcChildState, srcChildPath, srcStateMgr, srcAccessMgr, id, flag, refTracker);
            // store new child node
            stateMgr.store(newChildState);
            // add new child node entry to new node
            newState.addChildNodeEntry(entry.getName(), newChildState.getNodeId());
        }
        // init version history if needed
        VersionHistoryInfo history = null;
        if (versionable && flag == COPY) {
            NodeId copiedFrom = null;
            if (fullVersionable) {
                // base version of copied versionable node is reference value of
                // the histories jcr:copiedFrom property
                PropertyId propId = new PropertyId(srcState.getNodeId(), NameConstants.JCR_BASEVERSION);
                PropertyState prop = (PropertyState) srcStateMgr.getItemState(propId);
                copiedFrom = prop.getValues()[0].getNodeId();
            }
            InternalVersionManager manager = session.getInternalVersionManager();
            history = manager.getVersionHistory(session, newState, copiedFrom);
        }
        // copy properties
        for (Name propName : srcState.getPropertyNames()) {
            Path propPath = PathFactoryImpl.getInstance().create(srcPath, propName, true);
            PropertyId propId = new PropertyId(srcState.getNodeId(), propName);
            if (!srcAccessMgr.canRead(propPath, propId)) {
                continue;
            }
            PropertyState srcChildState = (PropertyState) srcStateMgr.getItemState(propId);
            /**
                 * special handling required for properties with special semantics
                 * (e.g. those defined by mix:referenceable, mix:versionable,
                 * mix:lockable, et.al.)
                 *
                 * todo FIXME delegate to 'node type instance handler'
                 */
            QPropertyDefinition def = ent.getApplicablePropertyDef(srcChildState.getName(), srcChildState.getType(), srcChildState.isMultiValued());
            if (NameConstants.MIX_LOCKABLE.equals(def.getDeclaringNodeType())) {
                // skip properties defined by mix:lockable
                continue;
            }
            PropertyState newChildState = copyPropertyState(srcChildState, id, propName, def);
            if (history != null) {
                if (fullVersionable) {
                    if (propName.equals(NameConstants.JCR_VERSIONHISTORY)) {
                        // jcr:versionHistory
                        InternalValue value = InternalValue.create(history.getVersionHistoryId());
                        newChildState.setValues(new InternalValue[] { value });
                    } else if (propName.equals(NameConstants.JCR_BASEVERSION) || propName.equals(NameConstants.JCR_PREDECESSORS)) {
                        // jcr:baseVersion or jcr:predecessors
                        InternalValue value = InternalValue.create(history.getRootVersionId());
                        newChildState.setValues(new InternalValue[] { value });
                    } else if (propName.equals(NameConstants.JCR_ISCHECKEDOUT)) {
                        // jcr:isCheckedOut
                        newChildState.setValues(new InternalValue[] { InternalValue.create(true) });
                    }
                } else {
                    // version history when we see the jcr:isCheckedOut
                    if (propName.equals(NameConstants.JCR_ISCHECKEDOUT)) {
                        // jcr:isCheckedOut
                        newChildState.setValues(new InternalValue[] { InternalValue.create(true) });
                    }
                }
            }
            if (newChildState.getType() == PropertyType.REFERENCE || newChildState.getType() == PropertyType.WEAKREFERENCE) {
                refTracker.processedReference(newChildState);
            }
            // store new property
            stateMgr.store(newChildState);
            // add new property entry to new node
            newState.addPropertyName(propName);
        }
        return newState;
    } catch (ItemStateException ise) {
        String msg = "internal error: failed to copy state of " + srcState.getNodeId();
        log.debug(msg);
        throw new RepositoryException(msg, ise);
    }
}
Also used : Path(org.apache.jackrabbit.spi.Path) VersionHistoryInfo(org.apache.jackrabbit.core.version.VersionHistoryInfo) NodeState(org.apache.jackrabbit.core.state.NodeState) ChildNodeEntry(org.apache.jackrabbit.core.state.ChildNodeEntry) RepositoryException(javax.jcr.RepositoryException) InternalValue(org.apache.jackrabbit.core.value.InternalValue) NoSuchItemStateException(org.apache.jackrabbit.core.state.NoSuchItemStateException) ItemStateException(org.apache.jackrabbit.core.state.ItemStateException) PropertyId(org.apache.jackrabbit.core.id.PropertyId) PropertyState(org.apache.jackrabbit.core.state.PropertyState) Name(org.apache.jackrabbit.spi.Name) EffectiveNodeType(org.apache.jackrabbit.core.nodetype.EffectiveNodeType) ItemExistsException(javax.jcr.ItemExistsException) QPropertyDefinition(org.apache.jackrabbit.spi.QPropertyDefinition) NodeId(org.apache.jackrabbit.core.id.NodeId) InternalVersionManager(org.apache.jackrabbit.core.version.InternalVersionManager)

Example 20 with ItemExistsException

use of javax.jcr.ItemExistsException in project jackrabbit by apache.

the class BatchedItemOperations method createPropertyState.

/**
     * Creates a new property based on the given definition.
     * <p>
     * Note that access rights are <b><i>not</i></b> enforced!
     * <p>
     * <b>Precondition:</b> the state manager needs to be in edit mode.
     *
     * @param parent
     * @param propName
     * @param type
     * @param def
     * @return
     * @throws ItemExistsException
     * @throws RepositoryException
     */
public PropertyState createPropertyState(NodeState parent, Name propName, int type, QPropertyDefinition def) throws ItemExistsException, RepositoryException {
    // check for name collisions with existing properties
    if (parent.hasPropertyName(propName)) {
        PropertyId errorId = new PropertyId(parent.getNodeId(), propName);
        throw new ItemExistsException(safeGetJCRPath(errorId));
    }
    // create property
    PropertyState prop = stateMgr.createNew(propName, parent.getNodeId());
    if (def.getRequiredType() != PropertyType.UNDEFINED) {
        prop.setType(def.getRequiredType());
    } else if (type != PropertyType.UNDEFINED) {
        prop.setType(type);
    } else {
        prop.setType(PropertyType.STRING);
    }
    prop.setMultiValued(def.isMultiple());
    // compute system generated values if necessary
    new NodeTypeInstanceHandler(session.getUserID()).setDefaultValues(prop, parent, def);
    // now add new property entry to parent
    parent.addPropertyName(propName);
    // store parent
    stateMgr.store(parent);
    return prop;
}
Also used : ItemExistsException(javax.jcr.ItemExistsException) PropertyId(org.apache.jackrabbit.core.id.PropertyId) PropertyState(org.apache.jackrabbit.core.state.PropertyState)

Aggregations

ItemExistsException (javax.jcr.ItemExistsException)63 Node (javax.jcr.Node)25 RepositoryException (javax.jcr.RepositoryException)25 NotExecutableException (org.apache.jackrabbit.test.NotExecutableException)16 ConstraintViolationException (javax.jcr.nodetype.ConstraintViolationException)15 NodeDefinition (javax.jcr.nodetype.NodeDefinition)14 ItemNotFoundException (javax.jcr.ItemNotFoundException)13 Version (javax.jcr.version.Version)13 NodeId (org.apache.jackrabbit.core.id.NodeId)12 Name (org.apache.jackrabbit.spi.Name)12 NodeState (org.apache.jackrabbit.core.state.NodeState)10 ChildNodeEntry (org.apache.jackrabbit.core.state.ChildNodeEntry)9 Path (org.apache.jackrabbit.spi.Path)8 PathNotFoundException (javax.jcr.PathNotFoundException)6 EffectiveNodeType (org.apache.jackrabbit.core.nodetype.EffectiveNodeType)6 QPropertyDefinition (org.apache.jackrabbit.spi.QPropertyDefinition)6 NodeImpl (org.apache.jackrabbit.core.NodeImpl)5 QNodeDefinition (org.apache.jackrabbit.spi.QNodeDefinition)5 ArrayList (java.util.ArrayList)4 AccessDeniedException (javax.jcr.AccessDeniedException)4