jdk/src/share/classes/java/util/Currency.java
author duke
Sat, 01 Dec 2007 00:00:00 +0000
changeset 2 90ce3da70b43
child 3861 a98a057ec335
permissions -rw-r--r--
Initial load
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
     2
 * Copyright 2000-2005 Sun Microsystems, Inc.  All Rights Reserved.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
90ce3da70b43 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Sun designates this
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
90ce3da70b43 Initial load
duke
parents:
diff changeset
     9
 * by Sun in the LICENSE file that accompanied this code.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    21
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    22
 * CA 95054 USA or visit www.sun.com if you need additional information or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    23
 * have any questions.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package java.util;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import java.io.BufferedInputStream;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import java.io.DataInputStream;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import java.io.File;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
import java.io.FileInputStream;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
import java.io.FileReader;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
import java.io.IOException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
import java.io.Serializable;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
import java.security.AccessController;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
import java.security.PrivilegedAction;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
import java.util.logging.Level;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
import java.util.logging.Logger;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
import java.util.regex.Pattern;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
import java.util.regex.Matcher;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
import java.util.spi.CurrencyNameProvider;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
import java.util.spi.LocaleServiceProvider;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
import sun.util.LocaleServiceProviderPool;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
import sun.util.resources.LocaleData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
import sun.util.resources.OpenListResourceBundle;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
 * Represents a currency. Currencies are identified by their ISO 4217 currency
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
 * codes. Visit the <a href="http://www.iso.org/iso/en/prods-services/popstds/currencycodes.html">
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
 * ISO web site</a> for more information, including a table of
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
 * currency codes.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
 * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
 * The class is designed so that there's never more than one
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
 * <code>Currency</code> instance for any given currency. Therefore, there's
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
 * no public constructor. You obtain a <code>Currency</code> instance using
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
 * the <code>getInstance</code> methods.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
 * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
 * Users can supersede the Java runtime currency data by creating a properties
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
 * file named <code>&lt;JAVA_HOME&gt;/lib/currency.properties</code>.  The contents
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
 * of the properties file are key/value pairs of the ISO 3166 country codes
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
 * and the ISO 4217 currency data respectively.  The value part consists of
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
 * three ISO 4217 values of a currency, i.e., an alphabetic code, a numeric
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
 * code, and a minor unit.  Those three ISO 4217 values are separated by commas.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
 * The lines which start with '#'s are considered comment lines.  For example,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
 * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
 * <code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
 * #Sample currency properties<br>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
 * JP=JPZ,999,0
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
 * </code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
 * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
 * will supersede the currency data for Japan.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
 * @since 1.4
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
public final class Currency implements Serializable {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
    private static final long serialVersionUID = -158308464356906721L;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
     * ISO 4217 currency code for this currency.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
     * @serial
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
    private final String currencyCode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
     * Default fraction digits for this currency.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
     * Set from currency data tables.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
    transient private final int defaultFractionDigits;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
     * ISO 4217 numeric code for this currency.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
     * Set from currency data tables.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
    transient private final int numericCode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
    // class data: instance map
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
    private static HashMap<String, Currency> instances = new HashMap<String, Currency>(7);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
    private static HashSet<Currency> available;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
    // Class data: currency data obtained from currency.data file.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
    // Purpose:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
    // - determine valid country codes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
    // - determine valid currency codes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
    // - map country codes to currency codes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
    // - obtain default fraction digits for currency codes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
    // sc = special case; dfd = default fraction digits
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
    // Simple countries are those where the country code is a prefix of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
    // currency code, and there are no known plans to change the currency.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
    // table formats:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
    // - mainTable:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
    //   - maps country code to 32-bit int
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
    //   - 26*26 entries, corresponding to [A-Z]*[A-Z]
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
    //   - \u007F -> not valid country
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
    //   - bits 18-31: unused
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
    //   - bits 8-17: numeric code (0 to 1023)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
    //   - bit 7: 1 - special case, bits 0-4 indicate which one
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
    //            0 - simple country, bits 0-4 indicate final char of currency code
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
    //   - bits 5-6: fraction digits for simple countries, 0 for special cases
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
    //   - bits 0-4: final char for currency code for simple country, or ID of special case
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
    // - special case IDs:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
    //   - 0: country has no currency
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
    //   - other: index into sc* arrays + 1
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
    // - scCutOverTimes: cut-over time in millis as returned by
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
    //   System.currentTimeMillis for special case countries that are changing
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
    //   currencies; Long.MAX_VALUE for countries that are not changing currencies
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
    // - scOldCurrencies: old currencies for special case countries
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
    // - scNewCurrencies: new currencies for special case countries that are
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
    //   changing currencies; null for others
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
    // - scOldCurrenciesDFD: default fraction digits for old currencies
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
    // - scNewCurrenciesDFD: default fraction digits for new currencies, 0 for
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
    //   countries that are not changing currencies
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
    // - otherCurrencies: concatenation of all currency codes that are not the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
    //   main currency of a simple country, separated by "-"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
    // - otherCurrenciesDFD: decimal format digits for currencies in otherCurrencies, same order
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
    static int formatVersion;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
    static int dataVersion;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
    static int[] mainTable;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
    static long[] scCutOverTimes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
    static String[] scOldCurrencies;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
    static String[] scNewCurrencies;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
    static int[] scOldCurrenciesDFD;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
    static int[] scNewCurrenciesDFD;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
    static int[] scOldCurrenciesNumericCode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
    static int[] scNewCurrenciesNumericCode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
    static String otherCurrencies;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
    static int[] otherCurrenciesDFD;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
    static int[] otherCurrenciesNumericCode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
    // handy constants - must match definitions in GenerateCurrencyData
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
    // magic number
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
    private static final int MAGIC_NUMBER = 0x43757244;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
    // number of characters from A to Z
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
    private static final int A_TO_Z = ('Z' - 'A') + 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
    // entry for invalid country codes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
    private static final int INVALID_COUNTRY_ENTRY = 0x007F;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
    // entry for countries without currency
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
    private static final int COUNTRY_WITHOUT_CURRENCY_ENTRY = 0x0080;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
    // mask for simple case country entries
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
    private static final int SIMPLE_CASE_COUNTRY_MASK = 0x0000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
    // mask for simple case country entry final character
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
    private static final int SIMPLE_CASE_COUNTRY_FINAL_CHAR_MASK = 0x001F;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
    // mask for simple case country entry default currency digits
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
    private static final int SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_MASK = 0x0060;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
    // shift count for simple case country entry default currency digits
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
    private static final int SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_SHIFT = 5;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
    // mask for special case country entries
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
    private static final int SPECIAL_CASE_COUNTRY_MASK = 0x0080;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
    // mask for special case country index
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
    private static final int SPECIAL_CASE_COUNTRY_INDEX_MASK = 0x001F;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
    // delta from entry index component in main table to index into special case tables
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
    private static final int SPECIAL_CASE_COUNTRY_INDEX_DELTA = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
    // mask for distinguishing simple and special case countries
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
    private static final int COUNTRY_TYPE_MASK = SIMPLE_CASE_COUNTRY_MASK | SPECIAL_CASE_COUNTRY_MASK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
    // mask for the numeric code of the currency
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
    private static final int NUMERIC_CODE_MASK = 0x0003FF00;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
    // shift count for the numeric code of the currency
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
    private static final int NUMERIC_CODE_SHIFT = 8;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
    // Currency data format version
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
    private static final int VALID_FORMAT_VERSION = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
    static {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
        AccessController.doPrivileged(new PrivilegedAction() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
            public Object run() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
                String homeDir = System.getProperty("java.home");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
                try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
                    String dataFile = homeDir + File.separator +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
                            "lib" + File.separator + "currency.data";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
                    DataInputStream dis = new DataInputStream(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
                        new BufferedInputStream(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
                        new FileInputStream(dataFile)));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
                    if (dis.readInt() != MAGIC_NUMBER) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
                        throw new InternalError("Currency data is possibly corrupted");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
                    formatVersion = dis.readInt();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
                    if (formatVersion != VALID_FORMAT_VERSION) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
                        throw new InternalError("Currency data format is incorrect");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
                    dataVersion = dis.readInt();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
                    mainTable = readIntArray(dis, A_TO_Z * A_TO_Z);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
                    int scCount = dis.readInt();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
                    scCutOverTimes = readLongArray(dis, scCount);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
                    scOldCurrencies = readStringArray(dis, scCount);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
                    scNewCurrencies = readStringArray(dis, scCount);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
                    scOldCurrenciesDFD = readIntArray(dis, scCount);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
                    scNewCurrenciesDFD = readIntArray(dis, scCount);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
                    scOldCurrenciesNumericCode = readIntArray(dis, scCount);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
                    scNewCurrenciesNumericCode = readIntArray(dis, scCount);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
                    int ocCount = dis.readInt();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
                    otherCurrencies = dis.readUTF();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
                    otherCurrenciesDFD = readIntArray(dis, ocCount);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
                    otherCurrenciesNumericCode = readIntArray(dis, ocCount);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
                    dis.close();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
                } catch (IOException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
                    InternalError ie = new InternalError();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
                    ie.initCause(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
                    throw ie;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
                // look for the properties file for overrides
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
                try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
                    File propFile = new File(homeDir + File.separator +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
                                             "lib" + File.separator +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
                                             "currency.properties");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
                    if (propFile.exists()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
                        Properties props = new Properties();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
                        props.load(new FileReader(propFile));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
                        Set<String> keys = props.stringPropertyNames();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
                        Pattern propertiesPattern =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
                            Pattern.compile("([A-Z]{3})\\s*,\\s*(\\d{3})\\s*,\\s*([0-3])");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
                        for (String key : keys) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
                           replaceCurrencyData(propertiesPattern,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
                               key.toUpperCase(Locale.ROOT),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
                               props.getProperty(key).toUpperCase(Locale.ROOT));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
                } catch (IOException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
                    log(Level.INFO, "currency.properties is ignored because of an IOException", e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
                return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
        });
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
     * Constants for retrieving localized names from the name providers.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
    private static final int SYMBOL = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
    private static final int DISPLAYNAME = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
     * Constructs a <code>Currency</code> instance. The constructor is private
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
     * so that we can insure that there's never more than one instance for a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
     * given currency.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
    private Currency(String currencyCode, int defaultFractionDigits, int numericCode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
        this.currencyCode = currencyCode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
        this.defaultFractionDigits = defaultFractionDigits;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
        this.numericCode = numericCode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
     * Returns the <code>Currency</code> instance for the given currency code.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
     * @param currencyCode the ISO 4217 code of the currency
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
     * @return the <code>Currency</code> instance for the given currency code
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
     * @exception NullPointerException if <code>currencyCode</code> is null
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
     * @exception IllegalArgumentException if <code>currencyCode</code> is not
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
     * a supported ISO 4217 code.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
    public static Currency getInstance(String currencyCode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
        return getInstance(currencyCode, Integer.MIN_VALUE, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
    private static Currency getInstance(String currencyCode, int defaultFractionDigits,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
        int numericCode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
        synchronized (instances) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
            // Try to look up the currency code in the instances table.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
            // This does the null pointer check as a side effect.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
            // Also, if there already is an entry, the currencyCode must be valid.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
            Currency instance = instances.get(currencyCode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
            if (instance != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
                return instance;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
            if (defaultFractionDigits == Integer.MIN_VALUE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
                // Currency code not internally generated, need to verify first
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
                // A currency code must have 3 characters and exist in the main table
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
                // or in the list of other currencies.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
                if (currencyCode.length() != 3) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
                    throw new IllegalArgumentException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
                char char1 = currencyCode.charAt(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
                char char2 = currencyCode.charAt(1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
                int tableEntry = getMainTableEntry(char1, char2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
                if ((tableEntry & COUNTRY_TYPE_MASK) == SIMPLE_CASE_COUNTRY_MASK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
                        && tableEntry != INVALID_COUNTRY_ENTRY
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
                        && currencyCode.charAt(2) - 'A' == (tableEntry & SIMPLE_CASE_COUNTRY_FINAL_CHAR_MASK)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
                    defaultFractionDigits = (tableEntry & SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_MASK) >> SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_SHIFT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
                    numericCode = (tableEntry & NUMERIC_CODE_MASK) >> NUMERIC_CODE_SHIFT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
                    // Check for '-' separately so we don't get false hits in the table.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
                    if (currencyCode.charAt(2) == '-') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
                        throw new IllegalArgumentException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
                    int index = otherCurrencies.indexOf(currencyCode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
                    if (index == -1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
                        throw new IllegalArgumentException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
                    defaultFractionDigits = otherCurrenciesDFD[index / 4];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
                    numericCode = otherCurrenciesNumericCode[index / 4];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
            instance = new Currency(currencyCode, defaultFractionDigits, numericCode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
            instances.put(currencyCode, instance);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
            return instance;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
     * Returns the <code>Currency</code> instance for the country of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
     * given locale. The language and variant components of the locale
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
     * are ignored. The result may vary over time, as countries change their
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
     * currencies. For example, for the original member countries of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
     * European Monetary Union, the method returns the old national currencies
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
     * until December 31, 2001, and the Euro from January 1, 2002, local time
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
     * of the respective countries.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
     * The method returns <code>null</code> for territories that don't
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
     * have a currency, such as Antarctica.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
     * @param locale the locale for whose country a <code>Currency</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
     * instance is needed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
     * @return the <code>Currency</code> instance for the country of the given
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
     * locale, or null
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
     * @exception NullPointerException if <code>locale</code> or its country
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
     * code is null
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
     * @exception IllegalArgumentException if the country of the given locale
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
     * is not a supported ISO 3166 country code.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
    public static Currency getInstance(Locale locale) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
        String country = locale.getCountry();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
        if (country == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
            throw new NullPointerException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
        if (country.length() != 2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
            throw new IllegalArgumentException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
        char char1 = country.charAt(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
        char char2 = country.charAt(1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
        int tableEntry = getMainTableEntry(char1, char2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
        if ((tableEntry & COUNTRY_TYPE_MASK) == SIMPLE_CASE_COUNTRY_MASK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
                    && tableEntry != INVALID_COUNTRY_ENTRY) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
            char finalChar = (char) ((tableEntry & SIMPLE_CASE_COUNTRY_FINAL_CHAR_MASK) + 'A');
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
            int defaultFractionDigits = (tableEntry & SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_MASK) >> SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_SHIFT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
            int numericCode = (tableEntry & NUMERIC_CODE_MASK) >> NUMERIC_CODE_SHIFT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
            StringBuffer sb = new StringBuffer(country);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
            sb.append(finalChar);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
            return getInstance(sb.toString(), defaultFractionDigits, numericCode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
            // special cases
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
            if (tableEntry == INVALID_COUNTRY_ENTRY) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
                throw new IllegalArgumentException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
            if (tableEntry == COUNTRY_WITHOUT_CURRENCY_ENTRY) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
                return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
                int index = (tableEntry & SPECIAL_CASE_COUNTRY_INDEX_MASK) - SPECIAL_CASE_COUNTRY_INDEX_DELTA;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
                if (scCutOverTimes[index] == Long.MAX_VALUE || System.currentTimeMillis() < scCutOverTimes[index]) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
                    return getInstance(scOldCurrencies[index], scOldCurrenciesDFD[index],
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
                        scOldCurrenciesNumericCode[index]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
                    return getInstance(scNewCurrencies[index], scNewCurrenciesDFD[index],
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
                        scNewCurrenciesNumericCode[index]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
     * Gets the set of available currencies.  The returned set of currencies
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
     * contains all of the available currencies, which may include currencies
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
     * that represent obsolete ISO 4217 codes.  The set can be modified
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
     * without affecting the available currencies in the runtime.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
     * @return the set of available currencies.  If there is no currency
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
     *    available in the runtime, the returned set is empty.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
     * @since 1.7
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
    public static Set<Currency> getAvailableCurrencies() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
        synchronized(Currency.class) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
            if (available == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
                available = new HashSet<Currency>(256);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
                // Add simple currencies first
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
                for (char c1 = 'A'; c1 <= 'Z'; c1 ++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
                    for (char c2 = 'A'; c2 <= 'Z'; c2 ++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
                        int tableEntry = getMainTableEntry(c1, c2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
                        if ((tableEntry & COUNTRY_TYPE_MASK) == SIMPLE_CASE_COUNTRY_MASK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
                             && tableEntry != INVALID_COUNTRY_ENTRY) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
                            char finalChar = (char) ((tableEntry & SIMPLE_CASE_COUNTRY_FINAL_CHAR_MASK) + 'A');
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
                            int defaultFractionDigits = (tableEntry & SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_MASK) >> SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_SHIFT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
                            int numericCode = (tableEntry & NUMERIC_CODE_MASK) >> NUMERIC_CODE_SHIFT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
                            StringBuilder sb = new StringBuilder();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
                            sb.append(c1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
                            sb.append(c2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
                            sb.append(finalChar);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
                            available.add(getInstance(sb.toString(), defaultFractionDigits, numericCode));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
                // Now add other currencies
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
                StringTokenizer st = new StringTokenizer(otherCurrencies, "-");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
                while (st.hasMoreElements()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
                    available.add(getInstance((String)st.nextElement()));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
        return (Set<Currency>) available.clone();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
     * Gets the ISO 4217 currency code of this currency.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
     * @return the ISO 4217 currency code of this currency.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
    public String getCurrencyCode() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
        return currencyCode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
     * Gets the symbol of this currency for the default locale.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
     * For example, for the US Dollar, the symbol is "$" if the default
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
     * locale is the US, while for other locales it may be "US$". If no
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
     * symbol can be determined, the ISO 4217 currency code is returned.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
     * @return the symbol of this currency for the default locale
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
    public String getSymbol() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
        return getSymbol(Locale.getDefault());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
     * Gets the symbol of this currency for the specified locale.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
     * For example, for the US Dollar, the symbol is "$" if the specified
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
     * locale is the US, while for other locales it may be "US$". If no
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
     * symbol can be determined, the ISO 4217 currency code is returned.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
     * @param locale the locale for which a display name for this currency is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
     * needed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
     * @return the symbol of this currency for the specified locale
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
     * @exception NullPointerException if <code>locale</code> is null
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
    public String getSymbol(Locale locale) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
            // Check whether a provider can provide an implementation that's closer
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
            // to the requested locale than what the Java runtime itself can provide.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
            LocaleServiceProviderPool pool =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
                LocaleServiceProviderPool.getPool(CurrencyNameProvider.class);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
            if (pool.hasProviders()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
                // Assuming that all the country locales include necessary currency
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
                // symbols in the Java runtime's resources,  so there is no need to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
                // examine whether Java runtime's currency resource bundle is missing
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
                // names.  Therefore, no resource bundle is provided for calling this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
                // method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
                String symbol = pool.getLocalizedObject(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
                                    CurrencyNameGetter.INSTANCE,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
                                    locale, (OpenListResourceBundle)null,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
                                    currencyCode, SYMBOL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
                if (symbol != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
                    return symbol;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
            ResourceBundle bundle = LocaleData.getCurrencyNames(locale);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
            return bundle.getString(currencyCode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
        } catch (MissingResourceException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
            // use currency code as symbol of last resort
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
            return currencyCode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
     * Gets the default number of fraction digits used with this currency.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
     * For example, the default number of fraction digits for the Euro is 2,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
     * while for the Japanese Yen it's 0.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
     * In the case of pseudo-currencies, such as IMF Special Drawing Rights,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
     * -1 is returned.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
     * @return the default number of fraction digits used with this currency
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
    public int getDefaultFractionDigits() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
        return defaultFractionDigits;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
     * Returns the ISO 4217 numeric code of this currency.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
     * @return the ISO 4217 numeric code of this currency
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
     * @since 1.7
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
    public int getNumericCode() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
        return numericCode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
     * Gets the name that is suitable for displaying this currency for
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
     * the default locale.  If there is no suitable display name found
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
     * for the default locale, the ISO 4217 currency code is returned.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
     * @return the display name of this currency for the default locale
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
     * @since 1.7
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
    public String getDisplayName() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
        return getDisplayName(Locale.getDefault());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
     * Gets the name that is suitable for displaying this currency for
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
     * the specified locale.  If there is no suitable display name found
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
     * for the specified locale, the ISO 4217 currency code is returned.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
     * @param locale the locale for which a display name for this currency is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
     * needed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
     * @return the display name of this currency for the specified locale
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
     * @exception NullPointerException if <code>locale</code> is null
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
     * @since 1.7
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
    public String getDisplayName(Locale locale) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
            OpenListResourceBundle bundle = LocaleData.getCurrencyNames(locale);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
            String result = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
            String bundleKey = currencyCode.toLowerCase(Locale.ROOT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
            // Check whether a provider can provide an implementation that's closer
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
            // to the requested locale than what the Java runtime itself can provide.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
            LocaleServiceProviderPool pool =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
                LocaleServiceProviderPool.getPool(CurrencyNameProvider.class);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
            if (pool.hasProviders()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
                result = pool.getLocalizedObject(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
                                    CurrencyNameGetter.INSTANCE,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
                                    locale, bundleKey, bundle, currencyCode, DISPLAYNAME);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
            if (result == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
                result = bundle.getString(bundleKey);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
            if (result != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
                return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
        } catch (MissingResourceException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
            // fall through
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
        // use currency code as symbol of last resort
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
        return currencyCode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
     * Returns the ISO 4217 currency code of this currency.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
     * @return the ISO 4217 currency code of this currency
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
    public String toString() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
        return currencyCode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
     * Resolves instances being deserialized to a single instance per currency.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
    private Object readResolve() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
        return getInstance(currencyCode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
     * Gets the main table entry for the country whose country code consists
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
     * of char1 and char2.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
    private static int getMainTableEntry(char char1, char char2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
        if (char1 < 'A' || char1 > 'Z' || char2 < 'A' || char2 > 'Z') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
            throw new IllegalArgumentException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
        return mainTable[(char1 - 'A') * A_TO_Z + (char2 - 'A')];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
     * Sets the main table entry for the country whose country code consists
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
     * of char1 and char2.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
    private static void setMainTableEntry(char char1, char char2, int entry) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
        if (char1 < 'A' || char1 > 'Z' || char2 < 'A' || char2 > 'Z') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
            throw new IllegalArgumentException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
        mainTable[(char1 - 'A') * A_TO_Z + (char2 - 'A')] = entry;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
     * Obtains a localized currency names from a CurrencyNameProvider
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
     * implementation.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
    private static class CurrencyNameGetter
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
        implements LocaleServiceProviderPool.LocalizedObjectGetter<CurrencyNameProvider,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
                                                                   String> {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
        private static final CurrencyNameGetter INSTANCE = new CurrencyNameGetter();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
        public String getObject(CurrencyNameProvider currencyNameProvider,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
                                Locale locale,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
                                String key,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
                                Object... params) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
            assert params.length == 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
            int type = (Integer)params[0];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
            switch(type) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
            case SYMBOL:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
                return currencyNameProvider.getSymbol(key, locale);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
            case DISPLAYNAME:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
                return currencyNameProvider.getDisplayName(key, locale);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
            default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
                assert false; // shouldn't happen
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
            return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
    private static int[] readIntArray(DataInputStream dis, int count) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
        int[] ret = new int[count];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
        for (int i = 0; i < count; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
            ret[i] = dis.readInt();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
        return ret;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
    private static long[] readLongArray(DataInputStream dis, int count) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
        long[] ret = new long[count];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
        for (int i = 0; i < count; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
            ret[i] = dis.readLong();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
        return ret;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
    private static String[] readStringArray(DataInputStream dis, int count) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
        String[] ret = new String[count];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
        for (int i = 0; i < count; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
            ret[i] = dis.readUTF();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
        return ret;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
     * Replaces currency data found in the currencydata.properties file
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
     * @param pattern regex pattern for the properties
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
     * @param ctry country code
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
     * @param data currency data.  This is a comma separated string that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
     *    consists of "three-letter alphabet code", "three-digit numeric code",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
     *    and "one-digit (0,1,2, or 3) default fraction digit".
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
     *    For example, "JPZ,392,0".
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
     * @throws
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
    private static void replaceCurrencyData(Pattern pattern, String ctry, String curdata) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
        if (ctry.length() != 2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
            // ignore invalid country code
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
            String message = new StringBuilder()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
                .append("The entry in currency.properties for ")
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
                .append(ctry).append(" is ignored because of the invalid country code.")
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
                .toString();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
            log(Level.INFO, message, null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
        Matcher m = pattern.matcher(curdata);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
        if (!m.find()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
            // format is not recognized.  ignore the data
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
            String message = new StringBuilder()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
                .append("The entry in currency.properties for ")
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
                .append(ctry)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
                .append(" is ignored because the value format is not recognized.")
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
                .toString();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
            log(Level.INFO, message, null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
        String code = m.group(1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
        int numeric = Integer.parseInt(m.group(2));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
        int fraction = Integer.parseInt(m.group(3));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
        int entry = numeric << NUMERIC_CODE_SHIFT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
        int index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
        for (index = 0; index < scOldCurrencies.length; index++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
            if (scOldCurrencies[index].equals(code)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
        if (index == scOldCurrencies.length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
            // simple case
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
            entry |= (fraction << SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_SHIFT) |
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
                     (code.charAt(2) - 'A');
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
            // special case
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
            entry |= SPECIAL_CASE_COUNTRY_MASK |
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
                     (index + SPECIAL_CASE_COUNTRY_INDEX_DELTA);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
        setMainTableEntry(ctry.charAt(0), ctry.charAt(1), entry);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
    private static void log(Level level, String message, Throwable t) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
        Logger logger = Logger.getLogger("java.util.Currency");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   731
        if (logger.isLoggable(level)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
            if (t != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
                logger.log(level, message, t);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   734
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   735
                logger.log(level, message);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   736
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
}