--- old/src/java.base/share/classes/sun/util/locale/provider/JRELocaleProviderAdapter.java 2014-08-22 11:18:39.624086060 -0700 +++ new/src/java.base/share/classes/sun/util/locale/provider/JRELocaleProviderAdapter.java 2014-08-22 11:18:39.313081466 -0700 @@ -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.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 @@ */ public class JRELocaleProviderAdapter extends LocaleProviderAdapter implements ResourceBundleBasedAdapter { - private static final String LOCALE_DATA_JAR_NAME = "localedata.jar"; - private final ConcurrentMap> langtagSets = new ConcurrentHashMap<>(); @@ -134,8 +133,7 @@ @Override public BreakIteratorProvider getBreakIteratorProvider() { if (breakIteratorProvider == null) { - BreakIteratorProvider provider = new BreakIteratorProviderImpl(getAdapterType(), - getLanguageTagSet("FormatData")); + BreakIteratorProvider provider = new BreakIteratorProviderImpl(getAdapterType()); synchronized (this) { if (breakIteratorProvider == null) { breakIteratorProvider = provider; @@ -148,8 +146,7 @@ @Override public CollatorProvider getCollatorProvider() { if (collatorProvider == null) { - CollatorProvider provider = new CollatorProviderImpl(getAdapterType(), - getLanguageTagSet("CollationData")); + CollatorProvider provider = new CollatorProviderImpl(getAdapterType()); synchronized (this) { if (collatorProvider == null) { collatorProvider = provider; @@ -162,8 +159,7 @@ @Override public DateFormatProvider getDateFormatProvider() { if (dateFormatProvider == null) { - DateFormatProvider provider = new DateFormatProviderImpl(getAdapterType(), - getLanguageTagSet("FormatData")); + DateFormatProvider provider = new DateFormatProviderImpl(getAdapterType()); synchronized (this) { if (dateFormatProvider == null) { dateFormatProvider = provider; @@ -176,8 +172,7 @@ @Override public DateFormatSymbolsProvider getDateFormatSymbolsProvider() { if (dateFormatSymbolsProvider == null) { - DateFormatSymbolsProvider provider = new DateFormatSymbolsProviderImpl(getAdapterType(), - getLanguageTagSet("FormatData")); + DateFormatSymbolsProvider provider = new DateFormatSymbolsProviderImpl(getAdapterType()); synchronized (this) { if (dateFormatSymbolsProvider == null) { dateFormatSymbolsProvider = provider; @@ -190,7 +185,7 @@ @Override public DecimalFormatSymbolsProvider getDecimalFormatSymbolsProvider() { if (decimalFormatSymbolsProvider == null) { - DecimalFormatSymbolsProvider provider = new DecimalFormatSymbolsProviderImpl(getAdapterType(), getLanguageTagSet("FormatData")); + DecimalFormatSymbolsProvider provider = new DecimalFormatSymbolsProviderImpl(getAdapterType()); synchronized (this) { if (decimalFormatSymbolsProvider == null) { decimalFormatSymbolsProvider = provider; @@ -203,8 +198,7 @@ @Override public NumberFormatProvider getNumberFormatProvider() { if (numberFormatProvider == null) { - NumberFormatProvider provider = new NumberFormatProviderImpl(getAdapterType(), - getLanguageTagSet("FormatData")); + NumberFormatProvider provider = new NumberFormatProviderImpl(getAdapterType()); synchronized (this) { if (numberFormatProvider == null) { numberFormatProvider = provider; @@ -220,8 +214,7 @@ @Override public CurrencyNameProvider getCurrencyNameProvider() { if (currencyNameProvider == null) { - CurrencyNameProvider provider = new CurrencyNameProviderImpl(getAdapterType(), - getLanguageTagSet("CurrencyNames")); + CurrencyNameProvider provider = new CurrencyNameProviderImpl(getAdapterType()); synchronized (this) { if (currencyNameProvider == null) { currencyNameProvider = provider; @@ -234,8 +227,7 @@ @Override public LocaleNameProvider getLocaleNameProvider() { if (localeNameProvider == null) { - LocaleNameProvider provider = new LocaleNameProviderImpl(getAdapterType(), - getLanguageTagSet("LocaleNames")); + LocaleNameProvider provider = new LocaleNameProviderImpl(getAdapterType()); synchronized (this) { if (localeNameProvider == null) { localeNameProvider = provider; @@ -248,8 +240,7 @@ @Override public TimeZoneNameProvider getTimeZoneNameProvider() { if (timeZoneNameProvider == null) { - TimeZoneNameProvider provider = new TimeZoneNameProviderImpl(getAdapterType(), - getLanguageTagSet("TimeZoneNames")); + TimeZoneNameProvider provider = new TimeZoneNameProviderImpl(getAdapterType()); synchronized (this) { if (timeZoneNameProvider == null) { timeZoneNameProvider = provider; @@ -263,8 +254,7 @@ public CalendarDataProvider getCalendarDataProvider() { if (calendarDataProvider == null) { CalendarDataProvider provider; - provider = new CalendarDataProviderImpl(getAdapterType(), - getLanguageTagSet("CalendarData")); + provider = new CalendarDataProviderImpl(getAdapterType()); synchronized (this) { if (calendarDataProvider == null) { calendarDataProvider = provider; @@ -278,8 +268,7 @@ public CalendarNameProvider getCalendarNameProvider() { if (calendarNameProvider == null) { CalendarNameProvider provider; - provider = new CalendarNameProviderImpl(getAdapterType(), - getLanguageTagSet("FormatData")); + provider = new CalendarNameProviderImpl(getAdapterType()); synchronized (this) { if (calendarNameProvider == null) { calendarNameProvider = provider; @@ -295,8 +284,7 @@ @Override public CalendarProvider getCalendarProvider() { if (calendarProvider == null) { - CalendarProvider provider = new CalendarProviderImpl(getAdapterType(), - getLanguageTagSet("CalendarData")); + CalendarProvider provider = new CalendarProviderImpl(getAdapterType()); synchronized (this) { if (calendarProvider == null) { calendarProvider = provider; @@ -356,24 +344,54 @@ } protected Set createLanguageTagSet(String category) { - String supportedLocaleString = LocaleDataMetaInfo.getSupportedLocaleString(category); + String supportedLocaleString = createSupportedLocaleString(category); if (supportedLocaleString == null) { return Collections.emptySet(); } Set tagset = new HashSet<>(); StringTokenizer tokens = new StringTokenizer(supportedLocaleString); while (tokens.hasMoreTokens()) { - String token = tokens.nextToken(); - if (token.equals("|")) { - if (isNonENLangSupported()) { - continue; + 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 = JREENLocaleDataMetaInfo.getSupportedLocaleString(category); + + // Use ServiceLoader to dynamically acquire installede locales' tags. + try { + String nonENTags = AccessController.doPrivileged(new PrivilegedExceptionAction() { + @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; } - break; + }); + + if (nonENTags != null) { + supportedLocaleString += " " + nonENTags; } - tagset.add(token); + } catch (Exception e) { + // catch any exception, and ignore them as if non-EN locales do not exist. } - return tagset; + return supportedLocaleString; } /** @@ -387,27 +405,17 @@ 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 +438,4 @@ } 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() { - @Override - public Boolean run() { - return f.exists(); - } - }); - } - } - } - return isNonENSupported; - } }