1 /* GENERATED SOURCE. DO NOT MODIFY. */ 2 // © 2016 and later: Unicode, Inc. and others. 3 // License & terms of use: http://www.unicode.org/copyright.html 4 /* 5 ******************************************************************************* 6 * Copyright (C) 2009-2014, International Business Machines Corporation and * 7 * others. All Rights Reserved. * 8 ******************************************************************************* 9 */ 10 package android.icu.text; 11 12 import java.io.Serializable; 13 import java.util.HashMap; 14 import java.util.Iterator; 15 import java.util.Locale; 16 import java.util.Map; 17 18 import android.icu.impl.CurrencyData; 19 import android.icu.util.ICUCloneNotSupportedException; 20 import android.icu.util.ULocale; 21 import android.icu.util.ULocale.Category; 22 23 /** 24 * This class represents the information needed by 25 * DecimalFormat to format currency plural, 26 * such as "3.00 US dollars" or "1.00 US dollar". 27 * DecimalFormat creates for itself an instance of 28 * CurrencyPluralInfo from its locale data. 29 * If you need to change any of these symbols, you can get the 30 * CurrencyPluralInfo object from your 31 * DecimalFormat and modify it. 32 * 33 * Following are the information needed for currency plural format and parse: 34 * locale information, 35 * plural rule of the locale, 36 * currency plural pattern of the locale. 37 */ 38 39 public class CurrencyPluralInfo implements Cloneable, Serializable { 40 private static final long serialVersionUID = 1; 41 42 /** 43 * Create a CurrencyPluralInfo object for the default <code>FORMAT</code> locale. 44 * @see Category#FORMAT 45 */ CurrencyPluralInfo()46 public CurrencyPluralInfo() { 47 initialize(ULocale.getDefault(Category.FORMAT)); 48 } 49 50 /** 51 * Create a CurrencyPluralInfo object for the given locale. 52 * @param locale the locale 53 */ CurrencyPluralInfo(Locale locale)54 public CurrencyPluralInfo(Locale locale) { 55 initialize(ULocale.forLocale(locale)); 56 } 57 58 /** 59 * Create a CurrencyPluralInfo object for the given locale. 60 * @param locale the locale 61 */ CurrencyPluralInfo(ULocale locale)62 public CurrencyPluralInfo(ULocale locale) { 63 initialize(locale); 64 } 65 66 /** 67 * Gets a CurrencyPluralInfo instance for the default locale. 68 * 69 * @return A CurrencyPluralInfo instance. 70 */ getInstance()71 public static CurrencyPluralInfo getInstance() { 72 return new CurrencyPluralInfo(); 73 } 74 75 /** 76 * Gets a CurrencyPluralInfo instance for the given locale. 77 * 78 * @param locale the locale. 79 * @return A CurrencyPluralInfo instance. 80 */ getInstance(Locale locale)81 public static CurrencyPluralInfo getInstance(Locale locale) { 82 return new CurrencyPluralInfo(locale); 83 } 84 85 /** 86 * Gets a CurrencyPluralInfo instance for the given locale. 87 * 88 * @param locale the locale. 89 * @return A CurrencyPluralInfo instance. 90 */ getInstance(ULocale locale)91 public static CurrencyPluralInfo getInstance(ULocale locale) { 92 return new CurrencyPluralInfo(locale); 93 } 94 95 /** 96 * Gets plural rules of this locale, used for currency plural format 97 * 98 * @return plural rule 99 */ getPluralRules()100 public PluralRules getPluralRules() { 101 return pluralRules; 102 } 103 104 /** 105 * Given a plural count, gets currency plural pattern of this locale, 106 * used for currency plural format 107 * 108 * @param pluralCount currency plural count 109 * @return a currency plural pattern based on plural count 110 */ getCurrencyPluralPattern(String pluralCount)111 public String getCurrencyPluralPattern(String pluralCount) { 112 String currencyPluralPattern = pluralCountToCurrencyUnitPattern.get(pluralCount); 113 if (currencyPluralPattern == null) { 114 // fall back to "other" 115 if (!pluralCount.equals("other")) { 116 currencyPluralPattern = pluralCountToCurrencyUnitPattern.get("other"); 117 } 118 if (currencyPluralPattern == null) { 119 // no currencyUnitPatterns defined, 120 // fallback to predefined default. 121 // This should never happen when ICU resource files are 122 // available, since currencyUnitPattern of "other" is always 123 // defined in root. 124 currencyPluralPattern = defaultCurrencyPluralPattern; 125 } 126 } 127 return currencyPluralPattern; 128 } 129 130 /** 131 * Get locale 132 * 133 * @return locale 134 */ getLocale()135 public ULocale getLocale() { 136 return ulocale; 137 } 138 139 /** 140 * Set plural rules. These are initially set in the constructor based on the locale, 141 * and usually do not need to be changed. 142 * 143 * @param ruleDescription new plural rule description 144 */ setPluralRules(String ruleDescription)145 public void setPluralRules(String ruleDescription) { 146 pluralRules = PluralRules.createRules(ruleDescription); 147 } 148 149 /** 150 * Set currency plural patterns. These are initially set in the constructor based on the 151 * locale, and usually do not need to be changed. 152 * 153 * The decimal digits part of the pattern cannot be specified via this method. All plural 154 * forms will use the same decimal pattern as set in the constructor of DecimalFormat. For 155 * example, you can't set "0.0" for plural "few" but "0.00" for plural "many". 156 * 157 * @param pluralCount the plural count for which the currency pattern will 158 * be overridden. 159 * @param pattern the new currency plural pattern 160 */ setCurrencyPluralPattern(String pluralCount, String pattern)161 public void setCurrencyPluralPattern(String pluralCount, String pattern) { 162 pluralCountToCurrencyUnitPattern.put(pluralCount, pattern); 163 } 164 165 /** 166 * Set locale. This also sets both the plural rules and the currency plural patterns to be 167 * the defaults for the locale. 168 * 169 * @param loc the new locale to set 170 */ setLocale(ULocale loc)171 public void setLocale(ULocale loc) { 172 ulocale = loc; 173 initialize(loc); 174 } 175 176 /** 177 * Standard override 178 */ 179 @Override clone()180 public Object clone() { 181 try { 182 CurrencyPluralInfo other = (CurrencyPluralInfo) super.clone(); 183 // locale is immutable 184 other.ulocale = (ULocale)ulocale.clone(); 185 // plural rule is immutable 186 //other.pluralRules = pluralRules; 187 // clone content 188 //other.pluralCountToCurrencyUnitPattern = pluralCountToCurrencyUnitPattern; 189 other.pluralCountToCurrencyUnitPattern = new HashMap<>(); 190 for (String pluralCount : pluralCountToCurrencyUnitPattern.keySet()) { 191 String currencyPattern = pluralCountToCurrencyUnitPattern.get(pluralCount); 192 other.pluralCountToCurrencyUnitPattern.put(pluralCount, currencyPattern); 193 } 194 return other; 195 } catch (CloneNotSupportedException e) { 196 throw new ICUCloneNotSupportedException(e); 197 } 198 } 199 200 /** 201 * Override equals 202 */ 203 @Override equals(Object a)204 public boolean equals(Object a) { 205 if (a instanceof CurrencyPluralInfo) { 206 CurrencyPluralInfo other = (CurrencyPluralInfo)a; 207 return pluralRules.equals(other.pluralRules) && 208 pluralCountToCurrencyUnitPattern.equals(other.pluralCountToCurrencyUnitPattern); 209 } 210 return false; 211 } 212 213 /** 214 * Override hashCode 215 * 216 * @hide original deprecated declaration 217 */ 218 @Override hashCode()219 public int hashCode() { 220 return pluralCountToCurrencyUnitPattern.hashCode() 221 ^ pluralRules.hashCode() 222 ^ ulocale.hashCode(); 223 } 224 225 /** 226 * Given a number, returns the keyword of the first rule that applies 227 * to the number. 228 * @deprecated This API is ICU internal only. 229 * @hide draft / provisional / internal are hidden on Android 230 */ 231 @Deprecated select(double number)232 String select(double number) { 233 return pluralRules.select(number); 234 } 235 236 /** 237 * Given a number, returns the keyword of the first rule that applies 238 * to the number. 239 * @deprecated This API is ICU internal only. 240 * @hide draft / provisional / internal are hidden on Android 241 */ 242 @Deprecated select(PluralRules.FixedDecimal numberInfo)243 public String select(PluralRules.FixedDecimal numberInfo) { 244 return pluralRules.select(numberInfo); 245 } 246 247 /** 248 * Currency plural pattern iterator. 249 * 250 * @return a iterator on the currency plural pattern key set. 251 * @deprecated This API is ICU internal only. 252 * @hide draft / provisional / internal are hidden on Android 253 */ 254 @Deprecated pluralPatternIterator()255 public Iterator<String> pluralPatternIterator() { 256 return pluralCountToCurrencyUnitPattern.keySet().iterator(); 257 } 258 initialize(ULocale uloc)259 private void initialize(ULocale uloc) { 260 ulocale = uloc; 261 pluralRules = PluralRules.forLocale(uloc); 262 setupCurrencyPluralPattern(uloc); 263 } 264 setupCurrencyPluralPattern(ULocale uloc)265 private void setupCurrencyPluralPattern(ULocale uloc) { 266 pluralCountToCurrencyUnitPattern = new HashMap<>(); 267 268 String numberStylePattern = NumberFormat.getPattern(uloc, NumberFormat.NUMBERSTYLE); 269 // Split the number style pattern into pos and neg if applicable 270 int separatorIndex = numberStylePattern.indexOf(";"); 271 String negNumberPattern = null; 272 if (separatorIndex != -1) { 273 negNumberPattern = numberStylePattern.substring(separatorIndex + 1); 274 numberStylePattern = numberStylePattern.substring(0, separatorIndex); 275 } 276 Map<String, String> map = CurrencyData.provider.getInstance(uloc, true).getUnitPatterns(); 277 for (Map.Entry<String, String> e : map.entrySet()) { 278 String pluralCount = e.getKey(); 279 String pattern = e.getValue(); 280 281 // replace {0} with numberStylePattern 282 // and {1} with triple currency sign 283 String patternWithNumber = pattern.replace("{0}", numberStylePattern); 284 String patternWithCurrencySign = patternWithNumber.replace("{1}", tripleCurrencyStr); 285 if (separatorIndex != -1) { 286 String negPattern = pattern; 287 String negWithNumber = negPattern.replace("{0}", negNumberPattern); 288 String negWithCurrSign = negWithNumber.replace("{1}", tripleCurrencyStr); 289 StringBuilder posNegPatterns = new StringBuilder(patternWithCurrencySign); 290 posNegPatterns.append(";"); 291 posNegPatterns.append(negWithCurrSign); 292 patternWithCurrencySign = posNegPatterns.toString(); 293 } 294 pluralCountToCurrencyUnitPattern.put(pluralCount, patternWithCurrencySign); 295 } 296 } 297 298 299 //-------------------- private data member --------------------- 300 // 301 // triple currency sign char array 302 private static final char[] tripleCurrencySign = {0xA4, 0xA4, 0xA4}; 303 // triple currency sign string 304 private static final String tripleCurrencyStr = new String(tripleCurrencySign); 305 306 // default currency plural pattern char array 307 private static final char[] defaultCurrencyPluralPatternChar = {0, '.', '#', '#', ' ', 0xA4, 0xA4, 0xA4}; 308 // default currency plural pattern string 309 private static final String defaultCurrencyPluralPattern = new String(defaultCurrencyPluralPatternChar); 310 311 // map from plural count to currency plural pattern, for example 312 // one (plural count) --> {0} {1} (currency plural pattern, 313 // in which {0} is the amount number, and {1} is the currency plural name). 314 private Map<String, String> pluralCountToCurrencyUnitPattern = null; 315 316 /* 317 * The plural rule is used to format currency plural name, 318 * for example: "3.00 US Dollars". 319 * If there are 3 currency signs in the currency pattern, 320 * the 3 currency signs will be replaced by the currency plural name. 321 */ 322 private PluralRules pluralRules = null; 323 324 // locale 325 private ULocale ulocale = null; 326 } 327