source: trunk/gcc/libjava/java/text/NumberFormat.java

Last change on this file was 2, checked in by bird, 22 years ago

Initial revision

  • Property cvs2svn:cvs-rev set to 1.1
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 19.8 KB
Line 
1/* NumberFormat.java -- Formats and parses numbers
2 Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
3
4This file is part of GNU Classpath.
5
6GNU Classpath is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU Classpath is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Classpath; see the file COPYING. If not, write to the
18Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
1902111-1307 USA.
20
21Linking this library statically or dynamically with other modules is
22making a combined work based on this library. Thus, the terms and
23conditions of the GNU General Public License cover the whole
24combination.
25
26As a special exception, the copyright holders of this library give you
27permission to link this library with independent modules to produce an
28executable, regardless of the license terms of these independent
29modules, and to copy and distribute the resulting executable under
30terms of your choice, provided that you also meet, for each linked
31independent module, the terms and conditions of the license of that
32module. An independent module is a module which is not derived from
33or based on this library. If you modify this library, you may extend
34this exception to your version of the library, but you are not
35obligated to do so. If you do not wish to do so, delete this
36exception statement from your version. */
37
38
39package java.text;
40
41import java.util.Locale;
42import java.util.ResourceBundle;
43import java.util.MissingResourceException;
44import java.io.ObjectInputStream;
45import java.io.ObjectOutputStream;
46import java.io.IOException;
47
48/**
49 * This is the abstract superclass of all classes which format and
50 * parse numeric values such as decimal numbers, integers, currency values,
51 * and percentages. These classes perform their parsing and formatting
52 * in a locale specific manner, accounting for such items as differing
53 * currency symbols and thousands separators.
54 * <p>
55 * To create an instance of a concrete subclass of <code>NumberFormat</code>,
56 * do not call a class constructor directly. Instead, use one of the
57 * static factory methods in this class such as
58 * <code>getCurrencyInstance</code>.
59 *
60 * @author Tom Tromey <tromey@cygnus.com>
61 * @author Aaron M. Renn (arenn@urbanophile.com)
62 * @date March 4, 1999
63 */
64/* Written using "Java Class Libraries", 2nd edition, plus online
65 * API docs for JDK 1.2 from http://www.javasoft.com.
66 * Status: Believed complete and correct to 1.2, except getAvailableLocales.
67 */
68public abstract class NumberFormat extends Format implements Cloneable
69{
70 /**
71 * This is a constant used to create a <code>FieldPosition</code> object
72 * that will return the integer portion of a formatted number.
73 */
74 public static final int INTEGER_FIELD = 0;
75
76 /**
77 * This is a constant used to create a <code>FieldPosition</code> object
78 * that will return the fractional portion of a formatted number.
79 */
80 public static final int FRACTION_FIELD = 1;
81
82 /**
83 * This method is a specialization of the format method that performs
84 * a simple formatting of the specified <code>long</code> number.
85 *
86 * @param number The <code>long</code> to format.
87 *
88 * @return The formatted number
89 */
90 public final String format (long number)
91 {
92 StringBuffer sbuf = new StringBuffer(50);
93 format (number, sbuf, null);
94 return sbuf.toString();
95 }
96
97 public final StringBuffer format (Object obj, StringBuffer sbuf,
98 FieldPosition pos)
99 {
100 if (obj instanceof Number)
101 return format(((Number) obj).doubleValue(), sbuf, pos);
102 else
103 throw new IllegalArgumentException
104 ("Cannot format given Object as a Number");
105 }
106
107 /**
108 * This method formats the specified <code>double</code> and appends it to
109 * a <code>StringBuffer</code>.
110 *
111 * @param number The <code>double</code> to format.
112 * @param sb The <code>StringBuffer</code> to append the formatted number to.
113 * @param pos The desired <code>FieldPosition</code>.
114 *
115 * @return The <code>StringBuffer</code> with the appended number.
116 */
117 public abstract StringBuffer format (double number,
118 StringBuffer sbuf, FieldPosition pos);
119
120 /**
121 * This method formats the specified <code>long</code> and appends it to
122 * a <code>StringBuffer</code>.
123 *
124 * @param number The <code>long</code> to format.
125 * @param sb The <code>StringBuffer</code> to append the formatted number to.
126 * @param pos The desired <code>FieldPosition</code>.
127 *
128 * @return The <code>StringBuffer</code> with the appended number.
129 */
130 public abstract StringBuffer format (long number,
131 StringBuffer sbuf, FieldPosition pos);
132
133 /**
134 * This method tests the specified object for equality against this object.
135 * This will be <code>true</code> if the following conditions are met:
136 * <p>
137 * <ul>
138 * <li>The specified object is not <code>null</code>.
139 * <li>The specified object is an instance of <code>NumberFormat</code>.
140 * </ul>
141 * <p>
142 * Since this method does not test much, it is highly advised that
143 * concrete subclasses override this method.
144 *
145 * @param obj The <code>Object</code> to test against equality with
146 * this object.
147 *
148 * @return <code>true</code> if the specified object is equal to
149 * this object, <code>false</code> otherwise.
150 */
151 public boolean equals (Object obj)
152 {
153 if (! (obj instanceof NumberFormat))
154 return false;
155 NumberFormat nf = (NumberFormat) obj;
156 return (groupingUsed == nf.groupingUsed
157 && maximumFractionDigits == nf.maximumFractionDigits
158 && maximumIntegerDigits == nf.maximumIntegerDigits
159 && minimumFractionDigits == nf.minimumFractionDigits
160 && minimumIntegerDigits == nf.minimumIntegerDigits
161 && parseIntegerOnly == nf.parseIntegerOnly);
162 }
163
164 /**
165 * This method returns a list of locales for which concrete instances
166 * of <code>NumberFormat</code> subclasses may be created.
167 *
168 * @return The list of available locales.
169 */
170 public static Locale[] getAvailableLocales ()
171 {
172 Locale[] list = new Locale[1];
173 list[0] = Locale.US;
174 return list;
175 }
176
177 private static final NumberFormat computeInstance (Locale loc,
178 String resource,
179 String def)
180 {
181 ResourceBundle res;
182 try
183 {
184 res = ResourceBundle.getBundle("gnu.java.locale.LocaleInformation",
185 loc);
186 }
187 catch (MissingResourceException x)
188 {
189 res = null;
190 }
191 String fmt;
192 try
193 {
194 fmt = res == null ? def : res.getString(resource);
195 }
196 catch (MissingResourceException x)
197 {
198 fmt = def;
199 }
200 DecimalFormatSymbols dfs = new DecimalFormatSymbols (loc);
201 return new DecimalFormat (fmt, dfs);
202 }
203
204 /**
205 * This method returns an instance of <code>NumberFormat</code> suitable
206 * for formatting and parsing currency values in the default locale.
207 *
208 * @return An instance of <code>NumberFormat</code> for handling currencies.
209 */
210 public static final NumberFormat getCurrencyInstance ()
211 {
212 return getCurrencyInstance (Locale.getDefault());
213 }
214
215 /**
216 * This method returns an instance of <code>NumberFormat</code> suitable
217 * for formatting and parsing currency values in the specified locale.
218 *
219 * @return An instance of <code>NumberFormat</code> for handling currencies.
220 */
221 public static NumberFormat getCurrencyInstance (Locale loc)
222 {
223 return computeInstance (loc, "currencyFormat", "$#,##0.00;($#,##0.00)");
224 }
225
226 /**
227 * This method returns a default instance for the default locale. This
228 * will be a concrete subclass of <code>NumberFormat</code>, but the
229 * actual class returned is dependent on the locale.
230 *
231 * @return An instance of the default <code>NumberFormat</code> class.
232 */
233 public static final NumberFormat getInstance ()
234 {
235 return getInstance (Locale.getDefault());
236 }
237
238 /**
239 * This method returns a default instance for the specified locale. This
240 * will be a concrete subclass of <code>NumberFormat</code>, but the
241 * actual class returned is dependent on the locale.
242 *
243 * @param locale The desired locale.
244 *
245 * @return An instance of the default <code>NumberFormat</code> class.
246 */
247 public static NumberFormat getInstance (Locale loc)
248 {
249 // For now always return a number instance.
250 return getNumberInstance (loc);
251 }
252
253 /**
254 * This method returns the maximum number of digits allowed in the fraction
255 * portion of a number.
256 *
257 * @return The maximum number of digits allowed in the fraction
258 * portion of a number.
259 */
260 public int getMaximumFractionDigits ()
261 {
262 return maximumFractionDigits;
263 }
264
265 /**
266 * This method returns the maximum number of digits allowed in the integer
267 * portion of a number.
268 *
269 * @return The maximum number of digits allowed in the integer
270 * portion of a number.
271 */
272 public int getMaximumIntegerDigits ()
273 {
274 return maximumIntegerDigits;
275 }
276
277 /**
278 * This method returns the minimum number of digits allowed in the fraction
279 * portion of a number.
280 *
281 * @return The minimum number of digits allowed in the fraction
282 * portion of a number.
283 */
284 public int getMinimumFractionDigits ()
285 {
286 return minimumFractionDigits;
287 }
288
289 /**
290 * This method returns the minimum number of digits allowed in the integer
291 * portion of a number.
292 *
293 * @return The minimum number of digits allowed in the integer
294 * portion of a number.
295 */
296 public int getMinimumIntegerDigits ()
297 {
298 return minimumIntegerDigits;
299 }
300
301 /**
302 * This method returns a default instance for the specified locale. This
303 * will be a concrete subclass of <code>NumberFormat</code>, but the
304 * actual class returned is dependent on the locale.
305 *
306 * @param locale The desired locale.
307 *
308 * @return An instance of the default <code>NumberFormat</code> class.
309 */
310 public static final NumberFormat getNumberInstance ()
311 {
312 return getNumberInstance (Locale.getDefault());
313 }
314
315 /**
316 * This method returns a general purpose number formatting and parsing
317 * class for the default locale. This will be a concrete subclass of
318 * <code>NumberFormat</code>, but the actual class returned is dependent
319 * on the locale.
320 *
321 * @return An instance of a generic number formatter for the default locale.
322 */
323 public static NumberFormat getNumberInstance (Locale loc)
324 {
325 return computeInstance (loc, "numberFormat", "#,##0.###");
326 }
327
328 /**
329 * This method returns an instance of <code>NumberFormat</code> suitable
330 * for formatting and parsing percentage values in the default locale.
331 *
332 * @return An instance of <code>NumberFormat</code> for handling percentages.
333 */
334 public static final NumberFormat getPercentInstance ()
335 {
336 return getPercentInstance (Locale.getDefault());
337 }
338
339 /**
340 * This method returns an instance of <code>NumberFormat</code> suitable
341 * for formatting and parsing percentage values in the specified locale.
342 *
343 * @param locale The desired locale.
344 *
345 * @return An instance of <code>NumberFormat</code> for handling percentages.
346 */
347 public static NumberFormat getPercentInstance (Locale loc)
348 {
349 return computeInstance (loc, "percentFormat", "#,##0%");
350 }
351
352 /**
353 * This method returns a hash value for this object.
354 *
355 * @return The hash code.
356 */
357 public int hashCode ()
358 {
359 int hash = super.hashCode();
360 hash ^= (maximumFractionDigits + maximumIntegerDigits
361 + minimumFractionDigits + minimumIntegerDigits);
362 if (groupingUsed)
363 hash ^= 0xf0f0;
364 if (parseIntegerOnly)
365 hash ^= 0x0f0f;
366 return hash;
367 }
368
369 /**
370 * This method tests whether or not grouping is in use. Grouping is
371 * a method of marking separations in numbers, such as thousand separators
372 * in the US English locale. The grouping positions and symbols are all
373 * locale specific. As an example, with grouping disabled, the number one
374 * million would appear as "1000000". With grouping enabled, this number
375 * might appear as "1,000,000". (Both of these assume the US English
376 * locale).
377 *
378 * @return <code>true</code> if grouping is enabled,
379 * <code>false</code> otherwise.
380 */
381 public boolean isGroupingUsed ()
382 {
383 return groupingUsed;
384 }
385
386 /**
387 * This method tests whether or not only integer values should be parsed.
388 * If this class is parsing only integers, parsing stops at the decimal
389 * point.
390 *
391 * @return <code>true</code> if only integers are parsed,
392 * <code>false</code> otherwise.
393 */
394 public boolean isParseIntegerOnly ()
395 {
396 return parseIntegerOnly;
397 }
398
399 /**
400 * This is a default constructor for use by subclasses.
401 */
402 public NumberFormat ()
403 {
404 }
405
406 /**
407 * This method parses the specified string into a <code>Number</code>. This
408 * will be a <code>Long</code> if possible, otherwise it will be a
409 * <code>Double</code>. If no number can be parsed, no exception is
410 * thrown. Instead, the parse position remains at its initial index.
411 *
412 * @param str The string to parse.
413 * @param pp The desired <code>ParsePosition</code>.
414 *
415 * @return The parsed <code>Number</code>
416 */
417 public abstract Number parse (String sourceStr, ParsePosition pos);
418
419 /**
420 * This method parses the specified string into a <code>Number</code>. This
421 * will be a <code>Long</code> if possible, otherwise it will be a
422 * <code>Double</code>. If no number can be parsed, an exception will be
423 * thrown.
424 *
425 * @param str The string to parse.
426 *
427 * @return The parsed <code>Number</code>
428 *
429 * @exception ParseException If no number can be parsed.
430 */
431 public Number parse (String sourceStr) throws ParseException
432 {
433 ParsePosition pp = new ParsePosition (0);
434 Number r = parse (sourceStr, pp);
435 if (r == null)
436 {
437 int index = pp.getErrorIndex();
438 if (index < 0)
439 index = pp.getIndex();
440 throw new ParseException ("couldn't parse number", index);
441 }
442 return r;
443 }
444
445 /**
446 * This method parses the specified string into an <code>Object</code>. This
447 * will be a <code>Long</code> if possible, otherwise it will be a
448 * <code>Double</code>. If no number can be parsed, no exception is
449 * thrown. Instead, the parse position remains at its initial index.
450 *
451 * @param str The string to parse.
452 * @param pp The desired <code>ParsePosition</code>.
453 *
454 * @return The parsed <code>Object</code>
455 */
456 public final Object parseObject (String sourceStr, ParsePosition pos)
457 {
458 return parse (sourceStr, pos);
459 }
460
461 /**
462 * This method sets the grouping behavior of this formatter. Grouping is
463 * a method of marking separations in numbers, such as thousand separators
464 * in the US English locale. The grouping positions and symbols are all
465 * locale specific. As an example, with grouping disabled, the number one
466 * million would appear as "1000000". With grouping enabled, this number
467 * might appear as "1,000,000". (Both of these assume the US English
468 * locale).
469 *
470 * @param groupingUsed <code>true</code> to enable grouping,
471 * <code>false</code> to disable it.
472 */
473 public void setGroupingUsed (boolean newValue)
474 {
475 groupingUsed = newValue;
476 }
477
478 /**
479 * This method sets the maximum number of digits allowed in the fraction
480 * portion of a number to the specified value. If this is less than the
481 * current minimum allowed digits, the minimum allowed digits value will
482 * be lowered to be equal to the new maximum allowed digits value.
483 *
484 * @param maximumFractionDigits The new maximum fraction digits value.
485 */
486 public void setMaximumFractionDigits (int newValue)
487 {
488 maximumFractionDigits = newValue;
489 if (getMinimumFractionDigits () > maximumFractionDigits)
490 setMinimumFractionDigits (maximumFractionDigits);
491 }
492
493 /**
494 * This method sets the maximum number of digits allowed in the integer
495 * portion of a number to the specified value. If this is less than the
496 * current minimum allowed digits, the minimum allowed digits value will
497 * be lowered to be equal to the new maximum allowed digits value.
498 *
499 * @param maximumIntegerDigits The new maximum integer digits value.
500 */
501 public void setMaximumIntegerDigits (int newValue)
502 {
503 maximumIntegerDigits = newValue;
504 if (getMinimumIntegerDigits () > maximumIntegerDigits)
505 setMinimumIntegerDigits (maximumIntegerDigits);
506 }
507
508 /**
509 * This method sets the minimum number of digits allowed in the fraction
510 * portion of a number to the specified value. If this is greater than the
511 * current maximum allowed digits, the maximum allowed digits value will
512 * be raised to be equal to the new minimum allowed digits value.
513 *
514 * @param minimumFractionDigits The new minimum fraction digits value.
515 */
516 public void setMinimumFractionDigits (int newValue)
517 {
518 minimumFractionDigits = newValue;
519 if (getMaximumFractionDigits () < minimumFractionDigits)
520 setMaximumFractionDigits (minimumFractionDigits);
521 }
522
523 /**
524 * This method sets the minimum number of digits allowed in the integer
525 * portion of a number to the specified value. If this is greater than the
526 * current maximum allowed digits, the maximum allowed digits value will
527 * be raised to be equal to the new minimum allowed digits value.
528 *
529 * @param minimumIntegerDigits The new minimum integer digits value.
530 */
531 public void setMinimumIntegerDigits (int newValue)
532 {
533 minimumIntegerDigits = newValue;
534 if (getMaximumIntegerDigits () < minimumIntegerDigits)
535 setMaximumIntegerDigits (minimumIntegerDigits);
536 }
537
538 /**
539 * This method sets the parsing behavior of this object to parse only
540 * integers or not.
541 *
542 * @param parseIntegerOnly <code>true</code> to parse only integers,
543 * <code>false</code> otherwise.
544 */
545 public void setParseIntegerOnly (boolean value)
546 {
547 parseIntegerOnly = value;
548 }
549
550 /**
551 * This method is a specialization of the format method that performs
552 * a simple formatting of the specified <code>double</code> number.
553 *
554 * @param number The <code>double</code> to format.
555 *
556 * @return The formatted number
557 */
558 public final String format (double number)
559 {
560 StringBuffer sbuf = new StringBuffer(50);
561 format (number, sbuf, null);
562 return sbuf.toString();
563 }
564
565 // These field names are fixed by the serialization spec.
566 boolean groupingUsed;
567 int maximumFractionDigits;
568 private byte maxFractionDigits;
569 int maximumIntegerDigits;
570 private byte maxIntegerDigits;
571 int minimumFractionDigits;
572 private byte minFractionDigits;
573 int minimumIntegerDigits;
574 private byte minIntegerDigits;
575 boolean parseIntegerOnly;
576 private int serialVersionOnStream;
577 private static final long serialVersionUID = -2308460125733713944L;
578
579 private void readObject(ObjectInputStream stream)
580 throws IOException, ClassNotFoundException
581 {
582 stream.defaultReadObject();
583 if (serialVersionOnStream < 1)
584 {
585 maximumFractionDigits = maxFractionDigits;
586 maximumIntegerDigits = maxIntegerDigits;
587 minimumFractionDigits = minFractionDigits;
588 minimumIntegerDigits = minIntegerDigits;
589 serialVersionOnStream = 1;
590 }
591 }
592
593 private void writeObject(ObjectOutputStream stream) throws IOException
594 {
595 maxFractionDigits = maximumFractionDigits < Byte.MAX_VALUE ?
596 (byte) maximumFractionDigits : Byte.MAX_VALUE;
597 maxIntegerDigits = maximumIntegerDigits < Byte.MAX_VALUE ?
598 (byte) maximumIntegerDigits : Byte.MAX_VALUE;
599 minFractionDigits = minimumFractionDigits < Byte.MAX_VALUE ?
600 (byte) minimumFractionDigits : Byte.MAX_VALUE;
601 minIntegerDigits = minimumIntegerDigits < Byte.MAX_VALUE ?
602 (byte) minimumIntegerDigits : Byte.MAX_VALUE;
603 serialVersionOnStream = 1;
604 stream.defaultWriteObject();
605 }
606}
Note: See TracBrowser for help on using the repository browser.