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/CalendarNameProviderImpl.java
38918 views
1
/*
2
* Copyright (c) 2012, 2019, 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
package sun.util.locale.provider;
26
27
import static java.util.Calendar.*;
28
import java.util.Comparator;
29
import java.util.Locale;
30
import java.util.Map;
31
import java.util.Set;
32
import java.util.TreeMap;
33
import java.util.spi.CalendarNameProvider;
34
import sun.util.calendar.CalendarSystem;
35
import sun.util.calendar.Era;
36
37
/**
38
* Concrete implementation of the {@link java.util.spi.CalendarNameProvider
39
* CalendarNameProvider} class for the JRE LocaleProviderAdapter.
40
*
41
* @author Masayoshi Okutsu
42
* @author Naoto Sato
43
*/
44
public class CalendarNameProviderImpl extends CalendarNameProvider implements AvailableLanguageTags {
45
private final LocaleProviderAdapter.Type type;
46
private final Set<String> langtags;
47
48
public CalendarNameProviderImpl(LocaleProviderAdapter.Type type, Set<String> langtags) {
49
this.type = type;
50
this.langtags = langtags;
51
}
52
53
@Override
54
public String getDisplayName(String calendarType, int field, int value, int style, Locale locale) {
55
return getDisplayNameImpl(calendarType, field, value, style, locale, false);
56
}
57
58
public String getJavaTimeDisplayName(String calendarType, int field, int value, int style, Locale locale) {
59
return getDisplayNameImpl(calendarType, field, value, style, locale, true);
60
}
61
62
public String getDisplayNameImpl(String calendarType, int field, int value, int style, Locale locale, boolean javatime) {
63
String name = null;
64
String key = getResourceKey(calendarType, field, style, javatime);
65
if (key != null) {
66
LocaleResources lr = LocaleProviderAdapter.forType(type).getLocaleResources(locale);
67
String[] strings = javatime ? lr.getJavaTimeNames(key) : lr.getCalendarNames(key);
68
if (strings != null && strings.length > 0) {
69
if (field == DAY_OF_WEEK || field == YEAR) {
70
--value;
71
}
72
if (value < 0) {
73
return null;
74
} else if (value >= strings.length) {
75
if (field == ERA && "japanese".equals(calendarType)) {
76
Era[] jeras = CalendarSystem.forName("japanese").getEras();
77
if (value <= jeras.length) {
78
// Localized era name could not be retrieved from this provider.
79
// This can occur either for Reiwa or SupEra.
80
//
81
// If it's CLDR provider, try COMPAT first, which is guaranteed to have
82
// the name for Reiwa.
83
if (type == LocaleProviderAdapter.Type.CLDR) {
84
lr = LocaleProviderAdapter.forJRE().getLocaleResources(locale);
85
key = getResourceKeyFor(LocaleProviderAdapter.Type.JRE,
86
calendarType, field, style, javatime);
87
strings =
88
javatime ? lr.getJavaTimeNames(key) : lr.getCalendarNames(key);
89
}
90
if (strings == null || value >= strings.length) {
91
// Get the default name for SupEra
92
Era supEra = jeras[value - 1]; // 0-based index
93
if (javatime) {
94
return getBaseStyle(style) == NARROW_FORMAT ?
95
supEra.getAbbreviation() :
96
supEra.getName();
97
} else {
98
return (style & LONG) != 0 ?
99
supEra.getName() :
100
supEra.getAbbreviation();
101
}
102
}
103
} else {
104
return null;
105
}
106
} else {
107
return null;
108
}
109
}
110
name = strings[value];
111
// If name is empty in standalone, try its `format' style.
112
if (name.length() == 0
113
&& (style == SHORT_STANDALONE || style == LONG_STANDALONE
114
|| style == NARROW_STANDALONE)) {
115
name = getDisplayName(calendarType, field, value,
116
getBaseStyle(style),
117
locale);
118
}
119
}
120
}
121
return name;
122
}
123
124
private static int[] REST_OF_STYLES = {
125
SHORT_STANDALONE, LONG_FORMAT, LONG_STANDALONE,
126
NARROW_FORMAT, NARROW_STANDALONE
127
};
128
129
@Override
130
public Map<String, Integer> getDisplayNames(String calendarType, int field, int style, Locale locale) {
131
Map<String, Integer> names;
132
if (style == ALL_STYLES) {
133
names = getDisplayNamesImpl(calendarType, field, SHORT_FORMAT, locale, false);
134
for (int st : REST_OF_STYLES) {
135
names.putAll(getDisplayNamesImpl(calendarType, field, st, locale, false));
136
}
137
} else {
138
// specific style
139
names = getDisplayNamesImpl(calendarType, field, style, locale, false);
140
}
141
return names.isEmpty() ? null : names;
142
}
143
144
// NOTE: This method should be used ONLY BY JSR 310 classes.
145
public Map<String, Integer> getJavaTimeDisplayNames(String calendarType, int field, int style, Locale locale) {
146
Map<String, Integer> names;
147
names = getDisplayNamesImpl(calendarType, field, style, locale, true);
148
return names.isEmpty() ? null : names;
149
}
150
151
private Map<String, Integer> getDisplayNamesImpl(String calendarType, int field,
152
int style, Locale locale, boolean javatime) {
153
String key = getResourceKey(calendarType, field, style, javatime);
154
Map<String, Integer> map = new TreeMap<>(LengthBasedComparator.INSTANCE);
155
if (key != null) {
156
LocaleResources lr = LocaleProviderAdapter.forType(type).getLocaleResources(locale);
157
String[] strings = javatime ? lr.getJavaTimeNames(key) : lr.getCalendarNames(key);
158
if (strings != null) {
159
if (!hasDuplicates(strings)) {
160
if (field == YEAR) {
161
if (strings.length > 0) {
162
map.put(strings[0], 1);
163
}
164
} else {
165
int base = (field == DAY_OF_WEEK) ? 1 : 0;
166
for (int i = 0; i < strings.length; i++) {
167
String name = strings[i];
168
// Ignore any empty string (some standalone month names
169
// are not defined)
170
if (name.length() == 0) {
171
continue;
172
}
173
map.put(name, base + i);
174
}
175
}
176
}
177
}
178
}
179
return map;
180
}
181
182
private static int getBaseStyle(int style) {
183
return style & ~(SHORT_STANDALONE - SHORT_FORMAT);
184
}
185
186
/**
187
* Comparator implementation for TreeMap which iterates keys from longest
188
* to shortest.
189
*/
190
private static class LengthBasedComparator implements Comparator<String> {
191
private static final LengthBasedComparator INSTANCE = new LengthBasedComparator();
192
193
private LengthBasedComparator() {
194
}
195
196
@Override
197
public int compare(String o1, String o2) {
198
int n = o2.length() - o1.length();
199
return (n == 0) ? o1.compareTo(o2) : n;
200
}
201
}
202
203
@Override
204
public Locale[] getAvailableLocales() {
205
return LocaleProviderAdapter.toLocaleArray(langtags);
206
}
207
208
@Override
209
public boolean isSupportedLocale(Locale locale) {
210
if (Locale.ROOT.equals(locale)) {
211
return true;
212
}
213
String calendarType = null;
214
if (locale.hasExtensions()) {
215
calendarType = locale.getUnicodeLocaleType("ca");
216
locale = locale.stripExtensions();
217
}
218
219
if (calendarType != null) {
220
switch (calendarType) {
221
case "buddhist":
222
case "japanese":
223
case "gregory":
224
case "islamic":
225
case "roc":
226
break;
227
default:
228
// Unknown calendar type
229
return false;
230
}
231
}
232
if (langtags.contains(locale.toLanguageTag())) {
233
return true;
234
}
235
if (type == LocaleProviderAdapter.Type.JRE) {
236
String oldname = locale.toString().replace('_', '-');
237
return langtags.contains(oldname);
238
}
239
return false;
240
}
241
242
@Override
243
public Set<String> getAvailableLanguageTags() {
244
return langtags;
245
}
246
247
private boolean hasDuplicates(String[] strings) {
248
int len = strings.length;
249
for (int i = 0; i < len - 1; i++) {
250
String a = strings[i];
251
if (a != null) {
252
for (int j = i + 1; j < len; j++) {
253
if (a.equals(strings[j])) {
254
return true;
255
}
256
}
257
}
258
}
259
return false;
260
}
261
262
private String getResourceKey(String type, int field, int style, boolean javatime) {
263
return getResourceKeyFor(this.type, type, field, style, javatime);
264
}
265
266
private static String getResourceKeyFor(LocaleProviderAdapter.Type adapterType,
267
String type, int field, int style, boolean javatime) {
268
int baseStyle = getBaseStyle(style);
269
boolean isStandalone = (style != baseStyle);
270
271
if ("gregory".equals(type)) {
272
type = null;
273
}
274
boolean isNarrow = (baseStyle == NARROW_FORMAT);
275
StringBuilder key = new StringBuilder();
276
// If javatime is true, use prefix "java.time.".
277
if (javatime) {
278
key.append("java.time.");
279
}
280
switch (field) {
281
case ERA:
282
if (type != null) {
283
key.append(type).append('.');
284
}
285
if (isNarrow) {
286
key.append("narrow.");
287
} else {
288
// JRE and CLDR use different resource key conventions
289
// due to historical reasons. (JRE DateFormatSymbols.getEras returns
290
// abbreviations while other getShort*() return abbreviations.)
291
if (adapterType == LocaleProviderAdapter.Type.JRE) {
292
if (javatime) {
293
if (baseStyle == LONG) {
294
key.append("long.");
295
}
296
}
297
if (baseStyle == SHORT) {
298
key.append("short.");
299
}
300
} else { // this.type == LocaleProviderAdapter.Type.CLDR
301
if (baseStyle == LONG) {
302
key.append("long.");
303
}
304
}
305
}
306
key.append("Eras");
307
break;
308
309
case YEAR:
310
if (!isNarrow) {
311
key.append(type).append(".FirstYear");
312
}
313
break;
314
315
case MONTH:
316
if ("islamic".equals(type)) {
317
key.append(type).append('.');
318
}
319
if (isStandalone) {
320
key.append("standalone.");
321
}
322
key.append("Month").append(toStyleName(baseStyle));
323
break;
324
325
case DAY_OF_WEEK:
326
// support standalone narrow day names
327
if (isStandalone && isNarrow) {
328
key.append("standalone.");
329
}
330
key.append("Day").append(toStyleName(baseStyle));
331
break;
332
333
case AM_PM:
334
if (isNarrow) {
335
key.append("narrow.");
336
}
337
key.append("AmPmMarkers");
338
break;
339
}
340
return key.length() > 0 ? key.toString() : null;
341
}
342
343
private static String toStyleName(int baseStyle) {
344
switch (baseStyle) {
345
case SHORT:
346
return "Abbreviations";
347
case NARROW_FORMAT:
348
return "Narrows";
349
}
350
return "Names";
351
}
352
}
353
354