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