Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/java/util/Currency/ValidateISO4217.java
47088 views
/*1* Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/22/*23* @test24* @bug 4691089 4819436 4942982 5104960 6544471 6627549 7066203 719575925* 8074350 8074351 8145952 8187946 8193552 8202026 820426926* 8208746 820977527* @summary Validate ISO 4217 data for Currency class.28*/2930/*31* ############################################################################32*33* ValidateISO4217 is a tool to detect differences between the latest ISO 421734* data and and Java's currency data which is based on ISO 4217.35* If there is a difference, the following file which includes currency data36* may need to be updated.37* src/share/classes/java/util/CurrencyData.properties38*39* ############################################################################40*41* 1) Make a golden-data file.42* From BSi's ISO4217 data (TABLE A1.doc), extract four (or eight, if currency is changing)43* fields and save as ./tablea1.txt.44* <Country code>\t<Currency code>\t<Numeric code>\t<Minor unit>[\t<Cutover Date>\t<new Currency code>\t<new Numeric code>\t<new Minor unit>]45* The Cutover Date is given in SimpleDateFormat's 'yyyy-MM-dd-HH-mm-ss' format in the GMT time zone.46*47* 2) Compile ValidateISO4217.java48*49* 3) Execute ValidateISO4217 as follows:50* java ValidateISO421751*/5253import java.io.*;54import java.text.*;55import java.util.*;5657public class ValidateISO4217 {5859static final int ALPHA_NUM = 26;6061static final byte UNDEFINED = 0;62static final byte DEFINED = 1;63static final byte SKIPPED = 2;6465/* input files */66static final String datafile = "tablea1.txt";6768/* alpha2-code table */69static byte[] codes = new byte[ALPHA_NUM * ALPHA_NUM];7071static final String[][] additionalCodes = {72/* Defined in ISO 4217 list, but don't have code and minor unit info. */73{"AQ", "", "", "0"}, // Antarctica7475/*76* Defined in ISO 4217 list, but don't have code and minor unit info in77* it. On the othe hand, both code and minor unit are defined in78* .properties file. I don't know why, though.79*/80{"GS", "GBP", "826", "2"}, // South Georgia And The South Sandwich Islands8182/* Not defined in ISO 4217 list, but defined in .properties file. */83{"AX", "EUR", "978", "2"}, // \u00c5LAND ISLANDS84{"PS", "ILS", "376", "2"}, // Palestinian Territory, Occupied8586/* Not defined in ISO 4217 list, but added in ISO 3166 country code list */87{"JE", "GBP", "826", "2"}, // Jersey88{"GG", "GBP", "826", "2"}, // Guernsey89{"IM", "GBP", "826", "2"}, // Isle of Man90{"BL", "EUR", "978", "2"}, // Saint Barthelemy91{"MF", "EUR", "978", "2"}, // Saint Martin92};9394/* Codes that are obsolete, do not have related country */95static final String otherCodes =96"ADP-AFA-ATS-AYM-AZM-BEF-BGL-BOV-BYB-BYR-CHE-CHW-CLF-COU-CUC-CYP-"97+ "DEM-EEK-ESP-FIM-FRF-GHC-GRD-GWP-IEP-ITL-LTL-LUF-LVL-MGF-MRO-MTL-MXV-MZM-NLG-"98+ "PTE-ROL-RUR-SDD-SIT-SKK-SRG-STD-TMM-TPE-TRL-VEF-UYI-USN-USS-VEB-"99+ "XAG-XAU-XBA-XBB-XBC-XBD-XDR-XFO-XFU-XPD-XPT-XSU-XTS-XUA-XXX-"100+ "YUM-ZMK-ZWD-ZWN-ZWR";101102static boolean err = false;103104static Set<Currency> testCurrencies = new HashSet<Currency>();105106public static void main(String[] args) throws Exception {107CheckDataVersion.check();108test1();109test2();110getAvailableCurrenciesTest();111112if (err) {113throw new RuntimeException("Failed: Validation ISO 4217 data");114}115}116117static void test1() throws Exception {118119try (FileReader fr = new FileReader(new File(System.getProperty("test.src", "."), datafile));120BufferedReader in = new BufferedReader(fr))121{122String line;123SimpleDateFormat format = null;124125while ((line = in.readLine()) != null) {126if (line.length() == 0 || line.charAt(0) == '#') {127continue;128}129130StringTokenizer tokens = new StringTokenizer(line, "\t");131String country = tokens.nextToken();132if (country.length() != 2) {133continue;134}135136String currency;137String numeric;138String minorUnit;139int tokensCount = tokens.countTokens();140if (tokensCount < 3) {141currency = "";142numeric = "0";143minorUnit = "0";144} else {145currency = tokens.nextToken();146numeric = tokens.nextToken();147minorUnit = tokens.nextToken();148testCurrencies.add(Currency.getInstance(currency));149150// check for the cutover151if (tokensCount > 3) {152if (format == null) {153format = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss", Locale.US);154format.setTimeZone(TimeZone.getTimeZone("GMT"));155format.setLenient(false);156}157if (format.parse(tokens.nextToken()).getTime() <158System.currentTimeMillis()) {159currency = tokens.nextToken();160numeric = tokens.nextToken();161minorUnit = tokens.nextToken();162testCurrencies.add(Currency.getInstance(currency));163}164}165}166int index = toIndex(country);167testCountryCurrency(country, currency, Integer.parseInt(numeric),168Integer.parseInt(minorUnit), index);169}170}171172for (int i = 0; i < additionalCodes.length; i++) {173int index = toIndex(additionalCodes[i][0]);174if (additionalCodes[i][1].length() != 0) {175testCountryCurrency(additionalCodes[i][0], additionalCodes[i][1],176Integer.parseInt(additionalCodes[i][2]),177Integer.parseInt(additionalCodes[i][3]), index);178testCurrencies.add(Currency.getInstance(additionalCodes[i][1]));179} else {180codes[index] = SKIPPED;181}182}183}184185static int toIndex(String s) {186return ((s.charAt(0) - 'A') * ALPHA_NUM + s.charAt(1) - 'A');187}188189static void testCountryCurrency(String country, String currencyCode,190int numericCode, int digits, int index) {191if (currencyCode.length() == 0) {192return;193}194testCurrencyDefined(currencyCode, numericCode, digits);195196Locale loc = new Locale("", country);197try {198Currency currency = Currency.getInstance(loc);199if (!currency.getCurrencyCode().equals(currencyCode)) {200System.err.println("Error: [" + country + ":" +201loc.getDisplayCountry() + "] expected: " + currencyCode +202", got: " + currency.getCurrencyCode());203err = true;204}205206if (codes[index] != UNDEFINED) {207System.out.println("Warning: [" + country + ":" +208loc.getDisplayCountry() +209"] multiple definitions. currency code=" + currencyCode);210}211codes[index] = DEFINED;212}213catch (Exception e) {214System.err.println("Error: " + e + ": Country=" + country);215err = true;216}217}218219static void testCurrencyDefined(String currencyCode, int numericCode, int digits) {220try {221Currency currency = currency = Currency.getInstance(currencyCode);222223if (currency.getNumericCode() != numericCode) {224System.err.println("Error: [" + currencyCode + "] expected: " +225numericCode + "; got: " + currency.getNumericCode());226err = true;227}228229if (currency.getDefaultFractionDigits() != digits) {230System.err.println("Error: [" + currencyCode + "] expected: " +231digits + "; got: " + currency.getDefaultFractionDigits());232err = true;233}234}235catch (Exception e) {236System.err.println("Error: " + e + ": Currency code=" +237currencyCode);238err = true;239}240}241242static void test2() {243for (int i = 0; i < ALPHA_NUM; i++) {244for (int j = 0; j < ALPHA_NUM; j++) {245char[] code = new char[2];246code[0] = (char)('A'+ i);247code[1] = (char)('A'+ j);248String country = new String(code);249boolean ex;250251if (codes[toIndex(country)] == UNDEFINED) {252ex = false;253try {254Currency.getInstance(new Locale("", country));255}256catch (IllegalArgumentException e) {257ex = true;258}259if (!ex) {260System.err.println("Error: This should be an undefined code and throw IllegalArgumentException: " +261country);262err = true;263}264} else if (codes[toIndex(country)] == SKIPPED) {265Currency cur = null;266try {267cur = Currency.getInstance(new Locale("", country));268}269catch (Exception e) {270System.err.println("Error: " + e + ": Country=" +271country);272err = true;273}274if (cur != null) {275System.err.println("Error: Currency.getInstance() for an this locale should return null: " +276country);277err = true;278}279}280}281}282}283284/**285* This test depends on test1(), where 'testCurrencies' set is constructed286*/287static void getAvailableCurrenciesTest() {288Set<Currency> jreCurrencies = Currency.getAvailableCurrencies();289290// add otherCodes291StringTokenizer st = new StringTokenizer(otherCodes, "-");292while (st.hasMoreTokens()) {293testCurrencies.add(Currency.getInstance(st.nextToken()));294}295296if (!testCurrencies.containsAll(jreCurrencies)) {297System.err.print("Error: getAvailableCurrencies() returned extra currencies than expected: ");298jreCurrencies.removeAll(testCurrencies);299for (Currency c : jreCurrencies) {300System.err.print(" "+c);301}302System.err.println();303err = true;304}305}306}307308309