8221701: Archive constant BaseLocales

Reviewed-by: naoto
This commit is contained in:
Claes Redestad 2019-04-03 17:06:35 +02:00
parent 8cdf747187
commit 5c06e0a912
6 changed files with 188 additions and 113 deletions

View file

@ -32,14 +32,64 @@
package sun.util.locale;
import jdk.internal.misc.VM;
import jdk.internal.vm.annotation.Stable;
import java.lang.ref.SoftReference;
import java.util.StringJoiner;
public final class BaseLocale {
public static final String SEP = "_";
public static @Stable BaseLocale[] constantBaseLocales;
public static final byte ENGLISH = 0,
FRENCH = 1,
GERMAN = 2,
ITALIAN = 3,
JAPANESE = 4,
KOREAN = 5,
CHINESE = 6,
SIMPLIFIED_CHINESE = 7,
TRADITIONAL_CHINESE = 8,
FRANCE = 9,
GERMANY = 10,
ITALY = 11,
JAPAN = 12,
KOREA = 13,
UK = 14,
US = 15,
CANADA = 16,
CANADA_FRENCH = 17,
ROOT = 18,
NUM_CONSTANTS = 19;
static {
VM.initializeFromArchive(BaseLocale.class);
BaseLocale[] baseLocales = constantBaseLocales;
if (baseLocales == null) {
baseLocales = new BaseLocale[NUM_CONSTANTS];
baseLocales[ENGLISH] = createInstance("en", "");
baseLocales[FRENCH] = createInstance("fr", "");
baseLocales[GERMAN] = createInstance("de", "");
baseLocales[ITALIAN] = createInstance("it", "");
baseLocales[JAPANESE] = createInstance("ja", "");
baseLocales[KOREAN] = createInstance("ko", "");
baseLocales[CHINESE] = createInstance("zh", "");
baseLocales[SIMPLIFIED_CHINESE] = createInstance("zh", "CN");
baseLocales[TRADITIONAL_CHINESE] = createInstance("zh", "TW");
baseLocales[FRANCE] = createInstance("fr", "FR");
baseLocales[GERMANY] = createInstance("de", "DE");
baseLocales[ITALY] = createInstance("it", "IT");
baseLocales[JAPAN] = createInstance("ja", "JP");
baseLocales[KOREA] = createInstance("ko", "KR");
baseLocales[UK] = createInstance("en", "GB");
baseLocales[US] = createInstance("en", "US");
baseLocales[CANADA] = createInstance("en", "CA");
baseLocales[CANADA_FRENCH] = createInstance("fr", "CA");
baseLocales[ROOT] = createInstance("", "");
constantBaseLocales = baseLocales;
}
}
private static final Cache CACHE = new Cache();
public static final String SEP = "_";
private final String language;
private final String script;
@ -67,28 +117,53 @@ public final class BaseLocale {
// Called for creating the Locale.* constants. No argument
// validation is performed.
public static BaseLocale createInstance(String language, String region) {
BaseLocale base = new BaseLocale(language, "", region, "", false);
CACHE.put(new Key(base), base);
return base;
private static BaseLocale createInstance(String language, String region) {
return new BaseLocale(language, "", region, "", false);
}
public static BaseLocale getInstance(String language, String script,
String region, String variant) {
if (script == null) {
script = "";
}
if (region == null) {
region = "";
}
if (language == null) {
language = null;
}
if (variant == null) {
variant = "";
}
// Non-allocating for most uses
language = LocaleUtils.toLowerString(language);
region = LocaleUtils.toUpperString(region);
// Check for constant base locales first
if (script.isEmpty() && variant.isEmpty()) {
for (BaseLocale baseLocale : constantBaseLocales) {
if (baseLocale.getLanguage().equals(language)
&& baseLocale.getRegion().equals(region)) {
return baseLocale;
}
}
}
// JDK uses deprecated ISO639.1 language codes for he, yi and id
if (language != null) {
if (LocaleUtils.caseIgnoreMatch(language, "he")) {
if (!language.isEmpty()) {
if (language.equals("he")) {
language = "iw";
} else if (LocaleUtils.caseIgnoreMatch(language, "yi")) {
} else if (language.equals("yi")) {
language = "ji";
} else if (LocaleUtils.caseIgnoreMatch(language, "id")) {
} else if (language.equals("id")) {
language = "in";
}
}
Key key = new Key(language, script, region, variant, false);
BaseLocale baseLocale = CACHE.get(key);
return baseLocale;
return Cache.CACHE.get(key);
}
public String getLanguage() {
@ -171,46 +246,8 @@ public final class BaseLocale {
private final boolean normalized;
private final int hash;
/**
* Creates a Key. language and region must be normalized
* (intern'ed in the proper case).
*/
private Key(BaseLocale locale) {
this.holder = locale;
this.holderRef = null;
this.normalized = true;
String language = locale.getLanguage();
String region = locale.getRegion();
assert LocaleUtils.toLowerString(language).intern() == language
&& LocaleUtils.toUpperString(region).intern() == region
&& locale.getVariant() == ""
&& locale.getScript() == "";
int h = language.hashCode();
if (region != "") {
int len = region.length();
for (int i = 0; i < len; i++) {
h = 31 * h + LocaleUtils.toLower(region.charAt(i));
}
}
hash = h;
}
private Key(String language, String script, String region,
String variant, boolean normalize) {
if (language == null) {
language = "";
}
if (script == null) {
script = "";
}
if (region == null) {
region = "";
}
if (variant == null) {
variant = "";
}
BaseLocale locale = new BaseLocale(language, script, region, variant, normalize);
this.normalized = normalize;
if (normalized) {
@ -291,6 +328,8 @@ public final class BaseLocale {
private static class Cache extends LocaleObjectCache<Key, BaseLocale> {
private static final Cache CACHE = new Cache();
public Cache() {
}

View file

@ -206,19 +206,19 @@ public final class LocaleUtils {
return true;
}
static boolean isEmpty(String str) {
public static boolean isEmpty(String str) {
return str == null || str.isEmpty();
}
static boolean isEmpty(Set<?> set) {
public static boolean isEmpty(Set<?> set) {
return set == null || set.isEmpty();
}
static boolean isEmpty(Map<?, ?> map) {
public static boolean isEmpty(Map<?, ?> map) {
return map == null || map.isEmpty();
}
static boolean isEmpty(List<?> list) {
public static boolean isEmpty(List<?> list) {
return list == null || list.isEmpty();
}
}

View file

@ -491,8 +491,7 @@ public class JRELocaleProviderAdapter extends LocaleProviderAdapter implements R
*/
private static class AvailableJRELocales {
private static final Locale[] localeList = createAvailableLocales();
private AvailableJRELocales() {
}
private AvailableJRELocales() {}
}
private static Locale[] createAvailableLocales() {
@ -535,7 +534,7 @@ public class JRELocaleProviderAdapter extends LocaleProviderAdapter implements R
public boolean isSupportedProviderLocale(Locale locale, Set<String> langtags) {
if (Locale.ROOT.equals(locale)) {
return true;
}
}
locale = locale.stripExtensions();
if (langtags.contains(locale.toLanguageTag())) {

View file

@ -44,6 +44,7 @@ import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.text.MessageFormat;
import java.text.NumberFormat;
import java.util.Arrays;
import java.util.Calendar;
import java.util.HashSet;
import java.util.LinkedHashSet;
@ -325,7 +326,7 @@ public class LocaleResources {
Set<String> keyset = getZoneIDs();
// Use a LinkedHashSet to preseve the order
Set<String[]> value = new LinkedHashSet<>();
Set<String> tzIds = new HashSet<>(Set.of(TimeZone.getAvailableIDs()));
Set<String> tzIds = new HashSet<>(Arrays.asList(TimeZone.getAvailableIDs()));
for (String key : keyset) {
if (!key.startsWith(TZNB_EXCITY_PREFIX)) {
value.add(rb.getStringArray(key));