view j2se/test/java/util/Currency/ValidateISO4217.java @ 2:16f2b6c91171 trunk

[svn] Load openjdk/jdk7/b14 into jdk/trunk.
author xiomara
date Fri, 22 Jun 2007 00:46:43 +0000
parents
children bf1d8af0651f
line wrap: on
line source

/* 
 * Copyright (c) 2007 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 * 
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 * 
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 * 
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 * 
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */
/*
 * @test 1.7 07/04/12
 * @bug 4819436 4942982 5104960 6544471
 * @summary Validate ISO 4217 data for Currency class.
 */

/*
 * ############################################################################
 * 
 *  ValidateISO4217 is a tool to detect differences between the latest ISO 4217
 *  data and and Java's currency data which is based on ISO 4217.
 *  If there is a difference, the following file which includes currency data
 *  may need to be updated.
 *      src/share/classes/java/util/CurrencyData.properties
 *
 * ############################################################################
 *
 * 1) Make a golden-data file.
 *      From BSi's ISO4217 data (TABLE A1.doc), extract three (or five, if currency is changing)
 *      fields and save as ./tablea1.txt.
 *	  <Country code>\t<Currency code>\t<Minor unit>[\t<Cutover Date>\t<new Currency code>\t<new Minor unit>]
 *      The Cutover Date is given in SimpleDateFormat's 'yyyy-MM-dd-HH-mm-ss' format in the GMT time zone.
 *
 * 2) Compile ValidateISO4217.java
 *
 * 3) Execute ValidateISO4217 as follows:
 *      java ValidateISO4217
 */

import java.io.*;
import java.text.*;
import java.util.*;

public class ValidateISO4217 {

    static final int ALPHA_NUM = 26;

    static final byte UNDEFINED = 0;
    static final byte DEFINED = 1;
    static final byte SKIPPED = 2;

    /* input files */
    static final String datafile = "tablea1.txt";

    /* alpha2-code table */
    static byte[] codes = new byte[ALPHA_NUM * ALPHA_NUM];

    static final String[][] additionalCodes = {
	/* Defined in ISO 4217 list, but don't have code and minor unit info. */
	{"AQ", "", "0"},	// Antarctica

	/*
	 * Defined in ISO 4217 list, but don't have code and minor unit info in
	 * it. On the othe hand, both code and minor unit are defined in
	 * .properties file. I don't know why, though.
	 */
	{"GS", "GBP", "2"},	// South Georgia And The South Sandwich Islands

	/* Not defined in ISO 4217 list, but defined in .properties file. */
	{"PS", "ILS", "2"},	// Palestinian Territory, Occupied

	/* Not defined in ISO 4217 list, but added in ISO 3166 country code list */
	{"JE", "GBP", "2"},	// Jersey
	{"GG", "GBP", "2"},	// Guernsey
	{"IM", "GBP", "2"},	// Isle of Man
    };

    static boolean err = false;

    public static void main(String[] args) throws Exception {
        CheckDataVersion.check();
	test1();
	test2();

	if (err) {
	    throw new RuntimeException("Failed: Validation ISO 4217 data");
	}
    }

    static void test1() throws Exception {

	FileReader fr = new FileReader(new File(System.getProperty("test.src", "."), datafile));
	BufferedReader in = new BufferedReader(fr);
	String line;
        SimpleDateFormat format = null;

	while ((line = in.readLine()) != null) {
	    if (line.length() == 0 || line.charAt(0) == '#') {
		continue;
	    }

	    StringTokenizer tokens = new StringTokenizer(line, "\t");
	    String country = tokens.nextToken();
	    if (country.length() != 2) {
	        continue;
	    }

	    String currency;
	    String minorUnit;
            int tokensCount = tokens.countTokens();
	    if (tokensCount < 2) {
		currency = "";
		minorUnit = "0";
	    } else {
		currency = tokens.nextToken();
		minorUnit = tokens.nextToken();

                // check for the cutover
                if (tokensCount > 2) {
                    if (format == null) {
                        format = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss", Locale.US);
                        format.setTimeZone(TimeZone.getTimeZone("GMT"));
                        format.setLenient(false);
                    }
                    if (format.parse(tokens.nextToken()).getTime() <
                        System.currentTimeMillis()) {
                        currency = tokens.nextToken();
                        minorUnit = tokens.nextToken();
                    }
                }
	    }
	    int index = toIndex(country);
	    testCountryCurrency(country, currency, Integer.parseInt(minorUnit),
		index);
	}
	in.close();

	for (int i = 0; i < additionalCodes.length; i++) {
	    int index = toIndex(additionalCodes[i][0]);
	    if (additionalCodes[i][1].length() != 0) {
		testCountryCurrency(additionalCodes[i][0], additionalCodes[i][1],
		    Integer.parseInt(additionalCodes[i][2]), index);
	    } else {
		codes[index] = SKIPPED;
	    }
	}
    }

    static int toIndex(String s) {
	return ((s.charAt(0) - 'A') * ALPHA_NUM + s.charAt(1) - 'A');
    }

    static void testCountryCurrency(String country, String currencyCode, int digits, int index) {
	if (currencyCode.length() == 0) {
	    return;
	}
	testCurrencyDefined(currencyCode, digits);

	Locale loc = new Locale("", country);
	try {
	    Currency currency = Currency.getInstance(loc);
	    if (!currency.getCurrencyCode().equals(currencyCode)) {
		System.err.println("Error: [" + country + ":" +
		    loc.getDisplayCountry() + "] expected: " + currencyCode +
		    ", got: " + currency.getCurrencyCode());
		err = true;
	    }

	    if (codes[index] != UNDEFINED) {
		System.out.println("Warning: [" + country + ":" +
		    loc.getDisplayCountry() +
		    "] multiple definitions. currency code=" + currencyCode);
	    }
	    codes[index] = DEFINED;
	}
	catch (Exception e) {
	    System.err.println("Error: " + e + ": Country=" + country);
	    err = true;
	}
    }

    static void testCurrencyDefined(String currencyCode, int digits) {
	try {
	    Currency currency = currency = Currency.getInstance(currencyCode);

	    if (currency.getDefaultFractionDigits() != digits) {
		System.err.println("Error: [" + currencyCode + "] expected: " +
		    digits + "; got: " + currency.getDefaultFractionDigits());
		err = true;
	    }
	}
	catch (Exception e) {
	    System.err.println("Error: " + e + ": Currency code=" +
		currencyCode);
	    err = true;
	}
    }

    static void test2() {
	for (int i = 0; i < ALPHA_NUM; i++) {
	    for (int j = 0; j < ALPHA_NUM; j++) {
		char[] code = new char[2];
		code[0] = (char)('A'+ i);
		code[1] = (char)('A'+ j);
		String country = new String(code);
		boolean ex;

		if (codes[toIndex(country)] == UNDEFINED) {
		    ex = false;
		    try {
			Currency.getInstance(new Locale("", country));
		    }
		    catch (IllegalArgumentException e) {
			ex = true;
		    }
		    if (!ex) {
			System.err.println("Error: This should be an undefined code and throw IllegalArgumentException: " +
			    country);
			err = true;
		    }
		} else if (codes[toIndex(country)] == SKIPPED) {
		    Currency cur = null;
		    try {
			cur = Currency.getInstance(new Locale("", country));
		    }
		    catch (Exception e) {
			System.err.println("Error: " + e + ": Country=" +
			    country);
			err = true;
		    }
		    if (cur != null) {
			System.err.println("Error: Currency.getInstance() for an this locale should return null: " +
			    country);
			err = true;
		    }
		}
	    }
	}
    }
}