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