diff options
author | Narayan Kamath <narayan@google.com> | 2015-01-16 12:19:52 +0000 |
---|---|---|
committer | Narayan Kamath <narayan@google.com> | 2015-01-21 17:00:07 +0000 |
commit | 61908bb6523ff12b53867e7bce15a672eca46e77 (patch) | |
tree | f305c34df0e40b5d857f8f23050c05880687eeac | |
parent | 1b462a5d4a5cd4f28c9c7b368110128520a84594 (diff) | |
download | libcore-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.java | 30 | ||||
-rw-r--r-- | luni/src/main/java/java/util/Locale.java | 117 | ||||
-rw-r--r-- | luni/src/test/java/libcore/java/util/LocaleTest.java | 38 |
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); + } + } } |