2 *******************************************************************************
\r
3 * Copyright (C) 2009-2010, International Business Machines Corporation and *
\r
4 * others. All Rights Reserved. *
\r
5 *******************************************************************************
\r
7 package com.ibm.icu.text;
\r
9 import java.lang.reflect.Field;
\r
10 import java.util.Collections;
\r
11 import java.util.Date;
\r
12 import java.util.List;
\r
14 import com.ibm.icu.util.Calendar;
\r
15 import com.ibm.icu.util.GregorianCalendar;
\r
18 * Provides information about currencies that is not specific to a locale.
\r
20 * @provisional This API might change or be removed in a future release.
\r
22 public class CurrencyMetaInfo {
\r
23 private static final CurrencyMetaInfo impl;
\r
24 private static final boolean hasData;
\r
27 * Returns the unique instance of the currency meta info.
\r
28 * @return the meta info
\r
30 * @provisional This API might change or be removed in a future release.
\r
32 public static CurrencyMetaInfo getInstance() {
\r
37 * Returns true if there is data for the currency meta info.
\r
38 * @return true if there is actual data
\r
40 * @provisional This API might change or be removed in a future release.
\r
42 public static boolean hasData() {
\r
47 * Subclass constructor.
\r
49 * @deprecated This API is ICU internal only.
\r
51 protected CurrencyMetaInfo() {
\r
55 * A filter used to select which currency info is returned.
\r
57 * @provisional This API might change or be removed in a future release.
\r
59 public static final class CurrencyFilter {
\r
61 * The region to filter on. If null, accepts any region.
\r
63 * @provisional This API might change or be removed in a future release.
\r
65 public final String region;
\r
68 * The currency to filter on. If null, accepts any currency.
\r
70 * @provisional This API might change or be removed in a future release.
\r
72 public final String currency;
\r
75 * The from date to filter on (milliseconds). Accepts any currency on or after this date.
\r
77 * @provisional This API might change or be removed in a future release.
\r
79 public final long from;
\r
82 * The to date to filter on (milliseconds). Accepts any currency on or before this date.
\r
84 * @provisional This API might change or be removed in a future release.
\r
86 public final long to;
\r
88 private CurrencyFilter(String region, String currency, long from, long to) {
\r
89 this.region = region;
\r
90 this.currency = currency;
\r
95 private CurrencyFilter(String region, String currency, Date dateFrom, Date dateTo) {
\r
96 this.region = region;
\r
97 this.currency = currency;
\r
98 this.from = dateFrom == null ? Long.MIN_VALUE : dateFrom.getTime();
\r
99 this.to = dateTo == null ? Long.MAX_VALUE : dateTo.getTime();
\r
102 private static final CurrencyFilter ALL = new CurrencyFilter(null, null, null, null);
\r
105 * Returns a filter that accepts all currency data.
\r
108 * @provisional This API might change or be removed in a future release.
\r
110 public static CurrencyFilter all() {
\r
115 * Returns a filter that accepts all currencies in use as of the current date.
\r
117 * @see #withDate(Date)
\r
119 * @provisional This API might change or be removed in a future release.
\r
121 public static CurrencyFilter now() {
\r
122 return ALL.withDate(new Date());
\r
126 * Returns a filter that accepts all currencies ever used in the given region.
\r
127 * @param region the region code
\r
129 * @see #withRegion(String)
\r
131 * @provisional This API might change or be removed in a future release.
\r
133 public static CurrencyFilter onRegion(String region) {
\r
134 return ALL.withRegion(region);
\r
138 * Returns a filter that accepts the given currency.
\r
139 * @param currency the currency code
\r
141 * @see #withCurrency(String)
\r
143 * @provisional This API might change or be removed in a future release.
\r
145 public static CurrencyFilter onCurrency(String currency) {
\r
146 return ALL.withCurrency(currency);
\r
150 * Returns a filter that accepts all currencies in use on the given date.
\r
151 * @param date the date
\r
153 * @see #withDate(Date)
\r
155 * @provisional This API might change or be removed in a future release.
\r
157 public static CurrencyFilter onDate(Date date) {
\r
158 return ALL.withDate(date);
\r
162 * Returns a filter that accepts all currencies that were in use at some point between
\r
163 * the given dates, or if dates are equal, currencies in use on that date.
\r
164 * @param from date on or after a currency must have been in use
\r
165 * @param to date before which a currency must have been in use, or if equal to from,
\r
166 * the date on which a currency must have been in use
\r
168 * @see #withRange(Date, Date)
\r
170 * @provisional This API might change or be removed in a future release.
\r
172 public static CurrencyFilter onRange(Date from, Date to) {
\r
173 return ALL.withRange(from, to);
\r
177 * Returns a copy of this filter, with the specified region. Region can be null to
\r
178 * indicate no filter on region.
\r
179 * @param region the region code
\r
180 * @return the filter
\r
181 * @see #onRegion(String)
\r
183 * @provisional This API might change or be removed in a future release.
\r
185 public CurrencyFilter withRegion(String region) {
\r
186 return new CurrencyFilter(region, this.currency, this.from, this.to);
\r
190 * Returns a copy of this filter, with the specified currency. Currency can be null to
\r
191 * indicate no filter on currency.
\r
192 * @param currency the currency code
\r
193 * @return the filter
\r
194 * @see #onCurrency(String)
\r
196 * @provisional This API might change or be removed in a future release.
\r
198 public CurrencyFilter withCurrency(String currency) {
\r
199 return new CurrencyFilter(this.region, currency, this.from, this.to);
\r
203 * Returns a copy of this filter, with from and to set to the given date.
\r
204 * @param date the date on which the currency must have been in use
\r
205 * @return the filter
\r
206 * @see #onDate(Date)
\r
208 * @provisional This API might change or be removed in a future release.
\r
210 public CurrencyFilter withDate(Date date) {
\r
211 return new CurrencyFilter(this.region, this.currency, date, date);
\r
215 * Returns a copy of this filter, with from and to set to the given dates.
\r
216 * @param from date on or after which the currency must have been in use
\r
217 * @param to date before which the currency must have been in use
\r
218 * @return the filter
\r
219 * @see #onRange(Date, Date)
\r
221 * @provisional This API might change or be removed in a future release.
\r
223 public CurrencyFilter withRange(Date from, Date to) {
\r
224 return new CurrencyFilter(this.region, this.currency, from, to);
\r
228 * Overrides equals.
\r
230 * @provisional This API might change or be removed in a future release.
\r
233 public boolean equals(Object rhs) {
\r
234 return rhs instanceof CurrencyFilter &&
\r
235 equals((CurrencyFilter) rhs);
\r
239 * Type-safe override of {@link #equals(Object)}.
\r
240 * @param rhs the currency filter to compare to
\r
241 * @return true if the filters are equal
\r
243 * @provisional This API might change or be removed in a future release.
\r
245 public boolean equals(CurrencyFilter rhs) {
\r
246 return this == rhs || (rhs != null &&
\r
247 equals(this.region, rhs.region) &&
\r
248 equals(this.currency, rhs.currency) &&
\r
249 this.from == rhs.from &&
\r
250 this.to == rhs.to);
\r
254 * Overrides hashCode.
\r
256 * @provisional This API might change or be removed in a future release.
\r
259 public int hashCode() {
\r
261 if (region != null) {
\r
262 hc = region.hashCode();
\r
264 if (currency != null) {
\r
265 hc = hc * 31 + currency.hashCode();
\r
267 hc = hc * 31 + (int) from;
\r
268 hc = hc * 31 + (int) (from >>> 32);
\r
269 hc = hc * 31 + (int) to;
\r
270 hc = hc * 31 + (int) (to >>> 32);
\r
275 * Returns a string representing the filter, for debugging.
\r
277 * @provisional This API might change or be removed in a future release.
\r
280 public String toString() {
\r
281 return debugString(this);
\r
284 private static boolean equals(String lhs, String rhs) {
\r
285 return lhs == rhs || (lhs != null && lhs.equals(rhs));
\r
290 * Represents the raw information about fraction digits and rounding increment.
\r
292 * @provisional This API might change or be removed in a future release.
\r
294 public static final class CurrencyDigits {
\r
296 * Number of fraction digits used to display this currency.
\r
298 * @provisional This API might change or be removed in a future release.
\r
300 public final byte fractionDigits;
\r
302 * Rounding increment used when displaying this currency.
\r
304 * @provisional This API might change or be removed in a future release.
\r
306 public final byte roundingIncrement;
\r
309 * Constructor for CurrencyDigits.
\r
310 * @param fractionDigits the fraction digits
\r
311 * @param roundingIncrement the rounding increment
\r
313 * @provisional This API might change or be removed in a future release.
\r
315 public CurrencyDigits(int fractionDigits, int roundingIncrement) {
\r
316 this.fractionDigits = (byte) fractionDigits;
\r
317 this.roundingIncrement = (byte) roundingIncrement;
\r
321 * Returns a string representing the currency digits, for debugging.
\r
323 * @provisional This API might change or be removed in a future release.
\r
326 public String toString() {
\r
327 return debugString(this);
\r
332 * Represents a complete currency info record listing the region, currency, from and to dates,
\r
335 * @provisional This API might change or be removed in a future release.
\r
337 public static final class CurrencyInfo {
\r
339 * Region code where currency is used.
\r
341 * @provisional This API might change or be removed in a future release.
\r
343 public final String region;
\r
346 * The three-letter ISO currency code.
\r
348 * @provisional This API might change or be removed in a future release.
\r
350 public final String code;
\r
353 * Date on which the currency was first officially used in the region. If there is no
\r
354 * date, this is Long.MIN_VALUE;
\r
356 * @provisional This API might change or be removed in a future release.
\r
358 public final long from;
\r
361 * Date at which the currency stopped being officially used in the region. If there is
\r
362 * no date, this is Long.MAX_VALUE;
\r
364 * @provisional This API might change or be removed in a future release.
\r
366 public final long to;
\r
369 * Preference order of currencies being used at the same time in the region. Lower
\r
370 * values are preferred (generally, this is a transition from an older to a newer
\r
371 * currency). Priorities within a single country are unique.
\r
373 * @provisional This API might change or be removed in a future release.
\r
375 public final short priority;
\r
378 * Constructs a currency info.
\r
379 * @param region region code
\r
380 * @param code currency code
\r
381 * @param from start date in milliseconds
\r
382 * @param to end date in milliseconds
\r
383 * @param priority priority value, 0 is highest priority, increasing values are lower
\r
385 * @provisional This API might change or be removed in a future release.
\r
387 public CurrencyInfo(String region, String code, long from, long to, int priority) {
\r
388 this.region = region;
\r
392 this.priority = (short) priority;
\r
396 * Returns a string useful for debugging.
\r
398 * @provisional This API might change or be removed in a future release.
\r
401 public String toString() {
\r
402 return debugString(this);
\r
407 * Returns the list of CurrencyInfos matching the provided filter. Results
\r
408 * are ordered by country code, then by highest to lowest priority (0 is highest).
\r
409 * The returned list is unmodifiable.
\r
410 * @param filter the filter to control which currency info to return
\r
411 * @return the matching information
\r
413 * @provisional This API might change or be removed in a future release.
\r
415 public List<CurrencyInfo> currencyInfo(CurrencyFilter filter) {
\r
416 return Collections.emptyList();
\r
420 * Returns the list of currency codes matching the provided filter.
\r
421 * Results are ordered as in {@link #currencyInfo(CurrencyFilter)}.
\r
422 * The returned list is unmodifiable.
\r
423 * @param filter the filter to control which currencies to return. If filter is null,
\r
424 * returns all currencies for which information is available.
\r
425 * @return the matching currency codes
\r
427 * @provisional This API might change or be removed in a future release.
\r
429 public List<String> currencies(CurrencyFilter filter) {
\r
430 return Collections.emptyList();
\r
434 * Returns the list of region codes matching the provided filter.
\r
435 * Results are ordered as in {@link #currencyInfo(CurrencyFilter)}.
\r
436 * The returned list is unmodifiable.
\r
437 * @param filter the filter to control which regions to return. If filter is null,
\r
438 * returns all regions for which information is available.
\r
439 * @return the matching region codes
\r
441 * @provisional This API might change or be removed in a future release.
\r
443 public List<String> regions(CurrencyFilter filter) {
\r
444 return Collections.emptyList();
\r
448 * Returns the CurrencyDigits for the currency code.
\r
449 * @param isoCode the currency code
\r
450 * @return the CurrencyDigits
\r
452 * @provisional This API might change or be removed in a future release.
\r
454 public CurrencyDigits currencyDigits(String isoCode) {
\r
455 return defaultDigits;
\r
460 * @deprecated This API is ICU internal only.
\r
462 protected static final CurrencyDigits defaultDigits = new CurrencyDigits(2, 0);
\r
465 CurrencyMetaInfo temp = null;
\r
466 boolean tempHasData = false;
\r
468 Class<?> clzz = Class.forName("com.ibm.icu.impl.ICUCurrencyMetaInfo");
\r
469 temp = (CurrencyMetaInfo) clzz.newInstance();
\r
470 tempHasData = true;
\r
471 } catch (Throwable t) {
\r
472 temp = new CurrencyMetaInfo();
\r
475 hasData = tempHasData;
\r
478 private static String dateString(long date) {
\r
479 if (date == Long.MAX_VALUE || date == Long.MIN_VALUE) {
\r
482 GregorianCalendar gc = new GregorianCalendar();
\r
483 gc.setTimeInMillis(date);
\r
484 return "" + gc.get(Calendar.YEAR) + '-' + (gc.get(Calendar.MONTH) + 1) + '-' +
\r
485 gc.get(Calendar.DAY_OF_MONTH);
\r
488 private static String debugString(Object o) {
\r
489 StringBuilder sb = new StringBuilder();
\r
491 for (Field f : o.getClass().getFields()) {
\r
492 Object v = f.get(o);
\r
495 if (v instanceof Date) {
\r
496 s = dateString(((Date)v).getTime());
\r
497 } else if (v instanceof Long) {
\r
498 s = dateString(((Long)v).longValue());
\r
500 s = String.valueOf(v);
\r
505 if (sb.length() > 0) {
\r
508 sb.append(f.getName())
\r
514 } catch (Throwable t) {
\r
516 sb.insert(0, o.getClass().getSimpleName() + "(");
\r
518 return sb.toString();
\r