summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNarayan Kamath <narayan@google.com>2015-01-16 12:19:52 +0000
committerNarayan Kamath <narayan@google.com>2015-01-21 17:00:07 +0000
commit61908bb6523ff12b53867e7bce15a672eca46e77 (patch)
treef305c34df0e40b5d857f8f23050c05880687eeac
parent1b462a5d4a5cd4f28c9c7b368110128520a84594 (diff)
downloadlibcore-61908bb6523ff12b53867e7bce15a672eca46e77.zip
libcore-61908bb6523ff12b53867e7bce15a672eca46e77.tar.gz
libcore-61908bb6523ff12b53867e7bce15a672eca46e77.tar.bz2
Introduce user.locale [take 2]
This reverts commit 5eba1f238e37e3fef73b492badb950225150cdcf and adds additional code to set user.language / user.region for backwards compatibility. The original commit had a static initialization order bug, so this change reorders static fields so that GRANDFATHERED_TAGS is initialized before the default locale. We also set user.language / user.region for backwards compatibility. The android framework have been changed to pass in user.locale instead of user.language / user.region but we parse that value and set user.language / country for code that still relies on it. bug: 17691569 Change-Id: Ie5e8ffe4bafa3977fea27289f9ffc5100288cab3
-rw-r--r--luni/src/main/java/java/lang/System.java30
-rw-r--r--luni/src/main/java/java/util/Locale.java117
-rw-r--r--luni/src/test/java/libcore/java/util/LocaleTest.java38
3 files changed, 133 insertions, 52 deletions
diff --git a/luni/src/main/java/java/lang/System.java b/luni/src/main/java/java/lang/System.java
index 51674e7..471b35f 100644
--- a/luni/src/main/java/java/lang/System.java
+++ b/luni/src/main/java/java/lang/System.java
@@ -50,6 +50,7 @@ import java.nio.channels.spi.SelectorProvider;
import java.util.AbstractMap;
import java.util.Collections;
import java.util.HashMap;
+import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
@@ -108,6 +109,33 @@ public final class System {
unchangeableSystemProperties = initUnchangeableSystemProperties();
systemProperties = createSystemProperties();
lineSeparator = System.getProperty("line.separator");
+
+ addLegacyLocaleSystemProperties();
+ }
+
+ private static void addLegacyLocaleSystemProperties() {
+ final String locale = getProperty("user.locale", "");
+ if (!locale.isEmpty()) {
+ Locale l = Locale.forLanguageTag(locale);
+ initUnchangeableSystemProperty("user.language", l.getLanguage());
+ initUnchangeableSystemProperty("user.region", l.getCountry());
+ initUnchangeableSystemProperty("user.variant", l.getVariant());
+ } else {
+ // If "user.locale" isn't set we fall back to our old defaults of
+ // language="en" and region="US" (if unset) and don't attempt to set it.
+ // The Locale class will fall back to using user.language and
+ // user.region if unset.
+ final String language = getProperty("user.language", "");
+ final String region = getProperty("user.region", "");
+
+ if (language.isEmpty()) {
+ initUnchangeableSystemProperty("user.language", "en");
+ }
+
+ if (region.isEmpty()) {
+ initUnchangeableSystemProperty("user.region", "US");
+ }
+ }
}
/**
@@ -751,8 +779,6 @@ public final class System {
p.put("java.vm.vendor.url", projectUrl);
p.put("file.encoding", "UTF-8");
- p.put("user.language", "en");
- p.put("user.region", "US");
try {
StructPasswd passwd = Libcore.os.getpwuid(Libcore.os.getuid());
diff --git a/luni/src/main/java/java/util/Locale.java b/luni/src/main/java/java/util/Locale.java
index e509a6e..b1a056a 100644
--- a/luni/src/main/java/java/util/Locale.java
+++ b/luni/src/main/java/java/util/Locale.java
@@ -272,17 +272,77 @@ public final class Locale implements Cloneable, Serializable {
*/
private static final String UNDETERMINED_LANGUAGE = "und";
+
+ /**
+ * Map of grandfathered language tags to their modern replacements.
+ */
+ private static final TreeMap<String, String> GRANDFATHERED_LOCALES;
+
/**
- * The current default locale. It is temporarily assigned to US because we
- * need a default locale to lookup the real default locale.
+ * The default locale, returned by {@code Locale.getDefault()}.
*/
- private static Locale defaultLocale = US;
+ private static Locale defaultLocale;
static {
- String language = System.getProperty("user.language", "en");
- String region = System.getProperty("user.region", "US");
- String variant = System.getProperty("user.variant", "");
- defaultLocale = new Locale(language, region, variant);
+ GRANDFATHERED_LOCALES = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
+
+ // From http://tools.ietf.org/html/bcp47
+ //
+ // grandfathered = irregular ; non-redundant tags registered
+ // / regular ; during the RFC 3066 era
+ // irregular =
+ GRANDFATHERED_LOCALES.put("en-GB-oed", "en-GB-x-oed");
+ GRANDFATHERED_LOCALES.put("i-ami", "ami");
+ GRANDFATHERED_LOCALES.put("i-bnn", "bnn");
+ GRANDFATHERED_LOCALES.put("i-default", "en-x-i-default");
+ GRANDFATHERED_LOCALES.put("i-enochian", "und-x-i-enochian");
+ GRANDFATHERED_LOCALES.put("i-hak", "hak");
+ GRANDFATHERED_LOCALES.put("i-klingon", "tlh");
+ GRANDFATHERED_LOCALES.put("i-lux", "lb");
+ GRANDFATHERED_LOCALES.put("i-mingo", "see-x-i-mingo");
+ GRANDFATHERED_LOCALES.put("i-navajo", "nv");
+ GRANDFATHERED_LOCALES.put("i-pwn", "pwn");
+ GRANDFATHERED_LOCALES.put("i-tao", "tao");
+ GRANDFATHERED_LOCALES.put("i-tay", "tay");
+ GRANDFATHERED_LOCALES.put("i-tsu", "tsu");
+ GRANDFATHERED_LOCALES.put("sgn-BE-FR", "sfb");
+ GRANDFATHERED_LOCALES.put("sgn-BE-NL", "vgt");
+ GRANDFATHERED_LOCALES.put("sgn-CH-DE", "sgg");
+
+ // regular =
+ GRANDFATHERED_LOCALES.put("art-lojban", "jbo");
+ GRANDFATHERED_LOCALES.put("cel-gaulish", "xtg-x-cel-gaulish");
+ GRANDFATHERED_LOCALES.put("no-bok", "nb");
+ GRANDFATHERED_LOCALES.put("no-nyn", "nn");
+ GRANDFATHERED_LOCALES.put("zh-guoyu", "cmn");
+ GRANDFATHERED_LOCALES.put("zh-hakka", "hak");
+ GRANDFATHERED_LOCALES.put("zh-min", "nan-x-zh-min");
+ GRANDFATHERED_LOCALES.put("zh-min-nan", "nan");
+ GRANDFATHERED_LOCALES.put("zh-xiang", "hsn");
+
+ // Initialize the default locale from the system properties.
+ defaultLocale = getDefaultLocaleFromSystemProperties();
+ }
+
+ /**
+ * Returns the default locale from system properties.
+ *
+ * @hide visible for testing.
+ */
+ public static Locale getDefaultLocaleFromSystemProperties() {
+ final String languageTag = System.getProperty("user.locale", "");
+
+ final Locale defaultLocale;
+ if (!languageTag.isEmpty()) {
+ defaultLocale = Locale.forLanguageTag(languageTag);
+ } else {
+ String language = System.getProperty("user.language", "en");
+ String region = System.getProperty("user.region", "US");
+ String variant = System.getProperty("user.variant", "");
+ defaultLocale = new Locale(language, region, variant);
+ }
+
+ return defaultLocale;
}
/**
@@ -2020,49 +2080,6 @@ public final class Locale implements Cloneable, Serializable {
return adjusted;
}
- /**
- * Map of grandfathered language tags to their modern replacements.
- */
- private static final TreeMap<String, String> GRANDFATHERED_LOCALES;
-
- static {
- GRANDFATHERED_LOCALES = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
-
- // From http://tools.ietf.org/html/bcp47
- //
- // grandfathered = irregular ; non-redundant tags registered
- // / regular ; during the RFC 3066 era
- // irregular =
- GRANDFATHERED_LOCALES.put("en-GB-oed", "en-GB-x-oed");
- GRANDFATHERED_LOCALES.put("i-ami", "ami");
- GRANDFATHERED_LOCALES.put("i-bnn", "bnn");
- GRANDFATHERED_LOCALES.put("i-default", "en-x-i-default");
- GRANDFATHERED_LOCALES.put("i-enochian", "und-x-i-enochian");
- GRANDFATHERED_LOCALES.put("i-hak", "hak");
- GRANDFATHERED_LOCALES.put("i-klingon", "tlh");
- GRANDFATHERED_LOCALES.put("i-lux", "lb");
- GRANDFATHERED_LOCALES.put("i-mingo", "see-x-i-mingo");
- GRANDFATHERED_LOCALES.put("i-navajo", "nv");
- GRANDFATHERED_LOCALES.put("i-pwn", "pwn");
- GRANDFATHERED_LOCALES.put("i-tao", "tao");
- GRANDFATHERED_LOCALES.put("i-tay", "tay");
- GRANDFATHERED_LOCALES.put("i-tsu", "tsu");
- GRANDFATHERED_LOCALES.put("sgn-BE-FR", "sfb");
- GRANDFATHERED_LOCALES.put("sgn-BE-NL", "vgt");
- GRANDFATHERED_LOCALES.put("sgn-CH-DE", "sgg");
-
- // regular =
- GRANDFATHERED_LOCALES.put("art-lojban", "jbo");
- GRANDFATHERED_LOCALES.put("cel-gaulish", "xtg-x-cel-gaulish");
- GRANDFATHERED_LOCALES.put("no-bok", "nb");
- GRANDFATHERED_LOCALES.put("no-nyn", "nn");
- GRANDFATHERED_LOCALES.put("zh-guoyu", "cmn");
- GRANDFATHERED_LOCALES.put("zh-hakka", "hak");
- GRANDFATHERED_LOCALES.put("zh-min", "nan-x-zh-min");
- GRANDFATHERED_LOCALES.put("zh-min-nan", "nan");
- GRANDFATHERED_LOCALES.put("zh-xiang", "hsn");
- }
-
private static String convertGrandfatheredTag(String original) {
final String converted = GRANDFATHERED_LOCALES.get(original);
return converted != null ? converted : original;
diff --git a/luni/src/test/java/libcore/java/util/LocaleTest.java b/luni/src/test/java/libcore/java/util/LocaleTest.java
index 15e01a1..c6dd730 100644
--- a/luni/src/test/java/libcore/java/util/LocaleTest.java
+++ b/luni/src/test/java/libcore/java/util/LocaleTest.java
@@ -1165,4 +1165,42 @@ public class LocaleTest extends junit.framework.TestCase {
assertEquals('\u0660', new DecimalFormatSymbols(ar_EG_arab).getZeroDigit());
assertEquals('0', new DecimalFormatSymbols(ar_EG_latn).getZeroDigit());
}
+
+ public void testDefaultLocale() throws Exception {
+ final String userLanguage = System.getProperty("user.language", "");
+ final String userRegion = System.getProperty("user.region", "");
+ final String userLocale = System.getProperty("user.locale", "");
+ try {
+ // Assert that user.locale gets priority.
+ System.setProperty("user.locale", "de-DE");
+ System.setProperty("user.language", "en");
+ System.setProperty("user.region", "US");
+
+ Locale l = Locale.getDefaultLocaleFromSystemProperties();
+ assertEquals("de", l.getLanguage());
+ assertEquals("DE", l.getCountry());
+
+ // Assert that it's parsed as a full language tag.
+ System.setProperty("user.locale", "de-Latn-DE");
+ System.setProperty("user.language", "en");
+ System.setProperty("user.region", "US");
+
+ l = Locale.getDefaultLocaleFromSystemProperties();
+ assertEquals("de", l.getLanguage());
+ assertEquals("DE", l.getCountry());
+ assertEquals("Latn", l.getScript());
+
+ // Assert that we use "und" if we're faced with a bad language tag, and
+ // that we don't end up with a null default locale or an exception.
+ System.setProperty("user.locale", "dexx-Latn-DE");
+
+ l = Locale.getDefaultLocaleFromSystemProperties();
+ assertEquals("und", l.getLanguage());
+ assertEquals("DE", l.getCountry());
+ } finally {
+ System.setProperty("user.language", userLanguage);
+ System.setProperty("user.region", userRegion);
+ System.setProperty("user.locale", userLocale);
+ }
+ }
}