static EffectiveNodeType create()

in jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/EffectiveNodeType.java [98:248]


    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) {
            // check if child node definition would be ambiguous within
            // 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) {
            // check if property definition would be ambiguous within
            // 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;
    }