8001205: Calendar.getDisplayName(...): Returns null when provider is SPI but there is no SPI implementation
authornaoto
Wed, 07 Nov 2012 15:08:28 -0800
changeset 14418 967376921f20
parent 14417 4615017b9cab
child 14419 e5214ad6600a
8001205: Calendar.getDisplayName(...): Returns null when provider is SPI but there is no SPI implementation 8001562: Collator.getAvailableLocales() doesn't return all locales for which localized instances are available Reviewed-by: okutsu
jdk/src/share/classes/sun/util/locale/provider/JRELocaleProviderAdapter.java
jdk/src/share/classes/sun/util/locale/provider/LocaleServiceProviderPool.java
jdk/test/java/util/Locale/Bug8001562.java
jdk/test/java/util/PluggableLocale/BreakIteratorProviderTest.java
jdk/test/java/util/PluggableLocale/CollatorProviderTest.java
jdk/test/java/util/PluggableLocale/DateFormatProviderTest.java
jdk/test/java/util/PluggableLocale/DateFormatSymbolsProviderTest.java
jdk/test/java/util/PluggableLocale/DecimalFormatSymbolsProviderTest.java
jdk/test/java/util/PluggableLocale/GenericTest.java
jdk/test/java/util/PluggableLocale/NumberFormatProviderTest.java
--- a/jdk/src/share/classes/sun/util/locale/provider/JRELocaleProviderAdapter.java	Wed Nov 07 16:07:54 2012 -0500
+++ b/jdk/src/share/classes/sun/util/locale/provider/JRELocaleProviderAdapter.java	Wed Nov 07 15:08:28 2012 -0800
@@ -329,9 +329,6 @@
             tagset.add(token);
         }
 
-        // ensure en-US is there (mandated by the spec, e.g. Collator.getAvailableLocales())
-        tagset.add("en-US");
-
         return tagset;
     }
 
--- a/jdk/src/share/classes/sun/util/locale/provider/LocaleServiceProviderPool.java	Wed Nov 07 16:07:54 2012 -0500
+++ b/jdk/src/share/classes/sun/util/locale/provider/LocaleServiceProviderPool.java	Wed Nov 07 15:08:28 2012 -0800
@@ -26,6 +26,7 @@
 package sun.util.locale.provider;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.IllformedLocaleException;
@@ -177,7 +178,7 @@
             for (Class<? extends LocaleServiceProvider> c : spiClasses) {
                 LocaleServiceProviderPool pool =
                     LocaleServiceProviderPool.getPool(c);
-                all.addAll(pool.getAvailableLocaleList());
+                all.addAll(pool.getAvailableLocaleSet());
             }
 
             allAvailableLocales = all.toArray(new Locale[0]);
@@ -207,13 +208,23 @@
      * @return an array of the available locales
      */
     public Locale[] getAvailableLocales() {
-        Set<Locale> locList = getAvailableLocaleList();
+        Set<Locale> locList = new HashSet<>();
+        locList.addAll(getAvailableLocaleSet());
+        // Make sure it all contains JRE's locales for compatibility.
+        locList.addAll(Arrays.asList(LocaleProviderAdapter.forJRE().getAvailableLocales()));
         Locale[] tmp = new Locale[locList.size()];
         locList.toArray(tmp);
         return tmp;
     }
 
-    private synchronized Set<Locale> getAvailableLocaleList() {
+    /**
+     * Returns the union of locale sets that are available from
+     * each service provider. This method does NOT return the
+     * defensive copy.
+     *
+     * @return a set of available locales
+     */
+    private synchronized Set<Locale> getAvailableLocaleSet() {
         if (availableLocales == null) {
             availableLocales = new HashSet<>();
             for (LocaleServiceProvider lsp : providers.values()) {
@@ -222,9 +233,6 @@
                     availableLocales.add(getLookupLocale(locale));
                 }
             }
-
-            // Remove Locale.ROOT for the compatibility.
-            availableLocales.remove(Locale.ROOT);
         }
 
         return availableLocales;
@@ -295,7 +303,7 @@
 
         List<Locale> lookupLocales = getLookupLocales(locale);
 
-        Set<Locale> available = getAvailableLocaleList();
+        Set<Locale> available = getAvailableLocaleSet();
         for (Locale current : lookupLocales) {
             if (available.contains(current)) {
                 S providersObj;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/Locale/Bug8001562.java	Wed Nov 07 15:08:28 2012 -0800
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 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.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8001562
+ * @summary Verify that getAvailableLocales() in locale sensitive services
+ *     classes return compatible set of locales as in JDK7.
+ * @run main Bug8001562
+ */
+
+import java.text.*;
+import java.util.*;
+
+public class Bug8001562 {
+
+    static final String[] jdk7availTags = {
+        "ar", "ar-AE", "ar-BH", "ar-DZ", "ar-EG", "ar-IQ", "ar-JO", "ar-KW",
+        "ar-LB", "ar-LY", "ar-MA", "ar-OM", "ar-QA", "ar-SA", "ar-SD", "ar-SY",
+        "ar-TN", "ar-YE", "be", "be-BY", "bg", "bg-BG", "ca", "ca-ES", "cs",
+        "cs-CZ", "da", "da-DK", "de", "de-AT", "de-CH", "de-DE", "de-LU", "el",
+        "el-CY", "el-GR", "en", "en-AU", "en-CA", "en-GB", "en-IE", "en-IN",
+        "en-MT", "en-NZ", "en-PH", "en-SG", "en-US", "en-ZA", "es", "es-AR",
+        "es-BO", "es-CL", "es-CO", "es-CR", "es-DO", "es-EC", "es-ES", "es-GT",
+        "es-HN", "es-MX", "es-NI", "es-PA", "es-PE", "es-PR", "es-PY", "es-SV",
+        "es-US", "es-UY", "es-VE", "et", "et-EE", "fi", "fi-FI", "fr", "fr-BE",
+        "fr-CA", "fr-CH", "fr-FR", "fr-LU", "ga", "ga-IE", "he", "he-IL",
+        "hi-IN", "hr", "hr-HR", "hu", "hu-HU", "id", "id-ID", "is", "is-IS",
+        "it", "it-CH", "it-IT", "ja", "ja-JP",
+        "ja-JP-u-ca-japanese-x-lvariant-JP", "ko", "ko-KR", "lt", "lt-LT", "lv",
+        "lv-LV", "mk", "mk-MK", "ms", "ms-MY", "mt", "mt-MT", "nl", "nl-BE",
+        "nl-NL", "no", "no-NO", "no-NO-x-lvariant-NY", "pl", "pl-PL", "pt",
+        "pt-BR", "pt-PT", "ro", "ro-RO", "ru", "ru-RU", "sk", "sk-SK", "sl",
+        "sl-SI", "sq", "sq-AL", "sr", "sr-BA", "sr-CS", "sr-Latn", "sr-Latn-BA",
+        "sr-Latn-ME", "sr-Latn-RS", "sr-ME", "sr-RS", "sv", "sv-SE", "th",
+        "th-TH", "th-TH-u-nu-thai-x-lvariant-TH", "tr", "tr-TR", "uk", "uk-UA",
+        "vi", "vi-VN", "zh", "zh-CN", "zh-HK", "zh-SG", "zh-TW", };
+    static List<Locale> jdk7availLocs = new ArrayList<>();
+    static {
+        for (String locStr : jdk7availTags) {
+            jdk7availLocs.add(Locale.forLanguageTag(locStr));
+        }
+    }
+
+    public static void main(String[] args) {
+        List<Locale> avail = Arrays.asList(BreakIterator.getAvailableLocales());
+        diffLocale(BreakIterator.class, avail);
+
+        avail = Arrays.asList(Collator.getAvailableLocales());
+        diffLocale(Collator.class, avail);
+
+        avail = Arrays.asList(DateFormat.getAvailableLocales());
+        diffLocale(DateFormat.class, avail);
+
+        avail = Arrays.asList(DateFormatSymbols.getAvailableLocales());
+        diffLocale(DateFormatSymbols.class, avail);
+
+        avail = Arrays.asList(DecimalFormatSymbols.getAvailableLocales());
+        diffLocale(DecimalFormatSymbols.class, avail);
+
+        avail = Arrays.asList(NumberFormat.getAvailableLocales());
+        diffLocale(NumberFormat.class, avail);
+
+        avail = Arrays.asList(Locale.getAvailableLocales());
+        diffLocale(Locale.class, avail);
+    }
+
+    static void diffLocale(Class c, List<Locale> locs) {
+        String diff = "";
+
+        System.out.printf("Only in target locales (%s.getAvailableLocales()): ", c.getSimpleName());
+        for (Locale l : locs) {
+            if (!jdk7availLocs.contains(l)) {
+                diff += "\""+l.toLanguageTag()+"\", ";
+            }
+        }
+        System.out.println(diff);
+        diff = "";
+
+        System.out.printf("Only in JDK7 (%s.getAvailableLocales()): ", c.getSimpleName());
+        for (Locale l : jdk7availLocs) {
+            if (!locs.contains(l)) {
+                diff += "\""+l.toLanguageTag()+"\", ";
+            }
+        }
+        System.out.println(diff);
+
+        if (diff.length() > 0) {
+            throw new RuntimeException("Above locale(s) were not included in the target available locales");
+        }
+    }
+}
--- a/jdk/test/java/util/PluggableLocale/BreakIteratorProviderTest.java	Wed Nov 07 16:07:54 2012 -0500
+++ b/jdk/test/java/util/PluggableLocale/BreakIteratorProviderTest.java	Wed Nov 07 15:08:28 2012 -0800
@@ -53,9 +53,8 @@
     }
 
     void availableLocalesTest() {
-        Set<Locale> localesFromAPI = new HashSet<Locale>(availloc);
-        Set<Locale> localesExpected = new HashSet<Locale>(jreimplloc);
-        localesExpected.remove(Locale.ROOT);
+        Set<Locale> localesFromAPI = new HashSet<>(availloc);
+        Set<Locale> localesExpected = new HashSet<>(jreloc);
         localesExpected.addAll(providerloc);
         if (localesFromAPI.equals(localesExpected)) {
             System.out.println("availableLocalesTest passed.");
--- a/jdk/test/java/util/PluggableLocale/CollatorProviderTest.java	Wed Nov 07 16:07:54 2012 -0500
+++ b/jdk/test/java/util/PluggableLocale/CollatorProviderTest.java	Wed Nov 07 15:08:28 2012 -0800
@@ -47,9 +47,8 @@
     }
 
     void availableLocalesTest() {
-        Set<Locale> localesFromAPI = new HashSet<Locale>(availloc);
-        Set<Locale> localesExpected = new HashSet<Locale>(jreimplloc);
-        localesExpected.remove(Locale.ROOT);
+        Set<Locale> localesFromAPI = new HashSet<>(availloc);
+        Set<Locale> localesExpected = new HashSet<>(jreloc);
         localesExpected.addAll(providerloc);
         if (localesFromAPI.equals(localesExpected)) {
             System.out.println("availableLocalesTest passed.");
--- a/jdk/test/java/util/PluggableLocale/DateFormatProviderTest.java	Wed Nov 07 16:07:54 2012 -0500
+++ b/jdk/test/java/util/PluggableLocale/DateFormatProviderTest.java	Wed Nov 07 15:08:28 2012 -0800
@@ -34,6 +34,7 @@
     com.foo.DateFormatProviderImpl dfp = new com.foo.DateFormatProviderImpl();
     List<Locale> availloc = Arrays.asList(DateFormat.getAvailableLocales());
     List<Locale> providerloc = Arrays.asList(dfp.getAvailableLocales());
+    List<Locale> jreloc = Arrays.asList(LocaleProviderAdapter.forJRE().getAvailableLocales());
     List<Locale> jreimplloc = Arrays.asList(LocaleProviderAdapter.forJRE().getDateFormatProvider().getAvailableLocales());
 
     public static void main(String[] s) {
@@ -41,11 +42,23 @@
     }
 
     DateFormatProviderTest() {
+        availableLocalesTest();
         objectValidityTest();
         extendedVariantTest();
         messageFormatTest();
     }
 
+    void availableLocalesTest() {
+        Set<Locale> localesFromAPI = new HashSet<>(availloc);
+        Set<Locale> localesExpected = new HashSet<>(jreloc);
+        localesExpected.addAll(providerloc);
+        if (localesFromAPI.equals(localesExpected)) {
+            System.out.println("availableLocalesTest passed.");
+        } else {
+            throw new RuntimeException("availableLocalesTest failed");
+        }
+    }
+
     void objectValidityTest() {
 
         for (Locale target: availloc) {
--- a/jdk/test/java/util/PluggableLocale/DateFormatSymbolsProviderTest.java	Wed Nov 07 16:07:54 2012 -0500
+++ b/jdk/test/java/util/PluggableLocale/DateFormatSymbolsProviderTest.java	Wed Nov 07 15:08:28 2012 -0800
@@ -48,9 +48,8 @@
     }
 
     void availableLocalesTest() {
-        Set<Locale> localesFromAPI = new HashSet<Locale>(availloc);
-        Set<Locale> localesExpected = new HashSet<Locale>(jreimplloc);
-        localesExpected.remove(Locale.ROOT);
+        Set<Locale> localesFromAPI = new HashSet<>(availloc);
+        Set<Locale> localesExpected = new HashSet<>(jreloc);
         localesExpected.addAll(providerloc);
         if (localesFromAPI.equals(localesExpected)) {
             System.out.println("availableLocalesTest passed.");
--- a/jdk/test/java/util/PluggableLocale/DecimalFormatSymbolsProviderTest.java	Wed Nov 07 16:07:54 2012 -0500
+++ b/jdk/test/java/util/PluggableLocale/DecimalFormatSymbolsProviderTest.java	Wed Nov 07 15:08:28 2012 -0800
@@ -47,9 +47,8 @@
     }
 
     void availableLocalesTest() {
-        Set<Locale> localesFromAPI = new HashSet<Locale>(availloc);
-        Set<Locale> localesExpected = new HashSet<Locale>(jreimplloc);
-        localesExpected.remove(Locale.ROOT);
+        Set<Locale> localesFromAPI = new HashSet<>(availloc);
+        Set<Locale> localesExpected = new HashSet<>(jreloc);
         localesExpected.addAll(providerloc);
         if (localesFromAPI.equals(localesExpected)) {
             System.out.println("availableLocalesTest passed.");
--- a/jdk/test/java/util/PluggableLocale/GenericTest.java	Wed Nov 07 16:07:54 2012 -0500
+++ b/jdk/test/java/util/PluggableLocale/GenericTest.java	Wed Nov 07 15:08:28 2012 -0800
@@ -73,7 +73,6 @@
         expected.addAll(Arrays.asList(localeNP.getAvailableLocales()));
         expected.addAll(Arrays.asList(tzNP.getAvailableLocales()));
         expected.addAll(Arrays.asList(calDataP.getAvailableLocales()));
-        expected.remove(Locale.ROOT);
         if (!result.equals(expected)) {
             throw new RuntimeException("Locale.getAvailableLocales() does not return the union of locales: diff="
                                        + getDiff(result, expected));
--- a/jdk/test/java/util/PluggableLocale/NumberFormatProviderTest.java	Wed Nov 07 16:07:54 2012 -0500
+++ b/jdk/test/java/util/PluggableLocale/NumberFormatProviderTest.java	Wed Nov 07 15:08:28 2012 -0800
@@ -50,9 +50,8 @@
     }
 
     void availableLocalesTest() {
-        Set<Locale> localesFromAPI = new HashSet<Locale>(availloc);
-        Set<Locale> localesExpected = new HashSet<Locale>(jreimplloc);
-        localesExpected.remove(Locale.ROOT);
+        Set<Locale> localesFromAPI = new HashSet<>(availloc);
+        Set<Locale> localesExpected = new HashSet<>(jreloc);
         localesExpected.addAll(providerloc);
         if (localesFromAPI.equals(localesExpected)) {
             System.out.println("availableLocalesTest passed.");