2 *******************************************************************************
\r
3 * Copyright (C) 2009, International Business Machines Corporation and *
\r
4 * others. All Rights Reserved. *
\r
5 *******************************************************************************
\r
7 package com.ibm.icu.text;
\r
9 import com.ibm.icu.impl.ICUResourceBundle;
\r
10 import com.ibm.icu.impl.Utility;
\r
11 import com.ibm.icu.util.ULocale;
\r
12 import com.ibm.icu.util.UResourceBundle;
\r
14 import java.io.Serializable;
\r
15 import java.util.HashMap;
\r
16 import java.util.HashSet;
\r
17 import java.util.Iterator;
\r
18 import java.util.Locale;
\r
19 import java.util.Map;
\r
20 import java.util.MissingResourceException;
\r
21 import java.util.Set;
\r
24 * This class represents the information needed by
\r
25 * DecimalFormat to format currency plural,
\r
26 * such as "3.00 US dollars" or "1.00 US dollar".
\r
27 * DecimalFormat creates for itself an instance of
\r
28 * CurrencyPluralInfo from its locale data.
\r
29 * If you need to change any of these symbols, you can get the
\r
30 * CurrencyPluralInfo object from your
\r
31 * DecimalFormat and modify it.
\r
33 * Following are the information needed for currency plural format and parse:
\r
34 * locale information,
\r
35 * plural rule of the locale,
\r
36 * currency plural pattern of the locale.
\r
39 * @provisional This API might change or be removed in a future release.
\r
42 public class CurrencyPluralInfo implements Cloneable, Serializable {
\r
43 private static final long serialVersionUID = 1;
\r
46 * Create a CurrencyPluralInfo object for the default locale.
\r
48 * @provisional This API might change or be removed in a future release.
\r
50 public CurrencyPluralInfo() {
\r
51 initialize( ULocale.getDefault() );
\r
55 * Create a CurrencyPluralInfo object for the given locale.
\r
56 * @param locale the locale
\r
58 * @provisional This API might change or be removed in a future release.
\r
60 public CurrencyPluralInfo( Locale locale ) {
\r
61 initialize( ULocale.forLocale(locale) );
\r
65 * Create a CurrencyPluralInfo object for the given locale.
\r
66 * @param locale the locale
\r
68 * @provisional This API might change or be removed in a future release.
\r
70 public CurrencyPluralInfo( ULocale locale ) {
\r
71 initialize( locale );
\r
75 * Gets a CurrencyPluralInfo instance for the default locale.
\r
77 * @return A CurrencyPluralInfo instance.
\r
79 * @provisional This API might change or be removed in a future release.
\r
81 public static CurrencyPluralInfo getInstance() {
\r
82 return new CurrencyPluralInfo();
\r
86 * Gets a CurrencyPluralInfo instance for the given locale.
\r
88 * @param locale the locale.
\r
89 * @return A CurrencyPluralInfo instance.
\r
91 * @provisional This API might change or be removed in a future release.
\r
93 public static CurrencyPluralInfo getInstance(Locale locale) {
\r
94 return new CurrencyPluralInfo(locale);
\r
98 * Gets a CurrencyPluralInfo instance for the given locale.
\r
100 * @param locale the locale.
\r
101 * @return A CurrencyPluralInfo instance.
\r
103 * @provisional This API might change or be removed in a future release.
\r
105 public static CurrencyPluralInfo getInstance(ULocale locale) {
\r
106 return new CurrencyPluralInfo(locale);
\r
110 * Gets plural rules of this locale, used for currency plural format
\r
112 * @return plural rule
\r
114 * @provisional This API might change or be removed in a future release.
\r
116 public PluralRules getPluralRules() {
\r
117 return pluralRules;
\r
121 * Given a plural count, gets currency plural pattern of this locale,
\r
122 * used for currency plural format
\r
124 * @param pluralCount currency plural count
\r
125 * @return a currency plural pattern based on plural count
\r
127 * @provisional This API might change or be removed in a future release.
\r
129 public String getCurrencyPluralPattern(String pluralCount) {
\r
130 String currencyPluralPattern =
\r
131 (String)pluralCountToCurrencyUnitPattern.get(pluralCount);
\r
132 if (currencyPluralPattern == null) {
\r
133 // fall back to "other"
\r
134 if (!pluralCount.equals("other")) {
\r
135 currencyPluralPattern =
\r
136 (String)pluralCountToCurrencyUnitPattern.get("other");
\r
138 if (currencyPluralPattern == null) {
\r
139 // no currencyUnitPatterns defined,
\r
140 // fallback to predefined defult.
\r
141 // This should never happen when ICU resource files are
\r
142 // available, since currencyUnitPattern of "other" is always
\r
143 // defined in root.
\r
144 currencyPluralPattern = defaultCurrencyPluralPattern;
\r
147 return currencyPluralPattern;
\r
156 * @provisional This API might change or be removed in a future release.
\r
158 public ULocale getLocale() {
\r
163 * Set plural rules.
\r
164 * The plural rule is set when CurrencyPluralInfo
\r
165 * instance is created.
\r
166 * You can call this method to reset plural rules only if you want
\r
167 * to modify the default plural rule of the locale.
\r
169 * @param ruleDescription new plural rule description
\r
171 * @provisional This API might change or be removed in a future release.
\r
173 public void setPluralRules(String ruleDescription) {
\r
174 pluralRules = PluralRules.createRules(ruleDescription);
\r
178 * Set currency plural patterns.
\r
179 * The currency plural pattern is set when CurrencyPluralInfo
\r
180 * instance is created.
\r
181 * You can call this method to reset currency plural patterns only if
\r
182 * you want to modify the default currency plural pattern of the locale.
\r
184 * @param pluralCount the plural count for which the currency pattern will
\r
186 * @param pattern the new currency plural pattern
\r
188 * @provisional This API might change or be removed in a future release.
\r
190 public void setCurrencyPluralPattern(String pluralCount, String pattern) {
\r
191 pluralCountToCurrencyUnitPattern.put(pluralCount, pattern);
\r
197 * @param loc the new locale to set
\r
199 * @provisional This API might change or be removed in a future release.
\r
201 public void setLocale(ULocale loc) {
\r
207 * Standard override
\r
210 * @provisional This API might change or be removed in a future release.
\r
212 public Object clone() {
\r
214 CurrencyPluralInfo other = (CurrencyPluralInfo) super.clone();
\r
215 // locale is immutable
\r
216 other.ulocale = (ULocale)ulocale.clone();
\r
217 // plural rule is immutable
\r
218 //other.pluralRules = pluralRules;
\r
220 //other.pluralCountToCurrencyUnitPattern = pluralCountToCurrencyUnitPattern;
\r
221 other.pluralCountToCurrencyUnitPattern = new HashMap();
\r
222 Iterator iter = pluralCountToCurrencyUnitPattern.keySet().iterator();
\r
223 while (iter.hasNext()) {
\r
224 String pluralCount = (String)iter.next();
\r
225 String currencyPattern = (String)pluralCountToCurrencyUnitPattern.get(pluralCount);
\r
226 other.pluralCountToCurrencyUnitPattern.put(pluralCount, currencyPattern);
\r
229 } catch (CloneNotSupportedException e) {
\r
230 throw new IllegalStateException();
\r
238 * @provisional This API might change or be removed in a future release.
\r
240 public boolean equals(Object a) {
\r
241 if (a instanceof CurrencyPluralInfo) {
\r
242 CurrencyPluralInfo other = (CurrencyPluralInfo)a;
\r
243 return pluralRules.equals(other.pluralRules) &&
\r
244 pluralCountToCurrencyUnitPattern.equals(other.pluralCountToCurrencyUnitPattern);
\r
250 * Given a number, returns the keyword of the first rule that applies
\r
253 String select(double number) {
\r
254 return pluralRules.select(number);
\r
258 * Currency plural pattern iterator.
\r
260 * @return a iterator on currency plural pattern key set.
\r
262 Iterator pluralPatternIterator() {
\r
263 return pluralCountToCurrencyUnitPattern.keySet().iterator();
\r
266 private void initialize(ULocale uloc) {
\r
268 pluralRules = PluralRules.forLocale(uloc);
\r
269 setupCurrencyPluralPattern(uloc);
\r
273 private void setupCurrencyPluralPattern(ULocale uloc) {
\r
274 pluralCountToCurrencyUnitPattern = new HashMap();
\r
275 Set pluralCountSet = new HashSet();
\r
276 ULocale parentLocale = uloc;
\r
277 String numberStylePattern = NumberFormat.getPattern(uloc, NumberFormat.NUMBERSTYLE);
\r
278 // Split the number style pattern into pos and neg if applicable
\r
279 int separatorIndex = numberStylePattern.indexOf(";");
\r
280 String negNumberPattern = null;
\r
281 if (separatorIndex != -1) {
\r
282 negNumberPattern = numberStylePattern.substring(separatorIndex + 1);
\r
283 numberStylePattern = numberStylePattern.substring(0, separatorIndex);
\r
285 while (parentLocale != null) {
\r
287 ICUResourceBundle resource = (ICUResourceBundle)UResourceBundle.getBundleInstance(ICUResourceBundle.ICU_BASE_NAME, parentLocale);
\r
288 ICUResourceBundle currencyRes = resource.getWithFallback("CurrencyUnitPatterns");
\r
289 int size = currencyRes.getSize();
\r
290 for (int index = 0; index < size; ++index) {
\r
291 String pluralCount = currencyRes.get(index).getKey();
\r
292 if (pluralCountSet.contains(pluralCount)) {
\r
295 String pattern = currencyRes.get(index).getString();
\r
296 // replace {0} with numberStylePattern
\r
297 // and {1} with triple currency sign
\r
298 String patternWithNumber = Utility.replace(pattern, "{0}", numberStylePattern);
\r
299 String patternWithCurrencySign = Utility.replace(patternWithNumber, "{1}", tripleCurrencyStr);
\r
300 if (separatorIndex != -1) {
\r
301 String negPattern = pattern;
\r
302 String negWithNumber = Utility.replace(negPattern, "{0}", negNumberPattern);
\r
303 String negWithCurrSign = Utility.replace(negWithNumber, "{1}", tripleCurrencyStr);
\r
304 StringBuffer posNegPatterns = new StringBuffer(patternWithCurrencySign);
\r
305 posNegPatterns.append(";");
\r
306 posNegPatterns.append(negWithCurrSign);
\r
307 patternWithCurrencySign = posNegPatterns.toString();
\r
310 pluralCountToCurrencyUnitPattern.put(pluralCount, patternWithCurrencySign);
\r
311 pluralCountSet.add(pluralCount);
\r
313 } catch (MissingResourceException e) {
\r
315 parentLocale = parentLocale.getFallback();
\r
321 //-------------------- private data member ---------------------
\r
323 // triple currency sign char array
\r
324 private static final char[] tripleCurrencySign = {0xA4, 0xA4, 0xA4};
\r
325 // triple currency sign string
\r
326 private static final String tripleCurrencyStr = new String(tripleCurrencySign);
\r
328 // default currency plural pattern char array
\r
329 private static final char[] defaultCurrencyPluralPatternChar = {0, '.', '#', '#', ' ', 0xA4, 0xA4, 0xA4};
\r
330 // default currency plural pattern string
\r
331 private static final String defaultCurrencyPluralPattern = new String(defaultCurrencyPluralPatternChar);
\r
333 // map from plural count to currency plural pattern, for example
\r
334 // one (plural count) --> {0} {1} (currency plural pattern,
\r
335 // in which, {0} is the amount number, and {1} is the currency plural name.
\r
336 private Map pluralCountToCurrencyUnitPattern = null;
\r
339 * The plural rule is used to format currency plural name,
\r
340 * for example: "3.00 US Dollars".
\r
341 * If there are 3 currency signs in the currency patttern,
\r
342 * the 3 currency signs will be replaced by currency plural name.
\r
344 private PluralRules pluralRules = null;
\r
347 private ULocale ulocale = null;
\r