ICU-9508 Merge changes from cmi branch into trunk.

X-SVN-Rev: 33025
This commit is contained in:
Travis Keep 2013-01-09 01:08:55 +00:00
parent a55953f65a
commit 4308b46d69
3 changed files with 159 additions and 32 deletions

View file

@ -1,6 +1,6 @@
/*
*******************************************************************************
* Copyright (C) 2009-2012, International Business Machines Corporation and *
* Copyright (C) 2009-2013, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
@ -99,22 +99,25 @@ public class CurrencyMetaInfo {
* @stable ICU 4.4
*/
public final long to;
/**
* true if we are filtering only for currencies used as legal tender.
* @internal
* @deprecated This API is ICU internal only.
*/
public final boolean tenderOnly;
private CurrencyFilter(String region, String currency, long from, long to) {
private CurrencyFilter(String region, String currency, long from, long to, boolean tenderOnly) {
this.region = region;
this.currency = currency;
this.from = from;
this.to = to;
this.tenderOnly = tenderOnly;
}
private CurrencyFilter(String region, String currency, Date dateFrom, Date dateTo) {
this.region = region;
this.currency = currency;
this.from = dateFrom == null ? Long.MIN_VALUE : dateFrom.getTime();
this.to = dateTo == null ? Long.MAX_VALUE : dateTo.getTime();
}
private static final CurrencyFilter ALL = new CurrencyFilter(null, null, null, null);
private static final CurrencyFilter ALL = new CurrencyFilter(
null, null, Long.MIN_VALUE, Long.MAX_VALUE, false);
/**
* Returns a filter that accepts all currency data.
@ -182,6 +185,38 @@ public class CurrencyMetaInfo {
public static CurrencyFilter onDateRange(Date from, Date to) {
return ALL.withDateRange(from, to);
}
/**
* Returns a filter that accepts all currencies in use on the given date.
* @param date the date as milliseconds after Jan 1, 1970
* @draft ICU 51
*/
public static CurrencyFilter onDate(long date) {
return ALL.withDate(date);
}
/**
* Returns a filter that accepts all currencies that were in use at some
* point between the given dates, or if dates are equal, currencies in
* use on that date.
* @param from The date on or after a currency must have been in use.
* Measured in milliseconds since Jan 1, 1970 GMT.
* @param to The date on or before which a currency must have been in use.
* Measured in milliseconds since Jan 1, 1970 GMT.
* @draft ICU 51
*/
public static CurrencyFilter onDateRange(long from, long to) {
return ALL.withDateRange(from, to);
}
/**
* Returns a CurrencyFilter for finding currencies that were either once used,
* are used, or will be used as tender.
* @draft ICU 51
*/
public static CurrencyFilter onTender() {
return ALL.withTender();
}
/**
* Returns a copy of this filter, with the specified region. Region can be null to
@ -192,7 +227,7 @@ public class CurrencyMetaInfo {
* @stable ICU 4.4
*/
public CurrencyFilter withRegion(String region) {
return new CurrencyFilter(region, this.currency, this.from, this.to);
return new CurrencyFilter(region, this.currency, this.from, this.to, this.tenderOnly);
}
/**
@ -204,7 +239,7 @@ public class CurrencyMetaInfo {
* @stable ICU 4.4
*/
public CurrencyFilter withCurrency(String currency) {
return new CurrencyFilter(this.region, currency, this.from, this.to);
return new CurrencyFilter(this.region, currency, this.from, this.to, this.tenderOnly);
}
/**
@ -215,7 +250,7 @@ public class CurrencyMetaInfo {
* @stable ICU 4.4
*/
public CurrencyFilter withDate(Date date) {
return new CurrencyFilter(this.region, this.currency, date, date);
return new CurrencyFilter(this.region, this.currency, date.getTime(), date.getTime(), this.tenderOnly);
}
/**
@ -228,7 +263,42 @@ public class CurrencyMetaInfo {
* @provisional This API might change or be removed in a future release.
*/
public CurrencyFilter withDateRange(Date from, Date to) {
return new CurrencyFilter(this.region, this.currency, from, to);
long fromLong = from == null ? Long.MIN_VALUE : from.getTime();
long toLong = to == null ? Long.MAX_VALUE : to.getTime();
return new CurrencyFilter(this.region, this.currency, fromLong, toLong, this.tenderOnly);
}
/**
* Returns a copy of this filter that accepts all currencies in use on
* the given date.
* @param date the date as milliseconds after Jan 1, 1970
* @draft ICU 51
*/
public CurrencyFilter withDate(long date) {
return new CurrencyFilter(this.region, this.currency, date, date, this.tenderOnly);
}
/**
* Returns a copy of this filter that accepts all currencies that were
* in use at some point between the given dates, or if dates are equal,
* currencies in use on that date.
* @param from The date on or after a currency must have been in use.
* Measured in milliseconds since Jan 1, 1970 GMT.
* @param to The date on or before which a currency must have been in use.
* Measured in milliseconds since Jan 1, 1970 GMT.
* @draft ICU 51
*/
public CurrencyFilter withDateRange(long from, long to) {
return new CurrencyFilter(this.region, this.currency, from, to, this.tenderOnly);
}
/**
* Returns a copy of this filter that filters for currencies that were
* either once used, are used, or will be used as tender.
* @draft ICU 51
*/
public CurrencyFilter withTender() {
return new CurrencyFilter(this.region, this.currency, this.from, this.to, true);
}
/**
@ -252,7 +322,8 @@ public class CurrencyMetaInfo {
equals(this.region, rhs.region) &&
equals(this.currency, rhs.currency) &&
this.from == rhs.from &&
this.to == rhs.to);
this.to == rhs.to &&
this.tenderOnly == rhs.tenderOnly);
}
/**
@ -272,6 +343,7 @@ public class CurrencyMetaInfo {
hc = hc * 31 + (int) (from >>> 32);
hc = hc * 31 + (int) to;
hc = hc * 31 + (int) (to >>> 32);
hc = hc * 31 + (tenderOnly ? 1 : 0);
return hc;
}
@ -373,6 +445,9 @@ public class CurrencyMetaInfo {
* @provisional This API might change or be removed in a future release.
*/
public final int priority;
private final boolean tender;
/**
* Constructs a currency info.
@ -384,12 +459,25 @@ public class CurrencyMetaInfo {
* @param priority priority value, 0 is highest priority, increasing values are lower
* @stable ICU 4.4
*/
/*
public CurrencyInfo(String region, String code, long from, long to, int priority) {
this(region, code, from, to, priority, true);
}
*/
/**
* Constructs a currency info.
*
* @internal
* @deprecated This API is ICU internal only.
*/
public CurrencyInfo(String region, String code, long from, long to, int priority, boolean tender) {
this.region = region;
this.code = code;
this.from = from;
this.to = to;
this.priority = priority;
this.tender = tender;
}
/**
@ -401,6 +489,15 @@ public class CurrencyMetaInfo {
public String toString() {
return debugString(this);
}
/**
* Determine whether or not this currency was once used, is used,
* or will be used as tender in this region.
* @draft ICU 51
*/
public boolean isTender() {
return tender;
}
}
///CLOVER:OFF

View file

@ -1,6 +1,6 @@
/*
*******************************************************************************
* Copyright (C) 2009-2012, International Business Machines Corporation and *
* Copyright (C) 2009-2013, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
@ -13,9 +13,6 @@ import java.util.List;
import java.util.Set;
import com.ibm.icu.text.CurrencyMetaInfo;
import com.ibm.icu.util.Calendar;
import com.ibm.icu.util.GregorianCalendar;
import com.ibm.icu.util.TimeZone;
/**
* ICU's currency meta info data.
@ -75,6 +72,9 @@ public class ICUCurrencyMetaInfo extends CurrencyMetaInfo {
if (filter.from != Long.MIN_VALUE || filter.to != Long.MAX_VALUE) {
needed |= Date;
}
if (filter.tenderOnly) {
needed |= Tender;
}
if (needed != 0) {
if (filter.region != null) {
@ -96,8 +96,8 @@ public class ICUCurrencyMetaInfo extends CurrencyMetaInfo {
int needed, ICUResourceBundle b) {
String region = b.getKey();
if ((needed & nonRegion) == 0) {
collector.collect(b.getKey(), null, 0, 0, -1);
if (needed == Region) {
collector.collect(b.getKey(), null, 0, 0, -1, false);
return;
}
@ -112,6 +112,7 @@ public class ICUCurrencyMetaInfo extends CurrencyMetaInfo {
String currency = null;
long from = Long.MIN_VALUE;
long to = Long.MAX_VALUE;
boolean tender = true;
if ((needed & Currency) != 0) {
ICUResourceBundle currBundle = r.at("id");
@ -135,9 +136,16 @@ public class ICUCurrencyMetaInfo extends CurrencyMetaInfo {
continue;
}
}
if ((needed & Tender) != 0) {
ICUResourceBundle tenderBundle = r.at("tender");
tender = tenderBundle == null || "true".equals(tenderBundle.getString());
if (filter.tenderOnly && !tender) {
continue;
}
}
// data lists elements in priority order, so 'i' suffices
collector.collect(region, currency, from, to, i);
collector.collect(region, currency, from, to, i, tender);
}
}
@ -177,8 +185,8 @@ public class ICUCurrencyMetaInfo extends CurrencyMetaInfo {
// about duplicates.
private List<CurrencyInfo> result = new ArrayList<CurrencyInfo>();
public void collect(String region, String currency, long from, long to, int priority) {
result.add(new CurrencyInfo(region, currency, from, to, priority));
public void collect(String region, String currency, long from, long to, int priority, boolean tender) {
result.add(new CurrencyInfo(region, currency, from, to, priority, tender));
}
public List<CurrencyInfo> getList() {
@ -186,14 +194,15 @@ public class ICUCurrencyMetaInfo extends CurrencyMetaInfo {
}
public int collects() {
return Region | Currency | Date;
return Everything;
}
}
private static class RegionCollector implements Collector<String> {
private final UniqueList<String> result = UniqueList.create();
public void collect(String region, String currency, long from, long to, int priority) {
public void collect(
String region, String currency, long from, long to, int priority, boolean tender) {
result.add(region);
}
@ -209,7 +218,8 @@ public class ICUCurrencyMetaInfo extends CurrencyMetaInfo {
private static class CurrencyCollector implements Collector<String> {
private final UniqueList<String> result = UniqueList.create();
public void collect(String region, String currency, long from, long to, int priority) {
public void collect(
String region, String currency, long from, long to, int priority, boolean tender) {
result.add(currency);
}
@ -225,8 +235,8 @@ public class ICUCurrencyMetaInfo extends CurrencyMetaInfo {
private static final int Region = 1;
private static final int Currency = 2;
private static final int Date = 4;
private static final int nonRegion = Currency | Date;
private static final int Tender = 8;
private static final int Everything = Integer.MAX_VALUE;
private static interface Collector<T> {
/**
@ -242,8 +252,9 @@ public class ICUCurrencyMetaInfo extends CurrencyMetaInfo {
* @param from start time (0 if ignored)
* @param to end time (0 if ignored)
* @param priority priority (-1 if ignored)
* @param tender true if currency is legal tender.
*/
void collect(String region, String currency, long from, long to, int priority);
void collect(String region, String currency, long from, long to, int priority, boolean tender);
/**
* Return the list of unique items in the order in which we encountered them for the

View file

@ -1,6 +1,6 @@
/*
**********************************************************************
* Copyright (c) 2002-2012, International Business Machines
* Copyright (c) 2002-2013, International Business Machines
* Corporation and others. All Rights Reserved.
**********************************************************************
* Author: Alan Liu
@ -378,6 +378,25 @@ public class CurrencyTest extends TestFmwk {
assertEquals("millisecond is 0", 0, cal.get(GregorianCalendar.MILLISECOND));
}
public void TestTicket9508() {
CurrencyMetaInfo metainfo = CurrencyMetaInfo.getInstance();
if (metainfo == null) {
errln("Unable to get CurrencyMetaInfo instance.");
return;
}
CurrencyMetaInfo.CurrencyFilter filter =
CurrencyMetaInfo.CurrencyFilter.onRegion("CH");
List<CurrencyInfo> currencyInfos = metainfo.currencyInfo(filter);
assertEquals("Number of currencies for switzerland", 3, currencyInfos.size());
currencyInfos = metainfo.currencyInfo(filter.withCurrency("CHF"));
assertEquals("One CHF", 1, currencyInfos.size());
CurrencyInfo swissFranc = currencyInfos.get(0);
assertEquals(
"With Date",
Arrays.asList(new String[] {"CHF"}),
metainfo.currencies(filter.withTender().withDate(swissFranc.from)));
}
// Coverage-only test of the CurrencyMetaInfo class
public void TestCurrencyMetaInfo() {
CurrencyMetaInfo metainfo = CurrencyMetaInfo.getInstance();
@ -425,7 +444,7 @@ public class CurrencyTest extends TestFmwk {
}
{ // CurrencyInfo
info = new CurrencyMetaInfo.CurrencyInfo("region", "code", 0, 1, 1);
info = new CurrencyMetaInfo.CurrencyInfo("region", "code", 0, 1, 1, false);
if (info == null) {
errln("Error creating CurrencyInfo.");
return;