Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.base/share/classes/sun/util/locale/BaseLocale.java
41159 views
1
/*
2
* Copyright (c) 2010, 2018, 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
*******************************************************************************
28
* Copyright (C) 2009-2010, International Business Machines Corporation and *
29
* others. All Rights Reserved. *
30
*******************************************************************************
31
*/
32
33
package sun.util.locale;
34
35
import jdk.internal.misc.CDS;
36
import jdk.internal.vm.annotation.Stable;
37
import sun.security.action.GetPropertyAction;
38
39
import java.lang.ref.SoftReference;
40
import java.util.StringJoiner;
41
42
public final class BaseLocale {
43
44
public static @Stable BaseLocale[] constantBaseLocales;
45
public static final byte ENGLISH = 0,
46
FRENCH = 1,
47
GERMAN = 2,
48
ITALIAN = 3,
49
JAPANESE = 4,
50
KOREAN = 5,
51
CHINESE = 6,
52
SIMPLIFIED_CHINESE = 7,
53
TRADITIONAL_CHINESE = 8,
54
FRANCE = 9,
55
GERMANY = 10,
56
ITALY = 11,
57
JAPAN = 12,
58
KOREA = 13,
59
UK = 14,
60
US = 15,
61
CANADA = 16,
62
CANADA_FRENCH = 17,
63
ROOT = 18,
64
NUM_CONSTANTS = 19;
65
static {
66
CDS.initializeFromArchive(BaseLocale.class);
67
BaseLocale[] baseLocales = constantBaseLocales;
68
if (baseLocales == null) {
69
baseLocales = new BaseLocale[NUM_CONSTANTS];
70
baseLocales[ENGLISH] = createInstance("en", "");
71
baseLocales[FRENCH] = createInstance("fr", "");
72
baseLocales[GERMAN] = createInstance("de", "");
73
baseLocales[ITALIAN] = createInstance("it", "");
74
baseLocales[JAPANESE] = createInstance("ja", "");
75
baseLocales[KOREAN] = createInstance("ko", "");
76
baseLocales[CHINESE] = createInstance("zh", "");
77
baseLocales[SIMPLIFIED_CHINESE] = createInstance("zh", "CN");
78
baseLocales[TRADITIONAL_CHINESE] = createInstance("zh", "TW");
79
baseLocales[FRANCE] = createInstance("fr", "FR");
80
baseLocales[GERMANY] = createInstance("de", "DE");
81
baseLocales[ITALY] = createInstance("it", "IT");
82
baseLocales[JAPAN] = createInstance("ja", "JP");
83
baseLocales[KOREA] = createInstance("ko", "KR");
84
baseLocales[UK] = createInstance("en", "GB");
85
baseLocales[US] = createInstance("en", "US");
86
baseLocales[CANADA] = createInstance("en", "CA");
87
baseLocales[CANADA_FRENCH] = createInstance("fr", "CA");
88
baseLocales[ROOT] = createInstance("", "");
89
constantBaseLocales = baseLocales;
90
}
91
}
92
93
public static final String SEP = "_";
94
95
private final String language;
96
private final String script;
97
private final String region;
98
private final String variant;
99
100
private volatile int hash;
101
102
/**
103
* Boolean for the old ISO language code compatibility.
104
*/
105
private static final boolean OLD_ISO_CODES = GetPropertyAction.privilegedGetProperties()
106
.getProperty("java.locale.useOldISOCodes", "false")
107
.equalsIgnoreCase("true");
108
109
// This method must be called with normalize = false only when creating the
110
// Locale.* constants and non-normalized BaseLocale$Keys used for lookup.
111
private BaseLocale(String language, String script, String region, String variant,
112
boolean normalize) {
113
if (normalize) {
114
this.language = LocaleUtils.toLowerString(language).intern();
115
this.script = LocaleUtils.toTitleString(script).intern();
116
this.region = LocaleUtils.toUpperString(region).intern();
117
this.variant = variant.intern();
118
} else {
119
this.language = language;
120
this.script = script;
121
this.region = region;
122
this.variant = variant;
123
}
124
}
125
126
// Called for creating the Locale.* constants. No argument
127
// validation is performed.
128
private static BaseLocale createInstance(String language, String region) {
129
return new BaseLocale(language, "", region, "", false);
130
}
131
132
public static BaseLocale getInstance(String language, String script,
133
String region, String variant) {
134
135
if (script == null) {
136
script = "";
137
}
138
if (region == null) {
139
region = "";
140
}
141
if (language == null) {
142
language = null;
143
}
144
if (variant == null) {
145
variant = "";
146
}
147
148
// Non-allocating for most uses
149
language = LocaleUtils.toLowerString(language);
150
region = LocaleUtils.toUpperString(region);
151
152
// Check for constant base locales first
153
if (script.isEmpty() && variant.isEmpty()) {
154
for (BaseLocale baseLocale : constantBaseLocales) {
155
if (baseLocale.getLanguage().equals(language)
156
&& baseLocale.getRegion().equals(region)) {
157
return baseLocale;
158
}
159
}
160
}
161
162
// JDK uses deprecated ISO639.1 language codes for he, yi and id
163
if (!language.isEmpty()) {
164
language = convertOldISOCodes(language);
165
}
166
167
Key key = new Key(language, script, region, variant, false);
168
return Cache.CACHE.get(key);
169
}
170
171
public static String convertOldISOCodes(String language) {
172
return switch (language) {
173
case "he", "iw" -> OLD_ISO_CODES ? "iw" : "he";
174
case "id", "in" -> OLD_ISO_CODES ? "in" : "id";
175
case "yi", "ji" -> OLD_ISO_CODES ? "ji" : "yi";
176
default -> language;
177
};
178
}
179
180
public String getLanguage() {
181
return language;
182
}
183
184
public String getScript() {
185
return script;
186
}
187
188
public String getRegion() {
189
return region;
190
}
191
192
public String getVariant() {
193
return variant;
194
}
195
196
@Override
197
public boolean equals(Object obj) {
198
if (this == obj) {
199
return true;
200
}
201
if (!(obj instanceof BaseLocale)) {
202
return false;
203
}
204
BaseLocale other = (BaseLocale)obj;
205
return language == other.language
206
&& script == other.script
207
&& region == other.region
208
&& variant == other.variant;
209
}
210
211
@Override
212
public String toString() {
213
StringJoiner sj = new StringJoiner(", ");
214
if (!language.isEmpty()) {
215
sj.add("language=" + language);
216
}
217
if (!script.isEmpty()) {
218
sj.add("script=" + script);
219
}
220
if (!region.isEmpty()) {
221
sj.add("region=" + region);
222
}
223
if (!variant.isEmpty()) {
224
sj.add("variant=" + variant);
225
}
226
return sj.toString();
227
}
228
229
@Override
230
public int hashCode() {
231
int h = hash;
232
if (h == 0) {
233
// Generating a hash value from language, script, region and variant
234
h = language.hashCode();
235
h = 31 * h + script.hashCode();
236
h = 31 * h + region.hashCode();
237
h = 31 * h + variant.hashCode();
238
if (h != 0) {
239
hash = h;
240
}
241
}
242
return h;
243
}
244
245
private static final class Key {
246
/**
247
* Keep a SoftReference to the Key data if normalized (actually used
248
* as a cache key) and not initialized via the constant creation path.
249
*
250
* This allows us to avoid creating SoftReferences on lookup Keys
251
* (which are short-lived) and for Locales created via
252
* Locale#createConstant.
253
*/
254
private final SoftReference<BaseLocale> holderRef;
255
private final BaseLocale holder;
256
257
private final boolean normalized;
258
private final int hash;
259
260
private Key(String language, String script, String region,
261
String variant, boolean normalize) {
262
BaseLocale locale = new BaseLocale(language, script, region, variant, normalize);
263
this.normalized = normalize;
264
if (normalized) {
265
this.holderRef = new SoftReference<>(locale);
266
this.holder = null;
267
} else {
268
this.holderRef = null;
269
this.holder = locale;
270
}
271
this.hash = hashCode(locale);
272
}
273
274
public int hashCode() {
275
return hash;
276
}
277
278
private int hashCode(BaseLocale locale) {
279
int h = 0;
280
String lang = locale.getLanguage();
281
int len = lang.length();
282
for (int i = 0; i < len; i++) {
283
h = 31*h + LocaleUtils.toLower(lang.charAt(i));
284
}
285
String scrt = locale.getScript();
286
len = scrt.length();
287
for (int i = 0; i < len; i++) {
288
h = 31*h + LocaleUtils.toLower(scrt.charAt(i));
289
}
290
String regn = locale.getRegion();
291
len = regn.length();
292
for (int i = 0; i < len; i++) {
293
h = 31*h + LocaleUtils.toLower(regn.charAt(i));
294
}
295
String vart = locale.getVariant();
296
len = vart.length();
297
for (int i = 0; i < len; i++) {
298
h = 31*h + vart.charAt(i);
299
}
300
return h;
301
}
302
303
private BaseLocale getBaseLocale() {
304
return (holder == null) ? holderRef.get() : holder;
305
}
306
307
@Override
308
public boolean equals(Object obj) {
309
if (this == obj) {
310
return true;
311
}
312
if (obj instanceof Key && this.hash == ((Key)obj).hash) {
313
BaseLocale other = ((Key) obj).getBaseLocale();
314
BaseLocale locale = this.getBaseLocale();
315
if (other != null && locale != null
316
&& LocaleUtils.caseIgnoreMatch(other.getLanguage(), locale.getLanguage())
317
&& LocaleUtils.caseIgnoreMatch(other.getScript(), locale.getScript())
318
&& LocaleUtils.caseIgnoreMatch(other.getRegion(), locale.getRegion())
319
// variant is case sensitive in JDK!
320
&& other.getVariant().equals(locale.getVariant())) {
321
return true;
322
}
323
}
324
return false;
325
}
326
327
public static Key normalize(Key key) {
328
if (key.normalized) {
329
return key;
330
}
331
332
// Only normalized keys may be softly referencing the data holder
333
assert (key.holder != null && key.holderRef == null);
334
BaseLocale locale = key.holder;
335
return new Key(locale.getLanguage(), locale.getScript(),
336
locale.getRegion(), locale.getVariant(), true);
337
}
338
}
339
340
private static class Cache extends LocaleObjectCache<Key, BaseLocale> {
341
342
private static final Cache CACHE = new Cache();
343
344
public Cache() {
345
}
346
347
@Override
348
protected Key normalizeKey(Key key) {
349
return Key.normalize(key);
350
}
351
352
@Override
353
protected BaseLocale createObject(Key key) {
354
return Key.normalize(key).getBaseLocale();
355
}
356
}
357
}
358
359