mirror of
https://github.com/openjdk/jdk.git
synced 2026-03-12 08:53:12 +00:00
8038436: Re-examine the mechanism to determine available localedata and cldrdata
Reviewed-by: alanb, mchung, okutsu
This commit is contained in:
parent
62b9ab4a81
commit
2cbff3dfc4
@ -76,13 +76,24 @@ LOCALEDATA_INCLUDE_LOCALES := ar be bg ca cs da de el es et fi fr ga hi hr hu in
|
||||
iw ja ko lt lv mk ms mt nl no pl pt ro ru sk sl sq sr sv \
|
||||
th tr uk vi zh
|
||||
|
||||
LOCALEDATA_INCLUDES := $(addprefix sun/text/resources/, $(LOCALEDATA_INCLUDE_LOCALES)) \
|
||||
LOCALEDATA_INCLUDES := sun/util/resources/provider/NonEnLocaleDataMetaInfo.class
|
||||
LOCALEDATA_INCLUDES += $(addprefix sun/text/resources/, $(LOCALEDATA_INCLUDE_LOCALES)) \
|
||||
$(addprefix sun/util/resources/, $(LOCALEDATA_INCLUDE_LOCALES))
|
||||
|
||||
$(eval $(call SetupArchive,BUILD_LOCALEDATA_JAR, , \
|
||||
SRCS := $(JDK_OUTPUTDIR)/modules/jdk.localedata, \
|
||||
LOCALEDATA_SERVICES_DIR := $(IMAGES_OUTPUTDIR)/localemetainfo
|
||||
|
||||
LOCALEDATA_METAINF_SERVICES := $(LOCALEDATA_SERVICES_DIR)/META-INF/services/sun.util.locale.provider.LocaleDataMetaInfo
|
||||
|
||||
$(LOCALEDATA_METAINF_SERVICES): $(JDK_TOPDIR)/src/jdk.localedata/META-INF/localedata-services/sun.util.locale.provider.LocaleDataMetaInfo
|
||||
$(install-file)
|
||||
|
||||
$(eval $(call SetupArchive,BUILD_LOCALEDATA_JAR, \
|
||||
$(LOCALEDATA_METAINF_SERVICES), \
|
||||
SRCS := $(JDK_OUTPUTDIR)/modules/jdk.localedata \
|
||||
$(LOCALEDATA_SERVICES_DIR), \
|
||||
SUFFIXES := .class _dict _th, \
|
||||
INCLUDES := $(LOCALEDATA_INCLUDES), \
|
||||
EXTRA_FILES := META-INF/services/sun.util.locale.provider.LocaleDataMetaInfo, \
|
||||
JAR := $(IMAGES_OUTPUTDIR)/lib/ext/localedata.jar, \
|
||||
SKIP_METAINF := true))
|
||||
|
||||
@ -210,6 +221,8 @@ RT_JAR_EXCLUDES += \
|
||||
sun/tools/tree \
|
||||
sun/tools/util \
|
||||
sun/util/cldr/CLDRLocaleDataMetaInfo.class \
|
||||
sun/util/resources/provider/NonEnLocaleDataMetaInfo.class \
|
||||
META-INF/services/sun.util.locale.provider.LocaleDataMetaInfo \
|
||||
sun/util/resources/cldr \
|
||||
$(LOCALEDATA_INCLUDES) \
|
||||
com/oracle/jrockit/jfr \
|
||||
@ -429,13 +442,23 @@ include gensrc/GensrcCLDR.gmk
|
||||
|
||||
CLDRDATA_JAR_DST := $(IMAGES_OUTPUTDIR)/lib/ext/cldrdata.jar
|
||||
|
||||
$(eval $(call SetupArchive,BUILD_CLDRDATA_JAR, , \
|
||||
CLDR_SERVICES_DIR := $(IMAGES_OUTPUTDIR)/cldrmetainfo
|
||||
|
||||
CLDR_METAINF_SERVICES := $(CLDR_SERVICES_DIR)/META-INF/services/sun.util.locale.provider.LocaleDataMetaInfo
|
||||
|
||||
$(CLDR_METAINF_SERVICES): $(JDK_TOPDIR)/src/jdk.localedata/META-INF/cldrdata-services/sun.util.locale.provider.LocaleDataMetaInfo
|
||||
$(install-file)
|
||||
|
||||
$(eval $(call SetupArchive,BUILD_CLDRDATA_JAR, \
|
||||
$(CLDR_METAINF_SERVICES), \
|
||||
SRCS := $(JDK_OUTPUTDIR)/modules/jdk.localedata \
|
||||
$(JDK_OUTPUTDIR)/modules/java.base, \
|
||||
$(JDK_OUTPUTDIR)/modules/java.base \
|
||||
$(CLDR_SERVICES_DIR), \
|
||||
SUFFIXES := .class, \
|
||||
INCLUDES := sun/text/resources/cldr \
|
||||
sun/util/cldr/CLDRLocaleDataMetaInfo.class \
|
||||
sun/util/resources/cldr, \
|
||||
EXTRA_FILES := META-INF/services/sun.util.locale.provider.LocaleDataMetaInfo, \
|
||||
JAR := $(CLDRDATA_JAR_DST), \
|
||||
EXTRA_MANIFEST_ATTR := CLDR-Version: $(CLDRVERSION), \
|
||||
SKIP_METAINF := true))
|
||||
|
||||
@ -58,7 +58,14 @@ EN_LOCALES := en%
|
||||
# Locales that don't have any resource files should be included here.
|
||||
ALL_NON_EN_LOCALES := ja-JP-JP nb-NO nn-NO th-TH-TH
|
||||
|
||||
SED_ARGS := -e 's|$(HASH)warn This file is preprocessed before being compiled|// -- This file was mechanically generated: Do not edit! -- //|g'
|
||||
SED_ENARGS := -e 's|$(HASH)warn This file is preprocessed before being compiled|// -- This file was mechanically generated: Do not edit! -- //|g'
|
||||
SED_NONENARGS := $(SED_ENARGS)
|
||||
|
||||
# Fill in the languages and package names
|
||||
SED_ENARGS += -e 's/$(HASH)Lang$(HASH)/En/' \
|
||||
-e 's/$(HASH)Package$(HASH)/sun.util.locale.provider/'
|
||||
SED_NONENARGS += -e 's/$(HASH)Lang$(HASH)/NonEn/' \
|
||||
-e 's/$(HASH)Package$(HASH)/sun.util.resources.provider/'
|
||||
|
||||
# This macro creates a sed expression that substitues for example:
|
||||
# #FormatData_ENLocales# with: en% locales.
|
||||
@ -78,8 +85,8 @@ define CaptureLocale
|
||||
ALL_NON_EN_LOCALES += $$($1_NON_EN_LOCALES)
|
||||
|
||||
# Don't sed in a space if there are no locales.
|
||||
SED_ARGS += -e 's/$$(HASH)$1_ENLocales$$(HASH)/$$(if $$($1_EN_LOCALES),$$(SPACE)$$($1_EN_LOCALES),)/g'
|
||||
SED_ARGS += -e 's/$$(HASH)$1_NonENLocales$$(HASH)/$$(if $$($1_NON_EN_LOCALES),$$(SPACE)$$($1_NON_EN_LOCALES),)/g'
|
||||
SED_ENARGS += -e 's/$$(HASH)$1_Locales$$(HASH)/$$(if $$($1_EN_LOCALES),$$(SPACE)$$($1_EN_LOCALES),)/g'
|
||||
SED_NONENARGS += -e 's/$$(HASH)$1_Locales$$(HASH)/$$(if $$($1_NON_EN_LOCALES),$$(SPACE)$$($1_NON_EN_LOCALES),)/g'
|
||||
endef
|
||||
|
||||
#sun.text.resources.FormatData
|
||||
@ -106,17 +113,25 @@ $(eval $(call CaptureLocale,CurrencyNames))
|
||||
#sun.util.resources.CalendarData
|
||||
$(eval $(call CaptureLocale,CalendarData))
|
||||
|
||||
SED_ARGS += -e 's/$(HASH)AvailableLocales_ENLocales$(HASH)/$(sort $(ALL_EN_LOCALES))/g'
|
||||
SED_ARGS += -e 's/$(HASH)AvailableLocales_NonENLocales$(HASH)/$(sort $(ALL_NON_EN_LOCALES))/g'
|
||||
SED_ENARGS += -e 's/$(HASH)AvailableLocales_Locales$(HASH)/$(sort $(ALL_EN_LOCALES))/g'
|
||||
SED_NONENARGS += -e 's/$(HASH)AvailableLocales_Locales$(HASH)/$(sort $(ALL_NON_EN_LOCALES))/g'
|
||||
|
||||
$(JDK_OUTPUTDIR)/gensrc/java.base/sun/util/locale/provider/LocaleDataMetaInfo.java: \
|
||||
$(JDK_OUTPUTDIR)/gensrc/java.base/sun/util/locale/provider/EnLocaleDataMetaInfo.java: \
|
||||
$(JDK_TOPDIR)/src/java.base/share/classes/sun/util/locale/provider/LocaleDataMetaInfo-XLocales.java.template
|
||||
$(MKDIR) -p $(@D)
|
||||
$(ECHO) Creating sun/util/LocaleDataMetaInfo.java from $(words $(LOCALE_RESOURCES)) found resources.
|
||||
$(ECHO) Creating sun/util/locale/provider/EnLocaleDataMetaInfo.java from $(words $(LOCALE_RESOURCES)) found resources.
|
||||
$(PRINTF) "PREV_LOCALE_RESOURCES:=$(LOCALE_RESOURCES)" > $(JDK_OUTPUTDIR)/gensrc/_the.locale_resources
|
||||
$(SED) $(SED_ARGS) $< > $@
|
||||
$(SED) $(SED_ENARGS) $< > $@
|
||||
|
||||
GENSRC_LOCALEDATAMETAINFO := $(JDK_OUTPUTDIR)/gensrc/java.base/sun/util/locale/provider/LocaleDataMetaInfo.java
|
||||
$(JDK_OUTPUTDIR)/gensrc/jdk.localedata/sun/util/resources/provider/NonEnLocaleDataMetaInfo.java: \
|
||||
$(JDK_TOPDIR)/src/java.base/share/classes/sun/util/locale/provider/LocaleDataMetaInfo-XLocales.java.template
|
||||
$(MKDIR) -p $(@D)
|
||||
$(ECHO) Creating sun/util/resources/provider/NonEnLocaleDataMetaInfo.java from $(words $(LOCALE_RESOURCES)) found resources.
|
||||
$(PRINTF) "PREV_LOCALE_RESOURCES:=$(LOCALE_RESOURCES)" > $(JDK_OUTPUTDIR)/gensrc/_the.locale_resources
|
||||
$(SED) $(SED_NONENARGS) $< > $@
|
||||
|
||||
GENSRC_LOCALEDATAMETAINFO := $(JDK_OUTPUTDIR)/gensrc/java.base/sun/util/locale/provider/EnLocaleDataMetaInfo.java \
|
||||
$(JDK_OUTPUTDIR)/gensrc/jdk.localedata/sun/util/resources/provider/NonEnLocaleDataMetaInfo.java
|
||||
|
||||
################################################################################
|
||||
|
||||
|
||||
@ -431,7 +431,7 @@ public class CLDRConverter {
|
||||
allLocales.addAll(metaInfo.get("LocaleNames"));
|
||||
allLocales.addAll(metaInfo.get("CalendarData"));
|
||||
allLocales.addAll(metaInfo.get("FormatData"));
|
||||
metaInfo.put("All", allLocales);
|
||||
metaInfo.put("AvailableLocales", allLocales);
|
||||
}
|
||||
|
||||
bundleGenerator.generateMetaInfo(metaInfo);
|
||||
|
||||
@ -159,8 +159,10 @@ class ResourceBundleGenerator implements BundleGenerator {
|
||||
out.println(CopyrightHeaders.getOpenJDKCopyright());
|
||||
|
||||
out.println("package sun.util.cldr;\n\n"
|
||||
+ "import java.util.ListResourceBundle;\n");
|
||||
out.printf("public class %s extends ListResourceBundle {\n", METAINFO_CLASS);
|
||||
+ "import java.util.ListResourceBundle;\n"
|
||||
+ "import sun.util.locale.provider.LocaleProviderAdapter;\n"
|
||||
+ "import sun.util.locale.provider.LocaleDataMetaInfo;\n");
|
||||
out.printf("public class %s extends ListResourceBundle implements LocaleDataMetaInfo {\n", METAINFO_CLASS);
|
||||
out.println(" @Override\n" +
|
||||
" protected final Object[][] getContents() {\n" +
|
||||
" final Object[][] data = new Object[][] {");
|
||||
@ -168,7 +170,15 @@ class ResourceBundleGenerator implements BundleGenerator {
|
||||
out.printf(" { \"%s\",\n", key);
|
||||
out.printf(" \"%s\" },\n", toLocaleList(metaInfo.get(key)));
|
||||
}
|
||||
out.println(" };\n return data;\n }\n}");
|
||||
out.println(" };\n return data;\n }\n\n");
|
||||
|
||||
out.println(" public LocaleProviderAdapter.Type getType() {\n" +
|
||||
" return LocaleProviderAdapter.Type.CLDR;\n" +
|
||||
" }\n\n");
|
||||
|
||||
out.println(" public String availableLanguageTags(String category) {\n" +
|
||||
" return getString(category);\n" +
|
||||
" };\n}");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -25,20 +25,20 @@
|
||||
|
||||
package sun.util.cldr;
|
||||
|
||||
import java.io.File;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.text.spi.BreakIteratorProvider;
|
||||
import java.text.spi.CollatorProvider;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Locale;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.Set;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.spi.TimeZoneNameProvider;
|
||||
import sun.util.locale.provider.JRELocaleProviderAdapter;
|
||||
import sun.util.locale.provider.LocaleProviderAdapter;
|
||||
import sun.util.locale.provider.LocaleDataMetaInfo;
|
||||
|
||||
/**
|
||||
* LocaleProviderAdapter implementation for the CLDR locale data.
|
||||
@ -47,26 +47,31 @@ import sun.util.locale.provider.LocaleProviderAdapter;
|
||||
* @author Naoto Sato
|
||||
*/
|
||||
public class CLDRLocaleProviderAdapter extends JRELocaleProviderAdapter {
|
||||
private static final String LOCALE_DATA_JAR_NAME = "cldrdata.jar";
|
||||
|
||||
private final LocaleDataMetaInfo metaInfo;
|
||||
|
||||
public CLDRLocaleProviderAdapter() {
|
||||
final String sep = File.separator;
|
||||
String localeDataJar = java.security.AccessController.doPrivileged(
|
||||
new sun.security.action.GetPropertyAction("java.home"))
|
||||
+ sep + "lib" + sep + "ext" + sep + LOCALE_DATA_JAR_NAME;
|
||||
|
||||
// Peek at the installed extension directory to see if the jar file for
|
||||
// CLDR resources is installed or not.
|
||||
final File f = new File(localeDataJar);
|
||||
boolean result = AccessController.doPrivileged(
|
||||
new PrivilegedAction<Boolean>() {
|
||||
try {
|
||||
metaInfo = AccessController.doPrivileged(new PrivilegedExceptionAction<LocaleDataMetaInfo>() {
|
||||
@Override
|
||||
public Boolean run() {
|
||||
return f.exists();
|
||||
public LocaleDataMetaInfo run() {
|
||||
for (LocaleDataMetaInfo ldmi : ServiceLoader.loadInstalled(LocaleDataMetaInfo.class)) {
|
||||
if (ldmi.getType() == LocaleProviderAdapter.Type.CLDR) {
|
||||
return ldmi;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
if (!result) {
|
||||
throw new UnsupportedOperationException();
|
||||
} catch (Exception e) {
|
||||
// Catch any exception, and fail gracefully as if CLDR locales do not exist.
|
||||
// It's ok ignore it if something wrong happens because there always is the
|
||||
// JRE or FALLBACK LocaleProviderAdapter that will do the right thing.
|
||||
throw new UnsupportedOperationException(e);
|
||||
}
|
||||
|
||||
if (metaInfo == null) {
|
||||
throw new UnsupportedOperationException("CLDR locale data could not be found.");
|
||||
}
|
||||
}
|
||||
|
||||
@ -91,7 +96,7 @@ public class CLDRLocaleProviderAdapter extends JRELocaleProviderAdapter {
|
||||
|
||||
@Override
|
||||
public Locale[] getAvailableLocales() {
|
||||
Set<String> all = createLanguageTagSet("All");
|
||||
Set<String> all = createLanguageTagSet("AvailableLocales");
|
||||
Locale[] locs = new Locale[all.size()];
|
||||
int index = 0;
|
||||
for (String tag : all) {
|
||||
@ -102,11 +107,10 @@ public class CLDRLocaleProviderAdapter extends JRELocaleProviderAdapter {
|
||||
|
||||
@Override
|
||||
protected Set<String> createLanguageTagSet(String category) {
|
||||
ResourceBundle rb = ResourceBundle.getBundle("sun.util.cldr.CLDRLocaleDataMetaInfo", Locale.ROOT);
|
||||
if (rb.containsKey(category)) {
|
||||
String supportedLocaleString = metaInfo.availableLanguageTags(category);
|
||||
if (supportedLocaleString == null) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
String supportedLocaleString = rb.getString(category);
|
||||
Set<String> tagset = new HashSet<>();
|
||||
StringTokenizer tokens = new StringTokenizer(supportedLocaleString);
|
||||
while (tokens.hasMoreTokens()) {
|
||||
|
||||
@ -56,7 +56,7 @@ public abstract class AuxLocaleProviderAdapter extends LocaleProviderAdapter {
|
||||
/**
|
||||
* SPI implementations map
|
||||
*/
|
||||
private ConcurrentMap<Class<? extends LocaleServiceProvider>, LocaleServiceProvider> providersMap =
|
||||
private final ConcurrentMap<Class<? extends LocaleServiceProvider>, LocaleServiceProvider> providersMap =
|
||||
new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
@ -167,7 +167,6 @@ public abstract class AuxLocaleProviderAdapter extends LocaleProviderAdapter {
|
||||
avail.addAll(Arrays.asList(lsp.getAvailableLocales()));
|
||||
}
|
||||
}
|
||||
availableLocales = avail.toArray(new Locale[0]);
|
||||
}
|
||||
|
||||
// assuming caller won't mutate the array.
|
||||
@ -178,7 +177,7 @@ public abstract class AuxLocaleProviderAdapter extends LocaleProviderAdapter {
|
||||
* A dummy locale service provider that indicates there is no
|
||||
* provider available
|
||||
*/
|
||||
private static NullProvider NULL_PROVIDER = new NullProvider();
|
||||
private static final NullProvider NULL_PROVIDER = new NullProvider();
|
||||
private static class NullProvider extends LocaleServiceProvider {
|
||||
@Override
|
||||
public Locale[] getAvailableLocales() {
|
||||
|
||||
@ -25,9 +25,9 @@
|
||||
|
||||
package sun.util.locale.provider;
|
||||
|
||||
import java.io.File;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.text.spi.BreakIteratorProvider;
|
||||
import java.text.spi.CollatorProvider;
|
||||
import java.text.spi.DateFormatProvider;
|
||||
@ -37,6 +37,7 @@ import java.text.spi.NumberFormatProvider;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Locale;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.Set;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
@ -58,8 +59,6 @@ import sun.util.spi.CalendarProvider;
|
||||
*/
|
||||
public class JRELocaleProviderAdapter extends LocaleProviderAdapter implements ResourceBundleBasedAdapter {
|
||||
|
||||
private static final String LOCALE_DATA_JAR_NAME = "localedata.jar";
|
||||
|
||||
private final ConcurrentMap<String, Set<String>> langtagSets
|
||||
= new ConcurrentHashMap<>();
|
||||
|
||||
@ -356,26 +355,56 @@ public class JRELocaleProviderAdapter extends LocaleProviderAdapter implements R
|
||||
}
|
||||
|
||||
protected Set<String> createLanguageTagSet(String category) {
|
||||
String supportedLocaleString = LocaleDataMetaInfo.getSupportedLocaleString(category);
|
||||
String supportedLocaleString = createSupportedLocaleString(category);
|
||||
if (supportedLocaleString == null) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
Set<String> tagset = new HashSet<>();
|
||||
StringTokenizer tokens = new StringTokenizer(supportedLocaleString);
|
||||
while (tokens.hasMoreTokens()) {
|
||||
String token = tokens.nextToken();
|
||||
if (token.equals("|")) {
|
||||
if (isNonENLangSupported()) {
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
tagset.add(token);
|
||||
tagset.add(tokens.nextToken());
|
||||
}
|
||||
|
||||
return tagset;
|
||||
}
|
||||
|
||||
private static String createSupportedLocaleString(String category) {
|
||||
// Directly call English tags, as we know it's in the base module.
|
||||
String supportedLocaleString = EnLocaleDataMetaInfo.getSupportedLocaleString(category);
|
||||
|
||||
// Use ServiceLoader to dynamically acquire installed locales' tags.
|
||||
try {
|
||||
String nonENTags = AccessController.doPrivileged(new PrivilegedExceptionAction<String>() {
|
||||
@Override
|
||||
public String run() {
|
||||
String tags = null;
|
||||
for (LocaleDataMetaInfo ldmi :
|
||||
ServiceLoader.loadInstalled(LocaleDataMetaInfo.class)) {
|
||||
if (ldmi.getType() == LocaleProviderAdapter.Type.JRE) {
|
||||
String t = ldmi.availableLanguageTags(category);
|
||||
if (t != null) {
|
||||
if (tags == null) {
|
||||
tags = t;
|
||||
} else {
|
||||
tags += " " + t;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return tags;
|
||||
}
|
||||
});
|
||||
|
||||
if (nonENTags != null) {
|
||||
supportedLocaleString += " " + nonENTags;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// catch any exception, and ignore them as if non-EN locales do not exist.
|
||||
}
|
||||
|
||||
return supportedLocaleString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazy load available locales.
|
||||
*/
|
||||
@ -387,27 +416,17 @@ public class JRELocaleProviderAdapter extends LocaleProviderAdapter implements R
|
||||
|
||||
private static Locale[] createAvailableLocales() {
|
||||
/*
|
||||
* Gets the locale string list from LocaleDataMetaInfo class and then
|
||||
* Gets the locale string list from LocaleDataMetaInfo classes and then
|
||||
* contructs the Locale array and a set of language tags based on the
|
||||
* locale string returned above.
|
||||
*/
|
||||
String supportedLocaleString = LocaleDataMetaInfo.getSupportedLocaleString("AvailableLocales");
|
||||
String supportedLocaleString = createSupportedLocaleString("AvailableLocales");
|
||||
|
||||
if (supportedLocaleString.length() == 0) {
|
||||
throw new InternalError("No available locales for JRE");
|
||||
}
|
||||
|
||||
/*
|
||||
* Look for "|" and construct a new locale string list.
|
||||
*/
|
||||
int barIndex = supportedLocaleString.indexOf('|');
|
||||
StringTokenizer localeStringTokenizer;
|
||||
if (isNonENLangSupported()) {
|
||||
localeStringTokenizer = new StringTokenizer(supportedLocaleString.substring(0, barIndex)
|
||||
+ supportedLocaleString.substring(barIndex + 1));
|
||||
} else {
|
||||
localeStringTokenizer = new StringTokenizer(supportedLocaleString.substring(0, barIndex));
|
||||
}
|
||||
StringTokenizer localeStringTokenizer = new StringTokenizer(supportedLocaleString);
|
||||
|
||||
int length = localeStringTokenizer.countTokens();
|
||||
Locale[] locales = new Locale[length + 1];
|
||||
@ -430,39 +449,4 @@ public class JRELocaleProviderAdapter extends LocaleProviderAdapter implements R
|
||||
}
|
||||
return locales;
|
||||
}
|
||||
|
||||
private static volatile Boolean isNonENSupported = null;
|
||||
|
||||
/*
|
||||
* Returns true if the non EN resources jar file exists in jre
|
||||
* extension directory. @returns true if the jar file is there. Otherwise,
|
||||
* returns false.
|
||||
*/
|
||||
private static boolean isNonENLangSupported() {
|
||||
if (isNonENSupported == null) {
|
||||
synchronized (JRELocaleProviderAdapter.class) {
|
||||
if (isNonENSupported == null) {
|
||||
final String sep = File.separator;
|
||||
String localeDataJar =
|
||||
java.security.AccessController.doPrivileged(
|
||||
new sun.security.action.GetPropertyAction("java.home"))
|
||||
+ sep + "lib" + sep + "ext" + sep + LOCALE_DATA_JAR_NAME;
|
||||
|
||||
/*
|
||||
* Peek at the installed extension directory to see if
|
||||
* localedata.jar is installed or not.
|
||||
*/
|
||||
final File f = new File(localeDataJar);
|
||||
isNonENSupported =
|
||||
AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
|
||||
@Override
|
||||
public Boolean run() {
|
||||
return f.exists();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
return isNonENSupported;
|
||||
}
|
||||
}
|
||||
|
||||
@ -30,19 +30,17 @@
|
||||
* each resource in sun.util.resources & sun.text.resources.
|
||||
* It is used to avoid loading non-existent localized resources so that
|
||||
* jar files won't be opened unnecessary to look up them.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
package sun.util.locale.provider;
|
||||
package #Package#;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import sun.util.locale.provider.LocaleDataMetaInfo;
|
||||
import static sun.util.locale.provider.LocaleProviderAdapter.Type;
|
||||
|
||||
public class #Lang#LocaleDataMetaInfo implements LocaleDataMetaInfo {
|
||||
|
||||
public class LocaleDataMetaInfo {
|
||||
|
||||
private static final HashMap<String, String> resourceNameToLocales =
|
||||
new HashMap<String, String>(7);
|
||||
|
||||
private static final Map<String, String> resourceNameToLocales = new HashMap<>(9);
|
||||
|
||||
static {
|
||||
/* During JDK build time, #XXX_YYY# will be replaced by a string contain all the locales
|
||||
@ -52,38 +50,51 @@ public class LocaleDataMetaInfo {
|
||||
look up locale string such as "en" could be based on if it contains " en ".
|
||||
*/
|
||||
resourceNameToLocales.put("FormatData",
|
||||
" #FormatData_ENLocales# | #FormatData_NonENLocales# ");
|
||||
" #FormatData_Locales# ");
|
||||
|
||||
resourceNameToLocales.put("CollationData",
|
||||
" #CollationData_ENLocales# | #CollationData_NonENLocales# ");
|
||||
" #CollationData_Locales# ");
|
||||
|
||||
resourceNameToLocales.put("BreakIteratorInfo",
|
||||
" #BreakIteratorInfo_ENLocales# | #BreakIteratorInfo_NonENLocales# ");
|
||||
" #BreakIteratorInfo_Locales# ");
|
||||
|
||||
resourceNameToLocales.put("BreakIteratorRules",
|
||||
" #BreakIteratorRules_ENLocales# | #BreakIteratorRules_NonENLocales# ");
|
||||
" #BreakIteratorRules_Locales# ");
|
||||
|
||||
resourceNameToLocales.put("TimeZoneNames",
|
||||
" #TimeZoneNames_ENLocales# | #TimeZoneNames_NonENLocales# ");
|
||||
" #TimeZoneNames_Locales# ");
|
||||
|
||||
resourceNameToLocales.put("LocaleNames",
|
||||
" #LocaleNames_ENLocales# | #LocaleNames_NonENLocales# ");
|
||||
" #LocaleNames_Locales# ");
|
||||
|
||||
resourceNameToLocales.put("CurrencyNames",
|
||||
" #CurrencyNames_ENLocales# | #CurrencyNames_NonENLocales# ");
|
||||
" #CurrencyNames_Locales# ");
|
||||
|
||||
resourceNameToLocales.put("CalendarData",
|
||||
" #CalendarData_ENLocales# | #CalendarData_NonENLocales# ");
|
||||
" #CalendarData_Locales# ");
|
||||
|
||||
resourceNameToLocales.put("AvailableLocales",
|
||||
" #AvailableLocales_ENLocales# | #AvailableLocales_NonENLocales# ");
|
||||
" #AvailableLocales_Locales# ");
|
||||
}
|
||||
|
||||
/*
|
||||
* Gets the supported locales string based on the availability of
|
||||
* locale data resource bundles for each resource name.
|
||||
*
|
||||
* @param resourceName the resource name
|
||||
* @return the supported locale string for the passed in resource.
|
||||
*/
|
||||
public static String getSupportedLocaleString(String resourceName) {
|
||||
return resourceNameToLocales.get(resourceName);
|
||||
return resourceNameToLocales.getOrDefault(resourceName, "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getType() {
|
||||
return Type.JRE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String availableLanguageTags(String category) {
|
||||
return getSupportedLocaleString(category);
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.util.locale.provider;
|
||||
|
||||
/**
|
||||
* LocaleData meta info SPI
|
||||
*
|
||||
* @author Naoto Sato
|
||||
*/
|
||||
public interface LocaleDataMetaInfo {
|
||||
|
||||
/**
|
||||
* Returns the type of LocaleProviderAdapter for which this LocaleData
|
||||
* provides the data.
|
||||
* @return type The type of the adapter.
|
||||
*/
|
||||
public LocaleProviderAdapter.Type getType();
|
||||
|
||||
/**
|
||||
* Returns the string concatenation of the supported language tags in
|
||||
* this LocaleData instance
|
||||
* @param category category of the locale data.
|
||||
* @return concatenated language tags, separated by a space.
|
||||
*/
|
||||
public String availableLanguageTags(String category);
|
||||
}
|
||||
@ -50,7 +50,6 @@ import java.util.MissingResourceException;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.Set;
|
||||
import sun.util.locale.provider.JRELocaleProviderAdapter;
|
||||
import sun.util.locale.provider.LocaleDataMetaInfo;
|
||||
import sun.util.locale.provider.LocaleProviderAdapter;
|
||||
import static sun.util.locale.provider.LocaleProviderAdapter.Type.CLDR;
|
||||
import static sun.util.locale.provider.LocaleProviderAdapter.Type.JRE;
|
||||
|
||||
@ -0,0 +1 @@
|
||||
sun.util.cldr.CLDRLocaleDataMetaInfo
|
||||
@ -0,0 +1 @@
|
||||
sun.util.resources.provider.NonEnLocaleDataMetaInfo
|
||||
218
jdk/test/sun/util/locale/provider/Bug8038436.java
Normal file
218
jdk/test/sun/util/locale/provider/Bug8038436.java
Normal file
@ -0,0 +1,218 @@
|
||||
/*
|
||||
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8038436
|
||||
* @summary Test for changes in 8038436
|
||||
* @compile -XDignore.symbol.file Bug8038436.java
|
||||
* @run main/othervm Bug8038436 -Djava.ext.dirs=foo security
|
||||
* @run main/othervm Bug8038436 -Djava.locale.providers=JRE availlocs
|
||||
*/
|
||||
|
||||
import java.security.*;
|
||||
import java.text.*;
|
||||
import java.util.*;
|
||||
import java.util.stream.*;
|
||||
import sun.util.locale.provider.*;
|
||||
|
||||
public class Bug8038436 {
|
||||
public static void main(String[] args) {
|
||||
switch (args[1]) {
|
||||
case "security":
|
||||
securityTests();
|
||||
break;
|
||||
case "availlocs":
|
||||
availableLocalesTests();
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("no test was specified.");
|
||||
}
|
||||
}
|
||||
|
||||
private static void securityTests() {
|
||||
Policy.setPolicy(new MyPolicy());
|
||||
System.setSecurityManager(new SecurityManager());
|
||||
|
||||
/*
|
||||
* Test for AccessClassInPackage security exception. Confirms that
|
||||
* exeption won't be thrown if an application sets a Permission that
|
||||
* does not allow any RuntimePermission, on loading LocaleDataMetaInfo
|
||||
* from jdk.localedata module.
|
||||
*/
|
||||
System.out.println(new Formatter(Locale.JAPAN).format("%1$tB %1$te, %1$tY",
|
||||
new GregorianCalendar()));
|
||||
|
||||
/*
|
||||
* Check only English/ROOT locales are returned if the jdk.localedata
|
||||
* module is not installed (implied by "java.ext.dirs" set to "foo").
|
||||
*/
|
||||
if (Arrays.asList(Locale.getAvailableLocales())
|
||||
.stream()
|
||||
.anyMatch(l -> l != Locale.ROOT && l.getLanguage() != "en")) {
|
||||
throw new RuntimeException("non English locale(s) included in available locales");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static class MyPolicy extends Policy {
|
||||
final PermissionCollection perms = new Permissions();
|
||||
|
||||
MyPolicy() {
|
||||
// allows no RuntimePermission
|
||||
}
|
||||
|
||||
public PermissionCollection getPermissions(ProtectionDomain domain) {
|
||||
return perms;
|
||||
}
|
||||
|
||||
public PermissionCollection getPermissions(CodeSource codesource) {
|
||||
return perms;
|
||||
}
|
||||
|
||||
public boolean implies(ProtectionDomain domain, Permission perm) {
|
||||
return perms.implies(perm);
|
||||
}
|
||||
}
|
||||
|
||||
static final String[] bipLocs = ("ar, ar-JO, ar-LB, ar-SY, be, be-BY, bg, " +
|
||||
"bg-BG, ca, ca-ES, cs, cs-CZ, da, da-DK, de, de-AT, de-CH, de-DE, " +
|
||||
"de-LU, el, el-CY, el-GR, en, en-AU, en-CA, en-GB, en-IE, en-IN, " +
|
||||
"en-MT, en-NZ, en-PH, en-SG, en-US, en-ZA, es, es-AR, es-BO, es-CL, " +
|
||||
"es-CO, es-CR, es-DO, es-EC, es-ES, es-GT, es-HN, es-MX, es-NI, " +
|
||||
"es-PA, es-PE, es-PR, es-PY, es-SV, es-US, es-UY, es-VE, et, et-EE, " +
|
||||
"fi, fi-FI, fr, fr-BE, fr-CA, fr-CH, fr-FR, ga, ga-IE, he, he-IL, " +
|
||||
"hi-IN, hr, hr-HR, hu, hu-HU, id, id-ID, is, is-IS, it, it-CH, it-IT, " +
|
||||
"ja, ja-JP, ko, ko-KR, lt, lt-LT, lv, lv-LV, mk, mk-MK, ms, ms-MY, mt, " +
|
||||
"mt-MT, nl, nl-BE, nl-NL, no, no-NO, no-NO, pl, pl-PL, pt, pt-BR, " +
|
||||
"pt-PT, ro, ro-RO, ru, ru-RU, sk, sk-SK, sl, sl-SI, sq, sq-AL, sr, " +
|
||||
"sr-BA, sr-CS, sr-Latn, sr-Latn-ME, sr-ME, sr-RS, sv, sv-SE, th, th-TH, " +
|
||||
"tr, tr-TR, uk, uk-UA, und, vi, vi-VN, zh, zh-CN, zh-HK, zh-Hans-CN, " +
|
||||
"zh-Hans-SG, zh-Hant-HK, zh-Hant-TW, zh-SG, zh-TW, ").split(",\\s*");
|
||||
static final String[] dfpLocs = bipLocs;
|
||||
static final String[] datefspLocs = bipLocs;
|
||||
static final String[] decimalfspLocs = bipLocs;
|
||||
static final String[] calnpLocs = bipLocs;
|
||||
static final String[] cpLocs = ("ar, be, bg, ca, cs, da, el, es, et, fi, " +
|
||||
"fr, he, hi, hr, hu, is, ja, ko, lt, lv, mk, no, pl, ro, ru, sk, sl, " +
|
||||
"sq, sr, sr-Latn, sv, th, tr, uk, und, vi, zh, zh-HK, zh-Hant-HK, " +
|
||||
"zh-Hant-TW, zh-TW, ").split(",\\s*");
|
||||
static final String[] nfpLocs = ("ar, ar-AE, ar-BH, ar-DZ, ar-EG, ar-IQ, " +
|
||||
"ar-JO, ar-KW, ar-LB, ar-LY, ar-MA, ar-OM, ar-QA, ar-SA, ar-SD, ar-SY, " +
|
||||
"ar-TN, ar-YE, be, be-BY, bg, bg-BG, ca, ca-ES, cs, cs-CZ, da, da-DK, " +
|
||||
"de, de-AT, de-CH, de-DE, de-GR, de-LU, el, el-CY, el-GR, en, en-AU, " +
|
||||
"en-CA, en-GB, en-IE, en-IN, en-MT, en-NZ, en-PH, en-SG, en-US, en-ZA, " +
|
||||
"es, es-AR, es-BO, es-CL, es-CO, es-CR, es-CU, es-DO, es-EC, es-ES, " +
|
||||
"es-GT, es-HN, es-MX, es-NI, es-PA, es-PE, es-PR, es-PY, es-SV, es-US, " +
|
||||
"es-UY, es-VE, et, et-EE, fi, fi-FI, fr, fr-BE, fr-CA, fr-CH, fr-FR, " +
|
||||
"fr-LU, ga, ga-IE, he, he-IL, hi, hi-IN, hr, hr-HR, hu, hu-HU, id, " +
|
||||
"id-ID, is, is-IS, it, it-CH, it-IT, ja, ja-JP, " +
|
||||
"ja-JP-u-ca-japanese-x-lvariant-JP, ko, ko-KR, lt, lt-LT, lv, lv-LV, " +
|
||||
"mk, mk-MK, ms, ms-MY, mt, mt-MT, nb-NO, nl, nl-BE, nl-NL, nn-NO, " +
|
||||
"nn-NO, no, no-NO, pl, pl-PL, pt, pt-BR, pt-PT, ro, ro-RO, ru, ru-RU, " +
|
||||
"sk, sk-SK, sl, sl-SI, sq, sq-AL, sr, sr-BA, sr-CS, sr-Latn, " +
|
||||
"sr-Latn-BA, sr-Latn-ME, sr-Latn-RS, sr-ME, sr-RS, sv, sv-SE, th, " +
|
||||
"th-TH, th-TH-u-nu-thai-x-lvariant-TH, tr, tr-TR, uk, uk-UA, und, vi, " +
|
||||
"vi-VN, zh, zh-CN, zh-HK, zh-Hans-CN, zh-Hans-SG, zh-Hant-HK, " +
|
||||
"zh-Hant-TW, zh-SG, zh-TW, ").split(",\\s*");
|
||||
static final String[] currencynpLocs = ("ar-AE, ar-BH, ar-DZ, ar-EG, ar-IQ, " +
|
||||
"ar-JO, ar-KW, ar-LB, ar-LY, ar-MA, ar-OM, ar-QA, ar-SA, ar-SD, ar-SY, " +
|
||||
"ar-TN, ar-YE, be-BY, bg-BG, ca-ES, cs-CZ, da-DK, de, de-AT, de-CH, " +
|
||||
"de-DE, de-GR, de-LU, el-CY, el-GR, en-AU, en-CA, en-GB, en-IE, en-IN, " +
|
||||
"en-MT, en-NZ, en-PH, en-SG, en-US, en-ZA, es, es-AR, es-BO, es-CL, " +
|
||||
"es-CO, es-CR, es-CU, es-DO, es-EC, es-ES, es-GT, es-HN, es-MX, es-NI, " +
|
||||
"es-PA, es-PE, es-PR, es-PY, es-SV, es-US, es-UY, es-VE, et-EE, fi-FI, " +
|
||||
"fr, fr-BE, fr-CA, fr-CH, fr-FR, fr-LU, ga-IE, he-IL, hi-IN, hr-HR, " +
|
||||
"hu-HU, id-ID, is-IS, it, it-CH, it-IT, ja, ja-JP, ko, ko-KR, lt-LT, " +
|
||||
"lv-LV, mk-MK, ms-MY, mt-MT, nl-BE, nl-NL, no-NO, pl-PL, pt, pt-BR, " +
|
||||
"pt-PT, ro-RO, ru-RU, sk-SK, sl-SI, sq-AL, sr-BA, sr-CS, sr-Latn-BA, " +
|
||||
"sr-Latn-ME, sr-Latn-RS, sr-ME, sr-RS, sv, sv-SE, th-TH, tr-TR, uk-UA, " +
|
||||
"und, vi-VN, zh-CN, zh-HK, zh-Hans-CN, zh-Hans-SG, zh-Hant-HK, " +
|
||||
"zh-Hant-TW, zh-SG, zh-TW, ").split(",\\s*");
|
||||
static final String[] lnpLocs = ("ar, be, bg, ca, cs, da, de, el, el-CY, " +
|
||||
"en, en-MT, en-PH, en-SG, es, es-US, et, fi, fr, ga, he, hi, hr, hu, " +
|
||||
"id, is, it, ja, ko, lt, lv, mk, ms, mt, nl, no, no-NO, pl, pt, pt-BR, " +
|
||||
"pt-PT, ro, ru, sk, sl, sq, sr, sr-Latn, sv, th, tr, uk, und, vi, zh, " +
|
||||
"zh-HK, zh-Hans-SG, zh-Hant-HK, zh-Hant-TW, zh-SG, zh-TW, ").split(",\\s*");
|
||||
static final String[] tznpLocs = ("de, en, en-CA, en-GB, en-IE, es, fr, hi, " +
|
||||
"it, ja, ko, pt-BR, sv, und, zh-CN, zh-HK, zh-Hans-CN, zh-Hant-HK, " +
|
||||
"zh-Hant-TW, zh-TW, ").split(",\\s*");
|
||||
static final String[] caldpLocs = ("ar, be, bg, ca, cs, da, de, el, el-CY, " +
|
||||
"en, en-GB, en-IE, en-MT, es, es-ES, es-US, et, fi, fr, fr-CA, he, hi, " +
|
||||
"hr, hu, id-ID, is, it, ja, ko, lt, lv, mk, ms-MY, mt, mt-MT, nl, no, " +
|
||||
"pl, pt, pt-BR, pt-PT, ro, ru, sk, sl, sq, sr, sr-Latn-BA, sr-Latn-ME, " +
|
||||
"sr-Latn-RS, sv, th, tr, uk, und, vi, zh, ").split(",\\s*");
|
||||
static final String[] calpLocs = caldpLocs;
|
||||
|
||||
/*
|
||||
* Validate whether JRE's *Providers return supported locales list based on
|
||||
* their actual resource bundle exsistence. The above golden data
|
||||
* are manually extracted, so they need to be updated if new locale
|
||||
* data resource bundle were added.
|
||||
*/
|
||||
private static void availableLocalesTests() {
|
||||
LocaleProviderAdapter jre = LocaleProviderAdapter.forJRE();
|
||||
|
||||
checkAvailableLocales("BreakIteratorProvider",
|
||||
jre.getBreakIteratorProvider().getAvailableLocales(), bipLocs);
|
||||
checkAvailableLocales("CollatorProvider",
|
||||
jre.getCollatorProvider().getAvailableLocales(), cpLocs);
|
||||
checkAvailableLocales("DateFormatProvider",
|
||||
jre.getDateFormatProvider().getAvailableLocales(), dfpLocs);
|
||||
checkAvailableLocales("DateFormatSymbolsProvider",
|
||||
jre.getDateFormatSymbolsProvider().getAvailableLocales(), datefspLocs);
|
||||
checkAvailableLocales("DecimalFormatSymbolsProvider",
|
||||
jre.getDecimalFormatSymbolsProvider().getAvailableLocales(), decimalfspLocs);
|
||||
checkAvailableLocales("NumberFormatProvider",
|
||||
jre.getNumberFormatProvider().getAvailableLocales(), nfpLocs);
|
||||
checkAvailableLocales("CurrencyNameProvider",
|
||||
jre.getCurrencyNameProvider().getAvailableLocales(), currencynpLocs);
|
||||
checkAvailableLocales("LocaleNameProvider",
|
||||
jre.getLocaleNameProvider().getAvailableLocales(), lnpLocs);
|
||||
checkAvailableLocales("TimeZoneNameProvider",
|
||||
jre.getTimeZoneNameProvider().getAvailableLocales(), tznpLocs);
|
||||
checkAvailableLocales("CalendarDataProvider",
|
||||
jre.getCalendarDataProvider().getAvailableLocales(), caldpLocs);
|
||||
checkAvailableLocales("CalendarNameProvider",
|
||||
jre.getCalendarNameProvider().getAvailableLocales(), calnpLocs);
|
||||
checkAvailableLocales("CalendarProvider",
|
||||
jre.getCalendarProvider().getAvailableLocales(), calpLocs);
|
||||
}
|
||||
|
||||
private static void checkAvailableLocales(String testName, Locale[] got, String[] expected) {
|
||||
System.out.println("Testing available locales for " + testName);
|
||||
List<Locale> gotList = Arrays.asList(got).stream()
|
||||
.map(Locale::toLanguageTag)
|
||||
.sorted()
|
||||
.map(Locale::forLanguageTag)
|
||||
.collect(Collectors.toList());
|
||||
List<Locale> expectedList = Arrays.asList(expected).stream()
|
||||
.map(Locale::forLanguageTag)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (!gotList.equals(expectedList)) {
|
||||
throw new RuntimeException("\n" + gotList.toString() + "\n is not equal to \n" +
|
||||
expectedList.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user