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 java.lang.ref.SoftReference;
28 import java.text.DateFormat;
29 import java.text.DateFormatSymbols;
30 import java.text.DecimalFormat;
31 import java.text.DecimalFormatSymbols;
32 import java.text.NumberFormat;
33 import java.text.SimpleDateFormat;
34 import java.text.spi.DateFormatProvider;
35 import java.text.spi.DateFormatSymbolsProvider;
36 import java.text.spi.DecimalFormatSymbolsProvider;
37 import java.text.spi.NumberFormatProvider;
38 import java.util.Collections;
39 import java.util.HashSet;
40 import java.util.Locale;
41 import java.util.Map;
42 import java.util.ResourceBundle.Control;
43 import java.util.Set;
44 import java.util.concurrent.ConcurrentHashMap;
45 import java.util.concurrent.ConcurrentMap;
46 import java.util.concurrent.atomic.AtomicReferenceArray;
47 import java.util.spi.CalendarDataProvider;
48 import java.util.spi.CalendarNameProvider;
49
50 /**
51 * LocaleProviderdapter implementation for the Windows locale data.
52 *
53 * @author Naoto Sato
54 */
55 public class HostLocaleProviderAdapterImpl {
56
57 // locale categories
58 private static final int CAT_DISPLAY = 0;
59 private static final int CAT_FORMAT = 1;
60
61 // NumberFormat styles
62 private static final int NF_NUMBER = 0;
63 private static final int NF_CURRENCY = 1;
64 private static final int NF_PERCENT = 2;
65 private static final int NF_INTEGER = 3;
66 private static final int NF_MAX = NF_INTEGER;
67
68 // CalendarData value types
156 patterns.compareAndSet(1, null, convertDateTimePattern(
157 getDateTimePattern(DateFormat.SHORT, -1, langtag)));
158 patterns.compareAndSet(2, null, convertDateTimePattern(
159 getDateTimePattern(-1, DateFormat.LONG, langtag)));
160 patterns.compareAndSet(3, null, convertDateTimePattern(
161 getDateTimePattern(-1, DateFormat.SHORT, langtag)));
162 ref = new SoftReference<>(patterns);
163 dateFormatCache.put(locale, ref);
164 }
165
166 return patterns;
167 }
168 };
169 }
170
171 public static DateFormatSymbolsProvider getDateFormatSymbolsProvider() {
172 return new DateFormatSymbolsProvider() {
173
174 @Override
175 public Locale[] getAvailableLocales() {
176 if (isSupportedLocale(Locale.getDefault(Locale.Category.FORMAT))) {
177 return supportedLocale;
178 }
179
180 return new Locale[0];
181 }
182
183 @Override
184 public boolean isSupportedLocale(Locale locale) {
185 // Only supports the locale with Gregorian calendar
186 if (supportedLocale.length != 0) {
187 int calid = getCalendarID(locale.toLanguageTag());
188 if (calid > 0 && calid < calIDToLDML.length) {
189 return calIDToLDML[calid].startsWith("gregory");
190 }
191 }
192
193 return false;
194 }
195
196 @Override
197 public DateFormatSymbols getInstance(Locale locale) {
198 DateFormatSymbols dfs;
199 SoftReference<DateFormatSymbols> ref =
200 dateFormatSymbolsCache.get(locale);
201
202 if (ref == null || (dfs = ref.get()) == null) {
203 dfs = new DateFormatSymbols(locale);
204 String langTag = removeExtensions(locale).toLanguageTag();
205
206 dfs.setAmPmStrings(getAmPmStrings(langTag, dfs.getAmPmStrings()));
207 dfs.setEras(getEras(langTag, dfs.getEras()));
208 dfs.setMonths(getMonths(langTag, dfs.getMonths()));
209 dfs.setShortMonths(getShortMonths(langTag, dfs.getShortMonths()));
210 dfs.setWeekdays(getWeekdays(langTag, dfs.getWeekdays()));
211 dfs.setShortWeekdays(getShortWeekdays(langTag, dfs.getShortWeekdays()));
212 ref = new SoftReference<>(dfs);
213 dateFormatSymbolsCache.put(locale, ref);
214 }
215 return (DateFormatSymbols)dfs.clone();
363
364 @Override
365 public boolean isSupportedLocale(Locale locale) {
366 return isSupportedCalendarLocale(locale);
367 }
368
369 @Override
370 public String getDisplayName(String calType, int field, int value,
371 int style, Locale locale) {
372 return null;
373 }
374
375 @Override
376 public Map<String, Integer> getDisplayNames(String calType,
377 int field, int style, Locale locale) {
378 return null;
379 }
380 };
381 }
382
383 private static String convertDateTimePattern(String winPattern) {
384 String ret = winPattern.replaceAll("dddd", "EEEE");
385 ret = ret.replaceAll("ddd", "EEE");
386 ret = ret.replaceAll("tt", "aa");
387 ret = ret.replaceAll("g", "GG");
388 return ret;
389 }
390
391 private static Locale[] getSupportedCalendarLocales() {
392 if (supportedLocale.length != 0 &&
393 supportedLocaleSet.contains(Locale.JAPAN) &&
394 isJapaneseCalendar()) {
395 Locale[] sup = new Locale[supportedLocale.length+1];
396 sup[0] = JRELocaleConstants.JA_JP_JP;
397 System.arraycopy(supportedLocale, 0, sup, 1, supportedLocale.length);
398 return sup;
399 }
400 return supportedLocale;
401 }
402
403 private static boolean isSupportedCalendarLocale(Locale locale) {
404 // special case for ja_JP_JP
405 if (JRELocaleConstants.JA_JP_JP.equals(locale)) {
406 return isJapaneseCalendar();
407 }
408
409 Locale base = locale.stripExtensions();
410 if (!supportedLocaleSet.contains(base)) {
411 return false;
412 }
413
414 String caltype = locale.getUnicodeLocaleType("ca");
415 if (caltype == null) {
416 return true;
417 }
418
419 return caltype.equals(
420 calIDToLDML[getCalendarID(locale.toLanguageTag())]
421 .replaceFirst("_.*", ""));
422 }
423
424 private static Locale[] getSupportedNativeDigitLocales() {
425 if (supportedLocale.length != 0 &&
426 supportedLocaleSet.contains(JRELocaleConstants.TH_TH) &&
427 isNativeDigit("th-TH")) {
428 Locale[] sup = new Locale[supportedLocale.length+1];
429 sup[0] = JRELocaleConstants.TH_TH_TH;
430 System.arraycopy(supportedLocale, 0, sup, 1, supportedLocale.length);
431 return sup;
432 }
433 return supportedLocale;
434 }
435
436 private static boolean isSupportedNativeDigitLocale(Locale locale) {
437 // special case for th_TH_TH
438 if (JRELocaleConstants.TH_TH_TH.equals(locale)) {
439 return isNativeDigit("th-TH");
440 }
441
442 String numtype = null;
|
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 java.lang.ref.SoftReference;
28 import java.text.DateFormat;
29 import java.text.DateFormatSymbols;
30 import java.text.DecimalFormat;
31 import java.text.DecimalFormatSymbols;
32 import java.text.NumberFormat;
33 import java.text.SimpleDateFormat;
34 import java.text.spi.DateFormatProvider;
35 import java.text.spi.DateFormatSymbolsProvider;
36 import java.text.spi.DecimalFormatSymbolsProvider;
37 import java.text.spi.NumberFormatProvider;
38 import java.util.Calendar;
39 import java.util.Collections;
40 import java.util.HashSet;
41 import java.util.Locale;
42 import java.util.Map;
43 import java.util.ResourceBundle.Control;
44 import java.util.Set;
45 import java.util.TimeZone;
46 import java.util.concurrent.ConcurrentHashMap;
47 import java.util.concurrent.ConcurrentMap;
48 import java.util.concurrent.atomic.AtomicReferenceArray;
49 import java.util.spi.CalendarDataProvider;
50 import java.util.spi.CalendarNameProvider;
51 import sun.util.spi.CalendarProvider;
52
53 /**
54 * LocaleProviderdapter implementation for the Windows locale data.
55 *
56 * @author Naoto Sato
57 */
58 public class HostLocaleProviderAdapterImpl {
59
60 // locale categories
61 private static final int CAT_DISPLAY = 0;
62 private static final int CAT_FORMAT = 1;
63
64 // NumberFormat styles
65 private static final int NF_NUMBER = 0;
66 private static final int NF_CURRENCY = 1;
67 private static final int NF_PERCENT = 2;
68 private static final int NF_INTEGER = 3;
69 private static final int NF_MAX = NF_INTEGER;
70
71 // CalendarData value types
159 patterns.compareAndSet(1, null, convertDateTimePattern(
160 getDateTimePattern(DateFormat.SHORT, -1, langtag)));
161 patterns.compareAndSet(2, null, convertDateTimePattern(
162 getDateTimePattern(-1, DateFormat.LONG, langtag)));
163 patterns.compareAndSet(3, null, convertDateTimePattern(
164 getDateTimePattern(-1, DateFormat.SHORT, langtag)));
165 ref = new SoftReference<>(patterns);
166 dateFormatCache.put(locale, ref);
167 }
168
169 return patterns;
170 }
171 };
172 }
173
174 public static DateFormatSymbolsProvider getDateFormatSymbolsProvider() {
175 return new DateFormatSymbolsProvider() {
176
177 @Override
178 public Locale[] getAvailableLocales() {
179 return getSupportedCalendarLocales();
180 }
181
182 @Override
183 public boolean isSupportedLocale(Locale locale) {
184 return isSupportedCalendarLocale(locale);
185 }
186
187 @Override
188 public DateFormatSymbols getInstance(Locale locale) {
189 DateFormatSymbols dfs;
190 SoftReference<DateFormatSymbols> ref =
191 dateFormatSymbolsCache.get(locale);
192
193 if (ref == null || (dfs = ref.get()) == null) {
194 dfs = new DateFormatSymbols(locale);
195 String langTag = removeExtensions(locale).toLanguageTag();
196
197 dfs.setAmPmStrings(getAmPmStrings(langTag, dfs.getAmPmStrings()));
198 dfs.setEras(getEras(langTag, dfs.getEras()));
199 dfs.setMonths(getMonths(langTag, dfs.getMonths()));
200 dfs.setShortMonths(getShortMonths(langTag, dfs.getShortMonths()));
201 dfs.setWeekdays(getWeekdays(langTag, dfs.getWeekdays()));
202 dfs.setShortWeekdays(getShortWeekdays(langTag, dfs.getShortWeekdays()));
203 ref = new SoftReference<>(dfs);
204 dateFormatSymbolsCache.put(locale, ref);
205 }
206 return (DateFormatSymbols)dfs.clone();
354
355 @Override
356 public boolean isSupportedLocale(Locale locale) {
357 return isSupportedCalendarLocale(locale);
358 }
359
360 @Override
361 public String getDisplayName(String calType, int field, int value,
362 int style, Locale locale) {
363 return null;
364 }
365
366 @Override
367 public Map<String, Integer> getDisplayNames(String calType,
368 int field, int style, Locale locale) {
369 return null;
370 }
371 };
372 }
373
374 public static CalendarProvider getCalendarProvider() {
375 return new CalendarProvider() {
376 @Override
377 public Locale[] getAvailableLocales() {
378 return getSupportedCalendarLocales();
379 }
380
381 @Override
382 public boolean isSupportedLocale(Locale locale) {
383 return isSupportedCalendarLocale(locale);
384 }
385
386 @Override
387 public Calendar getInstance(TimeZone zone, Locale locale) {
388 return new Calendar.Builder()
389 .setLocale(getCalendarLocale(locale))
390 .setTimeZone(zone)
391 .build();
392 }
393 };
394 }
395
396 private static String convertDateTimePattern(String winPattern) {
397 String ret = winPattern.replaceAll("dddd", "EEEE");
398 ret = ret.replaceAll("ddd", "EEE");
399 ret = ret.replaceAll("tt", "aa");
400 ret = ret.replaceAll("g", "GG");
401 return ret;
402 }
403
404 private static Locale[] getSupportedCalendarLocales() {
405 if (supportedLocale.length != 0 &&
406 supportedLocaleSet.contains(Locale.JAPAN) &&
407 isJapaneseCalendar()) {
408 Locale[] sup = new Locale[supportedLocale.length+1];
409 sup[0] = JRELocaleConstants.JA_JP_JP;
410 System.arraycopy(supportedLocale, 0, sup, 1, supportedLocale.length);
411 return sup;
412 }
413 return supportedLocale;
414 }
415
416 private static boolean isSupportedCalendarLocale(Locale locale) {
417 Locale base = locale.stripExtensions();
418 if (!supportedLocaleSet.contains(base)) {
419 return false;
420 }
421
422 String requestedCalType = locale.getUnicodeLocaleType("ca");
423 String nativeCalType =
424 calIDToLDML[getCalendarID(locale.toLanguageTag())]
425 .replaceFirst("_.*", ""); // remove locale part.
426
427 if (requestedCalType == null) {
428 return Calendar.getAvailableCalendarTypes().contains(nativeCalType);
429 } else {
430 return requestedCalType.equals(nativeCalType);
431 }
432 }
433
434 private static Locale[] getSupportedNativeDigitLocales() {
435 if (supportedLocale.length != 0 &&
436 supportedLocaleSet.contains(JRELocaleConstants.TH_TH) &&
437 isNativeDigit("th-TH")) {
438 Locale[] sup = new Locale[supportedLocale.length+1];
439 sup[0] = JRELocaleConstants.TH_TH_TH;
440 System.arraycopy(supportedLocale, 0, sup, 1, supportedLocale.length);
441 return sup;
442 }
443 return supportedLocale;
444 }
445
446 private static boolean isSupportedNativeDigitLocale(Locale locale) {
447 // special case for th_TH_TH
448 if (JRELocaleConstants.TH_TH_TH.equals(locale)) {
449 return isNativeDigit("th-TH");
450 }
451
452 String numtype = null;
|