src/share/classes/java/text/DecimalFormat.java
Print this page
rev 5696 : 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 packaging changes. by Naoto Sato and Masayoshi Okutsu)
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -36,25 +36,26 @@
*
*/
package java.text;
-import java.io.InvalidObjectException;
import java.io.IOException;
+import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
+import java.text.spi.NumberFormatProvider;
import java.util.ArrayList;
import java.util.Currency;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
-import sun.util.resources.LocaleData;
+import sun.util.locale.provider.LocaleProviderAdapter;
/**
* <code>DecimalFormat</code> is a concrete subclass of
* <code>NumberFormat</code> that formats decimal numbers. It has a variety of
* features designed to make it possible to parse and format numbers in any
@@ -396,19 +397,26 @@
Locale def = Locale.getDefault(Locale.Category.FORMAT);
// try to get the pattern from the cache
String pattern = cachedLocaleData.get(def);
if (pattern == null) { /* cache miss */
// Get the pattern for the default locale.
- ResourceBundle rb = LocaleData.getNumberFormatData(def);
+ LocaleProviderAdapter adapter = LocaleProviderAdapter.getAdapter(NumberFormatProvider.class, def);
+ switch (adapter.getAdapterType()) {
+ case HOST:
+ case SPI:
+ adapter = LocaleProviderAdapter.getResourceBundleBased();
+ break;
+ }
+ ResourceBundle rb = adapter.getLocaleData().getNumberFormatData(def);
String[] all = rb.getStringArray("NumberPatterns");
pattern = all[0];
/* update cache */
cachedLocaleData.putIfAbsent(def, pattern);
}
// Always applyPattern after the symbols are set
- this.symbols = new DecimalFormatSymbols(def);
+ this.symbols = DecimalFormatSymbols.getInstance(def);
applyPattern(pattern, false);
}
/**
@@ -429,11 +437,11 @@
* @see java.text.NumberFormat#getCurrencyInstance
* @see java.text.NumberFormat#getPercentInstance
*/
public DecimalFormat(String pattern) {
// Always applyPattern after the symbols are set
- this.symbols = new DecimalFormatSymbols(Locale.getDefault(Locale.Category.FORMAT));
+ this.symbols = DecimalFormatSymbols.getInstance(Locale.getDefault(Locale.Category.FORMAT));
applyPattern(pattern, false);
}
/**
@@ -483,10 +491,11 @@
* <code>pos</code> is null
* @exception ArithmeticException if rounding is needed with rounding
* mode being set to RoundingMode.UNNECESSARY
* @see java.text.FieldPosition
*/
+ @Override
public final StringBuffer format(Object number,
StringBuffer toAppendTo,
FieldPosition pos) {
if (number instanceof Long || number instanceof Integer ||
number instanceof Short || number instanceof Byte ||
@@ -515,10 +524,11 @@
* @exception ArithmeticException if rounding is needed with rounding
* mode being set to RoundingMode.UNNECESSARY
* @return The formatted number string
* @see java.text.FieldPosition
*/
+ @Override
public StringBuffer format(double number, StringBuffer result,
FieldPosition fieldPosition) {
fieldPosition.setBeginIndex(0);
fieldPosition.setEndIndex(0);
@@ -616,10 +626,11 @@
* @exception ArithmeticException if rounding is needed with rounding
* mode being set to RoundingMode.UNNECESSARY
* @return The formatted number string
* @see java.text.FieldPosition
*/
+ @Override
public StringBuffer format(long number, StringBuffer result,
FieldPosition fieldPosition) {
fieldPosition.setBeginIndex(0);
fieldPosition.setEndIndex(0);
@@ -830,10 +841,11 @@
* mode being set to RoundingMode.UNNECESSARY
* @param obj The object to format
* @return AttributedCharacterIterator describing the formatted value.
* @since 1.4
*/
+ @Override
public AttributedCharacterIterator formatToCharacterIterator(Object obj) {
CharacterIteratorFieldDelegate delegate =
new CharacterIteratorFieldDelegate();
StringBuffer sb = new StringBuffer();
@@ -1255,10 +1267,11 @@
* index information as described above.
* @return the parsed value, or <code>null</code> if the parse fails
* @exception NullPointerException if <code>text</code> or
* <code>pos</code> is null.
*/
+ @Override
public Number parse(String text, ParsePosition pos) {
// special case NaN
if (text.regionMatches(pos.index, symbols.getNaN(), 0, symbols.getNaN().length())) {
pos.index = pos.index + symbols.getNaN().length();
return new Double(Double.NaN);
@@ -1888,10 +1901,11 @@
}
/**
* Standard override; no change in semantics.
*/
+ @Override
public Object clone() {
DecimalFormat other = (DecimalFormat) super.clone();
other.symbols = (DecimalFormatSymbols) symbols.clone();
other.digitList = (DigitList) digitList.clone();
return other;
@@ -1898,10 +1912,11 @@
}
/**
* Overrides equals
*/
+ @Override
public boolean equals(Object obj)
{
if (obj == null) return false;
if (!super.equals(obj)) return false; // super does class check
DecimalFormat other = (DecimalFormat) obj;
@@ -1937,10 +1952,11 @@
}
/**
* Overrides hashCode
*/
+ @Override
public int hashCode() {
return super.hashCode() * 37 + positivePrefix.hashCode();
// just enough fields for a reasonable distribution
}
@@ -2666,10 +2682,11 @@
* For formatting numbers other than <code>BigInteger</code> and
* <code>BigDecimal</code> objects, the lower of <code>newValue</code> and
* 309 is used. Negative input values are replaced with 0.
* @see NumberFormat#setMaximumIntegerDigits
*/
+ @Override
public void setMaximumIntegerDigits(int newValue) {
maximumIntegerDigits = Math.min(Math.max(0, newValue), MAXIMUM_INTEGER_DIGITS);
super.setMaximumIntegerDigits((maximumIntegerDigits > DOUBLE_INTEGER_DIGITS) ?
DOUBLE_INTEGER_DIGITS : maximumIntegerDigits);
if (minimumIntegerDigits > maximumIntegerDigits) {
@@ -2685,10 +2702,11 @@
* For formatting numbers other than <code>BigInteger</code> and
* <code>BigDecimal</code> objects, the lower of <code>newValue</code> and
* 309 is used. Negative input values are replaced with 0.
* @see NumberFormat#setMinimumIntegerDigits
*/
+ @Override
public void setMinimumIntegerDigits(int newValue) {
minimumIntegerDigits = Math.min(Math.max(0, newValue), MAXIMUM_INTEGER_DIGITS);
super.setMinimumIntegerDigits((minimumIntegerDigits > DOUBLE_INTEGER_DIGITS) ?
DOUBLE_INTEGER_DIGITS : minimumIntegerDigits);
if (minimumIntegerDigits > maximumIntegerDigits) {
@@ -2704,10 +2722,11 @@
* For formatting numbers other than <code>BigInteger</code> and
* <code>BigDecimal</code> objects, the lower of <code>newValue</code> and
* 340 is used. Negative input values are replaced with 0.
* @see NumberFormat#setMaximumFractionDigits
*/
+ @Override
public void setMaximumFractionDigits(int newValue) {
maximumFractionDigits = Math.min(Math.max(0, newValue), MAXIMUM_FRACTION_DIGITS);
super.setMaximumFractionDigits((maximumFractionDigits > DOUBLE_FRACTION_DIGITS) ?
DOUBLE_FRACTION_DIGITS : maximumFractionDigits);
if (minimumFractionDigits > maximumFractionDigits) {
@@ -2723,10 +2742,11 @@
* For formatting numbers other than <code>BigInteger</code> and
* <code>BigDecimal</code> objects, the lower of <code>newValue</code> and
* 340 is used. Negative input values are replaced with 0.
* @see NumberFormat#setMinimumFractionDigits
*/
+ @Override
public void setMinimumFractionDigits(int newValue) {
minimumFractionDigits = Math.min(Math.max(0, newValue), MAXIMUM_FRACTION_DIGITS);
super.setMinimumFractionDigits((minimumFractionDigits > DOUBLE_FRACTION_DIGITS) ?
DOUBLE_FRACTION_DIGITS : minimumFractionDigits);
if (minimumFractionDigits > maximumFractionDigits) {
@@ -2742,10 +2762,11 @@
* For formatting numbers other than <code>BigInteger</code> and
* <code>BigDecimal</code> objects, the lower of the return value and
* 309 is used.
* @see #setMaximumIntegerDigits
*/
+ @Override
public int getMaximumIntegerDigits() {
return maximumIntegerDigits;
}
/**
@@ -2754,10 +2775,11 @@
* For formatting numbers other than <code>BigInteger</code> and
* <code>BigDecimal</code> objects, the lower of the return value and
* 309 is used.
* @see #setMinimumIntegerDigits
*/
+ @Override
public int getMinimumIntegerDigits() {
return minimumIntegerDigits;
}
/**
@@ -2766,10 +2788,11 @@
* For formatting numbers other than <code>BigInteger</code> and
* <code>BigDecimal</code> objects, the lower of the return value and
* 340 is used.
* @see #setMaximumFractionDigits
*/
+ @Override
public int getMaximumFractionDigits() {
return maximumFractionDigits;
}
/**
@@ -2778,10 +2801,11 @@
* For formatting numbers other than <code>BigInteger</code> and
* <code>BigDecimal</code> objects, the lower of the return value and
* 340 is used.
* @see #setMinimumFractionDigits
*/
+ @Override
public int getMinimumFractionDigits() {
return minimumFractionDigits;
}
/**
@@ -2792,10 +2816,11 @@
* on this number format's symbols.
*
* @return the currency used by this decimal format, or <code>null</code>
* @since 1.4
*/
+ @Override
public Currency getCurrency() {
return symbols.getCurrency();
}
/**
@@ -2808,10 +2833,11 @@
*
* @param currency the new currency to be used by this decimal format
* @exception NullPointerException if <code>currency</code> is null
* @since 1.4
*/
+ @Override
public void setCurrency(Currency currency) {
if (currency != symbols.getCurrency()) {
symbols.setCurrency(currency);
if (isCurrencyFormat) {
expandAffixes();
@@ -2824,10 +2850,11 @@
*
* @return The <code>RoundingMode</code> used for this DecimalFormat.
* @see #setRoundingMode(RoundingMode)
* @since 1.6
*/
+ @Override
public RoundingMode getRoundingMode() {
return roundingMode;
}
/**
@@ -2836,10 +2863,11 @@
* @param roundingMode The <code>RoundingMode</code> to be used
* @see #getRoundingMode()
* @exception NullPointerException if <code>roundingMode</code> is null.
* @since 1.6
*/
+ @Override
public void setRoundingMode(RoundingMode roundingMode) {
if (roundingMode == null) {
throw new NullPointerException();
}
@@ -2846,39 +2874,10 @@
this.roundingMode = roundingMode;
digitList.setRoundingMode(roundingMode);
}
/**
- * Adjusts the minimum and maximum fraction digits to values that
- * are reasonable for the currency's default fraction digits.
- */
- void adjustForCurrencyDefaultFractionDigits() {
- Currency currency = symbols.getCurrency();
- if (currency == null) {
- try {
- currency = Currency.getInstance(symbols.getInternationalCurrencySymbol());
- } catch (IllegalArgumentException e) {
- }
- }
- if (currency != null) {
- int digits = currency.getDefaultFractionDigits();
- if (digits != -1) {
- int oldMinDigits = getMinimumFractionDigits();
- // Common patterns are "#.##", "#.00", "#".
- // Try to adjust all of them in a reasonable way.
- if (oldMinDigits == getMaximumFractionDigits()) {
- setMinimumFractionDigits(digits);
- setMaximumFractionDigits(digits);
- } else {
- setMinimumFractionDigits(Math.min(digits, oldMinDigits));
- setMaximumFractionDigits(digits);
- }
- }
- }
- }
-
- /**
* Reads the default serializable fields from the stream and performs
* validations and adjustments for older serialized versions. The
* validations and adjustments are:
* <ol>
* <li>
@@ -3268,7 +3267,7 @@
/**
* Cache to hold the NumberPattern of a Locale.
*/
private static final ConcurrentMap<Locale, String> cachedLocaleData
- = new ConcurrentHashMap<Locale, String>(3);
+ = new ConcurrentHashMap<>(3);
}