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
56 * no public constructor. You obtain a <code>Currency</code> instance using
57 * the <code>getInstance</code> methods.
58 * <p>
59 * Users can supersede the Java runtime currency data by means of the system
60 * property {@code java.util.currency.data}. If this system property is
61 * defined then its value is the location of a properties file, the contents of
62 * which are key/value pairs of the ISO 3166 country codes and the ISO 4217
63 * currency data respectively. The value part consists of three ISO 4217 values
64 * of a currency, i.e., an alphabetic code, a numeric code, and a minor unit.
331 defaultFractionDigits = ocEntry.fraction;
332 numericCode = ocEntry.numericCode;
333 }
334 }
335
336 Currency currencyVal =
337 new Currency(currencyCode, defaultFractionDigits, numericCode);
338 instance = instances.putIfAbsent(currencyCode, currencyVal);
339 return (instance != null ? instance : currencyVal);
340 }
341
342 /**
343 * Returns the <code>Currency</code> instance for the country of the
344 * given locale. The language and variant components of the locale
345 * are ignored. The result may vary over time, as countries change their
346 * currencies. For example, for the original member countries of the
347 * European Monetary Union, the method returns the old national currencies
348 * until December 31, 2001, and the Euro from January 1, 2002, local time
349 * of the respective countries.
350 * <p>
351 * The method returns <code>null</code> for territories that don't
352 * have a currency, such as Antarctica.
353 *
354 * @param locale the locale for whose country a <code>Currency</code>
355 * instance is needed
356 * @return the <code>Currency</code> instance for the country of the given
357 * locale, or {@code null}
358 * @exception NullPointerException if <code>locale</code>
359 * is {@code null}
360 * @exception IllegalArgumentException if the country of the given {@code locale}
361 * is not a supported ISO 3166 country code.
362 */
363 public static Currency getInstance(Locale locale) {
364 String country = locale.getCountry();
365 if (country == null) {
366 throw new NullPointerException();
367 }
368
369 if (country.length() != 2) {
370 throw new IllegalArgumentException();
371 }
372
373 char char1 = country.charAt(0);
374 char char2 = country.charAt(1);
375 int tableEntry = getMainTableEntry(char1, char2);
376 if ((tableEntry & COUNTRY_TYPE_MASK) == SIMPLE_CASE_COUNTRY_MASK
377 && tableEntry != INVALID_COUNTRY_ENTRY) {
378 char finalChar = (char) ((tableEntry & SIMPLE_CASE_COUNTRY_FINAL_CHAR_MASK) + 'A');
379 int defaultFractionDigits = (tableEntry & SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_MASK) >> SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_SHIFT;
380 int numericCode = (tableEntry & NUMERIC_CODE_MASK) >> NUMERIC_CODE_SHIFT;
381 StringBuilder sb = new StringBuilder(country);
382 sb.append(finalChar);
383 return getInstance(sb.toString(), defaultFractionDigits, numericCode);
384 } else {
385 // special cases
386 if (tableEntry == INVALID_COUNTRY_ENTRY) {
387 throw new IllegalArgumentException();
388 }
389 if (tableEntry == COUNTRY_WITHOUT_CURRENCY_ENTRY) {
465 Set<Currency> result = (Set<Currency>) available.clone();
466 return result;
467 }
468
469 /**
470 * Gets the ISO 4217 currency code of this currency.
471 *
472 * @return the ISO 4217 currency code of this currency.
473 */
474 public String getCurrencyCode() {
475 return currencyCode;
476 }
477
478 /**
479 * Gets the symbol of this currency for the default
480 * {@link Locale.Category#DISPLAY DISPLAY} locale.
481 * For example, for the US Dollar, the symbol is "$" if the default
482 * locale is the US, while for other locales it may be "US$". If no
483 * symbol can be determined, the ISO 4217 currency code is returned.
484 * <p>
485 * This is equivalent to calling
486 * {@link #getSymbol(Locale)
487 * getSymbol(Locale.getDefault(Locale.Category.DISPLAY))}.
488 *
489 * @return the symbol of this currency for the default
490 * {@link Locale.Category#DISPLAY DISPLAY} locale
491 */
492 public String getSymbol() {
493 return getSymbol(Locale.getDefault(Locale.Category.DISPLAY));
494 }
495
496 /**
497 * Gets the symbol of this currency for the specified locale.
498 * For example, for the US Dollar, the symbol is "$" if the specified
499 * locale is the US, while for other locales it may be "US$". If no
500 * symbol can be determined, the ISO 4217 currency code is returned.
501 *
502 * @param locale the locale for which a display name for this currency is
503 * needed
504 * @return the symbol of this currency for the specified locale
505 * @exception NullPointerException if <code>locale</code> is null
506 */
507 public String getSymbol(Locale locale) {
508 LocaleServiceProviderPool pool =
509 LocaleServiceProviderPool.getPool(CurrencyNameProvider.class);
510 String symbol = pool.getLocalizedObject(
511 CurrencyNameGetter.INSTANCE,
512 locale, currencyCode, SYMBOL);
513 if (symbol != null) {
514 return symbol;
515 }
516
517 // use currency code as symbol of last resort
518 return currencyCode;
519 }
520
521 /**
522 * Gets the default number of fraction digits used with this currency.
523 * Note that the number of fraction digits is the same as ISO 4217's
524 * minor unit for the currency.
525 * For example, the default number of fraction digits for the Euro is 2,
526 * while for the Japanese Yen it's 0.
527 * In the case of pseudo-currencies, such as IMF Special Drawing Rights,
528 * -1 is returned.
529 *
|
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.FileReader;
32 import java.io.InputStream;
33 import java.io.IOException;
34 import java.io.Serializable;
35 import java.security.AccessController;
36 import java.security.PrivilegedAction;
37 import java.text.ParseException;
38 import java.text.SimpleDateFormat;
39 import java.util.concurrent.ConcurrentHashMap;
40 import java.util.concurrent.ConcurrentMap;
41 import java.util.regex.Pattern;
42 import java.util.regex.Matcher;
43 import java.util.spi.CurrencyNameProvider;
44 import sun.util.locale.provider.CalendarDataUtility;
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
56 * no public constructor. You obtain a <code>Currency</code> instance using
57 * the <code>getInstance</code> methods.
58 * <p>
59 * Users can supersede the Java runtime currency data by means of the system
60 * property {@code java.util.currency.data}. If this system property is
61 * defined then its value is the location of a properties file, the contents of
62 * which are key/value pairs of the ISO 3166 country codes and the ISO 4217
63 * currency data respectively. The value part consists of three ISO 4217 values
64 * of a currency, i.e., an alphabetic code, a numeric code, and a minor unit.
331 defaultFractionDigits = ocEntry.fraction;
332 numericCode = ocEntry.numericCode;
333 }
334 }
335
336 Currency currencyVal =
337 new Currency(currencyCode, defaultFractionDigits, numericCode);
338 instance = instances.putIfAbsent(currencyCode, currencyVal);
339 return (instance != null ? instance : currencyVal);
340 }
341
342 /**
343 * Returns the <code>Currency</code> instance for the country of the
344 * given locale. The language and variant components of the locale
345 * are ignored. The result may vary over time, as countries change their
346 * currencies. For example, for the original member countries of the
347 * European Monetary Union, the method returns the old national currencies
348 * until December 31, 2001, and the Euro from January 1, 2002, local time
349 * of the respective countries.
350 * <p>
351 * If the specified <code>locale</code> contains "cu" and/or "rg"
352 * <a href="./Locale.html#def_locale_extension">Unicode extensions</a>,
353 * the instance returned from this method reflects
354 * the values specified with those extensions. If both "cu" and "rg" are
355 * specified, the currency from "cu" extension supersedes the implicit one
356 * from "rg" extension.
357 * <p>
358 * The method returns <code>null</code> for territories that don't
359 * have a currency, such as Antarctica.
360 *
361 * @param locale the locale for whose country a <code>Currency</code>
362 * instance is needed
363 * @return the <code>Currency</code> instance for the country of the given
364 * locale, or {@code null}
365 * @exception NullPointerException if <code>locale</code>
366 * is {@code null}
367 * @exception IllegalArgumentException if the country of the given {@code locale}
368 * is not a supported ISO 3166 country code.
369 */
370 public static Currency getInstance(Locale locale) {
371 // check for locale overrides
372 String override = locale.getUnicodeLocaleType("cu");
373 if (override != null) {
374 try {
375 return getInstance(override.toUpperCase(Locale.ROOT));
376 } catch (IllegalArgumentException iae) {
377 // override currency is invalid. Fall through.
378 }
379 }
380
381 String country = CalendarDataUtility.findRegionOverride(locale).orElse(locale).getCountry();
382
383 if (country == null || !country.matches("^[a-zA-Z]{2}$")) {
384 throw new IllegalArgumentException();
385 }
386
387 char char1 = country.charAt(0);
388 char char2 = country.charAt(1);
389 int tableEntry = getMainTableEntry(char1, char2);
390 if ((tableEntry & COUNTRY_TYPE_MASK) == SIMPLE_CASE_COUNTRY_MASK
391 && tableEntry != INVALID_COUNTRY_ENTRY) {
392 char finalChar = (char) ((tableEntry & SIMPLE_CASE_COUNTRY_FINAL_CHAR_MASK) + 'A');
393 int defaultFractionDigits = (tableEntry & SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_MASK) >> SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_SHIFT;
394 int numericCode = (tableEntry & NUMERIC_CODE_MASK) >> NUMERIC_CODE_SHIFT;
395 StringBuilder sb = new StringBuilder(country);
396 sb.append(finalChar);
397 return getInstance(sb.toString(), defaultFractionDigits, numericCode);
398 } else {
399 // special cases
400 if (tableEntry == INVALID_COUNTRY_ENTRY) {
401 throw new IllegalArgumentException();
402 }
403 if (tableEntry == COUNTRY_WITHOUT_CURRENCY_ENTRY) {
479 Set<Currency> result = (Set<Currency>) available.clone();
480 return result;
481 }
482
483 /**
484 * Gets the ISO 4217 currency code of this currency.
485 *
486 * @return the ISO 4217 currency code of this currency.
487 */
488 public String getCurrencyCode() {
489 return currencyCode;
490 }
491
492 /**
493 * Gets the symbol of this currency for the default
494 * {@link Locale.Category#DISPLAY DISPLAY} locale.
495 * For example, for the US Dollar, the symbol is "$" if the default
496 * locale is the US, while for other locales it may be "US$". If no
497 * symbol can be determined, the ISO 4217 currency code is returned.
498 * <p>
499 * If the default {@link Locale.Category#DISPLAY DISPLAY} locale
500 * contains "rg" (region override)
501 * <a href="./Locale.html#def_locale_extension">Unicode extension</a>,
502 * the symbol returned from this method reflects
503 * the value specified with that extension.
504 * <p>
505 * This is equivalent to calling
506 * {@link #getSymbol(Locale)
507 * getSymbol(Locale.getDefault(Locale.Category.DISPLAY))}.
508 *
509 * @return the symbol of this currency for the default
510 * {@link Locale.Category#DISPLAY DISPLAY} locale
511 */
512 public String getSymbol() {
513 return getSymbol(Locale.getDefault(Locale.Category.DISPLAY));
514 }
515
516 /**
517 * Gets the symbol of this currency for the specified locale.
518 * For example, for the US Dollar, the symbol is "$" if the specified
519 * locale is the US, while for other locales it may be "US$". If no
520 * symbol can be determined, the ISO 4217 currency code is returned.
521 * <p>
522 * If the specified <code>locale</code> contains "rg" (region override)
523 * <a href="./Locale.html#def_locale_extension">Unicode extension</a>,
524 * the symbol returned from this method reflects
525 * the value specified with that extension.
526 *
527 * @param locale the locale for which a display name for this currency is
528 * needed
529 * @return the symbol of this currency for the specified locale
530 * @exception NullPointerException if <code>locale</code> is null
531 */
532 public String getSymbol(Locale locale) {
533 LocaleServiceProviderPool pool =
534 LocaleServiceProviderPool.getPool(CurrencyNameProvider.class);
535 locale = CalendarDataUtility.findRegionOverride(locale).orElse(locale);
536 String symbol = pool.getLocalizedObject(
537 CurrencyNameGetter.INSTANCE,
538 locale, currencyCode, SYMBOL);
539 if (symbol != null) {
540 return symbol;
541 }
542
543 // use currency code as symbol of last resort
544 return currencyCode;
545 }
546
547 /**
548 * Gets the default number of fraction digits used with this currency.
549 * Note that the number of fraction digits is the same as ISO 4217's
550 * minor unit for the currency.
551 * For example, the default number of fraction digits for the Euro is 2,
552 * while for the Japanese Yen it's 0.
553 * In the case of pseudo-currencies, such as IMF Special Drawing Rights,
554 * -1 is returned.
555 *
|