--- old/make/java/java/FILES_java.gmk Fri Jan 11 10:33:37 2013 +++ new/make/java/java/FILES_java.gmk Fri Jan 11 10:33:35 2013 @@ -227,6 +227,7 @@ sun/util/locale/provider/LocaleResources.java \ sun/util/locale/provider/NumberFormatProviderImpl.java \ sun/util/locale/provider/RuleBasedBreakIterator.java \ + sun/util/locale/provider/ResourceBundleBasedAdapter.java \ sun/util/locale/provider/SPILocaleProviderAdapter.java \ sun/util/locale/provider/TimeZoneNameProviderImpl.java \ sun/util/locale/provider/TimeZoneNameUtility.java \ --- old/src/share/classes/java/text/DateFormatSymbols.java Fri Jan 11 10:33:43 2013 +++ new/src/share/classes/java/text/DateFormatSymbols.java Fri Jan 11 10:33:41 2013 @@ -52,6 +52,7 @@ import java.util.concurrent.ConcurrentMap; import sun.util.locale.provider.LocaleProviderAdapter; import sun.util.locale.provider.LocaleServiceProviderPool; +import sun.util.locale.provider.ResourceBundleBasedAdapter; import sun.util.locale.provider.TimeZoneNameUtility; /** @@ -680,13 +681,10 @@ // Initialize the fields from the ResourceBundle for locale. LocaleProviderAdapter adapter = LocaleProviderAdapter.getAdapter(DateFormatSymbolsProvider.class, locale); // Avoid any potential recursions - switch (adapter.getAdapterType()) { - case HOST: - case SPI: + if (!(adapter instanceof ResourceBundleBasedAdapter)) { adapter = LocaleProviderAdapter.getResourceBundleBased(); - break; } - ResourceBundle resource = adapter.getLocaleData().getDateFormatData(locale); + ResourceBundle resource = ((ResourceBundleBasedAdapter)adapter).getLocaleData().getDateFormatData(locale); // JRE and CLDR use different keys // JRE: Eras, short.Eras and narrow.Eras --- old/src/share/classes/java/text/DecimalFormat.java Fri Jan 11 10:33:48 2013 +++ new/src/share/classes/java/text/DecimalFormat.java Fri Jan 11 10:33:47 2013 @@ -54,6 +54,7 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import sun.util.locale.provider.LocaleProviderAdapter; +import sun.util.locale.provider.ResourceBundleBasedAdapter; /** * DecimalFormat is a concrete subclass of @@ -394,28 +395,17 @@ * @see java.text.NumberFormat#getPercentInstance */ public DecimalFormat() { + // Get the pattern for the default locale. Locale def = Locale.getDefault(Locale.Category.FORMAT); - // try to get the pattern from the cache - String pattern = cachedLocaleData.get(def); - if (pattern == null) { /* cache miss */ - // Get the pattern for the default locale. - LocaleProviderAdapter adapter = LocaleProviderAdapter.getAdapter(NumberFormatProvider.class, def); - switch (adapter.getAdapterType()) { - case HOST: - case SPI: - adapter = LocaleProviderAdapter.getResourceBundleBased(); - break; - } - ResourceBundle rb = adapter.getLocaleData().getNumberFormatData(def); - String[] all = rb.getStringArray("NumberPatterns"); - pattern = all[0]; - /* update cache */ - cachedLocaleData.putIfAbsent(def, pattern); + LocaleProviderAdapter adapter = LocaleProviderAdapter.getAdapter(NumberFormatProvider.class, def); + if (!(adapter instanceof ResourceBundleBasedAdapter)) { + adapter = LocaleProviderAdapter.getResourceBundleBased(); } + String[] all = adapter.getLocaleResources(def).getNumberPatterns(); // Always applyPattern after the symbols are set this.symbols = DecimalFormatSymbols.getInstance(def); - applyPattern(pattern, false); + applyPattern(all[0], false); } @@ -4154,10 +4144,4 @@ // Proclaim JDK 1.1 serial compatibility. static final long serialVersionUID = 864413376551465018L; - - /** - * Cache to hold the NumberPattern of a Locale. - */ - private static final ConcurrentMap cachedLocaleData - = new ConcurrentHashMap<>(3); } --- old/src/share/classes/java/text/DecimalFormatSymbols.java Fri Jan 11 10:33:55 2013 +++ new/src/share/classes/java/text/DecimalFormatSymbols.java Fri Jan 11 10:33:53 2013 @@ -52,6 +52,7 @@ import java.util.concurrent.ConcurrentMap; import sun.util.locale.provider.LocaleProviderAdapter; import sun.util.locale.provider.LocaleServiceProviderPool; +import sun.util.locale.provider.ResourceBundleBasedAdapter; /** * This class represents the set of symbols (such as the decimal separator, @@ -542,48 +543,13 @@ private void initialize( Locale locale ) { this.locale = locale; - // get resource bundle data - try the cache first - boolean needCacheUpdate = false; - Object[] data = cachedLocaleData.get(locale); - if (data == null) { /* cache miss */ - LocaleProviderAdapter adapter = LocaleProviderAdapter.getAdapter(DecimalFormatSymbolsProvider.class, locale); - // Avoid potential recursions - switch (adapter.getAdapterType()) { - case HOST: - case SPI: - adapter = LocaleProviderAdapter.getResourceBundleBased(); - break; - } - ResourceBundle rb = adapter.getLocaleData().getNumberFormatData(locale); - data = new Object[3]; - - // NumberElements look up. First, try the Unicode extension - String numElemKey; - String numberType = locale.getUnicodeLocaleType("nu"); - if (numberType != null) { - numElemKey = numberType + ".NumberElements"; - if (rb.containsKey(numElemKey)) { - data[0] = rb.getStringArray(numElemKey); - } - } - - // Next, try DefaultNumberingSystem value - if (data[0] == null && rb.containsKey("DefaultNumberingSystem")) { - numElemKey = rb.getString("DefaultNumberingSystem") + ".NumberElements"; - if (rb.containsKey(numElemKey)) { - data[0] = rb.getStringArray(numElemKey); - } - } - - // Last resort. No need to check the availability. - // Just let it throw MissingResourceException when needed. - if (data[0] == null) { - data[0] = rb.getStringArray("NumberElements"); - } - - needCacheUpdate = true; + // get resource bundle data + LocaleProviderAdapter adapter = LocaleProviderAdapter.getAdapter(DecimalFormatSymbolsProvider.class, locale); + // Avoid potential recursions + if (!(adapter instanceof ResourceBundleBasedAdapter)) { + adapter = LocaleProviderAdapter.getResourceBundleBased(); } - + Object[] data = adapter.getLocaleResources(locale).getDecimalFormatSymbolsData(); String[] numberElements = (String[]) data[0]; decimalSeparator = numberElements[0].charAt(0); @@ -618,7 +584,6 @@ currencySymbol = currency.getSymbol(locale); data[1] = intlCurrencySymbol; data[2] = currencySymbol; - needCacheUpdate = true; } } else { // default values @@ -633,10 +598,6 @@ // standard decimal separator for all locales that we support. // If that changes, add a new entry to NumberElements. monetarySeparator = decimalSeparator; - - if (needCacheUpdate) { - cachedLocaleData.putIfAbsent(locale, data); - } } /** @@ -850,11 +811,4 @@ * @since JDK 1.1.6 */ private int serialVersionOnStream = currentSerialVersion; - - /** - * cache to hold the NumberElements and the Currency - * of a Locale. - */ - private static final ConcurrentMap cachedLocaleData - = new ConcurrentHashMap<>(3); } --- old/src/share/classes/java/text/NumberFormat.java Fri Jan 11 10:34:00 2013 +++ new/src/share/classes/java/text/NumberFormat.java Fri Jan 11 10:33:59 2013 @@ -56,7 +56,6 @@ import java.util.spi.LocaleServiceProvider; import sun.util.locale.provider.LocaleProviderAdapter; import sun.util.locale.provider.LocaleServiceProviderPool; -import sun.util.resources.LocaleData; /** * NumberFormat is the abstract base class for all number --- old/src/share/classes/java/util/Locale.java Fri Jan 11 10:34:06 2013 +++ new/src/share/classes/java/util/Locale.java Fri Jan 11 10:34:05 2013 @@ -50,7 +50,6 @@ import java.util.spi.LocaleNameProvider; import sun.security.action.GetPropertyAction; -import sun.util.locale.provider.LocaleServiceProviderPool; import sun.util.locale.BaseLocale; import sun.util.locale.InternalLocaleBuilder; import sun.util.locale.LanguageTag; @@ -61,7 +60,9 @@ import sun.util.locale.LocaleUtils; import sun.util.locale.ParseStatus; import sun.util.locale.provider.LocaleProviderAdapter; -import sun.util.resources.OpenListResourceBundle; +import sun.util.locale.provider.LocaleResources; +import sun.util.locale.provider.LocaleServiceProviderPool; +import sun.util.locale.provider.ResourceBundleBasedAdapter; /** * A Locale object represents a specific geographical, political, @@ -1779,20 +1780,15 @@ if (baseLocale.getVariant().length() == 0) return ""; - OpenListResourceBundle bundle = LocaleProviderAdapter.forJRE().getLocaleData().getLocaleNames(inLocale); + LocaleResources lr = LocaleProviderAdapter.forJRE().getLocaleResources(inLocale); - String names[] = getDisplayVariantArray(bundle, inLocale); + String names[] = getDisplayVariantArray(inLocale); // Get the localized patterns for formatting a list, and use // them to format the list. - String listPattern = null; - String listCompositionPattern = null; - try { - listPattern = bundle.getString("ListPattern"); - listCompositionPattern = bundle.getString("ListCompositionPattern"); - } catch (MissingResourceException e) { - } - return formatList(names, listPattern, listCompositionPattern); + return formatList(names, + lr.getLocaleName("ListPattern"), + lr.getLocaleName("ListCompositionPattern")); } /** @@ -1837,23 +1833,17 @@ * @throws NullPointerException if inLocale is null */ public String getDisplayName(Locale inLocale) { - OpenListResourceBundle bundle = LocaleProviderAdapter.forJRE().getLocaleData().getLocaleNames(inLocale); + LocaleResources lr = LocaleProviderAdapter.forJRE().getLocaleResources(inLocale); String languageName = getDisplayLanguage(inLocale); String scriptName = getDisplayScript(inLocale); String countryName = getDisplayCountry(inLocale); - String[] variantNames = getDisplayVariantArray(bundle, inLocale); + String[] variantNames = getDisplayVariantArray(inLocale); // Get the localized patterns for formatting a display name. - String displayNamePattern = null; - String listPattern = null; - String listCompositionPattern = null; - try { - displayNamePattern = bundle.getString("DisplayNamePattern"); - listPattern = bundle.getString("ListPattern"); - listCompositionPattern = bundle.getString("ListCompositionPattern"); - } catch (MissingResourceException e) { - } + String displayNamePattern = lr.getLocaleName("DisplayNamePattern"); + String listPattern = lr.getLocaleName("ListPattern"); + String listCompositionPattern = lr.getLocaleName("ListCompositionPattern"); // The display name consists of a main name, followed by qualifiers. // Typically, the format is "MainName (Qualifier, Qualifier)" but this @@ -2005,7 +1995,7 @@ * @param bundle the ResourceBundle to use to get the display names * @return an array of display names, possible of zero length. */ - private String[] getDisplayVariantArray(OpenListResourceBundle bundle, Locale inLocale) { + private String[] getDisplayVariantArray(Locale inLocale) { // Split the variant name into tokens separated by '_'. StringTokenizer tokenizer = new StringTokenizer(baseLocale.getVariant(), "_"); String[] names = new String[tokenizer.countTokens()]; --- old/src/share/classes/java/util/TimeZone.java Fri Jan 11 10:34:12 2013 +++ new/src/share/classes/java/util/TimeZone.java Fri Jan 11 10:34:11 2013 @@ -430,32 +430,7 @@ } private static String[] getDisplayNames(String id, Locale locale) { - Map>> displayNames = DisplayNames.CACHE; - - SoftReference> ref = displayNames.get(id); - if (ref != null) { - Map perLocale = ref.get(); - if (perLocale != null) { - String[] names = perLocale.get(locale); - if (names != null) { - return names; - } - names = TimeZoneNameUtility.retrieveDisplayNames(id, locale); - if (names != null) { - perLocale.put(locale, names); - } - return names; - } - } - - String[] names = TimeZoneNameUtility.retrieveDisplayNames(id, locale); - if (names != null) { - Map perLocale = new ConcurrentHashMap<>(); - perLocale.put(locale, names); - ref = new SoftReference<>(perLocale); - displayNames.put(id, ref); - } - return names; + return TimeZoneNameUtility.retrieveDisplayNames(id, locale); } /** --- old/src/share/classes/sun/text/resources/zh/CollationData_zh_HK.java Fri Jan 11 10:34:18 2013 +++ new/src/share/classes/sun/text/resources/zh/CollationData_zh_HK.java Fri Jan 11 10:34:17 2013 @@ -47,12 +47,13 @@ import java.util.Locale; import java.util.ResourceBundle; import sun.util.locale.provider.LocaleProviderAdapter; +import sun.util.locale.provider.ResourceBundleBasedAdapter; public class CollationData_zh_HK extends ListResourceBundle { // reparent to zh_TW for traditional Chinese collation sequence public CollationData_zh_HK() { - ResourceBundle bundle = LocaleProviderAdapter.forJRE().getLocaleData().getCollationData(Locale.TAIWAN); + ResourceBundle bundle = ((ResourceBundleBasedAdapter)LocaleProviderAdapter.forJRE()).getLocaleData().getCollationData(Locale.TAIWAN); setParent(bundle); } --- old/src/share/classes/sun/text/resources/zh/FormatData_zh_HK.java Fri Jan 11 10:34:24 2013 +++ new/src/share/classes/sun/text/resources/zh/FormatData_zh_HK.java Fri Jan 11 10:34:22 2013 @@ -44,12 +44,14 @@ import java.util.Locale; import java.util.ResourceBundle; import sun.util.locale.provider.LocaleProviderAdapter; +import sun.util.locale.provider.ResourceBundleBasedAdapter; public class FormatData_zh_HK extends ListResourceBundle { // reparent to zh_TW for traditional Chinese names public FormatData_zh_HK() { - ResourceBundle bundle = LocaleProviderAdapter.forJRE().getLocaleData().getDateFormatData(Locale.TAIWAN); + ResourceBundle bundle = ((ResourceBundleBasedAdapter)LocaleProviderAdapter.forJRE()) + .getLocaleData().getDateFormatData(Locale.TAIWAN); setParent(bundle); } --- old/src/share/classes/sun/util/locale/provider/AuxLocaleProviderAdapter.java Fri Jan 11 10:34:29 2013 +++ new/src/share/classes/sun/util/locale/provider/AuxLocaleProviderAdapter.java Fri Jan 11 10:34:28 2013 @@ -43,7 +43,6 @@ import java.util.spi.LocaleNameProvider; import java.util.spi.LocaleServiceProvider; import java.util.spi.TimeZoneNameProvider; -import sun.util.resources.LocaleData; /** * An abstract parent class for the @@ -145,11 +144,6 @@ public LocaleResources getLocaleResources(Locale locale) { return null; } - - @Override - public LocaleData getLocaleData() { - return null; - } private static Locale[] availableLocales = null; --- old/src/share/classes/sun/util/locale/provider/BreakIteratorProviderImpl.java Fri Jan 11 10:34:35 2013 +++ new/src/share/classes/sun/util/locale/provider/BreakIteratorProviderImpl.java Fri Jan 11 10:34:33 2013 @@ -25,12 +25,12 @@ package sun.util.locale.provider; +import java.io.IOException; import java.text.BreakIterator; import java.text.spi.BreakIteratorProvider; import java.util.Locale; -import java.util.ResourceBundle; +import java.util.MissingResourceException; import java.util.Set; -import sun.util.resources.LocaleData; /** * Concrete implementation of the {@link java.text.spi.BreakIteratorProvider @@ -159,24 +159,22 @@ throw new NullPointerException(); } - ResourceBundle bundle = LocaleData.getBundle( - LocaleProviderAdapter.Type.JRE.getTextResourcesPackage() + ".BreakIteratorInfo", locale); - String[] classNames = bundle.getStringArray("BreakIteratorClasses"); + LocaleResources lr = LocaleProviderAdapter.forJRE().getLocaleResources(locale); + String[] classNames = (String[]) lr.getBreakIteratorInfo("BreakIteratorClasses"); + String dataFile = (String) lr.getBreakIteratorInfo(dataName); - String dataFile = bundle.getString(dataName); - try { switch (classNames[type]) { case "RuleBasedBreakIterator": return new RuleBasedBreakIterator(dataFile); case "DictionaryBasedBreakIterator": - String dictionaryFile = bundle.getString(dictionaryName); + String dictionaryFile = (String) lr.getBreakIteratorInfo(dictionaryName); return new DictionaryBasedBreakIterator(dataFile, dictionaryFile); default: throw new IllegalArgumentException("Invalid break iterator class \"" + classNames[type] + "\""); } - } catch (Exception e) { + } catch (IOException | MissingResourceException | IllegalArgumentException e) { throw new InternalError(e.toString(), e); } } --- old/src/share/classes/sun/util/locale/provider/CalendarDataProviderImpl.java Fri Jan 11 10:34:41 2013 +++ new/src/share/classes/sun/util/locale/provider/CalendarDataProviderImpl.java Fri Jan 11 10:34:39 2013 @@ -24,10 +24,7 @@ */ package sun.util.locale.provider; -import java.util.Calendar; -import static java.util.Calendar.*; import java.util.Locale; -import java.util.ResourceBundle; import java.util.Set; import java.util.spi.CalendarDataProvider; @@ -49,12 +46,14 @@ @Override public int getFirstDayOfWeek(Locale locale) { - return getIntData(CalendarDataUtility.FIRST_DAY_OF_WEEK, locale); + return LocaleProviderAdapter.forType(type).getLocaleResources(locale) + .getCalendarData(CalendarDataUtility.FIRST_DAY_OF_WEEK); } @Override public int getMinimalDaysInFirstWeek(Locale locale) { - return getIntData(CalendarDataUtility.MINIMAL_DAYS_IN_FIRST_WEEK, locale); + return LocaleProviderAdapter.forType(type).getLocaleResources(locale) + .getCalendarData(CalendarDataUtility.MINIMAL_DAYS_IN_FIRST_WEEK); } @Override @@ -66,13 +65,4 @@ public Set getAvailableLanguageTags() { return langtags; } - - private int getIntData(String key, Locale locale) { - ResourceBundle rb = LocaleProviderAdapter.forType(type).getLocaleData().getCalendarData(locale); - if (rb.containsKey(key)) { - String firstday = rb.getString(key); - return Integer.parseInt(firstday); - } - return 0; - } } --- old/src/share/classes/sun/util/locale/provider/CalendarNameProviderImpl.java Fri Jan 11 10:34:46 2013 +++ new/src/share/classes/sun/util/locale/provider/CalendarNameProviderImpl.java Fri Jan 11 10:34:45 2013 @@ -28,7 +28,6 @@ import java.util.Comparator; import java.util.Locale; import java.util.Map; -import java.util.ResourceBundle; import java.util.Set; import java.util.TreeMap; import java.util.spi.CalendarNameProvider; @@ -54,23 +53,20 @@ String name = null; String key = getResourceKey(calendarType, field, style); if (key != null) { - ResourceBundle rb = LocaleProviderAdapter.forType(type).getLocaleData().getDateFormatData(locale); - if (rb.containsKey(key)) { - String[] strings = rb.getStringArray(key); - if (strings.length > 0) { - if (field == DAY_OF_WEEK || field == YEAR) { - --value; - } - name = strings[value]; - // If name is empty in standalone, try its `format' style. - if (name.length() == 0 - && (style == SHORT_STANDALONE || style == LONG_STANDALONE - || style == NARROW_STANDALONE)) { - name = getDisplayName(calendarType, field, value, - getBaseStyle(style), - locale); - } + String[] strings = LocaleProviderAdapter.forType(type).getLocaleResources(locale).getCalendarNames(key); + if (strings != null && strings.length > 0) { + if (field == DAY_OF_WEEK || field == YEAR) { + --value; } + name = strings[value]; + // If name is empty in standalone, try its `format' style. + if (name.length() == 0 + && (style == SHORT_STANDALONE || style == LONG_STANDALONE + || style == NARROW_STANDALONE)) { + name = getDisplayName(calendarType, field, value, + getBaseStyle(style), + locale); + } } } return name; @@ -100,9 +96,8 @@ String key = getResourceKey(calendarType, field, style); Map map = new TreeMap<>(LengthBasedComparator.INSTANCE); if (key != null) { - ResourceBundle rb = LocaleProviderAdapter.forType(type).getLocaleData().getDateFormatData(locale); - if (rb.containsKey(key)) { - String[] strings = rb.getStringArray(key); + String[] strings = LocaleProviderAdapter.forType(type).getLocaleResources(locale).getCalendarNames(key); + if (strings != null) { if (!hasDuplicates(strings)) { if (field == YEAR) { if (strings.length > 0) { --- old/src/share/classes/sun/util/locale/provider/CollatorProviderImpl.java Fri Jan 11 10:34:52 2013 +++ new/src/share/classes/sun/util/locale/provider/CollatorProviderImpl.java Fri Jan 11 10:34:51 2013 @@ -45,8 +45,6 @@ import java.text.RuleBasedCollator; import java.text.spi.CollatorProvider; import java.util.Locale; -import java.util.MissingResourceException; -import java.util.ResourceBundle; import java.util.Set; /** @@ -102,14 +100,7 @@ // Load the resource of the desired locale from resource // manager. - String colString = ""; - try { - ResourceBundle resource = LocaleProviderAdapter.forType(type).getLocaleData().getCollationData(locale); - - colString = resource.getString("Rule"); - } catch (MissingResourceException e) { - // Use default values - } + String colString = LocaleProviderAdapter.forType(type).getLocaleResources(locale).getCollationData(); try { result = new RuleBasedCollator(CollationRules.DEFAULTRULES + --- old/src/share/classes/sun/util/locale/provider/CurrencyNameProviderImpl.java Fri Jan 11 10:34:58 2013 +++ new/src/share/classes/sun/util/locale/provider/CurrencyNameProviderImpl.java Fri Jan 11 10:34:56 2013 @@ -26,7 +26,6 @@ package sun.util.locale.provider; import java.util.Locale; -import java.util.ResourceBundle; import java.util.Set; import java.util.spi.CurrencyNameProvider; @@ -120,11 +119,6 @@ throw new NullPointerException(); } - ResourceBundle bundle = LocaleProviderAdapter.forType(type).getLocaleData().getCurrencyNames(locale); - if (bundle.containsKey(key)) { - return bundle.getString(key); - } - - return null; + return LocaleProviderAdapter.forType(type).getLocaleResources(locale).getCurrencyName(key); } } --- old/src/share/classes/sun/util/locale/provider/JRELocaleProviderAdapter.java Fri Jan 11 10:35:03 2013 +++ new/src/share/classes/sun/util/locale/provider/JRELocaleProviderAdapter.java Fri Jan 11 10:35:02 2013 @@ -54,7 +54,7 @@ * @author Naoto Sato * @author Masayoshi Okutsu */ -public class JRELocaleProviderAdapter extends LocaleProviderAdapter { +public class JRELocaleProviderAdapter extends LocaleProviderAdapter implements ResourceBundleBasedAdapter { private static final String LOCALE_DATA_JAR_NAME = "localedata.jar"; @@ -296,6 +296,7 @@ return lr; } + // ResourceBundleBasedAdapter method implementation @Override public LocaleData getLocaleData() { if (localeData == null) { --- old/src/share/classes/sun/util/locale/provider/LocaleNameProviderImpl.java Fri Jan 11 10:35:09 2013 +++ new/src/share/classes/sun/util/locale/provider/LocaleNameProviderImpl.java Fri Jan 11 10:35:07 2013 @@ -26,7 +26,6 @@ package sun.util.locale.provider; import java.util.Locale; -import java.util.ResourceBundle; import java.util.Set; import java.util.spi.LocaleNameProvider; @@ -174,12 +173,7 @@ throw new NullPointerException(); } - ResourceBundle rb = LocaleProviderAdapter.forType(type).getLocaleData().getLocaleNames(locale); - if (rb.containsKey(key)) { - return rb.getString(key); - } - - return null; + return LocaleProviderAdapter.forType(type).getLocaleResources(locale).getLocaleName(key); } @Override --- old/src/share/classes/sun/util/locale/provider/LocaleProviderAdapter.java Fri Jan 11 10:35:15 2013 +++ new/src/share/classes/sun/util/locale/provider/LocaleProviderAdapter.java Fri Jan 11 10:35:13 2013 @@ -37,6 +37,8 @@ import java.util.Locale; import java.util.ResourceBundle; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; import java.util.spi.CalendarDataProvider; import java.util.spi.CalendarNameProvider; import java.util.spi.CurrencyNameProvider; @@ -44,7 +46,6 @@ import java.util.spi.LocaleServiceProvider; import java.util.spi.TimeZoneNameProvider; import sun.util.cldr.CLDRLocaleProviderAdapter; -import sun.util.resources.LocaleData; /** * The LocaleProviderAdapter abstract class. @@ -119,6 +120,12 @@ */ private static LocaleProviderAdapter fallbackLocaleProviderAdapter = null; + /** + * Adapter lookup cache. + */ + private static ConcurrentMap, ConcurrentMap> + adapterCache = new ConcurrentHashMap<>(); + static { String order = AccessController.doPrivileged( new sun.security.action.GetPropertyAction("java.locale.providers")); @@ -210,9 +217,23 @@ */ public static LocaleProviderAdapter getAdapter(Class providerClass, Locale locale) { + LocaleProviderAdapter adapter; + + // cache lookup + ConcurrentMap adapterMap = adapterCache.get(providerClass); + if (adapterMap != null) { + if ((adapter = adapterMap.get(locale)) != null) { + return adapter; + } + } else { + adapterMap = new ConcurrentHashMap<>(); + adapterCache.putIfAbsent(providerClass, adapterMap); + } + // Fast look-up for the given locale - LocaleProviderAdapter adapter = findAdapter(providerClass, locale); + adapter = findAdapter(providerClass, locale); if (adapter != null) { + adapterMap.putIfAbsent(locale, adapter); return adapter; } @@ -226,11 +247,13 @@ } adapter = findAdapter(providerClass, loc); if (adapter != null) { + adapterMap.putIfAbsent(locale, adapter); return adapter; } } // returns the adapter for FALLBACK as the last resort + adapterMap.putIfAbsent(locale, fallbackLocaleProviderAdapter); return fallbackLocaleProviderAdapter; } @@ -398,7 +421,5 @@ public abstract LocaleResources getLocaleResources(Locale locale); - public abstract LocaleData getLocaleData(); - public abstract Locale[] getAvailableLocales(); } --- old/src/share/classes/sun/util/locale/provider/LocaleResources.java Fri Jan 11 10:35:20 2013 +++ new/src/share/classes/sun/util/locale/provider/LocaleResources.java Fri Jan 11 10:35:19 2013 @@ -40,45 +40,297 @@ package sun.util.locale.provider; +import java.lang.ref.ReferenceQueue; +import java.lang.ref.SoftReference; import java.text.MessageFormat; import java.util.Calendar; +import java.util.LinkedHashSet; import java.util.Locale; +import java.util.Map; import java.util.ResourceBundle; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; +import sun.util.calendar.ZoneInfo; +import sun.util.resources.LocaleData; +import sun.util.resources.OpenListResourceBundle; import sun.util.resources.TimeZoneNamesBundle; /** - * Central accessor to locale-dependent resources. + * Central accessor to locale-dependent resources for JRE/CLDR provider adapters. * * @author Masayoshi Okutsu + * @author Naoto Sato */ public class LocaleResources { - private final LocaleProviderAdapter adapter; private final Locale locale; + private final LocaleData localeData; + private final LocaleProviderAdapter.Type type; // Resource cache - private ConcurrentMap cache = new ConcurrentHashMap<>(); + private ConcurrentMap cache = new ConcurrentHashMap<>(); + private ReferenceQueue referenceQueue = new ReferenceQueue<>(); + // cache key prefixes + private static final String BREAK_ITERATOR_INFO = "BII."; + private static final String CALENDAR_DATA = "CALD."; + private static final String COLLATION_DATA_CACHEKEY = "COLD"; + private static final String DECIMAL_FORMAT_SYMBOLS_DATA_CACHEKEY = "DFSD"; + private static final String CURRENCY_NAMES = "CN."; + private static final String LOCALE_NAMES = "LN."; + private static final String TIME_ZONE_NAMES = "TZN."; + private static final String ZONE_IDS_CACHEKEY = "ZID"; + private static final String CALENDAR_NAMES = "CALN."; + private static final String NUMBER_PATTERNS_CACHEKEY = "NP"; + private static final String DATE_TIME_PATTERN = "DTP."; - LocaleResources(LocaleProviderAdapter adapter, Locale locale) { - this.adapter = adapter; + // null singleton cache value + private static final Object NULLOBJECT = new Object(); + + LocaleResources(ResourceBundleBasedAdapter adapter, Locale locale) { this.locale = locale; + this.localeData = adapter.getLocaleData(); + type = ((LocaleProviderAdapter)adapter).getAdapterType(); } - public TimeZoneNamesBundle getTimeZoneNames() { - TimeZoneNamesBundle tznames = (TimeZoneNamesBundle) cache.get("TimeZoneNames"); - if (tznames == null) { - tznames = adapter.getLocaleData().getTimeZoneNames(locale); - TimeZoneNamesBundle tznb = (TimeZoneNamesBundle) cache.putIfAbsent("TimeZoneNames", tznames); - if (tznb != null) { - tznames = tznb; + private void removeEmptyReferences() { + Object ref; + while ((ref = referenceQueue.poll()) != null) { + cache.remove(((ResourceReference)ref).getCacheKey()); + } + } + + Object getBreakIteratorInfo(String key) { + Object biInfo; + String cacheKey = BREAK_ITERATOR_INFO + key; + + removeEmptyReferences(); + ResourceReference data = cache.get(cacheKey); + if (data == null || ((biInfo = data.get()) == null)) { + biInfo = localeData.getBreakIteratorInfo(locale).getObject(key); + cache.put(cacheKey, new ResourceReference(cacheKey, biInfo, referenceQueue)); + } + + return biInfo; + } + + int getCalendarData(String key) { + Integer caldata; + String cacheKey = CALENDAR_DATA + key; + + removeEmptyReferences(); + + ResourceReference data = cache.get(cacheKey); + if (data == null || ((caldata = (Integer) data.get()) == null)) { + ResourceBundle rb = localeData.getCalendarData(locale); + if (rb.containsKey(key)) { + caldata = Integer.parseInt(rb.getString(key)); + } else { + caldata = 0; } + + cache.put(cacheKey, + new ResourceReference(cacheKey, (Object) caldata, referenceQueue)); } - return tznames; + + return caldata; } + public String getCollationData() { + String key = "Rule"; + String coldata = ""; + + removeEmptyReferences(); + ResourceReference data = cache.get(COLLATION_DATA_CACHEKEY); + if (data == null || ((coldata = (String) data.get()) == null)) { + ResourceBundle rb = localeData.getCollationData(locale); + if (rb.containsKey(key)) { + coldata = rb.getString(key); + } + cache.put(COLLATION_DATA_CACHEKEY, + new ResourceReference(COLLATION_DATA_CACHEKEY, (Object) coldata, referenceQueue)); + } + + return coldata; + } + + public Object[] getDecimalFormatSymbolsData() { + Object[] dfsdata; + + removeEmptyReferences(); + ResourceReference data = cache.get(DECIMAL_FORMAT_SYMBOLS_DATA_CACHEKEY); + if (data == null || ((dfsdata = (Object[]) data.get()) == null)) { + // Note that only dfsdata[0] is prepared here in this method. Other + // elements are provided by the caller, yet they are cached here. + ResourceBundle rb = localeData.getNumberFormatData(locale); + dfsdata = new Object[3]; + + // NumberElements look up. First, try the Unicode extension + String numElemKey; + String numberType = locale.getUnicodeLocaleType("nu"); + if (numberType != null) { + numElemKey = numberType + ".NumberElements"; + if (rb.containsKey(numElemKey)) { + dfsdata[0] = rb.getStringArray(numElemKey); + } + } + + // Next, try DefaultNumberingSystem value + if (dfsdata[0] == null && rb.containsKey("DefaultNumberingSystem")) { + numElemKey = rb.getString("DefaultNumberingSystem") + ".NumberElements"; + if (rb.containsKey(numElemKey)) { + dfsdata[0] = rb.getStringArray(numElemKey); + } + } + + // Last resort. No need to check the availability. + // Just let it throw MissingResourceException when needed. + if (dfsdata[0] == null) { + dfsdata[0] = rb.getStringArray("NumberElements"); + } + + cache.put(DECIMAL_FORMAT_SYMBOLS_DATA_CACHEKEY, + new ResourceReference(DECIMAL_FORMAT_SYMBOLS_DATA_CACHEKEY, (Object) dfsdata, referenceQueue)); + } + + return dfsdata; + } + + public String getCurrencyName(String key) { + Object currencyName = null; + String cacheKey = CURRENCY_NAMES + key; + + removeEmptyReferences(); + ResourceReference data = cache.get(cacheKey); + + if (data != null && ((currencyName = data.get()) != null)) { + if (currencyName.equals(NULLOBJECT)) { + currencyName = null; + } + + return (String) currencyName; + } + + OpenListResourceBundle olrb = localeData.getCurrencyNames(locale); + + if (olrb.containsKey(key)) { + currencyName = olrb.getObject(key); + cache.put(cacheKey, + new ResourceReference(cacheKey, currencyName, referenceQueue)); + } + + return (String) currencyName; + } + + public String getLocaleName(String key) { + Object localeName = null; + String cacheKey = LOCALE_NAMES + key; + + removeEmptyReferences(); + ResourceReference data = cache.get(cacheKey); + + if (data != null && ((localeName = data.get()) != null)) { + if (localeName.equals(NULLOBJECT)) { + localeName = null; + } + + return (String) localeName; + } + + OpenListResourceBundle olrb = localeData.getLocaleNames(locale); + + if (olrb.containsKey(key)) { + localeName = olrb.getObject(key); + cache.put(cacheKey, + new ResourceReference(cacheKey, localeName, referenceQueue)); + } + + return (String) localeName; + } + + String[] getTimeZoneNames(String key, int size) { + String[] names = null; + String cacheKey = TIME_ZONE_NAMES + key; + + removeEmptyReferences(); + ResourceReference data = cache.get(cacheKey); + + if (data == null || ((names = (String[]) data.get()) == null)) { + TimeZoneNamesBundle tznb = localeData.getTimeZoneNames(locale); + if (tznb.containsKey(key)) { + names = tznb.getStringArray(key, size); + cache.put(cacheKey, + new ResourceReference(cacheKey, (Object) names, referenceQueue)); + } + } + + return names; + } + + @SuppressWarnings("unchecked") + Set getZoneIDs() { + Set zoneIDs = null; + + removeEmptyReferences(); + ResourceReference data = cache.get(ZONE_IDS_CACHEKEY); + if (data == null || ((zoneIDs = (Set) data.get()) == null)) { + TimeZoneNamesBundle rb = localeData.getTimeZoneNames(locale); + zoneIDs = rb.keySet(); + cache.put(ZONE_IDS_CACHEKEY, + new ResourceReference(ZONE_IDS_CACHEKEY, (Object) zoneIDs, referenceQueue)); + } + + return zoneIDs; + } + + // zoneStrings are cached separately in TimeZoneNameUtility. + String[][] getZoneStrings() { + TimeZoneNamesBundle rb = localeData.getTimeZoneNames(locale); + Set keyset = getZoneIDs(); + // Use a LinkedHashSet to preseve the order + Set value = new LinkedHashSet<>(); + for (String key : keyset) { + value.add(rb.getStringArray(key)); + } + + // Add aliases data for CLDR + if (type == LocaleProviderAdapter.Type.CLDR) { + // Note: TimeZoneNamesBundle creates a String[] on each getStringArray call. + Map aliases = ZoneInfo.getAliasTable(); + for (String alias : aliases.keySet()) { + if (!keyset.contains(alias)) { + String tzid = aliases.get(alias); + if (keyset.contains(tzid)) { + String[] val = rb.getStringArray(tzid); + val[0] = alias; + value.add(val); + } + } + } + } + return value.toArray(new String[0][]); + } + + String[] getCalendarNames(String key) { + String[] names = null; + String cacheKey = CALENDAR_NAMES + key; + + removeEmptyReferences(); + ResourceReference data = cache.get(cacheKey); + + if (data == null || ((names = (String[]) data.get()) == null)) { + ResourceBundle rb = localeData.getDateFormatData(locale); + if (rb.containsKey(key)) { + names = rb.getStringArray(key); + cache.put(cacheKey, + new ResourceReference(cacheKey, (Object) names, referenceQueue)); + } + } + + return names; + } + public String getDateTimePattern(int timeStyle, int dateStyle, Calendar cal) { String pattern; @@ -120,23 +372,31 @@ } public String[] getNumberPatterns() { - /* try the cache first */ - String[] numberPatterns = (String[]) cache.get("NumberPatterns"); - if (numberPatterns == null) { /* cache miss */ - ResourceBundle resource = adapter.getLocaleData().getNumberFormatData(locale); + String[] numberPatterns = null; + + removeEmptyReferences(); + ResourceReference data = cache.get(NUMBER_PATTERNS_CACHEKEY); + + if (data == null || ((numberPatterns = (String[]) data.get()) == null)) { + ResourceBundle resource = localeData.getNumberFormatData(locale); numberPatterns = resource.getStringArray("NumberPatterns"); - /* update cache */ - cache.put("NumberPatterns", numberPatterns); + cache.put(NUMBER_PATTERNS_CACHEKEY, + new ResourceReference(NUMBER_PATTERNS_CACHEKEY, (Object) numberPatterns, referenceQueue)); } + return numberPatterns; } private String getDateTimePattern(String key, int styleIndex, String calendarType) { String resourceKey = "gregory".equals(calendarType) ? key : calendarType + "." + key; - /* try the cache first */ - String[] patterns = (String[]) cache.get(resourceKey); - if (patterns == null) { /* cache miss */ - ResourceBundle r = adapter.getLocaleData().getDateFormatData(locale); + String cacheKey = DATE_TIME_PATTERN + resourceKey; + String[] patterns = null; + + removeEmptyReferences(); + ResourceReference data = cache.get(cacheKey); + + if (data == null || ((patterns = (String[]) data.get()) == null)) { + ResourceBundle r = localeData.getDateFormatData(locale); if (r.containsKey(resourceKey)) { patterns = r.getStringArray(resourceKey); } else { @@ -143,9 +403,23 @@ assert !resourceKey.equals(key); patterns = r.getStringArray(key); } - /* update cache */ - cache.putIfAbsent(resourceKey, patterns); + cache.put(cacheKey, + new ResourceReference(cacheKey, (Object) patterns, referenceQueue)); } + return patterns[styleIndex]; } + + private static class ResourceReference extends SoftReference { + private final String cacheKey; + + ResourceReference(String cacheKey, Object o, ReferenceQueue q) { + super(o, q); + this.cacheKey = cacheKey; + } + + String getCacheKey() { + return cacheKey; + } + } } --- old/src/share/classes/sun/util/locale/provider/TimeZoneNameProviderImpl.java Fri Jan 11 10:35:26 2013 +++ new/src/share/classes/sun/util/locale/provider/TimeZoneNameProviderImpl.java Fri Jan 11 10:35:24 2013 @@ -25,14 +25,10 @@ package sun.util.locale.provider; -import java.util.LinkedHashSet; import java.util.Locale; -import java.util.Map; import java.util.Set; import java.util.TimeZone; import java.util.spi.TimeZoneNameProvider; -import sun.util.calendar.ZoneInfo; -import sun.util.resources.TimeZoneNamesBundle; /** * Concrete implementation of the @@ -123,9 +119,7 @@ if (id == null || locale == null) { throw new NullPointerException(); } - LocaleProviderAdapter adapter = LocaleProviderAdapter.forType(type); - TimeZoneNamesBundle rb = adapter.getLocaleResources(locale).getTimeZoneNames(); - return rb.containsKey(id) ? rb.getStringArray(id, n) : null; + return LocaleProviderAdapter.forType(type).getLocaleResources(locale).getTimeZoneNames(id, n); } /** @@ -136,30 +130,6 @@ * @return an array of time zone names arrays */ String[][] getZoneStrings(Locale locale) { - LocaleProviderAdapter adapter = LocaleProviderAdapter.forType(type); - TimeZoneNamesBundle rb = adapter.getLocaleResources(locale).getTimeZoneNames(); - Set keyset = rb.keySet(); - // Use a LinkedHashSet to preseve the order - Set value = new LinkedHashSet<>(); - for (String key : keyset) { - value.add(rb.getStringArray(key)); - } - - // Add aliases data for CLDR - if (type == LocaleProviderAdapter.Type.CLDR) { - // Note: TimeZoneNamesBundle creates a String[] on each getStringArray call. - Map aliases = ZoneInfo.getAliasTable(); - for (String alias : aliases.keySet()) { - if (!keyset.contains(alias)) { - String tzid = aliases.get(alias); - if (keyset.contains(tzid)) { - String[] val = rb.getStringArray(tzid); - val[0] = alias; - value.add(val); - } - } - } - } - return value.toArray(new String[0][]); + return LocaleProviderAdapter.forType(type).getLocaleResources(locale).getZoneStrings(); } } --- old/src/share/classes/sun/util/locale/provider/TimeZoneNameUtility.java Fri Jan 11 10:35:32 2013 +++ new/src/share/classes/sun/util/locale/provider/TimeZoneNameUtility.java Fri Jan 11 10:35:30 2013 @@ -30,11 +30,10 @@ import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.spi.TimeZoneNameProvider; import sun.util.calendar.ZoneInfo; -import sun.util.resources.OpenListResourceBundle; -import sun.util.resources.TimeZoneNamesBundle; /** * Utility class that deals with the localized time zone names @@ -45,15 +44,17 @@ public final class TimeZoneNameUtility { /** - * cache to hold time zone resource bundles. Keyed by Locale + * cache to hold time zone localized strings. Keyed by Locale */ - private static ConcurrentHashMap> cachedBundles = + private static ConcurrentHashMap> cachedZoneData = new ConcurrentHashMap<>(); /** - * cache to hold time zone localized strings. Keyed by Locale + * Cache for managing display names per timezone per locale + * The structure is: + * Map(key=id, value=SoftReference(Map(key=locale, value=displaynames))) */ - private static ConcurrentHashMap> cachedZoneData = + private static final Map>> cachedDisplayNames = new ConcurrentHashMap<>(); /** @@ -82,9 +83,9 @@ } // Performs per-ID retrieval. + Set zoneIDs = LocaleProviderAdapter.forJRE().getLocaleResources(locale).getZoneIDs(); List zones = new LinkedList<>(); - OpenListResourceBundle rb = getBundle(locale); - for (String key : rb.keySet()) { + for (String key : zoneIDs) { String[] names = retrieveDisplayNamesImpl(key, locale); if (names != null) { zones.add(names); @@ -137,20 +138,31 @@ private static String[] retrieveDisplayNamesImpl(String id, Locale locale) { LocaleServiceProviderPool pool = LocaleServiceProviderPool.getPool(TimeZoneNameProvider.class); - return pool.getLocalizedObject(TimeZoneNameArrayGetter.INSTANCE, locale, id); - } - private static TimeZoneNamesBundle getBundle(Locale locale) { - TimeZoneNamesBundle rb; - SoftReference data = cachedBundles.get(locale); - - if (data == null || ((rb = data.get()) == null)) { - rb = LocaleProviderAdapter.forJRE().getLocaleData().getTimeZoneNames(locale); - data = new SoftReference<>(rb); - cachedBundles.put(locale, data); + SoftReference> ref = cachedDisplayNames.get(id); + if (ref != null) { + Map perLocale = ref.get(); + if (perLocale != null) { + String[] names = perLocale.get(locale); + if (names != null) { + return names; + } + names = pool.getLocalizedObject(TimeZoneNameArrayGetter.INSTANCE, locale, id); + if (names != null) { + perLocale.put(locale, names); + } + return names; + } } - return rb; + String[] names = pool.getLocalizedObject(TimeZoneNameArrayGetter.INSTANCE, locale, id); + if (names != null) { + Map perLocale = new ConcurrentHashMap<>(); + perLocale.put(locale, names); + ref = new SoftReference<>(perLocale); + cachedDisplayNames.put(id, ref); + } + return names; } /** --- old/src/share/classes/sun/util/resources/LocaleData.java Fri Jan 11 10:35:38 2013 +++ new/src/share/classes/sun/util/resources/LocaleData.java Fri Jan 11 10:35:36 2013 @@ -99,6 +99,14 @@ } /** + * Gets a break iterator info resource bundle, using privileges + * to allow accessing a sun.* package. + */ + public ResourceBundle getBreakIteratorInfo(Locale locale) { + return getBundle(type.getTextResourcesPackage() + ".BreakIteratorInfo", locale); + } + + /** * Gets a collation data resource bundle, using privileges * to allow accessing a sun.* package. */ --- old/src/share/classes/sun/util/resources/zh/CurrencyNames_zh_HK.java Fri Jan 11 10:35:43 2013 +++ new/src/share/classes/sun/util/resources/zh/CurrencyNames_zh_HK.java Fri Jan 11 10:35:42 2013 @@ -80,6 +80,7 @@ import java.util.Locale; import java.util.ResourceBundle; import sun.util.locale.provider.LocaleProviderAdapter; +import sun.util.locale.provider.ResourceBundleBasedAdapter; import sun.util.resources.OpenListResourceBundle; public final class CurrencyNames_zh_HK extends OpenListResourceBundle { @@ -86,7 +87,7 @@ // reparent to zh_TW for traditional Chinese names public CurrencyNames_zh_HK() { - ResourceBundle bundle = LocaleProviderAdapter.forJRE().getLocaleData().getCurrencyNames(Locale.TAIWAN); + ResourceBundle bundle = ((ResourceBundleBasedAdapter)LocaleProviderAdapter.forJRE()).getLocaleData().getCurrencyNames(Locale.TAIWAN); setParent(bundle); } --- old/src/share/classes/sun/util/resources/zh/CurrencyNames_zh_SG.java Fri Jan 11 10:35:49 2013 +++ new/src/share/classes/sun/util/resources/zh/CurrencyNames_zh_SG.java Fri Jan 11 10:35:47 2013 @@ -28,6 +28,7 @@ import java.util.Locale; import java.util.ResourceBundle; import sun.util.locale.provider.LocaleProviderAdapter; +import sun.util.locale.provider.ResourceBundleBasedAdapter; import sun.util.resources.OpenListResourceBundle; public final class CurrencyNames_zh_SG extends OpenListResourceBundle { @@ -34,7 +35,7 @@ // reparent to zh_CN for simplified Chinese names public CurrencyNames_zh_SG() { - ResourceBundle bundle = LocaleProviderAdapter.forJRE().getLocaleData().getCurrencyNames(Locale.CHINA); + ResourceBundle bundle = ((ResourceBundleBasedAdapter)LocaleProviderAdapter.forJRE()).getLocaleData().getCurrencyNames(Locale.CHINA); setParent(bundle); } --- old/src/share/classes/sun/util/resources/zh/LocaleNames_zh_HK.java Fri Jan 11 10:35:55 2013 +++ new/src/share/classes/sun/util/resources/zh/LocaleNames_zh_HK.java Fri Jan 11 10:35:53 2013 @@ -28,6 +28,7 @@ import java.util.Locale; import java.util.ResourceBundle; import sun.util.locale.provider.LocaleProviderAdapter; +import sun.util.locale.provider.ResourceBundleBasedAdapter; import sun.util.resources.OpenListResourceBundle; public final class LocaleNames_zh_HK extends OpenListResourceBundle { @@ -34,7 +35,7 @@ // reparent to zh_TW for traditional Chinese names public LocaleNames_zh_HK() { - ResourceBundle bundle = LocaleProviderAdapter.forJRE().getLocaleData().getLocaleNames(Locale.TAIWAN); + ResourceBundle bundle = ((ResourceBundleBasedAdapter)LocaleProviderAdapter.forJRE()).getLocaleData().getLocaleNames(Locale.TAIWAN); setParent(bundle); } --- old/src/share/classes/sun/util/resources/zh/TimeZoneNames_zh_HK.java Fri Jan 11 10:36:00 2013 +++ new/src/share/classes/sun/util/resources/zh/TimeZoneNames_zh_HK.java Fri Jan 11 10:35:58 2013 @@ -41,6 +41,7 @@ import java.util.Locale; import java.util.ResourceBundle; import sun.util.locale.provider.LocaleProviderAdapter; +import sun.util.locale.provider.ResourceBundleBasedAdapter; import sun.util.resources.TimeZoneNamesBundle; public final class TimeZoneNames_zh_HK extends TimeZoneNamesBundle { @@ -47,7 +48,7 @@ // reparent to zh_TW for traditional Chinese names public TimeZoneNames_zh_HK() { - ResourceBundle bundle = LocaleProviderAdapter.forJRE().getLocaleData().getTimeZoneNames(Locale.TAIWAN); + ResourceBundle bundle = ((ResourceBundleBasedAdapter)LocaleProviderAdapter.forJRE()).getLocaleData().getTimeZoneNames(Locale.TAIWAN); setParent(bundle); } --- old/test/java/util/PluggableLocale/BreakIteratorProviderTest.java Fri Jan 11 10:36:05 2013 +++ new/test/java/util/PluggableLocale/BreakIteratorProviderTest.java Fri Jan 11 10:36:04 2013 @@ -67,8 +67,7 @@ for (Locale target: availloc) { // pure JRE implementation - ResourceBundle rb = LocaleProviderAdapter.forJRE().getLocaleData().getBundle( - "sun.text.resources.BreakIteratorInfo", target); + ResourceBundle rb = ((ResourceBundleBasedAdapter)LocaleProviderAdapter.forJRE()).getLocaleData().getBreakIteratorInfo(target); String[] classNames = rb.getStringArray("BreakIteratorClasses"); boolean jreSupportsLocale = jreimplloc.contains(target); --- old/test/java/util/PluggableLocale/CollatorProviderTest.java Fri Jan 11 10:36:11 2013 +++ new/test/java/util/PluggableLocale/CollatorProviderTest.java Fri Jan 11 10:36:09 2013 @@ -67,7 +67,7 @@ for (String tag : ((AvailableLanguageTags)LocaleProviderAdapter.forJRE().getCollatorProvider()).getAvailableLanguageTags()) { jreimplloc.add(Locale.forLanguageTag(tag)); } - ResourceBundle rb = LocaleProviderAdapter.forJRE().getLocaleData().getCollationData(target); + ResourceBundle rb = ((ResourceBundleBasedAdapter)LocaleProviderAdapter.forJRE()).getLocaleData().getCollationData(target); boolean jreSupportsLocale = jreimplloc.contains(target); // result object --- old/test/java/util/PluggableLocale/CurrencyNameProviderTest.java Fri Jan 11 10:36:16 2013 +++ new/test/java/util/PluggableLocale/CurrencyNameProviderTest.java Fri Jan 11 10:36:15 2013 @@ -58,7 +58,7 @@ for (Locale target: availloc) { // pure JRE implementation - OpenListResourceBundle rb = (OpenListResourceBundle)LocaleProviderAdapter.forJRE().getLocaleData().getCurrencyNames(target); + OpenListResourceBundle rb = ((ResourceBundleBasedAdapter)LocaleProviderAdapter.forJRE()).getLocaleData().getCurrencyNames(target); boolean jreSupportsTarget = jreimplloc.contains(target); for (Locale test: testloc) { --- old/test/java/util/PluggableLocale/DateFormatProviderTest.java Fri Jan 11 10:36:22 2013 +++ new/test/java/util/PluggableLocale/DateFormatProviderTest.java Fri Jan 11 10:36:20 2013 @@ -84,7 +84,7 @@ break; } // pure JRE implementation - ResourceBundle rb = LocaleProviderAdapter.forJRE().getLocaleData().getDateFormatData(target); + ResourceBundle rb = ((ResourceBundleBasedAdapter)LocaleProviderAdapter.forJRE()).getLocaleData().getDateFormatData(target); boolean jreSupportsLocale = jreimplloc.contains(target); // JRE string arrays --- old/test/java/util/PluggableLocale/DateFormatSymbolsProviderTest.java Fri Jan 11 10:36:27 2013 +++ new/test/java/util/PluggableLocale/DateFormatSymbolsProviderTest.java Fri Jan 11 10:36:26 2013 @@ -62,7 +62,7 @@ for (Locale target: availloc) { // pure JRE implementation - ResourceBundle rb = LocaleProviderAdapter.forJRE().getLocaleData().getDateFormatData(target); + ResourceBundle rb = ((ResourceBundleBasedAdapter)LocaleProviderAdapter.forJRE()).getLocaleData().getDateFormatData(target); boolean jreSupportsLocale = jreimplloc.contains(target); // JRE string arrays --- old/test/java/util/PluggableLocale/DecimalFormatSymbolsProviderTest.java Fri Jan 11 10:36:33 2013 +++ new/test/java/util/PluggableLocale/DecimalFormatSymbolsProviderTest.java Fri Jan 11 10:36:31 2013 @@ -61,17 +61,15 @@ for (Locale target: availloc) { // pure JRE implementation - ResourceBundle rb = LocaleProviderAdapter.forJRE().getLocaleData().getNumberFormatData(target); + Object[] data = LocaleProviderAdapter.forJRE().getLocaleResources(target).getDecimalFormatSymbolsData(); boolean jreSupportsLocale = jreimplloc.contains(target); // JRE string arrays String[] jres = new String[2]; if (jreSupportsLocale) { - try { - String[] tmp = rb.getStringArray("NumberElements"); - jres[0] = tmp[9]; // infinity - jres[1] = tmp[10]; // NaN - } catch (MissingResourceException mre) {} + String[] tmp = (String[]) data[0]; + jres[0] = tmp[9]; // infinity + jres[1] = tmp[10]; // NaN } // result object --- old/test/java/util/PluggableLocale/LocaleNameProviderTest.java Fri Jan 11 10:36:38 2013 +++ new/test/java/util/PluggableLocale/LocaleNameProviderTest.java Fri Jan 11 10:36:37 2013 @@ -49,7 +49,7 @@ for (Locale target: availloc) { // pure JRE implementation - OpenListResourceBundle rb = LocaleProviderAdapter.forJRE().getLocaleData().getLocaleNames(target); + OpenListResourceBundle rb = ((ResourceBundleBasedAdapter)LocaleProviderAdapter.forJRE()).getLocaleData().getLocaleNames(target); boolean jreSupportsTarget = jreimplloc.contains(target); for (Locale test: testloc) { --- old/test/java/util/PluggableLocale/NumberFormatProviderTest.java Fri Jan 11 10:36:44 2013 +++ new/test/java/util/PluggableLocale/NumberFormatProviderTest.java Fri Jan 11 10:36:42 2013 @@ -63,16 +63,12 @@ void objectValidityTest() { for (Locale target: availloc) { - // pure JRE implementation - ResourceBundle rb = LocaleProviderAdapter.forJRE().getLocaleData().getNumberFormatData(target); boolean jreSupportsLocale = jreimplloc.contains(target); // JRE string arrays String[] jreNumberPatterns = null; if (jreSupportsLocale) { - try { - jreNumberPatterns = rb.getStringArray("NumberPatterns"); - } catch (MissingResourceException mre) {} + jreNumberPatterns = LocaleProviderAdapter.forJRE().getLocaleResources(target).getNumberPatterns(); } // result object --- old/test/java/util/PluggableLocale/TimeZoneNameProviderTest.java Fri Jan 11 10:36:49 2013 +++ new/test/java/util/PluggableLocale/TimeZoneNameProviderTest.java Fri Jan 11 10:36:48 2013 @@ -52,7 +52,7 @@ for (Locale target: available) { // pure JRE implementation - OpenListResourceBundle rb = LocaleProviderAdapter.forJRE().getLocaleData().getTimeZoneNames(target); + OpenListResourceBundle rb = ((ResourceBundleBasedAdapter)LocaleProviderAdapter.forJRE()).getLocaleData().getTimeZoneNames(target); boolean jreSupportsTarget = jreimplloc.contains(target); for (String id: ids) { --- /dev/null Fri Jan 11 10:36:55 2013 +++ new/src/share/classes/sun/util/locale/provider/ResourceBundleBasedAdapter.java Fri Jan 11 10:36:53 2013 @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2012, 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; + +import sun.util.resources.LocaleData; + +/** + * Accessor for LocaleData + * + * @author Naoto Sato + */ +public interface ResourceBundleBasedAdapter { + public LocaleData getLocaleData(); +}