Print this page
rev 5615 : 6336885: RFE: Locale Data Deployment Enhancements
4609153: Provide locale data for Indic locales
5104387: Support for gl_ES locale (galician language)
6337471: desktop/system locale preferences support
7056139: (cal) SPI support for locale-dependent Calendar parameters
7058206: Provide CalendarData SPI for week params and display field value names
7073852: Support multiple scripts for digits and decimal symbols per locale
7079560: [Fmt-Da] Context dependent month names support in SimpleDateFormat
7171324: getAvailableLocales() of locale sensitive services should return the actual availability of locales
7151414: (cal) Support calendar type identification
7168528: LocaleServiceProvider needs to be aware of Locale extensions
7171372: (cal) locale's default Calendar should be created if unknown calendar is specified
Summary: JEP 127: Improve Locale Data Packaging and Adopt Unicode CLDR Data (part 1 w/o Jigsaw. by Naoto Sato and Masayoshi Okutsu)

Split Close
Expand all
Collapse all
          --- old/src/share/classes/sun/util/resources/LocaleData.java
          +++ new/src/share/classes/sun/util/resources/LocaleData.java
   1    1  /*
   2      - * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
        2 + * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
   3    3   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4    4   *
   5    5   * This code is free software; you can redistribute it and/or modify it
   6    6   * under the terms of the GNU General Public License version 2 only, as
   7    7   * published by the Free Software Foundation.  Oracle designates this
   8    8   * particular file as subject to the "Classpath" exception as provided
   9    9   * by Oracle in the LICENSE file that accompanied this code.
  10   10   *
  11   11   * This code is distributed in the hope that it will be useful, but WITHOUT
  12   12   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
↓ open down ↓ 20 lines elided ↑ open up ↑
  33   33   * of a License Agreement between Taligent and Sun. This technology
  34   34   * is protected by multiple US and International patents.
  35   35   *
  36   36   * This notice and attribution to Taligent may not be removed.
  37   37   * Taligent is a registered trademark of Taligent, Inc.
  38   38   *
  39   39   */
  40   40  
  41   41  package sun.util.resources;
  42   42  
  43      -import java.io.File;
  44   43  import java.security.AccessController;
  45   44  import java.security.PrivilegedAction;
  46   45  import java.util.Iterator;
  47   46  import java.util.List;
  48   47  import java.util.Locale;
  49   48  import java.util.ResourceBundle;
  50      -import java.util.StringTokenizer;
       49 +import sun.util.locale.provider.LocaleProviderAdapter;
       50 +import static sun.util.locale.provider.LocaleProviderAdapter.Type.JRE;
       51 +import sun.util.locale.provider.LocaleDataMetaInfo;
  51   52  
  52      -import sun.util.LocaleDataMetaInfo;
  53      -
  54   53  /**
  55   54   * Provides information about and access to resource bundles in the
  56      - * sun.text.resources and sun.util.resources package.
       55 + * sun.text.resources and sun.util.resources packages or in their corresponding
       56 + * packages for CLDR.
  57   57   *
  58   58   * @author Asmus Freytag
  59   59   * @author Mark Davis
  60   60   */
  61   61  
  62   62  public class LocaleData {
       63 +    private final LocaleProviderAdapter.Type type;
  63   64  
  64      -    private static final String localeDataJarName = "localedata.jar";
  65      -
  66      -    /**
  67      -     * Lazy load available locales.
  68      -     */
  69      -    private static class AvailableLocales {
  70      -         static final Locale[] localeList = createLocaleList();
       65 +    public LocaleData(LocaleProviderAdapter.Type type) {
       66 +        this.type = type;
  71   67      }
  72   68  
  73   69      /**
  74      -     * Returns a list of the installed locales. Currently, this simply returns
  75      -     * the list of locales for which a sun.text.resources.FormatData bundle
  76      -     * exists. This bundle family happens to be the one with the broadest
  77      -     * locale coverage in the JRE.
  78      -     */
  79      -    public static Locale[] getAvailableLocales() {
  80      -        return AvailableLocales.localeList.clone();
  81      -    }
  82      -
  83      -    /**
  84   70       * Gets a calendar data resource bundle, using privileges
  85   71       * to allow accessing a sun.* package.
  86   72       */
  87      -    public static ResourceBundle getCalendarData(Locale locale) {
  88      -        return getBundle("sun.util.resources.CalendarData", locale);
       73 +    public ResourceBundle getCalendarData(Locale locale) {
       74 +        return getBundle(type.getUtilResourcesPackage() + ".CalendarData", locale);
  89   75      }
  90   76  
  91   77      /**
  92   78       * Gets a currency names resource bundle, using privileges
  93   79       * to allow accessing a sun.* package.
  94   80       */
  95      -    public static OpenListResourceBundle getCurrencyNames(Locale locale) {
  96      -        return (OpenListResourceBundle)getBundle("sun.util.resources.CurrencyNames", locale);
       81 +    public OpenListResourceBundle getCurrencyNames(Locale locale) {
       82 +        return (OpenListResourceBundle) getBundle(type.getUtilResourcesPackage() + ".CurrencyNames", locale);
  97   83      }
  98   84  
  99   85      /**
 100   86       * Gets a locale names resource bundle, using privileges
 101   87       * to allow accessing a sun.* package.
 102   88       */
 103      -    public static OpenListResourceBundle getLocaleNames(Locale locale) {
 104      -        return (OpenListResourceBundle)getBundle("sun.util.resources.LocaleNames", locale);
       89 +    public OpenListResourceBundle getLocaleNames(Locale locale) {
       90 +        return (OpenListResourceBundle) getBundle(type.getUtilResourcesPackage() + ".LocaleNames", locale);
 105   91      }
 106   92  
 107   93      /**
 108   94       * Gets a time zone names resource bundle, using privileges
 109   95       * to allow accessing a sun.* package.
 110   96       */
 111      -    public static OpenListResourceBundle getTimeZoneNames(Locale locale) {
 112      -        return (OpenListResourceBundle)getBundle("sun.util.resources.TimeZoneNames", locale);
       97 +    public OpenListResourceBundle getTimeZoneNames(Locale locale) {
       98 +        return (OpenListResourceBundle) getBundle(type.getUtilResourcesPackage() + ".TimeZoneNames", locale);
 113   99      }
 114  100  
 115  101      /**
 116  102       * Gets a collation data resource bundle, using privileges
 117  103       * to allow accessing a sun.* package.
 118  104       */
 119      -    public static ResourceBundle getCollationData(Locale locale) {
 120      -        return getBundle("sun.text.resources.CollationData", locale);
      105 +    public ResourceBundle getCollationData(Locale locale) {
      106 +        return getBundle(type.getTextResourcesPackage() + ".CollationData", locale);
 121  107      }
 122  108  
 123  109      /**
 124  110       * Gets a date format data resource bundle, using privileges
 125  111       * to allow accessing a sun.* package.
 126  112       */
 127      -    public static ResourceBundle getDateFormatData(Locale locale) {
 128      -        return getBundle("sun.text.resources.FormatData", locale);
      113 +    public ResourceBundle getDateFormatData(Locale locale) {
      114 +        return getBundle(type.getTextResourcesPackage() + ".FormatData", locale);
 129  115      }
 130  116  
 131  117      /**
 132  118       * Gets a number format data resource bundle, using privileges
 133  119       * to allow accessing a sun.* package.
 134  120       */
 135      -    public static ResourceBundle getNumberFormatData(Locale locale) {
 136      -        return getBundle("sun.text.resources.FormatData", locale);
      121 +    public ResourceBundle getNumberFormatData(Locale locale) {
      122 +        return getBundle(type.getTextResourcesPackage() + ".FormatData", locale);
 137  123      }
 138  124  
 139      -    private static ResourceBundle getBundle(final String baseName, final Locale locale) {
      125 +    public static ResourceBundle getBundle(final String baseName, final Locale locale) {
 140  126          return AccessController.doPrivileged(new PrivilegedAction<ResourceBundle>() {
      127 +                @Override
 141  128                  public ResourceBundle run() {
 142  129                      return ResourceBundle.
 143  130                          getBundle(baseName, locale,
 144  131                                    LocaleDataResourceBundleControl.getRBControlInstance());
 145  132                  }
 146  133              });
 147  134      }
 148  135  
 149      -    static class LocaleDataResourceBundleControl extends ResourceBundle.Control {
      136 +    private static class LocaleDataResourceBundleControl extends ResourceBundle.Control {
 150  137          /* Singlton instance of ResourceBundle.Control. */
 151  138          private static LocaleDataResourceBundleControl rbControlInstance =
 152  139              new LocaleDataResourceBundleControl();
 153  140  
 154  141          public static LocaleDataResourceBundleControl getRBControlInstance() {
 155  142              return rbControlInstance;
 156  143          }
 157  144  
 158  145          /*
 159  146           * This method overrides the default implementation to search
↓ open down ↓ 4 lines elided ↑ open up ↑
 164  151           *        locale   the requested locale for the resource bundle.
 165  152           * @returns a list of candidate locales to search from.
 166  153           * @exception NullPointerException if baseName or locale is null.
 167  154           */
 168  155          @Override
 169  156           public List<Locale> getCandidateLocales(String baseName, Locale locale) {
 170  157              List<Locale> candidates = super.getCandidateLocales(baseName, locale);
 171  158              /* Get the locale string list from LocaleDataMetaInfo class. */
 172  159              String localeString = LocaleDataMetaInfo.getSupportedLocaleString(baseName);
 173  160  
 174      -      if (localeString.length() == 0) {
      161 +            if (localeString == null || localeString.length() == 0) {
 175  162                  return candidates;
 176  163              }
 177  164  
 178  165              for (Iterator<Locale> l = candidates.iterator(); l.hasNext(); ) {
 179  166                  Locale loc = l.next();
 180      -                String lstr = null;
      167 +                String lstr;
 181  168                  if (loc.getScript().length() > 0) {
 182  169                      lstr = loc.toLanguageTag().replace('-', '_');
 183  170                  } else {
 184  171                      lstr = loc.toString();
 185  172                      int idx = lstr.indexOf("_#");
 186  173                      if (idx >= 0) {
 187  174                          lstr = lstr.substring(0, idx);
 188  175                      }
 189  176                  }
 190  177                  /* Every locale string in the locale string list returned from
↓ open down ↓ 16 lines elided ↑ open up ↑
 207  194           * @return null for the fallback locale.
 208  195           * @exception NullPointerException if baseName or locale is null.
 209  196           */
 210  197          @Override
 211  198          public Locale getFallbackLocale(String baseName, Locale locale) {
 212  199              if (baseName == null || locale == null) {
 213  200                  throw new NullPointerException();
 214  201              }
 215  202              return null;
 216  203          }
 217      -    }
 218  204  
 219      -    /*
 220      -     * Returns true if the non European resources jar file exists in jre
 221      -     * extension directory.
 222      -     * @returns true if the jar file is there. Otherwise, returns false.
 223      -     */
 224      -    private static boolean isNonEuroLangSupported() {
 225      -        final String sep = File.separator;
 226      -        String localeDataJar =
 227      -            java.security.AccessController.doPrivileged(
 228      -             new sun.security.action.GetPropertyAction("java.home")) +
 229      -            sep + "lib" + sep + "ext" + sep + localeDataJarName;
      205 +        private static final String CLDR      = ".cldr";
 230  206  
 231      -        /* Peek at the installed extension directory to see if
 232      -           localedata.jar is installed or not.
 233      -        */
 234      -        final File f = new File(localeDataJar);
 235      -        boolean isNonEuroResJarExist =
 236      -            AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
 237      -                    public Boolean run() {
 238      -                        return Boolean.valueOf(f.exists());
      207 +        /**
      208 +         * Changes baseName to its per-language package name and
      209 +         * calls the super class implementation. For example,
      210 +         * if the baseName is "sun.text.resources.FormatData" and locale is ja_JP,
      211 +         * the baseName is changed to "sun.text.resources.ja.FormatData". If
      212 +         * baseName contains "cldr", such as "sun.text.resources.cldr.FormatData",
      213 +         * the name is changed to "sun.text.resources.cldr.jp.FormatData".
      214 +         */
      215 +        @Override
      216 +        public String toBundleName(String baseName, Locale locale) {
      217 +            String newBaseName = baseName;
      218 +            String lang = locale.getLanguage();
      219 +            if (lang.length() > 0) {
      220 +                if (baseName.startsWith(JRE.getUtilResourcesPackage())
      221 +                        || baseName.startsWith(JRE.getTextResourcesPackage())) {
      222 +                    // Assume the lengths are the same.
      223 +                    assert JRE.getUtilResourcesPackage().length()
      224 +                        == JRE.getTextResourcesPackage().length();
      225 +                    int index = JRE.getUtilResourcesPackage().length();
      226 +                    if (baseName.indexOf(CLDR, index) > 0) {
      227 +                        index += CLDR.length();
 239  228                      }
 240      -                }).booleanValue();
 241      -
 242      -        return isNonEuroResJarExist;
 243      -    }
 244      -
 245      -    /*
 246      -     * This method gets the locale string list from LocaleDataMetaInfo class and
 247      -     * then contructs the Locale array based on the locale string returned above.
 248      -     * @returns the Locale array for the supported locale of JRE.
 249      -     *
 250      -     */
 251      -    private static Locale[] createLocaleList() {
 252      -        String supportedLocaleString = LocaleDataMetaInfo.
 253      -            getSupportedLocaleString("sun.text.resources.FormatData");
 254      -
 255      -        if (supportedLocaleString.length() == 0) {
 256      -            return null;
 257      -        }
 258      -
 259      -        /* Look for "|" and construct a new locale string list. */
 260      -        int barIndex = supportedLocaleString.indexOf("|");
 261      -        StringTokenizer localeStringTokenizer = null;
 262      -        if (isNonEuroLangSupported()) {
 263      -            localeStringTokenizer = new
 264      -                StringTokenizer(supportedLocaleString.substring(0, barIndex) +
 265      -                                supportedLocaleString.substring(barIndex + 1));
 266      -        } else {
 267      -            localeStringTokenizer = new
 268      -                StringTokenizer(supportedLocaleString.substring(0, barIndex));
 269      -        }
 270      -
 271      -        Locale[] locales = new Locale[localeStringTokenizer.countTokens()];
 272      -        for (int i = 0; i < locales.length; i++) {
 273      -            String currentToken = localeStringTokenizer.nextToken().replace('_','-');
 274      -            if (currentToken.equals("ja-JP-JP")) {
 275      -                currentToken = "ja-JP-u-ca-japanese-x-lvariant-JP";
 276      -            } else if (currentToken.equals("th-TH-TH")) {
 277      -                currentToken = "th-TH-u-nu-thai-x-lvariant-TH";
 278      -            } else if (currentToken.equals("no-NO-NY")) {
 279      -                currentToken = "no-NO-x-lvariant-NY";
      229 +                    newBaseName = baseName.substring(0, index + 1) + lang
      230 +                                      + baseName.substring(index);
      231 +                }
 280  232              }
 281      -            locales[i] = Locale.forLanguageTag(currentToken);
      233 +            return super.toBundleName(newBaseName, locale);
 282  234          }
 283      -        return locales;
 284      -    }
 285  235  
      236 +    }
 286  237  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX