From 1d32573438eff6785fcfcc4865bcfd0ff45c1af7 Mon Sep 17 00:00:00 2001
From: Doug Felt
Date: Tue, 23 May 2006 19:46:10 +0000
Subject: [PATCH] ICU-4743 yoshito's fixes to GP
X-SVN-Rev: 19644
---
.../icu/util/GlobalizationPreferences.java | 469 +++++++++++++++---
1 file changed, 398 insertions(+), 71 deletions(-)
diff --git a/icu4j/src/com/ibm/icu/util/GlobalizationPreferences.java b/icu4j/src/com/ibm/icu/util/GlobalizationPreferences.java
index 5fdec2b56a8..439a593a6a9 100644
--- a/icu4j/src/com/ibm/icu/util/GlobalizationPreferences.java
+++ b/icu4j/src/com/ibm/icu/util/GlobalizationPreferences.java
@@ -14,6 +14,8 @@ import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
import java.util.TreeMap;
//#ifndef FOUNDATION
@@ -23,6 +25,7 @@ import java.util.regex.Pattern;
import com.ibm.icu.impl.Utility;
import com.ibm.icu.impl.ZoneMeta;
+import com.ibm.icu.text.BreakIterator;
import com.ibm.icu.text.Collator;
import com.ibm.icu.text.DateFormat;
import com.ibm.icu.text.DecimalFormat;
@@ -67,12 +70,8 @@ import com.ibm.icu.text.SimpleDateFormat;
* changes that we would like yet; further feedback is welcome.
*
* TODO:
- * - Separate out base class
- * - Add BreakIterator
* - Add Holidays
* - Add convenience to get/take Locale as well as ULocale.
- * - Add getResourceBundle(String baseName, ClassLoader loader);
- * - Add getFallbackLocales();
* - Add Lenient datetime formatting when that is available.
* - Should this be serializable?
* - Other utilities?
@@ -99,16 +98,28 @@ public class GlobalizationPreferences implements Freezable {
* @internal
* @deprecated This API is ICU internal only.
*/
- public static final int CURRENCY = 0, NUMBER = 1, INTEGER = 2, SCIENTIFIC = 3,
- PERCENT = 4, NUMBER_LIMIT = 5;
+ public static final int
+ NF_NUMBER = 0, // NumberFormat.NUMBERSTYLE
+ NF_CURRENCY = 1, // NumberFormat.CURRENCYSTYLE
+ NF_PERCENT = 2, // NumberFormat.PERCENTSTYLE
+ NF_SCIENTIFIC = 3, // NumberFormat.SCIENTIFICSTYLE
+ NF_INTEGER = 4; // NumberFormat.INTEGERSTYLE
+
+ private static final int NF_LIMIT = NF_INTEGER + 1;
/**
- * Supplement to DateFormat.FULL, LONG, MEDIUM, SHORT. Indicates
- * that no value for one of date or time is to be used.
+ * Date Format types
* @internal
* @deprecated This API is ICU internal only.
*/
- public static final int NONE = 4;
+ public static final int
+ DF_FULL = DateFormat.FULL, // 0
+ DF_LONG = DateFormat.LONG, // 1
+ DF_MEDIUM = DateFormat.MEDIUM, // 2
+ DF_SHORT = DateFormat.SHORT, // 3
+ DF_NONE = 4;
+
+ private static final int DF_LIMIT = DF_NONE + 1;
/**
* For selecting a choice of display names
@@ -116,10 +127,33 @@ public class GlobalizationPreferences implements Freezable {
* @deprecated This API is ICU internal only.
*/
public static final int
- LOCALEID = 0, LANGUAGEID = 1, SCRIPTID = 2, TERRITORYID = 3, VARIANTID = 4,
- KEYWORDID = 5, KEYWORD_VALUEID = 6,
- CURRENCYID = 7, CURRENCY_SYMBOLID = 8, TIMEZONEID = 9, DISPLAYID_LIMIT = 10;
-
+ ID_LOCALE = 0,
+ ID_LANGUAGE = 1,
+ ID_SCRIPT = 2,
+ ID_TERRITORY = 3,
+ ID_VARIANT = 4,
+ ID_KEYWORD = 5,
+ ID_KEYWORD_VALUE = 6,
+ ID_CURRENCY = 7,
+ ID_CURRENCY_SYMBOL = 8,
+ ID_TIMEZONE = 9;
+
+ private static final int ID_LIMIT = ID_TIMEZONE + 1;
+
+ /**
+ * Break iterator types
+ * @internal
+ * @deprecated This API is ICU internal only
+ */
+ public static final int
+ BI_CHARACTER = BreakIterator.KIND_CHARACTER, // 0
+ BI_WORD = BreakIterator.KIND_WORD, // 1
+ BI_LINE = BreakIterator.KIND_LINE, // 2
+ BI_SENTENCE = BreakIterator.KIND_SENTENCE, // 3
+ BI_TITLE = BreakIterator.KIND_TITLE; // 4
+
+ private static final int BI_LIMIT = BI_TITLE + 1;
+
/**
* Sets the language/locale priority list. If other information is
* not (yet) available, this is used to to produce a default value
@@ -136,9 +170,9 @@ public class GlobalizationPreferences implements Freezable {
if (isFrozen()) {
throw new UnsupportedOperationException("Attempt to modify immutable object");
}
- if (locales.size() == 0) {
+ if (locales.size() == 1) {
this.locales = locales.get(0);
- } else {
+ } else if (locales.size() > 1) {
this.locales = new ArrayList(locales); // clone for safety
}
return this;
@@ -173,7 +207,9 @@ public class GlobalizationPreferences implements Freezable {
if (locales == null) {
return (ULocale)guessLocales().get(index);
} else if (locales instanceof ULocale) {
- if (index != 0) throw new IllegalArgumentException("Out of bounds: " + index);
+ if (index != 0) {
+ throw new IllegalArgumentException("Out of bounds: " + index);
+ }
return (ULocale)locales;
} else {
return (ULocale)((List)locales).get(index);
@@ -195,6 +231,7 @@ public class GlobalizationPreferences implements Freezable {
}
return setLocales(Arrays.asList(uLocales));
}
+
/**
* Convenience routine for setting the language/locale priority
* list from a single locale/language.
@@ -235,7 +272,7 @@ public class GlobalizationPreferences implements Freezable {
Matcher acceptMatcher = Pattern.compile("\\s*([-_a-zA-Z]+)(;q=([.0-9]+))?\\s*").matcher("");
Map reorder = new TreeMap();
String[] pieces = acceptLanguageString.split(",");
-
+
for (int i = 0; i < pieces.length; ++i) {
Double qValue = new Double(1);
try {
@@ -243,13 +280,17 @@ public class GlobalizationPreferences implements Freezable {
throw new IllegalArgumentException();
}
String qValueString = acceptMatcher.group(3);
- if (qValueString != null) qValue = new Double(Double.parseDouble(qValueString));
+ if (qValueString != null) {
+ qValue = new Double(Double.parseDouble(qValueString));
+ }
} catch (Exception e) {
throw new IllegalArgumentException("element '" + pieces[i] +
"' is not of the form '{;q=}");
}
List items = (List)reorder.get(qValue);
- if (items == null) reorder.put(qValue, items = new LinkedList());
+ if (items == null) {
+ reorder.put(qValue, items = new LinkedList());
+ }
items.add(0, acceptMatcher.group(1)); // reverse order, will reverse again
}
// now read out in reverse order
@@ -265,6 +306,206 @@ public class GlobalizationPreferences implements Freezable {
}
//#endif
+ /**
+ * Convenience routine for populating locale fallback order.
+ * @return a copy of fallback locale priority list
+ * @internal
+ * @deprecated This API is ICU internal only.
+ */
+ public List getFallbackLocales() {
+ ArrayList fallbacks = new ArrayList();
+ List localeList = getLocales();
+
+ /*
+ * Step 1: Relocate later occurence of more specific locale
+ * before earlier occurence of less specific locale.
+ *
+ * Example:
+ * Before - en_US, fr_FR, zh, en_US_Boston, zh_TW, zh_Hant, fr_CA
+ * After - en_US_Boston, en_US, fr_FR, zh_TW, zh_Hant, zh, fr_CA
+ */
+ for (int i = 0; i < localeList.size(); i++) {
+ ULocale uloc = (ULocale)localeList.get(i);
+
+ String language = uloc.getLanguage();
+ String script = uloc.getScript();
+ String country = uloc.getCountry();
+ String variant = uloc.getVariant();
+
+ boolean bInserted = false;
+ for (int j = 0; j < fallbacks.size(); j++) {
+ // Check if this locale is more specific
+ // than existing locale entries already inserted
+ // in the destination list
+ ULocale u = (ULocale)fallbacks.get(j);
+ if (!u.getLanguage().equals(language)) {
+ continue;
+ }
+ String s = u.getScript();
+ String c = u.getCountry();
+ String v = u.getVariant();
+ if (!s.equals(script)) {
+ if (s.length() == 0 && c.length() == 0 && v.length() == 0) {
+ fallbacks.add(j, uloc);
+ bInserted = true;
+ break;
+ } else if (s.length() == 0 && c.equals(country)) {
+ // We want to see zh_Hant_HK before zh_HK
+ fallbacks.add(j, uloc);
+ bInserted = true;
+ break;
+ } else if (script.length() == 0 && country.length() > 0 && c.length() == 0) {
+ // We want to see zh_HK before zh_Hant
+ fallbacks.add(j, uloc);
+ bInserted = true;
+ break;
+ }
+ continue;
+ }
+ if (!c.equals(country)) {
+ if (c.length() == 0 && v.length() == 0) {
+ fallbacks.add(j, uloc);
+ bInserted = true;
+ break;
+ }
+ }
+ if (!v.equals(variant) && v.length() == 0) {
+ fallbacks.add(j, uloc);
+ bInserted = true;
+ break;
+ }
+ }
+ if (!bInserted) {
+ // Add this locale at the end of the list
+ fallbacks.add(uloc);
+ }
+ }
+
+ // TODO: Locale aliases should be resolved here
+ // For example, zh_Hant_TW = zh_TW
+
+ /*
+ * Step 2: Append fallback locales for each entry
+ *
+ * Example:
+ * Before - en_US_Boston, en_US, fr_FR, zh_TW, zh_Hant, zh, fr_CA
+ * After - en_US_Boston, en_US, en, en_US, en, fr_FR, fr,
+ * zh_TW, zn, zh_Hant, zh, zh, fr_CA, fr
+ */
+ int index = 0;
+ while (index < fallbacks.size()) {
+ ULocale uloc = (ULocale)fallbacks.get(index);
+ while (true) {
+ uloc = uloc.getFallback();
+ if (uloc.getLanguage().length() == 0) {
+ break;
+ }
+ index++;
+ fallbacks.add(index, uloc);
+ }
+ index++;
+ }
+
+ /*
+ * Step 3: Remove earlier occurence of duplicated locales
+ *
+ * Example:
+ * Before - en_US_Boston, en_US, en, en_US, en, fr_FR, fr,
+ * zh_TW, zn, zh_Hant, zh, zh, fr_CA, fr
+ * After - en_US_Boston, en_US, en, fr_FR, zh_TW, zh_Hant,
+ * zh, fr_CA, fr
+ */
+ index = 0;
+ while (index < fallbacks.size() - 1) {
+ ULocale uloc = (ULocale)fallbacks.get(index);
+ boolean bRemoved = false;
+ for (int i = index + 1; i < fallbacks.size(); i++) {
+ if (uloc.equals((ULocale)fallbacks.get(i))) {
+ // Remove ealier one
+ fallbacks.remove(index);
+ bRemoved = true;
+ break;
+ }
+ }
+ if (!bRemoved) {
+ index++;
+ }
+ }
+ return fallbacks;
+ }
+
+ /**
+ * Convenience function to get a ResourceBundle instance using
+ * the specified base name based on the language/locale priority list
+ * stored in this object.
+ *
+ * @param baseName the base name of the resource bundle, a fully qualified
+ * class name
+ * @return a resource bundle for the given base name and locale based on the
+ * language/locale priority list stored in this object
+ * @internal
+ * @deprecated This API is ICU internal only.
+ */
+ public ResourceBundle getResourceBundle(String baseName) {
+ return getResourceBundle(baseName, null);
+ }
+
+ /**
+ * Convenience function to get a ResourceBundle instance using
+ * the specified base name and class loader based on the language/locale
+ * priority list stored in this object.
+ *
+ * @param baseName the base name of the resource bundle, a fully qualified
+ * class name
+ * @param loader the class object from which to load the resource bundle
+ * @return a resource bundle for the given base name and locale based on the
+ * language/locale priority list stored in this object
+ * @internal
+ * @deprecated This API is ICU internal only.
+ */
+ public ResourceBundle getResourceBundle(String baseName, ClassLoader loader) {
+ UResourceBundle urb = null;
+ UResourceBundle candidate = null;
+ String actualLocaleName = null;
+ List fallbacks = getFallbackLocales();
+ for (int i = 0; i < fallbacks.size(); i++) {
+ String localeName = ((ULocale)fallbacks.get(i)).toString();
+ if (actualLocaleName != null && localeName.equals(actualLocaleName)) {
+ // Actual locale name in the previous round may exactly matches
+ // with the next fallback locale
+ urb = candidate;
+ break;
+ }
+ try {
+ if (loader == null) {
+ candidate = UResourceBundle.getBundleInstance(baseName, localeName);
+ }
+ else {
+ candidate = UResourceBundle.getBundleInstance(baseName, localeName, loader);
+ }
+ if (candidate != null) {
+ actualLocaleName = candidate.getULocale().getName();
+ if (actualLocaleName.equals(localeName)) {
+ urb = candidate;
+ break;
+ }
+ if (urb == null) {
+ // Preserve the available bundle as the last resort
+ urb = candidate;
+ }
+ }
+ } catch (MissingResourceException mre) {
+ actualLocaleName = null;
+ continue;
+ }
+ }
+ if (urb == null) {
+ throw new MissingResourceException("Can't find bundle for base name "
+ + baseName, baseName, "");
+ }
+ return urb;
+ }
+
/**
* Sets the territory, which is a valid territory according to for
* RFC 3066 (or successor). If not otherwise set, default
@@ -292,7 +533,9 @@ public class GlobalizationPreferences implements Freezable {
* @deprecated This API is ICU internal only.
*/
public String getTerritory() {
- if (territory == null) return guessTerritory();
+ if (territory == null) {
+ return guessTerritory();
+ }
return territory; // immutable, so don't need to clone
}
@@ -318,7 +561,9 @@ public class GlobalizationPreferences implements Freezable {
* @deprecated This API is ICU internal only.
*/
public Currency getCurrency() {
- if (currency == null) return guessCurrency();
+ if (currency == null) {
+ return guessCurrency();
+ }
return currency; // immutable, so don't have to clone
}
@@ -333,7 +578,7 @@ public class GlobalizationPreferences implements Freezable {
if (isFrozen()) {
throw new UnsupportedOperationException("Attempt to modify immutable object");
}
- this.calendar = calendar;
+ this.calendar = (Calendar) calendar.clone(); // clone for safety
return this;
}
@@ -344,7 +589,9 @@ public class GlobalizationPreferences implements Freezable {
* @deprecated This API is ICU internal only.
*/
public Calendar getCalendar() {
- if (calendar == null) return guessCalendar();
+ if (calendar == null) {
+ return guessCalendar();
+ }
Calendar temp = (Calendar) calendar.clone(); // clone for safety
temp.setTimeZone(getTimeZone());
return temp;
@@ -361,7 +608,7 @@ public class GlobalizationPreferences implements Freezable {
if (isFrozen()) {
throw new UnsupportedOperationException("Attempt to modify immutable object");
}
- this.timezone = timezone;
+ this.timezone = (TimeZone) timezone.clone(); // clone for safety;
return this;
}
@@ -373,10 +620,12 @@ public class GlobalizationPreferences implements Freezable {
* @deprecated This API is ICU internal only.
*/
public TimeZone getTimeZone() {
- if (timezone == null) return guessTimeZone();
+ if (timezone == null) {
+ return guessTimeZone();
+ }
return (TimeZone) timezone.clone(); // clone for safety
}
-
+
/**
* Get a copy of the collator according to the settings.
* @return collator explicit or implicit.
@@ -384,11 +633,13 @@ public class GlobalizationPreferences implements Freezable {
* @deprecated This API is ICU internal only.
*/
public Collator getCollator() {
- if (collator == null) return guessCollator();
+ if (collator == null) {
+ return guessCollator();
+ }
try {
return (Collator) collator.clone(); // clone for safety
} catch (CloneNotSupportedException e) {
- throw new IllegalStateException("Error in cloning collator");
+ throw new IllegalStateException("Error in cloning collator");
}
}
@@ -403,10 +654,48 @@ public class GlobalizationPreferences implements Freezable {
if (isFrozen()) {
throw new UnsupportedOperationException("Attempt to modify immutable object");
}
- this.collator = collator;
+ try {
+ this.collator = (Collator) collator.clone();
+ } catch (CloneNotSupportedException e) {
+ throw new IllegalStateException("Error in cloning collator");
+ }
return this;
}
+ /**
+ * Get a copy of the break iterator for the specified type according to the
+ * settings.
+ *
+ * @param type
+ * break type - CHARACTER or TITLE, WORD, LINE, SENTENC
+ * @return break iterator explicit or implicit
+ */
+ public BreakIterator getBreakIterator(int type) {
+ if (breakIterators == null || breakIterators[type] == null) {
+ return guessBreakIterator(type);
+ }
+ return (BreakIterator) breakIterators[type].clone(); // clone for safety
+ }
+
+ /**
+ * Explicitly set the break iterator for this object.
+ *
+ * @param type
+ * break type - CHARACTER or TITLE, WORD, LINE, SENTENC
+ * @param iterator a break iterator
+ * @return
+ */
+ public GlobalizationPreferences setBreakIterator(int type, BreakIterator iterator) {
+ if (isFrozen()) {
+ throw new UnsupportedOperationException("Attempt to modify immutable object");
+ }
+ if (breakIterators == null)
+ breakIterators = new BreakIterator[BI_LIMIT];
+ breakIterators[type] = (BreakIterator) iterator.clone(); // clone for safety
+ return this;
+ }
+
+
/**
* Set the date locale.
* @param dateLocale If not null, overrides the locale priority list for all the date formats.
@@ -429,7 +718,7 @@ public class GlobalizationPreferences implements Freezable {
public ULocale getDateLocale() {
return dateLocale != null ? dateLocale : getLocale(0);
}
-
+
/**
* Set the number locale.
* @param numberLocale If not null, overrides the locale priority list for all the date formats.
@@ -454,7 +743,7 @@ public class GlobalizationPreferences implements Freezable {
public ULocale getNumberLocale() {
return numberLocale != null ? numberLocale : getLocale(0);
}
-
+
/**
* Get the display name for an ID: language, script, territory, currency, timezone...
* Uses the language priority list to do so.
@@ -469,36 +758,36 @@ public class GlobalizationPreferences implements Freezable {
for (Iterator it = getLocales().iterator(); it.hasNext();) {
ULocale locale = (ULocale) it.next();
switch (type) {
- case LOCALEID:
+ case ID_LOCALE:
result = ULocale.getDisplayName(id, locale);
break;
- case LANGUAGEID:
+ case ID_LANGUAGE:
result = ULocale.getDisplayLanguage(id, locale);
break;
- case SCRIPTID:
+ case ID_SCRIPT:
result = ULocale.getDisplayScript("und-" + id, locale);
break;
- case TERRITORYID:
+ case ID_TERRITORY:
result = ULocale.getDisplayCountry("und-" + id, locale);
break;
- case VARIANTID:
+ case ID_VARIANT:
// TODO fix variant parsing
result = ULocale.getDisplayVariant("und-QQ-" + id, locale);
break;
- case KEYWORDID:
+ case ID_KEYWORD:
result = ULocale.getDisplayKeyword(id, locale);
break;
- case KEYWORD_VALUEID:
+ case ID_KEYWORD_VALUE:
String[] parts = new String[2];
Utility.split(id,'=',parts);
result = ULocale.getDisplayKeywordValue("und@"+id, parts[0], locale);
// TODO fix to tell when successful
if (result.equals(parts[1])) continue;
break;
- case CURRENCY_SYMBOLID:
- case CURRENCYID:
+ case ID_CURRENCY_SYMBOL:
+ case ID_CURRENCY:
Currency temp = new Currency(id);
- result =temp.getName(locale, type==CURRENCYID
+ result =temp.getName(locale, type==ID_CURRENCY
? Currency.LONG_NAME
: Currency.SYMBOL_NAME, new boolean[1]);
// TODO: have method that doesn't take parameter. Add
@@ -507,7 +796,7 @@ public class GlobalizationPreferences implements Freezable {
// TODO: have method that doesn't require us
// to create a currency
break;
- case TIMEZONEID:
+ case ID_TIMEZONE:
SimpleDateFormat dtf = new SimpleDateFormat("vvvv",locale);
dtf.setTimeZone(TimeZone.getTimeZone(id));
result = dtf.format(new Date());
@@ -550,11 +839,13 @@ public class GlobalizationPreferences implements Freezable {
if (isFrozen()) {
throw new UnsupportedOperationException("Attempt to modify immutable object");
}
- if (dateFormats == null) dateFormats = new Object[NONE+1][NONE+1];
+ if (dateFormats == null) {
+ dateFormats = new Object[DF_LIMIT][DF_LIMIT];
+ }
dateFormats[dateStyle][timeStyle] = (DateFormat) format.clone(); // for safety
return this;
}
-
+
/**
* Set an explicit date format. Overrides both the date locale,
* and the locale priority list for a particular combination of
@@ -571,7 +862,9 @@ public class GlobalizationPreferences implements Freezable {
if (isFrozen()) {
throw new UnsupportedOperationException("Attempt to modify immutable object");
}
- if (dateFormats == null) dateFormats = new Object[NONE+1][NONE+1];
+ if (dateFormats == null) {
+ dateFormats = new Object[DF_LIMIT][DF_LIMIT];
+ }
// test the format to make sure it won't throw an error later
new SimpleDateFormat(formatPattern, getDateLocale());
dateFormats[dateStyle][timeStyle] = formatPattern; // for safety
@@ -600,7 +893,7 @@ public class GlobalizationPreferences implements Freezable {
result = (DateFormat) temp;
} else {
result = new SimpleDateFormat((String)temp, getDateLocale());
- }
+ }
}
if (result != null) {
result = (DateFormat) result.clone(); // clone for safety
@@ -609,9 +902,9 @@ public class GlobalizationPreferences implements Freezable {
// In the case of date formats, we don't have to look at more than one
// locale. May be different for other cases
// TODO Make this one function.
- if (timeStyle == NONE) {
+ if (timeStyle == DF_NONE) {
result = DateFormat.getDateInstance(getCalendar(), dateStyle, getDateLocale());
- } else if (dateStyle == NONE) {
+ } else if (dateStyle == DF_NONE) {
result = DateFormat.getTimeInstance(getCalendar(), timeStyle, getDateLocale());
} else {
result = DateFormat.getDateTimeInstance(getCalendar(), dateStyle, timeStyle, getDateLocale());
@@ -626,7 +919,7 @@ public class GlobalizationPreferences implements Freezable {
throw ex;
}
}
-
+
/**
* Gets a number format according to the current settings. If
* there is an explicit (non-null) number format set, a copy of
@@ -647,11 +940,11 @@ public class GlobalizationPreferences implements Freezable {
result = (NumberFormat) temp;
} else {
result = new DecimalFormat((String)temp, new DecimalFormatSymbols(getDateLocale()));
- }
+ }
}
if (result != null) {
result = (NumberFormat) result.clone(); // clone for safety (later optimize)
- if (style == CURRENCY) {
+ if (style == NF_CURRENCY) {
result.setCurrency(getCurrency());
}
return result;
@@ -659,18 +952,18 @@ public class GlobalizationPreferences implements Freezable {
// In the case of date formats, we don't have to look at more than one
// locale. May be different for other cases
switch (style) {
- case NUMBER: return NumberFormat.getInstance(getNumberLocale());
- case SCIENTIFIC: return NumberFormat.getScientificInstance(getNumberLocale());
- case INTEGER: return NumberFormat.getIntegerInstance(getNumberLocale());
- case PERCENT: return NumberFormat.getPercentInstance(getNumberLocale());
- case CURRENCY: result = NumberFormat.getCurrencyInstance(getNumberLocale());
+ case NF_NUMBER: return NumberFormat.getInstance(getNumberLocale());
+ case NF_SCIENTIFIC: return NumberFormat.getScientificInstance(getNumberLocale());
+ case NF_INTEGER: return NumberFormat.getIntegerInstance(getNumberLocale());
+ case NF_PERCENT: return NumberFormat.getPercentInstance(getNumberLocale());
+ case NF_CURRENCY: result = NumberFormat.getCurrencyInstance(getNumberLocale());
result.setCurrency(getCurrency());
return result;
}
} catch (RuntimeException e) {}
throw new IllegalArgumentException(); // fix later
}
-
+
/**
* Sets a number format explicitly. Overrides the number locale
* and the general locale settings.
@@ -683,11 +976,13 @@ public class GlobalizationPreferences implements Freezable {
if (isFrozen()) {
throw new UnsupportedOperationException("Attempt to modify immutable object");
}
- if (numberFormats == null) numberFormats = new Object[NUMBER_LIMIT];
+ if (numberFormats == null) {
+ numberFormats = new Object[NF_LIMIT];
+ }
numberFormats[style] = (NumberFormat) format.clone(); // for safety
return this;
}
-
+
/**
* Sets a number format explicitly. Overrides the number locale
* and the general locale settings.
@@ -699,7 +994,9 @@ public class GlobalizationPreferences implements Freezable {
if (isFrozen()) {
throw new UnsupportedOperationException("Attempt to modify immutable object");
}
- if (numberFormats == null) numberFormats = new Object[NUMBER_LIMIT];
+ if (numberFormats == null) {
+ numberFormats = new Object[NF_LIMIT];
+ }
// check to make sure it compiles
new DecimalFormat((String)formatPattern, new DecimalFormatSymbols(getDateLocale()));
numberFormats[style] = formatPattern; // for safety
@@ -719,6 +1016,7 @@ public class GlobalizationPreferences implements Freezable {
territory = null;
calendar = null;
collator = null;
+ breakIterators = null;
timezone = null;
currency = null;
dateFormats = null;
@@ -728,7 +1026,7 @@ public class GlobalizationPreferences implements Freezable {
locales = null;
return this;
}
-
+
/**
* This function can be overridden by subclasses to use different heuristics.
* @internal
@@ -755,8 +1053,12 @@ public class GlobalizationPreferences implements Freezable {
if (script.length() != 0) {
result = (String) language_territory_hack_map.get(language + "_" + script);
}
- if (result == null) result = (String) language_territory_hack_map.get(language);
- if (result == null) result = "US"; // need *some* default
+ if (result == null) {
+ result = (String) language_territory_hack_map.get(language);
+ }
+ if (result == null) {
+ result = "US"; // need *some* default
+ }
return result;
}
@@ -793,6 +1095,30 @@ public class GlobalizationPreferences implements Freezable {
return Collator.getInstance(getLocale(0));
}
+ protected BreakIterator guessBreakIterator(int type) {
+ BreakIterator bitr = null;
+ switch (type) {
+ case BI_CHARACTER:
+ bitr = BreakIterator.getCharacterInstance(getLocale(0));
+ break;
+ case BI_TITLE:
+ bitr = BreakIterator.getTitleInstance(getLocale(0));
+ break;
+ case BI_WORD:
+ bitr = BreakIterator.getWordInstance(getLocale(0));
+ break;
+ case BI_LINE:
+ bitr = BreakIterator.getLineInstance(getLocale(0));
+ break;
+ case BI_SENTENCE:
+ bitr = BreakIterator.getSentenceInstance(getLocale(0));
+ break;
+ default:
+ throw new IllegalArgumentException("Unknown break iterator type");
+ }
+ return bitr;
+ }
+
/**
* This function can be overridden by subclasses to use different heuristics.
* It MUST return a 'safe' value,
@@ -837,25 +1163,26 @@ public class GlobalizationPreferences implements Freezable {
// TODO add better API
return Calendar.getInstance(new ULocale("und-" + getTerritory()));
}
-
+
// PRIVATES
-
+
private Object locales;
private String territory;
private Currency currency;
private TimeZone timezone;
private Calendar calendar;
private Collator collator;
-
+ private BreakIterator[] breakIterators;
+
private ULocale dateLocale;
private Object[][] dateFormats;
private ULocale numberLocale;
private Object[] numberFormats;
-
+
{
reset();
}
-
+
/** WARNING: All of this data is temporary, until we start importing from CLDR!!!
*
*/
@@ -1014,13 +1341,13 @@ public class GlobalizationPreferences implements Freezable {
{"syr", "SY"},
{"tig", "ER"},
{"tt", "RU"},
- {"wal", "ET"}, };
+ {"wal", "ET"}, };
static {
for (int i = 0; i < language_territory_hack.length; ++i) {
language_territory_hack_map.put(language_territory_hack[i][0],language_territory_hack[i][1]);
}
}
-
+
static final Map territory_tzid_hack_map = new HashMap();
static final String[][] territory_tzid_hack = {
{"AQ", "Antarctica/McMurdo"},
@@ -1052,7 +1379,7 @@ public class GlobalizationPreferences implements Freezable {
{"MH", "Pacific/Majuro"},
{"MN", "Asia/Ulaanbaatar"},
{"SJ", "Arctic/Longyearbyen"},
- {"UM", "Pacific/Midway"},
+ {"UM", "Pacific/Midway"},
};
static {
for (int i = 0; i < territory_tzid_hack.length; ++i) {