ICU-6390 support for available locales and functional equivalent
X-SVN-Rev: 24381
This commit is contained in:
parent
30e587a108
commit
7c47091e1c
@ -17,7 +17,6 @@ import java.util.List;
|
||||
|
||||
/**
|
||||
* @author dougfelt (Doug Felt)
|
||||
*
|
||||
*/
|
||||
public class PluralRulesTest extends TestFmwk {
|
||||
public static void main(String[] args) throws Exception {
|
||||
@ -150,4 +149,25 @@ public class PluralRulesTest extends TestFmwk {
|
||||
assertEquals("ru 1", PluralRules.KEYWORD_ONE, rules.select(1));
|
||||
assertEquals("ru 2", PluralRules.KEYWORD_FEW, rules.select(2));
|
||||
}
|
||||
|
||||
public void testFunctionalEquivalent() {
|
||||
// spot check
|
||||
ULocale unknown = ULocale.createCanonical("zz_ZZ");
|
||||
ULocale un_equiv = PluralRules.getFunctionalEquivalent(unknown, null);
|
||||
assertEquals("unknown locales have root", ULocale.ROOT, un_equiv);
|
||||
|
||||
ULocale jp_equiv = PluralRules.getFunctionalEquivalent(ULocale.JAPAN, null);
|
||||
ULocale cn_equiv = PluralRules.getFunctionalEquivalent(ULocale.CHINA, null);
|
||||
assertEquals("japan and china equivalent locales", jp_equiv, cn_equiv);
|
||||
|
||||
boolean[] available = new boolean[1];
|
||||
ULocale russia = ULocale.createCanonical("ru_RU");
|
||||
ULocale ru_ru_equiv = PluralRules.getFunctionalEquivalent(russia, available);
|
||||
assertFalse("ru_RU not listed", available[0]);
|
||||
|
||||
ULocale russian = ULocale.createCanonical("ru");
|
||||
ULocale ru_equiv = PluralRules.getFunctionalEquivalent(russian, available);
|
||||
assertTrue("ru listed", available[0]);
|
||||
assertEquals("ru and ru_RU equivalent locales", ru_ru_equiv, ru_equiv);
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ import java.util.TreeMap;
|
||||
public class PluralRulesLoader {
|
||||
private final Map rulesIdToRules;
|
||||
private Map localeIdToRulesId; // lazy init, use getLocaleIdToRulesIdMap to access
|
||||
private Map rulesIdToEquivalentULocale; // lazy init, use getRulesIdToEquivalentULocaleMap to access
|
||||
|
||||
/**
|
||||
* Access through singleton.
|
||||
@ -47,28 +48,72 @@ public class PluralRulesLoader {
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazily construct the map from localeIds to rulesIds. This
|
||||
* map exactly reflects the contents of the locales resource
|
||||
* in plurals.res.
|
||||
* Returns the functionally equivalent locale.
|
||||
*/
|
||||
public ULocale getFunctionalEquivalent(ULocale locale, boolean[] isAvailable) {
|
||||
if (isAvailable != null && isAvailable.length > 0) {
|
||||
String localeId = ULocale.canonicalize(locale.getBaseName());
|
||||
Map idMap = getLocaleIdToRulesIdMap();
|
||||
isAvailable[0] = idMap.containsKey(localeId);
|
||||
}
|
||||
|
||||
String rulesId = getRulesIdForLocale(locale);
|
||||
if (rulesId == null || rulesId.trim().length() == 0) {
|
||||
return ULocale.ROOT; // ultimate fallback
|
||||
}
|
||||
|
||||
ULocale result = (ULocale) getRulesIdToEquivalentULocaleMap().get(rulesId);
|
||||
if (result == null) {
|
||||
return ULocale.ROOT; // ultimate fallback
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the lazily-constructed map.
|
||||
*/
|
||||
private Map getLocaleIdToRulesIdMap() {
|
||||
checkBuildRulesIdMaps();
|
||||
return localeIdToRulesId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the lazily-constructed map.
|
||||
*/
|
||||
private Map getRulesIdToEquivalentULocaleMap() {
|
||||
checkBuildRulesIdMaps();
|
||||
return rulesIdToEquivalentULocale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazily constructs the localeIdToRulesId and rulesIdToEquivalentULocale
|
||||
* maps if necessary. These exactly reflect the contents of the locales resource
|
||||
* in plurals.res.
|
||||
*/
|
||||
private void checkBuildRulesIdMaps() {
|
||||
if (localeIdToRulesId == null) {
|
||||
try {
|
||||
UResourceBundle pluralb = getPluralBundle();
|
||||
UResourceBundle localeb = pluralb.get("locales");
|
||||
localeIdToRulesId = new TreeMap(); // sort for convenience of getAvailableULocales
|
||||
rulesIdToEquivalentULocale = new HashMap(); // not visible
|
||||
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);
|
||||
|
||||
if (!rulesIdToEquivalentULocale.containsKey(value)) {
|
||||
rulesIdToEquivalentULocale.put(value, new ULocale(id));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (MissingResourceException e) {
|
||||
localeIdToRulesId = new HashMap(); // dummy so we don't try again
|
||||
localeIdToRulesId = new HashMap(); // dummy so we don't try again, can read
|
||||
rulesIdToEquivalentULocale = new HashMap();
|
||||
}
|
||||
}
|
||||
return localeIdToRulesId;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -735,6 +735,37 @@ public class PluralRules implements Serializable {
|
||||
return keywords;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the set of locales for which PluralRules are known.
|
||||
* @return the set of locales for which PluralRules are known, as a list
|
||||
* @draft ICU 4.2
|
||||
* @provisional This API might change or be removed in a future release.
|
||||
*/
|
||||
public static ULocale[] getAvailableULocales() {
|
||||
return PluralRulesLoader.loader.getAvailableULocales();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the 'functionally equivalent' locale with respect to
|
||||
* plural rules. Calling PluralRules.forLocale with the functionally equivalent
|
||||
* locale, and with the provided locale, returns rules that behave the same.
|
||||
* <br/>
|
||||
* All locales with the same functionally equivalent locale have
|
||||
* plural rules that behave the same. This is not exaustive;
|
||||
* there may be other locales whose plural rules behave the same
|
||||
* that do not have the same equivalent locale.
|
||||
*
|
||||
* @param locale the locale to check
|
||||
* @param isAvailable if not null and of length > 0, this will hold 'true' at
|
||||
* index 0 if locale is directly defined (without fallback) as having plural rules
|
||||
* @return the functionally-equivalent locale
|
||||
* @draft ICU 4.2
|
||||
* @provisional This API might change or be removed in a future release.
|
||||
*/
|
||||
public static ULocale getFunctionalEquivalent(ULocale locale, boolean[] isAvailable) {
|
||||
return PluralRulesLoader.loader.getFunctionalEquivalent(locale, isAvailable);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @draft ICU 3.8
|
||||
|
Loading…
Reference in New Issue
Block a user