2 *******************************************************************************
3 * Copyright (C) 2009-2013, International Business Machines Corporation and *
4 * others. All Rights Reserved. *
5 *******************************************************************************
7 package com.ibm.icu.text;
9 import java.io.Serializable;
10 import java.util.HashMap;
11 import java.util.Iterator;
12 import java.util.Locale;
15 import com.ibm.icu.impl.CurrencyData;
16 import com.ibm.icu.util.ULocale;
17 import com.ibm.icu.util.ULocale.Category;
20 * This class represents the information needed by
21 * DecimalFormat to format currency plural,
22 * such as "3.00 US dollars" or "1.00 US dollar".
23 * DecimalFormat creates for itself an instance of
24 * CurrencyPluralInfo from its locale data.
25 * If you need to change any of these symbols, you can get the
26 * CurrencyPluralInfo object from your
27 * DecimalFormat and modify it.
29 * Following are the information needed for currency plural format and parse:
31 * plural rule of the locale,
32 * currency plural pattern of the locale.
37 public class CurrencyPluralInfo implements Cloneable, Serializable {
38 private static final long serialVersionUID = 1;
41 * Create a CurrencyPluralInfo object for the default <code>FORMAT</code> locale.
42 * @see Category#FORMAT
45 public CurrencyPluralInfo() {
46 initialize(ULocale.getDefault(Category.FORMAT));
50 * Create a CurrencyPluralInfo object for the given locale.
51 * @param locale the locale
54 public CurrencyPluralInfo(Locale locale) {
55 initialize(ULocale.forLocale(locale));
59 * Create a CurrencyPluralInfo object for the given locale.
60 * @param locale the locale
63 public CurrencyPluralInfo(ULocale locale) {
68 * Gets a CurrencyPluralInfo instance for the default locale.
70 * @return A CurrencyPluralInfo instance.
73 public static CurrencyPluralInfo getInstance() {
74 return new CurrencyPluralInfo();
78 * Gets a CurrencyPluralInfo instance for the given locale.
80 * @param locale the locale.
81 * @return A CurrencyPluralInfo instance.
84 public static CurrencyPluralInfo getInstance(Locale locale) {
85 return new CurrencyPluralInfo(locale);
89 * Gets a CurrencyPluralInfo instance for the given locale.
91 * @param locale the locale.
92 * @return A CurrencyPluralInfo instance.
95 public static CurrencyPluralInfo getInstance(ULocale locale) {
96 return new CurrencyPluralInfo(locale);
100 * Gets plural rules of this locale, used for currency plural format
102 * @return plural rule
105 public PluralRules getPluralRules() {
110 * Given a plural count, gets currency plural pattern of this locale,
111 * used for currency plural format
113 * @param pluralCount currency plural count
114 * @return a currency plural pattern based on plural count
117 public String getCurrencyPluralPattern(String pluralCount) {
118 String currencyPluralPattern = pluralCountToCurrencyUnitPattern.get(pluralCount);
119 if (currencyPluralPattern == null) {
120 // fall back to "other"
121 if (!pluralCount.equals("other")) {
122 currencyPluralPattern = pluralCountToCurrencyUnitPattern.get("other");
124 if (currencyPluralPattern == null) {
125 // no currencyUnitPatterns defined,
126 // fallback to predefined default.
127 // This should never happen when ICU resource files are
128 // available, since currencyUnitPattern of "other" is always
130 currencyPluralPattern = defaultCurrencyPluralPattern;
133 return currencyPluralPattern;
143 public ULocale getLocale() {
148 * Set plural rules. These are initially set in the constructor based on the locale,
149 * and usually do not need to be changed.
151 * @param ruleDescription new plural rule description
154 public void setPluralRules(String ruleDescription) {
155 pluralRules = PluralRules.createRules(ruleDescription);
159 * Set currency plural patterns. These are initially set in the constructor based on the
160 * locale, and usually do not need to be changed.
162 * @param pluralCount the plural count for which the currency pattern will
164 * @param pattern the new currency plural pattern
167 public void setCurrencyPluralPattern(String pluralCount, String pattern) {
168 pluralCountToCurrencyUnitPattern.put(pluralCount, pattern);
172 * Set locale. This also sets both the plural rules and the currency plural patterns to be
173 * the defaults for the locale.
175 * @param loc the new locale to set
178 public void setLocale(ULocale loc) {
188 public Object clone() {
190 CurrencyPluralInfo other = (CurrencyPluralInfo) super.clone();
191 // locale is immutable
192 other.ulocale = (ULocale)ulocale.clone();
193 // plural rule is immutable
194 //other.pluralRules = pluralRules;
196 //other.pluralCountToCurrencyUnitPattern = pluralCountToCurrencyUnitPattern;
197 other.pluralCountToCurrencyUnitPattern = new HashMap<String, String>();
198 for (String pluralCount : pluralCountToCurrencyUnitPattern.keySet()) {
199 String currencyPattern = pluralCountToCurrencyUnitPattern.get(pluralCount);
200 other.pluralCountToCurrencyUnitPattern.put(pluralCount, currencyPattern);
203 } catch (CloneNotSupportedException e) {
204 throw new IllegalStateException();
213 public boolean equals(Object a) {
214 if (a instanceof CurrencyPluralInfo) {
215 CurrencyPluralInfo other = (CurrencyPluralInfo)a;
216 return pluralRules.equals(other.pluralRules) &&
217 pluralCountToCurrencyUnitPattern.equals(other.pluralCountToCurrencyUnitPattern);
223 * Mock implementation of hashCode(). This implementation always returns a constant
224 * value. When Java assertion is enabled, this method triggers an assertion failure.
226 * @deprecated This API is ICU internal only.
228 public int hashCode() {
229 assert false : "hashCode not designed";
234 * Given a number, returns the keyword of the first rule that applies
237 * @deprecated This API is ICU internal only.
239 String select(double number) {
240 return pluralRules.select(number);
244 * Given a number, returns the keyword of the first rule that applies
247 * @deprecated This API is ICU internal only.
249 String select(PluralRules.FixedDecimal numberInfo) {
250 return pluralRules.select(numberInfo);
254 * Currency plural pattern iterator.
256 * @return a iterator on the currency plural pattern key set.
258 Iterator<String> pluralPatternIterator() {
259 return pluralCountToCurrencyUnitPattern.keySet().iterator();
262 private void initialize(ULocale uloc) {
264 pluralRules = PluralRules.forLocale(uloc);
265 setupCurrencyPluralPattern(uloc);
268 private void setupCurrencyPluralPattern(ULocale uloc) {
269 pluralCountToCurrencyUnitPattern = new HashMap<String, String>();
271 String numberStylePattern = NumberFormat.getPattern(uloc, NumberFormat.NUMBERSTYLE);
272 // Split the number style pattern into pos and neg if applicable
273 int separatorIndex = numberStylePattern.indexOf(";");
274 String negNumberPattern = null;
275 if (separatorIndex != -1) {
276 negNumberPattern = numberStylePattern.substring(separatorIndex + 1);
277 numberStylePattern = numberStylePattern.substring(0, separatorIndex);
279 Map<String, String> map = CurrencyData.provider.getInstance(uloc, true).getUnitPatterns();
280 for (Map.Entry<String, String> e : map.entrySet()) {
281 String pluralCount = e.getKey();
282 String pattern = e.getValue();
284 // replace {0} with numberStylePattern
285 // and {1} with triple currency sign
286 String patternWithNumber = pattern.replace("{0}", numberStylePattern);
287 String patternWithCurrencySign = patternWithNumber.replace("{1}", tripleCurrencyStr);
288 if (separatorIndex != -1) {
289 String negPattern = pattern;
290 String negWithNumber = negPattern.replace("{0}", negNumberPattern);
291 String negWithCurrSign = negWithNumber.replace("{1}", tripleCurrencyStr);
292 StringBuilder posNegPatterns = new StringBuilder(patternWithCurrencySign);
293 posNegPatterns.append(";");
294 posNegPatterns.append(negWithCurrSign);
295 patternWithCurrencySign = posNegPatterns.toString();
297 pluralCountToCurrencyUnitPattern.put(pluralCount, patternWithCurrencySign);
302 //-------------------- private data member ---------------------
304 // triple currency sign char array
305 private static final char[] tripleCurrencySign = {0xA4, 0xA4, 0xA4};
306 // triple currency sign string
307 private static final String tripleCurrencyStr = new String(tripleCurrencySign);
309 // default currency plural pattern char array
310 private static final char[] defaultCurrencyPluralPatternChar = {0, '.', '#', '#', ' ', 0xA4, 0xA4, 0xA4};
311 // default currency plural pattern string
312 private static final String defaultCurrencyPluralPattern = new String(defaultCurrencyPluralPatternChar);
314 // map from plural count to currency plural pattern, for example
315 // one (plural count) --> {0} {1} (currency plural pattern,
316 // in which {0} is the amount number, and {1} is the currency plural name).
317 private Map<String, String> pluralCountToCurrencyUnitPattern = null;
320 * The plural rule is used to format currency plural name,
321 * for example: "3.00 US Dollars".
322 * If there are 3 currency signs in the currency pattern,
323 * the 3 currency signs will be replaced by the currency plural name.
325 private PluralRules pluralRules = null;
328 private ULocale ulocale = null;