ICU-11564 Improve the thread safety of RBNF.

The recursion count is now a method argument instead of a data member.
Some data fields are now marked final to ensure thread safety, which caused reordering of some data initialization/parsing.
Setting the DecimalFormatSymbols no longer reparses the rules, but it just sets a new version of DecimalFormatSymbols instead.

X-SVN-Rev: 37383
This commit is contained in:
George Rhoten 2015-04-23 07:44:14 +00:00
parent a649861ff9
commit a423e7cb09
4 changed files with 135 additions and 151 deletions

View file

@ -106,7 +106,7 @@ final class NFRule {
* rule list
* @param ownersOwner The RuleBasedNumberFormat that owns the
* rule set that owns the new rule(s)
* @param returnList A list of NFRules
* @param returnList One or more instances of NFRule are added and returned here
*/
public static void makeRules(String description,
NFRuleSet owner,
@ -684,7 +684,7 @@ final class NFRule {
* @param pos The position in toInsertInto where the resultant text
* should be inserted
*/
public void doFormat(long number, StringBuffer toInsertInto, int pos) {
public void doFormat(long number, StringBuffer toInsertInto, int pos, int recursionCount) {
// first, insert the rule's rule text into toInsertInto at the
// specified position, then insert the results of the substitutions
// into the right places in toInsertInto (notice we do the
@ -709,10 +709,10 @@ final class NFRule {
lengthOffset = ruleText.length() - (toInsertInto.length() - initialLength);
}
if (!sub2.isNullSubstitution()) {
sub2.doSubstitution(number, toInsertInto, pos - (sub2.getPos() > pluralRuleStart ? lengthOffset : 0));
sub2.doSubstitution(number, toInsertInto, pos - (sub2.getPos() > pluralRuleStart ? lengthOffset : 0), recursionCount);
}
if (!sub1.isNullSubstitution()) {
sub1.doSubstitution(number, toInsertInto, pos - (sub1.getPos() > pluralRuleStart ? lengthOffset : 0));
sub1.doSubstitution(number, toInsertInto, pos - (sub1.getPos() > pluralRuleStart ? lengthOffset : 0), recursionCount);
}
}
@ -725,7 +725,7 @@ final class NFRule {
* @param pos The position in toInsertInto where the resultant text
* should be inserted
*/
public void doFormat(double number, StringBuffer toInsertInto, int pos) {
public void doFormat(double number, StringBuffer toInsertInto, int pos, int recursionCount) {
// first, insert the rule's rule text into toInsertInto at the
// specified position, then insert the results of the substitutions
// into the right places in toInsertInto
@ -751,10 +751,10 @@ final class NFRule {
lengthOffset = ruleText.length() - (toInsertInto.length() - initialLength);
}
if (!sub2.isNullSubstitution()) {
sub2.doSubstitution(number, toInsertInto, pos - (sub2.getPos() > pluralRuleStart ? lengthOffset : 0));
sub2.doSubstitution(number, toInsertInto, pos - (sub2.getPos() > pluralRuleStart ? lengthOffset : 0), recursionCount);
}
if (!sub1.isNullSubstitution()) {
sub1.doSubstitution(number, toInsertInto, pos - (sub1.getPos() > pluralRuleStart ? lengthOffset : 0));
sub1.doSubstitution(number, toInsertInto, pos - (sub1.getPos() > pluralRuleStart ? lengthOffset : 0), recursionCount);
}
}
@ -1203,4 +1203,13 @@ final class NFRule {
RbnfLenientScanner scanner = formatter.getLenientScanner();
return scanner != null && scanner.allIgnorable(str);
}
public void setDecimalFormatSymbols(DecimalFormatSymbols newSymbols) {
if (sub1 != null) {
sub1.setDecimalFormatSymbols(newSymbols);
}
if (sub2 != null) {
sub2.setDecimalFormatSymbols(newSymbols);
}
}
}

View file

@ -29,7 +29,7 @@ final class NFRuleSet {
/**
* The rule set's name
*/
private String name;
private final String name;
/**
* The rule set's regular rules
@ -61,17 +61,12 @@ final class NFRuleSet {
/**
* True if the rule set is parseable.
*/
private boolean isParseable = true;
private final boolean isParseable;
/**
* Used to limit recursion for bad rule sets.
* Limit of recursion. It's about a 64 bit number formatted in base 2.
*/
private int recursionCount = 0;
/**
* Limit of recursion.
*/
private static final int RECURSION_LIMIT = 50;
private static final int RECURSION_LIMIT = 64;
//-----------------------------------------------------------------------
// construction
@ -102,7 +97,13 @@ final class NFRuleSet {
throw new IllegalArgumentException("Rule set name doesn't end in colon");
}
else {
name = description.substring(0, pos);
String name = description.substring(0, pos);
this.isParseable = !name.endsWith("@noparse");
if (!this.isParseable) {
name = name.substring(0,name.length()-8); // Remove the @noparse from the name
}
this.name = name;
while (pos < description.length() && PatternProps.isWhiteSpace(description.charAt(++pos))) {
}
description = description.substring(pos);
@ -113,17 +114,13 @@ final class NFRuleSet {
// if the description doesn't begin with a rule set name, its
// name is "%default"
name = "%default";
isParseable = true;
}
if (description.length() == 0) {
throw new IllegalArgumentException("Empty rule set description");
}
if ( name.endsWith("@noparse")) {
name = name.substring(0,name.length()-8); // Remove the @noparse from the name
isParseable = false;
}
// all of the other members of NFRuleSet are initialized
// by parseRules()
}
@ -389,15 +386,13 @@ final class NFRuleSet {
* @param pos The position in toInsertInto where the result of
* this operation is to be inserted
*/
public void format(long number, StringBuffer toInsertInto, int pos) {
public void format(long number, StringBuffer toInsertInto, int pos, int recursionCount) {
NFRule applicableRule = findNormalRule(number);
if (++recursionCount >= RECURSION_LIMIT) {
recursionCount = 0;
if (recursionCount >= RECURSION_LIMIT) {
throw new IllegalStateException("Recursion limit exceeded when applying ruleSet " + name);
}
applicableRule.doFormat(number, toInsertInto, pos);
--recursionCount;
applicableRule.doFormat(number, toInsertInto, pos, ++recursionCount);
}
/**
@ -408,15 +403,13 @@ final class NFRuleSet {
* @param pos The position in toInsertInto where the result of
* this operation is to be inserted
*/
public void format(double number, StringBuffer toInsertInto, int pos) {
public void format(double number, StringBuffer toInsertInto, int pos, int recursionCount) {
NFRule applicableRule = findRule(number);
if (++recursionCount >= RECURSION_LIMIT) {
recursionCount = 0;
if (recursionCount >= RECURSION_LIMIT) {
throw new IllegalStateException("Recursion limit exceeded when applying ruleSet " + name);
}
applicableRule.doFormat(number, toInsertInto, pos);
--recursionCount;
applicableRule.doFormat(number, toInsertInto, pos, ++recursionCount);
}
/**
@ -779,4 +772,10 @@ final class NFRuleSet {
return result;
}
public void setDecimalFormatSymbols(DecimalFormatSymbols newSymbols) {
for (NFRule rule : rules) {
rule.setDecimalFormatSymbols(newSymbols);
}
}
}

View file

@ -1,6 +1,6 @@
/*
*******************************************************************************
* Copyright (C) 1996-2014, International Business Machines Corporation and *
* Copyright (C) 1996-2015, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
@ -292,14 +292,14 @@ abstract class NFSubstitution {
* rule text begins (this value is added to this substitution's
* position to determine exactly where to insert the new text)
*/
public void doSubstitution(long number, StringBuffer toInsertInto, int position) {
public void doSubstitution(long number, StringBuffer toInsertInto, int position, int recursionCount) {
if (ruleSet != null) {
// perform a transformation on the number that is dependent
// on the type of substitution this is, then just call its
// rule set's format() method to format the result
long numberToFormat = transformNumber(number);
ruleSet.format(numberToFormat, toInsertInto, position + pos);
ruleSet.format(numberToFormat, toInsertInto, position + pos, recursionCount);
} else {
// or perform the transformation on the number (preserving
// the result's fractional part if the formatter it set
@ -324,7 +324,7 @@ abstract class NFSubstitution {
* rule text begins (this value is added to this substitution's
* position to determine exactly where to insert the new text)
*/
public void doSubstitution(double number, StringBuffer toInsertInto, int position) {
public void doSubstitution(double number, StringBuffer toInsertInto, int position, int recursionCount) {
// perform a transformation on the number being formatted that
// is dependent on the type of substitution this is
double numberToFormat = transformNumber(number);
@ -332,14 +332,14 @@ abstract class NFSubstitution {
// if the result is an integer, from here on out we work in integer
// space (saving time and memory and preserving accuracy)
if (numberToFormat == Math.floor(numberToFormat) && ruleSet != null) {
ruleSet.format((long)numberToFormat, toInsertInto, position + pos);
ruleSet.format((long)numberToFormat, toInsertInto, position + pos, recursionCount);
// if the result isn't an integer, then call either our rule set's
// format() method or our DecimalFormat's format() method to
// format the result
} else {
if (ruleSet != null) {
ruleSet.format(numberToFormat, toInsertInto, position + pos);
ruleSet.format(numberToFormat, toInsertInto, position + pos, recursionCount);
} else {
toInsertInto.insert(position + this.pos, numberFormat.format(numberToFormat));
}
@ -533,6 +533,13 @@ abstract class NFSubstitution {
public boolean isModulusSubstitution() {
return false;
}
public void setDecimalFormatSymbols(DecimalFormatSymbols newSymbols) {
if (numberFormat != null) {
numberFormat.setDecimalFormatSymbols(newSymbols);
}
}
}
//===================================================================
@ -697,13 +704,7 @@ class MultiplierSubstitution extends NFSubstitution {
* @return true if the two substitutions are functionally equal
*/
public boolean equals(Object that) {
if (super.equals(that)) {
MultiplierSubstitution that2 = (MultiplierSubstitution)that;
return divisor == that2.divisor;
} else {
return false;
}
return super.equals(that) && divisor == ((MultiplierSubstitution) that).divisor;
}
//-----------------------------------------------------------------------
@ -798,7 +799,7 @@ class ModulusSubstitution extends NFSubstitution {
* If this is a &gt;&gt;&gt; substitution, the rule to use to format
* the substitution value. Otherwise, null.
*/
NFRule ruleToUse;
private final NFRule ruleToUse;
//-----------------------------------------------------------------------
// construction
@ -893,18 +894,18 @@ class ModulusSubstitution extends NFSubstitution {
* into
* @param position The position of the rule text in toInsertInto
*/
public void doSubstitution(long number, StringBuffer toInsertInto, int position) {
public void doSubstitution(long number, StringBuffer toInsertInto, int position, int recursionCount) {
// if this isn't a >>> substitution, just use the inherited version
// of this function (which uses either a rule set or a DecimalFormat
// to format its substitution value)
if (ruleToUse == null) {
super.doSubstitution(number, toInsertInto, position);
super.doSubstitution(number, toInsertInto, position, recursionCount);
// a >>> substitution goes straight to a particular rule to
// format the substitution value
} else {
// a >>> substitution goes straight to a particular rule to
// format the substitution value
long numberToFormat = transformNumber(number);
ruleToUse.doFormat(numberToFormat, toInsertInto, position + pos);
ruleToUse.doFormat(numberToFormat, toInsertInto, position + pos, recursionCount);
}
}
@ -916,19 +917,19 @@ class ModulusSubstitution extends NFSubstitution {
* into
* @param position The position of the rule text in toInsertInto
*/
public void doSubstitution(double number, StringBuffer toInsertInto, int position) {
public void doSubstitution(double number, StringBuffer toInsertInto, int position, int recursionCount) {
// if this isn't a >>> substitution, just use the inherited version
// of this function (which uses either a rule set or a DecimalFormat
// to format its substitution value)
if (ruleToUse == null) {
super.doSubstitution(number, toInsertInto, position);
super.doSubstitution(number, toInsertInto, position, recursionCount);
// a >>> substitution goes straight to a particular rule to
// format the substitution value
} else {
// a >>> substitution goes straight to a particular rule to
// format the substitution value
double numberToFormat = transformNumber(number);
ruleToUse.doFormat(numberToFormat, toInsertInto, position + pos);
ruleToUse.doFormat(numberToFormat, toInsertInto, position + pos, recursionCount);
}
}
@ -972,10 +973,10 @@ class ModulusSubstitution extends NFSubstitution {
if (ruleToUse == null) {
return super.doParse(text, parsePosition, baseValue, upperBound, lenientParse);
// but if it IS a >>> substitution, we have to do it here: we
// use the specific rule's doParse() method, and then we have to
// do some of the other work of NFRuleSet.parse()
} else {
// but if it IS a >>> substitution, we have to do it here: we
// use the specific rule's doParse() method, and then we have to
// do some of the other work of NFRuleSet.parse()
Number tempResult = ruleToUse.doParse(text, parsePosition, false, upperBound);
if (parsePosition.getIndex() != 0) {
@ -1145,13 +1146,13 @@ class FractionalPartSubstitution extends NFSubstitution {
* true if this substitution should have the default "by digits"
* behavior, false otherwise
*/
private boolean byDigits = false;
private final boolean byDigits;
/**
* true if we automatically insert spaces to separate names of digits
* set to false by '>>>' in fraction rules, used by Thai.
*/
private boolean useSpaces = true;
private final boolean useSpaces;
//-----------------------------------------------------------------------
// construction
@ -1169,10 +1170,10 @@ class FractionalPartSubstitution extends NFSubstitution {
super(pos, ruleSet, formatter, description);
if (description.equals(">>") || description.equals(">>>") || ruleSet == this.ruleSet) {
byDigits = true;
if (description.equals(">>>")) {
useSpaces = false;
}
useSpaces = !description.equals(">>>");
} else {
byDigits = false;
useSpaces = true;
this.ruleSet.makeIntoFractionRuleSet();
}
}
@ -1191,11 +1192,11 @@ class FractionalPartSubstitution extends NFSubstitution {
* @param position The position of the owning rule's rule text in
* toInsertInto
*/
public void doSubstitution(double number, StringBuffer toInsertInto, int position) {
public void doSubstitution(double number, StringBuffer toInsertInto, int position, int recursionCount) {
if (!byDigits) {
// if we're not in "byDigits" mode, just use the inherited
// doSubstitution() routine
super.doSubstitution(number, toInsertInto, position);
super.doSubstitution(number, toInsertInto, position, recursionCount);
}
else {
// if we're in "byDigits" mode, transform the value into an integer
@ -1216,7 +1217,7 @@ class FractionalPartSubstitution extends NFSubstitution {
} else {
pad = true;
}
ruleSet.format(dl.digits[--dl.count] - '0', toInsertInto, position + pos);
ruleSet.format(dl.digits[--dl.count] - '0', toInsertInto, position + pos, recursionCount);
}
while (dl.decimalAt < 0) {
if (pad && useSpaces) {
@ -1224,7 +1225,7 @@ class FractionalPartSubstitution extends NFSubstitution {
} else {
pad = true;
}
ruleSet.format(0, toInsertInto, position + pos);
ruleSet.format(0, toInsertInto, position + pos, recursionCount);
++dl.decimalAt;
}
}
@ -1449,12 +1450,12 @@ class NumeratorSubstitution extends NFSubstitution {
* The denominator of the fraction we're finding the numerator for.
* (The base value of the rule that owns this substitution.)
*/
double denominator;
private final double denominator;
/**
* True if we format leading zeros (this is a hack for Hebrew spellout)
*/
boolean withZeros;
private final boolean withZeros;
//-----------------------------------------------------------------------
// construction
@ -1498,7 +1499,7 @@ class NumeratorSubstitution extends NFSubstitution {
public boolean equals(Object that) {
if (super.equals(that)) {
NumeratorSubstitution that2 = (NumeratorSubstitution)that;
return denominator == that2.denominator;
return denominator == that2.denominator && withZeros == that2.withZeros;
} else {
return false;
}
@ -1518,7 +1519,7 @@ class NumeratorSubstitution extends NFSubstitution {
* rule text begins (this value is added to this substitution's
* position to determine exactly where to insert the new text)
*/
public void doSubstitution(double number, StringBuffer toInsertInto, int position) {
public void doSubstitution(double number, StringBuffer toInsertInto, int position, int recursionCount) {
// perform a transformation on the number being formatted that
// is dependent on the type of substitution this is
//String s = toInsertInto.toString();
@ -1530,7 +1531,7 @@ class NumeratorSubstitution extends NFSubstitution {
int len = toInsertInto.length();
while ((nf *= 10) < denominator) {
toInsertInto.insert(position + pos, ' ');
ruleSet.format(0, toInsertInto, position + pos);
ruleSet.format(0, toInsertInto, position + pos, recursionCount);
}
position += toInsertInto.length() - len;
}
@ -1538,14 +1539,14 @@ class NumeratorSubstitution extends NFSubstitution {
// if the result is an integer, from here on out we work in integer
// space (saving time and memory and preserving accuracy)
if (numberToFormat == Math.floor(numberToFormat) && ruleSet != null) {
ruleSet.format((long)numberToFormat, toInsertInto, position + pos);
ruleSet.format((long)numberToFormat, toInsertInto, position + pos, recursionCount);
// if the result isn't an integer, then call either our rule set's
// format() method or our DecimalFormat's format() method to
// format the result
} else {
if (ruleSet != null) {
ruleSet.format(numberToFormat, toInsertInto, position + pos);
ruleSet.format(numberToFormat, toInsertInto, position + pos, recursionCount);
} else {
toInsertInto.insert(position + pos, numberFormat.format(numberToFormat));
}
@ -1701,13 +1702,6 @@ class NullSubstitution extends NFSubstitution {
// boilerplate
//-----------------------------------------------------------------------
/**
* Only checks for class equality
*/
public boolean equals(Object that) {
return super.equals(that);
}
/**
* NullSubstitutions don't show up in the textual representation
* of a RuleBasedNumberFormat

View file

@ -543,12 +543,12 @@ public class RuleBasedNumberFormat extends NumberFormat {
* The formatter's rule sets.
*/
private transient NFRuleSet[] ruleSets = null;
/**
* The formatter's rule sets' descriptions.
* The formatter's rule names mapped to rule sets.
*/
private transient String[] ruleSetDescriptions = null;
private transient Map<String, NFRuleSet> ruleSetsMap = null;
/**
* A pointer to the formatter's default rule set. This is always included
* in ruleSets.
@ -910,8 +910,8 @@ public class RuleBasedNumberFormat extends NumberFormat {
// accumulate the descriptions of all the rule sets in a
// StringBuffer, then cast it to a String and return it
StringBuilder result = new StringBuilder();
for (int i = 0; i < ruleSets.length; i++) {
result.append(ruleSets[i].toString());
for (NFRuleSet ruleSet : ruleSets) {
result.append(ruleSet.toString());
}
return result.toString();
}
@ -951,6 +951,7 @@ public class RuleBasedNumberFormat extends NumberFormat {
// get swept up by the garbage collector
RuleBasedNumberFormat temp = new RuleBasedNumberFormat(description, loc);
ruleSets = temp.ruleSets;
ruleSetsMap = temp.ruleSetsMap;
defaultRuleSet = temp.defaultRuleSet;
publicRuleSetNames = temp.publicRuleSetNames;
decimalFormatSymbols = temp.decimalFormatSymbols;
@ -995,8 +996,7 @@ public class RuleBasedNumberFormat extends NumberFormat {
private String[] getNameListForLocale(ULocale loc) {
if (loc != null && ruleSetDisplayNames != null) {
String[] localeNames = { loc.getBaseName(), ULocale.getDefault(Category.DISPLAY).getBaseName() };
for (int i = 0; i < localeNames.length; ++i) {
String lname = localeNames[i];
for (String lname : localeNames) {
while (lname.length() > 0) {
String[] names = ruleSetDisplayNames.get(lname);
if (names != null) {
@ -1411,8 +1411,8 @@ public class RuleBasedNumberFormat extends NumberFormat {
}
// Apply the new decimalFormatSymbols by reparsing the rulesets
for (int i = 0; i < ruleSets.length; i++) {
ruleSets[i].parseRules(ruleSetDescriptions[i], this);
for (NFRuleSet ruleSet : ruleSets) {
ruleSet.setDecimalFormatSymbols(decimalFormatSymbols);
}
}
}
@ -1579,15 +1579,21 @@ public class RuleBasedNumberFormat extends NumberFormat {
// pre-flight parsing the description and count the number of
// rule sets (";%" marks the end of one rule set and the beginning
// of the next)
int numRuleSets = 0;
for (int p = descBuf.indexOf(";%"); p != -1; p = descBuf.indexOf(";%", p)) {
int numRuleSets = 1;
int p = 0;
while ((p = descBuf.indexOf(";%", p)) != -1) {
++numRuleSets;
++p;
p += 2; // Skip the length of ";%"
}
++numRuleSets;
// our rule list is an array of the appropriate size
ruleSets = new NFRuleSet[numRuleSets];
ruleSetsMap = new HashMap<String, NFRuleSet>(numRuleSets * 2 + 1);
defaultRuleSet = null;
// Used to count the number of public rule sets
// Public rule sets have names that begin with % instead of %%.
int publicRuleSetCount = 0;
// divide up the descriptions into individual rule-set descriptions
// and store them in a temporary array. At each step, we also
@ -1596,18 +1602,34 @@ public class RuleBasedNumberFormat extends NumberFormat {
// the rest of the descriptions and finish initializing everything
// because we have to know the names and locations of all the rule
// sets before we can actually set everything up
ruleSetDescriptions = new String[numRuleSets];
String[] ruleSetDescriptions = new String[numRuleSets];
int curRuleSet = 0;
int start = 0;
for (int p = descBuf.indexOf(";%"); p != -1; p = descBuf.indexOf(";%", start)) {
while (curRuleSet < ruleSets.length) {
p = descBuf.indexOf(";%", start);
if (p < 0) {
p = descBuf.length() - 1;
}
ruleSetDescriptions[curRuleSet] = descBuf.substring(start, p + 1);
ruleSets[curRuleSet] = new NFRuleSet(ruleSetDescriptions, curRuleSet);
NFRuleSet ruleSet = new NFRuleSet(ruleSetDescriptions, curRuleSet);
ruleSets[curRuleSet] = ruleSet;
String currentName = ruleSet.getName();
ruleSetsMap.put(currentName, ruleSet);
if (!currentName.startsWith("%%")) {
++publicRuleSetCount;
if (defaultRuleSet == null
&& currentName.equals("%spellout-numbering")
|| currentName.equals("%digits-ordinal")
|| currentName.equals("%duration"))
{
defaultRuleSet = ruleSet;
}
}
++curRuleSet;
start = p + 1;
}
ruleSetDescriptions[curRuleSet] = descBuf.substring(start);
ruleSets[curRuleSet] = new NFRuleSet(ruleSetDescriptions, curRuleSet);
// now we can take note of the formatter's default rule set, which
// is the last public rule set in the description (it's the last
@ -1622,20 +1644,7 @@ public class RuleBasedNumberFormat extends NumberFormat {
// Set the default ruleset to the last public ruleset, unless one of the predefined
// ruleset names %spellout-numbering, %digits-ordinal, or %duration is found
boolean defaultNameFound = false;
int n = ruleSets.length;
defaultRuleSet = ruleSets[ruleSets.length - 1];
while (--n >= 0) {
String currentName = ruleSets[n].getName();
if (currentName.equals("%spellout-numbering") || currentName.equals("%digits-ordinal") || currentName.equals("%duration")) {
defaultRuleSet = ruleSets[n];
defaultNameFound = true;
break;
}
}
if ( !defaultNameFound ) {
if (defaultRuleSet == null) {
for (int i = ruleSets.length - 1; i >= 0; --i) {
if (!ruleSets[i].getName().startsWith("%%")) {
defaultRuleSet = ruleSets[i];
@ -1643,6 +1652,9 @@ public class RuleBasedNumberFormat extends NumberFormat {
}
}
}
if (defaultRuleSet == null) {
defaultRuleSet = ruleSets[ruleSets.length - 1];
}
// finally, we can go back through the temporary descriptions
// list and finish setting up the substructure
@ -1653,15 +1665,6 @@ public class RuleBasedNumberFormat extends NumberFormat {
// Now that the rules are initialized, the 'real' default rule
// set can be adjusted by the localization data.
// count the number of public rule sets
// (public rule sets have names that begin with % instead of %%)
int publicRuleSetCount = 0;
for (int i = 0; i < ruleSets.length; i++) {
if (!ruleSets[i].getName().startsWith("%%")) {
++publicRuleSetCount;
}
}
// prepare an array of the proper size and copy the names into it
String[] publicRuleSetTemp = new String[publicRuleSetCount];
publicRuleSetCount = 0;
@ -1787,26 +1790,6 @@ public class RuleBasedNumberFormat extends NumberFormat {
return result;
}
// /**
// * This function is called ONLY DURING CONSTRUCTION to fill in the
// * defaultRuleSet variable once we've set up all the rule sets.
// * The default rule set is the last public rule set in the description.
// * (It's the last rather than the first so that a caller can append
// * text to the end of an existing formatter description to change its
// * behavior.)
// */
// private void initDefaultRuleSet() {
// // seek backward from the end of the list until we reach a rule set
// // whose name DOESN'T begin with %%. That's the default rule set
// for (int i = ruleSets.length - 1; i >= 0; --i) {
// if (!ruleSets[i].getName().startsWith("%%")) {
// defaultRuleSet = ruleSets[i];
// return;
// }
// }
// defaultRuleSet = ruleSets[ruleSets.length - 1];
// }
//-----------------------------------------------------------------------
// formatting implementation
//-----------------------------------------------------------------------
@ -1826,7 +1809,7 @@ public class RuleBasedNumberFormat extends NumberFormat {
// position of 0 and the number being formatted) to the rule set
// for formatting
StringBuffer result = new StringBuffer();
ruleSet.format(number, result, 0);
ruleSet.format(number, result, 0, 0);
postProcess(result, ruleSet);
return result.toString();
}
@ -1851,7 +1834,7 @@ public class RuleBasedNumberFormat extends NumberFormat {
// position of 0 and the number being formatted) to the rule set
// for formatting
StringBuffer result = new StringBuffer();
ruleSet.format(number, result, 0);
ruleSet.format(number, result, 0, 0);
postProcess(result, ruleSet);
return result.toString();
}
@ -1913,11 +1896,10 @@ public class RuleBasedNumberFormat extends NumberFormat {
* @return The rule set with that name
*/
NFRuleSet findRuleSet(String name) throws IllegalArgumentException {
for (int i = 0; i < ruleSets.length; i++) {
if (ruleSets[i].getName().equals(name)) {
return ruleSets[i];
}
NFRuleSet result = ruleSetsMap.get(name);
if (result == null) {
throw new IllegalArgumentException("No rule set named " + name);
}
throw new IllegalArgumentException("No rule set named " + name);
return result;
}
}