33 import java.text.SimpleDateFormat; |
33 import java.text.SimpleDateFormat; |
34 import java.text.spi.DateFormatProvider; |
34 import java.text.spi.DateFormatProvider; |
35 import java.text.spi.DateFormatSymbolsProvider; |
35 import java.text.spi.DateFormatSymbolsProvider; |
36 import java.text.spi.DecimalFormatSymbolsProvider; |
36 import java.text.spi.DecimalFormatSymbolsProvider; |
37 import java.text.spi.NumberFormatProvider; |
37 import java.text.spi.NumberFormatProvider; |
|
38 import java.util.Calendar; |
38 import java.util.Collections; |
39 import java.util.Collections; |
39 import java.util.HashSet; |
40 import java.util.HashSet; |
40 import java.util.Locale; |
41 import java.util.Locale; |
41 import java.util.Map; |
42 import java.util.Map; |
42 import java.util.ResourceBundle.Control; |
43 import java.util.ResourceBundle.Control; |
43 import java.util.Set; |
44 import java.util.Set; |
|
45 import java.util.TimeZone; |
44 import java.util.concurrent.ConcurrentHashMap; |
46 import java.util.concurrent.ConcurrentHashMap; |
45 import java.util.concurrent.ConcurrentMap; |
47 import java.util.concurrent.ConcurrentMap; |
46 import java.util.concurrent.atomic.AtomicReferenceArray; |
48 import java.util.concurrent.atomic.AtomicReferenceArray; |
47 import java.util.spi.CalendarDataProvider; |
49 import java.util.spi.CalendarDataProvider; |
48 import java.util.spi.CalendarNameProvider; |
50 import java.util.spi.CalendarNameProvider; |
|
51 import sun.util.spi.CalendarProvider; |
49 |
52 |
50 /** |
53 /** |
51 * LocaleProviderdapter implementation for the Windows locale data. |
54 * LocaleProviderdapter implementation for the Windows locale data. |
52 * |
55 * |
53 * @author Naoto Sato |
56 * @author Naoto Sato |
96 static { |
99 static { |
97 Set<Locale> tmpSet = new HashSet<>(); |
100 Set<Locale> tmpSet = new HashSet<>(); |
98 if (initialize()) { |
101 if (initialize()) { |
99 // Assuming the default locales do not include any extensions, so |
102 // Assuming the default locales do not include any extensions, so |
100 // no stripping is needed here. |
103 // no stripping is needed here. |
101 Locale l = Locale.forLanguageTag(getDefaultLocale(CAT_FORMAT).replaceAll("_","-")); |
104 Locale l = Locale.forLanguageTag(getDefaultLocale(CAT_FORMAT).replace('_', '-')); |
102 tmpSet.addAll(Control.getNoFallbackControl(Control.FORMAT_DEFAULT).getCandidateLocales("", l)); |
105 tmpSet.addAll(Control.getNoFallbackControl(Control.FORMAT_DEFAULT).getCandidateLocales("", l)); |
103 l = Locale.forLanguageTag(getDefaultLocale(CAT_DISPLAY).replaceAll("_","-")); |
106 l = Locale.forLanguageTag(getDefaultLocale(CAT_DISPLAY).replace('_', '-')); |
104 tmpSet.addAll(Control.getNoFallbackControl(Control.FORMAT_DEFAULT).getCandidateLocales("", l)); |
107 tmpSet.addAll(Control.getNoFallbackControl(Control.FORMAT_DEFAULT).getCandidateLocales("", l)); |
105 } |
108 } |
106 supportedLocaleSet = Collections.unmodifiableSet(tmpSet); |
109 supportedLocaleSet = Collections.unmodifiableSet(tmpSet); |
107 } |
110 } |
108 private final static Locale[] supportedLocale = supportedLocaleSet.toArray(new Locale[0]); |
111 private final static Locale[] supportedLocale = supportedLocaleSet.toArray(new Locale[0]); |
171 public static DateFormatSymbolsProvider getDateFormatSymbolsProvider() { |
174 public static DateFormatSymbolsProvider getDateFormatSymbolsProvider() { |
172 return new DateFormatSymbolsProvider() { |
175 return new DateFormatSymbolsProvider() { |
173 |
176 |
174 @Override |
177 @Override |
175 public Locale[] getAvailableLocales() { |
178 public Locale[] getAvailableLocales() { |
176 if (isSupportedLocale(Locale.getDefault(Locale.Category.FORMAT))) { |
179 return getSupportedCalendarLocales(); |
177 return supportedLocale; |
180 } |
178 } |
181 |
179 |
182 @Override |
180 return new Locale[0]; |
183 public boolean isSupportedLocale(Locale locale) { |
181 } |
184 return isSupportedCalendarLocale(locale); |
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 } |
185 } |
195 |
186 |
196 @Override |
187 @Override |
197 public DateFormatSymbols getInstance(Locale locale) { |
188 public DateFormatSymbols getInstance(Locale locale) { |
198 DateFormatSymbols dfs; |
189 DateFormatSymbols dfs; |
378 return null; |
369 return null; |
379 } |
370 } |
380 }; |
371 }; |
381 } |
372 } |
382 |
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 .setInstant(System.currentTimeMillis()) |
|
392 .build(); |
|
393 } |
|
394 }; |
|
395 } |
|
396 |
383 private static String convertDateTimePattern(String winPattern) { |
397 private static String convertDateTimePattern(String winPattern) { |
384 String ret = winPattern.replaceAll("dddd", "EEEE"); |
398 String ret = winPattern.replaceAll("dddd", "EEEE"); |
385 ret = ret.replaceAll("ddd", "EEE"); |
399 ret = ret.replaceAll("ddd", "EEE"); |
386 ret = ret.replaceAll("tt", "aa"); |
400 ret = ret.replaceAll("tt", "aa"); |
387 ret = ret.replaceAll("g", "GG"); |
401 ret = ret.replaceAll("g", "GG"); |
399 } |
413 } |
400 return supportedLocale; |
414 return supportedLocale; |
401 } |
415 } |
402 |
416 |
403 private static boolean isSupportedCalendarLocale(Locale locale) { |
417 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(); |
418 Locale base = locale.stripExtensions(); |
410 if (!supportedLocaleSet.contains(base)) { |
419 if (!supportedLocaleSet.contains(base)) { |
411 return false; |
420 return false; |
412 } |
421 } |
413 |
422 |
414 String caltype = locale.getUnicodeLocaleType("ca"); |
423 String requestedCalType = locale.getUnicodeLocaleType("ca"); |
415 if (caltype == null) { |
424 String nativeCalType = |
416 return true; |
425 calIDToLDML[getCalendarID(locale.toLanguageTag())] |
417 } |
426 .replaceFirst("_.*", ""); // remove locale part. |
418 |
427 |
419 return caltype.equals( |
428 if (requestedCalType == null) { |
420 calIDToLDML[getCalendarID(locale.toLanguageTag())] |
429 return Calendar.getAvailableCalendarTypes().contains(nativeCalType); |
421 .replaceFirst("_.*", "")); |
430 } else { |
|
431 return requestedCalType.equals(nativeCalType); |
|
432 } |
422 } |
433 } |
423 |
434 |
424 private static Locale[] getSupportedNativeDigitLocales() { |
435 private static Locale[] getSupportedNativeDigitLocales() { |
425 if (supportedLocale.length != 0 && |
436 if (supportedLocale.length != 0 && |
426 supportedLocaleSet.contains(JRELocaleConstants.TH_TH) && |
437 supportedLocaleSet.contains(JRELocaleConstants.TH_TH) && |