2 *******************************************************************************
\r
3 * Copyright (C) 2009-2010, International Business Machines Corporation and *
\r
4 * others. All Rights Reserved. *
\r
5 *******************************************************************************
\r
7 package com.ibm.icu.text;
\r
9 import java.io.Serializable;
\r
10 import java.util.HashMap;
\r
11 import java.util.Iterator;
\r
12 import java.util.Locale;
\r
13 import java.util.Map;
\r
15 import com.ibm.icu.impl.CurrencyData;
\r
16 import com.ibm.icu.util.ULocale;
\r
19 * This class represents the information needed by
\r
20 * DecimalFormat to format currency plural,
\r
21 * such as "3.00 US dollars" or "1.00 US dollar".
\r
22 * DecimalFormat creates for itself an instance of
\r
23 * CurrencyPluralInfo from its locale data.
\r
24 * If you need to change any of these symbols, you can get the
\r
25 * CurrencyPluralInfo object from your
\r
26 * DecimalFormat and modify it.
\r
28 * Following are the information needed for currency plural format and parse:
\r
29 * locale information,
\r
30 * plural rule of the locale,
\r
31 * currency plural pattern of the locale.
\r
36 public class CurrencyPluralInfo implements Cloneable, Serializable {
\r
37 private static final long serialVersionUID = 1;
\r
40 * Create a CurrencyPluralInfo object for the default locale.
\r
43 public CurrencyPluralInfo() {
\r
44 initialize(ULocale.getDefault());
\r
48 * Create a CurrencyPluralInfo object for the given locale.
\r
49 * @param locale the locale
\r
52 public CurrencyPluralInfo(Locale locale) {
\r
53 initialize(ULocale.forLocale(locale));
\r
57 * Create a CurrencyPluralInfo object for the given locale.
\r
58 * @param locale the locale
\r
61 public CurrencyPluralInfo(ULocale locale) {
\r
66 * Gets a CurrencyPluralInfo instance for the default locale.
\r
68 * @return A CurrencyPluralInfo instance.
\r
71 public static CurrencyPluralInfo getInstance() {
\r
72 return new CurrencyPluralInfo();
\r
76 * Gets a CurrencyPluralInfo instance for the given locale.
\r
78 * @param locale the locale.
\r
79 * @return A CurrencyPluralInfo instance.
\r
82 public static CurrencyPluralInfo getInstance(Locale locale) {
\r
83 return new CurrencyPluralInfo(locale);
\r
87 * Gets a CurrencyPluralInfo instance for the given locale.
\r
89 * @param locale the locale.
\r
90 * @return A CurrencyPluralInfo instance.
\r
93 public static CurrencyPluralInfo getInstance(ULocale locale) {
\r
94 return new CurrencyPluralInfo(locale);
\r
98 * Gets plural rules of this locale, used for currency plural format
\r
100 * @return plural rule
\r
103 public PluralRules getPluralRules() {
\r
104 return pluralRules;
\r
108 * Given a plural count, gets currency plural pattern of this locale,
\r
109 * used for currency plural format
\r
111 * @param pluralCount currency plural count
\r
112 * @return a currency plural pattern based on plural count
\r
115 public String getCurrencyPluralPattern(String pluralCount) {
\r
116 String currencyPluralPattern = pluralCountToCurrencyUnitPattern.get(pluralCount);
\r
117 if (currencyPluralPattern == null) {
\r
118 // fall back to "other"
\r
119 if (!pluralCount.equals("other")) {
\r
120 currencyPluralPattern = pluralCountToCurrencyUnitPattern.get("other");
\r
122 if (currencyPluralPattern == null) {
\r
123 // no currencyUnitPatterns defined,
\r
124 // fallback to predefined default.
\r
125 // This should never happen when ICU resource files are
\r
126 // available, since currencyUnitPattern of "other" is always
\r
127 // defined in root.
\r
128 currencyPluralPattern = defaultCurrencyPluralPattern;
\r
131 return currencyPluralPattern;
\r
141 public ULocale getLocale() {
\r
146 * Set plural rules. These are initially set in the constructor based on the locale,
\r
147 * and usually do not need to be changed.
\r
149 * @param ruleDescription new plural rule description
\r
152 public void setPluralRules(String ruleDescription) {
\r
153 pluralRules = PluralRules.createRules(ruleDescription);
\r
157 * Set currency plural patterns. These are initially set in the constructor based on the
\r
158 * locale, and usually do not need to be changed.
\r
160 * @param pluralCount the plural count for which the currency pattern will
\r
162 * @param pattern the new currency plural pattern
\r
165 public void setCurrencyPluralPattern(String pluralCount, String pattern) {
\r
166 pluralCountToCurrencyUnitPattern.put(pluralCount, pattern);
\r
170 * Set locale. This also sets both the plural rules and the currency plural patterns to be
\r
171 * the defaults for the locale.
\r
173 * @param loc the new locale to set
\r
176 public void setLocale(ULocale loc) {
\r
182 * Standard override
\r
186 public Object clone() {
\r
188 CurrencyPluralInfo other = (CurrencyPluralInfo) super.clone();
\r
189 // locale is immutable
\r
190 other.ulocale = (ULocale)ulocale.clone();
\r
191 // plural rule is immutable
\r
192 //other.pluralRules = pluralRules;
\r
194 //other.pluralCountToCurrencyUnitPattern = pluralCountToCurrencyUnitPattern;
\r
195 other.pluralCountToCurrencyUnitPattern = new HashMap<String, String>();
\r
196 for (String pluralCount : pluralCountToCurrencyUnitPattern.keySet()) {
\r
197 String currencyPattern = pluralCountToCurrencyUnitPattern.get(pluralCount);
\r
198 other.pluralCountToCurrencyUnitPattern.put(pluralCount, currencyPattern);
\r
201 } catch (CloneNotSupportedException e) {
\r
202 throw new IllegalStateException();
\r
211 public boolean equals(Object a) {
\r
212 if (a instanceof CurrencyPluralInfo) {
\r
213 CurrencyPluralInfo other = (CurrencyPluralInfo)a;
\r
214 return pluralRules.equals(other.pluralRules) &&
\r
215 pluralCountToCurrencyUnitPattern.equals(other.pluralCountToCurrencyUnitPattern);
\r
221 * Given a number, returns the keyword of the first rule that applies
\r
224 String select(double number) {
\r
225 return pluralRules.select(number);
\r
229 * Currency plural pattern iterator.
\r
231 * @return a iterator on the currency plural pattern key set.
\r
233 Iterator<String> pluralPatternIterator() {
\r
234 return pluralCountToCurrencyUnitPattern.keySet().iterator();
\r
237 private void initialize(ULocale uloc) {
\r
239 pluralRules = PluralRules.forLocale(uloc);
\r
240 setupCurrencyPluralPattern(uloc);
\r
243 private void setupCurrencyPluralPattern(ULocale uloc) {
\r
244 pluralCountToCurrencyUnitPattern = new HashMap<String, String>();
\r
246 String numberStylePattern = NumberFormat.getPattern(uloc, NumberFormat.NUMBERSTYLE);
\r
247 // Split the number style pattern into pos and neg if applicable
\r
248 int separatorIndex = numberStylePattern.indexOf(";");
\r
249 String negNumberPattern = null;
\r
250 if (separatorIndex != -1) {
\r
251 negNumberPattern = numberStylePattern.substring(separatorIndex + 1);
\r
252 numberStylePattern = numberStylePattern.substring(0, separatorIndex);
\r
254 Map<String, String> map = CurrencyData.provider.getInstance(uloc, true).getUnitPatterns();
\r
255 for (Map.Entry<String, String> e : map.entrySet()) {
\r
256 String pluralCount = e.getKey();
\r
257 String pattern = e.getValue();
\r
259 // replace {0} with numberStylePattern
\r
260 // and {1} with triple currency sign
\r
261 String patternWithNumber = pattern.replace("{0}", numberStylePattern);
\r
262 String patternWithCurrencySign = patternWithNumber.replace("{1}", tripleCurrencyStr);
\r
263 if (separatorIndex != -1) {
\r
264 String negPattern = pattern;
\r
265 String negWithNumber = negPattern.replace("{0}", negNumberPattern);
\r
266 String negWithCurrSign = negWithNumber.replace("{1}", tripleCurrencyStr);
\r
267 StringBuilder posNegPatterns = new StringBuilder(patternWithCurrencySign);
\r
268 posNegPatterns.append(";");
\r
269 posNegPatterns.append(negWithCurrSign);
\r
270 patternWithCurrencySign = posNegPatterns.toString();
\r
272 pluralCountToCurrencyUnitPattern.put(pluralCount, patternWithCurrencySign);
\r
277 //-------------------- private data member ---------------------
\r
279 // triple currency sign char array
\r
280 private static final char[] tripleCurrencySign = {0xA4, 0xA4, 0xA4};
\r
281 // triple currency sign string
\r
282 private static final String tripleCurrencyStr = new String(tripleCurrencySign);
\r
284 // default currency plural pattern char array
\r
285 private static final char[] defaultCurrencyPluralPatternChar = {0, '.', '#', '#', ' ', 0xA4, 0xA4, 0xA4};
\r
286 // default currency plural pattern string
\r
287 private static final String defaultCurrencyPluralPattern = new String(defaultCurrencyPluralPatternChar);
\r
289 // map from plural count to currency plural pattern, for example
\r
290 // one (plural count) --> {0} {1} (currency plural pattern,
\r
291 // in which {0} is the amount number, and {1} is the currency plural name).
\r
292 private Map<String, String> pluralCountToCurrencyUnitPattern = null;
\r
295 * The plural rule is used to format currency plural name,
\r
296 * for example: "3.00 US Dollars".
\r
297 * If there are 3 currency signs in the currency pattern,
\r
298 * the 3 currency signs will be replaced by the currency plural name.
\r
300 private PluralRules pluralRules = null;
\r
303 private ULocale ulocale = null;
\r