diff options
Diffstat (limited to 'luni')
-rw-r--r-- | luni/src/main/java/java/util/Calendar.java | 2 | ||||
-rw-r--r-- | luni/src/main/java/java/util/Currency.java | 140 | ||||
-rw-r--r-- | luni/src/main/java/java/util/Locale.java | 139 |
3 files changed, 115 insertions, 166 deletions
diff --git a/luni/src/main/java/java/util/Calendar.java b/luni/src/main/java/java/util/Calendar.java index 49a8c3f..3d1f4ad 100644 --- a/luni/src/main/java/java/util/Calendar.java +++ b/luni/src/main/java/java/util/Calendar.java @@ -691,7 +691,7 @@ public abstract class Calendar implements Serializable, Cloneable, // .getTimeZone(timezone.getID()), locale); // setFirstDayOfWeek(icuCalendar.getFirstDayOfWeek()); // setMinimalDaysInFirstWeek(icuCalendar.getMinimalDaysInFirstWeek()); - ResourceBundle bundle = Locale.getBundle("Locale", locale); //$NON-NLS-1$ + ResourceBundle bundle = com.ibm.icu4jni.util.Resources.getLocaleInstance(locale); setFirstDayOfWeek(((Integer) bundle.getObject("First_Day")).intValue()); //$NON-NLS-1$ setMinimalDaysInFirstWeek(((Integer) bundle.getObject("Minimal_Days")) //$NON-NLS-1$ .intValue()); diff --git a/luni/src/main/java/java/util/Currency.java b/luni/src/main/java/java/util/Currency.java index 79de49d..1673455 100644 --- a/luni/src/main/java/java/util/Currency.java +++ b/luni/src/main/java/java/util/Currency.java @@ -18,10 +18,14 @@ package java.util; // BEGIN android-added +import com.ibm.icu4jni.util.Resources; +import java.util.logging.Logger; import org.apache.harmony.luni.util.Msg; // END android-added +import java.security.AccessController; import java.io.Serializable; +import java.security.PrivilegedAction; /** * This class represents a currency as identified in the ISO 4217 currency @@ -31,25 +35,36 @@ public final class Currency implements Serializable { private static final long serialVersionUID = -158308464356906721L; - private static Hashtable<String, Currency> codesToCurrencies = new Hashtable<String, Currency>(); + private static final Hashtable<String, Currency> codesToCurrencies = new Hashtable<String, Currency>(); - private String currencyCode; + private final String currencyCode; // BEGIN android-added - private static String currencyVars = "EURO, HK, PREEURO"; //$NON-NLS-1$ - + // TODO: this isn't set if we're restored from serialized form, + // so getDefaultFractionDigits always returns 0! private transient int defaultFractionDigits; // END android-added - /** - * @param currencyCode - */ private Currency(String currencyCode) { + // BEGIN android-changed this.currencyCode = currencyCode; + + // In some places the code XXX is used as the fall back currency. + // The RI returns -1, but ICU defaults to 2 for unknown currencies. + if (currencyCode.equals("XXX")) { + this.defaultFractionDigits = -1; + return; + } + + this.defaultFractionDigits = Resources.getCurrencyFractionDigitsNative(currencyCode); + if (defaultFractionDigits < 0) { + throw new IllegalArgumentException(Msg.getString("K0322", currencyCode)); + } + // END android-changed } /** - * Returns the {@code Currency} instance for this currency code. + * Returns the {@code Currency} instance for the given currency code. * <p> * * @param currencyCode @@ -61,29 +76,14 @@ public final class Currency implements Serializable { * code. */ public static Currency getInstance(String currencyCode) { + // BEGIN android-changed Currency currency = codesToCurrencies.get(currencyCode); - if (currency == null) { - // BEGIN android-added - ResourceBundle bundle = Locale.getBundle( - "ISO4CurrenciesToDigits", Locale.getDefault()); //$NON-NLS-1$ currency = new Currency(currencyCode); - - String defaultFractionDigits = null; - try { - defaultFractionDigits = bundle.getString(currencyCode); - } catch (MissingResourceException e) { - throw new IllegalArgumentException( - org.apache.harmony.luni.util.Msg.getString( - "K0322", currencyCode)); //$NON-NLS-1$ - } - currency.defaultFractionDigits = Integer - .parseInt(defaultFractionDigits); - // END android-added codesToCurrencies.put(currencyCode, currency); } - return currency; + // END android-changed } /** @@ -98,38 +98,20 @@ public final class Currency implements Serializable { */ public static Currency getInstance(Locale locale) { // BEGIN android-changed - // com.ibm.icu.util.Currency currency = null; - // try { - // currency = com.ibm.icu.util.Currency.getInstance(locale); - // } catch (IllegalArgumentException e) { - // return null; - // } - // if (currency == null) { - // throw new IllegalArgumentException(locale.getCountry()); - // } - // String currencyCode = currency.getCurrencyCode(); String country = locale.getCountry(); String variant = locale.getVariant(); - if (!variant.equals("") && currencyVars.indexOf(variant) > -1) { //$NON-NLS-1$ - country = country + "_" + variant; //$NON-NLS-1$ - } - - ResourceBundle bundle = Locale.getBundle( - "ISO4Currencies", Locale.getDefault()); //$NON-NLS-1$ - String currencyCode = null; - try { - currencyCode = bundle.getString(country); - } catch (MissingResourceException e) { - throw new IllegalArgumentException(Msg.getString( - "K0323", locale.toString())); //$NON-NLS-1$ + if (variant.length() > 0 && "EURO, HK, PREEURO".indexOf(variant) != -1) { + country = country + "_" + variant; } - // END android-changed - if (currencyCode.equals("None")) { //$NON-NLS-1$ + String currencyCode = com.ibm.icu4jni.util.Resources.getCurrencyCodeNative(country); + if (currencyCode == null) { + throw new IllegalArgumentException(Msg.getString("K0323", locale.toString())); + } else if (currencyCode.equals("None")) { return null; } - return getInstance(currencyCode); + // END android-changed } /** @@ -176,40 +158,38 @@ public final class Currency implements Serializable { * locale. */ public String getSymbol(Locale locale) { - if (locale.getCountry().equals("")) { //$NON-NLS-1$ + // BEGIN android-changed + if (locale.getCountry().length() == 0) { return currencyCode; } - // BEGIN android-changed - // return com.ibm.icu.util.Currency.getInstance(currencyCode).getSymbol(locale); - // check in the Locale bundle first, if the local has the same currency - ResourceBundle bundle = Locale.getBundle("Locale", locale); //$NON-NLS-1$ - if (((String) bundle.getObject("IntCurrencySymbol")) //$NON-NLS-1$ - .equals(currencyCode)) { - return (String) bundle.getObject("CurrencySymbol"); //$NON-NLS-1$ + // Check the Locale bundle first, in case the locale has the same currency. + ResourceBundle localeBundle = com.ibm.icu4jni.util.Resources.getLocaleInstance(locale); + if (localeBundle.getString("IntCurrencySymbol").equals(currencyCode)) { + return localeBundle.getString("CurrencySymbol"); } - // search for a Currency bundle - bundle = null; + // check if the currency bundle for this locale has an entry for this currency try { - bundle = Locale.getBundle("Currency", locale); //$NON-NLS-1$ - } catch (MissingResourceException e) { - return currencyCode; - } + ResourceBundle currencyBundle = getCurrencyBundle(locale); + + // is the bundle found for a different country? (for instance the + // default locale's currency bundle) + if (!currencyBundle.getLocale().getCountry().equals(locale.getCountry())) { + // TODO: the fact I never see output from this when running the tests suggests we + // don't have a test for this. Does it ever even happen? If it does, can we just + // ask ICU a slightly different question to get the behavior we want? + Logger.global.info("currencyBundle " + currencyBundle + " for " + locale + + " came back with locale " + currencyBundle.getLocale()); + return currencyCode; + } - // is the bundle found for a different country? (for instance the - // default locale's currency bundle) - if (!bundle.getLocale().getCountry().equals(locale.getCountry())) { + // Return the currency bundle's value, or currencyCode. + String result = (String) currencyBundle.handleGetObject(currencyCode); + return (result != null) ? result : currencyCode; + } catch (MissingResourceException e) { return currencyCode; } - - // check if the currency bundle for this locale - // has an entry for this currency - String result = (String) bundle.handleGetObject(currencyCode); - if (result != null) { - return result; - } - return currencyCode; // END android-changed } @@ -241,4 +221,14 @@ public final class Currency implements Serializable { private Object readResolve() { return getInstance(currencyCode); } + + // TODO: remove this in favor of direct access (and no ResourceBundle cruft). + private static ResourceBundle getCurrencyBundle(final Locale locale) { + return AccessController.doPrivileged(new PrivilegedAction<ResourceBundle>() { + public ResourceBundle run() { + String bundle = "org.apache.harmony.luni.internal.locale.Currency"; + return ResourceBundle.getBundle(bundle, locale); + } + }); + } } diff --git a/luni/src/main/java/java/util/Locale.java b/luni/src/main/java/java/util/Locale.java index 1e97d3c..5337e48 100644 --- a/luni/src/main/java/java/util/Locale.java +++ b/luni/src/main/java/java/util/Locale.java @@ -25,7 +25,6 @@ import java.io.ObjectOutputStream; import java.io.ObjectStreamField; import java.io.Serializable; import java.security.AccessController; -import java.security.PrivilegedAction; // import java.util.zip.ZipEntry; // import java.util.zip.ZipFile; @@ -200,6 +199,7 @@ public final class Locale implements Cloneable, Serializable { private transient String countryCode; private transient String languageCode; private transient String variantCode; + private transient String cachedToStringResult; // BEGIN android-removed // private transient ULocale uLocale; @@ -412,29 +412,18 @@ public final class Locale implements Cloneable, Serializable { * the {@code Locale} for which the display name is retrieved. * @return a country name. */ - public String getDisplayCountry(Locale locale) { + public String getDisplayCountry(Locale locale) { // BEGIN android-changed - // return ULocale.forLocale(this).getDisplayCountry(ULocale.forLocale(locale)); if (countryCode.length() == 0) { return countryCode; } - try { - // First try the specified locale - ResourceBundle bundle = getBundle("Country", locale); //$NON-NLS-1$ - String result = bundle.getString(this.toString()); - if (result != null) { - return result; - } - // Now use the default locale - if (locale != Locale.getDefault()) { - bundle = getBundle("Country", Locale.getDefault()); //$NON-NLS-1$ - } - return bundle.getString(countryCode); - } catch (MissingResourceException e) { - return countryCode; + String result = Resources.getDisplayCountryNative(toString(), locale.toString()); + if (result == null) { // TODO: do we need to do this, or does ICU do it for us? + result = Resources.getDisplayCountryNative(toString(), Locale.getDefault().toString()); } + return result; // END android-changed - } + } /** * Gets the full language name in the default {@code Locale} for the language code @@ -456,29 +445,18 @@ public final class Locale implements Cloneable, Serializable { * the {@code Locale} for which the display name is retrieved. * @return a language name. */ - public String getDisplayLanguage(Locale locale) { + public String getDisplayLanguage(Locale locale) { // BEGIN android-changed - // return ULocale.forLocale(this).getDisplayLanguage(ULocale.forLocale(locale)); if (languageCode.length() == 0) { return languageCode; } - try { - // First try the specified locale - ResourceBundle bundle = getBundle("Language", locale); //$NON-NLS-1$ - String result = bundle.getString(this.toString()); - if (result != null) { - return result; - } - // Now use the default locale - if (locale != Locale.getDefault()) { - bundle = getBundle("Language", Locale.getDefault()); //$NON-NLS-1$ - } - return bundle.getString(languageCode); - } catch (MissingResourceException e) { - return languageCode; + String result = Resources.getDisplayLanguageNative(toString(), locale.toString()); + if (result == null) { // TODO: do we need to do this, or does ICU do it for us? + result = Resources.getDisplayLanguageNative(toString(), Locale.getDefault().toString()); } + return result; // END android-changed - } + } /** * Gets the full language, country, and variant names in the default {@code Locale} @@ -547,29 +525,18 @@ public final class Locale implements Cloneable, Serializable { * the {@code Locale} for which the display name is retrieved. * @return a variant name. */ - public String getDisplayVariant(Locale locale) { + public String getDisplayVariant(Locale locale) { // BEGIN android-changed - // return ULocale.forLocale(this).getDisplayVariant(ULocale.forLocale(locale)); if (variantCode.length() == 0) { return variantCode; } - try { - // First try the specified locale - ResourceBundle bundle = getBundle("Variant", locale); //$NON-NLS-1$ - String result = bundle.getString(this.toString()); - if (result != null) { - return result; - } - // Now use the default locale - if (locale != Locale.getDefault()) { - bundle = getBundle("Variant", Locale.getDefault()); //$NON-NLS-1$ - } - return bundle.getString(variantCode); - } catch (MissingResourceException e) { - return variantCode; + String result = Resources.getDisplayVariantNative(toString(), locale.toString()); + if (result == null) { // TODO: do we need to do this, or does ICU do it for us? + result = Resources.getDisplayVariantNative(toString(), Locale.getDefault().toString()); } + return result; // END android-changed - } + } /** * Gets the three letter ISO country code which corresponds to the country @@ -579,16 +546,14 @@ public final class Locale implements Cloneable, Serializable { * @throws MissingResourceException * if there is no matching three letter ISO country code. */ - public String getISO3Country() throws MissingResourceException { + public String getISO3Country() throws MissingResourceException { // BEGIN android-changed - // return ULocale.forLocale(this).getISO3Country(); if (countryCode.length() == 0) { - return ""; //$NON-NLS-1$ + return countryCode; } - ResourceBundle bundle = getBundle("ISO3Countries", this); //$NON-NLS-1$ - return bundle.getString(this.toString()); + return Resources.getISO3CountryNative(toString()); // END android-changed - } + } /** * Gets the three letter ISO language code which corresponds to the language @@ -598,16 +563,14 @@ public final class Locale implements Cloneable, Serializable { * @throws MissingResourceException * if there is no matching three letter ISO language code. */ - public String getISO3Language() throws MissingResourceException { + public String getISO3Language() throws MissingResourceException { // BEGIN android-changed - // return ULocale.forLocale(this).getISO3Language(); if (languageCode.length() == 0) { - return ""; //$NON-NLS-1$ + return languageCode; } - ResourceBundle bundle = getBundle("ISO3Languages", this); //$NON-NLS-1$ - return bundle.getString(this.toString()); + return Resources.getISO3LanguageNative(toString()); // END android-changed - } + } /** * Gets the list of two letter ISO country codes which can be used as the @@ -617,7 +580,6 @@ public final class Locale implements Cloneable, Serializable { */ public static String[] getISOCountries() { // BEGIN android-changed - // return ULocale.getISOCountries(); return Resources.getISOCountries(); // END android-changed } @@ -628,12 +590,11 @@ public final class Locale implements Cloneable, Serializable { * * @return an array of strings. */ - public static String[] getISOLanguages() { + public static String[] getISOLanguages() { // BEGIN android-changed - // return ULocale.getISOLanguages(); return Resources.getISOLanguages(); // END android-changed - } + } /** * Gets the language code for this {@code Locale} or the empty string of no language @@ -646,7 +607,7 @@ public final class Locale implements Cloneable, Serializable { } /** - * Gets the variant code for this {@code Locale} or an empty {@code String} of no variant + * Gets the variant code for this {@code Locale} or an empty {@code String} if no variant * was set. * * @return a variant code. @@ -704,34 +665,32 @@ public final class Locale implements Cloneable, Serializable { */ @Override public final String toString() { - StringBuilder result = new StringBuilder(); + String result = cachedToStringResult; + return (result == null) ? (cachedToStringResult = toNewString()) : result; + } + + private String toNewString() { + // The string form of a locale that only has a variant is the empty string. + if (languageCode.length() == 0 && countryCode.length() == 0) { + return ""; + } + // Otherwise, the output format is "ll_cc_variant", where language and country are always + // two letters, but the variant is an arbitrary length. A size of 11 characters has room + // for "en_US_POSIX", the largest "common" value. (In practice, the string form is almost + // always 5 characters: "ll_cc".) + StringBuilder result = new StringBuilder(11); result.append(languageCode); - if (countryCode.length() > 0) { + if (countryCode.length() > 0 || variantCode.length() > 0) { result.append('_'); - result.append(countryCode); } - if (variantCode.length() > 0 && result.length() > 0) { - if (0 == countryCode.length()) { - result.append("__"); //$NON-NLS-1$ - } else { - result.append('_'); - } - result.append(variantCode); + result.append(countryCode); + if (variantCode.length() > 0) { + result.append('_'); } + result.append(variantCode); return result.toString(); } - // BEGIN android-added - static ResourceBundle getBundle(final String clName, final Locale locale) { - return AccessController.doPrivileged(new PrivilegedAction<ResourceBundle>() { - public ResourceBundle run() { - return ResourceBundle.getBundle("org.apache.harmony.luni.internal.locale." //$NON-NLS-1$ - + clName, locale); - } - }); - } - // END android-added - private static final ObjectStreamField[] serialPersistentFields = { new ObjectStreamField("country", String.class), //$NON-NLS-1$ new ObjectStreamField("hashcode", Integer.TYPE), //$NON-NLS-1$ |