1/*
2 * Copyright (c) 2017, 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.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24/*
25 * @test
26 * @bug 8167273
27 * @summary Test
28 * Era names retrieved from Calendar and DateFormatSymbols class
29 * should match for default providers preference
30 * as well as when  preference list is [COMPAT, CLDR],
31 * Empty era names are not retrieved from DateformatSymbols class.
32 * Equivalent locales specified for [zh-HK, no-NO, no] for
33 * CLDR Provider works correctly.
34 * Implict COMPAT Locale nb is reflected in available locales
35 * for all Providers for COMPAT.
36 * @modules java.base/sun.util.locale.provider
37 *          java.base/sun.util.spi
38 *          jdk.localedata
39 * @run main/othervm -Djava.locale.providers=COMPAT,CLDR Bug8167273 testEraName
40 * @run main/othervm  Bug8167273 testEraName
41 * @run main/othervm -Djava.locale.providers=CLDR Bug8167273 testCldr
42 * @run main/othervm  Bug8167273 testEmptyEraNames
43 * @run main/othervm  -Djava.locale.providers=COMPAT Bug8167273 testCompat
44 */
45import java.text.DateFormatSymbols;
46import java.util.Arrays;
47import java.util.Calendar;
48import java.util.HashSet;
49import java.util.List;
50import java.util.Locale;
51import java.util.Map;
52import java.util.Set;
53
54import sun.util.locale.provider.LocaleProviderAdapter;
55import sun.util.locale.provider.LocaleProviderAdapter.Type;
56
57public class Bug8167273 {
58
59    public static void main(String[] args) throws Exception {
60        switch (args[0]) {
61            case "testEraName":
62                testEraName();
63                break;
64            case "testEmptyEraNames":
65                testEmptyEraNames();
66                break;
67            case "testCldr":
68                testCldrSupportedLocales();
69                break;
70            case "testCompat":
71                testCompatSupportedLocale();
72                break;
73            default:
74                throw new RuntimeException("no test was specified.");
75        }
76    }
77
78    /**
79     * tests that era names retrieved from Calendar.getDisplayNames map should
80     * match with that of Era names retrieved from DateFormatSymbols.getEras()
81     * method for all Gregorian Calendar locales .
82     */
83    public static void testEraName() {
84        Set<Locale> allLocales = Set.of(Locale.getAvailableLocales());
85        Set<Locale> JpThlocales = Set.of(
86                new Locale("th", "TH"),
87                new Locale("ja", "JP", "JP"), new Locale("th", "TH", "TH")
88        );
89        Set<Locale> allLocs = new HashSet<>(allLocales);
90        // Removing Japense and Thai Locales to check  Gregorian Calendar Locales
91        allLocs.removeAll(JpThlocales);
92        allLocs.forEach((locale) -> {
93            Calendar cal = Calendar.getInstance(locale);
94            Map<String, Integer> names = cal.getDisplayNames(Calendar.ERA, Calendar.ALL_STYLES, locale);
95            DateFormatSymbols symbols = new DateFormatSymbols(locale);
96            String[] eras = symbols.getEras();
97            for (String era : eras) {
98                if (!names.containsKey(era)) {
99                    reportMismatch(names.keySet(), eras, locale);
100                }
101            }
102        });
103    }
104
105    private static void reportMismatch(Set<String> CalendarEras, String[] dfsEras, Locale locale) {
106        System.out.println("For Locale  " + locale + "era names in calendar map are  " + CalendarEras);
107        for (String era : dfsEras) {
108            System.out.println("For Locale  " + locale + " era names in DateFormatSymbols era array are  " + era);
109        }
110        throw new RuntimeException(" Era name retrived from Calendar class do not match with"
111                + " retrieved from DateFormatSymbols  for Locale   " + locale);
112
113    }
114
115    /**
116     * tests that Eras names returned from DateFormatSymbols.getEras()
117     * and Calendar.getDisplayNames() should not be empty for any Locale.
118     */
119    private static void testEmptyEraNames() {
120        Set<Locale> allLocales = Set.of(Locale.getAvailableLocales());
121        allLocales.forEach((loc) -> {
122            DateFormatSymbols dfs = new DateFormatSymbols(loc);
123            Calendar cal = Calendar.getInstance(loc);
124            Map<String, Integer> names = cal.getDisplayNames(Calendar.ERA, Calendar.ALL_STYLES, loc);
125            Set<String> CalendarEraNames = names.keySet();
126            String[] eras = dfs.getEras();
127            for (String era : eras) {
128                if (era.isEmpty()) {
129                    throw new RuntimeException("Empty era names retrieved for DateFomatSymbols.getEras"
130                            + " for locale " + loc);
131                }
132            }
133            CalendarEraNames.stream().filter((erakey) -> (erakey.isEmpty())).forEachOrdered((l) -> {
134                throw new RuntimeException("Empty era names retrieved for Calendar.getDisplayName"
135                        + " for locale " + loc);
136            });
137        });
138
139    }
140
141    /**
142     * tests that CLDR provider should return true for locale zh_HK, no-NO and
143     * no.
144     */
145    private static void testCldrSupportedLocales() {
146        Set<Locale> locales = Set.of(Locale.forLanguageTag("zh-HK"),
147                Locale.forLanguageTag("no-NO"),
148                Locale.forLanguageTag("no"));
149        LocaleProviderAdapter cldr = LocaleProviderAdapter.forType(Type.CLDR);
150        Set<Locale> availableLocs = Set.of(cldr.getAvailableLocales());
151        Set<String> langtags = new HashSet<>();
152        availableLocs.forEach((loc) -> {
153            langtags.add(loc.toLanguageTag());
154        });
155
156        locales.stream().filter((loc) -> (!cldr.isSupportedProviderLocale(loc, langtags))).forEachOrdered((loc) -> {
157            throw new RuntimeException("Locale " + loc + "  is not supported by CLDR Locale Provider");
158        });
159    }
160
161    /**
162     * Tests that locale nb should be supported by JRELocaleProvider .
163     */
164    private static void testCompatSupportedLocale() {
165        LocaleProviderAdapter jre = LocaleProviderAdapter.forJRE();
166        checkPresenceCompat("BreakIteratorProvider",
167                jre.getBreakIteratorProvider().getAvailableLocales());
168        checkPresenceCompat("CollatorProvider",
169                jre.getCollatorProvider().getAvailableLocales());
170        checkPresenceCompat("DateFormatProvider",
171                jre.getDateFormatProvider().getAvailableLocales());
172        checkPresenceCompat("DateFormatSymbolsProvider",
173                jre.getDateFormatSymbolsProvider().getAvailableLocales());
174        checkPresenceCompat("DecimalFormatSymbolsProvider",
175                jre.getDecimalFormatSymbolsProvider().getAvailableLocales());
176        checkPresenceCompat("NumberFormatProvider",
177                jre.getNumberFormatProvider().getAvailableLocales());
178        checkPresenceCompat("CurrencyNameProvider",
179                jre.getCurrencyNameProvider().getAvailableLocales());
180        checkPresenceCompat("LocaleNameProvider",
181                jre.getLocaleNameProvider().getAvailableLocales());
182        checkPresenceCompat("TimeZoneNameProvider",
183                jre.getTimeZoneNameProvider().getAvailableLocales());
184        checkPresenceCompat("CalendarDataProvider",
185                jre.getCalendarDataProvider().getAvailableLocales());
186        checkPresenceCompat("CalendarNameProvider",
187                jre.getCalendarNameProvider().getAvailableLocales());
188        checkPresenceCompat("CalendarProvider",
189                jre.getCalendarProvider().getAvailableLocales());
190    }
191
192    private static void checkPresenceCompat(String testName, Locale[] got) {
193        List<Locale> gotLocalesList = Arrays.asList(got);
194        Locale nb = Locale.forLanguageTag("nb");
195        if (!gotLocalesList.contains(nb)) {
196            throw new RuntimeException("Locale nb not supported by JREProvider for "
197                    + testName + " test ");
198        }
199    }
200}
201