ICU-9800 Fix Currency.isAvailable() to return true for a currency that is available but is non-tender.

X-SVN-Rev: 33037
This commit is contained in:
Travis Keep 2013-01-11 19:15:17 +00:00
parent f497bdb604
commit 16192c32d3
2 changed files with 25 additions and 22 deletions

View file

@ -1,6 +1,6 @@
/**
*******************************************************************************
* Copyright (C) 2001-2012, International Business Machines Corporation and *
* Copyright (C) 2001-2013, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
@ -29,7 +29,6 @@ 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;
import com.ibm.icu.text.CurrencyMetaInfo.CurrencyInfo;
import com.ibm.icu.util.ULocale.Category;
/**
@ -358,7 +357,7 @@ public class Currency extends MeasureUnit implements Serializable {
if (!commonlyUsed) {
// Behavior change from 4.3.3, no longer sort the currencies
return getAvailableCurrencyCodes().toArray(new String[0]);
return getAllTenderCurrencies().toArray(new String[0]);
}
// Don't resolve region if the requested locale is 'und', it will resolve to US
@ -833,19 +832,31 @@ public class Currency extends MeasureUnit implements Serializable {
};
private static SoftReference<List<String>> ALL_CODES;
private static SoftReference<List<String>> ALL_TENDER_CODES;
private static SoftReference<Set<String>> ALL_CODES_AS_SET;
/*
* Returns an unmodifiable String list including all known tender currency codes.
*/
private static synchronized List<String> getAvailableCurrencyCodes() {
List<String> all = (ALL_CODES == null) ? null : ALL_CODES.get();
private static synchronized List<String> getAllTenderCurrencies() {
List<String> all = (ALL_TENDER_CODES == null) ? null : ALL_TENDER_CODES.get();
if (all == null) {
// Filter out non-tender currencies which have "from" date set to 9999-12-31
// CurrencyFilter has "to" value set to 9998-12-31 in order to exclude them
//CurrencyFilter filter = CurrencyFilter.onDateRange(null, new Date(253373299200000L));
CurrencyFilter filter = CurrencyFilter.all();
all = Collections.unmodifiableList(getTenderCurrencies(filter));
ALL_CODES = new SoftReference<List<String>>(all);
ALL_TENDER_CODES = new SoftReference<List<String>>(all);
}
return all;
}
private static synchronized Set<String> getAllCurrenciesAsSet() {
Set<String> all = (ALL_CODES_AS_SET == null) ? null : ALL_CODES_AS_SET.get();
if (all == null) {
CurrencyMetaInfo info = CurrencyMetaInfo.getInstance();
all = Collections.unmodifiableSet(
new HashSet<String>(info.currencies(CurrencyFilter.all())));
ALL_CODES_AS_SET = new SoftReference<Set<String>>(all);
}
return all;
}
@ -880,17 +891,17 @@ public class Currency extends MeasureUnit implements Serializable {
}
code = code.toUpperCase(Locale.ENGLISH);
boolean isKnown = getAvailableCurrencyCodes().contains(code);
boolean isKnown = getAllCurrenciesAsSet().contains(code);
if (isKnown == false) {
return false;
} else if (from == null && to == null) {
return true;
}
// When asActiveOnly is true, check if the currency is currently
// active or not.
// If caller passed a date range, we cannot rely solely on the cache
CurrencyMetaInfo info = CurrencyMetaInfo.getInstance();
List<String> allActive = info.currencies(CurrencyFilter.onDateRange(from, to));
List<String> allActive = info.currencies(
CurrencyFilter.onDateRange(from, to).withCurrency(code));
return allActive.contains(code);
}
@ -901,16 +912,7 @@ public class Currency extends MeasureUnit implements Serializable {
*/
private static List<String> getTenderCurrencies(CurrencyFilter filter) {
CurrencyMetaInfo info = CurrencyMetaInfo.getInstance();
List<CurrencyInfo> infoList = info.currencyInfo(filter);
List<String> list = new ArrayList<String>();
for (CurrencyInfo currencyInfo : infoList) {
// Non-tender currencies always have a from of MIN_VALUE and a to of MAX_VALUE, so
// exclude them.
if (currencyInfo.from != Long.MIN_VALUE || currencyInfo.to != Long.MAX_VALUE) {
list.add(currencyInfo.code);
}
}
return list;
return info.currencies(filter.withTender());
}
}
//eof

View file

@ -645,8 +645,9 @@ public class CurrencyTest extends TestFmwk {
assertFalse("DEM after 2005", Currency.isAvailable("DEM", d2005, null));
assertTrue("DEM on 2000-01-01", Currency.isAvailable("DEM", d2000, d2000));
assertFalse("DEM on 2005-01-01", Currency.isAvailable("DEM", d2005, d2005));
assertTrue("CHE all the time", Currency.isAvailable("CHE", null, null));
assertFalse("XXX unknown code", Currency.isAvailable("XXX", null, null));
assertFalse("XXY unknown code", Currency.isAvailable("XXY", null, null));
assertFalse("USDOLLAR invalid code", Currency.isAvailable("USDOLLAR", null, null));