JDK-8232633 : Plural support in CompactNumberFormat
  • Type: CSR
  • Component: core-libs
  • Sub-Component: java.util:i18n
  • Priority: P3
  • Status: Closed
  • Resolution: Approved
  • Fix Versions: 14
  • Submitted: 2019-10-18
  • Updated: 2019-12-05
  • Resolved: 2019-12-05
Related Reports
CSR :  
Description
Summary
-------

Support for plural compact format is required for some languages.

Problem
-------

There are multiple prefixes/suffixes for a single format in some languages. For example, ```1_000_000``` should be formatted as ```"1 Million"``` while ```2_000_000``` should be ```"2 Millionen"``` in German.

Solution
--------

Extend the existing compact number pattern syntax to accommodate multiple choices, each representing singular/plural forms.

Specification
-------------

Add the following paragraph in ```Compact Number Patterns``` section in ```java.text.CompactNumberFormat``` class description:

     * <h3>Plurals</h3>
     * <p>
     * In case some localization requires compact number patterns to be different for
     * plurals, each singular and plural patterns can be enumerated within a pair of
     * curly brackets <code>'{' (U+007B)</code> and <code>'}' (U+007D)</code>, separated
     * by a space {@code ' ' (U+0020)}. If this format is used, each pattern needs to be
     * prepended by its {@code count}, followed by a single colon {@code ':' (U+003A)}.
     * Should the pattern include spaces literally, they must be quoted.
     * <p>
     * For example, the compact number pattern representing millions in German locale can be
     * specified as {@code "{one:0' 'Million other:0' 'Millionen}"}. The {@code count}
     * follows LDML's
     * <a href="https://unicode.org/reports/tr35/tr35-numbers.html#Language_Plural_Rules">
     * Language Plural Rules</a>.

Modify first rule of the compact pattern syntax from:

     * <i>Pattern:</i>
     *         <i>PositivePattern</i>
     *         <i>PositivePattern</i> <i>[; NegativePattern]<sub>optional</sub></i>

to:

     * <i>Pattern:</i>
     *         <i>SimplePattern</i>
     *         '{' <i>PluralPattern</i> <i>[' ' PluralPattern]<sub>optional</sub></i> '}'
     * <i>SimplePattern:</i>
     *         <i>PositivePattern</i>
     *         <i>PositivePattern</i> <i>[; NegativePattern]<sub>optional</sub></i>
     * <i>PluralPattern:</i>
     *         <i>Count</i>:<i>SimplePattern</i>
     * <i>Count:</i>
     *         "zero" / "one" / "two" / "few" / "many" / "other"

And move this entire syntax diagram after the "Plurals" section.

Add the following new constructor that takes ```pluralRules``` in ```CompactNumberFormat``` class:

    /**
     * Creates a {@code CompactNumberFormat} using the given decimal pattern,
     * decimal format symbols, compact patterns, and plural rules.
     * To obtain the instance of {@code CompactNumberFormat} with the standard
     * compact patterns for a {@code Locale}, {@code Style}, and {@code pluralRules},
     * it is recommended to use the factory methods given by
     * {@code NumberFormat} for compact number formatting. For example,
     * {@link NumberFormat#getCompactNumberInstance(Locale, Style)}.
     *
     * @param decimalPattern a decimal pattern for general number formatting
     * @param symbols the set of symbols to be used
     * @param compactPatterns an array of
     *        <a href = "CompactNumberFormat.html#compact_number_patterns">
     *        compact number patterns</a>
     * @param pluralRules a String designating plural rules which associate
     *        the {@code Count} keyword, such as "{@code one}", and the
     *        actual integer number. Its syntax is defined in Unicode Consortium's
     *        <a href = "http://unicode.org/reports/tr35/tr35-numbers.html#Plural_rules_syntax">
     *        Plural rules syntax</a>
     * @throws NullPointerException if any of the given arguments is
     *        {@code null}
     * @throws IllegalArgumentException if the given {@code decimalPattern},
     *        the {@code compactPatterns} array contains an invalid pattern,
     *        a {@code null} appears in the array of compact patterns,
     *        or if the given {@code pluralRules} contains an invalid syntax
     * @see DecimalFormat#DecimalFormat(java.lang.String, DecimalFormatSymbols)
     * @see DecimalFormatSymbols
     * @since 14
     */
    public CompactNumberFormat(String decimalPattern,
            DecimalFormatSymbols symbols, String[] compactPatterns,
            String pluralRules)

Add the following serializable field in ```CompactNumberFormat``` class:

    /**
     * The {@code pluralRules} used in this compact number format.
     * {@code pluralRules} is a String designating plural rules which associate
     * the {@code Count} keyword, such as "{@code one}", and the
     * actual integer number. Its syntax is defined in Unicode Consortium's
     * <a href = "http://unicode.org/reports/tr35/tr35-numbers.html#Plural_rules_syntax">
     * Plural rules syntax</a>
     * The default value is an empty string, meaning there is no plural rules.
     *
     * @serial
     * @since 14
     */
    private String pluralRules = "";

Add the following sentence at the end of  ```java.text.CompactNumberFormat.readObject()``` method description:

    * If the {@code pluralRules} field is not deserialized from the stream, it
    * will be set to an empty string.

Change the implementation requirements in the method description of  ```java.text.spi.NumberFormatProvider#getCompactNumberInstance()``` from:

     * @implSpec The default implementation of this method throws
     * {@code UnsupportedOperationException}. Overriding the implementation
     * of this method returns the compact number formatter instance
     * of the given {@code locale} with specified {@code formatStyle}.
to:

     * @implSpec The default implementation of this method throws
     * {@link java.lang.UnsupportedOperationException
     * UnsupportedOperationException}. Overriding the implementation
     * of this method returns the compact number formatter instance
     * of the given {@code locale} with specified {@code formatStyle}.

Add the following ```@throws``` clause in  the method description of  ```java.text.spi.NumberFormatProvider#getCompactNumberInstance()```.

    * @throws UnsupportedOperationException if the implementation does not
    *      support this method


Comments
Re-approving amended request; thanks [~naoto].
05-12-2019

Joe, I had to make additional changes to the constructor description, where I clarified IllegalArgumentException for the pluralRules. Finalizing the CSR again.
04-12-2019

Moving to Approved.
04-12-2019

Thanks, Joe. Added a sentence in readObject() explaining it.
03-12-2019

Does readObject need to be updated for the new serializable field? Marking the request as pended until that is determined; please re-finalized when ready.
02-12-2019