17935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/** 27935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ******************************************************************************* 37388b89454a914dd65a78a7fc321f60cd211561dFredrik Roubert * Copyright (C) 2001-2015, International Business Machines Corporation and 47388b89454a914dd65a78a7fc321f60cd211561dFredrik Roubert * others. All Rights Reserved. 57935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ******************************************************************************* 67935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 77935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertpackage com.ibm.icu.util; 87935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 97935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.io.ObjectStreamException; 107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.lang.ref.SoftReference; 117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.text.ParsePosition; 127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.ArrayList; 137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.Collections; 147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.Date; 157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.HashMap; 167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.HashSet; 177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.Iterator; 187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.List; 197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.Locale; 207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.Map; 217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.MissingResourceException; 227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.Set; 237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.impl.ICUCache; 257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.impl.ICUDebug; 267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.impl.ICUResourceBundle; 277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.impl.SimpleCache; 287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.impl.TextTrieMap; 297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.text.CurrencyDisplayNames; 307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.text.CurrencyMetaInfo; 317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.text.CurrencyMetaInfo.CurrencyDigits; 327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.text.CurrencyMetaInfo.CurrencyFilter; 337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.util.ULocale.Category; 347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/** 367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * A class encapsulating a currency, as defined by ISO 4217. A 377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <tt>Currency</tt> object can be created given a <tt>Locale</tt> or 387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * given an ISO 4217 code. Once created, the <tt>Currency</tt> object 397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * can return various data necessary to its proper display: 407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <ul><li>A display symbol, for a specific locale 427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <li>The number of fraction digits to display 437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <li>A rounding increment 447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * </ul> 457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * The <tt>DecimalFormat</tt> class uses these data to display 477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * currencies. 487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p>Note: This class deliberately resembles 507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <tt>java.util.Currency</tt> but it has a completely independent 517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * implementation, and adds features not present in the JDK. 527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @author Alan Liu 537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 2.2 547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertpublic class Currency extends MeasureUnit { 567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private static final long serialVersionUID = -5839973855554750484L; 577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private static final boolean DEBUG = ICUDebug.enabled("currency"); 587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Cache to save currency name trie 607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private static ICUCache<ULocale, List<TextTrieMap<CurrencyStringInfo>>> CURRENCY_NAME_CACHE = 617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert new SimpleCache<ULocale, List<TextTrieMap<CurrencyStringInfo>>>(); 627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Selector for getName() indicating a symbolic name for a 657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * currency, such as "$" for USD. 667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 2.6 677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static final int SYMBOL_NAME = 0; 697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Selector for getName() indicating the long name for a 727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * currency, such as "US Dollar" for USD. 737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 2.6 747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static final int LONG_NAME = 1; 767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Selector for getName() indicating the plural long name for a 797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * currency, such as "US dollar" for USD in "1 US dollar", 807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * and "US dollars" for USD in "2 US dollars". 817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 4.2 827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static final int PLURAL_LONG_NAME = 2; 847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private static final EquivalenceRelation<String> EQUIVALENT_CURRENCY_SYMBOLS = 867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert new EquivalenceRelation<String>() 877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert .add("\u00a5", "\uffe5") 887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert .add("$", "\ufe69", "\uff04") 897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert .add("\u20a8", "\u20b9") 907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert .add("\u00a3", "\u20a4"); 917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Currency Usage used for Decimal Format 947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @draft ICU 54 957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @provisional This API might change or be removed in a future release. 967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public enum CurrencyUsage{ 987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * a setting to specify currency usage which determines currency digit and rounding 1007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * for standard usage, for example: "50.00 NT$" 1017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @draft ICU 54 1027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @provisional This API might change or be removed in a future release. 1037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 1047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert STANDARD, 1057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 1077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * a setting to specify currency usage which determines currency digit and rounding 1087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * for cash usage, for example: "50 NT$" 1097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @draft ICU 54 1107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @provisional This API might change or be removed in a future release. 1117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 1127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert CASH 1137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // begin registry stuff 1167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // shim for service code 1187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /* package */ static abstract class ServiceShim { 1197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert abstract ULocale[] getAvailableULocales(); 1207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert abstract Locale[] getAvailableLocales(); 1217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert abstract Currency createInstance(ULocale l); 1227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert abstract Object registerInstance(Currency c, ULocale l); 1237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert abstract boolean unregister(Object f); 1247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private static ServiceShim shim; 1277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private static ServiceShim getShim() { 1287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Note: this instantiation is safe on loose-memory-model configurations 1297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // despite lack of synchronization, since the shim instance has no state-- 1307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // it's all in the class init. The worst problem is we might instantiate 1317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // two shim instances, but they'll share the same state so that's ok. 1327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (shim == null) { 1337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert try { 1347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Class<?> cls = Class.forName("com.ibm.icu.util.CurrencyServiceShim"); 1357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert shim = (ServiceShim)cls.newInstance(); 1367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert catch (Exception e) { 1387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if(DEBUG){ 1397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert e.printStackTrace(); 1407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert throw new RuntimeException(e.getMessage()); 1427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return shim; 1457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 1487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Returns a currency object for the default currency in the given 1497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * locale. 1507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param locale the locale 1517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @return the currency object for this locale 1527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 2.2 1537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 1547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static Currency getInstance(Locale locale) { 1557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return getInstance(ULocale.forLocale(locale)); 1567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 1597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Returns a currency object for the default currency in the given 1607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * locale. 1617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 3.2 1627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 1637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static Currency getInstance(ULocale locale) { 1647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String currency = locale.getKeywordValue("currency"); 1657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (currency != null) { 1667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return getInstance(currency); 1677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (shim == null) { 1707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return createCurrency(locale); 1717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return shim.createInstance(locale); 1747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 1777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Returns an array of Strings which contain the currency 1787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * identifiers that are valid for the given locale on the 1797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * given date. If there are no such identifiers, returns null. 1807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Returned identifiers are in preference order. 1817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param loc the locale for which to retrieve currency codes. 1827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param d the date for which to retrieve currency codes for the given locale. 1837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @return The array of ISO currency codes. 1847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 4.0 1857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 1867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static String[] getAvailableCurrencyCodes(ULocale loc, Date d) { 1877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert CurrencyFilter filter = CurrencyFilter.onDate(d).withRegion(loc.getCountry()); 1887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert List<String> list = getTenderCurrencies(filter); 1897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Note: Prior to 4.4 the spec didn't say that we return null if there are no results, but 1907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // the test assumed it did. Kept the behavior and amended the spec. 1917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (list.isEmpty()) { 1927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return null; 1937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return list.toArray(new String[list.size()]); 1957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 1987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Returns an array of Strings which contain the currency 1997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * identifiers that are valid for the given JDK locale on the 2007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * given date. If there are no such identifiers, returns null. 2017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Returned identifiers are in preference order. 2027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param loc the JDK locale for which to retrieve currency codes. 2037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param d the date for which to retrieve currency codes for the given locale. 2047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @return The array of ISO currency codes. 2057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @draft ICU 54 2067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @provisional This API might change or be removed in a future release. 2077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 2087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static String[] getAvailableCurrencyCodes(Locale loc, Date d) { 2097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return getAvailableCurrencyCodes(ULocale.forLocale(loc), d); 2107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 2137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Returns the set of available currencies. The returned set of currencies contains all of the 2147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * available currencies, including obsolete ones. The result set can be modified without 2157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * affecting the available currencies in the runtime. 2167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 2177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @return The set of available currencies. The returned set could be empty if there is no 2187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * currency data available. 2197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 2207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 49 2217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 2227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static Set<Currency> getAvailableCurrencies() { 2237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert CurrencyMetaInfo info = CurrencyMetaInfo.getInstance(); 2247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert List<String> list = info.currencies(CurrencyFilter.all()); 2257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert HashSet<Currency> resultSet = new HashSet<Currency>(list.size()); 2267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (String code : list) { 2277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert resultSet.add(getInstance(code)); 2287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return resultSet; 2307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private static final String EUR_STR = "EUR"; 2337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private static final ICUCache<ULocale, String> currencyCodeCache = new SimpleCache<ULocale, String>(); 2347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 2367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Instantiate a currency from resource data. 2377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 2387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /* package */ static Currency createCurrency(ULocale loc) { 2397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String variant = loc.getVariant(); 2417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if ("EURO".equals(variant)) { 2427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return getInstance(EUR_STR); 2437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String code = currencyCodeCache.get(loc); 2467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (code == null) { 2477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String country = loc.getCountry(); 2487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert CurrencyMetaInfo info = CurrencyMetaInfo.getInstance(); 2507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert List<String> list = info.currencies(CurrencyFilter.onRegion(country)); 2517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (list.size() > 0) { 2527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert code = list.get(0); 2537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert boolean isPreEuro = "PREEURO".equals(variant); 2547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (isPreEuro && EUR_STR.equals(code)) { 2557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (list.size() < 2) { 2567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return null; 2577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert code = list.get(1); 2597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 2617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return null; 2627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert currencyCodeCache.put(loc, code); 2647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return getInstance(code); 2667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 2697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Returns a currency object given an ISO 4217 3-letter code. 2707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param theISOCode the iso code 2717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @return the currency for this iso code 2727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @throws NullPointerException if <code>theISOCode</code> is null. 2737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @throws IllegalArgumentException if <code>theISOCode</code> is not a 2747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 3-letter alpha code. 2757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 2.2 2767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 2777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static Currency getInstance(String theISOCode) { 2787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (theISOCode == null) { 2797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert throw new NullPointerException("The input currency code is null."); 2807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (!isAlpha3Code(theISOCode)) { 2827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert throw new IllegalArgumentException( 2837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "The input currency code is not 3-letter alphabetic code."); 2847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return (Currency) MeasureUnit.internalGetInstance("currency", theISOCode.toUpperCase(Locale.ENGLISH)); 2867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private static boolean isAlpha3Code(String code) { 2907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (code.length() != 3) { 2917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return false; 2927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 2937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int i = 0; i < 3; i++) { 2947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert char ch = code.charAt(i); 2957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (ch < 'A' || (ch > 'Z' && ch < 'a') || ch > 'z') { 2967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return false; 2977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return true; 3017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 3047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Registers a new currency for the provided locale. The returned object 3057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * is a key that can be used to unregister this currency object. 3067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 3077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p>Because ICU may choose to cache Currency objects internally, this must 3087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * be called at application startup, prior to any calls to 3097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Currency.getInstance to avoid undefined behavior. 3107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 3117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param currency the currency to register 3127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param locale the ulocale under which to register the currency 3137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @return a registry key that can be used to unregister this currency 3147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @see #unregister 3157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 3.2 3167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 3177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static Object registerInstance(Currency currency, ULocale locale) { 3187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return getShim().registerInstance(currency, locale); 3197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 3227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Unregister the currency associated with this key (obtained from 3237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * registerInstance). 3247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param registryKey the registry key returned from registerInstance 3257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @see #registerInstance 3267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 2.6 3277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 3287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static boolean unregister(Object registryKey) { 3297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (registryKey == null) { 3307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert throw new IllegalArgumentException("registryKey must not be null"); 3317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (shim == null) { 3337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return false; 3347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return shim.unregister(registryKey); 3367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 3397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Return an array of the locales for which a currency 3407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * is defined. 3417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @return an array of the available locales 3427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 2.2 3437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 3447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static Locale[] getAvailableLocales() { 3457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (shim == null) { 3467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return ICUResourceBundle.getAvailableLocales(); 3477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 3487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return shim.getAvailableLocales(); 3497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 3537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Return an array of the ulocales for which a currency 3547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * is defined. 3557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @return an array of the available ulocales 3567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 3.2 3577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 3587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static ULocale[] getAvailableULocales() { 3597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (shim == null) { 3607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return ICUResourceBundle.getAvailableULocales(); 3617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 3627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return shim.getAvailableULocales(); 3637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // end registry stuff 3677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 3697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Given a key and a locale, returns an array of values for the key for which data 3707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * exists. If commonlyUsed is true, these are the values that typically are used 3717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * with this locale, otherwise these are all values for which data exists. 3727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * This is a common service API. 3737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p> 3747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * The only supported key is "currency", other values return an empty array. 3757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p> 3767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Currency information is based on the region of the locale. If the locale does not 3777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * indicate a region, {@link ULocale#addLikelySubtags(ULocale)} is used to infer a region, 3787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * except for the 'und' locale. 3797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p> 3807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * If commonlyUsed is true, only the currencies known to be in use as of the current date 3817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * are returned. When there are more than one, these are returned in preference order 3827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * (typically, this occurs when a country is transitioning to a new currency, and the 3837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * newer currency is preferred), see 3847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <a href="http://unicode.org/reports/tr35/#Supplemental_Currency_Data">Unicode TR#35 Sec. C1</a>. 3857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * If commonlyUsed is false, all currencies ever used in any locale are returned, in no 3867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * particular order. 3877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 3887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param key key whose values to look up. the only recognized key is "currency" 3897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param locale the locale 3907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param commonlyUsed if true, return only values that are currently used in the locale. 3917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Otherwise returns all values. 3927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @return an array of values for the given key and the locale. If there is no data, the 3937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * array will be empty. 3947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 4.2 3957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 3967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static final String[] getKeywordValuesForLocale(String key, ULocale locale, 3977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert boolean commonlyUsed) { 3987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // The only keyword we recognize is 'currency' 4007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (!"currency".equals(key)) { 4017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return EMPTY_STRING_ARRAY; 4027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (!commonlyUsed) { 4057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Behavior change from 4.3.3, no longer sort the currencies 4067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return getAllTenderCurrencies().toArray(new String[0]); 4077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Don't resolve region if the requested locale is 'und', it will resolve to US 4107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // which we don't want. 4117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String prefRegion = locale.getCountry(); 4127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (prefRegion.length() == 0) { 4137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (UND.equals(locale)) { 4147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return EMPTY_STRING_ARRAY; 4157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ULocale loc = ULocale.addLikelySubtags(locale); 4177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert prefRegion = loc.getCountry(); 4187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert CurrencyFilter filter = CurrencyFilter.now().withRegion(prefRegion); 4217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // currencies are in region's preferred order when we're filtering on region, which 4237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // matches our spec 4247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert List<String> result = getTenderCurrencies(filter); 4257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // No fallback anymore (change from 4.3.3) 4277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (result.size() == 0) { 4287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return EMPTY_STRING_ARRAY; 4297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return result.toArray(new String[result.size()]); 4327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private static final ULocale UND = new ULocale("und"); 4357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private static final String[] EMPTY_STRING_ARRAY = new String[0]; 4367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 4387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Returns the ISO 4217 3-letter code for this currency object. 4397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 2.2 4407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 4417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public String getCurrencyCode() { 4427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return subType; 4437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 4467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Returns the ISO 4217 numeric code for this currency object. 4477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p>Note: If the ISO 4217 numeric code is not assigned for the currency or 4487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * the currency is unknown, this method returns 0.</p> 4497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @return The ISO 4217 numeric code of this currency. 4507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 49 4517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 4527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public int getNumericCode() { 4537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int result = 0; 4547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert try { 4557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert UResourceBundle bundle = UResourceBundle.getBundleInstance( 4567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ICUResourceBundle.ICU_BASE_NAME, 4577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "currencyNumericCodes", 4587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ICUResourceBundle.ICU_DATA_CLASS_LOADER); 4597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert UResourceBundle codeMap = bundle.get("codeMap"); 4607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert UResourceBundle numCode = codeMap.get(subType); 4617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert result = numCode.getInt(); 4627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } catch (MissingResourceException e) { 4637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // fall through 4647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return result; 4667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 4697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Convenience and compatibility override of getName that 4707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * requests the symbol name for the default <code>DISPLAY</code> locale. 4717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @see #getName 4727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @see Category#DISPLAY 4737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 3.4 4747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 4757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public String getSymbol() { 4767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return getSymbol(ULocale.getDefault(Category.DISPLAY)); 4777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 4807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Convenience and compatibility override of getName that 4817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * requests the symbol name. 4827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param loc the Locale for the symbol 4837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @see #getName 4847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 3.4 4857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 4867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public String getSymbol(Locale loc) { 4877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return getSymbol(ULocale.forLocale(loc)); 4887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 4917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Convenience and compatibility override of getName that 4927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * requests the symbol name. 4937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param uloc the ULocale for the symbol 4947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @see #getName 4957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 3.4 4967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 4977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public String getSymbol(ULocale uloc) { 4987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return getName(uloc, SYMBOL_NAME, new boolean[1]); 4997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 5027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Returns the display name for the given currency in the 5037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * given locale. 5047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * This is a convenient method for 5057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * getName(ULocale, int, boolean[]); 5067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 3.2 5077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 5087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public String getName(Locale locale, 5097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int nameStyle, 5107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert boolean[] isChoiceFormat) { 5117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return getName(ULocale.forLocale(locale), nameStyle, isChoiceFormat); 5127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 5157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Returns the display name for the given currency in the 5167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * given locale. For example, the display name for the USD 5177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * currency object in the en_US locale is "$". 5187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param locale locale in which to display currency 5197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param nameStyle selector for which kind of name to return. 5207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * The nameStyle should be either SYMBOL_NAME or 5217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * LONG_NAME. Otherwise, throw IllegalArgumentException. 5227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param isChoiceFormat fill-in; isChoiceFormat[0] is set to true 5237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * if the returned value is a ChoiceFormat pattern; otherwise it 5247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * is set to false 5257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @return display string for this currency. If the resource data 5267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * contains no entry for this currency, then the ISO 4217 code is 5277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * returned. If isChoiceFormat[0] is true, then the result is a 5287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * ChoiceFormat pattern. Otherwise it is a static string. <b>Note:</b> 5297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * as of ICU 4.4, choice formats are not used, and the value returned 5307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * in isChoiceFormat is always false. 5317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p> 5327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @throws IllegalArgumentException if the nameStyle is not SYMBOL_NAME 5337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * or LONG_NAME. 5347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @see #getName(ULocale, int, String, boolean[]) 5357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 3.2 5367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 5377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public String getName(ULocale locale, int nameStyle, boolean[] isChoiceFormat) { 5387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (!(nameStyle == SYMBOL_NAME || nameStyle == LONG_NAME)) { 5397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert throw new IllegalArgumentException("bad name style: " + nameStyle); 5407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // We no longer support choice format data in names. Data should not contain 5437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // choice patterns. 5447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (isChoiceFormat != null) { 5457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert isChoiceFormat[0] = false; 5467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert CurrencyDisplayNames names = CurrencyDisplayNames.getInstance(locale); 5497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return nameStyle == SYMBOL_NAME ? names.getSymbol(subType) : names.getName(subType); 5507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 5537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Returns the display name for the given currency in the given locale. 5547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * This is a convenience overload of getName(ULocale, int, String, boolean[]); 5557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 4.2 5567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 5577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public String getName(Locale locale, int nameStyle, String pluralCount, 5587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert boolean[] isChoiceFormat) { 5597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return getName(ULocale.forLocale(locale), nameStyle, pluralCount, isChoiceFormat); 5607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 5637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Returns the display name for the given currency in the 5647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * given locale. For example, the SYMBOL_NAME for the USD 5657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * currency object in the en_US locale is "$". 5667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * The PLURAL_LONG_NAME for the USD currency object when the currency 5677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * amount is plural is "US dollars", such as in "3.00 US dollars"; 5687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * while the PLURAL_LONG_NAME for the USD currency object when the currency 5697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * amount is singular is "US dollar", such as in "1.00 US dollar". 5707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param locale locale in which to display currency 5717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param nameStyle selector for which kind of name to return 5727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param pluralCount plural count string for this locale 5737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param isChoiceFormat fill-in; isChoiceFormat[0] is set to true 5747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * if the returned value is a ChoiceFormat pattern; otherwise it 5757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * is set to false 5767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @return display string for this currency. If the resource data 5777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * contains no entry for this currency, then the ISO 4217 code is 5787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * returned. If isChoiceFormat[0] is true, then the result is a 5797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * ChoiceFormat pattern. Otherwise it is a static string. <b>Note:</b> 5807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * as of ICU 4.4, choice formats are not used, and the value returned 5817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * in isChoiceFormat is always false. 5827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @throws IllegalArgumentException if the nameStyle is not SYMBOL_NAME, 5837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * LONG_NAME, or PLURAL_LONG_NAME. 5847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 4.2 5857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 5867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public String getName(ULocale locale, int nameStyle, String pluralCount, 5877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert boolean[] isChoiceFormat) { 5887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (nameStyle != PLURAL_LONG_NAME) { 5897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return getName(locale, nameStyle, isChoiceFormat); 5907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // We no longer support choice format 5937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (isChoiceFormat != null) { 5947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert isChoiceFormat[0] = false; 5957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert CurrencyDisplayNames names = CurrencyDisplayNames.getInstance(locale); 5987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return names.getPluralName(subType, pluralCount); 5997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 6007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 6027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Returns the display name for this currency in the default locale. 6037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * If the resource data for the default locale contains no entry for this currency, 6047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * then the ISO 4217 code is returned. 6057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p> 6067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Note: This method was added for JDK compatibility support and equivalent to 6077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <code>getName(Locale.getDefault(), LONG_NAME, null)</code>. 6087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 6097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @return The display name of this currency 6107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @see #getDisplayName(Locale) 6117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @see #getName(Locale, int, boolean[]) 6127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 49 6137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 6147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public String getDisplayName() { 6157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return getName(Locale.getDefault(), LONG_NAME, null); 6167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 6177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 6197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Returns the display name for this currency in the given locale. 6207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * If the resource data for the given locale contains no entry for this currency, 6217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * then the ISO 4217 code is returned. 6227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p> 6237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Note: This method was added for JDK compatibility support and equivalent to 6247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <code>getName(locale, LONG_NAME, null)</code>. 6257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 6267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param locale locale in which to display currency 6277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @return The display name of this currency for the specified locale 6287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @see #getDisplayName(Locale) 6297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @see #getName(Locale, int, boolean[]) 6307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 49 6317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 6327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public String getDisplayName(Locale locale) { 6337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return getName(locale, LONG_NAME, null); 6347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 6357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 6377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Attempt to parse the given string as a currency, either as a 6387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * display name in the given locale, or as a 3-letter ISO 4217 6397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * code. If multiple display names match, then the longest one is 6407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * selected. If both a display name and a 3-letter ISO code 6417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * match, then the display name is preferred, unless it's length 6427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * is less than 3. 6437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 6447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param locale the locale of the display names to match 6457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param text the text to parse 6467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param type parse against currency type: LONG_NAME only or not 6477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param pos input-output position; on input, the position within 6487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * text to match; must have 0 <= pos.getIndex() < text.length(); 6497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * on output, the position after the last matched character. If 6507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * the parse fails, the position in unchanged upon output. 6517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @return the ISO 4217 code, as a string, of the best match, or 6527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * null if there is no match 6537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 6547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @internal 6557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @deprecated This API is ICU internal only. 6567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 6577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert @Deprecated 6587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static String parse(ULocale locale, String text, int type, ParsePosition pos) { 6597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert List<TextTrieMap<CurrencyStringInfo>> currencyTrieVec = CURRENCY_NAME_CACHE.get(locale); 6607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (currencyTrieVec == null) { 6617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TextTrieMap<CurrencyStringInfo> currencyNameTrie = 6627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert new TextTrieMap<CurrencyStringInfo>(true); 6637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TextTrieMap<CurrencyStringInfo> currencySymbolTrie = 6647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert new TextTrieMap<CurrencyStringInfo>(false); 6657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert currencyTrieVec = new ArrayList<TextTrieMap<CurrencyStringInfo>>(); 6667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert currencyTrieVec.add(currencySymbolTrie); 6677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert currencyTrieVec.add(currencyNameTrie); 6687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert setupCurrencyTrieVec(locale, currencyTrieVec); 6697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert CURRENCY_NAME_CACHE.put(locale, currencyTrieVec); 6707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 6717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int maxLength = 0; 6737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String isoResult = null; 6747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // look for the names 6767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TextTrieMap<CurrencyStringInfo> currencyNameTrie = currencyTrieVec.get(1); 6777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert CurrencyNameResultHandler handler = new CurrencyNameResultHandler(); 6787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert currencyNameTrie.find(text, pos.getIndex(), handler); 6797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert isoResult = handler.getBestCurrencyISOCode(); 6807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert maxLength = handler.getBestMatchLength(); 6817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (type != Currency.LONG_NAME) { // not long name only 6837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TextTrieMap<CurrencyStringInfo> currencySymbolTrie = currencyTrieVec.get(0); 6847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert handler = new CurrencyNameResultHandler(); 6857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert currencySymbolTrie.find(text, pos.getIndex(), handler); 6867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (handler.getBestMatchLength() > maxLength) { 6877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert isoResult = handler.getBestCurrencyISOCode(); 6887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert maxLength = handler.getBestMatchLength(); 6897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 6907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 6917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int start = pos.getIndex(); 6927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert pos.setIndex(start + maxLength); 6937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return isoResult; 6947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 6957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private static void setupCurrencyTrieVec(ULocale locale, 6977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert List<TextTrieMap<CurrencyStringInfo>> trieVec) { 6987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TextTrieMap<CurrencyStringInfo> symTrie = trieVec.get(0); 7007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TextTrieMap<CurrencyStringInfo> trie = trieVec.get(1); 7017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 7027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert CurrencyDisplayNames names = CurrencyDisplayNames.getInstance(locale); 7037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (Map.Entry<String, String> e : names.symbolMap().entrySet()) { 7047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String symbol = e.getKey(); 7057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String isoCode = e.getValue(); 7067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Register under not just symbol, but under every equivalent symbol as well 7077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // e.g short width yen and long width yen. 7087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (String equivalentSymbol : EQUIVALENT_CURRENCY_SYMBOLS.get(symbol)) { 7097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert symTrie.put(equivalentSymbol, new CurrencyStringInfo(isoCode, symbol)); 7107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 7117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 7127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (Map.Entry<String, String> e : names.nameMap().entrySet()) { 7137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String name = e.getKey(); 7147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String isoCode = e.getValue(); 7157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert trie.put(name, new CurrencyStringInfo(isoCode, name)); 7167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 7177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 7187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 7197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private static final class CurrencyStringInfo { 7207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private String isoCode; 7217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private String currencyString; 7227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 7237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public CurrencyStringInfo(String isoCode, String currencyString) { 7247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert this.isoCode = isoCode; 7257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert this.currencyString = currencyString; 7267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 7277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 7287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public String getISOCode() { 7297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return isoCode; 7307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 7317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 7327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert @SuppressWarnings("unused") 7337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public String getCurrencyString() { 7347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return currencyString; 7357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 7367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 7377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 7387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private static class CurrencyNameResultHandler 7397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert implements TextTrieMap.ResultHandler<CurrencyStringInfo> { 7407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // The length of longest matching key 7417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private int bestMatchLength; 7427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // The currency ISO code of longest matching key 7437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private String bestCurrencyISOCode; 7447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 7457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // As the trie is traversed, handlePrefixMatch is called at each node. matchLength is the 7467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // length length of the key at the current node; values is the list of all the values mapped to 7477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // that key. matchLength increases with each call as trie is traversed. 7487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public boolean handlePrefixMatch(int matchLength, Iterator<CurrencyStringInfo> values) { 7497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (values.hasNext()) { 7507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Since the best match criteria is only based on length of key in trie and since all the 7517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // values are mapped to the same key, we only need to examine the first value. 7527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert bestCurrencyISOCode = values.next().getISOCode(); 7537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert bestMatchLength = matchLength; 7547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 7557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return true; 7567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 7577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 7587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public String getBestCurrencyISOCode() { 7597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return bestCurrencyISOCode; 7607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 7617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 7627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public int getBestMatchLength() { 7637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return bestMatchLength; 7647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 7657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 7667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 7677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 7687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Returns the number of the number of fraction digits that should 7697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * be displayed for this currency. 7707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * This is equivalent to getDefaultFractionDigits(CurrencyUsage.STANDARD); 7717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @return a non-negative number of fraction digits to be 7727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * displayed 7737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 2.2 7747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 7757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public int getDefaultFractionDigits() { 7767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return getDefaultFractionDigits(CurrencyUsage.STANDARD); 7777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 7787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 7797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 7807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Returns the number of the number of fraction digits that should 7817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * be displayed for this currency with Usage. 7827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param Usage the usage of currency(Standard or Cash) 7837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @return a non-negative number of fraction digits to be 7847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * displayed 7857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @draft ICU 54 7867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @provisional This API might change or be removed in a future release. 7877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 7887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public int getDefaultFractionDigits(CurrencyUsage Usage) { 7897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert CurrencyMetaInfo info = CurrencyMetaInfo.getInstance(); 7907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert CurrencyDigits digits = info.currencyDigits(subType, Usage); 7917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return digits.fractionDigits; 7927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 7937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 7947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 7957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Returns the rounding increment for this currency, or 0.0 if no 7967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * rounding is done by this currency. 7977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * This is equivalent to getRoundingIncrement(CurrencyUsage.STANDARD); 7987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @return the non-negative rounding increment, or 0.0 if none 7997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 2.2 8007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 8017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public double getRoundingIncrement() { 8027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return getRoundingIncrement(CurrencyUsage.STANDARD); 8037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 8047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 8057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 8067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Returns the rounding increment for this currency, or 0.0 if no 8077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * rounding is done by this currency with the Usage. 8087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param Usage the usage of currency(Standard or Cash) 8097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @return the non-negative rounding increment, or 0.0 if none 8107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @draft ICU 54 8117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @provisional This API might change or be removed in a future release. 8127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 8137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public double getRoundingIncrement(CurrencyUsage Usage) { 8147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert CurrencyMetaInfo info = CurrencyMetaInfo.getInstance(); 8157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert CurrencyDigits digits = info.currencyDigits(subType, Usage); 8167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 8177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int data1 = digits.roundingIncrement; 8187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 8197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // If there is no rounding return 0.0 to indicate no rounding. 8207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // This is the high-runner case, by far. 8217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (data1 == 0) { 8227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return 0.0; 8237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 8247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 8257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int data0 = digits.fractionDigits; 8267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 8277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // If the meta data is invalid, return 0.0 to indicate no rounding. 8287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (data0 < 0 || data0 >= POW10.length) { 8297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return 0.0; 8307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 8317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 8327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Return data[1] / 10^(data[0]). The only actual rounding data, 8337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // as of this writing, is CHF { 2, 25 }. 8347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return (double) data1 / POW10[data0]; 8357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 8367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 8377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 8387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Returns the ISO 4217 code for this currency. 8397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 2.2 8407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 8417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public String toString() { 8427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return subType; 8437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 8447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 8457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 8467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Constructs a currency object for the given ISO 4217 3-letter 8477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * code. This constructor assumes that the code is valid. 8487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 8497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param theISOCode The iso code used to construct the currency. 8507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 3.4 8517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 8527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert protected Currency(String theISOCode) { 8537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert super("currency", theISOCode); 8547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 8557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // isoCode is kept for readResolve() and Currency class no longer 8567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // use it. So this statement actually does not have any effect. 8577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert isoCode = theISOCode; 8587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 8597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 8607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // POW10[i] = 10^i 8617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private static final int[] POW10 = { 8627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 8637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert }; 8647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 8657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 8667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private static SoftReference<List<String>> ALL_TENDER_CODES; 8677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private static SoftReference<Set<String>> ALL_CODES_AS_SET; 8687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /* 8697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Returns an unmodifiable String list including all known tender currency codes. 8707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 8717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private static synchronized List<String> getAllTenderCurrencies() { 8727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert List<String> all = (ALL_TENDER_CODES == null) ? null : ALL_TENDER_CODES.get(); 8737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (all == null) { 8747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Filter out non-tender currencies which have "from" date set to 9999-12-31 8757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // CurrencyFilter has "to" value set to 9998-12-31 in order to exclude them 8767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert //CurrencyFilter filter = CurrencyFilter.onDateRange(null, new Date(253373299200000L)); 8777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert CurrencyFilter filter = CurrencyFilter.all(); 8787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert all = Collections.unmodifiableList(getTenderCurrencies(filter)); 8797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ALL_TENDER_CODES = new SoftReference<List<String>>(all); 8807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 8817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return all; 8827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 8837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 8847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private static synchronized Set<String> getAllCurrenciesAsSet() { 8857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Set<String> all = (ALL_CODES_AS_SET == null) ? null : ALL_CODES_AS_SET.get(); 8867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (all == null) { 8877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert CurrencyMetaInfo info = CurrencyMetaInfo.getInstance(); 8887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert all = Collections.unmodifiableSet( 8897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert new HashSet<String>(info.currencies(CurrencyFilter.all()))); 8907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ALL_CODES_AS_SET = new SoftReference<Set<String>>(all); 8917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 8927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return all; 8937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 8947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 8957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 8967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Queries if the given ISO 4217 3-letter code is available on the specified date range. 8977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p> 8987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Note: For checking availability of a currency on a specific date, specify the date on both <code>from</code> and 8997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <code>to</code>. When both <code>from</code> and <code>to</code> are null, this method checks if the specified 9007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * currency is available all time. 9017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 9027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param code 9037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * The ISO 4217 3-letter code. 9047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param from 9057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * The lower bound of the date range, inclusive. When <code>from</code> is null, check the availability 9067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * of the currency any date before <code>to</code> 9077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param to 9087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * The upper bound of the date range, inclusive. When <code>to</code> is null, check the availability of 9097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * the currency any date after <code>from</code> 9107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @return true if the given ISO 4217 3-letter code is supported on the specified date range. 9117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @throws IllegalArgumentException when <code>to</code> is before <code>from</code>. 9127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 9137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 4.6 9147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 9157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static boolean isAvailable(String code, Date from, Date to) { 9167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (!isAlpha3Code(code)) { 9177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return false; 9187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 9197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 9207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (from != null && to != null && from.after(to)) { 9217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert throw new IllegalArgumentException("To is before from"); 9227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 9237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 9247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert code = code.toUpperCase(Locale.ENGLISH); 9257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert boolean isKnown = getAllCurrenciesAsSet().contains(code); 9267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (isKnown == false) { 9277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return false; 9287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else if (from == null && to == null) { 9297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return true; 9307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 9317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 9327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // If caller passed a date range, we cannot rely solely on the cache 9337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert CurrencyMetaInfo info = CurrencyMetaInfo.getInstance(); 9347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert List<String> allActive = info.currencies( 9357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert CurrencyFilter.onDateRange(from, to).withCurrency(code)); 9367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return allActive.contains(code); 9377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 9387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 9397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 9407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Returns the list of remaining tender currencies after a filter is applied. 9417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param filter the filter to apply to the tender currencies 9427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @return a list of tender currencies 9437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 9447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private static List<String> getTenderCurrencies(CurrencyFilter filter) { 9457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert CurrencyMetaInfo info = CurrencyMetaInfo.getInstance(); 9467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return info.currencies(filter.withTender()); 9477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 9487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 9497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private static final class EquivalenceRelation<T> { 9507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 9517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private Map<T, Set<T>> data = new HashMap<T, Set<T>>(); 9527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 9537388b89454a914dd65a78a7fc321f60cd211561dFredrik Roubert @SuppressWarnings("unchecked") // See ticket #11395, this is safe. 9547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public EquivalenceRelation<T> add(T... items) { 9557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Set<T> group = new HashSet<T>(); 9567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (T item : items) { 9577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (data.containsKey(item)) { 9587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert throw new IllegalArgumentException("All groups passed to add must be disjoint."); 9597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 9607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert group.add(item); 9617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 9627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (T item : items) { 9637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert data.put(item, group); 9647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 9657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return this; 9667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 9677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 9687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public Set<T> get(T item) { 9697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Set<T> result = data.get(item); 9707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (result == null) { 9717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return Collections.singleton(item); 9727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 9737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return Collections.unmodifiableSet(result); 9747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 9757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 9767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 9777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private Object writeReplace() throws ObjectStreamException { 9787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return new MeasureUnitProxy(type, subType); 9797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 9807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 9817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // For backward compatibility only 9827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 9837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * ISO 4217 3-letter code. 9847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 9857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private final String isoCode; 9867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 9877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private Object readResolve() throws ObjectStreamException { 9887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // The old isoCode field used to determine the currency. 9897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return Currency.getInstance(isoCode); 9907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 9917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert} 9927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//eof 993