ICU-6289 Merging another CLDR data update for resolving timezone format problem, Plural format enhancement(#6373) and a fix for Java1.3/Foundation 1.0 environment support in recent DateIntervalFormat change(#6157).
X-SVN-Rev: 24271
diff --git a/src/com/ibm/icu/dev/data/testdata.jar b/src/com/ibm/icu/dev/data/testdata.jar
index ed2ea72..dbab76a 100644
--- a/src/com/ibm/icu/dev/data/testdata.jar
+++ b/src/com/ibm/icu/dev/data/testdata.jar
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:194e372e448817d14bbc5b695cf783a570dafdbcb8cbdcc8658ed9f60ae16d3e
+oid sha256:9b76d1e3bc7e21552bbc2c78b258da2ddd60583f8c8a44735a3faa7957678098
size 764853
diff --git a/src/com/ibm/icu/dev/test/format/DateIntervalFormatTest.java b/src/com/ibm/icu/dev/test/format/DateIntervalFormatTest.java
index 80db513..a707252 100644
--- a/src/com/ibm/icu/dev/test/format/DateIntervalFormatTest.java
+++ b/src/com/ibm/icu/dev/test/format/DateIntervalFormatTest.java
@@ -24,6 +24,7 @@
import com.ibm.icu.util.DateInterval;
import com.ibm.icu.text.DateIntervalInfo;
import com.ibm.icu.text.DateIntervalFormat;
+import com.ibm.icu.util.ULocale;
public class DateIntervalFormatTest extends com.ibm.icu.dev.test.TestFmwk {
@@ -613,7 +614,7 @@
int i = 1;
while (i<data_length) {
String locName = data[i++];
- Locale loc = new Locale(locName);
+ ULocale loc = new ULocale(locName);
SimpleDateFormat ref = new SimpleDateFormat(data[0], loc);
// 'f'
String datestr = data[i++];
@@ -707,7 +708,7 @@
int i = 1;
while (i<data_length) {
String locName = data[i++];
- Locale loc = new Locale(locName);
+ ULocale loc = new ULocale(locName);
SimpleDateFormat ref = new SimpleDateFormat(data[0], loc);
// 'f'
String datestr = data[i++];
@@ -782,7 +783,7 @@
int i = 1;
while (i<data_length) {
String locName = data[i++];
- Locale loc = new Locale(locName);
+ ULocale loc = new ULocale(locName);
SimpleDateFormat ref = new SimpleDateFormat(data[0], loc);
// 'f'
String datestr = data[i++];
diff --git a/src/com/ibm/icu/dev/test/format/PluralFormatTest.java b/src/com/ibm/icu/dev/test/format/PluralFormatTest.java
index a382e12..5a141a9 100644
--- a/src/com/ibm/icu/dev/test/format/PluralFormatTest.java
+++ b/src/com/ibm/icu/dev/test/format/PluralFormatTest.java
@@ -1,6 +1,6 @@
/*
*******************************************************************************
- * Copyright (C) 2007, International Business Machines Corporation and *
+ * Copyright (C) 2007-2008, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
@@ -48,15 +48,19 @@
*/
log("test pattern: '" + testPattern + "'");
for (int i = 0; i < locales.length; ++i) {
- PluralFormat plf = new PluralFormat(new ULocale(locales[i]), testPattern);
- log("plf: " + plf);
- String expected = (String) changes.get(new Integer(0));
- for (int n = 0; n < 200; ++n) {
- if (changes.get(new Integer(n)) != null) {
- expected = (String) changes.get(new Integer(n));
+ try {
+ PluralFormat plf = new PluralFormat(new ULocale(locales[i]), testPattern);
+ log("plf: " + plf);
+ String expected = (String) changes.get(new Integer(0));
+ for (int n = 0; n < 200; ++n) {
+ if (changes.get(new Integer(n)) != null) {
+ expected = (String) changes.get(new Integer(n));
+ }
+ assertEquals("Locale: " + locales[i] + ", number: " + n,
+ expected, plf.format(n));
}
- assertEquals("Locale: " + locales[i] + ", number: " + n,
- expected, plf.format(n));
+ } catch (IllegalArgumentException e) {
+ errln(e.getMessage() + " locale: " + locales[i] + " pattern: '" + testPattern + "' " + System.currentTimeMillis());
}
}
}
@@ -70,7 +74,7 @@
}
public void TestSingular1Locales() {
- String localeIDs = "da,de,el,en,eo,es,et,fi,fo,he,hu,it,nb,nl,nn,no,pt,sv";
+ String localeIDs = "da,de,el,en,eo,es,et,fi,fo,he,it,nb,nl,nn,no,pt_PT,sv";
String testPattern = "one{one} other{other}";
Map changes = new HashMap();
changes.put(new Integer(0), "other");
@@ -118,13 +122,13 @@
public void TestSingularZeroSome() {
String localeIDs = "ro";
- String testPattern = "zero{zero} one{one} other{other}";
+ String testPattern = "few{few} one{one} other{other}";
Map changes = new HashMap();
- changes.put(new Integer(0), "zero");
+ changes.put(new Integer(0), "few");
changes.put(new Integer(1), "one");
- changes.put(new Integer(2), "zero");
+ changes.put(new Integer(2), "few");
changes.put(new Integer(20), "other");
- changes.put(new Integer(101), "zero");
+ changes.put(new Integer(101), "few");
changes.put(new Integer(120), "other");
helperTestRules(localeIDs, testPattern, changes);
}
@@ -187,7 +191,7 @@
changes.put(new Integer(2), "few");
changes.put(new Integer(5), "other");
for (int i = 2; i < 20; ++i) {
- if (i == 11) {
+ if (i == 2 || i == 11 || i == 12) {
continue;
}
changes.put(new Integer(i*10 + 2), "few");
diff --git a/src/com/ibm/icu/dev/test/format/PluralRulesTest.java b/src/com/ibm/icu/dev/test/format/PluralRulesTest.java
index 55b87f7..83d8876 100644
--- a/src/com/ibm/icu/dev/test/format/PluralRulesTest.java
+++ b/src/com/ibm/icu/dev/test/format/PluralRulesTest.java
@@ -9,6 +9,7 @@
import com.ibm.icu.dev.test.TestFmwk;
import com.ibm.icu.impl.Utility;
import com.ibm.icu.text.PluralRules;
+import com.ibm.icu.util.ULocale;
import java.text.ParseException;
import java.util.ArrayList;
@@ -131,4 +132,22 @@
compareEquality(rules);
}
}
+
+ public void testBuiltInRules() {
+ // spot check
+ PluralRules rules = PluralRules.forLocale(ULocale.US);
+ assertEquals("us 0", PluralRules.KEYWORD_OTHER, rules.select(0));
+ assertEquals("us 1", PluralRules.KEYWORD_ONE, rules.select(1));
+ assertEquals("us 2", PluralRules.KEYWORD_OTHER, rules.select(2));
+
+ rules = PluralRules.forLocale(ULocale.JAPAN);
+ assertEquals("ja 0", PluralRules.KEYWORD_OTHER, rules.select(0));
+ assertEquals("ja 1", PluralRules.KEYWORD_OTHER, rules.select(1));
+ assertEquals("ja 2", PluralRules.KEYWORD_OTHER, rules.select(2));
+
+ rules = PluralRules.forLocale(ULocale.createCanonical("ru"));
+ assertEquals("ru 0", PluralRules.KEYWORD_MANY, rules.select(0));
+ assertEquals("ru 1", PluralRules.KEYWORD_ONE, rules.select(1));
+ assertEquals("ru 2", PluralRules.KEYWORD_FEW, rules.select(2));
+ }
}
diff --git a/src/com/ibm/icu/impl/PluralRulesLoader.java b/src/com/ibm/icu/impl/PluralRulesLoader.java
new file mode 100644
index 0000000..79770d1
--- /dev/null
+++ b/src/com/ibm/icu/impl/PluralRulesLoader.java
@@ -0,0 +1,158 @@
+/*
+ *******************************************************************************
+ * Copyright (C) 2008, International Business Machines Corporation and *
+ * others. All Rights Reserved. *
+ *******************************************************************************
+ */
+package com.ibm.icu.impl;
+
+import com.ibm.icu.text.PluralRules;
+import com.ibm.icu.util.ULocale;
+import com.ibm.icu.util.UResourceBundle;
+
+import java.text.ParseException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.MissingResourceException;
+import java.util.Set;
+import java.util.TreeMap;
+
+/**
+ * Loader for plural rules data.
+ */
+public class PluralRulesLoader {
+ private final Map rulesIdToRules;
+ private Map localeIdToRulesId; // lazy init, use getLocaleIdToRulesIdMap to access
+
+ /**
+ * Access through singleton.
+ */
+ private PluralRulesLoader() {
+ rulesIdToRules = new HashMap();
+ }
+
+ /**
+ * Returns the locales for which we have plurals data.
+ * Utility for testing.
+ */
+ public ULocale[] getAvailableULocales() {
+ Set keys = getLocaleIdToRulesIdMap().keySet();
+ ULocale[] locales = new ULocale[keys.size()];
+ int n = 0;
+ for (Iterator iter = keys.iterator(); iter.hasNext();) {
+ locales[n++] = ULocale.createCanonical((String) iter.next());
+ }
+ return locales;
+ }
+
+ /**
+ * Lazily construct the map from localeIds to rulesIds. This
+ * map exactly reflects the contents of the locales resource
+ * in plurals.res.
+ */
+ private Map getLocaleIdToRulesIdMap() {
+ if (localeIdToRulesId == null) {
+ try {
+ UResourceBundle pluralb = getPluralBundle();
+ UResourceBundle localeb = pluralb.get("locales");
+ localeIdToRulesId = new TreeMap(); // sort for convenience of getAvailableULocales
+ 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);
+ }
+ }
+ catch (MissingResourceException e) {
+ localeIdToRulesId = new HashMap(); // dummy so we don't try again
+ }
+ }
+ return localeIdToRulesId;
+ }
+
+ /**
+ * Gets the rulesId from the locale,with locale fallback. If there is no
+ * rulesId, return null. The rulesId might be the empty string if the
+ * rule is the default rule.
+ */
+ public String getRulesIdForLocale(ULocale locale) {
+ Map idMap = getLocaleIdToRulesIdMap();
+ String localeId = ULocale.canonicalize(locale.getBaseName());
+ String rulesId = null;
+ while (null == (rulesId = (String) idMap.get(localeId))) {
+ int ix = localeId.lastIndexOf("_");
+ if (ix == -1) {
+ break;
+ }
+ localeId = localeId.substring(0, ix);
+ }
+ return rulesId;
+ }
+
+ /**
+ * Gets the rule from the rulesId. If there is no rule for this rulesId,
+ * return null.
+ */
+ public PluralRules getRulesForRulesId(String rulesId) {
+ PluralRules rules = (PluralRules) rulesIdToRules.get(rulesId);
+ if (rules == null) {
+ try {
+ UResourceBundle pluralb = getPluralBundle();
+ UResourceBundle rulesb = pluralb.get("rules");
+ UResourceBundle setb = rulesb.get(rulesId);
+
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < setb.getSize(); ++i) {
+ UResourceBundle b = setb.get(i);
+ if (i > 0) {
+ sb.append("; ");
+ }
+ sb.append(b.getKey());
+ sb.append(": ");
+ sb.append(b.getString());
+ }
+ rules = PluralRules.parseDescription(sb.toString());
+ } catch (ParseException e) {
+ } catch (MissingResourceException e) {
+ }
+ rulesIdToRules.put(rulesId, rules); // put even if null
+ }
+ return rules;
+ }
+
+ /**
+ * Return the plurals resource.
+ * Note MissingResourceException is unchecked, listed here for clarity.
+ * Callers should handle this exception.
+ */
+ public UResourceBundle getPluralBundle() throws MissingResourceException {
+ return ICUResourceBundle.getBundleInstance(
+ ICUResourceBundle.ICU_BASE_NAME,
+ "plurals",
+ ICUResourceBundle.ICU_DATA_CLASS_LOADER,
+ true);
+ }
+
+ /**
+ * 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);
+ if (rulesId == null || rulesId.trim().length() == 0) {
+ return PluralRules.DEFAULT;
+ }
+ PluralRules rules = getRulesForRulesId(rulesId);
+ if (rules == null) {
+ rules = PluralRules.DEFAULT;
+ }
+ return rules;
+ }
+
+ /**
+ * The only instance of the loader.
+ */
+ public static final PluralRulesLoader loader = new PluralRulesLoader();
+}
diff --git a/src/com/ibm/icu/impl/data/icudata.jar b/src/com/ibm/icu/impl/data/icudata.jar
index 96707fd..f298122 100755
--- a/src/com/ibm/icu/impl/data/icudata.jar
+++ b/src/com/ibm/icu/impl/data/icudata.jar
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:8948a491d5f863049e5f7a08530406635f1b0fccd5f5913d9db9349c45e21008
-size 6604684
+oid sha256:81f2ec380c532d8fc2d4f808cb1d4fc27c251fc2b742cbaa0c24177fe45c7289
+size 6604691
diff --git a/src/com/ibm/icu/text/PluralRules.java b/src/com/ibm/icu/text/PluralRules.java
index 7b160fd..5b49e1d 100644
--- a/src/com/ibm/icu/text/PluralRules.java
+++ b/src/com/ibm/icu/text/PluralRules.java
@@ -7,17 +7,16 @@
package com.ibm.icu.text;
-import com.ibm.icu.util.ULocale;
+import com.ibm.icu.impl.PluralRulesLoader;
import com.ibm.icu.impl.Utility;
+import com.ibm.icu.util.ULocale;
import java.io.Serializable;
import java.text.ParseException;
import java.util.Collections;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.Locale;
-import java.util.Map;
import java.util.Set;
/**
@@ -78,8 +77,6 @@
public class PluralRules implements Serializable {
private static final long serialVersionUID = 1;
- private static final Map ruleMap; // from locale string to PluralRules
-
private final RuleList rules;
private final Set keywords;
private int repeatLimit; // for equality test
@@ -276,46 +273,6 @@
int getRepeatLimit();
}
- // default data
- static {
- String[] ruledata = {
- "other: n/ja,ko,tr,vi", // not strictly necessary, default for all
- "zero: n is 0; one: n is 1; two: n is 2; few: n in 3..10; " +
- "many: n in 11..99/ar",
- "one: n is 1/da,de,el,en,eo,es,et,fi,fo,he,hu,it,nb,nl,nn,no,pt,sv",
- "one: n in 0..1/fr,pt_BR",
- "zero: n is 0; one: n mod 10 is 1 and n mod 100 is not 11/lv",
- "one: n is 1; two: n is 2/ga",
- "zero: n is 0; one: n is 1; zero: n mod 100 in 1..19/ro",
- "other: n mod 100 in 11..19; one: n mod 10 is 1; " +
- "few: n mod 10 in 2..9/lt",
- "one: n mod 10 is 1 and n mod 100 is not 11; " +
- "few: n mod 10 in 2..4 " +
- "and n mod 100 not in 12..14/hr,ru,sr,uk",
- "one: n is 1; few: n in 2..4/cs,sk",
- "one: n is 1; few: n mod 10 in 2..4 and n mod 100 not in 12..14/pl",
- "one: n mod 100 is 1; two: n mod 100 is 2; " +
- "few: n mod 100 in 3..4/sl",
- };
-
- HashMap map = new HashMap();
- for (int i = 0; i < ruledata.length; ++i) {
- String[] data = Utility.split(ruledata[i], '/');
- try {
- PluralRules pluralRules = parseDescription(data[0]);
- String[] locales = Utility.split(data[1], ',');
- for (int j = 0; j < locales.length; ++j) {
- map.put(locales[j].trim(), pluralRules);
- }
- } catch (Exception e) {
- System.err.println("PluralRules init failure, " +
- e.getMessage() + " at line " + i);
- }
- }
-
- ruleMap = map;
- }
-
/**
* syntax:
* condition : or_condition
@@ -724,14 +681,7 @@
* @provisional This API might change or be removed in a future release.
*/
public static PluralRules forLocale(ULocale locale) {
- PluralRules result = null;
- while (null == (result = (PluralRules) ruleMap.get(locale.getName()))) {
- locale = locale.getFallback();
- if (locale == null) {
- return DEFAULT;
- }
- }
- return result;
+ return PluralRulesLoader.loader.forLocale(locale);
}
/**
@@ -846,4 +796,4 @@
}
return repeatLimit;
}
-}
+ }