src/share/classes/sun/util/resources/LocaleData.java

Print this page
rev 5696 : 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 packaging changes. by Naoto Sato and Masayoshi Okutsu)
   1 /*
   2  * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   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
   7  * published by the Free Software Foundation.  Oracle designates this
   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 
  26 /*
  27  * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
  28  * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
  29  *
  30  * The original version of this source code and documentation
  31  * is copyrighted and owned by Taligent, Inc., a wholly-owned
  32  * subsidiary of IBM. These materials are provided under terms
  33  * of a License Agreement between Taligent and Sun. This technology
  34  * is protected by multiple US and International patents.
  35  *
  36  * This notice and attribution to Taligent may not be removed.
  37  * Taligent is a registered trademark of Taligent, Inc.
  38  *
  39  */
  40 
  41 package sun.util.resources;
  42 
  43 import java.io.File;
  44 import java.security.AccessController;
  45 import java.security.PrivilegedAction;
  46 import java.util.Iterator;
  47 import java.util.List;
  48 import java.util.Locale;
  49 import java.util.ResourceBundle;
  50 import java.util.StringTokenizer;


  51 
  52 import sun.util.LocaleDataMetaInfo;
  53 
  54 /**
  55  * Provides information about and access to resource bundles in the
  56  * sun.text.resources and sun.util.resources package.

  57  *
  58  * @author Asmus Freytag
  59  * @author Mark Davis
  60  */
  61 
  62 public class LocaleData {

  63 
  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();
  71     }
  72 
  73     /**
  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      * Gets a calendar data resource bundle, using privileges
  85      * to allow accessing a sun.* package.
  86      */
  87     public static ResourceBundle getCalendarData(Locale locale) {
  88         return getBundle("sun.util.resources.CalendarData", locale);
  89     }
  90 
  91     /**
  92      * Gets a currency names resource bundle, using privileges
  93      * to allow accessing a sun.* package.
  94      */
  95     public static OpenListResourceBundle getCurrencyNames(Locale locale) {
  96         return (OpenListResourceBundle)getBundle("sun.util.resources.CurrencyNames", locale);
  97     }
  98 
  99     /**
 100      * Gets a locale names resource bundle, using privileges
 101      * to allow accessing a sun.* package.
 102      */
 103     public static OpenListResourceBundle getLocaleNames(Locale locale) {
 104         return (OpenListResourceBundle)getBundle("sun.util.resources.LocaleNames", locale);
 105     }
 106 
 107     /**
 108      * Gets a time zone names resource bundle, using privileges
 109      * to allow accessing a sun.* package.
 110      */
 111     public static OpenListResourceBundle getTimeZoneNames(Locale locale) {
 112         return (OpenListResourceBundle)getBundle("sun.util.resources.TimeZoneNames", locale);
 113     }
 114 
 115     /**
 116      * Gets a collation data resource bundle, using privileges
 117      * to allow accessing a sun.* package.
 118      */
 119     public static ResourceBundle getCollationData(Locale locale) {
 120         return getBundle("sun.text.resources.CollationData", locale);
 121     }
 122 
 123     /**
 124      * Gets a date format data resource bundle, using privileges
 125      * to allow accessing a sun.* package.
 126      */
 127     public static ResourceBundle getDateFormatData(Locale locale) {
 128         return getBundle("sun.text.resources.FormatData", locale);
 129     }
 130 
 131     /**
 132      * Gets a number format data resource bundle, using privileges
 133      * to allow accessing a sun.* package.
 134      */
 135     public static ResourceBundle getNumberFormatData(Locale locale) {
 136         return getBundle("sun.text.resources.FormatData", locale);
 137     }
 138 
 139     private static ResourceBundle getBundle(final String baseName, final Locale locale) {
 140         return AccessController.doPrivileged(new PrivilegedAction<ResourceBundle>() {

 141                 public ResourceBundle run() {
 142                     return ResourceBundle.
 143                         getBundle(baseName, locale,
 144                                   LocaleDataResourceBundleControl.getRBControlInstance());
 145                 }
 146             });
 147     }
 148 
 149     static class LocaleDataResourceBundleControl extends ResourceBundle.Control {
 150         /* Singlton instance of ResourceBundle.Control. */
 151         private static LocaleDataResourceBundleControl rbControlInstance =
 152             new LocaleDataResourceBundleControl();
 153 
 154         public static LocaleDataResourceBundleControl getRBControlInstance() {
 155             return rbControlInstance;
 156         }
 157 
 158         /*
 159          * This method overrides the default implementation to search
 160          * from a prebaked locale string list to determin the candidate
 161          * locale list.
 162          *
 163          * @param baseName the resource bundle base name.
 164          *        locale   the requested locale for the resource bundle.
 165          * @returns a list of candidate locales to search from.
 166          * @exception NullPointerException if baseName or locale is null.
 167          */
 168         @Override
 169          public List<Locale> getCandidateLocales(String baseName, Locale locale) {
 170             List<Locale> candidates = super.getCandidateLocales(baseName, locale);
 171             /* Get the locale string list from LocaleDataMetaInfo class. */
 172             String localeString = LocaleDataMetaInfo.getSupportedLocaleString(baseName);
 173 
 174       if (localeString.length() == 0) {
 175                 return candidates;
 176             }
 177 
 178             for (Iterator<Locale> l = candidates.iterator(); l.hasNext(); ) {
 179                 Locale loc = l.next();
 180                 String lstr = null;
 181                 if (loc.getScript().length() > 0) {
 182                     lstr = loc.toLanguageTag().replace('-', '_');
 183                 } else {
 184                     lstr = loc.toString();
 185                     int idx = lstr.indexOf("_#");
 186                     if (idx >= 0) {
 187                         lstr = lstr.substring(0, idx);
 188                     }
 189                 }
 190                 /* Every locale string in the locale string list returned from
 191                    the above getSupportedLocaleString is enclosed
 192                    within two white spaces so that we could check some locale
 193                    such as "en".
 194                 */
 195                 if (lstr.length() != 0 && localeString.indexOf(" " + lstr + " ") == -1) {
 196                     l.remove();
 197                 }
 198             }
 199             return candidates;
 200         }
 201 
 202         /*
 203          * Overrides "getFallbackLocale" to return null so
 204          * that the fallback locale will be null.
 205          * @param baseName the resource bundle base name.
 206          *        locale   the requested locale for the resource bundle.
 207          * @return null for the fallback locale.
 208          * @exception NullPointerException if baseName or locale is null.
 209          */
 210         @Override
 211         public Locale getFallbackLocale(String baseName, Locale locale) {
 212             if (baseName == null || locale == null) {
 213                 throw new NullPointerException();
 214             }
 215             return null;
 216         }
 217     }
 218 
 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;
 230 
 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());








 239                     }
 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";
 280             }
 281             locales[i] = Locale.forLanguageTag(currentToken);
 282         }
 283         return locales;
 284     }
 285 
 286 }
   1 /*
   2  * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   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
   7  * published by the Free Software Foundation.  Oracle designates this
   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 
  26 /*
  27  * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
  28  * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
  29  *
  30  * The original version of this source code and documentation
  31  * is copyrighted and owned by Taligent, Inc., a wholly-owned
  32  * subsidiary of IBM. These materials are provided under terms
  33  * of a License Agreement between Taligent and Sun. This technology
  34  * is protected by multiple US and International patents.
  35  *
  36  * This notice and attribution to Taligent may not be removed.
  37  * Taligent is a registered trademark of Taligent, Inc.
  38  *
  39  */
  40 
  41 package sun.util.resources;
  42 

  43 import java.security.AccessController;
  44 import java.security.PrivilegedAction;
  45 import java.util.Iterator;
  46 import java.util.List;
  47 import java.util.Locale;
  48 import java.util.ResourceBundle;
  49 import sun.util.locale.provider.LocaleProviderAdapter;
  50 import static sun.util.locale.provider.LocaleProviderAdapter.Type.JRE;
  51 import sun.util.locale.provider.LocaleDataMetaInfo;
  52 


  53 /**
  54  * Provides information about and access to resource bundles in the
  55  * sun.text.resources and sun.util.resources packages or in their corresponding
  56  * packages for CLDR.
  57  *
  58  * @author Asmus Freytag
  59  * @author Mark Davis
  60  */
  61 
  62 public class LocaleData {
  63     private final LocaleProviderAdapter.Type type;
  64 
  65     public LocaleData(LocaleProviderAdapter.Type type) {
  66         this.type = type;





  67     }
  68 
  69     /**










  70      * Gets a calendar data resource bundle, using privileges
  71      * to allow accessing a sun.* package.
  72      */
  73     public ResourceBundle getCalendarData(Locale locale) {
  74         return getBundle(type.getUtilResourcesPackage() + ".CalendarData", locale);
  75     }
  76 
  77     /**
  78      * Gets a currency names resource bundle, using privileges
  79      * to allow accessing a sun.* package.
  80      */
  81     public OpenListResourceBundle getCurrencyNames(Locale locale) {
  82         return (OpenListResourceBundle) getBundle(type.getUtilResourcesPackage() + ".CurrencyNames", locale);
  83     }
  84 
  85     /**
  86      * Gets a locale names resource bundle, using privileges
  87      * to allow accessing a sun.* package.
  88      */
  89     public OpenListResourceBundle getLocaleNames(Locale locale) {
  90         return (OpenListResourceBundle) getBundle(type.getUtilResourcesPackage() + ".LocaleNames", locale);
  91     }
  92 
  93     /**
  94      * Gets a time zone names resource bundle, using privileges
  95      * to allow accessing a sun.* package.
  96      */
  97     public OpenListResourceBundle getTimeZoneNames(Locale locale) {
  98         return (OpenListResourceBundle) getBundle(type.getUtilResourcesPackage() + ".TimeZoneNames", locale);
  99     }
 100 
 101     /**
 102      * Gets a collation data resource bundle, using privileges
 103      * to allow accessing a sun.* package.
 104      */
 105     public ResourceBundle getCollationData(Locale locale) {
 106         return getBundle(type.getTextResourcesPackage() + ".CollationData", locale);
 107     }
 108 
 109     /**
 110      * Gets a date format data resource bundle, using privileges
 111      * to allow accessing a sun.* package.
 112      */
 113     public ResourceBundle getDateFormatData(Locale locale) {
 114         return getBundle(type.getTextResourcesPackage() + ".FormatData", locale);
 115     }
 116 
 117     /**
 118      * Gets a number format data resource bundle, using privileges
 119      * to allow accessing a sun.* package.
 120      */
 121     public ResourceBundle getNumberFormatData(Locale locale) {
 122         return getBundle(type.getTextResourcesPackage() + ".FormatData", locale);
 123     }
 124 
 125     public static ResourceBundle getBundle(final String baseName, final Locale locale) {
 126         return AccessController.doPrivileged(new PrivilegedAction<ResourceBundle>() {
 127                 @Override
 128                 public ResourceBundle run() {
 129                     return ResourceBundle.
 130                         getBundle(baseName, locale,
 131                                   LocaleDataResourceBundleControl.getRBControlInstance());
 132                 }
 133             });
 134     }
 135 
 136     private static class LocaleDataResourceBundleControl extends ResourceBundle.Control {
 137         /* Singlton instance of ResourceBundle.Control. */
 138         private static LocaleDataResourceBundleControl rbControlInstance =
 139             new LocaleDataResourceBundleControl();
 140 
 141         public static LocaleDataResourceBundleControl getRBControlInstance() {
 142             return rbControlInstance;
 143         }
 144 
 145         /*
 146          * This method overrides the default implementation to search
 147          * from a prebaked locale string list to determin the candidate
 148          * locale list.
 149          *
 150          * @param baseName the resource bundle base name.
 151          *        locale   the requested locale for the resource bundle.
 152          * @returns a list of candidate locales to search from.
 153          * @exception NullPointerException if baseName or locale is null.
 154          */
 155         @Override
 156          public List<Locale> getCandidateLocales(String baseName, Locale locale) {
 157             List<Locale> candidates = super.getCandidateLocales(baseName, locale);
 158             /* Get the locale string list from LocaleDataMetaInfo class. */
 159             String localeString = LocaleDataMetaInfo.getSupportedLocaleString(baseName);
 160 
 161             if (localeString == null || localeString.length() == 0) {
 162                 return candidates;
 163             }
 164 
 165             for (Iterator<Locale> l = candidates.iterator(); l.hasNext(); ) {
 166                 Locale loc = l.next();
 167                 String lstr;
 168                 if (loc.getScript().length() > 0) {
 169                     lstr = loc.toLanguageTag().replace('-', '_');
 170                 } else {
 171                     lstr = loc.toString();
 172                     int idx = lstr.indexOf("_#");
 173                     if (idx >= 0) {
 174                         lstr = lstr.substring(0, idx);
 175                     }
 176                 }
 177                 /* Every locale string in the locale string list returned from
 178                    the above getSupportedLocaleString is enclosed
 179                    within two white spaces so that we could check some locale
 180                    such as "en".
 181                 */
 182                 if (lstr.length() != 0 && localeString.indexOf(" " + lstr + " ") == -1) {
 183                     l.remove();
 184                 }
 185             }
 186             return candidates;
 187         }
 188 
 189         /*
 190          * Overrides "getFallbackLocale" to return null so
 191          * that the fallback locale will be null.
 192          * @param baseName the resource bundle base name.
 193          *        locale   the requested locale for the resource bundle.
 194          * @return null for the fallback locale.
 195          * @exception NullPointerException if baseName or locale is null.
 196          */
 197         @Override
 198         public Locale getFallbackLocale(String baseName, Locale locale) {
 199             if (baseName == null || locale == null) {
 200                 throw new NullPointerException();
 201             }
 202             return null;
 203         }

 204 
 205         private static final String CLDR      = ".cldr";










 206 
 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();
 228                     }
 229                     newBaseName = baseName.substring(0, index + 1) + lang
 230                                       + baseName.substring(index);

 231                 }













 232             }
 233             return super.toBundleName(newBaseName, locale);










 234         }
 235 









 236     }





 237 }