0001 /*
0002 * Copyright 1996-2005 Sun Microsystems, Inc. All Rights Reserved.
0003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004 *
0005 * This code is free software; you can redistribute it and/or modify it
0006 * under the terms of the GNU General Public License version 2 only, as
0007 * published by the Free Software Foundation. Sun designates this
0008 * particular file as subject to the "Classpath" exception as provided
0009 * by Sun in the LICENSE file that accompanied this code.
0010 *
0011 * This code is distributed in the hope that it will be useful, but WITHOUT
0012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0014 * version 2 for more details (a copy is included in the LICENSE file that
0015 * accompanied this code).
0016 *
0017 * You should have received a copy of the GNU General Public License version
0018 * 2 along with this work; if not, write to the Free Software Foundation,
0019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020 *
0021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022 * CA 95054 USA or visit www.sun.com if you need additional information or
0023 * have any questions.
0024 */
0025
0026 /*
0027 * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
0028 * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
0029 *
0030 * The original version of this source code and documentation is copyrighted
0031 * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
0032 * materials are provided under terms of a License Agreement between Taligent
0033 * and Sun. This technology is protected by multiple US and International
0034 * patents. This notice and attribution to Taligent may not be removed.
0035 * Taligent is a registered trademark of Taligent, Inc.
0036 *
0037 */
0038
0039 package java.text;
0040
0041 import java.io.InvalidObjectException;
0042 import java.io.IOException;
0043 import java.io.ObjectInputStream;
0044 import java.io.ObjectOutputStream;
0045 import java.math.BigInteger;
0046 import java.math.RoundingMode;
0047 import java.text.spi.NumberFormatProvider;
0048 import java.util.Currency;
0049 import java.util.HashMap;
0050 import java.util.Hashtable;
0051 import java.util.Locale;
0052 import java.util.Map;
0053 import java.util.ResourceBundle;
0054 import java.util.concurrent.atomic.AtomicInteger;
0055 import java.util.concurrent.atomic.AtomicLong;
0056 import java.util.spi.LocaleServiceProvider;
0057 import sun.util.LocaleServiceProviderPool;
0058 import sun.util.resources.LocaleData;
0059
0060 /**
0061 * <code>NumberFormat</code> is the abstract base class for all number
0062 * formats. This class provides the interface for formatting and parsing
0063 * numbers. <code>NumberFormat</code> also provides methods for determining
0064 * which locales have number formats, and what their names are.
0065 *
0066 * <p>
0067 * <code>NumberFormat</code> helps you to format and parse numbers for any locale.
0068 * Your code can be completely independent of the locale conventions for
0069 * decimal points, thousands-separators, or even the particular decimal
0070 * digits used, or whether the number format is even decimal.
0071 *
0072 * <p>
0073 * To format a number for the current Locale, use one of the factory
0074 * class methods:
0075 * <blockquote>
0076 * <pre>
0077 * myString = NumberFormat.getInstance().format(myNumber);
0078 * </pre>
0079 * </blockquote>
0080 * If you are formatting multiple numbers, it is
0081 * more efficient to get the format and use it multiple times so that
0082 * the system doesn't have to fetch the information about the local
0083 * language and country conventions multiple times.
0084 * <blockquote>
0085 * <pre>
0086 * NumberFormat nf = NumberFormat.getInstance();
0087 * for (int i = 0; i < myNumber.length; ++i) {
0088 * output.println(nf.format(myNumber[i]) + "; ");
0089 * }
0090 * </pre>
0091 * </blockquote>
0092 * To format a number for a different Locale, specify it in the
0093 * call to <code>getInstance</code>.
0094 * <blockquote>
0095 * <pre>
0096 * NumberFormat nf = NumberFormat.getInstance(Locale.FRENCH);
0097 * </pre>
0098 * </blockquote>
0099 * You can also use a <code>NumberFormat</code> to parse numbers:
0100 * <blockquote>
0101 * <pre>
0102 * myNumber = nf.parse(myString);
0103 * </pre>
0104 * </blockquote>
0105 * Use <code>getInstance</code> or <code>getNumberInstance</code> to get the
0106 * normal number format. Use <code>getIntegerInstance</code> to get an
0107 * integer number format. Use <code>getCurrencyInstance</code> to get the
0108 * currency number format. And use <code>getPercentInstance</code> to get a
0109 * format for displaying percentages. With this format, a fraction like
0110 * 0.53 is displayed as 53%.
0111 *
0112 * <p>
0113 * You can also control the display of numbers with such methods as
0114 * <code>setMinimumFractionDigits</code>.
0115 * If you want even more control over the format or parsing,
0116 * or want to give your users more control,
0117 * you can try casting the <code>NumberFormat</code> you get from the factory methods
0118 * to a <code>DecimalFormat</code>. This will work for the vast majority
0119 * of locales; just remember to put it in a <code>try</code> block in case you
0120 * encounter an unusual one.
0121 *
0122 * <p>
0123 * NumberFormat and DecimalFormat are designed such that some controls
0124 * work for formatting and others work for parsing. The following is
0125 * the detailed description for each these control methods,
0126 * <p>
0127 * setParseIntegerOnly : only affects parsing, e.g.
0128 * if true, "3456.78" -> 3456 (and leaves the parse position just after index 6)
0129 * if false, "3456.78" -> 3456.78 (and leaves the parse position just after index 8)
0130 * This is independent of formatting. If you want to not show a decimal point
0131 * where there might be no digits after the decimal point, use
0132 * setDecimalSeparatorAlwaysShown.
0133 * <p>
0134 * setDecimalSeparatorAlwaysShown : only affects formatting, and only where
0135 * there might be no digits after the decimal point, such as with a pattern
0136 * like "#,##0.##", e.g.,
0137 * if true, 3456.00 -> "3,456."
0138 * if false, 3456.00 -> "3456"
0139 * This is independent of parsing. If you want parsing to stop at the decimal
0140 * point, use setParseIntegerOnly.
0141 *
0142 * <p>
0143 * You can also use forms of the <code>parse</code> and <code>format</code>
0144 * methods with <code>ParsePosition</code> and <code>FieldPosition</code> to
0145 * allow you to:
0146 * <ul>
0147 * <li> progressively parse through pieces of a string
0148 * <li> align the decimal point and other areas
0149 * </ul>
0150 * For example, you can align numbers in two ways:
0151 * <ol>
0152 * <li> If you are using a monospaced font with spacing for alignment,
0153 * you can pass the <code>FieldPosition</code> in your format call, with
0154 * <code>field</code> = <code>INTEGER_FIELD</code>. On output,
0155 * <code>getEndIndex</code> will be set to the offset between the
0156 * last character of the integer and the decimal. Add
0157 * (desiredSpaceCount - getEndIndex) spaces at the front of the string.
0158 *
0159 * <li> If you are using proportional fonts,
0160 * instead of padding with spaces, measure the width
0161 * of the string in pixels from the start to <code>getEndIndex</code>.
0162 * Then move the pen by
0163 * (desiredPixelWidth - widthToAlignmentPoint) before drawing the text.
0164 * It also works where there is no decimal, but possibly additional
0165 * characters at the end, e.g., with parentheses in negative
0166 * numbers: "(12)" for -12.
0167 * </ol>
0168 *
0169 * <h4><a name="synchronization">Synchronization</a></h4>
0170 *
0171 * <p>
0172 * Number formats are generally not synchronized.
0173 * It is recommended to create separate format instances for each thread.
0174 * If multiple threads access a format concurrently, it must be synchronized
0175 * externally.
0176 *
0177 * @see DecimalFormat
0178 * @see ChoiceFormat
0179 * @version 1.80, 05/05/07
0180 * @author Mark Davis
0181 * @author Helena Shih
0182 */
0183 public abstract class NumberFormat extends Format {
0184
0185 /**
0186 * Field constant used to construct a FieldPosition object. Signifies that
0187 * the position of the integer part of a formatted number should be returned.
0188 * @see java.text.FieldPosition
0189 */
0190 public static final int INTEGER_FIELD = 0;
0191
0192 /**
0193 * Field constant used to construct a FieldPosition object. Signifies that
0194 * the position of the fraction part of a formatted number should be returned.
0195 * @see java.text.FieldPosition
0196 */
0197 public static final int FRACTION_FIELD = 1;
0198
0199 /**
0200 * Sole constructor. (For invocation by subclass constructors, typically
0201 * implicit.)
0202 */
0203 protected NumberFormat() {
0204 }
0205
0206 /**
0207 * Formats a number and appends the resulting text to the given string
0208 * buffer.
0209 * The number can be of any subclass of {@link java.lang.Number}.
0210 * <p>
0211 * This implementation extracts the number's value using
0212 * {@link java.lang.Number#longValue()} for all integral type values that
0213 * can be converted to <code>long</code> without loss of information,
0214 * including <code>BigInteger</code> values with a
0215 * {@link java.math.BigInteger#bitLength() bit length} of less than 64,
0216 * and {@link java.lang.Number#doubleValue()} for all other types. It
0217 * then calls
0218 * {@link #format(long,java.lang.StringBuffer,java.text.FieldPosition)}
0219 * or {@link #format(double,java.lang.StringBuffer,java.text.FieldPosition)}.
0220 * This may result in loss of magnitude information and precision for
0221 * <code>BigInteger</code> and <code>BigDecimal</code> values.
0222 * @param number the number to format
0223 * @param toAppendTo the <code>StringBuffer</code> to which the formatted
0224 * text is to be appended
0225 * @param pos On input: an alignment field, if desired.
0226 * On output: the offsets of the alignment field.
0227 * @return the value passed in as <code>toAppendTo</code>
0228 * @exception IllegalArgumentException if <code>number</code> is
0229 * null or not an instance of <code>Number</code>.
0230 * @exception NullPointerException if <code>toAppendTo</code> or
0231 * <code>pos</code> is null
0232 * @exception ArithmeticException if rounding is needed with rounding
0233 * mode being set to RoundingMode.UNNECESSARY
0234 * @see java.text.FieldPosition
0235 */
0236 public StringBuffer format(Object number, StringBuffer toAppendTo,
0237 FieldPosition pos) {
0238 if (number instanceof Long
0239 || number instanceof Integer
0240 || number instanceof Short
0241 || number instanceof Byte
0242 || number instanceof AtomicInteger
0243 || number instanceof AtomicLong
0244 || (number instanceof BigInteger && ((BigInteger) number)
0245 .bitLength() < 64)) {
0246 return format(((Number) number).longValue(), toAppendTo,
0247 pos);
0248 } else if (number instanceof Number) {
0249 return format(((Number) number).doubleValue(), toAppendTo,
0250 pos);
0251 } else {
0252 throw new IllegalArgumentException(
0253 "Cannot format given Object as a Number");
0254 }
0255 }
0256
0257 /**
0258 * Parses text from a string to produce a <code>Number</code>.
0259 * <p>
0260 * The method attempts to parse text starting at the index given by
0261 * <code>pos</code>.
0262 * If parsing succeeds, then the index of <code>pos</code> is updated
0263 * to the index after the last character used (parsing does not necessarily
0264 * use all characters up to the end of the string), and the parsed
0265 * number is returned. The updated <code>pos</code> can be used to
0266 * indicate the starting point for the next call to this method.
0267 * If an error occurs, then the index of <code>pos</code> is not
0268 * changed, the error index of <code>pos</code> is set to the index of
0269 * the character where the error occurred, and null is returned.
0270 * <p>
0271 * See the {@link #parse(String, ParsePosition)} method for more information
0272 * on number parsing.
0273 *
0274 * @param source A <code>String</code>, part of which should be parsed.
0275 * @param pos A <code>ParsePosition</code> object with index and error
0276 * index information as described above.
0277 * @return A <code>Number</code> parsed from the string. In case of
0278 * error, returns null.
0279 * @exception NullPointerException if <code>pos</code> is null.
0280 */
0281 public final Object parseObject(String source, ParsePosition pos) {
0282 return parse(source, pos);
0283 }
0284
0285 /**
0286 * Specialization of format.
0287 * @exception ArithmeticException if rounding is needed with rounding
0288 * mode being set to RoundingMode.UNNECESSARY
0289 * @see java.text.Format#format
0290 */
0291 public final String format(double number) {
0292 return format(number, new StringBuffer(),
0293 DontCareFieldPosition.INSTANCE).toString();
0294 }
0295
0296 /**
0297 * Specialization of format.
0298 * @exception ArithmeticException if rounding is needed with rounding
0299 * mode being set to RoundingMode.UNNECESSARY
0300 * @see java.text.Format#format
0301 */
0302 public final String format(long number) {
0303 return format(number, new StringBuffer(),
0304 DontCareFieldPosition.INSTANCE).toString();
0305 }
0306
0307 /**
0308 * Specialization of format.
0309 * @exception ArithmeticException if rounding is needed with rounding
0310 * mode being set to RoundingMode.UNNECESSARY
0311 * @see java.text.Format#format
0312 */
0313 public abstract StringBuffer format(double number,
0314 StringBuffer toAppendTo, FieldPosition pos);
0315
0316 /**
0317 * Specialization of format.
0318 * @exception ArithmeticException if rounding is needed with rounding
0319 * mode being set to RoundingMode.UNNECESSARY
0320 * @see java.text.Format#format
0321 */
0322 public abstract StringBuffer format(long number,
0323 StringBuffer toAppendTo, FieldPosition pos);
0324
0325 /**
0326 * Returns a Long if possible (e.g., within the range [Long.MIN_VALUE,
0327 * Long.MAX_VALUE] and with no decimals), otherwise a Double.
0328 * If IntegerOnly is set, will stop at a decimal
0329 * point (or equivalent; e.g., for rational numbers "1 2/3", will stop
0330 * after the 1).
0331 * Does not throw an exception; if no object can be parsed, index is
0332 * unchanged!
0333 * @see java.text.NumberFormat#isParseIntegerOnly
0334 * @see java.text.Format#parseObject
0335 */
0336 public abstract Number parse(String source,
0337 ParsePosition parsePosition);
0338
0339 /**
0340 * Parses text from the beginning of the given string to produce a number.
0341 * The method may not use the entire text of the given string.
0342 * <p>
0343 * See the {@link #parse(String, ParsePosition)} method for more information
0344 * on number parsing.
0345 *
0346 * @param source A <code>String</code> whose beginning should be parsed.
0347 * @return A <code>Number</code> parsed from the string.
0348 * @exception ParseException if the beginning of the specified string
0349 * cannot be parsed.
0350 */
0351 public Number parse(String source) throws ParseException {
0352 ParsePosition parsePosition = new ParsePosition(0);
0353 Number result = parse(source, parsePosition);
0354 if (parsePosition.index == 0) {
0355 throw new ParseException("Unparseable number: \"" + source
0356 + "\"", parsePosition.errorIndex);
0357 }
0358 return result;
0359 }
0360
0361 /**
0362 * Returns true if this format will parse numbers as integers only.
0363 * For example in the English locale, with ParseIntegerOnly true, the
0364 * string "1234." would be parsed as the integer value 1234 and parsing
0365 * would stop at the "." character. Of course, the exact format accepted
0366 * by the parse operation is locale dependant and determined by sub-classes
0367 * of NumberFormat.
0368 */
0369 public boolean isParseIntegerOnly() {
0370 return parseIntegerOnly;
0371 }
0372
0373 /**
0374 * Sets whether or not numbers should be parsed as integers only.
0375 * @see #isParseIntegerOnly
0376 */
0377 public void setParseIntegerOnly(boolean value) {
0378 parseIntegerOnly = value;
0379 }
0380
0381 //============== Locale Stuff =====================
0382
0383 /**
0384 * Returns a general-purpose number format for the current default locale.
0385 * This is the same as calling
0386 * {@link #getNumberInstance() getNumberInstance()}.
0387 */
0388 public final static NumberFormat getInstance() {
0389 return getInstance(Locale.getDefault(), NUMBERSTYLE);
0390 }
0391
0392 /**
0393 * Returns a general-purpose number format for the specified locale.
0394 * This is the same as calling
0395 * {@link #getNumberInstance(java.util.Locale) getNumberInstance(inLocale)}.
0396 */
0397 public static NumberFormat getInstance(Locale inLocale) {
0398 return getInstance(inLocale, NUMBERSTYLE);
0399 }
0400
0401 /**
0402 * Returns a general-purpose number format for the current default locale.
0403 */
0404 public final static NumberFormat getNumberInstance() {
0405 return getInstance(Locale.getDefault(), NUMBERSTYLE);
0406 }
0407
0408 /**
0409 * Returns a general-purpose number format for the specified locale.
0410 */
0411 public static NumberFormat getNumberInstance(Locale inLocale) {
0412 return getInstance(inLocale, NUMBERSTYLE);
0413 }
0414
0415 /**
0416 * Returns an integer number format for the current default locale. The
0417 * returned number format is configured to round floating point numbers
0418 * to the nearest integer using half-even rounding (see {@link
0419 * java.math.RoundingMode#HALF_EVEN RoundingMode.HALF_EVEN}) for formatting,
0420 * and to parse only the integer part of an input string (see {@link
0421 * #isParseIntegerOnly isParseIntegerOnly}).
0422 *
0423 * @see #getRoundingMode()
0424 * @return a number format for integer values
0425 * @since 1.4
0426 */
0427 public final static NumberFormat getIntegerInstance() {
0428 return getInstance(Locale.getDefault(), INTEGERSTYLE);
0429 }
0430
0431 /**
0432 * Returns an integer number format for the specified locale. The
0433 * returned number format is configured to round floating point numbers
0434 * to the nearest integer using half-even rounding (see {@link
0435 * java.math.RoundingMode#HALF_EVEN RoundingMode.HALF_EVEN}) for formatting,
0436 * and to parse only the integer part of an input string (see {@link
0437 * #isParseIntegerOnly isParseIntegerOnly}).
0438 *
0439 * @see #getRoundingMode()
0440 * @return a number format for integer values
0441 * @since 1.4
0442 */
0443 public static NumberFormat getIntegerInstance(Locale inLocale) {
0444 return getInstance(inLocale, INTEGERSTYLE);
0445 }
0446
0447 /**
0448 * Returns a currency format for the current default locale.
0449 */
0450 public final static NumberFormat getCurrencyInstance() {
0451 return getInstance(Locale.getDefault(), CURRENCYSTYLE);
0452 }
0453
0454 /**
0455 * Returns a currency format for the specified locale.
0456 */
0457 public static NumberFormat getCurrencyInstance(Locale inLocale) {
0458 return getInstance(inLocale, CURRENCYSTYLE);
0459 }
0460
0461 /**
0462 * Returns a percentage format for the current default locale.
0463 */
0464 public final static NumberFormat getPercentInstance() {
0465 return getInstance(Locale.getDefault(), PERCENTSTYLE);
0466 }
0467
0468 /**
0469 * Returns a percentage format for the specified locale.
0470 */
0471 public static NumberFormat getPercentInstance(Locale inLocale) {
0472 return getInstance(inLocale, PERCENTSTYLE);
0473 }
0474
0475 /**
0476 * Returns a scientific format for the current default locale.
0477 */
0478 /*public*/final static NumberFormat getScientificInstance() {
0479 return getInstance(Locale.getDefault(), SCIENTIFICSTYLE);
0480 }
0481
0482 /**
0483 * Returns a scientific format for the specified locale.
0484 */
0485 /*public*/static NumberFormat getScientificInstance(Locale inLocale) {
0486 return getInstance(inLocale, SCIENTIFICSTYLE);
0487 }
0488
0489 /**
0490 * Returns an array of all locales for which the
0491 * <code>get*Instance</code> methods of this class can return
0492 * localized instances.
0493 * The returned array represents the union of locales supported by the Java
0494 * runtime and by installed
0495 * {@link java.text.spi.NumberFormatProvider NumberFormatProvider} implementations.
0496 * It must contain at least a <code>Locale</code> instance equal to
0497 * {@link java.util.Locale#US Locale.US}.
0498 *
0499 * @return An array of locales for which localized
0500 * <code>NumberFormat</code> instances are available.
0501 */
0502 public static Locale[] getAvailableLocales() {
0503 LocaleServiceProviderPool pool = LocaleServiceProviderPool
0504 .getPool(NumberFormatProvider.class);
0505 return pool.getAvailableLocales();
0506 }
0507
0508 /**
0509 * Overrides hashCode
0510 */
0511 public int hashCode() {
0512 return maximumIntegerDigits * 37 + maxFractionDigits;
0513 // just enough fields for a reasonable distribution
0514 }
0515
0516 /**
0517 * Overrides equals
0518 */
0519 public boolean equals(Object obj) {
0520 if (obj == null) {
0521 return false;
0522 }
0523 if (this == obj) {
0524 return true;
0525 }
0526 if (getClass() != obj.getClass()) {
0527 return false;
0528 }
0529 NumberFormat other = (NumberFormat) obj;
0530 return (maximumIntegerDigits == other.maximumIntegerDigits
0531 && minimumIntegerDigits == other.minimumIntegerDigits
0532 && maximumFractionDigits == other.maximumFractionDigits
0533 && minimumFractionDigits == other.minimumFractionDigits
0534 && groupingUsed == other.groupingUsed && parseIntegerOnly == other.parseIntegerOnly);
0535 }
0536
0537 /**
0538 * Overrides Cloneable
0539 */
0540 public Object clone() {
0541 NumberFormat other = (NumberFormat) super .clone();
0542 return other;
0543 }
0544
0545 /**
0546 * Returns true if grouping is used in this format. For example, in the
0547 * English locale, with grouping on, the number 1234567 might be formatted
0548 * as "1,234,567". The grouping separator as well as the size of each group
0549 * is locale dependant and is determined by sub-classes of NumberFormat.
0550 * @see #setGroupingUsed
0551 */
0552 public boolean isGroupingUsed() {
0553 return groupingUsed;
0554 }
0555
0556 /**
0557 * Set whether or not grouping will be used in this format.
0558 * @see #isGroupingUsed
0559 */
0560 public void setGroupingUsed(boolean newValue) {
0561 groupingUsed = newValue;
0562 }
0563
0564 /**
0565 * Returns the maximum number of digits allowed in the integer portion of a
0566 * number.
0567 * @see #setMaximumIntegerDigits
0568 */
0569 public int getMaximumIntegerDigits() {
0570 return maximumIntegerDigits;
0571 }
0572
0573 /**
0574 * Sets the maximum number of digits allowed in the integer portion of a
0575 * number. maximumIntegerDigits must be >= minimumIntegerDigits. If the
0576 * new value for maximumIntegerDigits is less than the current value
0577 * of minimumIntegerDigits, then minimumIntegerDigits will also be set to
0578 * the new value.
0579 * @param newValue the maximum number of integer digits to be shown; if
0580 * less than zero, then zero is used. The concrete subclass may enforce an
0581 * upper limit to this value appropriate to the numeric type being formatted.
0582 * @see #getMaximumIntegerDigits
0583 */
0584 public void setMaximumIntegerDigits(int newValue) {
0585 maximumIntegerDigits = Math.max(0, newValue);
0586 if (minimumIntegerDigits > maximumIntegerDigits) {
0587 minimumIntegerDigits = maximumIntegerDigits;
0588 }
0589 }
0590
0591 /**
0592 * Returns the minimum number of digits allowed in the integer portion of a
0593 * number.
0594 * @see #setMinimumIntegerDigits
0595 */
0596 public int getMinimumIntegerDigits() {
0597 return minimumIntegerDigits;
0598 }
0599
0600 /**
0601 * Sets the minimum number of digits allowed in the integer portion of a
0602 * number. minimumIntegerDigits must be <= maximumIntegerDigits. If the
0603 * new value for minimumIntegerDigits exceeds the current value
0604 * of maximumIntegerDigits, then maximumIntegerDigits will also be set to
0605 * the new value
0606 * @param newValue the minimum number of integer digits to be shown; if
0607 * less than zero, then zero is used. The concrete subclass may enforce an
0608 * upper limit to this value appropriate to the numeric type being formatted.
0609 * @see #getMinimumIntegerDigits
0610 */
0611 public void setMinimumIntegerDigits(int newValue) {
0612 minimumIntegerDigits = Math.max(0, newValue);
0613 if (minimumIntegerDigits > maximumIntegerDigits) {
0614 maximumIntegerDigits = minimumIntegerDigits;
0615 }
0616 }
0617
0618 /**
0619 * Returns the maximum number of digits allowed in the fraction portion of a
0620 * number.
0621 * @see #setMaximumFractionDigits
0622 */
0623 public int getMaximumFractionDigits() {
0624 return maximumFractionDigits;
0625 }
0626
0627 /**
0628 * Sets the maximum number of digits allowed in the fraction portion of a
0629 * number. maximumFractionDigits must be >= minimumFractionDigits. If the
0630 * new value for maximumFractionDigits is less than the current value
0631 * of minimumFractionDigits, then minimumFractionDigits will also be set to
0632 * the new value.
0633 * @param newValue the maximum number of fraction digits to be shown; if
0634 * less than zero, then zero is used. The concrete subclass may enforce an
0635 * upper limit to this value appropriate to the numeric type being formatted.
0636 * @see #getMaximumFractionDigits
0637 */
0638 public void setMaximumFractionDigits(int newValue) {
0639 maximumFractionDigits = Math.max(0, newValue);
0640 if (maximumFractionDigits < minimumFractionDigits) {
0641 minimumFractionDigits = maximumFractionDigits;
0642 }
0643 }
0644
0645 /**
0646 * Returns the minimum number of digits allowed in the fraction portion of a
0647 * number.
0648 * @see #setMinimumFractionDigits
0649 */
0650 public int getMinimumFractionDigits() {
0651 return minimumFractionDigits;
0652 }
0653
0654 /**
0655 * Sets the minimum number of digits allowed in the fraction portion of a
0656 * number. minimumFractionDigits must be <= maximumFractionDigits. If the
0657 * new value for minimumFractionDigits exceeds the current value
0658 * of maximumFractionDigits, then maximumIntegerDigits will also be set to
0659 * the new value
0660 * @param newValue the minimum number of fraction digits to be shown; if
0661 * less than zero, then zero is used. The concrete subclass may enforce an
0662 * upper limit to this value appropriate to the numeric type being formatted.
0663 * @see #getMinimumFractionDigits
0664 */
0665 public void setMinimumFractionDigits(int newValue) {
0666 minimumFractionDigits = Math.max(0, newValue);
0667 if (maximumFractionDigits < minimumFractionDigits) {
0668 maximumFractionDigits = minimumFractionDigits;
0669 }
0670 }
0671
0672 /**
0673 * Gets the currency used by this number format when formatting
0674 * currency values. The initial value is derived in a locale dependent
0675 * way. The returned value may be null if no valid
0676 * currency could be determined and no currency has been set using
0677 * {@link #setCurrency(java.util.Currency) setCurrency}.
0678 * <p>
0679 * The default implementation throws
0680 * <code>UnsupportedOperationException</code>.
0681 *
0682 * @return the currency used by this number format, or <code>null</code>
0683 * @exception UnsupportedOperationException if the number format class
0684 * doesn't implement currency formatting
0685 * @since 1.4
0686 */
0687 public Currency getCurrency() {
0688 throw new UnsupportedOperationException();
0689 }
0690
0691 /**
0692 * Sets the currency used by this number format when formatting
0693 * currency values. This does not update the minimum or maximum
0694 * number of fraction digits used by the number format.
0695 * <p>
0696 * The default implementation throws
0697 * <code>UnsupportedOperationException</code>.
0698 *
0699 * @param currency the new currency to be used by this number format
0700 * @exception UnsupportedOperationException if the number format class
0701 * doesn't implement currency formatting
0702 * @exception NullPointerException if <code>currency</code> is null
0703 * @since 1.4
0704 */
0705 public void setCurrency(Currency currency) {
0706 throw new UnsupportedOperationException();
0707 }
0708
0709 /**
0710 * Gets the {@link java.math.RoundingMode} used in this NumberFormat.
0711 * The default implementation of this method in NumberFormat
0712 * always throws {@link java.lang.UnsupportedOperationException}.
0713 * Subclasses which handle different rounding modes should override
0714 * this method.
0715 *
0716 * @exception UnsupportedOperationException The default implementation
0717 * always throws this exception
0718 * @return The <code>RoundingMode</code> used for this NumberFormat.
0719 * @see #setRoundingMode(RoundingMode)
0720 * @since 1.6
0721 */
0722 public RoundingMode getRoundingMode() {
0723 throw new UnsupportedOperationException();
0724 }
0725
0726 /**
0727 * Sets the {@link java.math.RoundingMode} used in this NumberFormat.
0728 * The default implementation of this method in NumberFormat always
0729 * throws {@link java.lang.UnsupportedOperationException}.
0730 * Subclasses which handle different rounding modes should override
0731 * this method.
0732 *
0733 * @exception UnsupportedOperationException The default implementation
0734 * always throws this exception
0735 * @exception NullPointerException if <code>roundingMode</code> is null
0736 * @param roundingMode The <code>RoundingMode</code> to be used
0737 * @see #getRoundingMode()
0738 * @since 1.6
0739 */
0740 public void setRoundingMode(RoundingMode roundingMode) {
0741 throw new UnsupportedOperationException();
0742 }
0743
0744 // =======================privates===============================
0745
0746 private static NumberFormat getInstance(Locale desiredLocale,
0747 int choice) {
0748 // Check whether a provider can provide an implementation that's closer
0749 // to the requested locale than what the Java runtime itself can provide.
0750 LocaleServiceProviderPool pool = LocaleServiceProviderPool
0751 .getPool(NumberFormatProvider.class);
0752 if (pool.hasProviders()) {
0753 NumberFormat providersInstance = pool.getLocalizedObject(
0754 NumberFormatGetter.INSTANCE, desiredLocale, choice);
0755 if (providersInstance != null) {
0756 return providersInstance;
0757 }
0758 }
0759
0760 /* try the cache first */
0761 String[] numberPatterns = (String[]) cachedLocaleData
0762 .get(desiredLocale);
0763 if (numberPatterns == null) { /* cache miss */
0764 ResourceBundle resource = LocaleData
0765 .getNumberFormatData(desiredLocale);
0766 numberPatterns = resource.getStringArray("NumberPatterns");
0767 /* update cache */
0768 cachedLocaleData.put(desiredLocale, numberPatterns);
0769 }
0770
0771 DecimalFormatSymbols symbols = DecimalFormatSymbols
0772 .getInstance(desiredLocale);
0773 int entry = (choice == INTEGERSTYLE) ? NUMBERSTYLE : choice;
0774 DecimalFormat format = new DecimalFormat(numberPatterns[entry],
0775 symbols);
0776
0777 if (choice == INTEGERSTYLE) {
0778 format.setMaximumFractionDigits(0);
0779 format.setDecimalSeparatorAlwaysShown(false);
0780 format.setParseIntegerOnly(true);
0781 } else if (choice == CURRENCYSTYLE) {
0782 format.adjustForCurrencyDefaultFractionDigits();
0783 }
0784
0785 return format;
0786 }
0787
0788 /**
0789 * First, read in the default serializable data.
0790 *
0791 * Then, if <code>serialVersionOnStream</code> is less than 1, indicating that
0792 * the stream was written by JDK 1.1,
0793 * set the <code>int</code> fields such as <code>maximumIntegerDigits</code>
0794 * to be equal to the <code>byte</code> fields such as <code>maxIntegerDigits</code>,
0795 * since the <code>int</code> fields were not present in JDK 1.1.
0796 * Finally, set serialVersionOnStream back to the maximum allowed value so that
0797 * default serialization will work properly if this object is streamed out again.
0798 *
0799 * <p>If <code>minimumIntegerDigits</code> is greater than
0800 * <code>maximumIntegerDigits</code> or <code>minimumFractionDigits</code>
0801 * is greater than <code>maximumFractionDigits</code>, then the stream data
0802 * is invalid and this method throws an <code>InvalidObjectException</code>.
0803 * In addition, if any of these values is negative, then this method throws
0804 * an <code>InvalidObjectException</code>.
0805 *
0806 * @since 1.2
0807 */
0808 private void readObject(ObjectInputStream stream)
0809 throws IOException, ClassNotFoundException {
0810 stream.defaultReadObject();
0811 if (serialVersionOnStream < 1) {
0812 // Didn't have additional int fields, reassign to use them.
0813 maximumIntegerDigits = maxIntegerDigits;
0814 minimumIntegerDigits = minIntegerDigits;
0815 maximumFractionDigits = maxFractionDigits;
0816 minimumFractionDigits = minFractionDigits;
0817 }
0818 if (minimumIntegerDigits > maximumIntegerDigits
0819 || minimumFractionDigits > maximumFractionDigits
0820 || minimumIntegerDigits < 0
0821 || minimumFractionDigits < 0) {
0822 throw new InvalidObjectException(
0823 "Digit count range invalid");
0824 }
0825 serialVersionOnStream = currentSerialVersion;
0826 }
0827
0828 /**
0829 * Write out the default serializable data, after first setting
0830 * the <code>byte</code> fields such as <code>maxIntegerDigits</code> to be
0831 * equal to the <code>int</code> fields such as <code>maximumIntegerDigits</code>
0832 * (or to <code>Byte.MAX_VALUE</code>, whichever is smaller), for compatibility
0833 * with the JDK 1.1 version of the stream format.
0834 *
0835 * @since 1.2
0836 */
0837 private void writeObject(ObjectOutputStream stream)
0838 throws IOException {
0839 maxIntegerDigits = (maximumIntegerDigits > Byte.MAX_VALUE) ? Byte.MAX_VALUE
0840 : (byte) maximumIntegerDigits;
0841 minIntegerDigits = (minimumIntegerDigits > Byte.MAX_VALUE) ? Byte.MAX_VALUE
0842 : (byte) minimumIntegerDigits;
0843 maxFractionDigits = (maximumFractionDigits > Byte.MAX_VALUE) ? Byte.MAX_VALUE
0844 : (byte) maximumFractionDigits;
0845 minFractionDigits = (minimumFractionDigits > Byte.MAX_VALUE) ? Byte.MAX_VALUE
0846 : (byte) minimumFractionDigits;
0847 stream.defaultWriteObject();
0848 }
0849
0850 /**
0851 * Cache to hold the NumberPatterns of a Locale.
0852 */
0853 private static final Hashtable cachedLocaleData = new Hashtable(3);
0854
0855 // Constants used by factory methods to specify a style of format.
0856 private static final int NUMBERSTYLE = 0;
0857 private static final int CURRENCYSTYLE = 1;
0858 private static final int PERCENTSTYLE = 2;
0859 private static final int SCIENTIFICSTYLE = 3;
0860 private static final int INTEGERSTYLE = 4;
0861
0862 /**
0863 * True if the grouping (i.e. thousands) separator is used when
0864 * formatting and parsing numbers.
0865 *
0866 * @serial
0867 * @see #isGroupingUsed
0868 */
0869 private boolean groupingUsed = true;
0870
0871 /**
0872 * The maximum number of digits allowed in the integer portion of a
0873 * number. <code>maxIntegerDigits</code> must be greater than or equal to
0874 * <code>minIntegerDigits</code>.
0875 * <p>
0876 * <strong>Note:</strong> This field exists only for serialization
0877 * compatibility with JDK 1.1. In Java platform 2 v1.2 and higher, the new
0878 * <code>int</code> field <code>maximumIntegerDigits</code> is used instead.
0879 * When writing to a stream, <code>maxIntegerDigits</code> is set to
0880 * <code>maximumIntegerDigits</code> or <code>Byte.MAX_VALUE</code>,
0881 * whichever is smaller. When reading from a stream, this field is used
0882 * only if <code>serialVersionOnStream</code> is less than 1.
0883 *
0884 * @serial
0885 * @see #getMaximumIntegerDigits
0886 */
0887 private byte maxIntegerDigits = 40;
0888
0889 /**
0890 * The minimum number of digits allowed in the integer portion of a
0891 * number. <code>minimumIntegerDigits</code> must be less than or equal to
0892 * <code>maximumIntegerDigits</code>.
0893 * <p>
0894 * <strong>Note:</strong> This field exists only for serialization
0895 * compatibility with JDK 1.1. In Java platform 2 v1.2 and higher, the new
0896 * <code>int</code> field <code>minimumIntegerDigits</code> is used instead.
0897 * When writing to a stream, <code>minIntegerDigits</code> is set to
0898 * <code>minimumIntegerDigits</code> or <code>Byte.MAX_VALUE</code>,
0899 * whichever is smaller. When reading from a stream, this field is used
0900 * only if <code>serialVersionOnStream</code> is less than 1.
0901 *
0902 * @serial
0903 * @see #getMinimumIntegerDigits
0904 */
0905 private byte minIntegerDigits = 1;
0906
0907 /**
0908 * The maximum number of digits allowed in the fractional portion of a
0909 * number. <code>maximumFractionDigits</code> must be greater than or equal to
0910 * <code>minimumFractionDigits</code>.
0911 * <p>
0912 * <strong>Note:</strong> This field exists only for serialization
0913 * compatibility with JDK 1.1. In Java platform 2 v1.2 and higher, the new
0914 * <code>int</code> field <code>maximumFractionDigits</code> is used instead.
0915 * When writing to a stream, <code>maxFractionDigits</code> is set to
0916 * <code>maximumFractionDigits</code> or <code>Byte.MAX_VALUE</code>,
0917 * whichever is smaller. When reading from a stream, this field is used
0918 * only if <code>serialVersionOnStream</code> is less than 1.
0919 *
0920 * @serial
0921 * @see #getMaximumFractionDigits
0922 */
0923 private byte maxFractionDigits = 3; // invariant, >= minFractionDigits
0924
0925 /**
0926 * The minimum number of digits allowed in the fractional portion of a
0927 * number. <code>minimumFractionDigits</code> must be less than or equal to
0928 * <code>maximumFractionDigits</code>.
0929 * <p>
0930 * <strong>Note:</strong> This field exists only for serialization
0931 * compatibility with JDK 1.1. In Java platform 2 v1.2 and higher, the new
0932 * <code>int</code> field <code>minimumFractionDigits</code> is used instead.
0933 * When writing to a stream, <code>minFractionDigits</code> is set to
0934 * <code>minimumFractionDigits</code> or <code>Byte.MAX_VALUE</code>,
0935 * whichever is smaller. When reading from a stream, this field is used
0936 * only if <code>serialVersionOnStream</code> is less than 1.
0937 *
0938 * @serial
0939 * @see #getMinimumFractionDigits
0940 */
0941 private byte minFractionDigits = 0;
0942
0943 /**
0944 * True if this format will parse numbers as integers only.
0945 *
0946 * @serial
0947 * @see #isParseIntegerOnly
0948 */
0949 private boolean parseIntegerOnly = false;
0950
0951 // new fields for 1.2. byte is too small for integer digits.
0952
0953 /**
0954 * The maximum number of digits allowed in the integer portion of a
0955 * number. <code>maximumIntegerDigits</code> must be greater than or equal to
0956 * <code>minimumIntegerDigits</code>.
0957 *
0958 * @serial
0959 * @since 1.2
0960 * @see #getMaximumIntegerDigits
0961 */
0962 private int maximumIntegerDigits = 40;
0963
0964 /**
0965 * The minimum number of digits allowed in the integer portion of a
0966 * number. <code>minimumIntegerDigits</code> must be less than or equal to
0967 * <code>maximumIntegerDigits</code>.
0968 *
0969 * @serial
0970 * @since 1.2
0971 * @see #getMinimumIntegerDigits
0972 */
0973 private int minimumIntegerDigits = 1;
0974
0975 /**
0976 * The maximum number of digits allowed in the fractional portion of a
0977 * number. <code>maximumFractionDigits</code> must be greater than or equal to
0978 * <code>minimumFractionDigits</code>.
0979 *
0980 * @serial
0981 * @since 1.2
0982 * @see #getMaximumFractionDigits
0983 */
0984 private int maximumFractionDigits = 3; // invariant, >= minFractionDigits
0985
0986 /**
0987 * The minimum number of digits allowed in the fractional portion of a
0988 * number. <code>minimumFractionDigits</code> must be less than or equal to
0989 * <code>maximumFractionDigits</code>.
0990 *
0991 * @serial
0992 * @since 1.2
0993 * @see #getMinimumFractionDigits
0994 */
0995 private int minimumFractionDigits = 0;
0996
0997 static final int currentSerialVersion = 1;
0998
0999 /**
1000 * Describes the version of <code>NumberFormat</code> present on the stream.
1001 * Possible values are:
1002 * <ul>
1003 * <li><b>0</b> (or uninitialized): the JDK 1.1 version of the stream format.
1004 * In this version, the <code>int</code> fields such as
1005 * <code>maximumIntegerDigits</code> were not present, and the <code>byte</code>
1006 * fields such as <code>maxIntegerDigits</code> are used instead.
1007 *
1008 * <li><b>1</b>: the 1.2 version of the stream format. The values of the
1009 * <code>byte</code> fields such as <code>maxIntegerDigits</code> are ignored,
1010 * and the <code>int</code> fields such as <code>maximumIntegerDigits</code>
1011 * are used instead.
1012 * </ul>
1013 * When streaming out a <code>NumberFormat</code>, the most recent format
1014 * (corresponding to the highest allowable <code>serialVersionOnStream</code>)
1015 * is always written.
1016 *
1017 * @serial
1018 * @since 1.2
1019 */
1020 private int serialVersionOnStream = currentSerialVersion;
1021
1022 // Removed "implements Cloneable" clause. Needs to update serialization
1023 // ID for backward compatibility.
1024 static final long serialVersionUID = -2308460125733713944L;
1025
1026 //
1027 // class for AttributedCharacterIterator attributes
1028 //
1029 /**
1030 * Defines constants that are used as attribute keys in the
1031 * <code>AttributedCharacterIterator</code> returned
1032 * from <code>NumberFormat.formatToCharacterIterator</code> and as
1033 * field identifiers in <code>FieldPosition</code>.
1034 *
1035 * @since 1.4
1036 */
1037 public static class Field extends Format.Field {
1038
1039 // Proclaim serial compatibility with 1.4 FCS
1040 private static final long serialVersionUID = 7494728892700160890L;
1041
1042 // table of all instances in this class, used by readResolve
1043 private static final Map instanceMap = new HashMap(11);
1044
1045 /**
1046 * Creates a Field instance with the specified
1047 * name.
1048 *
1049 * @param name Name of the attribute
1050 */
1051 protected Field(String name) {
1052 super (name);
1053 if (this .getClass() == NumberFormat.Field.class) {
1054 instanceMap.put(name, this );
1055 }
1056 }
1057
1058 /**
1059 * Resolves instances being deserialized to the predefined constants.
1060 *
1061 * @throws InvalidObjectException if the constant could not be resolved.
1062 * @return resolved NumberFormat.Field constant
1063 */
1064 protected Object readResolve() throws InvalidObjectException {
1065 if (this .getClass() != NumberFormat.Field.class) {
1066 throw new InvalidObjectException(
1067 "subclass didn't correctly implement readResolve");
1068 }
1069
1070 Object instance = instanceMap.get(getName());
1071 if (instance != null) {
1072 return instance;
1073 } else {
1074 throw new InvalidObjectException(
1075 "unknown attribute name");
1076 }
1077 }
1078
1079 /**
1080 * Constant identifying the integer field.
1081 */
1082 public static final Field INTEGER = new Field("integer");
1083
1084 /**
1085 * Constant identifying the fraction field.
1086 */
1087 public static final Field FRACTION = new Field("fraction");
1088
1089 /**
1090 * Constant identifying the exponent field.
1091 */
1092 public static final Field EXPONENT = new Field("exponent");
1093
1094 /**
1095 * Constant identifying the decimal separator field.
1096 */
1097 public static final Field DECIMAL_SEPARATOR = new Field(
1098 "decimal separator");
1099
1100 /**
1101 * Constant identifying the sign field.
1102 */
1103 public static final Field SIGN = new Field("sign");
1104
1105 /**
1106 * Constant identifying the grouping separator field.
1107 */
1108 public static final Field GROUPING_SEPARATOR = new Field(
1109 "grouping separator");
1110
1111 /**
1112 * Constant identifying the exponent symbol field.
1113 */
1114 public static final Field EXPONENT_SYMBOL = new Field(
1115 "exponent symbol");
1116
1117 /**
1118 * Constant identifying the percent field.
1119 */
1120 public static final Field PERCENT = new Field("percent");
1121
1122 /**
1123 * Constant identifying the permille field.
1124 */
1125 public static final Field PERMILLE = new Field("per mille");
1126
1127 /**
1128 * Constant identifying the currency field.
1129 */
1130 public static final Field CURRENCY = new Field("currency");
1131
1132 /**
1133 * Constant identifying the exponent sign field.
1134 */
1135 public static final Field EXPONENT_SIGN = new Field(
1136 "exponent sign");
1137 }
1138
1139 /**
1140 * Obtains a NumberFormat instance from a NumberFormatProvider implementation.
1141 */
1142 private static class NumberFormatGetter
1143 implements
1144 LocaleServiceProviderPool.LocalizedObjectGetter<NumberFormatProvider, NumberFormat> {
1145 private static final NumberFormatGetter INSTANCE = new NumberFormatGetter();
1146
1147 public NumberFormat getObject(
1148 NumberFormatProvider numberFormatProvider,
1149 Locale locale, String key, Object... params) {
1150 assert params.length == 1;
1151 int choice = (Integer) params[0];
1152
1153 switch (choice) {
1154 case NUMBERSTYLE:
1155 return numberFormatProvider.getNumberInstance(locale);
1156 case PERCENTSTYLE:
1157 return numberFormatProvider.getPercentInstance(locale);
1158 case CURRENCYSTYLE:
1159 return numberFormatProvider.getCurrencyInstance(locale);
1160 case INTEGERSTYLE:
1161 return numberFormatProvider.getIntegerInstance(locale);
1162 default:
1163 assert false : choice;
1164 }
1165
1166 return null;
1167 }
1168 }
1169 }
|