Source for java.text.NumberFormat

   1: /* NumberFormat.java -- Formats and parses numbers
   2:    Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2007, 2012
   3:    Free Software Foundation, Inc.
   4: 
   5: This file is part of GNU Classpath.
   6: 
   7: GNU Classpath is free software; you can redistribute it and/or modify
   8: it under the terms of the GNU General Public License as published by
   9: the Free Software Foundation; either version 2, or (at your option)
  10: any later version.
  11: 
  12: GNU Classpath is distributed in the hope that it will be useful, but
  13: WITHOUT ANY WARRANTY; without even the implied warranty of
  14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15: General Public License for more details.
  16: 
  17: You should have received a copy of the GNU General Public License
  18: along with GNU Classpath; see the file COPYING.  If not, write to the
  19: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  20: 02110-1301 USA.
  21: 
  22: Linking this library statically or dynamically with other modules is
  23: making a combined work based on this library.  Thus, the terms and
  24: conditions of the GNU General Public License cover the whole
  25: combination.
  26: 
  27: As a special exception, the copyright holders of this library give you
  28: permission to link this library with independent modules to produce an
  29: executable, regardless of the license terms of these independent
  30: modules, and to copy and distribute the resulting executable under
  31: terms of your choice, provided that you also meet, for each linked
  32: independent module, the terms and conditions of the license of that
  33: module.  An independent module is a module which is not derived from
  34: or based on this library.  If you modify this library, you may extend
  35: this exception to your version of the library, but you are not
  36: obligated to do so.  If you do not wish to do so, delete this
  37: exception statement from your version. */
  38: 
  39: 
  40: package java.text;
  41: 
  42: import gnu.java.locale.LocaleHelper;
  43: 
  44: import java.io.IOException;
  45: import java.io.InvalidObjectException;
  46: import java.io.ObjectInputStream;
  47: import java.io.ObjectOutputStream;
  48: 
  49: import java.text.spi.NumberFormatProvider;
  50: 
  51: import java.util.Currency;
  52: import java.util.Locale;
  53: import java.util.MissingResourceException;
  54: import java.util.ResourceBundle;
  55: import java.util.ServiceLoader;
  56: 
  57: /**
  58:  * This is the abstract superclass of all classes which format and
  59:  * parse numeric values such as decimal numbers, integers, currency values,
  60:  * and percentages.  These classes perform their parsing and formatting
  61:  * in a locale specific manner, accounting for such items as differing
  62:  * currency symbols and thousands separators.
  63:  * <p>
  64:  * To create an instance of a concrete subclass of <code>NumberFormat</code>,
  65:  * do not call a class constructor directly.  Instead, use one of the
  66:  * static factory methods in this class such as
  67:  * <code>getCurrencyInstance</code>.
  68:  *
  69:  * @author Tom Tromey (tromey@cygnus.com)
  70:  * @author Aaron M. Renn (arenn@urbanophile.com)
  71:  * @date March 4, 1999
  72:  */
  73: /* Written using "Java Class Libraries", 2nd edition, plus online
  74:  * API docs for JDK 1.2 from http://www.javasoft.com.
  75:  * Status:  Believed complete and correct to 1.2, except getAvailableLocales.
  76:  */
  77: public abstract class NumberFormat extends Format implements Cloneable
  78: {
  79:   /**
  80:    * This is a constant used to create a <code>FieldPosition</code> object
  81:    * that will return the integer portion of a formatted number.
  82:    */
  83:   public static final int INTEGER_FIELD = 0;
  84: 
  85:   /**
  86:    * This is a constant used to create a <code>FieldPosition</code> object
  87:    * that will return the fractional portion of a formatted number.
  88:    */
  89:   public static final int FRACTION_FIELD = 1;
  90: 
  91:   public static class Field extends Format.Field
  92:   {
  93:     static final long serialVersionUID = 7494728892700160890L;
  94: 
  95:     /**
  96:      * Attribute set to all characters containing digits of the integer
  97:      * part.
  98:      */
  99:     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: }