1 /*
2 * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package java.util;
27
28 import java.io.BufferedInputStream;
29 import java.io.DataInputStream;
30 import java.io.File;
31 import java.io.FileInputStream;
32 import java.io.FileReader;
33 import java.io.InputStream;
34 import java.io.IOException;
35 import java.io.Serializable;
36 import java.security.AccessController;
37 import java.security.PrivilegedAction;
38 import java.text.ParseException;
39 import java.text.SimpleDateFormat;
40 import java.util.concurrent.ConcurrentHashMap;
41 import java.util.concurrent.ConcurrentMap;
42 import java.util.regex.Pattern;
43 import java.util.regex.Matcher;
44 import java.util.spi.CurrencyNameProvider;
45 import sun.util.locale.provider.LocaleServiceProviderPool;
46 import sun.util.logging.PlatformLogger;
47
48
49 /**
50 * Represents a currency. Currencies are identified by their ISO 4217 currency
51 * codes. Visit the <a href="http://www.iso.org/iso/home/standards/currency_codes.htm">
52 * ISO web site</a> for more information.
53 * <p>
54 * The class is designed so that there's never more than one
55 * <code>Currency</code> instance for any given currency. Therefore, there's
183 // mask for special case country entries
184 private static final int SPECIAL_CASE_COUNTRY_MASK = 0x00000200;
185 // mask for special case country index
186 private static final int SPECIAL_CASE_COUNTRY_INDEX_MASK = 0x0000001F;
187 // delta from entry index component in main table to index into special case tables
188 private static final int SPECIAL_CASE_COUNTRY_INDEX_DELTA = 1;
189 // mask for distinguishing simple and special case countries
190 private static final int COUNTRY_TYPE_MASK = SIMPLE_CASE_COUNTRY_MASK | SPECIAL_CASE_COUNTRY_MASK;
191 // mask for the numeric code of the currency
192 private static final int NUMERIC_CODE_MASK = 0x000FFC00;
193 // shift count for the numeric code of the currency
194 private static final int NUMERIC_CODE_SHIFT = 10;
195
196 // Currency data format version
197 private static final int VALID_FORMAT_VERSION = 3;
198
199 static {
200 AccessController.doPrivileged(new PrivilegedAction<>() {
201 @Override
202 public Void run() {
203 try {
204 try (InputStream in = getClass().getResourceAsStream("/java/util/currency.data")) {
205 if (in == null) {
206 throw new InternalError("Currency data not found");
207 }
208 DataInputStream dis = new DataInputStream(new BufferedInputStream(in));
209 if (dis.readInt() != MAGIC_NUMBER) {
210 throw new InternalError("Currency data is possibly corrupted");
211 }
212 formatVersion = dis.readInt();
213 if (formatVersion != VALID_FORMAT_VERSION) {
214 throw new InternalError("Currency data format is incorrect");
215 }
216 dataVersion = dis.readInt();
217 mainTable = readIntArray(dis, A_TO_Z * A_TO_Z);
218 int scCount = dis.readInt();
219 specialCasesList = readSpecialCases(dis, scCount);
220 int ocCount = dis.readInt();
221 otherCurrenciesList = readOtherCurrencies(dis, ocCount);
222 }
223 } catch (IOException e) {
224 throw new InternalError(e);
225 }
226
227 // look for the properties file for overrides
228 String propsFile = System.getProperty("java.util.currency.data");
229 if (propsFile == null) {
230 propsFile = System.getProperty("java.home") + File.separator + "lib" +
231 File.separator + "currency.properties";
232 }
233 try {
234 File propFile = new File(propsFile);
235 if (propFile.exists()) {
236 Properties props = new Properties();
237 try (FileReader fr = new FileReader(propFile)) {
238 props.load(fr);
239 }
240 Set<String> keys = props.stringPropertyNames();
241 Pattern propertiesPattern =
242 Pattern.compile("([A-Z]{3})\\s*,\\s*(\\d{3})\\s*,\\s*" +
|
1 /*
2 * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package java.util;
27
28 import java.io.BufferedInputStream;
29 import java.io.DataInputStream;
30 import java.io.File;
31 import java.io.FileInputStream;
32 import java.io.FileReader;
33 import java.io.InputStream;
34 import java.io.IOException;
35 import java.io.Serializable;
36 import java.nio.file.Files;
37 import java.nio.file.Paths;
38 import java.security.AccessController;
39 import java.security.PrivilegedAction;
40 import java.text.ParseException;
41 import java.text.SimpleDateFormat;
42 import java.util.concurrent.ConcurrentHashMap;
43 import java.util.concurrent.ConcurrentMap;
44 import java.util.regex.Pattern;
45 import java.util.regex.Matcher;
46 import java.util.spi.CurrencyNameProvider;
47 import sun.util.locale.provider.LocaleServiceProviderPool;
48 import sun.util.logging.PlatformLogger;
49
50
51 /**
52 * Represents a currency. Currencies are identified by their ISO 4217 currency
53 * codes. Visit the <a href="http://www.iso.org/iso/home/standards/currency_codes.htm">
54 * ISO web site</a> for more information.
55 * <p>
56 * The class is designed so that there's never more than one
57 * <code>Currency</code> instance for any given currency. Therefore, there's
185 // mask for special case country entries
186 private static final int SPECIAL_CASE_COUNTRY_MASK = 0x00000200;
187 // mask for special case country index
188 private static final int SPECIAL_CASE_COUNTRY_INDEX_MASK = 0x0000001F;
189 // delta from entry index component in main table to index into special case tables
190 private static final int SPECIAL_CASE_COUNTRY_INDEX_DELTA = 1;
191 // mask for distinguishing simple and special case countries
192 private static final int COUNTRY_TYPE_MASK = SIMPLE_CASE_COUNTRY_MASK | SPECIAL_CASE_COUNTRY_MASK;
193 // mask for the numeric code of the currency
194 private static final int NUMERIC_CODE_MASK = 0x000FFC00;
195 // shift count for the numeric code of the currency
196 private static final int NUMERIC_CODE_SHIFT = 10;
197
198 // Currency data format version
199 private static final int VALID_FORMAT_VERSION = 3;
200
201 static {
202 AccessController.doPrivileged(new PrivilegedAction<>() {
203 @Override
204 public Void run() {
205 try (DataInputStream dis = new DataInputStream(
206 new BufferedInputStream(Files.newInputStream(Paths
207 .get(System.getProperty("java.home"),
208 "lib", "currency.data"))))) {
209 if (dis.readInt() != MAGIC_NUMBER) {
210 throw new InternalError("Currency data is possibly corrupted");
211 }
212 formatVersion = dis.readInt();
213 if (formatVersion != VALID_FORMAT_VERSION) {
214 throw new InternalError("Currency data format is incorrect");
215 }
216 dataVersion = dis.readInt();
217 mainTable = readIntArray(dis, A_TO_Z * A_TO_Z);
218 int scCount = dis.readInt();
219 specialCasesList = readSpecialCases(dis, scCount);
220 int ocCount = dis.readInt();
221 otherCurrenciesList = readOtherCurrencies(dis, ocCount);
222 } catch (IOException e) {
223 throw new InternalError(e);
224 }
225
226 // look for the properties file for overrides
227 String propsFile = System.getProperty("java.util.currency.data");
228 if (propsFile == null) {
229 propsFile = System.getProperty("java.home") + File.separator + "lib" +
230 File.separator + "currency.properties";
231 }
232 try {
233 File propFile = new File(propsFile);
234 if (propFile.exists()) {
235 Properties props = new Properties();
236 try (FileReader fr = new FileReader(propFile)) {
237 props.load(fr);
238 }
239 Set<String> keys = props.stringPropertyNames();
240 Pattern propertiesPattern =
241 Pattern.compile("([A-Z]{3})\\s*,\\s*(\\d{3})\\s*,\\s*" +
|