Search in sources :

Example 11 with QItemDefinition

use of org.apache.jackrabbit.spi.QItemDefinition 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 12 with QItemDefinition

use of org.apache.jackrabbit.spi.QItemDefinition 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 13 with QItemDefinition

use of org.apache.jackrabbit.spi.QItemDefinition in project jackrabbit by apache.

the class EffectiveNodeType method create.

/**
     * Package private factory method.
     * <p>
     * Creates an effective node type representation of a node type definition.
     * Note that the definitions of all referenced node types must be contained
     * in <code>ntdCache</code>.
     *
     * @param ntd      node type definition
     * @param entCache cache of already-built effective node types
     * @param ntdCache cache of node type definitions, used to resolve dependencies
     * @return an effective node type representation of the given node type definition.
     * @throws NodeTypeConflictException if the node type definition is invalid,
     *                                   e.g. due to ambiguous child definitions.
     * @throws NoSuchNodeTypeException if a node type reference (e.g. a supertype)
     *                                 could not be resolved.
     */
static EffectiveNodeType create(QNodeTypeDefinition ntd, EffectiveNodeTypeCache entCache, Map<Name, QNodeTypeDefinition> ntdCache) throws NodeTypeConflictException, NoSuchNodeTypeException {
    // create empty effective node type instance
    EffectiveNodeType ent = new EffectiveNodeType();
    Name ntName = ntd.getName();
    // prepare new instance
    ent.mergedNodeTypes.add(ntName);
    ent.allNodeTypes.add(ntName);
    // map of all item definitions (maps id to definition)
    // used to effectively detect ambiguous child definitions where
    // ambiguity is defined in terms of definition identity
    Set<QItemDefinition> itemDefs = new HashSet<QItemDefinition>();
    QNodeDefinition[] cnda = ntd.getChildNodeDefs();
    for (QNodeDefinition aCnda : cnda) {
        // this node type definition
        if (itemDefs.contains(aCnda)) {
            // conflict
            String msg;
            if (aCnda.definesResidual()) {
                msg = ntName + " contains ambiguous residual child node definitions";
            } else {
                msg = ntName + " contains ambiguous definitions for child node named " + aCnda.getName();
            }
            log.debug(msg);
            throw new NodeTypeConflictException(msg);
        } else {
            itemDefs.add(aCnda);
        }
        if (aCnda.definesResidual()) {
            // residual node definition
            ent.unnamedItemDefs.add(aCnda);
        } else {
            // named node definition
            Name name = aCnda.getName();
            List<QItemDefinition> defs = ent.namedItemDefs.get(name);
            if (defs == null) {
                defs = new ArrayList<QItemDefinition>();
                ent.namedItemDefs.put(name, defs);
            }
            if (defs.size() > 0) {
                /**
                     * there already exists at least one definition with that
                     * name; make sure none of them is auto-create
                     */
                for (QItemDefinition def : defs) {
                    if (aCnda.isAutoCreated() || def.isAutoCreated()) {
                        // conflict
                        String msg = "There are more than one 'auto-create' item definitions for '" + name + "' in node type '" + ntName + "'";
                        log.debug(msg);
                        throw new NodeTypeConflictException(msg);
                    }
                }
            }
            defs.add(aCnda);
        }
    }
    QPropertyDefinition[] pda = ntd.getPropertyDefs();
    for (QPropertyDefinition aPda : pda) {
        // this node type definition
        if (itemDefs.contains(aPda)) {
            // conflict
            String msg;
            if (aPda.definesResidual()) {
                msg = ntName + " contains ambiguous residual property definitions";
            } else {
                msg = ntName + " contains ambiguous definitions for property named " + aPda.getName();
            }
            log.debug(msg);
            throw new NodeTypeConflictException(msg);
        } else {
            itemDefs.add(aPda);
        }
        if (aPda.definesResidual()) {
            // residual property definition
            ent.unnamedItemDefs.add(aPda);
        } else {
            // named property definition
            Name name = aPda.getName();
            List<QItemDefinition> defs = ent.namedItemDefs.get(name);
            if (defs == null) {
                defs = new ArrayList<QItemDefinition>();
                ent.namedItemDefs.put(name, defs);
            }
            if (defs.size() > 0) {
                /**
                     * there already exists at least one definition with that
                     * name; make sure none of them is auto-create
                     */
                for (QItemDefinition def : defs) {
                    if (aPda.isAutoCreated() || def.isAutoCreated()) {
                        // conflict
                        String msg = "There are more than one 'auto-create' item definitions for '" + name + "' in node type '" + ntName + "'";
                        log.debug(msg);
                        throw new NodeTypeConflictException(msg);
                    }
                }
            }
            defs.add(aPda);
        }
    }
    // resolve supertypes recursively
    Name[] supertypes = ntd.getSupertypes();
    if (supertypes.length > 0) {
        EffectiveNodeType base = NodeTypeRegistry.getEffectiveNodeType(supertypes, entCache, ntdCache);
        ent.internalMerge(base, true);
    }
    // resolve 'orderable child nodes' attribute value (JCR-1947)
    if (ntd.hasOrderableChildNodes()) {
        ent.orderableChildNodes = true;
    } else {
        Name[] nta = ent.getInheritedNodeTypes();
        for (Name aNta : nta) {
            QNodeTypeDefinition def = ntdCache.get(aNta);
            if (def.hasOrderableChildNodes()) {
                ent.orderableChildNodes = true;
                break;
            }
        }
    }
    // resolve 'primary item' attribute value (JCR-1947)
    if (ntd.getPrimaryItemName() != null) {
        ent.primaryItemName = ntd.getPrimaryItemName();
    } else {
        Name[] nta = ent.getInheritedNodeTypes();
        for (Name aNta : nta) {
            QNodeTypeDefinition def = ntdCache.get(aNta);
            if (def.getPrimaryItemName() != null) {
                ent.primaryItemName = def.getPrimaryItemName();
                break;
            }
        }
    }
    // we're done
    return ent;
}
Also used : QItemDefinition(org.apache.jackrabbit.spi.QItemDefinition) QNodeDefinition(org.apache.jackrabbit.spi.QNodeDefinition) Name(org.apache.jackrabbit.spi.Name) QNodeTypeDefinition(org.apache.jackrabbit.spi.QNodeTypeDefinition) QPropertyDefinition(org.apache.jackrabbit.spi.QPropertyDefinition) HashSet(java.util.HashSet)

Example 14 with QItemDefinition

use of org.apache.jackrabbit.spi.QItemDefinition in project jackrabbit by apache.

the class EffectiveNodeType method getNamedNodeDefs.

public QNodeDefinition[] getNamedNodeDefs(Name name) {
    List<QItemDefinition> list = namedItemDefs.get(name);
    if (list == null || list.size() == 0) {
        return QNodeDefinition.EMPTY_ARRAY;
    }
    ArrayList<QNodeDefinition> defs = new ArrayList<QNodeDefinition>(list.size());
    for (QItemDefinition def : list) {
        if (def.definesNode()) {
            defs.add((QNodeDefinition) def);
        }
    }
    if (defs.size() == 0) {
        return QNodeDefinition.EMPTY_ARRAY;
    }
    return defs.toArray(new QNodeDefinition[defs.size()]);
}
Also used : ArrayList(java.util.ArrayList) QItemDefinition(org.apache.jackrabbit.spi.QItemDefinition) QNodeDefinition(org.apache.jackrabbit.spi.QNodeDefinition)

Example 15 with QItemDefinition

use of org.apache.jackrabbit.spi.QItemDefinition in project jackrabbit by apache.

the class EffectiveNodeType method internalMerge.

/**
     * Internal helper method which merges another <code>EffectiveNodeType</code>
     * instance with <i>this</i> instance.
     * <p>
     * Warning: This instance might be in an inconsistent state if an exception
     * is thrown.
     *
     * @param other
     * @param supertype true if the merge is a result of inheritance, i.e. <code>other</code>
     *                  represents one or more supertypes of this instance; otherwise false, i.e.
     *                  the merge is the result of an explicit aggregation
     * @throws NodeTypeConflictException
     */
private synchronized void internalMerge(EffectiveNodeType other, boolean supertype) throws NodeTypeConflictException {
    Name[] nta = other.getAllNodeTypes();
    int includedCount = 0;
    for (Name aNta : nta) {
        if (includesNodeType(aNta)) {
            // redundant node type
            log.debug("node type '" + aNta + "' is already contained.");
            includedCount++;
        }
    }
    if (includedCount == nta.length) {
        // total overlap, ignore
        return;
    }
    // named item definitions
    QItemDefinition[] defs = other.getNamedItemDefs();
    for (QItemDefinition def : defs) {
        if (includesNodeType(def.getDeclaringNodeType())) {
            // ignore redundant definitions
            continue;
        }
        Name name = def.getName();
        List<QItemDefinition> existingDefs = namedItemDefs.get(name);
        if (existingDefs != null) {
            if (existingDefs.size() > 0) {
                // there already exists at least one definition with that name
                for (QItemDefinition existingDef : existingDefs) {
                    // make sure none of them is auto-create
                    if (def.isAutoCreated() || existingDef.isAutoCreated()) {
                        // conflict
                        String msg = "The item definition for '" + name + "' in node type '" + def.getDeclaringNodeType() + "' conflicts with node type '" + existingDef.getDeclaringNodeType() + "': name collision with auto-create definition";
                        log.debug(msg);
                        throw new NodeTypeConflictException(msg);
                    }
                    // check ambiguous definitions
                    if (def.definesNode() == existingDef.definesNode()) {
                        if (!def.definesNode()) {
                            // property definition
                            QPropertyDefinition pd = (QPropertyDefinition) def;
                            QPropertyDefinition epd = (QPropertyDefinition) existingDef;
                            // compare type & multiValued flag
                            if (pd.getRequiredType() == epd.getRequiredType() && pd.isMultiple() == epd.isMultiple()) {
                                // conflict
                                String msg = "The property definition for '" + name + "' in node type '" + def.getDeclaringNodeType() + "' conflicts with node type '" + existingDef.getDeclaringNodeType() + "': ambiguous property definition";
                                log.debug(msg);
                                throw new NodeTypeConflictException(msg);
                            }
                        } else {
                            // child node definition
                            // conflict
                            String msg = "The child node definition for '" + name + "' in node type '" + def.getDeclaringNodeType() + "' conflicts with node type '" + existingDef.getDeclaringNodeType() + "': ambiguous child node definition";
                            log.debug(msg);
                            throw new NodeTypeConflictException(msg);
                        }
                    }
                }
            }
        } else {
            existingDefs = new ArrayList<QItemDefinition>();
            namedItemDefs.put(name, existingDefs);
        }
        existingDefs.add(def);
    }
    // residual item definitions
    defs = other.getUnnamedItemDefs();
    for (QItemDefinition def : defs) {
        if (includesNodeType(def.getDeclaringNodeType())) {
            // ignore redundant definitions
            continue;
        }
        for (QItemDefinition existing : unnamedItemDefs) {
            // compare with existing definition
            if (def.definesNode() == existing.definesNode()) {
                if (!def.definesNode()) {
                    // property definition
                    QPropertyDefinition pd = (QPropertyDefinition) def;
                    QPropertyDefinition epd = (QPropertyDefinition) existing;
                    // compare type & multiValued flag
                    if (pd.getRequiredType() == epd.getRequiredType() && pd.isMultiple() == epd.isMultiple()) {
                        // conflict
                        String msg = "A property definition in node type '" + def.getDeclaringNodeType() + "' conflicts with node type '" + existing.getDeclaringNodeType() + "': ambiguous residual property definition";
                        log.debug(msg);
                        throw new NodeTypeConflictException(msg);
                    }
                } else {
                    // child node definition
                    QNodeDefinition nd = (QNodeDefinition) def;
                    QNodeDefinition end = (QNodeDefinition) existing;
                    // compare required & default primary types
                    if (Arrays.equals(nd.getRequiredPrimaryTypes(), end.getRequiredPrimaryTypes()) && (nd.getDefaultPrimaryType() == null ? end.getDefaultPrimaryType() == null : nd.getDefaultPrimaryType().equals(end.getDefaultPrimaryType()))) {
                        // conflict
                        String msg = "A child node definition in node type '" + def.getDeclaringNodeType() + "' conflicts with node type '" + existing.getDeclaringNodeType() + "': ambiguous residual child node definition";
                        log.debug(msg);
                        throw new NodeTypeConflictException(msg);
                    }
                }
            }
        }
        unnamedItemDefs.add(def);
    }
    allNodeTypes.addAll(Arrays.asList(nta));
    if (supertype) {
        // implicit merge as result of inheritance
        // add other merged node types as supertypes
        nta = other.getMergedNodeTypes();
        inheritedNodeTypes.addAll(Arrays.asList(nta));
        // add supertypes of other merged node types as supertypes
        nta = other.getInheritedNodeTypes();
        inheritedNodeTypes.addAll(Arrays.asList(nta));
    } else {
        // explicit merge
        // merge with other merged node types
        nta = other.getMergedNodeTypes();
        mergedNodeTypes.addAll(Arrays.asList(nta));
        // add supertypes of other merged node types as supertypes
        nta = other.getInheritedNodeTypes();
        inheritedNodeTypes.addAll(Arrays.asList(nta));
    }
    // update 'orderable child nodes' attribute value (JCR-1947)
    if (other.hasOrderableChildNodes()) {
        orderableChildNodes = true;
    }
    // update 'primary item' attribute value (JCR-1947)
    if (primaryItemName == null && other.getPrimaryItemName() != null) {
        primaryItemName = other.getPrimaryItemName();
    }
}
Also used : QPropertyDefinition(org.apache.jackrabbit.spi.QPropertyDefinition) QItemDefinition(org.apache.jackrabbit.spi.QItemDefinition) QNodeDefinition(org.apache.jackrabbit.spi.QNodeDefinition) QValueConstraint(org.apache.jackrabbit.spi.QValueConstraint) Name(org.apache.jackrabbit.spi.Name)

Aggregations

QItemDefinition (org.apache.jackrabbit.spi.QItemDefinition)22 ConstraintViolationException (javax.jcr.nodetype.ConstraintViolationException)10 Name (org.apache.jackrabbit.spi.Name)10 QNodeDefinition (org.apache.jackrabbit.spi.QNodeDefinition)9 QPropertyDefinition (org.apache.jackrabbit.spi.QPropertyDefinition)9 ArrayList (java.util.ArrayList)7 RepositoryException (javax.jcr.RepositoryException)6 EffectiveNodeType (org.apache.jackrabbit.core.nodetype.EffectiveNodeType)6 NodeState (org.apache.jackrabbit.core.state.NodeState)5 HashSet (java.util.HashSet)4 ChildNodeEntry (org.apache.jackrabbit.core.state.ChildNodeEntry)4 ItemStateException (org.apache.jackrabbit.core.state.ItemStateException)4 AccessDeniedException (javax.jcr.AccessDeniedException)3 ItemNotFoundException (javax.jcr.ItemNotFoundException)3 NodeId (org.apache.jackrabbit.core.id.NodeId)3 PropertyId (org.apache.jackrabbit.core.id.PropertyId)3 NodeTypeManagerImpl (org.apache.jackrabbit.core.nodetype.NodeTypeManagerImpl)3 NodeTypeRegistry (org.apache.jackrabbit.core.nodetype.NodeTypeRegistry)3 AccessManager (org.apache.jackrabbit.core.security.AccessManager)3 PropertyState (org.apache.jackrabbit.core.state.PropertyState)3