private synchronized void internalMerge()

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


    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();
        }
    }