8221701: Archive constant BaseLocales
Reviewed-by: naoto
This commit is contained in:
parent
8cdf747187
commit
5c06e0a912
src
hotspot/share/memory
java.base/share/classes
java/util
sun/util/locale
@ -69,6 +69,7 @@ static ArchivableStaticFieldInfo closed_archive_subgraph_entry_fields[] = {
|
||||
{"java/lang/Short$ShortCache", "archivedCache"},
|
||||
{"java/lang/Character$CharacterCache", "archivedCache"},
|
||||
{"java/util/jar/Attributes$Name", "KNOWN_NAMES"},
|
||||
{"sun/util/locale/BaseLocale", "constantBaseLocales"},
|
||||
};
|
||||
// Entry fields for subgraphs archived in the open archive heap region.
|
||||
static ArchivableStaticFieldInfo open_archive_subgraph_entry_fields[] = {
|
||||
|
@ -484,63 +484,111 @@ import sun.util.locale.provider.TimeZoneNameUtility;
|
||||
*/
|
||||
public final class Locale implements Cloneable, Serializable {
|
||||
|
||||
private static final Cache LOCALECACHE = new Cache();
|
||||
/** Useful constant for language.
|
||||
*/
|
||||
public static final Locale ENGLISH;
|
||||
|
||||
/** Useful constant for language.
|
||||
*/
|
||||
public static final Locale ENGLISH = createConstant("en", "");
|
||||
public static final Locale FRENCH;
|
||||
|
||||
/** Useful constant for language.
|
||||
*/
|
||||
public static final Locale FRENCH = createConstant("fr", "");
|
||||
public static final Locale GERMAN;
|
||||
|
||||
/** Useful constant for language.
|
||||
*/
|
||||
public static final Locale GERMAN = createConstant("de", "");
|
||||
public static final Locale ITALIAN;
|
||||
|
||||
/** Useful constant for language.
|
||||
*/
|
||||
public static final Locale ITALIAN = createConstant("it", "");
|
||||
public static final Locale JAPANESE;
|
||||
|
||||
/** Useful constant for language.
|
||||
*/
|
||||
public static final Locale JAPANESE = createConstant("ja", "");
|
||||
public static final Locale KOREAN;
|
||||
|
||||
/** Useful constant for language.
|
||||
*/
|
||||
public static final Locale KOREAN = createConstant("ko", "");
|
||||
public static final Locale CHINESE;
|
||||
|
||||
/** Useful constant for language.
|
||||
*/
|
||||
public static final Locale CHINESE = createConstant("zh", "");
|
||||
public static final Locale SIMPLIFIED_CHINESE;
|
||||
|
||||
/** Useful constant for language.
|
||||
*/
|
||||
public static final Locale SIMPLIFIED_CHINESE = createConstant("zh", "CN");
|
||||
|
||||
/** Useful constant for language.
|
||||
*/
|
||||
public static final Locale TRADITIONAL_CHINESE = createConstant("zh", "TW");
|
||||
public static final Locale TRADITIONAL_CHINESE;
|
||||
|
||||
/** Useful constant for country.
|
||||
*/
|
||||
public static final Locale FRANCE = createConstant("fr", "FR");
|
||||
public static final Locale FRANCE;
|
||||
|
||||
/** Useful constant for country.
|
||||
*/
|
||||
public static final Locale GERMANY = createConstant("de", "DE");
|
||||
public static final Locale GERMANY;
|
||||
|
||||
/** Useful constant for country.
|
||||
*/
|
||||
public static final Locale ITALY = createConstant("it", "IT");
|
||||
public static final Locale ITALY;
|
||||
|
||||
/** Useful constant for country.
|
||||
*/
|
||||
public static final Locale JAPAN = createConstant("ja", "JP");
|
||||
public static final Locale JAPAN;
|
||||
|
||||
/** Useful constant for country.
|
||||
*/
|
||||
public static final Locale KOREA = createConstant("ko", "KR");
|
||||
public static final Locale KOREA;
|
||||
|
||||
/** Useful constant for country.
|
||||
*/
|
||||
public static final Locale UK;
|
||||
|
||||
/** Useful constant for country.
|
||||
*/
|
||||
public static final Locale US;
|
||||
|
||||
/** Useful constant for country.
|
||||
*/
|
||||
public static final Locale CANADA;
|
||||
|
||||
/** Useful constant for country.
|
||||
*/
|
||||
public static final Locale CANADA_FRENCH;
|
||||
|
||||
/**
|
||||
* Useful constant for the root locale. The root locale is the locale whose
|
||||
* language, country, and variant are empty ("") strings. This is regarded
|
||||
* as the base locale of all locales, and is used as the language/country
|
||||
* neutral locale for the locale sensitive operations.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public static final Locale ROOT;
|
||||
|
||||
private static final Map<BaseLocale, Locale> CONSTANT_LOCALES = new HashMap<>();
|
||||
|
||||
static {
|
||||
ENGLISH = createConstant(BaseLocale.ENGLISH);
|
||||
FRENCH = createConstant(BaseLocale.FRENCH);
|
||||
GERMAN = createConstant(BaseLocale.GERMAN);
|
||||
ITALIAN = createConstant(BaseLocale.ITALIAN);
|
||||
JAPANESE = createConstant(BaseLocale.JAPANESE);
|
||||
KOREAN = createConstant(BaseLocale.KOREAN);
|
||||
CHINESE = createConstant(BaseLocale.CHINESE);
|
||||
SIMPLIFIED_CHINESE = createConstant(BaseLocale.SIMPLIFIED_CHINESE);
|
||||
TRADITIONAL_CHINESE = createConstant(BaseLocale.TRADITIONAL_CHINESE);
|
||||
FRANCE = createConstant(BaseLocale.FRANCE);
|
||||
GERMANY = createConstant(BaseLocale.GERMANY);
|
||||
ITALY = createConstant(BaseLocale.ITALY);
|
||||
JAPAN = createConstant(BaseLocale.JAPAN);
|
||||
KOREA = createConstant(BaseLocale.KOREA);
|
||||
UK = createConstant(BaseLocale.UK);
|
||||
US = createConstant(BaseLocale.US);
|
||||
CANADA = createConstant(BaseLocale.CANADA);
|
||||
CANADA_FRENCH = createConstant(BaseLocale.CANADA_FRENCH);
|
||||
ROOT = createConstant(BaseLocale.ROOT);
|
||||
}
|
||||
|
||||
/** Useful constant for country.
|
||||
*/
|
||||
@ -554,31 +602,16 @@ public final class Locale implements Cloneable, Serializable {
|
||||
*/
|
||||
public static final Locale TAIWAN = TRADITIONAL_CHINESE;
|
||||
|
||||
/** Useful constant for country.
|
||||
*/
|
||||
public static final Locale UK = createConstant("en", "GB");
|
||||
|
||||
/** Useful constant for country.
|
||||
*/
|
||||
public static final Locale US = createConstant("en", "US");
|
||||
|
||||
/** Useful constant for country.
|
||||
*/
|
||||
public static final Locale CANADA = createConstant("en", "CA");
|
||||
|
||||
/** Useful constant for country.
|
||||
*/
|
||||
public static final Locale CANADA_FRENCH = createConstant("fr", "CA");
|
||||
|
||||
/**
|
||||
* Useful constant for the root locale. The root locale is the locale whose
|
||||
* language, country, and variant are empty ("") strings. This is regarded
|
||||
* as the base locale of all locales, and is used as the language/country
|
||||
* neutral locale for the locale sensitive operations.
|
||||
*
|
||||
* @since 1.6
|
||||
* This method must be called only for creating the Locale.*
|
||||
* constants due to making shortcuts.
|
||||
*/
|
||||
public static final Locale ROOT = createConstant("", "");
|
||||
private static Locale createConstant(byte baseType) {
|
||||
BaseLocale base = BaseLocale.constantBaseLocales[baseType];
|
||||
Locale locale = new Locale(base, null);
|
||||
CONSTANT_LOCALES.put(base, locale);
|
||||
return locale;
|
||||
}
|
||||
|
||||
/**
|
||||
* The key for the private use extension ('x').
|
||||
@ -709,7 +742,7 @@ public final class Locale implements Cloneable, Serializable {
|
||||
* @exception NullPointerException thrown if any argument is null.
|
||||
*/
|
||||
public Locale(String language, String country, String variant) {
|
||||
if (language== null || country == null || variant == null) {
|
||||
if (language == null || country == null || variant == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
baseLocale = BaseLocale.getInstance(convertOldISOCodes(language), "", country, variant);
|
||||
@ -766,15 +799,6 @@ public final class Locale implements Cloneable, Serializable {
|
||||
this(language, "", "");
|
||||
}
|
||||
|
||||
/**
|
||||
* This method must be called only for creating the Locale.*
|
||||
* constants due to making shortcuts.
|
||||
*/
|
||||
private static Locale createConstant(String lang, String country) {
|
||||
BaseLocale base = BaseLocale.createInstance(lang, country);
|
||||
return getInstance(base, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a <code>Locale</code> constructed from the given
|
||||
* <code>language</code>, <code>country</code> and
|
||||
@ -803,20 +827,27 @@ public final class Locale implements Cloneable, Serializable {
|
||||
extensions = getCompatibilityExtensions(language, script, country, variant);
|
||||
}
|
||||
|
||||
BaseLocale baseloc = BaseLocale.getInstance(language, script, country, variant);
|
||||
BaseLocale baseloc = BaseLocale.getInstance(convertOldISOCodes(language), script, country, variant);
|
||||
return getInstance(baseloc, extensions);
|
||||
}
|
||||
|
||||
static Locale getInstance(BaseLocale baseloc, LocaleExtensions extensions) {
|
||||
if (extensions == null) {
|
||||
return LOCALECACHE.get(baseloc);
|
||||
Locale locale = CONSTANT_LOCALES.get(baseloc);
|
||||
if (locale != null) {
|
||||
return locale;
|
||||
}
|
||||
return Cache.LOCALECACHE.get(baseloc);
|
||||
} else {
|
||||
LocaleKey key = new LocaleKey(baseloc, extensions);
|
||||
return LOCALECACHE.get(key);
|
||||
return Cache.LOCALECACHE.get(key);
|
||||
}
|
||||
}
|
||||
|
||||
private static class Cache extends LocaleObjectCache<Object, Locale> {
|
||||
|
||||
private static final Cache LOCALECACHE = new Cache();
|
||||
|
||||
private Cache() {
|
||||
}
|
||||
|
||||
@ -977,8 +1008,11 @@ public final class Locale implements Cloneable, Serializable {
|
||||
}
|
||||
|
||||
private static Optional<LocaleExtensions> getDefaultExtensions(String extensionsProp) {
|
||||
LocaleExtensions exts = null;
|
||||
if (LocaleUtils.isEmpty(extensionsProp)) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
LocaleExtensions exts = null;
|
||||
try {
|
||||
exts = new InternalLocaleBuilder()
|
||||
.setExtensions(extensionsProp)
|
||||
@ -2308,6 +2342,7 @@ public final class Locale implements Cloneable, Serializable {
|
||||
String country = (String)fields.get("country", "");
|
||||
String variant = (String)fields.get("variant", "");
|
||||
String extStr = (String)fields.get("extensions", "");
|
||||
|
||||
baseLocale = BaseLocale.getInstance(convertOldISOCodes(language), script, country, variant);
|
||||
if (!extStr.isEmpty()) {
|
||||
try {
|
||||
|
@ -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() {
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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())) {
|
||||
|
@ -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));
|
||||
|
Loading…
x
Reference in New Issue
Block a user