jdk/src/windows/classes/sun/util/locale/provider/HostLocaleProviderAdapterImpl.java
changeset 17169 5e5039c3181d
parent 16733 9267ec7004a1
child 17944 bbd67fc49daa
equal deleted inserted replaced
17168:b7d3500f2516 17169:5e5039c3181d
     1 /*
     1 /*
     2  * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2012, 2013, 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
    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.Calendar;
    39 import java.util.Collections;
    39 import java.util.Collections;
       
    40 import java.util.Currency;
    40 import java.util.HashSet;
    41 import java.util.HashSet;
    41 import java.util.Locale;
    42 import java.util.Locale;
    42 import java.util.Map;
    43 import java.util.Map;
    43 import java.util.ResourceBundle.Control;
    44 import java.util.ResourceBundle.Control;
    44 import java.util.Set;
    45 import java.util.Set;
    46 import java.util.concurrent.ConcurrentHashMap;
    47 import java.util.concurrent.ConcurrentHashMap;
    47 import java.util.concurrent.ConcurrentMap;
    48 import java.util.concurrent.ConcurrentMap;
    48 import java.util.concurrent.atomic.AtomicReferenceArray;
    49 import java.util.concurrent.atomic.AtomicReferenceArray;
    49 import java.util.spi.CalendarDataProvider;
    50 import java.util.spi.CalendarDataProvider;
    50 import java.util.spi.CalendarNameProvider;
    51 import java.util.spi.CalendarNameProvider;
       
    52 import java.util.spi.CurrencyNameProvider;
       
    53 import java.util.spi.LocaleNameProvider;
    51 import sun.util.spi.CalendarProvider;
    54 import sun.util.spi.CalendarProvider;
    52 
    55 
    53 /**
    56 /**
    54  * LocaleProviderdapter implementation for the Windows locale data.
    57  * LocaleProviderdapter implementation for the Windows locale data.
    55  *
    58  *
    69     private static final int NF_MAX = NF_INTEGER;
    72     private static final int NF_MAX = NF_INTEGER;
    70 
    73 
    71     // CalendarData value types
    74     // CalendarData value types
    72     private static final int CD_FIRSTDAYOFWEEK = 0;
    75     private static final int CD_FIRSTDAYOFWEEK = 0;
    73     private static final int CD_MINIMALDAYSINFIRSTWEEK = 1;
    76     private static final int CD_MINIMALDAYSINFIRSTWEEK = 1;
       
    77 
       
    78     // Currency/Locale display name types
       
    79     private static final int DN_CURRENCY_NAME   = 0;
       
    80     private static final int DN_CURRENCY_SYMBOL = 1;
       
    81     private static final int DN_LOCALE_LANGUAGE = 2;
       
    82     private static final int DN_LOCALE_SCRIPT   = 3;
       
    83     private static final int DN_LOCALE_REGION   = 4;
       
    84     private static final int DN_LOCALE_VARIANT  = 5;
    74 
    85 
    75     // Native Calendar ID to LDML calendar type map
    86     // Native Calendar ID to LDML calendar type map
    76     private static final String[] calIDToLDML = {
    87     private static final String[] calIDToLDML = {
    77         "",
    88         "",
    78         "gregory",
    89         "gregory",
    94     private static ConcurrentMap<Locale, SoftReference<DateFormatSymbols>> dateFormatSymbolsCache = new ConcurrentHashMap<>();
   105     private static ConcurrentMap<Locale, SoftReference<DateFormatSymbols>> dateFormatSymbolsCache = new ConcurrentHashMap<>();
    95     private static ConcurrentMap<Locale, SoftReference<AtomicReferenceArray<String>>> numberFormatCache = new ConcurrentHashMap<>();
   106     private static ConcurrentMap<Locale, SoftReference<AtomicReferenceArray<String>>> numberFormatCache = new ConcurrentHashMap<>();
    96     private static ConcurrentMap<Locale, SoftReference<DecimalFormatSymbols>> decimalFormatSymbolsCache = new ConcurrentHashMap<>();
   107     private static ConcurrentMap<Locale, SoftReference<DecimalFormatSymbols>> decimalFormatSymbolsCache = new ConcurrentHashMap<>();
    97 
   108 
    98     private static final Set<Locale> supportedLocaleSet;
   109     private static final Set<Locale> supportedLocaleSet;
       
   110     private static final String nativeDisplayLanguage;
    99     static {
   111     static {
   100         Set<Locale> tmpSet = new HashSet<>();
   112         Set<Locale> tmpSet = new HashSet<>();
   101         if (initialize()) {
   113         if (initialize()) {
   102             // Assuming the default locales do not include any extensions, so
   114             // Assuming the default locales do not include any extensions, so
   103             // no stripping is needed here.
   115             // no stripping is needed here.
   104             Locale l = Locale.forLanguageTag(getDefaultLocale(CAT_FORMAT).replace('_', '-'));
   116             Control c = Control.getNoFallbackControl(Control.FORMAT_DEFAULT);
   105             tmpSet.addAll(Control.getNoFallbackControl(Control.FORMAT_DEFAULT).getCandidateLocales("", l));
   117             String displayLocale = getDefaultLocale(CAT_DISPLAY);
   106             l = Locale.forLanguageTag(getDefaultLocale(CAT_DISPLAY).replace('_', '-'));
   118             Locale l = Locale.forLanguageTag(displayLocale.replace('_', '-'));
   107             tmpSet.addAll(Control.getNoFallbackControl(Control.FORMAT_DEFAULT).getCandidateLocales("", l));
   119             tmpSet.addAll(c.getCandidateLocales("", l));
       
   120             nativeDisplayLanguage = l.getLanguage();
       
   121 
       
   122             String formatLocale = getDefaultLocale(CAT_FORMAT);
       
   123             if (!formatLocale.equals(displayLocale)) {
       
   124                 l = Locale.forLanguageTag(formatLocale.replace('_', '-'));
       
   125                 tmpSet.addAll(c.getCandidateLocales("", l));
       
   126             }
       
   127         } else {
       
   128             nativeDisplayLanguage = "";
   108         }
   129         }
   109         supportedLocaleSet = Collections.unmodifiableSet(tmpSet);
   130         supportedLocaleSet = Collections.unmodifiableSet(tmpSet);
   110     }
   131     }
   111     private final static Locale[] supportedLocale = supportedLocaleSet.toArray(new Locale[0]);
   132     private final static Locale[] supportedLocale = supportedLocaleSet.toArray(new Locale[0]);
   112 
   133 
   390                              .build();
   411                              .build();
   391             }
   412             }
   392         };
   413         };
   393     }
   414     }
   394 
   415 
       
   416     public static CurrencyNameProvider getCurrencyNameProvider() {
       
   417         return new CurrencyNameProvider() {
       
   418             @Override
       
   419             public Locale[] getAvailableLocales() {
       
   420                 return supportedLocale;
       
   421             }
       
   422 
       
   423             @Override
       
   424             public boolean isSupportedLocale(Locale locale) {
       
   425                 // Ignore the extensions for now
       
   426                 return supportedLocaleSet.contains(locale.stripExtensions()) &&
       
   427                        locale.getLanguage().equals(nativeDisplayLanguage);
       
   428             }
       
   429 
       
   430             @Override
       
   431             public String getSymbol(String currencyCode, Locale locale) {
       
   432                 // Retrieves the currency symbol by calling
       
   433                 // GetLocaleInfoEx(LOCALE_SCURRENCY).
       
   434                 // It only works with the "locale"'s currency in its native
       
   435                 // language.
       
   436                 try {
       
   437                     if (Currency.getInstance(locale).getCurrencyCode()
       
   438                         .equals(currencyCode)) {
       
   439                         return getDisplayString(locale.toLanguageTag(),
       
   440                                 DN_CURRENCY_SYMBOL, currencyCode);
       
   441                     }
       
   442                 } catch (IllegalArgumentException iae) {}
       
   443                 return null;
       
   444             }
       
   445 
       
   446             @Override
       
   447             public String getDisplayName(String currencyCode, Locale locale) {
       
   448                 // Retrieves the display name by calling
       
   449                 // GetLocaleInfoEx(LOCALE_SNATIVECURRNAME).
       
   450                 // It only works with the "locale"'s currency in its native
       
   451                 // language.
       
   452                 try {
       
   453                     if (Currency.getInstance(locale).getCurrencyCode()
       
   454                         .equals(currencyCode)) {
       
   455                         return getDisplayString(locale.toLanguageTag(),
       
   456                                 DN_CURRENCY_NAME, currencyCode);
       
   457                     }
       
   458                 } catch (IllegalArgumentException iae) {}
       
   459                 return null;
       
   460             }
       
   461         };
       
   462     }
       
   463 
       
   464     public static LocaleNameProvider getLocaleNameProvider() {
       
   465         return new LocaleNameProvider() {
       
   466             @Override
       
   467             public Locale[] getAvailableLocales() {
       
   468                 return supportedLocale;
       
   469             }
       
   470 
       
   471             @Override
       
   472             public boolean isSupportedLocale(Locale locale) {
       
   473                 return supportedLocaleSet.contains(locale.stripExtensions()) &&
       
   474                        locale.getLanguage().equals(nativeDisplayLanguage);
       
   475             }
       
   476 
       
   477             @Override
       
   478             public String getDisplayLanguage(String languageCode, Locale locale) {
       
   479                 // Retrieves the display language name by calling
       
   480                 // GetLocaleInfoEx(LOCALE_SLOCALIZEDLANGUAGENAME).
       
   481                 return getDisplayString(locale.toLanguageTag(),
       
   482                             DN_LOCALE_LANGUAGE, languageCode);
       
   483             }
       
   484 
       
   485             @Override
       
   486             public String getDisplayCountry(String countryCode, Locale locale) {
       
   487                 // Retrieves the display country name by calling
       
   488                 // GetLocaleInfoEx(LOCALE_SLOCALIZEDCOUNTRYNAME).
       
   489                 return getDisplayString(locale.toLanguageTag(),
       
   490                             DN_LOCALE_REGION, nativeDisplayLanguage+"-"+countryCode);
       
   491             }
       
   492 
       
   493             @Override
       
   494             public String getDisplayScript(String scriptCode, Locale locale) {
       
   495                 return null;
       
   496             }
       
   497 
       
   498             @Override
       
   499             public String getDisplayVariant(String variantCode, Locale locale) {
       
   500                 return null;
       
   501             }
       
   502         };
       
   503     }
       
   504 
       
   505 
   395     private static String convertDateTimePattern(String winPattern) {
   506     private static String convertDateTimePattern(String winPattern) {
   396         String ret = winPattern.replaceAll("dddd", "EEEE");
   507         String ret = winPattern.replaceAll("dddd", "EEEE");
   397         ret = ret.replaceAll("ddd", "EEE");
   508         ret = ret.replaceAll("ddd", "EEE");
   398         ret = ret.replaceAll("tt", "aa");
   509         ret = ret.replaceAll("tt", "aa");
   399         ret = ret.replaceAll("g", "GG");
   510         ret = ret.replaceAll("g", "GG");
   411         }
   522         }
   412         return supportedLocale;
   523         return supportedLocale;
   413     }
   524     }
   414 
   525 
   415     private static boolean isSupportedCalendarLocale(Locale locale) {
   526     private static boolean isSupportedCalendarLocale(Locale locale) {
   416         Locale base = locale.stripExtensions();
   527         Locale base = locale;
       
   528 
       
   529         if (base.hasExtensions() || base.getVariant() != "") {
       
   530             // strip off extensions and variant.
       
   531             base = new Locale.Builder()
       
   532                             .setLocale(locale)
       
   533                             .clearExtensions()
       
   534                             .build();
       
   535         }
       
   536 
   417         if (!supportedLocaleSet.contains(base)) {
   537         if (!supportedLocaleSet.contains(base)) {
   418             return false;
   538             return false;
   419         }
   539         }
   420 
   540 
   421         int calid = getCalendarID(locale.toLanguageTag());
   541         int calid = getCalendarID(base.toLanguageTag());
   422         if (calid <= 0 || calid >= calIDToLDML.length) {
   542         if (calid <= 0 || calid >= calIDToLDML.length) {
   423             return false;
   543             return false;
   424         }
   544         }
   425 
   545 
   426         String requestedCalType = locale.getUnicodeLocaleType("ca");
   546         String requestedCalType = locale.getUnicodeLocaleType("ca");
   544     private static native char getPerMill(String langTag, char perMill);
   664     private static native char getPerMill(String langTag, char perMill);
   545     private static native char getZeroDigit(String langTag, char zeroDigit);
   665     private static native char getZeroDigit(String langTag, char zeroDigit);
   546 
   666 
   547     // For CalendarDataProvider
   667     // For CalendarDataProvider
   548     private static native int getCalendarDataValue(String langTag, int type);
   668     private static native int getCalendarDataValue(String langTag, int type);
       
   669 
       
   670     // For Locale/CurrencyNameProvider
       
   671     private static native String getDisplayString(String langTag, int key, String value);
   549 }
   672 }