Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.base/share/classes/sun/util/resources/LocaleData.java
41159 views
1
/*
2
* Copyright (c) 1996, 2021, 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
/*
27
* (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
28
* (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
29
*
30
* The original version of this source code and documentation
31
* is copyrighted and owned by Taligent, Inc., a wholly-owned
32
* subsidiary of IBM. These materials are provided under terms
33
* of a License Agreement between Taligent and Sun. This technology
34
* is protected by multiple US and International patents.
35
*
36
* This notice and attribution to Taligent may not be removed.
37
* Taligent is a registered trademark of Taligent, Inc.
38
*
39
*/
40
41
package sun.util.resources;
42
43
import java.security.AccessController;
44
import java.security.PrivilegedAction;
45
import java.util.Arrays;
46
import java.util.Iterator;
47
import java.util.List;
48
import java.util.Locale;
49
import java.util.Map;
50
import java.util.MissingResourceException;
51
import java.util.ResourceBundle;
52
import java.util.Set;
53
import java.util.concurrent.ConcurrentHashMap;
54
import java.util.spi.ResourceBundleProvider;
55
import sun.util.locale.provider.JRELocaleProviderAdapter;
56
import sun.util.locale.provider.LocaleProviderAdapter;
57
import static sun.util.locale.provider.LocaleProviderAdapter.Type.CLDR;
58
import static sun.util.locale.provider.LocaleProviderAdapter.Type.JRE;
59
import sun.util.locale.provider.ResourceBundleBasedAdapter;
60
61
/**
62
* Provides information about and access to resource bundles in the
63
* sun.text.resources and sun.util.resources packages or in their corresponding
64
* packages for CLDR.
65
*
66
* @author Asmus Freytag
67
* @author Mark Davis
68
*/
69
70
public class LocaleData {
71
private static final ResourceBundle.Control defaultControl
72
= ResourceBundle.Control.getControl(ResourceBundle.Control.FORMAT_DEFAULT);
73
74
private static final String DOTCLDR = ".cldr";
75
76
// Map of key (base name + locale) to candidates
77
private static final Map<String, List<Locale>> CANDIDATES_MAP = new ConcurrentHashMap<>();
78
79
private final LocaleProviderAdapter.Type type;
80
81
public LocaleData(LocaleProviderAdapter.Type type) {
82
this.type = type;
83
}
84
85
/**
86
* Gets a calendar data resource bundle, using privileges
87
* to allow accessing a sun.* package.
88
*/
89
public ResourceBundle getCalendarData(Locale locale) {
90
return getBundle(type.getUtilResourcesPackage() + ".CalendarData", locale);
91
}
92
93
/**
94
* Gets a currency names resource bundle, using privileges
95
* to allow accessing a sun.* package.
96
*/
97
public OpenListResourceBundle getCurrencyNames(Locale locale) {
98
return (OpenListResourceBundle) getBundle(type.getUtilResourcesPackage() + ".CurrencyNames", locale);
99
}
100
101
/**
102
* Gets a locale names resource bundle, using privileges
103
* to allow accessing a sun.* package.
104
*/
105
public OpenListResourceBundle getLocaleNames(Locale locale) {
106
return (OpenListResourceBundle) getBundle(type.getUtilResourcesPackage() + ".LocaleNames", locale);
107
}
108
109
/**
110
* Gets a time zone names resource bundle, using privileges
111
* to allow accessing a sun.* package.
112
*/
113
public TimeZoneNamesBundle getTimeZoneNames(Locale locale) {
114
return (TimeZoneNamesBundle) getBundle(type.getUtilResourcesPackage() + ".TimeZoneNames", locale);
115
}
116
117
/**
118
* Gets a break iterator info resource bundle, using privileges
119
* to allow accessing a sun.* package.
120
*/
121
public ResourceBundle getBreakIteratorInfo(Locale locale) {
122
return getBundle(type.getTextResourcesPackage() + ".BreakIteratorInfo", locale);
123
}
124
125
/**
126
* Gets a break iterator resources resource bundle, using
127
* privileges to allow accessing a sun.* package.
128
*/
129
public ResourceBundle getBreakIteratorResources(Locale locale) {
130
return getBundle(type.getTextResourcesPackage() + ".BreakIteratorResources", locale);
131
}
132
133
/**
134
* Gets a collation data resource bundle, using privileges
135
* to allow accessing a sun.* package.
136
*/
137
public ResourceBundle getCollationData(Locale locale) {
138
return getBundle(type.getTextResourcesPackage() + ".CollationData", locale);
139
}
140
141
/**
142
* Gets a date format data resource bundle, using privileges
143
* to allow accessing a sun.* package.
144
*/
145
public ResourceBundle getDateFormatData(Locale locale) {
146
return getBundle(type.getTextResourcesPackage() + ".FormatData", locale);
147
}
148
149
public void setSupplementary(ParallelListResourceBundle formatData) {
150
if (!formatData.areParallelContentsComplete()) {
151
String suppName = type.getTextResourcesPackage() + ".JavaTimeSupplementary";
152
setSupplementary(suppName, formatData);
153
}
154
}
155
156
private boolean setSupplementary(String suppName, ParallelListResourceBundle formatData) {
157
ParallelListResourceBundle parent = (ParallelListResourceBundle) formatData.getParent();
158
boolean resetKeySet = false;
159
if (parent != null) {
160
resetKeySet = setSupplementary(suppName, parent);
161
}
162
OpenListResourceBundle supp = getSupplementary(suppName, formatData.getLocale());
163
formatData.setParallelContents(supp);
164
resetKeySet |= supp != null;
165
// If any parents or this bundle has parallel data, reset keyset to create
166
// a new keyset with the data.
167
if (resetKeySet) {
168
formatData.resetKeySet();
169
}
170
return resetKeySet;
171
}
172
173
/**
174
* Gets a number format data resource bundle, using privileges
175
* to allow accessing a sun.* package.
176
*/
177
public ResourceBundle getNumberFormatData(Locale locale) {
178
return getBundle(type.getTextResourcesPackage() + ".FormatData", locale);
179
}
180
181
@SuppressWarnings("removal")
182
public static ResourceBundle getBundle(final String baseName, final Locale locale) {
183
return AccessController.doPrivileged(new PrivilegedAction<>() {
184
@Override
185
public ResourceBundle run() {
186
return Bundles.of(baseName, locale, LocaleDataStrategy.INSTANCE);
187
}
188
});
189
}
190
191
@SuppressWarnings("removal")
192
private static OpenListResourceBundle getSupplementary(final String baseName, final Locale locale) {
193
return AccessController.doPrivileged(new PrivilegedAction<>() {
194
@Override
195
public OpenListResourceBundle run() {
196
OpenListResourceBundle rb = null;
197
try {
198
rb = (OpenListResourceBundle) Bundles.of(baseName, locale,
199
SupplementaryStrategy.INSTANCE);
200
} catch (MissingResourceException e) {
201
// return null if no supplementary is available
202
}
203
return rb;
204
}
205
});
206
}
207
208
private static abstract class LocaleDataResourceBundleProvider
209
implements ResourceBundleProvider {
210
/**
211
* Changes baseName to its module dependent package name and
212
* calls the super class implementation. For example,
213
* if the baseName is "sun.text.resources.FormatData" and locale is ja_JP,
214
* the baseName is changed to "sun.text.resources.ext.FormatData". If
215
* baseName contains ".cldr", such as "sun.text.resources.cldr.FormatData",
216
* the name is changed to "sun.text.resources.cldr.ext.FormatData".
217
*/
218
protected String toBundleName(String baseName, Locale locale) {
219
return LocaleDataStrategy.INSTANCE.toBundleName(baseName, locale);
220
}
221
222
/**
223
* Retrieves the other bundle name for legacy ISO 639 languages.
224
*/
225
protected String toOtherBundleName(String baseName, String bundleName, Locale locale) {
226
return Bundles.toOtherBundleName(baseName, bundleName, locale);
227
}
228
}
229
230
/**
231
* A ResourceBundleProvider implementation for loading locale data
232
* resource bundles except for the java.time supplementary data.
233
*/
234
public static abstract class CommonResourceBundleProvider extends LocaleDataResourceBundleProvider {
235
}
236
237
/**
238
* A ResourceBundleProvider implementation for loading supplementary
239
* resource bundles for java.time.
240
*/
241
public static abstract class SupplementaryResourceBundleProvider extends LocaleDataResourceBundleProvider {
242
}
243
244
// Bundles.Strategy implementations
245
246
private static class LocaleDataStrategy implements Bundles.Strategy {
247
private static final LocaleDataStrategy INSTANCE = new LocaleDataStrategy();
248
// TODO: avoid hard-coded Locales
249
private static Set<Locale> JAVA_BASE_LOCALES
250
= Set.of(Locale.ROOT, Locale.ENGLISH, Locale.US, new Locale("en", "US", "POSIX"));
251
252
private LocaleDataStrategy() {
253
}
254
255
/*
256
* This method overrides the default implementation to search
257
* from a prebaked locale string list to determin the candidate
258
* locale list.
259
*
260
* @param baseName the resource bundle base name.
261
* locale the requested locale for the resource bundle.
262
* @return a list of candidate locales to search from.
263
* @exception NullPointerException if baseName or locale is null.
264
*/
265
@Override
266
public List<Locale> getCandidateLocales(String baseName, Locale locale) {
267
String key = baseName + '-' + locale.toLanguageTag();
268
List<Locale> candidates = CANDIDATES_MAP.get(key);
269
if (candidates == null) {
270
LocaleProviderAdapter.Type type = baseName.contains(DOTCLDR) ? CLDR : JRE;
271
LocaleProviderAdapter adapter = LocaleProviderAdapter.forType(type);
272
candidates = adapter instanceof ResourceBundleBasedAdapter ?
273
((ResourceBundleBasedAdapter)adapter).getCandidateLocales(baseName, locale) :
274
defaultControl.getCandidateLocales(baseName, locale);
275
276
// Weed out Locales which are known to have no resource bundles
277
int lastDot = baseName.lastIndexOf('.');
278
String category = (lastDot >= 0) ? baseName.substring(lastDot + 1) : baseName;
279
Set<String> langtags = ((JRELocaleProviderAdapter)adapter).getLanguageTagSet(category);
280
if (!langtags.isEmpty()) {
281
for (Iterator<Locale> itr = candidates.iterator(); itr.hasNext();) {
282
if (!adapter.isSupportedProviderLocale(itr.next(), langtags)) {
283
itr.remove();
284
}
285
}
286
}
287
CANDIDATES_MAP.putIfAbsent(key, candidates);
288
}
289
return candidates;
290
}
291
292
boolean inJavaBaseModule(String baseName, Locale locale) {
293
return JAVA_BASE_LOCALES.contains(locale);
294
}
295
296
@Override
297
public String toBundleName(String baseName, Locale locale) {
298
String newBaseName = baseName;
299
if (!inJavaBaseModule(baseName, locale)) {
300
if (baseName.startsWith(JRE.getUtilResourcesPackage())
301
|| baseName.startsWith(JRE.getTextResourcesPackage())) {
302
// Assume the lengths are the same.
303
assert JRE.getUtilResourcesPackage().length()
304
== JRE.getTextResourcesPackage().length();
305
int index = JRE.getUtilResourcesPackage().length();
306
if (baseName.indexOf(DOTCLDR, index) > 0) {
307
index += DOTCLDR.length();
308
}
309
newBaseName = baseName.substring(0, index + 1) + "ext"
310
+ baseName.substring(index);
311
}
312
}
313
return defaultControl.toBundleName(newBaseName, locale);
314
}
315
316
@Override
317
public Class<? extends ResourceBundleProvider> getResourceBundleProviderType(String baseName,
318
Locale locale) {
319
return inJavaBaseModule(baseName, locale) ?
320
null : CommonResourceBundleProvider.class;
321
}
322
}
323
324
private static class SupplementaryStrategy extends LocaleDataStrategy {
325
private static final SupplementaryStrategy INSTANCE
326
= new SupplementaryStrategy();
327
// TODO: avoid hard-coded Locales
328
private static Set<Locale> JAVA_BASE_LOCALES
329
= Set.of(Locale.ROOT, Locale.ENGLISH, Locale.US);
330
331
private SupplementaryStrategy() {
332
}
333
334
@Override
335
public List<Locale> getCandidateLocales(String baseName, Locale locale) {
336
// Specifiy only the given locale
337
return Arrays.asList(locale);
338
}
339
340
@Override
341
public Class<? extends ResourceBundleProvider> getResourceBundleProviderType(String baseName,
342
Locale locale) {
343
return inJavaBaseModule(baseName, locale) ?
344
null : SupplementaryResourceBundleProvider.class;
345
}
346
347
@Override
348
boolean inJavaBaseModule(String baseName, Locale locale) {
349
return JAVA_BASE_LOCALES.contains(locale);
350
}
351
}
352
}
353
354