]> granicus.if.org Git - icu/commitdiff
ICU-13177 Removes old (ICU 59) number formatting middleware since it has been wholly...
authorShane Carr <shane@unicode.org>
Thu, 24 Aug 2017 08:18:22 +0000 (08:18 +0000)
committerShane Carr <shane@unicode.org>
Thu, 24 Aug 2017 08:18:22 +0000 (08:18 +0000)
X-SVN-Rev: 40352

52 files changed:
icu4j/main/classes/core/src/com/ibm/icu/impl/number/AffixPatternUtils.java
icu4j/main/classes/core/src/com/ibm/icu/impl/number/Endpoint.java [deleted file]
icu4j/main/classes/core/src/com/ibm/icu/impl/number/Exportable.java [deleted file]
icu4j/main/classes/core/src/com/ibm/icu/impl/number/Format.java [deleted file]
icu4j/main/classes/core/src/com/ibm/icu/impl/number/FormatQuantity.java
icu4j/main/classes/core/src/com/ibm/icu/impl/number/FormatQuantity1.java
icu4j/main/classes/core/src/com/ibm/icu/impl/number/FormatQuantityBCD.java
icu4j/main/classes/core/src/com/ibm/icu/impl/number/FormatQuantitySelector.java [deleted file]
icu4j/main/classes/core/src/com/ibm/icu/impl/number/LdmlPatternInfo.java
icu4j/main/classes/core/src/com/ibm/icu/impl/number/Modifier.java
icu4j/main/classes/core/src/com/ibm/icu/impl/number/ModifierHolder.java [deleted file]
icu4j/main/classes/core/src/com/ibm/icu/impl/number/PNAffixGenerator.java [deleted file]
icu4j/main/classes/core/src/com/ibm/icu/impl/number/Parse.java
icu4j/main/classes/core/src/com/ibm/icu/impl/number/PatternString.java
icu4j/main/classes/core/src/com/ibm/icu/impl/number/Properties.java
icu4j/main/classes/core/src/com/ibm/icu/impl/number/Rounder.java [deleted file]
icu4j/main/classes/core/src/com/ibm/icu/impl/number/RoundingUtils.java
icu4j/main/classes/core/src/com/ibm/icu/impl/number/ThingsNeedingNewHome.java [new file with mode: 0644]
icu4j/main/classes/core/src/com/ibm/icu/impl/number/formatters/BigDecimalMultiplier.java [deleted file]
icu4j/main/classes/core/src/com/ibm/icu/impl/number/formatters/CompactDecimalFormat.java [deleted file]
icu4j/main/classes/core/src/com/ibm/icu/impl/number/formatters/CurrencyFormat.java [deleted file]
icu4j/main/classes/core/src/com/ibm/icu/impl/number/formatters/MagnitudeMultiplier.java [deleted file]
icu4j/main/classes/core/src/com/ibm/icu/impl/number/formatters/MeasureFormat.java [deleted file]
icu4j/main/classes/core/src/com/ibm/icu/impl/number/formatters/PaddingFormat.java [deleted file]
icu4j/main/classes/core/src/com/ibm/icu/impl/number/formatters/PositiveDecimalFormat.java [deleted file]
icu4j/main/classes/core/src/com/ibm/icu/impl/number/formatters/PositiveNegativeAffixFormat.java [deleted file]
icu4j/main/classes/core/src/com/ibm/icu/impl/number/formatters/RangeFormat.java [deleted file]
icu4j/main/classes/core/src/com/ibm/icu/impl/number/formatters/RoundingFormat.java [deleted file]
icu4j/main/classes/core/src/com/ibm/icu/impl/number/formatters/ScientificFormat.java [deleted file]
icu4j/main/classes/core/src/com/ibm/icu/impl/number/formatters/StrongAffixFormat.java [deleted file]
icu4j/main/classes/core/src/com/ibm/icu/impl/number/modifiers/ConstantAffixModifier.java
icu4j/main/classes/core/src/com/ibm/icu/impl/number/modifiers/ConstantMultiFieldModifier.java
icu4j/main/classes/core/src/com/ibm/icu/impl/number/modifiers/GeneralPluralModifier.java
icu4j/main/classes/core/src/com/ibm/icu/impl/number/modifiers/PositiveNegativeAffixModifier.java
icu4j/main/classes/core/src/com/ibm/icu/impl/number/modifiers/SimpleModifier.java
icu4j/main/classes/core/src/com/ibm/icu/impl/number/rounders/IncrementRounder.java [deleted file]
icu4j/main/classes/core/src/com/ibm/icu/impl/number/rounders/MagnitudeRounder.java [deleted file]
icu4j/main/classes/core/src/com/ibm/icu/impl/number/rounders/NoRounder.java [deleted file]
icu4j/main/classes/core/src/com/ibm/icu/impl/number/rounders/SignificantDigitsRounder.java [deleted file]
icu4j/main/classes/core/src/com/ibm/icu/text/DecimalFormat.java
icu4j/main/classes/core/src/newapi/NumberFormatter.java
icu4j/main/classes/core/src/newapi/impl/NumberFormatterImpl.java
icu4j/main/classes/core/src/newapi/impl/NumberPropertyMapper.java
icu4j/main/classes/core/src/newapi/impl/PaddingImpl.java
icu4j/main/classes/core/src/newapi/impl/PositiveDecimalImpl.java
icu4j/main/classes/core/src/newapi/impl/SkeletonBuilder.java
icu4j/main/tests/core/src/com/ibm/icu/dev/data/numberformattestspecification.txt
icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/NumberFormatDataDrivenTest.java
icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/AffixPatternUtilsTest.java
icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/FormatQuantityTest.java
icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberFormatterTest.java
icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/PropertiesTest.java

index 2a79cc56de04a2dcfec181a01f2e5cc27c10d40c..c49ad5ecdf5d29d131c1ed0064c542928f85540b 100644 (file)
@@ -2,7 +2,6 @@
 // License & terms of use: http://www.unicode.org/copyright.html#License
 package com.ibm.icu.impl.number;
 
-import com.ibm.icu.text.DecimalFormatSymbols;
 import com.ibm.icu.text.NumberFormat;
 
 /**
@@ -229,75 +228,6 @@ public class AffixPatternUtils {
     return sb.toString();
   }
 
-  /**
-   * Executes the unescape state machine. Replaces the unquoted characters "-", "+", "%", and "‰"
-   * with their localized equivalents. Replaces "¤", "¤¤", and "¤¤¤" with the three argument
-   * strings.
-   *
-   * <p>Example input: "'-'¤x"; example output: "-$x"
-   *
-   * @param affixPattern The original string to be unescaped.
-   * @param symbols An instance of {@link DecimalFormatSymbols} for the locale of interest.
-   * @param currency1 The string to replace "¤".
-   * @param currency2 The string to replace "¤¤".
-   * @param currency3 The string to replace "¤¤¤".
-   * @param minusSign The string to replace "-". If null, symbols.getMinusSignString() is used.
-   * @param output The {@link NumberStringBuilder} to which the result will be appended.
-   */
-  public static void unescape(
-      CharSequence affixPattern,
-      DecimalFormatSymbols symbols,
-      String currency1,
-      String currency2,
-      String currency3,
-      String minusSign,
-      NumberStringBuilder output) {
-    if (affixPattern == null || affixPattern.length() == 0) return;
-    if (minusSign == null) minusSign = symbols.getMinusSignString();
-    long tag = 0L;
-    while (hasNext(tag, affixPattern)) {
-      tag = nextToken(tag, affixPattern);
-      int typeOrCp = getTypeOrCp(tag);
-      NumberFormat.Field field = (typeOrCp < 0) ? getFieldForType(typeOrCp) : null;
-      switch (typeOrCp) {
-        case TYPE_MINUS_SIGN:
-          output.append(minusSign, field);
-          break;
-        case TYPE_PLUS_SIGN:
-          output.append(symbols.getPlusSignString(), field);
-          break;
-        case TYPE_PERCENT:
-          output.append(symbols.getPercentString(), field);
-          break;
-        case TYPE_PERMILLE:
-          output.append(symbols.getPerMillString(), field);
-          break;
-        case TYPE_CURRENCY_SINGLE:
-          output.append(currency1, field);
-          break;
-        case TYPE_CURRENCY_DOUBLE:
-          output.append(currency2, field);
-          break;
-        case TYPE_CURRENCY_TRIPLE:
-          output.append(currency3, field);
-          break;
-        case TYPE_CURRENCY_QUAD:
-          output.appendCodePoint('\uFFFD', field);
-          break;
-        case TYPE_CURRENCY_QUINT:
-          // TODO: Add support for narrow currency symbols here.
-          output.appendCodePoint('\uFFFD', field);
-          break;
-        case TYPE_CURRENCY_OVERFLOW:
-          output.appendCodePoint('\uFFFD', field);
-          break;
-        default:
-          output.appendCodePoint(typeOrCp, null);
-          break;
-      }
-    }
-  }
-
   public static final NumberFormat.Field getFieldForType(int type) {
     switch (type) {
       case TYPE_MINUS_SIGN:
@@ -329,6 +259,18 @@ public class AffixPatternUtils {
     public CharSequence getSymbol(int type);
   }
 
+  /**
+   * Executes the unescape state machine. Replaces the unquoted characters "-", "+", "%", "‰", and
+   * "¤" with the corresponding symbols provided by the {@link SymbolProvider}, and inserts the
+   * result into the NumberStringBuilder at the requested location.
+   *
+   * <p>Example input: "'-'¤x"; example output: "-$x"
+   *
+   * @param affixPattern The original string to be unescaped.
+   * @param output The NumberStringBuilder to mutate with the result.
+   * @param position The index into the NumberStringBuilder to insert the the string.
+   * @param provider An object to generate locale symbols.
+   */
   public static int unescape(
       CharSequence affixPattern,
       NumberStringBuilder output,
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/Endpoint.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/Endpoint.java
deleted file mode 100644 (file)
index abf8324..0000000
+++ /dev/null
@@ -1,298 +0,0 @@
-// © 2017 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html#License
-package com.ibm.icu.impl.number;
-
-import java.util.HashMap;
-import java.util.Locale;
-import java.util.Map;
-
-import com.ibm.icu.impl.number.Format.BeforeTargetAfterFormat;
-import com.ibm.icu.impl.number.Format.SingularFormat;
-import com.ibm.icu.impl.number.Format.TargetFormat;
-import com.ibm.icu.impl.number.formatters.BigDecimalMultiplier;
-import com.ibm.icu.impl.number.formatters.CompactDecimalFormat;
-import com.ibm.icu.impl.number.formatters.CurrencyFormat;
-import com.ibm.icu.impl.number.formatters.MagnitudeMultiplier;
-import com.ibm.icu.impl.number.formatters.MeasureFormat;
-import com.ibm.icu.impl.number.formatters.PaddingFormat;
-import com.ibm.icu.impl.number.formatters.PositiveDecimalFormat;
-import com.ibm.icu.impl.number.formatters.PositiveNegativeAffixFormat;
-import com.ibm.icu.impl.number.formatters.RoundingFormat;
-import com.ibm.icu.impl.number.formatters.ScientificFormat;
-import com.ibm.icu.text.DecimalFormatSymbols;
-import com.ibm.icu.text.PluralRules;
-import com.ibm.icu.util.ULocale;
-
-public class Endpoint {
-  //  public static Format from(DecimalFormatSymbols symbols, Properties properties)
-  //      throws ParseException {
-  //    Format format = new PositiveIntegerFormat(symbols, properties);
-  //    // TODO: integer-only format
-  //    format = new PositiveDecimalFormat((SelfContainedFormat) format, symbols, properties);
-  //    if (properties.useCompactDecimalFormat()) {
-  //      format = CompactDecimalFormat.getInstance((SingularFormat) format, symbols, properties);
-  //    } else {
-  //      format =
-  //          PositiveNegativeAffixFormat.getInstance((SingularFormat) format, symbols, properties);
-  //    }
-  //    if (properties.useRoundingInterval()) {
-  //      format = new IntervalRoundingFormat((SingularFormat) format, properties);
-  //    } else if (properties.useSignificantDigits()) {
-  //      format = new SignificantDigitsFormat((SingularFormat) format, properties);
-  //    } else if (properties.useFractionFormat()) {
-  //      format = new RoundingFormat((SingularFormat) format, properties);
-  //    }
-  //    return format;
-  //  }
-
-  public static interface IProperties {
-    static PluralRules DEFAULT_PLURAL_RULES = null;
-
-    public PluralRules getPluralRules();
-
-    public IProperties setPluralRules(PluralRules pluralRules);
-  }
-
-  public static Format fromBTA(Properties properties) {
-    return fromBTA(properties, getSymbols());
-  }
-
-  public static SingularFormat fromBTA(Properties properties, Locale locale) {
-    return fromBTA(properties, getSymbols(locale));
-  }
-
-  public static SingularFormat fromBTA(Properties properties, ULocale uLocale) {
-    return fromBTA(properties, getSymbols(uLocale));
-  }
-
-  public static SingularFormat fromBTA(String pattern) {
-    return fromBTA(getProperties(pattern), getSymbols());
-  }
-
-  public static SingularFormat fromBTA(String pattern, Locale locale) {
-    return fromBTA(getProperties(pattern), getSymbols(locale));
-  }
-
-  public static SingularFormat fromBTA(String pattern, ULocale uLocale) {
-    return fromBTA(getProperties(pattern), getSymbols(uLocale));
-  }
-
-  public static SingularFormat fromBTA(String pattern, DecimalFormatSymbols symbols) {
-    return fromBTA(getProperties(pattern), symbols);
-  }
-
-  public static SingularFormat fromBTA(Properties properties, DecimalFormatSymbols symbols) {
-
-    if (symbols == null) throw new IllegalArgumentException("symbols must not be null");
-
-    // TODO: This fast track results in an improvement of about 10ns during formatting.  See if
-    // there is a way to implement it more elegantly.
-    boolean canUseFastTrack = true;
-    PluralRules rules = getPluralRules(symbols.getULocale(), properties);
-    BeforeTargetAfterFormat format = new Format.BeforeTargetAfterFormat(rules);
-    TargetFormat target = new PositiveDecimalFormat(symbols, properties);
-    format.setTargetFormat(target);
-    // TODO: integer-only format?
-    if (MagnitudeMultiplier.useMagnitudeMultiplier(properties)) {
-      canUseFastTrack = false;
-      format.addBeforeFormat(MagnitudeMultiplier.getInstance(properties));
-    }
-    if (BigDecimalMultiplier.useMultiplier(properties)) {
-      canUseFastTrack = false;
-      format.addBeforeFormat(BigDecimalMultiplier.getInstance(properties));
-    }
-    if (MeasureFormat.useMeasureFormat(properties)) {
-      canUseFastTrack = false;
-      format.addBeforeFormat(MeasureFormat.getInstance(symbols, properties));
-    }
-    if (CurrencyFormat.useCurrency(properties)) {
-      canUseFastTrack = false;
-      if (CompactDecimalFormat.useCompactDecimalFormat(properties)) {
-        format.addBeforeFormat(CompactDecimalFormat.getInstance(symbols, properties));
-      } else if (ScientificFormat.useScientificNotation(properties)) {
-        // TODO: Should the currency rounder or scientific rounder be used in this case?
-        // For now, default to using the scientific rounder.
-        format.addBeforeFormat(PositiveNegativeAffixFormat.getInstance(symbols, properties));
-        format.addBeforeFormat(ScientificFormat.getInstance(symbols, properties));
-      } else {
-        format.addBeforeFormat(CurrencyFormat.getCurrencyRounder(symbols, properties));
-        format.addBeforeFormat(CurrencyFormat.getCurrencyModifier(symbols, properties));
-      }
-    } else {
-      if (CompactDecimalFormat.useCompactDecimalFormat(properties)) {
-        canUseFastTrack = false;
-        format.addBeforeFormat(CompactDecimalFormat.getInstance(symbols, properties));
-      } else if (ScientificFormat.useScientificNotation(properties)) {
-        canUseFastTrack = false;
-        format.addBeforeFormat(PositiveNegativeAffixFormat.getInstance(symbols, properties));
-        format.addBeforeFormat(ScientificFormat.getInstance(symbols, properties));
-      } else {
-        format.addBeforeFormat(PositiveNegativeAffixFormat.getInstance(symbols, properties));
-        format.addBeforeFormat(RoundingFormat.getDefaultOrNoRounder(properties));
-      }
-    }
-    if (PaddingFormat.usePadding(properties)) {
-      canUseFastTrack = false;
-      format.addAfterFormat(PaddingFormat.getInstance(properties));
-    }
-    if (canUseFastTrack) {
-      return new Format.PositiveNegativeRounderTargetFormat(
-          PositiveNegativeAffixFormat.getInstance(symbols, properties),
-          RoundingFormat.getDefaultOrNoRounder(properties),
-          target);
-    } else {
-      return format;
-    }
-  }
-
-  public static String staticFormat(FormatQuantity input, Properties properties) {
-    return staticFormat(input, properties, getSymbols());
-  }
-
-  public static String staticFormat(FormatQuantity input, Properties properties, Locale locale) {
-    return staticFormat(input, properties, getSymbols(locale));
-  }
-
-  public static String staticFormat(FormatQuantity input, Properties properties, ULocale uLocale) {
-    return staticFormat(input, properties, getSymbols(uLocale));
-  }
-
-  public static String staticFormat(FormatQuantity input, String pattern) {
-    return staticFormat(input, getProperties(pattern), getSymbols());
-  }
-
-  public static String staticFormat(FormatQuantity input, String pattern, Locale locale) {
-    return staticFormat(input, getProperties(pattern), getSymbols(locale));
-  }
-
-  public static String staticFormat(FormatQuantity input, String pattern, ULocale uLocale) {
-    return staticFormat(input, getProperties(pattern), getSymbols(uLocale));
-  }
-
-  public static String staticFormat(
-      FormatQuantity input, String pattern, DecimalFormatSymbols symbols) {
-    return staticFormat(input, getProperties(pattern), symbols);
-  }
-
-  public static String staticFormat(
-      FormatQuantity input, Properties properties, DecimalFormatSymbols symbols) {
-    PluralRules rules = null;
-    ModifierHolder mods = Format.threadLocalModifierHolder.get().clear();
-    NumberStringBuilder sb = Format.threadLocalStringBuilder.get().clear();
-    int length = 0;
-
-    // Pre-processing
-    if (!input.isNaN()) {
-      if (MagnitudeMultiplier.useMagnitudeMultiplier(properties)) {
-        MagnitudeMultiplier.getInstance(properties).before(input, mods, rules);
-      }
-      if (BigDecimalMultiplier.useMultiplier(properties)) {
-        BigDecimalMultiplier.getInstance(properties).before(input, mods, rules);
-      }
-      if (MeasureFormat.useMeasureFormat(properties)) {
-        rules = (rules != null) ? rules : getPluralRules(symbols.getULocale(), properties);
-        MeasureFormat.getInstance(symbols, properties).before(input, mods, rules);
-      }
-      if (CompactDecimalFormat.useCompactDecimalFormat(properties)) {
-        rules = (rules != null) ? rules : getPluralRules(symbols.getULocale(), properties);
-        CompactDecimalFormat.apply(input, mods, rules, symbols, properties);
-      } else if (CurrencyFormat.useCurrency(properties)) {
-        rules = (rules != null) ? rules : getPluralRules(symbols.getULocale(), properties);
-        CurrencyFormat.getCurrencyRounder(symbols, properties).before(input, mods, rules);
-        CurrencyFormat.getCurrencyModifier(symbols, properties).before(input, mods, rules);
-      } else if (ScientificFormat.useScientificNotation(properties)) {
-        // TODO: Is it possible to combine significant digits with currency?
-        PositiveNegativeAffixFormat.getInstance(symbols, properties).before(input, mods, rules);
-        ScientificFormat.getInstance(symbols, properties).before(input, mods, rules);
-      } else {
-        PositiveNegativeAffixFormat.apply(input, mods, symbols, properties);
-        RoundingFormat.getDefaultOrNoRounder(properties).before(input, mods, rules);
-      }
-    }
-
-    // Primary format step
-    length += new PositiveDecimalFormat(symbols, properties).target(input, sb, 0);
-    length += mods.applyStrong(sb, 0, length);
-
-    // Post-processing
-    if (PaddingFormat.usePadding(properties)) {
-      length += PaddingFormat.getInstance(properties).after(mods, sb, 0, length);
-    }
-    length += mods.applyAll(sb, 0, length);
-
-    return sb.toString();
-  }
-
-  private static final ThreadLocal<Map<ULocale, DecimalFormatSymbols>> threadLocalSymbolsCache =
-      new ThreadLocal<Map<ULocale, DecimalFormatSymbols>>() {
-        @Override
-        protected Map<ULocale, DecimalFormatSymbols> initialValue() {
-          return new HashMap<ULocale, DecimalFormatSymbols>();
-        }
-      };
-
-  private static DecimalFormatSymbols getSymbols() {
-    ULocale uLocale = ULocale.getDefault();
-    return getSymbols(uLocale);
-  }
-
-  private static DecimalFormatSymbols getSymbols(Locale locale) {
-    ULocale uLocale = ULocale.forLocale(locale);
-    return getSymbols(uLocale);
-  }
-
-  private static DecimalFormatSymbols getSymbols(ULocale uLocale) {
-    if (uLocale == null) uLocale = ULocale.getDefault();
-    DecimalFormatSymbols symbols = threadLocalSymbolsCache.get().get(uLocale);
-    if (symbols == null) {
-      symbols = DecimalFormatSymbols.getInstance(uLocale);
-      threadLocalSymbolsCache.get().put(uLocale, symbols);
-    }
-    return symbols;
-  }
-
-  private static final ThreadLocal<Map<String, Properties>> threadLocalPropertiesCache =
-      new ThreadLocal<Map<String, Properties>>() {
-        @Override
-        protected Map<String, Properties> initialValue() {
-          return new HashMap<String, Properties>();
-        }
-      };
-
-  private static Properties getProperties(String pattern) {
-    if (pattern == null) pattern = "#";
-    Properties properties = threadLocalPropertiesCache.get().get(pattern);
-    if (properties == null) {
-      properties = PatternString.parseToProperties(pattern);
-      threadLocalPropertiesCache.get().put(pattern.intern(), properties);
-    }
-    return properties;
-  }
-
-  private static final ThreadLocal<Map<ULocale, PluralRules>> threadLocalRulesCache =
-      new ThreadLocal<Map<ULocale, PluralRules>>() {
-        @Override
-        protected Map<ULocale, PluralRules> initialValue() {
-          return new HashMap<ULocale, PluralRules>();
-        }
-      };
-
-  private static PluralRules getPluralRules(ULocale uLocale, Properties properties) {
-    if (properties.getPluralRules() != null) {
-      return properties.getPluralRules();
-    }
-
-    // Backwards compatibility: CurrencyPluralInfo wraps its own copy of PluralRules
-    if (properties.getCurrencyPluralInfo() != null) {
-      return properties.getCurrencyPluralInfo().getPluralRules();
-    }
-
-    if (uLocale == null) uLocale = ULocale.getDefault();
-    PluralRules rules = threadLocalRulesCache.get().get(uLocale);
-    if (rules == null) {
-      rules = PluralRules.forLocale(uLocale);
-      threadLocalRulesCache.get().put(uLocale, rules);
-    }
-    return rules;
-  }
-}
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/Exportable.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/Exportable.java
deleted file mode 100644 (file)
index 515667d..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// © 2017 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html#License
-package com.ibm.icu.impl.number;
-
-/**
- * This is a small interface I made to assist with converting from a formatter pipeline object to a
- * pattern string. It allows classes to "export" themselves to a property bag, which in turn can be
- * passed to {@link PatternString#propertiesToString(Properties)} to generate the pattern string.
- *
- * <p>Depending on the new API we expose, this process might not be necessary if we persist the
- * property bag in the current DecimalFormat shim.
- */
-public interface Exportable {
-  public void export(Properties properties);
-}
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/Format.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/Format.java
deleted file mode 100644 (file)
index c19e924..0000000
+++ /dev/null
@@ -1,277 +0,0 @@
-// © 2017 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html#License
-package com.ibm.icu.impl.number;
-
-import java.text.AttributedCharacterIterator;
-import java.text.FieldPosition;
-import java.util.ArrayDeque;
-import java.util.Arrays;
-import java.util.Deque;
-
-import com.ibm.icu.text.PluralRules;
-
-// TODO: Get a better name for this base class.
-public abstract class Format {
-
-  protected static final ThreadLocal<NumberStringBuilder> threadLocalStringBuilder =
-      new ThreadLocal<NumberStringBuilder>() {
-        @Override
-        protected NumberStringBuilder initialValue() {
-          return new NumberStringBuilder();
-        }
-      };
-
-  protected static final ThreadLocal<ModifierHolder> threadLocalModifierHolder =
-      new ThreadLocal<ModifierHolder>() {
-        @Override
-        protected ModifierHolder initialValue() {
-          return new ModifierHolder();
-        }
-      };
-
-  public String format(FormatQuantity... inputs) {
-    // Setup
-    Deque<FormatQuantity> inputDeque = new ArrayDeque<FormatQuantity>();
-    inputDeque.addAll(Arrays.asList(inputs));
-    ModifierHolder modDeque = threadLocalModifierHolder.get().clear();
-    NumberStringBuilder sb = threadLocalStringBuilder.get().clear();
-
-    // Primary "recursion" step, calling the implementation's process method
-    int length = process(inputDeque, modDeque, sb, 0);
-
-    // Resolve remaining affixes
-    modDeque.applyAll(sb, 0, length);
-    return sb.toString();
-  }
-
-  /** A Format that works on only one number. */
-  public abstract static class SingularFormat extends Format implements Exportable {
-
-    public String format(FormatQuantity input) {
-      NumberStringBuilder sb = formatToStringBuilder(input);
-      return sb.toString();
-    }
-
-    public void format(FormatQuantity input, StringBuffer output) {
-      NumberStringBuilder sb = formatToStringBuilder(input);
-      output.append(sb);
-    }
-
-    public String format(FormatQuantity input, FieldPosition fp) {
-      NumberStringBuilder sb = formatToStringBuilder(input);
-      sb.populateFieldPosition(fp, 0);
-      return sb.toString();
-    }
-
-    public void format(FormatQuantity input, StringBuffer output, FieldPosition fp) {
-      NumberStringBuilder sb = formatToStringBuilder(input);
-      sb.populateFieldPosition(fp, output.length());
-      output.append(sb);
-    }
-
-    public AttributedCharacterIterator formatToCharacterIterator(FormatQuantity input) {
-      NumberStringBuilder sb = formatToStringBuilder(input);
-      return sb.getIterator();
-    }
-
-    private NumberStringBuilder formatToStringBuilder(FormatQuantity input) {
-      // Setup
-      ModifierHolder modDeque = threadLocalModifierHolder.get().clear();
-      NumberStringBuilder sb = threadLocalStringBuilder.get().clear();
-
-      // Primary "recursion" step, calling the implementation's process method
-      int length = process(input, modDeque, sb, 0);
-
-      // Resolve remaining affixes
-      length += modDeque.applyAll(sb, 0, length);
-      return sb;
-    }
-
-    @Override
-    public int process(
-        Deque<FormatQuantity> input,
-        ModifierHolder mods,
-        NumberStringBuilder string,
-        int startIndex) {
-      return process(input.removeFirst(), mods, string, startIndex);
-    }
-
-    public abstract int process(
-        FormatQuantity input, ModifierHolder mods, NumberStringBuilder string, int startIndex);
-  }
-
-  public static class BeforeTargetAfterFormat extends SingularFormat {
-    // The formatters are kept as individual fields to avoid extra object creation overhead.
-    private BeforeFormat before1 = null;
-    private BeforeFormat before2 = null;
-    private BeforeFormat before3 = null;
-    private TargetFormat target = null;
-    private AfterFormat after1 = null;
-    private AfterFormat after2 = null;
-    private AfterFormat after3 = null;
-    private final PluralRules rules;
-
-    public BeforeTargetAfterFormat(PluralRules rules) {
-      this.rules = rules;
-    }
-
-    public void addBeforeFormat(BeforeFormat before) {
-      if (before1 == null) {
-        before1 = before;
-      } else if (before2 == null) {
-        before2 = before;
-      } else if (before3 == null) {
-        before3 = before;
-      } else {
-        throw new IllegalArgumentException("Only three BeforeFormats are allowed at a time");
-      }
-    }
-
-    public void setTargetFormat(TargetFormat target) {
-      this.target = target;
-    }
-
-    public void addAfterFormat(AfterFormat after) {
-      if (after1 == null) {
-        after1 = after;
-      } else if (after2 == null) {
-        after2 = after;
-      } else if (after3 == null) {
-        after3 = after;
-      } else {
-        throw new IllegalArgumentException("Only three AfterFormats are allowed at a time");
-      }
-    }
-
-    @Override
-    public String format(FormatQuantity input) {
-      ModifierHolder mods = threadLocalModifierHolder.get().clear();
-      NumberStringBuilder sb = threadLocalStringBuilder.get().clear();
-      int length = process(input, mods, sb, 0);
-      mods.applyAll(sb, 0, length);
-      return sb.toString();
-    }
-
-    @Override
-    public int process(
-        FormatQuantity input, ModifierHolder mods, NumberStringBuilder string, int startIndex) {
-      // Special case: modifiers are skipped for NaN
-      int length = 0;
-      if (!input.isNaN()) {
-        if (before1 != null) {
-          before1.before(input, mods, rules);
-        }
-        if (before2 != null) {
-          before2.before(input, mods, rules);
-        }
-        if (before3 != null) {
-          before3.before(input, mods, rules);
-        }
-      }
-      length = target.target(input, string, startIndex);
-      length += mods.applyStrong(string, startIndex, startIndex + length);
-      if (after1 != null) {
-        length += after1.after(mods, string, startIndex, startIndex + length);
-      }
-      if (after2 != null) {
-        length += after2.after(mods, string, startIndex, startIndex + length);
-      }
-      if (after3 != null) {
-        length += after3.after(mods, string, startIndex, startIndex + length);
-      }
-      return length;
-    }
-
-    @Override
-    public void export(Properties properties) {
-      if (before1 != null) {
-        before1.export(properties);
-      }
-      if (before2 != null) {
-        before2.export(properties);
-      }
-      if (before3 != null) {
-        before3.export(properties);
-      }
-      target.export(properties);
-      if (after1 != null) {
-        after1.export(properties);
-      }
-      if (after2 != null) {
-        after2.export(properties);
-      }
-      if (after3 != null) {
-        after3.export(properties);
-      }
-    }
-  }
-
-  public static class PositiveNegativeRounderTargetFormat extends SingularFormat {
-    private final Modifier.PositiveNegativeModifier positiveNegative;
-    private final Rounder rounder;
-    private final TargetFormat target;
-
-    public PositiveNegativeRounderTargetFormat(
-        Modifier.PositiveNegativeModifier positiveNegative, Rounder rounder, TargetFormat target) {
-      this.positiveNegative = positiveNegative;
-      this.rounder = rounder;
-      this.target = target;
-    }
-
-    @Override
-    public String format(FormatQuantity input) {
-      NumberStringBuilder sb = threadLocalStringBuilder.get().clear();
-      process(input, null, sb, 0);
-      return sb.toString();
-    }
-
-    @Override
-    public int process(
-        FormatQuantity input, ModifierHolder mods, NumberStringBuilder string, int startIndex) {
-      // Special case: modifiers are skipped for NaN
-      Modifier mod = null;
-      rounder.apply(input);
-      if (!input.isNaN() && positiveNegative != null) {
-        mod = positiveNegative.getModifier(input.isNegative());
-      }
-      int length = target.target(input, string, startIndex);
-      if (mod != null) {
-        length += mod.apply(string, 0, length);
-      }
-      return length;
-    }
-
-    @Override
-    public void export(Properties properties) {
-      rounder.export(properties);
-      positiveNegative.export(properties);
-      target.export(properties);
-    }
-  }
-
-  public abstract static class BeforeFormat implements Exportable {
-    protected abstract void before(FormatQuantity input, ModifierHolder mods);
-
-    @SuppressWarnings("unused")
-    public void before(FormatQuantity input, ModifierHolder mods, PluralRules rules) {
-      before(input, mods);
-    }
-  }
-
-  public static interface TargetFormat extends Exportable {
-    public abstract int target(FormatQuantity input, NumberStringBuilder string, int startIndex);
-  }
-
-  public static interface AfterFormat extends Exportable {
-    public abstract int after(
-        ModifierHolder mods, NumberStringBuilder string, int leftIndex, int rightIndex);
-  }
-
-  // Instead of Dequeue<BigDecimal>, it could be Deque<Quantity> where
-  // we control the API of Quantity
-  public abstract int process(
-      Deque<FormatQuantity> inputs,
-      ModifierHolder outputMods,
-      NumberStringBuilder outputString,
-      int startIndex);
-}
index aa80a422948796427f20c2c99743f00bad45f42d..c0f869bbf7046416476f7f4091fcacaa6de675ab 100644 (file)
@@ -4,9 +4,11 @@ package com.ibm.icu.impl.number;
 
 import java.math.BigDecimal;
 import java.math.MathContext;
+import java.text.FieldPosition;
 
 import com.ibm.icu.impl.StandardPlural;
 import com.ibm.icu.text.PluralRules;
+import com.ibm.icu.text.UFieldPosition;
 
 /**
  * An interface representing a number to be processed by the decimal formatting pipeline. Includes
@@ -186,4 +188,13 @@ public interface FormatQuantity extends PluralRules.IFixedDecimal {
 
   /** This method is for internal testing only. */
   public long getPositionFingerprint();
+
+  /**
+   * If the given {@link FieldPosition} is a {@link UFieldPosition}, populates it with the fraction
+   * length and fraction long value. If the argument is not a {@link UFieldPosition}, nothing
+   * happens.
+   *
+   * @param fp The {@link UFieldPosition} to populate.
+   */
+  public void populateUFieldPosition(FieldPosition fp);
 }
index d6820b202cd2819b6c41662368cf2e0d5eb58bef..e68cf99bbfee0fd7cbb091f40793841d5c4bafa7 100644 (file)
@@ -5,10 +5,12 @@ package com.ibm.icu.impl.number;
 import java.math.BigDecimal;
 import java.math.MathContext;
 import java.math.RoundingMode;
+import java.text.FieldPosition;
 
 import com.ibm.icu.impl.StandardPlural;
 import com.ibm.icu.text.PluralRules;
 import com.ibm.icu.text.PluralRules.Operand;
+import com.ibm.icu.text.UFieldPosition;
 
 /**
  * This is an older implementation of FormatQuantity. A newer, faster implementation is
@@ -862,4 +864,12 @@ public class FormatQuantity1 implements FormatQuantity {
       return i;
     }
   }
+
+  @Override
+  public void populateUFieldPosition(FieldPosition fp) {
+    if (fp instanceof UFieldPosition) {
+      ((UFieldPosition) fp)
+          .setFractionDigits((int) getPluralOperand(Operand.v), (long) getPluralOperand(Operand.f));
+    }
+  }
 }
index 0d6e82f87ac6c378f5cbac44ac56561fb89b54a2..90416bfa13782668d0ba9e27198fe8098da8bb47 100644 (file)
@@ -243,13 +243,7 @@ public abstract class FormatQuantityBCD implements FormatQuantity {
     }
   }
 
-  /**
-   * If the given {@link FieldPosition} is a {@link UFieldPosition}, populates it with the fraction
-   * length and fraction long value. If the argument is not a {@link UFieldPosition}, nothing
-   * happens.
-   *
-   * @param fp The {@link UFieldPosition} to populate.
-   */
+  @Override
   public void populateUFieldPosition(FieldPosition fp) {
     if (fp instanceof UFieldPosition) {
       ((UFieldPosition) fp)
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/FormatQuantitySelector.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/FormatQuantitySelector.java
deleted file mode 100644 (file)
index 95a11ba..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-// © 2017 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html#License
-package com.ibm.icu.impl.number;
-
-import java.math.BigDecimal;
-import java.math.BigInteger;
-
-/** @author sffc */
-public class FormatQuantitySelector {
-  public static FormatQuantityBCD from(int input) {
-    return new FormatQuantity4(input);
-  }
-
-  public static FormatQuantityBCD from(long input) {
-    return new FormatQuantity4(input);
-  }
-
-  public static FormatQuantityBCD from(double input) {
-    return new FormatQuantity4(input);
-  }
-
-  public static FormatQuantityBCD from(BigInteger input) {
-    return new FormatQuantity4(input);
-  }
-
-  public static FormatQuantityBCD from(BigDecimal input) {
-    return new FormatQuantity4(input);
-  }
-
-  public static FormatQuantityBCD from(com.ibm.icu.math.BigDecimal input) {
-    return from(input.toBigDecimal());
-  }
-
-  public static FormatQuantityBCD from(Number number) {
-    if (number instanceof Long) {
-      return from(number.longValue());
-    } else if (number instanceof Integer) {
-      return from(number.intValue());
-    } else if (number instanceof Double) {
-      return from(number.doubleValue());
-    } else if (number instanceof BigInteger) {
-      return from((BigInteger) number);
-    } else if (number instanceof BigDecimal) {
-      return from((BigDecimal) number);
-    } else if (number instanceof com.ibm.icu.math.BigDecimal) {
-      return from((com.ibm.icu.math.BigDecimal) number);
-    } else {
-      throw new IllegalArgumentException(
-          "Number is of an unsupported type: " + number.getClass().getName());
-    }
-  }
-}
index ef0781ab4b02fda89bb83b54462754f5c3fbd3e1..745b4d3344cc450e8bdb4505d1b83bd1b832afd8 100644 (file)
@@ -2,7 +2,7 @@
 // License & terms of use: http://www.unicode.org/copyright.html#License
 package com.ibm.icu.impl.number;
 
-import com.ibm.icu.impl.number.formatters.PaddingFormat.PadPosition;
+import com.ibm.icu.impl.number.ThingsNeedingNewHome.PadPosition;
 
 import newapi.impl.AffixPatternProvider;
 
index c05d7a110b67b25be209d42a123a74af6483955e..10b5e05ca00f1402e1689356d1698afb9466e7c4 100644 (file)
@@ -69,7 +69,7 @@ public interface Modifier {
    * class implementing {@link PositiveNegativeModifier} is not necessarily a {@link Modifier}
    * itself. Rather, it returns a {@link Modifier} when {@link #getModifier} is called.
    */
-  public static interface PositiveNegativeModifier extends Exportable {
+  public static interface PositiveNegativeModifier {
     /**
      * Converts this {@link PositiveNegativeModifier} to a {@link Modifier} given the negative sign.
      *
@@ -86,7 +86,7 @@ public interface Modifier {
    * necessarily a {@link Modifier} itself. Rather, it returns a {@link Modifier} when {@link
    * #getModifier} is called.
    */
-  public static interface PositiveNegativePluralModifier extends Exportable {
+  public static interface PositiveNegativePluralModifier {
     /**
      * Converts this {@link PositiveNegativePluralModifier} to a {@link Modifier} given the negative
      * sign and the standard plural.
@@ -111,13 +111,7 @@ public interface Modifier {
    * <p>Implements {@link PositiveNegativeModifier} only so that instances of this class can be used
    * when a {@link PositiveNegativeModifier} is required.
    */
-  public abstract static class BaseModifier extends Format.BeforeFormat
-      implements Modifier, PositiveNegativeModifier {
-
-    @Override
-    public void before(FormatQuantity input, ModifierHolder mods) {
-      mods.add(this);
-    }
+  public abstract static class BaseModifier implements Modifier, PositiveNegativeModifier {
 
     @Override
     public Modifier getModifier(boolean isNegative) {
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/ModifierHolder.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/ModifierHolder.java
deleted file mode 100644 (file)
index a35647c..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-// © 2017 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html#License
-package com.ibm.icu.impl.number;
-
-import java.util.ArrayDeque;
-
-public class ModifierHolder {
-  private ArrayDeque<Modifier> mods = new ArrayDeque<Modifier>();
-
-  // Using five separate fields instead of the ArrayDeque saves about 10ns at the expense of
-  // worse code.
-  // TODO: Decide which implementation to use.
-
-  //    private Modifier mod1 = null;
-  //    private Modifier mod2 = null;
-  //    private Modifier mod3 = null;
-  //    private Modifier mod4 = null;
-  //    private Modifier mod5 = null;
-
-  public ModifierHolder createCopy() {
-    ModifierHolder copy = new ModifierHolder();
-    copy.mods.addAll(mods);
-    return copy;
-  }
-
-  public ModifierHolder clear() {
-    //      mod1 = null;
-    //      mod2 = null;
-    //      mod3 = null;
-    //      mod4 = null;
-    //      mod5 = null;
-    mods.clear();
-    return this;
-  }
-
-  public void add(Modifier modifier) {
-    //      if (mod1 == null) {
-    //        mod1 = modifier;
-    //      } else if (mod2 == null) {
-    //        mod2 = modifier;
-    //      } else if (mod3 == null) {
-    //        mod3 = modifier;
-    //      } else if (mod4 == null) {
-    //        mod4 = modifier;
-    //      } else if (mod5 == null) {
-    //        mod5 = modifier;
-    //      } else {
-    //        throw new IndexOutOfBoundsException();
-    //      }
-    if (modifier != null) mods.addFirst(modifier);
-  }
-
-  public Modifier peekLast() {
-    return mods.peekLast();
-  }
-
-  public Modifier removeLast() {
-    return mods.removeLast();
-  }
-
-  public int applyAll(NumberStringBuilder string, int leftIndex, int rightIndex) {
-    int addedLength = 0;
-    //      if (mod5 != null) {
-    //        addedLength += mod5.apply(string, leftIndex, rightIndex + addedLength);
-    //        mod5 = null;
-    //      }
-    //      if (mod4 != null) {
-    //        addedLength += mod4.apply(string, leftIndex, rightIndex + addedLength);
-    //        mod4 = null;
-    //      }
-    //      if (mod3 != null) {
-    //        addedLength += mod3.apply(string, leftIndex, rightIndex + addedLength);
-    //        mod3 = null;
-    //      }
-    //      if (mod2 != null) {
-    //        addedLength += mod2.apply(string, leftIndex, rightIndex + addedLength);
-    //        mod2 = null;
-    //      }
-    //      if (mod1 != null) {
-    //        addedLength += mod1.apply(string, leftIndex, rightIndex + addedLength);
-    //        mod1 = null;
-    //      }
-    while (!mods.isEmpty()) {
-      Modifier mod = mods.removeFirst();
-      addedLength += mod.apply(string, leftIndex, rightIndex + addedLength);
-    }
-    return addedLength;
-  }
-
-  public int applyStrong(NumberStringBuilder string, int leftIndex, int rightIndex) {
-    int addedLength = 0;
-    while (!mods.isEmpty() && mods.peekFirst().isStrong()) {
-      Modifier mod = mods.removeFirst();
-      addedLength += mod.apply(string, leftIndex, rightIndex + addedLength);
-    }
-    return addedLength;
-  }
-}
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/PNAffixGenerator.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/PNAffixGenerator.java
deleted file mode 100644 (file)
index f50704b..0000000
+++ /dev/null
@@ -1,281 +0,0 @@
-// © 2017 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html#License
-package com.ibm.icu.impl.number;
-
-import com.ibm.icu.impl.number.Modifier.AffixModifier;
-import com.ibm.icu.impl.number.formatters.CompactDecimalFormat;
-import com.ibm.icu.impl.number.formatters.PositiveNegativeAffixFormat;
-import com.ibm.icu.impl.number.formatters.PositiveNegativeAffixFormat.IProperties;
-import com.ibm.icu.impl.number.modifiers.ConstantAffixModifier;
-import com.ibm.icu.impl.number.modifiers.ConstantMultiFieldModifier;
-import com.ibm.icu.text.DecimalFormatSymbols;
-import com.ibm.icu.text.NumberFormat.Field;
-
-/**
- * A class to convert from a bag of prefix/suffix properties into a positive and negative {@link
- * Modifier}. This is a standard implementation used by {@link PositiveNegativeAffixFormat}, {@link
- * CompactDecimalFormat}, {@link Parse}, and others.
- *
- * <p>This class is is intended to be an efficient generator for instances of Modifier by a single
- * thread during construction of a formatter or during static formatting. It uses internal caching
- * to avoid creating new Modifier objects when possible. It is NOT THREAD SAFE and NOT IMMUTABLE.
- *
- * <p>The thread-local instance of this class provided by {@link #getThreadLocalInstance} should be
- * used in most cases instead of constructing a new instance of the object.
- *
- * <p>This class also handles the logic of assigning positive signs, negative signs, and currency
- * signs according to the LDML specification.
- */
-public class PNAffixGenerator {
-  public static class Result {
-    public AffixModifier positive = null;
-    public AffixModifier negative = null;
-  }
-
-  protected static final ThreadLocal<PNAffixGenerator> threadLocalInstance =
-      new ThreadLocal<PNAffixGenerator>() {
-        @Override
-        protected PNAffixGenerator initialValue() {
-          return new PNAffixGenerator();
-        }
-      };
-
-  public static PNAffixGenerator getThreadLocalInstance() {
-    return threadLocalInstance.get();
-  }
-
-  // These instances are used internally and cached to avoid object creation.  The resultInstance
-  // also serves as a 1-element cache to avoid creating objects when subsequent calls have
-  // identical prefixes and suffixes.  This happens, for example, when consuming CDF data.
-  private Result resultInstance = new Result();
-  private NumberStringBuilder sb1 = new NumberStringBuilder();
-  private NumberStringBuilder sb2 = new NumberStringBuilder();
-  private NumberStringBuilder sb3 = new NumberStringBuilder();
-  private NumberStringBuilder sb4 = new NumberStringBuilder();
-  private NumberStringBuilder sb5 = new NumberStringBuilder();
-  private NumberStringBuilder sb6 = new NumberStringBuilder();
-
-  /**
-   * Generates modifiers using default currency symbols.
-   *
-   * @param symbols The symbols to interpolate for minus, plus, percent, permille, and currency.
-   * @param properties The bag of properties to convert.
-   * @return The positive and negative {@link Modifier}.
-   */
-  public Result getModifiers(
-      DecimalFormatSymbols symbols, PositiveNegativeAffixFormat.IProperties properties) {
-    // If this method is used, the user doesn't care about currencies. Default the currency symbols
-    // to the information we can get from the DecimalFormatSymbols instance.
-    return getModifiers(
-        symbols,
-        symbols.getCurrencySymbol(),
-        symbols.getInternationalCurrencySymbol(),
-        symbols.getCurrencySymbol(),
-        properties);
-  }
-
-  /**
-   * Generates modifiers using the specified currency symbol for all three lengths of currency
-   * placeholders in the pattern string.
-   *
-   * @param symbols The symbols to interpolate for minus, plus, percent, and permille.
-   * @param currencySymbol The currency symbol.
-   * @param properties The bag of properties to convert.
-   * @return The positive and negative {@link Modifier}.
-   */
-  public Result getModifiers(
-      DecimalFormatSymbols symbols,
-      String currencySymbol,
-      PositiveNegativeAffixFormat.IProperties properties) {
-    // If this method is used, the user doesn't cares about currencies but doesn't care about
-    // supporting all three sizes of currency placeholders.  Use the one provided string for all
-    // three sizes of placeholders.
-    return getModifiers(symbols, currencySymbol, currencySymbol, currencySymbol, properties);
-  }
-
-  /**
-   * Generates modifiers using the three specified strings to replace the three lengths of currency
-   * placeholders: "¤", "¤¤", and "¤¤¤".
-   *
-   * @param symbols The symbols to interpolate for minus, plus, percent, and permille.
-   * @param curr1 The string to replace "¤".
-   * @param curr2 The string to replace "¤¤".
-   * @param curr3 The string to replace "¤¤¤".
-   * @param properties The bag of properties to convert.
-   * @return The positive and negative {@link Modifier}.
-   */
-  public Result getModifiers(
-      DecimalFormatSymbols symbols,
-      String curr1,
-      String curr2,
-      String curr3,
-      PositiveNegativeAffixFormat.IProperties properties) {
-
-    // Use a different code path for handling affixes with "always show plus sign"
-    if (properties.getSignAlwaysShown()) {
-      return getModifiersWithPlusSign(symbols, curr1, curr2, curr3, properties);
-    }
-
-    String ppp = properties.getPositivePrefixPattern();
-    String psp = properties.getPositiveSuffixPattern();
-    String npp = properties.getNegativePrefixPattern();
-    String nsp = properties.getNegativeSuffixPattern();
-
-    // Set sb1/sb2 to the positive prefix/suffix.
-    sb1.clear();
-    sb2.clear();
-    AffixPatternUtils.unescape(ppp, symbols, curr1, curr2, curr3, null, sb1);
-    AffixPatternUtils.unescape(psp, symbols, curr1, curr2, curr3, null, sb2);
-    setPositiveResult(sb1, sb2, properties);
-
-    // Set sb1/sb2 to the negative prefix/suffix.
-    if (npp == null && nsp == null) {
-      // Negative prefix defaults to positive prefix prepended with the minus sign.
-      // Negative suffix defaults to positive suffix.
-      sb1.insert(0, symbols.getMinusSignString(), Field.SIGN);
-    } else {
-      sb1.clear();
-      sb2.clear();
-      AffixPatternUtils.unescape(npp, symbols, curr1, curr2, curr3, null, sb1);
-      AffixPatternUtils.unescape(nsp, symbols, curr1, curr2, curr3, null, sb2);
-    }
-    setNegativeResult(sb1, sb2, properties);
-
-    return resultInstance;
-  }
-
-  private Result getModifiersWithPlusSign(
-      DecimalFormatSymbols symbols,
-      String curr1,
-      String curr2,
-      String curr3,
-      IProperties properties) {
-
-    String ppp = properties.getPositivePrefixPattern();
-    String psp = properties.getPositiveSuffixPattern();
-    String npp = properties.getNegativePrefixPattern();
-    String nsp = properties.getNegativeSuffixPattern();
-
-    // There are three cases, listed below with their expected outcomes.
-    // TODO: Should we handle the cases when the positive subpattern has a '+' already?
-    //
-    //   1) No negative subpattern.
-    //        Positive => Positive subpattern prepended with '+'
-    //        Negative => Positive subpattern prepended with '-'
-    //   2) Negative subpattern does not have '-'.
-    //        Positive => Positive subpattern prepended with '+'
-    //        Negative => Negative subpattern
-    //   3) Negative subpattern has '-'.
-    //        Positive => Negative subpattern with '+' substituted for '-'
-    //        Negative => Negative subpattern
-
-    if (npp != null || nsp != null) {
-      // Case 2 or Case 3
-      sb1.clear();
-      sb2.clear();
-      sb3.clear();
-      sb4.clear();
-      AffixPatternUtils.unescape(npp, symbols, curr1, curr2, curr3, null, sb1);
-      AffixPatternUtils.unescape(nsp, symbols, curr1, curr2, curr3, null, sb2);
-      AffixPatternUtils.unescape(
-          npp, symbols, curr1, curr2, curr3, symbols.getPlusSignString(), sb3);
-      AffixPatternUtils.unescape(
-          nsp, symbols, curr1, curr2, curr3, symbols.getPlusSignString(), sb4);
-      if (!charSequenceEquals(sb1, sb3) || !charSequenceEquals(sb2, sb4)) {
-        // Case 3. The plus sign substitution was successful.
-        setPositiveResult(sb3, sb4, properties);
-        setNegativeResult(sb1, sb2, properties);
-        return resultInstance;
-      } else {
-        // Case 2. There was no minus sign. Set the negative result and fall through.
-        setNegativeResult(sb1, sb2, properties);
-      }
-    }
-
-    // Case 1 or 2. Set sb1/sb2 to the positive prefix/suffix.
-    sb1.clear();
-    sb2.clear();
-    AffixPatternUtils.unescape(ppp, symbols, curr1, curr2, curr3, null, sb1);
-    AffixPatternUtils.unescape(psp, symbols, curr1, curr2, curr3, null, sb2);
-
-    if (npp == null && nsp == null) {
-      // Case 1. Compute the negative result from the positive subpattern.
-      sb3.clear();
-      sb3.append(symbols.getMinusSignString(), Field.SIGN);
-      sb3.append(sb1);
-      setNegativeResult(sb3, sb2, properties);
-    }
-
-    // Case 1 or 2. Prepend a '+' sign to the positive prefix.
-    sb1.insert(0, symbols.getPlusSignString(), Field.SIGN);
-    setPositiveResult(sb1, sb2, properties);
-
-    return resultInstance;
-  }
-
-  private void setPositiveResult(
-      NumberStringBuilder prefix, NumberStringBuilder suffix, IProperties properties) {
-    // Override with custom affixes. We need to put these into NumberStringBuilders so that they
-    // have the same datatype as the incoming prefix and suffix (important when testing for field
-    // equality in contentEquals).
-    // TODO: It is a little inefficient that we copy String -> NumberStringBuilder -> Modifier.
-    // Consider re-working the logic so that fewer copies are required.
-    String _prefix = properties.getPositivePrefix();
-    String _suffix = properties.getPositiveSuffix();
-    if (_prefix != null) {
-      prefix = sb5.clear();
-      prefix.append(_prefix, null);
-    }
-    if (_suffix != null) {
-      suffix = sb6.clear();
-      suffix.append(_suffix, null);
-    }
-    if (prefix.length() == 0 && suffix.length() == 0) {
-      resultInstance.positive = ConstantAffixModifier.EMPTY;
-      return;
-    }
-    if (resultInstance.positive != null
-        && (resultInstance.positive instanceof ConstantMultiFieldModifier)
-        && ((ConstantMultiFieldModifier) resultInstance.positive).contentEquals(prefix, suffix)) {
-      // Use the cached modifier
-      return;
-    }
-    resultInstance.positive = new ConstantMultiFieldModifier(prefix, suffix, false);
-  }
-
-  private void setNegativeResult(
-      NumberStringBuilder prefix, NumberStringBuilder suffix, IProperties properties) {
-    String _prefix = properties.getNegativePrefix();
-    String _suffix = properties.getNegativeSuffix();
-    if (_prefix != null) {
-      prefix = sb5.clear();
-      prefix.append(_prefix, null);
-    }
-    if (_suffix != null) {
-      suffix = sb6.clear();
-      suffix.append(_suffix, null);
-    }
-    if (prefix.length() == 0 && suffix.length() == 0) {
-      resultInstance.negative = ConstantAffixModifier.EMPTY;
-      return;
-    }
-    if (resultInstance.negative != null
-        && (resultInstance.negative instanceof ConstantMultiFieldModifier)
-        && ((ConstantMultiFieldModifier) resultInstance.negative).contentEquals(prefix, suffix)) {
-      // Use the cached modifier
-      return;
-    }
-    resultInstance.negative = new ConstantMultiFieldModifier(prefix, suffix, false);
-  }
-
-  /** A null-safe equals method for CharSequences. */
-  private static boolean charSequenceEquals(CharSequence a, CharSequence b) {
-    if (a == b) return true;
-    if (a == null || b == null) return false;
-    if (a.length() != b.length()) return false;
-    for (int i = 0; i < a.length(); i++) {
-      if (a.charAt(i) != b.charAt(i)) return false;
-    }
-    return true;
-  }
-}
index 1cd6134434c8aec4b6994372a01a8b6650a9a154..e921a2eedeb91cd934246dbd0ea9e3bb68f91800 100644 (file)
@@ -13,13 +13,6 @@ import java.util.concurrent.ConcurrentHashMap;
 
 import com.ibm.icu.impl.StandardPlural;
 import com.ibm.icu.impl.TextTrieMap;
-import com.ibm.icu.impl.number.formatters.BigDecimalMultiplier;
-import com.ibm.icu.impl.number.formatters.CurrencyFormat;
-import com.ibm.icu.impl.number.formatters.MagnitudeMultiplier;
-import com.ibm.icu.impl.number.formatters.PaddingFormat;
-import com.ibm.icu.impl.number.formatters.PositiveDecimalFormat;
-import com.ibm.icu.impl.number.formatters.PositiveNegativeAffixFormat;
-import com.ibm.icu.impl.number.formatters.ScientificFormat;
 import com.ibm.icu.lang.UCharacter;
 import com.ibm.icu.text.CurrencyPluralInfo;
 import com.ibm.icu.text.DecimalFormatSymbols;
@@ -95,139 +88,6 @@ public class Parse {
     FAST,
   }
 
-  /** The set of properties required for {@link Parse}. Accepts a {@link Properties} object. */
-  public static interface IProperties
-      extends PositiveNegativeAffixFormat.IProperties,
-          PaddingFormat.IProperties,
-          CurrencyFormat.ICurrencyProperties,
-          BigDecimalMultiplier.IProperties,
-          MagnitudeMultiplier.IProperties,
-          PositiveDecimalFormat.IProperties,
-          ScientificFormat.IProperties {
-
-    boolean DEFAULT_PARSE_INTEGER_ONLY = false;
-
-    /** @see #setParseIntegerOnly */
-    public boolean getParseIntegerOnly();
-
-    /**
-     * Whether to ignore the fractional part of numbers. For example, parses "123.4" to "123"
-     * instead of "123.4".
-     *
-     * @param parseIntegerOnly true to parse integers only; false to parse integers with their
-     *     fraction parts
-     * @return The property bag, for chaining.
-     */
-    public IProperties setParseIntegerOnly(boolean parseIntegerOnly);
-
-    boolean DEFAULT_PARSE_NO_EXPONENT = false;
-
-    /** @see #setParseNoExponent */
-    public boolean getParseNoExponent();
-
-    /**
-     * Whether to ignore the exponential part of numbers. For example, parses "123E4" to "123"
-     * instead of "1230000".
-     *
-     * @param parseIgnoreExponent true to ignore exponents; false to parse them.
-     * @return The property bag, for chaining.
-     */
-    public IProperties setParseNoExponent(boolean parseIgnoreExponent);
-
-    boolean DEFAULT_DECIMAL_PATTERN_MATCH_REQUIRED = false;
-
-    /** @see #setDecimalPatternMatchRequired */
-    public boolean getDecimalPatternMatchRequired();
-
-    /**
-     * Whether to require that the presence of decimal point matches the pattern. If a decimal point
-     * is not present, but the pattern contained a decimal point, parse will not succeed: null will
-     * be returned from <code>parse()</code>, and an error index will be set in the {@link
-     * ParsePosition}.
-     *
-     * @param decimalPatternMatchRequired true to set an error if decimal is not present
-     * @return The property bag, for chaining.
-     */
-    public IProperties setDecimalPatternMatchRequired(boolean decimalPatternMatchRequired);
-
-    ParseMode DEFAULT_PARSE_MODE = null;
-
-    /** @see #setParseMode */
-    public ParseMode getParseMode();
-
-    /**
-     * Controls certain rules for how strict this parser is when reading strings. See {@link
-     * ParseMode#LENIENT} and {@link ParseMode#STRICT}.
-     *
-     * @param parseMode Either {@link ParseMode#LENIENT} or {@link ParseMode#STRICT}.
-     * @return The property bag, for chaining.
-     */
-    public IProperties setParseMode(ParseMode parseMode);
-
-    boolean DEFAULT_PARSE_TO_BIG_DECIMAL = false;
-
-    /** @see #setParseToBigDecimal */
-    public boolean getParseToBigDecimal();
-
-    /**
-     * Whether to always return a BigDecimal from {@link Parse#parse} and all other parse methods.
-     * By default, a Long or a BigInteger are returned when possible.
-     *
-     * @param parseToBigDecimal true to always return a BigDecimal; false to return a Long or a
-     *     BigInteger when possible.
-     * @return The property bag, for chaining.
-     */
-    public IProperties setParseToBigDecimal(boolean parseToBigDecimal);
-
-    boolean DEFAULT_PARSE_CASE_SENSITIVE = false;
-
-    /** @see #setParseCaseSensitive */
-    public boolean getParseCaseSensitive();
-
-    /**
-     * Whether to require cases to match when parsing strings; default is true. Case sensitivity
-     * applies to prefixes, suffixes, the exponent separator, the symbol "NaN", and the infinity
-     * symbol. Grouping separators, decimal separators, and padding are always case-sensitive.
-     * Currencies are always case-insensitive.
-     *
-     * <p>This setting is ignored in fast mode. In fast mode, strings are always compared in a
-     * case-sensitive way.
-     *
-     * @param parseCaseSensitive true to be case-sensitive when parsing; false to allow any case.
-     * @return The property bag, for chaining.
-     */
-    public IProperties setParseCaseSensitive(boolean parseCaseSensitive);
-
-    GroupingMode DEFAULT_PARSE_GROUPING_MODE = null;
-
-    /** @see #setParseGroupingMode */
-    public GroupingMode getParseGroupingMode();
-
-    /**
-     * Sets the strategy used during parsing when a code point needs to be interpreted as either a
-     * decimal separator or a grouping separator.
-     *
-     * <p>The comma, period, space, and apostrophe have different meanings in different locales. For
-     * example, in <em>en-US</em> and most American locales, the period is used as a decimal
-     * separator, but in <em>es-PY</em> and most European locales, it is used as a grouping
-     * separator.
-     *
-     * <p>Suppose you are in <em>fr-FR</em> the parser encounters the string "1.234". In
-     * <em>fr-FR</em>, the grouping is a space and the decimal is a comma. The <em>grouping
-     * mode</em> is a mechanism to let you specify whether to accept the string as 1234
-     * (GroupingMode.DEFAULT) or whether to reject it since the separators don't match
-     * (GroupingMode.RESTRICTED).
-     *
-     * <p>When resolving grouping separators, it is the <em>equivalence class</em> of separators
-     * that is considered. For example, a period is seen as equal to a fixed set of other
-     * period-like characters.
-     *
-     * @param parseGroupingMode The {@link GroupingMode} to use; either DEFAULT or RESTRICTED.
-     * @return The property bag, for chaining.
-     */
-    public IProperties setParseGroupingMode(GroupingMode parseGroupingMode);
-  }
-
   /**
    * An enum containing the choices for strategy in parsing when choosing between grouping and
    * decimal separators.
@@ -253,7 +113,7 @@ public class Parse {
   }
 
   /**
-   * @see Parse#parse(String, ParsePosition, ParseMode, boolean, boolean, IProperties,
+   * @see Parse#parse(String, ParsePosition, ParseMode, boolean, boolean, Properties,
    *     DecimalFormatSymbols)
    */
   private static enum StateName {
@@ -540,7 +400,7 @@ public class Parse {
      *
      * @return The Number. Never null.
      */
-    Number toNumber(IProperties properties) {
+    Number toNumber(Properties properties) {
       // Check for NaN, infinity, and -0.0
       if (sawNaN) {
         return Double.NaN;
@@ -610,7 +470,7 @@ public class Parse {
      *
      * @return The CurrencyAmount. Never null.
      */
-    public CurrencyAmount toCurrencyAmount(IProperties properties) {
+    public CurrencyAmount toCurrencyAmount(Properties properties) {
       assert isoCode != null;
       Number number = toNumber(properties);
       Currency currency = Currency.getInstance(isoCode);
@@ -679,7 +539,7 @@ public class Parse {
     int prevLength;
 
     // Properties and Symbols memory:
-    IProperties properties;
+    Properties properties;
     DecimalFormatSymbols symbols;
     ParseMode mode;
     boolean caseSensitive;
@@ -785,25 +645,25 @@ public class Parse {
 
     @Override
     public String toString() {
-        StringBuilder sb = new StringBuilder();
-        sb.append("<ParseState mode:");
-        sb.append(mode);
-        sb.append(" caseSensitive:");
-        sb.append(caseSensitive);
-        sb.append(" parseCurrency:");
-        sb.append(parseCurrency);
-        sb.append(" groupingMode:");
-        sb.append(groupingMode);
-        sb.append(" decimalCps:");
-        sb.append((char)decimalCp1);
-        sb.append((char)decimalCp2);
-        sb.append(" groupingCps:");
-        sb.append((char)groupingCp1);
-        sb.append((char)groupingCp2);
-        sb.append(" affixes:");
-        sb.append(affixHolders);
-        sb.append(">");
-        return sb.toString();
+      StringBuilder sb = new StringBuilder();
+      sb.append("<ParseState mode:");
+      sb.append(mode);
+      sb.append(" caseSensitive:");
+      sb.append(caseSensitive);
+      sb.append(" parseCurrency:");
+      sb.append(parseCurrency);
+      sb.append(" groupingMode:");
+      sb.append(groupingMode);
+      sb.append(" decimalCps:");
+      sb.append((char) decimalCp1);
+      sb.append((char) decimalCp2);
+      sb.append(" groupingCps:");
+      sb.append((char) groupingCp1);
+      sb.append((char) groupingCp2);
+      sb.append(" affixes:");
+      sb.append(affixHolders);
+      sb.append(">");
+      return sb.toString();
     }
   }
 
@@ -820,7 +680,7 @@ public class Parse {
     static final AffixHolder EMPTY_POSITIVE = new AffixHolder("", "", true, false);
     static final AffixHolder EMPTY_NEGATIVE = new AffixHolder("", "", true, true);
 
-    static void addToState(ParserState state, IProperties properties) {
+    static void addToState(ParserState state, Properties properties) {
       AffixHolder pp = fromPropertiesPositivePattern(properties);
       AffixHolder np = fromPropertiesNegativePattern(properties);
       AffixHolder ps = fromPropertiesPositiveString(properties);
@@ -831,11 +691,11 @@ public class Parse {
       if (ns != null) state.affixHolders.add(ns);
     }
 
-    static AffixHolder fromPropertiesPositivePattern(IProperties properties) {
+    static AffixHolder fromPropertiesPositivePattern(Properties properties) {
       String ppp = properties.getPositivePrefixPattern();
       String psp = properties.getPositiveSuffixPattern();
       if (properties.getSignAlwaysShown()) {
-        // TODO: This logic is somewhat duplicated from PNAffixGenerator.
+        // TODO: This logic is somewhat duplicated from MurkyModifier.
         boolean foundSign = false;
         String npp = properties.getNegativePrefixPattern();
         String nsp = properties.getNegativeSuffixPattern();
@@ -854,7 +714,7 @@ public class Parse {
       return getInstance(ppp, psp, false, false);
     }
 
-    static AffixHolder fromPropertiesNegativePattern(IProperties properties) {
+    static AffixHolder fromPropertiesNegativePattern(Properties properties) {
       String npp = properties.getNegativePrefixPattern();
       String nsp = properties.getNegativeSuffixPattern();
       if (npp == null && nsp == null) {
@@ -869,14 +729,14 @@ public class Parse {
       return getInstance(npp, nsp, false, true);
     }
 
-    static AffixHolder fromPropertiesPositiveString(IProperties properties) {
+    static AffixHolder fromPropertiesPositiveString(Properties properties) {
       String pp = properties.getPositivePrefix();
       String ps = properties.getPositiveSuffix();
       if (pp == null && ps == null) return null;
       return getInstance(pp, ps, true, false);
     }
 
-    static AffixHolder fromPropertiesNegativeString(IProperties properties) {
+    static AffixHolder fromPropertiesNegativeString(Properties properties) {
       String np = properties.getNegativePrefix();
       String ns = properties.getNegativeSuffix();
       if (np == null && ns == null) return null;
@@ -1052,7 +912,7 @@ public class Parse {
               0xFE63, 0xFE63, 0xFF0D, 0xFF0D)
           .freeze();
 
-  public static Number parse(String input, IProperties properties, DecimalFormatSymbols symbols) {
+  public static Number parse(String input, Properties properties, DecimalFormatSymbols symbols) {
     ParsePosition ppos = threadLocalParsePosition.get();
     ppos.setIndex(0);
     return parse(input, ppos, properties, symbols);
@@ -1080,19 +940,19 @@ public class Parse {
   public static Number parse(
       CharSequence input,
       ParsePosition ppos,
-      IProperties properties,
+      Properties properties,
       DecimalFormatSymbols symbols) {
     StateItem best = _parse(input, ppos, false, properties, symbols);
     return (best == null) ? null : best.toNumber(properties);
   }
 
   public static CurrencyAmount parseCurrency(
-      String input, IProperties properties, DecimalFormatSymbols symbols) throws ParseException {
+      String input, Properties properties, DecimalFormatSymbols symbols) throws ParseException {
     return parseCurrency(input, null, properties, symbols);
   }
 
   public static CurrencyAmount parseCurrency(
-      CharSequence input, ParsePosition ppos, IProperties properties, DecimalFormatSymbols symbols)
+      CharSequence input, ParsePosition ppos, Properties properties, DecimalFormatSymbols symbols)
       throws ParseException {
     if (ppos == null) {
       ppos = threadLocalParsePosition.get();
@@ -1107,7 +967,7 @@ public class Parse {
       CharSequence input,
       ParsePosition ppos,
       boolean parseCurrency,
-      IProperties properties,
+      Properties properties,
       DecimalFormatSymbols symbols) {
 
     if (input == null || ppos == null || properties == null || symbols == null) {
@@ -1481,7 +1341,9 @@ public class Parse {
 
         // Optionally require that the presence of a decimal point matches the pattern.
         if (properties.getDecimalPatternMatchRequired()
-            && item.sawDecimalPoint != PositiveDecimalFormat.allowsDecimalPoint(properties)) {
+            && item.sawDecimalPoint
+                != (properties.getDecimalSeparatorAlwaysShown()
+                    || properties.getMaximumFractionDigits() != 0)) {
           if (DEBUGGING) System.out.println("-> rejected due to decimal point violation");
           continue;
         }
index 1a1b83b11982bdee1c1e3b56429de6004ddc59bf..6b08f9b368540754cb00eec104260fd987c31d80 100644 (file)
@@ -4,8 +4,7 @@ package com.ibm.icu.impl.number;
 
 import java.math.BigDecimal;
 
-import com.ibm.icu.impl.number.formatters.PaddingFormat;
-import com.ibm.icu.impl.number.formatters.PaddingFormat.PadPosition;
+import com.ibm.icu.impl.number.ThingsNeedingNewHome.PadPosition;
 import com.ibm.icu.text.DecimalFormatSymbols;
 
 import newapi.impl.AffixPatternProvider;
@@ -105,17 +104,17 @@ public class PatternString {
 
     // Figure out the grouping sizes.
     int grouping1, grouping2, grouping;
-    if (groupingSize != Math.min(dosMax, Properties.DEFAULT_SECONDARY_GROUPING_SIZE)
-        && firstGroupingSize != Math.min(dosMax, Properties.DEFAULT_GROUPING_SIZE)
+    if (groupingSize != Math.min(dosMax, -1)
+        && firstGroupingSize != Math.min(dosMax, -1)
         && groupingSize != firstGroupingSize) {
       grouping = groupingSize;
       grouping1 = groupingSize;
       grouping2 = firstGroupingSize;
-    } else if (groupingSize != Math.min(dosMax, Properties.DEFAULT_SECONDARY_GROUPING_SIZE)) {
+    } else if (groupingSize != Math.min(dosMax, -1)) {
       grouping = groupingSize;
       grouping1 = 0;
       grouping2 = groupingSize;
-    } else if (firstGroupingSize != Math.min(dosMax, Properties.DEFAULT_GROUPING_SIZE)) {
+    } else if (firstGroupingSize != Math.min(dosMax, -1)) {
       grouping = groupingSize;
       grouping1 = 0;
       grouping2 = firstGroupingSize;
@@ -130,7 +129,7 @@ public class PatternString {
     BigDecimal roundingInterval = properties.getRoundingIncrement();
     StringBuilder digitsString = new StringBuilder();
     int digitsStringScale = 0;
-    if (maxSig != Math.min(dosMax, Properties.DEFAULT_MAXIMUM_SIGNIFICANT_DIGITS)) {
+    if (maxSig != Math.min(dosMax, -1)) {
       // Significant Digits.
       while (digitsString.length() < minSig) {
         digitsString.append('@');
@@ -138,7 +137,7 @@ public class PatternString {
       while (digitsString.length() < maxSig) {
         digitsString.append('#');
       }
-    } else if (roundingInterval != Properties.DEFAULT_ROUNDING_INCREMENT) {
+    } else if (roundingInterval != null) {
       // Rounding Interval.
       digitsStringScale = -roundingInterval.scale();
       // TODO: Check for DoS here?
@@ -179,7 +178,7 @@ public class PatternString {
     }
 
     // Exponential notation
-    if (exponentDigits != Math.min(dosMax, Properties.DEFAULT_MINIMUM_EXPONENT_DIGITS)) {
+    if (exponentDigits != Math.min(dosMax, -1)) {
       sb.append('E');
       if (exponentShowPlusSign) {
         sb.append('+');
@@ -195,7 +194,7 @@ public class PatternString {
     AffixPatternUtils.escape(ps, sb);
 
     // Resolve Padding
-    if (paddingWidth != Properties.DEFAULT_FORMAT_WIDTH) {
+    if (paddingWidth != -1) {
       while (paddingWidth - sb.length() > 0) {
         sb.insert(afterPrefixPos, '#');
         beforeSuffixPos++;
@@ -246,7 +245,7 @@ public class PatternString {
 
   /** @return The number of chars inserted. */
   private static int escapePaddingString(CharSequence input, StringBuilder output, int startIndex) {
-    if (input == null || input.length() == 0) input = PaddingFormat.FALLBACK_PADDING_STRING;
+    if (input == null || input.length() == 0) input = ThingsNeedingNewHome.FALLBACK_PADDING_STRING;
     int startLength = output.length();
     if (input.length() == 1) {
       if (input.equals("'")) {
@@ -474,12 +473,12 @@ public class PatternString {
     if (grouping2 != -1) {
       properties.setGroupingSize(grouping1);
     } else {
-      properties.setGroupingSize(Properties.DEFAULT_GROUPING_SIZE);
+      properties.setGroupingSize(-1);
     }
     if (grouping3 != -1) {
       properties.setSecondaryGroupingSize(grouping2);
     } else {
-      properties.setSecondaryGroupingSize(Properties.DEFAULT_SECONDARY_GROUPING_SIZE);
+      properties.setSecondaryGroupingSize(-1);
     }
 
     // For backwards compatibility, require that the pattern emit at least one min digit.
@@ -500,9 +499,9 @@ public class PatternString {
     // Rounding settings
     // Don't set basic rounding when there is a currency sign; defer to CurrencyUsage
     if (positive.minimumSignificantDigits > 0) {
-      properties.setMinimumFractionDigits(Properties.DEFAULT_MINIMUM_FRACTION_DIGITS);
-      properties.setMaximumFractionDigits(Properties.DEFAULT_MAXIMUM_FRACTION_DIGITS);
-      properties.setRoundingIncrement(Properties.DEFAULT_ROUNDING_INCREMENT);
+      properties.setMinimumFractionDigits(-1);
+      properties.setMaximumFractionDigits(-1);
+      properties.setRoundingIncrement(null);
       properties.setMinimumSignificantDigits(positive.minimumSignificantDigits);
       properties.setMaximumSignificantDigits(positive.maximumSignificantDigits);
     } else if (positive.rounding != null) {
@@ -512,24 +511,24 @@ public class PatternString {
         properties.setRoundingIncrement(
             positive.rounding.toBigDecimal().setScale(positive.minimumFractionDigits));
       } else {
-        properties.setMinimumFractionDigits(Properties.DEFAULT_MINIMUM_FRACTION_DIGITS);
-        properties.setMaximumFractionDigits(Properties.DEFAULT_MAXIMUM_FRACTION_DIGITS);
-        properties.setRoundingIncrement(Properties.DEFAULT_ROUNDING_INCREMENT);
+        properties.setMinimumFractionDigits(-1);
+        properties.setMaximumFractionDigits(-1);
+        properties.setRoundingIncrement(null);
       }
-      properties.setMinimumSignificantDigits(Properties.DEFAULT_MINIMUM_SIGNIFICANT_DIGITS);
-      properties.setMaximumSignificantDigits(Properties.DEFAULT_MAXIMUM_SIGNIFICANT_DIGITS);
+      properties.setMinimumSignificantDigits(-1);
+      properties.setMaximumSignificantDigits(-1);
     } else {
       if (!ignoreRounding) {
         properties.setMinimumFractionDigits(minFrac);
         properties.setMaximumFractionDigits(positive.maximumFractionDigits);
-        properties.setRoundingIncrement(Properties.DEFAULT_ROUNDING_INCREMENT);
+        properties.setRoundingIncrement(null);
       } else {
-        properties.setMinimumFractionDigits(Properties.DEFAULT_MINIMUM_FRACTION_DIGITS);
-        properties.setMaximumFractionDigits(Properties.DEFAULT_MAXIMUM_FRACTION_DIGITS);
-        properties.setRoundingIncrement(Properties.DEFAULT_ROUNDING_INCREMENT);
+        properties.setMinimumFractionDigits(-1);
+        properties.setMaximumFractionDigits(-1);
+        properties.setRoundingIncrement(null);
       }
-      properties.setMinimumSignificantDigits(Properties.DEFAULT_MINIMUM_SIGNIFICANT_DIGITS);
-      properties.setMaximumSignificantDigits(Properties.DEFAULT_MAXIMUM_SIGNIFICANT_DIGITS);
+      properties.setMinimumSignificantDigits(-1);
+      properties.setMaximumSignificantDigits(-1);
     }
 
     // If the pattern ends with a '.' then force the decimal point.
@@ -550,13 +549,13 @@ public class PatternString {
       } else {
         // patterns with '@' cannot define max integer digits
         properties.setMinimumIntegerDigits(1);
-        properties.setMaximumIntegerDigits(Properties.DEFAULT_MAXIMUM_INTEGER_DIGITS);
+        properties.setMaximumIntegerDigits(-1);
       }
     } else {
-      properties.setExponentSignAlwaysShown(Properties.DEFAULT_EXPONENT_SIGN_ALWAYS_SHOWN);
-      properties.setMinimumExponentDigits(Properties.DEFAULT_MINIMUM_EXPONENT_DIGITS);
+      properties.setExponentSignAlwaysShown(false);
+      properties.setMinimumExponentDigits(-1);
       properties.setMinimumIntegerDigits(minInt);
-      properties.setMaximumIntegerDigits(Properties.DEFAULT_MAXIMUM_INTEGER_DIGITS);
+      properties.setMaximumIntegerDigits(-1);
     }
 
     // Compute the affix patterns (required for both padding and affixes)
@@ -586,9 +585,9 @@ public class PatternString {
       assert positive.paddingLocation != null;
       properties.setPadPosition(positive.paddingLocation);
     } else {
-      properties.setFormatWidth(Properties.DEFAULT_FORMAT_WIDTH);
-      properties.setPadString(Properties.DEFAULT_PAD_STRING);
-      properties.setPadPosition(Properties.DEFAULT_PAD_POSITION);
+      properties.setFormatWidth(-1);
+      properties.setPadString(null);
+      properties.setPadPosition(null);
     }
 
     // Set the affixes
@@ -613,7 +612,7 @@ public class PatternString {
     } else if (positive.hasPerMilleSign) {
       properties.setMagnitudeMultiplier(3);
     } else {
-      properties.setMagnitudeMultiplier(Properties.DEFAULT_MAGNITUDE_MULTIPLIER);
+      properties.setMagnitudeMultiplier(0);
     }
   }
 }
index bb1092cb22a4faa0a4b660f149c4e9f301120b62..d86c66945aa00073d5725d91b8ebbc01df8fc931 100644 (file)
@@ -11,50 +11,20 @@ import java.lang.reflect.Modifier;
 import java.math.BigDecimal;
 import java.math.MathContext;
 import java.math.RoundingMode;
+import java.text.ParsePosition;
 import java.util.ArrayList;
 import java.util.Map;
 
 import com.ibm.icu.impl.number.Parse.GroupingMode;
 import com.ibm.icu.impl.number.Parse.ParseMode;
-import com.ibm.icu.impl.number.formatters.BigDecimalMultiplier;
-import com.ibm.icu.impl.number.formatters.CompactDecimalFormat;
-import com.ibm.icu.impl.number.formatters.CurrencyFormat;
-import com.ibm.icu.impl.number.formatters.CurrencyFormat.CurrencyStyle;
-import com.ibm.icu.impl.number.formatters.MagnitudeMultiplier;
-import com.ibm.icu.impl.number.formatters.MeasureFormat;
-import com.ibm.icu.impl.number.formatters.PaddingFormat;
-import com.ibm.icu.impl.number.formatters.PaddingFormat.PadPosition;
-import com.ibm.icu.impl.number.formatters.PositiveDecimalFormat;
-import com.ibm.icu.impl.number.formatters.PositiveNegativeAffixFormat;
-import com.ibm.icu.impl.number.formatters.ScientificFormat;
-import com.ibm.icu.impl.number.rounders.IncrementRounder;
-import com.ibm.icu.impl.number.rounders.MagnitudeRounder;
-import com.ibm.icu.impl.number.rounders.SignificantDigitsRounder;
+import com.ibm.icu.impl.number.ThingsNeedingNewHome.PadPosition;
 import com.ibm.icu.text.CompactDecimalFormat.CompactStyle;
 import com.ibm.icu.text.CurrencyPluralInfo;
-import com.ibm.icu.text.MeasureFormat.FormatWidth;
 import com.ibm.icu.text.PluralRules;
 import com.ibm.icu.util.Currency;
 import com.ibm.icu.util.Currency.CurrencyUsage;
-import com.ibm.icu.util.MeasureUnit;
-
-public class Properties
-    implements Cloneable,
-        Serializable,
-        PositiveDecimalFormat.IProperties,
-        PositiveNegativeAffixFormat.IProperties,
-        MagnitudeMultiplier.IProperties,
-        ScientificFormat.IProperties,
-        MeasureFormat.IProperties,
-        CompactDecimalFormat.IProperties,
-        PaddingFormat.IProperties,
-        BigDecimalMultiplier.IProperties,
-        CurrencyFormat.IProperties,
-        Parse.IProperties,
-        IncrementRounder.IProperties,
-        MagnitudeRounder.IProperties,
-        SignificantDigitsRounder.IProperties,
-        Endpoint.IProperties {
+
+public class Properties implements Cloneable, Serializable {
 
   private static final Properties DEFAULT = new Properties();
 
@@ -79,7 +49,6 @@ public class Properties
   private transient CompactStyle compactStyle;
   private transient Currency currency;
   private transient CurrencyPluralInfo currencyPluralInfo;
-  private transient CurrencyStyle currencyStyle;
   private transient CurrencyUsage currencyUsage;
   private transient boolean decimalPatternMatchRequired;
   private transient boolean decimalSeparatorAlwaysShown;
@@ -91,8 +60,6 @@ public class Properties
   private transient int maximumFractionDigits;
   private transient int maximumIntegerDigits;
   private transient int maximumSignificantDigits;
-  private transient FormatWidth measureFormatWidth;
-  private transient MeasureUnit measureUnit;
   private transient int minimumExponentDigits;
   private transient int minimumFractionDigits;
   private transient int minimumGroupingDigits;
@@ -134,52 +101,61 @@ public class Properties
     clear();
   }
 
+  /**
+   * Sets all properties to their defaults (unset).
+   *
+   * <p>All integers default to -1 EXCEPT FOR MAGNITUDE MULTIPLIER which has a default of 0 (since
+   * negative numbers are important).
+   *
+   * <p>All booleans default to false.
+   *
+   * <p>All non-primitive types default to null.
+   *
+   * @return The property bag, for chaining.
+   */
   private Properties _clear() {
-    compactCustomData = DEFAULT_COMPACT_CUSTOM_DATA;
-    compactStyle = DEFAULT_COMPACT_STYLE;
-    currency = DEFAULT_CURRENCY;
-    currencyPluralInfo = DEFAULT_CURRENCY_PLURAL_INFO;
-    currencyStyle = DEFAULT_CURRENCY_STYLE;
-    currencyUsage = DEFAULT_CURRENCY_USAGE;
-    decimalPatternMatchRequired = DEFAULT_DECIMAL_PATTERN_MATCH_REQUIRED;
-    decimalSeparatorAlwaysShown = DEFAULT_DECIMAL_SEPARATOR_ALWAYS_SHOWN;
-    exponentSignAlwaysShown = DEFAULT_EXPONENT_SIGN_ALWAYS_SHOWN;
-    formatWidth = DEFAULT_FORMAT_WIDTH;
-    groupingSize = DEFAULT_GROUPING_SIZE;
-    magnitudeMultiplier = DEFAULT_MAGNITUDE_MULTIPLIER;
-    mathContext = DEFAULT_MATH_CONTEXT;
-    maximumFractionDigits = DEFAULT_MAXIMUM_FRACTION_DIGITS;
-    maximumIntegerDigits = DEFAULT_MAXIMUM_INTEGER_DIGITS;
-    maximumSignificantDigits = DEFAULT_MAXIMUM_SIGNIFICANT_DIGITS;
-    measureFormatWidth = DEFAULT_MEASURE_FORMAT_WIDTH;
-    measureUnit = DEFAULT_MEASURE_UNIT;
-    minimumExponentDigits = DEFAULT_MINIMUM_EXPONENT_DIGITS;
-    minimumFractionDigits = DEFAULT_MINIMUM_FRACTION_DIGITS;
-    minimumGroupingDigits = DEFAULT_MINIMUM_GROUPING_DIGITS;
-    minimumIntegerDigits = DEFAULT_MINIMUM_INTEGER_DIGITS;
-    minimumSignificantDigits = DEFAULT_MINIMUM_SIGNIFICANT_DIGITS;
-    multiplier = DEFAULT_MULTIPLIER;
-    negativePrefix = DEFAULT_NEGATIVE_PREFIX;
-    negativePrefixPattern = DEFAULT_NEGATIVE_PREFIX_PATTERN;
-    negativeSuffix = DEFAULT_NEGATIVE_SUFFIX;
-    negativeSuffixPattern = DEFAULT_NEGATIVE_SUFFIX_PATTERN;
-    padPosition = DEFAULT_PAD_POSITION;
-    padString = DEFAULT_PAD_STRING;
-    parseCaseSensitive = DEFAULT_PARSE_CASE_SENSITIVE;
-    parseGroupingMode = DEFAULT_PARSE_GROUPING_MODE;
-    parseIntegerOnly = DEFAULT_PARSE_INTEGER_ONLY;
-    parseMode = DEFAULT_PARSE_MODE;
-    parseNoExponent = DEFAULT_PARSE_NO_EXPONENT;
-    parseToBigDecimal = DEFAULT_PARSE_TO_BIG_DECIMAL;
-    pluralRules = DEFAULT_PLURAL_RULES;
-    positivePrefix = DEFAULT_POSITIVE_PREFIX;
-    positivePrefixPattern = DEFAULT_POSITIVE_PREFIX_PATTERN;
-    positiveSuffix = DEFAULT_POSITIVE_SUFFIX;
-    positiveSuffixPattern = DEFAULT_POSITIVE_SUFFIX_PATTERN;
-    roundingIncrement = DEFAULT_ROUNDING_INCREMENT;
-    roundingMode = DEFAULT_ROUNDING_MODE;
-    secondaryGroupingSize = DEFAULT_SECONDARY_GROUPING_SIZE;
-    signAlwaysShown = DEFAULT_SIGN_ALWAYS_SHOWN;
+    compactCustomData = null;
+    compactStyle = null;
+    currency = null;
+    currencyPluralInfo = null;
+    currencyUsage = null;
+    decimalPatternMatchRequired = false;
+    decimalSeparatorAlwaysShown = false;
+    exponentSignAlwaysShown = false;
+    formatWidth = -1;
+    groupingSize = -1;
+    magnitudeMultiplier = 0;
+    mathContext = null;
+    maximumFractionDigits = -1;
+    maximumIntegerDigits = -1;
+    maximumSignificantDigits = -1;
+    minimumExponentDigits = -1;
+    minimumFractionDigits = -1;
+    minimumGroupingDigits = -1;
+    minimumIntegerDigits = -1;
+    minimumSignificantDigits = -1;
+    multiplier = null;
+    negativePrefix = null;
+    negativePrefixPattern = null;
+    negativeSuffix = null;
+    negativeSuffixPattern = null;
+    padPosition = null;
+    padString = null;
+    parseCaseSensitive = false;
+    parseGroupingMode = null;
+    parseIntegerOnly = false;
+    parseMode = null;
+    parseNoExponent = false;
+    parseToBigDecimal = false;
+    pluralRules = null;
+    positivePrefix = null;
+    positivePrefixPattern = null;
+    positiveSuffix = null;
+    positiveSuffixPattern = null;
+    roundingIncrement = null;
+    roundingMode = null;
+    secondaryGroupingSize = -1;
+    signAlwaysShown = false;
     return this;
   }
 
@@ -188,7 +164,6 @@ public class Properties
     compactStyle = other.compactStyle;
     currency = other.currency;
     currencyPluralInfo = other.currencyPluralInfo;
-    currencyStyle = other.currencyStyle;
     currencyUsage = other.currencyUsage;
     decimalPatternMatchRequired = other.decimalPatternMatchRequired;
     decimalSeparatorAlwaysShown = other.decimalSeparatorAlwaysShown;
@@ -200,8 +175,6 @@ public class Properties
     maximumFractionDigits = other.maximumFractionDigits;
     maximumIntegerDigits = other.maximumIntegerDigits;
     maximumSignificantDigits = other.maximumSignificantDigits;
-    measureFormatWidth = other.measureFormatWidth;
-    measureUnit = other.measureUnit;
     minimumExponentDigits = other.minimumExponentDigits;
     minimumFractionDigits = other.minimumFractionDigits;
     minimumGroupingDigits = other.minimumGroupingDigits;
@@ -238,7 +211,6 @@ public class Properties
     eq = eq && _equalsHelper(compactStyle, other.compactStyle);
     eq = eq && _equalsHelper(currency, other.currency);
     eq = eq && _equalsHelper(currencyPluralInfo, other.currencyPluralInfo);
-    eq = eq && _equalsHelper(currencyStyle, other.currencyStyle);
     eq = eq && _equalsHelper(currencyUsage, other.currencyUsage);
     eq = eq && _equalsHelper(decimalPatternMatchRequired, other.decimalPatternMatchRequired);
     eq = eq && _equalsHelper(decimalSeparatorAlwaysShown, other.decimalSeparatorAlwaysShown);
@@ -250,8 +222,6 @@ public class Properties
     eq = eq && _equalsHelper(maximumFractionDigits, other.maximumFractionDigits);
     eq = eq && _equalsHelper(maximumIntegerDigits, other.maximumIntegerDigits);
     eq = eq && _equalsHelper(maximumSignificantDigits, other.maximumSignificantDigits);
-    eq = eq && _equalsHelper(measureFormatWidth, other.measureFormatWidth);
-    eq = eq && _equalsHelper(measureUnit, other.measureUnit);
     eq = eq && _equalsHelper(minimumExponentDigits, other.minimumExponentDigits);
     eq = eq && _equalsHelper(minimumFractionDigits, other.minimumFractionDigits);
     eq = eq && _equalsHelper(minimumGroupingDigits, other.minimumGroupingDigits);
@@ -302,7 +272,6 @@ public class Properties
     hashCode ^= _hashCodeHelper(compactStyle);
     hashCode ^= _hashCodeHelper(currency);
     hashCode ^= _hashCodeHelper(currencyPluralInfo);
-    hashCode ^= _hashCodeHelper(currencyStyle);
     hashCode ^= _hashCodeHelper(currencyUsage);
     hashCode ^= _hashCodeHelper(decimalPatternMatchRequired);
     hashCode ^= _hashCodeHelper(decimalSeparatorAlwaysShown);
@@ -314,8 +283,6 @@ public class Properties
     hashCode ^= _hashCodeHelper(maximumFractionDigits);
     hashCode ^= _hashCodeHelper(maximumIntegerDigits);
     hashCode ^= _hashCodeHelper(maximumSignificantDigits);
-    hashCode ^= _hashCodeHelper(measureFormatWidth);
-    hashCode ^= _hashCodeHelper(measureUnit);
     hashCode ^= _hashCodeHelper(minimumExponentDigits);
     hashCode ^= _hashCodeHelper(minimumFractionDigits);
     hashCode ^= _hashCodeHelper(minimumGroupingDigits);
@@ -395,228 +362,170 @@ public class Properties
 
   /// BEGIN GETTERS/SETTERS ///
 
-  @Override
   public Map<String, Map<String, String>> getCompactCustomData() {
     return compactCustomData;
   }
 
-  @Override
   public CompactStyle getCompactStyle() {
     return compactStyle;
   }
 
-  @Override
   public Currency getCurrency() {
     return currency;
   }
 
-  @Override
-  @Deprecated
   public CurrencyPluralInfo getCurrencyPluralInfo() {
     return currencyPluralInfo;
   }
 
-  @Override
-  public CurrencyStyle getCurrencyStyle() {
-    return currencyStyle;
-  }
-
-  @Override
   public CurrencyUsage getCurrencyUsage() {
     return currencyUsage;
   }
 
-  @Override
   public boolean getDecimalPatternMatchRequired() {
     return decimalPatternMatchRequired;
   }
 
-  @Override
   public boolean getDecimalSeparatorAlwaysShown() {
     return decimalSeparatorAlwaysShown;
   }
 
-  @Override
   public boolean getExponentSignAlwaysShown() {
     return exponentSignAlwaysShown;
   }
 
-  @Override
   public int getFormatWidth() {
     return formatWidth;
   }
 
-  @Override
   public int getGroupingSize() {
     return groupingSize;
   }
 
-  @Override
   public int getMagnitudeMultiplier() {
     return magnitudeMultiplier;
   }
 
-  @Override
   public MathContext getMathContext() {
     return mathContext;
   }
 
-  @Override
   public int getMaximumFractionDigits() {
     return maximumFractionDigits;
   }
 
-  @Override
   public int getMaximumIntegerDigits() {
     return maximumIntegerDigits;
   }
 
-  @Override
   public int getMaximumSignificantDigits() {
     return maximumSignificantDigits;
   }
 
-  @Override
-  public FormatWidth getMeasureFormatWidth() {
-    return measureFormatWidth;
-  }
-
-  @Override
-  public MeasureUnit getMeasureUnit() {
-    return measureUnit;
-  }
-
-  @Override
   public int getMinimumExponentDigits() {
     return minimumExponentDigits;
   }
 
-  @Override
   public int getMinimumFractionDigits() {
     return minimumFractionDigits;
   }
 
-  @Override
   public int getMinimumGroupingDigits() {
     return minimumGroupingDigits;
   }
 
-  @Override
   public int getMinimumIntegerDigits() {
     return minimumIntegerDigits;
   }
 
-  @Override
   public int getMinimumSignificantDigits() {
     return minimumSignificantDigits;
   }
 
-  @Override
   public BigDecimal getMultiplier() {
     return multiplier;
   }
 
-  @Override
   public String getNegativePrefix() {
     return negativePrefix;
   }
 
-  @Override
   public String getNegativePrefixPattern() {
     return negativePrefixPattern;
   }
 
-  @Override
   public String getNegativeSuffix() {
     return negativeSuffix;
   }
 
-  @Override
   public String getNegativeSuffixPattern() {
     return negativeSuffixPattern;
   }
 
-  @Override
   public PadPosition getPadPosition() {
     return padPosition;
   }
 
-  @Override
   public String getPadString() {
     return padString;
   }
 
-  @Override
   public boolean getParseCaseSensitive() {
     return parseCaseSensitive;
   }
 
-  @Override
   public GroupingMode getParseGroupingMode() {
     return parseGroupingMode;
   }
 
-  @Override
   public boolean getParseIntegerOnly() {
     return parseIntegerOnly;
   }
 
-  @Override
   public ParseMode getParseMode() {
     return parseMode;
   }
 
-  @Override
   public boolean getParseNoExponent() {
     return parseNoExponent;
   }
 
-  @Override
   public boolean getParseToBigDecimal() {
     return parseToBigDecimal;
   }
 
-  @Override
   public PluralRules getPluralRules() {
     return pluralRules;
   }
 
-  @Override
   public String getPositivePrefix() {
     return positivePrefix;
   }
 
-  @Override
   public String getPositivePrefixPattern() {
     return positivePrefixPattern;
   }
 
-  @Override
   public String getPositiveSuffix() {
     return positiveSuffix;
   }
 
-  @Override
   public String getPositiveSuffixPattern() {
     return positiveSuffixPattern;
   }
 
-  @Override
   public BigDecimal getRoundingIncrement() {
     return roundingIncrement;
   }
 
-  @Override
   public RoundingMode getRoundingMode() {
     return roundingMode;
   }
 
-  @Override
   public int getSecondaryGroupingSize() {
     return secondaryGroupingSize;
   }
 
-  @Override
   public boolean getSignAlwaysShown() {
     return signAlwaysShown;
   }
@@ -672,27 +581,65 @@ public class Properties
     }
   }
 
-  @Override
+  /**
+   * Specifies custom data to be used instead of CLDR data when constructing a CompactDecimalFormat.
+   * The argument should be a map with the following structure:
+   *
+   * <pre>
+   * {
+   *   "1000": {
+   *     "one": "0 thousand",
+   *     "other": "0 thousand"
+   *   },
+   *   "10000": {
+   *     "one": "00 thousand",
+   *     "other": "00 thousand"
+   *   },
+   *   // ...
+   * }
+   * </pre>
+   *
+   * This API endpoint is used by the CLDR Survey Tool.
+   *
+   * @param compactCustomData A map with the above structure.
+   * @return The property bag, for chaining.
+   */
   public Properties setCompactCustomData(Map<String, Map<String, String>> compactCustomData) {
     // TODO: compactCustomData is not immutable.
     this.compactCustomData = compactCustomData;
     return this;
   }
 
-  @Override
+  /**
+   * Use compact decimal formatting with the specified {@link CompactStyle}. CompactStyle.SHORT
+   * produces output like "10K" in locale <em>en-US</em>, whereas CompactStyle.LONG produces output
+   * like "10 thousand" in that locale.
+   *
+   * @param compactStyle The style of prefixes/suffixes to append.
+   * @return The property bag, for chaining.
+   */
   public Properties setCompactStyle(CompactStyle compactStyle) {
     this.compactStyle = compactStyle;
     return this;
   }
 
-  @Override
+  /**
+   * Use the specified currency to substitute currency placeholders ('¤') in the pattern string.
+   *
+   * @param currency The currency.
+   * @return The property bag, for chaining.
+   */
   public Properties setCurrency(Currency currency) {
     this.currency = currency;
     return this;
   }
 
-  @Override
-  @Deprecated
+  /**
+   * Use the specified {@link CurrencyPluralInfo} instance when formatting currency long names.
+   *
+   * @param currencyPluralInfo The currency plural info object.
+   * @return The property bag, for chaining.
+   */
   public Properties setCurrencyPluralInfo(CurrencyPluralInfo currencyPluralInfo) {
     // TODO: In order to maintain immutability, we have to perform a clone here.
     // It would be better to just retire CurrencyPluralInfo entirely.
@@ -703,247 +650,610 @@ public class Properties
     return this;
   }
 
-  @Override
-  public Properties setCurrencyStyle(CurrencyStyle currencyStyle) {
-    this.currencyStyle = currencyStyle;
-    return this;
-  }
-
-  @Override
+  /**
+   * Use the specified {@link CurrencyUsage} instance, which provides default rounding rules for the
+   * currency in two styles, CurrencyUsage.CASH and CurrencyUsage.STANDARD.
+   *
+   * <p>The CurrencyUsage specified here will not be used unless there is a currency placeholder in
+   * the pattern.
+   *
+   * @param currencyUsage The currency usage. Defaults to CurrencyUsage.STANDARD.
+   * @return The property bag, for chaining.
+   */
   public Properties setCurrencyUsage(CurrencyUsage currencyUsage) {
     this.currencyUsage = currencyUsage;
     return this;
   }
 
-  @Override
+  /**
+   * PARSING: Whether to require that the presence of decimal point matches the pattern. If a
+   * decimal point is not present, but the pattern contained a decimal point, parse will not
+   * succeed: null will be returned from <code>parse()</code>, and an error index will be set in the
+   * {@link ParsePosition}.
+   *
+   * @param decimalPatternMatchRequired true to set an error if decimal is not present
+   * @return The property bag, for chaining.
+   */
   public Properties setDecimalPatternMatchRequired(boolean decimalPatternMatchRequired) {
     this.decimalPatternMatchRequired = decimalPatternMatchRequired;
     return this;
   }
 
-  @Override
+  /**
+   * Sets whether to always show the decimal point, even if the number doesn't require one. For
+   * example, if always show decimal is true, the number 123 would be formatted as "123." in locale
+   * <em>en-US</em>.
+   *
+   * @param decimalSeparatorAlwaysShown Whether to show the decimal point when it is optional.
+   * @return The property bag, for chaining.
+   */
   public Properties setDecimalSeparatorAlwaysShown(boolean alwaysShowDecimal) {
     this.decimalSeparatorAlwaysShown = alwaysShowDecimal;
     return this;
   }
 
-  @Override
+  /**
+   * Sets whether to show the plus sign in the exponent part of numbers with a zero or positive
+   * exponent. For example, the number "1200" with the pattern "0.0E0" would be formatted as
+   * "1.2E+3" instead of "1.2E3" in <em>en-US</em>.
+   *
+   * @param exponentSignAlwaysShown Whether to show the plus sign in positive exponents.
+   * @return The property bag, for chaining.
+   */
   public Properties setExponentSignAlwaysShown(boolean exponentSignAlwaysShown) {
     this.exponentSignAlwaysShown = exponentSignAlwaysShown;
     return this;
   }
 
-  @Override
+  /**
+   * Sets the minimum width of the string output by the formatting pipeline. For example, if padding
+   * is enabled and paddingWidth is set to 6, formatting the number "3.14159" with the pattern
+   * "0.00" will result in "··3.14" if '·' is your padding string.
+   *
+   * <p>If the number is longer than your padding width, the number will display as if no padding
+   * width had been specified, which may result in strings longer than the padding width.
+   *
+   * <p>Width is counted in UTF-16 code units.
+   *
+   * @param formatWidth The output width.
+   * @return The property bag, for chaining.
+   * @see #setPadPosition
+   * @see #setPadString
+   */
   public Properties setFormatWidth(int paddingWidth) {
     this.formatWidth = paddingWidth;
     return this;
   }
 
-  @Override
+  /**
+   * Sets the number of digits between grouping separators. For example, the <em>en-US</em> locale
+   * uses a grouping size of 3, so the number 1234567 would be formatted as "1,234,567". For locales
+   * whose grouping sizes vary with magnitude, see {@link #setSecondaryGroupingSize(int)}.
+   *
+   * @param groupingSize The primary grouping size.
+   * @return The property bag, for chaining.
+   */
   public Properties setGroupingSize(int groupingSize) {
     this.groupingSize = groupingSize;
     return this;
   }
 
-  @Override
+  /**
+   * Multiply all numbers by this power of ten before formatting. Negative multipliers reduce the
+   * magnitude and make numbers smaller (closer to zero).
+   *
+   * @param magnitudeMultiplier The number of powers of ten to scale.
+   * @return The property bag, for chaining.
+   * @see #setMultiplier
+   */
   public Properties setMagnitudeMultiplier(int magnitudeMultiplier) {
     this.magnitudeMultiplier = magnitudeMultiplier;
     return this;
   }
 
-  @Override
+  /**
+   * Sets the {@link MathContext} to be used during math and rounding operations. A MathContext
+   * encapsulates a RoundingMode and the number of significant digits in the output.
+   *
+   * @param mathContext The math context to use when rounding is required.
+   * @return The property bag, for chaining.
+   * @see MathContext
+   * @see #setRoundingMode
+   */
   public Properties setMathContext(MathContext mathContext) {
     this.mathContext = mathContext;
     return this;
   }
 
-  @Override
+  /**
+   * Sets the maximum number of digits to display after the decimal point. If the number has fewer
+   * than this number of digits, the number will be rounded off using the rounding mode specified by
+   * {@link #setRoundingMode(RoundingMode)}. The pattern "#00.0#", for example, corresponds to 2
+   * maximum fraction digits, and the number 456.789 would be formatted as "456.79" in locale
+   * <em>en-US</em> with the default rounding mode. Note that the number 456.999 would be formatted
+   * as "457.0" given the same configurations.
+   *
+   * @param maximumFractionDigits The maximum number of fraction digits to output.
+   * @return The property bag, for chaining.
+   */
   public Properties setMaximumFractionDigits(int maximumFractionDigits) {
     this.maximumFractionDigits = maximumFractionDigits;
     return this;
   }
 
-  @Override
+  /**
+   * Sets the maximum number of digits to display before the decimal point. If the number has more
+   * than this number of digits, the extra digits will be truncated. For example, if maximum integer
+   * digits is 2, and you attempt to format the number 1970, you will get "70" in locale
+   * <em>en-US</em>. It is not possible to specify the maximum integer digits using a pattern
+   * string, except in the special case of a scientific format pattern.
+   *
+   * @param maximumIntegerDigits The maximum number of integer digits to output.
+   * @return The property bag, for chaining.
+   */
   public Properties setMaximumIntegerDigits(int maximumIntegerDigits) {
     this.maximumIntegerDigits = maximumIntegerDigits;
     return this;
   }
 
-  @Override
+  /**
+   * Sets the maximum number of significant digits to display. The number of significant digits is
+   * equal to the number of digits counted from the leftmost nonzero digit through the rightmost
+   * nonzero digit; for example, the number "2010" has 3 significant digits. If the number has more
+   * significant digits than specified here, the extra significant digits will be rounded off using
+   * the rounding mode specified by {@link #setRoundingMode(RoundingMode)}. For example, if maximum
+   * significant digits is 3, the number 1234.56 will be formatted as "1230" in locale
+   * <em>en-US</em> with the default rounding mode.
+   *
+   * <p>If both maximum significant digits and maximum integer/fraction digits are set at the same
+   * time, the behavior is undefined.
+   *
+   * <p>The number of significant digits can be specified in a pattern string using the '@'
+   * character. For example, the pattern "@@#" corresponds to a minimum of 2 and a maximum of 3
+   * significant digits.
+   *
+   * @param maximumSignificantDigits The maximum number of significant digits to display.
+   * @return The property bag, for chaining.
+   */
   public Properties setMaximumSignificantDigits(int maximumSignificantDigits) {
     this.maximumSignificantDigits = maximumSignificantDigits;
     return this;
   }
 
-  @Override
-  public Properties setMeasureFormatWidth(FormatWidth measureFormatWidth) {
-    this.measureFormatWidth = measureFormatWidth;
-    return this;
-  }
-
-  @Override
-  public Properties setMeasureUnit(MeasureUnit measureUnit) {
-    this.measureUnit = measureUnit;
-    return this;
-  }
-
-  @Override
+  /**
+   * Sets the minimum number of digits to display in the exponent. For example, the number "1200"
+   * with the pattern "0.0E00", which has 2 exponent digits, would be formatted as "1.2E03" in
+   * <em>en-US</em>.
+   *
+   * @param minimumExponentDigits The minimum number of digits to display in the exponent field.
+   * @return The property bag, for chaining.
+   */
   public Properties setMinimumExponentDigits(int exponentDigits) {
     this.minimumExponentDigits = exponentDigits;
     return this;
   }
 
-  @Override
+  /**
+   * Sets the minimum number of digits to display after the decimal point. If the number has fewer
+   * than this number of digits, the number will be padded with zeros. The pattern "#00.0#", for
+   * example, corresponds to 1 minimum fraction digit, and the number 456 would be formatted as
+   * "456.0" in locale <em>en-US</em>.
+   *
+   * @param minimumFractionDigits The minimum number of fraction digits to output.
+   * @return The property bag, for chaining.
+   */
   public Properties setMinimumFractionDigits(int minimumFractionDigits) {
     this.minimumFractionDigits = minimumFractionDigits;
     return this;
   }
 
-  @Override
+  /**
+   * Sets the minimum number of digits required to be beyond the first grouping separator in order
+   * to enable grouping. For example, if the minimum grouping digits is 2, then 1234 would be
+   * formatted as "1234" but 12345 would be formatted as "12,345" in <em>en-US</em>. Note that
+   * 1234567 would still be formatted as "1,234,567", not "1234,567".
+   *
+   * @param minimumGroupingDigits How many digits must appear before a grouping separator before
+   *     enabling grouping.
+   * @return The property bag, for chaining.
+   */
   public Properties setMinimumGroupingDigits(int minimumGroupingDigits) {
     this.minimumGroupingDigits = minimumGroupingDigits;
     return this;
   }
 
-  @Override
+  /**
+   * Sets the minimum number of digits to display before the decimal point. If the number has fewer
+   * than this number of digits, the number will be padded with zeros. The pattern "#00.0#", for
+   * example, corresponds to 2 minimum integer digits, and the number 5.3 would be formatted as
+   * "05.3" in locale <em>en-US</em>.
+   *
+   * @param minimumIntegerDigits The minimum number of integer digits to output.
+   * @return The property bag, for chaining.
+   */
   public Properties setMinimumIntegerDigits(int minimumIntegerDigits) {
     this.minimumIntegerDigits = minimumIntegerDigits;
     return this;
   }
 
-  @Override
+  /**
+   * Sets the minimum number of significant digits to display. If, after rounding to the number of
+   * significant digits specified by {@link #setMaximumSignificantDigits}, the number of remaining
+   * significant digits is less than the minimum, the number will be padded with zeros. For example,
+   * if minimum significant digits is 3, the number 5.8 will be formatted as "5.80" in locale
+   * <em>en-US</em>. Note that minimum significant digits is relevant only when numbers have digits
+   * after the decimal point.
+   *
+   * <p>If both minimum significant digits and minimum integer/fraction digits are set at the same
+   * time, both values will be respected, and the one that results in the greater number of padding
+   * zeros will be used. For example, formatting the number 73 with 3 minimum significant digits and
+   * 2 minimum fraction digits will produce "73.00".
+   *
+   * <p>The number of significant digits can be specified in a pattern string using the '@'
+   * character. For example, the pattern "@@#" corresponds to a minimum of 2 and a maximum of 3
+   * significant digits.
+   *
+   * @param minimumSignificantDigits The minimum number of significant digits to display.
+   * @return The property bag, for chaining.
+   */
   public Properties setMinimumSignificantDigits(int minimumSignificantDigits) {
     this.minimumSignificantDigits = minimumSignificantDigits;
     return this;
   }
 
-  @Override
+  /**
+   * Multiply all numbers by this amount before formatting.
+   *
+   * @param multiplier The amount to multiply by.
+   * @return The property bag, for chaining.
+   * @see #setMagnitudeMultiplier
+   */
   public Properties setMultiplier(BigDecimal multiplier) {
     this.multiplier = multiplier;
     return this;
   }
 
-  @Override
+  /**
+   * Sets the prefix to prepend to negative numbers. The prefix will be interpreted literally. For
+   * example, if you set a negative prefix of <code>n</code>, then the number -123 will be formatted
+   * as "n123" in the locale <em>en-US</em>. Note that if the negative prefix is left unset, the
+   * locale's minus sign is used.
+   *
+   * <p>For more information on prefixes and suffixes, see {@link PositiveNegativeAffixFormat}.
+   *
+   * @param negativePrefix The CharSequence to prepend to negative numbers.
+   * @return The property bag, for chaining.
+   * @see PositiveNegativeAffixFormat
+   * @see #setNegativePrefixPattern
+   */
   public Properties setNegativePrefix(String negativePrefix) {
     this.negativePrefix = negativePrefix;
     return this;
   }
 
-  @Override
+  /**
+   * Sets the prefix to prepend to negative numbers. Locale-specific symbols will be substituted
+   * into the string according to Unicode Technical Standard #35 (LDML).
+   *
+   * <p>For more information on prefixes and suffixes, see {@link PositiveNegativeAffixFormat}.
+   *
+   * @param negativePrefixPattern The CharSequence to prepend to negative numbers after locale
+   *     symbol substitutions take place.
+   * @return The property bag, for chaining.
+   * @see PositiveNegativeAffixFormat
+   * @see #setNegativePrefix
+   */
   public Properties setNegativePrefixPattern(String negativePrefixPattern) {
     this.negativePrefixPattern = negativePrefixPattern;
     return this;
   }
 
-  @Override
+  /**
+   * Sets the suffix to append to negative numbers. The suffix will be interpreted literally. For
+   * example, if you set a suffix prefix of <code>n</code>, then the number -123 will be formatted
+   * as "-123n" in the locale <em>en-US</em>. Note that the minus sign is prepended by default
+   * unless otherwise specified in either the pattern string or in one of the {@link
+   * #setNegativePrefix} methods.
+   *
+   * <p>For more information on prefixes and suffixes, see {@link PositiveNegativeAffixFormat}.
+   *
+   * @param negativeSuffix The CharSequence to append to negative numbers.
+   * @return The property bag, for chaining.
+   * @see PositiveNegativeAffixFormat
+   * @see #setNegativeSuffixPattern
+   */
   public Properties setNegativeSuffix(String negativeSuffix) {
     this.negativeSuffix = negativeSuffix;
     return this;
   }
 
-  @Override
+  /**
+   * Sets the suffix to append to negative numbers. Locale-specific symbols will be substituted into
+   * the string according to Unicode Technical Standard #35 (LDML).
+   *
+   * <p>For more information on prefixes and suffixes, see {@link PositiveNegativeAffixFormat}.
+   *
+   * @param negativeSuffixPattern The CharSequence to append to negative numbers after locale symbol
+   *     substitutions take place.
+   * @return The property bag, for chaining.
+   * @see PositiveNegativeAffixFormat
+   * @see #setNegativeSuffix
+   */
   public Properties setNegativeSuffixPattern(String negativeSuffixPattern) {
     this.negativeSuffixPattern = negativeSuffixPattern;
     return this;
   }
 
-  @Override
+  /**
+   * Sets the location where the padding string is to be inserted to maintain the padding width: one
+   * of BEFORE_PREFIX, AFTER_PREFIX, BEFORE_SUFFIX, or AFTER_SUFFIX.
+   *
+   * <p>Must be used in conjunction with {@link #setFormatWidth}.
+   *
+   * @param padPosition The output width.
+   * @return The property bag, for chaining.
+   * @see #setFormatWidth
+   */
   public Properties setPadPosition(PadPosition paddingLocation) {
     this.padPosition = paddingLocation;
     return this;
   }
 
-  @Override
+  /**
+   * Sets the string used for padding. The string should contain a single character or grapheme
+   * cluster.
+   *
+   * <p>Must be used in conjunction with {@link #setFormatWidth}.
+   *
+   * @param paddingString The padding string. Defaults to an ASCII space (U+0020).
+   * @return The property bag, for chaining.
+   * @see #setFormatWidth
+   */
   public Properties setPadString(String paddingString) {
     this.padString = paddingString;
     return this;
   }
 
-  @Override
+  /**
+   * Whether to require cases to match when parsing strings; default is true. Case sensitivity
+   * applies to prefixes, suffixes, the exponent separator, the symbol "NaN", and the infinity
+   * symbol. Grouping separators, decimal separators, and padding are always case-sensitive.
+   * Currencies are always case-insensitive.
+   *
+   * <p>This setting is ignored in fast mode. In fast mode, strings are always compared in a
+   * case-sensitive way.
+   *
+   * @param parseCaseSensitive true to be case-sensitive when parsing; false to allow any case.
+   * @return The property bag, for chaining.
+   */
   public Properties setParseCaseSensitive(boolean parseCaseSensitive) {
     this.parseCaseSensitive = parseCaseSensitive;
     return this;
   }
 
-  @Override
+  /**
+   * Sets the strategy used during parsing when a code point needs to be interpreted as either a
+   * decimal separator or a grouping separator.
+   *
+   * <p>The comma, period, space, and apostrophe have different meanings in different locales. For
+   * example, in <em>en-US</em> and most American locales, the period is used as a decimal
+   * separator, but in <em>es-PY</em> and most European locales, it is used as a grouping separator.
+   *
+   * <p>Suppose you are in <em>fr-FR</em> the parser encounters the string "1.234". In
+   * <em>fr-FR</em>, the grouping is a space and the decimal is a comma. The <em>grouping mode</em>
+   * is a mechanism to let you specify whether to accept the string as 1234 (GroupingMode.DEFAULT)
+   * or whether to reject it since the separators don't match (GroupingMode.RESTRICTED).
+   *
+   * <p>When resolving grouping separators, it is the <em>equivalence class</em> of separators that
+   * is considered. For example, a period is seen as equal to a fixed set of other period-like
+   * characters.
+   *
+   * @param parseGroupingMode The {@link GroupingMode} to use; either DEFAULT or RESTRICTED.
+   * @return The property bag, for chaining.
+   */
   public Properties setParseGroupingMode(GroupingMode parseGroupingMode) {
     this.parseGroupingMode = parseGroupingMode;
     return this;
   }
 
-  @Override
+  /**
+   * Whether to ignore the fractional part of numbers. For example, parses "123.4" to "123" instead
+   * of "123.4".
+   *
+   * @param parseIntegerOnly true to parse integers only; false to parse integers with their
+   *     fraction parts
+   * @return The property bag, for chaining.
+   */
   public Properties setParseIntegerOnly(boolean parseIntegerOnly) {
     this.parseIntegerOnly = parseIntegerOnly;
     return this;
   }
 
-  @Override
+  /**
+   * Controls certain rules for how strict this parser is when reading strings. See {@link
+   * ParseMode#LENIENT} and {@link ParseMode#STRICT}.
+   *
+   * @param parseMode Either {@link ParseMode#LENIENT} or {@link ParseMode#STRICT}.
+   * @return The property bag, for chaining.
+   */
   public Properties setParseMode(ParseMode parseMode) {
     this.parseMode = parseMode;
     return this;
   }
 
-  @Override
+  /**
+   * Whether to ignore the exponential part of numbers. For example, parses "123E4" to "123" instead
+   * of "1230000".
+   *
+   * @param parseIgnoreExponent true to ignore exponents; false to parse them.
+   * @return The property bag, for chaining.
+   */
   public Properties setParseNoExponent(boolean parseNoExponent) {
     this.parseNoExponent = parseNoExponent;
     return this;
   }
 
-  @Override
+  /**
+   * Whether to always return a BigDecimal from {@link Parse#parse} and all other parse methods. By
+   * default, a Long or a BigInteger are returned when possible.
+   *
+   * @param parseToBigDecimal true to always return a BigDecimal; false to return a Long or a
+   *     BigInteger when possible.
+   * @return The property bag, for chaining.
+   */
   public Properties setParseToBigDecimal(boolean parseToBigDecimal) {
     this.parseToBigDecimal = parseToBigDecimal;
     return this;
   }
 
-  @Override
+  /**
+   * Sets the PluralRules object to use instead of the default for the locale.
+   *
+   * @param pluralRules The object to reference.
+   * @return The property bag, for chaining.
+   */
   public Properties setPluralRules(PluralRules pluralRules) {
     this.pluralRules = pluralRules;
     return this;
   }
 
-  @Override
+  /**
+   * Sets the prefix to prepend to positive numbers. The prefix will be interpreted literally. For
+   * example, if you set a positive prefix of <code>p</code>, then the number 123 will be formatted
+   * as "p123" in the locale <em>en-US</em>.
+   *
+   * <p>For more information on prefixes and suffixes, see {@link PositiveNegativeAffixFormat}.
+   *
+   * @param positivePrefix The CharSequence to prepend to positive numbers.
+   * @return The property bag, for chaining.
+   * @see PositiveNegativeAffixFormat
+   * @see #setPositivePrefixPattern
+   */
   public Properties setPositivePrefix(String positivePrefix) {
     this.positivePrefix = positivePrefix;
     return this;
   }
 
-  @Override
+  /**
+   * Sets the prefix to prepend to positive numbers. Locale-specific symbols will be substituted
+   * into the string according to Unicode Technical Standard #35 (LDML).
+   *
+   * <p>For more information on prefixes and suffixes, see {@link PositiveNegativeAffixFormat}.
+   *
+   * @param positivePrefixPattern The CharSequence to prepend to positive numbers after locale
+   *     symbol substitutions take place.
+   * @return The property bag, for chaining.
+   * @see PositiveNegativeAffixFormat
+   * @see #setPositivePrefix
+   */
   public Properties setPositivePrefixPattern(String positivePrefixPattern) {
     this.positivePrefixPattern = positivePrefixPattern;
     return this;
   }
 
-  @Override
+  /**
+   * Sets the suffix to append to positive numbers. The suffix will be interpreted literally. For
+   * example, if you set a positive suffix of <code>p</code>, then the number 123 will be formatted
+   * as "123p" in the locale <em>en-US</em>.
+   *
+   * <p>For more information on prefixes and suffixes, see {@link PositiveNegativeAffixFormat}.
+   *
+   * @param positiveSuffix The CharSequence to append to positive numbers.
+   * @return The property bag, for chaining.
+   * @see PositiveNegativeAffixFormat
+   * @see #setPositiveSuffixPattern
+   */
   public Properties setPositiveSuffix(String positiveSuffix) {
     this.positiveSuffix = positiveSuffix;
     return this;
   }
 
-  @Override
+  /**
+   * Sets the suffix to append to positive numbers. Locale-specific symbols will be substituted into
+   * the string according to Unicode Technical Standard #35 (LDML).
+   *
+   * <p>For more information on prefixes and suffixes, see {@link PositiveNegativeAffixFormat}.
+   *
+   * @param positiveSuffixPattern The CharSequence to append to positive numbers after locale symbol
+   *     substitutions take place.
+   * @return The property bag, for chaining.
+   * @see PositiveNegativeAffixFormat
+   * @see #setPositiveSuffix
+   */
   public Properties setPositiveSuffixPattern(String positiveSuffixPattern) {
     this.positiveSuffixPattern = positiveSuffixPattern;
     return this;
   }
 
-  @Override
+  /**
+   * Sets the increment to which to round numbers. For example, with a rounding interval of 0.05,
+   * the number 11.17 would be formatted as "11.15" in locale <em>en-US</em> with the default
+   * rounding mode.
+   *
+   * <p>You can use either a rounding increment or significant digits, but not both at the same
+   * time.
+   *
+   * <p>The rounding increment can be specified in a pattern string. For example, the pattern
+   * "#,##0.05" corresponds to a rounding interval of 0.05 with 1 minimum integer digit and a
+   * grouping size of 3.
+   *
+   * @param roundingIncrement The interval to which to round.
+   * @return The property bag, for chaining.
+   */
   public Properties setRoundingIncrement(BigDecimal roundingIncrement) {
     this.roundingIncrement = roundingIncrement;
     return this;
   }
 
-  @Override
+  /**
+   * Sets the rounding mode, which determines under which conditions extra decimal places are
+   * rounded either up or down. See {@link RoundingMode} for details on the choices of rounding
+   * mode. The default if not set explicitly is {@link RoundingMode#HALF_EVEN}.
+   *
+   * <p>This setting is ignored if {@link #setMathContext} is used.
+   *
+   * @param roundingMode The rounding mode to use when rounding is required.
+   * @return The property bag, for chaining.
+   * @see RoundingMode
+   * @see #setMathContext
+   */
   public Properties setRoundingMode(RoundingMode roundingMode) {
     this.roundingMode = roundingMode;
     return this;
   }
 
-  @Override
+  /**
+   * Sets the number of digits between grouping separators higher than the least-significant
+   * grouping separator. For example, the locale <em>hi</em> uses a primary grouping size of 3 and a
+   * secondary grouping size of 2, so the number 1234567 would be formatted as "12,34,567".
+   *
+   * <p>The two levels of grouping separators can be specified in the pattern string. For example,
+   * the <em>hi</em> locale's default decimal format pattern is "#,##,##0.###".
+   *
+   * @param secondaryGroupingSize The secondary grouping size.
+   * @return The property bag, for chaining.
+   */
   public Properties setSecondaryGroupingSize(int secondaryGroupingSize) {
     this.secondaryGroupingSize = secondaryGroupingSize;
     return this;
   }
 
-  @Override
+  /**
+   * Sets whether to always display of a plus sign on positive numbers.
+   *
+   * <p>If the location of the negative sign is specified by the decimal format pattern (or by the
+   * negative prefix/suffix pattern methods), a plus sign is substituted into that location, in
+   * accordance with Unicode Technical Standard #35 (LDML) section 3.2.1. Otherwise, the plus sign
+   * is prepended to the number. For example, if the decimal format pattern <code>#;#-</code> is
+   * used, then formatting 123 would result in "123+" in the locale <em>en-US</em>.
+   *
+   * <p>This method should be used <em>instead of</em> setting the positive prefix/suffix. The
+   * behavior is undefined if alwaysShowPlusSign is set but the positive prefix/suffix already
+   * contains a plus sign.
+   *
+   * @param plusSignAlwaysShown Whether positive numbers should display a plus sign.
+   * @return The property bag, for chaining.
+   */
   public Properties setSignAlwaysShown(boolean signAlwaysShown) {
     this.signAlwaysShown = signAlwaysShown;
     return this;
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/Rounder.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/Rounder.java
deleted file mode 100644 (file)
index f13b462..0000000
+++ /dev/null
@@ -1,252 +0,0 @@
-// © 2017 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html#License
-package com.ibm.icu.impl.number;
-
-import java.math.MathContext;
-import java.math.RoundingMode;
-
-import com.ibm.icu.impl.number.formatters.CompactDecimalFormat;
-import com.ibm.icu.impl.number.formatters.ScientificFormat;
-
-/**
- * The base class for a Rounder used by ICU Decimal Format.
- *
- * <p>A Rounder must implement the method {@link #apply}. An implementation must:
- *
- * <ol>
- *   <li>Either have the code <code>applyDefaults(input);</code> in its apply function, or otherwise
- *       ensure that minFrac, maxFrac, minInt, and maxInt are obeyed, paying special attention to
- *       the case when the input is zero.
- *   <li>Call one of {@link FormatQuantity#roundToIncrement}, {@link
- *       FormatQuantity#roundToMagnitude}, or {@link FormatQuantity#roundToInfinity} on the input.
- * </ol>
- *
- * <p>In order to be used by {@link CompactDecimalFormat} and {@link ScientificFormat}, among
- * others, your rounder must be stable upon <em>decreasing</em> the magnitude of the input number.
- * For example, if your rounder converts "999" to "1000", it must also convert "99.9" to "100" and
- * "0.999" to "1". (The opposite does not need to be the case: you can round "0.999" to "1" but keep
- * "999" as "999".)
- *
- * @see com.ibm.icu.impl.number.rounders.MagnitudeRounder
- * @see com.ibm.icu.impl.number.rounders.IncrementRounder
- * @see com.ibm.icu.impl.number.rounders.SignificantDigitsRounder
- * @see com.ibm.icu.impl.number.rounders.NoRounder
- */
-public abstract class Rounder extends Format.BeforeFormat {
-
-  public static interface IBasicRoundingProperties {
-
-    static int DEFAULT_MINIMUM_INTEGER_DIGITS = -1;
-
-    /** @see #setMinimumIntegerDigits */
-    public int getMinimumIntegerDigits();
-
-    /**
-     * Sets the minimum number of digits to display before the decimal point. If the number has
-     * fewer than this number of digits, the number will be padded with zeros. The pattern "#00.0#",
-     * for example, corresponds to 2 minimum integer digits, and the number 5.3 would be formatted
-     * as "05.3" in locale <em>en-US</em>.
-     *
-     * @param minimumIntegerDigits The minimum number of integer digits to output.
-     * @return The property bag, for chaining.
-     */
-    public IBasicRoundingProperties setMinimumIntegerDigits(int minimumIntegerDigits);
-
-    static int DEFAULT_MAXIMUM_INTEGER_DIGITS = -1;
-
-    /** @see #setMaximumIntegerDigits */
-    public int getMaximumIntegerDigits();
-
-    /**
-     * Sets the maximum number of digits to display before the decimal point. If the number has more
-     * than this number of digits, the extra digits will be truncated. For example, if maximum
-     * integer digits is 2, and you attempt to format the number 1970, you will get "70" in locale
-     * <em>en-US</em>. It is not possible to specify the maximum integer digits using a pattern
-     * string, except in the special case of a scientific format pattern.
-     *
-     * @param maximumIntegerDigits The maximum number of integer digits to output.
-     * @return The property bag, for chaining.
-     */
-    public IBasicRoundingProperties setMaximumIntegerDigits(int maximumIntegerDigits);
-
-    static int DEFAULT_MINIMUM_FRACTION_DIGITS = -1;
-
-    /** @see #setMinimumFractionDigits */
-    public int getMinimumFractionDigits();
-
-    /**
-     * Sets the minimum number of digits to display after the decimal point. If the number has fewer
-     * than this number of digits, the number will be padded with zeros. The pattern "#00.0#", for
-     * example, corresponds to 1 minimum fraction digit, and the number 456 would be formatted as
-     * "456.0" in locale <em>en-US</em>.
-     *
-     * @param minimumFractionDigits The minimum number of fraction digits to output.
-     * @return The property bag, for chaining.
-     */
-    public IBasicRoundingProperties setMinimumFractionDigits(int minimumFractionDigits);
-
-    static int DEFAULT_MAXIMUM_FRACTION_DIGITS = -1;
-
-    /** @see #setMaximumFractionDigits */
-    public int getMaximumFractionDigits();
-
-    /**
-     * Sets the maximum number of digits to display after the decimal point. If the number has fewer
-     * than this number of digits, the number will be rounded off using the rounding mode specified
-     * by {@link #setRoundingMode(RoundingMode)}. The pattern "#00.0#", for example, corresponds to
-     * 2 maximum fraction digits, and the number 456.789 would be formatted as "456.79" in locale
-     * <em>en-US</em> with the default rounding mode. Note that the number 456.999 would be
-     * formatted as "457.0" given the same configurations.
-     *
-     * @param maximumFractionDigits The maximum number of fraction digits to output.
-     * @return The property bag, for chaining.
-     */
-    public IBasicRoundingProperties setMaximumFractionDigits(int maximumFractionDigits);
-
-    static RoundingMode DEFAULT_ROUNDING_MODE = null;
-
-    /** @see #setRoundingMode */
-    public RoundingMode getRoundingMode();
-
-    /**
-     * Sets the rounding mode, which determines under which conditions extra decimal places are
-     * rounded either up or down. See {@link RoundingMode} for details on the choices of rounding
-     * mode. The default if not set explicitly is {@link RoundingMode#HALF_EVEN}.
-     *
-     * <p>This setting is ignored if {@link #setMathContext} is used.
-     *
-     * @param roundingMode The rounding mode to use when rounding is required.
-     * @return The property bag, for chaining.
-     * @see RoundingMode
-     * @see #setMathContext
-     */
-    public IBasicRoundingProperties setRoundingMode(RoundingMode roundingMode);
-
-    static MathContext DEFAULT_MATH_CONTEXT = null;
-
-    /** @see #setMathContext */
-    public MathContext getMathContext();
-
-    /**
-     * Sets the {@link MathContext} to be used during math and rounding operations. A MathContext
-     * encapsulates a RoundingMode and the number of significant digits in the output.
-     *
-     * @param mathContext The math context to use when rounding is required.
-     * @return The property bag, for chaining.
-     * @see MathContext
-     * @see #setRoundingMode
-     */
-    public IBasicRoundingProperties setMathContext(MathContext mathContext);
-  }
-
-  public static interface MultiplierGenerator {
-    public int getMultiplier(int magnitude);
-  }
-
-  // Properties available to all rounding strategies
-  protected final MathContext mathContext;
-  protected final int minInt;
-  protected final int maxInt;
-  protected final int minFrac;
-  protected final int maxFrac;
-
-  /**
-   * Constructor that uses integer and fraction digit lengths from IBasicRoundingProperties.
-   *
-   * @param properties
-   */
-  protected Rounder(IBasicRoundingProperties properties) {
-    mathContext = RoundingUtils.getMathContextOrUnlimited(properties);
-
-    int _maxInt = properties.getMaximumIntegerDigits();
-    int _minInt = properties.getMinimumIntegerDigits();
-    int _maxFrac = properties.getMaximumFractionDigits();
-    int _minFrac = properties.getMinimumFractionDigits();
-
-    // Validate min/max int/frac.
-    // For backwards compatibility, minimum overrides maximum if the two conflict.
-    // The following logic ensures that there is always a minimum of at least one digit.
-    if (_minInt == 0 && _maxFrac != 0) {
-      // Force a digit after the decimal point.
-      minFrac = _minFrac <= 0 ? 1 : _minFrac;
-      maxFrac = _maxFrac < 0 ? Integer.MAX_VALUE : _maxFrac < minFrac ? minFrac : _maxFrac;
-      minInt = 0;
-      maxInt = _maxInt < 0 ? Integer.MAX_VALUE : _maxInt;
-    } else {
-      // Force a digit before the decimal point.
-      minFrac = _minFrac < 0 ? 0 : _minFrac;
-      maxFrac = _maxFrac < 0 ? Integer.MAX_VALUE : _maxFrac < minFrac ? minFrac : _maxFrac;
-      minInt = _minInt <= 0 ? 1 : _minInt;
-      maxInt = _maxInt < 0 ? Integer.MAX_VALUE : _maxInt < minInt ? minInt : _maxInt;
-    }
-  }
-
-  /**
-   * Perform rounding and specification of integer and fraction digit lengths on the input quantity.
-   * Calling this method will change the state of the FormatQuantity.
-   *
-   * @param input The {@link FormatQuantity} to be modified and rounded.
-   */
-  public abstract void apply(FormatQuantity input);
-
-  /**
-   * Rounding can affect the magnitude. First we attempt to adjust according to the original
-   * magnitude, and if the magnitude changes, we adjust according to a magnitude one greater. Note
-   * that this algorithm assumes that increasing the multiplier never increases the number of digits
-   * that can be displayed.
-   *
-   * @param input The quantity to be rounded.
-   * @param mg The implementation that returns magnitude adjustment based on a given starting
-   *     magnitude.
-   * @return The multiplier that was chosen to best fit the input.
-   */
-  public int chooseMultiplierAndApply(FormatQuantity input, MultiplierGenerator mg) {
-    // TODO: Avoid the object creation here.
-    FormatQuantity copy = input.createCopy();
-
-    assert !input.isZero();
-    int magnitude = input.getMagnitude();
-    int multiplier = mg.getMultiplier(magnitude);
-    input.adjustMagnitude(multiplier);
-    apply(input);
-
-    // If the number turned to zero when rounding, do not re-attempt the rounding.
-    if (!input.isZero() && input.getMagnitude() == magnitude + multiplier + 1) {
-      magnitude += 1;
-      input.copyFrom(copy);
-      multiplier = mg.getMultiplier(magnitude);
-      input.adjustMagnitude(multiplier);
-      assert input.getMagnitude() == magnitude + multiplier - 1;
-      apply(input);
-      assert input.getMagnitude() == magnitude + multiplier;
-    }
-
-    return multiplier;
-  }
-
-  /**
-   * Implementations can call this method to perform default logic for min/max digits. This method
-   * performs logic for handling of a zero input.
-   *
-   * @param input The digits being formatted.
-   */
-  protected void applyDefaults(FormatQuantity input) {
-    input.setIntegerLength(minInt, maxInt);
-    input.setFractionLength(minFrac, maxFrac);
-  }
-
-  @Override
-  public void before(FormatQuantity input, ModifierHolder mods) {
-    apply(input);
-  }
-
-  @Override
-  public void export(Properties properties) {
-    properties.setMathContext(mathContext);
-    properties.setRoundingMode(mathContext.getRoundingMode());
-    properties.setMinimumFractionDigits(minFrac);
-    properties.setMinimumIntegerDigits(minInt);
-    properties.setMaximumFractionDigits(maxFrac);
-    properties.setMaximumIntegerDigits(maxInt);
-  }
-}
index 6594c5ee39066373b47901b8f6ddf8773fb34b25..7aa15eb5f421d5223280df728899beca4b95aac8 100644 (file)
@@ -6,8 +6,6 @@ import java.math.BigDecimal;
 import java.math.MathContext;
 import java.math.RoundingMode;
 
-import com.ibm.icu.impl.number.Rounder.IBasicRoundingProperties;
-
 /** @author sffc */
 public class RoundingUtils {
 
@@ -135,7 +133,7 @@ public class RoundingUtils {
    * @param properties The property bag.
    * @return A {@link MathContext}. Never null.
    */
-  public static MathContext getMathContextOrUnlimited(IBasicRoundingProperties properties) {
+  public static MathContext getMathContextOrUnlimited(Properties properties) {
     MathContext mathContext = properties.getMathContext();
     if (mathContext == null) {
       RoundingMode roundingMode = properties.getRoundingMode();
@@ -153,7 +151,7 @@ public class RoundingUtils {
    * @param properties The property bag.
    * @return A {@link MathContext}. Never null.
    */
-  public static MathContext getMathContextOr34Digits(IBasicRoundingProperties properties) {
+  public static MathContext getMathContextOr34Digits(Properties properties) {
     MathContext mathContext = properties.getMathContext();
     if (mathContext == null) {
       RoundingMode roundingMode = properties.getRoundingMode();
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/ThingsNeedingNewHome.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/ThingsNeedingNewHome.java
new file mode 100644 (file)
index 0000000..e322c87
--- /dev/null
@@ -0,0 +1,59 @@
+// © 2017 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html#License
+package com.ibm.icu.impl.number;
+
+/** @author sffc */
+public class ThingsNeedingNewHome {
+  public static final String FALLBACK_PADDING_STRING = "\u0020"; // i.e. a space
+
+  public enum PadPosition {
+    BEFORE_PREFIX,
+    AFTER_PREFIX,
+    BEFORE_SUFFIX,
+    AFTER_SUFFIX;
+
+    public static PadPosition fromOld(int old) {
+      switch (old) {
+        case com.ibm.icu.text.DecimalFormat.PAD_BEFORE_PREFIX:
+          return PadPosition.BEFORE_PREFIX;
+        case com.ibm.icu.text.DecimalFormat.PAD_AFTER_PREFIX:
+          return PadPosition.AFTER_PREFIX;
+        case com.ibm.icu.text.DecimalFormat.PAD_BEFORE_SUFFIX:
+          return PadPosition.BEFORE_SUFFIX;
+        case com.ibm.icu.text.DecimalFormat.PAD_AFTER_SUFFIX:
+          return PadPosition.AFTER_SUFFIX;
+        default:
+          throw new IllegalArgumentException("Don't know how to map " + old);
+      }
+    }
+
+    public int toOld() {
+      switch (this) {
+        case BEFORE_PREFIX:
+          return com.ibm.icu.text.DecimalFormat.PAD_BEFORE_PREFIX;
+        case AFTER_PREFIX:
+          return com.ibm.icu.text.DecimalFormat.PAD_AFTER_PREFIX;
+        case BEFORE_SUFFIX:
+          return com.ibm.icu.text.DecimalFormat.PAD_BEFORE_SUFFIX;
+        case AFTER_SUFFIX:
+          return com.ibm.icu.text.DecimalFormat.PAD_AFTER_SUFFIX;
+        default:
+          return -1; // silence compiler errors
+      }
+    }
+  }
+
+  /**
+   * Returns true if the currency is set in The property bag or if currency symbols are present in
+   * the prefix/suffix pattern.
+   */
+  public static boolean useCurrency(Properties properties) {
+    return ((properties.getCurrency() != null)
+        || properties.getCurrencyPluralInfo() != null
+        || properties.getCurrencyUsage() != null
+        || AffixPatternUtils.hasCurrencySymbols(properties.getPositivePrefixPattern())
+        || AffixPatternUtils.hasCurrencySymbols(properties.getPositiveSuffixPattern())
+        || AffixPatternUtils.hasCurrencySymbols(properties.getNegativePrefixPattern())
+        || AffixPatternUtils.hasCurrencySymbols(properties.getNegativeSuffixPattern()));
+  }
+}
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/formatters/BigDecimalMultiplier.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/formatters/BigDecimalMultiplier.java
deleted file mode 100644 (file)
index a6a008a..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-// © 2017 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html#License
-package com.ibm.icu.impl.number.formatters;
-
-import java.math.BigDecimal;
-
-import com.ibm.icu.impl.number.Format.BeforeFormat;
-import com.ibm.icu.impl.number.FormatQuantity;
-import com.ibm.icu.impl.number.ModifierHolder;
-import com.ibm.icu.impl.number.Properties;
-
-public class BigDecimalMultiplier extends BeforeFormat {
-  public static interface IProperties {
-
-    static BigDecimal DEFAULT_MULTIPLIER = null;
-
-    /** @see #setMultiplier */
-    public BigDecimal getMultiplier();
-
-    /**
-     * Multiply all numbers by this amount before formatting.
-     *
-     * @param multiplier The amount to multiply by.
-     * @return The property bag, for chaining.
-     * @see MagnitudeMultiplier
-     */
-    public IProperties setMultiplier(BigDecimal multiplier);
-  }
-
-  public static boolean useMultiplier(IProperties properties) {
-    return properties.getMultiplier() != IProperties.DEFAULT_MULTIPLIER;
-  }
-
-  private final BigDecimal multiplier;
-
-  public static BigDecimalMultiplier getInstance(IProperties properties) {
-    if (properties.getMultiplier() == null) {
-      throw new IllegalArgumentException("The multiplier must be present for MultiplierFormat");
-    }
-    // TODO: Intelligently fall back to a MagnitudeMultiplier if the multiplier is a power of ten?
-    return new BigDecimalMultiplier(properties);
-  }
-
-  private BigDecimalMultiplier(IProperties properties) {
-    this.multiplier = properties.getMultiplier();
-  }
-
-  @Override
-  public void before(FormatQuantity input, ModifierHolder mods) {
-    input.multiplyBy(multiplier);
-  }
-
-  @Override
-  public void export(Properties properties) {
-    properties.setMultiplier(multiplier);
-  }
-}
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/formatters/CompactDecimalFormat.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/formatters/CompactDecimalFormat.java
deleted file mode 100644 (file)
index 2caf40f..0000000
+++ /dev/null
@@ -1,553 +0,0 @@
-// © 2017 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html#License
-package com.ibm.icu.impl.number.formatters;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.MissingResourceException;
-
-import com.ibm.icu.impl.ICUData;
-import com.ibm.icu.impl.ICUResourceBundle;
-import com.ibm.icu.impl.StandardPlural;
-import com.ibm.icu.impl.UResource;
-import com.ibm.icu.impl.number.Format;
-import com.ibm.icu.impl.number.FormatQuantity;
-import com.ibm.icu.impl.number.Modifier;
-import com.ibm.icu.impl.number.Modifier.PositiveNegativeModifier;
-import com.ibm.icu.impl.number.ModifierHolder;
-import com.ibm.icu.impl.number.PNAffixGenerator;
-import com.ibm.icu.impl.number.PatternString;
-import com.ibm.icu.impl.number.Properties;
-import com.ibm.icu.impl.number.Rounder;
-import com.ibm.icu.impl.number.modifiers.ConstantAffixModifier;
-import com.ibm.icu.impl.number.modifiers.PositiveNegativeAffixModifier;
-import com.ibm.icu.impl.number.rounders.SignificantDigitsRounder;
-import com.ibm.icu.text.CompactDecimalFormat.CompactStyle;
-import com.ibm.icu.text.CompactDecimalFormat.CompactType;
-import com.ibm.icu.text.DecimalFormatSymbols;
-import com.ibm.icu.text.NumberFormat;
-import com.ibm.icu.text.NumberingSystem;
-import com.ibm.icu.text.PluralRules;
-import com.ibm.icu.util.ULocale;
-import com.ibm.icu.util.UResourceBundle;
-
-public class CompactDecimalFormat extends Format.BeforeFormat {
-  public static interface IProperties
-      extends RoundingFormat.IProperties, CurrencyFormat.ICurrencyProperties {
-
-    static CompactStyle DEFAULT_COMPACT_STYLE = null;
-
-    /** @see #setCompactStyle */
-    public CompactStyle getCompactStyle();
-
-    /**
-     * Use compact decimal formatting with the specified {@link CompactStyle}. CompactStyle.SHORT
-     * produces output like "10K" in locale <em>en-US</em>, whereas CompactStyle.LONG produces
-     * output like "10 thousand" in that locale.
-     *
-     * @param compactStyle The style of prefixes/suffixes to append.
-     * @return The property bag, for chaining.
-     */
-    public IProperties setCompactStyle(CompactStyle compactStyle);
-
-    static Map<String, Map<String, String>> DEFAULT_COMPACT_CUSTOM_DATA = null;
-
-    /** @see #setCompactCustomData */
-    public Map<String, Map<String, String>> getCompactCustomData();
-
-    /**
-     * Specifies custom data to be used instead of CLDR data when constructing a
-     * CompactDecimalFormat. The argument should be a map with the following structure:
-     *
-     * <pre>
-     * {
-     *   "1000": {
-     *     "one": "0 thousand",
-     *     "other": "0 thousand"
-     *   },
-     *   "10000": {
-     *     "one": "00 thousand",
-     *     "other": "00 thousand"
-     *   },
-     *   // ...
-     * }
-     * </pre>
-     *
-     * This API endpoint is used by the CLDR Survey Tool.
-     *
-     * @param compactCustomData A map with the above structure.
-     * @return The property bag, for chaining.
-     * @internal
-     * @deprecated This API is ICU internal only.
-     */
-    @Deprecated
-    public IProperties setCompactCustomData(Map<String, Map<String, String>> compactCustomData);
-  }
-
-  public static boolean useCompactDecimalFormat(IProperties properties) {
-    return properties.getCompactStyle() != IProperties.DEFAULT_COMPACT_STYLE;
-  }
-
-  static final int MAX_DIGITS = 15;
-
-  // Properties
-  private final CompactDecimalData data;
-  private final Rounder rounder;
-  private final PositiveNegativeModifier defaultMod;
-  private final CompactStyle style; // retained for exporting only
-
-  public static CompactDecimalFormat getInstance(
-      DecimalFormatSymbols symbols, IProperties properties) {
-    return new CompactDecimalFormat(symbols, properties);
-  }
-
-  private static final int DEFAULT_MIN_SIG = 1;
-  private static final int DEFAULT_MAX_SIG = 2;
-
-  private static final ThreadLocal<Properties> threadLocalProperties =
-      new ThreadLocal<Properties>() {
-        @Override
-        protected Properties initialValue() {
-          return new Properties();
-        }
-      };
-
-  private static Rounder getRounder(IProperties properties) {
-    // Use rounding settings if they were specified, or else use the default CDF rounder.
-    // TODO: Detecting and overriding significant digits here is a bit of a hack, since detection
-    // is also performed in the "RoundingFormat.getDefaultOrNull" method.
-    // It would be more elegant to call some sort of "fallback" copy method.
-    Rounder rounder = null;
-    if (!SignificantDigitsRounder.useSignificantDigits(properties)) {
-      rounder = RoundingFormat.getDefaultOrNull(properties);
-    }
-    if (rounder == null) {
-      int _minSig = properties.getMinimumSignificantDigits();
-      int _maxSig = properties.getMaximumSignificantDigits();
-      Properties rprops = threadLocalProperties.get().clear();
-      // Settings needing possible override:
-      rprops.setMinimumSignificantDigits(_minSig > 0 ? _minSig : DEFAULT_MIN_SIG);
-      rprops.setMaximumSignificantDigits(_maxSig > 0 ? _maxSig : DEFAULT_MAX_SIG);
-      // TODO: Should copyFrom() be used instead?  It requires a cast.
-      // Settings to copy verbatim:
-      rprops.setRoundingMode(properties.getRoundingMode());
-      rprops.setMinimumFractionDigits(properties.getMinimumFractionDigits());
-      rprops.setMaximumFractionDigits(properties.getMaximumFractionDigits());
-      rprops.setMinimumIntegerDigits(properties.getMinimumIntegerDigits());
-      rprops.setMaximumIntegerDigits(properties.getMaximumIntegerDigits());
-      rounder = SignificantDigitsRounder.getInstance(rprops);
-    }
-    return rounder;
-  }
-
-  protected static final ThreadLocal<Map<CompactDecimalFingerprint, CompactDecimalData>>
-      threadLocalDataCache =
-          new ThreadLocal<Map<CompactDecimalFingerprint, CompactDecimalData>>() {
-            @Override
-            protected Map<CompactDecimalFingerprint, CompactDecimalData> initialValue() {
-              return new HashMap<CompactDecimalFingerprint, CompactDecimalData>();
-            }
-          };
-
-  private static CompactDecimalData getData(
-      DecimalFormatSymbols symbols, CompactDecimalFingerprint fingerprint) {
-    // See if we already have a data object based on the fingerprint
-    CompactDecimalData data = threadLocalDataCache.get().get(fingerprint);
-    if (data != null) return data;
-
-    // Make data bundle object
-    data = new CompactDecimalData();
-    ULocale ulocale = symbols.getULocale();
-    CompactDecimalDataSink sink = new CompactDecimalDataSink(data, symbols, fingerprint);
-    String nsName = NumberingSystem.getInstance(ulocale).getName();
-    ICUResourceBundle rb =
-        (ICUResourceBundle) UResourceBundle.getBundleInstance(ICUData.ICU_BASE_NAME, ulocale);
-    internalPopulateData(nsName, rb, sink, data);
-    if (data.isEmpty() && fingerprint.compactStyle == CompactStyle.LONG) {
-      // No long data is available; load short data instead
-      sink.compactStyle = CompactStyle.SHORT;
-      internalPopulateData(nsName, rb, sink, data);
-    }
-    threadLocalDataCache.get().put(fingerprint, data);
-    return data;
-  }
-
-  private static void internalPopulateData(
-      String nsName, ICUResourceBundle rb, CompactDecimalDataSink sink, CompactDecimalData data) {
-    try {
-      rb.getAllItemsWithFallback("NumberElements/" + nsName, sink);
-    } catch (MissingResourceException e) {
-      // Fall back to latn
-    }
-    if (data.isEmpty() && !nsName.equals("latn")) {
-      rb.getAllItemsWithFallback("NumberElements/latn", sink);
-    }
-    if (sink.exception != null) {
-      throw sink.exception;
-    }
-  }
-
-  private static PositiveNegativeModifier getDefaultMod(
-      DecimalFormatSymbols symbols, CompactDecimalFingerprint fingerprint) {
-    ULocale uloc = symbols.getULocale();
-    String pattern;
-    if (fingerprint.compactType == CompactType.CURRENCY) {
-      pattern = NumberFormat.getPatternForStyle(uloc, NumberFormat.CURRENCYSTYLE);
-    } else {
-      pattern = NumberFormat.getPatternForStyle(uloc, NumberFormat.NUMBERSTYLE);
-    }
-    // TODO: Clean this up; avoid the extra object creations.
-    // TODO: Currency may also need to override grouping settings, not just affixes.
-    Properties properties = PatternString.parseToProperties(pattern);
-    PNAffixGenerator pnag = PNAffixGenerator.getThreadLocalInstance();
-    PNAffixGenerator.Result result =
-        pnag.getModifiers(symbols, fingerprint.currencySymbol, properties);
-    return new PositiveNegativeAffixModifier(result.positive, result.negative);
-  }
-
-  private CompactDecimalFormat(DecimalFormatSymbols symbols, IProperties properties) {
-    CompactDecimalFingerprint fingerprint = new CompactDecimalFingerprint(symbols, properties);
-    this.rounder = getRounder(properties);
-    // Short-circuit and use custom data if provided
-    if (properties.getCompactCustomData() != null) {
-      this.data = createDataFromCustom(symbols, fingerprint, properties.getCompactCustomData());
-    } else {
-      this.data = getData(symbols, fingerprint);
-    }
-    this.defaultMod = getDefaultMod(symbols, fingerprint);
-    this.style = properties.getCompactStyle(); // for exporting only
-  }
-
-  @Override
-  public void before(FormatQuantity input, ModifierHolder mods, PluralRules rules) {
-    apply(input, mods, rules, rounder, data, defaultMod);
-  }
-
-  @Override
-  protected void before(FormatQuantity input, ModifierHolder mods) {
-    throw new UnsupportedOperationException();
-  }
-
-  public static void apply(
-      FormatQuantity input,
-      ModifierHolder mods,
-      PluralRules rules,
-      DecimalFormatSymbols symbols,
-      IProperties properties) {
-    CompactDecimalFingerprint fingerprint = new CompactDecimalFingerprint(symbols, properties);
-    Rounder rounder = getRounder(properties);
-    CompactDecimalData data = getData(symbols, fingerprint);
-    PositiveNegativeModifier defaultMod = getDefaultMod(symbols, fingerprint);
-    apply(input, mods, rules, rounder, data, defaultMod);
-  }
-
-  private static void apply(
-      FormatQuantity input,
-      ModifierHolder mods,
-      PluralRules rules,
-      Rounder rounder,
-      CompactDecimalData data,
-      PositiveNegativeModifier defaultMod) {
-
-    // Treat zero as if it had magnitude 0
-    int magnitude;
-    if (input.isZero()) {
-      magnitude = 0;
-      rounder.apply(input);
-    } else {
-      // TODO: Revisit chooseMultiplierAndApply
-      int multiplier = rounder.chooseMultiplierAndApply(input, data);
-      magnitude = input.isZero() ? 0 : input.getMagnitude();
-      magnitude -= multiplier;
-    }
-
-    StandardPlural plural = input.getStandardPlural(rules);
-    boolean isNegative = input.isNegative();
-    Modifier mod = data.getModifier(magnitude, plural, isNegative);
-    if (mod == null) {
-      // Use the default (non-compact) modifier.
-      mod = defaultMod.getModifier(isNegative);
-    }
-    mods.add(mod);
-  }
-
-  @Override
-  public void export(Properties properties) {
-    properties.setCompactStyle(style);
-    rounder.export(properties);
-  }
-
-  static class CompactDecimalData implements Rounder.MultiplierGenerator {
-
-    // A dummy object used when a "0" compact decimal entry is encountered.  This is necessary
-    // in order to prevent falling back to root.
-    private static final Modifier USE_FALLBACK = new ConstantAffixModifier();
-
-    final Modifier[] mods;
-    final byte[] multipliers;
-    boolean isEmpty;
-    int largestMagnitude;
-
-    CompactDecimalData() {
-      mods = new Modifier[(MAX_DIGITS + 1) * StandardPlural.COUNT * 2];
-      multipliers = new byte[MAX_DIGITS + 1];
-      isEmpty = true;
-      largestMagnitude = -1;
-    }
-
-    boolean isEmpty() {
-      return isEmpty;
-    }
-
-    @Override
-    public int getMultiplier(int magnitude) {
-      if (magnitude < 0) {
-        return 0;
-      }
-      if (magnitude > largestMagnitude) {
-        magnitude = largestMagnitude;
-      }
-      return multipliers[magnitude];
-    }
-
-    int setOrGetMultiplier(int magnitude, byte multiplier) {
-      if (multipliers[magnitude] != 0) {
-        return multipliers[magnitude];
-      }
-      multipliers[magnitude] = multiplier;
-      isEmpty = false;
-      if (magnitude > largestMagnitude) largestMagnitude = magnitude;
-      return multiplier;
-    }
-
-    Modifier getModifier(int magnitude, StandardPlural plural, boolean isNegative) {
-      if (magnitude < 0) {
-        return null;
-      }
-      if (magnitude > largestMagnitude) {
-        magnitude = largestMagnitude;
-      }
-      Modifier mod = mods[modIndex(magnitude, plural, isNegative)];
-      if (mod == null && plural != StandardPlural.OTHER) {
-        // Fall back to "other" plural variant
-        mod = mods[modIndex(magnitude, StandardPlural.OTHER, isNegative)];
-      }
-      if (mod == USE_FALLBACK) {
-        // Return null if USE_FALLBACK is present
-        mod = null;
-      }
-      return mod;
-    }
-
-    public boolean has(int magnitude, StandardPlural plural) {
-      // Return true if USE_FALLBACK is present
-      return mods[modIndex(magnitude, plural, false)] != null;
-    }
-
-    void setModifiers(Modifier positive, Modifier negative, int magnitude, StandardPlural plural) {
-      mods[modIndex(magnitude, plural, false)] = positive;
-      mods[modIndex(magnitude, plural, true)] = negative;
-      isEmpty = false;
-      if (magnitude > largestMagnitude) largestMagnitude = magnitude;
-    }
-
-    void setNoFallback(int magnitude, StandardPlural plural) {
-      setModifiers(USE_FALLBACK, USE_FALLBACK, magnitude, plural);
-    }
-
-    private static final int modIndex(int magnitude, StandardPlural plural, boolean isNegative) {
-      return magnitude * StandardPlural.COUNT * 2 + plural.ordinal() * 2 + (isNegative ? 1 : 0);
-    }
-  }
-
-  static class CompactDecimalFingerprint {
-    // TODO: Add more stuff to the fingerprint, like the symbols used by PNAffixGenerator
-    final CompactStyle compactStyle;
-    final CompactType compactType;
-    final ULocale uloc;
-    final String currencySymbol;
-
-    CompactDecimalFingerprint(DecimalFormatSymbols symbols, IProperties properties) {
-      // CompactDecimalFormat does not need to worry about the same constraints as non-compact
-      // currency formatting needs to consider, like the currency rounding mode and the currency
-      // long names with plural forms.
-      if (properties.getCurrency() != CurrencyFormat.ICurrencyProperties.DEFAULT_CURRENCY) {
-        compactType = CompactType.CURRENCY;
-        currencySymbol = CurrencyFormat.getCurrencySymbol(symbols, properties);
-      } else {
-        compactType = CompactType.DECIMAL;
-        currencySymbol = ""; // fallback; should remain unused
-      }
-      compactStyle = properties.getCompactStyle();
-      uloc = symbols.getULocale();
-    }
-
-    @Override
-    public boolean equals(Object _other) {
-      if (_other == null) return false;
-      CompactDecimalFingerprint other = (CompactDecimalFingerprint) _other;
-      if (this == other) return true;
-      if (compactStyle != other.compactStyle) return false;
-      if (compactType != other.compactType) return false;
-      if (currencySymbol != other.currencySymbol) {
-        // String comparison with null handling
-        if (currencySymbol == null || other.currencySymbol == null) return false;
-        if (!currencySymbol.equals(other.currencySymbol)) return false;
-      }
-      if (!uloc.equals(other.uloc)) return false;
-      return true;
-    }
-
-    @Override
-    public int hashCode() {
-      int hashCode = 0;
-      if (compactStyle != null) hashCode ^= compactStyle.hashCode();
-      if (compactType != null) hashCode ^= compactType.hashCode();
-      if (uloc != null) hashCode ^= uloc.hashCode();
-      if (currencySymbol != null) hashCode ^= currencySymbol.hashCode();
-      return hashCode;
-    }
-  }
-
-  private static final class CompactDecimalDataSink extends UResource.Sink {
-
-    CompactDecimalData data;
-    DecimalFormatSymbols symbols;
-    CompactStyle compactStyle;
-    CompactType compactType;
-    String currencySymbol;
-    PNAffixGenerator pnag;
-    IllegalArgumentException exception;
-
-    /*
-     * NumberElements{              <-- top (numbering system table)
-     *  latn{                       <-- patternsTable (one per numbering system)
-     *    patternsLong{             <-- formatsTable (one per pattern)
-     *      decimalFormat{          <-- powersOfTenTable (one per format)
-     *        1000{                 <-- pluralVariantsTable (one per power of ten)
-     *          one{"0 thousand"}   <-- plural variant and template
-     */
-
-    public CompactDecimalDataSink(
-        CompactDecimalData data,
-        DecimalFormatSymbols symbols,
-        CompactDecimalFingerprint fingerprint) {
-      this.data = data;
-      this.symbols = symbols;
-      compactType = fingerprint.compactType;
-      currencySymbol = fingerprint.currencySymbol;
-      compactStyle = fingerprint.compactStyle;
-      pnag = PNAffixGenerator.getThreadLocalInstance();
-    }
-
-    @Override
-    public void put(UResource.Key key, UResource.Value value, boolean isRoot) {
-      UResource.Table patternsTable = value.getTable();
-      for (int i1 = 0; patternsTable.getKeyAndValue(i1, key, value); ++i1) {
-        if (key.contentEquals("patternsShort") && compactStyle == CompactStyle.SHORT) {
-        } else if (key.contentEquals("patternsLong") && compactStyle == CompactStyle.LONG) {
-        } else {
-          continue;
-        }
-
-        // traverse into the table of formats
-        UResource.Table formatsTable = value.getTable();
-        for (int i2 = 0; formatsTable.getKeyAndValue(i2, key, value); ++i2) {
-          if (key.contentEquals("decimalFormat") && compactType == CompactType.DECIMAL) {
-          } else if (key.contentEquals("currencyFormat") && compactType == CompactType.CURRENCY) {
-          } else {
-            continue;
-          }
-
-          // traverse into the table of powers of ten
-          UResource.Table powersOfTenTable = value.getTable();
-          for (int i3 = 0; powersOfTenTable.getKeyAndValue(i3, key, value); ++i3) {
-            try {
-
-              // Assumes that the keys are always of the form "10000" where the magnitude is the
-              // length of the key minus one
-              byte magnitude = (byte) (key.length() - 1);
-
-              // Silently ignore divisors that are too big.
-              if (magnitude >= MAX_DIGITS) continue;
-
-              // Iterate over the plural variants ("one", "other", etc)
-              UResource.Table pluralVariantsTable = value.getTable();
-              for (int i4 = 0; pluralVariantsTable.getKeyAndValue(i4, key, value); ++i4) {
-
-                // Skip this magnitude/plural if we already have it from a child locale.
-                StandardPlural plural = StandardPlural.fromString(key.toString());
-                if (data.has(magnitude, plural)) {
-                  continue;
-                }
-
-                // The value "0" means that we need to use the default pattern and not fall back
-                // to parent locales.  Example locale where this is relevant: 'it'.
-                String patternString = value.toString();
-                if (patternString.equals("0")) {
-                  data.setNoFallback(magnitude, plural);
-                  continue;
-                }
-
-                // The magnitude multiplier is the difference between the magnitude and the number
-                // of zeros in the pattern, getMinimumIntegerDigits.
-                Properties properties = PatternString.parseToProperties(patternString);
-                byte _multiplier = (byte) -(magnitude - properties.getMinimumIntegerDigits() + 1);
-                if (_multiplier != data.setOrGetMultiplier(magnitude, _multiplier)) {
-                  throw new IllegalArgumentException(
-                      String.format(
-                          "Different number of zeros for same power of ten in compact decimal format data for locale '%s', style '%s', type '%s'",
-                          symbols.getULocale().toString(),
-                          compactStyle.toString(),
-                          compactType.toString()));
-                }
-
-                PNAffixGenerator.Result result =
-                    pnag.getModifiers(symbols, currencySymbol, properties);
-                data.setModifiers(result.positive, result.negative, magnitude, plural);
-              }
-
-            } catch (IllegalArgumentException e) {
-              exception = e;
-              continue;
-            }
-          }
-
-          // We want only one table of compact decimal formats, so if we get here, stop consuming.
-          // The data.isEmpty() check will prevent further bundles from being traversed.
-          return;
-        }
-      }
-    }
-  }
-
-  /**
-   * Uses data from the custom powersToPluralsToPatterns map instead of an ICUResourceBundle to
-   * populate an instance of CompactDecimalData.
-   */
-  static CompactDecimalData createDataFromCustom(
-      DecimalFormatSymbols symbols,
-      CompactDecimalFingerprint fingerprint,
-      Map<String, Map<String, String>> powersToPluralsToPatterns) {
-    CompactDecimalData data = new CompactDecimalData();
-    PNAffixGenerator pnag = PNAffixGenerator.getThreadLocalInstance();
-    for (Map.Entry<String, Map<String, String>> magnitudeEntry :
-        powersToPluralsToPatterns.entrySet()) {
-      byte magnitude = (byte) (magnitudeEntry.getKey().length() - 1);
-      for (Map.Entry<String, String> pluralEntry : magnitudeEntry.getValue().entrySet()) {
-        StandardPlural plural = StandardPlural.fromString(pluralEntry.getKey().toString());
-        String patternString = pluralEntry.getValue().toString();
-        Properties properties = PatternString.parseToProperties(patternString);
-        byte _multiplier = (byte) -(magnitude - properties.getMinimumIntegerDigits() + 1);
-        if (_multiplier != data.setOrGetMultiplier(magnitude, _multiplier)) {
-          throw new IllegalArgumentException(
-              "Different number of zeros for same power of ten in custom compact decimal format data");
-        }
-        PNAffixGenerator.Result result =
-            pnag.getModifiers(symbols, fingerprint.currencySymbol, properties);
-        data.setModifiers(result.positive, result.negative, magnitude, plural);
-      }
-    }
-    return data;
-  }
-}
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/formatters/CurrencyFormat.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/formatters/CurrencyFormat.java
deleted file mode 100644 (file)
index 41e9d3f..0000000
+++ /dev/null
@@ -1,311 +0,0 @@
-// © 2017 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html#License
-package com.ibm.icu.impl.number.formatters;
-
-import java.math.BigDecimal;
-
-import com.ibm.icu.impl.StandardPlural;
-import com.ibm.icu.impl.number.AffixPatternUtils;
-import com.ibm.icu.impl.number.PNAffixGenerator;
-import com.ibm.icu.impl.number.PatternString;
-import com.ibm.icu.impl.number.Properties;
-import com.ibm.icu.impl.number.Rounder;
-import com.ibm.icu.impl.number.modifiers.GeneralPluralModifier;
-import com.ibm.icu.impl.number.rounders.IncrementRounder;
-import com.ibm.icu.impl.number.rounders.MagnitudeRounder;
-import com.ibm.icu.impl.number.rounders.SignificantDigitsRounder;
-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;
-
-public class CurrencyFormat {
-
-  public enum CurrencyStyle {
-    SYMBOL,
-    ISO_CODE;
-  }
-
-  public static interface ICurrencyProperties {
-    static Currency DEFAULT_CURRENCY = null;
-
-    /** @see #setCurrency */
-    public Currency getCurrency();
-
-    /**
-     * Use the specified currency to substitute currency placeholders ('¤') in the pattern string.
-     *
-     * @param currency The currency.
-     * @return The property bag, for chaining.
-     */
-    public IProperties setCurrency(Currency currency);
-
-    static CurrencyStyle DEFAULT_CURRENCY_STYLE = null;
-
-    /** @see #setCurrencyStyle */
-    public CurrencyStyle getCurrencyStyle();
-
-    /**
-     * Use the specified {@link CurrencyStyle} to replace currency placeholders ('¤').
-     * CurrencyStyle.SYMBOL will use the short currency symbol, like "$" or "€", whereas
-     * CurrencyStyle.ISO_CODE will use the ISO 4217 currency code, like "USD" or "EUR".
-     *
-     * <p>For long currency names, use {@link MeasureFormat.IProperties#setMeasureUnit}.
-     *
-     * @param currencyStyle The currency style. Defaults to CurrencyStyle.SYMBOL.
-     * @return The property bag, for chaining.
-     */
-    public IProperties setCurrencyStyle(CurrencyStyle currencyStyle);
-
-    /**
-     * An old enum that specifies how currencies should be rounded. It contains a subset of the
-     * functionality supported by RoundingInterval.
-     */
-    static Currency.CurrencyUsage DEFAULT_CURRENCY_USAGE = null;
-
-    /** @see #setCurrencyUsage */
-    public Currency.CurrencyUsage getCurrencyUsage();
-
-    /**
-     * Use the specified {@link CurrencyUsage} instance, which provides default rounding rules for
-     * the currency in two styles, CurrencyUsage.CASH and CurrencyUsage.STANDARD.
-     *
-     * <p>The CurrencyUsage specified here will not be used unless there is a currency placeholder
-     * in the pattern.
-     *
-     * @param currencyUsage The currency usage. Defaults to CurrencyUsage.STANDARD.
-     * @return The property bag, for chaining.
-     */
-    public IProperties setCurrencyUsage(Currency.CurrencyUsage currencyUsage);
-
-    static CurrencyPluralInfo DEFAULT_CURRENCY_PLURAL_INFO = null;
-
-    /** @see #setCurrencyPluralInfo */
-    @Deprecated
-    public CurrencyPluralInfo getCurrencyPluralInfo();
-
-    /**
-     * Use the specified {@link CurrencyPluralInfo} instance when formatting currency long names.
-     *
-     * @param currencyPluralInfo The currency plural info object.
-     * @return The property bag, for chaining.
-     * @deprecated Use {@link MeasureFormat.IProperties#setMeasureUnit} with a Currency instead.
-     */
-    @Deprecated
-    public IProperties setCurrencyPluralInfo(CurrencyPluralInfo currencyPluralInfo);
-  }
-
-  public static interface IProperties
-      extends ICurrencyProperties,
-          RoundingFormat.IProperties,
-          PositiveNegativeAffixFormat.IProperties {}
-
-  /**
-   * Returns true if the currency is set in The property bag or if currency symbols are present in
-   * the prefix/suffix pattern.
-   */
-  public static boolean useCurrency(IProperties properties) {
-    return ((properties.getCurrency() != null)
-        || properties.getCurrencyPluralInfo() != null
-        || properties.getCurrencyUsage() != null
-        || AffixPatternUtils.hasCurrencySymbols(properties.getPositivePrefixPattern())
-        || AffixPatternUtils.hasCurrencySymbols(properties.getPositiveSuffixPattern())
-        || AffixPatternUtils.hasCurrencySymbols(properties.getNegativePrefixPattern())
-        || AffixPatternUtils.hasCurrencySymbols(properties.getNegativeSuffixPattern()));
-  }
-
-  /**
-   * Returns the effective currency symbol based on the input. If {@link
-   * ICurrencyProperties#setCurrencyStyle} was set to {@link CurrencyStyle#ISO_CODE}, the ISO Code
-   * will be returned; otherwise, the currency symbol, like "$", will be returned.
-   *
-   * @param symbols The current {@link DecimalFormatSymbols} instance
-   * @param properties The current property bag
-   * @return The currency symbol string, e.g., to substitute '¤' in a decimal pattern string.
-   */
-  public static String getCurrencySymbol(
-      DecimalFormatSymbols symbols, ICurrencyProperties properties) {
-    // If the user asked for ISO Code, return the ISO Code instead of the symbol
-    CurrencyStyle style = properties.getCurrencyStyle();
-    if (style == CurrencyStyle.ISO_CODE) {
-      return getCurrencyIsoCode(symbols, properties);
-    }
-
-    // Get the currency symbol
-    Currency currency = properties.getCurrency();
-    if (currency == null) {
-      return symbols.getCurrencySymbol();
-    } else if (currency.equals(symbols.getCurrency())) {
-      // The user may have set a custom currency symbol in DecimalFormatSymbols.
-      return symbols.getCurrencySymbol();
-    } else {
-      // Use the canonical symbol.
-      return currency.getName(symbols.getULocale(), Currency.SYMBOL_NAME, null);
-    }
-  }
-
-  /**
-   * Returns the currency ISO code based on the input, like "USD".
-   *
-   * @param symbols The current {@link DecimalFormatSymbols} instance
-   * @param properties The current property bag
-   * @return The currency ISO code string, e.g., to substitute '¤¤' in a decimal pattern string.
-   */
-  public static String getCurrencyIsoCode(
-      DecimalFormatSymbols symbols, ICurrencyProperties properties) {
-    Currency currency = properties.getCurrency();
-    if (currency == null) {
-      // If a currency object was not provided, use the string from symbols
-      // Note: symbols.getCurrency().getCurrencyCode() won't work here because
-      // DecimalFormatSymbols#setInternationalCurrencySymbol() does not update the
-      // immutable internal currency instance.
-      return symbols.getInternationalCurrencySymbol();
-    } else if (currency.equals(symbols.getCurrency())) {
-      // The user may have set a custom currency symbol in DecimalFormatSymbols.
-      return symbols.getInternationalCurrencySymbol();
-    } else {
-      // Use the canonical currency code.
-      return currency.getCurrencyCode();
-    }
-  }
-
-  /**
-   * Returns the currency long name on the input, like "US dollars".
-   *
-   * @param symbols The current {@link DecimalFormatSymbols} instance
-   * @param properties The current property bag
-   * @param plural The plural form
-   * @return The currency long name string, e.g., to substitute '¤¤¤' in a decimal pattern string.
-   */
-  public static String getCurrencyLongName(
-      DecimalFormatSymbols symbols, ICurrencyProperties properties, StandardPlural plural) {
-    // Attempt to get a currency object first from properties then from symbols
-    Currency currency = properties.getCurrency();
-    if (currency == null) {
-      currency = symbols.getCurrency();
-    }
-
-    // If no currency object is available, fall back to the currency symbol
-    if (currency == null) {
-      return getCurrencySymbol(symbols, properties);
-    }
-
-    // Get the long name
-    return currency.getName(
-        symbols.getULocale(), Currency.PLURAL_LONG_NAME, plural.getKeyword(), null);
-  }
-
-  public static GeneralPluralModifier getCurrencyModifier(
-      DecimalFormatSymbols symbols, IProperties properties) {
-
-    PNAffixGenerator pnag = PNAffixGenerator.getThreadLocalInstance();
-    String sym = getCurrencySymbol(symbols, properties);
-    String iso = getCurrencyIsoCode(symbols, properties);
-
-    // Previously, the user was also able to specify '¤¤' and '¤¤¤' directly into the prefix or
-    // suffix, which is how the user specified whether they wanted the ISO code or long name.
-    // For backwards compatibility support, that feature is implemented here.
-
-    CurrencyPluralInfo info = properties.getCurrencyPluralInfo();
-    GeneralPluralModifier mod = new GeneralPluralModifier();
-    Properties temp = new Properties();
-    for (StandardPlural plural : StandardPlural.VALUES) {
-      String longName = getCurrencyLongName(symbols, properties, plural);
-
-      PNAffixGenerator.Result result;
-      if (info == null) {
-        // CurrencyPluralInfo is not available.
-        result = pnag.getModifiers(symbols, sym, iso, longName, properties);
-      } else {
-        // CurrencyPluralInfo is available. Use it to generate affixes for long name support.
-        String pluralPattern = info.getCurrencyPluralPattern(plural.getKeyword());
-        PatternString.parseToExistingProperties(
-            pluralPattern, temp, PatternString.IGNORE_ROUNDING_ALWAYS);
-        result = pnag.getModifiers(symbols, sym, iso, longName, temp);
-      }
-      mod.put(plural, result.positive, result.negative);
-    }
-    return mod;
-  }
-
-  private static final Currency DEFAULT_CURRENCY = Currency.getInstance("XXX");
-
-  public static void populateCurrencyRounderProperties(
-      Properties destination, DecimalFormatSymbols symbols, IProperties properties) {
-
-    Currency currency = properties.getCurrency();
-    if (currency == null) {
-      // Fall back to the DecimalFormatSymbols currency instance.
-      currency = symbols.getCurrency();
-    }
-    if (currency == null) {
-      // There is a currency symbol in the pattern, but we have no currency available to use.
-      // Use the default currency instead so that we can still apply currency usage rules.
-      currency = DEFAULT_CURRENCY;
-    }
-
-    CurrencyUsage _currencyUsage = properties.getCurrencyUsage();
-    int _minFrac = properties.getMinimumFractionDigits();
-    int _maxFrac = properties.getMaximumFractionDigits();
-
-    CurrencyUsage effectiveCurrencyUsage =
-        (_currencyUsage != null) ? _currencyUsage : CurrencyUsage.STANDARD;
-    double incrementDouble = currency.getRoundingIncrement(effectiveCurrencyUsage);
-    int fractionDigits = currency.getDefaultFractionDigits(effectiveCurrencyUsage);
-
-    destination.setRoundingMode(properties.getRoundingMode());
-    destination.setMinimumIntegerDigits(properties.getMinimumIntegerDigits());
-    destination.setMaximumIntegerDigits(properties.getMaximumIntegerDigits());
-
-    if (_currencyUsage == null && (_minFrac >= 0 || _maxFrac >= 0)) {
-      // User override of fraction length
-      if (_minFrac < 0) {
-        destination.setMinimumFractionDigits(fractionDigits < _maxFrac ? fractionDigits : _maxFrac);
-        destination.setMaximumFractionDigits(_maxFrac);
-      } else if (_maxFrac < 0) {
-        destination.setMinimumFractionDigits(_minFrac);
-        destination.setMaximumFractionDigits(fractionDigits > _minFrac ? fractionDigits : _minFrac);
-      } else {
-        destination.setMinimumFractionDigits(_minFrac);
-        destination.setMaximumFractionDigits(_maxFrac);
-      }
-    } else {
-      // Currency rounding
-      destination.setMinimumFractionDigits(fractionDigits);
-      destination.setMaximumFractionDigits(fractionDigits);
-    }
-
-    if (incrementDouble > 0.0) {
-      BigDecimal incrementBigDecimal;
-      BigDecimal _roundingIncrement = properties.getRoundingIncrement();
-      if (_roundingIncrement != null) {
-        incrementBigDecimal = _roundingIncrement;
-      } else {
-        incrementBigDecimal = BigDecimal.valueOf(incrementDouble);
-      }
-      destination.setRoundingIncrement(incrementBigDecimal);
-    } else {
-    }
-  }
-
-  private static final ThreadLocal<Properties> threadLocalProperties =
-      new ThreadLocal<Properties>() {
-        @Override
-        protected Properties initialValue() {
-          return new Properties();
-        }
-      };
-
-  public static Rounder getCurrencyRounder(DecimalFormatSymbols symbols, IProperties properties) {
-    if (SignificantDigitsRounder.useSignificantDigits(properties)) {
-      return SignificantDigitsRounder.getInstance(properties);
-    }
-    Properties cprops = threadLocalProperties.get().clear();
-    populateCurrencyRounderProperties(cprops, symbols, properties);
-    if (cprops.getRoundingIncrement() != null) {
-      return IncrementRounder.getInstance(cprops);
-    } else {
-      return MagnitudeRounder.getInstance(cprops);
-    }
-  }
-}
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/formatters/MagnitudeMultiplier.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/formatters/MagnitudeMultiplier.java
deleted file mode 100644 (file)
index 6e19c7d..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-// © 2017 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html#License
-package com.ibm.icu.impl.number.formatters;
-
-import com.ibm.icu.impl.number.Format;
-import com.ibm.icu.impl.number.Format.BeforeFormat;
-import com.ibm.icu.impl.number.FormatQuantity;
-import com.ibm.icu.impl.number.ModifierHolder;
-import com.ibm.icu.impl.number.Properties;
-
-public class MagnitudeMultiplier extends Format.BeforeFormat {
-  private static final MagnitudeMultiplier DEFAULT = new MagnitudeMultiplier(0);
-
-  public static interface IProperties {
-
-    static int DEFAULT_MAGNITUDE_MULTIPLIER = 0;
-
-    /** @see #setMagnitudeMultiplier */
-    public int getMagnitudeMultiplier();
-
-    /**
-     * Multiply all numbers by this power of ten before formatting. Negative multipliers reduce the
-     * magnitude and make numbers smaller (closer to zero).
-     *
-     * @param magnitudeMultiplier The number of powers of ten to scale.
-     * @return The property bag, for chaining.
-     * @see BigDecimalMultiplier
-     */
-    public IProperties setMagnitudeMultiplier(int magnitudeMultiplier);
-  }
-
-  public static boolean useMagnitudeMultiplier(IProperties properties) {
-    return properties.getMagnitudeMultiplier() != IProperties.DEFAULT_MAGNITUDE_MULTIPLIER;
-  }
-
-  // Properties
-  final int delta;
-
-  public static BeforeFormat getInstance(Properties properties) {
-    if (properties.getMagnitudeMultiplier() == 0) {
-      return DEFAULT;
-    }
-    return new MagnitudeMultiplier(properties.getMagnitudeMultiplier());
-  }
-
-  private MagnitudeMultiplier(int delta) {
-    this.delta = delta;
-  }
-
-  @Override
-  public void before(FormatQuantity input, ModifierHolder mods) {
-    input.adjustMagnitude(delta);
-  }
-
-  @Override
-  public void export(Properties properties) {
-    properties.setMagnitudeMultiplier(delta);
-  }
-}
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/formatters/MeasureFormat.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/formatters/MeasureFormat.java
deleted file mode 100644 (file)
index 752dc0a..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-// © 2017 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html#License
-package com.ibm.icu.impl.number.formatters;
-
-import com.ibm.icu.impl.StandardPlural;
-import com.ibm.icu.impl.number.modifiers.GeneralPluralModifier;
-import com.ibm.icu.impl.number.modifiers.SimpleModifier;
-import com.ibm.icu.text.DecimalFormatSymbols;
-import com.ibm.icu.text.MeasureFormat.FormatWidth;
-import com.ibm.icu.util.MeasureUnit;
-import com.ibm.icu.util.ULocale;
-
-public class MeasureFormat {
-
-  public static interface IProperties {
-
-    static MeasureUnit DEFAULT_MEASURE_UNIT = null;
-
-    /** @see #setMeasureUnit */
-    public MeasureUnit getMeasureUnit();
-
-    /**
-     * Apply prefixes and suffixes for the specified {@link MeasureUnit} to the formatted number.
-     *
-     * @param measureUnit The measure unit.
-     * @return The property bag, for chaining.
-     */
-    public IProperties setMeasureUnit(MeasureUnit measureUnit);
-
-    static FormatWidth DEFAULT_MEASURE_FORMAT_WIDTH = null;
-
-    /** @see #setMeasureFormatWidth */
-    public FormatWidth getMeasureFormatWidth();
-
-    /**
-     * Use the specified {@link FormatWidth} when choosing the style of measure unit prefix/suffix.
-     *
-     * <p>Must be used in conjunction with {@link #setMeasureUnit}.
-     *
-     * @param measureFormatWidth The width style. Defaults to FormatWidth.WIDE.
-     * @return The property bag, for chaining.
-     */
-    public IProperties setMeasureFormatWidth(FormatWidth measureFormatWidth);
-  }
-
-  public static boolean useMeasureFormat(IProperties properties) {
-    return properties.getMeasureUnit() != IProperties.DEFAULT_MEASURE_UNIT;
-  }
-
-  public static GeneralPluralModifier getInstance(DecimalFormatSymbols symbols, IProperties properties) {
-    ULocale uloc = symbols.getULocale();
-    MeasureUnit unit = properties.getMeasureUnit();
-    FormatWidth width = properties.getMeasureFormatWidth();
-
-    if (unit == null) {
-      throw new IllegalArgumentException("A measure unit is required for MeasureFormat");
-    }
-    if (width == null) {
-      width = FormatWidth.WIDE;
-    }
-
-    // Temporarily, create a MeasureFormat instance for its data loading capability
-    // TODO: Move data loading directly into this class file
-    com.ibm.icu.text.MeasureFormat mf = com.ibm.icu.text.MeasureFormat.getInstance(uloc, width);
-    GeneralPluralModifier mod = new GeneralPluralModifier();
-    for (StandardPlural plural : StandardPlural.VALUES) {
-      String formatString = null;
-      mf.getPluralFormatter(unit, width, plural.ordinal());
-      mod.put(plural, new SimpleModifier(formatString, null, false));
-    }
-    return mod;
-  }
-}
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/formatters/PaddingFormat.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/formatters/PaddingFormat.java
deleted file mode 100644 (file)
index 77eb6dc..0000000
+++ /dev/null
@@ -1,173 +0,0 @@
-// © 2017 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html#License
-package com.ibm.icu.impl.number.formatters;
-
-import com.ibm.icu.impl.number.Format.AfterFormat;
-import com.ibm.icu.impl.number.ModifierHolder;
-import com.ibm.icu.impl.number.NumberStringBuilder;
-import com.ibm.icu.impl.number.Properties;
-
-public class PaddingFormat implements AfterFormat {
-  public enum PadPosition {
-    BEFORE_PREFIX,
-    AFTER_PREFIX,
-    BEFORE_SUFFIX,
-    AFTER_SUFFIX;
-
-    public static PadPosition fromOld(int old) {
-      switch (old) {
-        case com.ibm.icu.text.DecimalFormat.PAD_BEFORE_PREFIX:
-          return PadPosition.BEFORE_PREFIX;
-        case com.ibm.icu.text.DecimalFormat.PAD_AFTER_PREFIX:
-          return PadPosition.AFTER_PREFIX;
-        case com.ibm.icu.text.DecimalFormat.PAD_BEFORE_SUFFIX:
-          return PadPosition.BEFORE_SUFFIX;
-        case com.ibm.icu.text.DecimalFormat.PAD_AFTER_SUFFIX:
-          return PadPosition.AFTER_SUFFIX;
-        default:
-          throw new IllegalArgumentException("Don't know how to map " + old);
-      }
-    }
-
-    public int toOld() {
-      switch (this) {
-        case BEFORE_PREFIX:
-          return com.ibm.icu.text.DecimalFormat.PAD_BEFORE_PREFIX;
-        case AFTER_PREFIX:
-          return com.ibm.icu.text.DecimalFormat.PAD_AFTER_PREFIX;
-        case BEFORE_SUFFIX:
-          return com.ibm.icu.text.DecimalFormat.PAD_BEFORE_SUFFIX;
-        case AFTER_SUFFIX:
-          return com.ibm.icu.text.DecimalFormat.PAD_AFTER_SUFFIX;
-        default:
-          return -1; // silence compiler errors
-      }
-    }
-  }
-
-  public static interface IProperties {
-
-    static int DEFAULT_FORMAT_WIDTH = 0;
-
-    /** @see #setFormatWidth */
-    public int getFormatWidth();
-
-    /**
-     * Sets the minimum width of the string output by the formatting pipeline. For example, if
-     * padding is enabled and paddingWidth is set to 6, formatting the number "3.14159" with the
-     * pattern "0.00" will result in "··3.14" if '·' is your padding string.
-     *
-     * <p>If the number is longer than your padding width, the number will display as if no padding
-     * width had been specified, which may result in strings longer than the padding width.
-     *
-     * <p>Width is counted in UTF-16 code units.
-     *
-     * @param formatWidth The output width.
-     * @return The property bag, for chaining.
-     * @see #setPadPosition
-     * @see #setPadString
-     */
-    public IProperties setFormatWidth(int formatWidth);
-
-    static String DEFAULT_PAD_STRING = null;
-
-    /** @see #setPadString */
-    public String getPadString();
-
-    /**
-     * Sets the string used for padding. The string should contain a single character or grapheme
-     * cluster.
-     *
-     * <p>Must be used in conjunction with {@link #setFormatWidth}.
-     *
-     * @param paddingString The padding string. Defaults to an ASCII space (U+0020).
-     * @return The property bag, for chaining.
-     * @see #setFormatWidth
-     */
-    public IProperties setPadString(String paddingString);
-
-    static PadPosition DEFAULT_PAD_POSITION = null;
-
-    /** @see #setPadPosition */
-    public PadPosition getPadPosition();
-
-    /**
-     * Sets the location where the padding string is to be inserted to maintain the padding width:
-     * one of BEFORE_PREFIX, AFTER_PREFIX, BEFORE_SUFFIX, or AFTER_SUFFIX.
-     *
-     * <p>Must be used in conjunction with {@link #setFormatWidth}.
-     *
-     * @param padPosition The output width.
-     * @return The property bag, for chaining.
-     * @see #setFormatWidth
-     */
-    public IProperties setPadPosition(PadPosition padPosition);
-  }
-
-  public static final String FALLBACK_PADDING_STRING = "\u0020"; // i.e. a space
-
-  public static boolean usePadding(IProperties properties) {
-    return properties.getFormatWidth() != IProperties.DEFAULT_FORMAT_WIDTH;
-  }
-
-  public static AfterFormat getInstance(IProperties properties) {
-    return new PaddingFormat(
-        properties.getFormatWidth(), properties.getPadString(), properties.getPadPosition());
-  }
-
-  // Properties
-  private final int paddingWidth;
-  private final String paddingString;
-  private final PadPosition paddingLocation;
-
-  private PaddingFormat(int paddingWidth, String paddingString, PadPosition paddingLocation) {
-    this.paddingWidth = paddingWidth > 0 ? paddingWidth : 10; // TODO: Is this a sensible default?
-    this.paddingString = paddingString != null ? paddingString : FALLBACK_PADDING_STRING;
-    this.paddingLocation = paddingLocation != null ? paddingLocation : PadPosition.BEFORE_PREFIX;
-  }
-
-  @Override
-  public int after(ModifierHolder mods, NumberStringBuilder string, int leftIndex, int rightIndex) {
-
-    // TODO: Count code points instead of code units?
-    // TODO: Make this more efficient (less copying)
-    NumberStringBuilder copy1 = new NumberStringBuilder(string);
-    ModifierHolder copy2 = mods.createCopy();
-    copy2.applyAll(copy1, leftIndex, rightIndex);
-    int requiredPadding = paddingWidth - copy1.length();
-
-    if (requiredPadding <= 0) {
-      // Skip padding, but still apply modifiers to be consistent
-      return mods.applyAll(string, leftIndex, rightIndex);
-    }
-
-    int length = 0;
-    if (paddingLocation == PadPosition.AFTER_PREFIX) {
-      length += addPadding(requiredPadding, string, leftIndex);
-    } else if (paddingLocation == PadPosition.BEFORE_SUFFIX) {
-      length += addPadding(requiredPadding, string, rightIndex);
-    }
-    length += mods.applyAll(string, leftIndex, rightIndex + length);
-    if (paddingLocation == PadPosition.BEFORE_PREFIX) {
-      length += addPadding(requiredPadding, string, leftIndex);
-    } else if (paddingLocation == PadPosition.AFTER_SUFFIX) {
-      length += addPadding(requiredPadding, string, rightIndex + length);
-    }
-
-    return length;
-  }
-
-  private int addPadding(int requiredPadding, NumberStringBuilder string, int index) {
-    for (int i = 0; i < requiredPadding; i++) {
-      string.insert(index, paddingString, null);
-    }
-    return paddingString.length() * requiredPadding;
-  }
-
-  @Override
-  public void export(Properties properties) {
-    properties.setFormatWidth(paddingWidth);
-    properties.setPadString(paddingString);
-    properties.setPadPosition(paddingLocation);
-  }
-}
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/formatters/PositiveDecimalFormat.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/formatters/PositiveDecimalFormat.java
deleted file mode 100644 (file)
index fdb2606..0000000
+++ /dev/null
@@ -1,222 +0,0 @@
-// © 2017 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html#License
-package com.ibm.icu.impl.number.formatters;
-
-import com.ibm.icu.impl.number.Format;
-import com.ibm.icu.impl.number.FormatQuantity;
-import com.ibm.icu.impl.number.NumberStringBuilder;
-import com.ibm.icu.impl.number.Properties;
-import com.ibm.icu.text.DecimalFormatSymbols;
-import com.ibm.icu.text.NumberFormat;
-import com.ibm.icu.text.NumberFormat.Field;
-
-public class PositiveDecimalFormat implements Format.TargetFormat {
-
-  public static interface IProperties extends CurrencyFormat.IProperties {
-
-    static int DEFAULT_GROUPING_SIZE = -1;
-
-    /** @see #setGroupingSize */
-    public int getGroupingSize();
-
-    /**
-     * Sets the number of digits between grouping separators. For example, the <em>en-US</em> locale
-     * uses a grouping size of 3, so the number 1234567 would be formatted as "1,234,567". For
-     * locales whose grouping sizes vary with magnitude, see {@link #setSecondaryGroupingSize(int)}.
-     *
-     * @param groupingSize The primary grouping size.
-     * @return The property bag, for chaining.
-     */
-    public IProperties setGroupingSize(int groupingSize);
-
-    static int DEFAULT_SECONDARY_GROUPING_SIZE = -1;
-
-    /** @see #setSecondaryGroupingSize */
-    public int getSecondaryGroupingSize();
-
-    /**
-     * Sets the number of digits between grouping separators higher than the least-significant
-     * grouping separator. For example, the locale <em>hi</em> uses a primary grouping size of 3 and
-     * a secondary grouping size of 2, so the number 1234567 would be formatted as "12,34,567".
-     *
-     * <p>The two levels of grouping separators can be specified in the pattern string. For example,
-     * the <em>hi</em> locale's default decimal format pattern is "#,##,##0.###".
-     *
-     * @param secondaryGroupingSize The secondary grouping size.
-     * @return The property bag, for chaining.
-     */
-    public IProperties setSecondaryGroupingSize(int secondaryGroupingSize);
-
-    static boolean DEFAULT_DECIMAL_SEPARATOR_ALWAYS_SHOWN = false;
-
-    /** @see #setDecimalSeparatorAlwaysShown */
-    public boolean getDecimalSeparatorAlwaysShown();
-
-    /**
-     * Sets whether to always show the decimal point, even if the number doesn't require one. For
-     * example, if always show decimal is true, the number 123 would be formatted as "123." in
-     * locale <em>en-US</em>.
-     *
-     * @param decimalSeparatorAlwaysShown Whether to show the decimal point when it is optional.
-     * @return The property bag, for chaining.
-     */
-    public IProperties setDecimalSeparatorAlwaysShown(boolean decimalSeparatorAlwaysShown);
-
-    static int DEFAULT_MINIMUM_GROUPING_DIGITS = 1;
-
-    /** @see #setMinimumGroupingDigits */
-    public int getMinimumGroupingDigits();
-
-    /**
-     * Sets the minimum number of digits required to be beyond the first grouping separator in order
-     * to enable grouping. For example, if the minimum grouping digits is 2, then 1234 would be
-     * formatted as "1234" but 12345 would be formatted as "12,345" in <em>en-US</em>. Note that
-     * 1234567 would still be formatted as "1,234,567", not "1234,567".
-     *
-     * @param minimumGroupingDigits How many digits must appear before a grouping separator before
-     *     enabling grouping.
-     * @return The property bag, for chaining.
-     */
-    public IProperties setMinimumGroupingDigits(int minimumGroupingDigits);
-  }
-
-  public static boolean useGrouping(IProperties properties) {
-    return properties.getGroupingSize() != IProperties.DEFAULT_GROUPING_SIZE
-        || properties.getSecondaryGroupingSize() != IProperties.DEFAULT_SECONDARY_GROUPING_SIZE;
-  }
-
-  public static boolean allowsDecimalPoint(IProperties properties) {
-    return properties.getDecimalSeparatorAlwaysShown()
-        || properties.getMaximumFractionDigits() != 0;
-  }
-
-  // Properties
-  private final boolean alwaysShowDecimal;
-  private final int primaryGroupingSize;
-  private final int secondaryGroupingSize;
-  private final int minimumGroupingDigits;
-
-  // Symbols
-  private final String infinityString;
-  private final String nanString;
-  private final String groupingSeparator;
-  private final String decimalSeparator;
-  private final String[] digitStrings;
-  private final int codePointZero;
-
-  public PositiveDecimalFormat(DecimalFormatSymbols symbols, IProperties properties) {
-    int _primary = properties.getGroupingSize();
-    int _secondary = properties.getSecondaryGroupingSize();
-    primaryGroupingSize = _primary > 0 ? _primary : _secondary > 0 ? _secondary : 0;
-    secondaryGroupingSize = _secondary > 0 ? _secondary : primaryGroupingSize;
-
-    minimumGroupingDigits = properties.getMinimumGroupingDigits();
-    alwaysShowDecimal = properties.getDecimalSeparatorAlwaysShown();
-    infinityString = symbols.getInfinity();
-    nanString = symbols.getNaN();
-
-    if (CurrencyFormat.useCurrency(properties)) {
-      groupingSeparator = symbols.getMonetaryGroupingSeparatorString();
-      decimalSeparator = symbols.getMonetaryDecimalSeparatorString();
-    } else {
-      groupingSeparator = symbols.getGroupingSeparatorString();
-      decimalSeparator = symbols.getDecimalSeparatorString();
-    }
-
-    // Check to see if we can use code points instead of strings
-    int _codePointZero = symbols.getCodePointZero();
-    if (_codePointZero != -1) {
-      // Fast Path (~9% faster than slow path when formatting long strings)
-      digitStrings = null;
-      codePointZero = _codePointZero;
-    } else {
-      // Slow Path
-      digitStrings = symbols.getDigitStrings(); // makes a copy
-      codePointZero = -1;
-    }
-  }
-
-  @Override
-  public int target(FormatQuantity input, NumberStringBuilder string, int startIndex) {
-    int length = 0;
-
-    if (input.isInfinite()) {
-      length += string.insert(startIndex, infinityString, NumberFormat.Field.INTEGER);
-
-    } else if (input.isNaN()) {
-      length += string.insert(startIndex, nanString, NumberFormat.Field.INTEGER);
-
-    } else {
-      // Add the integer digits
-      length += addIntegerDigits(input, string, startIndex);
-
-      // Add the decimal point
-      if (input.getLowerDisplayMagnitude() < 0 || alwaysShowDecimal) {
-        length +=
-            string.insert(
-                startIndex + length, decimalSeparator, NumberFormat.Field.DECIMAL_SEPARATOR);
-      }
-
-      // Add the fraction digits
-      length += addFractionDigits(input, string, startIndex + length);
-    }
-
-    return length;
-  }
-
-  private int addIntegerDigits(FormatQuantity input, NumberStringBuilder string, int startIndex) {
-    int length = 0;
-    int integerCount = input.getUpperDisplayMagnitude() + 1;
-    for (int i = 0; i < integerCount; i++) {
-      // Add grouping separator
-      if (primaryGroupingSize > 0
-          && i == primaryGroupingSize
-          && integerCount - i >= minimumGroupingDigits) {
-        length +=
-            string.insert(startIndex, groupingSeparator, NumberFormat.Field.GROUPING_SEPARATOR);
-      } else if (secondaryGroupingSize > 0
-          && i > primaryGroupingSize
-          && (i - primaryGroupingSize) % secondaryGroupingSize == 0) {
-        length +=
-            string.insert(startIndex, groupingSeparator, NumberFormat.Field.GROUPING_SEPARATOR);
-      }
-
-      // Get and append the next digit value
-      byte nextDigit = input.getDigit(i);
-      length += addDigit(nextDigit, string, startIndex, NumberFormat.Field.INTEGER);
-    }
-
-    return length;
-  }
-
-  private int addFractionDigits(FormatQuantity input, NumberStringBuilder string, int index) {
-    int length = 0;
-    int fractionCount = -input.getLowerDisplayMagnitude();
-    for (int i = 0; i < fractionCount; i++) {
-      // Get and append the next digit value
-      byte nextDigit = input.getDigit(-i - 1);
-      length += addDigit(nextDigit, string, index + length, NumberFormat.Field.FRACTION);
-    }
-    return length;
-  }
-
-  private int addDigit(byte digit, NumberStringBuilder outputString, int index, Field field) {
-    if (codePointZero != -1) {
-      return outputString.insertCodePoint(index, codePointZero + digit, field);
-    } else {
-      return outputString.insert(index, digitStrings[digit], field);
-    }
-  }
-
-  @Override
-  public void export(Properties properties) {
-    // For backwards compatibility, export 0 as secondary grouping if primary and secondary are the same
-    int effectiveSecondaryGroupingSize =
-        secondaryGroupingSize == primaryGroupingSize ? 0 : secondaryGroupingSize;
-
-    properties.setDecimalSeparatorAlwaysShown(alwaysShowDecimal);
-    properties.setGroupingSize(primaryGroupingSize);
-    properties.setSecondaryGroupingSize(effectiveSecondaryGroupingSize);
-    properties.setMinimumGroupingDigits(minimumGroupingDigits);
-  }
-}
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/formatters/PositiveNegativeAffixFormat.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/formatters/PositiveNegativeAffixFormat.java
deleted file mode 100644 (file)
index 6036eb0..0000000
+++ /dev/null
@@ -1,256 +0,0 @@
-// © 2017 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html#License
-package com.ibm.icu.impl.number.formatters;
-
-import com.ibm.icu.impl.number.FormatQuantity;
-import com.ibm.icu.impl.number.ModifierHolder;
-import com.ibm.icu.impl.number.PNAffixGenerator;
-import com.ibm.icu.impl.number.modifiers.PositiveNegativeAffixModifier;
-import com.ibm.icu.text.DecimalFormatSymbols;
-
-/**
- * The implementation of this class is a thin wrapper around {@link PNAffixGenerator}, a utility
- * used by this and other classes, including {@link CompactDecimalFormat} and {@link Parse}, to
- * efficiently convert from the abstract properties in the property bag to actual prefix and suffix
- * strings.
- */
-
-/**
- * This class is responsible for adding the positive/negative prefixes and suffixes from the decimal
- * format pattern. Properties are set using the following methods:
- *
- * <ul>
- *   <li>{@link IProperties#setPositivePrefix(String)}
- *   <li>{@link IProperties#setPositiveSuffix(String)}
- *   <li>{@link IProperties#setNegativePrefix(String)}
- *   <li>{@link IProperties#setNegativeSuffix(String)}
- *   <li>{@link IProperties#setPositivePrefixPattern(String)}
- *   <li>{@link IProperties#setPositiveSuffixPattern(String)}
- *   <li>{@link IProperties#setNegativePrefixPattern(String)}
- *   <li>{@link IProperties#setNegativeSuffixPattern(String)}
- * </ul>
- *
- * If one of the first four methods is used (those of the form <code>setXxxYyy</code>), the value
- * will be interpreted literally. If one of the second four methods is used (those of the form
- * <code>setXxxYyyPattern</code>), locale-specific symbols for the plus sign, minus sign, percent
- * sign, permille sign, and currency sign will be substituted into the string, according to Unicode
- * Technical Standard #35 (LDML) section 3.2.
- *
- * <p>Literal characters can be used in the <code>setXxxYyyPattern</code> methods by using quotes;
- * for example, to display a literal "%" sign, you can set the pattern <code>'%'</code>. To display
- * a literal quote, use two quotes in a row, like <code>''</code>.
- *
- * <p>If a value is set in both a <code>setXxxYyy</code> method and in the corresponding <code>
- * setXxxYyyPattern</code> method, the one set in <code>setXxxYyy</code> takes precedence.
- *
- * <p>For more information on formatting currencies, see {@link CurrencyFormat}.
- *
- * <p>The parameter is taken by reference by these methods into the property bag, meaning that if a
- * mutable object like StringBuilder is passed, changes to the StringBuilder will be reflected in
- * the property bag. However, upon creation of a finalized formatter object, all prefixes and
- * suffixes will be converted to strings and will stop reflecting changes in the property bag.
- */
-public class PositiveNegativeAffixFormat {
-
-  public static interface IProperties {
-
-    static String DEFAULT_POSITIVE_PREFIX = null;
-
-    /** @see #setPositivePrefix */
-    public String getPositivePrefix();
-
-    /**
-     * Sets the prefix to prepend to positive numbers. The prefix will be interpreted literally. For
-     * example, if you set a positive prefix of <code>p</code>, then the number 123 will be
-     * formatted as "p123" in the locale <em>en-US</em>.
-     *
-     * <p>For more information on prefixes and suffixes, see {@link PositiveNegativeAffixFormat}.
-     *
-     * @param positivePrefix The CharSequence to prepend to positive numbers.
-     * @return The property bag, for chaining.
-     * @see PositiveNegativeAffixFormat
-     * @see #setPositivePrefixPattern
-     */
-    public IProperties setPositivePrefix(String positivePrefix);
-
-    static String DEFAULT_POSITIVE_SUFFIX = null;
-
-    /** @see #setPositiveSuffix */
-    public String getPositiveSuffix();
-
-    /**
-     * Sets the suffix to append to positive numbers. The suffix will be interpreted literally. For
-     * example, if you set a positive suffix of <code>p</code>, then the number 123 will be
-     * formatted as "123p" in the locale <em>en-US</em>.
-     *
-     * <p>For more information on prefixes and suffixes, see {@link PositiveNegativeAffixFormat}.
-     *
-     * @param positiveSuffix The CharSequence to append to positive numbers.
-     * @return The property bag, for chaining.
-     * @see PositiveNegativeAffixFormat
-     * @see #setPositiveSuffixPattern
-     */
-    public IProperties setPositiveSuffix(String positiveSuffix);
-
-    static String DEFAULT_NEGATIVE_PREFIX = null;
-
-    /** @see #setNegativePrefix */
-    public String getNegativePrefix();
-
-    /**
-     * Sets the prefix to prepend to negative numbers. The prefix will be interpreted literally. For
-     * example, if you set a negative prefix of <code>n</code>, then the number -123 will be
-     * formatted as "n123" in the locale <em>en-US</em>. Note that if the negative prefix is left unset,
-     * the locale's minus sign is used.
-     *
-     * <p>For more information on prefixes and suffixes, see {@link PositiveNegativeAffixFormat}.
-     *
-     * @param negativePrefix The CharSequence to prepend to negative numbers.
-     * @return The property bag, for chaining.
-     * @see PositiveNegativeAffixFormat
-     * @see #setNegativePrefixPattern
-     */
-    public IProperties setNegativePrefix(String negativePrefix);
-
-    static String DEFAULT_NEGATIVE_SUFFIX = null;
-
-    /** @see #setNegativeSuffix */
-    public String getNegativeSuffix();
-
-    /**
-     * Sets the suffix to append to negative numbers. The suffix will be interpreted literally. For
-     * example, if you set a suffix prefix of <code>n</code>, then the number -123 will be formatted
-     * as "-123n" in the locale <em>en-US</em>. Note that the minus sign is prepended by default unless
-     * otherwise specified in either the pattern string or in one of the {@link #setNegativePrefix}
-     * methods.
-     *
-     * <p>For more information on prefixes and suffixes, see {@link PositiveNegativeAffixFormat}.
-     *
-     * @param negativeSuffix The CharSequence to append to negative numbers.
-     * @return The property bag, for chaining.
-     * @see PositiveNegativeAffixFormat
-     * @see #setNegativeSuffixPattern
-     */
-    public IProperties setNegativeSuffix(String negativeSuffix);
-
-    static String DEFAULT_POSITIVE_PREFIX_PATTERN = null;
-
-    /** @see #setPositivePrefixPattern */
-    public String getPositivePrefixPattern();
-
-    /**
-     * Sets the prefix to prepend to positive numbers. Locale-specific symbols will be substituted
-     * into the string according to Unicode Technical Standard #35 (LDML).
-     *
-     * <p>For more information on prefixes and suffixes, see {@link PositiveNegativeAffixFormat}.
-     *
-     * @param positivePrefixPattern The CharSequence to prepend to positive numbers after locale
-     *     symbol substitutions take place.
-     * @return The property bag, for chaining.
-     * @see PositiveNegativeAffixFormat
-     * @see #setPositivePrefix
-     */
-    public IProperties setPositivePrefixPattern(String positivePrefixPattern);
-
-    static String DEFAULT_POSITIVE_SUFFIX_PATTERN = null;
-
-    /** @see #setPositiveSuffixPattern */
-    public String getPositiveSuffixPattern();
-
-    /**
-     * Sets the suffix to append to positive numbers. Locale-specific symbols will be substituted
-     * into the string according to Unicode Technical Standard #35 (LDML).
-     *
-     * <p>For more information on prefixes and suffixes, see {@link PositiveNegativeAffixFormat}.
-     *
-     * @param positiveSuffixPattern The CharSequence to append to positive numbers after locale
-     *     symbol substitutions take place.
-     * @return The property bag, for chaining.
-     * @see PositiveNegativeAffixFormat
-     * @see #setPositiveSuffix
-     */
-    public IProperties setPositiveSuffixPattern(String positiveSuffixPattern);
-
-    static String DEFAULT_NEGATIVE_PREFIX_PATTERN = null;
-
-    /** @see #setNegativePrefixPattern */
-    public String getNegativePrefixPattern();
-
-    /**
-     * Sets the prefix to prepend to negative numbers. Locale-specific symbols will be substituted
-     * into the string according to Unicode Technical Standard #35 (LDML).
-     *
-     * <p>For more information on prefixes and suffixes, see {@link PositiveNegativeAffixFormat}.
-     *
-     * @param negativePrefixPattern The CharSequence to prepend to negative numbers after locale
-     *     symbol substitutions take place.
-     * @return The property bag, for chaining.
-     * @see PositiveNegativeAffixFormat
-     * @see #setNegativePrefix
-     */
-    public IProperties setNegativePrefixPattern(String negativePrefixPattern);
-
-    static String DEFAULT_NEGATIVE_SUFFIX_PATTERN = null;
-
-    /** @see #setNegativeSuffixPattern */
-    public String getNegativeSuffixPattern();
-
-    /**
-     * Sets the suffix to append to negative numbers. Locale-specific symbols will be substituted
-     * into the string according to Unicode Technical Standard #35 (LDML).
-     *
-     * <p>For more information on prefixes and suffixes, see {@link PositiveNegativeAffixFormat}.
-     *
-     * @param negativeSuffixPattern The CharSequence to append to negative numbers after locale
-     *     symbol substitutions take place.
-     * @return The property bag, for chaining.
-     * @see PositiveNegativeAffixFormat
-     * @see #setNegativeSuffix
-     */
-    public IProperties setNegativeSuffixPattern(String negativeSuffixPattern);
-
-    static boolean DEFAULT_SIGN_ALWAYS_SHOWN = false;
-
-    /** @see #setSignAlwaysShown */
-    public boolean getSignAlwaysShown();
-
-    /**
-     * Sets whether to always display of a plus sign on positive numbers.
-     *
-     * <p>If the location of the negative sign is specified by the decimal format pattern (or by the
-     * negative prefix/suffix pattern methods), a plus sign is substituted into that location, in
-     * accordance with Unicode Technical Standard #35 (LDML) section 3.2.1. Otherwise, the plus sign
-     * is prepended to the number. For example, if the decimal format pattern <code>#;#-</code> is
-     * used, then formatting 123 would result in "123+" in the locale <em>en-US</em>.
-     *
-     * <p>This method should be used <em>instead of</em> setting the positive prefix/suffix. The
-     * behavior is undefined if alwaysShowPlusSign is set but the positive prefix/suffix already
-     * contains a plus sign.
-     *
-     * @param plusSignAlwaysShown Whether positive numbers should display a plus sign.
-     * @return The property bag, for chaining.
-     */
-    public IProperties setSignAlwaysShown(boolean plusSignAlwaysShown);
-  }
-
-  public static PositiveNegativeAffixModifier getInstance(DecimalFormatSymbols symbols, IProperties properties) {
-    PNAffixGenerator pnag = PNAffixGenerator.getThreadLocalInstance();
-    PNAffixGenerator.Result result = pnag.getModifiers(symbols, properties);
-    return new PositiveNegativeAffixModifier(result.positive, result.negative);
-  }
-
-  // TODO: Investigate static interface methods (Java 8 only?)
-  public static void apply(
-      FormatQuantity input,
-      ModifierHolder mods,
-      DecimalFormatSymbols symbols,
-      IProperties properties) {
-    PNAffixGenerator pnag = PNAffixGenerator.getThreadLocalInstance();
-    PNAffixGenerator.Result result = pnag.getModifiers(symbols, properties);
-    if (input.isNegative()) {
-      mods.add(result.negative);
-    } else {
-      mods.add(result.positive);
-    }
-  }
-}
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/formatters/RangeFormat.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/formatters/RangeFormat.java
deleted file mode 100644 (file)
index 7c72e62..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-// © 2017 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html#License
-// THIS CLASS IS A PROOF OF CONCEPT ONLY.
-// IT REQUIRES ADDITIONAL DISCUSION ABOUT ITS DESIGN AND IMPLEMENTATION.
-
-package com.ibm.icu.impl.number.formatters;
-
-import java.util.Deque;
-
-import com.ibm.icu.impl.number.Format;
-import com.ibm.icu.impl.number.FormatQuantity;
-import com.ibm.icu.impl.number.ModifierHolder;
-import com.ibm.icu.impl.number.NumberStringBuilder;
-
-public class RangeFormat extends Format {
-  // Primary settings
-  private final String separator;
-
-  // Child formatters
-  private final Format left;
-  private final Format right;
-
-  public RangeFormat(Format left, Format right, String separator) {
-    this.separator = separator; // TODO: This would be loaded from locale data.
-    this.left = left;
-    this.right = right;
-
-    if (left == null || right == null) {
-      throw new IllegalArgumentException("Both child formatters are required for RangeFormat");
-    }
-  }
-
-  @Override
-  public int process(
-      Deque<FormatQuantity> inputs,
-      ModifierHolder mods,
-      NumberStringBuilder string,
-      int startIndex) {
-    ModifierHolder lMods = new ModifierHolder();
-    ModifierHolder rMods = new ModifierHolder();
-    int lLen = left.process(inputs, lMods, string, startIndex);
-    int rLen = right.process(inputs, rMods, string, startIndex + lLen);
-
-    // Bubble up any modifiers that are shared between the two sides
-    while (lMods.peekLast() != null && lMods.peekLast() == rMods.peekLast()) {
-      mods.add(lMods.removeLast());
-      rMods.removeLast();
-    }
-
-    // Apply the remaining modifiers
-    lLen += lMods.applyAll(string, startIndex, startIndex + lLen);
-    rLen += rMods.applyAll(string, startIndex + lLen, startIndex + lLen + rLen);
-
-    int sLen = string.insert(startIndex + lLen, separator, null);
-
-    return lLen + sLen + rLen;
-  }
-}
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/formatters/RoundingFormat.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/formatters/RoundingFormat.java
deleted file mode 100644 (file)
index a57caf4..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-// © 2017 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html#License
-package com.ibm.icu.impl.number.formatters;
-
-import com.ibm.icu.impl.number.Rounder;
-import com.ibm.icu.impl.number.Rounder.IBasicRoundingProperties;
-import com.ibm.icu.impl.number.rounders.IncrementRounder;
-import com.ibm.icu.impl.number.rounders.MagnitudeRounder;
-import com.ibm.icu.impl.number.rounders.NoRounder;
-import com.ibm.icu.impl.number.rounders.SignificantDigitsRounder;
-
-// TODO: Figure out a better place to put these methods.
-
-public class RoundingFormat {
-
-  public static interface IProperties
-      extends IBasicRoundingProperties,
-          IncrementRounder.IProperties,
-          MagnitudeRounder.IProperties,
-          SignificantDigitsRounder.IProperties {}
-
-  public static Rounder getDefaultOrNoRounder(IProperties properties) {
-    Rounder candidate = getDefaultOrNull(properties);
-    if (candidate == null) {
-      candidate = NoRounder.getInstance(properties);
-    }
-    return candidate;
-  }
-
-  public static Rounder getDefaultOrNull(IProperties properties) {
-    if (SignificantDigitsRounder.useSignificantDigits(properties)) {
-      return SignificantDigitsRounder.getInstance(properties);
-    } else if (IncrementRounder.useRoundingIncrement(properties)) {
-      return IncrementRounder.getInstance(properties);
-    } else if (MagnitudeRounder.useFractionFormat(properties)) {
-      return MagnitudeRounder.getInstance(properties);
-    } else {
-      return null;
-    }
-  }
-}
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/formatters/ScientificFormat.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/formatters/ScientificFormat.java
deleted file mode 100644 (file)
index 9ef9fdb..0000000
+++ /dev/null
@@ -1,240 +0,0 @@
-// © 2017 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html#License
-package com.ibm.icu.impl.number.formatters;
-
-import com.ibm.icu.impl.number.Format;
-import com.ibm.icu.impl.number.FormatQuantity;
-import com.ibm.icu.impl.number.FormatQuantitySelector;
-import com.ibm.icu.impl.number.ModifierHolder;
-import com.ibm.icu.impl.number.Properties;
-import com.ibm.icu.impl.number.Rounder;
-import com.ibm.icu.impl.number.modifiers.ConstantAffixModifier;
-import com.ibm.icu.impl.number.modifiers.PositiveNegativeAffixModifier;
-import com.ibm.icu.impl.number.rounders.IncrementRounder;
-import com.ibm.icu.impl.number.rounders.SignificantDigitsRounder;
-import com.ibm.icu.text.DecimalFormatSymbols;
-import com.ibm.icu.text.NumberFormat;
-
-public class ScientificFormat extends Format.BeforeFormat implements Rounder.MultiplierGenerator {
-
-  public static interface IProperties
-      extends RoundingFormat.IProperties, CurrencyFormat.IProperties {
-
-    static boolean DEFAULT_EXPONENT_SIGN_ALWAYS_SHOWN = false;
-
-    /** @see #setExponentSignAlwaysShown */
-    public boolean getExponentSignAlwaysShown();
-
-    /**
-     * Sets whether to show the plus sign in the exponent part of numbers with a zero or positive
-     * exponent. For example, the number "1200" with the pattern "0.0E0" would be formatted as
-     * "1.2E+3" instead of "1.2E3" in <em>en-US</em>.
-     *
-     * @param exponentSignAlwaysShown Whether to show the plus sign in positive exponents.
-     * @return The property bag, for chaining.
-     */
-    public IProperties setExponentSignAlwaysShown(boolean exponentSignAlwaysShown);
-
-    static int DEFAULT_MINIMUM_EXPONENT_DIGITS = -1;
-
-    /** @see #setMinimumExponentDigits */
-    public int getMinimumExponentDigits();
-
-    /**
-     * Sets the minimum number of digits to display in the exponent. For example, the number "1200"
-     * with the pattern "0.0E00", which has 2 exponent digits, would be formatted as "1.2E03" in
-     * <em>en-US</em>.
-     *
-     * @param minimumExponentDigits The minimum number of digits to display in the exponent field.
-     * @return The property bag, for chaining.
-     */
-    public IProperties setMinimumExponentDigits(int minimumExponentDigits);
-  }
-
-  public static boolean useScientificNotation(IProperties properties) {
-    return properties.getMinimumExponentDigits() != IProperties.DEFAULT_MINIMUM_EXPONENT_DIGITS;
-  }
-
-  private static final ThreadLocal<Properties> threadLocalProperties =
-      new ThreadLocal<Properties>() {
-        @Override
-        protected Properties initialValue() {
-          return new Properties();
-        }
-      };
-
-  public static ScientificFormat getInstance(DecimalFormatSymbols symbols, IProperties properties) {
-    // If significant digits or rounding interval are specified through normal means, we use those.
-    // Otherwise, we use the special significant digit rules for scientific notation.
-    Rounder rounder;
-    if (IncrementRounder.useRoundingIncrement(properties)) {
-      rounder = IncrementRounder.getInstance(properties);
-    } else if (SignificantDigitsRounder.useSignificantDigits(properties)) {
-      rounder = SignificantDigitsRounder.getInstance(properties);
-    } else {
-      Properties rprops = threadLocalProperties.get().clear();
-
-      int minInt = properties.getMinimumIntegerDigits();
-      int maxInt = properties.getMaximumIntegerDigits();
-      int minFrac = properties.getMinimumFractionDigits();
-      int maxFrac = properties.getMaximumFractionDigits();
-
-      // If currency is in use, pull information from CurrencyUsage.
-      if (CurrencyFormat.useCurrency(properties)) {
-        // Use rprops as the vehicle (it is still clean)
-        CurrencyFormat.populateCurrencyRounderProperties(rprops, symbols, properties);
-        minFrac = rprops.getMinimumFractionDigits();
-        maxFrac = rprops.getMaximumFractionDigits();
-        rprops.clear();
-      }
-
-      // TODO: Mark/Andy, take a look at this logic and see if it makes sense to you.
-      // I fiddled with the settings and fallbacks to make the unit tests pass, but I
-      // don't feel that it's the "right way" to do things.
-
-      if (minInt < 0) minInt = 0;
-      if (maxInt < minInt) maxInt = minInt;
-      if (minFrac < 0) minFrac = 0;
-      if (maxFrac < minFrac) maxFrac = minFrac;
-
-      rprops.setRoundingMode(properties.getRoundingMode());
-
-      if (minInt == 0 && maxFrac == 0) {
-        // Special case for the pattern "#E0" with no significant digits specified.
-        rprops.setMinimumSignificantDigits(1);
-        rprops.setMaximumSignificantDigits(Integer.MAX_VALUE);
-      } else if (minInt == 0 && minFrac == 0) {
-        // Special case for patterns like "#.##E0" with no significant digits specified.
-        rprops.setMinimumSignificantDigits(1);
-        rprops.setMaximumSignificantDigits(1 + maxFrac);
-      } else {
-        rprops.setMinimumSignificantDigits(minInt + minFrac);
-        rprops.setMaximumSignificantDigits(minInt + maxFrac);
-      }
-      rprops.setMinimumIntegerDigits(maxInt == 0 ? 0 : Math.max(1, minInt + minFrac - maxFrac));
-      rprops.setMaximumIntegerDigits(maxInt);
-      rprops.setMinimumFractionDigits(Math.max(0, minFrac + minInt - maxInt));
-      rprops.setMaximumFractionDigits(maxFrac);
-      rounder = SignificantDigitsRounder.getInstance(rprops);
-    }
-
-    return new ScientificFormat(symbols, properties, rounder);
-  }
-
-  public static ScientificFormat getInstance(
-      DecimalFormatSymbols symbols, IProperties properties, Rounder rounder) {
-    return new ScientificFormat(symbols, properties, rounder);
-  }
-
-  // Properties
-  private final boolean exponentShowPlusSign;
-  private final int exponentDigits;
-  private final int minInt;
-  private final int maxInt;
-  private final int interval;
-  private final Rounder rounder;
-  private final ConstantAffixModifier separatorMod;
-  private final PositiveNegativeAffixModifier signMod;
-
-  // Symbols
-  private final String[] digitStrings;
-
-  private ScientificFormat(DecimalFormatSymbols symbols, IProperties properties, Rounder rounder) {
-    exponentShowPlusSign = properties.getExponentSignAlwaysShown();
-    exponentDigits = Math.max(1, properties.getMinimumExponentDigits());
-
-    // Calculate minInt/maxInt for the purposes of engineering notation:
-    //   0 <= minInt <= maxInt < 8
-    // The values are validated separately for rounding. This scheme needs to prevent OOM issues
-    // (see #13118). Note that the bound 8 on integer digits is historic.
-    int _maxInt = properties.getMaximumIntegerDigits();
-    int _minInt = properties.getMinimumIntegerDigits();
-    // Bug #13289: if maxInt > minInt > 1, then minInt should be 1 for the
-    // purposes of engineering notatation.
-    if (_maxInt > _minInt && _minInt > 1) {
-        _minInt = 1;
-    }
-    minInt = _minInt < 0 ? 0 : _minInt >= 8 ? 1 : _minInt;
-    maxInt = _maxInt < _minInt ? _minInt : _maxInt >= 8 ? _minInt : _maxInt;
-    assert 0 <= minInt && minInt <= maxInt && maxInt < 8;
-
-    interval = maxInt < 1 ? 1 : maxInt;
-    this.rounder = rounder;
-    digitStrings = symbols.getDigitStrings(); // makes a copy
-
-    separatorMod =
-        new ConstantAffixModifier(
-            "", symbols.getExponentSeparator(), NumberFormat.Field.EXPONENT_SYMBOL, true);
-    signMod =
-        new PositiveNegativeAffixModifier(
-            new ConstantAffixModifier(
-                "",
-                exponentShowPlusSign ? symbols.getPlusSignString() : "",
-                NumberFormat.Field.EXPONENT_SIGN,
-                true),
-            new ConstantAffixModifier(
-                "", symbols.getMinusSignString(), NumberFormat.Field.EXPONENT_SIGN, true));
-  }
-
-  private static final ThreadLocal<StringBuilder> threadLocalStringBuilder =
-      new ThreadLocal<StringBuilder>() {
-        @Override
-        protected StringBuilder initialValue() {
-          return new StringBuilder();
-        }
-      };
-
-  @Override
-  public void before(FormatQuantity input, ModifierHolder mods) {
-
-    // Treat zero as if it had magnitude 0
-    int exponent;
-    if (input.isZero()) {
-      rounder.apply(input);
-      exponent = 0;
-    } else {
-      // TODO: Revisit chooseMultiplierAndApply
-      exponent = -rounder.chooseMultiplierAndApply(input, this);
-    }
-
-    // Format the exponent part of the scientific format.
-    // Insert digits starting from the left so that append can be used.
-    // TODO: Use thread locals here.
-    FormatQuantity exponentQ = FormatQuantitySelector.from(exponent);
-    StringBuilder exponentSB = threadLocalStringBuilder.get();
-    exponentSB.setLength(0);
-    exponentQ.setIntegerLength(exponentDigits, Integer.MAX_VALUE);
-    exponentQ.setFractionLength(0, 0);
-    for (int i = exponentQ.getUpperDisplayMagnitude(); i >= 0; i--) {
-      exponentSB.append(digitStrings[exponentQ.getDigit(i)]);
-    }
-
-    // Add modifiers from the outside in.
-    mods.add(
-        new ConstantAffixModifier("", exponentSB.toString(), NumberFormat.Field.EXPONENT, true));
-    mods.add(signMod.getModifier(exponent < 0));
-    mods.add(separatorMod);
-  }
-
-  @Override
-  public int getMultiplier(int magnitude) {
-    int digitsShown = ((magnitude % interval + interval) % interval) + 1;
-    if (digitsShown < minInt) {
-      digitsShown = minInt;
-    } else if (digitsShown > maxInt) {
-      digitsShown = maxInt;
-    }
-    int retval = digitsShown - magnitude - 1;
-    return retval;
-  }
-
-  @Override
-  public void export(Properties properties) {
-    properties.setMinimumExponentDigits(exponentDigits);
-    properties.setExponentSignAlwaysShown(exponentShowPlusSign);
-
-    // Set the transformed object into the property bag.  This may result in a pattern string that
-    // uses different syntax from the original, but it will be functionally equivalent.
-    rounder.export(properties);
-  }
-}
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/formatters/StrongAffixFormat.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/formatters/StrongAffixFormat.java
deleted file mode 100644 (file)
index c70352d..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-// © 2017 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html#License
-package com.ibm.icu.impl.number.formatters;
-
-import java.util.Deque;
-
-import com.ibm.icu.impl.number.Format;
-import com.ibm.icu.impl.number.FormatQuantity;
-import com.ibm.icu.impl.number.ModifierHolder;
-import com.ibm.icu.impl.number.NumberStringBuilder;
-import com.ibm.icu.impl.number.Properties;
-
-// TODO: This class isn't currently being used anywhere.  Consider removing it.
-
-/** Attaches all prefixes and suffixes at this point in the render tree without bubbling up. */
-public class StrongAffixFormat extends Format implements Format.AfterFormat {
-  private final Format child;
-
-  public StrongAffixFormat(Format child) {
-    this.child = child;
-
-    if (child == null) {
-      throw new IllegalArgumentException("A child formatter is required for StrongAffixFormat");
-    }
-  }
-
-  @Override
-  public int process(
-      Deque<FormatQuantity> inputs,
-      ModifierHolder mods,
-      NumberStringBuilder string,
-      int startIndex) {
-    int length = child.process(inputs, mods, string, startIndex);
-    length += mods.applyAll(string, startIndex, startIndex + length);
-    return length;
-  }
-
-  @Override
-  public int after(
-      ModifierHolder mods, NumberStringBuilder string, int leftIndex, int rightIndex) {
-    return mods.applyAll(string, leftIndex, rightIndex);
-  }
-
-  @Override
-  public void export(Properties properties) {
-    // Nothing to do.
-  }
-}
index ba46aa9d0cb8820500a422a1cfd9dbc7767162e9..1b2d88d3245991ada41c3a4b6f3e6f0c9866623b 100644 (file)
@@ -5,7 +5,6 @@ package com.ibm.icu.impl.number.modifiers;
 import com.ibm.icu.impl.number.Modifier;
 import com.ibm.icu.impl.number.Modifier.AffixModifier;
 import com.ibm.icu.impl.number.NumberStringBuilder;
-import com.ibm.icu.impl.number.Properties;
 import com.ibm.icu.text.NumberFormat.Field;
 
 /** The canonical implementation of {@link Modifier}, containing a prefix and suffix string. */
@@ -89,9 +88,4 @@ public class ConstantAffixModifier extends Modifier.BaseModifier implements Affi
   public String toString() {
     return String.format("<ConstantAffixModifier prefix:'%s' suffix:'%s'>", prefix, suffix);
   }
-
-  @Override
-  public void export(Properties properties) {
-    throw new UnsupportedOperationException();
-  }
 }
index 499f6d7ee0495ee311536d554e5a054a86e12a3f..c6c4d880501c1bf66016b89db5c054001165d873 100644 (file)
@@ -5,7 +5,6 @@ package com.ibm.icu.impl.number.modifiers;
 import com.ibm.icu.impl.number.Modifier;
 import com.ibm.icu.impl.number.Modifier.AffixModifier;
 import com.ibm.icu.impl.number.NumberStringBuilder;
-import com.ibm.icu.impl.number.Properties;
 import com.ibm.icu.text.NumberFormat.Field;
 
 /**
@@ -79,9 +78,4 @@ public class ConstantMultiFieldModifier extends Modifier.BaseModifier implements
   public String toString() {
     return String.format("<ConstantMultiFieldModifier prefix:'%s' suffix:'%s'>", prefix, suffix);
   }
-
-  @Override
-  public void export(Properties properties) {
-    throw new UnsupportedOperationException();
-  }
 }
index 3dfeefa4059af5b91c63ac731609a040c8289633..15ba186916a8bb2d15e3c2ef835575d91396681e 100644 (file)
@@ -3,22 +3,18 @@
 package com.ibm.icu.impl.number.modifiers;
 
 import com.ibm.icu.impl.StandardPlural;
-import com.ibm.icu.impl.number.Format;
-import com.ibm.icu.impl.number.FormatQuantity;
 import com.ibm.icu.impl.number.Modifier;
-import com.ibm.icu.impl.number.ModifierHolder;
-import com.ibm.icu.impl.number.Properties;
-import com.ibm.icu.text.PluralRules;
 
 // TODO: Is it okay that this class is not completely immutable? Right now it is internal-only.
 // Freezable or Builder could be used if necessary.
 
+// TODO: This class is currently unused.  Probably should be deleted.
+
 /**
  * A basic implementation of {@link com.ibm.icu.impl.number.Modifier.PositiveNegativePluralModifier}
  * that is built on the fly using its <code>put</code> methods.
  */
-public class GeneralPluralModifier extends Format.BeforeFormat
-    implements Modifier.PositiveNegativePluralModifier {
+public class GeneralPluralModifier implements Modifier.PositiveNegativePluralModifier {
   /**
    * A single array for modifiers. Even elements are positive; odd elements are negative. The
    * elements 2i and 2i+1 belong to the StandardPlural with ordinal i.
@@ -55,22 +51,4 @@ public class GeneralPluralModifier extends Format.BeforeFormat
     }
     return mod;
   }
-
-  @Override
-  public void before(FormatQuantity input, ModifierHolder mods, PluralRules rules) {
-    mods.add(getModifier(input.getStandardPlural(rules), input.isNegative()));
-  }
-
-  @Override
-  public void before(FormatQuantity input, ModifierHolder mods) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void export(Properties properties) {
-    // Since we can export only one affix pair, do the one for "other".
-    Modifier positive = getModifier(StandardPlural.OTHER, false);
-    Modifier negative = getModifier(StandardPlural.OTHER, true);
-    PositiveNegativeAffixModifier.exportPositiveNegative(properties, positive, negative);
-  }
 }
index 1384b7bbdf0c6dfab8084aae7e23b384680e4bbf..6ccd243f8c6fe4c3eac8e760d855edde33cef134 100644 (file)
@@ -2,16 +2,13 @@
 // License & terms of use: http://www.unicode.org/copyright.html#License
 package com.ibm.icu.impl.number.modifiers;
 
-import com.ibm.icu.impl.number.Format;
-import com.ibm.icu.impl.number.FormatQuantity;
 import com.ibm.icu.impl.number.Modifier;
 import com.ibm.icu.impl.number.Modifier.AffixModifier;
-import com.ibm.icu.impl.number.ModifierHolder;
-import com.ibm.icu.impl.number.Properties;
+
+// TODO: This class is currently unused.  Should probably be deleted.
 
 /** A class containing a positive form and a negative form of {@link ConstantAffixModifier}. */
-public class PositiveNegativeAffixModifier extends Format.BeforeFormat
-    implements Modifier.PositiveNegativeModifier {
+public class PositiveNegativeAffixModifier implements Modifier.PositiveNegativeModifier {
   private final AffixModifier positive;
   private final AffixModifier negative;
 
@@ -31,23 +28,4 @@ public class PositiveNegativeAffixModifier extends Format.BeforeFormat
   public Modifier getModifier(boolean isNegative) {
     return isNegative ? negative : positive;
   }
-
-  @Override
-  public void before(FormatQuantity input, ModifierHolder mods) {
-    Modifier mod = getModifier(input.isNegative());
-    mods.add(mod);
-  }
-
-  @Override
-  public void export(Properties properties) {
-    exportPositiveNegative(properties, positive, negative);
-  }
-
-  /** Internal method used to export a positive and negative modifier to a property bag. */
-  static void exportPositiveNegative(Properties properties, Modifier positive, Modifier negative) {
-    properties.setPositivePrefix(positive.getPrefix().isEmpty() ? null : positive.getPrefix());
-    properties.setPositiveSuffix(positive.getSuffix().isEmpty() ? null : positive.getSuffix());
-    properties.setNegativePrefix(negative.getPrefix().isEmpty() ? null : negative.getPrefix());
-    properties.setNegativeSuffix(negative.getSuffix().isEmpty() ? null : negative.getSuffix());
-  }
 }
index 98385a9dc5698bade1f3e833795cea2bdc94d93e..c1ceb221d646725e03681d38b81150605bfc2bea 100644 (file)
@@ -5,7 +5,6 @@ package com.ibm.icu.impl.number.modifiers;
 import com.ibm.icu.impl.SimpleFormatterImpl;
 import com.ibm.icu.impl.number.Modifier;
 import com.ibm.icu.impl.number.NumberStringBuilder;
-import com.ibm.icu.impl.number.Properties;
 import com.ibm.icu.text.NumberFormat.Field;
 
 /**
@@ -128,9 +127,4 @@ public class SimpleModifier extends Modifier.BaseModifier {
       }
     }
   }
-
-  @Override
-  public void export(Properties properties) {
-    throw new UnsupportedOperationException();
-  }
 }
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/rounders/IncrementRounder.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/rounders/IncrementRounder.java
deleted file mode 100644 (file)
index 01ba69c..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-// © 2017 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html#License
-package com.ibm.icu.impl.number.rounders;
-
-import java.math.BigDecimal;
-
-import com.ibm.icu.impl.number.FormatQuantity;
-import com.ibm.icu.impl.number.Properties;
-import com.ibm.icu.impl.number.Rounder;
-
-public class IncrementRounder extends Rounder {
-
-  public static interface IProperties extends IBasicRoundingProperties {
-
-    static BigDecimal DEFAULT_ROUNDING_INCREMENT = null;
-
-    /** @see #setRoundingIncrement */
-    public BigDecimal getRoundingIncrement();
-
-    /**
-     * Sets the increment to which to round numbers. For example, with a rounding interval of 0.05,
-     * the number 11.17 would be formatted as "11.15" in locale <em>en-US</em> with the default
-     * rounding mode.
-     *
-     * <p>You can use either a rounding increment or significant digits, but not both at the same
-     * time.
-     *
-     * <p>The rounding increment can be specified in a pattern string. For example, the pattern
-     * "#,##0.05" corresponds to a rounding interval of 0.05 with 1 minimum integer digit and a
-     * grouping size of 3.
-     *
-     * @param roundingIncrement The interval to which to round.
-     * @return The property bag, for chaining.
-     */
-    public IProperties setRoundingIncrement(BigDecimal roundingIncrement);
-  }
-
-  public static boolean useRoundingIncrement(IProperties properties) {
-    return properties.getRoundingIncrement() != IProperties.DEFAULT_ROUNDING_INCREMENT;
-  }
-
-  private final BigDecimal roundingIncrement;
-
-  public static IncrementRounder getInstance(IProperties properties) {
-    return new IncrementRounder(properties);
-  }
-
-  private IncrementRounder(IProperties properties) {
-    super(properties);
-    if (properties.getRoundingIncrement().compareTo(BigDecimal.ZERO) <= 0) {
-      throw new IllegalArgumentException("Rounding interval must be greater than zero");
-    }
-    roundingIncrement = properties.getRoundingIncrement();
-  }
-
-  @Override
-  public void apply(FormatQuantity input) {
-    input.roundToIncrement(roundingIncrement, mathContext);
-    applyDefaults(input);
-  }
-
-  @Override
-  public void export(Properties properties) {
-    super.export(properties);
-    properties.setRoundingIncrement(roundingIncrement);
-  }
-}
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/rounders/MagnitudeRounder.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/rounders/MagnitudeRounder.java
deleted file mode 100644 (file)
index d53f966..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-// © 2017 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html#License
-package com.ibm.icu.impl.number.rounders;
-
-import com.ibm.icu.impl.number.FormatQuantity;
-import com.ibm.icu.impl.number.Rounder;
-
-public class MagnitudeRounder extends Rounder {
-
-  public static interface IProperties extends IBasicRoundingProperties {}
-
-  public static boolean useFractionFormat(IProperties properties) {
-    return properties.getMinimumFractionDigits() != IProperties.DEFAULT_MINIMUM_FRACTION_DIGITS
-        || properties.getMaximumFractionDigits() != IProperties.DEFAULT_MAXIMUM_FRACTION_DIGITS;
-  }
-
-  public static MagnitudeRounder getInstance(IBasicRoundingProperties properties) {
-    return new MagnitudeRounder(properties);
-  }
-
-  private MagnitudeRounder(IBasicRoundingProperties properties) {
-    super(properties);
-  }
-
-  @Override
-  public void apply(FormatQuantity input) {
-    input.roundToMagnitude(-maxFrac, mathContext);
-    applyDefaults(input);
-  }
-}
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/rounders/NoRounder.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/rounders/NoRounder.java
deleted file mode 100644 (file)
index 814e11e..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-// © 2017 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html#License
-package com.ibm.icu.impl.number.rounders;
-
-import com.ibm.icu.impl.number.FormatQuantity;
-import com.ibm.icu.impl.number.Rounder;
-
-/** Sets the integer and fraction length based on the properties, but does not perform rounding. */
-public final class NoRounder extends Rounder {
-
-  public static NoRounder getInstance(IBasicRoundingProperties properties) {
-    return new NoRounder(properties);
-  }
-
-  private NoRounder(IBasicRoundingProperties properties) {
-    super(properties);
-  }
-
-  @Override
-  public void apply(FormatQuantity input) {
-    applyDefaults(input);
-    input.roundToInfinity();
-  }
-}
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/rounders/SignificantDigitsRounder.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/rounders/SignificantDigitsRounder.java
deleted file mode 100644 (file)
index 23977c3..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-// © 2017 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html#License
-package com.ibm.icu.impl.number.rounders;
-
-import java.math.RoundingMode;
-
-import com.ibm.icu.impl.number.FormatQuantity;
-import com.ibm.icu.impl.number.Properties;
-import com.ibm.icu.impl.number.Rounder;
-
-public class SignificantDigitsRounder extends Rounder {
-
-  public static interface IProperties extends Rounder.IBasicRoundingProperties {
-
-    static int DEFAULT_MINIMUM_SIGNIFICANT_DIGITS = -1;
-
-    /** @see #setMinimumSignificantDigits */
-    public int getMinimumSignificantDigits();
-
-    /**
-     * Sets the minimum number of significant digits to display. If, after rounding to the number of
-     * significant digits specified by {@link #setMaximumSignificantDigits}, the number of remaining
-     * significant digits is less than the minimum, the number will be padded with zeros. For
-     * example, if minimum significant digits is 3, the number 5.8 will be formatted as "5.80" in
-     * locale <em>en-US</em>. Note that minimum significant digits is relevant only when numbers
-     * have digits after the decimal point.
-     *
-     * <p>If both minimum significant digits and minimum integer/fraction digits are set at the same
-     * time, both values will be respected, and the one that results in the greater number of
-     * padding zeros will be used. For example, formatting the number 73 with 3 minimum significant
-     * digits and 2 minimum fraction digits will produce "73.00".
-     *
-     * <p>The number of significant digits can be specified in a pattern string using the '@'
-     * character. For example, the pattern "@@#" corresponds to a minimum of 2 and a maximum of 3
-     * significant digits.
-     *
-     * @param minimumSignificantDigits The minimum number of significant digits to display.
-     * @return The property bag, for chaining.
-     */
-    public IProperties setMinimumSignificantDigits(int minimumSignificantDigits);
-
-    static int DEFAULT_MAXIMUM_SIGNIFICANT_DIGITS = -1;
-
-    /** @see #setMaximumSignificantDigits */
-    public int getMaximumSignificantDigits();
-
-    /**
-     * Sets the maximum number of significant digits to display. The number of significant digits is
-     * equal to the number of digits counted from the leftmost nonzero digit through the rightmost
-     * nonzero digit; for example, the number "2010" has 3 significant digits. If the number has
-     * more significant digits than specified here, the extra significant digits will be rounded off
-     * using the rounding mode specified by {@link #setRoundingMode(RoundingMode)}. For example, if
-     * maximum significant digits is 3, the number 1234.56 will be formatted as "1230" in locale
-     * <em>en-US</em> with the default rounding mode.
-     *
-     * <p>If both maximum significant digits and maximum integer/fraction digits are set at the same
-     * time, the behavior is undefined.
-     *
-     * <p>The number of significant digits can be specified in a pattern string using the '@'
-     * character. For example, the pattern "@@#" corresponds to a minimum of 2 and a maximum of 3
-     * significant digits.
-     *
-     * @param maximumSignificantDigits The maximum number of significant digits to display.
-     * @return The property bag, for chaining.
-     */
-    public IProperties setMaximumSignificantDigits(int maximumSignificantDigits);
-  }
-
-  public static boolean useSignificantDigits(IProperties properties) {
-    return properties.getMinimumSignificantDigits()
-            != IProperties.DEFAULT_MINIMUM_SIGNIFICANT_DIGITS
-        || properties.getMaximumSignificantDigits()
-            != IProperties.DEFAULT_MAXIMUM_SIGNIFICANT_DIGITS;
-  }
-
-  public static SignificantDigitsRounder getInstance(IProperties properties) {
-    return new SignificantDigitsRounder(properties);
-  }
-
-  private final int minSig;
-  private final int maxSig;
-
-  private SignificantDigitsRounder(IProperties properties) {
-    super(properties);
-    int _minSig = properties.getMinimumSignificantDigits();
-    int _maxSig = properties.getMaximumSignificantDigits();
-    minSig = _minSig < 1 ? 1 : _minSig > 1000 ? 1000 : _minSig;
-    maxSig = _maxSig < 0 ? 1000 : _maxSig < minSig ? minSig : _maxSig > 1000 ? 1000 : _maxSig;
-  }
-
-  @Override
-  public void apply(FormatQuantity input) {
-
-    int magnitude, effectiveMag, magMinSig, magMaxSig;
-
-    if (input.isZero()) {
-      // Treat zero as if magnitude corresponded to the minimum number of zeros
-      magnitude = minInt - 1;
-    } else {
-      magnitude = input.getMagnitude();
-    }
-    effectiveMag = Math.min(magnitude + 1, maxInt);
-    magMinSig = effectiveMag - minSig;
-    magMaxSig = effectiveMag - maxSig;
-
-    // Step 1: pick the rounding magnitude and apply.
-    int roundingMagnitude = magMaxSig;
-    input.roundToMagnitude(roundingMagnitude, mathContext);
-
-    // In case magnitude changed:
-    if (input.isZero()) {
-      magnitude = minInt - 1;
-    } else {
-      magnitude = input.getMagnitude();
-    }
-    effectiveMag = Math.min(magnitude + 1, maxInt);
-    magMinSig = effectiveMag - minSig;
-    magMaxSig = effectiveMag - maxSig;
-
-    // Step 2: pick the number of visible digits.
-    input.setIntegerLength(minInt, maxInt);
-    input.setFractionLength(Math.max(minFrac, -magMinSig), Integer.MAX_VALUE);
-  }
-
-  @Override
-  public void export(Properties properties) {
-    super.export(properties);
-    properties.setMinimumSignificantDigits(minSig);
-    properties.setMaximumSignificantDigits(maxSig);
-  }
-}
index 7fb96a2eb4d31cfa03056378da2bc186d0f28eb6..3efa8fa15b8c3106b06d11e295abe6bbb193563f 100644 (file)
@@ -16,10 +16,8 @@ import java.text.ParsePosition;
 import com.ibm.icu.impl.number.Parse;
 import com.ibm.icu.impl.number.PatternString;
 import com.ibm.icu.impl.number.Properties;
-import com.ibm.icu.impl.number.formatters.PaddingFormat.PadPosition;
-import com.ibm.icu.impl.number.formatters.PositiveDecimalFormat;
-import com.ibm.icu.impl.number.formatters.ScientificFormat;
-import com.ibm.icu.impl.number.rounders.SignificantDigitsRounder;
+import com.ibm.icu.impl.number.ThingsNeedingNewHome;
+import com.ibm.icu.impl.number.ThingsNeedingNewHome.PadPosition;
 import com.ibm.icu.lang.UCharacter;
 import com.ibm.icu.math.BigDecimal;
 import com.ibm.icu.math.MathContext;
@@ -1472,7 +1470,8 @@ public class DecimalFormat extends NumberFormat {
    * @stable ICU 3.0
    */
   public synchronized boolean areSignificantDigitsUsed() {
-    return SignificantDigitsRounder.useSignificantDigits(properties);
+    return properties.getMinimumSignificantDigits() != -1
+        || properties.getMaximumSignificantDigits() != -1;
   }
 
   /**
@@ -1496,8 +1495,8 @@ public class DecimalFormat extends NumberFormat {
       properties.setMinimumSignificantDigits(1);
       properties.setMaximumSignificantDigits(6);
     } else {
-      properties.setMinimumSignificantDigits(Properties.DEFAULT_MINIMUM_SIGNIFICANT_DIGITS);
-      properties.setMaximumSignificantDigits(Properties.DEFAULT_MAXIMUM_SIGNIFICANT_DIGITS);
+      properties.setMinimumSignificantDigits(-1);
+      properties.setMaximumSignificantDigits(-1);
     }
     refreshFormatter();
   }
@@ -1691,7 +1690,7 @@ public class DecimalFormat extends NumberFormat {
    * @stable ICU 2.0
    */
   public synchronized boolean isScientificNotation() {
-    return ScientificFormat.useScientificNotation(properties);
+    return properties.getMinimumExponentDigits() != -1;
   }
 
   /**
@@ -1712,7 +1711,7 @@ public class DecimalFormat extends NumberFormat {
     if (useScientific) {
       properties.setMinimumExponentDigits(1);
     } else {
-      properties.setMinimumExponentDigits(Properties.DEFAULT_MINIMUM_EXPONENT_DIGITS);
+      properties.setMinimumExponentDigits(-1);
     }
     refreshFormatter();
   }
@@ -1783,7 +1782,7 @@ public class DecimalFormat extends NumberFormat {
    */
   @Override
   public synchronized boolean isGroupingUsed() {
-    return PositiveDecimalFormat.useGrouping(properties);
+    return properties.getGroupingSize() != -1 || properties.getSecondaryGroupingSize() != -1;
   }
 
   /**
@@ -1809,8 +1808,8 @@ public class DecimalFormat extends NumberFormat {
       // Set to a reasonable default value
       properties.setGroupingSize(3);
     } else {
-      properties.setGroupingSize(Properties.DEFAULT_GROUPING_SIZE);
-      properties.setSecondaryGroupingSize(Properties.DEFAULT_SECONDARY_GROUPING_SIZE);
+      properties.setGroupingSize(-1);
+      properties.setSecondaryGroupingSize(-1);
     }
     refreshFormatter();
   }
@@ -1894,7 +1893,12 @@ public class DecimalFormat extends NumberFormat {
    */
   @Deprecated
   public synchronized int getMinimumGroupingDigits() {
-    return properties.getMinimumGroupingDigits();
+    // Only 1 and 2 are supported right now.
+    if (properties.getMinimumGroupingDigits() == 2) {
+      return 2;
+    } else {
+      return 1;
+    }
   }
 
   /**
@@ -2374,7 +2378,7 @@ public class DecimalFormat extends NumberFormat {
     // so that CurrencyUsage is reflected properly.
     // TODO: Consider putting this logic in PatternString.java instead.
     Properties tprops = threadLocalProperties.get().copyFrom(properties);
-    if (com.ibm.icu.impl.number.formatters.CurrencyFormat.useCurrency(properties)) {
+    if (ThingsNeedingNewHome.useCurrency(properties)) {
       tprops.setMinimumFractionDigits(exportedProperties.getMinimumFractionDigits());
       tprops.setMaximumFractionDigits(exportedProperties.getMaximumFractionDigits());
       tprops.setRoundingIncrement(exportedProperties.getRoundingIncrement());
index 8d6c975e26ee1f3460fea272bf43842418dcda42..80f7138f54c66a5126a6a3bb5e02f28c42824eee 100644 (file)
@@ -11,9 +11,9 @@ import java.text.FieldPosition;
 import java.util.Arrays;
 import java.util.Locale;
 
-import com.ibm.icu.impl.number.FormatQuantityBCD;
+import com.ibm.icu.impl.number.FormatQuantity;
 import com.ibm.icu.impl.number.NumberStringBuilder;
-import com.ibm.icu.impl.number.formatters.PaddingFormat.PadPosition;
+import com.ibm.icu.impl.number.ThingsNeedingNewHome.PadPosition;
 import com.ibm.icu.text.CompactDecimalFormat.CompactStyle;
 import com.ibm.icu.text.DecimalFormatSymbols;
 import com.ibm.icu.text.MeasureFormat.FormatWidth;
@@ -236,7 +236,7 @@ public final class NumberFormatter {
 
   public static class NumberFormatterResult {
     NumberStringBuilder nsb;
-    FormatQuantityBCD fq;
+    FormatQuantity fq;
     MicroProps micros;
 
     /**
@@ -244,7 +244,7 @@ public final class NumberFormatter {
      * @deprecated This API is ICU internal only.
      */
     @Deprecated
-    public NumberFormatterResult(NumberStringBuilder nsb, FormatQuantityBCD fq, MicroProps micros) {
+    public NumberFormatterResult(NumberStringBuilder nsb, FormatQuantity fq, MicroProps micros) {
       this.nsb = nsb;
       this.fq = fq;
       this.micros = micros;
index 173031e884a4a4860722464587fa5804151b84ba..f772ed2492db8a18824b61875599952ecf2c4867 100644 (file)
@@ -6,8 +6,8 @@ import java.util.Locale;
 import java.util.Objects;
 import java.util.concurrent.atomic.AtomicLongFieldUpdater;
 
+import com.ibm.icu.impl.number.FormatQuantity;
 import com.ibm.icu.impl.number.FormatQuantity4;
-import com.ibm.icu.impl.number.FormatQuantityBCD;
 import com.ibm.icu.impl.number.NumberStringBuilder;
 import com.ibm.icu.impl.number.PatternString;
 import com.ibm.icu.impl.number.Properties;
@@ -216,7 +216,7 @@ public class NumberFormatterImpl extends NumberFormatter.LocalizedNumberFormatte
    * @param fq The quantity to be formatted.
    * @return The formatted number result.
    */
-  private NumberFormatterResult format(FormatQuantityBCD fq) {
+  public NumberFormatterResult format(FormatQuantity fq) {
     MacroProps macros = resolve();
     NumberStringBuilder string = new NumberStringBuilder();
     long currentCount = callCount.incrementAndGet(this);
index 747695325387bc858e00952edc78907d503ea9f8..81cf952960abdaf93b17dc78611725cabc03c14f 100644 (file)
@@ -33,6 +33,13 @@ import newapi.impl.RoundingImpl.RoundingImplSignificant;
 /** @author sffc */
 public final class NumberPropertyMapper {
 
+  /** Convenience method to create a NumberFormatterImpl directly. */
+  public static NumberFormatterImpl create(
+      Properties properties, DecimalFormatSymbols symbols, ULocale uloc) {
+    MacroProps macros = oldToNew(properties, symbols, null);
+    return NumberFormatterImpl.fromMacros(macros).locale(uloc);
+  }
+
   /**
    * Creates a new {@link MacroProps} object based on the content of a {@link Properties} object. In
    * other words, maps Properties to MacroProps. This function is used by the JDK-compatibility API
@@ -96,7 +103,7 @@ public final class NumberPropertyMapper {
             || affixProvider.hasCurrencySign());
     Currency currency = CustomSymbolCurrency.resolve(properties.getCurrency(), locale, symbols);
     CurrencyUsage currencyUsage = properties.getCurrencyUsage();
-    boolean explicitCurrencyUsage = currencyUsage != Properties.DEFAULT_CURRENCY_USAGE;
+    boolean explicitCurrencyUsage = currencyUsage != null;
     if (!explicitCurrencyUsage) {
       currencyUsage = CurrencyUsage.STANDARD;
     }
@@ -116,12 +123,8 @@ public final class NumberPropertyMapper {
     int maxSig = properties.getMaximumSignificantDigits();
     BigDecimal roundingIncrement = properties.getRoundingIncrement();
     MathContext mathContext = RoundingUtils.getMathContextOrUnlimited(properties);
-    boolean explicitMinMaxFrac =
-        minFrac != Properties.DEFAULT_MINIMUM_FRACTION_DIGITS
-            || maxFrac != Properties.DEFAULT_MAXIMUM_FRACTION_DIGITS;
-    boolean explicitMinMaxSig =
-        minSig != Properties.DEFAULT_MINIMUM_SIGNIFICANT_DIGITS
-            || maxSig != Properties.DEFAULT_MAXIMUM_SIGNIFICANT_DIGITS;
+    boolean explicitMinMaxFrac = minFrac != -1 || maxFrac != -1;
+    boolean explicitMinMaxSig = minSig != -1 || maxSig != -1;
     // Validate min/max int/frac.
     // For backwards compatibility, minimum overrides maximum if the two conflict.
     // The following logic ensures that there is always a minimum of at least one digit.
@@ -181,7 +184,7 @@ public final class NumberPropertyMapper {
     // PADDING //
     /////////////
 
-    if (properties.getFormatWidth() != Properties.DEFAULT_FORMAT_WIDTH) {
+    if (properties.getFormatWidth() != -1) {
       macros.padding =
           PaddingImpl.getInstance(
               properties.getPadString(), properties.getFormatWidth(), properties.getPadPosition());
@@ -206,13 +209,18 @@ public final class NumberPropertyMapper {
     // SCIENTIFIC NOTATION //
     /////////////////////////
 
-    if (properties.getMinimumExponentDigits() != Properties.DEFAULT_MINIMUM_EXPONENT_DIGITS) {
+    if (properties.getMinimumExponentDigits() != -1) {
       // Scientific notation is required.
       // The mapping from property bag to scientific notation is nontrivial due to LDML rules.
       // The maximum of 8 engineering digits has unknown origins and is not in the spec.
       int engineering =
           (maxInt != Integer.MAX_VALUE) ? maxInt : properties.getMaximumIntegerDigits();
       engineering = (engineering < 0) ? 0 : (engineering > 8) ? minInt : engineering;
+      // Bug #13289: if maxInt > minInt > 1, then minInt should be 1.
+      // Clear out IntegerWidth to prevent padding extra zeros.
+      if (maxInt > minInt && minInt > 1) {
+        macros.integerWidth = null;
+      }
       macros.notation =
           new NotationScientificImpl(
               // Engineering interval:
@@ -222,9 +230,7 @@ public final class NumberPropertyMapper {
               // Minimum exponent digits:
               properties.getMinimumExponentDigits(),
               // Exponent sign always shown:
-              properties.getExponentSignAlwaysShown()
-                  ? SignDisplay.ALWAYS
-                  : SignDisplay.AUTO);
+              properties.getExponentSignAlwaysShown() ? SignDisplay.ALWAYS : SignDisplay.AUTO);
       // Scientific notation also involves overriding the rounding mode.
       if (macros.rounding instanceof RoundingImplFraction) {
         int minInt_ = properties.getMinimumIntegerDigits();
@@ -249,7 +255,7 @@ public final class NumberPropertyMapper {
     // COMPACT NOTATION //
     //////////////////////
 
-    if (properties.getCompactStyle() != Properties.DEFAULT_COMPACT_STYLE) {
+    if (properties.getCompactStyle() != null) {
       if (properties.getCompactCustomData() != null) {
         macros.notation = new NotationImpl.NotationCompactImpl(properties.getCompactCustomData());
       } else if (properties.getCompactStyle() == CompactStyle.LONG) {
@@ -265,9 +271,9 @@ public final class NumberPropertyMapper {
     // MULTIPLIERS //
     /////////////////
 
-    if (properties.getMagnitudeMultiplier() != Properties.DEFAULT_MAGNITUDE_MULTIPLIER) {
+    if (properties.getMagnitudeMultiplier() != 0) {
       macros.multiplier = new MultiplierImpl(properties.getMagnitudeMultiplier());
-    } else if (properties.getMultiplier() != Properties.DEFAULT_MULTIPLIER) {
+    } else if (properties.getMultiplier() != null) {
       macros.multiplier = new MultiplierImpl(properties.getMultiplier());
     }
 
index f747ebb0e623689bac4558913c5c13ec124c6cc6..6700d87182065a81f9551cb2b175a30fb8a30ba2 100644 (file)
@@ -3,7 +3,7 @@
 package newapi.impl;
 
 import com.ibm.icu.impl.number.NumberStringBuilder;
-import com.ibm.icu.impl.number.formatters.PaddingFormat.PadPosition;
+import com.ibm.icu.impl.number.ThingsNeedingNewHome.PadPosition;
 
 import newapi.NumberFormatter.Padding;
 
index 65f3cb11668ca138776ece34ea019543a5212a08..01df495c4771da83a099185f915ebe20de39d622 100644 (file)
@@ -3,28 +3,14 @@
 package newapi.impl;
 // License & terms of use: http://www.unicode.org/copyright.html#License
 
-import com.ibm.icu.impl.number.Format;
 import com.ibm.icu.impl.number.FormatQuantity;
 import com.ibm.icu.impl.number.NumberStringBuilder;
-import com.ibm.icu.impl.number.Properties;
 import com.ibm.icu.text.NumberFormat;
 
 import newapi.NumberFormatter.DecimalMarkDisplay;
 
-public class PositiveDecimalImpl implements Format.TargetFormat {
+public class PositiveDecimalImpl {
 
-  @Override
-  public int target(FormatQuantity input, NumberStringBuilder string, int startIndex) {
-    // FIXME
-    throw new UnsupportedOperationException();
-  }
-
-  /**
-   * @param micros
-   * @param fq
-   * @param output
-   * @return
-   */
   public static int apply(MicroProps micros, FormatQuantity input, NumberStringBuilder string) {
     int length = 0;
     if (input.isInfinite()) {
@@ -106,9 +92,4 @@ public class PositiveDecimalImpl implements Format.TargetFormat {
     }
     return length;
   }
-
-  @Override
-  public void export(Properties properties) {
-    throw new UnsupportedOperationException();
-  }
 }
index 97160d5462d9ecd2b61d25fc33b4c8e0990a7be4..8663f715483c79da87491bddcf25ad5ffe4abc5a 100644 (file)
@@ -6,7 +6,7 @@ import java.math.BigDecimal;
 import java.math.MathContext;
 import java.math.RoundingMode;
 
-import com.ibm.icu.impl.number.formatters.PaddingFormat.PadPosition;
+import com.ibm.icu.impl.number.ThingsNeedingNewHome.PadPosition;
 import com.ibm.icu.text.CompactDecimalFormat.CompactStyle;
 import com.ibm.icu.text.DecimalFormatSymbols;
 import com.ibm.icu.text.MeasureFormat.FormatWidth;
@@ -461,9 +461,9 @@ public final class SkeletonBuilder {
       if (c1 == ',') {
         char c2 = safeCharAt(skeleton, offset++);
         char c3 = safeCharAt(skeleton, offset++);
-        result = GroupingImpl.getInstance((short) (c0 - '0'), (short) (c2 - '0'), c3 == '&');
+        result = GroupingImpl.getInstance((byte) (c0 - '0'), (byte) (c2 - '0'), c3 == '&');
       } else {
-        result = GroupingImpl.getInstance((short) (c0 - '0'), (short) (c0 - '0'), c1 == '&');
+        result = GroupingImpl.getInstance((byte) (c0 - '0'), (byte) (c0 - '0'), c1 == '&');
       }
     } else {
       StringBuilder sb = new StringBuilder();
index 38b5f3acbf5bd8c975ace10a453f13233b84ba3a..31955450cf625b93b1b48c92d006c14d0ee128c1 100644 (file)
@@ -364,8 +364,7 @@ minIntegerDigits    maxIntegerDigits        minFractionDigits       maxFractionDigits       output  bre
 // Treat max int digits > 8 as being the same as min int digits.
 // This behavior is not spelled out in the specification.
 // JDK fails here because it tries to use 9 + 6 = 15 sig digits.
-// C and J get 29.979246E7
-2      9       1       6       2.9979246E8     CJK
+2      9       1       6       29.979246E7     K
 
 test significant digits scientific
 set locale en
index 8772d332c76d8b50817d14013985a77d7de6d710..1c8dd8277ed0f7b8f81882fc28d80fbe53f1e9d6 100644 (file)
@@ -4,26 +4,15 @@ package com.ibm.icu.dev.test.format;
 
 import java.math.BigDecimal;
 import java.math.RoundingMode;
-import java.text.ParseException;
 import java.text.ParsePosition;
 
 import org.junit.Test;
 
 import com.ibm.icu.dev.test.TestUtil;
-import com.ibm.icu.impl.number.Endpoint;
-import com.ibm.icu.impl.number.Format;
-import com.ibm.icu.impl.number.FormatQuantity;
-import com.ibm.icu.impl.number.FormatQuantity1;
-import com.ibm.icu.impl.number.FormatQuantity2;
-import com.ibm.icu.impl.number.FormatQuantity3;
-import com.ibm.icu.impl.number.FormatQuantity4;
-import com.ibm.icu.impl.number.Parse;
 import com.ibm.icu.impl.number.Parse.ParseMode;
 import com.ibm.icu.impl.number.PatternString;
 import com.ibm.icu.impl.number.Properties;
-import com.ibm.icu.impl.number.formatters.PaddingFormat.PadPosition;
-import com.ibm.icu.text.DecimalFormat;
-import com.ibm.icu.text.DecimalFormat.PropertySetter;
+import com.ibm.icu.impl.number.ThingsNeedingNewHome.PadPosition;
 import com.ibm.icu.text.DecimalFormatSymbols;
 import com.ibm.icu.text.DecimalFormat_ICU58;
 import com.ibm.icu.util.CurrencyAmount;
@@ -436,244 +425,6 @@ public class NumberFormatDataDrivenTest {
         }
       };
 
-  private DataDrivenNumberFormatTestUtility.CodeUnderTest ICU59 =
-      new DataDrivenNumberFormatTestUtility.CodeUnderTest() {
-
-        @Override
-        public Character Id() {
-          return 'S';
-        }
-
-        /**
-         * Runs a single formatting test. On success, returns null. On failure, returns the error.
-         * This implementation just returns null. Subclasses should override.
-         *
-         * @param tuple contains the parameters of the format test.
-         */
-        @Override
-        public String format(DataDrivenNumberFormatTestData tuple) {
-          String pattern = (tuple.pattern == null) ? "0" : tuple.pattern;
-          ULocale locale = (tuple.locale == null) ? ULocale.ENGLISH : tuple.locale;
-          Properties properties =
-              PatternString.parseToProperties(
-                  pattern,
-                  tuple.currency != null
-                      ? PatternString.IGNORE_ROUNDING_ALWAYS
-                      : PatternString.IGNORE_ROUNDING_NEVER);
-          propertiesFromTuple(tuple, properties);
-          Format fmt = Endpoint.fromBTA(properties, locale);
-          FormatQuantity q1, q2, q3;
-          if (tuple.format.equals("NaN")) {
-            q1 = q2 = new FormatQuantity1(Double.NaN);
-            q3 = new FormatQuantity2(Double.NaN);
-          } else if (tuple.format.equals("-Inf")) {
-            q1 = q2 = new FormatQuantity1(Double.NEGATIVE_INFINITY);
-            q3 = new FormatQuantity1(Double.NEGATIVE_INFINITY);
-          } else if (tuple.format.equals("Inf")) {
-            q1 = q2 = new FormatQuantity1(Double.POSITIVE_INFINITY);
-            q3 = new FormatQuantity1(Double.POSITIVE_INFINITY);
-          } else {
-            BigDecimal d = new BigDecimal(tuple.format);
-            if (d.precision() <= 16) {
-              q1 = new FormatQuantity1(d);
-              q2 = new FormatQuantity1(Double.parseDouble(tuple.format));
-              q3 = new FormatQuantity4(d);
-            } else {
-              q1 = new FormatQuantity1(d);
-              q2 = new FormatQuantity3(d);
-              q3 = new FormatQuantity4(d); // duplicate values so no null
-            }
-          }
-          String expected = tuple.output;
-          String actual1 = fmt.format(q1);
-          if (!expected.equals(actual1)) {
-            return "Expected \""
-                + expected
-                + "\", got \""
-                + actual1
-                + "\" on FormatQuantity1 BigDecimal";
-          }
-          String actual2 = fmt.format(q2);
-          if (!expected.equals(actual2)) {
-            return "Expected \""
-                + expected
-                + "\", got \""
-                + actual2
-                + "\" on FormatQuantity1 double";
-          }
-          String actual3 = fmt.format(q3);
-          if (!expected.equals(actual3)) {
-            return "Expected \""
-                + expected
-                + "\", got \""
-                + actual3
-                + "\" on FormatQuantity4 BigDecimal";
-          }
-          return null;
-        }
-
-        /**
-         * Runs a single toPattern test. On success, returns null. On failure, returns the error.
-         * This implementation just returns null. Subclasses should override.
-         *
-         * @param tuple contains the parameters of the format test.
-         */
-        @Override
-        public String toPattern(DataDrivenNumberFormatTestData tuple) {
-          String pattern = (tuple.pattern == null) ? "0" : tuple.pattern;
-          final Properties properties;
-          DecimalFormat df;
-          try {
-            properties =
-                PatternString.parseToProperties(
-                    pattern,
-                    tuple.currency != null
-                        ? PatternString.IGNORE_ROUNDING_ALWAYS
-                        : PatternString.IGNORE_ROUNDING_NEVER);
-            propertiesFromTuple(tuple, properties);
-            // TODO: Use PatternString.propertiesToString() directly. (How to deal with CurrencyUsage?)
-            df = new DecimalFormat();
-            df.setProperties(
-                new PropertySetter() {
-                  @Override
-                  public void set(Properties props) {
-                    props.copyFrom(properties);
-                  }
-                });
-          } catch (IllegalArgumentException e) {
-            e.printStackTrace();
-            return e.getLocalizedMessage();
-          }
-
-          if (tuple.toPattern != null) {
-            String expected = tuple.toPattern;
-            String actual = df.toPattern();
-            if (!expected.equals(actual)) {
-              return "Expected toPattern='" + expected + "'; got '" + actual + "'";
-            }
-          }
-          if (tuple.toLocalizedPattern != null) {
-            String expected = tuple.toLocalizedPattern;
-            String actual = PatternString.propertiesToString(properties);
-            if (!expected.equals(actual)) {
-              return "Expected toLocalizedPattern='" + expected + "'; got '" + actual + "'";
-            }
-          }
-          return null;
-        }
-
-        /**
-         * Runs a single parse test. On success, returns null. On failure, returns the error. This
-         * implementation just returns null. Subclasses should override.
-         *
-         * @param tuple contains the parameters of the format test.
-         */
-        @Override
-        public String parse(DataDrivenNumberFormatTestData tuple) {
-          String pattern = (tuple.pattern == null) ? "0" : tuple.pattern;
-          Properties properties;
-          ParsePosition ppos = new ParsePosition(0);
-          Number actual;
-          try {
-            properties =
-                PatternString.parseToProperties(
-                    pattern,
-                    tuple.currency != null
-                        ? PatternString.IGNORE_ROUNDING_ALWAYS
-                        : PatternString.IGNORE_ROUNDING_NEVER);
-            propertiesFromTuple(tuple, properties);
-            actual =
-                Parse.parse(
-                    tuple.parse, ppos, properties, DecimalFormatSymbols.getInstance(tuple.locale));
-          } catch (IllegalArgumentException e) {
-            return "parse exception: " + e.getMessage();
-          }
-          if (actual == null && ppos.getIndex() != 0) {
-            throw new AssertionError("Error: value is null but parse position is not zero");
-          }
-          if (ppos.getIndex() == 0) {
-            return "Parse failed; got " + actual + ", but expected " + tuple.output;
-          }
-          if (tuple.output.equals("NaN")) {
-            if (!Double.isNaN(actual.doubleValue())) {
-              return "Expected NaN, but got: " + actual;
-            }
-            return null;
-          } else if (tuple.output.equals("Inf")) {
-            if (!Double.isInfinite(actual.doubleValue())
-                || Double.compare(actual.doubleValue(), 0.0) < 0) {
-              return "Expected Inf, but got: " + actual;
-            }
-            return null;
-          } else if (tuple.output.equals("-Inf")) {
-            if (!Double.isInfinite(actual.doubleValue())
-                || Double.compare(actual.doubleValue(), 0.0) > 0) {
-              return "Expected -Inf, but got: " + actual;
-            }
-            return null;
-          } else if (tuple.output.equals("fail")) {
-            return null;
-          } else if (new BigDecimal(tuple.output).compareTo(new BigDecimal(actual.toString()))
-              != 0) {
-            return "Expected: " + tuple.output + ", got: " + actual;
-          } else {
-            return null;
-          }
-        }
-
-        /**
-         * Runs a single parse currency test. On success, returns null. On failure, returns the
-         * error. This implementation just returns null. Subclasses should override.
-         *
-         * @param tuple contains the parameters of the format test.
-         */
-        @Override
-        public String parseCurrency(DataDrivenNumberFormatTestData tuple) {
-          String pattern = (tuple.pattern == null) ? "0" : tuple.pattern;
-          Properties properties;
-          ParsePosition ppos = new ParsePosition(0);
-          CurrencyAmount actual;
-          try {
-            properties =
-                PatternString.parseToProperties(
-                    pattern,
-                    tuple.currency != null
-                        ? PatternString.IGNORE_ROUNDING_ALWAYS
-                        : PatternString.IGNORE_ROUNDING_NEVER);
-            propertiesFromTuple(tuple, properties);
-            actual =
-                Parse.parseCurrency(
-                    tuple.parse, ppos, properties, DecimalFormatSymbols.getInstance(tuple.locale));
-          } catch (ParseException e) {
-            e.printStackTrace();
-            return "parse exception: " + e.getMessage();
-          }
-          if (ppos.getIndex() == 0 || actual.getCurrency().getCurrencyCode().equals("XXX")) {
-            return "Parse failed; got " + actual + ", but expected " + tuple.output;
-          }
-          BigDecimal expectedNumber = new BigDecimal(tuple.output);
-          if (expectedNumber.compareTo(new BigDecimal(actual.getNumber().toString())) != 0) {
-            return "Wrong number: Expected: " + expectedNumber + ", got: " + actual;
-          }
-          String expectedCurrency = tuple.outputCurrency;
-          if (!expectedCurrency.equals(actual.getCurrency().toString())) {
-            return "Wrong currency: Expected: " + expectedCurrency + ", got: " + actual;
-          }
-          return null;
-        }
-
-        /**
-         * Runs a single select test. On success, returns null. On failure, returns the error. This
-         * implementation just returns null. Subclasses should override.
-         *
-         * @param tuple contains the parameters of the format test.
-         */
-        @Override
-        public String select(DataDrivenNumberFormatTestData tuple) {
-          return null;
-        }
-      };
-
   static void propertiesFromTuple(DataDrivenNumberFormatTestData tuple, Properties properties) {
     if (tuple.minIntegerDigits != null) {
       properties.setMinimumIntegerDigits(tuple.minIntegerDigits);
@@ -720,7 +471,7 @@ public class NumberFormatDataDrivenTest {
     }
     if (tuple.useScientific != null) {
       properties.setMinimumExponentDigits(
-          tuple.useScientific != 0 ? 1 : Properties.DEFAULT_MINIMUM_EXPONENT_DIGITS);
+          tuple.useScientific != 0 ? 1 : -1);
     }
     if (tuple.grouping != null) {
       properties.setGroupingSize(tuple.grouping);
@@ -836,12 +587,6 @@ public class NumberFormatDataDrivenTest {
         "numberformattestspecification.txt", JDK);
   }
 
-  @Test
-  public void TestDataDrivenICU59() {
-    DataDrivenNumberFormatTestUtility.runFormatSuiteIncludingKnownFailures(
-        "numberformattestspecification.txt", ICU59);
-  }
-
   @Test
   public void TestDataDrivenICU60() {
     DataDrivenNumberFormatTestUtility.runFormatSuiteIncludingKnownFailures(
index 4f5e6a7f8151cf15149feb621905bf275bbfe014..32bcc71e04ff9c63a35f8db9fcfb526e20bb9018 100644 (file)
@@ -79,10 +79,6 @@ public class AffixPatternUtilsTest {
       {"#0#@#*#;#", false, 9, "#0#@#*#;#"}
     };
 
-    // ar_SA has an interesting percent sign and various Arabic letter marks
-    DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance(new ULocale("ar_SA"));
-    NumberStringBuilder sb = new NumberStringBuilder();
-
     for (Object[] cas : cases) {
       String input = (String) cas[0];
       boolean curr = (Boolean) cas[1];
@@ -93,9 +89,8 @@ public class AffixPatternUtilsTest {
           "Currency on <" + input + ">", curr, AffixPatternUtils.hasCurrencySymbols(input));
       assertEquals("Length on <" + input + ">", length, AffixPatternUtils.unescapedLength(input));
 
-      sb.clear();
-      AffixPatternUtils.unescape(input, symbols, "$", "XXX", "long name", "−", sb);
-      assertEquals("Output on <" + input + ">", output, sb.toString());
+      String actual = unescapeWithDefaults(input);
+      assertEquals("Output on <" + input + ">", output, actual);
     }
   }
 
@@ -130,8 +125,6 @@ public class AffixPatternUtilsTest {
   @Test
   public void testInvalid() {
     String[] invalidExamples = {"'", "x'", "'x", "'x''", "''x'"};
-    DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance(new ULocale("en_US"));
-    NumberStringBuilder sb = new NumberStringBuilder();
 
     for (String str : invalidExamples) {
       try {
@@ -147,7 +140,7 @@ public class AffixPatternUtilsTest {
         // OK
       }
       try {
-        AffixPatternUtils.unescape(str, symbols, "$", "XXX", "long name", "−", sb);
+        unescapeWithDefaults(str);
         fail("No exception was thrown on an invalid string");
       } catch (IllegalArgumentException e) {
         // OK
@@ -189,4 +182,46 @@ public class AffixPatternUtilsTest {
     AffixPatternUtils.unescape("-+%", sb, 4, provider);
     assertEquals("Symbol provider into middle", "abcd123efg", sb.toString());
   }
+
+  private static final SymbolProvider DEFAULT_SYMBOL_PROVIDER =
+      new SymbolProvider() {
+        // ar_SA has an interesting percent sign and various Arabic letter marks
+        private final DecimalFormatSymbols SYMBOLS =
+            DecimalFormatSymbols.getInstance(new ULocale("ar_SA"));
+
+        @Override
+        public CharSequence getSymbol(int type) {
+          switch (type) {
+            case AffixPatternUtils.TYPE_MINUS_SIGN:
+              return "−";
+            case AffixPatternUtils.TYPE_PLUS_SIGN:
+              return SYMBOLS.getPlusSignString();
+            case AffixPatternUtils.TYPE_PERCENT:
+              return SYMBOLS.getPercentString();
+            case AffixPatternUtils.TYPE_PERMILLE:
+              return SYMBOLS.getPerMillString();
+            case AffixPatternUtils.TYPE_CURRENCY_SINGLE:
+              return "$";
+            case AffixPatternUtils.TYPE_CURRENCY_DOUBLE:
+              return "XXX";
+            case AffixPatternUtils.TYPE_CURRENCY_TRIPLE:
+              return "long name";
+            case AffixPatternUtils.TYPE_CURRENCY_QUAD:
+              return "\uFFFD";
+            case AffixPatternUtils.TYPE_CURRENCY_QUINT:
+              // TODO: Add support for narrow currency symbols here.
+              return "\uFFFD";
+            case AffixPatternUtils.TYPE_CURRENCY_OVERFLOW:
+              return "\uFFFD";
+            default:
+              throw new AssertionError();
+          }
+        }
+      };
+
+  private static String unescapeWithDefaults(String input) {
+    NumberStringBuilder nsb = new NumberStringBuilder();
+    AffixPatternUtils.unescape(input, nsb, 0, DEFAULT_SYMBOL_PROVIDER);
+    return nsb.toString();
+  }
 }
index 45bc3b5c3461b8bd13edf29c6ffce76620c63d09..c92905b261f6378371ed6287118c984207f41887 100644 (file)
@@ -13,8 +13,6 @@ import java.util.Random;
 import org.junit.Test;
 
 import com.ibm.icu.dev.test.TestFmwk;
-import com.ibm.icu.impl.number.Endpoint;
-import com.ibm.icu.impl.number.Format;
 import com.ibm.icu.impl.number.FormatQuantity;
 import com.ibm.icu.impl.number.FormatQuantity1;
 import com.ibm.icu.impl.number.FormatQuantity2;
@@ -22,6 +20,10 @@ import com.ibm.icu.impl.number.FormatQuantity3;
 import com.ibm.icu.impl.number.FormatQuantity4;
 import com.ibm.icu.impl.number.Properties;
 import com.ibm.icu.text.CompactDecimalFormat.CompactStyle;
+import com.ibm.icu.util.ULocale;
+
+import newapi.impl.NumberFormatterImpl;
+import newapi.impl.NumberPropertyMapper;
 
 /** TODO: This is a temporary name for this class. Suggestions for a better name? */
 public class FormatQuantityTest extends TestFmwk {
@@ -30,31 +32,27 @@ public class FormatQuantityTest extends TestFmwk {
   public void testBehavior() throws ParseException {
 
     // Make a list of several formatters to test the behavior of FormatQuantity.
-    List<Format> formats = new ArrayList<Format>();
+    List<NumberFormatterImpl> formats = new ArrayList<NumberFormatterImpl>();
 
     Properties properties = new Properties();
-    Format ndf = Endpoint.fromBTA(properties);
-    formats.add(ndf);
+    formats.add(NumberPropertyMapper.create(properties, null, ULocale.ENGLISH));
 
     properties =
         new Properties()
             .setMinimumSignificantDigits(3)
             .setMaximumSignificantDigits(3)
             .setCompactStyle(CompactStyle.LONG);
-    Format cdf = Endpoint.fromBTA(properties);
-    formats.add(cdf);
+    formats.add(NumberPropertyMapper.create(properties, null, ULocale.ENGLISH));
 
     properties =
         new Properties()
             .setMinimumExponentDigits(1)
             .setMaximumIntegerDigits(3)
             .setMaximumFractionDigits(1);
-    Format exf = Endpoint.fromBTA(properties);
-    formats.add(exf);
+    formats.add(NumberPropertyMapper.create(properties, null, ULocale.ENGLISH));
 
     properties = new Properties().setRoundingIncrement(new BigDecimal("0.5"));
-    Format rif = Endpoint.fromBTA(properties);
-    formats.add(rif);
+    formats.add(NumberPropertyMapper.create(properties, null, ULocale.ENGLISH));
 
     String[] cases = {
       "1.0",
@@ -112,7 +110,7 @@ public class FormatQuantityTest extends TestFmwk {
     }
   }
 
-  static void testFormatQuantity(int t, String str, List<Format> formats, int mode) {
+  static void testFormatQuantity(int t, String str, List<NumberFormatterImpl> formats, int mode) {
     if (mode == 2) {
       assertEquals("Double is not valid", Double.toString(Double.parseDouble(str)), str);
     }
@@ -230,12 +228,12 @@ public class FormatQuantityTest extends TestFmwk {
   }
 
   private static void testFormatQuantityWithFormats(
-      FormatQuantity rq0, FormatQuantity rq1, List<Format> formats) {
-    for (Format format : formats) {
+      FormatQuantity rq0, FormatQuantity rq1, List<NumberFormatterImpl> formats) {
+    for (NumberFormatterImpl format : formats) {
       FormatQuantity q0 = rq0.createCopy();
       FormatQuantity q1 = rq1.createCopy();
-      String s1 = format.format(q0);
-      String s2 = format.format(q1);
+      String s1 = format.format(q0).toString();
+      String s2 = format.format(q1).toString();
       assertEquals("Different output from formatter (" + q0 + ", " + q1 + ")", s1, s2);
     }
   }
index bcdd4d31d237acb9ba87441a641557344257f521..89cb4ac64976fdda0f5d10450115ce70e507b992 100644 (file)
@@ -12,7 +12,7 @@ import java.util.Locale;
 import org.junit.Ignore;
 import org.junit.Test;
 
-import com.ibm.icu.impl.number.formatters.PaddingFormat.PadPosition;
+import com.ibm.icu.impl.number.ThingsNeedingNewHome.PadPosition;
 import com.ibm.icu.text.DecimalFormatSymbols;
 import com.ibm.icu.text.MeasureFormat.FormatWidth;
 import com.ibm.icu.text.NumberingSystem;
index 7f64bf03a6ae2c95ec3d1f21d328078292332655..d8e786a9a948a73afd10c6baf07f00717208bbdc 100644 (file)
@@ -33,8 +33,7 @@ import com.ibm.icu.impl.number.Parse.GroupingMode;
 import com.ibm.icu.impl.number.Parse.ParseMode;
 import com.ibm.icu.impl.number.PatternString;
 import com.ibm.icu.impl.number.Properties;
-import com.ibm.icu.impl.number.formatters.CurrencyFormat.CurrencyStyle;
-import com.ibm.icu.impl.number.formatters.PaddingFormat.PadPosition;
+import com.ibm.icu.impl.number.ThingsNeedingNewHome.PadPosition;
 import com.ibm.icu.text.CompactDecimalFormat.CompactStyle;
 import com.ibm.icu.text.CurrencyPluralInfo;
 import com.ibm.icu.text.MeasureFormat.FormatWidth;
@@ -241,11 +240,6 @@ public class PropertiesTest {
       ULocale[] locales = ULocale.getAvailableLocales();
       return CurrencyPluralInfo.getInstance(locales[seed % locales.length]);
 
-    } else if (type == CurrencyStyle.class) {
-      if (seed == 0) return null;
-      CurrencyStyle[] values = CurrencyStyle.values();
-      return values[seed % values.length];
-
     } else if (type == CurrencyUsage.class) {
       if (seed == 0) return null;
       CurrencyUsage[] values = CurrencyUsage.values();