8013903: Japanese calendar field names are not displayed with -Djava.locale.providers=HOST on Windows
authornaoto
Tue, 04 Jun 2013 10:33:13 -0700
changeset 17944 bbd67fc49daa
parent 17943 a8293d390273
child 17945 97634ef9dd1c
8013903: Japanese calendar field names are not displayed with -Djava.locale.providers=HOST on Windows Reviewed-by: okutsu
jdk/src/share/classes/java/util/spi/LocaleServiceProvider.java
jdk/src/share/classes/sun/util/locale/provider/FallbackLocaleProviderAdapter.java
jdk/src/share/classes/sun/util/locale/provider/JRELocaleProviderAdapter.java
jdk/src/share/classes/sun/util/locale/provider/LocaleProviderAdapter.java
jdk/src/share/classes/sun/util/locale/provider/LocaleServiceProviderPool.java
jdk/src/windows/classes/sun/util/locale/provider/HostLocaleProviderAdapterImpl.java
jdk/test/java/util/Locale/LocaleProviders.java
jdk/test/java/util/Locale/LocaleProviders.sh
--- a/jdk/src/share/classes/java/util/spi/LocaleServiceProvider.java	Tue Jun 04 15:18:39 2013 +0100
+++ b/jdk/src/share/classes/java/util/spi/LocaleServiceProvider.java	Tue Jun 04 10:33:13 2013 -0700
@@ -128,6 +128,14 @@
  * installed SPI providers, and "JRE" represents the locale sensitive services
  * in the Java Runtime Environment, the locale sensitive services in the SPI
  * providers are looked up first.
+ * <p>
+ * There are two other possible locale sensitive service providers, i.e., "CLDR"
+ * which is a provider based on Unicode Consortium's
+ * <a href="http://cldr.unicode.org/">CLDR Project</a>, and "HOST" which is a
+ * provider that reflects the user's custom settings in the underlying operating
+ * system. These two providers may not be available, depending on the Java Runtime
+ * Environment implementation. Specifying "JRE,SPI" is identical to the default
+ * behavior, which is compatibile with the prior releases.
  *
  * @since        1.6
  */
--- a/jdk/src/share/classes/sun/util/locale/provider/FallbackLocaleProviderAdapter.java	Tue Jun 04 15:18:39 2013 +0100
+++ b/jdk/src/share/classes/sun/util/locale/provider/FallbackLocaleProviderAdapter.java	Tue Jun 04 10:33:13 2013 -0700
@@ -25,6 +25,11 @@
 
 package sun.util.locale.provider;
 
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Set;
+
 /**
  * FallbackProviderAdapter implementation.
  *
@@ -33,10 +38,32 @@
 public class FallbackLocaleProviderAdapter extends JRELocaleProviderAdapter {
 
     /**
+     * Supported language tag set.
+     */
+    private static final Set<String> rootTagSet =
+        Collections.singleton(Locale.ROOT.toLanguageTag());
+
+    /**
+     * Fallback provider only provides the ROOT locale data.
+     */
+    private final LocaleResources rootLocaleResources =
+        new LocaleResources(this, Locale.ROOT);
+
+    /**
      * Returns the type of this LocaleProviderAdapter
      */
     @Override
     public LocaleProviderAdapter.Type getAdapterType() {
         return Type.FALLBACK;
     }
+
+    @Override
+    public LocaleResources getLocaleResources(Locale locale) {
+        return rootLocaleResources;
+    }
+
+    @Override
+    protected Set<String> createLanguageTagSet(String category) {
+        return rootTagSet;
+    }
 }
--- a/jdk/src/share/classes/sun/util/locale/provider/JRELocaleProviderAdapter.java	Tue Jun 04 15:18:39 2013 +0100
+++ b/jdk/src/share/classes/sun/util/locale/provider/JRELocaleProviderAdapter.java	Tue Jun 04 10:33:13 2013 -0700
@@ -34,12 +34,10 @@
 import java.text.spi.DateFormatSymbolsProvider;
 import java.text.spi.DecimalFormatSymbolsProvider;
 import java.text.spi.NumberFormatProvider;
-import java.util.Calendar;
 import java.util.HashSet;
 import java.util.Locale;
 import java.util.Set;
 import java.util.StringTokenizer;
-import java.util.TimeZone;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import java.util.spi.CalendarDataProvider;
--- a/jdk/src/share/classes/sun/util/locale/provider/LocaleProviderAdapter.java	Tue Jun 04 15:18:39 2013 +0100
+++ b/jdk/src/share/classes/sun/util/locale/provider/LocaleProviderAdapter.java	Tue Jun 04 10:33:13 2013 -0700
@@ -120,6 +120,12 @@
     private static LocaleProviderAdapter fallbackLocaleProviderAdapter = null;
 
     /**
+     * Default fallback adapter type, which should return something meaningful in any case.
+     * This is either JRE or FALLBACK.
+     */
+    static LocaleProviderAdapter.Type defaultLocaleProviderAdapter = null;
+
+    /**
      * Adapter lookup cache.
      */
     private static ConcurrentMap<Class<? extends LocaleServiceProvider>, ConcurrentMap<Locale, LocaleProviderAdapter>>
@@ -140,13 +146,19 @@
                     // load adapter if necessary
                     switch (aType) {
                         case CLDR:
-                            cldrLocaleProviderAdapter = new CLDRLocaleProviderAdapter();
+                            if (cldrLocaleProviderAdapter == null) {
+                                cldrLocaleProviderAdapter = new CLDRLocaleProviderAdapter();
+                            }
                             break;
                         case HOST:
-                            hostLocaleProviderAdapter = new HostLocaleProviderAdapter();
+                            if (hostLocaleProviderAdapter == null) {
+                                hostLocaleProviderAdapter = new HostLocaleProviderAdapter();
+                            }
                             break;
                     }
-                    typeList.add(aType);
+                    if (!typeList.contains(aType)) {
+                        typeList.add(aType);
+                    }
                 } catch (IllegalArgumentException | UnsupportedOperationException e) {
                     // could be caused by the user specifying wrong
                     // provider name or format in the system property
@@ -160,11 +172,15 @@
                 // Append FALLBACK as the last resort.
                 fallbackLocaleProviderAdapter = new FallbackLocaleProviderAdapter();
                 typeList.add(Type.FALLBACK);
+                defaultLocaleProviderAdapter = Type.FALLBACK;
+            } else {
+                defaultLocaleProviderAdapter = Type.JRE;
             }
         } else {
             // Default preference list
             typeList.add(Type.JRE);
             typeList.add(Type.SPI);
+            defaultLocaleProviderAdapter = Type.JRE;
         }
 
         adapterPreference = Collections.unmodifiableList(typeList);
--- a/jdk/src/share/classes/sun/util/locale/provider/LocaleServiceProviderPool.java	Tue Jun 04 15:18:39 2013 +0100
+++ b/jdk/src/share/classes/sun/util/locale/provider/LocaleServiceProviderPool.java	Tue Jun 04 10:33:13 2013 -0700
@@ -127,32 +127,13 @@
     private LocaleServiceProviderPool (final Class<? extends LocaleServiceProvider> c) {
         providerClass = c;
 
-        // Add the JRE Locale Data Adapter implementation.
-        providers.putIfAbsent(LocaleProviderAdapter.Type.JRE,
-            LocaleProviderAdapter.forJRE().getLocaleServiceProvider(c));
-
-        // Add the SPI Locale Data Adapter implementation.
-        LocaleProviderAdapter lda = LocaleProviderAdapter.forType(LocaleProviderAdapter.Type.SPI);
-        LocaleServiceProvider provider = lda.getLocaleServiceProvider(c);
-        if (provider != null) {
-            providers.putIfAbsent(LocaleProviderAdapter.Type.SPI, provider);
-        }
-
-        // Add the CLDR Locale Data Adapter implementation, if needed.
-        lda =  LocaleProviderAdapter.forType(LocaleProviderAdapter.Type.CLDR);
-        if (lda != null) {
-            provider = lda.getLocaleServiceProvider(c);
-            if (provider != null) {
-                providers.putIfAbsent(LocaleProviderAdapter.Type.CLDR, provider);
-            }
-        }
-
-        // Add the Host Locale Data Adapter implementation, if needed.
-        lda =  LocaleProviderAdapter.forType(LocaleProviderAdapter.Type.HOST);
-        if (lda != null) {
-            provider = lda.getLocaleServiceProvider(c);
-            if (provider != null) {
-                providers.putIfAbsent(LocaleProviderAdapter.Type.HOST, provider);
+        for (LocaleProviderAdapter.Type type : LocaleProviderAdapter.getAdapterPreference()) {
+            LocaleProviderAdapter lda = LocaleProviderAdapter.forType(type);
+            if (lda != null) {
+                LocaleServiceProvider provider = lda.getLocaleServiceProvider(c);
+                if (provider != null) {
+                    providers.putIfAbsent(type, provider);
+                }
             }
         }
     }
@@ -246,7 +227,8 @@
      */
     boolean hasProviders() {
         return providers.size() != 1 ||
-               providers.get(LocaleProviderAdapter.Type.JRE) == null;
+               (providers.get(LocaleProviderAdapter.Type.JRE) == null &&
+                providers.get(LocaleProviderAdapter.Type.FALLBACK) == null);
     }
 
     /**
@@ -296,9 +278,8 @@
         // Check whether JRE is the sole locale data provider or not,
         // and directly call it if it is.
         if (!hasProviders()) {
-            return getter.getObject(
-                (P)providers.get(LocaleProviderAdapter.Type.JRE),
-                locale, key, params);
+            return getter.getObject((P)providers.get(LocaleProviderAdapter.defaultLocaleProviderAdapter),
+                                    locale, key, params);
         }
 
         List<Locale> lookupLocales = getLookupLocales(locale);
--- a/jdk/src/windows/classes/sun/util/locale/provider/HostLocaleProviderAdapterImpl.java	Tue Jun 04 15:18:39 2013 +0100
+++ b/jdk/src/windows/classes/sun/util/locale/provider/HostLocaleProviderAdapterImpl.java	Tue Jun 04 10:33:13 2013 -0700
@@ -48,7 +48,6 @@
 import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.atomic.AtomicReferenceArray;
 import java.util.spi.CalendarDataProvider;
-import java.util.spi.CalendarNameProvider;
 import java.util.spi.CurrencyNameProvider;
 import java.util.spi.LocaleNameProvider;
 import sun.util.spi.CalendarProvider;
@@ -364,32 +363,6 @@
         };
     }
 
-    public static CalendarNameProvider getCalendarNameProvider() {
-        return new CalendarNameProvider() {
-            @Override
-            public Locale[] getAvailableLocales() {
-                return getSupportedCalendarLocales();
-            }
-
-            @Override
-            public boolean isSupportedLocale(Locale locale) {
-                return isSupportedCalendarLocale(locale);
-            }
-
-            @Override
-            public String getDisplayName(String calType, int field, int value,
-                                         int style, Locale locale) {
-                return null;
-            }
-
-            @Override
-            public Map<String, Integer> getDisplayNames(String calType,
-                                         int field, int style, Locale locale) {
-                return null;
-            }
-        };
-    }
-
     public static CalendarProvider getCalendarProvider() {
         return new CalendarProvider() {
             @Override
--- a/jdk/test/java/util/Locale/LocaleProviders.java	Tue Jun 04 15:18:39 2013 +0100
+++ b/jdk/test/java/util/Locale/LocaleProviders.java	Tue Jun 04 10:33:13 2013 -0700
@@ -64,6 +64,10 @@
                 bug8013086Test(args[1], args[2]);
                 break;
 
+            case "bug8013903Test":
+                bug8013903Test();
+                break;
+
             default:
                 throw new RuntimeException("Test method '"+methodName+"' not found.");
         }
@@ -195,4 +199,30 @@
             // ParseException is fine in this test, as it's not "UTC"
 }
     }
+
+    static void bug8013903Test() {
+        if (System.getProperty("os.name").startsWith("Windows")) {
+            Date sampleDate = new Date(0x10000000000L);
+            String fallbackResult = "Heisei 16.Nov.03 (Wed) AM 11:53:47";
+            String jreResult = "\u5e73\u6210 16.11.03 (\u6c34) \u5348\u524d 11:53:47";
+            Locale l = new Locale("ja", "JP", "JP");
+            SimpleDateFormat sdf = new SimpleDateFormat("GGGG yyyy.MMM.dd '('E')' a hh:mm:ss", l);
+            String result = sdf.format(sampleDate);
+            System.out.println(result);
+            if (LocaleProviderAdapter.getAdapterPreference()
+                .contains(LocaleProviderAdapter.Type.JRE)) {
+                if (!jreResult.equals(result)) {
+                    throw new RuntimeException("Format failed. result: \"" +
+                        result + "\", expected: \"" + jreResult);
+                }
+            } else {
+                // should be FALLBACK, as Windows HOST does not return
+                // display names
+                if (!fallbackResult.equals(result)) {
+                    throw new RuntimeException("Format failed. result: \"" +
+                        result + "\", expected: \"" + fallbackResult);
+                }
+            }
+        }
+    }
 }
--- a/jdk/test/java/util/Locale/LocaleProviders.sh	Tue Jun 04 15:18:39 2013 +0100
+++ b/jdk/test/java/util/Locale/LocaleProviders.sh	Tue Jun 04 10:33:13 2013 -0700
@@ -24,7 +24,7 @@
 #
 # @test
 # @bug 6336885 7196799 7197573 7198834 8000245 8000615 8001440 8010666
-#      8013086 8013233
+#      8013086 8013233 8013903
 # @summary tests for "java.locale.providers" system property
 # @compile -XDignore.symbol.file LocaleProviders.java
 # @run shell/timeout=600 LocaleProviders.sh
@@ -300,4 +300,18 @@
 PARAM3=
 runTest
 
+# testing 8013903 fix. (Windows only)
+METHODNAME=bug8013903Test
+PREFLIST=HOST,JRE
+PARAM1=
+PARAM2=
+PARAM3=
+runTest
+METHODNAME=bug8013903Test
+PREFLIST=HOST
+PARAM1=
+PARAM2=
+PARAM3=
+runTest
+
 exit $result