From 47695b8314e5fdf44dc089f8bb31991172117cdf Mon Sep 17 00:00:00 2001 From: Doug Felt Date: Wed, 14 Jul 2004 19:22:18 +0000 Subject: [PATCH] ICU-3634 RBNF rule sets should have localized display names X-SVN-Rev: 15998 --- .../ibm/icu/text/RuleBasedNumberFormat.java | 136 +++++++++++++++++- icu4j/src/com/ibm/icu/util/ULocale.java | 36 +++++ 2 files changed, 168 insertions(+), 4 deletions(-) diff --git a/icu4j/src/com/ibm/icu/text/RuleBasedNumberFormat.java b/icu4j/src/com/ibm/icu/text/RuleBasedNumberFormat.java index bb1ed12e772..95446a709a4 100755 --- a/icu4j/src/com/ibm/icu/text/RuleBasedNumberFormat.java +++ b/icu4j/src/com/ibm/icu/text/RuleBasedNumberFormat.java @@ -16,7 +16,12 @@ import com.ibm.icu.util.UResourceBundle; import java.math.BigInteger; import java.text.FieldPosition; import java.text.ParsePosition; +import java.util.Arrays; +import java.util.HashMap; import java.util.Locale; +import java.util.Map; +import java.util.Set; + //import java.util.ResourceBundle; @@ -562,6 +567,11 @@ public class RuleBasedNumberFormat extends NumberFormat { */ private RBNFPostProcessor postProcessor; + /** + * Localizations for rule set names. + */ + private Map ruleSetDisplayNames; + //----------------------------------------------------------------------- // constructors //----------------------------------------------------------------------- @@ -576,7 +586,25 @@ public class RuleBasedNumberFormat extends NumberFormat { */ public RuleBasedNumberFormat(String description) { locale = Locale.getDefault(); - init(description); + init(description, null); + } + + /** + * Creates a RuleBasedNumberFormat that behaves according to the description + * passed in. The formatter uses the default locale. + * @param description A description of the formatter's desired behavior. + * See the class documentation for a complete explanation of the description + * syntax. + * @param a list of localizations for the rule set names in the description. + * Each element is an array or strings. The first string is the ulocale, the + * remainder are the localizations of the public rule set names, in reverse + * order from how they they appear in the description. + * @draft ICU 3.2 + * @deprecated This is a draft API and might change in a future release of ICU. + */ + public RuleBasedNumberFormat(String description, String[][] localizations) { + locale = Locale.getDefault(); + init(description, localizations); } /** @@ -594,7 +622,30 @@ public class RuleBasedNumberFormat extends NumberFormat { */ public RuleBasedNumberFormat(String description, Locale locale) { this.locale = locale; - init(description); + init(description, null); + } + + /** + * Creates a RuleBasedNumberFormat that behaves according to the description + * passed in. The formatter uses the specified locale to determine the + * characters to use when formatting in numerals, and to define equivalences + * for lenient parsing. + * @param description A description of the formatter's desired behavior. + * See the class documentation for a complete explanation of the description + * syntax. + * @param a list of localizations for the rule set names in the description. + * Each element is an array or strings. The first string is the ulocale, the + * remainder are the localizations of the public rule set names, in reverse + * order from how they appear in the description. + * @param locale A locale, which governs which characters are used for + * formatting values in numerals, and which characters are equivalent in + * lenient parsing. + * @draft ICU 3.2 + * @deprecated This is a draft API and might change in a future release of ICU. + */ + public RuleBasedNumberFormat(String description, String[][] localizations, Locale locale) { + this.locale = locale; + init(description, localizations); } /** @@ -642,7 +693,8 @@ public class RuleBasedNumberFormat extends NumberFormat { } // construct the formatter based on the description - init(description); + // TODO: amend this so we can add the localizations + init(description, null); } /** @@ -788,6 +840,61 @@ public class RuleBasedNumberFormat extends NumberFormat { return result; } + /** + * Return a list of locales for which there are locale-specific display names + * for the rule sets in this formatter. If there are no localized display names, return null. + * @return an array of the locales for which there is rule set display name information + * @draft ICU 3.2 + * @deprecated This is a draft API and might change in a future release of ICU. + */ + public ULocale[] getRuleSetDisplayNameLocales() { + if (ruleSetDisplayNames != null) { + Set s = ruleSetDisplayNames.keySet(); + String[] locales = (String[])s.toArray(new String[s.size()]); + Arrays.sort(locales, String.CASE_INSENSITIVE_ORDER); + ULocale[] result = new ULocale[locales.length]; + for (int i = 0; i < locales.length; ++i) { + result[i] = new ULocale(locales[i]); + } + return result; + } + return null; + } + + + /** + * Return the rule set display names for the provided locale. These are in the same order + * as those returned by getRuleSetNames. The locale is matched against the locales for + * which there is display name data, using normal fallback rules. If no locale matches + * the default display names are returned. (These are the internal rule set names minus + * the leading '%'.) + * @return an array of the locales that have display name information + * @draft ICU 3.2 + * @see #getRuleSetNames + * @deprecated This is a draft API and might change in a future release of ICU. + */ + public String[] getRuleSetDisplayNames(ULocale locale) { + String[] names = null; + if (locale != null && ruleSetDisplayNames != null) { + String[] localeNames = { locale.getBaseName(), ULocale.getDefault().getBaseName() }; + for (int i = 0; i < localeNames.length; ++i) { + String lname = localeNames[i]; + while (lname.length() > 0) { + names = (String[])ruleSetDisplayNames.get(lname); + if (names != null) { + return (String[])names.clone(); + } + lname = ULocale.getFallback(lname); + } + } + } + names = getRuleSetNames(); + for (int i = 0; i < names.length; ++i) { + names[i] = names[i].substring(1); + } + return names; + } + /** * Formats the specified number according to the specified rule set. * @param number The number to format. @@ -1178,7 +1285,9 @@ public class RuleBasedNumberFormat extends NumberFormat { * by one of the constructors, and is in the description format specified * in the class docs. */ - private void init(String description) { + private void init(String description, String[][] localizations) { + + initLocalizations(localizations); // start by stripping the trailing whitespace from all the rules // (this is all the whitespace follwing each semicolon in the @@ -1244,6 +1353,25 @@ public class RuleBasedNumberFormat extends NumberFormat { } } + /** + * Take the localizations array and create a Map from the locale strings to + * the localization arrays. + */ + private void initLocalizations(String[][] localizations) { + if (localizations != null) { + Map m = new HashMap(); + for (int i = 0; i < localizations.length; ++i) { + String[] data = localizations[i]; + String locale = data[0]; + String[] names = new String[data.length-1]; + System.arraycopy(data, 1, names, 0, names.length); + m.put(locale, names); + } + + ruleSetDisplayNames = m; + } + } + /** * This function is used by init() to strip whitespace between rules (i.e., * after semicolons). diff --git a/icu4j/src/com/ibm/icu/util/ULocale.java b/icu4j/src/com/ibm/icu/util/ULocale.java index b95c66aab86..3227970f297 100644 --- a/icu4j/src/com/ibm/icu/util/ULocale.java +++ b/icu4j/src/com/ibm/icu/util/ULocale.java @@ -1010,6 +1010,42 @@ public final class ULocale implements Serializable { return new IDParser(localeID).getVariant(); } + /** + * Returns the fallback locale for the specified locale, which might be the empty string. + * @draft ICU 3.2 + * @deprecated This is a draft API and might change in a future release of ICU. + */ + public static String getFallback(String localeID) { + return getFallbackString(getName(localeID)); + } + + /** + * Returns the fallback locale for this locale. If this locale is root, returns null. + * @draft ICU 3.2 + * @deprecated This is a draft API and might change in a future release of ICU. + */ + public ULocale getFallback() { + if (localeID.length() == 0 || localeID.charAt(0) == '@') { + return null; + } + return new ULocale(getFallbackString(localeID), null); + } + + /** + * Return the given (canonical) locale id minus the last part before the tags. + */ + private static String getFallbackString(String fallback) { + int limit = fallback.indexOf('@'); + if (limit == -1) { + limit = fallback.length(); + } + int start = fallback.lastIndexOf('_', limit); + if (start == -1) { + start = 0; + } + return fallback.substring(0, start) + fallback.substring(limit); + } + /** * Returns the (normalized) base name for this locale. * @return the base name as a String.