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.Currency;
41 import java.util.HashMap;
42 import java.util.HashSet;
43 import java.util.Locale;
44 import java.util.Map;
45 import java.util.ResourceBundle.Control;
46 import java.util.Set;
47 import java.util.TimeZone;
48 import java.util.concurrent.ConcurrentHashMap;
49 import java.util.concurrent.ConcurrentMap;
50 import java.util.concurrent.atomic.AtomicReferenceArray;
51 import java.util.spi.CalendarDataProvider;
52 import java.util.spi.CalendarNameProvider;
53 import java.util.spi.CurrencyNameProvider;
54 import java.util.spi.LocaleNameProvider;
55 import sun.util.spi.CalendarProvider;
56
57 /**
58 * LocaleProviderdapter implementation for the Windows locale data.
59 *
60 * @author Naoto Sato
61 */
62 public class HostLocaleProviderAdapterImpl {
63
64 // locale categories
65 private static final int CAT_DISPLAY = 0;
66 private static final int CAT_FORMAT = 1;
67
68 // NumberFormat styles
69 private static final int NF_NUMBER = 0;
70 private static final int NF_CURRENCY = 1;
71 private static final int NF_PERCENT = 2;
72 private static final int NF_INTEGER = 3;
73 private static final int NF_MAX = NF_INTEGER;
74
508 @Override
509 public String getDisplayCountry(String countryCode, Locale locale) {
510 // Retrieves the display country name by calling
511 // GetLocaleInfoEx(LOCALE_SLOCALIZEDCOUNTRYNAME).
512 return getDisplayString(locale.toLanguageTag(),
513 DN_LOCALE_REGION, nativeDisplayLanguage+"-"+countryCode);
514 }
515
516 @Override
517 public String getDisplayScript(String scriptCode, Locale locale) {
518 return null;
519 }
520
521 @Override
522 public String getDisplayVariant(String variantCode, Locale locale) {
523 return null;
524 }
525 };
526 }
527
528
529 private static String convertDateTimePattern(String winPattern) {
530 String ret = winPattern.replaceAll("dddd", "EEEE");
531 ret = ret.replaceAll("ddd", "EEE");
532 ret = ret.replaceAll("tt", "aa");
533 ret = ret.replaceAll("g", "GG");
534 return ret;
535 }
536
537 private static Locale[] getSupportedCalendarLocales() {
538 if (supportedLocale.length != 0 &&
539 supportedLocaleSet.contains(Locale.JAPAN) &&
540 isJapaneseCalendar()) {
541 Locale[] sup = new Locale[supportedLocale.length+1];
542 sup[0] = JRELocaleConstants.JA_JP_JP;
543 System.arraycopy(supportedLocale, 0, sup, 1, supportedLocale.length);
544 return sup;
545 }
546 return supportedLocale;
547 }
|
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.Currency;
41 import java.util.HashMap;
42 import java.util.HashSet;
43 import java.util.Locale;
44 import java.util.Map;
45 import java.util.ResourceBundle.Control;
46 import java.util.Set;
47 import java.util.TimeZone;
48 import java.util.concurrent.ConcurrentHashMap;
49 import java.util.concurrent.ConcurrentMap;
50 import java.util.concurrent.atomic.AtomicReferenceArray;
51 import java.util.spi.CalendarDataProvider;
52 import java.util.spi.CalendarNameProvider;
53 import java.util.spi.CurrencyNameProvider;
54 import java.util.spi.LocaleNameProvider;
55 import sun.text.spi.JavaTimeDateTimePatternProvider;
56 import sun.util.spi.CalendarProvider;
57
58 /**
59 * LocaleProviderdapter implementation for the Windows locale data.
60 *
61 * @author Naoto Sato
62 */
63 public class HostLocaleProviderAdapterImpl {
64
65 // locale categories
66 private static final int CAT_DISPLAY = 0;
67 private static final int CAT_FORMAT = 1;
68
69 // NumberFormat styles
70 private static final int NF_NUMBER = 0;
71 private static final int NF_CURRENCY = 1;
72 private static final int NF_PERCENT = 2;
73 private static final int NF_INTEGER = 3;
74 private static final int NF_MAX = NF_INTEGER;
75
509 @Override
510 public String getDisplayCountry(String countryCode, Locale locale) {
511 // Retrieves the display country name by calling
512 // GetLocaleInfoEx(LOCALE_SLOCALIZEDCOUNTRYNAME).
513 return getDisplayString(locale.toLanguageTag(),
514 DN_LOCALE_REGION, nativeDisplayLanguage+"-"+countryCode);
515 }
516
517 @Override
518 public String getDisplayScript(String scriptCode, Locale locale) {
519 return null;
520 }
521
522 @Override
523 public String getDisplayVariant(String variantCode, Locale locale) {
524 return null;
525 }
526 };
527 }
528
529 public static JavaTimeDateTimePatternProvider getJavaTimeDateTimePatternProvider() {
530 return new JavaTimeDateTimePatternProvider() {
531 @Override
532 public Locale[] getAvailableLocales() {
533 return getSupportedCalendarLocales();
534 }
535
536 @Override
537 public boolean isSupportedLocale(Locale locale) {
538 return isSupportedCalendarLocale(locale);
539 }
540
541 @Override
542 public String getJavaTimeDateTimePattern(int timeStyle, int dateStyle, String calType, Locale locale) {
543 AtomicReferenceArray<String> patterns = getDateTimePatterns(locale);
544 String pattern = new StringBuilder(patterns.get(dateStyle / 2))
545 .append(" ")
546 .append(patterns.get(timeStyle / 2 + 2))
547 .toString();
548 return toJavaTimeDateTimePattern(calType, pattern);
549
550 }
551
552 private AtomicReferenceArray<String> getDateTimePatterns(Locale locale) {
553 AtomicReferenceArray<String> patterns;
554 SoftReference<AtomicReferenceArray<String>> ref = dateFormatCache.get(locale);
555
556 if (ref == null || (patterns = ref.get()) == null) {
557 String langtag = removeExtensions(locale).toLanguageTag();
558 patterns = new AtomicReferenceArray<>(4);
559 patterns.compareAndSet(0, null, convertDateTimePattern(
560 getDateTimePattern(DateFormat.LONG, -1, langtag)));
561 patterns.compareAndSet(1, null, convertDateTimePattern(
562 getDateTimePattern(DateFormat.SHORT, -1, langtag)));
563 patterns.compareAndSet(2, null, convertDateTimePattern(
564 getDateTimePattern(-1, DateFormat.LONG, langtag)));
565 patterns.compareAndSet(3, null, convertDateTimePattern(
566 getDateTimePattern(-1, DateFormat.SHORT, langtag)));
567 ref = new SoftReference<>(patterns);
568 dateFormatCache.put(locale, ref);
569 }
570 return patterns;
571 }
572 /**
573 * This method will convert JRE Date/time Pattern String to JSR310
574 * type Date/Time Pattern
575 */
576 private String toJavaTimeDateTimePattern(String calendarType, String jrePattern) {
577 int length = jrePattern.length();
578 StringBuilder sb = new StringBuilder(length);
579 boolean inQuote = false;
580 int count = 0;
581 char lastLetter = 0;
582 for (int i = 0; i < length; i++) {
583 char c = jrePattern.charAt(i);
584 if (c == '\'') {
585 // '' is treated as a single quote regardless of being
586 // in a quoted section.
587 if ((i + 1) < length) {
588 char nextc = jrePattern.charAt(i + 1);
589 if (nextc == '\'') {
590 i++;
591 if (count != 0) {
592 convert(calendarType, lastLetter, count, sb);
593 lastLetter = 0;
594 count = 0;
595 }
596 sb.append("''");
597 continue;
598 }
599 }
600 if (!inQuote) {
601 if (count != 0) {
602 convert(calendarType, lastLetter, count, sb);
603 lastLetter = 0;
604 count = 0;
605 }
606 inQuote = true;
607 } else {
608 inQuote = false;
609 }
610 sb.append(c);
611 continue;
612 }
613 if (inQuote) {
614 sb.append(c);
615 continue;
616 }
617 if (!(c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z')) {
618 if (count != 0) {
619 convert(calendarType, lastLetter, count, sb);
620 lastLetter = 0;
621 count = 0;
622 }
623 sb.append(c);
624 continue;
625 }
626 if (lastLetter == 0 || lastLetter == c) {
627 lastLetter = c;
628 count++;
629 continue;
630 }
631 convert(calendarType, lastLetter, count, sb);
632 lastLetter = c;
633 count = 1;
634 }
635 if (inQuote) {
636 // should not come here.
637 // returning null so that FALLBACK provider will kick in.
638 return null;
639 }
640 if (count != 0) {
641 convert(calendarType, lastLetter, count, sb);
642 }
643 return sb.toString();
644 }
645
646 private void convert(String calendarType, char letter, int count, StringBuilder sb) {
647 switch (letter) {
648 case 'G':
649 if (calendarType.equals("japanese")) {
650 if (count >= 4) {
651 count = 1;
652 } else {
653 count = 5;
654 }
655 } else if (!calendarType.equals("iso8601")) {
656 // Adjust the number of 'G's
657 // Gregorian calendar is iso8601 for java.time
658 if (count >= 4) {
659 // JRE full -> JavaTime full
660 count = 4;
661 } else {
662 // JRE short -> JavaTime short
663 count = 1;
664 }
665 }
666 break;
667 case 'y':
668 if (calendarType.equals("japanese") && count >= 4) {
669 // JRE specific "gan-nen" support
670 count = 1;
671 }
672 break;
673 default:
674 // JSR 310 and CLDR define 5-letter patterns for narrow text.
675 if (count > 4) {
676 count = 4;
677 }
678 break;
679 }
680 appendN(letter, count, sb);
681 }
682
683 private void appendN(char c, int n, StringBuilder sb) {
684 for (int i = 0; i < n; i++) {
685 sb.append(c);
686 }
687 }
688 };
689 }
690
691 private static String convertDateTimePattern(String winPattern) {
692 String ret = winPattern.replaceAll("dddd", "EEEE");
693 ret = ret.replaceAll("ddd", "EEE");
694 ret = ret.replaceAll("tt", "aa");
695 ret = ret.replaceAll("g", "GG");
696 return ret;
697 }
698
699 private static Locale[] getSupportedCalendarLocales() {
700 if (supportedLocale.length != 0 &&
701 supportedLocaleSet.contains(Locale.JAPAN) &&
702 isJapaneseCalendar()) {
703 Locale[] sup = new Locale[supportedLocale.length+1];
704 sup[0] = JRELocaleConstants.JA_JP_JP;
705 System.arraycopy(supportedLocale, 0, sup, 1, supportedLocale.length);
706 return sup;
707 }
708 return supportedLocale;
709 }
|