20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package sun.util.locale.provider;
27
28 import java.security.AccessController;
29 import java.text.spi.BreakIteratorProvider;
30 import java.text.spi.CollatorProvider;
31 import java.text.spi.DateFormatProvider;
32 import java.text.spi.DateFormatSymbolsProvider;
33 import java.text.spi.DecimalFormatSymbolsProvider;
34 import java.text.spi.NumberFormatProvider;
35 import java.util.ArrayList;
36 import java.util.List;
37 import java.util.Locale;
38 import java.util.ResourceBundle;
39 import java.util.Set;
40 import java.util.spi.CalendarDataProvider;
41 import java.util.spi.CalendarNameProvider;
42 import java.util.spi.CurrencyNameProvider;
43 import java.util.spi.LocaleNameProvider;
44 import java.util.spi.LocaleServiceProvider;
45 import java.util.spi.TimeZoneNameProvider;
46 import sun.util.cldr.CLDRLocaleProviderAdapter;
47 import sun.util.resources.LocaleData;
48
49 /**
50 * The LocaleProviderAdapter abstract class.
51 *
52 * @author Naoto Sato
53 * @author Masayoshi Okutsu
54 */
55 public abstract class LocaleProviderAdapter {
56 /**
57 * Adapter type.
58 */
59 public static enum Type {
60 JRE("sun.util.resources", "sun.text.resources"),
61 CLDR("sun.util.resources.cldr", "sun.text.resources.cldr"),
62 SPI,
63 HOST,
64 FALLBACK("sun.util.resources", "sun.text.resources");
65
66 private final String UTIL_RESOURCES_PACKAGE;
67 private final String TEXT_RESOURCES_PACKAGE;
102 * SPI Locale Data Adapter instance
103 */
104 private static LocaleProviderAdapter spiLocaleProviderAdapter = new SPILocaleProviderAdapter();
105
106 /**
107 * CLDR Locale Data Adapter instance, if any.
108 */
109 private static LocaleProviderAdapter cldrLocaleProviderAdapter = null;
110
111 /**
112 * HOST Locale Data Adapter instance, if any.
113 */
114 private static LocaleProviderAdapter hostLocaleProviderAdapter = null;
115
116 /**
117 * FALLBACK Locale Data Adapter instance. It's basically the same with JRE, but only kicks
118 * in for the root locale.
119 */
120 private static LocaleProviderAdapter fallbackLocaleProviderAdapter = null;
121
122 static {
123 String order = AccessController.doPrivileged(
124 new sun.security.action.GetPropertyAction("java.locale.providers"));
125 // Override adapterPreference with the properties one
126 if (order != null && order.length() != 0) {
127 String[] types = order.split(",");
128 List<Type> typeList = new ArrayList<>();
129 for (String type : types) {
130 try {
131 Type aType = Type.valueOf(type.trim().toUpperCase(Locale.ROOT));
132
133 // load adapter if necessary
134 switch (aType) {
135 case CLDR:
136 cldrLocaleProviderAdapter = new CLDRLocaleProviderAdapter();
137 break;
138 case HOST:
139 hostLocaleProviderAdapter = new HostLocaleProviderAdapter();
140 break;
141 }
193 throw new InternalError();
194 }
195 /**
196 * Returns the preference order of LocaleProviderAdapter.Type
197 */
198 public static Type[] getAdapterPreference() {
199 return adapterPreference;
200 }
201
202 /**
203 * Returns a LocaleProviderAdapter for the given locale service provider that
204 * best matches the given locale. This method returns the LocaleProviderAdapter
205 * for JRE if none is found for the given locale.
206 *
207 * @param providerClass the class for the locale service provider
208 * @param locale the desired locale.
209 * @return a LocaleProviderAdapter
210 */
211 public static LocaleProviderAdapter getAdapter(Class<? extends LocaleServiceProvider> providerClass,
212 Locale locale) {
213 // Fast look-up for the given locale
214 LocaleProviderAdapter adapter = findAdapter(providerClass, locale);
215 if (adapter != null) {
216 return adapter;
217 }
218
219 // Try finding an adapter in the normal candidate locales path of the given locale.
220 List<Locale> lookupLocales = ResourceBundle.Control.getControl(ResourceBundle.Control.FORMAT_DEFAULT)
221 .getCandidateLocales("", locale);
222 for (Locale loc : lookupLocales) {
223 if (loc.equals(locale)) {
224 // We've already done with this loc.
225 continue;
226 }
227 adapter = findAdapter(providerClass, loc);
228 if (adapter != null) {
229 return adapter;
230 }
231 }
232
233 // returns the adapter for FALLBACK as the last resort
234 return fallbackLocaleProviderAdapter;
235 }
236
237 private static LocaleProviderAdapter findAdapter(Class<? extends LocaleServiceProvider> providerClass,
238 Locale locale) {
239 for (Type type : getAdapterPreference()) {
240 LocaleProviderAdapter adapter = forType(type);
241 LocaleServiceProvider provider = adapter.getLocaleServiceProvider(providerClass);
242 if (provider != null) {
243 if (provider.isSupportedLocale(locale)) {
244 return adapter;
245 }
246 }
247 }
248 return null;
249 }
250
251 /**
252 * A utility method for implementing the default LocaleServiceProvider.isSupportedLocale
253 * for the JRE, CLDR, and FALLBACK adapters.
381 public abstract TimeZoneNameProvider getTimeZoneNameProvider();
382
383 /**
384 * Returns a CalendarDataProvider for this LocaleProviderAdapter, or null if no
385 * CalendarDataProvider is available.
386 *
387 * @return a CalendarDataProvider
388 */
389 public abstract CalendarDataProvider getCalendarDataProvider();
390
391 /**
392 * Returns a CalendarNameProvider for this LocaleProviderAdapter, or null if no
393 * CalendarNameProvider is available.
394 *
395 * @return a CalendarNameProvider
396 */
397 public abstract CalendarNameProvider getCalendarNameProvider();
398
399 public abstract LocaleResources getLocaleResources(Locale locale);
400
401 public abstract LocaleData getLocaleData();
402
403 public abstract Locale[] getAvailableLocales();
404 }
|
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package sun.util.locale.provider;
27
28 import java.security.AccessController;
29 import java.text.spi.BreakIteratorProvider;
30 import java.text.spi.CollatorProvider;
31 import java.text.spi.DateFormatProvider;
32 import java.text.spi.DateFormatSymbolsProvider;
33 import java.text.spi.DecimalFormatSymbolsProvider;
34 import java.text.spi.NumberFormatProvider;
35 import java.util.ArrayList;
36 import java.util.List;
37 import java.util.Locale;
38 import java.util.ResourceBundle;
39 import java.util.Set;
40 import java.util.concurrent.ConcurrentHashMap;
41 import java.util.concurrent.ConcurrentMap;
42 import java.util.spi.CalendarDataProvider;
43 import java.util.spi.CalendarNameProvider;
44 import java.util.spi.CurrencyNameProvider;
45 import java.util.spi.LocaleNameProvider;
46 import java.util.spi.LocaleServiceProvider;
47 import java.util.spi.TimeZoneNameProvider;
48 import sun.util.cldr.CLDRLocaleProviderAdapter;
49
50 /**
51 * The LocaleProviderAdapter abstract class.
52 *
53 * @author Naoto Sato
54 * @author Masayoshi Okutsu
55 */
56 public abstract class LocaleProviderAdapter {
57 /**
58 * Adapter type.
59 */
60 public static enum Type {
61 JRE("sun.util.resources", "sun.text.resources"),
62 CLDR("sun.util.resources.cldr", "sun.text.resources.cldr"),
63 SPI,
64 HOST,
65 FALLBACK("sun.util.resources", "sun.text.resources");
66
67 private final String UTIL_RESOURCES_PACKAGE;
68 private final String TEXT_RESOURCES_PACKAGE;
103 * SPI Locale Data Adapter instance
104 */
105 private static LocaleProviderAdapter spiLocaleProviderAdapter = new SPILocaleProviderAdapter();
106
107 /**
108 * CLDR Locale Data Adapter instance, if any.
109 */
110 private static LocaleProviderAdapter cldrLocaleProviderAdapter = null;
111
112 /**
113 * HOST Locale Data Adapter instance, if any.
114 */
115 private static LocaleProviderAdapter hostLocaleProviderAdapter = null;
116
117 /**
118 * FALLBACK Locale Data Adapter instance. It's basically the same with JRE, but only kicks
119 * in for the root locale.
120 */
121 private static LocaleProviderAdapter fallbackLocaleProviderAdapter = null;
122
123 /**
124 * Adapter lookup cache.
125 */
126 private static ConcurrentMap<Class<? extends LocaleServiceProvider>, ConcurrentMap<Locale, LocaleProviderAdapter>>
127 adapterCache = new ConcurrentHashMap<>();
128
129 static {
130 String order = AccessController.doPrivileged(
131 new sun.security.action.GetPropertyAction("java.locale.providers"));
132 // Override adapterPreference with the properties one
133 if (order != null && order.length() != 0) {
134 String[] types = order.split(",");
135 List<Type> typeList = new ArrayList<>();
136 for (String type : types) {
137 try {
138 Type aType = Type.valueOf(type.trim().toUpperCase(Locale.ROOT));
139
140 // load adapter if necessary
141 switch (aType) {
142 case CLDR:
143 cldrLocaleProviderAdapter = new CLDRLocaleProviderAdapter();
144 break;
145 case HOST:
146 hostLocaleProviderAdapter = new HostLocaleProviderAdapter();
147 break;
148 }
200 throw new InternalError();
201 }
202 /**
203 * Returns the preference order of LocaleProviderAdapter.Type
204 */
205 public static Type[] getAdapterPreference() {
206 return adapterPreference;
207 }
208
209 /**
210 * Returns a LocaleProviderAdapter for the given locale service provider that
211 * best matches the given locale. This method returns the LocaleProviderAdapter
212 * for JRE if none is found for the given locale.
213 *
214 * @param providerClass the class for the locale service provider
215 * @param locale the desired locale.
216 * @return a LocaleProviderAdapter
217 */
218 public static LocaleProviderAdapter getAdapter(Class<? extends LocaleServiceProvider> providerClass,
219 Locale locale) {
220 LocaleProviderAdapter adapter;
221
222 // cache lookup
223 ConcurrentMap<Locale, LocaleProviderAdapter> adapterMap = adapterCache.get(providerClass);
224 if (adapterMap != null) {
225 if ((adapter = adapterMap.get(locale)) != null) {
226 return adapter;
227 }
228 } else {
229 adapterMap = new ConcurrentHashMap<>();
230 adapterCache.putIfAbsent(providerClass, adapterMap);
231 }
232
233 // Fast look-up for the given locale
234 adapter = findAdapter(providerClass, locale);
235 if (adapter != null) {
236 adapterMap.putIfAbsent(locale, adapter);
237 return adapter;
238 }
239
240 // Try finding an adapter in the normal candidate locales path of the given locale.
241 List<Locale> lookupLocales = ResourceBundle.Control.getControl(ResourceBundle.Control.FORMAT_DEFAULT)
242 .getCandidateLocales("", locale);
243 for (Locale loc : lookupLocales) {
244 if (loc.equals(locale)) {
245 // We've already done with this loc.
246 continue;
247 }
248 adapter = findAdapter(providerClass, loc);
249 if (adapter != null) {
250 adapterMap.putIfAbsent(locale, adapter);
251 return adapter;
252 }
253 }
254
255 // returns the adapter for FALLBACK as the last resort
256 adapterMap.putIfAbsent(locale, fallbackLocaleProviderAdapter);
257 return fallbackLocaleProviderAdapter;
258 }
259
260 private static LocaleProviderAdapter findAdapter(Class<? extends LocaleServiceProvider> providerClass,
261 Locale locale) {
262 for (Type type : getAdapterPreference()) {
263 LocaleProviderAdapter adapter = forType(type);
264 LocaleServiceProvider provider = adapter.getLocaleServiceProvider(providerClass);
265 if (provider != null) {
266 if (provider.isSupportedLocale(locale)) {
267 return adapter;
268 }
269 }
270 }
271 return null;
272 }
273
274 /**
275 * A utility method for implementing the default LocaleServiceProvider.isSupportedLocale
276 * for the JRE, CLDR, and FALLBACK adapters.
404 public abstract TimeZoneNameProvider getTimeZoneNameProvider();
405
406 /**
407 * Returns a CalendarDataProvider for this LocaleProviderAdapter, or null if no
408 * CalendarDataProvider is available.
409 *
410 * @return a CalendarDataProvider
411 */
412 public abstract CalendarDataProvider getCalendarDataProvider();
413
414 /**
415 * Returns a CalendarNameProvider for this LocaleProviderAdapter, or null if no
416 * CalendarNameProvider is available.
417 *
418 * @return a CalendarNameProvider
419 */
420 public abstract CalendarNameProvider getCalendarNameProvider();
421
422 public abstract LocaleResources getLocaleResources(Locale locale);
423
424 public abstract Locale[] getAvailableLocales();
425 }
|