< prev index next >

src/java.base/share/classes/sun/util/cldr/CLDRLocaleProviderAdapter.java

Print this page




  28 import java.security.AccessController;
  29 import java.security.AccessControlException;
  30 import java.security.PrivilegedAction;
  31 import java.security.PrivilegedActionException;
  32 import java.security.PrivilegedExceptionAction;
  33 import java.text.spi.BreakIteratorProvider;
  34 import java.text.spi.CollatorProvider;
  35 import java.util.Arrays;
  36 import java.util.Collections;
  37 import java.util.HashSet;
  38 import java.util.List;
  39 import java.util.Locale;
  40 import java.util.Map;
  41 import java.util.Optional;
  42 import java.util.ServiceLoader;
  43 import java.util.ServiceConfigurationError;
  44 import java.util.Set;
  45 import java.util.StringTokenizer;
  46 import java.util.concurrent.ConcurrentHashMap;
  47 import java.util.spi.CalendarDataProvider;

  48 import java.util.spi.TimeZoneNameProvider;
  49 import sun.util.locale.provider.JRELocaleProviderAdapter;
  50 import sun.util.locale.provider.LocaleDataMetaInfo;
  51 import sun.util.locale.provider.LocaleProviderAdapter;
  52 
  53 /**
  54  * LocaleProviderAdapter implementation for the CLDR locale data.
  55  *
  56  * @author Masayoshi Okutsu
  57  * @author Naoto Sato
  58  */
  59 public class CLDRLocaleProviderAdapter extends JRELocaleProviderAdapter {
  60 
  61     private static final CLDRBaseLocaleDataMetaInfo baseMetaInfo = new CLDRBaseLocaleDataMetaInfo();
  62     // Assumption: CLDR has only one non-Base module.
  63     private final LocaleDataMetaInfo nonBaseMetaInfo;
  64 
  65     // parent locales map
  66     private static volatile Map<Locale, Locale> parentLocalesMap;
  67     // language aliases map


 116 
 117     @Override
 118     public CalendarDataProvider getCalendarDataProvider() {
 119         if (calendarDataProvider == null) {
 120             CalendarDataProvider provider = AccessController.doPrivileged(
 121                 (PrivilegedAction<CalendarDataProvider>) () ->
 122                     new CLDRCalendarDataProviderImpl(
 123                         getAdapterType(),
 124                         getLanguageTagSet("CalendarData")));
 125 
 126             synchronized (this) {
 127                 if (calendarDataProvider == null) {
 128                     calendarDataProvider = provider;
 129                 }
 130             }
 131         }
 132         return calendarDataProvider;
 133     }
 134 
 135     @Override


















 136     public CollatorProvider getCollatorProvider() {
 137         return null;
 138     }
 139 
 140     @Override
 141     public TimeZoneNameProvider getTimeZoneNameProvider() {
 142         if (timeZoneNameProvider == null) {
 143             TimeZoneNameProvider provider = AccessController.doPrivileged(
 144                 (PrivilegedAction<TimeZoneNameProvider>) () ->
 145                     new CLDRTimeZoneNameProviderImpl(
 146                         getAdapterType(),
 147                         getLanguageTagSet("TimeZoneNames")));
 148 
 149             synchronized (this) {
 150                 if (timeZoneNameProvider == null) {
 151                     timeZoneNameProvider = provider;
 152                 }
 153             }
 154         }
 155         return timeZoneNameProvider;
 156     }
 157 
 158     @Override
 159     public Locale[] getAvailableLocales() {
 160         Set<String> all = createLanguageTagSet("AvailableLocales");
 161         Locale[] locs = new Locale[all.size()];
 162         int index = 0;
 163         for (String tag : all) {
 164             locs[index++] = Locale.forLanguageTag(tag);
 165         }
 166         return locs;
 167     }
 168 
 169     private Locale applyAliases(Locale loc) {
 170         if (langAliasesMap.isEmpty()) {
 171             langAliasesMap = baseMetaInfo.getLanguageAliasMap();
 172         }
 173         Locale locale = langAliasesCache.get(loc);
 174         if (locale == null) {
 175             String locTag = loc.toLanguageTag();
 176             Locale aliasLocale = langAliasesMap.containsKey(locTag)
 177                     ? Locale.forLanguageTag(langAliasesMap.get(locTag)) : loc;
 178             langAliasesCache.putIfAbsent(loc, aliasLocale);
 179             return aliasLocale;
 180         } else {
 181             return locale;
 182         }
 183     }
 184 
 185     @Override
 186     protected Set<String> createLanguageTagSet(String category) {
 187         // Assume all categories support the same set as AvailableLocales
 188         // in CLDR adapter.
 189         category = "AvailableLocales";


 247                 if (Arrays.binarySearch(entry.getValue(), tag) >= 0) {
 248                     parent = entry.getKey();
 249                     break;
 250                 }
 251             }
 252             if (parent == null) {
 253                 parent = locale; // non existent marker
 254             }
 255             parentLocalesMap.putIfAbsent(locale, parent);
 256         }
 257 
 258         if (locale.equals(parent)) {
 259             // means no irregular parent.
 260             parent = null;
 261         }
 262 
 263         return parent;
 264     }
 265 
 266     /**
 267      * This method returns equivalent CLDR supported locale for zh-HK,
 268      * no, no-NO locales so that COMPAT locales do not precede
 269      * those locales during ResourceBundle search path.

 270      */
 271     private static Locale getEquivalentLoc(Locale locale) {
 272         switch (locale.toString()) {
 273             case "zh_HK":
 274                 return Locale.forLanguageTag("zh-Hant-HK");
 275             case "no":
 276             case "no_NO":
 277                 return Locale.forLanguageTag("nb");
 278         }
 279         return locale;
 280     }
 281 
 282     @Override
 283     public boolean isSupportedProviderLocale(Locale locale, Set<String> langtags) {
 284         return Locale.ROOT.equals(locale)
 285                 || langtags.contains(locale.stripExtensions().toLanguageTag())
 286                 || langtags.contains(getEquivalentLoc(locale).toLanguageTag());
 287     }
 288 
 289     /**
 290      * Returns the canonical ID for the given ID
 291      */
 292     public Optional<String> canonicalTZID(String id) {
 293         return Optional.ofNullable(baseMetaInfo.tzCanonicalIDs().get(id));
 294     }
 295 }


  28 import java.security.AccessController;
  29 import java.security.AccessControlException;
  30 import java.security.PrivilegedAction;
  31 import java.security.PrivilegedActionException;
  32 import java.security.PrivilegedExceptionAction;
  33 import java.text.spi.BreakIteratorProvider;
  34 import java.text.spi.CollatorProvider;
  35 import java.util.Arrays;
  36 import java.util.Collections;
  37 import java.util.HashSet;
  38 import java.util.List;
  39 import java.util.Locale;
  40 import java.util.Map;
  41 import java.util.Optional;
  42 import java.util.ServiceLoader;
  43 import java.util.ServiceConfigurationError;
  44 import java.util.Set;
  45 import java.util.StringTokenizer;
  46 import java.util.concurrent.ConcurrentHashMap;
  47 import java.util.spi.CalendarDataProvider;
  48 import java.util.spi.CalendarNameProvider;
  49 import java.util.spi.TimeZoneNameProvider;
  50 import sun.util.locale.provider.JRELocaleProviderAdapter;
  51 import sun.util.locale.provider.LocaleDataMetaInfo;
  52 import sun.util.locale.provider.LocaleProviderAdapter;
  53 
  54 /**
  55  * LocaleProviderAdapter implementation for the CLDR locale data.
  56  *
  57  * @author Masayoshi Okutsu
  58  * @author Naoto Sato
  59  */
  60 public class CLDRLocaleProviderAdapter extends JRELocaleProviderAdapter {
  61 
  62     private static final CLDRBaseLocaleDataMetaInfo baseMetaInfo = new CLDRBaseLocaleDataMetaInfo();
  63     // Assumption: CLDR has only one non-Base module.
  64     private final LocaleDataMetaInfo nonBaseMetaInfo;
  65 
  66     // parent locales map
  67     private static volatile Map<Locale, Locale> parentLocalesMap;
  68     // language aliases map


 117 
 118     @Override
 119     public CalendarDataProvider getCalendarDataProvider() {
 120         if (calendarDataProvider == null) {
 121             CalendarDataProvider provider = AccessController.doPrivileged(
 122                 (PrivilegedAction<CalendarDataProvider>) () ->
 123                     new CLDRCalendarDataProviderImpl(
 124                         getAdapterType(),
 125                         getLanguageTagSet("CalendarData")));
 126 
 127             synchronized (this) {
 128                 if (calendarDataProvider == null) {
 129                     calendarDataProvider = provider;
 130                 }
 131             }
 132         }
 133         return calendarDataProvider;
 134     }
 135     
 136     @Override
 137     public CalendarNameProvider getCalendarNameProvider() {
 138         if (calendarNameProvider == null) {
 139             CalendarNameProvider provider = AccessController.doPrivileged(
 140                     (PrivilegedAction<CalendarNameProvider>) ()
 141                     -> new CLDRCalendarNameProviderImpl(
 142                             getAdapterType(),
 143                             getLanguageTagSet("FormatData")));
 144 
 145             synchronized (this) {
 146                 if (calendarNameProvider == null) {
 147                     calendarNameProvider = provider;
 148                 }
 149             }
 150         }
 151         return calendarNameProvider;
 152     }
 153 
 154     @Override
 155     public CollatorProvider getCollatorProvider() {
 156         return null;
 157     }
 158 
 159     @Override
 160     public TimeZoneNameProvider getTimeZoneNameProvider() {
 161         if (timeZoneNameProvider == null) {
 162             TimeZoneNameProvider provider = AccessController.doPrivileged(
 163                 (PrivilegedAction<TimeZoneNameProvider>) () ->
 164                     new CLDRTimeZoneNameProviderImpl(
 165                         getAdapterType(),
 166                         getLanguageTagSet("TimeZoneNames")));
 167 
 168             synchronized (this) {
 169                 if (timeZoneNameProvider == null) {
 170                     timeZoneNameProvider = provider;
 171                 }
 172             }
 173         }
 174         return timeZoneNameProvider;
 175     }
 176 
 177     @Override
 178     public Locale[] getAvailableLocales() {
 179         Set<String> all = createLanguageTagSet("AvailableLocales");
 180         Locale[] locs = new Locale[all.size()];
 181         int index = 0;
 182         for (String tag : all) {
 183             locs[index++] = Locale.forLanguageTag(tag);
 184         }
 185         return locs;
 186     }
 187 
 188     private static Locale applyAliases(Locale loc) {
 189         if (langAliasesMap.isEmpty()) {
 190             langAliasesMap = baseMetaInfo.getLanguageAliasMap();
 191         }
 192         Locale locale = langAliasesCache.get(loc);
 193         if (locale == null) {
 194             String locTag = loc.toLanguageTag();
 195             Locale aliasLocale = langAliasesMap.containsKey(locTag)
 196                     ? Locale.forLanguageTag(langAliasesMap.get(locTag)) : loc;
 197             langAliasesCache.putIfAbsent(loc, aliasLocale);
 198             return aliasLocale;
 199         } else {
 200             return locale;
 201         }
 202     }
 203 
 204     @Override
 205     protected Set<String> createLanguageTagSet(String category) {
 206         // Assume all categories support the same set as AvailableLocales
 207         // in CLDR adapter.
 208         category = "AvailableLocales";


 266                 if (Arrays.binarySearch(entry.getValue(), tag) >= 0) {
 267                     parent = entry.getKey();
 268                     break;
 269                 }
 270             }
 271             if (parent == null) {
 272                 parent = locale; // non existent marker
 273             }
 274             parentLocalesMap.putIfAbsent(locale, parent);
 275         }
 276 
 277         if (locale.equals(parent)) {
 278             // means no irregular parent.
 279             parent = null;
 280         }
 281 
 282         return parent;
 283     }
 284 
 285     /**
 286      * This method returns equivalent CLDR supported locale
 287      * for no, no-NO locales so that COMPAT locales do not precede
 288      * those locales during ResourceBundle search path, also if an alias exists for a locale,
 289      * it returns equivalent locale, e.g for zh_HK it returns zh_Hant-HK.
 290      */
 291     private static Locale getEquivalentLoc(Locale locale) {
 292         switch (locale.toString()) {


 293             case "no":
 294             case "no_NO":
 295                 return Locale.forLanguageTag("nb");
 296         }        
 297         return applyAliases(locale);
 298     }
 299 
 300     @Override
 301     public boolean isSupportedProviderLocale(Locale locale, Set<String> langtags) {
 302         return Locale.ROOT.equals(locale)
 303                 || langtags.contains(locale.stripExtensions().toLanguageTag())
 304                 || langtags.contains(getEquivalentLoc(locale).toLanguageTag());
 305     }
 306 
 307     /**
 308      * Returns the canonical ID for the given ID
 309      */
 310     public Optional<String> canonicalTZID(String id) {
 311         return Optional.ofNullable(baseMetaInfo.tzCanonicalIDs().get(id));
 312     }
 313 }
< prev index next >