1/*
2 * Copyright (c) 2007, 2013, 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 */
26
27import java.text.*;
28import java.util.*;
29import sun.util.locale.provider.*;
30import sun.util.resources.*;
31
32import com.foo.FooNumberFormat;
33
34public class NumberFormatProviderTest extends ProviderTest {
35
36    com.foo.NumberFormatProviderImpl nfp = new com.foo.NumberFormatProviderImpl();
37    List<Locale> availloc = Arrays.asList(NumberFormat.getAvailableLocales());
38    List<Locale> providerloc = Arrays.asList(nfp.getAvailableLocales());
39    List<Locale> jreloc = Arrays.asList(LocaleProviderAdapter.forJRE().getAvailableLocales());
40    List<Locale> jreimplloc = Arrays.asList(LocaleProviderAdapter.forJRE().getNumberFormatProvider().getAvailableLocales());
41
42    public static void main(String[] s) {
43        new NumberFormatProviderTest();
44    }
45
46    NumberFormatProviderTest() {
47        availableLocalesTest();
48        objectValidityTest();
49        messageFormatTest();
50    }
51
52    void availableLocalesTest() {
53        Set<Locale> localesFromAPI = new HashSet<>(availloc);
54        Set<Locale> localesExpected = new HashSet<>(jreloc);
55        localesExpected.addAll(providerloc);
56        if (localesFromAPI.equals(localesExpected)) {
57            System.out.println("availableLocalesTest passed.");
58        } else {
59            throw new RuntimeException("availableLocalesTest failed");
60        }
61    }
62
63    void objectValidityTest() {
64
65        for (Locale target: availloc) {
66            boolean jreSupportsLocale = jreimplloc.contains(target);
67
68            // JRE string arrays
69            String[] jreNumberPatterns = null;
70            if (jreSupportsLocale) {
71                jreNumberPatterns = LocaleProviderAdapter.forJRE().getLocaleResources(target).getNumberPatterns();
72            }
73
74            // result object
75            String resultCur = getPattern(NumberFormat.getCurrencyInstance(target));
76            String resultInt = getPattern(NumberFormat.getIntegerInstance(target));
77            String resultNum = getPattern(NumberFormat.getNumberInstance(target));
78            String resultPer = getPattern(NumberFormat.getPercentInstance(target));
79
80            // provider's object (if any)
81            String providersCur = null;
82            String providersInt = null;
83            String providersNum = null;
84            String providersPer = null;
85            if (providerloc.contains(target)) {
86                NumberFormat dfCur = nfp.getCurrencyInstance(target);
87                if (dfCur != null) {
88                    providersCur = getPattern(dfCur);
89                }
90                NumberFormat dfInt = nfp.getIntegerInstance(target);
91                if (dfInt != null) {
92                    providersInt = getPattern(dfInt);
93                }
94                NumberFormat dfNum = nfp.getNumberInstance(target);
95                if (dfNum != null) {
96                    providersNum = getPattern(dfNum);
97                }
98                NumberFormat dfPer = nfp.getPercentInstance(target);
99                if (dfPer != null) {
100                    providersPer = getPattern(dfPer);
101                }
102            }
103
104            // JRE's object (if any)
105            // note that this totally depends on the current implementation
106            String jresCur = null;
107            String jresInt = null;
108            String jresNum = null;
109            String jresPer = null;
110            if (jreSupportsLocale) {
111                DecimalFormat dfCur = new DecimalFormat(jreNumberPatterns[1],
112                    DecimalFormatSymbols.getInstance(target));
113                if (dfCur != null) {
114                    adjustForCurrencyDefaultFractionDigits(dfCur);
115                    jresCur = dfCur.toPattern();
116                }
117                DecimalFormat dfInt = new DecimalFormat(jreNumberPatterns[0],
118                    DecimalFormatSymbols.getInstance(target));
119                if (dfInt != null) {
120                    dfInt.setMaximumFractionDigits(0);
121                    dfInt.setDecimalSeparatorAlwaysShown(false);
122                    dfInt.setParseIntegerOnly(true);
123                    jresInt = dfInt.toPattern();
124                }
125                DecimalFormat dfNum = new DecimalFormat(jreNumberPatterns[0],
126                    DecimalFormatSymbols.getInstance(target));
127                if (dfNum != null) {
128                    jresNum = dfNum.toPattern();
129                }
130                DecimalFormat dfPer = new DecimalFormat(jreNumberPatterns[2],
131                    DecimalFormatSymbols.getInstance(target));
132                if (dfPer != null) {
133                    jresPer = dfPer.toPattern();
134                }
135            }
136
137            checkValidity(target, jresCur, providersCur, resultCur, jreSupportsLocale);
138            checkValidity(target, jresInt, providersInt, resultInt, jreSupportsLocale);
139            checkValidity(target, jresNum, providersNum, resultNum, jreSupportsLocale);
140            checkValidity(target, jresPer, providersPer, resultPer, jreSupportsLocale);
141        }
142    }
143
144    /**
145     * Adjusts the minimum and maximum fraction digits to values that
146     * are reasonable for the currency's default fraction digits.
147     */
148    void adjustForCurrencyDefaultFractionDigits(DecimalFormat df) {
149        DecimalFormatSymbols dfs = df.getDecimalFormatSymbols();
150        Currency currency = dfs.getCurrency();
151        if (currency == null) {
152            try {
153                currency = Currency.getInstance(dfs.getInternationalCurrencySymbol());
154            } catch (IllegalArgumentException e) {
155            }
156        }
157        if (currency != null) {
158            int digits = currency.getDefaultFractionDigits();
159            if (digits != -1) {
160                int oldMinDigits = df.getMinimumFractionDigits();
161                // Common patterns are "#.##", "#.00", "#".
162                // Try to adjust all of them in a reasonable way.
163                if (oldMinDigits == df.getMaximumFractionDigits()) {
164                    df.setMinimumFractionDigits(digits);
165                    df.setMaximumFractionDigits(digits);
166                } else {
167                    df.setMinimumFractionDigits(Math.min(digits, oldMinDigits));
168                    df.setMaximumFractionDigits(digits);
169                }
170            }
171        }
172    }
173
174    private static String getPattern(NumberFormat nf) {
175        if (nf instanceof DecimalFormat) {
176            return ((DecimalFormat)nf).toPattern();
177        }
178        if (nf instanceof FooNumberFormat) {
179            return ((FooNumberFormat)nf).toPattern();
180        }
181        return null;
182    }
183
184    private static final String[] NUMBER_PATTERNS = {
185        "num={0,number}",
186        "num={0,number,currency}",
187        "num={0,number,percent}",
188        "num={0,number,integer}"
189    };
190
191    void messageFormatTest() {
192        for (Locale target : providerloc) {
193            for (String pattern : NUMBER_PATTERNS) {
194                MessageFormat mf = new MessageFormat(pattern, target);
195                String toPattern = mf.toPattern();
196                if (!pattern.equals(toPattern)) {
197                    throw new RuntimeException("MessageFormat.toPattern: got '"
198                                               + toPattern
199                                               + "', expected '" + pattern + "'");
200                }
201            }
202        }
203    }
204}
205