Search in sources :

Example 61 with ItemExistsException

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

the class NodeImpl method addNode.

@Override
@Nonnull
public Node addNode(final String relPath, String primaryNodeTypeName) throws RepositoryException {
    final String oakPath = getOakPathOrThrowNotFound(relPath);
    final String oakTypeName;
    if (primaryNodeTypeName != null) {
        oakTypeName = getOakName(primaryNodeTypeName);
    } else {
        oakTypeName = null;
    }
    checkIndexOnName(relPath);
    return perform(new ItemWriteOperation<Node>("addNode") {

        @Nonnull
        @Override
        public Node perform() throws RepositoryException {
            String oakName = PathUtils.getName(oakPath);
            String parentPath = PathUtils.getParentPath(oakPath);
            NodeDelegate parent = dlg.getChild(parentPath);
            if (parent == null) {
                // is it a property?
                String grandParentPath = PathUtils.getParentPath(parentPath);
                NodeDelegate grandParent = dlg.getChild(grandParentPath);
                if (grandParent != null) {
                    String propName = PathUtils.getName(parentPath);
                    if (grandParent.getPropertyOrNull(propName) != null) {
                        throw new ConstraintViolationException("Can't add new node to property.");
                    }
                }
                throw new PathNotFoundException(relPath);
            }
            if (parent.getChild(oakName) != null) {
                throw new ItemExistsException(relPath);
            }
            // modification of that property in the PermissionValidator
            if (oakTypeName != null) {
                PropertyState prop = PropertyStates.createProperty(JCR_PRIMARYTYPE, oakTypeName, NAME);
                sessionContext.getAccessManager().checkPermissions(parent.getTree(), prop, Permissions.NODE_TYPE_MANAGEMENT);
            }
            NodeDelegate added = parent.addChild(oakName, oakTypeName);
            if (added == null) {
                throw new ItemExistsException(format("Node [%s/%s] exists", getNodePath(), oakName));
            }
            return createNode(added, sessionContext);
        }

        @Override
        public String toString() {
            return format("Adding node [%s/%s]", dlg.getPath(), relPath);
        }
    });
}
Also used : Nonnull(javax.annotation.Nonnull) ItemExistsException(javax.jcr.ItemExistsException) JackrabbitNode(org.apache.jackrabbit.api.JackrabbitNode) Node(javax.jcr.Node) ConstraintViolationException(javax.jcr.nodetype.ConstraintViolationException) RepositoryException(javax.jcr.RepositoryException) PathNotFoundException(javax.jcr.PathNotFoundException) NodeDelegate(org.apache.jackrabbit.oak.jcr.delegate.NodeDelegate) PropertyState(org.apache.jackrabbit.oak.api.PropertyState) Nonnull(javax.annotation.Nonnull)

Example 62 with ItemExistsException

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

the class ImporterImpl method startNode.

@Override
public void startNode(NodeInfo nodeInfo, List<PropInfo> propInfos) throws RepositoryException {
    Tree parent = parents.peek();
    Tree tree = null;
    String id = nodeInfo.getUUID();
    String nodeName = nodeInfo.getName();
    String ntName = nodeInfo.getPrimaryTypeName();
    if (parent == null) {
        log.debug("Skipping node: {}", nodeName);
        // parent node was skipped, skip this child node too
        // push null onto stack for skipped node
        parents.push(null);
        // notify the p-i-importer
        if (pnImporter != null) {
            pnImporter.startChildInfo(nodeInfo, propInfos);
        }
        return;
    }
    NodeDefinition parentDef = getDefinition(parent);
    if (parentDef.isProtected()) {
        // skip protected node
        parents.push(null);
        log.debug("Skipping protected node: {}", nodeName);
        if (pnImporter != null) {
            // pnImporter was already started (current nodeInfo is a sibling)
            // notify it about this child node.
            pnImporter.startChildInfo(nodeInfo, propInfos);
        } else {
            // potentially is able to deal with it, notify it about the child node.
            for (ProtectedNodeImporter pni : getNodeImporters()) {
                if (pni.start(parent)) {
                    log.debug("Protected node -> delegated to ProtectedNodeImporter");
                    pnImporter = pni;
                    pnImporter.startChildInfo(nodeInfo, propInfos);
                    break;
                }
            /* else: p-i-Importer isn't able to deal with the protected tree.
                     try next. and if none can handle the passed parent the
                     tree below will be skipped */
            }
        }
        return;
    }
    if (parent.hasChild(nodeName)) {
        // a node with that name already exists...
        Tree existing = parent.getChild(nodeName);
        NodeDefinition def = getDefinition(existing);
        if (!def.allowsSameNameSiblings()) {
            // check for potential conflicts
            if (def.isProtected() && isNodeType(existing, ntName)) {
                /*
                     use the existing node as parent for the possible subsequent
                     import of a protected tree, that the protected node importer
                     may or may not be able to deal with.
                     -> upon the next 'startNode' the check for the parent being
                        protected will notify the protected node importer.
                     -> if the importer is able to deal with that node it needs
                        to care of the complete subtree until it is notified
                        during the 'endNode' call.
                     -> if the import can't deal with that node or if that node
                        is the a leaf in the tree to be imported 'end' will
                        not have an effect on the importer, that was never started.
                    */
                log.debug("Skipping protected node: {}", existing);
                parents.push(existing);
                /**
                     * let ProtectedPropertyImporters handle the properties
                     * associated with the imported node. this may include overwriting,
                     * merging or just adding missing properties.
                     */
                importProperties(existing, propInfos, true);
                return;
            }
            if (def.isAutoCreated() && isNodeType(existing, ntName)) {
                // this node has already been auto-created, no need to create it
                tree = existing;
            } else {
                // edge case: colliding node does have same uuid
                // (see http://issues.apache.org/jira/browse/JCR-1128)
                String existingIdentifier = IdentifierManager.getIdentifier(existing);
                if (!(existingIdentifier.equals(id) && (uuidBehavior == ImportUUIDBehavior.IMPORT_UUID_COLLISION_REMOVE_EXISTING || uuidBehavior == ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING))) {
                    throw new ItemExistsException("Node with the same UUID exists:" + existing);
                }
            // fall through
            }
        }
    }
    if (tree == null) {
        // create node
        if (id == null) {
            // no potential uuid conflict, always add new node
            tree = createTree(parent, nodeInfo, null);
        } else if (uuidBehavior == ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW) {
            // always create a new UUID even if no
            // conflicting node exists. see OAK-1244
            tree = createTree(parent, nodeInfo, UUID.randomUUID().toString());
            // remember uuid mapping
            if (isNodeType(tree, JcrConstants.MIX_REFERENCEABLE)) {
                refTracker.put(nodeInfo.getUUID(), TreeUtil.getString(tree, JcrConstants.JCR_UUID));
            }
        } else {
            Tree conflicting = idLookup.getConflictingTree(id);
            if (conflicting != null && conflicting.exists()) {
                // resolve uuid conflict
                tree = resolveUUIDConflict(parent, conflicting, id, nodeInfo);
                if (tree == null) {
                    // no new node has been created, so skip this node
                    // push null onto stack for skipped node
                    parents.push(null);
                    log.debug("Skipping existing node {}", nodeInfo.getName());
                    return;
                }
            } else {
                // create new with given uuid
                tree = createTree(parent, nodeInfo, id);
            }
        }
    }
    // process properties
    importProperties(tree, propInfos, false);
    if (tree.exists()) {
        parents.push(tree);
    }
}
Also used : ItemExistsException(javax.jcr.ItemExistsException) NodeDefinition(javax.jcr.nodetype.NodeDefinition) Tree(org.apache.jackrabbit.oak.api.Tree) ProtectedNodeImporter(org.apache.jackrabbit.oak.spi.xml.ProtectedNodeImporter)

Example 63 with ItemExistsException

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

the class ImporterImpl method resolveUUIDConflict.

private Tree resolveUUIDConflict(Tree parent, Tree conflicting, String conflictingId, NodeInfo nodeInfo) throws RepositoryException {
    Tree tree;
    if (uuidBehavior == ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW) {
        // create new with new uuid
        tree = createTree(parent, nodeInfo, UUID.randomUUID().toString());
        // remember uuid mapping
        if (isNodeType(tree, JcrConstants.MIX_REFERENCEABLE)) {
            refTracker.put(nodeInfo.getUUID(), TreeUtil.getString(tree, JcrConstants.JCR_UUID));
        }
    } else if (uuidBehavior == ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW) {
        // if conflicting node is shareable, then clone it
        String msg = "a node with uuid " + nodeInfo.getUUID() + " already exists!";
        log.debug(msg);
        throw new ItemExistsException(msg);
    } else if (uuidBehavior == ImportUUIDBehavior.IMPORT_UUID_COLLISION_REMOVE_EXISTING) {
        if (conflicting == null) {
            // since the conflicting node can't be read,
            // we can't remove it
            String msg = "node with uuid " + conflictingId + " cannot be removed";
            log.debug(msg);
            throw new RepositoryException(msg);
        }
        // make sure conflicting node is not importTargetNode or an ancestor thereof
        if (importTargetTree.getPath().startsWith(conflicting.getPath())) {
            String msg = "cannot remove ancestor node";
            log.debug(msg);
            throw new ConstraintViolationException(msg);
        }
        // remove conflicting
        conflicting.remove();
        // create new with given uuid
        tree = createTree(parent, nodeInfo, nodeInfo.getUUID());
    } else if (uuidBehavior == ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING) {
        if (conflicting == null) {
            // since the conflicting node can't be read,
            // we can't replace it
            String msg = "node with uuid " + conflictingId + " cannot be replaced";
            log.debug(msg);
            throw new RepositoryException(msg);
        }
        if (conflicting.isRoot()) {
            String msg = "root node cannot be replaced";
            log.debug(msg);
            throw new RepositoryException(msg);
        }
        // 'replace' current parent with parent of conflicting
        parent = conflicting.getParent();
        // replace child node
        //TODO ordering! (what happened to replace?)
        conflicting.remove();
        tree = createTree(parent, nodeInfo, nodeInfo.getUUID());
    } else {
        String msg = "unknown uuidBehavior: " + uuidBehavior;
        log.debug(msg);
        throw new RepositoryException(msg);
    }
    return tree;
}
Also used : ItemExistsException(javax.jcr.ItemExistsException) Tree(org.apache.jackrabbit.oak.api.Tree) ConstraintViolationException(javax.jcr.nodetype.ConstraintViolationException) RepositoryException(javax.jcr.RepositoryException)

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