summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/text/DateFormatSymbolsTest.java2
-rw-r--r--luni/src/main/java/java/text/DateFormatSymbols.java9
-rw-r--r--luni/src/main/java/java/text/DecimalFormatSymbols.java1
-rw-r--r--luni/src/main/java/libcore/icu/ICU.java2
-rw-r--r--luni/src/main/java/libcore/icu/LocaleData.java25
-rw-r--r--luni/src/main/native/libcore_icu_ICU.cpp22
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");
}