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

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)

@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.  Oracle designates this

@@ -38,117 +38,104 @@
  *
  */
 
 package sun.util.resources;
 
-import java.io.File;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Locale;
 import java.util.ResourceBundle;
-import java.util.StringTokenizer;
+import sun.util.locale.provider.LocaleProviderAdapter;
+import static sun.util.locale.provider.LocaleProviderAdapter.Type.JRE;
+import sun.util.locale.provider.LocaleDataMetaInfo;
 
-import sun.util.LocaleDataMetaInfo;
-
 /**
  * Provides information about and access to resource bundles in the
- * sun.text.resources and sun.util.resources package.
+ * sun.text.resources and sun.util.resources packages or in their corresponding
+ * packages for CLDR.
  *
  * @author Asmus Freytag
  * @author Mark Davis
  */
 
 public class LocaleData {
+    private final LocaleProviderAdapter.Type type;
 
-    private static final String localeDataJarName = "localedata.jar";
-
-    /**
-     * Lazy load available locales.
-     */
-    private static class AvailableLocales {
-         static final Locale[] localeList = createLocaleList();
+    public LocaleData(LocaleProviderAdapter.Type type) {
+        this.type = type;
     }
 
     /**
-     * Returns a list of the installed locales. Currently, this simply returns
-     * the list of locales for which a sun.text.resources.FormatData bundle
-     * exists. This bundle family happens to be the one with the broadest
-     * locale coverage in the JRE.
-     */
-    public static Locale[] getAvailableLocales() {
-        return AvailableLocales.localeList.clone();
-    }
-
-    /**
      * Gets a calendar data resource bundle, using privileges
      * to allow accessing a sun.* package.
      */
-    public static ResourceBundle getCalendarData(Locale locale) {
-        return getBundle("sun.util.resources.CalendarData", locale);
+    public ResourceBundle getCalendarData(Locale locale) {
+        return getBundle(type.getUtilResourcesPackage() + ".CalendarData", locale);
     }
 
     /**
      * Gets a currency names resource bundle, using privileges
      * to allow accessing a sun.* package.
      */
-    public static OpenListResourceBundle getCurrencyNames(Locale locale) {
-        return (OpenListResourceBundle)getBundle("sun.util.resources.CurrencyNames", locale);
+    public OpenListResourceBundle getCurrencyNames(Locale locale) {
+        return (OpenListResourceBundle) getBundle(type.getUtilResourcesPackage() + ".CurrencyNames", locale);
     }
 
     /**
      * Gets a locale names resource bundle, using privileges
      * to allow accessing a sun.* package.
      */
-    public static OpenListResourceBundle getLocaleNames(Locale locale) {
-        return (OpenListResourceBundle)getBundle("sun.util.resources.LocaleNames", locale);
+    public OpenListResourceBundle getLocaleNames(Locale locale) {
+        return (OpenListResourceBundle) getBundle(type.getUtilResourcesPackage() + ".LocaleNames", locale);
     }
 
     /**
      * Gets a time zone names resource bundle, using privileges
      * to allow accessing a sun.* package.
      */
-    public static OpenListResourceBundle getTimeZoneNames(Locale locale) {
-        return (OpenListResourceBundle)getBundle("sun.util.resources.TimeZoneNames", locale);
+    public OpenListResourceBundle getTimeZoneNames(Locale locale) {
+        return (OpenListResourceBundle) getBundle(type.getUtilResourcesPackage() + ".TimeZoneNames", locale);
     }
 
     /**
      * Gets a collation data resource bundle, using privileges
      * to allow accessing a sun.* package.
      */
-    public static ResourceBundle getCollationData(Locale locale) {
-        return getBundle("sun.text.resources.CollationData", locale);
+    public ResourceBundle getCollationData(Locale locale) {
+        return getBundle(type.getTextResourcesPackage() + ".CollationData", locale);
     }
 
     /**
      * Gets a date format data resource bundle, using privileges
      * to allow accessing a sun.* package.
      */
-    public static ResourceBundle getDateFormatData(Locale locale) {
-        return getBundle("sun.text.resources.FormatData", locale);
+    public ResourceBundle getDateFormatData(Locale locale) {
+        return getBundle(type.getTextResourcesPackage() + ".FormatData", locale);
     }
 
     /**
      * Gets a number format data resource bundle, using privileges
      * to allow accessing a sun.* package.
      */
-    public static ResourceBundle getNumberFormatData(Locale locale) {
-        return getBundle("sun.text.resources.FormatData", locale);
+    public ResourceBundle getNumberFormatData(Locale locale) {
+        return getBundle(type.getTextResourcesPackage() + ".FormatData", locale);
     }
 
-    private static ResourceBundle getBundle(final String baseName, final Locale locale) {
+    public static ResourceBundle getBundle(final String baseName, final Locale locale) {
         return AccessController.doPrivileged(new PrivilegedAction<ResourceBundle>() {
+                @Override
                 public ResourceBundle run() {
                     return ResourceBundle.
                         getBundle(baseName, locale,
                                   LocaleDataResourceBundleControl.getRBControlInstance());
                 }
             });
     }
 
-    static class LocaleDataResourceBundleControl extends ResourceBundle.Control {
+    private static class LocaleDataResourceBundleControl extends ResourceBundle.Control {
         /* Singlton instance of ResourceBundle.Control. */
         private static LocaleDataResourceBundleControl rbControlInstance =
             new LocaleDataResourceBundleControl();
 
         public static LocaleDataResourceBundleControl getRBControlInstance() {

@@ -169,17 +156,17 @@
          public List<Locale> getCandidateLocales(String baseName, Locale locale) {
             List<Locale> candidates = super.getCandidateLocales(baseName, locale);
             /* Get the locale string list from LocaleDataMetaInfo class. */
             String localeString = LocaleDataMetaInfo.getSupportedLocaleString(baseName);
 
-      if (localeString.length() == 0) {
+            if (localeString == null || localeString.length() == 0) {
                 return candidates;
             }
 
             for (Iterator<Locale> l = candidates.iterator(); l.hasNext(); ) {
                 Locale loc = l.next();
-                String lstr = null;
+                String lstr;
                 if (loc.getScript().length() > 0) {
                     lstr = loc.toLanguageTag().replace('-', '_');
                 } else {
                     lstr = loc.toString();
                     int idx = lstr.indexOf("_#");

@@ -212,75 +199,39 @@
             if (baseName == null || locale == null) {
                 throw new NullPointerException();
             }
             return null;
         }
-    }
 
-    /*
-     * Returns true if the non European resources jar file exists in jre
-     * extension directory.
-     * @returns true if the jar file is there. Otherwise, returns false.
-     */
-    private static boolean isNonEuroLangSupported() {
-        final String sep = File.separator;
-        String localeDataJar =
-            java.security.AccessController.doPrivileged(
-             new sun.security.action.GetPropertyAction("java.home")) +
-            sep + "lib" + sep + "ext" + sep + localeDataJarName;
+        private static final String CLDR      = ".cldr";
 
-        /* Peek at the installed extension directory to see if
-           localedata.jar is installed or not.
+        /**
+         * Changes baseName to its per-language package name and
+         * calls the super class implementation. For example,
+         * if the baseName is "sun.text.resources.FormatData" and locale is ja_JP,
+         * the baseName is changed to "sun.text.resources.ja.FormatData". If
+         * baseName contains "cldr", such as "sun.text.resources.cldr.FormatData",
+         * the name is changed to "sun.text.resources.cldr.jp.FormatData".
         */
-        final File f = new File(localeDataJar);
-        boolean isNonEuroResJarExist =
-            AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
-                    public Boolean run() {
-                        return Boolean.valueOf(f.exists());
+        @Override
+        public String toBundleName(String baseName, Locale locale) {
+            String newBaseName = baseName;
+            String lang = locale.getLanguage();
+            if (lang.length() > 0) {
+                if (baseName.startsWith(JRE.getUtilResourcesPackage())
+                        || baseName.startsWith(JRE.getTextResourcesPackage())) {
+                    // Assume the lengths are the same.
+                    assert JRE.getUtilResourcesPackage().length()
+                        == JRE.getTextResourcesPackage().length();
+                    int index = JRE.getUtilResourcesPackage().length();
+                    if (baseName.indexOf(CLDR, index) > 0) {
+                        index += CLDR.length();
                     }
-                }).booleanValue();
-
-        return isNonEuroResJarExist;
+                    newBaseName = baseName.substring(0, index + 1) + lang
+                                      + baseName.substring(index);
     }
-
-    /*
-     * This method gets the locale string list from LocaleDataMetaInfo class and
-     * then contructs the Locale array based on the locale string returned above.
-     * @returns the Locale array for the supported locale of JRE.
-     *
-     */
-    private static Locale[] createLocaleList() {
-        String supportedLocaleString = LocaleDataMetaInfo.
-            getSupportedLocaleString("sun.text.resources.FormatData");
-
-        if (supportedLocaleString.length() == 0) {
-            return null;
         }
-
-        /* Look for "|" and construct a new locale string list. */
-        int barIndex = supportedLocaleString.indexOf("|");
-        StringTokenizer localeStringTokenizer = null;
-        if (isNonEuroLangSupported()) {
-            localeStringTokenizer = new
-                StringTokenizer(supportedLocaleString.substring(0, barIndex) +
-                                supportedLocaleString.substring(barIndex + 1));
-        } else {
-            localeStringTokenizer = new
-                StringTokenizer(supportedLocaleString.substring(0, barIndex));
+            return super.toBundleName(newBaseName, locale);
         }
 
-        Locale[] locales = new Locale[localeStringTokenizer.countTokens()];
-        for (int i = 0; i < locales.length; i++) {
-            String currentToken = localeStringTokenizer.nextToken().replace('_','-');
-            if (currentToken.equals("ja-JP-JP")) {
-                currentToken = "ja-JP-u-ca-japanese-x-lvariant-JP";
-            } else if (currentToken.equals("th-TH-TH")) {
-                currentToken = "th-TH-u-nu-thai-x-lvariant-TH";
-            } else if (currentToken.equals("no-NO-NY")) {
-                currentToken = "no-NO-x-lvariant-NY";
             }
-            locales[i] = Locale.forLanguageTag(currentToken);
-        }
-        return locales;
-    }
-
 }