]> gitweb.fperrin.net Git - Dictionary.git/blobdiff - jars/icu4j-52_1/main/classes/core/src/com/ibm/icu/impl/PluralRulesLoader.java
Upgrade ICU4J.
[Dictionary.git] / jars / icu4j-52_1 / main / classes / core / src / com / ibm / icu / impl / PluralRulesLoader.java
similarity index 58%
rename from jars/icu4j-4_8_1_1/main/classes/core/src/com/ibm/icu/impl/PluralRulesLoader.java
rename to jars/icu4j-52_1/main/classes/core/src/com/ibm/icu/impl/PluralRulesLoader.java
index 51b1e5d3f4744a104a227e330623f2f5c0303a29..24e23875af57213d30e58103b8be1fb8807dfd0c 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *******************************************************************************
- * Copyright (C) 2008-2010, International Business Machines Corporation and    *
+ * Copyright (C) 2008-2013, International Business Machines Corporation and    *
  * others. All Rights Reserved.                                                *
  *******************************************************************************
  */
@@ -16,20 +16,19 @@ import java.util.Set;
 import java.util.TreeMap;
 
 import com.ibm.icu.text.PluralRules;
+import com.ibm.icu.text.PluralRules.PluralType;
 import com.ibm.icu.util.ULocale;
 import com.ibm.icu.util.UResourceBundle;
 
 /**
  * Loader for plural rules data.
  */
-public class PluralRulesLoader {
+public class PluralRulesLoader extends PluralRules.Factory {
     private final Map<String, PluralRules> rulesIdToRules;
-    private Map<String, String> localeIdToRulesId; // lazy init, use
-                                                   // getLocaleIdToRulesIdMap to
-                                                   // access
-    private Map<String, ULocale> rulesIdToEquivalentULocale; // lazy init, use
-                                                             // getRulesIdToEquivalentULocaleMap
-                                                             // to access
+    // lazy init, use getLocaleIdToRulesIdMap to access
+    private Map<String, String> localeIdToCardinalRulesId;
+    private Map<String, String> localeIdToOrdinalRulesId;
+    private Map<String, ULocale> rulesIdToEquivalentULocale;
 
     /**
      * Access through singleton.
@@ -42,7 +41,7 @@ public class PluralRulesLoader {
      * Returns the locales for which we have plurals data. Utility for testing.
      */
     public ULocale[] getAvailableULocales() {
-        Set<String> keys = getLocaleIdToRulesIdMap().keySet();
+        Set<String> keys = getLocaleIdToRulesIdMap(PluralType.CARDINAL).keySet();
         ULocale[] locales = new ULocale[keys.size()];
         int n = 0;
         for (Iterator<String> iter = keys.iterator(); iter.hasNext();) {
@@ -57,11 +56,11 @@ public class PluralRulesLoader {
     public ULocale getFunctionalEquivalent(ULocale locale, boolean[] isAvailable) {
         if (isAvailable != null && isAvailable.length > 0) {
             String localeId = ULocale.canonicalize(locale.getBaseName());
-            Map<String, String> idMap = getLocaleIdToRulesIdMap();
+            Map<String, String> idMap = getLocaleIdToRulesIdMap(PluralType.CARDINAL);
             isAvailable[0] = idMap.containsKey(localeId);
         }
 
-        String rulesId = getRulesIdForLocale(locale);
+        String rulesId = getRulesIdForLocale(locale, PluralType.CARDINAL);
         if (rulesId == null || rulesId.trim().length() == 0) {
             return ULocale.ROOT; // ultimate fallback
         }
@@ -78,9 +77,9 @@ public class PluralRulesLoader {
     /**
      * Returns the lazily-constructed map.
      */
-    private Map<String, String> getLocaleIdToRulesIdMap() {
+    private Map<String, String> getLocaleIdToRulesIdMap(PluralType type) {
         checkBuildRulesIdMaps();
-        return localeIdToRulesId;
+        return (type == PluralType.CARDINAL) ? localeIdToCardinalRulesId : localeIdToOrdinalRulesId;
     }
 
     /**
@@ -97,31 +96,57 @@ public class PluralRulesLoader {
      * resource in plurals.res.
      */
     private void checkBuildRulesIdMaps() {
-        if (localeIdToRulesId == null) {
+        boolean haveMap;
+        synchronized (this) {
+            haveMap = localeIdToCardinalRulesId != null;
+        }
+        if (!haveMap) {
+            Map<String, String> tempLocaleIdToCardinalRulesId;
+            Map<String, String> tempLocaleIdToOrdinalRulesId;
+            Map<String, ULocale> tempRulesIdToEquivalentULocale;
             try {
                 UResourceBundle pluralb = getPluralBundle();
+                // Read cardinal-number rules.
                 UResourceBundle localeb = pluralb.get("locales");
-                localeIdToRulesId = new TreeMap<String, String>(); // sort for
-                                                                   // convenience
-                                                                   // of
-                                                                   // getAvailableULocales
-                rulesIdToEquivalentULocale = new HashMap<String, ULocale>(); // not
-                                                                             // visible
+
+                // sort for convenience of getAvailableULocales
+                tempLocaleIdToCardinalRulesId = new TreeMap<String, String>();
+                // not visible
+                tempRulesIdToEquivalentULocale = new HashMap<String, ULocale>();
+
                 for (int i = 0; i < localeb.getSize(); ++i) {
                     UResourceBundle b = localeb.get(i);
                     String id = b.getKey();
                     String value = b.getString().intern();
-                    localeIdToRulesId.put(id, value);
+                    tempLocaleIdToCardinalRulesId.put(id, value);
 
-                    if (!rulesIdToEquivalentULocale.containsKey(value)) {
-                        rulesIdToEquivalentULocale.put(value, new ULocale(id));
+                    if (!tempRulesIdToEquivalentULocale.containsKey(value)) {
+                        tempRulesIdToEquivalentULocale.put(value, new ULocale(id));
                     }
                 }
+
+                // Read ordinal-number rules.
+                localeb = pluralb.get("locales_ordinals");
+                tempLocaleIdToOrdinalRulesId = new TreeMap<String, String>();
+                for (int i = 0; i < localeb.getSize(); ++i) {
+                    UResourceBundle b = localeb.get(i);
+                    String id = b.getKey();
+                    String value = b.getString().intern();
+                    tempLocaleIdToOrdinalRulesId.put(id, value);
+                }
             } catch (MissingResourceException e) {
-                localeIdToRulesId = Collections.emptyMap(); // dummy so we don't
-                                                            // try again, can
-                                                            // read
-                rulesIdToEquivalentULocale = Collections.emptyMap();
+                // dummy so we don't try again
+                tempLocaleIdToCardinalRulesId = Collections.emptyMap();
+                tempLocaleIdToOrdinalRulesId = Collections.emptyMap();
+                tempRulesIdToEquivalentULocale = Collections.emptyMap();
+            }
+            
+            synchronized(this) {
+                if (localeIdToCardinalRulesId == null) {
+                    localeIdToCardinalRulesId = tempLocaleIdToCardinalRulesId;
+                    localeIdToOrdinalRulesId = tempLocaleIdToOrdinalRulesId;
+                    rulesIdToEquivalentULocale = tempRulesIdToEquivalentULocale;
+                }
             }
         }
     }
@@ -131,8 +156,8 @@ public class PluralRulesLoader {
      * rulesId, return null. The rulesId might be the empty string if the rule
      * is the default rule.
      */
-    public String getRulesIdForLocale(ULocale locale) {
-        Map<String, String> idMap = getLocaleIdToRulesIdMap();
+    public String getRulesIdForLocale(ULocale locale, PluralType type) {
+        Map<String, String> idMap = getLocaleIdToRulesIdMap(type);
         String localeId = ULocale.canonicalize(locale.getBaseName());
         String rulesId = null;
         while (null == (rulesId = idMap.get(localeId))) {
@@ -150,8 +175,16 @@ public class PluralRulesLoader {
      * return null.
      */
     public PluralRules getRulesForRulesId(String rulesId) {
-        PluralRules rules = rulesIdToRules.get(rulesId);
-        if (rules == null) {
+        // synchronize on the map.  release the lock temporarily while we build the rules.
+        PluralRules rules = null;
+        boolean hasRules;  // Separate boolean because stored rules can be null.
+        synchronized (rulesIdToRules) {
+            hasRules = rulesIdToRules.containsKey(rulesId);
+            if (hasRules) {
+                rules = rulesIdToRules.get(rulesId);  // can be null
+            }
+        }
+        if (!hasRules) {
             try {
                 UResourceBundle pluralb = getPluralBundle();
                 UResourceBundle rulesb = pluralb.get("rules");
@@ -171,7 +204,13 @@ public class PluralRulesLoader {
             } catch (ParseException e) {
             } catch (MissingResourceException e) {
             }
-            rulesIdToRules.put(rulesId, rules); // put even if null
+            synchronized (rulesIdToRules) {
+                if (rulesIdToRules.containsKey(rulesId)) {
+                    rules = rulesIdToRules.get(rulesId);
+                } else {
+                    rulesIdToRules.put(rulesId, rules);  // can be null
+                }
+            }
         }
         return rules;
     }
@@ -190,8 +229,8 @@ public class PluralRulesLoader {
      * Returns the plural rules for the the locale. If we don't have data,
      * com.ibm.icu.text.PluralRules.DEFAULT is returned.
      */
-    public PluralRules forLocale(ULocale locale) {
-        String rulesId = getRulesIdForLocale(locale);
+    public PluralRules forLocale(ULocale locale, PluralRules.PluralType type) {
+        String rulesId = getRulesIdForLocale(locale, type);
         if (rulesId == null || rulesId.trim().length() == 0) {
             return PluralRules.DEFAULT;
         }
@@ -206,4 +245,12 @@ public class PluralRulesLoader {
      * The only instance of the loader.
      */
     public static final PluralRulesLoader loader = new PluralRulesLoader();
+
+    /* (non-Javadoc)
+     * @see com.ibm.icu.text.PluralRules.Factory#hasOverride(com.ibm.icu.util.ULocale)
+     */
+    @Override
+    public boolean hasOverride(ULocale locale) {
+        return false;
+    }
 }