From 1203231cf954fd4097419f72fb7c7544f8cd044b Mon Sep 17 00:00:00 2001 From: Naoto Sato Date: Mon, 29 Oct 2012 10:42:41 -0700 Subject: [PATCH] 8000997: Multiple locale sensitive services cannot be loaded Reviewed-by: okutsu --- .../provider/LocaleServiceProviderPool.java | 2 +- .../provider/SPILocaleProviderAdapter.java | 504 +++++++++++++++++- .../CurrencyNameProviderTest.java | 30 +- .../CurrencyNameProviderTest.sh | 2 +- .../util/PluggableLocale/GenericTest.java | 2 + .../java/util/PluggableLocale/barprovider.jar | Bin 12810 -> 13747 bytes .../CurrencyNameProviderImpl2.java | 63 +++ .../util/PluggableLocale/providersrc/Makefile | 1 + .../java.util.spi.CurrencyNameProvider | 1 + 9 files changed, 595 insertions(+), 10 deletions(-) create mode 100644 jdk/test/java/util/PluggableLocale/providersrc/CurrencyNameProviderImpl2.java diff --git a/jdk/src/share/classes/sun/util/locale/provider/LocaleServiceProviderPool.java b/jdk/src/share/classes/sun/util/locale/provider/LocaleServiceProviderPool.java index 71e6b425887..2683b7dd62b 100644 --- a/jdk/src/share/classes/sun/util/locale/provider/LocaleServiceProviderPool.java +++ b/jdk/src/share/classes/sun/util/locale/provider/LocaleServiceProviderPool.java @@ -356,7 +356,7 @@ public final class LocaleServiceProviderPool { * @param locale the input locale * @return the list of candidate locales for the given locale */ - private static List getLookupLocales(Locale locale) { + static List getLookupLocales(Locale locale) { // Note: We currently use the default implementation of // ResourceBundle.Control.getCandidateLocales. The result // returned by getCandidateLocales are already normalized diff --git a/jdk/src/share/classes/sun/util/locale/provider/SPILocaleProviderAdapter.java b/jdk/src/share/classes/sun/util/locale/provider/SPILocaleProviderAdapter.java index 0f123c5d51b..cb4f9aee7de 100644 --- a/jdk/src/share/classes/sun/util/locale/provider/SPILocaleProviderAdapter.java +++ b/jdk/src/share/classes/sun/util/locale/provider/SPILocaleProviderAdapter.java @@ -28,8 +28,11 @@ 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; +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. @@ -54,11 +57,28 @@ public class SPILocaleProviderAdapter extends AuxLocaleProviderAdapter { @Override @SuppressWarnings("unchecked") public P run() { - P lsp = null; + P delegate = null; + for (LocaleServiceProvider provider : ServiceLoader.loadInstalled(c)) { - lsp = (P) provider; + 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; } - return lsp; + } + + ((Delegate)delegate).addImpl(provider); + } + return delegate; } }); } catch (PrivilegedActionException e) { @@ -66,4 +86,478 @@ public class SPILocaleProviderAdapter extends AuxLocaleProviderAdapter { } return null; } + + /* + * Delegate interface. All the implementations have to have the class name + * following "Delegate" convention. + */ + interface Delegate

{ + public void addImpl(P impl); + public P getImpl(Locale locale); +} + + /* + * Obtain the real SPI implementation, using locale fallback + */ + private static

P getImpl(Map 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 { + private ConcurrentMap 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.containsKey(locale); + } + + @Override + public BreakIterator getWordInstance(Locale locale) { + BreakIteratorProvider bip = getImpl(locale); + assert bip != null; + return bip.getWordInstance(locale); + } + + @Override + public BreakIterator getLineInstance(Locale locale) { + BreakIteratorProvider bip = getImpl(locale); + assert bip != null; + return bip.getLineInstance(locale); + } + + @Override + public BreakIterator getCharacterInstance(Locale locale) { + BreakIteratorProvider bip = getImpl(locale); + assert bip != null; + return bip.getCharacterInstance(locale); + } + + @Override + public BreakIterator getSentenceInstance(Locale locale) { + BreakIteratorProvider bip = getImpl(locale); + assert bip != null; + return bip.getSentenceInstance(locale); + } + + } + + static class CollatorProviderDelegate extends CollatorProvider implements Delegate { + private ConcurrentMap 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.containsKey(locale); + } + + @Override + public Collator getInstance(Locale locale) { + CollatorProvider cp = getImpl(locale); + assert cp != null; + return cp.getInstance(locale); + } + } + + static class DateFormatProviderDelegate extends DateFormatProvider + implements Delegate { + private ConcurrentMap 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.containsKey(locale); + } + + @Override + public DateFormat getTimeInstance(int style, Locale locale) { + DateFormatProvider dfp = getImpl(locale); + assert dfp != null; + return dfp.getTimeInstance(style, locale); + } + + @Override + public DateFormat getDateInstance(int style, Locale locale) { + DateFormatProvider dfp = getImpl(locale); + assert dfp != null; + return dfp.getDateInstance(style, locale); + } + + @Override + public DateFormat getDateTimeInstance(int dateStyle, int timeStyle, Locale locale) { + DateFormatProvider dfp = getImpl(locale); + assert dfp != null; + return dfp.getDateTimeInstance(dateStyle, timeStyle, locale); + } + } + + static class DateFormatSymbolsProviderDelegate extends DateFormatSymbolsProvider + implements Delegate { + private ConcurrentMap 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.containsKey(locale); + } + + @Override + public DateFormatSymbols getInstance(Locale locale) { + DateFormatSymbolsProvider dfsp = getImpl(locale); + assert dfsp != null; + return dfsp.getInstance(locale); + } + } + + static class DecimalFormatSymbolsProviderDelegate extends DecimalFormatSymbolsProvider + implements Delegate { + private ConcurrentMap 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.containsKey(locale); + } + + @Override + public DecimalFormatSymbols getInstance(Locale locale) { + DecimalFormatSymbolsProvider dfsp = getImpl(locale); + assert dfsp != null; + return dfsp.getInstance(locale); + } + } + + static class NumberFormatProviderDelegate extends NumberFormatProvider + implements Delegate { + private ConcurrentMap 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.containsKey(locale); + } + + @Override + public NumberFormat getCurrencyInstance(Locale locale) { + NumberFormatProvider nfp = getImpl(locale); + assert nfp != null; + return nfp.getCurrencyInstance(locale); + } + + @Override + public NumberFormat getIntegerInstance(Locale locale) { + NumberFormatProvider nfp = getImpl(locale); + assert nfp != null; + return nfp.getIntegerInstance(locale); + } + + @Override + public NumberFormat getNumberInstance(Locale locale) { + NumberFormatProvider nfp = getImpl(locale); + assert nfp != null; + return nfp.getNumberInstance(locale); + } + + @Override + public NumberFormat getPercentInstance(Locale locale) { + NumberFormatProvider nfp = getImpl(locale); + assert nfp != null; + return nfp.getPercentInstance(locale); + } + } + + static class CalendarDataProviderDelegate extends CalendarDataProvider + implements Delegate { + private ConcurrentMap 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.containsKey(locale); + } + + @Override + public int getFirstDayOfWeek(Locale locale) { + CalendarDataProvider cdp = getImpl(locale); + assert cdp != null; + return cdp.getFirstDayOfWeek(locale); + } + + @Override + public int getMinimalDaysInFirstWeek(Locale locale) { + CalendarDataProvider cdp = getImpl(locale); + assert cdp != null; + return cdp.getMinimalDaysInFirstWeek(locale); + } + + @Override + public String getDisplayName(String calendarType, + int field, int value, + int style, Locale locale) { + CalendarDataProvider cdp = getImpl(locale); + assert cdp != null; + return cdp.getDisplayName(calendarType, field, value, style, locale); + } + + @Override + public Map getDisplayNames(String calendarType, + int field, int style, + Locale locale) { + CalendarDataProvider cdp = getImpl(locale); + assert cdp != null; + return cdp.getDisplayNames(calendarType, field, style, locale); + } + } + + static class CurrencyNameProviderDelegate extends CurrencyNameProvider + implements Delegate { + private ConcurrentMap 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.containsKey(locale); + } + + @Override + public String getSymbol(String currencyCode, Locale locale) { + CurrencyNameProvider cnp = getImpl(locale); + assert cnp != null; + return cnp.getSymbol(currencyCode, locale); + } + + @Override + public String getDisplayName(String currencyCode, Locale locale) { + CurrencyNameProvider cnp = getImpl(locale); + assert cnp != null; + return cnp.getDisplayName(currencyCode, locale); + } + } + + static class LocaleNameProviderDelegate extends LocaleNameProvider + implements Delegate { + private ConcurrentMap 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.containsKey(locale); + } + + @Override + public String getDisplayLanguage(String languageCode, Locale locale) { + LocaleNameProvider lnp = getImpl(locale); + assert lnp != null; + return lnp.getDisplayLanguage(languageCode, locale); + } + + @Override + public String getDisplayScript(String scriptCode, Locale locale) { + LocaleNameProvider lnp = getImpl(locale); + assert lnp != null; + return lnp.getDisplayScript(scriptCode, locale); + } + + @Override + public String getDisplayCountry(String countryCode, Locale locale) { + LocaleNameProvider lnp = getImpl(locale); + assert lnp != null; + return lnp.getDisplayCountry(countryCode, locale); + } + + @Override + public String getDisplayVariant(String variant, Locale locale) { + LocaleNameProvider lnp = getImpl(locale); + assert lnp != null; + return lnp.getDisplayVariant(variant, locale); + } + } + + static class TimeZoneNameProviderDelegate extends TimeZoneNameProvider + implements Delegate { + private ConcurrentMap 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.containsKey(locale); + } + + @Override + public String getDisplayName(String ID, boolean daylight, int style, Locale locale) { + TimeZoneNameProvider tznp = getImpl(locale); + assert tznp != null; + return tznp.getDisplayName(ID, daylight, style, locale); + } + } } diff --git a/jdk/test/java/util/PluggableLocale/CurrencyNameProviderTest.java b/jdk/test/java/util/PluggableLocale/CurrencyNameProviderTest.java index 7c9f631258b..ebffc3f4f3c 100644 --- a/jdk/test/java/util/PluggableLocale/CurrencyNameProviderTest.java +++ b/jdk/test/java/util/PluggableLocale/CurrencyNameProviderTest.java @@ -48,10 +48,13 @@ public class CurrencyNameProviderTest extends ProviderTest { void test1() { com.bar.CurrencyNameProviderImpl cnp = new com.bar.CurrencyNameProviderImpl(); + com.bar.CurrencyNameProviderImpl2 cnp2 = new com.bar.CurrencyNameProviderImpl2(); Locale[] availloc = Locale.getAvailableLocales(); Locale[] testloc = availloc.clone(); List jreimplloc = Arrays.asList(LocaleProviderAdapter.forJRE().getCurrencyNameProvider().getAvailableLocales()); - List providerloc = Arrays.asList(cnp.getAvailableLocales()); + List providerloc = new ArrayList(); + providerloc.addAll(Arrays.asList(cnp.getAvailableLocales())); + providerloc.addAll(Arrays.asList(cnp2.getAvailableLocales())); for (Locale target: availloc) { // pure JRE implementation @@ -79,8 +82,13 @@ public class CurrencyNameProviderTest extends ProviderTest { String providerscurrency = null; String providersname = null; if (providerloc.contains(target)) { + if (cnp.isSupportedLocale(target)) { providerscurrency = cnp.getSymbol(c.getCurrencyCode(), target); providersname = cnp.getDisplayName(c.getCurrencyCode(), target); + } else { + providerscurrency = cnp2.getSymbol(c.getCurrencyCode(), target); + providersname = cnp2.getDisplayName(c.getCurrencyCode(), target); + } } // JRE's name @@ -109,18 +117,22 @@ public class CurrencyNameProviderTest extends ProviderTest { final String pattern = "###,###\u00A4"; final String YEN_IN_OSAKA = "100,000\u5186\u3084\u3002"; final String YEN_IN_KYOTO = "100,000\u5186\u3069\u3059\u3002"; + final String YEN_IN_TOKYO= "100,000JPY-tokyo"; final Locale OSAKA = new Locale("ja", "JP", "osaka"); final Locale KYOTO = new Locale("ja", "JP", "kyoto"); + final Locale TOKYO = new Locale("ja", "JP", "tokyo"); Integer i = new Integer(100000); String formatted; DecimalFormat df; void test2() { + Locale defloc = Locale.getDefault(); + try { df = new DecimalFormat(pattern, DecimalFormatSymbols.getInstance(OSAKA)); System.out.println(formatted = df.format(i)); if(!formatted.equals(YEN_IN_OSAKA)) { - throw new RuntimeException("formatted zone names mismatch. " + + throw new RuntimeException("formatted currency names mismatch. " + "Should match with " + YEN_IN_OSAKA); } @@ -130,13 +142,25 @@ public class CurrencyNameProviderTest extends ProviderTest { df = new DecimalFormat(pattern, DecimalFormatSymbols.getInstance()); System.out.println(formatted = df.format(i)); if(!formatted.equals(YEN_IN_KYOTO)) { - throw new RuntimeException("formatted zone names mismatch. " + + throw new RuntimeException("formatted currency names mismatch. " + "Should match with " + YEN_IN_KYOTO); } df.parse(YEN_IN_KYOTO); + + Locale.setDefault(TOKYO); + df = new DecimalFormat(pattern, DecimalFormatSymbols.getInstance()); + System.out.println(formatted = df.format(i)); + if(!formatted.equals(YEN_IN_TOKYO)) { + throw new RuntimeException("formatted currency names mismatch. " + + "Should match with " + YEN_IN_TOKYO); + } + + df.parse(YEN_IN_TOKYO); } catch (ParseException pe) { throw new RuntimeException("parse error occured" + pe); + } finally { + Locale.setDefault(defloc); } } } diff --git a/jdk/test/java/util/PluggableLocale/CurrencyNameProviderTest.sh b/jdk/test/java/util/PluggableLocale/CurrencyNameProviderTest.sh index a0a9d582eae..f9abbe09071 100644 --- a/jdk/test/java/util/PluggableLocale/CurrencyNameProviderTest.sh +++ b/jdk/test/java/util/PluggableLocale/CurrencyNameProviderTest.sh @@ -23,6 +23,6 @@ #!/bin/sh # # @test -# @bug 4052440 +# @bug 4052440 8000997 # @summary CurrencyNameProvider tests # @run shell ExecTest.sh bar CurrencyNameProviderTest true diff --git a/jdk/test/java/util/PluggableLocale/GenericTest.java b/jdk/test/java/util/PluggableLocale/GenericTest.java index 3987f986bea..288d7a3ab04 100644 --- a/jdk/test/java/util/PluggableLocale/GenericTest.java +++ b/jdk/test/java/util/PluggableLocale/GenericTest.java @@ -38,6 +38,7 @@ public class GenericTest { com.foo.DecimalFormatSymbolsProviderImpl decimalFSP = new com.foo.DecimalFormatSymbolsProviderImpl(); com.foo.NumberFormatProviderImpl numberFP = new com.foo.NumberFormatProviderImpl(); com.bar.CurrencyNameProviderImpl currencyNP = new com.bar.CurrencyNameProviderImpl(); + com.bar.CurrencyNameProviderImpl2 currencyNP2 = new com.bar.CurrencyNameProviderImpl2(); com.bar.LocaleNameProviderImpl localeNP = new com.bar.LocaleNameProviderImpl(); com.bar.TimeZoneNameProviderImpl tzNP = new com.bar.TimeZoneNameProviderImpl(); com.bar.CalendarDataProviderImpl calDataP = new com.bar.CalendarDataProviderImpl(); @@ -68,6 +69,7 @@ public class GenericTest { expected.addAll(Arrays.asList(decimalFSP.getAvailableLocales())); expected.addAll(Arrays.asList(numberFP.getAvailableLocales())); expected.addAll(Arrays.asList(currencyNP.getAvailableLocales())); + expected.addAll(Arrays.asList(currencyNP2.getAvailableLocales())); expected.addAll(Arrays.asList(localeNP.getAvailableLocales())); expected.addAll(Arrays.asList(tzNP.getAvailableLocales())); expected.addAll(Arrays.asList(calDataP.getAvailableLocales())); diff --git a/jdk/test/java/util/PluggableLocale/barprovider.jar b/jdk/test/java/util/PluggableLocale/barprovider.jar index b5247a09262b7ad030f74b0cb32aca424065e4ca..901b2b2b7f6264a4f8fe6b7e4af75f573897e55e 100644 GIT binary patch delta 1600 zcmY*Z2~ZPf6kb9I7_M-HCL|;n8m`_I*cU<@*fze%eTL zKu=E(I20au!titLCGeHNFhpJgP)o}OMg_`J?xppU&JvL;P$Z-Y^xy@oxa`0Il#R%V z8519sn%X1{4K(w@+*$;4#;e7&=V+W~Y&+ISiMAdNU=xF-Wu1>~FaLh%o~rRrS=W|U z{~yD2q|$j+ZuR(W87Ax4s4TtojmJQXs-#P?Ygdc*sW#f03Ebt)gxEDv23v6*hcg9Q zF{U4J<|e~K$%(f0MN)pYgNgsA?xLIAlZwNquxz{N2wu>QtQ=c9I>c0cROam};GUJu zS!eL>`gHe9`#j%9YqX40v-XHbnVfHw>W$g^d)$NYmM>1rR3p_6JsA}j4!q^=4s!0$ zo=TXiX}|B7Tkc&!O{1LKUL;KqW;!0Y*~v4ltiTt&npij7PZ2lflwUYjC&HE^1^!XJ z+*=O|KNd)+x%J1N_w3C3ZPUxPlAhv(a_>g#e)&DK34X1!{O66X9gmPnWMjlD z&r6v~AUedP%JRD96a4(YDeQn7Ft&uIOqxsXG_ZcU_d47=f(HV|1$}&zfsbnq!P332w!aCr@vw6!f}xpE1ZU z%#T(R9b&J3*i)@zV$3@;SW}dL!Q3rn_n7h-`T^0eyzJTur?2{bOFG7P7T1r~8)(06 zt#zF!EqGiLP7<0(V!8F+M(?`0t_s52z@zg4wBi&i?G$B$W8Djef1)U~EV+{%rlbrs ze|B*zk2dWbTK;--FTD{LHc~e8N3CURMnhchHC{!t!l5xRxpbRXoZ+3iyA^|(4Q`8` ziyv}k9{64Hb!&18BDPG_l*!f$GpdC(Z%SD&2W9$I{yI_4p`zBOTdwLF`#r3bJf6Xq z$k9sRDTYdO6wdy2aZ-eKU=3R}(?X1hpsB2wK~QnB)woh z5IL5aE}1sGq}C-UaEg}>BYSOrh3Hd?i)rca~?9IQC#jJ^(iX+jXI_E5W z=6V+D`kDIQ{VfSr-e?HG-o;3L$68uVyGLBsr*{v}?mV`GsXH@_Tsj0|LVWgqNF-#? zy;^R-M8_t$J0?xj7+5dq*Qm;);vh65CnNxnR%jUjG?_ucSnwB& zK4{D|fL}~v5)j!Ikl6-|ST-dv30gm?F4OFofs_3|?qJ#*g;=m*e zB=|3r2v@XX5fCM0$ZP@fS$NnK51E1~U>=JL)9VoJvk$qvIkqJIFQNKbhUv^ zKuprWFt#82bTEQL0gWBZ!TW5@hpwChcU4;>nqU$~lkdeLAZi&lTpX?=aPcb-Y1IOFLAC@+6 zFb`bg`XRG%O8nydy!JP5n!UA7brvsHo2IC7)vB&pwPy0;#k-67p2x0j_7M;8X6J|q zY1*90z`#%s#E?*9hX&i^L%MsRZZe$QX(}@LxLz%o@2+nFrknKb!SoS*eK7q^-xy5m z7zBdp1}Lp*D9!YkYqBq&+TM|UtW zFx+8bU{C})2mwrmfr^#k3iqB2FWCT8cowKo3!w_gvJnF+l$g9vQe<+x5yY}QBWWfV zNwDxS8407IMf>HZnE= z`zq5|+PX@Wfgw3RS3fO3KPj5_Dds(oBlllPBt#O`dDY!3Xk*05BAuXoJiF0O|$^-2eap diff --git a/jdk/test/java/util/PluggableLocale/providersrc/CurrencyNameProviderImpl2.java b/jdk/test/java/util/PluggableLocale/providersrc/CurrencyNameProviderImpl2.java new file mode 100644 index 00000000000..5ed7222f95e --- /dev/null +++ b/jdk/test/java/util/PluggableLocale/providersrc/CurrencyNameProviderImpl2.java @@ -0,0 +1,63 @@ +/* + * 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. + * + * 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 com.bar; + +import java.util.*; +import java.util.spi.*; + +import com.foobar.Utils; + +public class CurrencyNameProviderImpl2 extends CurrencyNameProvider { + static Locale[] avail = {new Locale("ja", "JP", "tokyo")}; + public Locale[] getAvailableLocales() { + return avail; + } + + @Override + public String getSymbol(String c, Locale locale) { + if (!Utils.supportsLocale(Arrays.asList(avail), locale)) { + throw new IllegalArgumentException("locale is not supported: "+locale); + } + + if (c.equals("JPY") && Utils.supportsLocale(avail[0], locale)) { + return "JPY-tokyo"; + } + return null; + } + + @Override + public String getDisplayName(String c, Locale locale) { + if (!Utils.supportsLocale(Arrays.asList(avail), locale)) { + throw new IllegalArgumentException("locale is not supported: "+locale); + } + + if (c.equals("JPY") && Utils.supportsLocale(avail[0], locale)) { + return "JPY-tokyo"; + } + return null; + } +} diff --git a/jdk/test/java/util/PluggableLocale/providersrc/Makefile b/jdk/test/java/util/PluggableLocale/providersrc/Makefile index d69cecd149d..3c550992691 100644 --- a/jdk/test/java/util/PluggableLocale/providersrc/Makefile +++ b/jdk/test/java/util/PluggableLocale/providersrc/Makefile @@ -35,6 +35,7 @@ FOOFILES_JAVA = \ BARFILES_JAVA = \ CurrencyNameProviderImpl.java \ + CurrencyNameProviderImpl2.java \ TimeZoneNameProviderImpl.java \ LocaleNameProviderImpl.java \ CalendarDataProviderImpl.java \ diff --git a/jdk/test/java/util/PluggableLocale/providersrc/java.util.spi.CurrencyNameProvider b/jdk/test/java/util/PluggableLocale/providersrc/java.util.spi.CurrencyNameProvider index 938d6b090c1..9817ed386e2 100644 --- a/jdk/test/java/util/PluggableLocale/providersrc/java.util.spi.CurrencyNameProvider +++ b/jdk/test/java/util/PluggableLocale/providersrc/java.util.spi.CurrencyNameProvider @@ -5,3 +5,4 @@ # implementation class # com.bar.CurrencyNameProviderImpl +com.bar.CurrencyNameProviderImpl2