7102969: currency.properties supercede not working correctly
8149452: j.t.SimpleDateFormat.getDateFormatSymbols().getZoneStrings() returns incorrect result for some time zones 8157138: Error while fetching currency instance by Currency.getInstance(currencycode) Reviewed-by: naoto, okutsu, peytoia
This commit is contained in:
parent
06fe4b9a0b
commit
93f4f6c1b5
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2000, 2016, Oracle and/or its affiliates. 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
|
||||
@ -26,7 +26,8 @@
|
||||
# Version of the currency data format.
|
||||
# 1: initial
|
||||
# 2: Change in minor unit (allowing 4-9 digits)
|
||||
formatVersion=2
|
||||
# 3: Change in the order of special case and other currency entries
|
||||
formatVersion=3
|
||||
|
||||
# Version of the currency code information in this class.
|
||||
# It is a serial number that accompanies with each amendment.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2016, Oracle and/or its affiliates. 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
|
||||
@ -584,7 +584,9 @@ public class CLDRConverter {
|
||||
String[] data = (String[])e[1];
|
||||
|
||||
if (map.get(TIMEZONE_ID_PREFIX + tzid) == null &&
|
||||
handlerMetaZones.get(tzid) == null) {
|
||||
handlerMetaZones.get(tzid) == null ||
|
||||
handlerMetaZones.get(tzid) != null &&
|
||||
map.get(METAZONE_ID_PREFIX + handlerMetaZones.get(tzid)) == null) {
|
||||
// First, check the CLDR meta key
|
||||
Optional<Map.Entry<String, String>> cldrMeta =
|
||||
handlerMetaZones.getData().entrySet().stream()
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 2016, Oracle and/or its affiliates. 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
|
||||
@ -121,7 +121,7 @@ public class GenerateCurrencyData {
|
||||
|
||||
private static final int maxOtherCurrencies = 128;
|
||||
private static int otherCurrenciesCount = 0;
|
||||
private static StringBuffer otherCurrencies = new StringBuffer();
|
||||
private static String[] otherCurrencies = new String[maxOtherCurrencies];
|
||||
private static int[] otherCurrenciesDefaultFractionDigits = new int[maxOtherCurrencies];
|
||||
private static int[] otherCurrenciesNumericCode= new int[maxOtherCurrencies];
|
||||
|
||||
@ -318,10 +318,7 @@ public class GenerateCurrencyData {
|
||||
if (otherCurrenciesCount == maxOtherCurrencies) {
|
||||
throw new RuntimeException("too many other currencies");
|
||||
}
|
||||
if (otherCurrencies.length() > 0) {
|
||||
otherCurrencies.append('-');
|
||||
}
|
||||
otherCurrencies.append(currencyCode);
|
||||
otherCurrencies[otherCurrenciesCount] = currencyCode;
|
||||
otherCurrenciesDefaultFractionDigits[otherCurrenciesCount] = getDefaultFractionDigits(currencyCode);
|
||||
otherCurrenciesNumericCode[otherCurrenciesCount] = getNumericCode(currencyCode);
|
||||
otherCurrenciesCount++;
|
||||
@ -350,35 +347,41 @@ public class GenerateCurrencyData {
|
||||
out.writeInt(Integer.parseInt(dataVersion));
|
||||
writeIntArray(mainTable, mainTable.length);
|
||||
out.writeInt(specialCaseCount);
|
||||
writeLongArray(specialCaseCutOverTimes, specialCaseCount);
|
||||
writeStringArray(specialCaseOldCurrencies, specialCaseCount);
|
||||
writeStringArray(specialCaseNewCurrencies, specialCaseCount);
|
||||
writeIntArray(specialCaseOldCurrenciesDefaultFractionDigits, specialCaseCount);
|
||||
writeIntArray(specialCaseNewCurrenciesDefaultFractionDigits, specialCaseCount);
|
||||
writeIntArray(specialCaseOldCurrenciesNumericCode, specialCaseCount);
|
||||
writeIntArray(specialCaseNewCurrenciesNumericCode, specialCaseCount);
|
||||
writeSpecialCaseEntries();
|
||||
out.writeInt(otherCurrenciesCount);
|
||||
out.writeUTF(otherCurrencies.toString());
|
||||
writeIntArray(otherCurrenciesDefaultFractionDigits, otherCurrenciesCount);
|
||||
writeIntArray(otherCurrenciesNumericCode, otherCurrenciesCount);
|
||||
writeOtherCurrencies();
|
||||
}
|
||||
|
||||
private static void writeIntArray(int[] ia, int count) throws IOException {
|
||||
for (int i = 0; i < count; i ++) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
out.writeInt(ia[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private static void writeLongArray(long[] la, int count) throws IOException {
|
||||
for (int i = 0; i < count; i ++) {
|
||||
out.writeLong(la[i]);
|
||||
private static void writeSpecialCaseEntries() throws IOException {
|
||||
for (int index = 0; index < specialCaseCount; index++) {
|
||||
out.writeLong(specialCaseCutOverTimes[index]);
|
||||
String str = (specialCaseOldCurrencies[index] != null)
|
||||
? specialCaseOldCurrencies[index] : "";
|
||||
out.writeUTF(str);
|
||||
str = (specialCaseNewCurrencies[index] != null)
|
||||
? specialCaseNewCurrencies[index] : "";
|
||||
out.writeUTF(str);
|
||||
out.writeInt(specialCaseOldCurrenciesDefaultFractionDigits[index]);
|
||||
out.writeInt(specialCaseNewCurrenciesDefaultFractionDigits[index]);
|
||||
out.writeInt(specialCaseOldCurrenciesNumericCode[index]);
|
||||
out.writeInt(specialCaseNewCurrenciesNumericCode[index]);
|
||||
}
|
||||
}
|
||||
|
||||
private static void writeStringArray(String[] sa, int count) throws IOException {
|
||||
for (int i = 0; i < count; i ++) {
|
||||
String str = (sa[i] != null) ? sa[i] : "";
|
||||
private static void writeOtherCurrencies() throws IOException {
|
||||
for (int index = 0; index < otherCurrenciesCount; index++) {
|
||||
String str = (otherCurrencies[index] != null)
|
||||
? otherCurrencies[index] : "";
|
||||
out.writeUTF(str);
|
||||
out.writeInt(otherCurrenciesDefaultFractionDigits[index]);
|
||||
out.writeInt(otherCurrenciesNumericCode[index]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -153,33 +153,13 @@ public final class Currency implements Serializable {
|
||||
// - bits 0-4: final char for currency code for simple country, or ID of special case
|
||||
// - special case IDs:
|
||||
// - 0: country has no currency
|
||||
// - other: index into sc* arrays + 1
|
||||
// - scCutOverTimes: cut-over time in millis as returned by
|
||||
// System.currentTimeMillis for special case countries that are changing
|
||||
// currencies; Long.MAX_VALUE for countries that are not changing currencies
|
||||
// - scOldCurrencies: old currencies for special case countries
|
||||
// - scNewCurrencies: new currencies for special case countries that are
|
||||
// changing currencies; null for others
|
||||
// - scOldCurrenciesDFD: default fraction digits for old currencies
|
||||
// - scNewCurrenciesDFD: default fraction digits for new currencies, 0 for
|
||||
// countries that are not changing currencies
|
||||
// - otherCurrencies: concatenation of all currency codes that are not the
|
||||
// main currency of a simple country, separated by "-"
|
||||
// - otherCurrenciesDFD: decimal format digits for currencies in otherCurrencies, same order
|
||||
// - other: index into specialCasesList
|
||||
|
||||
static int formatVersion;
|
||||
static int dataVersion;
|
||||
static int[] mainTable;
|
||||
static long[] scCutOverTimes;
|
||||
static String[] scOldCurrencies;
|
||||
static String[] scNewCurrencies;
|
||||
static int[] scOldCurrenciesDFD;
|
||||
static int[] scNewCurrenciesDFD;
|
||||
static int[] scOldCurrenciesNumericCode;
|
||||
static int[] scNewCurrenciesNumericCode;
|
||||
static String otherCurrencies;
|
||||
static int[] otherCurrenciesDFD;
|
||||
static int[] otherCurrenciesNumericCode;
|
||||
static List<SpecialCaseEntry> specialCasesList;
|
||||
static List<OtherCurrencyEntry> otherCurrenciesList;
|
||||
|
||||
// handy constants - must match definitions in GenerateCurrencyData
|
||||
// magic number
|
||||
@ -214,7 +194,7 @@ public final class Currency implements Serializable {
|
||||
private static final int NUMERIC_CODE_SHIFT = 10;
|
||||
|
||||
// Currency data format version
|
||||
private static final int VALID_FORMAT_VERSION = 2;
|
||||
private static final int VALID_FORMAT_VERSION = 3;
|
||||
|
||||
static {
|
||||
AccessController.doPrivileged(new PrivilegedAction<>() {
|
||||
@ -236,17 +216,9 @@ public final class Currency implements Serializable {
|
||||
dataVersion = dis.readInt();
|
||||
mainTable = readIntArray(dis, A_TO_Z * A_TO_Z);
|
||||
int scCount = dis.readInt();
|
||||
scCutOverTimes = readLongArray(dis, scCount);
|
||||
scOldCurrencies = readStringArray(dis, scCount);
|
||||
scNewCurrencies = readStringArray(dis, scCount);
|
||||
scOldCurrenciesDFD = readIntArray(dis, scCount);
|
||||
scNewCurrenciesDFD = readIntArray(dis, scCount);
|
||||
scOldCurrenciesNumericCode = readIntArray(dis, scCount);
|
||||
scNewCurrenciesNumericCode = readIntArray(dis, scCount);
|
||||
specialCasesList = readSpecialCases(dis, scCount);
|
||||
int ocCount = dis.readInt();
|
||||
otherCurrencies = dis.readUTF();
|
||||
otherCurrenciesDFD = readIntArray(dis, ocCount);
|
||||
otherCurrenciesNumericCode = readIntArray(dis, ocCount);
|
||||
otherCurrenciesList = readOtherCurrencies(dis, ocCount);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new InternalError(e);
|
||||
@ -329,6 +301,7 @@ public final class Currency implements Serializable {
|
||||
// Currency code not internally generated, need to verify first
|
||||
// A currency code must have 3 characters and exist in the main table
|
||||
// or in the list of other currencies.
|
||||
boolean found = false;
|
||||
if (currencyCode.length() != 3) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
@ -340,17 +313,23 @@ public final class Currency implements Serializable {
|
||||
&& currencyCode.charAt(2) - 'A' == (tableEntry & SIMPLE_CASE_COUNTRY_FINAL_CHAR_MASK)) {
|
||||
defaultFractionDigits = (tableEntry & SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_MASK) >> SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_SHIFT;
|
||||
numericCode = (tableEntry & NUMERIC_CODE_MASK) >> NUMERIC_CODE_SHIFT;
|
||||
} else {
|
||||
// Check for '-' separately so we don't get false hits in the table.
|
||||
if (currencyCode.charAt(2) == '-') {
|
||||
found = true;
|
||||
} else { //special case
|
||||
int[] fractionAndNumericCode = SpecialCaseEntry.findEntry(currencyCode);
|
||||
if (fractionAndNumericCode != null) {
|
||||
defaultFractionDigits = fractionAndNumericCode[0];
|
||||
numericCode = fractionAndNumericCode[1];
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
OtherCurrencyEntry ocEntry = OtherCurrencyEntry.findEntry(currencyCode);
|
||||
if (ocEntry == null) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
int index = otherCurrencies.indexOf(currencyCode);
|
||||
if (index == -1) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
defaultFractionDigits = otherCurrenciesDFD[index / 4];
|
||||
numericCode = otherCurrenciesNumericCode[index / 4];
|
||||
defaultFractionDigits = ocEntry.fraction;
|
||||
numericCode = ocEntry.numericCode;
|
||||
}
|
||||
}
|
||||
|
||||
@ -410,13 +389,17 @@ public final class Currency implements Serializable {
|
||||
if (tableEntry == COUNTRY_WITHOUT_CURRENCY_ENTRY) {
|
||||
return null;
|
||||
} else {
|
||||
int index = (tableEntry & SPECIAL_CASE_COUNTRY_INDEX_MASK) - SPECIAL_CASE_COUNTRY_INDEX_DELTA;
|
||||
if (scCutOverTimes[index] == Long.MAX_VALUE || System.currentTimeMillis() < scCutOverTimes[index]) {
|
||||
return getInstance(scOldCurrencies[index], scOldCurrenciesDFD[index],
|
||||
scOldCurrenciesNumericCode[index]);
|
||||
int index = SpecialCaseEntry.toIndex(tableEntry);
|
||||
SpecialCaseEntry scEntry = specialCasesList.get(index);
|
||||
if (scEntry.cutOverTime == Long.MAX_VALUE
|
||||
|| System.currentTimeMillis() < scEntry.cutOverTime) {
|
||||
return getInstance(scEntry.oldCurrency,
|
||||
scEntry.oldCurrencyFraction,
|
||||
scEntry.oldCurrencyNumericCode);
|
||||
} else {
|
||||
return getInstance(scNewCurrencies[index], scNewCurrenciesDFD[index],
|
||||
scNewCurrenciesNumericCode[index]);
|
||||
return getInstance(scEntry.newCurrency,
|
||||
scEntry.newCurrencyFraction,
|
||||
scEntry.newCurrencyNumericCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -451,14 +434,29 @@ public final class Currency implements Serializable {
|
||||
sb.append(c2);
|
||||
sb.append(finalChar);
|
||||
available.add(getInstance(sb.toString(), defaultFractionDigits, numericCode));
|
||||
} else if ((tableEntry & COUNTRY_TYPE_MASK) == SPECIAL_CASE_COUNTRY_MASK
|
||||
&& tableEntry != INVALID_COUNTRY_ENTRY
|
||||
&& tableEntry != COUNTRY_WITHOUT_CURRENCY_ENTRY) {
|
||||
int index = SpecialCaseEntry.toIndex(tableEntry);
|
||||
SpecialCaseEntry scEntry = specialCasesList.get(index);
|
||||
|
||||
if (scEntry.cutOverTime == Long.MAX_VALUE
|
||||
|| System.currentTimeMillis() < scEntry.cutOverTime) {
|
||||
available.add(getInstance(scEntry.oldCurrency,
|
||||
scEntry.oldCurrencyFraction,
|
||||
scEntry.oldCurrencyNumericCode));
|
||||
} else {
|
||||
available.add(getInstance(scEntry.newCurrency,
|
||||
scEntry.newCurrencyFraction,
|
||||
scEntry.newCurrencyNumericCode));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now add other currencies
|
||||
StringTokenizer st = new StringTokenizer(otherCurrencies, "-");
|
||||
while (st.hasMoreElements()) {
|
||||
available.add(getInstance((String)st.nextElement()));
|
||||
for (OtherCurrencyEntry entry : otherCurrenciesList) {
|
||||
available.add(getInstance(entry.currencyCode));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -521,15 +519,15 @@ public final class Currency implements Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the default number of fraction digits used with this currency.
|
||||
* Note that the number of fraction digits is the same as ISO 4217's
|
||||
* minor unit for the currency.
|
||||
* For example, the default number of fraction digits for the Euro is 2,
|
||||
* while for the Japanese Yen it's 0.
|
||||
* In the case of pseudo-currencies, such as IMF Special Drawing Rights,
|
||||
* -1 is returned.
|
||||
*
|
||||
* @return the default number of fraction digits used with this currency
|
||||
* Gets the default number of fraction digits used with this currency.
|
||||
* Note that the number of fraction digits is the same as ISO 4217's
|
||||
* minor unit for the currency.
|
||||
* For example, the default number of fraction digits for the Euro is 2,
|
||||
* while for the Japanese Yen it's 0.
|
||||
* In the case of pseudo-currencies, such as IMF Special Drawing Rights,
|
||||
* -1 is returned.
|
||||
*
|
||||
* @return the default number of fraction digits used with this currency
|
||||
*/
|
||||
public int getDefaultFractionDigits() {
|
||||
return defaultFractionDigits;
|
||||
@ -693,22 +691,55 @@ public final class Currency implements Serializable {
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static long[] readLongArray(DataInputStream dis, int count) throws IOException {
|
||||
long[] ret = new long[count];
|
||||
for (int i = 0; i < count; i++) {
|
||||
ret[i] = dis.readLong();
|
||||
}
|
||||
private static List<SpecialCaseEntry> readSpecialCases(DataInputStream dis,
|
||||
int count)
|
||||
throws IOException {
|
||||
|
||||
return ret;
|
||||
List<SpecialCaseEntry> list = new ArrayList<>(count);
|
||||
long cutOverTime;
|
||||
String oldCurrency;
|
||||
String newCurrency;
|
||||
int oldCurrencyFraction;
|
||||
int newCurrencyFraction;
|
||||
int oldCurrencyNumericCode;
|
||||
int newCurrencyNumericCode;
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
cutOverTime = dis.readLong();
|
||||
oldCurrency = dis.readUTF();
|
||||
newCurrency = dis.readUTF();
|
||||
oldCurrencyFraction = dis.readInt();
|
||||
newCurrencyFraction = dis.readInt();
|
||||
oldCurrencyNumericCode = dis.readInt();
|
||||
newCurrencyNumericCode = dis.readInt();
|
||||
SpecialCaseEntry sc = new SpecialCaseEntry(cutOverTime,
|
||||
oldCurrency, newCurrency,
|
||||
oldCurrencyFraction, newCurrencyFraction,
|
||||
oldCurrencyNumericCode, newCurrencyNumericCode);
|
||||
list.add(sc);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private static String[] readStringArray(DataInputStream dis, int count) throws IOException {
|
||||
String[] ret = new String[count];
|
||||
for (int i = 0; i < count; i++) {
|
||||
ret[i] = dis.readUTF();
|
||||
}
|
||||
private static List<OtherCurrencyEntry> readOtherCurrencies(DataInputStream dis,
|
||||
int count)
|
||||
throws IOException {
|
||||
|
||||
return ret;
|
||||
List<OtherCurrencyEntry> list = new ArrayList<>(count);
|
||||
String currencyCode;
|
||||
int fraction;
|
||||
int numericCode;
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
currencyCode = dis.readUTF();
|
||||
fraction = dis.readInt();
|
||||
numericCode = dis.readInt();
|
||||
OtherCurrencyEntry oc = new OtherCurrencyEntry(currencyCode,
|
||||
fraction,
|
||||
numericCode);
|
||||
list.add(oc);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -766,21 +797,27 @@ public final class Currency implements Serializable {
|
||||
return;
|
||||
}
|
||||
|
||||
int index;
|
||||
for (index = 0; index < scOldCurrencies.length; index++) {
|
||||
if (scOldCurrencies[index].equals(code)) {
|
||||
break;
|
||||
}
|
||||
int index = SpecialCaseEntry.indexOf(code, fraction, numeric);
|
||||
|
||||
/* if a country switches from simple case to special case or
|
||||
* one special case to other special case which is not present
|
||||
* in the sc arrays then insert the new entry in special case arrays
|
||||
*/
|
||||
if (index == -1 && (ctry.charAt(0) != code.charAt(0)
|
||||
|| ctry.charAt(1) != code.charAt(1))) {
|
||||
|
||||
specialCasesList.add(new SpecialCaseEntry(code, fraction, numeric));
|
||||
index = specialCasesList.size() - 1;
|
||||
}
|
||||
|
||||
if (index == scOldCurrencies.length) {
|
||||
if (index == -1) {
|
||||
// simple case
|
||||
entry |= (fraction << SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_SHIFT) |
|
||||
(code.charAt(2) - 'A');
|
||||
entry |= (fraction << SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_SHIFT)
|
||||
| (code.charAt(2) - 'A');
|
||||
} else {
|
||||
// special case
|
||||
entry |= SPECIAL_CASE_COUNTRY_MASK |
|
||||
(index + SPECIAL_CASE_COUNTRY_INDEX_DELTA);
|
||||
entry = SPECIAL_CASE_COUNTRY_MASK
|
||||
| (index + SPECIAL_CASE_COUNTRY_INDEX_DELTA);
|
||||
}
|
||||
setMainTableEntry(ctry.charAt(0), ctry.charAt(1), entry);
|
||||
}
|
||||
@ -814,5 +851,128 @@ public final class Currency implements Serializable {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Used to represent a special case currency entry
|
||||
* - cutOverTime: cut-over time in millis as returned by
|
||||
* System.currentTimeMillis for special case countries that are changing
|
||||
* currencies; Long.MAX_VALUE for countries that are not changing currencies
|
||||
* - oldCurrency: old currencies for special case countries
|
||||
* - newCurrency: new currencies for special case countries that are
|
||||
* changing currencies; null for others
|
||||
* - oldCurrencyFraction: default fraction digits for old currencies
|
||||
* - newCurrencyFraction: default fraction digits for new currencies, 0 for
|
||||
* countries that are not changing currencies
|
||||
* - oldCurrencyNumericCode: numeric code for old currencies
|
||||
* - newCurrencyNumericCode: numeric code for new currencies, 0 for countries
|
||||
* that are not changing currencies
|
||||
*/
|
||||
private static class SpecialCaseEntry {
|
||||
|
||||
final private long cutOverTime;
|
||||
final private String oldCurrency;
|
||||
final private String newCurrency;
|
||||
final private int oldCurrencyFraction;
|
||||
final private int newCurrencyFraction;
|
||||
final private int oldCurrencyNumericCode;
|
||||
final private int newCurrencyNumericCode;
|
||||
|
||||
private SpecialCaseEntry(long cutOverTime, String oldCurrency, String newCurrency,
|
||||
int oldCurrencyFraction, int newCurrencyFraction,
|
||||
int oldCurrencyNumericCode, int newCurrencyNumericCode) {
|
||||
this.cutOverTime = cutOverTime;
|
||||
this.oldCurrency = oldCurrency;
|
||||
this.newCurrency = newCurrency;
|
||||
this.oldCurrencyFraction = oldCurrencyFraction;
|
||||
this.newCurrencyFraction = newCurrencyFraction;
|
||||
this.oldCurrencyNumericCode = oldCurrencyNumericCode;
|
||||
this.newCurrencyNumericCode = newCurrencyNumericCode;
|
||||
}
|
||||
|
||||
private SpecialCaseEntry(String currencyCode, int fraction,
|
||||
int numericCode) {
|
||||
this(Long.MAX_VALUE, currencyCode, "", fraction, 0, numericCode, 0);
|
||||
}
|
||||
|
||||
//get the index of the special case entry
|
||||
private static int indexOf(String code, int fraction, int numeric) {
|
||||
int size = specialCasesList.size();
|
||||
for (int index = 0; index < size; index++) {
|
||||
SpecialCaseEntry scEntry = specialCasesList.get(index);
|
||||
if (scEntry.oldCurrency.equals(code)
|
||||
&& scEntry.oldCurrencyFraction == fraction
|
||||
&& scEntry.oldCurrencyNumericCode == numeric
|
||||
&& scEntry.cutOverTime == Long.MAX_VALUE) {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// get the fraction and numericCode of the sc currencycode
|
||||
private static int[] findEntry(String code) {
|
||||
int[] fractionAndNumericCode = null;
|
||||
int size = specialCasesList.size();
|
||||
for (int index = 0; index < size; index++) {
|
||||
SpecialCaseEntry scEntry = specialCasesList.get(index);
|
||||
if (scEntry.oldCurrency.equals(code) && (scEntry.cutOverTime == Long.MAX_VALUE
|
||||
|| System.currentTimeMillis() < scEntry.cutOverTime)) {
|
||||
//consider only when there is no new currency or cutover time is not passed
|
||||
fractionAndNumericCode = new int[2];
|
||||
fractionAndNumericCode[0] = scEntry.oldCurrencyFraction;
|
||||
fractionAndNumericCode[1] = scEntry.oldCurrencyNumericCode;
|
||||
break;
|
||||
} else if (scEntry.newCurrency.equals(code)
|
||||
&& System.currentTimeMillis() >= scEntry.cutOverTime) {
|
||||
//consider only if the cutover time is passed
|
||||
fractionAndNumericCode = new int[2];
|
||||
fractionAndNumericCode[0] = scEntry.newCurrencyFraction;
|
||||
fractionAndNumericCode[1] = scEntry.newCurrencyNumericCode;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return fractionAndNumericCode;
|
||||
}
|
||||
|
||||
// convert the special case entry to sc arrays index
|
||||
private static int toIndex(int tableEntry) {
|
||||
return (tableEntry & SPECIAL_CASE_COUNTRY_INDEX_MASK) - SPECIAL_CASE_COUNTRY_INDEX_DELTA;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Used to represent Other currencies
|
||||
* - currencyCode: currency codes that are not the main currency
|
||||
* of a simple country
|
||||
* - otherCurrenciesDFD: decimal format digits for other currencies
|
||||
* - otherCurrenciesNumericCode: numeric code for other currencies
|
||||
*/
|
||||
private static class OtherCurrencyEntry {
|
||||
|
||||
final private String currencyCode;
|
||||
final private int fraction;
|
||||
final private int numericCode;
|
||||
|
||||
private OtherCurrencyEntry(String currencyCode, int fraction,
|
||||
int numericCode) {
|
||||
this.currencyCode = currencyCode;
|
||||
this.fraction = fraction;
|
||||
this.numericCode = numericCode;
|
||||
}
|
||||
|
||||
//get the instance of the other currency code
|
||||
private static OtherCurrencyEntry findEntry(String code) {
|
||||
int size = otherCurrenciesList.size();
|
||||
for (int index = 0; index < size; index++) {
|
||||
OtherCurrencyEntry ocEntry = otherCurrenciesList.get(index);
|
||||
if (ocEntry.currencyCode.equalsIgnoreCase(code)) {
|
||||
return ocEntry;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2007, 2016, Oracle and/or its affiliates. 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
|
||||
@ -25,6 +25,7 @@ import java.io.*;
|
||||
import java.text.*;
|
||||
import java.util.*;
|
||||
import java.util.regex.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class PropertiesTest {
|
||||
public static void main(String[] args) throws Exception {
|
||||
@ -32,9 +33,14 @@ public class PropertiesTest {
|
||||
dump(args[1]);
|
||||
} else if (args.length == 4 && args[0].equals("-c")) {
|
||||
compare(args[1], args[2], args[3]);
|
||||
} else if (args.length == 1 && args[0].equals("bug7102969")) {
|
||||
bug7102969();
|
||||
} else if (args.length == 1 && args[0].equals("bug8157138")) {
|
||||
bug8157138();
|
||||
} else {
|
||||
System.err.println("Usage: java PropertiesTest -d <dumpfile>");
|
||||
System.err.println(" java PropertiesTest -c <beforedump> <afterdump> <propsfile>");
|
||||
System.err.println(" java PropertiesTest bug[JBS bug id number] e.g. bug7102969");
|
||||
System.exit(-1);
|
||||
}
|
||||
}
|
||||
@ -174,6 +180,74 @@ public class PropertiesTest {
|
||||
}
|
||||
}
|
||||
|
||||
private static void bug7102969() {
|
||||
|
||||
// check the correct overriding of special case entries
|
||||
Currency cur = Currency.getInstance(new Locale("", "JP"));
|
||||
if (!cur.getCurrencyCode().equals("ABC")) {
|
||||
throw new RuntimeException("[Expected: ABC as currency code of JP, found: "
|
||||
+ cur.getCurrencyCode() + "]");
|
||||
}
|
||||
|
||||
/* check if the currency instance is returned by
|
||||
* getAvailableCurrencies() method
|
||||
*/
|
||||
if (!Currency.getAvailableCurrencies().contains(cur)) {
|
||||
throw new RuntimeException("[The Currency instance ["
|
||||
+ cur.getCurrencyCode() + ", "
|
||||
+ cur.getNumericCode() + ", "
|
||||
+ cur.getDefaultFractionDigits()
|
||||
+ "] is not available in the currencies list]");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void bug8157138() {
|
||||
|
||||
/* check the currencies which exist only as a special case are
|
||||
* accessible i.e. it should not throw IllegalArgumentException
|
||||
*/
|
||||
try {
|
||||
Currency.getInstance("MAD");
|
||||
} catch (IllegalArgumentException ex) {
|
||||
throw new RuntimeException("Test Failed: "
|
||||
+ "special case currency instance MAD not found"
|
||||
+ " via Currency.getInstance(\"MAD\")");
|
||||
}
|
||||
|
||||
try {
|
||||
Currency.getInstance("ABC");
|
||||
} catch (IllegalArgumentException ex) {
|
||||
throw new RuntimeException("Test Failed: "
|
||||
+ "special case currency instance ABC not found"
|
||||
+ " via Currency.getInstance(\"ABC\")");
|
||||
}
|
||||
|
||||
/* check the currency value is returned by getAvailableCurrencies()
|
||||
* method
|
||||
*/
|
||||
List<Currency> list = Currency.getAvailableCurrencies().stream()
|
||||
.filter(cur -> cur.getCurrencyCode().equals("MAD"))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (list.isEmpty()) {
|
||||
throw new RuntimeException("Test Failed: "
|
||||
+ "special case currency instance MAD not found"
|
||||
+ " in Currency.getAvailableCurrencies() list");
|
||||
}
|
||||
|
||||
list = Currency.getAvailableCurrencies().stream()
|
||||
.filter(cur -> cur.getCurrencyCode().equals("ABC"))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (list.isEmpty()) {
|
||||
throw new RuntimeException("Test Failed: "
|
||||
+ "special case currency instance ABC not found"
|
||||
+ " in Currency.getAvailableCurrencies() list");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static boolean isPastCutoverDate(String s)
|
||||
throws IndexOutOfBoundsException, NullPointerException, ParseException {
|
||||
String dateString = s.substring(s.lastIndexOf(',')+1, s.length()).trim();
|
||||
|
@ -23,7 +23,8 @@
|
||||
#
|
||||
|
||||
# @test
|
||||
# @bug 6332666 6863624 7180362 8003846 8074350 8074351 8130246 8149735
|
||||
# @bug 6332666 6863624 7180362 8003846 8074350 8074351 8130246 8149735 7102969
|
||||
# 8157138
|
||||
# @summary tests the capability of replacing the currency data with user
|
||||
# specified currency properties file
|
||||
# @build PropertiesTest
|
||||
@ -113,6 +114,16 @@ ${WRITABLEJDK}${FS}bin${FS}java ${TESTVMOPTS} -cp ${TESTCLASSES} PropertiesTest
|
||||
if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
|
||||
if [ ! -f dump3 ]; then echo "file dump3 not created. Test cannot execute. Failed."; exit 1; fi
|
||||
|
||||
# run bug7102969 test
|
||||
echo ''
|
||||
${WRITABLEJDK}${FS}bin${FS}java ${TESTVMOPTS} -cp ${TESTCLASSES} PropertiesTest bug7102969
|
||||
if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
|
||||
|
||||
# run bug8157138 test
|
||||
echo ''
|
||||
${WRITABLEJDK}${FS}bin${FS}java ${TESTVMOPTS} -cp ${TESTCLASSES} PropertiesTest bug8157138
|
||||
if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
|
||||
|
||||
# Cleanup
|
||||
rm -rf $WRITABLEJDK
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
CL=CLF,990,4
|
||||
CM=IED,111,2, 2004-01-01T00:70:00
|
||||
ES=ESD,877,2
|
||||
JP=JPZ,123,2
|
||||
JP=ABC,999,0
|
||||
MA=MAA,555,5
|
||||
MC=MCC,555,6
|
||||
MD=MDD,555,7
|
||||
|
@ -5,7 +5,7 @@
|
||||
#
|
||||
|
||||
# Version
|
||||
FILEVERSION=2
|
||||
FILEVERSION=3
|
||||
DATAVERSION=160
|
||||
|
||||
# ISO 4217 currency data
|
||||
|
58
jdk/test/java/util/TimeZone/Bug8149452.java
Normal file
58
jdk/test/java/util/TimeZone/Bug8149452.java
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
/*
|
||||
* @test
|
||||
* @bug 8149452
|
||||
* @summary Check the missing time zone names.
|
||||
*/
|
||||
import java.text.DateFormatSymbols;
|
||||
import java.util.ArrayList;
|
||||
import java.util.TimeZone;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class Bug8149452 {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
List<String> listNotFound = new ArrayList<>();
|
||||
String[][] zoneStrings = DateFormatSymbols.getInstance()
|
||||
.getZoneStrings();
|
||||
for (String tzID : TimeZone.getAvailableIDs()) {
|
||||
if (!Arrays.stream(zoneStrings)
|
||||
.anyMatch(zone -> tzID.equalsIgnoreCase(zone[0]))) {
|
||||
// to ignore names for Etc/GMT[+-][0-9]+ which are not supported
|
||||
if (!tzID.startsWith("Etc/GMT") && !tzID.startsWith("GMT")) {
|
||||
listNotFound.add(tzID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!listNotFound.isEmpty()) {
|
||||
throw new RuntimeException("Test Failed: Time Zone Strings for "
|
||||
+ listNotFound + " not found");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user