110 if (pool == null) {
111 LocaleServiceProviderPool newPool =
112 new LocaleServiceProviderPool(providerClass);
113 pool = poolOfPools.putIfAbsent(providerClass, newPool);
114 if (pool == null) {
115 pool = newPool;
116 }
117 }
118
119 return pool;
120 }
121
122 /**
123 * The sole constructor.
124 *
125 * @param c class of the locale sensitive service
126 */
127 private LocaleServiceProviderPool (final Class<? extends LocaleServiceProvider> c) {
128 providerClass = c;
129
130 // Add the JRE Locale Data Adapter implementation.
131 providers.putIfAbsent(LocaleProviderAdapter.Type.JRE,
132 LocaleProviderAdapter.forJRE().getLocaleServiceProvider(c));
133
134 // Add the SPI Locale Data Adapter implementation.
135 LocaleProviderAdapter lda = LocaleProviderAdapter.forType(LocaleProviderAdapter.Type.SPI);
136 LocaleServiceProvider provider = lda.getLocaleServiceProvider(c);
137 if (provider != null) {
138 providers.putIfAbsent(LocaleProviderAdapter.Type.SPI, provider);
139 }
140
141 // Add the CLDR Locale Data Adapter implementation, if needed.
142 lda = LocaleProviderAdapter.forType(LocaleProviderAdapter.Type.CLDR);
143 if (lda != null) {
144 provider = lda.getLocaleServiceProvider(c);
145 if (provider != null) {
146 providers.putIfAbsent(LocaleProviderAdapter.Type.CLDR, provider);
147 }
148 }
149
150 // Add the Host Locale Data Adapter implementation, if needed.
151 lda = LocaleProviderAdapter.forType(LocaleProviderAdapter.Type.HOST);
152 if (lda != null) {
153 provider = lda.getLocaleServiceProvider(c);
154 if (provider != null) {
155 providers.putIfAbsent(LocaleProviderAdapter.Type.HOST, provider);
156 }
157 }
158 }
159
160 static void config(Class<? extends Object> caller, String message) {
161 PlatformLogger logger = PlatformLogger.getLogger(caller.getCanonicalName());
162 logger.config(message);
163 }
164
165 /**
166 * Lazy loaded set of available locales.
167 * Loading all locales is a very long operation.
168 */
169 private static class AllAvailableLocales {
170 /**
171 * Available locales for all locale sensitive services.
172 * This also contains JRE's available locales
173 */
174 static final Locale[] allAvailableLocales;
175
176 static {
177 Set<Locale> all = new HashSet<>();
178 for (Class<? extends LocaleServiceProvider> c : spiClasses) {
229 availableLocales = new HashSet<>();
230 for (LocaleServiceProvider lsp : providers.values()) {
231 Locale[] locales = lsp.getAvailableLocales();
232 for (Locale locale: locales) {
233 availableLocales.add(getLookupLocale(locale));
234 }
235 }
236 }
237
238 return availableLocales;
239 }
240
241 /**
242 * Returns whether any provider for this locale sensitive
243 * service is available or not, excluding JRE's one.
244 *
245 * @return true if any provider (other than JRE) is available
246 */
247 boolean hasProviders() {
248 return providers.size() != 1 ||
249 providers.get(LocaleProviderAdapter.Type.JRE) == null;
250 }
251
252 /**
253 * Returns the provider's localized object for the specified
254 * locale.
255 *
256 * @param getter an object on which getObject() method
257 * is called to obtain the provider's instance.
258 * @param locale the given locale that is used as the starting one
259 * @param params provider specific parameters
260 * @return provider's instance, or null.
261 */
262 public <P extends LocaleServiceProvider, S> S getLocalizedObject(LocalizedObjectGetter<P, S> getter,
263 Locale locale,
264 Object... params) {
265 return getLocalizedObjectImpl(getter, locale, true, null, params);
266 }
267
268 /**
269 * Returns the provider's localized name for the specified
279 public <P extends LocaleServiceProvider, S> S getLocalizedObject(LocalizedObjectGetter<P, S> getter,
280 Locale locale,
281 String key,
282 Object... params) {
283 return getLocalizedObjectImpl(getter, locale, false, key, params);
284 }
285
286 @SuppressWarnings("unchecked")
287 private <P extends LocaleServiceProvider, S> S getLocalizedObjectImpl(LocalizedObjectGetter<P, S> getter,
288 Locale locale,
289 boolean isObjectProvider,
290 String key,
291 Object... params) {
292 if (locale == null) {
293 throw new NullPointerException();
294 }
295
296 // Check whether JRE is the sole locale data provider or not,
297 // and directly call it if it is.
298 if (!hasProviders()) {
299 return getter.getObject(
300 (P)providers.get(LocaleProviderAdapter.Type.JRE),
301 locale, key, params);
302 }
303
304 List<Locale> lookupLocales = getLookupLocales(locale);
305
306 Set<Locale> available = getAvailableLocaleSet();
307 for (Locale current : lookupLocales) {
308 if (available.contains(current)) {
309 S providersObj;
310
311 for (LocaleProviderAdapter.Type type: findProviders(current)) {
312 LocaleServiceProvider lsp = providers.get(type);
313 providersObj = getter.getObject((P)lsp, locale, key, params);
314 if (providersObj != null) {
315 return providersObj;
316 } else if (isObjectProvider) {
317 config(LocaleServiceProviderPool.class,
318 "A locale sensitive service provider returned null for a localized objects, which should not happen. provider: "
319 + lsp + " locale: " + locale);
320 }
|
110 if (pool == null) {
111 LocaleServiceProviderPool newPool =
112 new LocaleServiceProviderPool(providerClass);
113 pool = poolOfPools.putIfAbsent(providerClass, newPool);
114 if (pool == null) {
115 pool = newPool;
116 }
117 }
118
119 return pool;
120 }
121
122 /**
123 * The sole constructor.
124 *
125 * @param c class of the locale sensitive service
126 */
127 private LocaleServiceProviderPool (final Class<? extends LocaleServiceProvider> c) {
128 providerClass = c;
129
130 for (LocaleProviderAdapter.Type type : LocaleProviderAdapter.getAdapterPreference()) {
131 LocaleProviderAdapter lda = LocaleProviderAdapter.forType(type);
132 if (lda != null) {
133 LocaleServiceProvider provider = lda.getLocaleServiceProvider(c);
134 if (provider != null) {
135 providers.putIfAbsent(type, provider);
136 }
137 }
138 }
139 }
140
141 static void config(Class<? extends Object> caller, String message) {
142 PlatformLogger logger = PlatformLogger.getLogger(caller.getCanonicalName());
143 logger.config(message);
144 }
145
146 /**
147 * Lazy loaded set of available locales.
148 * Loading all locales is a very long operation.
149 */
150 private static class AllAvailableLocales {
151 /**
152 * Available locales for all locale sensitive services.
153 * This also contains JRE's available locales
154 */
155 static final Locale[] allAvailableLocales;
156
157 static {
158 Set<Locale> all = new HashSet<>();
159 for (Class<? extends LocaleServiceProvider> c : spiClasses) {
210 availableLocales = new HashSet<>();
211 for (LocaleServiceProvider lsp : providers.values()) {
212 Locale[] locales = lsp.getAvailableLocales();
213 for (Locale locale: locales) {
214 availableLocales.add(getLookupLocale(locale));
215 }
216 }
217 }
218
219 return availableLocales;
220 }
221
222 /**
223 * Returns whether any provider for this locale sensitive
224 * service is available or not, excluding JRE's one.
225 *
226 * @return true if any provider (other than JRE) is available
227 */
228 boolean hasProviders() {
229 return providers.size() != 1 ||
230 (providers.get(LocaleProviderAdapter.Type.JRE) == null &&
231 providers.get(LocaleProviderAdapter.Type.FALLBACK) == null);
232 }
233
234 /**
235 * Returns the provider's localized object for the specified
236 * locale.
237 *
238 * @param getter an object on which getObject() method
239 * is called to obtain the provider's instance.
240 * @param locale the given locale that is used as the starting one
241 * @param params provider specific parameters
242 * @return provider's instance, or null.
243 */
244 public <P extends LocaleServiceProvider, S> S getLocalizedObject(LocalizedObjectGetter<P, S> getter,
245 Locale locale,
246 Object... params) {
247 return getLocalizedObjectImpl(getter, locale, true, null, params);
248 }
249
250 /**
251 * Returns the provider's localized name for the specified
261 public <P extends LocaleServiceProvider, S> S getLocalizedObject(LocalizedObjectGetter<P, S> getter,
262 Locale locale,
263 String key,
264 Object... params) {
265 return getLocalizedObjectImpl(getter, locale, false, key, params);
266 }
267
268 @SuppressWarnings("unchecked")
269 private <P extends LocaleServiceProvider, S> S getLocalizedObjectImpl(LocalizedObjectGetter<P, S> getter,
270 Locale locale,
271 boolean isObjectProvider,
272 String key,
273 Object... params) {
274 if (locale == null) {
275 throw new NullPointerException();
276 }
277
278 // Check whether JRE is the sole locale data provider or not,
279 // and directly call it if it is.
280 if (!hasProviders()) {
281 return getter.getObject((P)providers.get(LocaleProviderAdapter.defaultLocaleProviderAdapter),
282 locale, key, params);
283 }
284
285 List<Locale> lookupLocales = getLookupLocales(locale);
286
287 Set<Locale> available = getAvailableLocaleSet();
288 for (Locale current : lookupLocales) {
289 if (available.contains(current)) {
290 S providersObj;
291
292 for (LocaleProviderAdapter.Type type: findProviders(current)) {
293 LocaleServiceProvider lsp = providers.get(type);
294 providersObj = getter.getObject((P)lsp, locale, key, params);
295 if (providersObj != null) {
296 return providersObj;
297 } else if (isObjectProvider) {
298 config(LocaleServiceProviderPool.class,
299 "A locale sensitive service provider returned null for a localized objects, which should not happen. provider: "
300 + lsp + " locale: " + locale);
301 }
|