From da39f45ae2d1523b96651b16fd12d6952ed3a199 Mon Sep 17 00:00:00 2001
From: Nicolas Capponi <nicolas.capponi@forgerock.com>
Date: Thu, 16 Oct 2014 15:51:10 +0000
Subject: [PATCH] OPENDJ-1590 CR-4861 Add collation matching rules to SDK Core Schema

---
 opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CollationLessThanMatchingRuleTest.java           |   14 -
 opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CoreSchemaImpl.java                              |  281 ++++++++++++++++++++++++++++++++++++++++
 opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CollationGreaterThanMatchingRuleTest.java        |   14 -
 opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CollationSubstringMatchingRuleTest.java          |   14 -
 opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CollationLessThanOrEqualMatchingRuleTest.java    |   14 -
 opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CollationMatchingRulesImpl.java                  |   33 ++--
 opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CollationEqualityMatchingRuleTest.java           |   29 ++-
 opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CollationGreaterThanOrEqualMatchingRuleTest.java |   15 -
 8 files changed, 320 insertions(+), 94 deletions(-)

diff --git a/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CollationMatchingRulesImpl.java b/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CollationMatchingRulesImpl.java
index 4783028..89ee97d 100644
--- a/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CollationMatchingRulesImpl.java
+++ b/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CollationMatchingRulesImpl.java
@@ -50,7 +50,7 @@
  * For a given locale, two indexes are used: a shared one (for equality and
  * ordering rules) and a substring one (for substring rule).
  */
-public final class CollationMatchingRulesImpl {
+final class CollationMatchingRulesImpl {
 
     private static final String INDEX_ID_SHARED = "shared";
     private static final String INDEX_ID_SUBSTRING = "substring";
@@ -66,7 +66,7 @@
      *            the locale to use for this rule
      * @return the matching rule implementation
      */
-    public static CollationEqualityMatchingRuleImpl equalityMatchingRule(Locale locale) {
+    static MatchingRuleImpl collationEqualityMatchingRule(Locale locale) {
         return new CollationEqualityMatchingRuleImpl(locale);
     }
 
@@ -77,7 +77,7 @@
      *            the locale to use for this rule
      * @return the matching rule implementation
      */
-    public static CollationSubstringMatchingRuleImpl substringMatchingRule(Locale locale) {
+    static MatchingRuleImpl collationSubstringMatchingRule(Locale locale) {
         return new CollationSubstringMatchingRuleImpl(locale);
     }
 
@@ -88,7 +88,7 @@
      *            the locale to use for this rule
      * @return the matching rule implementation
      */
-    public static CollationLessThanMatchingRuleImpl lessThanMatchingRule(Locale locale) {
+    static MatchingRuleImpl collationLessThanMatchingRule(Locale locale) {
         return new CollationLessThanMatchingRuleImpl(locale);
     }
 
@@ -99,7 +99,7 @@
      *            the locale to use for this rule
      * @return the matching rule implementation
      */
-    public static CollationLessThanOrEqualToMatchingRuleImpl lessThanOrEqualMatchingRule(Locale locale) {
+    static MatchingRuleImpl collationLessThanOrEqualMatchingRule(Locale locale) {
         return new CollationLessThanOrEqualToMatchingRuleImpl(locale);
     }
 
@@ -110,7 +110,7 @@
      *            the locale to use for this rule
      * @return the matching rule implementation
      */
-    public static CollationGreaterThanMatchingRuleImpl greaterThanMatchingRule(Locale locale) {
+    static MatchingRuleImpl collationGreaterThanMatchingRule(Locale locale) {
         return new CollationGreaterThanMatchingRuleImpl(locale);
     }
 
@@ -121,14 +121,14 @@
      *            the locale to use for this rule
      * @return the matching rule implementation
      */
-    public static CollationGreaterThanOrEqualToMatchingRuleImpl greaterThanOrEqualToMatchingRule(Locale locale) {
+    static MatchingRuleImpl collationGreaterThanOrEqualToMatchingRule(Locale locale) {
         return new CollationGreaterThanOrEqualToMatchingRuleImpl(locale);
     }
 
     /**
      * Defines the base for collation matching rules.
      */
-    static abstract class AbstractCollationMatchingRuleImpl extends AbstractMatchingRuleImpl {
+    private static abstract class AbstractCollationMatchingRuleImpl extends AbstractMatchingRuleImpl {
 
         private final Locale locale;
         final Collator collator;
@@ -140,7 +140,7 @@
          * @param locale
          *            Locale associated with this rule.
          */
-        public AbstractCollationMatchingRuleImpl(Locale locale) {
+        AbstractCollationMatchingRuleImpl(Locale locale) {
             this.locale = locale;
             this.collator = createCollator(locale);
             this.indexer = new DefaultIndexer(getSharedIndexName());
@@ -205,7 +205,7 @@
     /**
      * Defines the collation equality matching rule.
      */
-    static final class CollationEqualityMatchingRuleImpl extends AbstractCollationMatchingRuleImpl {
+    private static final class CollationEqualityMatchingRuleImpl extends AbstractCollationMatchingRuleImpl {
 
         /**
          * Creates the matching rule with the provided locale.
@@ -228,7 +228,7 @@
     /**
      * Defines the collation substring matching rule.
      */
-    static final class CollationSubstringMatchingRuleImpl extends AbstractCollationMatchingRuleImpl {
+    private static final class CollationSubstringMatchingRuleImpl extends AbstractCollationMatchingRuleImpl {
 
         private final AbstractSubstringMatchingRuleImpl substringMatchingRule;
         private final Indexer subIndexer;
@@ -275,7 +275,7 @@
     /**
      * Defines the collation ordering matching rule.
      */
-    static abstract class CollationOrderingMatchingRuleImpl extends AbstractCollationMatchingRuleImpl {
+    private static abstract class CollationOrderingMatchingRuleImpl extends AbstractCollationMatchingRuleImpl {
 
         final AbstractOrderingMatchingRuleImpl orderingMatchingRule;
 
@@ -300,7 +300,7 @@
     /**
      * Defines the collation less than matching rule.
      */
-    static final class CollationLessThanMatchingRuleImpl extends CollationOrderingMatchingRuleImpl {
+    private static final class CollationLessThanMatchingRuleImpl extends CollationOrderingMatchingRuleImpl {
 
         CollationLessThanMatchingRuleImpl(Locale locale) {
             super(locale);
@@ -316,7 +316,7 @@
     /**
      * Defines the collation less than or equal matching rule.
      */
-    static final class CollationLessThanOrEqualToMatchingRuleImpl extends CollationOrderingMatchingRuleImpl {
+    private static final class CollationLessThanOrEqualToMatchingRuleImpl extends CollationOrderingMatchingRuleImpl {
 
         CollationLessThanOrEqualToMatchingRuleImpl(Locale locale) {
             super(locale);
@@ -332,7 +332,7 @@
     /**
      * Defines the collation greater than matching rule.
      */
-    static final class CollationGreaterThanMatchingRuleImpl extends CollationOrderingMatchingRuleImpl {
+    private static final class CollationGreaterThanMatchingRuleImpl extends CollationOrderingMatchingRuleImpl {
 
         CollationGreaterThanMatchingRuleImpl(Locale locale) {
             super(locale);
@@ -348,7 +348,8 @@
     /**
      * Defines the collation greater than or equal matching rule.
      */
-    static final class CollationGreaterThanOrEqualToMatchingRuleImpl extends CollationOrderingMatchingRuleImpl {
+    private static final class CollationGreaterThanOrEqualToMatchingRuleImpl
+        extends CollationOrderingMatchingRuleImpl {
 
         CollationGreaterThanOrEqualToMatchingRuleImpl(Locale locale) {
             super(locale);
diff --git a/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CoreSchemaImpl.java b/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CoreSchemaImpl.java
index 87b4a60..148e03e 100644
--- a/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CoreSchemaImpl.java
+++ b/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CoreSchemaImpl.java
@@ -27,14 +27,19 @@
  */
 package org.forgerock.opendj.ldap.schema;
 
+import static org.forgerock.opendj.ldap.schema.CollationMatchingRulesImpl.*;
 import static org.forgerock.opendj.ldap.schema.SchemaConstants.*;
 import static org.forgerock.opendj.ldap.schema.TimeBasedMatchingRulesImpl.*;
 
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
+import java.util.Map.Entry;
 import java.util.Set;
 
 final class CoreSchemaImpl {
@@ -77,6 +82,176 @@
 
     private static final Schema SINGLETON;
 
+    /**
+     * Provides the oid associated to each locale, for the registration of collation matching rules.
+     * <p>
+     * To add support for a new locale to collation matching rules, add its name as key and the corresponding oid as
+     * value.
+     */
+    private static final Map<String, String> LOCALE_NAMES_TO_OIDS = new HashMap<String, String>();
+
+    static {
+        LOCALE_NAMES_TO_OIDS.put("af", "1.3.6.1.4.1.42.2.27.9.4.1.1");
+        LOCALE_NAMES_TO_OIDS.put("am", "1.3.6.1.4.1.42.2.27.9.4.2.1");
+        LOCALE_NAMES_TO_OIDS.put("ar", "1.3.6.1.4.1.42.2.27.9.4.3.1");
+        LOCALE_NAMES_TO_OIDS.put("ar-AE", "1.3.6.1.4.1.42.2.27.9.4.4.1");
+        LOCALE_NAMES_TO_OIDS.put("ar-BH", "1.3.6.1.4.1.42.2.27.9.4.5.1");
+        LOCALE_NAMES_TO_OIDS.put("ar-DZ", "1.3.6.1.4.1.42.2.27.9.4.6.1");
+        LOCALE_NAMES_TO_OIDS.put("ar-EG", "1.3.6.1.4.1.42.2.27.9.4.7.1");
+        LOCALE_NAMES_TO_OIDS.put("ar-IN", "1.3.6.1.4.1.42.2.27.9.4.8.1");
+        LOCALE_NAMES_TO_OIDS.put("ar-IQ", "1.3.6.1.4.1.42.2.27.9.4.9.1");
+        LOCALE_NAMES_TO_OIDS.put("ar-JO", "1.3.6.1.4.1.42.2.27.9.4.10.1");
+        LOCALE_NAMES_TO_OIDS.put("ar-KW", "1.3.6.1.4.1.42.2.27.9.4.11.1");
+        LOCALE_NAMES_TO_OIDS.put("ar-LB", "1.3.6.1.4.1.42.2.27.9.4.12.1");
+        LOCALE_NAMES_TO_OIDS.put("ar-LY", "1.3.6.1.4.1.42.2.27.9.4.13.1");
+        LOCALE_NAMES_TO_OIDS.put("ar-MA", "1.3.6.1.4.1.42.2.27.9.4.14.1");
+        LOCALE_NAMES_TO_OIDS.put("ar-OM", "1.3.6.1.4.1.42.2.27.9.4.15.1");
+        LOCALE_NAMES_TO_OIDS.put("ar-QA", "1.3.6.1.4.1.42.2.27.9.4.16.1");
+        LOCALE_NAMES_TO_OIDS.put("ar-SA", "1.3.6.1.4.1.42.2.27.9.4.17.1");
+        LOCALE_NAMES_TO_OIDS.put("ar-SD", "1.3.6.1.4.1.42.2.27.9.4.18.1");
+        LOCALE_NAMES_TO_OIDS.put("ar-SY", "1.3.6.1.4.1.42.2.27.9.4.19.1");
+        LOCALE_NAMES_TO_OIDS.put("ar-TN", "1.3.6.1.4.1.42.2.27.9.4.20.1");
+        LOCALE_NAMES_TO_OIDS.put("ar-YE", "1.3.6.1.4.1.42.2.27.9.4.21.1");
+        LOCALE_NAMES_TO_OIDS.put("be", "1.3.6.1.4.1.42.2.27.9.4.22.1");
+        LOCALE_NAMES_TO_OIDS.put("bg", "1.3.6.1.4.1.42.2.27.9.4.23.1");
+        LOCALE_NAMES_TO_OIDS.put("bn", "1.3.6.1.4.1.42.2.27.9.4.24.1");
+        LOCALE_NAMES_TO_OIDS.put("ca", "1.3.6.1.4.1.42.2.27.9.4.25.1");
+        LOCALE_NAMES_TO_OIDS.put("cs", "1.3.6.1.4.1.42.2.27.9.4.26.1");
+        LOCALE_NAMES_TO_OIDS.put("da", "1.3.6.1.4.1.42.2.27.9.4.27.1");
+        LOCALE_NAMES_TO_OIDS.put("de", "1.3.6.1.4.1.42.2.27.9.4.28.1");
+        LOCALE_NAMES_TO_OIDS.put("de-DE", "1.3.6.1.4.1.42.2.27.9.4.28.1");
+        LOCALE_NAMES_TO_OIDS.put("de-AT", "1.3.6.1.4.1.42.2.27.9.4.29.1");
+        LOCALE_NAMES_TO_OIDS.put("de-BE", "1.3.6.1.4.1.42.2.27.9.4.30.1");
+        LOCALE_NAMES_TO_OIDS.put("de-CH", "1.3.6.1.4.1.42.2.27.9.4.31.1");
+        LOCALE_NAMES_TO_OIDS.put("de-LU", "1.3.6.1.4.1.42.2.27.9.4.32.1");
+        LOCALE_NAMES_TO_OIDS.put("el", "1.3.6.1.4.1.42.2.27.9.4.33.1");
+        LOCALE_NAMES_TO_OIDS.put("en", "1.3.6.1.4.1.42.2.27.9.4.34.1");
+        LOCALE_NAMES_TO_OIDS.put("en-US", "1.3.6.1.4.1.42.2.27.9.4.34.1");
+        LOCALE_NAMES_TO_OIDS.put("en-AU", "1.3.6.1.4.1.42.2.27.9.4.35.1");
+        LOCALE_NAMES_TO_OIDS.put("en-CA", "1.3.6.1.4.1.42.2.27.9.4.36.1");
+        LOCALE_NAMES_TO_OIDS.put("en-GB", "1.3.6.1.4.1.42.2.27.9.4.37.1");
+        LOCALE_NAMES_TO_OIDS.put("en-HK", "1.3.6.1.4.1.42.2.27.9.4.38.1");
+        LOCALE_NAMES_TO_OIDS.put("en-IE", "1.3.6.1.4.1.42.2.27.9.4.39.1");
+        LOCALE_NAMES_TO_OIDS.put("en-IN", "1.3.6.1.4.1.42.2.27.9.4.40.1");
+        LOCALE_NAMES_TO_OIDS.put("en-MT", "1.3.6.1.4.1.42.2.27.9.4.41.1");
+        LOCALE_NAMES_TO_OIDS.put("en-NZ", "1.3.6.1.4.1.42.2.27.9.4.42.1");
+        LOCALE_NAMES_TO_OIDS.put("en-PH", "1.3.6.1.4.1.42.2.27.9.4.43.1");
+        LOCALE_NAMES_TO_OIDS.put("en-SG", "1.3.6.1.4.1.42.2.27.9.4.44.1");
+        LOCALE_NAMES_TO_OIDS.put("en-VI", "1.3.6.1.4.1.42.2.27.9.4.45.1");
+        LOCALE_NAMES_TO_OIDS.put("en-ZA", "1.3.6.1.4.1.42.2.27.9.4.46.1");
+        LOCALE_NAMES_TO_OIDS.put("en-ZW", "1.3.6.1.4.1.42.2.27.9.4.47.1");
+        LOCALE_NAMES_TO_OIDS.put("eo", "1.3.6.1.4.1.42.2.27.9.4.48.1");
+        LOCALE_NAMES_TO_OIDS.put("es", "1.3.6.1.4.1.42.2.27.9.4.49.1");
+        LOCALE_NAMES_TO_OIDS.put("es-ES", "1.3.6.1.4.1.42.2.27.9.4.49.1");
+        LOCALE_NAMES_TO_OIDS.put("es-AR", "1.3.6.1.4.1.42.2.27.9.4.50.1");
+        LOCALE_NAMES_TO_OIDS.put("es-BO", "1.3.6.1.4.1.42.2.27.9.4.51.1");
+        LOCALE_NAMES_TO_OIDS.put("es-CL", "1.3.6.1.4.1.42.2.27.9.4.52.1");
+        LOCALE_NAMES_TO_OIDS.put("es-CO", "1.3.6.1.4.1.42.2.27.9.4.53.1");
+        LOCALE_NAMES_TO_OIDS.put("es-CR", "1.3.6.1.4.1.42.2.27.9.4.54.1");
+        LOCALE_NAMES_TO_OIDS.put("es-DO", "1.3.6.1.4.1.42.2.27.9.4.55.1");
+        LOCALE_NAMES_TO_OIDS.put("es-EC", "1.3.6.1.4.1.42.2.27.9.4.56.1");
+        LOCALE_NAMES_TO_OIDS.put("es-GT", "1.3.6.1.4.1.42.2.27.9.4.57.1");
+        LOCALE_NAMES_TO_OIDS.put("es-HN", "1.3.6.1.4.1.42.2.27.9.4.58.1");
+        LOCALE_NAMES_TO_OIDS.put("es-MX", "1.3.6.1.4.1.42.2.27.9.4.59.1");
+        LOCALE_NAMES_TO_OIDS.put("es-NI", "1.3.6.1.4.1.42.2.27.9.4.60.1");
+        LOCALE_NAMES_TO_OIDS.put("es-PA", "1.3.6.1.4.1.42.2.27.9.4.61.1");
+        LOCALE_NAMES_TO_OIDS.put("es-PE", "1.3.6.1.4.1.42.2.27.9.4.62.1");
+        LOCALE_NAMES_TO_OIDS.put("es-PR", "1.3.6.1.4.1.42.2.27.9.4.63.1");
+        LOCALE_NAMES_TO_OIDS.put("es-PY", "1.3.6.1.4.1.42.2.27.9.4.64.1");
+        LOCALE_NAMES_TO_OIDS.put("es-SV", "1.3.6.1.4.1.42.2.27.9.4.65.1");
+        LOCALE_NAMES_TO_OIDS.put("es-US", "1.3.6.1.4.1.42.2.27.9.4.66.1");
+        LOCALE_NAMES_TO_OIDS.put("es-UY", "1.3.6.1.4.1.42.2.27.9.4.67.1");
+        LOCALE_NAMES_TO_OIDS.put("es-VE", "1.3.6.1.4.1.42.2.27.9.4.68.1");
+        LOCALE_NAMES_TO_OIDS.put("et", "1.3.6.1.4.1.42.2.27.9.4.69.1");
+        LOCALE_NAMES_TO_OIDS.put("eu", "1.3.6.1.4.1.42.2.27.9.4.70.1");
+        LOCALE_NAMES_TO_OIDS.put("fa", "1.3.6.1.4.1.42.2.27.9.4.71.1");
+        LOCALE_NAMES_TO_OIDS.put("fa-IN", "1.3.6.1.4.1.42.2.27.9.4.72.1");
+        LOCALE_NAMES_TO_OIDS.put("fa-IR", "1.3.6.1.4.1.42.2.27.9.4.73.1");
+        LOCALE_NAMES_TO_OIDS.put("fi", "1.3.6.1.4.1.42.2.27.9.4.74.1");
+        LOCALE_NAMES_TO_OIDS.put("fo", "1.3.6.1.4.1.42.2.27.9.4.75.1");
+        LOCALE_NAMES_TO_OIDS.put("fr", "1.3.6.1.4.1.42.2.27.9.4.76.1");
+        LOCALE_NAMES_TO_OIDS.put("fr-FR", "1.3.6.1.4.1.42.2.27.9.4.76.1");
+        LOCALE_NAMES_TO_OIDS.put("fr-BE", "1.3.6.1.4.1.42.2.27.9.4.77.1");
+        LOCALE_NAMES_TO_OIDS.put("fr-CA", "1.3.6.1.4.1.42.2.27.9.4.78.1");
+        LOCALE_NAMES_TO_OIDS.put("fr-CH", "1.3.6.1.4.1.42.2.27.9.4.79.1");
+        LOCALE_NAMES_TO_OIDS.put("fr-LU", "1.3.6.1.4.1.42.2.27.9.4.80.1");
+        LOCALE_NAMES_TO_OIDS.put("ga", "1.3.6.1.4.1.42.2.27.9.4.81.1");
+        LOCALE_NAMES_TO_OIDS.put("gl", "1.3.6.1.4.1.42.2.27.9.4.82.1");
+        LOCALE_NAMES_TO_OIDS.put("gu", "1.3.6.1.4.1.42.2.27.9.4.83.1");
+        LOCALE_NAMES_TO_OIDS.put("gv", "1.3.6.1.4.1.42.2.27.9.4.84.1");
+        LOCALE_NAMES_TO_OIDS.put("he", "1.3.6.1.4.1.42.2.27.9.4.85.1");
+        LOCALE_NAMES_TO_OIDS.put("hi", "1.3.6.1.4.1.42.2.27.9.4.86.1");
+        LOCALE_NAMES_TO_OIDS.put("hr", "1.3.6.1.4.1.42.2.27.9.4.87.1");
+        LOCALE_NAMES_TO_OIDS.put("hu", "1.3.6.1.4.1.42.2.27.9.4.88.1");
+        LOCALE_NAMES_TO_OIDS.put("hy", "1.3.6.1.4.1.42.2.27.9.4.89.1");
+        LOCALE_NAMES_TO_OIDS.put("id", "1.3.6.1.4.1.42.2.27.9.4.90.1");
+        LOCALE_NAMES_TO_OIDS.put("is", "1.3.6.1.4.1.42.2.27.9.4.91.1");
+        LOCALE_NAMES_TO_OIDS.put("it", "1.3.6.1.4.1.42.2.27.9.4.92.1");
+        LOCALE_NAMES_TO_OIDS.put("it-CH", "1.3.6.1.4.1.42.2.27.9.4.93.1");
+        LOCALE_NAMES_TO_OIDS.put("ja", "1.3.6.1.4.1.42.2.27.9.4.94.1");
+        LOCALE_NAMES_TO_OIDS.put("kl", "1.3.6.1.4.1.42.2.27.9.4.95.1");
+        LOCALE_NAMES_TO_OIDS.put("kn", "1.3.6.1.4.1.42.2.27.9.4.96.1");
+        LOCALE_NAMES_TO_OIDS.put("ko", "1.3.6.1.4.1.42.2.27.9.4.97.1");
+        LOCALE_NAMES_TO_OIDS.put("kok", "1.3.6.1.4.1.42.2.27.9.4.98.1");
+        LOCALE_NAMES_TO_OIDS.put("kw", "1.3.6.1.4.1.42.2.27.9.4.99.1");
+        LOCALE_NAMES_TO_OIDS.put("lt", "1.3.6.1.4.1.42.2.27.9.4.100.1");
+        LOCALE_NAMES_TO_OIDS.put("lv", "1.3.6.1.4.1.42.2.27.9.4.101.1");
+        LOCALE_NAMES_TO_OIDS.put("mk", "1.3.6.1.4.1.42.2.27.9.4.102.1");
+        LOCALE_NAMES_TO_OIDS.put("mr", "1.3.6.1.4.1.42.2.27.9.4.103.1");
+        LOCALE_NAMES_TO_OIDS.put("mt", "1.3.6.1.4.1.42.2.27.9.4.104.1");
+        LOCALE_NAMES_TO_OIDS.put("nl", "1.3.6.1.4.1.42.2.27.9.4.105.1");
+        LOCALE_NAMES_TO_OIDS.put("nl-NL", "1.3.6.1.4.1.42.2.27.9.4.105.1");
+        LOCALE_NAMES_TO_OIDS.put("nl-BE", "1.3.6.1.4.1.42.2.27.9.4.106.1");
+        LOCALE_NAMES_TO_OIDS.put("no", "1.3.6.1.4.1.42.2.27.9.4.107.1");
+        LOCALE_NAMES_TO_OIDS.put("no-NO", "1.3.6.1.4.1.42.2.27.9.4.107.1");
+        LOCALE_NAMES_TO_OIDS.put("no-NO-NY", "1.3.6.1.4.1.42.2.27.9.4.108.1");
+        LOCALE_NAMES_TO_OIDS.put("nn", "1.3.6.1.4.1.42.2.27.9.4.109.1");
+        LOCALE_NAMES_TO_OIDS.put("nb", "1.3.6.1.4.1.42.2.27.9.4.110.1");
+        LOCALE_NAMES_TO_OIDS.put("no-NO-B", "1.3.6.1.4.1.42.2.27.9.4.110.1");
+        LOCALE_NAMES_TO_OIDS.put("om", "1.3.6.1.4.1.42.2.27.9.4.111.1");
+        LOCALE_NAMES_TO_OIDS.put("om-ET", "1.3.6.1.4.1.42.2.27.9.4.112.1");
+        LOCALE_NAMES_TO_OIDS.put("om-KE", "1.3.6.1.4.1.42.2.27.9.4.113.1");
+        LOCALE_NAMES_TO_OIDS.put("pl", "1.3.6.1.4.1.42.2.27.9.4.114.1");
+        LOCALE_NAMES_TO_OIDS.put("pt", "1.3.6.1.4.1.42.2.27.9.4.115.1");
+        LOCALE_NAMES_TO_OIDS.put("pt-PT", "1.3.6.1.4.1.42.2.27.9.4.115.1");
+        LOCALE_NAMES_TO_OIDS.put("pt-BR", "1.3.6.1.4.1.42.2.27.9.4.116.1");
+        LOCALE_NAMES_TO_OIDS.put("ro", "1.3.6.1.4.1.42.2.27.9.4.117.1");
+        LOCALE_NAMES_TO_OIDS.put("ru", "1.3.6.1.4.1.42.2.27.9.4.118.1");
+        LOCALE_NAMES_TO_OIDS.put("ru-RU", "1.3.6.1.4.1.42.2.27.9.4.118.1");
+        LOCALE_NAMES_TO_OIDS.put("ru-UA", "1.3.6.1.4.1.42.2.27.9.4.119.1");
+        LOCALE_NAMES_TO_OIDS.put("sh", "1.3.6.1.4.1.42.2.27.9.4.120.1");
+        LOCALE_NAMES_TO_OIDS.put("sk", "1.3.6.1.4.1.42.2.27.9.4.121.1");
+        LOCALE_NAMES_TO_OIDS.put("sl", "1.3.6.1.4.1.42.2.27.9.4.122.1");
+        LOCALE_NAMES_TO_OIDS.put("so", "1.3.6.1.4.1.42.2.27.9.4.123.1");
+        LOCALE_NAMES_TO_OIDS.put("so-SO", "1.3.6.1.4.1.42.2.27.9.4.123.1");
+        LOCALE_NAMES_TO_OIDS.put("so-DJ", "1.3.6.1.4.1.42.2.27.9.4.124.1");
+        LOCALE_NAMES_TO_OIDS.put("so-ET", "1.3.6.1.4.1.42.2.27.9.4.125.1");
+        LOCALE_NAMES_TO_OIDS.put("so-KE", "1.3.6.1.4.1.42.2.27.9.4.126.1");
+        LOCALE_NAMES_TO_OIDS.put("sq", "1.3.6.1.4.1.42.2.27.9.4.127.1");
+        LOCALE_NAMES_TO_OIDS.put("sr", "1.3.6.1.4.1.42.2.27.9.4.128.1");
+        LOCALE_NAMES_TO_OIDS.put("sv", "1.3.6.1.4.1.42.2.27.9.4.129.1");
+        LOCALE_NAMES_TO_OIDS.put("sv-SE", "1.3.6.1.4.1.42.2.27.9.4.129.1");
+        LOCALE_NAMES_TO_OIDS.put("sv-FI", "1.3.6.1.4.1.42.2.27.9.4.130.1");
+        LOCALE_NAMES_TO_OIDS.put("sw", "1.3.6.1.4.1.42.2.27.9.4.131.1");
+        LOCALE_NAMES_TO_OIDS.put("sw-KE", "1.3.6.1.4.1.42.2.27.9.4.132.1");
+        LOCALE_NAMES_TO_OIDS.put("sw-TZ", "1.3.6.1.4.1.42.2.27.9.4.133.1");
+        LOCALE_NAMES_TO_OIDS.put("ta", "1 3  1.3.6.1.4.1.42.2.27.9.4.134.1");
+        LOCALE_NAMES_TO_OIDS.put("te", "1.3.6.1.4.1.42.2.27.9.4.135.1");
+        LOCALE_NAMES_TO_OIDS.put("th", "1.3.6.1.4.1.42.2.27.9.4.136.1");
+        LOCALE_NAMES_TO_OIDS.put("ti", "1.3.6.1.4.1.42.2.27.9.4.137.1");
+        LOCALE_NAMES_TO_OIDS.put("ti-ER", "1.3.6.1.4.1.42.2.27.9.4.138.1");
+        LOCALE_NAMES_TO_OIDS.put("ti-ET", "1.3.6.1.4.1.42.2.27.9.4.139.1");
+        LOCALE_NAMES_TO_OIDS.put("tr", "1.3.6.1.4.1.42.2.27.9.4.140.1");
+        LOCALE_NAMES_TO_OIDS.put("uk", "1.3.6.1.4.1.42.2.27.9.4.141.1");
+        LOCALE_NAMES_TO_OIDS.put("vi", "1.3.6.1.4.1.42.2.27.9.4.142.1");
+        LOCALE_NAMES_TO_OIDS.put("zh", "1.3.6.1.4.1.42.2.27.9.4.143.1");
+        LOCALE_NAMES_TO_OIDS.put("zh-CN", "1.3.6.1.4.1.42.2.27.9.4.144.1");
+        LOCALE_NAMES_TO_OIDS.put("zh-HK", "1.3.6.1.4.1.42.2.27.9.4.145.1");
+        LOCALE_NAMES_TO_OIDS.put("zh-MO", "1.3.6.1.4.1.42.2.27.9.4.146.1");
+        LOCALE_NAMES_TO_OIDS.put("zh-SG", "1.3.6.1.4.1.42.2.27.9.4.147.1");
+        LOCALE_NAMES_TO_OIDS.put("zh-TW", "1.3.6.1.4.1.42.2.27.9.4.148.1");
+    }
+
     static {
         final SchemaBuilder builder = new SchemaBuilder("Core Schema");
         defaultSyntaxes(builder);
@@ -700,6 +875,112 @@
                 .description(MR_PARTIAL_DATE_AND_TIME_DESCRIPTION).syntaxOID(SYNTAX_GENERALIZED_TIME_OID)
                 .extraProperties(OPENDJ_ORIGIN).implementation(partialDateAndTimeMatchingRule())
                 .addToSchema();
+        addCollationMatchingRules(builder);
+    }
+
+    /**
+     * Adds the collation matching rules.
+     * <p>
+     * A set of collation matching rules is registered for each locale that is both available in the java runtime
+     * environment and has an oid defined in the {@code LOCALE_NAMES_TO_OIDS} map. Note that the same oid can be used
+     * for multiple locales (e.g., matching rule for "en" and "en-US" uses the same oid).
+     * <p>
+     * To add support for a new locale, add a corresponding entry in the {@code LOCALE_NAMES_TO_OIDS} map.
+     */
+    private static void addCollationMatchingRules(final SchemaBuilder builder) {
+        // Build an intermediate map to ensure each locale name appears only once
+        final Map<String, Locale> localesCache = new HashMap<String, Locale>();
+        for (Locale locale : Locale.getAvailableLocales()) {
+            localesCache.put(localeName(locale), locale);
+        }
+        // Build a intermediate map to list all available oids with their locale names
+        // An oid can be associated to multiple locale names
+        final Map<String, List<String>> oidsCache = new HashMap<String, List<String>>();
+        for (final String localeName: localesCache.keySet()) {
+            String oid = LOCALE_NAMES_TO_OIDS.get(localeName);
+            if (oid != null) {
+                List<String> names = oidsCache.get(oid);
+                if (names == null) {
+                    names = new ArrayList<String>(5);
+                    oidsCache.put(oid, names);
+                }
+                names.add(localeName);
+            }
+        }
+
+        // Now build the matching rules from all available oids
+        for (final Entry<String, List<String>> entry : oidsCache.entrySet()) {
+            final String oid = entry.getKey();
+            final List<String> names = entry.getValue();
+            // take locale from first name - all locales of names are considered equivalent here
+            final Locale locale = localesCache.get(names.get(0));
+            addCollationMatchingRule(builder, oid, names, 1, "lt", collationLessThanMatchingRule(locale));
+            addCollationMatchingRule(builder, oid, names, 2, "lte", collationLessThanOrEqualMatchingRule(locale));
+            addCollationMatchingRule(builder, oid, names, 3, "eq", collationEqualityMatchingRule(locale));
+            addCollationMatchingRule(builder, oid, names, 4, "gte", collationGreaterThanOrEqualToMatchingRule(locale));
+            addCollationMatchingRule(builder, oid, names, 5, "gt", collationGreaterThanMatchingRule(locale));
+            addCollationMatchingRule(builder, oid, names, 6, "sub", collationSubstringMatchingRule(locale));
+        }
+    }
+
+    /** Add a specific collation matching rule to the schema. */
+    private static void addCollationMatchingRule(final SchemaBuilder builder, final String baseOid,
+            final List<String> names, final int numericSuffix, final String symbolicSuffix,
+            final MatchingRuleImpl matchingRuleImplementation) {
+        builder.buildMatchingRule(baseOid + "." + numericSuffix)
+            .names(collationMatchingRuleNames(names, numericSuffix, symbolicSuffix))
+            .syntaxOID(SYNTAX_DIRECTORY_STRING_OID)
+            .extraProperties(OPENDJ_ORIGIN)
+            .implementation(matchingRuleImplementation)
+            .addToSchema();
+    }
+
+    /**
+     * Build the complete list of names for a collation matching rule.
+     *
+     * @param localeNames
+     *            List of locale names that correspond to the matching rule (e.g., "en", "en-US")
+     * @param numSuffix
+     *            numeric suffix corresponding to type of matching rule (e.g, 5 for greater than matching rule)
+     * @param symbolicSuffix
+     *            symbolic suffix corresponding to type of matching rule (e.g, "gt" for greater than matching rule)
+     * @return the names list (e.g, "en.5", "en.gt", "en-US.5", "en-US.gt")
+     */
+    private static String[] collationMatchingRuleNames(final List<String> localeNames, final int numSuffix,
+            final String symbolicSuffix) {
+        final List<String> names = new ArrayList<String>();
+        for (String localeName : localeNames) {
+            names.add(localeName + "." + numSuffix);
+            names.add(localeName + "." + symbolicSuffix);
+        }
+        return names.toArray(new String[names.size()]);
+    }
+
+    /**
+     * Returns the name corresponding to the provided locale.
+     * <p>
+     * The name is using format:
+     * <pre>
+     *   language code (lower case) + "-" + country code (upper case) + "-" + variant (upper case)
+     * </pre>
+     * Country code and variant are optional, they may not appear.
+     * See LOCALE_NAMES_TO_OIDS keys for examples of names
+     *
+     * @param locale
+     *          The locale
+     * @return the name associated to the locale
+     */
+    private static String localeName(final Locale locale) {
+        final StringBuilder name = new StringBuilder(locale.getLanguage());
+        final String country = locale.getCountry();
+        if (!country.isEmpty()) {
+            name.append('-').append(country);
+        }
+        final String variant = locale.getVariant();
+        if (!variant.isEmpty()) {
+            name.append('-').append(variant.toUpperCase());
+        }
+        return name.toString();
     }
 
     private static void defaultAttributeTypes(final SchemaBuilder builder) {
diff --git a/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CollationEqualityMatchingRuleTest.java b/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CollationEqualityMatchingRuleTest.java
index a5c0659..4587d38 100644
--- a/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CollationEqualityMatchingRuleTest.java
+++ b/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CollationEqualityMatchingRuleTest.java
@@ -25,8 +25,6 @@
  */
 package org.forgerock.opendj.ldap.schema;
 
-import java.util.Locale;
-
 import org.forgerock.opendj.ldap.Assertion;
 import org.forgerock.opendj.ldap.ByteString;
 import org.forgerock.opendj.ldap.ConditionResult;
@@ -34,6 +32,7 @@
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
 
+import static org.fest.assertions.Assertions.*;
 import static org.forgerock.opendj.ldap.schema.AbstractSubstringMatchingRuleImplTest.*;
 import static org.testng.Assert.*;
 
@@ -86,17 +85,21 @@
     /** {@inheritDoc} */
     @Override
     protected MatchingRule getRule() {
-        // Note that oid and names are not used by the test (ie, they could be any value, test should pass anyway)
-        // Only the implementation class and the provided locale are really tested here.
-        String oid = "1.3.6.1.4.1.42.2.27.9.4.76.1.3";
-        Schema schema = new SchemaBuilder(Schema.getCoreSchema()).
-            buildMatchingRule(oid).
-                syntaxOID(SchemaConstants.SYNTAX_DIRECTORY_STRING_OID).
-                names("fr.eq").
-                implementation(CollationMatchingRulesImpl.equalityMatchingRule(new Locale("fr"))).
-                addToSchema().
-            toSchema();
-        return schema.getMatchingRule(oid);
+        return Schema.getCoreSchema().getMatchingRule("fr.eq");
+    }
+
+    @Test
+    public void testMatchingRuleNames() throws Exception {
+        // 'fr' and 'fr-FR' share the same oid (they are aliases)
+        MatchingRule rule = Schema.getCoreSchema().getMatchingRule("fr.eq");
+        assertThat(rule.getNames()).containsOnly("fr.eq", "fr.3", "fr-FR.eq", "fr-FR.3");
+
+        MatchingRule rule2 = Schema.getCoreSchema().getMatchingRule("fr-FR.eq");
+        assertThat(rule2.getNames()).containsOnly("fr.eq", "fr.3", "fr-FR.eq", "fr-FR.3");
+
+        // 'ar' does not share oid with another locale
+        MatchingRule rule3 = Schema.getCoreSchema().getMatchingRule("ar.3");
+        assertThat(rule3.getNames()).containsOnly("ar.eq", "ar.3");
     }
 
     @Test
diff --git a/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CollationGreaterThanMatchingRuleTest.java b/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CollationGreaterThanMatchingRuleTest.java
index 42c2554..85658f6 100644
--- a/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CollationGreaterThanMatchingRuleTest.java
+++ b/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CollationGreaterThanMatchingRuleTest.java
@@ -25,8 +25,6 @@
  */
 package org.forgerock.opendj.ldap.schema;
 
-import java.util.Locale;
-
 import org.forgerock.opendj.ldap.Assertion;
 import org.forgerock.opendj.ldap.ByteString;
 import org.forgerock.opendj.ldap.ConditionResult;
@@ -86,17 +84,7 @@
     /** {@inheritDoc} */
     @Override
     protected MatchingRule getRule() {
-        // Note that oid and names are not used by the test (ie, they could be any value, test should pass anyway)
-        // Only the implementation class and the provided locale are really tested here.
-        String oid = "1.3.6.1.4.1.42.2.27.9.4.76.1.5";
-        Schema schema = new SchemaBuilder(Schema.getCoreSchema()).
-            buildMatchingRule(oid).
-                syntaxOID(SchemaConstants.SYNTAX_DIRECTORY_STRING_OID).
-                names("fr.gt").
-                implementation(CollationMatchingRulesImpl.greaterThanMatchingRule(new Locale("fr"))).
-                addToSchema().
-            toSchema();
-        return schema.getMatchingRule(oid);
+        return Schema.getCoreSchema().getMatchingRule("fr.gt");
     }
 
     @Test
diff --git a/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CollationGreaterThanOrEqualMatchingRuleTest.java b/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CollationGreaterThanOrEqualMatchingRuleTest.java
index 0b345d5..1df1fac 100644
--- a/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CollationGreaterThanOrEqualMatchingRuleTest.java
+++ b/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CollationGreaterThanOrEqualMatchingRuleTest.java
@@ -25,8 +25,6 @@
  */
 package org.forgerock.opendj.ldap.schema;
 
-import java.util.Locale;
-
 import org.forgerock.opendj.ldap.Assertion;
 import org.forgerock.opendj.ldap.ByteString;
 import org.forgerock.opendj.ldap.ConditionResult;
@@ -86,17 +84,8 @@
     /** {@inheritDoc} */
     @Override
     protected MatchingRule getRule() {
-        // Note that oid and names are not used by the test (ie, they could be any value, test should pass anyway)
-        // Only the implementation class and the provided locale are really tested here.
-        String oid = "1.3.6.1.4.1.42.2.27.9.4.76.1.4";
-        Schema schema = new SchemaBuilder(Schema.getCoreSchema()).
-            buildMatchingRule(oid).
-                syntaxOID(SchemaConstants.SYNTAX_DIRECTORY_STRING_OID).
-                names("fr.gt2").
-                implementation(CollationMatchingRulesImpl.greaterThanOrEqualToMatchingRule(new Locale("fr"))).
-                addToSchema().
-            toSchema();
-        return schema.getMatchingRule(oid);
+        return Schema.getCoreSchema().getMatchingRule("fr.gte");
+
     }
 
     @Test
diff --git a/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CollationLessThanMatchingRuleTest.java b/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CollationLessThanMatchingRuleTest.java
index eda0ccf..e3fee52 100644
--- a/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CollationLessThanMatchingRuleTest.java
+++ b/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CollationLessThanMatchingRuleTest.java
@@ -25,8 +25,6 @@
  */
 package org.forgerock.opendj.ldap.schema;
 
-import java.util.Locale;
-
 import org.forgerock.opendj.ldap.Assertion;
 import org.forgerock.opendj.ldap.ByteString;
 import org.forgerock.opendj.ldap.ConditionResult;
@@ -86,17 +84,7 @@
     /** {@inheritDoc} */
     @Override
     protected MatchingRule getRule() {
-        // Note that oid and names are not used by the test (ie, they could be any value, test should pass anyway)
-        // Only the implementation class and the provided locale are really tested here.
-        String oid = "1.3.6.1.4.1.42.2.27.9.4.76.1.1";
-        Schema schema = new SchemaBuilder(Schema.getCoreSchema()).
-            buildMatchingRule(oid).
-                syntaxOID(SchemaConstants.SYNTAX_DIRECTORY_STRING_OID).
-                names("fr.lt").
-                implementation(CollationMatchingRulesImpl.lessThanMatchingRule(new Locale("fr"))).
-                addToSchema().
-            toSchema();
-        return schema.getMatchingRule(oid);
+        return Schema.getCoreSchema().getMatchingRule("fr.lt");
     }
 
     @Test
diff --git a/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CollationLessThanOrEqualMatchingRuleTest.java b/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CollationLessThanOrEqualMatchingRuleTest.java
index 1e36a5b..87c667a 100644
--- a/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CollationLessThanOrEqualMatchingRuleTest.java
+++ b/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CollationLessThanOrEqualMatchingRuleTest.java
@@ -25,8 +25,6 @@
  */
 package org.forgerock.opendj.ldap.schema;
 
-import java.util.Locale;
-
 import org.forgerock.opendj.ldap.Assertion;
 import org.forgerock.opendj.ldap.ByteString;
 import org.forgerock.opendj.ldap.ConditionResult;
@@ -86,17 +84,7 @@
     /** {@inheritDoc} */
     @Override
     protected MatchingRule getRule() {
-        // Note that oid and names are not used by the test (ie, they could be any value, test should pass anyway)
-        // Only the implementation class and the provided locale are really tested here.
-        String oid = "1.3.6.1.4.1.42.2.27.9.4.76.1.2";
-        Schema schema = new SchemaBuilder(Schema.getCoreSchema()).
-            buildMatchingRule(oid).
-                syntaxOID(SchemaConstants.SYNTAX_DIRECTORY_STRING_OID).
-                names("fr.lte").
-                implementation(CollationMatchingRulesImpl.lessThanOrEqualMatchingRule(new Locale("fr"))).
-                addToSchema().
-            toSchema();
-        return schema.getMatchingRule(oid);
+        return Schema.getCoreSchema().getMatchingRule("fr.lte");
     }
 
     @Test
diff --git a/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CollationSubstringMatchingRuleTest.java b/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CollationSubstringMatchingRuleTest.java
index 585c40f..e389e44 100644
--- a/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CollationSubstringMatchingRuleTest.java
+++ b/opendj-core/src/test/java/org/forgerock/opendj/ldap/schema/CollationSubstringMatchingRuleTest.java
@@ -25,8 +25,6 @@
  */
 package org.forgerock.opendj.ldap.schema;
 
-import java.util.Locale;
-
 import org.forgerock.opendj.ldap.Assertion;
 import org.forgerock.opendj.ldap.ByteString;
 import org.forgerock.opendj.ldap.ConditionResult;
@@ -146,17 +144,7 @@
     /** {@inheritDoc} */
     @Override
     protected MatchingRule getRule() {
-        // Note that oid and names are not used by the test (ie, they could be any value, test should pass anyway)
-        // Only the implementation class and the provided locale are really tested here.
-        String oid = "1.3.6.1.4.1.42.2.27.9.4.76.1.6";
-        Schema schema = new SchemaBuilder(Schema.getCoreSchema()).
-            buildMatchingRule(oid).
-                syntaxOID(SchemaConstants.SYNTAX_DIRECTORY_STRING_OID).
-                names("fr.sub").
-                implementation(CollationMatchingRulesImpl.substringMatchingRule(new Locale("fr"))).
-                addToSchema().
-            toSchema();
-        return schema.getMatchingRule(oid);
+        return Schema.getCoreSchema().getMatchingRule("fr.sub");
     }
 
     @Test

--
Gitblit v1.10.0