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); }