]> granicus.if.org Git - icu/commitdiff
ICU-12030 move some code to QuantityFormatter so that PluralRules does not depend...
authorMarkus Scherer <markus.icu@gmail.com>
Wed, 16 Dec 2015 04:30:48 +0000 (04:30 +0000)
committerMarkus Scherer <markus.icu@gmail.com>
Wed, 16 Dec 2015 04:30:48 +0000 (04:30 +0000)
X-SVN-Rev: 38135

icu4j/main/classes/core/src/com/ibm/icu/text/MeasureFormat.java
icu4j/main/classes/core/src/com/ibm/icu/text/PluralRules.java
icu4j/main/classes/core/src/com/ibm/icu/text/QuantityFormatter.java

index 482f564af10f1ec6f04acfdef1c2fb568bea4323..cb08f625465b5b241c84b5511e054ddb9e2f5eee 100644 (file)
@@ -1017,34 +1017,23 @@ public class MeasureFormat extends UFormat {
             ImmutableNumberFormat nf,
             StringBuilder appendTo,
             FieldPosition fieldPosition) {
-        if (measure.getUnit() instanceof Currency) {
+        Number n = measure.getNumber();
+        MeasureUnit unit = measure.getUnit();
+        if (unit instanceof Currency) {
             return appendTo.append(
                     currencyFormat.format(
-                            new CurrencyAmount(measure.getNumber(), (Currency) measure.getUnit()),
+                            new CurrencyAmount(n, (Currency) unit),
                             new StringBuffer(),
                             fieldPosition));
 
         }
-        Number n = measure.getNumber();
-        MeasureUnit unit = measure.getUnit(); 
-        UFieldPosition fpos = new UFieldPosition(fieldPosition.getFieldAttribute(), fieldPosition.getField());
-        StringBuffer formattedNumber = nf.format(n, new StringBuffer(), fpos);
-        String keyword = rules.select(new PluralRules.FixedDecimal(n.doubleValue(), fpos.getCountVisibleFractionDigits(), fpos.getFractionDigits()));
-
-        int pluralForm = StandardPlural.indexOrOtherIndexFromString(keyword);
-        SimplePatternFormatter formatter = getPluralFormatter(unit, formatWidth, pluralForm);
-        int[] offsets = new int[1];
-        formatter.formatAndAppend(appendTo, offsets, formattedNumber);
-        if (offsets[0] != -1) { // there is a number (may not happen with, say, Arabic dual)
-            // Fix field position
-            if (fpos.getBeginIndex() != 0 || fpos.getEndIndex() != 0) {
-                fieldPosition.setBeginIndex(fpos.getBeginIndex() + offsets[0]);
-                fieldPosition.setEndIndex(fpos.getEndIndex() + offsets[0]);
-            }
-        }
-        return appendTo;
+        StringBuffer formattedNumber = new StringBuffer();
+        StandardPlural pluralForm = QuantityFormatter.selectPlural(
+                n, nf.nf, rules, formattedNumber, fieldPosition);
+        SimplePatternFormatter formatter = getPluralFormatter(unit, formatWidth, pluralForm.ordinal());
+        return QuantityFormatter.format(formatter, formattedNumber, appendTo, fieldPosition);
     }
-    
+
     /**
      * Instances contain all MeasureFormat specific data for a particular locale.
      * This data is cached. It is never copied, but is shared via shared pointers.
index 4b3349247b818c55e4b11f52cb53b78b6e3312e3..495ab5597c98369e913463cf03312fb055845393 100644 (file)
@@ -1954,18 +1954,6 @@ public class PluralRules implements Serializable {
         return rules.select(number);
     }
 
-    /**
-     * @internal
-     * @deprecated This API is ICU internal only.
-     */
-    @Deprecated
-    public String select(double number, NumberFormat numberFormat) {
-        if (numberFormat instanceof DecimalFormat) {
-            return select(((DecimalFormat) numberFormat).getFixedDecimal(number));
-        }
-        return select(number);
-    }
-
     /**
      * Given a number information, and keyword, return whether the keyword would match the number.
      *
index cd5ae87fb9dd7becee53f873ac4dcb2c5a9ace0a..99fd38480b04dab50a0ac3800e00b975351f6a63 100644 (file)
@@ -6,8 +6,11 @@
  */
 package com.ibm.icu.text;
 
+import java.text.FieldPosition;
+
 import com.ibm.icu.impl.SimplePatternFormatter;
 import com.ibm.icu.impl.StandardPlural;
+import com.ibm.icu.text.PluralRules.FixedDecimal;
 
 /**
  * QuantityFormatter represents an unknown quantity of something and formats a known quantity
@@ -49,19 +52,24 @@ class QuantityFormatter {
     }
 
     /**
-     * Format formats a quantity with this object.
-     * @param quantity the quantity to be formatted
-     * @param numberFormat used to actually format the quantity.
-     * @param pluralRules uses the quantity and the numberFormat to determine what plural
+     * Format formats a number with this object.
+     * @param number the number to be formatted
+     * @param numberFormat used to actually format the number.
+     * @param pluralRules uses the number and the numberFormat to determine what plural
      *  variant to use for fetching the formatting template.
      * @return the formatted string e.g '3 apples'
      */
-    public String format(double quantity, NumberFormat numberFormat, PluralRules pluralRules) {
-        String formatStr = numberFormat.format(quantity);
-        String variant = pluralRules.select(quantity, numberFormat);
-        return getByVariant(variant).format(formatStr);
+    public String format(double number, NumberFormat numberFormat, PluralRules pluralRules) {
+        String formatStr = numberFormat.format(number);
+        StandardPlural p = selectPlural(number, numberFormat, pluralRules);
+        SimplePatternFormatter formatter = templates[p.ordinal()];
+        if (formatter == null) {
+            formatter = templates[StandardPlural.OTHER_INDEX];
+            assert formatter != null;
+        }
+        return formatter.format(formatStr);
     }
-    
+
     /**
      * Gets the SimplePatternFormatter for a particular variant.
      * @param variant "zero", "one", "two", "few", "many", "other"
@@ -74,4 +82,57 @@ class QuantityFormatter {
         return (template == null && idx != StandardPlural.OTHER_INDEX) ?
                 templates[StandardPlural.OTHER_INDEX] : template;
     }
+
+    // The following methods live here so that class PluralRules does not depend on number formatting,
+    // and the SimplePatternFormatter does not depend on FieldPosition.
+
+    /**
+     * Selects the standard plural form for the number/formatter/rules.
+     */
+    public static StandardPlural selectPlural(double number, NumberFormat numberFormat, PluralRules rules) {
+        String pluralKeyword;
+        if (numberFormat instanceof DecimalFormat) {
+            pluralKeyword = rules.select(((DecimalFormat) numberFormat).getFixedDecimal(number));
+        } else {
+            pluralKeyword = rules.select(number);
+        }
+        return StandardPlural.orOtherFromString(pluralKeyword);
+    }
+
+    /**
+     * Selects the standard plural form for the number/formatter/rules.
+     */
+    public static StandardPlural selectPlural(
+            Number number, NumberFormat fmt, PluralRules rules,
+            StringBuffer formattedNumber, FieldPosition pos) {
+        UFieldPosition fpos = new UFieldPosition(pos.getFieldAttribute(), pos.getField());
+        fmt.format(number, formattedNumber, fpos);
+        // TODO: Long, BigDecimal & BigInteger may not fit into doubleValue().
+        FixedDecimal fd = new FixedDecimal(
+                number.doubleValue(),
+                fpos.getCountVisibleFractionDigits(), fpos.getFractionDigits());
+        String pluralKeyword = rules.select(fd);
+        pos.setBeginIndex(fpos.getBeginIndex());
+        pos.setEndIndex(fpos.getEndIndex());
+        return StandardPlural.orOtherFromString(pluralKeyword);
+    }
+
+    /**
+     * Formats the pattern with the value and adjusts the FieldPosition.
+     */
+    public static StringBuilder format(SimplePatternFormatter pattern, CharSequence value,
+            StringBuilder appendTo, FieldPosition pos) {
+        int[] offsets = new int[1];
+        pattern.formatAndAppend(appendTo, offsets, value);
+        if (pos.getBeginIndex() != 0 || pos.getEndIndex() != 0) {
+            if (offsets[0] >= 0) {
+                pos.setBeginIndex(pos.getBeginIndex() + offsets[0]);
+                pos.setEndIndex(pos.getEndIndex() + offsets[0]);
+            } else {
+                pos.setBeginIndex(0);
+                pos.setEndIndex(0);
+            }
+        }
+        return appendTo;
+    }
 }