KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > ibm > icu > text > NumberFormat


1 //##header 1189099963000 FOUNDATION
2
/*
3  *******************************************************************************
4  * Copyright (C) 1996-2006, International Business Machines Corporation and *
5  * others. All Rights Reserved. *
6  *******************************************************************************
7  */

8 package com.ibm.icu.text;
9
10 import java.io.IOException JavaDoc;
11 import java.io.InvalidObjectException JavaDoc;
12 import java.io.ObjectInputStream JavaDoc;
13 import java.io.ObjectOutputStream JavaDoc;
14 import java.math.BigInteger JavaDoc;
15 import java.text.FieldPosition JavaDoc;
16 import java.text.Format JavaDoc;
17 import java.text.ParseException JavaDoc;
18 import java.text.ParsePosition JavaDoc;
19 import java.util.Collections JavaDoc;
20 import java.util.Locale JavaDoc;
21 import java.util.MissingResourceException JavaDoc;
22 import java.util.Set JavaDoc;
23
24 import com.ibm.icu.impl.ICUResourceBundle;
25 import com.ibm.icu.util.Currency;
26 import com.ibm.icu.util.CurrencyAmount;
27 import com.ibm.icu.util.ULocale;
28 import com.ibm.icu.util.UResourceBundle;
29
30 /**
31  * <code>NumberFormat</code> is the abstract base class for all number
32  * formats. This class provides the interface for formatting and parsing
33  * numbers. <code>NumberFormat</code> also provides methods for determining
34  * which locales have number formats, and what their names are.
35  *
36  * <p><strong>This is an enhanced version of <code>NumberFormat</code> that
37  * is based on the standard version in the JDK. New or changed functionality
38  * is labeled
39  * <strong><font face=helvetica color=red>NEW</font></strong> or
40  * <strong><font face=helvetica color=red>CHANGED</font></strong>.</strong>
41  *
42  * <p>
43  * <code>NumberFormat</code> helps you to format and parse numbers for any locale.
44  * Your code can be completely independent of the locale conventions for
45  * decimal points, thousands-separators, or even the particular decimal
46  * digits used, or whether the number format is even decimal.
47  *
48  * <p>
49  * To format a number for the current Locale, use one of the factory
50  * class methods:
51  * <blockquote>
52  * <pre>
53  * myString = NumberFormat.getInstance().format(myNumber);
54  * </pre>
55  * </blockquote>
56  * If you are formatting multiple numbers, it is
57  * more efficient to get the format and use it multiple times so that
58  * the system doesn't have to fetch the information about the local
59  * language and country conventions multiple times.
60  * <blockquote>
61  * <pre>
62  * NumberFormat nf = NumberFormat.getInstance();
63  * for (int i = 0; i < a.length; ++i) {
64  * output.println(nf.format(myNumber[i]) + "; ");
65  * }
66  * </pre>
67  * </blockquote>
68  * To format a number for a different Locale, specify it in the
69  * call to <code>getInstance</code>.
70  * <blockquote>
71  * <pre>
72  * NumberFormat nf = NumberFormat.getInstance(Locale.FRENCH);
73  * </pre>
74  * </blockquote>
75  * You can also use a <code>NumberFormat</code> to parse numbers:
76  * <blockquote>
77  * <pre>
78  * myNumber = nf.parse(myString);
79  * </pre>
80  * </blockquote>
81  * Use <code>getInstance</code> or <code>getNumberInstance</code> to get the
82  * normal number format. Use <code>getIntegerInstance</code> to get an
83  * integer number format. Use <code>getCurrencyInstance</code> to get the
84  * currency number format. And use <code>getPercentInstance</code> to get a
85  * format for displaying percentages. With this format, a fraction like
86  * 0.53 is displayed as 53%.
87  *
88  * <p>
89  * You can also control the display of numbers with such methods as
90  * <code>setMinimumFractionDigits</code>.
91  * If you want even more control over the format or parsing,
92  * or want to give your users more control,
93  * you can try casting the <code>NumberFormat</code> you get from the factory methods
94  * to a <code>DecimalFormat</code>. This will work for the vast majority
95  * of locales; just remember to put it in a <code>try</code> block in case you
96  * encounter an unusual one.
97  *
98  * <p>
99  * NumberFormat is designed such that some controls
100  * work for formatting and others work for parsing. The following is
101  * the detailed description for each these control methods,
102  * <p>
103  * setParseIntegerOnly : only affects parsing, e.g.
104  * if true, "3456.78" -> 3456 (and leaves the parse position just after '6')
105  * if false, "3456.78" -> 3456.78 (and leaves the parse position just after '8')
106  * This is independent of formatting. If you want to not show a decimal point
107  * where there might be no digits after the decimal point, use
108  * setDecimalSeparatorAlwaysShown on DecimalFormat.
109  * <p>
110  * You can also use forms of the <code>parse</code> and <code>format</code>
111  * methods with <code>ParsePosition</code> and <code>FieldPosition</code> to
112  * allow you to:
113  * <ul>
114  * <li> progressively parse through pieces of a string
115  * <li> align the decimal point and other areas
116  * </ul>
117  * For example, you can align numbers in two ways:
118  * <ol>
119  * <li> If you are using a monospaced font with spacing for alignment,
120  * you can pass the <code>FieldPosition</code> in your format call, with
121  * <code>field</code> = <code>INTEGER_FIELD</code>. On output,
122  * <code>getEndIndex</code> will be set to the offset between the
123  * last character of the integer and the decimal. Add
124  * (desiredSpaceCount - getEndIndex) spaces at the front of the string.
125  *
126  * <li> If you are using proportional fonts,
127  * instead of padding with spaces, measure the width
128  * of the string in pixels from the start to <code>getEndIndex</code>.
129  * Then move the pen by
130  * (desiredPixelWidth - widthToAlignmentPoint) before drawing the text.
131  * It also works where there is no decimal, but possibly additional
132  * characters at the end, e.g., with parentheses in negative
133  * numbers: "(12)" for -12.
134  * </ol>
135  *
136  * <h4>Synchronization</h4>
137  * <p>
138  * Number formats are generally not synchronized. It is recommended to create
139  * separate format instances for each thread. If multiple threads access a format
140  * concurrently, it must be synchronized externally.
141  * <p>
142  *
143  * <h4>DecimalFormat</h4>
144  * <p>DecimalFormat is the concrete implementation of NumberFormat, and the
145  * NumberFormat API is essentially an abstraction from DecimalFormat's API.
146  * Refer to DecimalFormat for more information about this API.</p>
147  *
148  * see DecimalFormat
149  * see java.text.ChoiceFormat
150  * @author Mark Davis
151  * @author Helena Shih
152  * @author Alan Liu
153  * @stable ICU 2.0
154  */

155 public abstract class NumberFormat extends UFormat {
156
157     // Constants used by factory methods to specify a style of format.
158
private static final int NUMBERSTYLE = 0;
159     private static final int CURRENCYSTYLE = 1;
160     private static final int PERCENTSTYLE = 2;
161     private static final int SCIENTIFICSTYLE = 3;
162     private static final int INTEGERSTYLE = 4;
163
164     /**
165      * Field constant used to construct a FieldPosition object. Signifies that
166      * the position of the integer part of a formatted number should be returned.
167      * @see java.text.FieldPosition
168      * @stable ICU 2.0
169      */

170     public static final int INTEGER_FIELD = 0;
171
172     /**
173      * Field constant used to construct a FieldPosition object. Signifies that
174      * the position of the fraction part of a formatted number should be returned.
175      * @see java.text.FieldPosition
176      * @stable ICU 2.0
177      */

178     public static final int FRACTION_FIELD = 1;
179
180     /**
181      * <strong><font face=helvetica color=red>CHANGED</font></strong>
182      * Format an object. Change: recognizes <code>BigInteger</code>
183      * and <code>BigDecimal</code> objects.
184      * @stable ICU 2.0
185      */

186     public StringBuffer JavaDoc format(Object JavaDoc number,
187                                StringBuffer JavaDoc toAppendTo,
188                                FieldPosition JavaDoc pos)
189     {
190         if (number instanceof Long JavaDoc) {
191             return format(((Long JavaDoc)number).longValue(), toAppendTo, pos);
192         } else if (number instanceof BigInteger JavaDoc) {
193             return format((BigInteger JavaDoc) number, toAppendTo, pos);
194 //#ifndef FOUNDATION
195
//## } else if (number instanceof java.math.BigDecimal) {
196
//## return format((java.math.BigDecimal) number, toAppendTo, pos);
197
//#endif
198
} else if (number instanceof com.ibm.icu.math.BigDecimal) {
199             return format((com.ibm.icu.math.BigDecimal) number, toAppendTo, pos);
200         } else if (number instanceof CurrencyAmount) {
201             return format((CurrencyAmount)number, toAppendTo, pos);
202         } else if (number instanceof Number JavaDoc) {
203             return format(((Number JavaDoc)number).doubleValue(), toAppendTo, pos);
204         } else {
205             throw new IllegalArgumentException JavaDoc("Cannot format given Object as a Number");
206         }
207     }
208
209     /**
210      * @stable ICU 2.0
211      */

212     public final Object JavaDoc parseObject(String JavaDoc source,
213                                     ParsePosition JavaDoc parsePosition)
214     {
215         return parse(source, parsePosition);
216     }
217
218     /**
219      * Specialization of format.
220      * @see java.text.Format#format(Object)
221      * @stable ICU 2.0
222      */

223     public final String JavaDoc format(double number) {
224         return format(number,new StringBuffer JavaDoc(),
225                       new FieldPosition JavaDoc(0)).toString();
226     }
227
228     /**
229      * Specialization of format.
230      * @see java.text.Format#format(Object)
231      * @stable ICU 2.0
232      */

233     public final String JavaDoc format(long number) {
234         StringBuffer JavaDoc buf = new StringBuffer JavaDoc(19);
235         FieldPosition JavaDoc pos = new FieldPosition JavaDoc(0);
236         format(number, buf, pos);
237         return buf.toString();
238     }
239
240     /**
241      * <strong><font face=helvetica color=red>NEW</font></strong>
242      * Convenience method to format a BigInteger.
243      * @stable ICU 2.0
244      */

245     public final String JavaDoc format(BigInteger JavaDoc number) {
246         return format(number, new StringBuffer JavaDoc(),
247                       new FieldPosition JavaDoc(0)).toString();
248     }
249
250 //#ifndef FOUNDATION
251
//## /**
252
//## * <strong><font face=helvetica color=red>NEW</font></strong>
253
//## * Convenience method to format a BigDecimal.
254
//## * @stable ICU 2.0
255
//## */
256
//## public final String format(java.math.BigDecimal number) {
257
//## return format(number, new StringBuffer(),
258
//## new FieldPosition(0)).toString();
259
//## }
260
//#endif
261

262     /**
263      * <strong><font face=helvetica color=red>NEW</font></strong>
264      * Convenience method to format an ICU BigDecimal.
265      * @stable ICU 2.0
266      */

267     public final String JavaDoc format(com.ibm.icu.math.BigDecimal number) {
268         return format(number, new StringBuffer JavaDoc(),
269                       new FieldPosition JavaDoc(0)).toString();
270     }
271
272     /**
273      * <strong><font face=helvetica color=red>NEW</font></strong>
274      * Convenience method to format a CurrencyAmount.
275      * @stable ICU 3.0
276      */

277     public final String JavaDoc format(CurrencyAmount currAmt) {
278         return format(currAmt, new StringBuffer JavaDoc(),
279                       new FieldPosition JavaDoc(0)).toString();
280     }
281
282     /**
283      * Specialization of format.
284      * @see java.text.Format#format(Object, StringBuffer, FieldPosition)
285      * @stable ICU 2.0
286      */

287     public abstract StringBuffer JavaDoc format(double number,
288                                         StringBuffer JavaDoc toAppendTo,
289                                         FieldPosition JavaDoc pos);
290
291     /**
292      * Specialization of format.
293      * @see java.text.Format#format(Object, StringBuffer, FieldPosition)
294      * @stable ICU 2.0
295      */

296     public abstract StringBuffer JavaDoc format(long number,
297                                         StringBuffer JavaDoc toAppendTo,
298                                         FieldPosition JavaDoc pos);
299
300     /**
301      * <strong><font face=helvetica color=red>NEW</font></strong>
302      * Format a BigInteger.
303      * @see java.text.Format#format(Object, StringBuffer, FieldPosition)
304      * @stable ICU 2.0
305      */

306     public abstract StringBuffer JavaDoc format(BigInteger JavaDoc number,
307                                         StringBuffer JavaDoc toAppendTo,
308                                         FieldPosition JavaDoc pos);
309 //#ifndef FOUNDATION
310
//## /**
311
//## * <strong><font face=helvetica color=red>NEW</font></strong>
312
//## * Format a BigDecimal.
313
//## * @see java.text.Format#format(Object, StringBuffer, FieldPosition)
314
//## * @stable ICU 2.0
315
//## */
316
//## public abstract StringBuffer format(java.math.BigDecimal number,
317
//## StringBuffer toAppendTo,
318
//## FieldPosition pos);
319
//#endif
320

321     /**
322      * <strong><font face=helvetica color=red>NEW</font></strong>
323      * Format a BigDecimal.
324      * @see java.text.Format#format(Object, StringBuffer, FieldPosition)
325      * @stable ICU 2.0
326      */

327     public abstract StringBuffer JavaDoc format(com.ibm.icu.math.BigDecimal number,
328                                         StringBuffer JavaDoc toAppendTo,
329                                         FieldPosition JavaDoc pos);
330
331     /**
332      * <strong><font face=helvetica color=red>NEW</font></strong>
333      * Format a CurrencyAmount.
334      * @see java.text.Format#format(Object, StringBuffer, FieldPosition)
335      * @stable ICU 3.0
336      */

337     public StringBuffer JavaDoc format(CurrencyAmount currAmt,
338                                StringBuffer JavaDoc toAppendTo,
339                                FieldPosition JavaDoc pos) {
340         // Default implementation -- subclasses may override
341
Currency save = getCurrency(), curr = currAmt.getCurrency();
342         boolean same = curr.equals(save);
343         if (!same) setCurrency(curr);
344         format(currAmt.getNumber(), toAppendTo, pos);
345         if (!same) setCurrency(save);
346         return toAppendTo;
347     }
348
349     /**
350      * Returns a Long if possible (e.g., within the range [Long.MIN_VALUE,
351      * Long.MAX_VALUE] and with no decimals), otherwise a Double.
352      * If IntegerOnly is set, will stop at a decimal
353      * point (or equivalent; e.g., for rational numbers "1 2/3", will stop
354      * after the 1).
355      * Does not throw an exception; if no object can be parsed, index is
356      * unchanged!
357      * @see #isParseIntegerOnly
358      * @see java.text.Format#parseObject(String, ParsePosition)
359      * @stable ICU 2.0
360      */

361     public abstract Number JavaDoc parse(String JavaDoc text, ParsePosition JavaDoc parsePosition);
362
363     /**
364      * Parses text from the beginning of the given string to produce a number.
365      * The method might not use the entire text of the given string.
366      *
367      * @param text A String whose beginning should be parsed.
368      * @return A Number parsed from the string.
369      * @exception ParseException if the beginning of the specified string
370      * cannot be parsed.
371      * @see #format
372      * @stable ICU 2.0
373      */

374     //Bug 4375399 [Richard/GCL]
375
public Number JavaDoc parse(String JavaDoc text) throws ParseException JavaDoc {
376         ParsePosition JavaDoc parsePosition = new ParsePosition JavaDoc(0);
377         Number JavaDoc result = parse(text, parsePosition);
378         if (parsePosition.getIndex() == 0) {
379             throw new ParseException JavaDoc("Unparseable number: \"" + text + '"',
380                                      parsePosition.getErrorIndex());
381         }
382         return result;
383     }
384
385     /**
386      * <strong><font face=helvetica color=red>NEW</font></strong>
387      * Parses text from the given string as a CurrencyAmount. Unlike
388      * the parse() method, this method will attempt to parse a generic
389      * currency name, searching for a match of this object's locale's
390      * currency display names, or for a 3-letter ISO currency code.
391      * This method will fail if this format is not a currency format,
392      * that is, if it does not contain the currency pattern symbol
393      * (U+00A4) in its prefix or suffix.
394      *
395      * @param text the string to parse
396      * @param pos input-output position; on input, the position within
397      * text to match; must have 0 <= pos.getIndex() < text.length();
398      * on output, the position after the last matched character. If
399      * the parse fails, the position in unchanged upon output.
400      * @return a CurrencyAmount, or null upon failure
401      * @internal
402      * @deprecated This API is ICU internal only.
403      */

404     CurrencyAmount parseCurrency(String JavaDoc text, ParsePosition JavaDoc pos) {
405         // Default implementation only -- subclasses should override
406
Number JavaDoc n = parse(text, pos);
407         return n == null ? null : new CurrencyAmount(n, getEffectiveCurrency());
408     }
409
410     /**
411      * Returns true if this format will parse numbers as integers only.
412      * For example in the English locale, with ParseIntegerOnly true, the
413      * string "1234." would be parsed as the integer value 1234 and parsing
414      * would stop at the "." character. The decimal separator accepted
415      * by the parse operation is locale-dependent and determined by the
416      * subclass.
417      * @return true if this will parse integers only
418      * @stable ICU 2.0
419      */

420     public boolean isParseIntegerOnly() {
421         return parseIntegerOnly;
422     }
423
424     /**
425      * Sets whether or not numbers should be parsed as integers only.
426      * @param value true if this should parse integers only
427      * @see #isParseIntegerOnly
428      * @stable ICU 2.0
429      */

430     public void setParseIntegerOnly(boolean value) {
431         parseIntegerOnly = value;
432     }
433
434     /**
435      * Sets whether strict parsing is in effect. When this is true, the
436      * following conditions cause a parse failure (examples use the pattern "#,##0.#"):<ul>
437      * <li>Leading zeros<br>
438      * '00', '0123' fail the parse, but '0' and '0.001' pass</li>
439      * <li>Leading or doubled grouping separators<br>
440      * ',123' and '1,,234" fail</li>
441      * <li>Groups of incorrect length when grouping is used<br>
442      * '1,23' and '1234,567' fail, but '1234' passes</li>
443      * <li>Grouping separators used in numbers followed by exponents<br>
444      * '1,234E5' fails, but '1234E5' and '1,234E' pass ('E' is not an exponent when
445      * not followed by a number)</li>
446      * </ul>
447      * When strict parsing is off, leading zeros and all grouping separators are ignored.
448      * This is the default behavior.
449      * @param value True to enable strict parsing. Default is false.
450      * @see #isParseStrict
451      * @draft ICU 3.6
452      * @provisional This API might change or be removed in a future release.
453      */

454     public void setParseStrict(boolean value) {
455         parseStrict = value;
456     }
457
458     /**
459      * Return whether strict parsing is in effect.
460      * @return true if strict parsing is in effect
461      * @see #setParseStrict
462      * @draft ICU 3.6
463      * @provisional This API might change or be removed in a future release.
464      */

465     public boolean isParseStrict() {
466         return parseStrict;
467     }
468
469     //============== Locale Stuff =====================
470

471     /**
472      * Returns the default number format for the current default locale.
473      * The default format is one of the styles provided by the other
474      * factory methods: getNumberInstance, getIntegerInstance,
475      * getCurrencyInstance or getPercentInstance.
476      * Exactly which one is locale-dependent.
477      * @stable ICU 2.0
478      */

479     //Bug 4408066 [Richard/GCL]
480
public final static NumberFormat getInstance() {
481         return getInstance(ULocale.getDefault(), NUMBERSTYLE);
482     }
483
484     /**
485      * Returns the default number format for the specified locale.
486      * The default format is one of the styles provided by the other
487      * factory methods: getNumberInstance, getCurrencyInstance or getPercentInstance.
488      * Exactly which one is locale-dependent.
489      * @stable ICU 2.0
490      */

491     public static NumberFormat getInstance(Locale JavaDoc inLocale) {
492         return getInstance(ULocale.forLocale(inLocale), NUMBERSTYLE);
493     }
494
495     /**
496      * Returns the default number format for the specified locale.
497      * The default format is one of the styles provided by the other
498      * factory methods: getNumberInstance, getCurrencyInstance or getPercentInstance.
499      * Exactly which one is locale-dependent.
500      * @draft ICU 3.2
501      * @provisional This API might change or be removed in a future release.
502      */

503     public static NumberFormat getInstance(ULocale inLocale) {
504         return getInstance(inLocale, NUMBERSTYLE);
505     }
506
507     /**
508      * Returns a general-purpose number format for the current default locale.
509      * @stable ICU 2.0
510      */

511     public final static NumberFormat getNumberInstance() {
512         return getInstance(ULocale.getDefault(), NUMBERSTYLE);
513     }
514
515     /**
516      * Returns a general-purpose number format for the specified locale.
517      * @stable ICU 2.0
518      */

519     public static NumberFormat getNumberInstance(Locale JavaDoc inLocale) {
520         return getInstance(ULocale.forLocale(inLocale), NUMBERSTYLE);
521     }
522
523     /**
524      * Returns a general-purpose number format for the specified locale.
525      * @draft ICU 3.2
526      * @provisional This API might change or be removed in a future release.
527      */

528     public static NumberFormat getNumberInstance(ULocale inLocale) {
529         return getInstance(inLocale, NUMBERSTYLE);
530     }
531
532     /**
533      * Returns an integer number format for the current default locale. The
534      * returned number format is configured to round floating point numbers
535      * to the nearest integer using IEEE half-even rounding (see {@link
536      * com.ibm.icu.math.BigDecimal#ROUND_HALF_EVEN ROUND_HALF_EVEN}) for formatting,
537      * and to parse only the integer part of an input string (see {@link
538      * #isParseIntegerOnly isParseIntegerOnly}).
539      *
540      * @return a number format for integer values
541      * @stable ICU 2.0
542      */

543     //Bug 4408066 [Richard/GCL]
544
public final static NumberFormat getIntegerInstance() {
545         return getInstance(ULocale.getDefault(), INTEGERSTYLE);
546     }
547
548     /**
549      * Returns an integer number format for the specified locale. The
550      * returned number format is configured to round floating point numbers
551      * to the nearest integer using IEEE half-even rounding (see {@link
552      * com.ibm.icu.math.BigDecimal#ROUND_HALF_EVEN ROUND_HALF_EVEN}) for formatting,
553      * and to parse only the integer part of an input string (see {@link
554      * #isParseIntegerOnly isParseIntegerOnly}).
555      *
556      * @param inLocale the locale for which a number format is needed
557      * @return a number format for integer values
558      * @stable ICU 2.0
559      */

560     //Bug 4408066 [Richard/GCL]
561
public static NumberFormat getIntegerInstance(Locale JavaDoc inLocale) {
562         return getInstance(ULocale.forLocale(inLocale), INTEGERSTYLE);
563     }
564
565     /**
566      * Returns an integer number format for the specified locale. The
567      * returned number format is configured to round floating point numbers
568      * to the nearest integer using IEEE half-even rounding (see {@link
569      * com.ibm.icu.math.BigDecimal#ROUND_HALF_EVEN ROUND_HALF_EVEN}) for formatting,
570      * and to parse only the integer part of an input string (see {@link
571      * #isParseIntegerOnly isParseIntegerOnly}).
572      *
573      * @param inLocale the locale for which a number format is needed
574      * @return a number format for integer values
575      * @draft ICU 3.2
576      * @provisional This API might change or be removed in a future release.
577      */

578     public static NumberFormat getIntegerInstance(ULocale inLocale) {
579         return getInstance(inLocale, INTEGERSTYLE);
580     }
581
582     /**
583      * Returns a currency format for the current default locale.
584      * @return a number format for currency
585      * @stable ICU 2.0
586      */

587     public final static NumberFormat getCurrencyInstance() {
588         return getInstance(ULocale.getDefault(), CURRENCYSTYLE);
589     }
590
591     /**
592      * Returns a currency format for the specified locale.
593      * @return a number format for currency
594      * @stable ICU 2.0
595      */

596     public static NumberFormat getCurrencyInstance(Locale JavaDoc inLocale) {
597         return getInstance(ULocale.forLocale(inLocale), CURRENCYSTYLE);
598     }
599
600     /**
601      * Returns a currency format for the specified locale.
602      * @return a number format for currency
603      * @draft ICU 3.2
604      * @provisional This API might change or be removed in a future release.
605      */

606     public static NumberFormat getCurrencyInstance(ULocale inLocale) {
607         return getInstance(inLocale, CURRENCYSTYLE);
608     }
609
610     /**
611      * Returns a percentage format for the current default locale.
612      * @return a number format for percents
613      * @stable ICU 2.0
614      */

615     public final static NumberFormat getPercentInstance() {
616         return getInstance(ULocale.getDefault(), PERCENTSTYLE);
617     }
618
619     /**
620      * Returns a percentage format for the specified locale.
621      * @return a number format for percents
622      * @stable ICU 2.0
623      */

624     public static NumberFormat getPercentInstance(Locale JavaDoc inLocale) {
625         return getInstance(ULocale.forLocale(inLocale), PERCENTSTYLE);
626     }
627
628     /**
629      * Returns a percentage format for the specified locale.
630      * @return a number format for percents
631      * @draft ICU 3.2
632      * @provisional This API might change or be removed in a future release.
633      */

634     public static NumberFormat getPercentInstance(ULocale inLocale) {
635         return getInstance(inLocale, PERCENTSTYLE);
636     }
637
638     /**
639      * <strong><font face=helvetica color=red>NEW</font></strong>
640      * Returns a scientific format for the current default locale.
641      * @return a scientific number format
642      * @stable ICU 2.0
643      */

644     public final static NumberFormat getScientificInstance() {
645         return getInstance(ULocale.getDefault(), SCIENTIFICSTYLE);
646     }
647
648     /**
649      * <strong><font face=helvetica color=red>NEW</font></strong>
650      * Returns a scientific format for the specified locale.
651      * @return a scientific number format
652      * @stable ICU 2.0
653      */

654     public static NumberFormat getScientificInstance(Locale JavaDoc inLocale) {
655         return getInstance(ULocale.forLocale(inLocale), SCIENTIFICSTYLE);
656     }
657
658     /**
659      * <strong><font face=helvetica color=red>NEW</font></strong>
660      * Returns a scientific format for the specified locale.
661      * @return a scientific number format
662      * @draft ICU 3.2
663      * @provisional This API might change or be removed in a future release.
664      */

665     public static NumberFormat getScientificInstance(ULocale inLocale) {
666         return getInstance(inLocale, SCIENTIFICSTYLE);
667     }
668
669     // ===== Factory stuff =====
670
/**
671      * A NumberFormatFactory is used to register new number formats. The factory
672      * should be able to create any of the predefined formats for each locale it
673      * supports. When registered, the locales it supports extend or override the
674      * locales already supported by ICU.
675      * <p><b>Note:</b> as of ICU4J 3.2, the default API for NumberFormatFactory uses
676      * ULocale instead of Locale. Instead of overriding createFormat(Locale, int),
677      * new implementations should override createFactory(ULocale, int). Note that
678      * one of these two methods <b>MUST</b> be overridden or else an infinite
679      * loop will occur.
680      *
681      * @stable ICU 2.6
682      */

683     public static abstract class NumberFormatFactory {
684         /**
685          * Value passed to format requesting a default number format.
686          * @stable ICU 2.6
687          */

688         public static final int FORMAT_NUMBER = NUMBERSTYLE;
689
690         /**
691          * Value passed to format requesting a currency format.
692          * @stable ICU 2.6
693          */

694         public static final int FORMAT_CURRENCY = CURRENCYSTYLE;
695
696         /**
697          * Value passed to format requesting a percent format.
698          * @stable ICU 2.6
699          */

700         public static final int FORMAT_PERCENT = PERCENTSTYLE;
701
702         /**
703          * Value passed to format requesting a scientific format.
704          * @stable ICU 2.6
705          */

706         public static final int FORMAT_SCIENTIFIC = SCIENTIFICSTYLE;
707
708         /**
709          * Value passed to format requesting an integer format.
710          * @stable ICU 2.6
711          */

712         public static final int FORMAT_INTEGER = INTEGERSTYLE;
713
714         /**
715          * Returns true if this factory is visible. Default is true.
716          * If not visible, the locales supported by this factory will not
717          * be listed by getAvailableLocales. This value must not change.
718          * @return true if the factory is visible.
719          * @stable ICU 2.6
720          */

721         ///CLOVER:OFF
722
public boolean visible() {
723             return true;
724         }
725         ///CLOVER:ON
726

727         /**
728          * Returns an immutable collection of the locale names directly
729          * supported by this factory.
730          * @return the supported locale names.
731          * @stable ICU 2.6
732          */

733          public abstract Set JavaDoc getSupportedLocaleNames();
734
735         /**
736          * Returns a number format of the appropriate type. If the locale
737          * is not supported, return null. If the locale is supported, but
738          * the type is not provided by this service, return null. Otherwise
739          * return an appropriate instance of NumberFormat.
740          * <b>Note:</b> as of ICU4J 3.2, implementations should override
741          * this method instead of createFormat(Locale, int).
742          * @param loc the locale for which to create the format
743          * @param formatType the type of format
744          * @return the NumberFormat, or null.
745          * @draft ICU 3.2
746          * @provisional This API might change or be removed in a future release.
747          */

748         public NumberFormat createFormat(ULocale loc, int formatType) {
749             return createFormat(loc.toLocale(), formatType);
750         }
751
752         /**
753          * Returns a number format of the appropriate type. If the locale
754          * is not supported, return null. If the locale is supported, but
755          * the type is not provided by this service, return null. Otherwise
756          * return an appropriate instance of NumberFormat.
757          * <b>Note:</b> as of ICU4J 3.2, createFormat(ULocale, int) should be
758          * overridden instead of this method. This method is no longer
759          * abstract and delegates to that method.
760          * @param loc the locale for which to create the format
761          * @param formatType the type of format
762          * @return the NumberFormat, or null.
763          * @stable ICU 2.6
764          */

765         public NumberFormat createFormat(Locale JavaDoc loc, int formatType) {
766             return createFormat(ULocale.forLocale(loc), formatType);
767         }
768
769         /**
770          * @stable ICU 2.6
771          */

772         protected NumberFormatFactory() {
773         }
774     }
775
776     /**
777      * A NumberFormatFactory that supports a single locale. It can be visible or invisible.
778      * @stable ICU 2.6
779      */

780     public static abstract class SimpleNumberFormatFactory extends NumberFormatFactory {
781         final Set JavaDoc localeNames;
782         final boolean visible;
783
784         /**
785          * @stable ICU 2.6
786          */

787         public SimpleNumberFormatFactory(Locale JavaDoc locale) {
788             this(locale, true);
789         }
790         
791         /**
792          * @stable ICU 2.6
793          */

794         public SimpleNumberFormatFactory(Locale JavaDoc locale, boolean visible) {
795             localeNames = Collections.singleton(ULocale.forLocale(locale).getBaseName());
796             this.visible = visible;
797         }
798
799         /**
800          * @draft ICU 3.2
801          * @provisional This API might change or be removed in a future release.
802          */

803         public SimpleNumberFormatFactory(ULocale locale) {
804             this(locale, true);
805         }
806         
807         /**
808          * @draft ICU 3.2
809          * @provisional This API might change or be removed in a future release.
810          */

811         public SimpleNumberFormatFactory(ULocale locale, boolean visible) {
812             localeNames = Collections.singleton(locale.getBaseName());
813             this.visible = visible;
814         }
815
816         /**
817          * @stable ICU 2.6
818          */

819         public final boolean visible() {
820             return visible;
821         }
822
823         /**
824          * @stable ICU 2.6
825          */

826         public final Set JavaDoc getSupportedLocaleNames() {
827             return localeNames;
828         }
829     }
830
831     // shim so we can build without service code
832
static abstract class NumberFormatShim {
833         abstract Locale JavaDoc[] getAvailableLocales();
834         abstract ULocale[] getAvailableULocales();
835         abstract Object JavaDoc registerFactory(NumberFormatFactory f);
836         abstract boolean unregister(Object JavaDoc k);
837         abstract NumberFormat createInstance(ULocale l, int k);
838     }
839
840     private static NumberFormatShim shim;
841     private static NumberFormatShim getShim() {
842         // Note: this instantiation is safe on loose-memory-model configurations
843
// despite lack of synchronization, since the shim instance has no state--
844
// it's all in the class init. The worst problem is we might instantiate
845
// two shim instances, but they'll share the same state so that's ok.
846
if (shim == null) {
847             try {
848                 Class JavaDoc cls = Class.forName("com.ibm.icu.text.NumberFormatServiceShim");
849                 shim = (NumberFormatShim)cls.newInstance();
850             }
851             catch (MissingResourceException JavaDoc e){
852                 throw e;
853             }
854             catch (Exception JavaDoc e) {
855                 ///CLOVER:OFF
856
// e.printStackTrace();
857
throw new RuntimeException JavaDoc(e.getMessage());
858                 ///CLOVER:ON
859
}
860         }
861         return shim;
862     }
863
864     /**
865      * Get the list of Locales for which NumberFormats are available.
866      * @return the available locales
867      * @stable ICU 2.0
868      */

869     public static Locale JavaDoc[] getAvailableLocales() {
870         if (shim == null) {
871             return ICUResourceBundle.getAvailableLocales(ICUResourceBundle.ICU_BASE_NAME);
872         }
873         return getShim().getAvailableLocales();
874     }
875
876     /**
877      * Get the list of Locales for which NumberFormats are available.
878      * @return the available locales
879      * @draft ICU 3.2
880      * @provisional This API might change or be removed in a future release.
881      */

882     public static ULocale[] getAvailableULocales() {
883         if (shim == null) {
884             return ICUResourceBundle.getAvailableULocales(ICUResourceBundle.ICU_BASE_NAME);
885         }
886         return getShim().getAvailableULocales();
887     }
888
889     /**
890      * Registers a new NumberFormatFactory. The factory is adopted by
891      * the service and must not be modified. The returned object is a
892      * key that can be used to unregister this factory.
893      * @param factory the factory to register
894      * @return a key with which to unregister the factory
895      * @stable ICU 2.6
896      */

897     public static Object JavaDoc registerFactory(NumberFormatFactory factory) {
898         if (factory == null) {
899             throw new IllegalArgumentException JavaDoc("factory must not be null");
900         }
901         return getShim().registerFactory(factory);
902     }
903
904     /**
905      * Unregister the factory or instance associated with this key (obtained from
906      * registerInstance or registerFactory).
907      * @param registryKey a key obtained from registerFactory
908      * @return true if the object was successfully unregistered
909      * @stable ICU 2.6
910      */

911     public static boolean unregister(Object JavaDoc registryKey) {
912         if (registryKey == null) {
913             throw new IllegalArgumentException JavaDoc("registryKey must not be null");
914         }
915
916         if (shim == null) {
917             return false;
918         }
919
920         return shim.unregister(registryKey);
921     }
922
923     // ===== End of factory stuff =====
924

925     /**
926      * Overrides hashCode
927      * @stable ICU 2.0
928      */

929     public int hashCode() {
930         return maximumIntegerDigits * 37 + maxFractionDigits;
931         // just enough fields for a reasonable distribution
932
}
933
934     /**
935      * Overrides equals. Two NumberFormats are equal if they are of the same class
936      * and the settings (groupingUsed, parseIntegerOnly, maximumIntegerDigits, etc.
937      * are equal.
938      * @param obj the object to compare against
939      * @return true if the object is equal to this.
940      * @stable ICU 2.0
941      */

942     public boolean equals(Object JavaDoc obj) {
943         if (obj == null) return false;
944         if (this == obj)
945             return true;
946         if (getClass() != obj.getClass())
947             return false;
948         NumberFormat other = (NumberFormat) obj;
949         return maximumIntegerDigits == other.maximumIntegerDigits
950             && minimumIntegerDigits == other.minimumIntegerDigits
951             && maximumFractionDigits == other.maximumFractionDigits
952             && minimumFractionDigits == other.minimumFractionDigits
953             && groupingUsed == other.groupingUsed
954             && parseIntegerOnly == other.parseIntegerOnly
955             && parseStrict == other.parseStrict;
956     }
957
958     /**
959      * Overrides Cloneable.
960      * @stable ICU 2.0
961      */

962     public Object JavaDoc clone()
963     {
964         NumberFormat other = (NumberFormat) super.clone();
965         return other;
966     }
967
968     /**
969      * Returns true if grouping is used in this format. For example, in the
970      * en_US locale, with grouping on, the number 1234567 will be formatted
971      * as "1,234,567". The grouping separator as well as the size of each group
972      * is locale-dependent and is determined by subclasses of NumberFormat.
973      * Grouping affects both parsing and formatting.
974      * @return true if grouping is used
975      * @see #setGroupingUsed
976      * @stable ICU 2.0
977      */

978     public boolean isGroupingUsed() {
979         return groupingUsed;
980     }
981
982     /**
983      * Sets whether or not grouping will be used in this format. Grouping
984      * affects both parsing and formatting.
985      * @see #isGroupingUsed
986      * @param newValue true to use grouping.
987      * @stable ICU 2.0
988      */

989     public void setGroupingUsed(boolean newValue) {
990         groupingUsed = newValue;
991     }
992
993     /**
994      * Returns the maximum number of digits allowed in the integer portion of a
995      * number. The default value is 40, which subclasses can override.
996      * When formatting, the exact behavior when this value is exceeded is
997      * subclass-specific. When parsing, this has no effect.
998      * @return the maximum number of integer digits
999      * @see #setMaximumIntegerDigits
1000     * @stable ICU 2.0
1001     */

1002    public int getMaximumIntegerDigits() {
1003        return maximumIntegerDigits;
1004    }
1005
1006    /**
1007     * Sets the maximum number of digits allowed in the integer portion of a
1008     * number. This must be >= minimumIntegerDigits. If the
1009     * new value for maximumIntegerDigits is less than the current value
1010     * of minimumIntegerDigits, then minimumIntegerDigits will also be set to
1011     * the new value.
1012     * @param newValue the maximum number of integer digits to be shown; if
1013     * less than zero, then zero is used. Subclasses might enforce an
1014     * upper limit to this value appropriate to the numeric type being formatted.
1015     * @see #getMaximumIntegerDigits
1016     * @stable ICU 2.0
1017     */

1018    public void setMaximumIntegerDigits(int newValue) {
1019        maximumIntegerDigits = Math.max(0,newValue);
1020        if (minimumIntegerDigits > maximumIntegerDigits)
1021            minimumIntegerDigits = maximumIntegerDigits;
1022    }
1023
1024    /**
1025     * Returns the minimum number of digits allowed in the integer portion of a
1026     * number. The default value is 1, which subclasses can override.
1027     * When formatting, if this value is not reached, numbers are padded on the
1028     * left with the locale-specific '0' character to ensure at least this
1029     * number of integer digits. When parsing, this has no effect.
1030     * @return the minimum number of integer digits
1031     * @see #setMinimumIntegerDigits
1032     * @stable ICU 2.0
1033     */

1034    public int getMinimumIntegerDigits() {
1035        return minimumIntegerDigits;
1036    }
1037
1038    /**
1039     * Sets the minimum number of digits allowed in the integer portion of a
1040     * number. This must be <= maximumIntegerDigits. If the
1041     * new value for minimumIntegerDigits is more than the current value
1042     * of maximumIntegerDigits, then maximumIntegerDigits will also be set to
1043     * the new value.
1044     * @param newValue the minimum number of integer digits to be shown; if
1045     * less than zero, then zero is used. Subclasses might enforce an
1046     * upper limit to this value appropriate to the numeric type being formatted.
1047     * @see #getMinimumIntegerDigits
1048     * @stable ICU 2.0
1049     */

1050    public void setMinimumIntegerDigits(int newValue) {
1051        minimumIntegerDigits = Math.max(0,newValue);
1052        if (minimumIntegerDigits > maximumIntegerDigits)
1053            maximumIntegerDigits = minimumIntegerDigits;
1054    }
1055
1056    /**
1057     * Returns the maximum number of digits allowed in the fraction
1058     * portion of a number. The default value is 3, which subclasses
1059     * can override. When formatting, the exact behavior when this
1060     * value is exceeded is subclass-specific. When parsing, this has
1061     * no effect.
1062     * @return the maximum number of fraction digits
1063     * @see #setMaximumFractionDigits
1064     * @stable ICU 2.0
1065     */

1066    public int getMaximumFractionDigits() {
1067        return maximumFractionDigits;
1068    }
1069
1070    /**
1071     * Sets the maximum number of digits allowed in the fraction portion of a
1072     * number. This must be >= minimumFractionDigits. If the
1073     * new value for maximumFractionDigits is less than the current value
1074     * of minimumFractionDigits, then minimumFractionDigits will also be set to
1075     * the new value.
1076     * @param newValue the maximum number of fraction digits to be shown; if
1077     * less than zero, then zero is used. The concrete subclass may enforce an
1078     * upper limit to this value appropriate to the numeric type being formatted.
1079     * @see #getMaximumFractionDigits
1080     * @stable ICU 2.0
1081     */

1082    public void setMaximumFractionDigits(int newValue) {
1083        maximumFractionDigits = Math.max(0,newValue);
1084        if (maximumFractionDigits < minimumFractionDigits)
1085            minimumFractionDigits = maximumFractionDigits;
1086    }
1087
1088    /**
1089     * Returns the minimum number of digits allowed in the fraction portion of a
1090     * number. The default value is 0, which subclasses can override.
1091     * When formatting, if this value is not reached, numbers are padded on
1092     * the right with the locale-specific '0' character to ensure at least
1093     * this number of fraction digits. When parsing, this has no effect.
1094     * @return the minimum number of fraction digits
1095     * @see #setMinimumFractionDigits
1096     * @stable ICU 2.0
1097     */

1098    public int getMinimumFractionDigits() {
1099        return minimumFractionDigits;
1100    }
1101
1102    /**
1103     * Sets the minimum number of digits allowed in the fraction portion of a
1104     * number. This must be <= maximumFractionDigits. If the
1105     * new value for minimumFractionDigits exceeds the current value
1106     * of maximumFractionDigits, then maximumFractionDigits will also be set to
1107     * the new value.
1108     * @param newValue the minimum number of fraction digits to be shown; if
1109     * less than zero, then zero is used. Subclasses might enforce an
1110     * upper limit to this value appropriate to the numeric type being formatted.
1111     * @see #getMinimumFractionDigits
1112     * @stable ICU 2.0
1113     */

1114    public void setMinimumFractionDigits(int newValue) {
1115        minimumFractionDigits = Math.max(0,newValue);
1116        if (maximumFractionDigits < minimumFractionDigits)
1117            maximumFractionDigits = minimumFractionDigits;
1118    }
1119
1120    /**
1121     * Sets the <tt>Currency</tt> object used to display currency
1122     * amounts. This takes effect immediately, if this format is a
1123     * currency format. If this format is not a currency format, then
1124     * the currency object is used if and when this object becomes a
1125     * currency format.
1126     * @param theCurrency new currency object to use. May be null for
1127     * some subclasses.
1128     * @stable ICU 2.6
1129     */

1130    public void setCurrency(Currency theCurrency) {
1131        currency = theCurrency;
1132    }
1133
1134    /**
1135     * Gets the <tt>Currency</tt> object used to display currency
1136     * amounts. This may be null.
1137     * @stable ICU 2.6
1138     */

1139    public Currency getCurrency() {
1140        return currency;
1141    }
1142    
1143    /**
1144     * Returns the currency in effect for this formatter. Subclasses
1145     * should override this method as needed. Unlike getCurrency(),
1146     * this method should never return null.
1147     * @return a non-null Currency
1148     * @internal
1149     * @deprecated This API is ICU internal only.
1150     */

1151    protected Currency getEffectiveCurrency() {
1152        Currency c = getCurrency();
1153        if (c == null) {
1154            ULocale uloc = getLocale(ULocale.VALID_LOCALE);
1155            if (uloc == null) {
1156                uloc = ULocale.getDefault();
1157            }
1158            c = Currency.getInstance(uloc);
1159        }
1160        return c;
1161    }
1162
1163    // =======================privates===============================
1164

1165    // Hook for service
1166
private static NumberFormat getInstance(ULocale desiredLocale, int choice) {
1167// if (shim == null) {
1168
// return createInstance(desiredLocale, choice);
1169
// } else {
1170
// // TODO: shims must call setLocale() on object they create
1171
// return getShim().createInstance(desiredLocale, choice);
1172
// }
1173
return getShim().createInstance(desiredLocale, choice);
1174    }
1175
1176    // [NEW]
1177
static NumberFormat createInstance(ULocale desiredLocale, int choice) {
1178        String JavaDoc pattern = getPattern(desiredLocale, choice);
1179        DecimalFormatSymbols symbols = new DecimalFormatSymbols(desiredLocale);
1180        
1181        // Here we assume that the locale passed in is in the canonical
1182
// form, e.g: pt_PT_@currency=PTE not pt_PT_PREEURO
1183
if(choice == CURRENCYSTYLE){
1184            String JavaDoc temp = symbols.getCurrencyPattern();
1185            if(temp!=null){
1186                pattern = temp;
1187            }
1188        }
1189        
1190        DecimalFormat format = new DecimalFormat(pattern, symbols);
1191        // System.out.println("loc: " + desiredLocale + " choice: " + choice + " pat: " + pattern + " sym: " + symbols + " result: " + format);
1192

1193        /*Bug 4408066
1194         Add codes for the new method getIntegerInstance() [Richard/GCL]
1195        */

1196        // TODO: revisit this -- this is almost certainly not the way we want
1197
// to do this. aliu 1/6/2004
1198
if (choice == INTEGERSTYLE) {
1199            format.setMaximumFractionDigits(0);
1200            format.setDecimalSeparatorAlwaysShown(false);
1201            format.setParseIntegerOnly(true);
1202        }
1203        
1204        // TODO: the actual locale of the *pattern* may differ from that
1205
// for the *symbols*. For now, we use the data for the symbols.
1206
// Revisit this.
1207
ULocale valid = symbols.getLocale(ULocale.VALID_LOCALE);
1208        ULocale actual = symbols.getLocale(ULocale.ACTUAL_LOCALE);
1209        format.setLocale(valid, actual);
1210        
1211        return format;
1212    }
1213
1214    /**
1215     * Returns the pattern for the provided locale and choice.
1216     * @param forLocale the locale of the data.
1217     * @param choice the pattern format.
1218     * @return the pattern
1219     * @deprecated ICU 3.4 subclassers should override getPattern(ULocale, int) instead of this method.
1220     */

1221    protected static String JavaDoc getPattern(Locale JavaDoc forLocale, int choice) {
1222        return getPattern(ULocale.forLocale(forLocale), choice);
1223    }
1224
1225    /**
1226     * Returns the pattern for the provided locale and choice.
1227     * @param forLocale the locale of the data.
1228     * @param choice the pattern format.
1229     * @return the pattern
1230     * @draft ICU 3.2
1231     * @provisional This API might change or be removed in a future release.
1232     */

1233    protected static String JavaDoc getPattern(ULocale forLocale, int choice) {
1234
1235        /* The following code takes care of a few cases where the
1236         * resource data in the underlying JDK lags the new features
1237         * we have added to ICU4J: scientific notation, rounding, and
1238         * secondary grouping.
1239         *
1240         * We detect these cases here and return various hard-coded
1241         * resource data. This is the simplest solution for now, but
1242         * it is not a good long-term mechanism.
1243         *
1244         * We should replace this code with a data-driven mechanism
1245         * that reads the bundle com.ibm.icu.impl.data.LocaleElements
1246         * and parses an exception table that overrides the standard
1247         * data at java.text.resource.LocaleElements*.java.
1248         * Alternatively, we should create our own copy of the
1249         * resource data, and use that exclusively.
1250         */

1251
1252        // TEMPORARY, until we get scientific patterns into the main
1253
// resources: Retrieve scientific patterns from our resources.
1254
if (choice == SCIENTIFICSTYLE) {
1255            // Temporarily hard code; retrieve from resource later
1256
/*For ICU compatibility [Richard/GCL]*/
1257            return "#E0";
1258            // return NumberFormat.getBaseStringArray("NumberPatterns")[SCIENTIFICSTYLE];
1259
}
1260        // TEMPORARY: Use rounding for Swiss currency
1261
//if (choice == CURRENCYSTYLE &&
1262
// forLocale.getCountry().equals("CH")) {
1263
// return "'Fr. '#,##0.05;'Fr.-'#,##0.05";
1264
//}
1265
// TEMPORARY: Special case IN number format
1266
//if (choice == NUMBERSTYLE &&
1267
// forLocale.getCountry().equals("IN")) {
1268
// return "#,##,##0.###";
1269
//}
1270

1271        // {dlf}
1272
ICUResourceBundle rb = (ICUResourceBundle)UResourceBundle.
1273            getBundleInstance(ICUResourceBundle.ICU_BASE_NAME, forLocale);
1274        String JavaDoc[] numberPatterns = rb.getStringArray("NumberPatterns");
1275
1276        /* {dlf}
1277        // Try the cache first
1278        String[] numberPatterns = (String[]) cachedLocaleData.get(forLocale);
1279        if (numberPatterns == null) {
1280            OverlayBundle resource = new OverlayBundle(new String[]
1281                { "com.ibm.icu.impl.data.LocaleElements", RESOURCE_BASE }, forLocale);
1282            numberPatterns = resource.getStringArray("NumberPatterns");
1283            // Update the cache
1284            cachedLocaleData.put(forLocale, numberPatterns);
1285        }
1286        */

1287
1288        /*Bug 4408066
1289         Add codes for the new method getIntegerInstance() [Richard/GCL]
1290        */

1291        int entry = (choice == INTEGERSTYLE) ? NUMBERSTYLE : choice; //[Richard/GCL]
1292
return numberPatterns[entry]; //[Richard/GCL]
1293
}
1294
1295    /**
1296     * First, read in the default serializable data.
1297     *
1298     * Then, if <code>serialVersionOnStream</code> is less than 1, indicating that
1299     * the stream was written by JDK 1.1,
1300     * set the <code>int</code> fields such as <code>maximumIntegerDigits</code>
1301     * to be equal to the <code>byte</code> fields such as <code>maxIntegerDigits</code>,
1302     * since the <code>int</code> fields were not present in JDK 1.1.
1303     * Finally, set serialVersionOnStream back to the maximum allowed value so that
1304     * default serialization will work properly if this object is streamed out again.
1305     */

1306    private void readObject(ObjectInputStream JavaDoc stream)
1307         throws IOException JavaDoc, ClassNotFoundException JavaDoc
1308    {
1309        stream.defaultReadObject();
1310        ///CLOVER:OFF
1311
// we don't have serialization data for this format
1312
if (serialVersionOnStream < 1) {
1313            // Didn't have additional int fields, reassign to use them.
1314
maximumIntegerDigits = maxIntegerDigits;
1315            minimumIntegerDigits = minIntegerDigits;
1316            maximumFractionDigits = maxFractionDigits;
1317            minimumFractionDigits = minFractionDigits;
1318        }
1319        ///CLOVER:ON
1320
/*Bug 4185761
1321          Validate the min and max fields [Richard/GCL]
1322        */

1323        if (minimumIntegerDigits > maximumIntegerDigits ||
1324            minimumFractionDigits > maximumFractionDigits ||
1325            minimumIntegerDigits < 0 || minimumFractionDigits < 0) {
1326            throw new InvalidObjectException JavaDoc("Digit count range invalid");
1327        }
1328        serialVersionOnStream = currentSerialVersion;
1329    }
1330
1331    /**
1332     * Write out the default serializable data, after first setting
1333     * the <code>byte</code> fields such as <code>maxIntegerDigits</code> to be
1334     * equal to the <code>int</code> fields such as <code>maximumIntegerDigits</code>
1335     * (or to <code>Byte.MAX_VALUE</code>, whichever is smaller), for compatibility
1336     * with the JDK 1.1 version of the stream format.
1337     */

1338    private void writeObject(ObjectOutputStream JavaDoc stream)
1339         throws IOException JavaDoc
1340    {
1341        maxIntegerDigits = (maximumIntegerDigits > Byte.MAX_VALUE) ? Byte.MAX_VALUE :
1342            (byte)maximumIntegerDigits;
1343        minIntegerDigits = (minimumIntegerDigits > Byte.MAX_VALUE) ? Byte.MAX_VALUE :
1344            (byte)minimumIntegerDigits;
1345        maxFractionDigits = (maximumFractionDigits > Byte.MAX_VALUE) ? Byte.MAX_VALUE :
1346            (byte)maximumFractionDigits;
1347        minFractionDigits = (minimumFractionDigits > Byte.MAX_VALUE) ? Byte.MAX_VALUE :
1348            (byte)minimumFractionDigits;
1349        stream.defaultWriteObject();
1350    }
1351
1352// Unused -- Alan 2003-05
1353
// /**
1354
// * Cache to hold the NumberPatterns of a Locale.
1355
// */
1356
// private static final Hashtable cachedLocaleData = new Hashtable(3);
1357

1358    /*Bug 4408066
1359      Add Field for the new method getIntegerInstance() [Richard/GCL]
1360    */

1361
1362    /**
1363     * True if the the grouping (i.e. thousands) separator is used when
1364     * formatting and parsing numbers.
1365     *
1366     * @serial
1367     * @see #isGroupingUsed
1368     */

1369    private boolean groupingUsed = true;
1370
1371    /**
1372     * The maximum number of digits allowed in the integer portion of a
1373     * number. <code>maxIntegerDigits</code> must be greater than or equal to
1374     * <code>minIntegerDigits</code>.
1375     * <p>
1376     * <strong>Note:</strong> This field exists only for serialization
1377     * compatibility with JDK 1.1. In JDK 1.2 and higher, the new
1378     * <code>int</code> field <code>maximumIntegerDigits</code> is used instead.
1379     * When writing to a stream, <code>maxIntegerDigits</code> is set to
1380     * <code>maximumIntegerDigits</code> or <code>Byte.MAX_VALUE</code>,
1381     * whichever is smaller. When reading from a stream, this field is used
1382     * only if <code>serialVersionOnStream</code> is less than 1.
1383     *
1384     * @serial
1385     * @see #getMaximumIntegerDigits
1386     */

1387    private byte maxIntegerDigits = 40;
1388
1389    /**
1390     * The minimum number of digits allowed in the integer portion of a
1391     * number. <code>minimumIntegerDigits</code> must be less than or equal to
1392     * <code>maximumIntegerDigits</code>.
1393     * <p>
1394     * <strong>Note:</strong> This field exists only for serialization
1395     * compatibility with JDK 1.1. In JDK 1.2 and higher, the new
1396     * <code>int</code> field <code>minimumIntegerDigits</code> is used instead.
1397     * When writing to a stream, <code>minIntegerDigits</code> is set to
1398     * <code>minimumIntegerDigits</code> or <code>Byte.MAX_VALUE</code>,
1399     * whichever is smaller. When reading from a stream, this field is used
1400     * only if <code>serialVersionOnStream</code> is less than 1.
1401     *
1402     * @serial
1403     * @see #getMinimumIntegerDigits
1404     */

1405    private byte minIntegerDigits = 1;
1406
1407    /**
1408     * The maximum number of digits allowed in the fractional portion of a
1409     * number. <code>maximumFractionDigits</code> must be greater than or equal to
1410     * <code>minimumFractionDigits</code>.
1411     * <p>
1412     * <strong>Note:</strong> This field exists only for serialization
1413     * compatibility with JDK 1.1. In JDK 1.2 and higher, the new
1414     * <code>int</code> field <code>maximumFractionDigits</code> is used instead.
1415     * When writing to a stream, <code>maxFractionDigits</code> is set to
1416     * <code>maximumFractionDigits</code> or <code>Byte.MAX_VALUE</code>,
1417     * whichever is smaller. When reading from a stream, this field is used
1418     * only if <code>serialVersionOnStream</code> is less than 1.
1419     *
1420     * @serial
1421     * @see #getMaximumFractionDigits
1422     */

1423    private byte maxFractionDigits = 3; // invariant, >= minFractionDigits
1424

1425    /**
1426     * The minimum number of digits allowed in the fractional portion of a
1427     * number. <code>minimumFractionDigits</code> must be less than or equal to
1428     * <code>maximumFractionDigits</code>.
1429     * <p>
1430     * <strong>Note:</strong> This field exists only for serialization
1431     * compatibility with JDK 1.1. In JDK 1.2 and higher, the new
1432     * <code>int</code> field <code>minimumFractionDigits</code> is used instead.
1433     * When writing to a stream, <code>minFractionDigits</code> is set to
1434     * <code>minimumFractionDigits</code> or <code>Byte.MAX_VALUE</code>,
1435     * whichever is smaller. When reading from a stream, this field is used
1436     * only if <code>serialVersionOnStream</code> is less than 1.
1437     *
1438     * @serial
1439     * @see #getMinimumFractionDigits
1440     */

1441    private byte minFractionDigits = 0;
1442
1443    /**
1444     * True if this format will parse numbers as integers only.
1445     *
1446     * @serial
1447     * @see #isParseIntegerOnly
1448     */

1449    private boolean parseIntegerOnly = false;
1450
1451    // new fields for 1.2. byte is too small for integer digits.
1452

1453    /**
1454     * The maximum number of digits allowed in the integer portion of a
1455     * number. <code>maximumIntegerDigits</code> must be greater than or equal to
1456     * <code>minimumIntegerDigits</code>.
1457     *
1458     * @serial
1459     * @see #getMaximumIntegerDigits
1460     */

1461    private int maximumIntegerDigits = 40;
1462
1463    /**
1464     * The minimum number of digits allowed in the integer portion of a
1465     * number. <code>minimumIntegerDigits</code> must be less than or equal to
1466     * <code>maximumIntegerDigits</code>.
1467     *
1468     * @serial
1469     * @see #getMinimumIntegerDigits
1470     */

1471    private int minimumIntegerDigits = 1;
1472
1473    /**
1474     * The maximum number of digits allowed in the fractional portion of a
1475     * number. <code>maximumFractionDigits</code> must be greater than or equal to
1476     * <code>minimumFractionDigits</code>.
1477     *
1478     * @serial
1479     * @see #getMaximumFractionDigits
1480     */

1481    private int maximumFractionDigits = 3; // invariant, >= minFractionDigits
1482

1483    /**
1484     * The minimum number of digits allowed in the fractional portion of a
1485     * number. <code>minimumFractionDigits</code> must be less than or equal to
1486     * <code>maximumFractionDigits</code>.
1487     *
1488     * @serial
1489     * @see #getMinimumFractionDigits
1490     */

1491    private int minimumFractionDigits = 0;
1492
1493    /**
1494     * Currency object used to format currencies. Subclasses may
1495     * ignore this if they are not currency formats. This will be
1496     * null unless a subclass sets it to a non-null value.
1497     * @since ICU 2.6
1498     */

1499    private Currency currency;
1500
1501    static final int currentSerialVersion = 1;
1502
1503    /**
1504     * Describes the version of <code>NumberFormat</code> present on the stream.
1505     * Possible values are:
1506     * <ul>
1507     * <li><b>0</b> (or uninitialized): the JDK 1.1 version of the stream format.
1508     * In this version, the <code>int</code> fields such as
1509     * <code>maximumIntegerDigits</code> were not present, and the <code>byte</code>
1510     * fields such as <code>maxIntegerDigits</code> are used instead.
1511     *
1512     * <li><b>1</b>: the JDK 1.2 version of the stream format. The values of the
1513     * <code>byte</code> fields such as <code>maxIntegerDigits</code> are ignored,
1514     * and the <code>int</code> fields such as <code>maximumIntegerDigits</code>
1515     * are used instead.
1516     * </ul>
1517     * When streaming out a <code>NumberFormat</code>, the most recent format
1518     * (corresponding to the highest allowable <code>serialVersionOnStream</code>)
1519     * is always written.
1520     *
1521     * @serial
1522     */

1523    private int serialVersionOnStream = currentSerialVersion;
1524
1525    // Removed "implements Cloneable" clause. Needs to update serialization
1526
// ID for backward compatibility.
1527
private static final long serialVersionUID = -2308460125733713944L;
1528
1529    /**
1530     * Empty constructor. Public for compatibily with JDK which lets the
1531     * compiler generate a default public constructor even though this is
1532     * an abstract class.
1533     * @stable ICU 2.6
1534     */

1535    public NumberFormat() {
1536    }
1537
1538    // new in ICU4J 3.6
1539
private boolean parseStrict;
1540
1541//#ifndef FOUNDATION
1542
//## /**
1543
//## * [Spark/CDL] The instances of this inner class are used as attribute keys and values
1544
//## * in AttributedCharacterIterator that
1545
//## * NumberFormat.formatToCharacterIterator() method returns.
1546
//## * <p>
1547
//## * There is no public constructor to this class, the only instances are the
1548
//## * constants defined here.
1549
//## * <p>
1550
//## * @stable ICU 3.6
1551
//## */
1552
//## public static class Field extends Format.Field {
1553
//## // generated by serialver from JDK 1.4.1_01
1554
//## static final long serialVersionUID = -4516273749929385842L;
1555
//##
1556
//## /**
1557
//## * @stable ICU 3.6
1558
//## */
1559
//## public static final Field SIGN = new Field("sign");
1560
//##
1561
//## /**
1562
//## * @stable ICU 3.6
1563
//## */
1564
//## public static final Field INTEGER = new Field("integer");
1565
//##
1566
//## /**
1567
//## * @stable ICU 3.6
1568
//## */
1569
//## public static final Field FRACTION = new Field("fraction");
1570
//##
1571
//## /**
1572
//## * @stable ICU 3.6
1573
//## */
1574
//## public static final Field EXPONENT = new Field("exponent");
1575
//##
1576
//## /**
1577
//## * @stable ICU 3.6
1578
//## */
1579
//## public static final Field EXPONENT_SIGN = new Field("exponent sign");
1580
//##
1581
//## /**
1582
//## * @stable ICU 3.6
1583
//## */
1584
//## public static final Field EXPONENT_SYMBOL = new Field("exponent symbol");
1585
//##
1586
//## /**
1587
//## * @stable ICU 3.6
1588
//## */
1589
//## public static final Field DECIMAL_SEPARATOR = new Field("decimal separator");
1590
//## /**
1591
//## * @stable ICU 3.6
1592
//## */
1593
//## public static final Field GROUPING_SEPARATOR = new Field("grouping separator");
1594
//##
1595
//## /**
1596
//## * @stable ICU 3.6
1597
//## */
1598
//## public static final Field PERCENT = new Field("percent");
1599
//##
1600
//## /**
1601
//## * @stable ICU 3.6
1602
//## */
1603
//## public static final Field PERMILLE = new Field("per mille");
1604
//##
1605
//## /**
1606
//## * @stable ICU 3.6
1607
//## */
1608
//## public static final Field CURRENCY = new Field("currency");
1609
//##
1610
//## /**
1611
//## * Constructs a new instance of NumberFormat.Field with the given field
1612
//## * name.
1613
//## * @stable ICU 3.6
1614
//## */
1615
//## protected Field(String fieldName) {
1616
//## super(fieldName);
1617
//## }
1618
//##
1619
//## /**
1620
//## * serizalization method resolve instances to the constant
1621
//## * NumberFormat.Field values
1622
//## * @stable ICU 3.6
1623
//## */
1624
//## protected Object readResolve() throws InvalidObjectException {
1625
//## if (this.getName().equals(INTEGER.getName()))
1626
//## return INTEGER;
1627
//## if (this.getName().equals(FRACTION.getName()))
1628
//## return FRACTION;
1629
//## if (this.getName().equals(EXPONENT.getName()))
1630
//## return EXPONENT;
1631
//## if (this.getName().equals(EXPONENT_SIGN.getName()))
1632
//## return EXPONENT_SIGN;
1633
//## if (this.getName().equals(EXPONENT_SYMBOL.getName()))
1634
//## return EXPONENT_SYMBOL;
1635
//## if (this.getName().equals(CURRENCY.getName()))
1636
//## return CURRENCY;
1637
//## if (this.getName().equals(DECIMAL_SEPARATOR.getName()))
1638
//## return DECIMAL_SEPARATOR;
1639
//## if (this.getName().equals(GROUPING_SEPARATOR.getName()))
1640
//## return GROUPING_SEPARATOR;
1641
//## if (this.getName().equals(PERCENT.getName()))
1642
//## return PERCENT;
1643
//## if (this.getName().equals(PERMILLE.getName()))
1644
//## return PERMILLE;
1645
//## if (this.getName().equals(SIGN.getName()))
1646
//## return SIGN;
1647
//##
1648
//## throw new InvalidObjectException("An invalid object.");
1649
//## }
1650
//## }
1651
//#endif
1652
}
1653
Popular Tags