ICU-6433 currency plural format merged to trunk
X-SVN-Rev: 25254
This commit is contained in:
parent
084842e74a
commit
3ec5b5cb90
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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()
|
||||
|
@ -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());
|
||||
|
331
icu4j/src/com/ibm/icu/text/CurrencyPluralInfo.java
Normal file
331
icu4j/src/com/ibm/icu/text/CurrencyPluralInfo.java
Normal 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;
|
||||
}
|
@ -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
|
||||
|
@ -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()) {
|
||||
|
Loading…
Reference in New Issue
Block a user