jdk/src/java.base/macosx/classes/sun/util/locale/provider/HostLocaleProviderAdapterImpl.java
changeset 42360 5e60b1e45041
parent 33310 2701a9854bb5
equal deleted inserted replaced
42359:e9e4835c9027 42360:5e60b1e45041
     1 /*
     1 /*
     2  * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     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
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     7  * published by the Free Software Foundation.  Oracle designates this
    45 import java.util.spi.CalendarDataProvider;
    45 import java.util.spi.CalendarDataProvider;
    46 import java.util.spi.CalendarNameProvider;
    46 import java.util.spi.CalendarNameProvider;
    47 import java.util.spi.CurrencyNameProvider;
    47 import java.util.spi.CurrencyNameProvider;
    48 import java.util.spi.LocaleNameProvider;
    48 import java.util.spi.LocaleNameProvider;
    49 import java.util.spi.TimeZoneNameProvider;
    49 import java.util.spi.TimeZoneNameProvider;
       
    50 import sun.text.spi.JavaTimeDateTimePatternProvider;
    50 import sun.util.spi.CalendarProvider;
    51 import sun.util.spi.CalendarProvider;
    51 
    52 
    52 /**
    53 /**
    53  * LocaleProviderAdapter implementation for the Mac OS X locale data
    54  * LocaleProviderAdapter implementation for the Mac OS X locale data
    54  *
    55  *
   145         }
   146         }
   146 
   147 
   147         return Locale.forLanguageTag(langTag);
   148         return Locale.forLanguageTag(langTag);
   148     }
   149     }
   149 
   150 
       
   151     public static JavaTimeDateTimePatternProvider getJavaTimeDateTimePatternProvider() {
       
   152         return new JavaTimeDateTimePatternProvider() {
       
   153             @Override
       
   154             public Locale[] getAvailableLocales() {
       
   155                 return getSupportedCalendarLocales();
       
   156             }
       
   157 
       
   158             @Override
       
   159             public boolean isSupportedLocale(Locale locale) {
       
   160                 return isSupportedCalendarLocale(locale);
       
   161             }
       
   162 
       
   163             @Override
       
   164             public String getJavaTimeDateTimePattern(int timeStyle, int dateStyle, String calType, Locale locale) {
       
   165                 return toJavaTimeDateTimePattern(calType, getDateTimePattern(dateStyle, timeStyle, locale));
       
   166 
       
   167             }
       
   168 
       
   169             private String getDateTimePattern(int dateStyle, int timeStyle, Locale locale) {
       
   170                 AtomicReferenceArray<String> dateFormatPatterns;
       
   171                 SoftReference<AtomicReferenceArray<String>> ref = dateFormatPatternsMap.get(locale);
       
   172 
       
   173                 if (ref == null || (dateFormatPatterns = ref.get()) == null) {
       
   174                     dateFormatPatterns = new AtomicReferenceArray<>(5 * 5);
       
   175                     ref = new SoftReference<>(dateFormatPatterns);
       
   176                     dateFormatPatternsMap.put(locale, ref);
       
   177                 }
       
   178                 int index = (dateStyle + 1) * 5 + timeStyle + 1;
       
   179                 String pattern = dateFormatPatterns.get(index);
       
   180                 if (pattern == null) {
       
   181                     String langTag = locale.toLanguageTag();
       
   182                     pattern = translateDateFormatLetters(getCalendarID(langTag),
       
   183                             getDateTimePatternNative(dateStyle, timeStyle, langTag));
       
   184                     if (!dateFormatPatterns.compareAndSet(index, null, pattern)) {
       
   185                         pattern = dateFormatPatterns.get(index);
       
   186                     }
       
   187                 }
       
   188                 return pattern;
       
   189             }
       
   190 
       
   191             /**
       
   192              * This method will convert JRE Date/time Pattern String to JSR310
       
   193              * type Date/Time Pattern
       
   194              */
       
   195             private String toJavaTimeDateTimePattern(String calendarType, String jrePattern) {
       
   196                 int length = jrePattern.length();
       
   197                 StringBuilder sb = new StringBuilder(length);
       
   198                 boolean inQuote = false;
       
   199                 int count = 0;
       
   200                 char lastLetter = 0;
       
   201                 for (int i = 0; i < length; i++) {
       
   202                     char c = jrePattern.charAt(i);
       
   203                     if (c == '\'') {
       
   204                         // '' is treated as a single quote regardless of being
       
   205                         // in a quoted section.
       
   206                         if ((i + 1) < length) {
       
   207                             char nextc = jrePattern.charAt(i + 1);
       
   208                             if (nextc == '\'') {
       
   209                                 i++;
       
   210                                 if (count != 0) {
       
   211                                     convert(calendarType, lastLetter, count, sb);
       
   212                                     lastLetter = 0;
       
   213                                     count = 0;
       
   214                                 }
       
   215                                 sb.append("''");
       
   216                                 continue;
       
   217                             }
       
   218                         }
       
   219                         if (!inQuote) {
       
   220                             if (count != 0) {
       
   221                                 convert(calendarType, lastLetter, count, sb);
       
   222                                 lastLetter = 0;
       
   223                                 count = 0;
       
   224                             }
       
   225                             inQuote = true;
       
   226                         } else {
       
   227                             inQuote = false;
       
   228                         }
       
   229                         sb.append(c);
       
   230                         continue;
       
   231                     }
       
   232                     if (inQuote) {
       
   233                         sb.append(c);
       
   234                         continue;
       
   235                     }
       
   236                     if (!(c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z')) {
       
   237                         if (count != 0) {
       
   238                             convert(calendarType, lastLetter, count, sb);
       
   239                             lastLetter = 0;
       
   240                             count = 0;
       
   241                         }
       
   242                         sb.append(c);
       
   243                         continue;
       
   244                     }
       
   245                     if (lastLetter == 0 || lastLetter == c) {
       
   246                         lastLetter = c;
       
   247                         count++;
       
   248                         continue;
       
   249                     }
       
   250                     convert(calendarType, lastLetter, count, sb);
       
   251                     lastLetter = c;
       
   252                     count = 1;
       
   253                 }
       
   254                 if (inQuote) {
       
   255                     // should not come here.
       
   256                     // returning null so that FALLBACK provider will kick in.
       
   257                     return null;
       
   258                 }
       
   259                 if (count != 0) {
       
   260                     convert(calendarType, lastLetter, count, sb);
       
   261                 }
       
   262                 return sb.toString();
       
   263             }
       
   264 
       
   265             private void convert(String calendarType, char letter, int count, StringBuilder sb) {
       
   266                 switch (letter) {
       
   267                     case 'G':
       
   268                         if (calendarType.equals("japanese")) {
       
   269                             if (count >= 4) {
       
   270                                 count = 1;
       
   271                             } else {
       
   272                                 count = 5;
       
   273                             }
       
   274                         } else if (!calendarType.equals("iso8601")) {
       
   275                             // Gregorian calendar is iso8601 for java.time
       
   276                             // Adjust the number of 'G's
       
   277                             if (count >= 4) {
       
   278                                 // JRE full -> JavaTime full
       
   279                                 count = 4;
       
   280                             } else {
       
   281                                 // JRE short -> JavaTime short
       
   282                                 count = 1;
       
   283                             }
       
   284                         }
       
   285                         break;
       
   286                     case 'y':
       
   287                         if (calendarType.equals("japanese") && count >= 4) {
       
   288                             // JRE specific "gan-nen" support
       
   289                             count = 1;
       
   290                         }
       
   291                         break;
       
   292                     default:
       
   293                         // JSR 310 and CLDR define 5-letter patterns for narrow text.
       
   294                         if (count > 4) {
       
   295                             count = 4;
       
   296                         }
       
   297                         break;
       
   298                 }
       
   299                 appendN(letter, count, sb);
       
   300             }
       
   301 
       
   302             private void appendN(char c, int n, StringBuilder sb) {
       
   303                 for (int i = 0; i < n; i++) {
       
   304                     sb.append(c);
       
   305                 }
       
   306             }
       
   307         };
       
   308     }
       
   309 
   150     public static DateFormatProvider getDateFormatProvider() {
   310     public static DateFormatProvider getDateFormatProvider() {
   151         return new DateFormatProvider() {
   311         return new DateFormatProvider() {
   152 
   312 
   153             @Override
   313             @Override
   154             public Locale[] getAvailableLocales() {
   314             public Locale[] getAvailableLocales() {
   161             }
   321             }
   162 
   322 
   163             @Override
   323             @Override
   164             public DateFormat getDateInstance(int style, Locale locale) {
   324             public DateFormat getDateInstance(int style, Locale locale) {
   165                 return new SimpleDateFormat(getDateTimePattern(style, -1, locale),
   325                 return new SimpleDateFormat(getDateTimePattern(style, -1, locale),
   166                                             getCalendarLocale(locale));
   326                         getCalendarLocale(locale));
   167             }
   327             }
   168 
   328 
   169             @Override
   329             @Override
   170             public DateFormat getTimeInstance(int style, Locale locale) {
   330             public DateFormat getTimeInstance(int style, Locale locale) {
   171                 return new SimpleDateFormat(getDateTimePattern(-1, style, locale),
   331                 return new SimpleDateFormat(getDateTimePattern(-1, style, locale),
   172                                             getCalendarLocale(locale));
   332                         getCalendarLocale(locale));
   173             }
   333             }
   174 
   334 
   175             @Override
   335             @Override
   176             public DateFormat getDateTimeInstance(int dateStyle,
   336             public DateFormat getDateTimeInstance(int dateStyle,
   177                     int timeStyle, Locale locale) {
   337                     int timeStyle, Locale locale) {
   178                 return new SimpleDateFormat(getDateTimePattern(dateStyle, timeStyle, locale),
   338                 return new SimpleDateFormat(getDateTimePattern(dateStyle, timeStyle, locale),
   179                                             getCalendarLocale(locale));
   339                         getCalendarLocale(locale));
   180             }
   340             }
   181 
   341 
   182             private String getDateTimePattern(int dateStyle, int timeStyle, Locale locale) {
   342             private String getDateTimePattern(int dateStyle, int timeStyle, Locale locale) {
   183                 AtomicReferenceArray<String> dateFormatPatterns;
   343                 AtomicReferenceArray<String> dateFormatPatterns;
   184                 SoftReference<AtomicReferenceArray<String>> ref = dateFormatPatternsMap.get(locale);
   344                 SoftReference<AtomicReferenceArray<String>> ref = dateFormatPatternsMap.get(locale);