src/share/classes/sun/util/locale/provider/SPILocaleProviderAdapter.java

Print this page
rev 5974 : imported patch 8000997

*** 26,37 **** package sun.util.locale.provider; import java.security.AccessController; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; ! import java.util.ServiceLoader; ! import java.util.spi.LocaleServiceProvider; /** * LocaleProviderAdapter implementation for the installed SPI implementations. * * @author Naoto Sato --- 26,40 ---- package sun.util.locale.provider; import java.security.AccessController; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; ! import java.text.*; ! import java.text.spi.*; ! import java.util.*; ! import java.util.concurrent.*; ! import java.util.spi.*; /** * LocaleProviderAdapter implementation for the installed SPI implementations. * * @author Naoto Sato
*** 52,69 **** try { return AccessController.doPrivileged(new PrivilegedExceptionAction<P>() { @Override @SuppressWarnings("unchecked") public P run() { ! P lsp = null; for (LocaleServiceProvider provider : ServiceLoader.loadInstalled(c)) { ! lsp = (P) provider; } - return lsp; } }); } catch (PrivilegedActionException e) { LocaleServiceProviderPool.config(SPILocaleProviderAdapter.class, e.toString()); } return null; } } --- 55,639 ---- try { return AccessController.doPrivileged(new PrivilegedExceptionAction<P>() { @Override @SuppressWarnings("unchecked") public P run() { ! P delegate = null; ! for (LocaleServiceProvider provider : ServiceLoader.loadInstalled(c)) { ! if (delegate == null) { ! try { ! delegate = ! (P) Class.forName(SPILocaleProviderAdapter.class.getCanonicalName() + ! "$" + ! c.getSimpleName() + ! "Delegate") ! .newInstance(); ! } catch (ClassNotFoundException | ! InstantiationException | ! IllegalAccessException e) { ! LocaleServiceProviderPool.config(SPILocaleProviderAdapter.class, e.toString()); ! return null; } } + + ((Delegate)delegate).addImpl(provider); + } + return delegate; + } }); } catch (PrivilegedActionException e) { LocaleServiceProviderPool.config(SPILocaleProviderAdapter.class, e.toString()); } return null; } + + /* + * Delegate interface. All the implementations have to have the class name + * following "<provider class name>Delegate" convention. + */ + interface Delegate<P extends LocaleServiceProvider> { + public void addImpl(P impl); + public P getImpl(Locale locale); + } + + /* + * Obtain the real SPI implementation, using locale fallback + */ + private static <P extends LocaleServiceProvider> P getImpl(Map<Locale, P> map, Locale locale) { + for (Locale l : LocaleServiceProviderPool.getLookupLocales(locale)) { + P ret = map.get(l); + if (ret != null) { + return ret; + } + } + return null; + } + + /* + * Delegates for the actual SPI implementations. + */ + static class BreakIteratorProviderDelegate extends BreakIteratorProvider + implements Delegate<BreakIteratorProvider> { + private ConcurrentMap<Locale, BreakIteratorProvider> map = new ConcurrentHashMap<>(); + + @Override + public void addImpl(BreakIteratorProvider impl) { + for (Locale l : impl.getAvailableLocales()) { + map.put(l, impl); + } + } + + @Override + public BreakIteratorProvider getImpl(Locale locale) { + return SPILocaleProviderAdapter.getImpl(map, locale); + } + + @Override + public Locale[] getAvailableLocales() { + return map.keySet().toArray(new Locale[0]); + } + + @Override + public boolean isSupportedLocale(Locale locale) { + return map.keySet().contains(locale); + } + + @Override + public BreakIterator getWordInstance(Locale locale) { + BreakIteratorProvider bip = getImpl(locale); + if (bip != null) { + return bip.getWordInstance(locale); + } else { + return null; + } + } + + @Override + public BreakIterator getLineInstance(Locale locale) { + BreakIteratorProvider bip = getImpl(locale); + if (bip != null) { + return bip.getLineInstance(locale); + } else { + return null; + } + } + + @Override + public BreakIterator getCharacterInstance(Locale locale) { + BreakIteratorProvider bip = getImpl(locale); + if (bip != null) { + return bip.getCharacterInstance(locale); + } else { + return null; + } + } + + @Override + public BreakIterator getSentenceInstance(Locale locale) { + BreakIteratorProvider bip = getImpl(locale); + if (bip != null) { + return bip.getSentenceInstance(locale); + } else { + return null; + } + } + + } + + static class CollatorProviderDelegate extends CollatorProvider implements Delegate<CollatorProvider> { + private ConcurrentMap<Locale, CollatorProvider> map = new ConcurrentHashMap<>(); + + @Override + public void addImpl(CollatorProvider impl) { + for (Locale l : impl.getAvailableLocales()) { + map.put(l, impl); + } + } + + @Override + public CollatorProvider getImpl(Locale locale) { + return SPILocaleProviderAdapter.getImpl(map, locale); + } + + @Override + public Locale[] getAvailableLocales() { + return map.keySet().toArray(new Locale[0]); + } + + @Override + public boolean isSupportedLocale(Locale locale) { + return map.keySet().contains(locale); + } + + @Override + public Collator getInstance(Locale locale) { + CollatorProvider cp = getImpl(locale); + if (cp != null) { + return cp.getInstance(locale); + } else { + return null; + } + } + } + + static class DateFormatProviderDelegate extends DateFormatProvider + implements Delegate<DateFormatProvider> { + private ConcurrentMap<Locale, DateFormatProvider> map = new ConcurrentHashMap<>(); + + @Override + public void addImpl(DateFormatProvider impl) { + for (Locale l : impl.getAvailableLocales()) { + map.put(l, impl); + } + } + + @Override + public DateFormatProvider getImpl(Locale locale) { + return SPILocaleProviderAdapter.getImpl(map, locale); + } + + @Override + public Locale[] getAvailableLocales() { + return map.keySet().toArray(new Locale[0]); + } + + @Override + public boolean isSupportedLocale(Locale locale) { + return map.keySet().contains(locale); + } + + @Override + public DateFormat getTimeInstance(int style, Locale locale) { + DateFormatProvider dfp = getImpl(locale); + if (dfp != null) { + return dfp.getTimeInstance(style, locale); + } else { + return null; + } + } + + @Override + public DateFormat getDateInstance(int style, Locale locale) { + DateFormatProvider dfp = getImpl(locale); + if (dfp != null) { + return dfp.getDateInstance(style, locale); + } else { + return null; + } + } + + @Override + public DateFormat getDateTimeInstance(int dateStyle, int timeStyle, Locale locale) { + DateFormatProvider dfp = getImpl(locale); + if (dfp != null) { + return dfp.getDateTimeInstance(dateStyle, timeStyle, locale); + } else { + return null; + } + } + } + + static class DateFormatSymbolsProviderDelegate extends DateFormatSymbolsProvider + implements Delegate<DateFormatSymbolsProvider> { + private ConcurrentMap<Locale, DateFormatSymbolsProvider> map = new ConcurrentHashMap<>(); + + @Override + public void addImpl(DateFormatSymbolsProvider impl) { + for (Locale l : impl.getAvailableLocales()) { + map.put(l, impl); + } + } + + @Override + public DateFormatSymbolsProvider getImpl(Locale locale) { + return SPILocaleProviderAdapter.getImpl(map, locale); + } + + @Override + public Locale[] getAvailableLocales() { + return map.keySet().toArray(new Locale[0]); + } + + @Override + public boolean isSupportedLocale(Locale locale) { + return map.keySet().contains(locale); + } + + @Override + public DateFormatSymbols getInstance(Locale locale) { + DateFormatSymbolsProvider dfsp = getImpl(locale); + if (dfsp != null) { + return dfsp.getInstance(locale); + } else { + return null; + } + } + } + + static class DecimalFormatSymbolsProviderDelegate extends DecimalFormatSymbolsProvider + implements Delegate<DecimalFormatSymbolsProvider> { + private ConcurrentMap<Locale, DecimalFormatSymbolsProvider> map = new ConcurrentHashMap<>(); + + @Override + public void addImpl(DecimalFormatSymbolsProvider impl) { + for (Locale l : impl.getAvailableLocales()) { + map.put(l, impl); + } + } + + @Override + public DecimalFormatSymbolsProvider getImpl(Locale locale) { + return SPILocaleProviderAdapter.getImpl(map, locale); + } + + @Override + public Locale[] getAvailableLocales() { + return map.keySet().toArray(new Locale[0]); + } + + @Override + public boolean isSupportedLocale(Locale locale) { + return map.keySet().contains(locale); + } + + @Override + public DecimalFormatSymbols getInstance(Locale locale) { + DecimalFormatSymbolsProvider dfsp = getImpl(locale); + if (dfsp != null) { + return dfsp.getInstance(locale); + } else { + return null; + } + } + } + + static class NumberFormatProviderDelegate extends NumberFormatProvider + implements Delegate<NumberFormatProvider> { + private ConcurrentMap<Locale, NumberFormatProvider> map = new ConcurrentHashMap<>(); + + @Override + public void addImpl(NumberFormatProvider impl) { + for (Locale l : impl.getAvailableLocales()) { + map.put(l, impl); + } + } + + @Override + public NumberFormatProvider getImpl(Locale locale) { + return SPILocaleProviderAdapter.getImpl(map, locale); + } + + @Override + public Locale[] getAvailableLocales() { + return map.keySet().toArray(new Locale[0]); + } + + @Override + public boolean isSupportedLocale(Locale locale) { + return map.keySet().contains(locale); + } + + @Override + public NumberFormat getCurrencyInstance(Locale locale) { + NumberFormatProvider nfp = getImpl(locale); + if (nfp != null) { + return nfp.getCurrencyInstance(locale); + } else { + return null; + } + } + + @Override + public NumberFormat getIntegerInstance(Locale locale) { + NumberFormatProvider nfp = getImpl(locale); + if (nfp != null) { + return nfp.getIntegerInstance(locale); + } else { + return null; + } + } + + @Override + public NumberFormat getNumberInstance(Locale locale) { + NumberFormatProvider nfp = getImpl(locale); + if (nfp != null) { + return nfp.getNumberInstance(locale); + } else { + return null; + } + } + + @Override + public NumberFormat getPercentInstance(Locale locale) { + NumberFormatProvider nfp = getImpl(locale); + if (nfp != null) { + return nfp.getPercentInstance(locale); + } else { + return null; + } + } + } + + static class CalendarDataProviderDelegate extends CalendarDataProvider + implements Delegate<CalendarDataProvider> { + private ConcurrentMap<Locale, CalendarDataProvider> map = new ConcurrentHashMap<>(); + + @Override + public void addImpl(CalendarDataProvider impl) { + for (Locale l : impl.getAvailableLocales()) { + map.put(l, impl); + } + } + + @Override + public CalendarDataProvider getImpl(Locale locale) { + return SPILocaleProviderAdapter.getImpl(map, locale); + } + + @Override + public Locale[] getAvailableLocales() { + return map.keySet().toArray(new Locale[0]); + } + + @Override + public boolean isSupportedLocale(Locale locale) { + return map.keySet().contains(locale); + } + + @Override + public int getFirstDayOfWeek(Locale locale) { + CalendarDataProvider cdp = getImpl(locale); + if (cdp != null) { + return cdp.getFirstDayOfWeek(locale); + } else { + return 0; + } + } + + @Override + public int getMinimalDaysInFirstWeek(Locale locale) { + CalendarDataProvider cdp = getImpl(locale); + if (cdp != null) { + return cdp.getMinimalDaysInFirstWeek(locale); + } else { + return 0; + } + } + + @Override + public String getDisplayName(String calendarType, + int field, int value, + int style, Locale locale) { + CalendarDataProvider cdp = getImpl(locale); + if (cdp != null) { + return cdp.getDisplayName(calendarType, field, value, style, locale); + } else { + return null; + } + } + + @Override + public Map<String, Integer> getDisplayNames(String calendarType, + int field, int style, + Locale locale) { + CalendarDataProvider cdp = getImpl(locale); + if (cdp != null) { + return cdp.getDisplayNames(calendarType, field, style, locale); + } else { + return null; + } + } + } + + static class CurrencyNameProviderDelegate extends CurrencyNameProvider + implements Delegate<CurrencyNameProvider> { + private ConcurrentMap<Locale, CurrencyNameProvider> map = new ConcurrentHashMap<>(); + + @Override + public void addImpl(CurrencyNameProvider impl) { + for (Locale l : impl.getAvailableLocales()) { + map.put(l, impl); + } + } + + @Override + public CurrencyNameProvider getImpl(Locale locale) { + return SPILocaleProviderAdapter.getImpl(map, locale); + } + + @Override + public Locale[] getAvailableLocales() { + return map.keySet().toArray(new Locale[0]); + } + + @Override + public boolean isSupportedLocale(Locale locale) { + return map.keySet().contains(locale); + } + + @Override + public String getSymbol(String currencyCode, Locale locale) { + CurrencyNameProvider cnp = getImpl(locale); + if (cnp != null) { + return cnp.getSymbol(currencyCode, locale); + } else { + return null; + } + } + + @Override + public String getDisplayName(String currencyCode, Locale locale) { + CurrencyNameProvider cnp = getImpl(locale); + if (cnp != null) { + return cnp.getDisplayName(currencyCode, locale); + } else { + return null; + } + } + } + + static class LocaleNameProviderDelegate extends LocaleNameProvider + implements Delegate<LocaleNameProvider> { + private ConcurrentMap<Locale, LocaleNameProvider> map = new ConcurrentHashMap<>(); + + @Override + public void addImpl(LocaleNameProvider impl) { + for (Locale l : impl.getAvailableLocales()) { + map.put(l, impl); + } + } + + @Override + public LocaleNameProvider getImpl(Locale locale) { + return SPILocaleProviderAdapter.getImpl(map, locale); + } + + @Override + public Locale[] getAvailableLocales() { + return map.keySet().toArray(new Locale[0]); + } + + @Override + public boolean isSupportedLocale(Locale locale) { + return map.keySet().contains(locale); + } + + @Override + public String getDisplayLanguage(String languageCode, Locale locale) { + LocaleNameProvider lnp = getImpl(locale); + if (lnp != null) { + return lnp.getDisplayLanguage(languageCode, locale); + } else { + return null; + } + } + + @Override + public String getDisplayScript(String scriptCode, Locale locale) { + LocaleNameProvider lnp = getImpl(locale); + if (lnp != null) { + return lnp.getDisplayScript(scriptCode, locale); + } else { + return null; + } + } + + @Override + public String getDisplayCountry(String countryCode, Locale locale) { + LocaleNameProvider lnp = getImpl(locale); + if (lnp != null) { + return lnp.getDisplayCountry(countryCode, locale); + } else { + return null; + } + } + + @Override + public String getDisplayVariant(String variant, Locale locale) { + LocaleNameProvider lnp = getImpl(locale); + if (lnp != null) { + return lnp.getDisplayVariant(variant, locale); + } else { + return null; + } + } + + } + + static class TimeZoneNameProviderDelegate extends TimeZoneNameProvider + implements Delegate<TimeZoneNameProvider> { + private ConcurrentMap<Locale, TimeZoneNameProvider> map = new ConcurrentHashMap<>(); + + @Override + public void addImpl(TimeZoneNameProvider impl) { + for (Locale l : impl.getAvailableLocales()) { + map.put(l, impl); + } + } + + @Override + public TimeZoneNameProvider getImpl(Locale locale) { + return SPILocaleProviderAdapter.getImpl(map, locale); + } + + @Override + public Locale[] getAvailableLocales() { + return map.keySet().toArray(new Locale[0]); + } + + @Override + public boolean isSupportedLocale(Locale locale) { + return map.keySet().contains(locale); + } + + @Override + public String getDisplayName(String ID, boolean daylight, int style, Locale locale) { + TimeZoneNameProvider tznp = getImpl(locale); + if (tznp != null) { + return tznp.getDisplayName(ID, daylight, style, locale); + } else { + return null; + } + } + } }