8000245: SimpleDateFormat.format(date, StringBuffer, FieldPosition) doesn't work as expected with custom extensions
authornaoto
Tue, 16 Oct 2012 10:59:21 -0700
changeset 14185 916ec0a4d039
parent 14184 5553422ece67
child 14186 bfb891f72a79
8000245: SimpleDateFormat.format(date, StringBuffer, FieldPosition) doesn't work as expected with custom extensions 8000273: java.util.Locale.getDisplayVariant(Locale l) isn't transferred to the custom service provider 8000615: JRE adapter: timezone name of en_US is changed when extension directory is added Reviewed-by: okutsu
jdk/src/share/classes/sun/util/locale/provider/CurrencyNameProviderImpl.java
jdk/src/share/classes/sun/util/locale/provider/LocaleNameProviderImpl.java
jdk/src/share/classes/sun/util/locale/provider/LocaleServiceProviderPool.java
jdk/src/share/classes/sun/util/locale/provider/TimeZoneNameProviderImpl.java
jdk/test/java/util/Locale/LocaleProviders.java
jdk/test/java/util/Locale/LocaleProviders.sh
jdk/test/java/util/PluggableLocale/CurrencyNameProviderTest.java
jdk/test/java/util/PluggableLocale/LocaleNameProviderTest.java
jdk/test/java/util/PluggableLocale/LocaleNameProviderTest.sh
jdk/test/java/util/PluggableLocale/ProviderTest.java
jdk/test/java/util/PluggableLocale/TimeZoneNameProviderTest.java
jdk/test/java/util/PluggableLocale/providersrc/LocaleNameProviderImpl.java
--- a/jdk/src/share/classes/sun/util/locale/provider/CurrencyNameProviderImpl.java	Mon Oct 15 22:34:35 2012 +0100
+++ b/jdk/src/share/classes/sun/util/locale/provider/CurrencyNameProviderImpl.java	Tue Oct 16 10:59:21 2012 -0700
@@ -26,10 +26,9 @@
 package sun.util.locale.provider;
 
 import java.util.Locale;
-import java.util.MissingResourceException;
+import java.util.ResourceBundle;
 import java.util.Set;
 import java.util.spi.CurrencyNameProvider;
-import sun.util.resources.OpenListResourceBundle;
 
 /**
  * Concrete implementation of the
@@ -121,16 +120,10 @@
             throw new NullPointerException();
         }
 
-        OpenListResourceBundle bundle = LocaleProviderAdapter.forType(type).getLocaleData().getCurrencyNames(locale);
-        LocaleServiceProviderPool pool =
-                LocaleServiceProviderPool.getPool(CurrencyNameProvider.class);
-        try {
-            if (!pool.hasProviders() ||
-                (bundle.getLocale().equals(locale) &&
-                 bundle.handleGetKeys().contains(key))) {
+        ResourceBundle bundle = LocaleProviderAdapter.forType(type).getLocaleData().getCurrencyNames(locale);
+        if (bundle.containsKey(key)) {
                 return bundle.getString(key);
             }
-        } catch (MissingResourceException mre) {}
 
         return null;
     }
--- a/jdk/src/share/classes/sun/util/locale/provider/LocaleNameProviderImpl.java	Mon Oct 15 22:34:35 2012 +0100
+++ b/jdk/src/share/classes/sun/util/locale/provider/LocaleNameProviderImpl.java	Tue Oct 16 10:59:21 2012 -0700
@@ -26,10 +26,9 @@
 package sun.util.locale.provider;
 
 import java.util.Locale;
-import java.util.MissingResourceException;
+import java.util.ResourceBundle;
 import java.util.Set;
 import java.util.spi.LocaleNameProvider;
-import sun.util.resources.OpenListResourceBundle;
 
 /**
  * Concrete implementation of the
@@ -175,15 +174,10 @@
             throw new NullPointerException();
         }
 
-        OpenListResourceBundle rb = LocaleProviderAdapter.forType(type).getLocaleData().getLocaleNames(locale);
-        LocaleServiceProviderPool pool =
-                LocaleServiceProviderPool.getPool(LocaleNameProvider.class);
-        try {
-            if (!pool.hasProviders() ||
-                (rb.getLocale().equals(locale) && rb.handleGetKeys().contains(key))) {
+        ResourceBundle rb = LocaleProviderAdapter.forType(type).getLocaleData().getLocaleNames(locale);
+        if (rb.containsKey(key)) {
                 return rb.getString(key);
             }
-        } catch (MissingResourceException mre) {}
 
         return null;
     }
--- a/jdk/src/share/classes/sun/util/locale/provider/LocaleServiceProviderPool.java	Mon Oct 15 22:34:35 2012 +0100
+++ b/jdk/src/share/classes/sun/util/locale/provider/LocaleServiceProviderPool.java	Tue Oct 16 10:59:21 2012 -0700
@@ -302,7 +302,7 @@
 
                 for (LocaleProviderAdapter.Type type: findProviders(current)) {
                     LocaleServiceProvider lsp = providers.get(type);
-                    providersObj = getter.getObject((P)lsp, current, key, params);
+                    providersObj = getter.getObject((P)lsp, locale, key, params);
                     if (providersObj != null) {
                         return providersObj;
                     } else if (isObjectProvider) {
--- a/jdk/src/share/classes/sun/util/locale/provider/TimeZoneNameProviderImpl.java	Mon Oct 15 22:34:35 2012 +0100
+++ b/jdk/src/share/classes/sun/util/locale/provider/TimeZoneNameProviderImpl.java	Tue Oct 16 10:59:21 2012 -0700
@@ -26,11 +26,10 @@
 package sun.util.locale.provider;
 
 import java.util.Locale;
-import java.util.MissingResourceException;
+import java.util.ResourceBundle;
 import java.util.Set;
 import java.util.TimeZone;
 import java.util.spi.TimeZoneNameProvider;
-import sun.util.resources.OpenListResourceBundle;
 
 /**
  * Concrete implementation of the
@@ -102,12 +101,8 @@
         }
 
         LocaleProviderAdapter adapter = LocaleProviderAdapter.forType(type);
-        OpenListResourceBundle rb = adapter.getLocaleResources(locale).getTimeZoneNames();
-        LocaleServiceProviderPool pool =
-                LocaleServiceProviderPool.getPool(TimeZoneNameProvider.class);
-        try {
-            if (!pool.hasProviders() ||
-                (rb.getLocale().equals(locale) && rb.handleGetKeys().contains(id))) {
+        ResourceBundle rb = adapter.getLocaleResources(locale).getTimeZoneNames();
+        if (rb.containsKey(id)) {
                 String[] names = rb.getStringArray(id);
                 int index = daylight ? 3 : 1;
                 if (style == TimeZone.SHORT) {
@@ -115,8 +110,6 @@
                 }
                 return names[index];
             }
-        } catch (MissingResourceException mre) {
-        }
 
         return null;
     }
--- a/jdk/test/java/util/Locale/LocaleProviders.java	Mon Oct 15 22:34:35 2012 +0100
+++ b/jdk/test/java/util/Locale/LocaleProviders.java	Tue Oct 16 10:59:21 2012 -0700
@@ -47,6 +47,10 @@
                 bug7198834Test();
                 break;
 
+            case "tzNameTest":
+                tzNameTest(args[1]);
+                break;
+
             default:
                 throw new RuntimeException("Test method '"+methodName+"' not found.");
         }
@@ -81,4 +85,12 @@
             System.out.println("Windows HOST locale adapter not found. Ignoring this test.");
         }
     }
+
+    static void tzNameTest(String id) {
+        TimeZone tz = TimeZone.getTimeZone(id);
+        String tzName = tz.getDisplayName(false, TimeZone.SHORT, Locale.US);
+        if (tzName.startsWith("GMT")) {
+            throw new RuntimeException("JRE's localized time zone name for "+id+" could not be retrieved. Returned name was: "+tzName);
+        }
+    }
 }
--- a/jdk/test/java/util/Locale/LocaleProviders.sh	Mon Oct 15 22:34:35 2012 +0100
+++ b/jdk/test/java/util/Locale/LocaleProviders.sh	Tue Oct 16 10:59:21 2012 -0700
@@ -23,7 +23,7 @@
 #!/bin/sh
 #
 # @test
-# @bug 6336885 7196799 7197573 7198834
+# @bug 6336885 7196799 7197573 7198834 8000245 8000615
 # @summary tests for "java.locale.providers" system property
 # @compile -XDignore.symbol.file LocaleProviders.java
 # @run shell/timeout=600 LocaleProviders.sh
@@ -65,6 +65,36 @@
     ;;
 esac
 
+# create an SPI implementation
+mk() {
+  d=`dirname $1`
+  if [ ! -d $d ]; then mkdir -p $d; fi
+  cat - >$1
+}
+
+SPIDIR=${TESTCLASSES}${FS}spi
+rm -rf ${SPIDIR}
+mk ${SPIDIR}${FS}src${FS}tznp.java << EOF
+import java.util.spi.TimeZoneNameProvider;
+import java.util.Locale;
+
+public class tznp extends TimeZoneNameProvider {
+    public String getDisplayName(String ID, boolean daylight, int style, Locale locale) {
+        return "tznp";
+    }
+
+    public Locale[] getAvailableLocales() {
+        Locale[] locales = {Locale.GERMAN, Locale.US, Locale.JAPANESE, Locale.CHINESE};
+        return locales;
+    }
+}
+EOF
+mk ${SPIDIR}${FS}dest${FS}META-INF${FS}services${FS}java.util.spi.TimeZoneNameProvider << EOF
+tznp
+EOF
+${TESTJAVA}${FS}bin${FS}javac -d ${SPIDIR}${FS}dest ${SPIDIR}${FS}src${FS}tznp.java
+${TESTJAVA}${FS}bin${FS}jar cvf ${SPIDIR}${FS}tznp.jar -C ${SPIDIR}${FS}dest .
+
 # get the platform default locales
 PLATDEF=`${TESTJAVA}${FS}bin${FS}java -classpath ${TESTCLASSES} LocaleProviders getPlatformLocale display`
 DEFLANG=`echo ${PLATDEF} | sed -e "s/,.*//"`
@@ -199,4 +229,20 @@
 PARAM3=
 runTest
 
+# testing 8000245 fix.
+METHODNAME=tzNameTest
+PREFLIST="JRE -Djava.ext.dirs=${SPIDIR}"
+PARAM1=Europe/Moscow
+PARAM2=
+PARAM3=
+runTest
+
+# testing 8000615 fix.
+METHODNAME=tzNameTest
+PREFLIST="JRE -Djava.ext.dirs=${SPIDIR}"
+PARAM1=America/Los_Angeles
+PARAM2=
+PARAM3=
+runTest
+
 exit $result
--- a/jdk/test/java/util/PluggableLocale/CurrencyNameProviderTest.java	Mon Oct 15 22:34:35 2012 +0100
+++ b/jdk/test/java/util/PluggableLocale/CurrencyNameProviderTest.java	Tue Oct 16 10:59:21 2012 -0700
@@ -50,12 +50,13 @@
         com.bar.CurrencyNameProviderImpl cnp = new com.bar.CurrencyNameProviderImpl();
         Locale[] availloc = Locale.getAvailableLocales();
         Locale[] testloc = availloc.clone();
+        List<Locale> jreimplloc = Arrays.asList(LocaleProviderAdapter.forJRE().getCurrencyNameProvider().getAvailableLocales());
         List<Locale> providerloc = Arrays.asList(cnp.getAvailableLocales());
 
         for (Locale target: availloc) {
             // pure JRE implementation
             OpenListResourceBundle rb = (OpenListResourceBundle)LocaleProviderAdapter.forJRE().getLocaleData().getCurrencyNames(target);
-            boolean jreHasBundle = rb.getLocale().equals(target);
+            boolean jreSupportsTarget = jreimplloc.contains(target);
 
             for (Locale test: testloc) {
                 // get a Currency instance
@@ -82,27 +83,24 @@
                     providersname = cnp.getDisplayName(c.getCurrencyCode(), target);
                 }
 
-                // JRE's name (if any)
+                // JRE's name
                 String jrescurrency = null;
                 String jresname = null;
                 String key = c.getCurrencyCode();
                 String nameKey = key.toLowerCase(Locale.ROOT);
-                if (jreHasBundle) {
+                if (jreSupportsTarget) {
                     try {
                         jrescurrency = rb.getString(key);
-                    } catch (MissingResourceException mre) {
-                        // JRE does not have any resource, "jrescurrency" should remain null
-                    }
+                    } catch (MissingResourceException mre) {}
                     try {
                         jresname = rb.getString(nameKey);
-                    } catch (MissingResourceException mre) {
-                        // JRE does not have any resource, "jresname" should remain null
-                    }
+                    } catch (MissingResourceException mre) {}
                 }
 
-                checkValidity(target, jrescurrency, providerscurrency, currencyresult, jrescurrency!=null);
+                checkValidity(target, jrescurrency, providerscurrency, currencyresult,
+                              jreSupportsTarget && jrescurrency != null);
                 checkValidity(target, jresname, providersname, nameresult,
-                              jreHasBundle && rb.handleGetKeys().contains(nameKey));
+                              jreSupportsTarget && jresname != null);
             }
         }
     }
--- a/jdk/test/java/util/PluggableLocale/LocaleNameProviderTest.java	Mon Oct 15 22:34:35 2012 +0100
+++ b/jdk/test/java/util/PluggableLocale/LocaleNameProviderTest.java	Tue Oct 16 10:59:21 2012 -0700
@@ -36,15 +36,21 @@
     }
 
     LocaleNameProviderTest() {
+        checkAvailLocValidityTest();
+        variantFallbackTest();
+    }
+
+    void checkAvailLocValidityTest() {
         com.bar.LocaleNameProviderImpl lnp = new com.bar.LocaleNameProviderImpl();
         Locale[] availloc = Locale.getAvailableLocales();
         Locale[] testloc = availloc.clone();
+        List<Locale> jreimplloc = Arrays.asList(LocaleProviderAdapter.forJRE().getLocaleNameProvider().getAvailableLocales());
         List<Locale> providerloc = Arrays.asList(lnp.getAvailableLocales());
 
         for (Locale target: availloc) {
             // pure JRE implementation
             OpenListResourceBundle rb = LocaleProviderAdapter.forJRE().getLocaleData().getLocaleNames(target);
-            boolean jreHasBundle = rb.getLocale().equals(target);
+            boolean jreSupportsTarget = jreimplloc.contains(target);
 
             for (Locale test: testloc) {
                 // codes
@@ -67,7 +73,7 @@
                     providersvrnt = lnp.getDisplayVariant(vrnt, target);
                 }
 
-                // JRE's name (if any)
+                // JRE's name
                 String jreslang = null;
                 String jresctry = null;
                 String jresvrnt = null;
@@ -84,18 +90,41 @@
                 if (!vrnt.equals("")) {
                     try {
                         jresvrnt = rb.getString("%%"+vrnt);
-                    } catch (MissingResourceException mre) {
-                        jresvrnt = vrnt;
-                    }
+                    } catch (MissingResourceException mre) {}
                 }
 
+                System.out.print("For key: "+lang+" ");
                 checkValidity(target, jreslang, providerslang, langresult,
-                    jreHasBundle && rb.handleGetKeys().contains(lang));
+                    jreSupportsTarget && jreslang != null);
+                System.out.print("For key: "+ctry+" ");
                 checkValidity(target, jresctry, providersctry, ctryresult,
-                    jreHasBundle && rb.handleGetKeys().contains(ctry));
+                    jreSupportsTarget && jresctry != null);
+                System.out.print("For key: "+vrnt+" ");
                 checkValidity(target, jresvrnt, providersvrnt, vrntresult,
-                    jreHasBundle && rb.handleGetKeys().contains("%%"+vrnt));
+                    jreSupportsTarget && jresvrnt != null);
             }
         }
     }
+
+    void variantFallbackTest() {
+        Locale YY = new Locale("yy", "YY", "YYYY");
+        Locale YY_suffix = new Locale("yy", "YY", "YYYY_suffix");
+        String retVrnt = null;
+        String message = "variantFallbackTest() succeeded.";
+
+
+        try {
+            YY.getDisplayVariant(YY_suffix);
+            message = "variantFallbackTest() failed. Either provider wasn't invoked, or invoked without suffix.";
+        } catch (RuntimeException re) {
+            retVrnt = re.getMessage();
+            if (YY_suffix.getVariant().equals(retVrnt)) {
+                System.out.println(message);
+                return;
 }
+            message = "variantFallbackTest() failed. Returned variant: "+retVrnt;
+        }
+
+        throw new RuntimeException(message);
+    }
+}
--- a/jdk/test/java/util/PluggableLocale/LocaleNameProviderTest.sh	Mon Oct 15 22:34:35 2012 +0100
+++ b/jdk/test/java/util/PluggableLocale/LocaleNameProviderTest.sh	Tue Oct 16 10:59:21 2012 -0700
@@ -23,6 +23,6 @@
 #!/bin/sh
 #
 # @test
-# @bug 4052440
+# @bug 4052440 8000273
 # @summary LocaleNameProvider tests
 # @run shell ExecTest.sh bar LocaleNameProviderTest true
--- a/jdk/test/java/util/PluggableLocale/ProviderTest.java	Mon Oct 15 22:34:35 2012 +0100
+++ b/jdk/test/java/util/PluggableLocale/ProviderTest.java	Tue Oct 16 10:59:21 2012 -0700
@@ -42,5 +42,7 @@
                     "result do not match with provider's result. target: "+target+" result: "+result+" providers: "+providers);
             }
         }
+
+        System.out.println("checkValidity succeeded. target: "+target+" result: "+result+" jre's: "+jres+" providers: "+providers+" jre-preferred: "+jresPreferred);
     }
 }
--- a/jdk/test/java/util/PluggableLocale/TimeZoneNameProviderTest.java	Mon Oct 15 22:34:35 2012 +0100
+++ b/jdk/test/java/util/PluggableLocale/TimeZoneNameProviderTest.java	Tue Oct 16 10:59:21 2012 -0700
@@ -45,13 +45,14 @@
 
     void test1() {
         Locale[] available = Locale.getAvailableLocales();
+        List<Locale> jreimplloc = Arrays.asList(LocaleProviderAdapter.forJRE().getTimeZoneNameProvider().getAvailableLocales());
         List<Locale> providerLocales = Arrays.asList(tznp.getAvailableLocales());
         String[] ids = TimeZone.getAvailableIDs();
 
         for (Locale target: available) {
             // pure JRE implementation
             OpenListResourceBundle rb = LocaleProviderAdapter.forJRE().getLocaleData().getTimeZoneNames(target);
-            boolean jreHasBundle = rb.getLocale().equals(target);
+            boolean jreSupportsTarget = jreimplloc.contains(target);
 
             for (String id: ids) {
                 // the time zone
@@ -59,7 +60,7 @@
 
                 // JRE string array for the id
                 String[] jrearray = null;
-                if (jreHasBundle) {
+                if (jreSupportsTarget) {
                     try {
                         jrearray = rb.getStringArray(id);
                     } catch (MissingResourceException mre) {}
@@ -75,14 +76,14 @@
                         providersname = tznp.getDisplayName(id, i>=3, i%2, target);
                     }
 
-                    // JRE's name (if any)
+                    // JRE's name
                     String jresname = null;
                     if (jrearray != null) {
                         jresname = jrearray[i];
                     }
 
                     checkValidity(target, jresname, providersname, name,
-                        jreHasBundle && rb.handleGetKeys().contains(id));
+                        jreSupportsTarget && jresname != null);
                 }
             }
         }
--- a/jdk/test/java/util/PluggableLocale/providersrc/LocaleNameProviderImpl.java	Mon Oct 15 22:34:35 2012 +0100
+++ b/jdk/test/java/util/PluggableLocale/providersrc/LocaleNameProviderImpl.java	Tue Oct 16 10:59:21 2012 -0700
@@ -37,57 +37,64 @@
                              Locale.JAPAN,
                              new Locale("ja", "JP", "osaka"),
                              new Locale("ja", "JP", "kyoto"),
-                             new Locale("xx")};
+                             new Locale("xx"),
+                             new Locale("yy", "YY", "YYYY")};
     static List<Locale> availList = Arrays.asList(avail);
     public Locale[] getAvailableLocales() {
         return avail;
     }
 
+    @Override
     public String getDisplayLanguage(String lang, Locale target) {
+        return getDisplayString(lang, target);
+    }
+
+    @Override
+    public String getDisplayCountry(String ctry, Locale target) {
+        return getDisplayString(ctry, target);
+    }
+
+    @Override
+    public String getDisplayVariant(String vrnt, Locale target) {
+        return getDisplayString(vrnt, target);
+    }
+
+    private String getDisplayString(String key, Locale target) {
         if (!Utils.supportsLocale(availList, target)) {
             throw new IllegalArgumentException("locale is not supported: "+target);
         }
 
         String ret = null;
 
+        if (target.getLanguage().equals("yy") &&
+            target.getCountry().equals("YY")) {
+            String vrnt = target.getVariant();
+            if (vrnt.startsWith("YYYY")) {
+                switch (key) {
+                    case "yy":
+                    case "YY":
+                        ret = "waiwai";
+                        break;
+
+                    case "YYYY":
+                        if (vrnt.equals("YYYY_suffix")) {
+                            // for LocaleNameProviderTest.variantFallbackTest()
+                            throw new RuntimeException(vrnt);
+                        } else {
+                            ret = "waiwai";
+                        }
+                        break;
+                }
+            }
+        } else {
+            // resource bundle based (allows fallback)
         try {
             ResourceBundle rb = ResourceBundle.getBundle("com.bar.LocaleNames", target);
-            ret = rb.getString(lang);
+                ret = rb.getString(key);
         } catch (MissingResourceException mre) {
         }
+        }
 
         return ret;
     }
-
-    public String getDisplayCountry(String ctry, Locale target) {
-        if (!Utils.supportsLocale(availList, target)) {
-            throw new IllegalArgumentException("locale is not supported: "+target);
         }
-
-        String ret = null;
-
-        try {
-            ResourceBundle rb = ResourceBundle.getBundle("LocaleNames", target);
-            ret = rb.getString(ctry);
-        } catch (MissingResourceException mre) {
-        }
-
-        return ret;
-    }
-
-    public String getDisplayVariant(String vrnt, Locale target) {
-        if (!Utils.supportsLocale(availList, target)) {
-            throw new IllegalArgumentException("locale is not supported: "+target);
-        }
-
-        String ret = null;
-
-        try {
-            ResourceBundle rb = ResourceBundle.getBundle("LocaleNames", target);
-            ret = rb.getString(vrnt);
-        } catch (MissingResourceException mre) {
-        }
-
-        return ret;
-    }
-}