Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/util/locale/provider/JRELocaleProviderAdapter.java
38918 views
1
/*
2
* Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
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.io.File;
29
import java.security.AccessController;
30
import java.security.PrivilegedAction;
31
import java.text.spi.BreakIteratorProvider;
32
import java.text.spi.CollatorProvider;
33
import java.text.spi.DateFormatProvider;
34
import java.text.spi.DateFormatSymbolsProvider;
35
import java.text.spi.DecimalFormatSymbolsProvider;
36
import java.text.spi.NumberFormatProvider;
37
import java.util.Collections;
38
import java.util.HashSet;
39
import java.util.Locale;
40
import java.util.Set;
41
import java.util.StringTokenizer;
42
import java.util.concurrent.ConcurrentHashMap;
43
import java.util.concurrent.ConcurrentMap;
44
import java.util.spi.CalendarDataProvider;
45
import java.util.spi.CalendarNameProvider;
46
import java.util.spi.CurrencyNameProvider;
47
import java.util.spi.LocaleNameProvider;
48
import java.util.spi.LocaleServiceProvider;
49
import java.util.spi.TimeZoneNameProvider;
50
import sun.util.resources.LocaleData;
51
import sun.util.spi.CalendarProvider;
52
53
/**
54
* LocaleProviderAdapter implementation for the legacy JRE locale data.
55
*
56
* @author Naoto Sato
57
* @author Masayoshi Okutsu
58
*/
59
public class JRELocaleProviderAdapter extends LocaleProviderAdapter implements ResourceBundleBasedAdapter {
60
61
private static final String LOCALE_DATA_JAR_NAME = "localedata.jar";
62
63
private final ConcurrentMap<String, Set<String>> langtagSets
64
= new ConcurrentHashMap<>();
65
66
private final ConcurrentMap<Locale, LocaleResources> localeResourcesMap
67
= new ConcurrentHashMap<>();
68
69
// LocaleData specific to this LocaleProviderAdapter.
70
private volatile LocaleData localeData;
71
72
/**
73
* Returns the type of this LocaleProviderAdapter
74
*/
75
@Override
76
public LocaleProviderAdapter.Type getAdapterType() {
77
return Type.JRE;
78
}
79
80
/**
81
* Getter method for Locale Service Providers
82
*/
83
@Override
84
@SuppressWarnings("unchecked")
85
public <P extends LocaleServiceProvider> P getLocaleServiceProvider(Class<P> c) {
86
switch (c.getSimpleName()) {
87
case "BreakIteratorProvider":
88
return (P) getBreakIteratorProvider();
89
case "CollatorProvider":
90
return (P) getCollatorProvider();
91
case "DateFormatProvider":
92
return (P) getDateFormatProvider();
93
case "DateFormatSymbolsProvider":
94
return (P) getDateFormatSymbolsProvider();
95
case "DecimalFormatSymbolsProvider":
96
return (P) getDecimalFormatSymbolsProvider();
97
case "NumberFormatProvider":
98
return (P) getNumberFormatProvider();
99
case "CurrencyNameProvider":
100
return (P) getCurrencyNameProvider();
101
case "LocaleNameProvider":
102
return (P) getLocaleNameProvider();
103
case "TimeZoneNameProvider":
104
return (P) getTimeZoneNameProvider();
105
case "CalendarDataProvider":
106
return (P) getCalendarDataProvider();
107
case "CalendarNameProvider":
108
return (P) getCalendarNameProvider();
109
case "CalendarProvider":
110
return (P) getCalendarProvider();
111
default:
112
throw new InternalError("should not come down here");
113
}
114
}
115
116
private volatile BreakIteratorProvider breakIteratorProvider = null;
117
private volatile CollatorProvider collatorProvider = null;
118
private volatile DateFormatProvider dateFormatProvider = null;
119
private volatile DateFormatSymbolsProvider dateFormatSymbolsProvider = null;
120
private volatile DecimalFormatSymbolsProvider decimalFormatSymbolsProvider = null;
121
private volatile NumberFormatProvider numberFormatProvider = null;
122
123
private volatile CurrencyNameProvider currencyNameProvider = null;
124
private volatile LocaleNameProvider localeNameProvider = null;
125
private volatile TimeZoneNameProvider timeZoneNameProvider = null;
126
private volatile CalendarDataProvider calendarDataProvider = null;
127
private volatile CalendarNameProvider calendarNameProvider = null;
128
129
private volatile CalendarProvider calendarProvider = null;
130
131
/*
132
* Getter methods for java.text.spi.* providers
133
*/
134
@Override
135
public BreakIteratorProvider getBreakIteratorProvider() {
136
if (breakIteratorProvider == null) {
137
BreakIteratorProvider provider = new BreakIteratorProviderImpl(getAdapterType(),
138
getLanguageTagSet("FormatData"));
139
synchronized (this) {
140
if (breakIteratorProvider == null) {
141
breakIteratorProvider = provider;
142
}
143
}
144
}
145
return breakIteratorProvider;
146
}
147
148
@Override
149
public CollatorProvider getCollatorProvider() {
150
if (collatorProvider == null) {
151
CollatorProvider provider = new CollatorProviderImpl(getAdapterType(),
152
getLanguageTagSet("CollationData"));
153
synchronized (this) {
154
if (collatorProvider == null) {
155
collatorProvider = provider;
156
}
157
}
158
}
159
return collatorProvider;
160
}
161
162
@Override
163
public DateFormatProvider getDateFormatProvider() {
164
if (dateFormatProvider == null) {
165
DateFormatProvider provider = new DateFormatProviderImpl(getAdapterType(),
166
getLanguageTagSet("FormatData"));
167
synchronized (this) {
168
if (dateFormatProvider == null) {
169
dateFormatProvider = provider;
170
}
171
}
172
}
173
return dateFormatProvider;
174
}
175
176
@Override
177
public DateFormatSymbolsProvider getDateFormatSymbolsProvider() {
178
if (dateFormatSymbolsProvider == null) {
179
DateFormatSymbolsProvider provider = new DateFormatSymbolsProviderImpl(getAdapterType(),
180
getLanguageTagSet("FormatData"));
181
synchronized (this) {
182
if (dateFormatSymbolsProvider == null) {
183
dateFormatSymbolsProvider = provider;
184
}
185
}
186
}
187
return dateFormatSymbolsProvider;
188
}
189
190
@Override
191
public DecimalFormatSymbolsProvider getDecimalFormatSymbolsProvider() {
192
if (decimalFormatSymbolsProvider == null) {
193
DecimalFormatSymbolsProvider provider = new DecimalFormatSymbolsProviderImpl(getAdapterType(), getLanguageTagSet("FormatData"));
194
synchronized (this) {
195
if (decimalFormatSymbolsProvider == null) {
196
decimalFormatSymbolsProvider = provider;
197
}
198
}
199
}
200
return decimalFormatSymbolsProvider;
201
}
202
203
@Override
204
public NumberFormatProvider getNumberFormatProvider() {
205
if (numberFormatProvider == null) {
206
NumberFormatProvider provider = new NumberFormatProviderImpl(getAdapterType(),
207
getLanguageTagSet("FormatData"));
208
synchronized (this) {
209
if (numberFormatProvider == null) {
210
numberFormatProvider = provider;
211
}
212
}
213
}
214
return numberFormatProvider;
215
}
216
217
/**
218
* Getter methods for java.util.spi.* providers
219
*/
220
@Override
221
public CurrencyNameProvider getCurrencyNameProvider() {
222
if (currencyNameProvider == null) {
223
CurrencyNameProvider provider = new CurrencyNameProviderImpl(getAdapterType(),
224
getLanguageTagSet("CurrencyNames"));
225
synchronized (this) {
226
if (currencyNameProvider == null) {
227
currencyNameProvider = provider;
228
}
229
}
230
}
231
return currencyNameProvider;
232
}
233
234
@Override
235
public LocaleNameProvider getLocaleNameProvider() {
236
if (localeNameProvider == null) {
237
LocaleNameProvider provider = new LocaleNameProviderImpl(getAdapterType(),
238
getLanguageTagSet("LocaleNames"));
239
synchronized (this) {
240
if (localeNameProvider == null) {
241
localeNameProvider = provider;
242
}
243
}
244
}
245
return localeNameProvider;
246
}
247
248
@Override
249
public TimeZoneNameProvider getTimeZoneNameProvider() {
250
if (timeZoneNameProvider == null) {
251
TimeZoneNameProvider provider = new TimeZoneNameProviderImpl(getAdapterType(),
252
getLanguageTagSet("TimeZoneNames"));
253
synchronized (this) {
254
if (timeZoneNameProvider == null) {
255
timeZoneNameProvider = provider;
256
}
257
}
258
}
259
return timeZoneNameProvider;
260
}
261
262
@Override
263
public CalendarDataProvider getCalendarDataProvider() {
264
if (calendarDataProvider == null) {
265
CalendarDataProvider provider;
266
provider = new CalendarDataProviderImpl(getAdapterType(),
267
getLanguageTagSet("CalendarData"));
268
synchronized (this) {
269
if (calendarDataProvider == null) {
270
calendarDataProvider = provider;
271
}
272
}
273
}
274
return calendarDataProvider;
275
}
276
277
@Override
278
public CalendarNameProvider getCalendarNameProvider() {
279
if (calendarNameProvider == null) {
280
CalendarNameProvider provider;
281
provider = new CalendarNameProviderImpl(getAdapterType(),
282
getLanguageTagSet("FormatData"));
283
synchronized (this) {
284
if (calendarNameProvider == null) {
285
calendarNameProvider = provider;
286
}
287
}
288
}
289
return calendarNameProvider;
290
}
291
292
/**
293
* Getter methods for sun.util.spi.* providers
294
*/
295
@Override
296
public CalendarProvider getCalendarProvider() {
297
if (calendarProvider == null) {
298
CalendarProvider provider = new CalendarProviderImpl(getAdapterType(),
299
getLanguageTagSet("CalendarData"));
300
synchronized (this) {
301
if (calendarProvider == null) {
302
calendarProvider = provider;
303
}
304
}
305
}
306
return calendarProvider;
307
}
308
309
@Override
310
public LocaleResources getLocaleResources(Locale locale) {
311
LocaleResources lr = localeResourcesMap.get(locale);
312
if (lr == null) {
313
lr = new LocaleResources(this, locale);
314
LocaleResources lrc = localeResourcesMap.putIfAbsent(locale, lr);
315
if (lrc != null) {
316
lr = lrc;
317
}
318
}
319
return lr;
320
}
321
322
// ResourceBundleBasedAdapter method implementation
323
@Override
324
public LocaleData getLocaleData() {
325
if (localeData == null) {
326
synchronized (this) {
327
if (localeData == null) {
328
localeData = new LocaleData(getAdapterType());
329
}
330
}
331
}
332
return localeData;
333
}
334
335
/**
336
* Returns a list of the installed locales. Currently, this simply returns
337
* the list of locales for which a sun.text.resources.FormatData bundle
338
* exists. This bundle family happens to be the one with the broadest
339
* locale coverage in the JRE.
340
*/
341
@Override
342
public Locale[] getAvailableLocales() {
343
return AvailableJRELocales.localeList.clone();
344
}
345
346
public Set<String> getLanguageTagSet(String category) {
347
Set<String> tagset = langtagSets.get(category);
348
if (tagset == null) {
349
tagset = createLanguageTagSet(category);
350
Set<String> ts = langtagSets.putIfAbsent(category, tagset);
351
if (ts != null) {
352
tagset = ts;
353
}
354
}
355
return tagset;
356
}
357
358
protected Set<String> createLanguageTagSet(String category) {
359
String supportedLocaleString = LocaleDataMetaInfo.getSupportedLocaleString(category);
360
if (supportedLocaleString == null) {
361
return Collections.emptySet();
362
}
363
Set<String> tagset = new HashSet<>();
364
StringTokenizer tokens = new StringTokenizer(supportedLocaleString);
365
while (tokens.hasMoreTokens()) {
366
String token = tokens.nextToken();
367
if (token.equals("|")) {
368
if (isNonENLangSupported()) {
369
continue;
370
}
371
break;
372
}
373
tagset.add(token);
374
}
375
376
return tagset;
377
}
378
379
/**
380
* Lazy load available locales.
381
*/
382
private static class AvailableJRELocales {
383
private static final Locale[] localeList = createAvailableLocales();
384
private AvailableJRELocales() {
385
}
386
}
387
388
private static Locale[] createAvailableLocales() {
389
/*
390
* Gets the locale string list from LocaleDataMetaInfo class and then
391
* contructs the Locale array and a set of language tags based on the
392
* locale string returned above.
393
*/
394
String supportedLocaleString = LocaleDataMetaInfo.getSupportedLocaleString("AvailableLocales");
395
396
if (supportedLocaleString.length() == 0) {
397
throw new InternalError("No available locales for JRE");
398
}
399
400
/*
401
* Look for "|" and construct a new locale string list.
402
*/
403
int barIndex = supportedLocaleString.indexOf('|');
404
StringTokenizer localeStringTokenizer;
405
if (isNonENLangSupported()) {
406
localeStringTokenizer = new StringTokenizer(supportedLocaleString.substring(0, barIndex)
407
+ supportedLocaleString.substring(barIndex + 1));
408
} else {
409
localeStringTokenizer = new StringTokenizer(supportedLocaleString.substring(0, barIndex));
410
}
411
412
int length = localeStringTokenizer.countTokens();
413
Locale[] locales = new Locale[length + 1];
414
locales[0] = Locale.ROOT;
415
for (int i = 1; i <= length; i++) {
416
String currentToken = localeStringTokenizer.nextToken();
417
switch (currentToken) {
418
case "ja-JP-JP":
419
locales[i] = JRELocaleConstants.JA_JP_JP;
420
break;
421
case "no-NO-NY":
422
locales[i] = JRELocaleConstants.NO_NO_NY;
423
break;
424
case "th-TH-TH":
425
locales[i] = JRELocaleConstants.TH_TH_TH;
426
break;
427
default:
428
locales[i] = Locale.forLanguageTag(currentToken);
429
}
430
}
431
return locales;
432
}
433
434
private static volatile Boolean isNonENSupported = null;
435
436
/*
437
* Returns true if the non EN resources jar file exists in jre
438
* extension directory. @returns true if the jar file is there. Otherwise,
439
* returns false.
440
*/
441
private static boolean isNonENLangSupported() {
442
if (isNonENSupported == null) {
443
synchronized (JRELocaleProviderAdapter.class) {
444
if (isNonENSupported == null) {
445
final String sep = File.separator;
446
String localeDataJar =
447
java.security.AccessController.doPrivileged(
448
new sun.security.action.GetPropertyAction("java.home"))
449
+ sep + "lib" + sep + "ext" + sep + LOCALE_DATA_JAR_NAME;
450
451
/*
452
* Peek at the installed extension directory to see if
453
* localedata.jar is installed or not.
454
*/
455
final File f = new File(localeDataJar);
456
isNonENSupported =
457
AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
458
@Override
459
public Boolean run() {
460
return f.exists();
461
}
462
});
463
}
464
}
465
}
466
return isNonENSupported;
467
}
468
}
469
470