/** ******************************************************************************* * Copyright (C) 2001-2010, International Business Machines Corporation and * * others. All Rights Reserved. * ******************************************************************************* */ package com.ibm.icu.util; import java.io.Serializable; import java.text.ParsePosition; import java.util.ArrayList; import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Vector; import com.ibm.icu.impl.ICUCache; import com.ibm.icu.impl.ICUDebug; import com.ibm.icu.impl.ICUResourceBundle; import com.ibm.icu.impl.SimpleCache; import com.ibm.icu.impl.TextTrieMap; import com.ibm.icu.text.CurrencyDisplayNames; import com.ibm.icu.text.CurrencyMetaInfo; import com.ibm.icu.text.CurrencyMetaInfo.CurrencyDigits; import com.ibm.icu.text.CurrencyMetaInfo.CurrencyFilter; /** * A class encapsulating a currency, as defined by ISO 4217. A * Currency object can be created given a Locale or * given an ISO 4217 code. Once created, the Currency object * can return various data necessary to its proper display: * *
Note: This class deliberately resembles
* java.util.Currency but it has a completely independent
* implementation, and adds features not present in the JDK.
* @author Alan Liu
* @stable ICU 2.2
*/
public class Currency extends MeasureUnit implements Serializable {
// using serialver from jdk1.4.2_05
private static final long serialVersionUID = -5839973855554750484L;
private static final boolean DEBUG = ICUDebug.enabled("currency");
// Cache to save currency name trie
private static ICUCache
* The only supported key is "currency", other values return an empty array.
*
* Currency information is based on the region of the locale. If the locale does not
* indicate a region, {@link ULocale#addLikelySubtags(ULocale)} is used to infer a region,
* except for the 'und' locale.
*
* If commonlyUsed is true, only the currencies known to be in use as of the current date
* are returned. When there are more than one, these are returned in preference order
* (typically, this occurs when a country is transitioning to a new currency, and the
* newer currency is preferred), see
* Unicode TR#35 Sec. C1.
* If commonlyUsed is false, all currencies ever used in any locale are returned, in no
* particular order.
*
* @param key key whose values to look up. the only recognized key is "currency"
* @param locale the locale
* @param commonlyUsed if true, return only values that are currently used in the locale.
* Otherwise returns all values.
* @return an array of values for the given key and the locale. If there is no data, the
* array will be empty.
* @stable ICU 4.2
*/
public static final String[] getKeywordValuesForLocale(String key, ULocale locale,
boolean commonlyUsed) {
// The only keyword we recognize is 'currency'
if (!"currency".equals(key)) {
return EMPTY_STRING_ARRAY;
}
CurrencyMetaInfo info = CurrencyMetaInfo.getInstance();
if (!commonlyUsed) {
// Behavior change from 4.3.3, no longer sort the currencies
List
* @throws IllegalArgumentException if the nameStyle is not SYMBOL_NAME
* or LONG_NAME.
* @see #getName(ULocale, int, String, boolean[])
* @stable ICU 3.2
*/
public String getName(ULocale locale, int nameStyle, boolean[] isChoiceFormat) {
if (!(nameStyle == SYMBOL_NAME || nameStyle == LONG_NAME)) {
throw new IllegalArgumentException("bad name style: " + nameStyle);
}
// We no longer support choice format data in names. Data should not contain
// choice patterns.
if (isChoiceFormat != null) {
isChoiceFormat[0] = false;
}
CurrencyDisplayNames names = CurrencyDisplayNames.getInstance(locale);
return nameStyle == SYMBOL_NAME ? names.getSymbol(isoCode) : names.getName(isoCode);
}
/**
* Returns the display name for the given currency in the given locale.
* This is a convenience overload of getName(ULocale, int, String, boolean[]);
* @stable ICU 4.2
*/
public String getName(Locale locale, int nameStyle, String pluralCount,
boolean[] isChoiceFormat) {
return getName(ULocale.forLocale(locale), nameStyle, pluralCount, isChoiceFormat);
}
/**
* Returns the display name for the given currency in the
* given locale. For example, the SYMBOL_NAME for the USD
* currency object in the en_US locale is "$".
* The PLURAL_LONG_NAME for the USD currency object when the currency
* amount is plural is "US dollars", such as in "3.00 US dollars";
* while the PLURAL_LONG_NAME for the USD currency object when the currency
* amount is singular is "US dollar", such as in "1.00 US dollar".
* @param locale locale in which to display currency
* @param nameStyle selector for which kind of name to return
* @param pluralCount plural count string for this locale
* @param isChoiceFormat fill-in; isChoiceFormat[0] is set to true
* if the returned value is a ChoiceFormat pattern; otherwise it
* is set to false
* @return display string for this currency. If the resource data
* contains no entry for this currency, then the ISO 4217 code is
* returned. If isChoiceFormat[0] is true, then the result is a
* ChoiceFormat pattern. Otherwise it is a static string. Note:
* as of ICU 4.4, choice formats are not used, and the value returned
* in isChoiceFormat is always false.
* @throws IllegalArgumentException if the nameStyle is not SYMBOL_NAME,
* LONG_NAME, or PLURAL_LONG_NAME.
* @stable ICU 4.2
*/
public String getName(ULocale locale, int nameStyle, String pluralCount,
boolean[] isChoiceFormat) {
if (nameStyle != PLURAL_LONG_NAME) {
return getName(locale, nameStyle, isChoiceFormat);
}
// We no longer support choice format
if (isChoiceFormat != null) {
isChoiceFormat[0] = false;
}
CurrencyDisplayNames names = CurrencyDisplayNames.getInstance(locale);
return names.getPluralName(isoCode, pluralCount);
}
/**
* Attempt to parse the given string as a currency, either as a
* display name in the given locale, or as a 3-letter ISO 4217
* code. If multiple display names match, then the longest one is
* selected. If both a display name and a 3-letter ISO code
* match, then the display name is preferred, unless it's length
* is less than 3.
*
* @param locale the locale of the display names to match
* @param text the text to parse
* @param type parse against currency type: LONG_NAME only or not
* @param pos input-output position; on input, the position within
* text to match; must have 0 <= pos.getIndex() < text.length();
* on output, the position after the last matched character. If
* the parse fails, the position in unchanged upon output.
* @return the ISO 4217 code, as a string, of the best match, or
* null if there is no match
*
* @internal
* @deprecated This API is ICU internal only.
*/
public static String parse(ULocale locale, String text, int type, ParsePosition pos) {
Vector Note: This method will be obsoleted. The implementation is
* no longer locale-specific and so there is no longer a valid or
* actual locale associated with the Currency object. Until
* it is removed, this method will return the root locale.
* @param type type of information requested, either {@link
* com.ibm.icu.util.ULocale#VALID_LOCALE} or {@link
* com.ibm.icu.util.ULocale#ACTUAL_LOCALE}.
* @return the information specified by type, or null if
* this object was not constructed from locale data.
* @see com.ibm.icu.util.ULocale
* @see com.ibm.icu.util.ULocale#VALID_LOCALE
* @see com.ibm.icu.util.ULocale#ACTUAL_LOCALE
* @obsolete ICU 3.2 to be removed
* @deprecated This API is obsolete.
*/
public final ULocale getLocale(ULocale.Type type) {
ULocale result = (type == ULocale.ACTUAL_LOCALE) ? actualLocale : validLocale;
if (result == null) {
return ULocale.ROOT;
}
return result;
}
/**
* Set information about the locales that were used to create this
* object. If the object was not constructed from locale data,
* both arguments should be set to null. Otherwise, neither
* should be null. The actual locale must be at the same level or
* less specific than the valid locale. This method is intended
* for use by factories or other entities that create objects of
* this class.
* @param valid the most specific locale containing any resource
* data, or null
* @param actual the locale containing data used to construct this
* object, or null
* @see com.ibm.icu.util.ULocale
* @see com.ibm.icu.util.ULocale#VALID_LOCALE
* @see com.ibm.icu.util.ULocale#ACTUAL_LOCALE
*/
final void setLocale(ULocale valid, ULocale actual) {
// Change the following to an assertion later
if ((valid == null) != (actual == null)) {
///CLOVER:OFF
throw new IllegalArgumentException();
///CLOVER:ON
}
// Another check we could do is that the actual locale is at
// the same level or less specific than the valid locale.
this.validLocale = valid;
this.actualLocale = actual;
}
/*
* The most specific locale containing any resource data, or null.
*/
private ULocale validLocale;
/*
* The locale containing data used to construct this object, or null.
*/
private ULocale actualLocale;
// -------- END ULocale boilerplate --------
}
//eof
theISOCode
is null.
* @throws IllegalArgumentException if theISOCode
is not a
* 3-letter alpha code.
* @stable ICU 2.2
*/
public static Currency getInstance(String theISOCode) {
if (theISOCode == null) {
throw new NullPointerException("The input currency code is null.");
}
boolean is3alpha = true;
if (theISOCode.length() != 3) {
is3alpha = false;
} else {
for (int i = 0; i < 3; i++) {
char ch = theISOCode.charAt(i);
if (ch < 'A' || (ch > 'Z' && ch < 'a') || ch > 'z') {
is3alpha = false;
break;
}
}
}
if (!is3alpha) {
throw new IllegalArgumentException(
"The input currency code is not 3-letter alphabetic code.");
}
return new Currency(theISOCode.toUpperCase(Locale.US));
}
/**
* Registers a new currency for the provided locale. The returned object
* is a key that can be used to unregister this currency object.
* @param currency the currency to register
* @param locale the ulocale under which to register the currency
* @return a registry key that can be used to unregister this currency
* @see #unregister
* @stable ICU 3.2
*/
public static Object registerInstance(Currency currency, ULocale locale) {
return getShim().registerInstance(currency, locale);
}
/**
* Unregister the currency associated with this key (obtained from
* registerInstance).
* @param registryKey the registry key returned from registerInstance
* @see #registerInstance
* @stable ICU 2.6
*/
public static boolean unregister(Object registryKey) {
if (registryKey == null) {
throw new IllegalArgumentException("registryKey must not be null");
}
if (shim == null) {
return false;
}
return shim.unregister(registryKey);
}
/**
* Return an array of the locales for which a currency
* is defined.
* @return an array of the available locales
* @stable ICU 2.2
*/
public static Locale[] getAvailableLocales() {
if (shim == null) {
return ICUResourceBundle.getAvailableLocales();
} else {
return shim.getAvailableLocales();
}
}
/**
* Return an array of the ulocales for which a currency
* is defined.
* @return an array of the available ulocales
* @stable ICU 3.2
*/
public static ULocale[] getAvailableULocales() {
if (shim == null) {
return ICUResourceBundle.getAvailableULocales();
} else {
return shim.getAvailableULocales();
}
}
// end registry stuff
/**
* Given a key and a locale, returns an array of values for the key for which data
* exists. If commonlyUsed is true, these are the values that typically are used
* with this locale, otherwise these are all values for which data exists.
* This is a common service API.
*