rt/emul/compact/src/main/java/java/text/NumberFormat.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Fri, 04 Oct 2013 11:07:00 +0200
changeset 1339 8cc04f85a683
parent 1334 588d5bf7a560
permissions -rw-r--r--
Commenting out stuff in java.text so the classes compile
     1 /*
     2  * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Oracle in the LICENSE file that accompanied this code.
    10  *
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    14  * version 2 for more details (a copy is included in the LICENSE file that
    15  * accompanied this code).
    16  *
    17  * You should have received a copy of the GNU General Public License version
    18  * 2 along with this work; if not, write to the Free Software Foundation,
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    20  *
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    24  */
    25 
    26 /*
    27  * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
    28  * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
    29  *
    30  *   The original version of this source code and documentation is copyrighted
    31  * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
    32  * materials are provided under terms of a License Agreement between Taligent
    33  * and Sun. This technology is protected by multiple US and International
    34  * patents. This notice and attribution to Taligent may not be removed.
    35  *   Taligent is a registered trademark of Taligent, Inc.
    36  *
    37  */
    38 
    39 package java.text;
    40 
    41 import java.io.InvalidObjectException;
    42 import java.io.IOException;
    43 import java.io.ObjectInputStream;
    44 import java.io.ObjectOutputStream;
    45 import java.math.BigInteger;
    46 import java.math.RoundingMode;
    47 import java.util.Currency;
    48 import java.util.HashMap;
    49 import java.util.Hashtable;
    50 import java.util.Locale;
    51 import java.util.Map;
    52 import java.util.ResourceBundle;
    53 import java.util.concurrent.atomic.AtomicInteger;
    54 import java.util.concurrent.atomic.AtomicLong;
    55 
    56 /**
    57  * <code>NumberFormat</code> is the abstract base class for all number
    58  * formats. This class provides the interface for formatting and parsing
    59  * numbers. <code>NumberFormat</code> also provides methods for determining
    60  * which locales have number formats, and what their names are.
    61  *
    62  * <p>
    63  * <code>NumberFormat</code> helps you to format and parse numbers for any locale.
    64  * Your code can be completely independent of the locale conventions for
    65  * decimal points, thousands-separators, or even the particular decimal
    66  * digits used, or whether the number format is even decimal.
    67  *
    68  * <p>
    69  * To format a number for the current Locale, use one of the factory
    70  * class methods:
    71  * <blockquote>
    72  * <pre>
    73  *  myString = NumberFormat.getInstance().format(myNumber);
    74  * </pre>
    75  * </blockquote>
    76  * If you are formatting multiple numbers, it is
    77  * more efficient to get the format and use it multiple times so that
    78  * the system doesn't have to fetch the information about the local
    79  * language and country conventions multiple times.
    80  * <blockquote>
    81  * <pre>
    82  * NumberFormat nf = NumberFormat.getInstance();
    83  * for (int i = 0; i < myNumber.length; ++i) {
    84  *     output.println(nf.format(myNumber[i]) + "; ");
    85  * }
    86  * </pre>
    87  * </blockquote>
    88  * To format a number for a different Locale, specify it in the
    89  * call to <code>getInstance</code>.
    90  * <blockquote>
    91  * <pre>
    92  * NumberFormat nf = NumberFormat.getInstance(Locale.FRENCH);
    93  * </pre>
    94  * </blockquote>
    95  * You can also use a <code>NumberFormat</code> to parse numbers:
    96  * <blockquote>
    97  * <pre>
    98  * myNumber = nf.parse(myString);
    99  * </pre>
   100  * </blockquote>
   101  * Use <code>getInstance</code> or <code>getNumberInstance</code> to get the
   102  * normal number format. Use <code>getIntegerInstance</code> to get an
   103  * integer number format. Use <code>getCurrencyInstance</code> to get the
   104  * currency number format. And use <code>getPercentInstance</code> to get a
   105  * format for displaying percentages. With this format, a fraction like
   106  * 0.53 is displayed as 53%.
   107  *
   108  * <p>
   109  * You can also control the display of numbers with such methods as
   110  * <code>setMinimumFractionDigits</code>.
   111  * If you want even more control over the format or parsing,
   112  * or want to give your users more control,
   113  * you can try casting the <code>NumberFormat</code> you get from the factory methods
   114  * to a <code>DecimalFormat</code>. This will work for the vast majority
   115  * of locales; just remember to put it in a <code>try</code> block in case you
   116  * encounter an unusual one.
   117  *
   118  * <p>
   119  * NumberFormat and DecimalFormat are designed such that some controls
   120  * work for formatting and others work for parsing.  The following is
   121  * the detailed description for each these control methods,
   122  * <p>
   123  * setParseIntegerOnly : only affects parsing, e.g.
   124  * if true,  "3456.78" -> 3456 (and leaves the parse position just after index 6)
   125  * if false, "3456.78" -> 3456.78 (and leaves the parse position just after index 8)
   126  * This is independent of formatting.  If you want to not show a decimal point
   127  * where there might be no digits after the decimal point, use
   128  * setDecimalSeparatorAlwaysShown.
   129  * <p>
   130  * setDecimalSeparatorAlwaysShown : only affects formatting, and only where
   131  * there might be no digits after the decimal point, such as with a pattern
   132  * like "#,##0.##", e.g.,
   133  * if true,  3456.00 -> "3,456."
   134  * if false, 3456.00 -> "3456"
   135  * This is independent of parsing.  If you want parsing to stop at the decimal
   136  * point, use setParseIntegerOnly.
   137  *
   138  * <p>
   139  * You can also use forms of the <code>parse</code> and <code>format</code>
   140  * methods with <code>ParsePosition</code> and <code>FieldPosition</code> to
   141  * allow you to:
   142  * <ul>
   143  * <li> progressively parse through pieces of a string
   144  * <li> align the decimal point and other areas
   145  * </ul>
   146  * For example, you can align numbers in two ways:
   147  * <ol>
   148  * <li> If you are using a monospaced font with spacing for alignment,
   149  *      you can pass the <code>FieldPosition</code> in your format call, with
   150  *      <code>field</code> = <code>INTEGER_FIELD</code>. On output,
   151  *      <code>getEndIndex</code> will be set to the offset between the
   152  *      last character of the integer and the decimal. Add
   153  *      (desiredSpaceCount - getEndIndex) spaces at the front of the string.
   154  *
   155  * <li> If you are using proportional fonts,
   156  *      instead of padding with spaces, measure the width
   157  *      of the string in pixels from the start to <code>getEndIndex</code>.
   158  *      Then move the pen by
   159  *      (desiredPixelWidth - widthToAlignmentPoint) before drawing the text.
   160  *      It also works where there is no decimal, but possibly additional
   161  *      characters at the end, e.g., with parentheses in negative
   162  *      numbers: "(12)" for -12.
   163  * </ol>
   164  *
   165  * <h4><a name="synchronization">Synchronization</a></h4>
   166  *
   167  * <p>
   168  * Number formats are generally not synchronized.
   169  * It is recommended to create separate format instances for each thread.
   170  * If multiple threads access a format concurrently, it must be synchronized
   171  * externally.
   172  *
   173  * @see          DecimalFormat
   174  * @see          ChoiceFormat
   175  * @author       Mark Davis
   176  * @author       Helena Shih
   177  */
   178 public abstract class NumberFormat extends Format  {
   179 
   180     /**
   181      * Field constant used to construct a FieldPosition object. Signifies that
   182      * the position of the integer part of a formatted number should be returned.
   183      * @see java.text.FieldPosition
   184      */
   185     public static final int INTEGER_FIELD = 0;
   186 
   187     /**
   188      * Field constant used to construct a FieldPosition object. Signifies that
   189      * the position of the fraction part of a formatted number should be returned.
   190      * @see java.text.FieldPosition
   191      */
   192     public static final int FRACTION_FIELD = 1;
   193 
   194     /**
   195      * Sole constructor.  (For invocation by subclass constructors, typically
   196      * implicit.)
   197      */
   198     protected NumberFormat() {
   199     }
   200 
   201     /**
   202      * Formats a number and appends the resulting text to the given string
   203      * buffer.
   204      * The number can be of any subclass of {@link java.lang.Number}.
   205      * <p>
   206      * This implementation extracts the number's value using
   207      * {@link java.lang.Number#longValue()} for all integral type values that
   208      * can be converted to <code>long</code> without loss of information,
   209      * including <code>BigInteger</code> values with a
   210      * {@link java.math.BigInteger#bitLength() bit length} of less than 64,
   211      * and {@link java.lang.Number#doubleValue()} for all other types. It
   212      * then calls
   213      * {@link #format(long,java.lang.StringBuffer,java.text.FieldPosition)}
   214      * or {@link #format(double,java.lang.StringBuffer,java.text.FieldPosition)}.
   215      * This may result in loss of magnitude information and precision for
   216      * <code>BigInteger</code> and <code>BigDecimal</code> values.
   217      * @param number     the number to format
   218      * @param toAppendTo the <code>StringBuffer</code> to which the formatted
   219      *                   text is to be appended
   220      * @param pos        On input: an alignment field, if desired.
   221      *                   On output: the offsets of the alignment field.
   222      * @return           the value passed in as <code>toAppendTo</code>
   223      * @exception        IllegalArgumentException if <code>number</code> is
   224      *                   null or not an instance of <code>Number</code>.
   225      * @exception        NullPointerException if <code>toAppendTo</code> or
   226      *                   <code>pos</code> is null
   227      * @exception        ArithmeticException if rounding is needed with rounding
   228      *                   mode being set to RoundingMode.UNNECESSARY
   229      * @see              java.text.FieldPosition
   230      */
   231     public StringBuffer format(Object number,
   232                                StringBuffer toAppendTo,
   233                                FieldPosition pos) {
   234         if (number instanceof Long || number instanceof Integer ||
   235             number instanceof Short || number instanceof Byte ||
   236             number instanceof AtomicInteger || number instanceof AtomicLong ||
   237             (number instanceof BigInteger &&
   238              ((BigInteger)number).bitLength() < 64)) {
   239             return format(((Number)number).longValue(), toAppendTo, pos);
   240         } else if (number instanceof Number) {
   241             return format(((Number)number).doubleValue(), toAppendTo, pos);
   242         } else {
   243             throw new IllegalArgumentException("Cannot format given Object as a Number");
   244         }
   245     }
   246 
   247     /**
   248      * Parses text from a string to produce a <code>Number</code>.
   249      * <p>
   250      * The method attempts to parse text starting at the index given by
   251      * <code>pos</code>.
   252      * If parsing succeeds, then the index of <code>pos</code> is updated
   253      * to the index after the last character used (parsing does not necessarily
   254      * use all characters up to the end of the string), and the parsed
   255      * number is returned. The updated <code>pos</code> can be used to
   256      * indicate the starting point for the next call to this method.
   257      * If an error occurs, then the index of <code>pos</code> is not
   258      * changed, the error index of <code>pos</code> is set to the index of
   259      * the character where the error occurred, and null is returned.
   260      * <p>
   261      * See the {@link #parse(String, ParsePosition)} method for more information
   262      * on number parsing.
   263      *
   264      * @param source A <code>String</code>, part of which should be parsed.
   265      * @param pos A <code>ParsePosition</code> object with index and error
   266      *            index information as described above.
   267      * @return A <code>Number</code> parsed from the string. In case of
   268      *         error, returns null.
   269      * @exception NullPointerException if <code>pos</code> is null.
   270      */
   271     public final Object parseObject(String source, ParsePosition pos) {
   272         return parse(source, pos);
   273     }
   274 
   275    /**
   276      * Specialization of format.
   277      * @exception        ArithmeticException if rounding is needed with rounding
   278      *                   mode being set to RoundingMode.UNNECESSARY
   279      * @see java.text.Format#format
   280      */
   281     public final String format(double number) {
   282         return format(number, new StringBuffer(),
   283                       DontCareFieldPosition.INSTANCE).toString();
   284     }
   285 
   286    /**
   287      * Specialization of format.
   288      * @exception        ArithmeticException if rounding is needed with rounding
   289      *                   mode being set to RoundingMode.UNNECESSARY
   290      * @see java.text.Format#format
   291      */
   292     public final String format(long number) {
   293         return format(number, new StringBuffer(),
   294                       DontCareFieldPosition.INSTANCE).toString();
   295     }
   296 
   297    /**
   298      * Specialization of format.
   299      * @exception        ArithmeticException if rounding is needed with rounding
   300      *                   mode being set to RoundingMode.UNNECESSARY
   301      * @see java.text.Format#format
   302      */
   303     public abstract StringBuffer format(double number,
   304                                         StringBuffer toAppendTo,
   305                                         FieldPosition pos);
   306 
   307    /**
   308      * Specialization of format.
   309      * @exception        ArithmeticException if rounding is needed with rounding
   310      *                   mode being set to RoundingMode.UNNECESSARY
   311      * @see java.text.Format#format
   312      */
   313     public abstract StringBuffer format(long number,
   314                                         StringBuffer toAppendTo,
   315                                         FieldPosition pos);
   316 
   317    /**
   318      * Returns a Long if possible (e.g., within the range [Long.MIN_VALUE,
   319      * Long.MAX_VALUE] and with no decimals), otherwise a Double.
   320      * If IntegerOnly is set, will stop at a decimal
   321      * point (or equivalent; e.g., for rational numbers "1 2/3", will stop
   322      * after the 1).
   323      * Does not throw an exception; if no object can be parsed, index is
   324      * unchanged!
   325      * @see java.text.NumberFormat#isParseIntegerOnly
   326      * @see java.text.Format#parseObject
   327      */
   328     public abstract Number parse(String source, ParsePosition parsePosition);
   329 
   330     /**
   331      * Parses text from the beginning of the given string to produce a number.
   332      * The method may not use the entire text of the given string.
   333      * <p>
   334      * See the {@link #parse(String, ParsePosition)} method for more information
   335      * on number parsing.
   336      *
   337      * @param source A <code>String</code> whose beginning should be parsed.
   338      * @return A <code>Number</code> parsed from the string.
   339      * @exception ParseException if the beginning of the specified string
   340      *            cannot be parsed.
   341      */
   342     public Number parse(String source) throws ParseException {
   343         ParsePosition parsePosition = new ParsePosition(0);
   344         Number result = parse(source, parsePosition);
   345         if (parsePosition.index == 0) {
   346             throw new ParseException("Unparseable number: \"" + source + "\"",
   347                                      parsePosition.errorIndex);
   348         }
   349         return result;
   350     }
   351 
   352     /**
   353      * Returns true if this format will parse numbers as integers only.
   354      * For example in the English locale, with ParseIntegerOnly true, the
   355      * string "1234." would be parsed as the integer value 1234 and parsing
   356      * would stop at the "." character.  Of course, the exact format accepted
   357      * by the parse operation is locale dependant and determined by sub-classes
   358      * of NumberFormat.
   359      */
   360     public boolean isParseIntegerOnly() {
   361         return parseIntegerOnly;
   362     }
   363 
   364     /**
   365      * Sets whether or not numbers should be parsed as integers only.
   366      * @see #isParseIntegerOnly
   367      */
   368     public void setParseIntegerOnly(boolean value) {
   369         parseIntegerOnly = value;
   370     }
   371 
   372     //============== Locale Stuff =====================
   373 
   374     /**
   375      * Returns a general-purpose number format for the current default locale.
   376      * This is the same as calling
   377      * {@link #getNumberInstance() getNumberInstance()}.
   378      */
   379     public final static NumberFormat getInstance() {
   380         return getInstance(Locale.getDefault(Locale.Category.FORMAT), NUMBERSTYLE);
   381     }
   382 
   383     /**
   384      * Returns a general-purpose number format for the specified locale.
   385      * This is the same as calling
   386      * {@link #getNumberInstance(java.util.Locale) getNumberInstance(inLocale)}.
   387      */
   388     public static NumberFormat getInstance(Locale inLocale) {
   389         return getInstance(inLocale, NUMBERSTYLE);
   390     }
   391 
   392     /**     * Returns a general-purpose number format for the current default locale.
   393      */
   394     public final static NumberFormat getNumberInstance() {
   395         return getInstance(Locale.getDefault(Locale.Category.FORMAT), NUMBERSTYLE);
   396     }
   397 
   398     /**
   399      * Returns a general-purpose number format for the specified locale.
   400      */
   401     public static NumberFormat getNumberInstance(Locale inLocale) {
   402         return getInstance(inLocale, NUMBERSTYLE);
   403     }
   404 
   405     /**
   406      * Returns an integer number format for the current default locale. The
   407      * returned number format is configured to round floating point numbers
   408      * to the nearest integer using half-even rounding (see {@link
   409      * java.math.RoundingMode#HALF_EVEN RoundingMode.HALF_EVEN}) for formatting,
   410      * and to parse only the integer part of an input string (see {@link
   411      * #isParseIntegerOnly isParseIntegerOnly}).
   412      *
   413      * @see #getRoundingMode()
   414      * @return a number format for integer values
   415      * @since 1.4
   416      */
   417     public final static NumberFormat getIntegerInstance() {
   418         return getInstance(Locale.getDefault(Locale.Category.FORMAT), INTEGERSTYLE);
   419     }
   420 
   421     /**
   422      * Returns an integer number format for the specified locale. The
   423      * returned number format is configured to round floating point numbers
   424      * to the nearest integer using half-even rounding (see {@link
   425      * java.math.RoundingMode#HALF_EVEN RoundingMode.HALF_EVEN}) for formatting,
   426      * and to parse only the integer part of an input string (see {@link
   427      * #isParseIntegerOnly isParseIntegerOnly}).
   428      *
   429      * @see #getRoundingMode()
   430      * @return a number format for integer values
   431      * @since 1.4
   432      */
   433     public static NumberFormat getIntegerInstance(Locale inLocale) {
   434         return getInstance(inLocale, INTEGERSTYLE);
   435     }
   436 
   437     /**
   438      * Returns a currency format for the current default locale.
   439      */
   440     public final static NumberFormat getCurrencyInstance() {
   441         return getInstance(Locale.getDefault(Locale.Category.FORMAT), CURRENCYSTYLE);
   442     }
   443 
   444     /**
   445      * Returns a currency format for the specified locale.
   446      */
   447     public static NumberFormat getCurrencyInstance(Locale inLocale) {
   448         return getInstance(inLocale, CURRENCYSTYLE);
   449     }
   450 
   451     /**
   452      * Returns a percentage format for the current default locale.
   453      */
   454     public final static NumberFormat getPercentInstance() {
   455         return getInstance(Locale.getDefault(Locale.Category.FORMAT), PERCENTSTYLE);
   456     }
   457 
   458     /**
   459      * Returns a percentage format for the specified locale.
   460      */
   461     public static NumberFormat getPercentInstance(Locale inLocale) {
   462         return getInstance(inLocale, PERCENTSTYLE);
   463     }
   464 
   465     /**
   466      * Returns a scientific format for the current default locale.
   467      */
   468     /*public*/ final static NumberFormat getScientificInstance() {
   469         return getInstance(Locale.getDefault(Locale.Category.FORMAT), SCIENTIFICSTYLE);
   470     }
   471 
   472     /**
   473      * Returns a scientific format for the specified locale.
   474      */
   475     /*public*/ static NumberFormat getScientificInstance(Locale inLocale) {
   476         return getInstance(inLocale, SCIENTIFICSTYLE);
   477     }
   478 
   479     /**
   480      * Returns an array of all locales for which the
   481      * <code>get*Instance</code> methods of this class can return
   482      * localized instances.
   483      * The returned array represents the union of locales supported by the Java
   484      * runtime and by installed
   485      * {@link java.text.spi.NumberFormatProvider NumberFormatProvider} implementations.
   486      * It must contain at least a <code>Locale</code> instance equal to
   487      * {@link java.util.Locale#US Locale.US}.
   488      *
   489      * @return An array of locales for which localized
   490      *         <code>NumberFormat</code> instances are available.
   491      */
   492     public static Locale[] getAvailableLocales() {
   493         return new Locale[] { Locale.US };
   494 //        LocaleServiceProviderPool pool =
   495 //            LocaleServiceProviderPool.getPool(NumberFormatProvider.class);
   496 //        return pool.getAvailableLocales();
   497     }
   498 
   499     /**
   500      * Overrides hashCode
   501      */
   502     public int hashCode() {
   503         return maximumIntegerDigits * 37 + maxFractionDigits;
   504         // just enough fields for a reasonable distribution
   505     }
   506 
   507     /**
   508      * Overrides equals
   509      */
   510     public boolean equals(Object obj) {
   511         if (obj == null) {
   512             return false;
   513         }
   514         if (this == obj) {
   515             return true;
   516         }
   517         if (getClass() != obj.getClass()) {
   518             return false;
   519         }
   520         NumberFormat other = (NumberFormat) obj;
   521         return (maximumIntegerDigits == other.maximumIntegerDigits
   522             && minimumIntegerDigits == other.minimumIntegerDigits
   523             && maximumFractionDigits == other.maximumFractionDigits
   524             && minimumFractionDigits == other.minimumFractionDigits
   525             && groupingUsed == other.groupingUsed
   526             && parseIntegerOnly == other.parseIntegerOnly);
   527     }
   528 
   529     /**
   530      * Overrides Cloneable
   531      */
   532     public Object clone() {
   533         NumberFormat other = (NumberFormat) super.clone();
   534         return other;
   535     }
   536 
   537     /**
   538      * Returns true if grouping is used in this format. For example, in the
   539      * English locale, with grouping on, the number 1234567 might be formatted
   540      * as "1,234,567". The grouping separator as well as the size of each group
   541      * is locale dependant and is determined by sub-classes of NumberFormat.
   542      * @see #setGroupingUsed
   543      */
   544     public boolean isGroupingUsed() {
   545         return groupingUsed;
   546     }
   547 
   548     /**
   549      * Set whether or not grouping will be used in this format.
   550      * @see #isGroupingUsed
   551      */
   552     public void setGroupingUsed(boolean newValue) {
   553         groupingUsed = newValue;
   554     }
   555 
   556     /**
   557      * Returns the maximum number of digits allowed in the integer portion of a
   558      * number.
   559      * @see #setMaximumIntegerDigits
   560      */
   561     public int getMaximumIntegerDigits() {
   562         return maximumIntegerDigits;
   563     }
   564 
   565     /**
   566      * Sets the maximum number of digits allowed in the integer portion of a
   567      * number. maximumIntegerDigits must be >= minimumIntegerDigits.  If the
   568      * new value for maximumIntegerDigits is less than the current value
   569      * of minimumIntegerDigits, then minimumIntegerDigits will also be set to
   570      * the new value.
   571      * @param newValue the maximum number of integer digits to be shown; if
   572      * less than zero, then zero is used. The concrete subclass may enforce an
   573      * upper limit to this value appropriate to the numeric type being formatted.
   574      * @see #getMaximumIntegerDigits
   575      */
   576     public void setMaximumIntegerDigits(int newValue) {
   577         maximumIntegerDigits = Math.max(0,newValue);
   578         if (minimumIntegerDigits > maximumIntegerDigits) {
   579             minimumIntegerDigits = maximumIntegerDigits;
   580         }
   581     }
   582 
   583     /**
   584      * Returns the minimum number of digits allowed in the integer portion of a
   585      * number.
   586      * @see #setMinimumIntegerDigits
   587      */
   588     public int getMinimumIntegerDigits() {
   589         return minimumIntegerDigits;
   590     }
   591 
   592     /**
   593      * Sets the minimum number of digits allowed in the integer portion of a
   594      * number. minimumIntegerDigits must be <= maximumIntegerDigits.  If the
   595      * new value for minimumIntegerDigits exceeds the current value
   596      * of maximumIntegerDigits, then maximumIntegerDigits will also be set to
   597      * the new value
   598      * @param newValue the minimum number of integer digits to be shown; if
   599      * less than zero, then zero is used. The concrete subclass may enforce an
   600      * upper limit to this value appropriate to the numeric type being formatted.
   601      * @see #getMinimumIntegerDigits
   602      */
   603     public void setMinimumIntegerDigits(int newValue) {
   604         minimumIntegerDigits = Math.max(0,newValue);
   605         if (minimumIntegerDigits > maximumIntegerDigits) {
   606             maximumIntegerDigits = minimumIntegerDigits;
   607         }
   608     }
   609 
   610     /**
   611      * Returns the maximum number of digits allowed in the fraction portion of a
   612      * number.
   613      * @see #setMaximumFractionDigits
   614      */
   615     public int getMaximumFractionDigits() {
   616         return maximumFractionDigits;
   617     }
   618 
   619     /**
   620      * Sets the maximum number of digits allowed in the fraction portion of a
   621      * number. maximumFractionDigits must be >= minimumFractionDigits.  If the
   622      * new value for maximumFractionDigits is less than the current value
   623      * of minimumFractionDigits, then minimumFractionDigits will also be set to
   624      * the new value.
   625      * @param newValue the maximum number of fraction digits to be shown; if
   626      * less than zero, then zero is used. The concrete subclass may enforce an
   627      * upper limit to this value appropriate to the numeric type being formatted.
   628      * @see #getMaximumFractionDigits
   629      */
   630     public void setMaximumFractionDigits(int newValue) {
   631         maximumFractionDigits = Math.max(0,newValue);
   632         if (maximumFractionDigits < minimumFractionDigits) {
   633             minimumFractionDigits = maximumFractionDigits;
   634         }
   635     }
   636 
   637     /**
   638      * Returns the minimum number of digits allowed in the fraction portion of a
   639      * number.
   640      * @see #setMinimumFractionDigits
   641      */
   642     public int getMinimumFractionDigits() {
   643         return minimumFractionDigits;
   644     }
   645 
   646     /**
   647      * Sets the minimum number of digits allowed in the fraction portion of a
   648      * number. minimumFractionDigits must be <= maximumFractionDigits.  If the
   649      * new value for minimumFractionDigits exceeds the current value
   650      * of maximumFractionDigits, then maximumIntegerDigits will also be set to
   651      * the new value
   652      * @param newValue the minimum number of fraction digits to be shown; if
   653      * less than zero, then zero is used. The concrete subclass may enforce an
   654      * upper limit to this value appropriate to the numeric type being formatted.
   655      * @see #getMinimumFractionDigits
   656      */
   657     public void setMinimumFractionDigits(int newValue) {
   658         minimumFractionDigits = Math.max(0,newValue);
   659         if (maximumFractionDigits < minimumFractionDigits) {
   660             maximumFractionDigits = minimumFractionDigits;
   661         }
   662     }
   663 
   664     /**
   665      * Gets the currency used by this number format when formatting
   666      * currency values. The initial value is derived in a locale dependent
   667      * way. The returned value may be null if no valid
   668      * currency could be determined and no currency has been set using
   669      * {@link #setCurrency(java.util.Currency) setCurrency}.
   670      * <p>
   671      * The default implementation throws
   672      * <code>UnsupportedOperationException</code>.
   673      *
   674      * @return the currency used by this number format, or <code>null</code>
   675      * @exception UnsupportedOperationException if the number format class
   676      * doesn't implement currency formatting
   677      * @since 1.4
   678      */
   679     public Currency getCurrency() {
   680         throw new UnsupportedOperationException();
   681     }
   682 
   683     /**
   684      * Sets the currency used by this number format when formatting
   685      * currency values. This does not update the minimum or maximum
   686      * number of fraction digits used by the number format.
   687      * <p>
   688      * The default implementation throws
   689      * <code>UnsupportedOperationException</code>.
   690      *
   691      * @param currency the new currency to be used by this number format
   692      * @exception UnsupportedOperationException if the number format class
   693      * doesn't implement currency formatting
   694      * @exception NullPointerException if <code>currency</code> is null
   695      * @since 1.4
   696      */
   697     public void setCurrency(Currency currency) {
   698         throw new UnsupportedOperationException();
   699     }
   700 
   701     /**
   702      * Gets the {@link java.math.RoundingMode} used in this NumberFormat.
   703      * The default implementation of this method in NumberFormat
   704      * always throws {@link java.lang.UnsupportedOperationException}.
   705      * Subclasses which handle different rounding modes should override
   706      * this method.
   707      *
   708      * @exception UnsupportedOperationException The default implementation
   709      *     always throws this exception
   710      * @return The <code>RoundingMode</code> used for this NumberFormat.
   711      * @see #setRoundingMode(RoundingMode)
   712      * @since 1.6
   713      */
   714     public RoundingMode getRoundingMode() {
   715         throw new UnsupportedOperationException();
   716     }
   717 
   718     /**
   719      * Sets the {@link java.math.RoundingMode} used in this NumberFormat.
   720      * The default implementation of this method in NumberFormat always
   721      * throws {@link java.lang.UnsupportedOperationException}.
   722      * Subclasses which handle different rounding modes should override
   723      * this method.
   724      *
   725      * @exception UnsupportedOperationException The default implementation
   726      *     always throws this exception
   727      * @exception NullPointerException if <code>roundingMode</code> is null
   728      * @param roundingMode The <code>RoundingMode</code> to be used
   729      * @see #getRoundingMode()
   730      * @since 1.6
   731      */
   732     public void setRoundingMode(RoundingMode roundingMode) {
   733         throw new UnsupportedOperationException();
   734     }
   735 
   736     // =======================privates===============================
   737 
   738     private static NumberFormat getInstance(Locale desiredLocale,
   739                                            int choice) {
   740         // Check whether a provider can provide an implementation that's closer
   741         // to the requested locale than what the Java runtime itself can provide.
   742 //        LocaleServiceProviderPool pool =
   743 //            LocaleServiceProviderPool.getPool(NumberFormatProvider.class);
   744 //        if (pool.hasProviders()) {
   745 //            NumberFormat providersInstance = pool.getLocalizedObject(
   746 //                                    NumberFormatGetter.INSTANCE,
   747 //                                    desiredLocale,
   748 //                                    choice);
   749 //            if (providersInstance != null) {
   750 //                return providersInstance;
   751 //            }
   752 //        }
   753 
   754         /* try the cache first */
   755         String[] numberPatterns = (String[])cachedLocaleData.get(desiredLocale);
   756 //        if (numberPatterns == null) { /* cache miss */
   757 //            ResourceBundle resource = LocaleData.getNumberFormatData(desiredLocale);
   758 //            numberPatterns = resource.getStringArray("NumberPatterns");
   759 //            /* update cache */
   760 //            cachedLocaleData.put(desiredLocale, numberPatterns);
   761 //        }
   762 
   763         DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance(desiredLocale);
   764         int entry = (choice == INTEGERSTYLE) ? NUMBERSTYLE : choice;
   765         DecimalFormat format = new DecimalFormat(numberPatterns[entry], symbols);
   766 
   767         if (choice == INTEGERSTYLE) {
   768             format.setMaximumFractionDigits(0);
   769             format.setDecimalSeparatorAlwaysShown(false);
   770             format.setParseIntegerOnly(true);
   771         } else if (choice == CURRENCYSTYLE) {
   772             format.adjustForCurrencyDefaultFractionDigits();
   773         }
   774 
   775         return format;
   776     }
   777 
   778     /**
   779      * First, read in the default serializable data.
   780      *
   781      * Then, if <code>serialVersionOnStream</code> is less than 1, indicating that
   782      * the stream was written by JDK 1.1,
   783      * set the <code>int</code> fields such as <code>maximumIntegerDigits</code>
   784      * to be equal to the <code>byte</code> fields such as <code>maxIntegerDigits</code>,
   785      * since the <code>int</code> fields were not present in JDK 1.1.
   786      * Finally, set serialVersionOnStream back to the maximum allowed value so that
   787      * default serialization will work properly if this object is streamed out again.
   788      *
   789      * <p>If <code>minimumIntegerDigits</code> is greater than
   790      * <code>maximumIntegerDigits</code> or <code>minimumFractionDigits</code>
   791      * is greater than <code>maximumFractionDigits</code>, then the stream data
   792      * is invalid and this method throws an <code>InvalidObjectException</code>.
   793      * In addition, if any of these values is negative, then this method throws
   794      * an <code>InvalidObjectException</code>.
   795      *
   796      * @since 1.2
   797      */
   798     private void readObject(ObjectInputStream stream)
   799          throws IOException, ClassNotFoundException
   800     {
   801         stream.defaultReadObject();
   802         if (serialVersionOnStream < 1) {
   803             // Didn't have additional int fields, reassign to use them.
   804             maximumIntegerDigits = maxIntegerDigits;
   805             minimumIntegerDigits = minIntegerDigits;
   806             maximumFractionDigits = maxFractionDigits;
   807             minimumFractionDigits = minFractionDigits;
   808         }
   809         if (minimumIntegerDigits > maximumIntegerDigits ||
   810             minimumFractionDigits > maximumFractionDigits ||
   811             minimumIntegerDigits < 0 || minimumFractionDigits < 0) {
   812             throw new InvalidObjectException("Digit count range invalid");
   813         }
   814         serialVersionOnStream = currentSerialVersion;
   815     }
   816 
   817     /**
   818      * Write out the default serializable data, after first setting
   819      * the <code>byte</code> fields such as <code>maxIntegerDigits</code> to be
   820      * equal to the <code>int</code> fields such as <code>maximumIntegerDigits</code>
   821      * (or to <code>Byte.MAX_VALUE</code>, whichever is smaller), for compatibility
   822      * with the JDK 1.1 version of the stream format.
   823      *
   824      * @since 1.2
   825      */
   826     private void writeObject(ObjectOutputStream stream)
   827          throws IOException
   828     {
   829         maxIntegerDigits = (maximumIntegerDigits > Byte.MAX_VALUE) ?
   830                            Byte.MAX_VALUE : (byte)maximumIntegerDigits;
   831         minIntegerDigits = (minimumIntegerDigits > Byte.MAX_VALUE) ?
   832                            Byte.MAX_VALUE : (byte)minimumIntegerDigits;
   833         maxFractionDigits = (maximumFractionDigits > Byte.MAX_VALUE) ?
   834                             Byte.MAX_VALUE : (byte)maximumFractionDigits;
   835         minFractionDigits = (minimumFractionDigits > Byte.MAX_VALUE) ?
   836                             Byte.MAX_VALUE : (byte)minimumFractionDigits;
   837         stream.defaultWriteObject();
   838     }
   839 
   840     /**
   841      * Cache to hold the NumberPatterns of a Locale.
   842      */
   843     private static final Hashtable cachedLocaleData = new Hashtable(3);
   844 
   845     // Constants used by factory methods to specify a style of format.
   846     private static final int NUMBERSTYLE = 0;
   847     private static final int CURRENCYSTYLE = 1;
   848     private static final int PERCENTSTYLE = 2;
   849     private static final int SCIENTIFICSTYLE = 3;
   850     private static final int INTEGERSTYLE = 4;
   851 
   852     /**
   853      * True if the grouping (i.e. thousands) separator is used when
   854      * formatting and parsing numbers.
   855      *
   856      * @serial
   857      * @see #isGroupingUsed
   858      */
   859     private boolean groupingUsed = true;
   860 
   861     /**
   862      * The maximum number of digits allowed in the integer portion of a
   863      * number.  <code>maxIntegerDigits</code> must be greater than or equal to
   864      * <code>minIntegerDigits</code>.
   865      * <p>
   866      * <strong>Note:</strong> This field exists only for serialization
   867      * compatibility with JDK 1.1.  In Java platform 2 v1.2 and higher, the new
   868      * <code>int</code> field <code>maximumIntegerDigits</code> is used instead.
   869      * When writing to a stream, <code>maxIntegerDigits</code> is set to
   870      * <code>maximumIntegerDigits</code> or <code>Byte.MAX_VALUE</code>,
   871      * whichever is smaller.  When reading from a stream, this field is used
   872      * only if <code>serialVersionOnStream</code> is less than 1.
   873      *
   874      * @serial
   875      * @see #getMaximumIntegerDigits
   876      */
   877     private byte    maxIntegerDigits = 40;
   878 
   879     /**
   880      * The minimum number of digits allowed in the integer portion of a
   881      * number.  <code>minimumIntegerDigits</code> must be less than or equal to
   882      * <code>maximumIntegerDigits</code>.
   883      * <p>
   884      * <strong>Note:</strong> This field exists only for serialization
   885      * compatibility with JDK 1.1.  In Java platform 2 v1.2 and higher, the new
   886      * <code>int</code> field <code>minimumIntegerDigits</code> is used instead.
   887      * When writing to a stream, <code>minIntegerDigits</code> is set to
   888      * <code>minimumIntegerDigits</code> or <code>Byte.MAX_VALUE</code>,
   889      * whichever is smaller.  When reading from a stream, this field is used
   890      * only if <code>serialVersionOnStream</code> is less than 1.
   891      *
   892      * @serial
   893      * @see #getMinimumIntegerDigits
   894      */
   895     private byte    minIntegerDigits = 1;
   896 
   897     /**
   898      * The maximum number of digits allowed in the fractional portion of a
   899      * number.  <code>maximumFractionDigits</code> must be greater than or equal to
   900      * <code>minimumFractionDigits</code>.
   901      * <p>
   902      * <strong>Note:</strong> This field exists only for serialization
   903      * compatibility with JDK 1.1.  In Java platform 2 v1.2 and higher, the new
   904      * <code>int</code> field <code>maximumFractionDigits</code> is used instead.
   905      * When writing to a stream, <code>maxFractionDigits</code> is set to
   906      * <code>maximumFractionDigits</code> or <code>Byte.MAX_VALUE</code>,
   907      * whichever is smaller.  When reading from a stream, this field is used
   908      * only if <code>serialVersionOnStream</code> is less than 1.
   909      *
   910      * @serial
   911      * @see #getMaximumFractionDigits
   912      */
   913     private byte    maxFractionDigits = 3;    // invariant, >= minFractionDigits
   914 
   915     /**
   916      * The minimum number of digits allowed in the fractional portion of a
   917      * number.  <code>minimumFractionDigits</code> must be less than or equal to
   918      * <code>maximumFractionDigits</code>.
   919      * <p>
   920      * <strong>Note:</strong> This field exists only for serialization
   921      * compatibility with JDK 1.1.  In Java platform 2 v1.2 and higher, the new
   922      * <code>int</code> field <code>minimumFractionDigits</code> is used instead.
   923      * When writing to a stream, <code>minFractionDigits</code> is set to
   924      * <code>minimumFractionDigits</code> or <code>Byte.MAX_VALUE</code>,
   925      * whichever is smaller.  When reading from a stream, this field is used
   926      * only if <code>serialVersionOnStream</code> is less than 1.
   927      *
   928      * @serial
   929      * @see #getMinimumFractionDigits
   930      */
   931     private byte    minFractionDigits = 0;
   932 
   933     /**
   934      * True if this format will parse numbers as integers only.
   935      *
   936      * @serial
   937      * @see #isParseIntegerOnly
   938      */
   939     private boolean parseIntegerOnly = false;
   940 
   941     // new fields for 1.2.  byte is too small for integer digits.
   942 
   943     /**
   944      * The maximum number of digits allowed in the integer portion of a
   945      * number.  <code>maximumIntegerDigits</code> must be greater than or equal to
   946      * <code>minimumIntegerDigits</code>.
   947      *
   948      * @serial
   949      * @since 1.2
   950      * @see #getMaximumIntegerDigits
   951      */
   952     private int    maximumIntegerDigits = 40;
   953 
   954     /**
   955      * The minimum number of digits allowed in the integer portion of a
   956      * number.  <code>minimumIntegerDigits</code> must be less than or equal to
   957      * <code>maximumIntegerDigits</code>.
   958      *
   959      * @serial
   960      * @since 1.2
   961      * @see #getMinimumIntegerDigits
   962      */
   963     private int    minimumIntegerDigits = 1;
   964 
   965     /**
   966      * The maximum number of digits allowed in the fractional portion of a
   967      * number.  <code>maximumFractionDigits</code> must be greater than or equal to
   968      * <code>minimumFractionDigits</code>.
   969      *
   970      * @serial
   971      * @since 1.2
   972      * @see #getMaximumFractionDigits
   973      */
   974     private int    maximumFractionDigits = 3;    // invariant, >= minFractionDigits
   975 
   976     /**
   977      * The minimum number of digits allowed in the fractional portion of a
   978      * number.  <code>minimumFractionDigits</code> must be less than or equal to
   979      * <code>maximumFractionDigits</code>.
   980      *
   981      * @serial
   982      * @since 1.2
   983      * @see #getMinimumFractionDigits
   984      */
   985     private int    minimumFractionDigits = 0;
   986 
   987     static final int currentSerialVersion = 1;
   988 
   989     /**
   990      * Describes the version of <code>NumberFormat</code> present on the stream.
   991      * Possible values are:
   992      * <ul>
   993      * <li><b>0</b> (or uninitialized): the JDK 1.1 version of the stream format.
   994      *     In this version, the <code>int</code> fields such as
   995      *     <code>maximumIntegerDigits</code> were not present, and the <code>byte</code>
   996      *     fields such as <code>maxIntegerDigits</code> are used instead.
   997      *
   998      * <li><b>1</b>: the 1.2 version of the stream format.  The values of the
   999      *     <code>byte</code> fields such as <code>maxIntegerDigits</code> are ignored,
  1000      *     and the <code>int</code> fields such as <code>maximumIntegerDigits</code>
  1001      *     are used instead.
  1002      * </ul>
  1003      * When streaming out a <code>NumberFormat</code>, the most recent format
  1004      * (corresponding to the highest allowable <code>serialVersionOnStream</code>)
  1005      * is always written.
  1006      *
  1007      * @serial
  1008      * @since 1.2
  1009      */
  1010     private int serialVersionOnStream = currentSerialVersion;
  1011 
  1012     // Removed "implements Cloneable" clause.  Needs to update serialization
  1013     // ID for backward compatibility.
  1014     static final long serialVersionUID = -2308460125733713944L;
  1015 
  1016 
  1017     //
  1018     // class for AttributedCharacterIterator attributes
  1019     //
  1020     /**
  1021      * Defines constants that are used as attribute keys in the
  1022      * <code>AttributedCharacterIterator</code> returned
  1023      * from <code>NumberFormat.formatToCharacterIterator</code> and as
  1024      * field identifiers in <code>FieldPosition</code>.
  1025      *
  1026      * @since 1.4
  1027      */
  1028     public static class Field extends Format.Field {
  1029 
  1030         // Proclaim serial compatibility with 1.4 FCS
  1031         private static final long serialVersionUID = 7494728892700160890L;
  1032 
  1033         // table of all instances in this class, used by readResolve
  1034         private static final Map instanceMap = new HashMap(11);
  1035 
  1036         /**
  1037          * Creates a Field instance with the specified
  1038          * name.
  1039          *
  1040          * @param name Name of the attribute
  1041          */
  1042         protected Field(String name) {
  1043             super(name);
  1044             if (this.getClass() == NumberFormat.Field.class) {
  1045                 instanceMap.put(name, this);
  1046             }
  1047         }
  1048 
  1049         /**
  1050          * Resolves instances being deserialized to the predefined constants.
  1051          *
  1052          * @throws InvalidObjectException if the constant could not be resolved.
  1053          * @return resolved NumberFormat.Field constant
  1054          */
  1055         protected Object readResolve() throws InvalidObjectException {
  1056             if (this.getClass() != NumberFormat.Field.class) {
  1057                 throw new InvalidObjectException("subclass didn't correctly implement readResolve");
  1058             }
  1059 
  1060             Object instance = instanceMap.get(getName());
  1061             if (instance != null) {
  1062                 return instance;
  1063             } else {
  1064                 throw new InvalidObjectException("unknown attribute name");
  1065             }
  1066         }
  1067 
  1068         /**
  1069          * Constant identifying the integer field.
  1070          */
  1071         public static final Field INTEGER = new Field("integer");
  1072 
  1073         /**
  1074          * Constant identifying the fraction field.
  1075          */
  1076         public static final Field FRACTION = new Field("fraction");
  1077 
  1078         /**
  1079          * Constant identifying the exponent field.
  1080          */
  1081         public static final Field EXPONENT = new Field("exponent");
  1082 
  1083         /**
  1084          * Constant identifying the decimal separator field.
  1085          */
  1086         public static final Field DECIMAL_SEPARATOR =
  1087                             new Field("decimal separator");
  1088 
  1089         /**
  1090          * Constant identifying the sign field.
  1091          */
  1092         public static final Field SIGN = new Field("sign");
  1093 
  1094         /**
  1095          * Constant identifying the grouping separator field.
  1096          */
  1097         public static final Field GROUPING_SEPARATOR =
  1098                             new Field("grouping separator");
  1099 
  1100         /**
  1101          * Constant identifying the exponent symbol field.
  1102          */
  1103         public static final Field EXPONENT_SYMBOL = new
  1104                             Field("exponent symbol");
  1105 
  1106         /**
  1107          * Constant identifying the percent field.
  1108          */
  1109         public static final Field PERCENT = new Field("percent");
  1110 
  1111         /**
  1112          * Constant identifying the permille field.
  1113          */
  1114         public static final Field PERMILLE = new Field("per mille");
  1115 
  1116         /**
  1117          * Constant identifying the currency field.
  1118          */
  1119         public static final Field CURRENCY = new Field("currency");
  1120 
  1121         /**
  1122          * Constant identifying the exponent sign field.
  1123          */
  1124         public static final Field EXPONENT_SIGN = new Field("exponent sign");
  1125     }
  1126 
  1127     /**
  1128      * Obtains a NumberFormat instance from a NumberFormatProvider implementation.
  1129      *
  1130     private static class NumberFormatGetter
  1131         implements LocaleServiceProviderPool.LocalizedObjectGetter<NumberFormatProvider,
  1132                                                                    NumberFormat> {
  1133         private static final NumberFormatGetter INSTANCE = new NumberFormatGetter();
  1134 
  1135         public NumberFormat getObject(NumberFormatProvider numberFormatProvider,
  1136                                 Locale locale,
  1137                                 String key,
  1138                                 Object... params) {
  1139             assert params.length == 1;
  1140             int choice = (Integer)params[0];
  1141 
  1142             switch (choice) {
  1143             case NUMBERSTYLE:
  1144                 return numberFormatProvider.getNumberInstance(locale);
  1145             case PERCENTSTYLE:
  1146                 return numberFormatProvider.getPercentInstance(locale);
  1147             case CURRENCYSTYLE:
  1148                 return numberFormatProvider.getCurrencyInstance(locale);
  1149             case INTEGERSTYLE:
  1150                 return numberFormatProvider.getIntegerInstance(locale);
  1151             default:
  1152                 assert false : choice;
  1153             }
  1154 
  1155             return null;
  1156         }
  1157     }
  1158     */
  1159 }