Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(1650)

Unified Diff: icu4j/main/classes/core/src/com/ibm/icu/number/NumberPropertyMapper.java

Issue 335150043: Refreshing Number Parsing: ICU4J Base URL: svn+icussh://source.icu-project.org/repos/icu/trunk/
Patch Set: Replying to Andy feedback round one. See commit message. Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: icu4j/main/classes/core/src/com/ibm/icu/number/NumberPropertyMapper.java
===================================================================
--- icu4j/main/classes/core/src/com/ibm/icu/number/NumberPropertyMapper.java (revision 40724)
+++ icu4j/main/classes/core/src/com/ibm/icu/number/NumberPropertyMapper.java (working copy)
@@ -5,9 +5,8 @@
import java.math.BigDecimal;
import java.math.MathContext;
-import com.ibm.icu.impl.StandardPlural;
import com.ibm.icu.impl.number.AffixPatternProvider;
-import com.ibm.icu.impl.number.AffixUtils;
+import com.ibm.icu.impl.number.CurrencyPluralInfoAffixProvider;
import com.ibm.icu.impl.number.CustomSymbolCurrency;
import com.ibm.icu.impl.number.DecimalFormatProperties;
import com.ibm.icu.impl.number.MacroProps;
@@ -14,7 +13,7 @@
import com.ibm.icu.impl.number.MultiplierImpl;
import com.ibm.icu.impl.number.Padder;
import com.ibm.icu.impl.number.PatternStringParser;
-import com.ibm.icu.impl.number.PatternStringParser.ParsedPatternInfo;
+import com.ibm.icu.impl.number.PropertiesAffixPatternProvider;
import com.ibm.icu.impl.number.RoundingUtils;
import com.ibm.icu.number.NumberFormatter.DecimalSeparatorDisplay;
import com.ibm.icu.number.NumberFormatter.SignDisplay;
@@ -22,7 +21,6 @@
import com.ibm.icu.number.Rounder.IncrementRounderImpl;
import com.ibm.icu.number.Rounder.SignificantRounderImpl;
import com.ibm.icu.text.CompactDecimalFormat.CompactStyle;
-import com.ibm.icu.text.CurrencyPluralInfo;
import com.ibm.icu.text.DecimalFormatSymbols;
import com.ibm.icu.util.Currency;
import com.ibm.icu.util.Currency.CurrencyUsage;
@@ -30,20 +28,22 @@
/**
* <p>
- * This class, as well as NumberFormatterImpl, could go into the impl package, but they depend on too many
- * package-private members of the public APIs.
+ * This class, as well as NumberFormatterImpl, could go into the impl package, but they depend on too
+ * many package-private members of the public APIs.
*/
final class NumberPropertyMapper {
/** Convenience method to create a NumberFormatter directly from Properties. */
- public static UnlocalizedNumberFormatter create(DecimalFormatProperties properties, DecimalFormatSymbols symbols) {
+ public static UnlocalizedNumberFormatter create(
+ DecimalFormatProperties properties,
+ DecimalFormatSymbols symbols) {
MacroProps macros = oldToNew(properties, symbols, null);
return NumberFormatter.with().macros(macros);
}
/**
- * Convenience method to create a NumberFormatter directly from a pattern string. Something like this could become
- * public API if there is demand.
+ * Convenience method to create a NumberFormatter directly from a pattern string. Something like this
+ * could become public API if there is demand.
*/
public static UnlocalizedNumberFormatter create(String pattern, DecimalFormatSymbols symbols) {
DecimalFormatProperties properties = PatternStringParser.parseToProperties(pattern);
@@ -51,9 +51,9 @@
}
/**
- * Creates a new {@link MacroProps} object based on the content of a {@link DecimalFormatProperties} object. In
- * other words, maps Properties to MacroProps. This function is used by the JDK-compatibility API to call into the
- * ICU 60 fluent number formatting pipeline.
+ * Creates a new {@link MacroProps} object based on the content of a {@link DecimalFormatProperties}
+ * object. In other words, maps Properties to MacroProps. This function is used by the
+ * JDK-compatibility API to call into the ICU 60 fluent number formatting pipeline.
*
* @param properties
* The property bag to be mapped.
@@ -60,10 +60,13 @@
* @param symbols
* The symbols associated with the property bag.
* @param exportedProperties
- * A property bag in which to store validated properties.
+ * A property bag in which to store validated properties. Used by some DecimalFormat
+ * getters.
* @return A new MacroProps containing all of the information in the Properties.
*/
- public static MacroProps oldToNew(DecimalFormatProperties properties, DecimalFormatSymbols symbols,
+ public static MacroProps oldToNew(
+ DecimalFormatProperties properties,
+ DecimalFormatSymbols symbols,
DecimalFormatProperties exportedProperties) {
MacroProps macros = new MacroProps();
ULocale locale = symbols.getULocale();
@@ -96,8 +99,10 @@
// UNITS //
///////////
- boolean useCurrency = ((properties.getCurrency() != null) || properties.getCurrencyPluralInfo() != null
- || properties.getCurrencyUsage() != null || affixProvider.hasCurrencySign());
+ boolean useCurrency = ((properties.getCurrency() != null)
+ || properties.getCurrencyPluralInfo() != null
+ || properties.getCurrencyUsage() != null
+ || affixProvider.hasCurrencySign());
Currency currency = CustomSymbolCurrency.resolve(properties.getCurrency(), locale, symbols);
CurrencyUsage currencyUsage = properties.getCurrencyUsage();
boolean explicitCurrencyUsage = currencyUsage != null;
@@ -122,7 +127,8 @@
MathContext mathContext = RoundingUtils.getMathContextOrUnlimited(properties);
boolean explicitMinMaxFrac = minFrac != -1 || maxFrac != -1;
boolean explicitMinMaxSig = minSig != -1 || maxSig != -1;
- // Resolve min/max frac for currencies, required for the validation logic and for when minFrac or maxFrac was
+ // Resolve min/max frac for currencies, required for the validation logic and for when minFrac or
+ // maxFrac was
// set (but not both) on a currency instance.
// NOTE: Increments are handled in "Rounder.constructCurrency()".
if (useCurrency) {
@@ -151,7 +157,8 @@
minFrac = minFrac < 0 ? 0 : minFrac;
maxFrac = maxFrac < 0 ? Integer.MAX_VALUE : maxFrac < minFrac ? minFrac : maxFrac;
minInt = minInt <= 0 ? 1 : minInt > RoundingUtils.MAX_INT_FRAC_SIG ? 1 : minInt;
- maxInt = maxInt < 0 ? -1 : maxInt < minInt ? minInt : maxInt > RoundingUtils.MAX_INT_FRAC_SIG ? -1 : maxInt;
+ maxInt = maxInt < 0 ? -1
+ : maxInt < minInt ? minInt : maxInt > RoundingUtils.MAX_INT_FRAC_SIG ? -1 : maxInt;
}
Rounder rounding = null;
if (explicitCurrencyUsage) {
@@ -159,10 +166,12 @@
} else if (roundingIncrement != null) {
rounding = Rounder.constructIncrement(roundingIncrement);
} else if (explicitMinMaxSig) {
- minSig = minSig < 1 ? 1 : minSig > RoundingUtils.MAX_INT_FRAC_SIG ? RoundingUtils.MAX_INT_FRAC_SIG : minSig;
+ minSig = minSig < 1 ? 1
+ : minSig > RoundingUtils.MAX_INT_FRAC_SIG ? RoundingUtils.MAX_INT_FRAC_SIG : minSig;
maxSig = maxSig < 0 ? RoundingUtils.MAX_INT_FRAC_SIG
: maxSig < minSig ? minSig
- : maxSig > RoundingUtils.MAX_INT_FRAC_SIG ? RoundingUtils.MAX_INT_FRAC_SIG : maxSig;
+ : maxSig > RoundingUtils.MAX_INT_FRAC_SIG ? RoundingUtils.MAX_INT_FRAC_SIG
+ : maxSig;
rounding = Rounder.constructSignificant(minSig, maxSig);
} else if (explicitMinMaxFrac) {
rounding = Rounder.constructFraction(minFrac, maxFrac);
@@ -184,14 +193,7 @@
// GROUPING STRATEGY //
///////////////////////
- int grouping1 = properties.getGroupingSize();
- int grouping2 = properties.getSecondaryGroupingSize();
- int minGrouping = properties.getMinimumGroupingDigits();
- assert grouping1 >= -2; // value of -2 means to forward no grouping information
- grouping1 = grouping1 > 0 ? grouping1 : grouping2 > 0 ? grouping2 : grouping1;
- grouping2 = grouping2 > 0 ? grouping2 : grouping1;
- // TODO: Is it important to handle minGrouping > 2?
- macros.grouper = Grouper.getInstance((byte) grouping1, (byte) grouping2, minGrouping == 2);
+ macros.grouper = Grouper.defaults().withProperties(properties);
/////////////
// PADDING //
@@ -198,7 +200,8 @@
/////////////
if (properties.getFormatWidth() != -1) {
- macros.padder = new Padder(properties.getPadString(), properties.getFormatWidth(),
+ macros.padder = new Padder(properties.getPadString(),
+ properties.getFormatWidth(),
properties.getPadPosition());
}
@@ -246,7 +249,8 @@
// Scientific notation also involves overriding the rounding mode.
// TODO: Overriding here is a bit of a hack. Should this logic go earlier?
if (macros.rounder instanceof FractionRounder) {
- // For the purposes of rounding, get the original min/max int/frac, since the local variables
+ // For the purposes of rounding, get the original min/max int/frac, since the local
+ // variables
// have been manipulated for display purposes.
int minInt_ = properties.getMinimumIntegerDigits();
int minFrac_ = properties.getMinimumFractionDigits();
@@ -334,178 +338,4 @@
return macros;
}
-
- private static class PropertiesAffixPatternProvider implements AffixPatternProvider {
- private final String posPrefix;
- private final String posSuffix;
- private final String negPrefix;
- private final String negSuffix;
-
- public PropertiesAffixPatternProvider(DecimalFormatProperties properties) {
- // There are two ways to set affixes in DecimalFormat: via the pattern string (applyPattern), and via the
- // explicit setters (setPositivePrefix and friends). The way to resolve the settings is as follows:
- //
- // 1) If the explicit setting is present for the field, use it.
- // 2) Otherwise, follows UTS 35 rules based on the pattern string.
- //
- // Importantly, the explicit setters affect only the one field they override. If you set the positive
- // prefix, that should not affect the negative prefix. Since it is impossible for the user of this class
- // to know whether the origin for a string was the override or the pattern, we have to say that we always
- // have a negative subpattern and perform all resolution logic here.
-
- // Convenience: Extract the properties into local variables.
- // Variables are named with three chars: [p/n][p/s][o/p]
- // [p/n] => p for positive, n for negative
- // [p/s] => p for prefix, s for suffix
- // [o/p] => o for escaped custom override string, p for pattern string
- String ppo = AffixUtils.escape(properties.getPositivePrefix());
- String pso = AffixUtils.escape(properties.getPositiveSuffix());
- String npo = AffixUtils.escape(properties.getNegativePrefix());
- String nso = AffixUtils.escape(properties.getNegativeSuffix());
- String ppp = properties.getPositivePrefixPattern();
- String psp = properties.getPositiveSuffixPattern();
- String npp = properties.getNegativePrefixPattern();
- String nsp = properties.getNegativeSuffixPattern();
-
- if (ppo != null) {
- posPrefix = ppo;
- } else if (ppp != null) {
- posPrefix = ppp;
- } else {
- // UTS 35: Default positive prefix is empty string.
- posPrefix = "";
- }
-
- if (pso != null) {
- posSuffix = pso;
- } else if (psp != null) {
- posSuffix = psp;
- } else {
- // UTS 35: Default positive suffix is empty string.
- posSuffix = "";
- }
-
- if (npo != null) {
- negPrefix = npo;
- } else if (npp != null) {
- negPrefix = npp;
- } else {
- // UTS 35: Default negative prefix is "-" with positive prefix.
- // Important: We prepend the "-" to the pattern, not the override!
- negPrefix = ppp == null ? "-" : "-" + ppp;
- }
-
- if (nso != null) {
- negSuffix = nso;
- } else if (nsp != null) {
- negSuffix = nsp;
- } else {
- // UTS 35: Default negative prefix is the positive prefix.
- negSuffix = psp == null ? "" : psp;
- }
- }
-
- @Override
- public char charAt(int flags, int i) {
- return getStringForFlags(flags).charAt(i);
- }
-
- @Override
- public int length(int flags) {
- return getStringForFlags(flags).length();
- }
-
- private String getStringForFlags(int flags) {
- boolean prefix = (flags & Flags.PREFIX) != 0;
- boolean negative = (flags & Flags.NEGATIVE_SUBPATTERN) != 0;
- if (prefix && negative) {
- return negPrefix;
- } else if (prefix) {
- return posPrefix;
- } else if (negative) {
- return negSuffix;
- } else {
- return posSuffix;
- }
- }
-
- @Override
- public boolean positiveHasPlusSign() {
- return AffixUtils.containsType(posPrefix, AffixUtils.TYPE_PLUS_SIGN)
- || AffixUtils.containsType(posSuffix, AffixUtils.TYPE_PLUS_SIGN);
- }
-
- @Override
- public boolean hasNegativeSubpattern() {
- // See comments in the constructor for more information on why this is always true.
- return true;
- }
-
- @Override
- public boolean negativeHasMinusSign() {
- return AffixUtils.containsType(negPrefix, AffixUtils.TYPE_MINUS_SIGN)
- || AffixUtils.containsType(negSuffix, AffixUtils.TYPE_MINUS_SIGN);
- }
-
- @Override
- public boolean hasCurrencySign() {
- return AffixUtils.hasCurrencySymbols(posPrefix) || AffixUtils.hasCurrencySymbols(posSuffix)
- || AffixUtils.hasCurrencySymbols(negPrefix) || AffixUtils.hasCurrencySymbols(negSuffix);
- }
-
- @Override
- public boolean containsSymbolType(int type) {
- return AffixUtils.containsType(posPrefix, type) || AffixUtils.containsType(posSuffix, type)
- || AffixUtils.containsType(negPrefix, type) || AffixUtils.containsType(negSuffix, type);
- }
- }
-
- private static class CurrencyPluralInfoAffixProvider implements AffixPatternProvider {
- private final AffixPatternProvider[] affixesByPlural;
-
- public CurrencyPluralInfoAffixProvider(CurrencyPluralInfo cpi) {
- affixesByPlural = new ParsedPatternInfo[StandardPlural.COUNT];
- for (StandardPlural plural : StandardPlural.VALUES) {
- affixesByPlural[plural.ordinal()] = PatternStringParser
- .parseToPatternInfo(cpi.getCurrencyPluralPattern(plural.getKeyword()));
- }
- }
-
- @Override
- public char charAt(int flags, int i) {
- int pluralOrdinal = (flags & Flags.PLURAL_MASK);
- return affixesByPlural[pluralOrdinal].charAt(flags, i);
- }
-
- @Override
- public int length(int flags) {
- int pluralOrdinal = (flags & Flags.PLURAL_MASK);
- return affixesByPlural[pluralOrdinal].length(flags);
- }
-
- @Override
- public boolean positiveHasPlusSign() {
- return affixesByPlural[StandardPlural.OTHER.ordinal()].positiveHasPlusSign();
- }
-
- @Override
- public boolean hasNegativeSubpattern() {
- return affixesByPlural[StandardPlural.OTHER.ordinal()].hasNegativeSubpattern();
- }
-
- @Override
- public boolean negativeHasMinusSign() {
- return affixesByPlural[StandardPlural.OTHER.ordinal()].negativeHasMinusSign();
- }
-
- @Override
- public boolean hasCurrencySign() {
- return affixesByPlural[StandardPlural.OTHER.ordinal()].hasCurrencySign();
- }
-
- @Override
- public boolean containsSymbolType(int type) {
- return affixesByPlural[StandardPlural.OTHER.ordinal()].containsSymbolType(type);
- }
- }
}

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b