src/share/classes/java/text/DecimalFormatSymbols.java
Print this page
rev 5615 : 6336885: RFE: Locale Data Deployment Enhancements
4609153: Provide locale data for Indic locales
5104387: Support for gl_ES locale (galician language)
6337471: desktop/system locale preferences support
7056139: (cal) SPI support for locale-dependent Calendar parameters
7058206: Provide CalendarData SPI for week params and display field value names
7073852: Support multiple scripts for digits and decimal symbols per locale
7079560: [Fmt-Da] Context dependent month names support in SimpleDateFormat
7171324: getAvailableLocales() of locale sensitive services should return the actual availability of locales
7151414: (cal) Support calendar type identification
7168528: LocaleServiceProvider needs to be aware of Locale extensions
7171372: (cal) locale's default Calendar should be created if unknown calendar is specified
Summary: JEP 127: Improve Locale Data Packaging and Adopt Unicode CLDR Data (part 1 w/o Jigsaw. by Naoto Sato and Masayoshi Okutsu)
*** 1,7 ****
/*
! * Copyright (c) 1996, 2010, 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. Oracle designates this
--- 1,7 ----
/*
! * Copyright (c) 1996, 2012, 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. Oracle designates this
*** 42,56 ****
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.text.spi.DecimalFormatSymbolsProvider;
import java.util.Currency;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.concurrent.ConcurrentHashMap;
! import sun.util.LocaleServiceProviderPool;
! import sun.util.resources.LocaleData;
/**
* This class represents the set of symbols (such as the decimal separator,
* the grouping separator, and so on) needed by <code>DecimalFormat</code>
* to format numbers. <code>DecimalFormat</code> creates for itself an instance of
--- 42,58 ----
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.text.spi.DecimalFormatSymbolsProvider;
import java.util.Currency;
import java.util.Locale;
+ import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.concurrent.ConcurrentHashMap;
+ import java.util.concurrent.ConcurrentMap;
! import sun.util.locale.provider.LocaleProviderAdapter;
! import sun.util.locale.provider.LocaleServiceProviderPool;
/**
* This class represents the set of symbols (such as the decimal separator,
* the grouping separator, and so on) needed by <code>DecimalFormat</code>
* to format numbers. <code>DecimalFormat</code> creates for itself an instance of
*** 85,94 ****
--- 87,104 ----
* supported by the Java runtime environment, not for those
* supported by installed
* {@link java.text.spi.DecimalFormatSymbolsProvider DecimalFormatSymbolsProvider}
* implementations. For full locale coverage, use the
* {@link #getInstance(Locale) getInstance} method.
+ * If the specified locale contains the {@link java.util.Locale#UNICODE_LOCALE_EXTENSION}
+ * for the numbering system, the instance is initialized with the specified numbering
+ * system if the JRE implementation supports it. For example,
+ * <pre>
+ * NumberFormat.getNumberInstance(Locale.forLanguageTag("th-TH-u-nu-thai"))
+ * </pre>
+ * This may return a {@code NumberFormat} instance with the Thai numbering system,
+ * instead of the Latin numbering system.
*
* @exception NullPointerException if <code>locale</code> is null
*/
public DecimalFormatSymbols( Locale locale ) {
initialize( locale );
*** 133,164 ****
* locale. This method provides access to <code>DecimalFormatSymbols</code>
* instances for locales supported by the Java runtime itself as well
* as for those supported by installed
* {@link java.text.spi.DecimalFormatSymbolsProvider
* DecimalFormatSymbolsProvider} implementations.
* @param locale the desired locale.
* @return a <code>DecimalFormatSymbols</code> instance.
* @exception NullPointerException if <code>locale</code> is null
* @since 1.6
*/
public static final DecimalFormatSymbols getInstance(Locale locale) {
!
! // Check whether a provider can provide an implementation that's closer
! // to the requested locale than what the Java runtime itself can provide.
! LocaleServiceProviderPool pool =
! LocaleServiceProviderPool.getPool(DecimalFormatSymbolsProvider.class);
! if (pool.hasProviders()) {
! DecimalFormatSymbols providersInstance = pool.getLocalizedObject(
! DecimalFormatSymbolsGetter.INSTANCE, locale);
! if (providersInstance != null) {
! return providersInstance;
}
- }
- return new DecimalFormatSymbols(locale);
- }
-
/**
* Gets the character used for zero. Different for Arabic, etc.
*/
public char getZeroDigit() {
return zeroDigit;
--- 143,171 ----
* locale. This method provides access to <code>DecimalFormatSymbols</code>
* instances for locales supported by the Java runtime itself as well
* as for those supported by installed
* {@link java.text.spi.DecimalFormatSymbolsProvider
* DecimalFormatSymbolsProvider} implementations.
+ * If the specified locale contains the {@link java.util.Locale#UNICODE_LOCALE_EXTENSION}
+ * for the numbering system, the instance is initialized with the specified numbering
+ * system if the JRE implementation supports it. For example,
+ * <pre>
+ * NumberFormat.getNumberInstance(Locale.forLanguageTag("th-TH-u-nu-thai"))
+ * </pre>
+ * This may return a {@code NumberFormat} instance with the Thai numbering system,
+ * instead of the Latin numbering system.
* @param locale the desired locale.
* @return a <code>DecimalFormatSymbols</code> instance.
* @exception NullPointerException if <code>locale</code> is null
* @since 1.6
*/
public static final DecimalFormatSymbols getInstance(Locale locale) {
! LocaleProviderAdapter adapter = LocaleProviderAdapter.getAdapter(DecimalFormatSymbolsProvider.class, locale);
! DecimalFormatSymbolsProvider provider = adapter.getLocaleServiceProvider(DecimalFormatSymbolsProvider.class);
! return provider.getInstance(locale);
}
/**
* Gets the character used for zero. Different for Arabic, etc.
*/
public char getZeroDigit() {
return zeroDigit;
*** 472,481 ****
--- 479,489 ----
//------------------------------------------------------------
/**
* Standard override.
*/
+ @Override
public Object clone() {
try {
return (DecimalFormatSymbols)super.clone();
// other fields are bit-copied
} catch (CloneNotSupportedException e) {
*** 484,493 ****
--- 492,502 ----
}
/**
* Override equals.
*/
+ @Override
public boolean equals(Object obj) {
if (obj == null) return false;
if (this == obj) return true;
if (getClass() != obj.getClass()) return false;
DecimalFormatSymbols other = (DecimalFormatSymbols) obj;
*** 510,519 ****
--- 519,529 ----
}
/**
* Override hashCode.
*/
+ @Override
public int hashCode() {
int result = zeroDigit;
result = result * 37 + groupingSeparator;
result = result * 37 + decimalSeparator;
return result;
*** 527,546 ****
// get resource bundle data - try the cache first
boolean needCacheUpdate = false;
Object[] data = cachedLocaleData.get(locale);
if (data == null) { /* cache miss */
! // When numbering system is thai (Locale's extension contains u-nu-thai),
! // we read the data from th_TH_TH.
! Locale lookupLocale = locale;
! String numberType = locale.getUnicodeLocaleType("nu");
! if (numberType != null && numberType.equals("thai")) {
! lookupLocale = new Locale("th", "TH", "TH");
}
data = new Object[3];
! ResourceBundle rb = LocaleData.getNumberFormatData(lookupLocale);
data[0] = rb.getStringArray("NumberElements");
needCacheUpdate = true;
}
String[] numberElements = (String[]) data[0];
--- 537,570 ----
// get resource bundle data - try the cache first
boolean needCacheUpdate = false;
Object[] data = cachedLocaleData.get(locale);
if (data == null) { /* cache miss */
! LocaleProviderAdapter adapter = LocaleProviderAdapter.getAdapter(DecimalFormatSymbolsProvider.class, locale);
! // Avoid potential recursions
! switch (adapter.getAdapterType()) {
! case HOST:
! case SPI:
! adapter = LocaleProviderAdapter.getResourceBundleBased();
! break;
}
+ ResourceBundle rb = adapter.getLocaleData().getNumberFormatData(locale);
data = new Object[3];
! String numberType = locale.getUnicodeLocaleType("nu");
! StringBuilder numElemKey =
! new StringBuilder(numberType != null ?
! numberType : rb.getString("DefaultNumberingSystem"));
! if (numElemKey.length() != 0) {
! numElemKey.append(".");
! }
! numElemKey.append("NumberElements");
! try {
! data[0] = rb.getStringArray(numElemKey.toString());
! } catch (MissingResourceException mre) {
! // numberType must be bogus. Use the last resort numbering system.
data[0] = rb.getStringArray("NumberElements");
+ }
needCacheUpdate = true;
}
String[] numberElements = (String[]) data[0];
*** 559,569 ****
// Try to obtain the currency used in the locale's country.
// Check for empty country string separately because it's a valid
// country ID for Locale (and used for the C locale), but not a valid
// ISO 3166 country code, and exceptions are expensive.
! if (!"".equals(locale.getCountry())) {
try {
currency = Currency.getInstance(locale);
} catch (IllegalArgumentException e) {
// use default values below for compatibility
}
--- 583,593 ----
// Try to obtain the currency used in the locale's country.
// Check for empty country string separately because it's a valid
// country ID for Locale (and used for the C locale), but not a valid
// ISO 3166 country code, and exceptions are expensive.
! if (locale.getCountry().length() > 0) {
try {
currency = Currency.getInstance(locale);
} catch (IllegalArgumentException e) {
// use default values below for compatibility
}
*** 811,837 ****
/**
* cache to hold the NumberElements and the Currency
* of a Locale.
*/
! private static final ConcurrentHashMap<Locale, Object[]> cachedLocaleData = new ConcurrentHashMap<Locale, Object[]>(3);
!
! /**
! * Obtains a DecimalFormatSymbols instance from a DecimalFormatSymbolsProvider
! * implementation.
! */
! private static class DecimalFormatSymbolsGetter
! implements LocaleServiceProviderPool.LocalizedObjectGetter<DecimalFormatSymbolsProvider,
! DecimalFormatSymbols> {
! private static final DecimalFormatSymbolsGetter INSTANCE =
! new DecimalFormatSymbolsGetter();
!
! public DecimalFormatSymbols getObject(
! DecimalFormatSymbolsProvider decimalFormatSymbolsProvider,
! Locale locale,
! String key,
! Object... params) {
! assert params.length == 0;
! return decimalFormatSymbolsProvider.getInstance(locale);
! }
! }
}
--- 835,841 ----
/**
* cache to hold the NumberElements and the Currency
* of a Locale.
*/
! private static final ConcurrentMap<Locale, Object[]> cachedLocaleData = new ConcurrentHashMap<>(3);
}