001/* NumberFormat.java -- Formats and parses numbers
002   Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2007, 2012
003   Free Software Foundation, Inc.
004
005This file is part of GNU Classpath.
006
007GNU Classpath is free software; you can redistribute it and/or modify
008it under the terms of the GNU General Public License as published by
009the Free Software Foundation; either version 2, or (at your option)
010any later version.
011
012GNU Classpath is distributed in the hope that it will be useful, but
013WITHOUT ANY WARRANTY; without even the implied warranty of
014MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
015General Public License for more details.
016
017You should have received a copy of the GNU General Public License
018along with GNU Classpath; see the file COPYING.  If not, write to the
019Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02002110-1301 USA.
021
022Linking this library statically or dynamically with other modules is
023making a combined work based on this library.  Thus, the terms and
024conditions of the GNU General Public License cover the whole
025combination.
026
027As a special exception, the copyright holders of this library give you
028permission to link this library with independent modules to produce an
029executable, regardless of the license terms of these independent
030modules, and to copy and distribute the resulting executable under
031terms of your choice, provided that you also meet, for each linked
032independent module, the terms and conditions of the license of that
033module.  An independent module is a module which is not derived from
034or based on this library.  If you modify this library, you may extend
035this exception to your version of the library, but you are not
036obligated to do so.  If you do not wish to do so, delete this
037exception statement from your version. */
038
039
040package java.text;
041
042import gnu.java.locale.LocaleHelper;
043
044import java.io.IOException;
045import java.io.InvalidObjectException;
046import java.io.ObjectInputStream;
047import java.io.ObjectOutputStream;
048
049import java.text.spi.NumberFormatProvider;
050
051import java.util.Currency;
052import java.util.Locale;
053import java.util.MissingResourceException;
054import java.util.ResourceBundle;
055import java.util.ServiceLoader;
056
057/**
058 * This is the abstract superclass of all classes which format and
059 * parse numeric values such as decimal numbers, integers, currency values,
060 * and percentages.  These classes perform their parsing and formatting
061 * in a locale specific manner, accounting for such items as differing
062 * currency symbols and thousands separators.
063 * <p>
064 * To create an instance of a concrete subclass of <code>NumberFormat</code>,
065 * do not call a class constructor directly.  Instead, use one of the
066 * static factory methods in this class such as
067 * <code>getCurrencyInstance</code>.
068 *
069 * @author Tom Tromey (tromey@cygnus.com)
070 * @author Aaron M. Renn (arenn@urbanophile.com)
071 * @date March 4, 1999
072 */
073/* Written using "Java Class Libraries", 2nd edition, plus online
074 * API docs for JDK 1.2 from http://www.javasoft.com.
075 * Status:  Believed complete and correct to 1.2, except getAvailableLocales.
076 */
077public abstract class NumberFormat extends Format implements Cloneable
078{
079  /**
080   * This is a constant used to create a <code>FieldPosition</code> object
081   * that will return the integer portion of a formatted number.
082   */
083  public static final int INTEGER_FIELD = 0;
084
085  /**
086   * This is a constant used to create a <code>FieldPosition</code> object
087   * that will return the fractional portion of a formatted number.
088   */
089  public static final int FRACTION_FIELD = 1;
090
091  public static class Field extends Format.Field
092  {
093    static final long serialVersionUID = 7494728892700160890L;
094
095    /**
096     * Attribute set to all characters containing digits of the integer
097     * part.
098     */
099    public static final NumberFormat.Field INTEGER
100      = new Field("integer");
101
102    /**
103     * Attribute set to all characters containing digits of the fractional
104     * part.
105     */
106    public static final NumberFormat.Field FRACTION
107      = new Field("fraction");
108
109    /**
110     * Attribute set to all characters containing digits of the exponential
111     * part.
112     */
113    public static final NumberFormat.Field EXPONENT
114      = new Field("exponent");
115
116    /**
117     * Attribute set to all characters containing a decimal separator.
118     */
119    public static final NumberFormat.Field DECIMAL_SEPARATOR
120      = new Field("decimal separator");
121
122    /**
123     * Attribute set to all characters containing a sign (plus or minus).
124     */
125    public static final NumberFormat.Field SIGN
126      = new Field("sign");
127
128    /**
129     * Attribute set to all characters containing a grouping separator (e.g.
130     * a comma, a white space,...).
131     */
132    public static final NumberFormat.Field GROUPING_SEPARATOR
133      = new Field("grouping separator");
134
135    /**
136     * Attribute set to all characters containing an exponential symbol (e.g.
137     * 'E')
138     */
139    public static final NumberFormat.Field EXPONENT_SYMBOL
140      = new Field("exponent symbol");
141
142    /**
143     * Attribute set to all characters containing a percent symbol (e.g. '%')
144     */
145    public static final NumberFormat.Field PERCENT
146      = new Field("percent");
147
148    /**
149     * Attribute set to all characters containing a permille symbol.
150     */
151    public static final NumberFormat.Field PERMILLE
152      = new Field("permille");
153
154    /**
155     * Attribute set to all characters containing the currency unit.
156     */
157    public static final NumberFormat.Field CURRENCY
158      = new Field("currency");
159
160    /**
161     * Attribute set to all characters containing the exponent sign.
162     */
163    public static final NumberFormat.Field EXPONENT_SIGN
164      = new Field("exponent sign");
165
166    /**
167     * Private fields to register all fields contained in this descriptor.
168     */
169    private static final NumberFormat.Field[] allFields =
170    {
171      INTEGER, FRACTION, EXPONENT, DECIMAL_SEPARATOR, SIGN,
172      GROUPING_SEPARATOR, EXPONENT_SYMBOL, PERCENT,
173      PERMILLE, CURRENCY, EXPONENT_SIGN
174    };
175
176    /**
177     * This constructor is only used by the deserializer. Without it,
178     * it would fail to construct a valid object.
179     */
180    private Field()
181    {
182      super("");
183    }
184
185    /**
186     * Create a Field instance with the specified field name.
187     *
188     * @param field_name Field name for the new Field instance.
189     */
190    protected Field(String field_name)
191    {
192      super (field_name);
193    }
194
195    /**
196     * This function is used by the deserializer to know which object
197     * to use when it encounters an encoded NumberFormat.Field in a
198     * serialization stream. If the stream is valid it should return
199     * one of the above field. In the other case we throw an exception.
200     *
201     * @return a valid official NumberFormat.Field instance.
202     *
203     * @throws InvalidObjectException if the field name is invalid.
204     */
205    protected Object readResolve() throws InvalidObjectException
206    {
207      String s = getName();
208      for (int i = 0; i < allFields.length; i++)
209        if (s.equals(allFields[i].getName()))
210          return allFields[i];
211
212      throw new InvalidObjectException("no such NumberFormat field called "
213                                       + s);
214    }
215  }
216
217  /**
218   * This method is a specialization of the format method that performs
219   * a simple formatting of the specified <code>long</code> number.
220   *
221   * @param number The <code>long</code> to format.
222   *
223   * @return The formatted number
224   */
225  public final String format (long number)
226  {
227    StringBuffer sbuf = new StringBuffer(50);
228    format (number, sbuf, new FieldPosition(0));
229    return sbuf.toString();
230  }
231
232  /**
233   * @specnote this method was final in releases before 1.5
234   */
235  public StringBuffer format (Object obj, StringBuffer sbuf,
236                              FieldPosition pos)
237  {
238    if (obj instanceof Number)
239      return format(((Number) obj).doubleValue(), sbuf, pos);
240
241    throw new
242      IllegalArgumentException("Cannot format given Object as a Number");
243  }
244
245  /**
246   * This method formats the specified <code>double</code> and appends it to
247   * a <code>StringBuffer</code>.
248   *
249   * @param number The <code>double</code> to format.
250   * @param sbuf The <code>StringBuffer</code> to append the formatted number
251   *             to.
252   * @param pos The desired <code>FieldPosition</code>.
253   *
254   * @return The <code>StringBuffer</code> with the appended number.
255   */
256  public abstract StringBuffer format (double number,
257                                       StringBuffer sbuf, FieldPosition pos);
258
259  /**
260   * This method formats the specified <code>long</code> and appends it to
261   * a <code>StringBuffer</code>.
262   *
263   * @param number The <code>long</code> to format.
264   * @param sbuf The <code>StringBuffer</code> to append the formatted number
265   *             to.
266   * @param pos The desired <code>FieldPosition</code>.
267   *
268   * @return The <code>StringBuffer</code> with the appended number.
269   */
270  public abstract StringBuffer format (long number,
271                                       StringBuffer sbuf, FieldPosition pos);
272
273  /**
274   * This method tests the specified object for equality against this object.
275   * This will be <code>true</code> if the following conditions are met:
276   * <p>
277   * <ul>
278   * <li>The specified object is not <code>null</code>.
279   * <li>The specified object is an instance of <code>NumberFormat</code>.
280   * </ul>
281   * <p>
282   * Since this method does not test much, it is highly advised that
283   * concrete subclasses override this method.
284   *
285   * @param obj The <code>Object</code> to test against equality with
286   *            this object.
287   *
288   * @return <code>true</code> if the specified object is equal to
289   * this object, <code>false</code> otherwise.
290   */
291  public boolean equals (Object obj)
292  {
293    if (! (obj instanceof NumberFormat))
294      return false;
295    NumberFormat nf = (NumberFormat) obj;
296    return (groupingUsed == nf.groupingUsed
297            && maximumFractionDigits == nf.maximumFractionDigits
298            && maximumIntegerDigits == nf.maximumIntegerDigits
299            && minimumFractionDigits == nf.minimumFractionDigits
300            && minimumIntegerDigits == nf.minimumIntegerDigits
301            && parseIntegerOnly == nf.parseIntegerOnly);
302  }
303
304  /**
305   * This method returns a list of locales for which concrete instances
306   * of <code>NumberFormat</code> subclasses may be created.
307   *
308   * @return The list of available locales.
309   */
310  public static Locale[] getAvailableLocales ()
311  {
312    Locale[] list = new Locale[1];
313    list[0] = Locale.US;
314    return list;
315  }
316
317  private static NumberFormat computeInstance(Locale loc, String resource,
318                                              String def)
319    throws MissingResourceException
320  {
321    if (loc.equals(Locale.ROOT))
322      return new DecimalFormat(def, DecimalFormatSymbols.getInstance(loc));
323    ResourceBundle res =
324      ResourceBundle.getBundle("gnu.java.locale.LocaleInformation",
325                               loc, ClassLoader.getSystemClassLoader());
326    String fmt;
327    try
328      {
329        fmt = res == null ? def : res.getString(resource);
330      }
331    catch (MissingResourceException x)
332      {
333        fmt = def;
334      }
335    DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance(loc);
336    return new DecimalFormat (fmt, dfs);
337  }
338
339  /**
340   * This method returns an instance of <code>NumberFormat</code> suitable
341   * for formatting and parsing currency values in the default locale.
342   *
343   * @return An instance of <code>NumberFormat</code> for handling currencies.
344   */
345  public static final NumberFormat getCurrencyInstance ()
346  {
347    return getCurrencyInstance (Locale.getDefault());
348  }
349
350  /**
351   * This method returns an instance of <code>NumberFormat</code> suitable
352   * for formatting and parsing currency values in the specified locale.
353   *
354   * @return An instance of <code>NumberFormat</code> for handling currencies.
355   */
356  public static NumberFormat getCurrencyInstance (Locale loc)
357  {
358    try
359      {
360        NumberFormat format;
361
362        format = computeInstance (loc, "currencyFormat",
363                                  "\u00A4#,##0.00;(\u00A4#,##0.00)");
364        format.setMaximumFractionDigits(format.getCurrency().getDefaultFractionDigits());
365        return format;
366      }
367    catch (MissingResourceException e)
368      {
369        for (NumberFormatProvider p :
370               ServiceLoader.load(NumberFormatProvider.class))
371          {
372            for (Locale l : p.getAvailableLocales())
373              {
374                if (l.equals(loc))
375                  {
376                    NumberFormat nf = p.getCurrencyInstance(loc);
377                    if (nf != null)
378                      return nf;
379                    break;
380                  }
381              }
382          }
383        return getCurrencyInstance(LocaleHelper.getFallbackLocale(loc));
384      }
385  }
386
387  /**
388   * This method returns a default instance for the default locale. This
389   * will be a concrete subclass of <code>NumberFormat</code>, but the
390   * actual class returned is dependent on the locale.
391   *
392   * @return An instance of the default <code>NumberFormat</code> class.
393   */
394  public static final NumberFormat getInstance ()
395  {
396    return getInstance (Locale.getDefault());
397  }
398
399  /**
400   * This method returns a default instance for the specified locale. This
401   * will be a concrete subclass of <code>NumberFormat</code>, but the
402   * actual class returned is dependent on the locale.
403   *
404   * @param loc The desired locale.
405   *
406   * @return An instance of the default <code>NumberFormat</code> class.
407   */
408  public static NumberFormat getInstance (Locale loc)
409  {
410    // For now always return a number instance.
411    return getNumberInstance (loc);
412  }
413
414  /**
415   * This method returns the maximum number of digits allowed in the fraction
416   * portion of a number.
417   *
418   * @return The maximum number of digits allowed in the fraction
419   * portion of a number.
420   */
421  public int getMaximumFractionDigits ()
422  {
423    return maximumFractionDigits;
424  }
425
426  /**
427   * This method returns the maximum number of digits allowed in the integer
428   * portion of a number.
429   *
430   * @return The maximum number of digits allowed in the integer
431   * portion of a number.
432   */
433  public int getMaximumIntegerDigits ()
434  {
435    return maximumIntegerDigits;
436  }
437
438  /**
439   * This method returns the minimum number of digits allowed in the fraction
440   * portion of a number.
441   *
442   * @return The minimum number of digits allowed in the fraction
443   * portion of a number.
444   */
445  public int getMinimumFractionDigits ()
446  {
447    return minimumFractionDigits;
448  }
449
450  /**
451   * This method returns the minimum number of digits allowed in the integer
452   * portion of a number.
453   *
454   * @return The minimum number of digits allowed in the integer
455   * portion of a number.
456   */
457  public int getMinimumIntegerDigits ()
458  {
459    return minimumIntegerDigits;
460  }
461
462  /**
463   * This method returns a default instance for the specified locale. This
464   * will be a concrete subclass of <code>NumberFormat</code>, but the
465   * actual class returned is dependent on the locale.
466   *
467   * @return An instance of the default <code>NumberFormat</code> class.
468   */
469  public static final NumberFormat getNumberInstance ()
470  {
471    return getNumberInstance (Locale.getDefault());
472  }
473
474  /**
475   * This method returns a general purpose number formatting and parsing
476   * class for the default locale.  This will be a concrete subclass of
477   * <code>NumberFormat</code>, but the actual class returned is dependent
478   * on the locale.
479   *
480   * @return An instance of a generic number formatter for the default locale.
481   */
482  public static NumberFormat getNumberInstance (Locale loc)
483  {
484    try
485      {
486        return computeInstance (loc, "numberFormat", "#,##0.###");
487      }
488    catch (MissingResourceException e)
489      {
490        for (NumberFormatProvider p :
491               ServiceLoader.load(NumberFormatProvider.class))
492          {
493            for (Locale l : p.getAvailableLocales())
494              {
495                if (l.equals(loc))
496                  {
497                    NumberFormat nf = p.getNumberInstance(loc);
498                    if (nf != null)
499                      return nf;
500                    break;
501                  }
502              }
503          }
504        return getNumberInstance(LocaleHelper.getFallbackLocale(loc));
505      }
506  }
507
508  /**
509   * This method returns an integer formatting and parsing class for the
510   * default locale. This will be a concrete subclass of <code>NumberFormat</code>,
511   * but the actual class returned is dependent on the locale.
512   *
513   * @return An instance of an integer number formatter for the default locale.
514   * @since 1.4
515   */
516  public static final NumberFormat getIntegerInstance()
517  {
518    return getIntegerInstance (Locale.getDefault());
519  }
520
521  /**
522   * This method returns an integer formatting and parsing class for the
523   * default locale. This will be a concrete subclass of <code>NumberFormat</code>,
524   * but the actual class returned is dependent on the locale.
525   *
526   * @param locale the desired locale.
527   *
528   * @return An instance of an integer number formatter for the desired locale.
529   * @since 1.4
530   */
531  public static NumberFormat getIntegerInstance(Locale locale)
532  {
533    try
534      {
535        NumberFormat format = computeInstance (locale,
536                                               "integerFormat", "#,##0");
537        format.setMaximumFractionDigits(0);
538        format.setParseIntegerOnly (true);
539        return format;
540      }
541    catch (MissingResourceException e)
542      {
543        for (NumberFormatProvider p :
544               ServiceLoader.load(NumberFormatProvider.class))
545          {
546            for (Locale l : p.getAvailableLocales())
547              {
548                if (l.equals(locale))
549                  {
550                    NumberFormat nf = p.getIntegerInstance(locale);
551                    if (nf != null)
552                      return nf;
553                    break;
554                  }
555              }
556          }
557        return getIntegerInstance(LocaleHelper.getFallbackLocale(locale));
558      }
559  }
560
561  /**
562   * This method returns an instance of <code>NumberFormat</code> suitable
563   * for formatting and parsing percentage values in the default locale.
564   *
565   * @return An instance of <code>NumberFormat</code> for handling percentages.
566   */
567  public static final NumberFormat getPercentInstance ()
568  {
569    return getPercentInstance (Locale.getDefault());
570  }
571
572  /**
573   * This method returns an instance of <code>NumberFormat</code> suitable
574   * for formatting and parsing percentage values in the specified locale.
575   *
576   * @param loc The desired locale.
577   *
578   * @return An instance of <code>NumberFormat</code> for handling percentages.
579   */
580  public static NumberFormat getPercentInstance (Locale loc)
581  {
582    try
583      {
584        return computeInstance (loc, "percentFormat", "#,##0%");
585      }
586    catch (MissingResourceException e)
587      {
588        for (NumberFormatProvider p :
589               ServiceLoader.load(NumberFormatProvider.class))
590          {
591            for (Locale l : p.getAvailableLocales())
592              {
593                if (l.equals(loc))
594                  {
595                    NumberFormat nf = p.getPercentInstance(loc);
596                    if (nf != null)
597                      return nf;
598                    break;
599                  }
600              }
601          }
602        return getPercentInstance(LocaleHelper.getFallbackLocale(loc));
603      }
604  }
605
606  /**
607   * This method returns a hash value for this object.
608   *
609   * @return The hash code.
610   */
611  public int hashCode ()
612  {
613    int hash = super.hashCode();
614    hash ^= (maximumFractionDigits + maximumIntegerDigits
615             + minimumFractionDigits + minimumIntegerDigits);
616    if (groupingUsed)
617      hash ^= 0xf0f0;
618    if (parseIntegerOnly)
619      hash ^= 0x0f0f;
620    return hash;
621  }
622
623  /**
624   * This method tests whether or not grouping is in use.  Grouping is
625   * a method of marking separations in numbers, such as thousand separators
626   * in the US English locale.  The grouping positions and symbols are all
627   * locale specific.  As an example, with grouping disabled, the number one
628   * million would appear as "1000000".  With grouping enabled, this number
629   * might appear as "1,000,000".  (Both of these assume the US English
630   * locale).
631   *
632   * @return <code>true</code> if grouping is enabled,
633   * <code>false</code> otherwise.
634   */
635  public boolean isGroupingUsed ()
636  {
637    return groupingUsed;
638  }
639
640  /**
641   * This method tests whether or not only integer values should be parsed.
642   * If this class is parsing only integers, parsing stops at the decimal
643   * point.
644   *
645   * @return <code>true</code> if only integers are parsed,
646   * <code>false</code> otherwise.
647   */
648  public boolean isParseIntegerOnly ()
649  {
650    return parseIntegerOnly;
651  }
652
653  /**
654   * This is a default constructor for use by subclasses.
655   */
656  protected NumberFormat ()
657  {
658  }
659
660  /**
661   * This method parses the specified string into a <code>Number</code>.  This
662   * will be a <code>Long</code> if possible, otherwise it will be a
663   * <code>Double</code>.    If no number can be parsed, no exception is
664   * thrown.  Instead, the parse position remains at its initial index.
665   *
666   * @param sourceStr The string to parse.
667   * @param pos The desired <code>ParsePosition</code>.
668   *
669   * @return The parsed <code>Number</code>
670   */
671  public abstract Number parse (String sourceStr, ParsePosition pos);
672
673  /**
674   * This method parses the specified string into a <code>Number</code>.  This
675   * will be a <code>Long</code> if possible, otherwise it will be a
676   * <code>Double</code>.  If no number can be parsed, an exception will be
677   * thrown.
678   *
679   * @param sourceStr The string to parse.
680   *
681   * @return The parsed <code>Number</code>
682   *
683   * @exception ParseException If no number can be parsed.
684   */
685  public Number parse (String sourceStr) throws ParseException
686  {
687    ParsePosition pp = new ParsePosition (0);
688    Number r = parse (sourceStr, pp);
689    if (r == null)
690      {
691        int index = pp.getErrorIndex();
692        if (index < 0)
693          index = pp.getIndex();
694        throw new ParseException ("couldn't parse number", index);
695      }
696    return r;
697  }
698
699  /**
700   * This method parses the specified string into an <code>Object</code>.  This
701   * will be a <code>Long</code> if possible, otherwise it will be a
702   * <code>Double</code>.    If no number can be parsed, no exception is
703   * thrown.  Instead, the parse position remains at its initial index.
704   *
705   * @param sourceStr The string to parse.
706   * @param pos The desired <code>ParsePosition</code>.
707  *
708  * @return The parsed <code>Object</code>
709  */
710  public final Object parseObject (String sourceStr, ParsePosition pos)
711  {
712    return parse (sourceStr, pos);
713  }
714
715  /**
716   * This method sets the grouping behavior of this formatter.  Grouping is
717   * a method of marking separations in numbers, such as thousand separators
718   * in the US English locale.  The grouping positions and symbols are all
719   * locale specific.  As an example, with grouping disabled, the number one
720   * million would appear as "1000000".  With grouping enabled, this number
721   * might appear as "1,000,000".  (Both of these assume the US English
722   * locale).
723   *
724   * @param newValue <code>true</code> to enable grouping,
725   *                     <code>false</code> to disable it.
726   */
727  public void setGroupingUsed (boolean newValue)
728  {
729    groupingUsed = newValue;
730  }
731
732  /**
733   * This method sets the maximum number of digits allowed in the fraction
734   * portion of a number to the specified value.  If this is less than the
735   * current minimum allowed digits, the minimum allowed digits value will
736   * be lowered to be equal to the new maximum allowed digits value.
737   *
738   * @param digits The new maximum fraction digits value.
739   */
740  public void setMaximumFractionDigits (int digits)
741  {
742    maximumFractionDigits = digits;
743    if (getMinimumFractionDigits () > maximumFractionDigits)
744      setMinimumFractionDigits (maximumFractionDigits);
745  }
746
747  /**
748   * This method sets the maximum number of digits allowed in the integer
749   * portion of a number to the specified value.  If this is less than the
750   * current minimum allowed digits, the minimum allowed digits value will
751   * be lowered to be equal to the new maximum allowed digits value.
752   *
753   * @param digits The new maximum integer digits value.
754   */
755  public void setMaximumIntegerDigits (int digits)
756  {
757    maximumIntegerDigits = digits;
758    if (getMinimumIntegerDigits () > maximumIntegerDigits)
759      setMinimumIntegerDigits (maximumIntegerDigits);
760  }
761
762  /**
763   * This method sets the minimum number of digits allowed in the fraction
764   * portion of a number to the specified value.  If this is greater than the
765   * current maximum allowed digits, the maximum allowed digits value will
766   * be raised to be equal to the new minimum allowed digits value.
767   *
768   * @param digits The new minimum fraction digits value.
769   */
770  public void setMinimumFractionDigits (int digits)
771  {
772    minimumFractionDigits = digits;
773    if (getMaximumFractionDigits () < minimumFractionDigits)
774      setMaximumFractionDigits (minimumFractionDigits);
775  }
776
777  /**
778   * This method sets the minimum number of digits allowed in the integer
779   * portion of a number to the specified value.  If this is greater than the
780   * current maximum allowed digits, the maximum allowed digits value will
781   * be raised to be equal to the new minimum allowed digits value.
782   *
783   * @param digits The new minimum integer digits value.
784   */
785  public void setMinimumIntegerDigits (int digits)
786  {
787    minimumIntegerDigits = digits;
788    if (getMaximumIntegerDigits () < minimumIntegerDigits)
789      setMaximumIntegerDigits (minimumIntegerDigits);
790  }
791
792  /**
793   * This method sets the parsing behavior of this object to parse only
794   * integers or not.
795   *
796   * @param value <code>true</code> to parse only integers,
797   *                         <code>false</code> otherwise.
798   */
799  public void setParseIntegerOnly (boolean value)
800  {
801    parseIntegerOnly = value;
802  }
803
804  /**
805   * This method is a specialization of the format method that performs
806   * a simple formatting of the specified <code>double</code> number.
807   *
808   * @param number The <code>double</code> to format.
809   *
810   * @return The formatted number
811   */
812  public final String format (double number)
813  {
814    StringBuffer sbuf = new StringBuffer(50);
815    FieldPosition position = new FieldPosition(0);
816
817    format (number, sbuf, position);
818    return sbuf.toString();
819  }
820
821  // These field names are fixed by the serialization spec.
822  boolean groupingUsed;
823  int maximumFractionDigits;
824  private byte maxFractionDigits;
825  int maximumIntegerDigits;
826  private byte maxIntegerDigits;
827  int minimumFractionDigits;
828  private byte minFractionDigits;
829  int minimumIntegerDigits;
830  private byte minIntegerDigits;
831  boolean parseIntegerOnly;
832  private int serialVersionOnStream;
833  private static final long serialVersionUID = -2308460125733713944L;
834
835  private void readObject(ObjectInputStream stream)
836    throws IOException, ClassNotFoundException
837  {
838    stream.defaultReadObject();
839    if (serialVersionOnStream < 1)
840      {
841        maximumFractionDigits = maxFractionDigits;
842        maximumIntegerDigits = maxIntegerDigits;
843        minimumFractionDigits = minFractionDigits;
844        minimumIntegerDigits = minIntegerDigits;
845        serialVersionOnStream = 1;
846      }
847  }
848
849  private void writeObject(ObjectOutputStream stream) throws IOException
850  {
851    maxFractionDigits = maximumFractionDigits < Byte.MAX_VALUE ?
852      (byte) maximumFractionDigits : Byte.MAX_VALUE;
853    maxIntegerDigits = maximumIntegerDigits < Byte.MAX_VALUE ?
854      (byte) maximumIntegerDigits : Byte.MAX_VALUE;
855    minFractionDigits = minimumFractionDigits < Byte.MAX_VALUE ?
856      (byte) minimumFractionDigits : Byte.MAX_VALUE;
857    minIntegerDigits = minimumIntegerDigits < Byte.MAX_VALUE ?
858      (byte) minimumIntegerDigits : Byte.MAX_VALUE;
859    serialVersionOnStream = 1;
860    stream.defaultWriteObject();
861  }
862
863  /**
864   * Returns the currency used by this number format when formatting currency
865   * values.
866   *
867   * The default implementation throws UnsupportedOperationException.
868   *
869   * @return The used currency object, or null.
870   *
871   * @throws UnsupportedOperationException If the number format class doesn't
872   * implement currency formatting.
873   *
874   * @since 1.4
875   */
876  public Currency getCurrency()
877  {
878    throw new UnsupportedOperationException();
879  }
880
881  /**
882   * Sets the currency used by this number format when formatting currency
883   * values.
884   *
885   * The default implementation throws UnsupportedOperationException.
886   *
887   * @param currency The new currency to be used by this number format.
888   *
889   * @throws NullPointerException If currenc is null.
890   * @throws UnsupportedOperationException If the number format class doesn't
891   * implement currency formatting.
892   *
893   * @since 1.4
894   */
895  public void setCurrency(Currency currency)
896  {
897    if (currency == null)
898      throw new NullPointerException("currency may not be null");
899
900    throw new UnsupportedOperationException();
901  }
902}