ICU-6620 make lenient parsing use same locale that was used to instantiate the RBNF formatter

X-SVN-Rev: 25013
This commit is contained in:
Doug Felt 2008-11-27 01:25:21 +00:00
parent bd48f81ef1
commit 59f17b771b
3 changed files with 78 additions and 3 deletions

View File

@ -1,12 +1,13 @@
/*
*******************************************************************************
* Copyright (C) 2004, International Business Machines Corporation and *
* Copyright (C) 2004-2008, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
package com.ibm.icu.dev.test.format;
import com.ibm.icu.text.RuleBasedNumberFormat;
import com.ibm.icu.util.ULocale;
import com.ibm.icu.dev.test.TestFmwk;
import java.util.Locale;
@ -98,4 +99,57 @@ public class RBNFParseTest extends TestFmwk {
}
}
}
private void parseFormat(RuleBasedNumberFormat rbnf, String s, String target) {
try {
Number n = rbnf.parse(s);
String t = rbnf.format(n);
assertEquals(rbnf.getLocale(ULocale.ACTUAL_LOCALE) + ": " + s + " : " + n, target, t);
} catch (java.text.ParseException e){
fail("exception:" + e);
}
}
private void parseList(RuleBasedNumberFormat rbnf_en, RuleBasedNumberFormat rbnf_fr, String[][] lists) {
for (int i = 0; i < lists.length; ++i) {
String[] list = lists[i];
String s = list[0];
String target_en = list[1];
String target_fr = list[2];
parseFormat(rbnf_en, s, target_en);
parseFormat(rbnf_fr, s, target_fr);
}
}
public void TestLenientParse() throws Exception {
RuleBasedNumberFormat rbnf_en, rbnf_fr;
rbnf_en = new RuleBasedNumberFormat(Locale.ENGLISH, RuleBasedNumberFormat.SPELLOUT);
rbnf_en.setLenientParseMode(true);
rbnf_fr = new RuleBasedNumberFormat(Locale.FRENCH, RuleBasedNumberFormat.SPELLOUT);
rbnf_fr.setLenientParseMode(true);
Number n = rbnf_en.parse("1,2 million");
logln(n.toString());
String[][] lists = {
{ "1,2", "twelve", "un virgule deux" },
{ "1,2 million", "twelve million", "un million deux cents mille" },
{ "1.2", "one point two", "douze" },
{ "1.2 million", "one million two hundred thousand", "douze million" },
};
Locale.setDefault(Locale.FRANCE);
logln("Default locale:" + Locale.getDefault());
logln("rbnf_en:" + rbnf_en.getDefaultRuleSetName());
logln("rbnf_fr:" + rbnf_en.getDefaultRuleSetName());
parseList(rbnf_en, rbnf_fr, lists);
Locale.setDefault(Locale.US);
logln("Default locale:" + Locale.getDefault());
logln("rbnf_en:" + rbnf_en.getDefaultRuleSetName());
logln("rbnf_fr:" + rbnf_en.getDefaultRuleSetName());
parseList(rbnf_en, rbnf_fr, lists);
}
}

View File

@ -39,6 +39,11 @@ abstract class NFSubstitution {
* or null. (Either this or ruleSet has to be non-null.)
*/
DecimalFormat numberFormat = null;
/**
* Link to the RBNF so that we can access its decimalFormat if need be.
*/
RuleBasedNumberFormat rbnf = null;
//-----------------------------------------------------------------------
// construction
@ -158,6 +163,7 @@ abstract class NFSubstitution {
String description) {
// initialize the substitution's position in its parent rule
this.pos = pos;
this.rbnf = formatter;
// the description should begin and end with the same character.
// If it doesn't that's a syntax error. Otherwise,
@ -405,7 +411,7 @@ abstract class NFSubstitution {
if (ruleSet != null) {
tempResult = ruleSet.parse(text, parsePosition, upperBound);
if (lenientParse && !ruleSet.isFractionSet() && parsePosition.getIndex() == 0) {
tempResult = NumberFormat.getInstance().parse(text, parsePosition);
tempResult = rbnf.getDecimalFormat().parse(text, parsePosition);
}
// ...or use our DecimalFormat to parse the text
@ -1327,7 +1333,7 @@ class FractionalPartSubstitution extends NFSubstitution {
workPos.setIndex(0);
digit = ruleSet.parse(workText, workPos, 10).intValue();
if (lenientParse && workPos.getIndex() == 0) {
digit = NumberFormat.getInstance().parse(workText, workPos).intValue();
digit = rbnf.getDecimalFormat().parse(workText, workPos).intValue();
}
if (workPos.getIndex() != 0) {

View File

@ -543,6 +543,13 @@ public class RuleBasedNumberFormat extends NumberFormat {
* filled in if the rule set never uses a DecimalFormat pattern.
*/
private transient DecimalFormatSymbols decimalFormatSymbols = null;
/**
* The NumberFormat used when lenient parsing numbers. This needs to reflect
* the locale. This is lazy-evaluated, like decimalFormatSymbols. It is
* here so it can be shared by different NFSubstitutions.
*/
private transient DecimalFormat decimalFormat = null;
/**
* Flag specifying whether lenient parse mode is on or off. Off by default.
@ -873,6 +880,7 @@ public class RuleBasedNumberFormat extends NumberFormat {
defaultRuleSet = temp.defaultRuleSet;
publicRuleSetNames = temp.publicRuleSetNames;
decimalFormatSymbols = temp.decimalFormatSymbols;
decimalFormat = temp.decimalFormat;
locale = temp.locale;
}
@ -1341,6 +1349,13 @@ public class RuleBasedNumberFormat extends NumberFormat {
}
return decimalFormatSymbols;
}
DecimalFormat getDecimalFormat() {
if (decimalFormat == null) {
decimalFormat = (DecimalFormat)NumberFormat.getInstance(locale);
}
return decimalFormat;
}
//-----------------------------------------------------------------------
// construction implementation