src/windows/classes/sun/util/locale/provider/HostLocaleProviderAdapterImpl.java

Print this page




   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 package sun.util.locale.provider;
  26 
  27 import java.lang.ref.SoftReference;
  28 import java.text.*;





  29 import java.text.spi.DateFormatProvider;
  30 import java.text.spi.DateFormatSymbolsProvider;
  31 import java.text.spi.DecimalFormatSymbolsProvider;
  32 import java.text.spi.NumberFormatProvider;
  33 import java.util.Collections;
  34 import java.util.HashSet;
  35 import java.util.Locale;
  36 import java.util.Map;
  37 import java.util.Set;
  38 import java.util.ResourceBundle.Control;

  39 import java.util.concurrent.ConcurrentHashMap;
  40 import java.util.concurrent.ConcurrentMap;
  41 import java.util.concurrent.atomic.AtomicReferenceArray;
  42 import java.util.spi.CalendarDataProvider;

  43 
  44 /**
  45  * LocaleProviderdapter implementation for the Windows locale data.
  46  *
  47  * @author Naoto Sato
  48  */
  49 public class HostLocaleProviderAdapterImpl {
  50 
  51     // locale categories
  52     private static final int CAT_DISPLAY = 0;
  53     private static final int CAT_FORMAT  = 1;
  54 
  55     // NumberFormat styles
  56     private static final int NF_NUMBER   = 0;
  57     private static final int NF_CURRENCY = 1;
  58     private static final int NF_PERCENT  = 2;
  59     private static final int NF_INTEGER  = 3;
  60     private static final int NF_MAX = NF_INTEGER;
  61 
  62     // CalendarData value types


  71         "japanese",
  72         "roc",
  73         "",          // No appropriate type for CAL_KOREA
  74         "islamic",
  75         "buddhist",
  76         "hebrew",
  77         "gregory_fr",
  78         "gregory_ar",
  79         "gregory_en",
  80         "gregory_fr",
  81     };
  82 
  83     // Caches
  84     private static ConcurrentMap<Locale, SoftReference<AtomicReferenceArray<String>>> dateFormatCache = new ConcurrentHashMap<>();
  85     private static ConcurrentMap<Locale, SoftReference<DateFormatSymbols>> dateFormatSymbolsCache = new ConcurrentHashMap<>();
  86     private static ConcurrentMap<Locale, SoftReference<AtomicReferenceArray<String>>> numberFormatCache = new ConcurrentHashMap<>();
  87     private static ConcurrentMap<Locale, SoftReference<DecimalFormatSymbols>> decimalFormatSymbolsCache = new ConcurrentHashMap<>();
  88 
  89     private static final Set<Locale> supportedLocaleSet;
  90     static {
  91         Set<Locale> tmpSet = new HashSet<Locale>();
  92         if (initialize()) {
  93             // Assuming the default locales do not include any extensions, so
  94             // no stripping is needed here.
  95             Locale l = Locale.forLanguageTag(getDefaultLocale(CAT_FORMAT).replaceAll("_","-"));
  96             tmpSet.addAll(Control.getNoFallbackControl(Control.FORMAT_DEFAULT).getCandidateLocales("", l));
  97             l = Locale.forLanguageTag(getDefaultLocale(CAT_DISPLAY).replaceAll("_","-"));
  98             tmpSet.addAll(Control.getNoFallbackControl(Control.FORMAT_DEFAULT).getCandidateLocales("", l));
  99         }
 100         supportedLocaleSet = Collections.unmodifiableSet(tmpSet);
 101     }
 102     private final static Locale[] supportedLocale = supportedLocaleSet.toArray(new Locale[0]);
 103 
 104     public static DateFormatProvider getDateFormatProvider() {
 105         return new DateFormatProvider() {
 106             @Override
 107             public Locale[] getAvailableLocales() {
 108                 return getSupportedCalendarLocales();
 109             }
 110 
 111             @Override


 241             @Override
 242             public NumberFormat getNumberInstance(Locale locale) {
 243                 AtomicReferenceArray<String> patterns = getNumberPatterns(locale);
 244                 return new DecimalFormat(patterns.get(NF_NUMBER),
 245                     DecimalFormatSymbols.getInstance(locale));
 246             }
 247 
 248             @Override
 249             public NumberFormat getPercentInstance(Locale locale) {
 250                 AtomicReferenceArray<String> patterns = getNumberPatterns(locale);
 251                 return new DecimalFormat(patterns.get(NF_PERCENT),
 252                     DecimalFormatSymbols.getInstance(locale));
 253             }
 254 
 255             private AtomicReferenceArray<String> getNumberPatterns(Locale locale) {
 256                 AtomicReferenceArray<String> patterns;
 257                 SoftReference<AtomicReferenceArray<String>> ref = numberFormatCache.get(locale);
 258 
 259                 if (ref == null || (patterns = ref.get()) == null) {
 260                     String langtag = locale.toLanguageTag();
 261                     patterns = new AtomicReferenceArray<String>(NF_MAX+1);
 262                     for (int i = 0; i <= NF_MAX; i++) {
 263                         patterns.compareAndSet(i, null, getNumberPattern(i, langtag));
 264                     }
 265                     ref = new SoftReference<>(patterns);
 266                     numberFormatCache.put(locale, ref);
 267                 }
 268                 return patterns;
 269             }
 270         };
 271     }
 272 
 273     public static DecimalFormatSymbolsProvider getDecimalFormatSymbolsProvider() {
 274         return new DecimalFormatSymbolsProvider() {
 275 
 276             @Override
 277             public Locale[] getAvailableLocales() {
 278                 return getSupportedNativeDigitLocales();
 279             }
 280 
 281             @Override


 313                     decimalFormatSymbolsCache.put(locale, ref);
 314                 }
 315                 return (DecimalFormatSymbols)dfs.clone();
 316             }
 317         };
 318     }
 319 
 320     public static CalendarDataProvider getCalendarDataProvider() {
 321         return new CalendarDataProvider() {
 322             @Override
 323             public Locale[] getAvailableLocales() {
 324                 return getSupportedCalendarLocales();
 325             }
 326 
 327             @Override
 328             public boolean isSupportedLocale(Locale locale) {
 329                 return isSupportedCalendarLocale(locale);
 330             }
 331 
 332             @Override
 333             public String getDisplayName(String calType, int field, int value,
 334                                          int style, Locale locale) {
 335                 return null;
 336             }
 337 
 338             @Override
 339             public Map<String, Integer> getDisplayNames(String calType,
 340                                          int field, int style, Locale locale) {
 341                 return null;
 342             }
 343 
 344             @Override
 345             public int getFirstDayOfWeek(Locale locale) {
 346                 int first = getCalendarDataValue(
 347                                  removeExtensions(locale).toLanguageTag(),
 348                                  CD_FIRSTDAYOFWEEK);
 349                 if (first != -1) {
 350                     return (first + 1) % 7 + 1;
 351                 } else {
 352                     return 0;
 353                 }
 354             }
 355 
 356             @Override
 357             public int getMinimalDaysInFirstWeek(Locale locale) {
 358                 return 0;


























 359             }
 360         };
 361     }
 362 
 363     private static String convertDateTimePattern(String winPattern) {
 364         String ret = winPattern.replaceAll("dddd", "EEEE");
 365         ret = ret.replaceAll("ddd", "EEE");
 366         ret = ret.replaceAll("tt", "aa");
 367         ret = ret.replaceAll("g", "GG");
 368         return ret;
 369     }
 370 
 371     private static Locale[] getSupportedCalendarLocales() {
 372         if (supportedLocale.length != 0 &&
 373             supportedLocaleSet.contains(Locale.JAPAN) &&
 374             isJapaneseCalendar()) {
 375             Locale[] sup = new Locale[supportedLocale.length+1];
 376             sup[0] = JRELocaleConstants.JA_JP_JP;
 377             System.arraycopy(supportedLocale, 0, sup, 1, supportedLocale.length);
 378             return sup;




   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 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


  77         "japanese",
  78         "roc",
  79         "",          // No appropriate type for CAL_KOREA
  80         "islamic",
  81         "buddhist",
  82         "hebrew",
  83         "gregory_fr",
  84         "gregory_ar",
  85         "gregory_en",
  86         "gregory_fr",
  87     };
  88 
  89     // Caches
  90     private static ConcurrentMap<Locale, SoftReference<AtomicReferenceArray<String>>> dateFormatCache = new ConcurrentHashMap<>();
  91     private static ConcurrentMap<Locale, SoftReference<DateFormatSymbols>> dateFormatSymbolsCache = new ConcurrentHashMap<>();
  92     private static ConcurrentMap<Locale, SoftReference<AtomicReferenceArray<String>>> numberFormatCache = new ConcurrentHashMap<>();
  93     private static ConcurrentMap<Locale, SoftReference<DecimalFormatSymbols>> decimalFormatSymbolsCache = new ConcurrentHashMap<>();
  94 
  95     private static final Set<Locale> supportedLocaleSet;
  96     static {
  97         Set<Locale> tmpSet = new HashSet<>();
  98         if (initialize()) {
  99             // Assuming the default locales do not include any extensions, so
 100             // no stripping is needed here.
 101             Locale l = Locale.forLanguageTag(getDefaultLocale(CAT_FORMAT).replaceAll("_","-"));
 102             tmpSet.addAll(Control.getNoFallbackControl(Control.FORMAT_DEFAULT).getCandidateLocales("", l));
 103             l = Locale.forLanguageTag(getDefaultLocale(CAT_DISPLAY).replaceAll("_","-"));
 104             tmpSet.addAll(Control.getNoFallbackControl(Control.FORMAT_DEFAULT).getCandidateLocales("", l));
 105         }
 106         supportedLocaleSet = Collections.unmodifiableSet(tmpSet);
 107     }
 108     private final static Locale[] supportedLocale = supportedLocaleSet.toArray(new Locale[0]);
 109 
 110     public static DateFormatProvider getDateFormatProvider() {
 111         return new DateFormatProvider() {
 112             @Override
 113             public Locale[] getAvailableLocales() {
 114                 return getSupportedCalendarLocales();
 115             }
 116 
 117             @Override


 247             @Override
 248             public NumberFormat getNumberInstance(Locale locale) {
 249                 AtomicReferenceArray<String> patterns = getNumberPatterns(locale);
 250                 return new DecimalFormat(patterns.get(NF_NUMBER),
 251                     DecimalFormatSymbols.getInstance(locale));
 252             }
 253 
 254             @Override
 255             public NumberFormat getPercentInstance(Locale locale) {
 256                 AtomicReferenceArray<String> patterns = getNumberPatterns(locale);
 257                 return new DecimalFormat(patterns.get(NF_PERCENT),
 258                     DecimalFormatSymbols.getInstance(locale));
 259             }
 260 
 261             private AtomicReferenceArray<String> getNumberPatterns(Locale locale) {
 262                 AtomicReferenceArray<String> patterns;
 263                 SoftReference<AtomicReferenceArray<String>> ref = numberFormatCache.get(locale);
 264 
 265                 if (ref == null || (patterns = ref.get()) == null) {
 266                     String langtag = locale.toLanguageTag();
 267                     patterns = new AtomicReferenceArray<>(NF_MAX+1);
 268                     for (int i = 0; i <= NF_MAX; i++) {
 269                         patterns.compareAndSet(i, null, getNumberPattern(i, langtag));
 270                     }
 271                     ref = new SoftReference<>(patterns);
 272                     numberFormatCache.put(locale, ref);
 273                 }
 274                 return patterns;
 275             }
 276         };
 277     }
 278 
 279     public static DecimalFormatSymbolsProvider getDecimalFormatSymbolsProvider() {
 280         return new DecimalFormatSymbolsProvider() {
 281 
 282             @Override
 283             public Locale[] getAvailableLocales() {
 284                 return getSupportedNativeDigitLocales();
 285             }
 286 
 287             @Override


 319                     decimalFormatSymbolsCache.put(locale, ref);
 320                 }
 321                 return (DecimalFormatSymbols)dfs.clone();
 322             }
 323         };
 324     }
 325 
 326     public static CalendarDataProvider getCalendarDataProvider() {
 327         return new CalendarDataProvider() {
 328             @Override
 329             public Locale[] getAvailableLocales() {
 330                 return getSupportedCalendarLocales();
 331             }
 332 
 333             @Override
 334             public boolean isSupportedLocale(Locale locale) {
 335                 return isSupportedCalendarLocale(locale);
 336             }
 337 
 338             @Override












 339             public int getFirstDayOfWeek(Locale locale) {
 340                 int first = getCalendarDataValue(
 341                                  removeExtensions(locale).toLanguageTag(),
 342                                  CD_FIRSTDAYOFWEEK);
 343                 if (first != -1) {
 344                     return (first + 1) % 7 + 1;
 345                 } else {
 346                     return 0;
 347                 }
 348             }
 349 
 350             @Override
 351             public int getMinimalDaysInFirstWeek(Locale locale) {
 352                 return 0;
 353             }
 354         };
 355     }
 356 
 357     public static CalendarNameProvider getCalendarNameProvider() {
 358         return new CalendarNameProvider() {
 359             @Override
 360             public Locale[] getAvailableLocales() {
 361                 return getSupportedCalendarLocales();
 362             }
 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;