author | naoto |
Mon, 09 Sep 2019 12:42:01 -0700 | |
changeset 58058 | b553ad95acf0 |
parent 54412 | 41356f083e93 |
permissions | -rw-r--r-- |
13583 | 1 |
/* |
54026
3e7fd3fe8411
8218948: SimpleDateFormat :: format - Zone Names are not reflected correctly during run time
naoto
parents:
52869
diff
changeset
|
2 |
* Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. |
13583 | 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.locale.provider; |
|
42 |
||
15260 | 43 |
import java.lang.ref.ReferenceQueue; |
44 |
import java.lang.ref.SoftReference; |
|
13583 | 45 |
import java.text.MessageFormat; |
52869 | 46 |
import java.text.NumberFormat; |
54412 | 47 |
import java.util.Arrays; |
13583 | 48 |
import java.util.Calendar; |
51247
13e816d02c25
8206965: java/util/TimeZone/Bug8149452.java failed on de_DE and ja_JP locale.
rgoel
parents:
49904
diff
changeset
|
49 |
import java.util.HashSet; |
15260 | 50 |
import java.util.LinkedHashSet; |
13583 | 51 |
import java.util.Locale; |
15260 | 52 |
import java.util.Map; |
29926
2eceae3716d9
8076287: Performance degradation observed with TimeZone Benchmark
naoto
parents:
25859
diff
changeset
|
53 |
import java.util.Objects; |
13583 | 54 |
import java.util.ResourceBundle; |
15260 | 55 |
import java.util.Set; |
51247
13e816d02c25
8206965: java/util/TimeZone/Bug8149452.java failed on de_DE and ja_JP locale.
rgoel
parents:
49904
diff
changeset
|
56 |
import java.util.TimeZone; |
13583 | 57 |
import java.util.concurrent.ConcurrentHashMap; |
58 |
import java.util.concurrent.ConcurrentMap; |
|
49904
cadca99d52e7
8181157: CLDR Timezone name fallback implementation
naoto
parents:
48251
diff
changeset
|
59 |
import sun.security.action.GetPropertyAction; |
15260 | 60 |
import sun.util.resources.LocaleData; |
61 |
import sun.util.resources.OpenListResourceBundle; |
|
16852 | 62 |
import sun.util.resources.ParallelListResourceBundle; |
14765
0987999ed367
8000983: Support narrow display names for calendar fields
okutsu
parents:
13583
diff
changeset
|
63 |
import sun.util.resources.TimeZoneNamesBundle; |
13583 | 64 |
|
65 |
/** |
|
15260 | 66 |
* Central accessor to locale-dependent resources for JRE/CLDR provider adapters. |
13583 | 67 |
* |
68 |
* @author Masayoshi Okutsu |
|
15260 | 69 |
* @author Naoto Sato |
13583 | 70 |
*/ |
71 |
public class LocaleResources { |
|
72 |
||
73 |
private final Locale locale; |
|
15260 | 74 |
private final LocaleData localeData; |
75 |
private final LocaleProviderAdapter.Type type; |
|
13583 | 76 |
|
77 |
// Resource cache |
|
33310
2701a9854bb5
8134720: Lazy initialization support for currency names in DecimalFormatSymbols
naoto
parents:
31263
diff
changeset
|
78 |
private final ConcurrentMap<String, ResourceReference> cache = new ConcurrentHashMap<>(); |
2701a9854bb5
8134720: Lazy initialization support for currency names in DecimalFormatSymbols
naoto
parents:
31263
diff
changeset
|
79 |
private final ReferenceQueue<Object> referenceQueue = new ReferenceQueue<>(); |
15260 | 80 |
|
81 |
// cache key prefixes |
|
82 |
private static final String BREAK_ITERATOR_INFO = "BII."; |
|
83 |
private static final String CALENDAR_DATA = "CALD."; |
|
84 |
private static final String COLLATION_DATA_CACHEKEY = "COLD"; |
|
85 |
private static final String DECIMAL_FORMAT_SYMBOLS_DATA_CACHEKEY = "DFSD"; |
|
86 |
private static final String CURRENCY_NAMES = "CN."; |
|
87 |
private static final String LOCALE_NAMES = "LN."; |
|
88 |
private static final String TIME_ZONE_NAMES = "TZN."; |
|
89 |
private static final String ZONE_IDS_CACHEKEY = "ZID"; |
|
90 |
private static final String CALENDAR_NAMES = "CALN."; |
|
91 |
private static final String NUMBER_PATTERNS_CACHEKEY = "NP"; |
|
52869 | 92 |
private static final String COMPACT_NUMBER_PATTERNS_CACHEKEY = "CNP"; |
15260 | 93 |
private static final String DATE_TIME_PATTERN = "DTP."; |
94 |
||
49904
cadca99d52e7
8181157: CLDR Timezone name fallback implementation
naoto
parents:
48251
diff
changeset
|
95 |
// TimeZoneNamesBundle exemplar city prefix |
cadca99d52e7
8181157: CLDR Timezone name fallback implementation
naoto
parents:
48251
diff
changeset
|
96 |
private static final String TZNB_EXCITY_PREFIX = "timezone.excity."; |
cadca99d52e7
8181157: CLDR Timezone name fallback implementation
naoto
parents:
48251
diff
changeset
|
97 |
|
15260 | 98 |
// null singleton cache value |
99 |
private static final Object NULLOBJECT = new Object(); |
|
100 |
||
101 |
LocaleResources(ResourceBundleBasedAdapter adapter, Locale locale) { |
|
102 |
this.locale = locale; |
|
103 |
this.localeData = adapter.getLocaleData(); |
|
104 |
type = ((LocaleProviderAdapter)adapter).getAdapterType(); |
|
105 |
} |
|
13583 | 106 |
|
15260 | 107 |
private void removeEmptyReferences() { |
108 |
Object ref; |
|
109 |
while ((ref = referenceQueue.poll()) != null) { |
|
110 |
cache.remove(((ResourceReference)ref).getCacheKey()); |
|
111 |
} |
|
112 |
} |
|
113 |
||
114 |
Object getBreakIteratorInfo(String key) { |
|
115 |
Object biInfo; |
|
116 |
String cacheKey = BREAK_ITERATOR_INFO + key; |
|
117 |
||
118 |
removeEmptyReferences(); |
|
119 |
ResourceReference data = cache.get(cacheKey); |
|
120 |
if (data == null || ((biInfo = data.get()) == null)) { |
|
121 |
biInfo = localeData.getBreakIteratorInfo(locale).getObject(key); |
|
122 |
cache.put(cacheKey, new ResourceReference(cacheKey, biInfo, referenceQueue)); |
|
41750
25ee1c2ee27e
8165804: Revisit the way of loading BreakIterator rules/dictionaries
okutsu
parents:
36511
diff
changeset
|
123 |
} |
15260 | 124 |
|
125 |
return biInfo; |
|
126 |
} |
|
127 |
||
41750
25ee1c2ee27e
8165804: Revisit the way of loading BreakIterator rules/dictionaries
okutsu
parents:
36511
diff
changeset
|
128 |
@SuppressWarnings("unchecked") |
25ee1c2ee27e
8165804: Revisit the way of loading BreakIterator rules/dictionaries
okutsu
parents:
36511
diff
changeset
|
129 |
byte[] getBreakIteratorResources(String key) { |
25ee1c2ee27e
8165804: Revisit the way of loading BreakIterator rules/dictionaries
okutsu
parents:
36511
diff
changeset
|
130 |
return (byte[]) localeData.getBreakIteratorResources(locale).getObject(key); |
36511 | 131 |
} |
132 |
||
48251
57148c79bd75
8176841: Additional Unicode Language-Tag Extensions
naoto
parents:
47216
diff
changeset
|
133 |
public String getCalendarData(String key) { |
57148c79bd75
8176841: Additional Unicode Language-Tag Extensions
naoto
parents:
47216
diff
changeset
|
134 |
String caldata = ""; |
15260 | 135 |
String cacheKey = CALENDAR_DATA + key; |
136 |
||
137 |
removeEmptyReferences(); |
|
138 |
||
139 |
ResourceReference data = cache.get(cacheKey); |
|
48251
57148c79bd75
8176841: Additional Unicode Language-Tag Extensions
naoto
parents:
47216
diff
changeset
|
140 |
if (data == null || ((caldata = (String) data.get()) == null)) { |
15260 | 141 |
ResourceBundle rb = localeData.getCalendarData(locale); |
142 |
if (rb.containsKey(key)) { |
|
48251
57148c79bd75
8176841: Additional Unicode Language-Tag Extensions
naoto
parents:
47216
diff
changeset
|
143 |
caldata = rb.getString(key); |
15260 | 144 |
} |
13583 | 145 |
|
15260 | 146 |
cache.put(cacheKey, |
48251
57148c79bd75
8176841: Additional Unicode Language-Tag Extensions
naoto
parents:
47216
diff
changeset
|
147 |
new ResourceReference(cacheKey, caldata, referenceQueue)); |
15260 | 148 |
} |
149 |
||
150 |
return caldata; |
|
151 |
} |
|
152 |
||
153 |
public String getCollationData() { |
|
154 |
String key = "Rule"; |
|
155 |
String coldata = ""; |
|
156 |
||
157 |
removeEmptyReferences(); |
|
158 |
ResourceReference data = cache.get(COLLATION_DATA_CACHEKEY); |
|
159 |
if (data == null || ((coldata = (String) data.get()) == null)) { |
|
160 |
ResourceBundle rb = localeData.getCollationData(locale); |
|
161 |
if (rb.containsKey(key)) { |
|
162 |
coldata = rb.getString(key); |
|
163 |
} |
|
164 |
cache.put(COLLATION_DATA_CACHEKEY, |
|
165 |
new ResourceReference(COLLATION_DATA_CACHEKEY, (Object) coldata, referenceQueue)); |
|
166 |
} |
|
167 |
||
168 |
return coldata; |
|
169 |
} |
|
170 |
||
171 |
public Object[] getDecimalFormatSymbolsData() { |
|
172 |
Object[] dfsdata; |
|
173 |
||
174 |
removeEmptyReferences(); |
|
175 |
ResourceReference data = cache.get(DECIMAL_FORMAT_SYMBOLS_DATA_CACHEKEY); |
|
176 |
if (data == null || ((dfsdata = (Object[]) data.get()) == null)) { |
|
177 |
// Note that only dfsdata[0] is prepared here in this method. Other |
|
178 |
// elements are provided by the caller, yet they are cached here. |
|
179 |
ResourceBundle rb = localeData.getNumberFormatData(locale); |
|
180 |
dfsdata = new Object[3]; |
|
58058
b553ad95acf0
8230284: Accounting currency format support does not cope with explicit number system
naoto
parents:
54412
diff
changeset
|
181 |
dfsdata[0] = getNumberStrings(rb, "NumberElements"); |
15260 | 182 |
|
183 |
cache.put(DECIMAL_FORMAT_SYMBOLS_DATA_CACHEKEY, |
|
184 |
new ResourceReference(DECIMAL_FORMAT_SYMBOLS_DATA_CACHEKEY, (Object) dfsdata, referenceQueue)); |
|
185 |
} |
|
186 |
||
187 |
return dfsdata; |
|
13583 | 188 |
} |
189 |
||
58058
b553ad95acf0
8230284: Accounting currency format support does not cope with explicit number system
naoto
parents:
54412
diff
changeset
|
190 |
private String[] getNumberStrings(ResourceBundle rb, String type) { |
b553ad95acf0
8230284: Accounting currency format support does not cope with explicit number system
naoto
parents:
54412
diff
changeset
|
191 |
String[] ret = null; |
b553ad95acf0
8230284: Accounting currency format support does not cope with explicit number system
naoto
parents:
54412
diff
changeset
|
192 |
String key; |
b553ad95acf0
8230284: Accounting currency format support does not cope with explicit number system
naoto
parents:
54412
diff
changeset
|
193 |
String numSys; |
b553ad95acf0
8230284: Accounting currency format support does not cope with explicit number system
naoto
parents:
54412
diff
changeset
|
194 |
|
b553ad95acf0
8230284: Accounting currency format support does not cope with explicit number system
naoto
parents:
54412
diff
changeset
|
195 |
// Number strings look up. First, try the Unicode extension |
b553ad95acf0
8230284: Accounting currency format support does not cope with explicit number system
naoto
parents:
54412
diff
changeset
|
196 |
numSys = locale.getUnicodeLocaleType("nu"); |
b553ad95acf0
8230284: Accounting currency format support does not cope with explicit number system
naoto
parents:
54412
diff
changeset
|
197 |
if (numSys != null) { |
b553ad95acf0
8230284: Accounting currency format support does not cope with explicit number system
naoto
parents:
54412
diff
changeset
|
198 |
key = numSys + "." + type; |
b553ad95acf0
8230284: Accounting currency format support does not cope with explicit number system
naoto
parents:
54412
diff
changeset
|
199 |
if (rb.containsKey(key)) { |
b553ad95acf0
8230284: Accounting currency format support does not cope with explicit number system
naoto
parents:
54412
diff
changeset
|
200 |
ret = rb.getStringArray(key); |
b553ad95acf0
8230284: Accounting currency format support does not cope with explicit number system
naoto
parents:
54412
diff
changeset
|
201 |
} |
b553ad95acf0
8230284: Accounting currency format support does not cope with explicit number system
naoto
parents:
54412
diff
changeset
|
202 |
} |
b553ad95acf0
8230284: Accounting currency format support does not cope with explicit number system
naoto
parents:
54412
diff
changeset
|
203 |
|
b553ad95acf0
8230284: Accounting currency format support does not cope with explicit number system
naoto
parents:
54412
diff
changeset
|
204 |
// Next, try DefaultNumberingSystem value |
b553ad95acf0
8230284: Accounting currency format support does not cope with explicit number system
naoto
parents:
54412
diff
changeset
|
205 |
if (ret == null && rb.containsKey("DefaultNumberingSystem")) { |
b553ad95acf0
8230284: Accounting currency format support does not cope with explicit number system
naoto
parents:
54412
diff
changeset
|
206 |
key = rb.getString("DefaultNumberingSystem") + "." + type; |
b553ad95acf0
8230284: Accounting currency format support does not cope with explicit number system
naoto
parents:
54412
diff
changeset
|
207 |
if (rb.containsKey(key)) { |
b553ad95acf0
8230284: Accounting currency format support does not cope with explicit number system
naoto
parents:
54412
diff
changeset
|
208 |
ret = rb.getStringArray(key); |
b553ad95acf0
8230284: Accounting currency format support does not cope with explicit number system
naoto
parents:
54412
diff
changeset
|
209 |
} |
b553ad95acf0
8230284: Accounting currency format support does not cope with explicit number system
naoto
parents:
54412
diff
changeset
|
210 |
} |
b553ad95acf0
8230284: Accounting currency format support does not cope with explicit number system
naoto
parents:
54412
diff
changeset
|
211 |
|
b553ad95acf0
8230284: Accounting currency format support does not cope with explicit number system
naoto
parents:
54412
diff
changeset
|
212 |
// Last resort. No need to check the availability. |
b553ad95acf0
8230284: Accounting currency format support does not cope with explicit number system
naoto
parents:
54412
diff
changeset
|
213 |
// Just let it throw MissingResourceException when needed. |
b553ad95acf0
8230284: Accounting currency format support does not cope with explicit number system
naoto
parents:
54412
diff
changeset
|
214 |
if (ret == null) { |
b553ad95acf0
8230284: Accounting currency format support does not cope with explicit number system
naoto
parents:
54412
diff
changeset
|
215 |
ret = rb.getStringArray(type); |
b553ad95acf0
8230284: Accounting currency format support does not cope with explicit number system
naoto
parents:
54412
diff
changeset
|
216 |
} |
b553ad95acf0
8230284: Accounting currency format support does not cope with explicit number system
naoto
parents:
54412
diff
changeset
|
217 |
|
b553ad95acf0
8230284: Accounting currency format support does not cope with explicit number system
naoto
parents:
54412
diff
changeset
|
218 |
return ret; |
b553ad95acf0
8230284: Accounting currency format support does not cope with explicit number system
naoto
parents:
54412
diff
changeset
|
219 |
} |
b553ad95acf0
8230284: Accounting currency format support does not cope with explicit number system
naoto
parents:
54412
diff
changeset
|
220 |
|
15260 | 221 |
public String getCurrencyName(String key) { |
222 |
Object currencyName = null; |
|
223 |
String cacheKey = CURRENCY_NAMES + key; |
|
224 |
||
225 |
removeEmptyReferences(); |
|
226 |
ResourceReference data = cache.get(cacheKey); |
|
227 |
||
228 |
if (data != null && ((currencyName = data.get()) != null)) { |
|
229 |
if (currencyName.equals(NULLOBJECT)) { |
|
230 |
currencyName = null; |
|
231 |
} |
|
232 |
||
233 |
return (String) currencyName; |
|
234 |
} |
|
235 |
||
236 |
OpenListResourceBundle olrb = localeData.getCurrencyNames(locale); |
|
237 |
||
238 |
if (olrb.containsKey(key)) { |
|
239 |
currencyName = olrb.getObject(key); |
|
240 |
cache.put(cacheKey, |
|
241 |
new ResourceReference(cacheKey, currencyName, referenceQueue)); |
|
242 |
} |
|
243 |
||
244 |
return (String) currencyName; |
|
245 |
} |
|
246 |
||
247 |
public String getLocaleName(String key) { |
|
248 |
Object localeName = null; |
|
249 |
String cacheKey = LOCALE_NAMES + key; |
|
250 |
||
251 |
removeEmptyReferences(); |
|
252 |
ResourceReference data = cache.get(cacheKey); |
|
253 |
||
254 |
if (data != null && ((localeName = data.get()) != null)) { |
|
255 |
if (localeName.equals(NULLOBJECT)) { |
|
256 |
localeName = null; |
|
257 |
} |
|
258 |
||
259 |
return (String) localeName; |
|
260 |
} |
|
261 |
||
262 |
OpenListResourceBundle olrb = localeData.getLocaleNames(locale); |
|
263 |
||
264 |
if (olrb.containsKey(key)) { |
|
265 |
localeName = olrb.getObject(key); |
|
266 |
cache.put(cacheKey, |
|
267 |
new ResourceReference(cacheKey, localeName, referenceQueue)); |
|
268 |
} |
|
269 |
||
270 |
return (String) localeName; |
|
271 |
} |
|
272 |
||
49904
cadca99d52e7
8181157: CLDR Timezone name fallback implementation
naoto
parents:
48251
diff
changeset
|
273 |
public Object getTimeZoneNames(String key) { |
cadca99d52e7
8181157: CLDR Timezone name fallback implementation
naoto
parents:
48251
diff
changeset
|
274 |
Object val = null; |
cadca99d52e7
8181157: CLDR Timezone name fallback implementation
naoto
parents:
48251
diff
changeset
|
275 |
String cacheKey = TIME_ZONE_NAMES + key; |
15260 | 276 |
|
277 |
removeEmptyReferences(); |
|
278 |
ResourceReference data = cache.get(cacheKey); |
|
279 |
||
49904
cadca99d52e7
8181157: CLDR Timezone name fallback implementation
naoto
parents:
48251
diff
changeset
|
280 |
if (Objects.isNull(data) || Objects.isNull(val = data.get())) { |
15260 | 281 |
TimeZoneNamesBundle tznb = localeData.getTimeZoneNames(locale); |
54026
3e7fd3fe8411
8218948: SimpleDateFormat :: format - Zone Names are not reflected correctly during run time
naoto
parents:
52869
diff
changeset
|
282 |
if (key.startsWith(TZNB_EXCITY_PREFIX)) { |
3e7fd3fe8411
8218948: SimpleDateFormat :: format - Zone Names are not reflected correctly during run time
naoto
parents:
52869
diff
changeset
|
283 |
if (tznb.containsKey(key)) { |
49904
cadca99d52e7
8181157: CLDR Timezone name fallback implementation
naoto
parents:
48251
diff
changeset
|
284 |
val = tznb.getString(key); |
cadca99d52e7
8181157: CLDR Timezone name fallback implementation
naoto
parents:
48251
diff
changeset
|
285 |
assert val instanceof String; |
cadca99d52e7
8181157: CLDR Timezone name fallback implementation
naoto
parents:
48251
diff
changeset
|
286 |
trace("tznb: %s key: %s, val: %s\n", tznb, key, val); |
54026
3e7fd3fe8411
8218948: SimpleDateFormat :: format - Zone Names are not reflected correctly during run time
naoto
parents:
52869
diff
changeset
|
287 |
} |
3e7fd3fe8411
8218948: SimpleDateFormat :: format - Zone Names are not reflected correctly during run time
naoto
parents:
52869
diff
changeset
|
288 |
} else { |
3e7fd3fe8411
8218948: SimpleDateFormat :: format - Zone Names are not reflected correctly during run time
naoto
parents:
52869
diff
changeset
|
289 |
String[] names = null; |
3e7fd3fe8411
8218948: SimpleDateFormat :: format - Zone Names are not reflected correctly during run time
naoto
parents:
52869
diff
changeset
|
290 |
if (tznb.containsKey(key)) { |
3e7fd3fe8411
8218948: SimpleDateFormat :: format - Zone Names are not reflected correctly during run time
naoto
parents:
52869
diff
changeset
|
291 |
names = tznb.getStringArray(key); |
49904
cadca99d52e7
8181157: CLDR Timezone name fallback implementation
naoto
parents:
48251
diff
changeset
|
292 |
} else { |
54026
3e7fd3fe8411
8218948: SimpleDateFormat :: format - Zone Names are not reflected correctly during run time
naoto
parents:
52869
diff
changeset
|
293 |
var tz = TimeZoneNameUtility.canonicalTZID(key).orElse(key); |
3e7fd3fe8411
8218948: SimpleDateFormat :: format - Zone Names are not reflected correctly during run time
naoto
parents:
52869
diff
changeset
|
294 |
if (tznb.containsKey(tz)) { |
3e7fd3fe8411
8218948: SimpleDateFormat :: format - Zone Names are not reflected correctly during run time
naoto
parents:
52869
diff
changeset
|
295 |
names = tznb.getStringArray(tz); |
3e7fd3fe8411
8218948: SimpleDateFormat :: format - Zone Names are not reflected correctly during run time
naoto
parents:
52869
diff
changeset
|
296 |
} |
3e7fd3fe8411
8218948: SimpleDateFormat :: format - Zone Names are not reflected correctly during run time
naoto
parents:
52869
diff
changeset
|
297 |
} |
3e7fd3fe8411
8218948: SimpleDateFormat :: format - Zone Names are not reflected correctly during run time
naoto
parents:
52869
diff
changeset
|
298 |
|
3e7fd3fe8411
8218948: SimpleDateFormat :: format - Zone Names are not reflected correctly during run time
naoto
parents:
52869
diff
changeset
|
299 |
if (names != null) { |
3e7fd3fe8411
8218948: SimpleDateFormat :: format - Zone Names are not reflected correctly during run time
naoto
parents:
52869
diff
changeset
|
300 |
names[0] = key; |
49904
cadca99d52e7
8181157: CLDR Timezone name fallback implementation
naoto
parents:
48251
diff
changeset
|
301 |
trace("tznb: %s key: %s, names: %s, %s, %s, %s, %s, %s, %s\n", tznb, key, |
cadca99d52e7
8181157: CLDR Timezone name fallback implementation
naoto
parents:
48251
diff
changeset
|
302 |
names[0], names[1], names[2], names[3], names[4], names[5], names[6]); |
cadca99d52e7
8181157: CLDR Timezone name fallback implementation
naoto
parents:
48251
diff
changeset
|
303 |
val = names; |
cadca99d52e7
8181157: CLDR Timezone name fallback implementation
naoto
parents:
48251
diff
changeset
|
304 |
} |
54026
3e7fd3fe8411
8218948: SimpleDateFormat :: format - Zone Names are not reflected correctly during run time
naoto
parents:
52869
diff
changeset
|
305 |
} |
3e7fd3fe8411
8218948: SimpleDateFormat :: format - Zone Names are not reflected correctly during run time
naoto
parents:
52869
diff
changeset
|
306 |
if (val != null) { |
15260 | 307 |
cache.put(cacheKey, |
49904
cadca99d52e7
8181157: CLDR Timezone name fallback implementation
naoto
parents:
48251
diff
changeset
|
308 |
new ResourceReference(cacheKey, val, referenceQueue)); |
13583 | 309 |
} |
310 |
} |
|
15260 | 311 |
|
49904
cadca99d52e7
8181157: CLDR Timezone name fallback implementation
naoto
parents:
48251
diff
changeset
|
312 |
return val; |
15260 | 313 |
} |
314 |
||
315 |
@SuppressWarnings("unchecked") |
|
316 |
Set<String> getZoneIDs() { |
|
317 |
Set<String> zoneIDs = null; |
|
318 |
||
319 |
removeEmptyReferences(); |
|
320 |
ResourceReference data = cache.get(ZONE_IDS_CACHEKEY); |
|
321 |
if (data == null || ((zoneIDs = (Set<String>) data.get()) == null)) { |
|
322 |
TimeZoneNamesBundle rb = localeData.getTimeZoneNames(locale); |
|
323 |
zoneIDs = rb.keySet(); |
|
324 |
cache.put(ZONE_IDS_CACHEKEY, |
|
325 |
new ResourceReference(ZONE_IDS_CACHEKEY, (Object) zoneIDs, referenceQueue)); |
|
326 |
} |
|
327 |
||
328 |
return zoneIDs; |
|
329 |
} |
|
330 |
||
331 |
// zoneStrings are cached separately in TimeZoneNameUtility. |
|
332 |
String[][] getZoneStrings() { |
|
333 |
TimeZoneNamesBundle rb = localeData.getTimeZoneNames(locale); |
|
334 |
Set<String> keyset = getZoneIDs(); |
|
335 |
// Use a LinkedHashSet to preseve the order |
|
336 |
Set<String[]> value = new LinkedHashSet<>(); |
|
54412 | 337 |
Set<String> tzIds = new HashSet<>(Arrays.asList(TimeZone.getAvailableIDs())); |
15260 | 338 |
for (String key : keyset) { |
49904
cadca99d52e7
8181157: CLDR Timezone name fallback implementation
naoto
parents:
48251
diff
changeset
|
339 |
if (!key.startsWith(TZNB_EXCITY_PREFIX)) { |
cadca99d52e7
8181157: CLDR Timezone name fallback implementation
naoto
parents:
48251
diff
changeset
|
340 |
value.add(rb.getStringArray(key)); |
51247
13e816d02c25
8206965: java/util/TimeZone/Bug8149452.java failed on de_DE and ja_JP locale.
rgoel
parents:
49904
diff
changeset
|
341 |
tzIds.remove(key); |
49904
cadca99d52e7
8181157: CLDR Timezone name fallback implementation
naoto
parents:
48251
diff
changeset
|
342 |
} |
15260 | 343 |
} |
344 |
||
345 |
if (type == LocaleProviderAdapter.Type.CLDR) { |
|
51247
13e816d02c25
8206965: java/util/TimeZone/Bug8149452.java failed on de_DE and ja_JP locale.
rgoel
parents:
49904
diff
changeset
|
346 |
// Note: TimeZoneNamesBundle creates a String[] on each getStringArray call. |
13e816d02c25
8206965: java/util/TimeZone/Bug8149452.java failed on de_DE and ja_JP locale.
rgoel
parents:
49904
diff
changeset
|
347 |
|
13e816d02c25
8206965: java/util/TimeZone/Bug8149452.java failed on de_DE and ja_JP locale.
rgoel
parents:
49904
diff
changeset
|
348 |
// Add timezones which are not present in this keyset, |
13e816d02c25
8206965: java/util/TimeZone/Bug8149452.java failed on de_DE and ja_JP locale.
rgoel
parents:
49904
diff
changeset
|
349 |
// so that their fallback names will be generated at runtime. |
13e816d02c25
8206965: java/util/TimeZone/Bug8149452.java failed on de_DE and ja_JP locale.
rgoel
parents:
49904
diff
changeset
|
350 |
tzIds.stream().filter(i -> (!i.startsWith("Etc/GMT") |
13e816d02c25
8206965: java/util/TimeZone/Bug8149452.java failed on de_DE and ja_JP locale.
rgoel
parents:
49904
diff
changeset
|
351 |
&& !i.startsWith("GMT") |
13e816d02c25
8206965: java/util/TimeZone/Bug8149452.java failed on de_DE and ja_JP locale.
rgoel
parents:
49904
diff
changeset
|
352 |
&& !i.startsWith("SystemV"))) |
13e816d02c25
8206965: java/util/TimeZone/Bug8149452.java failed on de_DE and ja_JP locale.
rgoel
parents:
49904
diff
changeset
|
353 |
.forEach(tzid -> { |
13e816d02c25
8206965: java/util/TimeZone/Bug8149452.java failed on de_DE and ja_JP locale.
rgoel
parents:
49904
diff
changeset
|
354 |
String[] val = new String[7]; |
13e816d02c25
8206965: java/util/TimeZone/Bug8149452.java failed on de_DE and ja_JP locale.
rgoel
parents:
49904
diff
changeset
|
355 |
if (keyset.contains(tzid)) { |
13e816d02c25
8206965: java/util/TimeZone/Bug8149452.java failed on de_DE and ja_JP locale.
rgoel
parents:
49904
diff
changeset
|
356 |
val = rb.getStringArray(tzid); |
13e816d02c25
8206965: java/util/TimeZone/Bug8149452.java failed on de_DE and ja_JP locale.
rgoel
parents:
49904
diff
changeset
|
357 |
} else { |
54026
3e7fd3fe8411
8218948: SimpleDateFormat :: format - Zone Names are not reflected correctly during run time
naoto
parents:
52869
diff
changeset
|
358 |
var canonID = TimeZoneNameUtility.canonicalTZID(tzid) |
3e7fd3fe8411
8218948: SimpleDateFormat :: format - Zone Names are not reflected correctly during run time
naoto
parents:
52869
diff
changeset
|
359 |
.orElse(tzid); |
3e7fd3fe8411
8218948: SimpleDateFormat :: format - Zone Names are not reflected correctly during run time
naoto
parents:
52869
diff
changeset
|
360 |
if (keyset.contains(canonID)) { |
3e7fd3fe8411
8218948: SimpleDateFormat :: format - Zone Names are not reflected correctly during run time
naoto
parents:
52869
diff
changeset
|
361 |
val = rb.getStringArray(canonID); |
51247
13e816d02c25
8206965: java/util/TimeZone/Bug8149452.java failed on de_DE and ja_JP locale.
rgoel
parents:
49904
diff
changeset
|
362 |
} |
13e816d02c25
8206965: java/util/TimeZone/Bug8149452.java failed on de_DE and ja_JP locale.
rgoel
parents:
49904
diff
changeset
|
363 |
} |
13e816d02c25
8206965: java/util/TimeZone/Bug8149452.java failed on de_DE and ja_JP locale.
rgoel
parents:
49904
diff
changeset
|
364 |
val[0] = tzid; |
15260 | 365 |
value.add(val); |
51247
13e816d02c25
8206965: java/util/TimeZone/Bug8149452.java failed on de_DE and ja_JP locale.
rgoel
parents:
49904
diff
changeset
|
366 |
}); |
15260 | 367 |
} |
368 |
return value.toArray(new String[0][]); |
|
369 |
} |
|
370 |
||
371 |
String[] getCalendarNames(String key) { |
|
372 |
String[] names = null; |
|
373 |
String cacheKey = CALENDAR_NAMES + key; |
|
374 |
||
375 |
removeEmptyReferences(); |
|
376 |
ResourceReference data = cache.get(cacheKey); |
|
377 |
||
378 |
if (data == null || ((names = (String[]) data.get()) == null)) { |
|
379 |
ResourceBundle rb = localeData.getDateFormatData(locale); |
|
380 |
if (rb.containsKey(key)) { |
|
381 |
names = rb.getStringArray(key); |
|
382 |
cache.put(cacheKey, |
|
383 |
new ResourceReference(cacheKey, (Object) names, referenceQueue)); |
|
384 |
} |
|
385 |
} |
|
386 |
||
387 |
return names; |
|
13583 | 388 |
} |
389 |
||
16852 | 390 |
String[] getJavaTimeNames(String key) { |
391 |
String[] names = null; |
|
392 |
String cacheKey = CALENDAR_NAMES + key; |
|
393 |
||
394 |
removeEmptyReferences(); |
|
395 |
ResourceReference data = cache.get(cacheKey); |
|
396 |
||
397 |
if (data == null || ((names = (String[]) data.get()) == null)) { |
|
398 |
ResourceBundle rb = getJavaTimeFormatData(); |
|
399 |
if (rb.containsKey(key)) { |
|
400 |
names = rb.getStringArray(key); |
|
401 |
cache.put(cacheKey, |
|
402 |
new ResourceReference(cacheKey, (Object) names, referenceQueue)); |
|
403 |
} |
|
404 |
} |
|
405 |
||
406 |
return names; |
|
407 |
} |
|
408 |
||
13583 | 409 |
public String getDateTimePattern(int timeStyle, int dateStyle, Calendar cal) { |
410 |
if (cal == null) { |
|
411 |
cal = Calendar.getInstance(locale); |
|
412 |
} |
|
15658 | 413 |
return getDateTimePattern(null, timeStyle, dateStyle, cal.getCalendarType()); |
414 |
} |
|
415 |
||
416 |
/** |
|
417 |
* Returns a date-time format pattern |
|
418 |
* @param timeStyle style of time; one of FULL, LONG, MEDIUM, SHORT in DateFormat, |
|
419 |
* or -1 if not required |
|
420 |
* @param dateStyle style of time; one of FULL, LONG, MEDIUM, SHORT in DateFormat, |
|
421 |
* or -1 if not required |
|
422 |
* @param calType the calendar type for the pattern |
|
423 |
* @return the pattern string |
|
424 |
*/ |
|
16852 | 425 |
public String getJavaTimeDateTimePattern(int timeStyle, int dateStyle, String calType) { |
15658 | 426 |
calType = CalendarDataUtility.normalizeCalendarType(calType); |
427 |
String pattern; |
|
16852 | 428 |
pattern = getDateTimePattern("java.time.", timeStyle, dateStyle, calType); |
15658 | 429 |
if (pattern == null) { |
430 |
pattern = getDateTimePattern(null, timeStyle, dateStyle, calType); |
|
431 |
} |
|
432 |
return pattern; |
|
433 |
} |
|
434 |
||
435 |
private String getDateTimePattern(String prefix, int timeStyle, int dateStyle, String calType) { |
|
436 |
String pattern; |
|
13583 | 437 |
String timePattern = null; |
438 |
String datePattern = null; |
|
15658 | 439 |
|
13583 | 440 |
if (timeStyle >= 0) { |
15658 | 441 |
if (prefix != null) { |
442 |
timePattern = getDateTimePattern(prefix, "TimePatterns", timeStyle, calType); |
|
443 |
} |
|
444 |
if (timePattern == null) { |
|
445 |
timePattern = getDateTimePattern(null, "TimePatterns", timeStyle, calType); |
|
446 |
} |
|
13583 | 447 |
} |
448 |
if (dateStyle >= 0) { |
|
15658 | 449 |
if (prefix != null) { |
450 |
datePattern = getDateTimePattern(prefix, "DatePatterns", dateStyle, calType); |
|
451 |
} |
|
452 |
if (datePattern == null) { |
|
453 |
datePattern = getDateTimePattern(null, "DatePatterns", dateStyle, calType); |
|
454 |
} |
|
13583 | 455 |
} |
456 |
if (timeStyle >= 0) { |
|
457 |
if (dateStyle >= 0) { |
|
15658 | 458 |
String dateTimePattern = null; |
31263 | 459 |
int dateTimeStyle = Math.max(dateStyle, timeStyle); |
15658 | 460 |
if (prefix != null) { |
31263 | 461 |
dateTimePattern = getDateTimePattern(prefix, "DateTimePatterns", dateTimeStyle, calType); |
15658 | 462 |
} |
463 |
if (dateTimePattern == null) { |
|
31263 | 464 |
dateTimePattern = getDateTimePattern(null, "DateTimePatterns", dateTimeStyle, calType); |
15658 | 465 |
} |
13583 | 466 |
switch (dateTimePattern) { |
467 |
case "{1} {0}": |
|
468 |
pattern = datePattern + " " + timePattern; |
|
469 |
break; |
|
470 |
case "{0} {1}": |
|
471 |
pattern = timePattern + " " + datePattern; |
|
472 |
break; |
|
473 |
default: |
|
31263 | 474 |
pattern = MessageFormat.format(dateTimePattern.replaceAll("'", "''"), timePattern, datePattern); |
13583 | 475 |
break; |
476 |
} |
|
477 |
} else { |
|
478 |
pattern = timePattern; |
|
479 |
} |
|
480 |
} else if (dateStyle >= 0) { |
|
481 |
pattern = datePattern; |
|
482 |
} else { |
|
483 |
throw new IllegalArgumentException("No date or time style specified"); |
|
484 |
} |
|
485 |
return pattern; |
|
486 |
} |
|
487 |
||
488 |
public String[] getNumberPatterns() { |
|
15260 | 489 |
String[] numberPatterns = null; |
490 |
||
491 |
removeEmptyReferences(); |
|
492 |
ResourceReference data = cache.get(NUMBER_PATTERNS_CACHEKEY); |
|
493 |
||
494 |
if (data == null || ((numberPatterns = (String[]) data.get()) == null)) { |
|
495 |
ResourceBundle resource = localeData.getNumberFormatData(locale); |
|
58058
b553ad95acf0
8230284: Accounting currency format support does not cope with explicit number system
naoto
parents:
54412
diff
changeset
|
496 |
numberPatterns = getNumberStrings(resource, "NumberPatterns"); |
15260 | 497 |
cache.put(NUMBER_PATTERNS_CACHEKEY, |
498 |
new ResourceReference(NUMBER_PATTERNS_CACHEKEY, (Object) numberPatterns, referenceQueue)); |
|
13583 | 499 |
} |
15260 | 500 |
|
13583 | 501 |
return numberPatterns; |
502 |
} |
|
503 |
||
15281
dd43cb9be0e1
8004489: Add support for Minguo and Hijrah calendars to CalendarNameProvider SPI
okutsu
parents:
15260
diff
changeset
|
504 |
/** |
52869 | 505 |
* Returns the compact number format patterns. |
506 |
* @param formatStyle the style for formatting a number |
|
507 |
* @return an array of compact number patterns |
|
508 |
*/ |
|
509 |
@SuppressWarnings("unchecked") |
|
510 |
public String[] getCNPatterns(NumberFormat.Style formatStyle) { |
|
511 |
||
512 |
Objects.requireNonNull(formatStyle); |
|
513 |
String[] compactNumberPatterns = null; |
|
514 |
removeEmptyReferences(); |
|
515 |
String width = (formatStyle == NumberFormat.Style.LONG) ? "long" : "short"; |
|
516 |
String cacheKey = width + "." + COMPACT_NUMBER_PATTERNS_CACHEKEY; |
|
517 |
ResourceReference data = cache.get(cacheKey); |
|
518 |
if (data == null || ((compactNumberPatterns |
|
519 |
= (String[]) data.get()) == null)) { |
|
520 |
ResourceBundle resource = localeData.getNumberFormatData(locale); |
|
521 |
compactNumberPatterns = (String[]) resource |
|
522 |
.getObject(width + ".CompactNumberPatterns"); |
|
523 |
cache.put(cacheKey, new ResourceReference(cacheKey, |
|
524 |
(Object) compactNumberPatterns, referenceQueue)); |
|
525 |
} |
|
526 |
return compactNumberPatterns; |
|
527 |
} |
|
528 |
||
529 |
||
530 |
/** |
|
15281
dd43cb9be0e1
8004489: Add support for Minguo and Hijrah calendars to CalendarNameProvider SPI
okutsu
parents:
15260
diff
changeset
|
531 |
* Returns the FormatData resource bundle of this LocaleResources. |
dd43cb9be0e1
8004489: Add support for Minguo and Hijrah calendars to CalendarNameProvider SPI
okutsu
parents:
15260
diff
changeset
|
532 |
* The FormatData should be used only for accessing extra |
dd43cb9be0e1
8004489: Add support for Minguo and Hijrah calendars to CalendarNameProvider SPI
okutsu
parents:
15260
diff
changeset
|
533 |
* resources required by JSR 310. |
dd43cb9be0e1
8004489: Add support for Minguo and Hijrah calendars to CalendarNameProvider SPI
okutsu
parents:
15260
diff
changeset
|
534 |
*/ |
16852 | 535 |
public ResourceBundle getJavaTimeFormatData() { |
536 |
ResourceBundle rb = localeData.getDateFormatData(locale); |
|
537 |
if (rb instanceof ParallelListResourceBundle) { |
|
538 |
localeData.setSupplementary((ParallelListResourceBundle) rb); |
|
539 |
} |
|
540 |
return rb; |
|
15281
dd43cb9be0e1
8004489: Add support for Minguo and Hijrah calendars to CalendarNameProvider SPI
okutsu
parents:
15260
diff
changeset
|
541 |
} |
dd43cb9be0e1
8004489: Add support for Minguo and Hijrah calendars to CalendarNameProvider SPI
okutsu
parents:
15260
diff
changeset
|
542 |
|
15658 | 543 |
private String getDateTimePattern(String prefix, String key, int styleIndex, String calendarType) { |
544 |
StringBuilder sb = new StringBuilder(); |
|
545 |
if (prefix != null) { |
|
546 |
sb.append(prefix); |
|
547 |
} |
|
548 |
if (!"gregory".equals(calendarType)) { |
|
549 |
sb.append(calendarType).append('.'); |
|
550 |
} |
|
551 |
sb.append(key); |
|
552 |
String resourceKey = sb.toString(); |
|
553 |
String cacheKey = sb.insert(0, DATE_TIME_PATTERN).toString(); |
|
15260 | 554 |
|
555 |
removeEmptyReferences(); |
|
556 |
ResourceReference data = cache.get(cacheKey); |
|
15658 | 557 |
Object value = NULLOBJECT; |
15260 | 558 |
|
15658 | 559 |
if (data == null || ((value = data.get()) == null)) { |
16852 | 560 |
ResourceBundle r = (prefix != null) ? getJavaTimeFormatData() : localeData.getDateFormatData(locale); |
13583 | 561 |
if (r.containsKey(resourceKey)) { |
15658 | 562 |
value = r.getStringArray(resourceKey); |
13583 | 563 |
} else { |
564 |
assert !resourceKey.equals(key); |
|
15658 | 565 |
if (r.containsKey(key)) { |
566 |
value = r.getStringArray(key); |
|
567 |
} |
|
13583 | 568 |
} |
15260 | 569 |
cache.put(cacheKey, |
15658 | 570 |
new ResourceReference(cacheKey, value, referenceQueue)); |
13583 | 571 |
} |
15658 | 572 |
if (value == NULLOBJECT) { |
573 |
assert prefix != null; |
|
574 |
return null; |
|
575 |
} |
|
31263 | 576 |
|
577 |
// for DateTimePatterns. CLDR has multiple styles, while JRE has one. |
|
578 |
String[] styles = (String[])value; |
|
579 |
return (styles.length > 1 ? styles[styleIndex] : styles[0]); |
|
13583 | 580 |
} |
15260 | 581 |
|
582 |
private static class ResourceReference extends SoftReference<Object> { |
|
583 |
private final String cacheKey; |
|
584 |
||
585 |
ResourceReference(String cacheKey, Object o, ReferenceQueue<Object> q) { |
|
586 |
super(o, q); |
|
587 |
this.cacheKey = cacheKey; |
|
588 |
} |
|
589 |
||
590 |
String getCacheKey() { |
|
591 |
return cacheKey; |
|
592 |
} |
|
593 |
} |
|
49904
cadca99d52e7
8181157: CLDR Timezone name fallback implementation
naoto
parents:
48251
diff
changeset
|
594 |
|
cadca99d52e7
8181157: CLDR Timezone name fallback implementation
naoto
parents:
48251
diff
changeset
|
595 |
private static final boolean TRACE_ON = Boolean.valueOf( |
cadca99d52e7
8181157: CLDR Timezone name fallback implementation
naoto
parents:
48251
diff
changeset
|
596 |
GetPropertyAction.privilegedGetProperty("locale.resources.debug", "false")); |
cadca99d52e7
8181157: CLDR Timezone name fallback implementation
naoto
parents:
48251
diff
changeset
|
597 |
|
cadca99d52e7
8181157: CLDR Timezone name fallback implementation
naoto
parents:
48251
diff
changeset
|
598 |
public static void trace(String format, Object... params) { |
cadca99d52e7
8181157: CLDR Timezone name fallback implementation
naoto
parents:
48251
diff
changeset
|
599 |
if (TRACE_ON) { |
cadca99d52e7
8181157: CLDR Timezone name fallback implementation
naoto
parents:
48251
diff
changeset
|
600 |
System.out.format(format, params); |
cadca99d52e7
8181157: CLDR Timezone name fallback implementation
naoto
parents:
48251
diff
changeset
|
601 |
} |
cadca99d52e7
8181157: CLDR Timezone name fallback implementation
naoto
parents:
48251
diff
changeset
|
602 |
} |
13583 | 603 |
} |