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