diff options
6 files changed, 38 insertions, 23 deletions
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/DateFormatSymbolsTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/DateFormatSymbolsTest.java index 9fe3681..70e41a2 100644 --- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/DateFormatSymbolsTest.java +++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/DateFormatSymbolsTest.java @@ -88,7 +88,7 @@ public class DateFormatSymbolsTest extends junit.framework.TestCase { Locale locale = new Locale("not exist language", "not exist country"); DateFormatSymbols symbols = DateFormatSymbols.getInstance(locale); - assertNotNull(symbols); + assertEquals(DateFormatSymbols.getInstance(Locale.ROOT), symbols); } /** diff --git a/luni/src/main/java/java/text/DateFormatSymbols.java b/luni/src/main/java/java/text/DateFormatSymbols.java index 0d33d75..54a1a3f 100644 --- a/luni/src/main/java/java/text/DateFormatSymbols.java +++ b/luni/src/main/java/java/text/DateFormatSymbols.java @@ -102,7 +102,7 @@ public class DateFormatSymbols implements Serializable, Cloneable { * the locale. */ public DateFormatSymbols(Locale locale) { - this.locale = locale; + this.locale = LocaleData.mapInvalidAndNullLocales(locale); this.localPatternChars = SimpleDateFormat.PATTERN_CHARS; this.localeData = LocaleData.get(locale); @@ -152,7 +152,12 @@ public class DateFormatSymbols implements Serializable, Cloneable { private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { ois.defaultReadObject(); - this.localeData = LocaleData.get(locale); + + // NOTE: We don't serialize the locale we were created with, so we can't + // get back the localeData object we want. This is broken for callers that + // access this field directly (i.e, SimpleDateFormat). We should ideally + // have serialized the locale we were created with. See b/16502916. + this.localeData = LocaleData.get(Locale.getDefault()); } private void writeObject(ObjectOutputStream oos) throws IOException { diff --git a/luni/src/main/java/java/text/DecimalFormatSymbols.java b/luni/src/main/java/java/text/DecimalFormatSymbols.java index 1611594..6e25c1b 100644 --- a/luni/src/main/java/java/text/DecimalFormatSymbols.java +++ b/luni/src/main/java/java/text/DecimalFormatSymbols.java @@ -81,6 +81,7 @@ public class DecimalFormatSymbols implements Cloneable, Serializable { * the locale. */ public DecimalFormatSymbols(Locale locale) { + locale = LocaleData.mapInvalidAndNullLocales(locale); LocaleData localeData = LocaleData.get(locale); this.zeroDigit = localeData.zeroDigit; this.digit = '#'; diff --git a/luni/src/main/java/libcore/icu/ICU.java b/luni/src/main/java/libcore/icu/ICU.java index bb57f49..06e2205 100644 --- a/luni/src/main/java/libcore/icu/ICU.java +++ b/luni/src/main/java/libcore/icu/ICU.java @@ -432,7 +432,7 @@ public final class ICU { private static native String[] getISOLanguagesNative(); private static native String[] getISOCountriesNative(); - static native boolean initLocaleDataNative(String locale, LocaleData result); + static native boolean initLocaleDataNative(String languageTag, LocaleData result); /** * Takes a BCP-47 language tag (Locale.toLanguageTag()). e.g. en-US, not en_US diff --git a/luni/src/main/java/libcore/icu/LocaleData.java b/luni/src/main/java/libcore/icu/LocaleData.java index 845ba32..ec05b53 100644 --- a/luni/src/main/java/libcore/icu/LocaleData.java +++ b/luni/src/main/java/libcore/icu/LocaleData.java @@ -112,27 +112,36 @@ public final class LocaleData { private LocaleData() { } + public static Locale mapInvalidAndNullLocales(Locale locale) { + if (locale == null) { + return Locale.getDefault(); + } + + if ("und".equals(locale.toLanguageTag())) { + return Locale.ROOT; + } + + return locale; + } + /** * Returns a shared LocaleData for the given locale. */ public static LocaleData get(Locale locale) { - if (locale == null) { - locale = Locale.getDefault(); - } - String localeName = locale.toString(); + final String languageTag = locale.toLanguageTag(); synchronized (localeDataCache) { - LocaleData localeData = localeDataCache.get(localeName); + LocaleData localeData = localeDataCache.get(languageTag); if (localeData != null) { return localeData; } } LocaleData newLocaleData = initLocaleData(locale); synchronized (localeDataCache) { - LocaleData localeData = localeDataCache.get(localeName); + LocaleData localeData = localeDataCache.get(languageTag); if (localeData != null) { return localeData; } - localeDataCache.put(localeName, newLocaleData); + localeDataCache.put(languageTag, newLocaleData); return newLocaleData; } } @@ -171,7 +180,7 @@ public final class LocaleData { private static LocaleData initLocaleData(Locale locale) { LocaleData localeData = new LocaleData(); - if (!ICU.initLocaleDataNative(locale.toString(), localeData)) { + if (!ICU.initLocaleDataNative(locale.toLanguageTag(), localeData)) { throw new AssertionError("couldn't initialize LocaleData for locale " + locale); } diff --git a/luni/src/main/native/libcore_icu_ICU.cpp b/luni/src/main/native/libcore_icu_ICU.cpp index 733bf38..df26b39 100644 --- a/luni/src/main/native/libcore_icu_ICU.cpp +++ b/luni/src/main/native/libcore_icu_ICU.cpp @@ -513,16 +513,16 @@ static bool getYesterdayTodayAndTomorrow(JNIEnv* env, jobject localeData, const return true; } -static jboolean ICU_initLocaleDataNative(JNIEnv* env, jclass, jstring javaLocaleName, jobject localeData) { - ScopedUtfChars localeName(env, javaLocaleName); - if (localeName.c_str() == NULL) { +static jboolean ICU_initLocaleDataNative(JNIEnv* env, jclass, jstring javaLanguageTag, jobject localeData) { + ScopedUtfChars languageTag(env, javaLanguageTag); + if (languageTag.c_str() == NULL) { return JNI_FALSE; } - if (localeName.size() >= ULOC_FULLNAME_CAPACITY) { + if (languageTag.size() >= ULOC_FULLNAME_CAPACITY) { return JNI_FALSE; // ICU has a fixed-length limit. } - ScopedIcuLocale icuLocale(env, javaLocaleName); + ScopedIcuLocale icuLocale(env, javaLanguageTag); if (!icuLocale.valid()) { return JNI_FALSE; } @@ -530,27 +530,27 @@ static jboolean ICU_initLocaleDataNative(JNIEnv* env, jclass, jstring javaLocale // Get the DateTimePatterns. UErrorCode status = U_ZERO_ERROR; bool foundDateTimePatterns = false; - for (LocaleNameIterator it(localeName.c_str(), status); it.HasNext(); it.Up()) { + for (LocaleNameIterator it(icuLocale.locale().getBaseName(), status); it.HasNext(); it.Up()) { if (getDateTimePatterns(env, localeData, it.Get())) { foundDateTimePatterns = true; break; } } if (!foundDateTimePatterns) { - ALOGE("Couldn't find ICU DateTimePatterns for %s", localeName.c_str()); + ALOGE("Couldn't find ICU DateTimePatterns for %s", languageTag.c_str()); return JNI_FALSE; } // Get the "Yesterday", "Today", and "Tomorrow" strings. bool foundYesterdayTodayAndTomorrow = false; - for (LocaleNameIterator it(localeName.c_str(), status); it.HasNext(); it.Up()) { + for (LocaleNameIterator it(icuLocale.locale().getBaseName(), status); it.HasNext(); it.Up()) { if (getYesterdayTodayAndTomorrow(env, localeData, icuLocale.locale(), it.Get())) { foundYesterdayTodayAndTomorrow = true; break; } } if (!foundYesterdayTodayAndTomorrow) { - ALOGE("Couldn't find ICU yesterday/today/tomorrow for %s", localeName.c_str()); + ALOGE("Couldn't find ICU yesterday/today/tomorrow for %s", languageTag.c_str()); return JNI_FALSE; } @@ -621,14 +621,14 @@ static jboolean ICU_initLocaleDataNative(JNIEnv* env, jclass, jstring javaLocale setNumberPatterns(env, localeData, icuLocale.locale()); setDecimalFormatSymbolsData(env, localeData, icuLocale.locale()); - jstring countryCode = env->NewStringUTF(Locale::createFromName(localeName.c_str()).getCountry()); + jstring countryCode = env->NewStringUTF(icuLocale.locale().getCountry()); jstring internationalCurrencySymbol = ICU_getCurrencyCode(env, NULL, countryCode); env->DeleteLocalRef(countryCode); countryCode = NULL; jstring currencySymbol = NULL; if (internationalCurrencySymbol != NULL) { - currencySymbol = ICU_getCurrencySymbol(env, NULL, javaLocaleName, internationalCurrencySymbol); + currencySymbol = ICU_getCurrencySymbol(env, NULL, javaLanguageTag, internationalCurrencySymbol); } else { internationalCurrencySymbol = env->NewStringUTF("XXX"); } |