mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

Nicolas Capponi
05.51.2016 97233d69036f6475b984105b2affb0b3f565400c
OPENDJ-3196 Remove multiple names mapping from Schema class
2 files modified
315 ■■■■■ changed files
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/Schema.java 83 ●●●● patch | view | raw | blame | history
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/SchemaBuilder.java 232 ●●●●● patch | view | raw | blame | history
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/Schema.java
@@ -17,6 +17,8 @@
 */
package org.forgerock.opendj.ldap.schema;
import static com.forgerock.opendj.util.StaticUtils.toLowerCase;
import static com.forgerock.opendj.ldap.CoreMessages.*;
import static org.forgerock.opendj.ldap.AttributeDescription.*;
@@ -46,8 +48,6 @@
import org.forgerock.util.Options;
import org.forgerock.util.Reject;
import com.forgerock.opendj.util.StaticUtils;
/**
 * This class defines a data structure that holds information about the
 * components of the LDAP schema. It includes the following kinds of elements:
@@ -354,13 +354,13 @@
    static final class StrictImpl implements Impl {
        private final Map<Integer, DITStructureRule> id2StructureRules;
        private final Map<String, List<AttributeType>> name2AttributeTypes;
        private final Map<String, List<DITContentRule>> name2ContentRules;
        private final Map<String, List<MatchingRule>> name2MatchingRules;
        private final Map<String, List<MatchingRuleUse>> name2MatchingRuleUses;
        private final Map<String, List<NameForm>> name2NameForms;
        private final Map<String, List<ObjectClass>> name2ObjectClasses;
        private final Map<String, List<DITStructureRule>> name2StructureRules;
        private final Map<String, AttributeType> name2AttributeTypes;
        private final Map<String, DITContentRule> name2ContentRules;
        private final Map<String, MatchingRule> name2MatchingRules;
        private final Map<String, MatchingRuleUse> name2MatchingRuleUses;
        private final Map<String, NameForm> name2NameForms;
        private final Map<String, ObjectClass> name2ObjectClasses;
        private final Map<String, DITStructureRule> name2StructureRules;
        private final Map<String, List<DITStructureRule>> nameForm2StructureRules;
        private final Map<String, AttributeType> numericOID2AttributeTypes;
        private final Map<String, DITContentRule> numericOID2ContentRules;
@@ -390,13 +390,13 @@
                final Map<String, NameForm> numericOID2NameForms,
                final Map<String, DITContentRule> numericOID2ContentRules,
                final Map<Integer, DITStructureRule> id2StructureRules,
                final Map<String, List<MatchingRule>> name2MatchingRules,
                final Map<String, List<MatchingRuleUse>> name2MatchingRuleUses,
                final Map<String, List<AttributeType>> name2AttributeTypes,
                final Map<String, List<ObjectClass>> name2ObjectClasses,
                final Map<String, List<NameForm>> name2NameForms,
                final Map<String, List<DITContentRule>> name2ContentRules,
                final Map<String, List<DITStructureRule>> name2StructureRules,
                final Map<String, MatchingRule> name2MatchingRules,
                final Map<String, MatchingRuleUse> name2MatchingRuleUses,
                final Map<String, AttributeType> name2AttributeTypes,
                final Map<String, ObjectClass> name2ObjectClasses,
                final Map<String, NameForm> name2NameForms,
                final Map<String, DITContentRule> name2ContentRules,
                final Map<String, DITStructureRule> name2StructureRules,
                final Map<String, List<NameForm>> objectClass2NameForms,
                final Map<String, List<DITStructureRule>> nameForm2StructureRules,
                final List<LocalizableMessage> warnings) {
@@ -481,9 +481,9 @@
            if (rule != null) {
                return rule;
            }
            final List<DITContentRule> rules = name2ContentRules.get(StaticUtils.toLowerCase(nameOrOid));
            if (rules != null && rules.size() == 1) {
                return rules.get(0);
            final DITContentRule rule2 = name2ContentRules.get(toLowerCase(nameOrOid));
            if (rule2 != null) {
                return rule2;
            }
            throw new UnknownSchemaElementException(WARN_DCR_UNKNOWN.get(nameOrOid));
        }
@@ -514,9 +514,9 @@
        @Override
        public DITStructureRule getDITStructureRule(final String name) {
            List<DITStructureRule> rules = name2StructureRules.get(StaticUtils.toLowerCase(name));
            if (rules != null && rules.size() == 1) {
                return rules.get(0);
            DITStructureRule rule = name2StructureRules.get(toLowerCase(name));
            if (rule != null) {
                return rule;
            }
            throw new UnknownSchemaElementException(WARN_DIT_SR_UNKNOWN.get(name));
        }
@@ -532,9 +532,9 @@
            if (rule != null) {
                return rule;
            }
            final List<MatchingRule> rules = name2MatchingRules.get(StaticUtils.toLowerCase(nameOrOid));
            if (rules != null && rules.size() == 1) {
                return rules.get(0);
            final MatchingRule rule2 = name2MatchingRules.get(toLowerCase(nameOrOid));
            if (rule2 != null) {
                return rule2;
            }
            throw new UnknownSchemaElementException(WARN_MR_UNKNOWN.get(nameOrOid));
        }
@@ -555,9 +555,9 @@
            if (use != null) {
                return use;
            }
            final List<MatchingRuleUse> uses = name2MatchingRuleUses.get(StaticUtils.toLowerCase(nameOrOid));
            if (uses != null && uses.size() == 1) {
                return uses.get(0);
            final MatchingRuleUse use2 = name2MatchingRuleUses.get(toLowerCase(nameOrOid));
            if (use2 != null) {
                return use2;
            }
            throw new UnknownSchemaElementException(WARN_MRU_UNKNOWN.get(nameOrOid));
        }
@@ -573,9 +573,9 @@
            if (form != null) {
                return form;
            }
            final List<NameForm> forms = name2NameForms.get(StaticUtils.toLowerCase(nameOrOid));
            if (forms != null && forms.size() == 1) {
                return forms.get(0);
            final NameForm form2 = name2NameForms.get(toLowerCase(nameOrOid));
            if (form2 != null) {
                return form2;
            }
            throw new UnknownSchemaElementException(WARN_NAMEFORM_UNKNOWN.get(nameOrOid));
        }
@@ -608,9 +608,9 @@
            if (oc != null) {
                return oc;
            }
            final List<ObjectClass> classes = name2ObjectClasses.get(StaticUtils.toLowerCase(nameOrOid));
            if (classes != null && classes.size() == 1) {
                return classes.get(0);
            final ObjectClass oc2 = name2ObjectClasses.get(toLowerCase(nameOrOid));
            if (oc2 != null) {
                return oc2;
            }
            return null;
        }
@@ -647,13 +647,13 @@
        @Override
        public boolean hasAttributeType(final String nameOrOid) {
            return numericOID2AttributeTypes.containsKey(nameOrOid)
                    || name2AttributeTypes.containsKey(StaticUtils.toLowerCase(nameOrOid));
                    || name2AttributeTypes.containsKey(toLowerCase(nameOrOid));
        }
        @Override
        public boolean hasDITContentRule(final String nameOrOid) {
            return numericOID2ContentRules.containsKey(nameOrOid)
                    || name2ContentRules.containsKey(StaticUtils.toLowerCase(nameOrOid));
                    || name2ContentRules.containsKey(toLowerCase(nameOrOid));
        }
        @Override
@@ -664,25 +664,25 @@
        @Override
        public boolean hasMatchingRule(final String nameOrOid) {
            return numericOID2MatchingRules.containsKey(nameOrOid)
                    || name2MatchingRules.containsKey(StaticUtils.toLowerCase(nameOrOid));
                    || name2MatchingRules.containsKey(toLowerCase(nameOrOid));
        }
        @Override
        public boolean hasMatchingRuleUse(final String nameOrOid) {
            return numericOID2MatchingRuleUses.containsKey(nameOrOid)
                    || name2MatchingRuleUses.containsKey(StaticUtils.toLowerCase(nameOrOid));
                    || name2MatchingRuleUses.containsKey(toLowerCase(nameOrOid));
        }
        @Override
        public boolean hasNameForm(final String nameOrOid) {
            return numericOID2NameForms.containsKey(nameOrOid)
                    || name2NameForms.containsKey(StaticUtils.toLowerCase(nameOrOid));
                    || name2NameForms.containsKey(toLowerCase(nameOrOid));
        }
        @Override
        public boolean hasObjectClass(final String nameOrOid) {
            return numericOID2ObjectClasses.containsKey(nameOrOid)
                    || name2ObjectClasses.containsKey(StaticUtils.toLowerCase(nameOrOid));
                    || name2ObjectClasses.containsKey(toLowerCase(nameOrOid));
        }
        @Override
@@ -700,8 +700,7 @@
            if (type != null) {
                return type;
            }
            final List<AttributeType> attrs = name2AttributeTypes.get(StaticUtils.toLowerCase(nameOrOid));
            return attrs != null && attrs.size() == 1 ? attrs.get(0) : null;
            return name2AttributeTypes.get(toLowerCase(nameOrOid));
        }
    }
opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/SchemaBuilder.java
@@ -1953,13 +1953,13 @@
        final AttributeType element = numericOID2AttributeTypes.get(nameOrOid);
        if (element != null) {
            removeAttributeType(element);
            removeAttributeType(element, null);
            return true;
        }
        final List<AttributeType> elements = name2AttributeTypes.get(toLowerCase(nameOrOid));
        if (elements != null) {
            for (final AttributeType e : elements) {
                removeAttributeType(e);
                removeAttributeType(e, null);
            }
            return true;
        }
@@ -1978,13 +1978,13 @@
        final DITContentRule element = numericOID2ContentRules.get(nameOrOid);
        if (element != null) {
            removeDITContentRule(element);
            removeDITContentRule(element, null);
            return true;
        }
        final List<DITContentRule> elements = name2ContentRules.get(toLowerCase(nameOrOid));
        if (elements != null) {
            for (final DITContentRule e : elements) {
                removeDITContentRule(e);
                removeDITContentRule(e, null);
            }
            return true;
        }
@@ -2003,7 +2003,7 @@
        final DITStructureRule element = id2StructureRules.get(ruleID);
        if (element != null) {
            removeDITStructureRule(element);
            removeDITStructureRule(element, null);
            return true;
        }
        return false;
@@ -2021,13 +2021,13 @@
        final MatchingRule element = numericOID2MatchingRules.get(nameOrOid);
        if (element != null) {
            removeMatchingRule(element);
            removeMatchingRule(element, null);
            return true;
        }
        final List<MatchingRule> elements = name2MatchingRules.get(toLowerCase(nameOrOid));
        if (elements != null) {
            for (final MatchingRule e : elements) {
                removeMatchingRule(e);
                removeMatchingRule(e, null);
            }
            return true;
        }
@@ -2046,13 +2046,13 @@
        final MatchingRuleUse element = numericOID2MatchingRuleUses.get(nameOrOid);
        if (element != null) {
            removeMatchingRuleUse(element);
            removeMatchingRuleUse(element, null);
            return true;
        }
        final List<MatchingRuleUse> elements = name2MatchingRuleUses.get(toLowerCase(nameOrOid));
        if (elements != null) {
            for (final MatchingRuleUse e : elements) {
                removeMatchingRuleUse(e);
                removeMatchingRuleUse(e, null);
            }
            return true;
        }
@@ -2071,13 +2071,13 @@
        final NameForm element = numericOID2NameForms.get(nameOrOid);
        if (element != null) {
            removeNameForm(element);
            removeNameForm(element, null);
            return true;
        }
        final List<NameForm> elements = name2NameForms.get(toLowerCase(nameOrOid));
        if (elements != null) {
            for (final NameForm e : elements) {
                removeNameForm(e);
                removeNameForm(e, null);
            }
            return true;
        }
@@ -2096,13 +2096,13 @@
        final ObjectClass element = numericOID2ObjectClasses.get(nameOrOid);
        if (element != null) {
            removeObjectClass(element);
            removeObjectClass(element, null);
            return true;
        }
        final List<ObjectClass> elements = name2ObjectClasses.get(toLowerCase(nameOrOid));
        if (elements != null) {
            for (final ObjectClass e : elements) {
                removeObjectClass(e);
                removeObjectClass(e, null);
            }
            return true;
        }
@@ -2121,7 +2121,7 @@
        final Syntax element = numericOID2Syntaxes.get(numericOID);
        if (element != null) {
            removeSyntax(element);
            removeSyntax(element, null);
            return true;
        }
        return false;
@@ -2145,6 +2145,29 @@
        return this;
    }
    private static final class NamesMapping {
        final Map<String, MatchingRule> name2MatchingRules;
        final Map<String, MatchingRuleUse> name2MatchingRuleUses;
        final Map<String, AttributeType> name2AttributeTypes;
        final Map<String, ObjectClass> name2ObjectClasses;
        final Map<String, NameForm> name2NameForms;
        final Map<String, DITContentRule> name2ContentRules;
        final Map<String, DITStructureRule> name2StructureRules;
        NamesMapping(Map<String, MatchingRule> name2MatchingRules, Map<String, MatchingRuleUse> name2MatchingRuleUses,
                Map<String, AttributeType> name2AttributeTypes, Map<String, ObjectClass> name2ObjectClasses,
                Map<String, NameForm> name2NameForms, Map<String, DITContentRule> name2ContentRules,
                Map<String, DITStructureRule> name2StructureRules) {
            this.name2MatchingRules = name2MatchingRules;
            this.name2MatchingRuleUses = name2MatchingRuleUses;
            this.name2AttributeTypes = name2AttributeTypes;
            this.name2ObjectClasses = name2ObjectClasses;
            this.name2NameForms = name2NameForms;
            this.name2ContentRules = name2ContentRules;
            this.name2StructureRules = name2StructureRules;
        }
    }
    /**
     * Returns a strict {@code Schema} containing all of the schema elements
     * contained in this schema builder as well as the same set of schema
@@ -2185,24 +2208,21 @@
            defaultMatchingRule = Schema.getCoreSchema().getDefaultMatchingRule();
        }
        removeDuplicateMatchingRulesNames();
        removeDuplicateMatchingRuleUsesNames();
        removeDuplicateAttributeTypesNames();
        removeDuplicateObjectClassesNames();
        removeDuplicateNameFormsNames();
        removeDuplicateDITContentRulesNames();
        removeDuplicateDITStructureRulesNames();
        NamesMapping names = new NamesMapping(removeDuplicateMatchingRulesNames(),
                removeDuplicateMatchingRuleUsesNames(), removeDuplicateAttributeTypesNames(),
                removeDuplicateObjectClassesNames(), removeDuplicateNameFormsNames(),
                removeDuplicateDITContentRulesNames(), removeDuplicateDITStructureRulesNames());
        final Schema schema =
                new Schema.StrictImpl(localSchemaName, options,
                        defaultSyntax, defaultMatchingRule, numericOID2Syntaxes,
                        numericOID2MatchingRules, numericOID2MatchingRuleUses,
                        numericOID2AttributeTypes, numericOID2ObjectClasses, numericOID2NameForms,
                        numericOID2ContentRules, id2StructureRules, name2MatchingRules,
                        name2MatchingRuleUses, name2AttributeTypes, name2ObjectClasses,
                        name2NameForms, name2ContentRules, name2StructureRules,
                        numericOID2ContentRules, id2StructureRules, names.name2MatchingRules,
                        names.name2MatchingRuleUses, names.name2AttributeTypes, names.name2ObjectClasses,
                        names.name2NameForms, names.name2ContentRules, names.name2StructureRules,
                        objectClass2NameForms, nameForm2StructureRules, warnings).asStrictSchema();
        validate(schema);
        validate(schema, names);
        // Re-init this builder so that it can continue to be used afterwards.
        preLazyInitBuilder(schemaName, schema);
@@ -2220,7 +2240,7 @@
                                attribute.getOID(), conflictingAttribute.getNameOrOID());
                throw new ConflictingSchemaElementException(message);
            }
            removeAttributeType(conflictingAttribute);
            removeAttributeType(conflictingAttribute, null);
        }
        numericOID2AttributeTypes.put(attribute.getOID(), attribute);
@@ -2251,7 +2271,7 @@
                                .getStructuralClassOID(), conflictingRule.getNameOrOID());
                throw new ConflictingSchemaElementException(message);
            }
            removeDITContentRule(conflictingRule);
            removeDITContentRule(conflictingRule, null);
        }
        numericOID2ContentRules.put(rule.getStructuralClassOID(), rule);
@@ -2282,7 +2302,7 @@
                                rule.getRuleID(), conflictingRule.getNameOrRuleID());
                throw new ConflictingSchemaElementException(message);
            }
            removeDITStructureRule(conflictingRule);
            removeDITStructureRule(conflictingRule, null);
        }
        id2StructureRules.put(rule.getRuleID(), rule);
@@ -2313,7 +2333,7 @@
                                .getMatchingRuleOID(), conflictingUse.getNameOrOID());
                throw new ConflictingSchemaElementException(message);
            }
            removeMatchingRuleUse(conflictingUse);
            removeMatchingRuleUse(conflictingUse, null);
        }
        numericOID2MatchingRuleUses.put(use.getMatchingRuleOID(), use);
@@ -2346,7 +2366,7 @@
                                conflictingRule.getNameOrOID());
                throw new ConflictingSchemaElementException(message);
            }
            removeMatchingRule(conflictingRule);
            removeMatchingRule(conflictingRule, null);
        }
        numericOID2MatchingRules.put(rule.getOID(), rule);
@@ -2376,7 +2396,7 @@
                                form.getOID(), conflictingForm.getNameOrOID());
                throw new ConflictingSchemaElementException(message);
            }
            removeNameForm(conflictingForm);
            removeNameForm(conflictingForm, null);
        }
        numericOID2NameForms.put(form.getOID(), form);
@@ -2406,7 +2426,7 @@
                                conflictingOC.getNameOrOID());
                throw new ConflictingSchemaElementException(message);
            }
            removeObjectClass(conflictingOC);
            removeObjectClass(conflictingOC, null);
        }
        numericOID2ObjectClasses.put(oc.getOID(), oc);
@@ -2475,7 +2495,7 @@
                        syntax.getOID(), conflictingSyntax.getOID());
                throw new ConflictingSchemaElementException(message);
            }
            removeSyntax(conflictingSyntax);
            removeSyntax(conflictingSyntax, null);
        }
        numericOID2Syntaxes.put(syntax.getOID(), syntax);
@@ -2545,7 +2565,7 @@
        this.warnings = null;
    }
    private void removeAttributeType(final AttributeType attributeType) {
    private void removeAttributeType(final AttributeType attributeType, NamesMapping names) {
        numericOID2AttributeTypes.remove(attributeType.getOID());
        for (final String name : attributeType.getNames()) {
            final String lowerName = StaticUtils.toLowerCase(name);
@@ -2557,10 +2577,13 @@
                    attributes.remove(attributeType);
                }
            }
            if (names != null) {
                names.name2AttributeTypes.remove(lowerName);
            }
        }
    }
    private void removeDITContentRule(final DITContentRule rule) {
    private void removeDITContentRule(final DITContentRule rule, NamesMapping names) {
        numericOID2ContentRules.remove(rule.getStructuralClassOID());
        for (final String name : rule.getNames()) {
            final String lowerName = StaticUtils.toLowerCase(name);
@@ -2572,10 +2595,13 @@
                    rules.remove(rule);
                }
            }
            if (names != null) {
                names.name2ContentRules.remove(lowerName);
            }
        }
    }
    private void removeDITStructureRule(final DITStructureRule rule) {
    private void removeDITStructureRule(final DITStructureRule rule, NamesMapping names) {
        id2StructureRules.remove(rule.getRuleID());
        for (final String name : rule.getNames()) {
            final String lowerName = StaticUtils.toLowerCase(name);
@@ -2587,10 +2613,13 @@
                    rules.remove(rule);
                }
            }
            if (names != null) {
                names.name2StructureRules.remove(lowerName);
            }
        }
    }
    private void removeMatchingRule(final MatchingRule rule) {
    private void removeMatchingRule(final MatchingRule rule, NamesMapping names) {
        numericOID2MatchingRules.remove(rule.getOID());
        for (final String name : rule.getNames()) {
            final String lowerName = StaticUtils.toLowerCase(name);
@@ -2602,10 +2631,13 @@
                    rules.remove(rule);
                }
            }
            if (names != null) {
                names.name2MatchingRules.remove(lowerName);
            }
        }
    }
    private void removeMatchingRuleUse(final MatchingRuleUse use) {
    private void removeMatchingRuleUse(final MatchingRuleUse use, NamesMapping names) {
        numericOID2MatchingRuleUses.remove(use.getMatchingRuleOID());
        for (final String name : use.getNames()) {
            final String lowerName = StaticUtils.toLowerCase(name);
@@ -2617,10 +2649,13 @@
                    uses.remove(use);
                }
            }
            if (names != null) {
                names.name2MatchingRuleUses.remove(lowerName);
            }
        }
    }
    private void removeNameForm(final NameForm form) {
    private void removeNameForm(final NameForm form, NamesMapping names) {
        numericOID2NameForms.remove(form.getOID());
        name2NameForms.remove(form.getOID());
        for (final String name : form.getNames()) {
@@ -2633,10 +2668,13 @@
                    forms.remove(form);
                }
            }
            if (names != null) {
                names.name2NameForms.remove(lowerName);
            }
        }
    }
    private void removeObjectClass(final ObjectClass oc) {
    private void removeObjectClass(final ObjectClass oc, NamesMapping names) {
        numericOID2ObjectClasses.remove(oc.getOID());
        name2ObjectClasses.remove(oc.getOID());
        for (final String name : oc.getNames()) {
@@ -2649,10 +2687,13 @@
                    classes.remove(oc);
                }
            }
            if (names != null) {
                names.name2ObjectClasses.remove(lowerName);
            }
        }
    }
    private void removeSyntax(final Syntax syntax) {
    private void removeSyntax(final Syntax syntax, NamesMapping names) {
        for (Map.Entry<String, List<String>> property : syntax.getExtraProperties().entrySet()) {
            if ("x-enum".equalsIgnoreCase(property.getKey())) {
                removeMatchingRule(OMR_OID_GENERIC_ENUM + "." + syntax.getOID());
@@ -2662,14 +2703,14 @@
        numericOID2Syntaxes.remove(syntax.getOID());
    }
    private void validate(final Schema schema) {
    private void validate(final Schema schema, NamesMapping names) {
        // Verify all references in all elements
        for (final Syntax syntax : numericOID2Syntaxes.values().toArray(
                new Syntax[numericOID2Syntaxes.values().size()])) {
            try {
                syntax.validate(schema, warnings);
            } catch (final SchemaException e) {
                removeSyntax(syntax);
                removeSyntax(syntax, names);
                warnings.add(ERR_SYNTAX_VALIDATION_FAIL
                        .get(syntax.toString(), e.getMessageObject()));
            }
@@ -2680,7 +2721,7 @@
            try {
                rule.validate(schema, warnings);
            } catch (final SchemaException e) {
                removeMatchingRule(rule);
                removeMatchingRule(rule, names);
                warnings.add(ERR_MR_VALIDATION_FAIL.get(rule.toString(), e.getMessageObject()));
            }
        }
@@ -2693,7 +2734,7 @@
        }
        for (final AttributeType attributeType : invalidAttributeTypes) {
            removeAttributeType(attributeType);
            removeAttributeType(attributeType, names);
        }
        // Object classes need special processing because they have hierarchical
@@ -2704,7 +2745,7 @@
        }
        for (final ObjectClass objectClass : invalidObjectClasses) {
            removeObjectClass(objectClass);
            removeObjectClass(objectClass, names);
        }
        for (final MatchingRuleUse use : numericOID2MatchingRuleUses.values().toArray(
@@ -2712,7 +2753,7 @@
            try {
                use.validate(schema, warnings);
            } catch (final SchemaException e) {
                removeMatchingRuleUse(use);
                removeMatchingRuleUse(use, names);
                warnings.add(ERR_MRU_VALIDATION_FAIL.get(use.toString(), e.getMessageObject()));
            }
        }
@@ -2735,7 +2776,7 @@
                    forms.add(form);
                }
            } catch (final SchemaException e) {
                removeNameForm(form);
                removeNameForm(form, names);
                warnings.add(ERR_NAMEFORM_VALIDATION_FAIL
                        .get(form.toString(), e.getMessageObject()));
            }
@@ -2746,7 +2787,7 @@
            try {
                rule.validate(schema, warnings);
            } catch (final SchemaException e) {
                removeDITContentRule(rule);
                removeDITContentRule(rule, names);
                warnings.add(ERR_DCR_VALIDATION_FAIL.get(rule.toString(), e.getMessageObject()));
            }
        }
@@ -2759,7 +2800,7 @@
        }
        for (final DITStructureRule rule : invalidStructureRules) {
            removeDITStructureRule(rule);
            removeDITStructureRule(rule, names);
        }
        for (final DITStructureRule rule : id2StructureRules.values()) {
@@ -2778,8 +2819,9 @@
        }
    }
    private void removeDuplicateMatchingRulesNames() {
        for (final java.util.Map.Entry<String, List<MatchingRule>> entry : name2MatchingRules.entrySet()) {
    private Map<String, MatchingRule> removeDuplicateMatchingRulesNames() {
        final Map<String, MatchingRule> names = newMap(name2MatchingRules.size());
        for (final Map.Entry<String, List<MatchingRule>> entry : name2MatchingRules.entrySet()) {
            List<MatchingRule> rules = entry.getValue();
            if (rules.size() > 1) {
                StringBuilder oids = new StringBuilder();
@@ -2791,14 +2833,17 @@
                }
                String name = entry.getKey();
                warnings.add(WARN_MATCHING_RULES_DUPLICATED_NAME.get(oids, name, name, rules.get(0).getOID()));
                // keep only the first value
                rules.subList(1, rules.size()).clear();
            }
            if (!rules.isEmpty()) {
                names.put(entry.getKey(), rules.get(0));
            }
        }
        return names;
    }
    private void removeDuplicateMatchingRuleUsesNames() {
        for (final java.util.Map.Entry<String, List<MatchingRuleUse>> entry : name2MatchingRuleUses.entrySet()) {
    private Map<String, MatchingRuleUse> removeDuplicateMatchingRuleUsesNames() {
        final Map<String, MatchingRuleUse> names = newMap(name2MatchingRuleUses.size());
        for (final Map.Entry<String, List<MatchingRuleUse>> entry : name2MatchingRuleUses.entrySet()) {
            List<MatchingRuleUse> uses = entry.getValue();
            if (uses.size() > 1) {
                StringBuilder oids = new StringBuilder();
@@ -2811,16 +2856,19 @@
                String name = entry.getKey();
                warnings.add(WARN_MATCHING_RULE_USES_DUPLICATED_NAME.get(oids, name, name,
                        uses.get(0).getMatchingRuleOID()));
                // keep only the first value
                uses.subList(1, uses.size()).clear();
            }
            if (!uses.isEmpty()) {
                names.put(entry.getKey(), uses.get(0));
            }
        }
        return names;
    }
    private void removeDuplicateAttributeTypesNames() {
        for (final java.util.Map.Entry<String, List<AttributeType>> entry : name2AttributeTypes.entrySet()) {
    private Map<String, AttributeType> removeDuplicateAttributeTypesNames() {
        final Map<String, AttributeType> names = newMap(name2AttributeTypes.size());
        for (final Map.Entry<String, List<AttributeType>> entry : name2AttributeTypes.entrySet()) {
            List<AttributeType> types = entry.getValue();
            if (entry.getValue().size() > 1) {
            if (types.size() > 1) {
                StringBuilder oids = new StringBuilder();
                for (AttributeType attr : types) {
                    if (oids.length() > 0) {
@@ -2830,16 +2878,19 @@
                }
                String name = entry.getKey();
                warnings.add(WARN_ATTR_TYPES_DUPLICATED_NAME.get(oids, name, name, types.get(0).getOID()));
                // keep only the first value
                types.subList(1, types.size()).clear();
            }
            if (!types.isEmpty()) {
                names.put(entry.getKey(), types.get(0));
            }
        }
        return names;
    }
    private void removeDuplicateObjectClassesNames() {
        for (final java.util.Map.Entry<String, List<ObjectClass>> entry : name2ObjectClasses.entrySet()) {
    private Map<String, ObjectClass> removeDuplicateObjectClassesNames() {
        final Map<String, ObjectClass> names = newMap(name2ObjectClasses.size());
        for (final Map.Entry<String, List<ObjectClass>> entry : name2ObjectClasses.entrySet()) {
            List<ObjectClass> classes = entry.getValue();
            if (entry.getValue().size() > 1) {
            if (classes.size() > 1) {
                StringBuilder oids = new StringBuilder();
                for (ObjectClass attr : classes) {
                    if (oids.length() > 0) {
@@ -2849,16 +2900,19 @@
                }
                String name = entry.getKey();
                warnings.add(WARN_CLASSES_DUPLICATED_NAME.get(oids, name, name, classes.get(0).getOID()));
                // keep only the first value
                classes.subList(1, classes.size()).clear();
            }
            if (!classes.isEmpty()) {
                names.put(entry.getKey(), classes.get(0));
            }
        }
        return names;
    }
    private void removeDuplicateNameFormsNames() {
        for (final java.util.Map.Entry<String, List<NameForm>> entry : name2NameForms.entrySet()) {
    private Map<String, NameForm> removeDuplicateNameFormsNames() {
        final Map<String, NameForm> names = newMap(name2NameForms.size());
        for (final Map.Entry<String, List<NameForm>> entry : name2NameForms.entrySet()) {
            List<NameForm> forms = entry.getValue();
            if (entry.getValue().size() > 1) {
            if (forms.size() > 1) {
                StringBuilder oids = new StringBuilder();
                for (NameForm attr : forms) {
                    if (oids.length() > 0) {
@@ -2868,16 +2922,19 @@
                }
                String name = entry.getKey();
                warnings.add(WARN_NAME_FORMS_DUPLICATED_NAME.get(oids, name, name, forms.get(0).getOID()));
                // keep only the first value
                forms.subList(1, forms.size()).clear();
            }
            if (!forms.isEmpty()) {
                names.put(entry.getKey(), forms.get(0));
            }
        }
        return names;
    }
    private void removeDuplicateDITStructureRulesNames() {
        for (final java.util.Map.Entry<String, List<DITStructureRule>> entry : name2StructureRules.entrySet()) {
    private Map<String, DITStructureRule> removeDuplicateDITStructureRulesNames() {
        final Map<String, DITStructureRule> names = newMap(name2StructureRules.size());
        for (final Map.Entry<String, List<DITStructureRule>> entry : name2StructureRules.entrySet()) {
            List<DITStructureRule> rules = entry.getValue();
            if (entry.getValue().size() > 1) {
            if (rules.size() > 1) {
                StringBuilder ids = new StringBuilder();
                for (DITStructureRule attr : rules) {
                    if (ids.length() > 0) {
@@ -2887,16 +2944,19 @@
                }
                String name = entry.getKey();
                warnings.add(WARN_DIT_SR_DUPLICATED_NAME.get(ids, name, name, rules.get(0).getRuleID()));
                // keep only the first value
                rules.subList(1, rules.size()).clear();
            }
            if (!rules.isEmpty()) {
                names.put(entry.getKey(), rules.get(0));
            }
        }
        return names;
    }
    private void removeDuplicateDITContentRulesNames() {
        for (final java.util.Map.Entry<String, List<DITContentRule>> entry : name2ContentRules.entrySet()) {
    private Map<String, DITContentRule> removeDuplicateDITContentRulesNames() {
        final Map<String, DITContentRule> names = newMap(name2ContentRules.size());
        for (final Map.Entry<String, List<DITContentRule>> entry : name2ContentRules.entrySet()) {
            List<DITContentRule> rules = entry.getValue();
            if (entry.getValue().size() > 1) {
            if (rules.size() > 1) {
                StringBuilder ids = new StringBuilder();
                for (DITContentRule attr : rules) {
                    if (ids.length() > 0) {
@@ -2906,9 +2966,15 @@
                }
                String name = entry.getKey();
                warnings.add(WARN_DIT_CR_DUPLICATED_NAME.get(ids, name, name, rules.get(0).getStructuralClassOID()));
                // keep only the first value
                rules.subList(1, rules.size()).clear();
            }
            if (!rules.isEmpty()) {
                names.put(entry.getKey(), rules.get(0));
            }
        }
        return names;
    }
    private <T extends SchemaElement> Map<String, T> newMap(int size) {
        return new HashMap<String, T>((int) ((size) / 0.75 + 1));
    }
}