]> granicus.if.org Git - icu/commitdiff
ICU-11276 Assorted Java NumberRangeFormatter API improvements.
authorShane Carr <shane@unicode.org>
Wed, 29 Aug 2018 05:36:09 +0000 (22:36 -0700)
committerShane Carr <shane@unicode.org>
Thu, 27 Sep 2018 21:27:39 +0000 (14:27 -0700)
icu4j/main/classes/core/src/com/ibm/icu/number/FormattedNumberRange.java
icu4j/main/classes/core/src/com/ibm/icu/number/LocalizedNumberRangeFormatter.java
icu4j/main/classes/core/src/com/ibm/icu/number/NumberRangeFormatter.java
icu4j/main/classes/core/src/com/ibm/icu/number/NumberRangeFormatterSettings.java
icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberRangeFormatterTest.java

index f3add3297eac601239c259a6d17ee32589700657..132420e154c562ed6975aea0a9c453b4cec41a94 100644 (file)
@@ -10,6 +10,7 @@ import java.util.Arrays;
 
 import com.ibm.icu.impl.number.DecimalQuantity;
 import com.ibm.icu.impl.number.NumberStringBuilder;
+import com.ibm.icu.number.NumberRangeFormatter.RangeIdentityType;
 import com.ibm.icu.util.ICUUncheckedIOException;
 
 /**
@@ -17,7 +18,7 @@ import com.ibm.icu.util.ICUUncheckedIOException;
  * including a String, an AttributedCharacterIterator, and a BigDecimal.
  *
  * @author sffc
- * @draft ICU 62
+ * @draft ICU 63
  * @provisional This API might change or be removed in a future release.
  * @see NumberRangeFormatter
  */
@@ -27,10 +28,6 @@ public class FormattedNumberRange {
     final DecimalQuantity second;
     final RangeIdentityType identityType;
 
-    public static enum RangeIdentityType {
-        EQUAL_BEFORE_ROUNDING, EQUAL_AFTER_ROUNDING, NOT_EQUAL
-    }
-
     FormattedNumberRange(NumberStringBuilder nsb, DecimalQuantity first, DecimalQuantity second,
             RangeIdentityType identityType) {
         this.nsb = nsb;
@@ -89,8 +86,8 @@ public class FormattedNumberRange {
      * multiple times, this method may be called repeatedly with the following pattern:
      *
      * <pre>
-     * FieldPosition fpos = new FieldPosition(NumberFormat.Field.GROUPING_SEPARATOR);
-     * while (formattedNumber.nextFieldPosition(fpos, status)) {
+     * FieldPosition fpos = new FieldPosition(NumberFormat.Field.INTEGER);
+     * while (formattedNumberRange.nextFieldPosition(fpos, status)) {
      *     // do something with fpos.
      * }
      * </pre>
@@ -162,7 +159,7 @@ public class FormattedNumberRange {
      * used. For example, if the first and second number were the same either before or after rounding occurred, an
      * identity fallback was used.
      *
-     * @return A IdentityType indicating the resulting identity situation in the formatted number range.
+     * @return A RangeIdentityType indicating the resulting identity situation in the formatted number range.
      * @draft ICU 63
      * @provisional This API might change or be removed in a future release.
      * @see NumberRangeFormatter
index 193706b3a962d30f5bfecf2d79bed8f546ae5da2..33aa65be7fe03b87d8dc9cf5c91ab8a4ac7b8c29 100644 (file)
@@ -6,7 +6,7 @@ import com.ibm.icu.impl.number.DecimalQuantity;
 import com.ibm.icu.impl.number.DecimalQuantity_DualStorageBCD;
 import com.ibm.icu.impl.number.NumberStringBuilder;
 import com.ibm.icu.impl.number.range.RangeMacroProps;
-import com.ibm.icu.number.FormattedNumberRange.RangeIdentityType;
+import com.ibm.icu.number.NumberRangeFormatter.RangeIdentityType;
 
 /**
  * A NumberRangeFormatter that has a locale associated with it; this means .formatRange() methods are available.
@@ -30,7 +30,7 @@ public class LocalizedNumberRangeFormatter extends NumberRangeFormatterSettings<
      *            The first number in the range, usually to the left in LTR locales.
      * @param second
      *            The second number in the range, usually to the right in LTR locales.
-     * @return A FormattedNumber object; call .toString() to get the string.
+     * @return A FormattedNumberRange object; call .toString() to get the string.
      * @draft ICU 63
      * @provisional This API might change or be removed in a future release.
      * @see NumberRangeFormatter
@@ -49,7 +49,7 @@ public class LocalizedNumberRangeFormatter extends NumberRangeFormatterSettings<
      *            The first number in the range, usually to the left in LTR locales.
      * @param second
      *            The second number in the range, usually to the right in LTR locales.
-     * @return A FormattedNumber object; call .toString() to get the string.
+     * @return A FormattedNumberRange object; call .toString() to get the string.
      * @draft ICU 63
      * @provisional This API might change or be removed in a future release.
      * @see NumberRangeFormatter
@@ -70,7 +70,7 @@ public class LocalizedNumberRangeFormatter extends NumberRangeFormatterSettings<
      *            The first number in the range, usually to the left in LTR locales.
      * @param second
      *            The second number in the range, usually to the right in LTR locales.
-     * @return A FormattedNumber object; call .toString() to get the string.
+     * @return A FormattedNumberRange object; call .toString() to get the string.
      * @draft ICU 63
      * @provisional This API might change or be removed in a future release.
      * @see NumberRangeFormatter
index a138a6d2daf7711fabe80ee584b087ead7470b44..437d1b86978c8167bffc509d4e5e5e28ec852de6 100644 (file)
@@ -8,6 +8,20 @@ import com.ibm.icu.util.ULocale;
 
 /**
  * The main entrypoint to the formatting of ranges of numbers, including currencies and other units of measurement.
+ * <p>
+ * Usage example:
+ * <p>
+ *
+ * <pre>
+ * NumberRangeFormatter.with().identityFallback(RangeIdentityFallback.APPROXIMATELY_OR_SINGLE_VALUE)
+ *         .numberFormatterFirst(NumberFormatter.with().unit(MeasureUnit.METER))
+ *         .numberFormatterSecond(NumberFormatter.with().unit(MeasureUnit.KILOMETER)).locale(ULocale.UK)
+ *         .formatRange(750, 1.2).toString();
+ * // => "750 m - 1.2 km"
+ * </pre>
+ * <p>
+ * Like NumberFormatter, NumberRangeFormatter instances are immutable and thread-safe. This API is based on the
+ * <em>fluent</em> design pattern popularized by libraries such as Google's Guava.
  *
  * @author sffc
  * @draft ICU 63
@@ -72,7 +86,7 @@ public abstract class NumberRangeFormatter {
      * @provisional This API might change or be removed in a future release.
      * @see NumberRangeFormatter
      */
-    public enum IdentityFallback {
+    public static enum RangeIdentityFallback {
         /**
          * Show the number as a single value rather than a range. Example: "$5"
          *
@@ -114,41 +128,64 @@ public abstract class NumberRangeFormatter {
     }
 
     /**
-     * Defines the behavior when the two numbers in the range are identical after rounding. To programmatically detect
-     * when the identity fallback is used, compare the lower and upper BigDecimals via FormattedNumber.
+     * Used in the result class FormattedNumberRange to indicate to the user whether the numbers formatted in the range
+     * were equal or not, and whether or not the identity fallback was applied.
+     *
+     * @draft ICU 63
+     * @provisional This API might change or be removed in a future release.
+     * @see NumberRangeFormatter
      */
-
-    public static enum RangeIdentityFallback {
-        /**
-         * Show the number as a single value rather than a range. Example: "$5"
-         */
-        SINGLE_VALUE,
-
+    public static enum RangeIdentityType {
         /**
-         * Show the number using a locale-sensitive approximation pattern. If the numbers were the same before rounding,
-         * show the single value. Example: "~$5" or "$5"
+         * Used to indicate that the two numbers in the range were equal, even before any rounding rules were applied.
+         *
+         * @draft ICU 63
+         * @provisional This API might change or be removed in a future release.
+         * @see NumberRangeFormatter
          */
-        APPROXIMATELY_OR_SINGLE_VALUE,
+        EQUAL_BEFORE_ROUNDING,
 
         /**
-         * Show the number using a locale-sensitive approximation pattern. Use the range pattern always, even if the
-         * inputs are the same. Example: "~$5"
+         * Used to indicate that the two numbers in the range were equal, but only after rounding rules were applied.
+         *
+         * @draft ICU 63
+         * @provisional This API might change or be removed in a future release.
+         * @see NumberRangeFormatter
          */
-        APPROXIMATELY,
+        EQUAL_AFTER_ROUNDING,
 
         /**
-         * Show the number as the range of two equal values. Use the range pattern always, even if the inputs are the
-         * same. Example (with RangeCollapse.NONE): "$5 – $5"
+         * Used to indicate that the two numbers in the range were not equal, even after rounding rules were applied.
+         *
+         * @draft ICU 63
+         * @provisional This API might change or be removed in a future release.
+         * @see NumberRangeFormatter
          */
-        RANGE
+        NOT_EQUAL
     }
 
     private static final UnlocalizedNumberRangeFormatter BASE = new UnlocalizedNumberRangeFormatter();
 
+    /**
+     * Call this method at the beginning of a NumberRangeFormatter fluent chain in which the locale is not currently
+     * known at the call site.
+     *
+     * @return An {@link UnlocalizedNumberRangeFormatter}, to be used for chaining.
+     * @draft ICU 63
+     */
     public static UnlocalizedNumberRangeFormatter with() {
         return BASE;
     }
 
+    /**
+     * Call this method at the beginning of a NumberRangeFormatter fluent chain in which the locale is known at the call
+     * site.
+     *
+     * @param locale
+     *            The locale from which to load formats and symbols for number range formatting.
+     * @return A {@link LocalizedNumberRangeFormatter}, to be used for chaining.
+     * @draft ICU 63
+     */
     public static LocalizedNumberRangeFormatter withLocale(Locale locale) {
         return BASE.locale(locale);
     }
index 7c9a70fb23bed553cdd3540f0ba78a5070c635ed..4971a9e6c1fe14b1ff1a3ef2e0ae17ef0186d088 100644 (file)
@@ -53,19 +53,35 @@ public abstract class NumberRangeFormatterSettings<T extends NumberRangeFormatte
      * @see NumberFormatter
      * @see NumberRangeFormatter
      */
-    public T numberFormatter(UnlocalizedNumberFormatter formatter) {
-        return numberFormatters(formatter, formatter);
+    public T numberFormatterBoth(UnlocalizedNumberFormatter formatter) {
+        return (T) numberFormatterFirst(formatter).numberFormatterSecond(formatter);
     }
 
     /**
-     * Sets the NumberFormatter instances to use for the numbers in the range. This method allows you to set a different
-     * formatter for the first and second numbers.
+     * Sets the NumberFormatter instance to use for the first number in the range.
      * <p>
-     * The NumberFormatter instances must not have a locale applied yet; the locale specified on the
+     * The NumberFormatter instance must not have a locale applied yet; the locale specified on the
      * NumberRangeFormatter will be used.
      *
      * @param formatterFirst
      *            The formatter to use for the first number in the range.
+     * @return The fluent chain.
+     * @draft ICU 63
+     * @provisional This API might change or be removed in a future release.
+     * @see NumberFormatter
+     * @see NumberRangeFormatter
+     */
+    public T numberFormatterFirst(UnlocalizedNumberFormatter formatterFirst) {
+        return create(KEY_FORMATTER_1, formatterFirst);
+    }
+
+    /**
+     * Sets the NumberFormatter instances to use for the numbers in the range. This method allows you to set a different
+     * formatter for the first and second numbers.
+     * <p>
+     * The NumberFormatter instance must not have a locale applied yet; the locale specified on the
+     * NumberRangeFormatter will be used.
+     *
      * @param formatterSecond
      *            The formatter to use for the second number in the range.
      * @return The fluent chain.
@@ -74,9 +90,8 @@ public abstract class NumberRangeFormatterSettings<T extends NumberRangeFormatte
      * @see NumberFormatter
      * @see NumberRangeFormatter
      */
-    public T numberFormatters(UnlocalizedNumberFormatter formatterFirst, UnlocalizedNumberFormatter formatterSecond) {
-        T intermediate = create(KEY_FORMATTER_1, formatterFirst);
-        return (T) intermediate.create(KEY_FORMATTER_2, formatterSecond);
+    public T numberFormatterSecond(UnlocalizedNumberFormatter formatterSecond) {
+        return create(KEY_FORMATTER_2, formatterSecond);
     }
 
     /**
@@ -113,7 +128,7 @@ public abstract class NumberRangeFormatterSettings<T extends NumberRangeFormatte
      * <li>APPROXIMATELY: "~5 miles"</li>
      * <li>RANGE: "5-5 miles" (with collapse=UNIT)</li>
      * <p>
-     * The default value is AUTO.
+     * The default value is APPROXIMATELY.
      *
      * @param identityFallback
      *            The strategy to use when formatting two numbers that end up being the same.
index c0cfce5c1f5f05aba0b716d656cc47e941571e80..1e150d3fe4c76bec72c087e559f11d98a569f405 100644 (file)
@@ -61,7 +61,7 @@ public class NumberRangeFormatterTest {
     public void testNullBehavior() {
         assertFormatRange(
                 "Basic",
-                NumberRangeFormatter.with().numberFormatter(null),
+                NumberRangeFormatter.with().numberFormatterBoth(null),
                 ULocale.US,
                 "1 --- 5",
                 "5 --- 5",
@@ -76,7 +76,7 @@ public class NumberRangeFormatterTest {
 
         assertFormatRange(
                 "Basic",
-                NumberRangeFormatter.with().numberFormatters(null, null),
+                NumberRangeFormatter.with().numberFormatterFirst(null),
                 ULocale.US,
                 "1 --- 5",
                 "5 --- 5",
@@ -91,10 +91,9 @@ public class NumberRangeFormatterTest {
 
         assertFormatRange(
                 "Basic",
-                NumberRangeFormatter.with().numberFormatters(
-                        NumberFormatter.with().grouping(GroupingStrategy.OFF),
-                        null
-                ),
+                NumberRangeFormatter.with()
+                    .numberFormatterFirst(NumberFormatter.with().grouping(GroupingStrategy.OFF))
+                    .numberFormatterSecond(null),
                 ULocale.US,
                 "1 --- 5",
                 "5 --- 5",
@@ -109,10 +108,9 @@ public class NumberRangeFormatterTest {
 
         assertFormatRange(
                 "Basic",
-                NumberRangeFormatter.with().numberFormatters(
-                        null,
-                        NumberFormatter.with().grouping(GroupingStrategy.OFF)
-                ),
+                NumberRangeFormatter.with()
+                    .numberFormatterFirst(null)
+                    .numberFormatterSecond(NumberFormatter.with().grouping(GroupingStrategy.OFF)),
                 ULocale.US,
                 "1 --- 5",
                 "5 --- 5",