ICU-6433 currency plural format merged to trunk

X-SVN-Rev: 25254
This commit is contained in:
Xiaomei Ji 2009-01-15 01:10:02 +00:00
parent 084842e74a
commit 3ec5b5cb90
7 changed files with 697 additions and 251 deletions

1
.gitattributes vendored
View File

@ -354,6 +354,7 @@ icu4j/src/com/ibm/icu/dev/tool/docs/icu4j400.api.gz -text
icu4j/src/com/ibm/icu/dev/tool/docs/icu4j401.api.gz -text
icu4j/src/com/ibm/icu/dev/tool/tzu/icu.gif -text
icu4j/src/com/ibm/icu/impl/data/icudata.jar -text
icu4j/src/com/ibm/icu/text/CurrencyPluralInfo.java -text
icu4j/src/com/ibm/richtext/textapps/resources/unicode.arabic.red -text
icu4j/src/com/ibm/richtext/textapps/resources/unicode.hebrew.red -text
tools/release/java/icu4c.css -text

View File

@ -1,7 +1,7 @@
//##header J2SE15
/*
*******************************************************************************
* Copyright (C) 2001-2008, International Business Machines Corporation and *
* Copyright (C) 2001-2009, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
@ -256,23 +256,24 @@ public class NumberFormatTest extends com.ibm.icu.dev.test.TestFmwk {
NumberFormat foo = NumberFormat.getCurrencyInstance();
for (int i = 0; i < DATA.length; ++i) {
ParsePosition parsePosition = new ParsePosition(0);
Number result = foo.parse(DATA[i][0], parsePosition);
if (parsePosition.getIndex() !=
new Integer(DATA[i][1]).intValue() ||
parsePosition.getErrorIndex() !=
new Integer(DATA[i][2]).intValue()) {
errln("FAILED parse " + DATA[i][0]);
String stringToBeParsed = DATA[i][0];
int parsedPosition = Integer.parseInt(DATA[i][1]);
int errorIndex = Integer.parseInt(DATA[i][2]);
Number result = foo.parse(stringToBeParsed, parsePosition);
if (parsePosition.getIndex() != parsedPosition ||
parsePosition.getErrorIndex() != errorIndex) {
errln("FAILED parse " + stringToBeParsed);
}
if (parsePosition.getErrorIndex() == -1 &&
result.doubleValue() != 124) {
errln("FAILED parse " + DATA[i][0]);
errln("FAILED parse " + stringToBeParsed);
}
}
}
public void TestMultiCurrencySign() {
Object[][] DATA = {
String[][] DATA = {
// the fields in the following test are:
// locale,
// currency pattern (with negative pattern),
@ -281,13 +282,13 @@ public class NumberFormatTest extends com.ibm.icu.dev.test.TestFmwk {
// currency format using currency ISO name, such as "USD",
// currency format using plural name, such as "US dollars".
// for US locale
{Locale.US, "\u00A4#,##0.00;-\u00A4#,##0.00", "1234.56", "$1,234.56", "USD1,234.56", "US dollars1,234.56"},
{Locale.US, "\u00A4#,##0.00;-\u00A4#,##0.00", "-1234.56", "-$1,234.56", "-USD1,234.56", "-US dollars1,234.56"},
{Locale.US, "\u00A4#,##0.00;-\u00A4#,##0.00", "1", "$1.00", "USD1.00", "US dollar1.00"},
{"en_US", "\u00A4#,##0.00;-\u00A4#,##0.00", "1234.56", "$1,234.56", "USD1,234.56", "US dollars1,234.56"},
{"en_US", "\u00A4#,##0.00;-\u00A4#,##0.00", "-1234.56", "-$1,234.56", "-USD1,234.56", "-US dollars1,234.56"},
{"en_US", "\u00A4#,##0.00;-\u00A4#,##0.00", "1", "$1.00", "USD1.00", "US dollar1.00"},
// for CHINA locale
{Locale.CHINA, "\u00A4#,##0.00;(\u00A4#,##0.00)", "1234.56", "\uFFE51,234.56", "CNY1,234.56", "\u4EBA\u6C11\u5E011,234.56"},
{Locale.CHINA, "\u00A4#,##0.00;(\u00A4#,##0.00)", "-1234.56", "(\uFFE51,234.56)", "(CNY1,234.56)", "(\u4EBA\u6C11\u5E011,234.56)"},
{Locale.CHINA, "\u00A4#,##0.00;(\u00A4#,##0.00)", "1", "\uFFE51.00", "CNY1.00", "\u4EBA\u6C11\u5E011.00"}
{"zh_CN", "\u00A4#,##0.00;(\u00A4#,##0.00)", "1234.56", "\uFFE51,234.56", "CNY1,234.56", "\u4EBA\u6C11\u5E011,234.56"},
{"zh_CN", "\u00A4#,##0.00;(\u00A4#,##0.00)", "-1234.56", "(\uFFE51,234.56)", "(CNY1,234.56)", "(\u4EBA\u6C11\u5E011,234.56)"},
{"zh_CN", "\u00A4#,##0.00;(\u00A4#,##0.00)", "1", "\uFFE51.00", "CNY1.00", "\u4EBA\u6C11\u5E011.00"}
};
char[] doubleCurrencySign = {0xA4, 0xA4};
@ -296,25 +297,44 @@ public class NumberFormatTest extends com.ibm.icu.dev.test.TestFmwk {
String tripleCurrencyStr = new String(tripleCurrencySign);
for (int i=0; i<DATA.length; ++i) {
// Locale.US
DecimalFormatSymbols sym = new DecimalFormatSymbols((Locale)DATA[i][0]);
String pat = Utility.unescape((String)DATA[i][1]);
String locale = DATA[i][0];
String pat = Utility.unescape(DATA[i][1]);
Double numberToBeFormat = new Double(DATA[i][2]);
DecimalFormatSymbols sym = new DecimalFormatSymbols(new Locale(locale));
for (int j=1; j<=3; ++j) {
// j represents the number of currency sign in the pattern.
if (j == 2) {
pat = pat.replaceAll("\\xA4", doubleCurrencyStr);
} else if (j == 3) {
pat = pat.replaceAll("\\xA4\\xA4", tripleCurrencyStr);
}
DecimalFormat fmt = new DecimalFormat(pat, sym);
String s = ((NumberFormat) fmt).format(new Double((String)DATA[i][2]));
if (!s.equals((String)DATA[i][2+j])) {
errln("FAIL format: Expected " + (String)DATA[i][2+j]);
String s = ((NumberFormat) fmt).format(numberToBeFormat);
// DATA[i][3] is the currency format result using a
// single currency sign.
// DATA[i][4] is the currency format result using
// double currency sign.
// DATA[i][5] is the currency format result using
// triple currency sign.
// DATA[i][j+2] is the currency format result using
// 'j' number of currency sign.
String currencyFormatResult = DATA[i][2+j];
if (!s.equals(currencyFormatResult)) {
errln("FAIL format: Expected " + currencyFormatResult);
}
try {
// mix style parsing
for (int k=3; k<=5; ++k) {
if (fmt.parse((String)DATA[i][k]).doubleValue() !=
(new Double((String)DATA[i][2])).doubleValue()) {
errln("FAILED parse " + DATA[i][k]);
// DATA[i][3] is the currency format result using a
// single currency sign.
// DATA[i][4] is the currency format result using
// double currency sign.
// DATA[i][5] is the currency format result using
// triple currency sign.
String oneCurrencyFormat = DATA[i][k];
if (fmt.parse(oneCurrencyFormat).doubleValue() !=
numberToBeFormat.doubleValue()) {
errln("FAILED parse " + oneCurrencyFormat);
}
}
} catch (ParseException e) {
@ -327,14 +347,15 @@ public class NumberFormatTest extends com.ibm.icu.dev.test.TestFmwk {
public void TestCurrencyFormatForMixParsing() {
MeasureFormat curFmt = MeasureFormat.getCurrencyFormat(new ULocale("en_US"));
String[] formats = {
"$1,234.56",
"$1,234.56", // string to be parsed
"USD1,234.56",
"US dollars1,234.56",
"1,234.56 US dollars"
};
try {
for (int i = 0; i < formats.length; ++i) {
CurrencyAmount parsedVal = (CurrencyAmount)curFmt.parseObject(formats[i]);
String stringToBeParsed = formats[i];
CurrencyAmount parsedVal = (CurrencyAmount)curFmt.parseObject(stringToBeParsed);
Number val = parsedVal.getNumber();
if (!val.equals(new BigDecimal("1234.56"))) {
errln("FAIL: getCurrencyFormat of default locale (en_US) failed roundtripping the number. val=" + val);
@ -356,19 +377,23 @@ public class NumberFormatTest extends com.ibm.icu.dev.test.TestFmwk {
// "\xA4#,##0.00;-\xA4#,##0.00"
pat.append(currency).append(currency).append(currency).append("#,##0.00;-").append(currency).append(currency).append(currency).append("#,##0.00");
DecimalFormat fmt = new DecimalFormat(pat.toString(), sym);
String[] DATA = {
"$1.00", "1",
"USD1.00", "1",
"1.00 US dollar", "1",
"$1,234.56", "1234.56",
"USD1,234.56", "1234.56",
"1,234.56 US dollar", "1234.56",
String[][] DATA = {
// the data are:
// string to be parsed, the parsed result (number)
{"$1.00", "1"},
{"USD1.00", "1"},
{"1.00 US dollar", "1"},
{"$1,234.56", "1234.56"},
{"USD1,234.56", "1234.56"},
{"1,234.56 US dollar", "1234.56"},
};
try {
for (int i = 0; i < DATA.length; i +=2) {
Number num = fmt.parse(DATA[i]);
if (num.doubleValue() != (new Double(DATA[i+1])).doubleValue()){
errln("FAIL parse: Expected " + DATA[i+1]);
for (int i = 0; i < DATA.length; ++i) {
String stringToBeParsed = DATA[i][0];
double parsedResult = Double.parseDouble(DATA[i][1]);
Number num = fmt.parse(stringToBeParsed);
if (num.doubleValue() != parsedResult) {
errln("FAIL parse: Expected " + parsedResult);
}
}
} catch (ParseException e) {
@ -442,50 +467,72 @@ public class NumberFormatTest extends com.ibm.icu.dev.test.TestFmwk {
}
public void TestCurrencyIsoPluralFormat() {
String[] DATA = {
"en_US", "1", "USD", "$1.00", "USD1.00", "1.00 US dollar",
"en_US", "1234.56", "USD", "$1,234.56", "USD1,234.56", "1,234.56 US dollars",
"en_US", "-1234.56", "USD", "($1,234.56)", "(USD1,234.56)", "-1,234.56 US dollars",
"zh_CN", "1", "USD", "US$1.00", "USD1.00", "1.00 \u7F8E\u5143",
"zh_CN", "1234.56", "USD", "US$1,234.56", "USD1,234.56", "1,234.56 \u7F8E\u5143",
"zh_CN", "1", "CHY", "CHY1.00", "CHY1.00", "1.00 CHY",
"zh_CN", "1234.56", "CHY", "CHY1,234.56", "CHY1,234.56", "1,234.56 CHY",
"zh_CN", "1", "CNY", "\uFFE51.00", "CNY1.00", "1.00 \u4EBA\u6C11\u5E01",
"zh_CN", "1234.56", "CNY", "\uFFE51,234.56", "CNY1,234.56", "1,234.56 \u4EBA\u6C11\u5E01",
"ru_RU", "1", "RUB", "1,00\u00A0\u0440\u0443\u0431.", "1,00\u00A0RUB", "1,00 \u0420\u043E\u0441\u0441\u0438\u0439\u0441\u043A\u0438\u0439 \u0440\u0443\u0431\u043B\u044C",
"ru_RU", "2", "RUB", "2,00\u00A0\u0440\u0443\u0431.", "2,00\u00A0RUB", "2,00 \u0420\u043E\u0441\u0441\u0438\u0439\u0441\u043A\u0438\u0445 \u0440\u0443\u0431\u043B\u044F",
"ru_RU", "5", "RUB", "5,00\u00A0\u0440\u0443\u0431.", "5,00\u00A0RUB", "5,00 \u0420\u043E\u0441\u0441\u0438\u0439\u0441\u043A\u0438\u0445 \u0440\u0443\u0431\u043B\u0435\u0439",
String[][] DATA = {
// the data are:
// locale,
// currency amount to be formatted,
// currency ISO code to be formatted,
// format result using CURRENCYSTYLE,
// format result using ISOCURRENCYSTYLE,
// format result using PLURALCURRENCYSTYLE,
{"en_US", "1", "USD", "$1.00", "USD1.00", "1.00 US dollar"},
{"en_US", "1234.56", "USD", "$1,234.56", "USD1,234.56", "1,234.56 US dollars"},
{"en_US", "-1234.56", "USD", "($1,234.56)", "(USD1,234.56)", "-1,234.56 US dollars"},
{"zh_CN", "1", "USD", "US$1.00", "USD1.00", "1.00 \u7F8E\u5143"},
{"zh_CN", "1234.56", "USD", "US$1,234.56", "USD1,234.56", "1,234.56 \u7F8E\u5143"},
{"zh_CN", "1", "CHY", "CHY1.00", "CHY1.00", "1.00 CHY"},
{"zh_CN", "1234.56", "CHY", "CHY1,234.56", "CHY1,234.56", "1,234.56 CHY"},
{"zh_CN", "1", "CNY", "\uFFE51.00", "CNY1.00", "1.00 \u4EBA\u6C11\u5E01"},
{"zh_CN", "1234.56", "CNY", "\uFFE51,234.56", "CNY1,234.56", "1,234.56 \u4EBA\u6C11\u5E01"},
{"ru_RU", "1", "RUB", "1,00\u00A0\u0440\u0443\u0431.", "1,00\u00A0RUB", "1,00 \u0420\u043E\u0441\u0441\u0438\u0439\u0441\u043A\u0438\u0439 \u0440\u0443\u0431\u043B\u044C"},
{"ru_RU", "2", "RUB", "2,00\u00A0\u0440\u0443\u0431.", "2,00\u00A0RUB", "2,00 \u0420\u043E\u0441\u0441\u0438\u0439\u0441\u043A\u0438\u0445 \u0440\u0443\u0431\u043B\u044F"},
{"ru_RU", "5", "RUB", "5,00\u00A0\u0440\u0443\u0431.", "5,00\u00A0RUB", "5,00 \u0420\u043E\u0441\u0441\u0438\u0439\u0441\u043A\u0438\u0445 \u0440\u0443\u0431\u043B\u0435\u0439"},
// test locale without currency information
"ti_ET", "-1.23", "USD", "-US$1.23", "-USD1.23", "-1.23 USD",
{"ti_ET", "-1.23", "USD", "-US$1.23", "-USD1.23", "-1.23 USD"},
// test choice format
"es_AR", "1", "INR", "Re.\u00A01,00", "INR\u00A01,00", "1,00 rupia india",
{"es_AR", "1", "INR", "Re.\u00A01,00", "INR\u00A01,00", "1,00 rupia india"},
};
for (int i=0; i<DATA.length; i+=6) {
for (int i=0; i<DATA.length; ++i) {
for (int k = NumberFormat.CURRENCYSTYLE;
k <= NumberFormat.PLURALCURRENCYSTYLE;
++k) {
// k represents currency format style.
if ( k != NumberFormat.CURRENCYSTYLE &&
k != NumberFormat.ISOCURRENCYSTYLE &&
k != NumberFormat.PLURALCURRENCYSTYLE ) {
continue;
}
NumberFormat numFmt = NumberFormat.getInstance(new ULocale(DATA[i]), k);
numFmt.setCurrency(Currency.getInstance(DATA[i+2]));
String strBuf = numFmt.format(new Double(DATA[i+1]));
int resultDataIndex = i+k-1;
String localeString = DATA[i][0];
Double numberToBeFormat = new Double(DATA[i][1]);
String currencyISOCode = DATA[i][2];
ULocale locale = new ULocale(localeString);
NumberFormat numFmt = NumberFormat.getInstance(locale, k);
numFmt.setCurrency(Currency.getInstance(currencyISOCode));
String strBuf = numFmt.format(numberToBeFormat);
int resultDataIndex = k-1;
if ( k == NumberFormat.CURRENCYSTYLE ) {
resultDataIndex = i+k+2;
resultDataIndex = k+2;
}
if (!strBuf.equals(Utility.unescape(DATA[resultDataIndex]))) {
errln("FAIL: Expected " + DATA[resultDataIndex] + " actual: " + Utility.escape(strBuf));
// DATA[i][resultDataIndex] is the currency format result
// using 'k' currency style.
String formatResult = DATA[i][resultDataIndex];
if (!strBuf.equals(Utility.unescape(formatResult))) {
errln("FAIL: Expected " + formatResult + " actual: " + Utility.escape(strBuf));
}
try {
// test parsing, and test parsing for all currency formats.
for (int j = i+3; j < i+6; ++j) {
Number val = numFmt.parse(DATA[j]);
if (val.doubleValue() != ((new Double(DATA[i+1])).doubleValue())) {
errln("FAIL: getCurrencyFormat of locale " + DATA[i] + " failed roundtripping the number. val=" + val + "; expected: " + DATA[i+1]);
for (int j = 3; j < 6; ++j) {
// DATA[i][3] is the currency format result using
// CURRENCYSTYLE formatter.
// DATA[i][4] is the currency format result using
// ISOCURRENCYSTYLE formatter.
// DATA[i][5] is the currency format result using
// PLURALCURRENCYSTYLE formatter.
String oneCurrencyFormatResult = DATA[i][j];
Number val = numFmt.parse(oneCurrencyFormatResult);
if (val.doubleValue() != numberToBeFormat.doubleValue()) {
errln("FAIL: getCurrencyFormat of locale " + localeString + " failed roundtripping the number. val=" + val + "; expected: " + numberToBeFormat);
}
}
}

View File

@ -1,7 +1,7 @@
//##header J2SE15
/*
*******************************************************************************
* Copyright (C) 1996-2008, International Business Machines Corporation and *
* Copyright (C) 1996-2009, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*
@ -22,6 +22,7 @@ import com.ibm.icu.text.DateFormatSymbols;
import com.ibm.icu.text.DateIntervalFormat;
import com.ibm.icu.text.DateIntervalInfo;
import com.ibm.icu.text.DecimalFormat;
import com.ibm.icu.text.CurrencyPluralInfo;
import com.ibm.icu.text.DecimalFormatSymbols;
import com.ibm.icu.text.DurationFormat;
import com.ibm.icu.text.MessageFormat;
@ -1691,6 +1692,24 @@ public class FormatTests
}
}
public static class CurrencyPluralInfoHandler implements SerializableTest.Handler
{
public Object[] getTestObjects()
{
CurrencyPluralInfo currencyPluralInfo[] = {
new CurrencyPluralInfo()
};
currencyPluralInfo[0].setPluralRules("one: n is 1; few: n in 2..4");
currencyPluralInfo[0].setCurrencyPluralPattern("few", "few currency");
return currencyPluralInfo;
}
public boolean hasSameBehavior(Object a, Object b)
{
return a.equals(b);
}
}
public static class MessageFormatHandler implements SerializableTest.Handler
{
public Object[] getTestObjects()

View File

@ -1,7 +1,7 @@
//##header J2SE15
/*
*******************************************************************************
* Copyright (C) 1996-2008, International Business Machines Corporation and *
* Copyright (C) 1996-2009, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*
@ -656,6 +656,7 @@ public class SerializableTest extends TestFmwk.TestGroup
map.put("com.ibm.icu.text.NumberFormat", new FormatTests.NumberFormatHandler());
map.put("com.ibm.icu.text.DecimalFormat", new FormatTests.DecimalFormatHandler());
map.put("com.ibm.icu.text.RuleBasedNumberFormat", new FormatTests.RuleBasedNumberFormatHandler());
map.put("com.ibm.icu.text.CurrencyPluralInfo", new FormatTests.CurrencyPluralInfoHandler());
map.put("com.ibm.icu.text.DecimalFormatSymbols", new FormatTests.DecimalFormatSymbolsHandler());
map.put("com.ibm.icu.text.MessageFormat", new FormatTests.MessageFormatHandler());
map.put("com.ibm.icu.text.DateFormat", new FormatTests.DateFormatHandler());

View File

@ -0,0 +1,331 @@
/*
*******************************************************************************
* Copyright (C) 2009, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
package com.ibm.icu.text;
import com.ibm.icu.impl.ICUResourceBundle;
import com.ibm.icu.impl.Utility;
import com.ibm.icu.util.ULocale;
import com.ibm.icu.util.UResourceBundle;
import java.io.Serializable;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.Set;
/**
* This class represents the information needed by
* DecimalFormat to format currency plural,
* such as "3.00 US dollars" or "1.00 US dollar".
* DecimalFormat creates for itself an instance of
* CurrencyPluralInfo from its locale data.
* If you need to change any of these symbols, you can get the
* CurrencyPluralInfo object from your
* DecimalFormat and modify it.
*
* Following are the information needed for currency plural format and parse:
* locale information,
* plural rule of the locale,
* currency plural pattern of the locale.
*
* @draft ICU 4.2
* @provisional This API might change or be removed in a future release.
*/
public class CurrencyPluralInfo implements Cloneable, Serializable {
private static final long serialVersionUID = 1;
/**
* Create a CurrencyPluralInfo object for the default locale.
* @draft ICU 4.2
* @provisional This API might change or be removed in a future release.
*/
public CurrencyPluralInfo() {
initialize( ULocale.getDefault() );
}
/**
* Create a CurrencyPluralInfo object for the given locale.
* @param locale the locale
* @draft ICU 4.2
* @provisional This API might change or be removed in a future release.
*/
public CurrencyPluralInfo( Locale locale ) {
initialize( ULocale.forLocale(locale) );
}
/**
* Create a CurrencyPluralInfo object for the given locale.
* @param locale the locale
* @draft ICU 4.2
* @provisional This API might change or be removed in a future release.
*/
public CurrencyPluralInfo( ULocale locale ) {
initialize( locale );
}
/**
* Gets a CurrencyPluralInfo instance for the default locale.
*
* @return A CurrencyPluralInfo instance.
* @draft ICU 4.2
* @provisional This API might change or be removed in a future release.
*/
public static CurrencyPluralInfo getInstance() {
return new CurrencyPluralInfo();
}
/**
* Gets a CurrencyPluralInfo instance for the given locale.
*
* @param locale the locale.
* @return A CurrencyPluralInfo instance.
* @draft ICU 4.2
* @provisional This API might change or be removed in a future release.
*/
public static CurrencyPluralInfo getInstance(Locale locale) {
return new CurrencyPluralInfo(locale);
}
/**
* Gets a CurrencyPluralInfo instance for the given locale.
*
* @param locale the locale.
* @return A CurrencyPluralInfo instance.
* @draft ICU 4.2
* @provisional This API might change or be removed in a future release.
*/
public static CurrencyPluralInfo getInstance(ULocale locale) {
return new CurrencyPluralInfo(locale);
}
/**
* Gets plural rules of this locale, used for currency plural format
*
* @return plural rule
* @draft ICU 4.2
* @provisional This API might change or be removed in a future release.
*/
public PluralRules getPluralRules() {
return pluralRules;
}
/**
* Given a plural count, gets currency plural pattern of this locale,
* used for currency plural format
*
* @param pluralCount currency plural count
* @return a currency plural pattern based on plural count
* @draft ICU 4.2
* @provisional This API might change or be removed in a future release.
*/
public String getCurrencyPluralPattern(String pluralCount) {
String currencyPluralPattern =
(String)pluralCountToCurrencyUnitPattern.get(pluralCount);
if (currencyPluralPattern == null) {
// fall back to "other"
if (!pluralCount.equals("other")) {
currencyPluralPattern =
(String)pluralCountToCurrencyUnitPattern.get("other");
}
if (currencyPluralPattern == null) {
// no currencyUnitPatterns defined,
// fallback to predefined defult.
// This should never happen when ICU resource files are
// available, since currencyUnitPattern of "other" is always
// defined in root.
currencyPluralPattern = defaultCurrencyPluralPattern;
}
}
return currencyPluralPattern;
}
/**
* Get locale
*
* @return locale
*
* @draft ICU 4.2
* @provisional This API might change or be removed in a future release.
*/
public ULocale getLocale() {
return ulocale;
}
/**
* Set plural rules.
* The plural rule is set when CurrencyPluralInfo
* instance is created.
* You can call this method to reset plural rules only if you want
* to modify the default plural rule of the locale.
*
* @param ruleDescription new plural rule description
* @draft ICU 4.2
* @provisional This API might change or be removed in a future release.
*/
public void setPluralRules(String ruleDescription) {
pluralRules = PluralRules.createRules(ruleDescription);
}
/**
* Set currency plural patterns.
* The currency plural pattern is set when CurrencyPluralInfo
* instance is created.
* You can call this method to reset currency plural patterns only if
* you want to modify the default currency plural pattern of the locale.
*
* @param pluralCount the plural count for which the currency pattern will
* be overridden.
* @param pattern the new currency plural pattern
* @draft ICU 4.2
* @provisional This API might change or be removed in a future release.
*/
public void setCurrencyPluralPattern(String pluralCount, String pattern) {
pluralCountToCurrencyUnitPattern.put(pluralCount, pattern);
}
/**
* Set locale
*
* @param loc the new locale to set
* @draft ICU 4.2
* @provisional This API might change or be removed in a future release.
*/
public void setLocale(ULocale loc) {
ulocale = loc;
initialize(loc);
}
/**
* Standard override
*
* @draft ICU 4.2
* @provisional This API might change or be removed in a future release.
*/
public Object clone() {
try {
CurrencyPluralInfo other = (CurrencyPluralInfo) super.clone();
// locale is immutable
other.ulocale = (ULocale)ulocale.clone();
// plural rule is immutable
//other.pluralRules = pluralRules;
// clone content
//other.pluralCountToCurrencyUnitPattern = pluralCountToCurrencyUnitPattern;
other.pluralCountToCurrencyUnitPattern = new HashMap();
Iterator iter = pluralCountToCurrencyUnitPattern.keySet().iterator();
while (iter.hasNext()) {
String pluralCount = (String)iter.next();
String currencyPattern = (String)pluralCountToCurrencyUnitPattern.get(pluralCount);
other.pluralCountToCurrencyUnitPattern.put(pluralCount, currencyPattern);
}
return other;
} catch (CloneNotSupportedException e) {
throw new IllegalStateException();
}
}
/**
* Override equals
*
* @draft ICU 4.2
* @provisional This API might change or be removed in a future release.
*/
public boolean equals(Object a) {
if (a instanceof CurrencyPluralInfo) {
CurrencyPluralInfo other = (CurrencyPluralInfo)a;
return pluralRules.equals(other.pluralRules) &&
pluralCountToCurrencyUnitPattern.equals(other.pluralCountToCurrencyUnitPattern);
}
return false;
}
/**
* Given a number, returns the keyword of the first rule that applies
* to the number
*/
String select(double number) {
return pluralRules.select(number);
}
/**
* Currency plural pattern iterator.
*
* @return a iterator on currency plural pattern key set.
*/
Iterator pluralPatternIterator() {
return pluralCountToCurrencyUnitPattern.keySet().iterator();
}
private void initialize(ULocale uloc) {
ulocale = uloc;
pluralRules = PluralRules.forLocale(uloc);
setupCurrencyPluralPattern(uloc);
}
private void setupCurrencyPluralPattern(ULocale uloc) {
pluralCountToCurrencyUnitPattern = new HashMap();
Set pluralCountSet = new HashSet();
ULocale parentLocale = uloc;
String numberStylePattern = NumberFormat.getPattern(uloc, NumberFormat.NUMBERSTYLE);
while (parentLocale != null) {
try {
ICUResourceBundle resource = (ICUResourceBundle)UResourceBundle.getBundleInstance(ICUResourceBundle.ICU_BASE_NAME, parentLocale);
ICUResourceBundle currencyRes = resource.getWithFallback("CurrencyUnitPatterns");
int size = currencyRes.getSize();
for (int index = 0; index < size; ++index) {
String pluralCount = currencyRes.get(index).getKey();
if (pluralCountSet.contains(pluralCount)) {
continue;
}
String pattern = currencyRes.get(index).getString();
// replace {0} with numberStylePattern
// and {1} with triple currency sign
String patternWithNumber = Utility.replace(pattern, "{0}", numberStylePattern);
String patternWithCurrencySign = Utility.replace(patternWithNumber, "{1}", tripleCurrencyStr);
pluralCountToCurrencyUnitPattern.put(pluralCount, patternWithCurrencySign);
pluralCountSet.add(pluralCount);
}
} catch (MissingResourceException e) {
}
parentLocale = parentLocale.getFallback();
}
}
//-------------------- private data member ---------------------
//
// triple currency sign char array
private static final char[] tripleCurrencySign = {0xA4, 0xA4, 0xA4};
// triple currency sign string
private static final String tripleCurrencyStr = new String(tripleCurrencySign);
// default currency plural pattern char array
private static final char[] defaultCurrencyPluralPatternChar = {0, '.', '#', '#', ' ', 0xA4, 0xA4, 0xA4};
// default currency plural pattern string
private static final String defaultCurrencyPluralPattern = new String(defaultCurrencyPluralPatternChar);
// map from plural count to currency plural pattern, for example
// one (plural count) --> {0} {1} (currency plural pattern,
// in which, {0} is the amount number, and {1} is the currency plural name.
private Map pluralCountToCurrencyUnitPattern = null;
/*
* The plural rule is used to format currency plural name,
* for example: "3.00 US Dollars".
* If there are 3 currency signs in the currency patttern,
* the 3 currency signs will be replaced by currency plural name.
*/
private PluralRules pluralRules = null;
// locale
private ULocale ulocale = null;
}

View File

@ -13,11 +13,8 @@ import java.math.BigInteger;
import java.text.ChoiceFormat;
import java.text.FieldPosition;
import java.text.ParsePosition;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.Set;
//#if defined(FOUNDATION10)
@ -33,15 +30,12 @@ import java.text.Format;
import java.util.ArrayList;
//#endif
import com.ibm.icu.impl.ICUResourceBundle;
import com.ibm.icu.impl.UCharacterProperty;
import com.ibm.icu.impl.Utility;
import com.ibm.icu.lang.UCharacter;
import com.ibm.icu.math.BigDecimal;
import com.ibm.icu.util.Currency;
import com.ibm.icu.util.CurrencyAmount;
import com.ibm.icu.util.ULocale;
import com.ibm.icu.util.UResourceBundle;
//This is an enhanced version of DecimalFormat that is based on the standard version in the JDK.
/**
@ -669,8 +663,7 @@ public class DecimalFormat extends NumberFormat {
setCurrency(Currency.getInstance(def));
applyPatternWithoutExpandAffix(pattern, false);
if (currencySignCount == CURRENCY_SIGN_COUNT_IN_PLURAL_FORMAT) {
// plural rule is only needed for currency plural format.
pluralRules = PluralRules.forLocale(def);
currencyPluralInfo = new CurrencyPluralInfo(def);
// the exact pattern is not known until the plural count is known.
// so, no need to expand affix now.
} else {
@ -703,8 +696,7 @@ public class DecimalFormat extends NumberFormat {
setCurrency(Currency.getInstance(def));
applyPatternWithoutExpandAffix( pattern, false );
if (currencySignCount == CURRENCY_SIGN_COUNT_IN_PLURAL_FORMAT) {
// plural rule is only needed for currency plural format.
pluralRules = PluralRules.forLocale(def);
currencyPluralInfo = new CurrencyPluralInfo(def);
} else {
expandAffixAdjustWidth(null);
}
@ -737,36 +729,72 @@ public class DecimalFormat extends NumberFormat {
private void createFromPatternAndSymbols(String pattern, DecimalFormatSymbols inputSymbols) {
// Always applyPattern after the symbols are set
this.symbols = (DecimalFormatSymbols) inputSymbols.clone();
symbols = (DecimalFormatSymbols) inputSymbols.clone();
setCurrencyForSymbols();
applyPatternWithoutExpandAffix(pattern, false);
if (currencySignCount == CURRENCY_SIGN_COUNT_IN_PLURAL_FORMAT) {
// plural rule is only needed for currency plural format.
ULocale uloc = getLocale(ULocale.VALID_LOCALE);
if (uloc == null) {
uloc = inputSymbols.getLocale(ULocale.VALID_LOCALE);
}
pluralRules = PluralRules.forLocale(uloc);
currencyPluralInfo = new CurrencyPluralInfo(symbols.getLocale());
} else {
expandAffixAdjustWidth(null);
}
}
/*
* Create a DecimalFormat for currency plural format
* from the given pattern, symbols, and style.
/**
* Create a DecimalFormat from the given pattern, symbols,
* information used for currency plural format, and format style.
* Use this constructor when you need to completely customize the
* behavior of the format.
* <p>
* To obtain standard formats for a given
* locale, use the factory methods on NumberFormat such as
* getInstance or getCurrencyInstance.
* <p>
* If you need only minor adjustments to a standard format,
* you can modify the format returned by
* a NumberFormat factory method using the setters.
* <p>
* If you want to completely customize a decimal format,
* using your own DecimalFormatSymbols (such as group separators) and
* your own information for currency plural formatting (such as
* plural rule and currency plural patterns), you can use this constructor.
* <p>
* @param pattern a non-localized pattern string
* @param symbols the set of symbols to be used
* @param infoInput the information used for currency plural format,
* including currency plural patterns and plural rules.
* @param style the decimal formatting style,
* it is one of the following values:
* NumberFormat.NUMBERSTYLE;
* NumberFormat.CURRENCYSTYLE;
* NumberFormat.PERCENTSTYLE;
* NumberFormat.SCIENTIFICSTYLE;
* NumberFormat.INTEGERSTYLE;
* NumberFormat.ISOCURRENCYSTYLE;
* NumberFormat.PLURALCURRENCYSTYLE;
* @draft ICU 4.2
* @provisional This API might change or be removed in a future release.
*/
DecimalFormat(String pattern, DecimalFormatSymbols symbols, int style) {
if (style != NumberFormat.PLURALCURRENCYSTYLE) {
createFromPatternAndSymbols(pattern, symbols);
public DecimalFormat(String pattern, DecimalFormatSymbols symbols,
CurrencyPluralInfo infoInput,
int style) {
CurrencyPluralInfo info = infoInput;
if (style == NumberFormat.PLURALCURRENCYSTYLE) {
info = (CurrencyPluralInfo)infoInput.clone();
}
create(pattern, symbols, info, style);
}
private void create(String pattern, DecimalFormatSymbols inputSymbols,
CurrencyPluralInfo info,
int inputStyle) {
if (inputStyle != NumberFormat.PLURALCURRENCYSTYLE) {
createFromPatternAndSymbols(pattern, inputSymbols);
} else {
// Always applyPattern after the symbols are set
this.symbols = (DecimalFormatSymbols) symbols.clone();
ULocale uloc = getLocale(ULocale.VALID_LOCALE);
if (uloc == null) {
uloc = symbols.getLocale(ULocale.VALID_LOCALE);
}
setupCurrencyPluralPattern(uloc);
symbols = (DecimalFormatSymbols) inputSymbols.clone();
currencyPluralInfo = info;
// the pattern used in format is not fixed until formatting,
// in which, the number is known and
// will be used to pick the right pattern based on plural count.
@ -774,45 +802,24 @@ public class DecimalFormat extends NumberFormat {
// For most locale, the patterns are probably the same for all
// plural count. If not, the right pattern need to be re-applied
// during format.
String currencyPluralPatternForOther = (String)pluralCountToCurrencyUnitPattern.get("other");
if (currencyPluralPatternForOther == null) {
currencyPluralPatternForOther = defaultCurrencyPluralPattern;
}
String currencyPluralPatternForOther = currencyPluralInfo.getCurrencyPluralPattern("other");
applyPatternWithoutExpandAffix(currencyPluralPatternForOther,false);
setCurrencyForSymbols();
pluralRules = PluralRules.forLocale(uloc);
}
this.style = style;
style = inputStyle;
}
private void setupCurrencyPluralPattern(ULocale uloc) {
pluralCountToCurrencyUnitPattern = new HashMap();
Set pluralCountSet = new HashSet();
ULocale parentLocale = uloc;
String numberStylePattern = getPattern(uloc, NumberFormat.NUMBERSTYLE);
while (parentLocale != null) {
try {
ICUResourceBundle resource = (ICUResourceBundle)UResourceBundle.getBundleInstance(ICUResourceBundle.ICU_BASE_NAME, parentLocale);
ICUResourceBundle currencyRes = resource.getWithFallback("CurrencyUnitPatterns");
int size = currencyRes.getSize();
for (int index = 0; index < size; ++index) {
String pluralCount = currencyRes.get(index).getKey();
if (pluralCountSet.contains(pluralCount)) {
continue;
}
String pattern = currencyRes.get(index).getString();
// replace {0} with numberStylePattern
// and {1} with triple currency sign
String patternWithNumber = Utility.replace(pattern, "{0}", numberStylePattern);
String patternWithCurrencySign = Utility.replace(patternWithNumber, "{1}", tripleCurrencyStr);
pluralCountToCurrencyUnitPattern.put(pluralCount, patternWithCurrencySign);
pluralCountSet.add(pluralCount);
}
} catch (MissingResourceException e) {
}
parentLocale = parentLocale.getFallback();
}
/*
* Create a DecimalFormat for currency plural format
* from the given pattern, symbols, and style.
*/
DecimalFormat(String pattern, DecimalFormatSymbols inputSymbols, int style) {
CurrencyPluralInfo info = null;
if (style == NumberFormat.PLURALCURRENCYSTYLE) {
info = new CurrencyPluralInfo(inputSymbols.getLocale());
}
create(pattern, inputSymbols, info, style);
}
/**
@ -1226,7 +1233,7 @@ public class DecimalFormat extends NumberFormat {
boolean isNegative, boolean isInteger,
boolean parseAttr) {
if (currencySignCount == CURRENCY_SIGN_COUNT_IN_PLURAL_FORMAT) {
return subformat(pluralRules.select(number), result, fieldPosition,
return subformat(currencyPluralInfo.select(number), result, fieldPosition,
isNegative, isInteger, parseAttr);
} else {
return subformat(result, fieldPosition, isNegative, isInteger, parseAttr);
@ -1238,7 +1245,7 @@ public class DecimalFormat extends NumberFormat {
boolean isNegative, boolean isInteger,
boolean parseAttr) {
if (currencySignCount == CURRENCY_SIGN_COUNT_IN_PLURAL_FORMAT) {
return subformat(pluralRules.select(number), result, fieldPosition,
return subformat(currencyPluralInfo.select(number), result, fieldPosition,
isNegative, isInteger, parseAttr);
} else {
return subformat(result, fieldPosition, isNegative, isInteger, parseAttr);
@ -1265,21 +1272,7 @@ public class DecimalFormat extends NumberFormat {
// DecimalFormat(pattern, symbol, style)
if (style == NumberFormat.PLURALCURRENCYSTYLE) {
// May need to reset pattern if the style is PLURALCURRENCYSTYLE.
String currencyPluralPattern =
(String)pluralCountToCurrencyUnitPattern.get(pluralCount);
if (currencyPluralPattern == null) {
// fall back to "other"
currencyPluralPattern =
(String)pluralCountToCurrencyUnitPattern.get("other");
if (currencyPluralPattern == null) {
// no currencyUnitPatterns defined,
// fallback to SYMBOL_NAME format.
// This should never happen when ICU resource files are
// available, since currencyUnitPattern of "other" is always
// defined in root.
currencyPluralPattern = defaultCurrencyPluralPattern;
}
}
String currencyPluralPattern = currencyPluralInfo.getCurrencyPluralPattern(pluralCount);
if (formatPattern.equals(currencyPluralPattern) == false) {
applyPatternWithoutExpandAffix(currencyPluralPattern, false);
}
@ -2123,20 +2116,21 @@ public class DecimalFormat extends NumberFormat {
// Get affix patterns used in locale's currency pattern
// (NumberPatterns[1]) and currency plural pattern (CurrencyUnitPatterns).
private void setupCurrencyAffixForAllPatterns() {
ULocale uloc = getLocale(ULocale.VALID_LOCALE);
if (uloc == null) {
uloc = symbols.getLocale(ULocale.VALID_LOCALE);
}
if (pluralCountToCurrencyUnitPattern == null) {
setupCurrencyPluralPattern(uloc);
if (currencyPluralInfo == null) {
currencyPluralInfo = new CurrencyPluralInfo(symbols.getLocale());
}
affixPatternsForCurrency = new HashSet();
// save the current pattern, since it will be changed by
// applyPatternWithoutExpandAffix
String savedFormatPattern = formatPattern;
// CURRENCYSTYLE and ISOCURRENCYSTYLE should have the same
// prefix and suffix, so, only need to save one of them.
// Here, chose onlyApplyPatternWithoutExpandAffix without
// saving the actualy pattern in 'pattern' data member.
onlyApplyPatternWithoutExpandAffix(getPattern(uloc, NumberFormat.CURRENCYSTYLE), false);
// TODO: is it uloc?
applyPatternWithoutExpandAffix(getPattern(symbols.getLocale(), NumberFormat.CURRENCYSTYLE), false);
AffixForCurrency affixes = new AffixForCurrency(negPrefixPattern,
negSuffixPattern,
posPrefixPattern,
@ -2144,17 +2138,15 @@ public class DecimalFormat extends NumberFormat {
affixPatternsForCurrency.add(affixes);
// add plural pattern
Iterator iter = pluralCountToCurrencyUnitPattern.keySet().iterator();
Iterator iter = currencyPluralInfo.pluralPatternIterator();
Set currencyUnitPatternSet = new HashSet();
while (iter.hasNext()) {
String pluralCount = (String)iter.next();
String currencyPattern = (String)pluralCountToCurrencyUnitPattern.get(pluralCount);
String currencyPattern = (String)currencyPluralInfo.getCurrencyPluralPattern(pluralCount);
if (currencyPattern != null &&
currencyUnitPatternSet.contains(currencyPattern) == false) {
currencyUnitPatternSet.add(currencyPattern);
// Here, chose onlyApplyPatternWithoutExpandAffix without
// saving the actualy pattern in 'pattern' data member.
onlyApplyPatternWithoutExpandAffix(currencyPattern, false);
applyPatternWithoutExpandAffix(currencyPattern, false);
affixes = new AffixForCurrency(negPrefixPattern,
negSuffixPattern,
posPrefixPattern,
@ -2162,6 +2154,8 @@ public class DecimalFormat extends NumberFormat {
affixPatternsForCurrency.add(affixes);
}
}
// reset pattern back
formatPattern = savedFormatPattern;
}
private static final int CURRENCY_SIGN_COUNT_IN_SYMBOL_FORMAT = 1;
@ -2827,6 +2821,7 @@ public class DecimalFormat extends NumberFormat {
// have a display name, or any 3-letter ISO code.
// Try to parse display name for our locale; first
// determine our locale.
// TODO: use locale in CurrencyPluralInfo
ULocale uloc = getLocale(ULocale.VALID_LOCALE);
if (uloc == null) {
// applyPattern has been called; use the symbols
@ -3564,6 +3559,44 @@ public class DecimalFormat extends NumberFormat {
decimalSeparatorAlwaysShown = newValue;
}
/**
* Returns a copy of the CurrencyPluralInfo
* used by this format.
* It might return null if the decimal format is not a plural type
* currency decimal format.
* Plural type currency decimal format means either
* the pattern in the decimal format contains 3 currency signs,
* or the decimal format is initialized with PLURALCURRENCYSTYLE.
* @return desired CurrencyPluralInfo
* @see CurrencyPluralInfo
* @draft ICU 4.2
* @provisional This API might change or be removed in a future release.
*/
public CurrencyPluralInfo getCurrencyPluralInfo() {
try {
// don't allow multiple references
return currencyPluralInfo == null ?
null :
(CurrencyPluralInfo) currencyPluralInfo.clone();
} catch (Exception foo) {
return null; // should never happen
}
}
/**
* Sets the CurrencyPluralInfo used by this format. The
* format uses a copy of the provided information.
* @param newInfo desired CurrencyPluralInfo
* @see CurrencyPluralInfo
* @draft ICU 4.2
* @provisional This API might change or be removed in a future release.
*/
public void setCurrencyPluralInfo(CurrencyPluralInfo newInfo) {
currencyPluralInfo = (CurrencyPluralInfo) newInfo.clone();
isReadyForParsing = false;
}
/**
* Standard override; no change in semantics.
* @stable ICU 2.0
@ -3573,6 +3606,9 @@ public class DecimalFormat extends NumberFormat {
DecimalFormat other = (DecimalFormat) super.clone();
other.symbols = (DecimalFormatSymbols) symbols.clone();
other.digitList = new DigitList(); // fix for JB#5358
if (currencyPluralInfo != null) {
other.currencyPluralInfo = (CurrencyPluralInfo)currencyPluralInfo.clone();
}
/*
* TODO: We need to figure out whether we share a single copy
* of DigitList by multiple cloned copies. format/subformat
@ -3600,12 +3636,8 @@ public class DecimalFormat extends NumberFormat {
* [Richard/GCL]
*/
// following are added to accomodate changes for currency plural format.
return style == other.style
&& (pluralRules == null && other.pluralRules == null ||
pluralRules.equals(other.pluralRules))
&& (style == NumberFormat.PLURALCURRENCYSTYLE)?
(pluralCountToCurrencyUnitPattern ==
other.pluralCountToCurrencyUnitPattern):
return currencySignCount == other.currencySignCount &&
(style == NumberFormat.PLURALCURRENCYSTYLE)? true :
((posPrefixPattern != null &&
equals(posPrefixPattern, other.posPrefixPattern))
&& (posSuffixPattern != null &&
@ -3625,7 +3657,9 @@ public class DecimalFormat extends NumberFormat {
&& (!useSignificantDigits ||
minSignificantDigits == other.minSignificantDigits &&
maxSignificantDigits == other.maxSignificantDigits)
&& symbols.equals(other.symbols);
&& symbols.equals(other.symbols)
&& (currencyPluralInfo == null
|| currencyPluralInfo.equals(other.currencyPluralInfo));
}
//method to unquote the strings and compare
@ -4335,14 +4369,6 @@ public class DecimalFormat extends NumberFormat {
}
private void applyPatternWithoutExpandAffix(String pattern, boolean localized) {
onlyApplyPatternWithoutExpandAffix(pattern, localized);
formatPattern = pattern;
}
// only used when formatting currency plural format.
// in which, the right affix (based on the formatted number)
// is not known until formatting.
private void onlyApplyPatternWithoutExpandAffix(String pattern, boolean localized) {
char zeroDigit = PATTERN_ZERO_DIGIT; // '0'
char sigDigit = PATTERN_SIGNIFICANT_DIGIT; // '@'
char groupingSeparator = PATTERN_GROUPING_SEPARATOR;
@ -4841,6 +4867,13 @@ public class DecimalFormat extends NumberFormat {
negPrefixPattern = PATTERN_MINUS + posPrefixPattern;
}
setLocale(null, null);
// save the pattern
formatPattern = pattern;
// initialize currencyPluralInfo if needed
if (currencySignCount == CURRENCY_SIGN_COUNT_IN_PLURAL_FORMAT &&
currencyPluralInfo == null) {
currencyPluralInfo = new CurrencyPluralInfo(symbols.getLocale());
}
}
/**
@ -5238,84 +5271,6 @@ public class DecimalFormat extends NumberFormat {
//[Richard/GCL]
private String negSuffixPattern;
/*
* Following are used in currency format
*/
private static final char[] tripleCurrencySign = {0xA4, 0xA4, 0xA4};
private static final String tripleCurrencyStr = new String(tripleCurrencySign);
private static final char[] defaultCurrencyPluralPatternChar = {0, '.', '#', '#', ' ', 0xA4, 0xA4, 0xA4};
private static final String defaultCurrencyPluralPattern = new String(defaultCurrencyPluralPatternChar);
private Map pluralCountToCurrencyUnitPattern = null;
// pattern used in this formatter
private String formatPattern = "";
// style is only valid when decimal formatter is constructed by
// DecimalFormat(pattern, decimalFormatSymbol, style)
private int style = NumberFormat.NUMBERSTYLE;
/* For parsing purose,
* Need to remember all prefix patterns and suffix patterns of
* every currency format pattern,
* including the pattern of default currecny style, ISO currency style,
* and plural currency style. And the patterns are set through applyPattern.
* Following are used to represent the affix patterns in currency plural
* formats.
*/
private static final class AffixForCurrency {
private String negPrefixPatternForCurrency = null;
private String negSuffixPatternForCurrency = null;
private String posPrefixPatternForCurrency = null;
private String posSuffixPatternForCurrency = null;
public AffixForCurrency() {}
public AffixForCurrency(String negPrefix, String negSuffix,
String posPrefix, String posSuffix) {
negPrefixPatternForCurrency = negPrefix;
negSuffixPatternForCurrency = negSuffix;
posPrefixPatternForCurrency = posPrefix;
posSuffixPatternForCurrency = posSuffix;
}
public String getNegPrefix() {
return negPrefixPatternForCurrency;
}
public String getNegSuffix() {
return negSuffixPatternForCurrency;
}
public String getPosPrefix() {
return posPrefixPatternForCurrency;
}
public String getPosSuffix() {
return posSuffixPatternForCurrency;
}
}
private Set affixPatternsForCurrency = null;
private boolean isReadyForParsing = false;
/*
* Represents whether this is a currency format, and which
* currency format style.
* 0: not currency format type;
* 1: currency style -- symbol name, such as "$" for US dollar.
* 2: currency style -- ISO name, such as USD for US dollar.
* 3: currency style -- plural long name, such as "US Dollar" for
* "1.00 US Dollar", or "US Dollars" for
* "3.00 US Dollars".
*/
private transient int currencySignCount = 0;
/*
* The plural rule is used to format currency plural name,
* for example: "3.00 US Dollars".
* If there are 3 currency signs in the currency patttern,
* the 3 currency signs will be replaced by currency plural name.
*/
private PluralRules pluralRules = null;
/**
@ -5691,6 +5646,97 @@ public class DecimalFormat extends NumberFormat {
//#else
private ArrayList attributes = new ArrayList();
//#endif
/*
* Following are used in currency format
*/
/*
// triple currency sign char array
private static final char[] tripleCurrencySign = {0xA4, 0xA4, 0xA4};
// triple currency sign string
private static final String tripleCurrencyStr = new String(tripleCurrencySign);
// default currency plural pattern char array
private static final char[] defaultCurrencyPluralPatternChar = {0, '.', '#', '#', ' ', 0xA4, 0xA4, 0xA4};
// default currency plural pattern string
private static final String defaultCurrencyPluralPattern = new String(defaultCurrencyPluralPatternChar);
*/
// pattern used in this formatter
private String formatPattern = "";
// style is only valid when decimal formatter is constructed by
// DecimalFormat(pattern, decimalFormatSymbol, style)
private int style = NumberFormat.NUMBERSTYLE;
/*
* Represents whether this is a currency format, and which
* currency format style.
* 0: not currency format type;
* 1: currency style -- symbol name, such as "$" for US dollar.
* 2: currency style -- ISO name, such as USD for US dollar.
* 3: currency style -- plural long name, such as "US Dollar" for
* "1.00 US Dollar", or "US Dollars" for
* "3.00 US Dollars".
*/
private int currencySignCount = 0;
/* For parsing purose,
* Need to remember all prefix patterns and suffix patterns of
* every currency format pattern,
* including the pattern of default currecny style, ISO currency style,
* and plural currency style. And the patterns are set through applyPattern.
* Following are used to represent the affix patterns in currency plural
* formats.
*/
private static final class AffixForCurrency {
// negative prefix pattern
private String negPrefixPatternForCurrency = null;
// negative suffix pattern
private String negSuffixPatternForCurrency = null;
// positive prefix pattern
private String posPrefixPatternForCurrency = null;
// positive suffix pattern
private String posSuffixPatternForCurrency = null;
public AffixForCurrency() {}
public AffixForCurrency(String negPrefix, String negSuffix,
String posPrefix, String posSuffix) {
negPrefixPatternForCurrency = negPrefix;
negSuffixPatternForCurrency = negSuffix;
posPrefixPatternForCurrency = posPrefix;
posSuffixPatternForCurrency = posSuffix;
}
public String getNegPrefix() {
return negPrefixPatternForCurrency;
}
public String getNegSuffix() {
return negSuffixPatternForCurrency;
}
public String getPosPrefix() {
return posPrefixPatternForCurrency;
}
public String getPosSuffix() {
return posSuffixPatternForCurrency;
}
}
// Affix patter set for currency.
// It is a set of AffixForCurrency,
// each element of the set saves the negative prefix,
// negative suffix, positive prefix, and positive suffix of a pattern.
private transient Set affixPatternsForCurrency = null;
// For currency parsing, since currency parsing need to parse
// against all currency patterns, before the parsing, need to set up
// the affix patterns for currency.
private transient boolean isReadyForParsing = false;
// Information needed for DecimalFormat to format/parse currency plural.
private CurrencyPluralInfo currencyPluralInfo = null;
}
//eof

View File

@ -1,6 +1,6 @@
/**
*******************************************************************************
* Copyright (C) 2001-2008, International Business Machines Corporation and *
* Copyright (C) 2001-2009, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
@ -852,6 +852,7 @@ public class Currency extends MeasureUnit implements Serializable {
if (matchLength > tmp.getCurrencyString().length()) {
resultList.set(i, item);
}
break;
}
}
if (i == resultList.size()) {