]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-52_1/main/classes/core/src/com/ibm/icu/text/CurrencyMetaInfo.java
Added flags.
[Dictionary.git] / jars / icu4j-52_1 / main / classes / core / src / com / ibm / icu / text / CurrencyMetaInfo.java
1 /*
2  *******************************************************************************
3  * Copyright (C) 2009-2013, International Business Machines Corporation and    *
4  * others. All Rights Reserved.                                                *
5  *******************************************************************************
6  */
7 package com.ibm.icu.text;
8
9 import java.lang.reflect.Field;
10 import java.util.Collections;
11 import java.util.Date;
12 import java.util.List;
13
14 import com.ibm.icu.util.Calendar;
15 import com.ibm.icu.util.GregorianCalendar;
16 import com.ibm.icu.util.TimeZone;
17
18 /**
19  * Provides information about currencies that is not specific to a locale.
20  * 
21  * A note about currency dates.  The CLDR data provides data to the day,
22  * inclusive.  The date information used by CurrencyInfo and CurrencyFilter
23  * is represented by milliseconds, which is overly precise.  These times are 
24  * in GMT, so queries involving dates should use GMT times, but more generally
25  * you should avoid relying on time of day in queries.
26  * 
27  * This class is not intended for public subclassing.
28  * 
29  * @stable ICU 4.4
30  */
31 public class CurrencyMetaInfo {
32     private static final CurrencyMetaInfo impl;
33     private static final boolean hasData;
34
35     /**
36      * Returns the unique instance of the currency meta info.
37      * @return the meta info
38      * @stable ICU 4.4
39      */
40     public static CurrencyMetaInfo getInstance() {
41         return impl;
42     }
43
44     /**
45      * Returns the unique instance of the currency meta info, or null if 
46      * noSubstitute is true and there is no data to support this API.
47      * @param noSubstitute true if no substitute data should be used
48      * @return the meta info, or null
49      * @stable ICU 49
50      */
51     public static CurrencyMetaInfo getInstance(boolean noSubstitute) {
52         return hasData ? impl : null;
53     }
54
55     /**
56      * Returns true if there is data for the currency meta info.
57      * @return true if there is actual data
58      * @internal
59      * @deprecated This API is ICU internal only.
60      */
61     public static boolean hasData() {
62         return hasData;
63     }
64
65     /**
66      * Subclass constructor.
67      * @internal
68      * @deprecated This API is ICU internal only.
69      */
70     protected CurrencyMetaInfo() {
71     }
72
73     /**
74      * A filter used to select which currency info is returned.
75      * @stable ICU 4.4
76      */
77     public static final class CurrencyFilter {
78         /**
79          * The region to filter on.  If null, accepts any region.
80          * @stable ICU 4.4
81          */
82         public final String region;
83
84         /**
85          * The currency to filter on.  If null, accepts any currency.
86          * @stable ICU 4.4
87          */
88         public final String currency;
89
90         /**
91          * The from date to filter on (as milliseconds).  Accepts any currency on or after this date.
92          * @stable ICU 4.4
93          */
94         public final long from;
95
96         /**
97          * The to date to filter on (as milliseconds).  Accepts any currency on or before this date.
98          * @stable ICU 4.4
99          */
100         public final long to;
101         
102         /**
103          * true if we are filtering only for currencies used as legal tender.
104          * @internal
105          * @deprecated This API is ICU internal only.
106          */
107         public final boolean tenderOnly;
108
109         private CurrencyFilter(String region, String currency, long from, long to, boolean tenderOnly) {
110             this.region = region;
111             this.currency = currency;
112             this.from = from;
113             this.to = to;
114             this.tenderOnly = tenderOnly;
115             
116         }
117
118         private static final CurrencyFilter ALL = new CurrencyFilter(
119                 null, null, Long.MIN_VALUE, Long.MAX_VALUE, false);
120
121         /**
122          * Returns a filter that accepts all currency data.
123          * @return a filter
124          * @stable ICU 4.4
125          */
126         public static CurrencyFilter all() {
127             return ALL;
128         }
129
130         /**
131          * Returns a filter that accepts all currencies in use as of the current date.
132          * @return a filter
133          * @see #withDate(Date)
134          * @stable ICU 4.4
135          */
136         public static CurrencyFilter now() {
137             return ALL.withDate(new Date());
138         }
139
140         /**
141          * Returns a filter that accepts all currencies ever used in the given region.
142          * @param region the region code
143          * @return a filter
144          * @see #withRegion(String)
145          * @stable ICU 4.4
146          */
147         public static CurrencyFilter onRegion(String region) {
148             return ALL.withRegion(region);
149         }
150
151         /**
152          * Returns a filter that accepts the given currency.
153          * @param currency the currency code
154          * @return a filter
155          * @see #withCurrency(String)
156          * @stable ICU 4.4
157          */
158         public static CurrencyFilter onCurrency(String currency) {
159             return ALL.withCurrency(currency);
160         }
161
162         /**
163          * Returns a filter that accepts all currencies in use on the given date.
164          * @param date the date
165          * @return a filter
166          * @see #withDate(Date)
167          * @stable ICU 4.4
168          */
169         public static CurrencyFilter onDate(Date date) {
170             return ALL.withDate(date);
171         }
172
173         /**
174          * Returns a filter that accepts all currencies that were in use at some point between
175          * the given dates, or if dates are equal, currencies in use on that date.
176          * @param from date on or after a currency must have been in use
177          * @param to date on or before which a currency must have been in use,
178          * or if equal to from, the date on which a currency must have been in use
179          * @return a filter
180          * @see #withDateRange(Date, Date)
181          * @stable ICU 49
182          */
183         public static CurrencyFilter onDateRange(Date from, Date to) {
184             return ALL.withDateRange(from, to);
185         }
186         
187         /**
188          * Returns a filter that accepts all currencies in use on the given date.
189          * @param date the date as milliseconds after Jan 1, 1970
190          * @draft ICU 51
191          * @provisional This API might change or be removed in a future release.
192          */
193         public static CurrencyFilter onDate(long date) {
194             return ALL.withDate(date);
195         }
196
197         /**
198          * Returns a filter that accepts all currencies that were in use at some
199          * point between the given dates, or if dates are equal, currencies in
200          * use on that date.
201          * @param from The date on or after a currency must have been in use.
202          *   Measured in milliseconds since Jan 1, 1970 GMT.
203          * @param to The date on or before which a currency must have been in use.
204          *   Measured in milliseconds since Jan 1, 1970 GMT.
205          * @draft ICU 51
206          * @provisional This API might change or be removed in a future release.
207          */
208         public static CurrencyFilter onDateRange(long from, long to) {
209             return ALL.withDateRange(from, to);
210         }
211         
212         /**
213          * Returns a CurrencyFilter for finding currencies that were either once used,
214          * are used, or will be used as tender.
215          * @draft ICU 51
216          * @provisional This API might change or be removed in a future release.
217          */
218         public static CurrencyFilter onTender() {
219             return ALL.withTender();
220         }
221
222         /**
223          * Returns a copy of this filter, with the specified region.  Region can be null to
224          * indicate no filter on region.
225          * @param region the region code
226          * @return the filter
227          * @see #onRegion(String)
228          * @stable ICU 4.4
229          */
230         public CurrencyFilter withRegion(String region) {
231             return new CurrencyFilter(region, this.currency, this.from, this.to, this.tenderOnly);
232         }
233
234         /**
235          * Returns a copy of this filter, with the specified currency.  Currency can be null to
236          * indicate no filter on currency.
237          * @param currency the currency code
238          * @return the filter
239          * @see #onCurrency(String)
240          * @stable ICU 4.4
241          */
242         public CurrencyFilter withCurrency(String currency) {
243             return new CurrencyFilter(this.region, currency, this.from, this.to, this.tenderOnly);
244         }
245
246         /**
247          * Returns a copy of this filter, with from and to set to the given date.
248          * @param date the date on which the currency must have been in use
249          * @return the filter
250          * @see #onDate(Date)
251          * @stable ICU 4.4
252          */
253         public CurrencyFilter withDate(Date date) {
254             return new CurrencyFilter(this.region, this.currency, date.getTime(), date.getTime(), this.tenderOnly);
255         }
256
257         /**
258          * Returns a copy of this filter, with from and to set to the given dates.
259          * @param from date on or after which the currency must have been in use
260          * @param to date on or before which the currency must have been in use
261          * @return the filter
262          * @see #onDateRange(Date, Date)
263          * @stable ICU 49
264          */
265         public CurrencyFilter withDateRange(Date from, Date to) {
266             long fromLong = from == null ? Long.MIN_VALUE : from.getTime();
267             long toLong = to == null ? Long.MAX_VALUE : to.getTime();
268             return new CurrencyFilter(this.region, this.currency, fromLong, toLong, this.tenderOnly);
269         }
270         
271         /**
272          * Returns a copy of this filter that accepts all currencies in use on
273          * the given date.
274          * @param date the date as milliseconds after Jan 1, 1970
275          * @draft ICU 51
276          * @provisional This API might change or be removed in a future release.
277          */
278         public CurrencyFilter withDate(long date) {
279             return new CurrencyFilter(this.region, this.currency, date, date, this.tenderOnly);
280         }
281
282         /**
283          * Returns a copy of this filter that accepts all currencies that were
284          * in use at some point between the given dates, or if dates are equal,
285          * currencies in use on that date.
286          * @param from The date on or after a currency must have been in use.
287          *   Measured in milliseconds since Jan 1, 1970 GMT.
288          * @param to The date on or before which a currency must have been in use.
289          *   Measured in milliseconds since Jan 1, 1970 GMT.
290          * @draft ICU 51
291          * @provisional This API might change or be removed in a future release.
292          */
293         public CurrencyFilter withDateRange(long from, long to) {
294             return new CurrencyFilter(this.region, this.currency, from, to, this.tenderOnly);
295         }
296         
297         /**
298          * Returns a copy of this filter that filters for currencies that were
299          * either once used, are used, or will be used as tender.
300          * @draft ICU 51
301          * @provisional This API might change or be removed in a future release.
302          */
303         public CurrencyFilter withTender() {
304             return new CurrencyFilter(this.region, this.currency, this.from, this.to, true);
305         }
306
307         /**
308          * {@inheritDoc}
309          * @stable ICU 4.4
310          */
311         @Override
312         public boolean equals(Object rhs) {
313             return rhs instanceof CurrencyFilter &&
314                 equals((CurrencyFilter) rhs);
315         }
316
317         /**
318          * Type-safe override of {@link #equals(Object)}.
319          * @param rhs the currency filter to compare to
320          * @return true if the filters are equal
321          * @stable ICU 4.4
322          */
323         public boolean equals(CurrencyFilter rhs) {
324             return this == rhs || (rhs != null &&
325                     equals(this.region, rhs.region) &&
326                     equals(this.currency, rhs.currency) &&
327                     this.from == rhs.from &&
328                     this.to == rhs.to &&
329                     this.tenderOnly == rhs.tenderOnly);
330         }
331
332         /**
333          * {@inheritDoc}
334          * @stable ICU 4.4
335          */
336         @Override
337         public int hashCode() {
338             int hc = 0;
339             if (region != null) {
340                 hc = region.hashCode();
341             }
342             if (currency != null) {
343                 hc = hc * 31 + currency.hashCode();
344             }
345             hc = hc * 31 + (int) from;
346             hc = hc * 31 + (int) (from >>> 32);
347             hc = hc * 31 + (int) to;
348             hc = hc * 31 + (int) (to >>> 32);
349             hc = hc * 31 + (tenderOnly ? 1 : 0);
350             return hc;
351         }
352
353         /**
354          * Returns a string representing the filter, for debugging.
355          * @return A string representing the filter.
356          * @stable ICU 4.4
357          */
358         @Override
359         public String toString() {
360             return debugString(this);
361         }
362
363         private static boolean equals(String lhs, String rhs) {
364             return lhs == rhs || (lhs != null && lhs.equals(rhs));
365         }
366     }
367
368     /**
369      * Represents the raw information about fraction digits and rounding increment.
370      * @stable ICU 4.4
371      */
372     public static final class CurrencyDigits {
373         /**
374          * Number of fraction digits used to display this currency.
375          * @stable ICU 49
376          */
377         public final int fractionDigits;
378         /**
379          * Rounding increment used when displaying this currency.
380          * @stable ICU 49
381          */
382         public final int roundingIncrement;
383
384         /**
385          * Constructor for CurrencyDigits.
386          * @param fractionDigits the fraction digits
387          * @param roundingIncrement the rounding increment
388          * @stable ICU 4.4
389          */
390         public CurrencyDigits(int fractionDigits, int roundingIncrement) {
391             this.fractionDigits = fractionDigits;
392             this.roundingIncrement = roundingIncrement;
393         }
394
395         /**
396          * Returns a string representing the currency digits, for debugging.
397          * @return A string representing the currency digits.
398          * @stable ICU 4.4
399          */
400         @Override
401         public String toString() {
402             return debugString(this);
403         }
404     }
405
406     /**
407      * Represents a complete currency info record listing the region, currency, from and to dates,
408      * and priority.
409      * Use {@link CurrencyMetaInfo#currencyInfo(CurrencyFilter)}
410      * for a list of info objects matching the filter.
411      * @stable ICU 4.4
412      */
413     public static final class CurrencyInfo {
414         /**
415          * Region code where currency is used.
416          * @stable ICU 4.4
417          */
418         public final String region;
419
420         /**
421          * The three-letter ISO currency code.
422          * @stable ICU 4.4
423          */
424         public final String code;
425
426         /**
427          * Date on which the currency was first officially used in the region.  
428          * This is midnight at the start of the first day on which the currency was used, GMT. 
429          * If there is no date, this is Long.MIN_VALUE;
430          * @stable ICU 4.4
431          */
432         public final long from;
433
434         /**
435          * Date at which the currency stopped being officially used in the region.
436          * This is one millisecond before midnight at the end of the last day on which the currency was used, GMT.
437          * If there is no date, this is Long.MAX_VALUE.
438          * 
439          * @stable ICU 4.4
440          */
441         public final long to;
442
443         /**
444          * Preference order of currencies being used at the same time in the region.  Lower
445          * values are preferred (generally, this is a transition from an older to a newer
446          * currency).  Priorities within a single country are unique.
447          * @stable ICU 49
448          */
449         public final int priority;
450         
451         
452         private final boolean tender;
453
454         /**
455          * @deprecated ICU 51 Use {@link CurrencyMetaInfo#currencyInfo(CurrencyFilter)} instead.
456          */     
457         public CurrencyInfo(String region, String code, long from, long to, int priority) {
458             this(region, code, from, to, priority, true);
459         }
460         
461         /**
462          * Constructs a currency info.
463          * 
464          * @internal
465          * @deprecated This API is ICU internal only.
466          */
467         public CurrencyInfo(String region, String code, long from, long to, int priority, boolean tender) {
468             this.region = region;
469             this.code = code;
470             this.from = from;
471             this.to = to;
472             this.priority = priority;
473             this.tender = tender;
474         }
475
476         /**
477          * Returns a string representation of this object, useful for debugging.
478          * @return A string representation of this object.
479          * @stable ICU 4.4
480          */
481         @Override
482         public String toString() {
483             return debugString(this);
484         }
485         
486         /**
487          * Determine whether or not this currency was once used, is used,
488          * or will be used as tender in this region.
489          * @draft ICU 51
490          * @provisional This API might change or be removed in a future release.
491          */
492         public boolean isTender() {
493             return tender;
494         }
495     }
496
497 ///CLOVER:OFF
498     /**
499      * Returns the list of CurrencyInfos matching the provided filter.  Results
500      * are ordered by country code, then by highest to lowest priority (0 is highest).
501      * The returned list is unmodifiable.
502      * @param filter the filter to control which currency info to return
503      * @return the matching information
504      * @stable ICU 4.4
505      */
506     public List<CurrencyInfo> currencyInfo(CurrencyFilter filter) {
507         return Collections.emptyList();
508     }
509
510     /**
511      * Returns the list of currency codes matching the provided filter.
512      * Results are ordered as in {@link #currencyInfo(CurrencyFilter)}.
513      * The returned list is unmodifiable.
514      * @param filter the filter to control which currencies to return.  If filter is null,
515      * returns all currencies for which information is available.
516      * @return the matching currency codes
517      * @stable ICU 4.4
518      */
519     public List<String> currencies(CurrencyFilter filter) {
520         return Collections.emptyList();
521     }
522
523     /**
524      * Returns the list of region codes matching the provided filter.
525      * Results are ordered as in {@link #currencyInfo(CurrencyFilter)}.
526      * The returned list is unmodifiable.
527      * @param filter the filter to control which regions to return.  If filter is null,
528      * returns all regions for which information is available.
529      * @return the matching region codes
530      * @stable ICU 4.4
531      */
532     public List<String> regions(CurrencyFilter filter) {
533         return Collections.emptyList();
534     }
535 ///CLOVER:ON
536
537     /**
538      * Returns the CurrencyDigits for the currency code.
539      * @param isoCode the currency code
540      * @return the CurrencyDigits
541      * @stable ICU 4.4
542      */
543     public CurrencyDigits currencyDigits(String isoCode) {
544         return defaultDigits;
545     }
546
547     /**
548      * @internal
549      * @deprecated This API is ICU internal only.
550      */
551     protected static final CurrencyDigits defaultDigits = new CurrencyDigits(2, 0);
552
553     static {
554         CurrencyMetaInfo temp = null;
555         boolean tempHasData = false;
556         try {
557             Class<?> clzz = Class.forName("com.ibm.icu.impl.ICUCurrencyMetaInfo");
558             temp = (CurrencyMetaInfo) clzz.newInstance();
559             tempHasData = true;
560         } catch (Throwable t) {
561             temp = new CurrencyMetaInfo();
562         }
563         impl = temp;
564         hasData = tempHasData;
565     }
566
567     private static String dateString(long date) {
568         if (date == Long.MAX_VALUE || date == Long.MIN_VALUE) {
569             return null;
570         }
571         GregorianCalendar gc = new GregorianCalendar();
572         gc.setTimeZone(TimeZone.getTimeZone("GMT"));
573         gc.setTimeInMillis(date);
574         return "" + gc.get(Calendar.YEAR) + '-' + (gc.get(Calendar.MONTH) + 1) + '-' +
575                 gc.get(Calendar.DAY_OF_MONTH);
576     }
577
578     private static String debugString(Object o) {
579         StringBuilder sb = new StringBuilder();
580         try {
581             for (Field f : o.getClass().getFields()) {
582                 Object v = f.get(o);
583                 if (v != null) {
584                     String s;
585                     if (v instanceof Date) {
586                         s = dateString(((Date)v).getTime());
587                     } else if (v instanceof Long) {
588                         s = dateString(((Long)v).longValue());
589                     } else {
590                         s = String.valueOf(v);
591                     }
592                     if (s == null) {
593                         continue;
594                     }
595                     if (sb.length() > 0) {
596                         sb.append(",");
597                     }
598                     sb.append(f.getName())
599                         .append("='")
600                         .append(s)
601                         .append("'");
602                 }
603             }
604         } catch (Throwable t) {
605         }
606         sb.insert(0, o.getClass().getSimpleName() + "(");
607         sb.append(")");
608         return sb.toString();
609     }
610 }