Home | History | Annotate | Download | only in text
      1 /*
      2  *******************************************************************************
      3  * Copyright (C) 1996-2016, International Business Machines Corporation and    *
      4  * others. All Rights Reserved.                                                *
      5  *******************************************************************************
      6  */
      7 
      8 package com.ibm.icu.text;
      9 
     10 import java.io.IOException;
     11 import java.io.InvalidObjectException;
     12 import java.io.ObjectInputStream;
     13 import java.io.ObjectOutputStream;
     14 import java.math.BigInteger;
     15 import java.text.FieldPosition;
     16 import java.text.Format;
     17 import java.text.ParseException;
     18 import java.text.ParsePosition;
     19 import java.util.Collections;
     20 import java.util.Locale;
     21 import java.util.MissingResourceException;
     22 import java.util.Set;
     23 
     24 import com.ibm.icu.impl.ICUResourceBundle;
     25 import com.ibm.icu.util.Currency;
     26 import com.ibm.icu.util.Currency.CurrencyUsage;
     27 import com.ibm.icu.util.CurrencyAmount;
     28 import com.ibm.icu.util.ULocale;
     29 import com.ibm.icu.util.ULocale.Category;
     30 import com.ibm.icu.util.UResourceBundle;
     31 
     32 /**
     33  * {@icuenhanced java.text.NumberFormat}.{@icu _usage_}
     34  *
     35  * <code>NumberFormat</code> is the abstract base class for all number
     36  * formats. This class provides the interface for formatting and parsing
     37  * numbers. <code>NumberFormat</code> also provides methods for determining
     38  * which locales have number formats, and what their names are.
     39  *
     40  * <code>NumberFormat</code> helps you to format and parse numbers for any locale.
     41  * Your code can be completely independent of the locale conventions for
     42  * decimal points, thousands-separators, or even the particular decimal
     43  * digits used, or whether the number format is even decimal.
     44  *
     45  * <p>
     46  * To format a number for the current Locale, use one of the factory
     47  * class methods:
     48  * <blockquote>
     49  * <pre>
     50  *  myString = NumberFormat.getInstance().format(myNumber);
     51  * </pre>
     52  * </blockquote>
     53  * If you are formatting multiple numbers, it is
     54  * more efficient to get the format and use it multiple times so that
     55  * the system doesn't have to fetch the information about the local
     56  * language and country conventions multiple times.
     57  * <blockquote>
     58  * <pre>
     59  * NumberFormat nf = NumberFormat.getInstance();
     60  * for (int i = 0; i &lt; a.length; ++i) {
     61  *     output.println(nf.format(myNumber[i]) + "; ");
     62  * }
     63  * </pre>
     64  * </blockquote>
     65  * To format a number for a different Locale, specify it in the
     66  * call to <code>getInstance</code>.
     67  * <blockquote>
     68  * <pre>
     69  * NumberFormat nf = NumberFormat.getInstance(Locale.FRENCH);
     70  * </pre>
     71  * </blockquote>
     72  * You can also use a <code>NumberFormat</code> to parse numbers:
     73  * <blockquote>
     74  * <pre>
     75  * myNumber = nf.parse(myString);
     76  * </pre>
     77  * </blockquote>
     78  * Use <code>getInstance</code> or <code>getNumberInstance</code> to get the
     79  * normal number format. Use <code>getIntegerInstance</code> to get an
     80  * integer number format. Use <code>getCurrencyInstance</code> to get the
     81  * currency number format. And use <code>getPercentInstance</code> to get a
     82  * format for displaying percentages. Some factory methods are found within
     83  * subclasses of NumberFormat. With this format, a fraction like
     84  * 0.53 is displayed as 53%.
     85  *
     86  * <p>
     87  * Starting from ICU 4.2, you can use getInstance() by passing in a 'style'
     88  * as parameter to get the correct instance.
     89  * For example,
     90  * use getInstance(...NUMBERSTYLE) to get the normal number format,
     91  * getInstance(...PERCENTSTYLE) to get a format for displaying percentage,
     92  * getInstance(...SCIENTIFICSTYLE) to get a format for displaying scientific number,
     93  * getInstance(...INTEGERSTYLE) to get an integer number format,
     94  * getInstance(...CURRENCYSTYLE) to get the currency number format,
     95  * in which the currency is represented by its symbol, for example, "$3.00".
     96  * getInstance(...ISOCURRENCYSTYLE)  to get the currency number format,
     97  * in which the currency is represented by its ISO code, for example "USD3.00".
     98  * getInstance(...PLURALCURRENCYSTYLE) to get the currency number format,
     99  * in which the currency is represented by its full name in plural format,
    100  * for example, "3.00 US dollars" or "1.00 US dollar".
    101  *
    102  *
    103  * <p>
    104  * You can also control the display of numbers with such methods as
    105  * <code>setMinimumFractionDigits</code>.
    106  * If you want even more control over the format or parsing,
    107  * or want to give your users more control,
    108  * you can try casting the <code>NumberFormat</code> you get from the factory methods
    109  * to a <code>DecimalFormat</code>. This will work for the vast majority
    110  * of locales; just remember to put it in a <code>try</code> block in case you
    111  * encounter an unusual one.
    112  *
    113  * <p>
    114  * NumberFormat is designed such that some controls
    115  * work for formatting and others work for parsing.  The following is
    116  * the detailed description for each these control methods,
    117  * <p>
    118  * setParseIntegerOnly : only affects parsing, e.g.
    119  * if true,  "3456.78" -&gt; 3456 (and leaves the parse position just after '6')
    120  * if false, "3456.78" -&gt; 3456.78 (and leaves the parse position just after '8')
    121  * This is independent of formatting.  If you want to not show a decimal point
    122  * where there might be no digits after the decimal point, use
    123  * setDecimalSeparatorAlwaysShown on DecimalFormat.
    124  * <p>
    125  * You can also use forms of the <code>parse</code> and <code>format</code>
    126  * methods with <code>ParsePosition</code> and <code>FieldPosition</code> to
    127  * allow you to:
    128  * <ul>
    129  * <li> progressively parse through pieces of a string
    130  * <li> align the decimal point and other areas
    131  * </ul>
    132  * For example, you can align numbers in two ways:
    133  * <ol>
    134  * <li> If you are using a monospaced font with spacing for alignment,
    135  *      you can pass the <code>FieldPosition</code> in your format call, with
    136  *      <code>field</code> = <code>INTEGER_FIELD</code>. On output,
    137  *      <code>getEndIndex</code> will be set to the offset between the
    138  *      last character of the integer and the decimal. Add
    139  *      (desiredSpaceCount - getEndIndex) spaces at the front of the string.
    140  *
    141  * <li> If you are using proportional fonts,
    142  *      instead of padding with spaces, measure the width
    143  *      of the string in pixels from the start to <code>getEndIndex</code>.
    144  *      Then move the pen by
    145  *      (desiredPixelWidth - widthToAlignmentPoint) before drawing the text.
    146  *      It also works where there is no decimal, but possibly additional
    147  *      characters at the end, e.g., with parentheses in negative
    148  *      numbers: "(12)" for -12.
    149  * </ol>
    150  *
    151  * <h3>Synchronization</h3>
    152  * <p>
    153  * Number formats are generally not synchronized. It is recommended to create
    154  * separate format instances for each thread. If multiple threads access a format
    155  * concurrently, it must be synchronized externally.
    156  *
    157  * <h4>DecimalFormat</h4>
    158  * <p>DecimalFormat is the concrete implementation of NumberFormat, and the
    159  * NumberFormat API is essentially an abstraction from DecimalFormat's API.
    160  * Refer to DecimalFormat for more information about this API.</p>
    161  *
    162  * see          DecimalFormat
    163  * see          java.text.ChoiceFormat
    164  * @author       Mark Davis
    165  * @author       Helena Shih
    166  * @author       Alan Liu
    167  * @stable ICU 2.0
    168  */
    169 public abstract class NumberFormat extends UFormat {
    170 
    171     /**
    172      * {@icu} Constant to specify normal number style of format.
    173      * @stable ICU 4.2
    174      */
    175     public static final int NUMBERSTYLE = 0;
    176     /**
    177      * {@icu} Constant to specify general currency style of format. Defaults to
    178      * STANDARDCURRENCYSTYLE, using currency symbol, for example "$3.00", with
    179      * non-accounting style for negative values (e.g. minus sign).
    180      * The specific style may be specified using the -cf- locale key.
    181      * @stable ICU 4.2
    182      */
    183     public static final int CURRENCYSTYLE = 1;
    184     /**
    185      * {@icu} Constant to specify a style of format to display percent.
    186      * @stable ICU 4.2
    187      */
    188     public static final int PERCENTSTYLE = 2;
    189     /**
    190      * {@icu} Constant to specify a style of format to display scientific number.
    191      * @stable ICU 4.2
    192      */
    193     public static final int SCIENTIFICSTYLE = 3;
    194     /**
    195      * {@icu} Constant to specify a integer number style format.
    196      * @stable ICU 4.2
    197      */
    198     public static final int INTEGERSTYLE = 4;
    199     /**
    200      * {@icu} Constant to specify currency style of format which uses currency
    201      * ISO code to represent currency, for example: "USD3.00".
    202      * @stable ICU 4.2
    203      */
    204     public static final int ISOCURRENCYSTYLE = 5;
    205     /**
    206      * {@icu} Constant to specify currency style of format which uses currency
    207      * long name with plural format to represent currency, for example,
    208      * "3.00 US Dollars".
    209      * @stable ICU 4.2
    210      */
    211     public static final int PLURALCURRENCYSTYLE = 6;
    212     /**
    213      * {@icu} Constant to specify currency style of format which uses currency symbol
    214      * to represent currency for accounting, for example: "($3.00), instead of
    215      * "-$3.00" ({@link #CURRENCYSTYLE}).
    216      * Overrides any style specified using -cf- key in locale.
    217      * @stable ICU 53
    218      */
    219     public static final int ACCOUNTINGCURRENCYSTYLE = 7;
    220     /**
    221      * {@icu} Constant to specify currency cash style of format which uses currency
    222      * ISO code to represent currency, for example: "NT$3" instead of "NT$3.23".
    223      * @stable ICU 54
    224      */
    225     public static final int CASHCURRENCYSTYLE = 8;
    226     /**
    227      * {@icu} Constant to specify currency style of format which uses currency symbol
    228      * to represent currency, for example "$3.00", using non-accounting style for
    229      * negative values (e.g. minus sign).
    230      * Overrides any style specified using -cf- key in locale.
    231      * @draft ICU 56
    232      * @provisional This API might change or be removed in a future release.
    233      */
    234     public static final int STANDARDCURRENCYSTYLE = 9;
    235 
    236     /**
    237      * Field constant used to construct a FieldPosition object. Signifies that
    238      * the position of the integer part of a formatted number should be returned.
    239      * @see java.text.FieldPosition
    240      * @stable ICU 2.0
    241      */
    242     public static final int INTEGER_FIELD = 0;
    243 
    244     /**
    245      * Field constant used to construct a FieldPosition object. Signifies that
    246      * the position of the fraction part of a formatted number should be returned.
    247      * @see java.text.FieldPosition
    248      * @stable ICU 2.0
    249      */
    250     public static final int FRACTION_FIELD = 1;
    251 
    252     /**
    253      * Formats a number and appends the resulting text to the given string buffer.
    254      * {@icunote} recognizes <code>BigInteger</code>
    255      * and <code>BigDecimal</code> objects.
    256      * @see java.text.Format#format(Object, StringBuffer, FieldPosition)
    257      * @stable ICU 2.0
    258      */
    259     @Override
    260     public StringBuffer format(Object number,
    261                                StringBuffer toAppendTo,
    262                                FieldPosition pos) {
    263         if (number instanceof Long) {
    264             return format(((Long)number).longValue(), toAppendTo, pos);
    265         } else if (number instanceof BigInteger) {
    266             return format((BigInteger) number, toAppendTo, pos);
    267         } else if (number instanceof java.math.BigDecimal) {
    268             return format((java.math.BigDecimal) number, toAppendTo, pos);
    269         } else if (number instanceof com.ibm.icu.math.BigDecimal) {
    270             return format((com.ibm.icu.math.BigDecimal) number, toAppendTo, pos);
    271         } else if (number instanceof CurrencyAmount) {
    272             return format((CurrencyAmount)number, toAppendTo, pos);
    273         } else if (number instanceof Number) {
    274             return format(((Number)number).doubleValue(), toAppendTo, pos);
    275         } else {
    276             throw new IllegalArgumentException("Cannot format given Object as a Number");
    277         }
    278     }
    279 
    280     /**
    281      * Parses text from a string to produce a number.
    282      * @param source the String to parse
    283      * @param parsePosition the position at which to start the parse
    284      * @return the parsed number, or null
    285      * @see java.text.NumberFormat#parseObject(String, ParsePosition)
    286      * @stable ICU 2.0
    287      */
    288     @Override
    289     public final Object parseObject(String source,
    290                                     ParsePosition parsePosition) {
    291         return parse(source, parsePosition);
    292     }
    293 
    294     /**
    295      * Specialization of format.
    296      * @see java.text.Format#format(Object)
    297      * @stable ICU 2.0
    298      */
    299     public final String format(double number) {
    300         return format(number,new StringBuffer(),
    301                       new FieldPosition(0)).toString();
    302     }
    303 
    304     /**
    305      * Specialization of format.
    306      * @see java.text.Format#format(Object)
    307      * @stable ICU 2.0
    308      */
    309     public final String format(long number) {
    310         StringBuffer buf = new StringBuffer(19);
    311         FieldPosition pos = new FieldPosition(0);
    312         format(number, buf, pos);
    313         return buf.toString();
    314     }
    315 
    316     /**
    317      * {@icu} Convenience method to format a BigInteger.
    318      * @stable ICU 2.0
    319      */
    320     public final String format(BigInteger number) {
    321         return format(number, new StringBuffer(),
    322                       new FieldPosition(0)).toString();
    323     }
    324 
    325     /**
    326      * Convenience method to format a BigDecimal.
    327      * @stable ICU 2.0
    328      */
    329     public final String format(java.math.BigDecimal number) {
    330         return format(number, new StringBuffer(),
    331                       new FieldPosition(0)).toString();
    332     }
    333 
    334     /**
    335      * {@icu} Convenience method to format an ICU BigDecimal.
    336      * @stable ICU 2.0
    337      */
    338     public final String format(com.ibm.icu.math.BigDecimal number) {
    339         return format(number, new StringBuffer(),
    340                       new FieldPosition(0)).toString();
    341     }
    342 
    343     /**
    344      * {@icu} Convenience method to format a CurrencyAmount.
    345      * @stable ICU 3.0
    346      */
    347     public final String format(CurrencyAmount currAmt) {
    348         return format(currAmt, new StringBuffer(),
    349                       new FieldPosition(0)).toString();
    350     }
    351 
    352     /**
    353      * Specialization of format.
    354      * @see java.text.Format#format(Object, StringBuffer, FieldPosition)
    355      * @stable ICU 2.0
    356      */
    357     public abstract StringBuffer format(double number,
    358                                         StringBuffer toAppendTo,
    359                                         FieldPosition pos);
    360 
    361     /**
    362      * Specialization of format.
    363      * @see java.text.Format#format(Object, StringBuffer, FieldPosition)
    364      * @stable ICU 2.0
    365      */
    366     public abstract StringBuffer format(long number,
    367                                         StringBuffer toAppendTo,
    368                                         FieldPosition pos);
    369     /**
    370      * {@icu} Formats a BigInteger. Specialization of format.
    371      * @see java.text.Format#format(Object, StringBuffer, FieldPosition)
    372      * @stable ICU 2.0
    373      */
    374     public abstract StringBuffer format(BigInteger number,
    375                                         StringBuffer toAppendTo,
    376                                         FieldPosition pos);
    377     /**
    378      * {@icu} Formats a BigDecimal. Specialization of format.
    379      * @see java.text.Format#format(Object, StringBuffer, FieldPosition)
    380      * @stable ICU 2.0
    381      */
    382     public abstract StringBuffer format(java.math.BigDecimal number,
    383                                         StringBuffer toAppendTo,
    384                                         FieldPosition pos);
    385     /**
    386      * {@icu} Formats an ICU BigDecimal. Specialization of format.
    387      * @see java.text.Format#format(Object, StringBuffer, FieldPosition)
    388      * @stable ICU 2.0
    389      */
    390     public abstract StringBuffer format(com.ibm.icu.math.BigDecimal number,
    391                                         StringBuffer toAppendTo,
    392                                         FieldPosition pos);
    393     /**
    394      * {@icu} Formats a CurrencyAmount. Specialization of format.
    395      * @see java.text.Format#format(Object, StringBuffer, FieldPosition)
    396      * @stable ICU 3.0
    397      */
    398     public StringBuffer format(CurrencyAmount currAmt,
    399                                StringBuffer toAppendTo,
    400                                FieldPosition pos) {
    401         // Default implementation -- subclasses may override
    402         Currency save = getCurrency(), curr = currAmt.getCurrency();
    403         boolean same = curr.equals(save);
    404         if (!same) setCurrency(curr);
    405         format(currAmt.getNumber(), toAppendTo, pos);
    406         if (!same) setCurrency(save);
    407         return toAppendTo;
    408     }
    409 
    410     /**
    411      * Returns a Long if possible (e.g., within the range [Long.MIN_VALUE,
    412      * Long.MAX_VALUE] and with no decimals), otherwise a Double.
    413      * If IntegerOnly is set, will stop at a decimal
    414      * point (or equivalent; e.g., for rational numbers "1 2/3", will stop
    415      * after the 1).
    416      * Does not throw an exception; if no object can be parsed, index is
    417      * unchanged!
    418      * @see #isParseIntegerOnly
    419      * @see java.text.Format#parseObject(String, ParsePosition)
    420      * @stable ICU 2.0
    421      */
    422     public abstract Number parse(String text, ParsePosition parsePosition);
    423 
    424     /**
    425      * Parses text from the beginning of the given string to produce a number.
    426      * The method might not use the entire text of the given string.
    427      *
    428      * @param text A String whose beginning should be parsed.
    429      * @return A Number parsed from the string.
    430      * @throws ParseException if the beginning of the specified string
    431      * cannot be parsed.
    432      * @see #format
    433      * @stable ICU 2.0
    434      */
    435     //Bug 4375399 [Richard/GCL]
    436     public Number parse(String text) throws ParseException {
    437         ParsePosition parsePosition = new ParsePosition(0);
    438         Number result = parse(text, parsePosition);
    439         if (parsePosition.getIndex() == 0) {
    440             throw new ParseException("Unparseable number: \"" + text + '"',
    441                                      parsePosition.getErrorIndex());
    442         }
    443         return result;
    444     }
    445 
    446     /**
    447      * Parses text from the given string as a CurrencyAmount.  Unlike
    448      * the parse() method, this method will attempt to parse a generic
    449      * currency name, searching for a match of this object's locale's
    450      * currency display names, or for a 3-letter ISO currency code.
    451      * This method will fail if this format is not a currency format,
    452      * that is, if it does not contain the currency pattern symbol
    453      * (U+00A4) in its prefix or suffix.
    454      *
    455      * @param text the text to parse
    456      * @param pos input-output position; on input, the position within
    457      * text to match; must have 0 &lt;= pos.getIndex() &lt; text.length();
    458      * on output, the position after the last matched character. If
    459      * the parse fails, the position in unchanged upon output.
    460      * @return a CurrencyAmount, or null upon failure
    461      * @stable ICU 49
    462      */
    463     public CurrencyAmount parseCurrency(CharSequence text, ParsePosition pos) {
    464         ///CLOVER:OFF
    465         // Default implementation only -- subclasses should override
    466         Number n = parse(text.toString(), pos);
    467         return n == null ? null : new CurrencyAmount(n, getEffectiveCurrency());
    468         ///CLOVER:ON
    469     }
    470 
    471     /**
    472      * Returns true if this format will parse numbers as integers only.
    473      * For example in the English locale, with ParseIntegerOnly true, the
    474      * string "1234." would be parsed as the integer value 1234 and parsing
    475      * would stop at the "." character.  The decimal separator accepted
    476      * by the parse operation is locale-dependent and determined by the
    477      * subclass.
    478      * @return true if this will parse integers only
    479      * @stable ICU 2.0
    480      */
    481     public boolean isParseIntegerOnly() {
    482         return parseIntegerOnly;
    483     }
    484 
    485     /**
    486      * Sets whether or not numbers should be parsed as integers only.
    487      * @param value true if this should parse integers only
    488      * @see #isParseIntegerOnly
    489      * @stable ICU 2.0
    490      */
    491     public void setParseIntegerOnly(boolean value) {
    492         parseIntegerOnly = value;
    493     }
    494 
    495     /**
    496      * {@icu} Sets whether strict parsing is in effect.  When this is true, the
    497      * following conditions cause a parse failure (examples use the pattern "#,##0.#"):<ul>
    498      * <li>Leading or doubled grouping separators<br>
    499      * ',123' and '1,,234" fail</li>
    500      * <li>Groups of incorrect length when grouping is used<br>
    501      * '1,23' and '1234,567' fail, but '1234' passes</li>
    502      * <li>Grouping separators used in numbers followed by exponents<br>
    503      * '1,234E5' fails, but '1234E5' and '1,234E' pass ('E' is not an exponent when
    504      * not followed by a number)</li>
    505      * </ul>
    506      * When strict parsing is off,  all grouping separators are ignored.
    507      * This is the default behavior.
    508      * @param value True to enable strict parsing.  Default is false.
    509      * @see #isParseStrict
    510      * @stable ICU 3.6
    511      */
    512     public void setParseStrict(boolean value) {
    513         parseStrict = value;
    514     }
    515 
    516     /**
    517      * {@icu} Returns whether strict parsing is in effect.
    518      * @return true if strict parsing is in effect
    519      * @see #setParseStrict
    520      * @stable ICU 3.6
    521      */
    522     public boolean isParseStrict() {
    523         return parseStrict;
    524     }
    525 
    526     /**
    527      * {@icu} Set a particular DisplayContext value in the formatter,
    528      * such as CAPITALIZATION_FOR_STANDALONE.
    529      *
    530      * @param context The DisplayContext value to set.
    531      * @stable ICU 53
    532      */
    533     public void setContext(DisplayContext context) {
    534         if (context.type() == DisplayContext.Type.CAPITALIZATION) {
    535             capitalizationSetting = context;
    536         }
    537     }
    538 
    539     /**
    540      * {@icu} Get the formatter's DisplayContext value for the specified DisplayContext.Type,
    541      * such as CAPITALIZATION.
    542      *
    543      * @param type the DisplayContext.Type whose value to return
    544      * @return the current DisplayContext setting for the specified type
    545      * @stable ICU 53
    546      */
    547     public DisplayContext getContext(DisplayContext.Type type) {
    548         return (type == DisplayContext.Type.CAPITALIZATION && capitalizationSetting != null)?
    549                 capitalizationSetting: DisplayContext.CAPITALIZATION_NONE;
    550     }
    551 
    552     //============== Locale Stuff =====================
    553 
    554     /**
    555      * Returns the default number format for the current default <code>FORMAT</code> locale.
    556      * The default format is one of the styles provided by the other
    557      * factory methods: getNumberInstance, getIntegerInstance,
    558      * getCurrencyInstance or getPercentInstance.
    559      * Exactly which one is locale-dependent.
    560      * @see Category#FORMAT
    561      * @stable ICU 2.0
    562      */
    563     //Bug 4408066 [Richard/GCL]
    564     public final static NumberFormat getInstance() {
    565         return getInstance(ULocale.getDefault(Category.FORMAT), NUMBERSTYLE);
    566     }
    567 
    568     /**
    569      * Returns the default number format for the specified locale.
    570      * The default format is one of the styles provided by the other
    571      * factory methods: getNumberInstance, getCurrencyInstance or getPercentInstance.
    572      * Exactly which one is locale-dependent.
    573      * @stable ICU 2.0
    574      */
    575     public static NumberFormat getInstance(Locale inLocale) {
    576         return getInstance(ULocale.forLocale(inLocale), NUMBERSTYLE);
    577     }
    578 
    579     /**
    580      * {@icu} Returns the default number format for the specified locale.
    581      * The default format is one of the styles provided by the other
    582      * factory methods: getNumberInstance, getCurrencyInstance or getPercentInstance.
    583      * Exactly which one is locale-dependent.
    584      * @stable ICU 3.2
    585      */
    586     public static NumberFormat getInstance(ULocale inLocale) {
    587         return getInstance(inLocale, NUMBERSTYLE);
    588     }
    589 
    590     /**
    591      * {@icu} Returns a specific style number format for default <code>FORMAT</code> locale.
    592      * @param style  number format style
    593      * @see Category#FORMAT
    594      * @stable ICU 4.2
    595      */
    596     public final static NumberFormat getInstance(int style) {
    597         return getInstance(ULocale.getDefault(Category.FORMAT), style);
    598     }
    599 
    600     /**
    601      * {@icu} Returns a specific style number format for a specific locale.
    602      * @param inLocale  the specific locale.
    603      * @param style     number format style
    604      * @stable ICU 4.2
    605      */
    606     public static NumberFormat getInstance(Locale inLocale, int style) {
    607         return getInstance(ULocale.forLocale(inLocale), style);
    608     }
    609 
    610 
    611     /**
    612      * Returns a general-purpose number format for the current default <code>FORMAT</code> locale.
    613      * @see Category#FORMAT
    614      * @stable ICU 2.0
    615      */
    616     public final static NumberFormat getNumberInstance() {
    617         return getInstance(ULocale.getDefault(Category.FORMAT), NUMBERSTYLE);
    618     }
    619 
    620     /**
    621      * Returns a general-purpose number format for the specified locale.
    622      * @stable ICU 2.0
    623      */
    624     public static NumberFormat getNumberInstance(Locale inLocale) {
    625         return getInstance(ULocale.forLocale(inLocale), NUMBERSTYLE);
    626     }
    627 
    628     /**
    629      * {@icu} Returns a general-purpose number format for the specified locale.
    630      * @stable ICU 3.2
    631      */
    632     public static NumberFormat getNumberInstance(ULocale inLocale) {
    633         return getInstance(inLocale, NUMBERSTYLE);
    634     }
    635 
    636     /**
    637      * Returns an integer number format for the current default <code>FORMAT</code> locale. The
    638      * returned number format is configured to round floating point numbers
    639      * to the nearest integer using IEEE half-even rounding (see {@link
    640      * com.ibm.icu.math.BigDecimal#ROUND_HALF_EVEN ROUND_HALF_EVEN}) for formatting,
    641      * and to parse only the integer part of an input string (see {@link
    642      * #isParseIntegerOnly isParseIntegerOnly}).
    643      *
    644      * @return a number format for integer values
    645      * @see Category#FORMAT
    646      * @stable ICU 2.0
    647      */
    648     //Bug 4408066 [Richard/GCL]
    649     public final static NumberFormat getIntegerInstance() {
    650         return getInstance(ULocale.getDefault(Category.FORMAT), INTEGERSTYLE);
    651     }
    652 
    653     /**
    654      * Returns an integer number format for the specified locale. The
    655      * returned number format is configured to round floating point numbers
    656      * to the nearest integer using IEEE half-even rounding (see {@link
    657      * com.ibm.icu.math.BigDecimal#ROUND_HALF_EVEN ROUND_HALF_EVEN}) for formatting,
    658      * and to parse only the integer part of an input string (see {@link
    659      * #isParseIntegerOnly isParseIntegerOnly}).
    660      *
    661      * @param inLocale the locale for which a number format is needed
    662      * @return a number format for integer values
    663      * @stable ICU 2.0
    664      */
    665     //Bug 4408066 [Richard/GCL]
    666     public static NumberFormat getIntegerInstance(Locale inLocale) {
    667         return getInstance(ULocale.forLocale(inLocale), INTEGERSTYLE);
    668     }
    669 
    670     /**
    671      * {@icu} Returns an integer number format for the specified locale. The
    672      * returned number format is configured to round floating point numbers
    673      * to the nearest integer using IEEE half-even rounding (see {@link
    674      * com.ibm.icu.math.BigDecimal#ROUND_HALF_EVEN ROUND_HALF_EVEN}) for formatting,
    675      * and to parse only the integer part of an input string (see {@link
    676      * #isParseIntegerOnly isParseIntegerOnly}).
    677      *
    678      * @param inLocale the locale for which a number format is needed
    679      * @return a number format for integer values
    680      * @stable ICU 3.2
    681      */
    682     public static NumberFormat getIntegerInstance(ULocale inLocale) {
    683         return getInstance(inLocale, INTEGERSTYLE);
    684     }
    685 
    686     /**
    687      * Returns a currency format for the current default <code>FORMAT</code> locale.
    688      * @return a number format for currency
    689      * @see Category#FORMAT
    690      * @stable ICU 2.0
    691      */
    692     public final static NumberFormat getCurrencyInstance() {
    693         return getInstance(ULocale.getDefault(Category.FORMAT), CURRENCYSTYLE);
    694     }
    695 
    696     /**
    697      * Returns a currency format for the specified locale.
    698      * @return a number format for currency
    699      * @stable ICU 2.0
    700      */
    701     public static NumberFormat getCurrencyInstance(Locale inLocale) {
    702         return getInstance(ULocale.forLocale(inLocale), CURRENCYSTYLE);
    703     }
    704 
    705     /**
    706      * {@icu} Returns a currency format for the specified locale.
    707      * @return a number format for currency
    708      * @stable ICU 3.2
    709      */
    710     public static NumberFormat getCurrencyInstance(ULocale inLocale) {
    711         return getInstance(inLocale, CURRENCYSTYLE);
    712     }
    713 
    714     /**
    715      * Returns a percentage format for the current default <code>FORMAT</code> locale.
    716      * @return a number format for percents
    717      * @see Category#FORMAT
    718      * @stable ICU 2.0
    719      */
    720     public final static NumberFormat getPercentInstance() {
    721         return getInstance(ULocale.getDefault(Category.FORMAT), PERCENTSTYLE);
    722     }
    723 
    724     /**
    725      * Returns a percentage format for the specified locale.
    726      * @return a number format for percents
    727      * @stable ICU 2.0
    728      */
    729     public static NumberFormat getPercentInstance(Locale inLocale) {
    730         return getInstance(ULocale.forLocale(inLocale), PERCENTSTYLE);
    731     }
    732 
    733     /**
    734      * {@icu} Returns a percentage format for the specified locale.
    735      * @return a number format for percents
    736      * @stable ICU 3.2
    737      */
    738     public static NumberFormat getPercentInstance(ULocale inLocale) {
    739         return getInstance(inLocale, PERCENTSTYLE);
    740     }
    741 
    742     /**
    743      * {@icu} Returns a scientific format for the current default <code>FORMAT</code> locale.
    744      * @return a scientific number format
    745      * @see Category#FORMAT
    746      * @stable ICU 2.0
    747      */
    748     public final static NumberFormat getScientificInstance() {
    749         return getInstance(ULocale.getDefault(Category.FORMAT), SCIENTIFICSTYLE);
    750     }
    751 
    752     /**
    753      * {@icu} Returns a scientific format for the specified locale.
    754      * @return a scientific number format
    755      * @stable ICU 2.0
    756      */
    757     public static NumberFormat getScientificInstance(Locale inLocale) {
    758         return getInstance(ULocale.forLocale(inLocale), SCIENTIFICSTYLE);
    759     }
    760 
    761     /**
    762      * {@icu} Returns a scientific format for the specified locale.
    763      * @return a scientific number format
    764      * @stable ICU 3.2
    765      */
    766     public static NumberFormat getScientificInstance(ULocale inLocale) {
    767         return getInstance(inLocale, SCIENTIFICSTYLE);
    768     }
    769 
    770     // ===== Factory stuff =====
    771     /**
    772      * A NumberFormatFactory is used to register new number formats.  The factory
    773      * should be able to create any of the predefined formats for each locale it
    774      * supports.  When registered, the locales it supports extend or override the
    775      * locales already supported by ICU.
    776      *
    777      * <p><b>Note:</b> as of ICU4J 3.2, the default API for NumberFormatFactory uses
    778      * ULocale instead of Locale.  Instead of overriding createFormat(Locale, int),
    779      * new implementations should override createFactory(ULocale, int).  Note that
    780      * one of these two methods <b>MUST</b> be overridden or else an infinite
    781      * loop will occur.
    782      *
    783      * @stable ICU 2.6
    784      */
    785     public static abstract class NumberFormatFactory {
    786         /**
    787          * Value passed to format requesting a default number format.
    788          * @stable ICU 2.6
    789          */
    790         public static final int FORMAT_NUMBER = NUMBERSTYLE;
    791 
    792         /**
    793          * Value passed to format requesting a currency format.
    794          * @stable ICU 2.6
    795          */
    796         public static final int FORMAT_CURRENCY = CURRENCYSTYLE;
    797 
    798         /**
    799          * Value passed to format requesting a percent format.
    800          * @stable ICU 2.6
    801          */
    802         public static final int FORMAT_PERCENT = PERCENTSTYLE;
    803 
    804         /**
    805          * Value passed to format requesting a scientific format.
    806          * @stable ICU 2.6
    807          */
    808         public static final int FORMAT_SCIENTIFIC = SCIENTIFICSTYLE;
    809 
    810         /**
    811          * Value passed to format requesting an integer format.
    812          * @stable ICU 2.6
    813          */
    814         public static final int FORMAT_INTEGER = INTEGERSTYLE;
    815 
    816         /**
    817          * Returns true if this factory is visible.  Default is true.
    818          * If not visible, the locales supported by this factory will not
    819          * be listed by getAvailableLocales.  This value must not change.
    820          * @return true if the factory is visible.
    821          * @stable ICU 2.6
    822          */
    823         public boolean visible() {
    824             return true;
    825         }
    826 
    827         /**
    828          * Returns an immutable collection of the locale names directly
    829          * supported by this factory.
    830          * @return the supported locale names.
    831          * @stable ICU 2.6
    832          */
    833          public abstract Set<String> getSupportedLocaleNames();
    834 
    835         /**
    836          * Returns a number format of the appropriate type.  If the locale
    837          * is not supported, return null.  If the locale is supported, but
    838          * the type is not provided by this service, return null.  Otherwise
    839          * return an appropriate instance of NumberFormat.
    840          * <b>Note:</b> as of ICU4J 3.2, implementations should override
    841          * this method instead of createFormat(Locale, int).
    842          * @param loc the locale for which to create the format
    843          * @param formatType the type of format
    844          * @return the NumberFormat, or null.
    845          * @stable ICU 3.2
    846          */
    847         public NumberFormat createFormat(ULocale loc, int formatType) {
    848             return createFormat(loc.toLocale(), formatType);
    849         }
    850 
    851         /**
    852          * Returns a number format of the appropriate type.  If the locale
    853          * is not supported, return null.  If the locale is supported, but
    854          * the type is not provided by this service, return null.  Otherwise
    855          * return an appropriate instance of NumberFormat.
    856          * <b>Note:</b> as of ICU4J 3.2, createFormat(ULocale, int) should be
    857          * overridden instead of this method.  This method is no longer
    858          * abstract and delegates to that method.
    859          * @param loc the locale for which to create the format
    860          * @param formatType the type of format
    861          * @return the NumberFormat, or null.
    862          * @stable ICU 2.6
    863          */
    864         public NumberFormat createFormat(Locale loc, int formatType) {
    865             return createFormat(ULocale.forLocale(loc), formatType);
    866         }
    867 
    868         /**
    869          * @stable ICU 2.6
    870          */
    871         protected NumberFormatFactory() {
    872         }
    873     }
    874 
    875     /**
    876      * A NumberFormatFactory that supports a single locale.  It can be visible or invisible.
    877      * @stable ICU 2.6
    878      */
    879     public static abstract class SimpleNumberFormatFactory extends NumberFormatFactory {
    880         final Set<String> localeNames;
    881         final boolean visible;
    882 
    883         /**
    884          * Constructs a SimpleNumberFormatFactory with the given locale.
    885          * @stable ICU 2.6
    886          */
    887         public SimpleNumberFormatFactory(Locale locale) {
    888             this(locale, true);
    889         }
    890 
    891         /**
    892          * Constructs a SimpleNumberFormatFactory with the given locale and the
    893          * visibility.
    894          * @stable ICU 2.6
    895          */
    896         public SimpleNumberFormatFactory(Locale locale, boolean visible) {
    897             localeNames = Collections.singleton(ULocale.forLocale(locale).getBaseName());
    898             this.visible = visible;
    899         }
    900 
    901         /**
    902          * Constructs a SimpleNumberFormatFactory with the given locale.
    903          * @stable ICU 3.2
    904          */
    905         public SimpleNumberFormatFactory(ULocale locale) {
    906             this(locale, true);
    907         }
    908 
    909         /**
    910          * Constructs a SimpleNumberFormatFactory with the given locale and the
    911          * visibility.
    912          * @stable ICU 3.2
    913          */
    914         public SimpleNumberFormatFactory(ULocale locale, boolean visible) {
    915             localeNames = Collections.singleton(locale.getBaseName());
    916             this.visible = visible;
    917         }
    918 
    919         /**
    920          * {@inheritDoc}
    921          * @stable ICU 2.6
    922          */
    923         @Override
    924         public final boolean visible() {
    925             return visible;
    926         }
    927 
    928         /**
    929          * {@inheritDoc}
    930          * @stable ICU 2.6
    931          */
    932         @Override
    933         public final Set<String> getSupportedLocaleNames() {
    934             return localeNames;
    935         }
    936     }
    937 
    938     // shim so we can build without service code
    939     static abstract class NumberFormatShim {
    940         abstract Locale[] getAvailableLocales();
    941         abstract ULocale[] getAvailableULocales();
    942         abstract Object registerFactory(NumberFormatFactory f);
    943         abstract boolean unregister(Object k);
    944         abstract NumberFormat createInstance(ULocale l, int k);
    945     }
    946 
    947     private static NumberFormatShim shim;
    948     private static NumberFormatShim getShim() {
    949         // Note: this instantiation is safe on loose-memory-model configurations
    950         // despite lack of synchronization, since the shim instance has no state--
    951         // it's all in the class init.  The worst problem is we might instantiate
    952         // two shim instances, but they'll share the same state so that's ok.
    953         if (shim == null) {
    954             try {
    955                 Class<?> cls = Class.forName("com.ibm.icu.text.NumberFormatServiceShim");
    956                 shim = (NumberFormatShim)cls.newInstance();
    957             }
    958             ///CLOVER:OFF
    959             catch (MissingResourceException e){
    960                 throw e;
    961             }
    962             catch (Exception e) {
    963                // e.printStackTrace();
    964                 throw new RuntimeException(e.getMessage());
    965             }
    966             ///CLOVER:ON
    967         }
    968         return shim;
    969     }
    970 
    971     /**
    972      * Returns the list of Locales for which NumberFormats are available.
    973      * @return the available locales
    974      * @stable ICU 2.0
    975      */
    976     public static Locale[] getAvailableLocales() {
    977         if (shim == null) {
    978             return ICUResourceBundle.getAvailableLocales();
    979         }
    980         return getShim().getAvailableLocales();
    981     }
    982 
    983     /**
    984      * {@icu} Returns the list of Locales for which NumberFormats are available.
    985      * @return the available locales
    986      * @draft ICU 3.2 (retain)
    987      * @provisional This API might change or be removed in a future release.
    988      */
    989     public static ULocale[] getAvailableULocales() {
    990         if (shim == null) {
    991             return ICUResourceBundle.getAvailableULocales();
    992         }
    993         return getShim().getAvailableULocales();
    994     }
    995 
    996     /**
    997      * {@icu} Registers a new NumberFormatFactory.  The factory is adopted by
    998      * the service and must not be modified.  The returned object is a
    999      * key that can be used to unregister this factory.
   1000      *
   1001      * <p>Because ICU may choose to cache NumberFormat objects internally, this must
   1002      * be called at application startup, prior to any calls to
   1003      * NumberFormat.getInstance to avoid undefined behavior.
   1004      *
   1005      * @param factory the factory to register
   1006      * @return a key with which to unregister the factory
   1007      * @stable ICU 2.6
   1008      */
   1009     public static Object registerFactory(NumberFormatFactory factory) {
   1010         if (factory == null) {
   1011             throw new IllegalArgumentException("factory must not be null");
   1012         }
   1013         return getShim().registerFactory(factory);
   1014     }
   1015 
   1016     /**
   1017      * {@icu} Unregisters the factory or instance associated with this key (obtained from
   1018      * registerInstance or registerFactory).
   1019      * @param registryKey a key obtained from registerFactory
   1020      * @return true if the object was successfully unregistered
   1021      * @stable ICU 2.6
   1022      */
   1023     public static boolean unregister(Object registryKey) {
   1024         if (registryKey == null) {
   1025             throw new IllegalArgumentException("registryKey must not be null");
   1026         }
   1027 
   1028         if (shim == null) {
   1029             return false;
   1030         }
   1031 
   1032         return shim.unregister(registryKey);
   1033     }
   1034 
   1035     // ===== End of factory stuff =====
   1036 
   1037     /**
   1038      * Overrides hashCode.
   1039      * @stable ICU 2.0
   1040      */
   1041     @Override
   1042     public int hashCode() {
   1043         return maximumIntegerDigits * 37 + maxFractionDigits;
   1044         // just enough fields for a reasonable distribution
   1045     }
   1046 
   1047     /**
   1048      * Overrides equals.
   1049      * Two NumberFormats are equal if they are of the same class
   1050      * and the settings (groupingUsed, parseIntegerOnly, maximumIntegerDigits, etc.
   1051      * are equal.
   1052      * @param obj the object to compare against
   1053      * @return true if the object is equal to this.
   1054      * @stable ICU 2.0
   1055      */
   1056     @Override
   1057     public boolean equals(Object obj) {
   1058         if (obj == null) return false;
   1059         if (this == obj)
   1060             return true;
   1061         if (getClass() != obj.getClass())
   1062             return false;
   1063         NumberFormat other = (NumberFormat) obj;
   1064         return maximumIntegerDigits == other.maximumIntegerDigits
   1065             && minimumIntegerDigits == other.minimumIntegerDigits
   1066             && maximumFractionDigits == other.maximumFractionDigits
   1067             && minimumFractionDigits == other.minimumFractionDigits
   1068             && groupingUsed == other.groupingUsed
   1069             && parseIntegerOnly == other.parseIntegerOnly
   1070             && parseStrict == other.parseStrict
   1071             && capitalizationSetting == other.capitalizationSetting;
   1072     }
   1073 
   1074     /**
   1075      * Overrides clone.
   1076      * @stable ICU 2.0
   1077      */
   1078     @Override
   1079     public Object clone() {
   1080         NumberFormat other = (NumberFormat) super.clone();
   1081         return other;
   1082     }
   1083 
   1084     /**
   1085      * Returns true if grouping is used in this format. For example, in the
   1086      * en_US locale, with grouping on, the number 1234567 will be formatted
   1087      * as "1,234,567". The grouping separator as well as the size of each group
   1088      * is locale-dependent and is determined by subclasses of NumberFormat.
   1089      * Grouping affects both parsing and formatting.
   1090      * @return true if grouping is used
   1091      * @see #setGroupingUsed
   1092      * @stable ICU 2.0
   1093      */
   1094     public boolean isGroupingUsed() {
   1095         return groupingUsed;
   1096     }
   1097 
   1098     /**
   1099      * Sets whether or not grouping will be used in this format.  Grouping
   1100      * affects both parsing and formatting.
   1101      * @see #isGroupingUsed
   1102      * @param newValue true to use grouping.
   1103      * @stable ICU 2.0
   1104      */
   1105     public void setGroupingUsed(boolean newValue) {
   1106         groupingUsed = newValue;
   1107     }
   1108 
   1109     /**
   1110      * Returns the maximum number of digits allowed in the integer portion of a
   1111      * number.  The default value is 40, which subclasses can override.
   1112      * When formatting, the exact behavior when this value is exceeded is
   1113      * subclass-specific.  When parsing, this has no effect.
   1114      * @return the maximum number of integer digits
   1115      * @see #setMaximumIntegerDigits
   1116      * @stable ICU 2.0
   1117      */
   1118     public int getMaximumIntegerDigits() {
   1119         return maximumIntegerDigits;
   1120     }
   1121 
   1122     /**
   1123      * Sets the maximum number of digits allowed in the integer portion of a
   1124      * number. This must be &gt;= minimumIntegerDigits.  If the
   1125      * new value for maximumIntegerDigits is less than the current value
   1126      * of minimumIntegerDigits, then minimumIntegerDigits will also be set to
   1127      * the new value.
   1128      * @param newValue the maximum number of integer digits to be shown; if
   1129      * less than zero, then zero is used.  Subclasses might enforce an
   1130      * upper limit to this value appropriate to the numeric type being formatted.
   1131      * @see #getMaximumIntegerDigits
   1132      * @stable ICU 2.0
   1133      */
   1134     public void setMaximumIntegerDigits(int newValue) {
   1135         maximumIntegerDigits = Math.max(0,newValue);
   1136         if (minimumIntegerDigits > maximumIntegerDigits)
   1137             minimumIntegerDigits = maximumIntegerDigits;
   1138     }
   1139 
   1140     /**
   1141      * Returns the minimum number of digits allowed in the integer portion of a
   1142      * number.  The default value is 1, which subclasses can override.
   1143      * When formatting, if this value is not reached, numbers are padded on the
   1144      * left with the locale-specific '0' character to ensure at least this
   1145      * number of integer digits.  When parsing, this has no effect.
   1146      * @return the minimum number of integer digits
   1147      * @see #setMinimumIntegerDigits
   1148      * @stable ICU 2.0
   1149      */
   1150     public int getMinimumIntegerDigits() {
   1151         return minimumIntegerDigits;
   1152     }
   1153 
   1154     /**
   1155      * Sets the minimum number of digits allowed in the integer portion of a
   1156      * number.  This must be &lt;= maximumIntegerDigits.  If the
   1157      * new value for minimumIntegerDigits is more than the current value
   1158      * of maximumIntegerDigits, then maximumIntegerDigits will also be set to
   1159      * the new value.
   1160      * @param newValue the minimum number of integer digits to be shown; if
   1161      * less than zero, then zero is used. Subclasses might enforce an
   1162      * upper limit to this value appropriate to the numeric type being formatted.
   1163      * @see #getMinimumIntegerDigits
   1164      * @stable ICU 2.0
   1165      */
   1166     public void setMinimumIntegerDigits(int newValue) {
   1167         minimumIntegerDigits = Math.max(0,newValue);
   1168         if (minimumIntegerDigits > maximumIntegerDigits)
   1169             maximumIntegerDigits = minimumIntegerDigits;
   1170     }
   1171 
   1172     /**
   1173      * Returns the maximum number of digits allowed in the fraction
   1174      * portion of a number.  The default value is 3, which subclasses
   1175      * can override.  When formatting, the exact behavior when this
   1176      * value is exceeded is subclass-specific.  When parsing, this has
   1177      * no effect.
   1178      * @return the maximum number of fraction digits
   1179      * @see #setMaximumFractionDigits
   1180      * @stable ICU 2.0
   1181      */
   1182     public int getMaximumFractionDigits() {
   1183         return maximumFractionDigits;
   1184     }
   1185 
   1186     /**
   1187      * Sets the maximum number of digits allowed in the fraction portion of a
   1188      * number. This must be &gt;= minimumFractionDigits.  If the
   1189      * new value for maximumFractionDigits is less than the current value
   1190      * of minimumFractionDigits, then minimumFractionDigits will also be set to
   1191      * the new value.
   1192      * @param newValue the maximum number of fraction digits to be shown; if
   1193      * less than zero, then zero is used. The concrete subclass may enforce an
   1194      * upper limit to this value appropriate to the numeric type being formatted.
   1195      * @see #getMaximumFractionDigits
   1196      * @stable ICU 2.0
   1197      */
   1198     public void setMaximumFractionDigits(int newValue) {
   1199         maximumFractionDigits = Math.max(0,newValue);
   1200         if (maximumFractionDigits < minimumFractionDigits)
   1201             minimumFractionDigits = maximumFractionDigits;
   1202     }
   1203 
   1204     /**
   1205      * Returns the minimum number of digits allowed in the fraction portion of a
   1206      * number.  The default value is 0, which subclasses can override.
   1207      * When formatting, if this value is not reached, numbers are padded on
   1208      * the right with the locale-specific '0' character to ensure at least
   1209      * this number of fraction digits.  When parsing, this has no effect.
   1210      * @return the minimum number of fraction digits
   1211      * @see #setMinimumFractionDigits
   1212      * @stable ICU 2.0
   1213      */
   1214     public int getMinimumFractionDigits() {
   1215         return minimumFractionDigits;
   1216     }
   1217 
   1218     /**
   1219      * Sets the minimum number of digits allowed in the fraction portion of a
   1220      * number.  This must be &lt;= maximumFractionDigits.  If the
   1221      * new value for minimumFractionDigits exceeds the current value
   1222      * of maximumFractionDigits, then maximumFractionDigits will also be set to
   1223      * the new value.
   1224      * @param newValue the minimum number of fraction digits to be shown; if
   1225      * less than zero, then zero is used.  Subclasses might enforce an
   1226      * upper limit to this value appropriate to the numeric type being formatted.
   1227      * @see #getMinimumFractionDigits
   1228      * @stable ICU 2.0
   1229      */
   1230     public void setMinimumFractionDigits(int newValue) {
   1231         minimumFractionDigits = Math.max(0,newValue);
   1232         if (maximumFractionDigits < minimumFractionDigits)
   1233             maximumFractionDigits = minimumFractionDigits;
   1234     }
   1235 
   1236     /**
   1237      * Sets the <tt>Currency</tt> object used to display currency
   1238      * amounts.  This takes effect immediately, if this format is a
   1239      * currency format.  If this format is not a currency format, then
   1240      * the currency object is used if and when this object becomes a
   1241      * currency format.
   1242      * @param theCurrency new currency object to use.  May be null for
   1243      * some subclasses.
   1244      * @stable ICU 2.6
   1245      */
   1246     public void setCurrency(Currency theCurrency) {
   1247         currency = theCurrency;
   1248     }
   1249 
   1250     /**
   1251      * Returns the <tt>Currency</tt> object used to display currency
   1252      * amounts.  This may be null.
   1253      * @stable ICU 2.6
   1254      */
   1255     public Currency getCurrency() {
   1256         return currency;
   1257     }
   1258 
   1259     /**
   1260      * Returns the currency in effect for this formatter.  Subclasses
   1261      * should override this method as needed.  Unlike getCurrency(),
   1262      * this method should never return null.
   1263      * @return a non-null Currency
   1264      * @internal
   1265      * @deprecated This API is ICU internal only.
   1266      */
   1267     @Deprecated
   1268     protected Currency getEffectiveCurrency() {
   1269         Currency c = getCurrency();
   1270         if (c == null) {
   1271             ULocale uloc = getLocale(ULocale.VALID_LOCALE);
   1272             if (uloc == null) {
   1273                 uloc = ULocale.getDefault(Category.FORMAT);
   1274             }
   1275             c = Currency.getInstance(uloc);
   1276         }
   1277         return c;
   1278     }
   1279 
   1280     /**
   1281      * Returns the rounding mode used in this NumberFormat.  The default implementation of
   1282      * tis method in NumberFormat always throws <code>UnsupportedOperationException</code>.
   1283      * @return A rounding mode, between <code>BigDecimal.ROUND_UP</code>
   1284      * and <code>BigDecimal.ROUND_UNNECESSARY</code>.
   1285      * @see #setRoundingMode(int)
   1286      * @stable ICU 4.0
   1287      */
   1288     public int getRoundingMode() {
   1289         throw new UnsupportedOperationException(
   1290             "getRoundingMode must be implemented by the subclass implementation.");
   1291     }
   1292 
   1293     /**
   1294      * Set the rounding mode used in this NumberFormat.  The default implementation of
   1295      * tis method in NumberFormat always throws <code>UnsupportedOperationException</code>.
   1296      * @param roundingMode A rounding mode, between
   1297      * <code>BigDecimal.ROUND_UP</code> and
   1298      * <code>BigDecimal.ROUND_UNNECESSARY</code>.
   1299      * @see #getRoundingMode()
   1300      * @stable ICU 4.0
   1301      */
   1302     public void setRoundingMode(int roundingMode) {
   1303         throw new UnsupportedOperationException(
   1304             "setRoundingMode must be implemented by the subclass implementation.");
   1305     }
   1306 
   1307 
   1308     /**
   1309      * Returns a specific style number format for a specific locale.
   1310      * @param desiredLocale  the specific locale.
   1311      * @param choice         number format style
   1312      * @throws IllegalArgumentException  if choice is not one of
   1313      *                                   NUMBERSTYLE, CURRENCYSTYLE,
   1314      *                                   PERCENTSTYLE, SCIENTIFICSTYLE,
   1315      *                                   INTEGERSTYLE, ISOCURRENCYSTYLE,
   1316      *                                   PLURALCURRENCYSTYLE, ACCOUNTINGCURRENCYSTYLE.
   1317      *                                   CASHCURRENCYSTYLE, STANDARDCURRENCYSTYLE.
   1318      * @stable ICU 4.2
   1319      */
   1320     public static NumberFormat getInstance(ULocale desiredLocale, int choice) {
   1321         if (choice < NUMBERSTYLE || choice > STANDARDCURRENCYSTYLE) {
   1322             throw new IllegalArgumentException(
   1323                 "choice should be from NUMBERSTYLE to STANDARDCURRENCYSTYLE");
   1324         }
   1325 //          if (shim == null) {
   1326 //              return createInstance(desiredLocale, choice);
   1327 //          } else {
   1328 //              // TODO: shims must call setLocale() on object they create
   1329 //              return getShim().createInstance(desiredLocale, choice);
   1330 //          }
   1331         return getShim().createInstance(desiredLocale, choice);
   1332     }
   1333 
   1334     // =======================privates===============================
   1335     // Hook for service
   1336     static NumberFormat createInstance(ULocale desiredLocale, int choice) {
   1337         // If the choice is PLURALCURRENCYSTYLE, the pattern is not a single
   1338         // pattern, it is a pattern set, so we do not need to get them here.
   1339         // If the choice is ISOCURRENCYSTYLE, the pattern is the currrency
   1340         // pattern in the locale but by replacing the single currency sign
   1341         // with double currency sign.
   1342         String pattern = getPattern(desiredLocale, choice);
   1343         DecimalFormatSymbols symbols = new DecimalFormatSymbols(desiredLocale);
   1344 
   1345         // Here we assume that the locale passed in is in the canonical
   1346         // form, e.g: pt_PT_@currency=PTE not pt_PT_PREEURO
   1347         // This style wont work for currency plural format.
   1348         // For currency plural format, the pattern is get from
   1349         // the locale (from CurrencyUnitPatterns) without override.
   1350         if (choice == CURRENCYSTYLE || choice == ISOCURRENCYSTYLE || choice == ACCOUNTINGCURRENCYSTYLE
   1351                 || choice == CASHCURRENCYSTYLE || choice == STANDARDCURRENCYSTYLE) {
   1352             String temp = symbols.getCurrencyPattern();
   1353             if(temp!=null){
   1354                 pattern = temp;
   1355             }
   1356         }
   1357 
   1358         // replace single currency sign in the pattern with double currency sign
   1359         // if the choice is ISOCURRENCYSTYLE.
   1360         if (choice == ISOCURRENCYSTYLE) {
   1361             pattern = pattern.replace("\u00A4", doubleCurrencyStr);
   1362         }
   1363 
   1364         // Get the numbering system
   1365         NumberingSystem ns = NumberingSystem.getInstance(desiredLocale);
   1366         if ( ns == null ) {
   1367             return null;
   1368         }
   1369 
   1370         NumberFormat format;
   1371 
   1372         if ( ns != null && ns.isAlgorithmic()) {
   1373             String nsDesc;
   1374             String nsRuleSetGroup;
   1375             String nsRuleSetName;
   1376             ULocale nsLoc;
   1377             int desiredRulesType = RuleBasedNumberFormat.NUMBERING_SYSTEM;
   1378 
   1379             nsDesc = ns.getDescription();
   1380             int firstSlash = nsDesc.indexOf("/");
   1381             int lastSlash = nsDesc.lastIndexOf("/");
   1382 
   1383             if ( lastSlash > firstSlash ) {
   1384                String nsLocID = nsDesc.substring(0,firstSlash);
   1385                nsRuleSetGroup = nsDesc.substring(firstSlash+1,lastSlash);
   1386                nsRuleSetName = nsDesc.substring(lastSlash+1);
   1387 
   1388                nsLoc = new ULocale(nsLocID);
   1389                if ( nsRuleSetGroup.equals("SpelloutRules")) {
   1390                    desiredRulesType = RuleBasedNumberFormat.SPELLOUT;
   1391                }
   1392             } else {
   1393                 nsLoc = desiredLocale;
   1394                 nsRuleSetName = nsDesc;
   1395             }
   1396 
   1397             RuleBasedNumberFormat r = new RuleBasedNumberFormat(nsLoc,desiredRulesType);
   1398             r.setDefaultRuleSet(nsRuleSetName);
   1399             format = r;
   1400         } else {
   1401             DecimalFormat f = new DecimalFormat(pattern, symbols, choice);
   1402             // System.out.println("loc: " + desiredLocale + " choice: " + choice + " pat: " + pattern + " sym: " + symbols + " result: " + format);
   1403 
   1404             /*Bug 4408066
   1405              Add codes for the new method getIntegerInstance() [Richard/GCL]
   1406             */
   1407             // TODO: revisit this -- this is almost certainly not the way we want
   1408             // to do this.  aliu 1/6/2004
   1409             if (choice == INTEGERSTYLE) {
   1410                 f.setMaximumFractionDigits(0);
   1411                 f.setDecimalSeparatorAlwaysShown(false);
   1412                 f.setParseIntegerOnly(true);
   1413             }
   1414 
   1415             if (choice == CASHCURRENCYSTYLE) {
   1416                 f.setCurrencyUsage(CurrencyUsage.CASH);
   1417             }
   1418             format = f;
   1419        }
   1420         // TODO: the actual locale of the *pattern* may differ from that
   1421         // for the *symbols*.  For now, we use the data for the symbols.
   1422         // Revisit this.
   1423         ULocale valid = symbols.getLocale(ULocale.VALID_LOCALE);
   1424         ULocale actual = symbols.getLocale(ULocale.ACTUAL_LOCALE);
   1425         format.setLocale(valid, actual);
   1426 
   1427         return format;
   1428     }
   1429 
   1430     /**
   1431      * Returns the pattern for the provided locale and choice.
   1432      * @param forLocale the locale of the data.
   1433      * @param choice the pattern format.
   1434      * @return the pattern
   1435      * @deprecated ICU 3.4 subclassers should override getPattern(ULocale, int) instead of this method.
   1436      */
   1437     @Deprecated
   1438     protected static String getPattern(Locale forLocale, int choice) {
   1439         return getPattern(ULocale.forLocale(forLocale), choice);
   1440     }
   1441 
   1442     /**
   1443      * Returns the pattern for the provided locale and choice.
   1444      * @param forLocale the locale of the data.
   1445      * @param choice the pattern format.
   1446      * @return the pattern
   1447      * @stable ICU 3.2
   1448      */
   1449     protected static String getPattern(ULocale forLocale, int choice) {
   1450 
   1451         /* The following code takes care of a few cases where the
   1452          * resource data in the underlying JDK lags the new features
   1453          * we have added to ICU4J: scientific notation, rounding, and
   1454          * secondary grouping.
   1455          *
   1456          * We detect these cases here and return various hard-coded
   1457          * resource data.  This is the simplest solution for now, but
   1458          * it is not a good long-term mechanism.
   1459          *
   1460          * We should replace this code with a data-driven mechanism
   1461          * that reads the bundle com.ibm.icu.impl.data.LocaleElements
   1462          * and parses an exception table that overrides the standard
   1463          * data at java.text.resource.LocaleElements*.java.
   1464          * Alternatively, we should create our own copy of the
   1465          * resource data, and use that exclusively.
   1466          */
   1467 
   1468         // TEMPORARY, until we get scientific patterns into the main
   1469         // resources:  Retrieve scientific patterns from our resources.
   1470         //if (choice == SCIENTIFICSTYLE) {
   1471             // Temporarily hard code; retrieve from resource later
   1472             /*For ICU compatibility [Richard/GCL]*/
   1473         //    return "#E0";
   1474             // return NumberFormat.getBaseStringArray("NumberPatterns")[SCIENTIFICSTYLE];
   1475         //}
   1476 
   1477         /* {dlf}
   1478         // Try the cache first
   1479         String[] numberPatterns = (String[]) cachedLocaleData.get(forLocale);
   1480         if (numberPatterns == null) {
   1481             OverlayBundle resource = new OverlayBundle(new String[]
   1482                 { "com.ibm.icu.impl.data.LocaleElements", RESOURCE_BASE }, forLocale);
   1483             numberPatterns = resource.getStringArray("NumberPatterns");
   1484             // Update the cache
   1485             cachedLocaleData.put(forLocale, numberPatterns);
   1486         }
   1487         */
   1488 
   1489         /* for ISOCURRENCYSTYLE and PLURALCURRENCYSTYLE,
   1490          * the pattern is the same as the pattern of CURRENCYSTYLE
   1491          * but by replacing the single currency sign with
   1492          * double currency sign or triple currency sign.
   1493          */
   1494         String patternKey = null;
   1495         switch (choice) {
   1496         case NUMBERSTYLE:
   1497         case INTEGERSTYLE:
   1498             patternKey = "decimalFormat";
   1499             break;
   1500         case CURRENCYSTYLE:
   1501             String cfKeyValue = forLocale.getKeywordValue("cf");
   1502             patternKey = (cfKeyValue != null && cfKeyValue.equals("account"))? "accountingFormat": "currencyFormat";
   1503             break;
   1504         case CASHCURRENCYSTYLE:
   1505         case ISOCURRENCYSTYLE:
   1506         case PLURALCURRENCYSTYLE:
   1507         case STANDARDCURRENCYSTYLE:
   1508             patternKey = "currencyFormat";
   1509             break;
   1510         case PERCENTSTYLE:
   1511             patternKey = "percentFormat";
   1512             break;
   1513         case SCIENTIFICSTYLE:
   1514             patternKey = "scientificFormat";
   1515             break;
   1516         case ACCOUNTINGCURRENCYSTYLE:
   1517             patternKey = "accountingFormat";
   1518             break;
   1519         default:
   1520             assert false;
   1521             patternKey = "decimalFormat";
   1522             break;
   1523         }
   1524 
   1525         ICUResourceBundle rb = (ICUResourceBundle)UResourceBundle.
   1526         getBundleInstance(ICUResourceBundle.ICU_BASE_NAME, forLocale);
   1527         NumberingSystem ns = NumberingSystem.getInstance(forLocale);
   1528 
   1529         String result = null;
   1530         try {
   1531             result = rb.getStringWithFallback("NumberElements/" + ns.getName() + "/patterns/"+ patternKey);
   1532         } catch ( MissingResourceException ex ) {
   1533             result = rb.getStringWithFallback("NumberElements/latn/patterns/"+ patternKey);
   1534         }
   1535 
   1536         return result;
   1537     }
   1538 
   1539     /**
   1540      * First, read in the default serializable data.
   1541      *
   1542      * Then, if <code>serialVersionOnStream</code> is less than 1, indicating that
   1543      * the stream was written by JDK 1.1,
   1544      * set the <code>int</code> fields such as <code>maximumIntegerDigits</code>
   1545      * to be equal to the <code>byte</code> fields such as <code>maxIntegerDigits</code>,
   1546      * since the <code>int</code> fields were not present in JDK 1.1.
   1547      * Finally, set serialVersionOnStream back to the maximum allowed value so that
   1548      * default serialization will work properly if this object is streamed out again.
   1549      */
   1550     private void readObject(ObjectInputStream stream)
   1551          throws IOException, ClassNotFoundException
   1552     {
   1553         stream.defaultReadObject();
   1554         ///CLOVER:OFF
   1555         // we don't have serialization data for this format
   1556         if (serialVersionOnStream < 1) {
   1557             // Didn't have additional int fields, reassign to use them.
   1558             maximumIntegerDigits = maxIntegerDigits;
   1559             minimumIntegerDigits = minIntegerDigits;
   1560             maximumFractionDigits = maxFractionDigits;
   1561             minimumFractionDigits = minFractionDigits;
   1562         }
   1563         if (serialVersionOnStream < 2) {
   1564             // Didn't have capitalizationSetting, set it to default
   1565             capitalizationSetting = DisplayContext.CAPITALIZATION_NONE;
   1566         }
   1567         ///CLOVER:ON
   1568         /*Bug 4185761
   1569           Validate the min and max fields [Richard/GCL]
   1570         */
   1571         if (minimumIntegerDigits > maximumIntegerDigits ||
   1572             minimumFractionDigits > maximumFractionDigits ||
   1573             minimumIntegerDigits < 0 || minimumFractionDigits < 0) {
   1574             throw new InvalidObjectException("Digit count range invalid");
   1575         }
   1576         serialVersionOnStream = currentSerialVersion;
   1577     }
   1578 
   1579     /**
   1580      * Write out the default serializable data, after first setting
   1581      * the <code>byte</code> fields such as <code>maxIntegerDigits</code> to be
   1582      * equal to the <code>int</code> fields such as <code>maximumIntegerDigits</code>
   1583      * (or to <code>Byte.MAX_VALUE</code>, whichever is smaller), for compatibility
   1584      * with the JDK 1.1 version of the stream format.
   1585      */
   1586     private void writeObject(ObjectOutputStream stream)
   1587          throws IOException
   1588     {
   1589         maxIntegerDigits = (maximumIntegerDigits > Byte.MAX_VALUE) ? Byte.MAX_VALUE :
   1590             (byte)maximumIntegerDigits;
   1591         minIntegerDigits = (minimumIntegerDigits > Byte.MAX_VALUE) ? Byte.MAX_VALUE :
   1592             (byte)minimumIntegerDigits;
   1593         maxFractionDigits = (maximumFractionDigits > Byte.MAX_VALUE) ? Byte.MAX_VALUE :
   1594             (byte)maximumFractionDigits;
   1595         minFractionDigits = (minimumFractionDigits > Byte.MAX_VALUE) ? Byte.MAX_VALUE :
   1596             (byte)minimumFractionDigits;
   1597         stream.defaultWriteObject();
   1598     }
   1599 
   1600 // Unused -- Alan 2003-05
   1601 //    /**
   1602 //     * Cache to hold the NumberPatterns of a Locale.
   1603 //     */
   1604 //    private static final Hashtable cachedLocaleData = new Hashtable(3);
   1605 
   1606       private static final char[] doubleCurrencySign = {0xA4, 0xA4};
   1607       private static final String doubleCurrencyStr = new String(doubleCurrencySign);
   1608 
   1609     /*Bug 4408066
   1610       Add Field for the new method getIntegerInstance() [Richard/GCL]
   1611     */
   1612 
   1613 
   1614     /**
   1615      * True if the the grouping (i.e. thousands) separator is used when
   1616      * formatting and parsing numbers.
   1617      *
   1618      * @serial
   1619      * @see #isGroupingUsed
   1620      */
   1621     private boolean groupingUsed = true;
   1622 
   1623     /**
   1624      * The maximum number of digits allowed in the integer portion of a
   1625      * number.  <code>maxIntegerDigits</code> must be greater than or equal to
   1626      * <code>minIntegerDigits</code>.
   1627      * <p>
   1628      * <strong>Note:</strong> This field exists only for serialization
   1629      * compatibility with JDK 1.1.  In JDK 1.2 and higher, the new
   1630      * <code>int</code> field <code>maximumIntegerDigits</code> is used instead.
   1631      * When writing to a stream, <code>maxIntegerDigits</code> is set to
   1632      * <code>maximumIntegerDigits</code> or <code>Byte.MAX_VALUE</code>,
   1633      * whichever is smaller.  When reading from a stream, this field is used
   1634      * only if <code>serialVersionOnStream</code> is less than 1.
   1635      *
   1636      * @serial
   1637      * @see #getMaximumIntegerDigits
   1638      */
   1639     private byte    maxIntegerDigits = 40;
   1640 
   1641     /**
   1642      * The minimum number of digits allowed in the integer portion of a
   1643      * number.  <code>minimumIntegerDigits</code> must be less than or equal to
   1644      * <code>maximumIntegerDigits</code>.
   1645      * <p>
   1646      * <strong>Note:</strong> This field exists only for serialization
   1647      * compatibility with JDK 1.1.  In JDK 1.2 and higher, the new
   1648      * <code>int</code> field <code>minimumIntegerDigits</code> is used instead.
   1649      * When writing to a stream, <code>minIntegerDigits</code> is set to
   1650      * <code>minimumIntegerDigits</code> or <code>Byte.MAX_VALUE</code>,
   1651      * whichever is smaller.  When reading from a stream, this field is used
   1652      * only if <code>serialVersionOnStream</code> is less than 1.
   1653      *
   1654      * @serial
   1655      * @see #getMinimumIntegerDigits
   1656      */
   1657     private byte    minIntegerDigits = 1;
   1658 
   1659     /**
   1660      * The maximum number of digits allowed in the fractional portion of a
   1661      * number.  <code>maximumFractionDigits</code> must be greater than or equal to
   1662      * <code>minimumFractionDigits</code>.
   1663      * <p>
   1664      * <strong>Note:</strong> This field exists only for serialization
   1665      * compatibility with JDK 1.1.  In JDK 1.2 and higher, the new
   1666      * <code>int</code> field <code>maximumFractionDigits</code> is used instead.
   1667      * When writing to a stream, <code>maxFractionDigits</code> is set to
   1668      * <code>maximumFractionDigits</code> or <code>Byte.MAX_VALUE</code>,
   1669      * whichever is smaller.  When reading from a stream, this field is used
   1670      * only if <code>serialVersionOnStream</code> is less than 1.
   1671      *
   1672      * @serial
   1673      * @see #getMaximumFractionDigits
   1674      */
   1675     private byte    maxFractionDigits = 3;    // invariant, >= minFractionDigits
   1676 
   1677     /**
   1678      * The minimum number of digits allowed in the fractional portion of a
   1679      * number.  <code>minimumFractionDigits</code> must be less than or equal to
   1680      * <code>maximumFractionDigits</code>.
   1681      * <p>
   1682      * <strong>Note:</strong> This field exists only for serialization
   1683      * compatibility with JDK 1.1.  In JDK 1.2 and higher, the new
   1684      * <code>int</code> field <code>minimumFractionDigits</code> is used instead.
   1685      * When writing to a stream, <code>minFractionDigits</code> is set to
   1686      * <code>minimumFractionDigits</code> or <code>Byte.MAX_VALUE</code>,
   1687      * whichever is smaller.  When reading from a stream, this field is used
   1688      * only if <code>serialVersionOnStream</code> is less than 1.
   1689      *
   1690      * @serial
   1691      * @see #getMinimumFractionDigits
   1692      */
   1693     private byte    minFractionDigits = 0;
   1694 
   1695     /**
   1696      * True if this format will parse numbers as integers only.
   1697      *
   1698      * @serial
   1699      * @see #isParseIntegerOnly
   1700      */
   1701     private boolean parseIntegerOnly = false;
   1702 
   1703     // new fields for 1.2.  byte is too small for integer digits.
   1704 
   1705     /**
   1706      * The maximum number of digits allowed in the integer portion of a
   1707      * number.  <code>maximumIntegerDigits</code> must be greater than or equal to
   1708      * <code>minimumIntegerDigits</code>.
   1709      *
   1710      * @serial
   1711      * @see #getMaximumIntegerDigits
   1712      */
   1713     private int    maximumIntegerDigits = 40;
   1714 
   1715     /**
   1716      * The minimum number of digits allowed in the integer portion of a
   1717      * number.  <code>minimumIntegerDigits</code> must be less than or equal to
   1718      * <code>maximumIntegerDigits</code>.
   1719      *
   1720      * @serial
   1721      * @see #getMinimumIntegerDigits
   1722      */
   1723     private int    minimumIntegerDigits = 1;
   1724 
   1725     /**
   1726      * The maximum number of digits allowed in the fractional portion of a
   1727      * number.  <code>maximumFractionDigits</code> must be greater than or equal to
   1728      * <code>minimumFractionDigits</code>.
   1729      *
   1730      * @serial
   1731      * @see #getMaximumFractionDigits
   1732      */
   1733     private int    maximumFractionDigits = 3;    // invariant, >= minFractionDigits
   1734 
   1735     /**
   1736      * The minimum number of digits allowed in the fractional portion of a
   1737      * number.  <code>minimumFractionDigits</code> must be less than or equal to
   1738      * <code>maximumFractionDigits</code>.
   1739      *
   1740      * @serial
   1741      * @see #getMinimumFractionDigits
   1742      */
   1743     private int    minimumFractionDigits = 0;
   1744 
   1745     /**
   1746      * Currency object used to format currencies.  Subclasses may
   1747      * ignore this if they are not currency formats.  This will be
   1748      * null unless a subclass sets it to a non-null value.
   1749      * @since ICU 2.6
   1750      */
   1751     private Currency currency;
   1752 
   1753     static final int currentSerialVersion = 2;
   1754 
   1755     /**
   1756      * Describes the version of <code>NumberFormat</code> present on the stream.
   1757      * Possible values are:
   1758      * <ul>
   1759      * <li><b>0</b> (or uninitialized): the JDK 1.1 version of the stream format.
   1760      *     In this version, the <code>int</code> fields such as
   1761      *     <code>maximumIntegerDigits</code> were not present, and the <code>byte</code>
   1762      *     fields such as <code>maxIntegerDigits</code> are used instead.
   1763      *
   1764      * <li><b>1</b>: the JDK 1.2 version of the stream format.  The values of the
   1765      *     <code>byte</code> fields such as <code>maxIntegerDigits</code> are ignored,
   1766      *     and the <code>int</code> fields such as <code>maximumIntegerDigits</code>
   1767      *     are used instead.
   1768      *
   1769      * <li><b>2</b>: adds capitalizationSetting.
   1770      * </ul>
   1771      * When streaming out a <code>NumberFormat</code>, the most recent format
   1772      * (corresponding to the highest allowable <code>serialVersionOnStream</code>)
   1773      * is always written.
   1774      *
   1775      * @serial
   1776      */
   1777     private int serialVersionOnStream = currentSerialVersion;
   1778 
   1779     // Removed "implements Cloneable" clause.  Needs to update serialization
   1780     // ID for backward compatibility.
   1781     private static final long serialVersionUID = -2308460125733713944L;
   1782 
   1783     /**
   1784      * Empty constructor.  Public for API compatibility with historic versions of
   1785      * {@link java.text.NumberFormat} which had public constructor even though this is
   1786      * an abstract class.
   1787      * @stable ICU 2.6
   1788      */
   1789     public NumberFormat() {
   1790     }
   1791 
   1792     // new in ICU4J 3.6
   1793     private boolean parseStrict;
   1794 
   1795     /*
   1796      * Capitalization context setting, new in ICU 53
   1797      * @serial
   1798      */
   1799     private DisplayContext capitalizationSetting = DisplayContext.CAPITALIZATION_NONE;
   1800 
   1801     /**
   1802      * The instances of this inner class are used as attribute keys and values
   1803      * in AttributedCharacterIterator that
   1804      * NumberFormat.formatToCharacterIterator() method returns.
   1805      * <p>
   1806      * There is no public constructor to this class, the only instances are the
   1807      * constants defined here.
   1808      * <p>
   1809      * @stable ICU 3.6
   1810      */
   1811     public static class Field extends Format.Field {
   1812         // generated by serialver from JDK 1.4.1_01
   1813         static final long serialVersionUID = -4516273749929385842L;
   1814 
   1815         /**
   1816          * @stable ICU 3.6
   1817          */
   1818         public static final Field SIGN = new Field("sign");
   1819 
   1820         /**
   1821          * @stable ICU 3.6
   1822          */
   1823         public static final Field INTEGER = new Field("integer");
   1824 
   1825         /**
   1826          * @stable ICU 3.6
   1827          */
   1828         public static final Field FRACTION = new Field("fraction");
   1829 
   1830         /**
   1831          * @stable ICU 3.6
   1832          */
   1833         public static final Field EXPONENT = new Field("exponent");
   1834 
   1835         /**
   1836          * @stable ICU 3.6
   1837          */
   1838         public static final Field EXPONENT_SIGN = new Field("exponent sign");
   1839 
   1840         /**
   1841          * @stable ICU 3.6
   1842          */
   1843         public static final Field EXPONENT_SYMBOL = new Field("exponent symbol");
   1844 
   1845         /**
   1846          * @stable ICU 3.6
   1847          */
   1848         public static final Field DECIMAL_SEPARATOR = new Field("decimal separator");
   1849         /**
   1850          * @stable ICU 3.6
   1851          */
   1852         public static final Field GROUPING_SEPARATOR = new Field("grouping separator");
   1853 
   1854         /**
   1855          * @stable ICU 3.6
   1856          */
   1857         public static final Field PERCENT = new Field("percent");
   1858 
   1859         /**
   1860          * @stable ICU 3.6
   1861          */
   1862         public static final Field PERMILLE = new Field("per mille");
   1863 
   1864         /**
   1865          * @stable ICU 3.6
   1866          */
   1867         public static final Field CURRENCY = new Field("currency");
   1868 
   1869         /**
   1870          * Constructs a new instance of NumberFormat.Field with the given field
   1871          * name.
   1872          * @stable ICU 3.6
   1873          */
   1874         protected Field(String fieldName) {
   1875             super(fieldName);
   1876         }
   1877 
   1878         /**
   1879          * serizalization method resolve instances to the constant
   1880          * NumberFormat.Field values
   1881          * @stable ICU 3.6
   1882          */
   1883         @Override
   1884         protected Object readResolve() throws InvalidObjectException {
   1885             if (this.getName().equals(INTEGER.getName()))
   1886                 return INTEGER;
   1887             if (this.getName().equals(FRACTION.getName()))
   1888                 return FRACTION;
   1889             if (this.getName().equals(EXPONENT.getName()))
   1890                 return EXPONENT;
   1891             if (this.getName().equals(EXPONENT_SIGN.getName()))
   1892                 return EXPONENT_SIGN;
   1893             if (this.getName().equals(EXPONENT_SYMBOL.getName()))
   1894                 return EXPONENT_SYMBOL;
   1895             if (this.getName().equals(CURRENCY.getName()))
   1896                 return CURRENCY;
   1897             if (this.getName().equals(DECIMAL_SEPARATOR.getName()))
   1898                 return DECIMAL_SEPARATOR;
   1899             if (this.getName().equals(GROUPING_SEPARATOR.getName()))
   1900                 return GROUPING_SEPARATOR;
   1901             if (this.getName().equals(PERCENT.getName()))
   1902                 return PERCENT;
   1903             if (this.getName().equals(PERMILLE.getName()))
   1904                 return PERMILLE;
   1905             if (this.getName().equals(SIGN.getName()))
   1906                 return SIGN;
   1907 
   1908             throw new InvalidObjectException("An invalid object.");
   1909         }
   1910     }
   1911 }
   1912