]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-4_2_1-src/src/com/ibm/icu/text/NumberFormat.java
icu4jsrc
[Dictionary.git] / jars / icu4j-4_2_1-src / src / com / ibm / icu / text / NumberFormat.java
1 //##header\r
2 /*\r
3  *******************************************************************************\r
4  * Copyright (C) 1996-2009, International Business Machines Corporation and    *\r
5  * others. All Rights Reserved.                                                *\r
6  *******************************************************************************\r
7  */\r
8 \r
9 package com.ibm.icu.text;\r
10 \r
11 import java.io.IOException;\r
12 import java.io.InvalidObjectException;\r
13 import java.io.ObjectInputStream;\r
14 import java.io.ObjectOutputStream;\r
15 import java.math.BigInteger;\r
16 import java.text.FieldPosition;\r
17 import java.text.ParseException;\r
18 import java.text.ParsePosition;\r
19 import java.util.Collections;\r
20 import java.util.Locale;\r
21 import java.util.MissingResourceException;\r
22 import java.util.Set;\r
23 //#if defined(FOUNDATION10) || defined(J2SE13)\r
24 //#else\r
25 import java.text.Format;\r
26 //#endif\r
27 \r
28 import com.ibm.icu.impl.ICUResourceBundle;\r
29 import com.ibm.icu.impl.Utility;\r
30 import com.ibm.icu.util.Currency;\r
31 import com.ibm.icu.util.CurrencyAmount;\r
32 import com.ibm.icu.util.ULocale;\r
33 import com.ibm.icu.util.UResourceBundle;\r
34 \r
35 // this is an enhanced version that is based on the standard version in the JDK\r
36 /**\r
37  * <code>NumberFormat</code> is the abstract base class for all number\r
38  * formats. This class provides the interface for formatting and parsing\r
39  * numbers. <code>NumberFormat</code> also provides methods for determining\r
40  * which locales have number formats, and what their names are.\r
41  *\r
42  * <code>NumberFormat</code> helps you to format and parse numbers for any locale.\r
43  * Your code can be completely independent of the locale conventions for\r
44  * decimal points, thousands-separators, or even the particular decimal\r
45  * digits used, or whether the number format is even decimal.\r
46  *\r
47  * <p>\r
48  * To format a number for the current Locale, use one of the factory\r
49  * class methods:\r
50  * <blockquote>\r
51  * <pre>\r
52  *  myString = NumberFormat.getInstance().format(myNumber);\r
53  * </pre>\r
54  * </blockquote>\r
55  * If you are formatting multiple numbers, it is\r
56  * more efficient to get the format and use it multiple times so that\r
57  * the system doesn't have to fetch the information about the local\r
58  * language and country conventions multiple times.\r
59  * <blockquote>\r
60  * <pre>\r
61  * NumberFormat nf = NumberFormat.getInstance();\r
62  * for (int i = 0; i < a.length; ++i) {\r
63  *     output.println(nf.format(myNumber[i]) + "; ");\r
64  * }\r
65  * </pre>\r
66  * </blockquote>\r
67  * To format a number for a different Locale, specify it in the\r
68  * call to <code>getInstance</code>.\r
69  * <blockquote>\r
70  * <pre>\r
71  * NumberFormat nf = NumberFormat.getInstance(Locale.FRENCH);\r
72  * </pre>\r
73  * </blockquote>\r
74  * You can also use a <code>NumberFormat</code> to parse numbers:\r
75  * <blockquote>\r
76  * <pre>\r
77  * myNumber = nf.parse(myString);\r
78  * </pre>\r
79  * </blockquote>\r
80  * Use <code>getInstance</code> or <code>getNumberInstance</code> to get the\r
81  * normal number format. Use <code>getIntegerInstance</code> to get an\r
82  * integer number format. Use <code>getCurrencyInstance</code> to get the\r
83  * currency number format. And use <code>getPercentInstance</code> to get a\r
84  * format for displaying percentages. With this format, a fraction like\r
85  * 0.53 is displayed as 53%.\r
86  *\r
87  * <p>\r
88  * Starting from ICU 4.2, you can use getInstance() by passing in a 'style'\r
89  * as parameter to get the correct instance. \r
90  * For example, \r
91  * use getInstance(...NUMBERSTYLE) to get the normal number format,\r
92  * getInstance(...PERCENTSTYLE) to get a format for displaying percentage,\r
93  * getInstance(...SCIENTIFICSTYLE) to get a format for displaying scientific number,\r
94  * getInstance(...INTEGERSTYLE) to get an integer number format,\r
95  * getInstance(...CURRENCYSTYLE) to get the currency number format, \r
96  * in which the currency is represented by its symbol, for example, "$3.00".\r
97  * getInstance(...ISOCURRENCYSTYLE)  to get the currency number format, \r
98  * in which the currency is represented by its ISO code, for example "USD3.00".\r
99  * getInstance(...PLURALCURRENCYSTYLE) to get the currency number format,\r
100  * in which the currency is represented by its full name in plural format,\r
101  * for example, "3.00 US dollars" or "1.00 US dollar".\r
102  *\r
103  *\r
104  * <p>\r
105  * You can also control the display of numbers with such methods as\r
106  * <code>setMinimumFractionDigits</code>.\r
107  * If you want even more control over the format or parsing,\r
108  * or want to give your users more control,\r
109  * you can try casting the <code>NumberFormat</code> you get from the factory methods\r
110  * to a <code>DecimalFormat</code>. This will work for the vast majority\r
111  * of locales; just remember to put it in a <code>try</code> block in case you\r
112  * encounter an unusual one.\r
113  *\r
114  * <p>\r
115  * NumberFormat is designed such that some controls\r
116  * work for formatting and others work for parsing.  The following is\r
117  * the detailed description for each these control methods,\r
118  * <p>\r
119  * setParseIntegerOnly : only affects parsing, e.g.\r
120  * if true,  "3456.78" -> 3456 (and leaves the parse position just after '6')\r
121  * if false, "3456.78" -> 3456.78 (and leaves the parse position just after '8')\r
122  * This is independent of formatting.  If you want to not show a decimal point\r
123  * where there might be no digits after the decimal point, use\r
124  * setDecimalSeparatorAlwaysShown on DecimalFormat.\r
125  * <p>\r
126  * You can also use forms of the <code>parse</code> and <code>format</code>\r
127  * methods with <code>ParsePosition</code> and <code>FieldPosition</code> to\r
128  * allow you to:\r
129  * <ul>\r
130  * <li> progressively parse through pieces of a string\r
131  * <li> align the decimal point and other areas\r
132  * </ul>\r
133  * For example, you can align numbers in two ways:\r
134  * <ol>\r
135  * <li> If you are using a monospaced font with spacing for alignment,\r
136  *      you can pass the <code>FieldPosition</code> in your format call, with\r
137  *      <code>field</code> = <code>INTEGER_FIELD</code>. On output,\r
138  *      <code>getEndIndex</code> will be set to the offset between the\r
139  *      last character of the integer and the decimal. Add\r
140  *      (desiredSpaceCount - getEndIndex) spaces at the front of the string.\r
141  *\r
142  * <li> If you are using proportional fonts,\r
143  *      instead of padding with spaces, measure the width\r
144  *      of the string in pixels from the start to <code>getEndIndex</code>.\r
145  *      Then move the pen by\r
146  *      (desiredPixelWidth - widthToAlignmentPoint) before drawing the text.\r
147  *      It also works where there is no decimal, but possibly additional\r
148  *      characters at the end, e.g., with parentheses in negative\r
149  *      numbers: "(12)" for -12.\r
150  * </ol>\r
151  *\r
152  * <h4>Synchronization</h4>\r
153  * <p>\r
154  * Number formats are generally not synchronized. It is recommended to create \r
155  * separate format instances for each thread. If multiple threads access a format\r
156  * concurrently, it must be synchronized externally. \r
157  * <p>\r
158  *\r
159  * <h4>DecimalFormat</h4>\r
160  * <p>DecimalFormat is the concrete implementation of NumberFormat, and the\r
161  * NumberFormat API is essentially an abstraction from DecimalFormat's API.\r
162  * Refer to DecimalFormat for more information about this API.</p>\r
163  *\r
164  * see          DecimalFormat\r
165  * see          java.text.ChoiceFormat\r
166  * @author       Mark Davis\r
167  * @author       Helena Shih\r
168  * @author       Alan Liu\r
169  * @stable ICU 2.0\r
170  */\r
171 public abstract class NumberFormat extends UFormat {\r
172 \r
173     /**\r
174      * Constants to specify normal number style of format.\r
175      * @draft ICU 4.2\r
176      * @provisional This API might change or be removed in a future release.\r
177      */\r
178     public static final int NUMBERSTYLE = 0;\r
179     /**\r
180      * Constants to specify currency style of format which uses currency symbol\r
181      * to represent currency, for example: "$3.00".\r
182      * @draft ICU 4.2\r
183      * @provisional This API might change or be removed in a future release.\r
184      */\r
185     public static final int CURRENCYSTYLE = 1;\r
186     /**\r
187      * Constants to specify a style of format to display percent.\r
188      * @draft ICU 4.2\r
189      * @provisional This API might change or be removed in a future release.\r
190      */\r
191     public static final int PERCENTSTYLE = 2;\r
192     /**\r
193      * Constants to specify a style of format to display scientific number.\r
194      * @draft ICU 4.2\r
195      * @provisional This API might change or be removed in a future release.\r
196      */\r
197     public static final int SCIENTIFICSTYLE = 3;\r
198     /**\r
199      * Constants to specify a integer number style format.\r
200      * @draft ICU 4.2\r
201      * @provisional This API might change or be removed in a future release.\r
202      */\r
203     public static final int INTEGERSTYLE = 4;\r
204     /**\r
205      * Constants to specify currency style of format which uses currency \r
206      * ISO code to represent currency, for example: "USD3.00".\r
207      * @draft ICU 4.2\r
208      * @provisional This API might change or be removed in a future release.\r
209      */\r
210     public static final int ISOCURRENCYSTYLE = 5;\r
211     /**\r
212      * Constants to specify currency style of format which uses currency \r
213      * long name with plural format to represent currency, for example,\r
214      * "3.00 US Dollars".\r
215      * @draft ICU 4.2\r
216      * @provisional This API might change or be removed in a future release.\r
217      */\r
218     public static final int PLURALCURRENCYSTYLE = 6;\r
219 \r
220     /**\r
221      * Field constant used to construct a FieldPosition object. Signifies that\r
222      * the position of the integer part of a formatted number should be returned.\r
223      * @see java.text.FieldPosition\r
224      * @stable ICU 2.0\r
225      */\r
226     public static final int INTEGER_FIELD = 0;\r
227 \r
228     /**\r
229      * Field constant used to construct a FieldPosition object. Signifies that\r
230      * the position of the fraction part of a formatted number should be returned.\r
231      * @see java.text.FieldPosition\r
232      * @stable ICU 2.0\r
233      */\r
234     public static final int FRACTION_FIELD = 1;\r
235 \r
236     // changed in ICU4J\r
237     /**\r
238      * Format an object.  Change: recognizes <code>BigInteger</code>\r
239      * and <code>BigDecimal</code> objects.\r
240      * @stable ICU 2.0\r
241      */\r
242     public StringBuffer format(Object number,\r
243                                StringBuffer toAppendTo,\r
244                                FieldPosition pos)\r
245     {\r
246         if (number instanceof Long) {\r
247             return format(((Long)number).longValue(), toAppendTo, pos);\r
248         } else if (number instanceof BigInteger) {\r
249             return format((BigInteger) number, toAppendTo, pos);\r
250 //#if defined(FOUNDATION10)\r
251 //#else\r
252         } else if (number instanceof java.math.BigDecimal) {\r
253             return format((java.math.BigDecimal) number, toAppendTo, pos);\r
254 //#endif\r
255         } else if (number instanceof com.ibm.icu.math.BigDecimal) {\r
256             return format((com.ibm.icu.math.BigDecimal) number, toAppendTo, pos);\r
257         } else if (number instanceof CurrencyAmount) {\r
258             return format((CurrencyAmount)number, toAppendTo, pos);\r
259         } else if (number instanceof Number) {\r
260             return format(((Number)number).doubleValue(), toAppendTo, pos);\r
261         } else {\r
262             throw new IllegalArgumentException("Cannot format given Object as a Number");\r
263         }\r
264     }\r
265 \r
266     /**\r
267      * @stable ICU 2.0\r
268      */\r
269     public final Object parseObject(String source,\r
270                                     ParsePosition parsePosition)\r
271     {\r
272         return parse(source, parsePosition);\r
273     }\r
274 \r
275     /**\r
276      * Specialization of format.\r
277      * @see java.text.Format#format(Object)\r
278      * @stable ICU 2.0\r
279      */\r
280     public final String format(double number) {\r
281         return format(number,new StringBuffer(),\r
282                       new FieldPosition(0)).toString();\r
283     }\r
284 \r
285     /**\r
286      * Specialization of format.\r
287      * @see java.text.Format#format(Object)\r
288      * @stable ICU 2.0\r
289      */\r
290     public final String format(long number) {\r
291         StringBuffer buf = new StringBuffer(19);\r
292         FieldPosition pos = new FieldPosition(0);\r
293         format(number, buf, pos);\r
294         return buf.toString();\r
295     }\r
296     \r
297     // [NEW]\r
298     /**\r
299      * Convenience method to format a BigInteger.\r
300      * @stable ICU 2.0\r
301      */\r
302     public final String format(BigInteger number) {\r
303         return format(number, new StringBuffer(),\r
304                       new FieldPosition(0)).toString();\r
305     }\r
306 \r
307 //#if defined(FOUNDATION10)\r
308 //#else\r
309     // [NEW]\r
310     /**\r
311      * Convenience method to format a BigDecimal.\r
312      * @stable ICU 2.0\r
313      */\r
314     public final String format(java.math.BigDecimal number) {\r
315         return format(number, new StringBuffer(),\r
316                       new FieldPosition(0)).toString();\r
317     }\r
318 //#endif\r
319 \r
320     // [NEW]\r
321     /**\r
322      * Convenience method to format an ICU BigDecimal.\r
323      * @stable ICU 2.0\r
324      */\r
325     public final String format(com.ibm.icu.math.BigDecimal number) {\r
326         return format(number, new StringBuffer(),\r
327                       new FieldPosition(0)).toString();\r
328     }\r
329 \r
330     // [NEW]\r
331     /**\r
332      * Convenience method to format a CurrencyAmount.\r
333      * @stable ICU 3.0\r
334      */\r
335     public final String format(CurrencyAmount currAmt) {\r
336         return format(currAmt, new StringBuffer(),\r
337                       new FieldPosition(0)).toString();\r
338     }\r
339 \r
340     /**\r
341      * Specialization of format.\r
342      * @see java.text.Format#format(Object, StringBuffer, FieldPosition)\r
343      * @stable ICU 2.0\r
344      */\r
345     public abstract StringBuffer format(double number,\r
346                                         StringBuffer toAppendTo,\r
347                                         FieldPosition pos);\r
348 \r
349     /**\r
350      * Specialization of format.\r
351      * @see java.text.Format#format(Object, StringBuffer, FieldPosition)\r
352      * @stable ICU 2.0\r
353      */\r
354     public abstract StringBuffer format(long number,\r
355                                         StringBuffer toAppendTo,\r
356                                         FieldPosition pos);\r
357     // [NEW] \r
358     /**\r
359      * Format a BigInteger.\r
360      * @see java.text.Format#format(Object, StringBuffer, FieldPosition)\r
361      * @stable ICU 2.0\r
362      */\r
363     public abstract StringBuffer format(BigInteger number,\r
364                                         StringBuffer toAppendTo,\r
365                                         FieldPosition pos); \r
366 //#if defined(FOUNDATION10)\r
367 //#else\r
368     \r
369     // [NEW]\r
370     /**\r
371      * Format a BigDecimal.\r
372      * @see java.text.Format#format(Object, StringBuffer, FieldPosition)\r
373      * @stable ICU 2.0\r
374      */\r
375     public abstract StringBuffer format(java.math.BigDecimal number,\r
376                                         StringBuffer toAppendTo,\r
377                                         FieldPosition pos);\r
378 //#endif\r
379 \r
380     // [NEW]\r
381     /**\r
382      * Format a BigDecimal.\r
383      * @see java.text.Format#format(Object, StringBuffer, FieldPosition)\r
384      * @stable ICU 2.0\r
385      */\r
386     public abstract StringBuffer format(com.ibm.icu.math.BigDecimal number,\r
387                                         StringBuffer toAppendTo,\r
388                                         FieldPosition pos);\r
389     // [NEW]\r
390     /**\r
391      * Format a CurrencyAmount.\r
392      * @see java.text.Format#format(Object, StringBuffer, FieldPosition)\r
393      * @stable ICU 3.0\r
394      */\r
395     public StringBuffer format(CurrencyAmount currAmt,\r
396                                StringBuffer toAppendTo,\r
397                                FieldPosition pos) {\r
398         // Default implementation -- subclasses may override\r
399         Currency save = getCurrency(), curr = currAmt.getCurrency();\r
400         boolean same = curr.equals(save);\r
401         if (!same) setCurrency(curr);\r
402         format(currAmt.getNumber(), toAppendTo, pos);\r
403         if (!same) setCurrency(save);\r
404         return toAppendTo;\r
405     }\r
406 \r
407     /**\r
408      * Returns a Long if possible (e.g., within the range [Long.MIN_VALUE,\r
409      * Long.MAX_VALUE] and with no decimals), otherwise a Double.\r
410      * If IntegerOnly is set, will stop at a decimal\r
411      * point (or equivalent; e.g., for rational numbers "1 2/3", will stop\r
412      * after the 1).\r
413      * Does not throw an exception; if no object can be parsed, index is\r
414      * unchanged!\r
415      * @see #isParseIntegerOnly\r
416      * @see java.text.Format#parseObject(String, ParsePosition)\r
417      * @stable ICU 2.0\r
418      */\r
419     public abstract Number parse(String text, ParsePosition parsePosition);\r
420 \r
421     /**\r
422      * Parses text from the beginning of the given string to produce a number.\r
423      * The method might not use the entire text of the given string.\r
424      *\r
425      * @param text A String whose beginning should be parsed.\r
426      * @return A Number parsed from the string.\r
427      * @exception ParseException if the beginning of the specified string \r
428      * cannot be parsed.\r
429      * @see #format\r
430      * @stable ICU 2.0\r
431      */\r
432     //Bug 4375399 [Richard/GCL]\r
433     public Number parse(String text) throws ParseException {\r
434         ParsePosition parsePosition = new ParsePosition(0);\r
435         Number result = parse(text, parsePosition);\r
436         if (parsePosition.getIndex() == 0) {\r
437             throw new ParseException("Unparseable number: \"" + text + '"',\r
438                                      parsePosition.getErrorIndex());\r
439         }\r
440         return result;\r
441     }\r
442 \r
443     // [NEW]\r
444     /**\r
445      * Parses text from the given string as a CurrencyAmount.  Unlike\r
446      * the parse() method, this method will attempt to parse a generic\r
447      * currency name, searching for a match of this object's locale's\r
448      * currency display names, or for a 3-letter ISO currency code.\r
449      * This method will fail if this format is not a currency format,\r
450      * that is, if it does not contain the currency pattern symbol\r
451      * (U+00A4) in its prefix or suffix.\r
452      *\r
453      * @param text the string to parse\r
454      * @param pos input-output position; on input, the position within\r
455      * text to match; must have 0 <= pos.getIndex() < text.length();\r
456      * on output, the position after the last matched character. If\r
457      * the parse fails, the position in unchanged upon output.\r
458      * @return a CurrencyAmount, or null upon failure\r
459      * @internal\r
460      * @deprecated This API is ICU internal only.\r
461      */\r
462     CurrencyAmount parseCurrency(String text, ParsePosition pos) {\r
463         // Default implementation only -- subclasses should override\r
464         Number n = parse(text, pos);\r
465         return n == null ? null : new CurrencyAmount(n, getEffectiveCurrency());\r
466     }\r
467 \r
468     /**\r
469      * Returns true if this format will parse numbers as integers only.\r
470      * For example in the English locale, with ParseIntegerOnly true, the\r
471      * string "1234." would be parsed as the integer value 1234 and parsing\r
472      * would stop at the "." character.  The decimal separator accepted\r
473      * by the parse operation is locale-dependent and determined by the\r
474      * subclass.\r
475      * @return true if this will parse integers only\r
476      * @stable ICU 2.0\r
477      */\r
478     public boolean isParseIntegerOnly() {\r
479         return parseIntegerOnly;\r
480     }\r
481 \r
482     /**\r
483      * Sets whether or not numbers should be parsed as integers only.\r
484      * @param value true if this should parse integers only\r
485      * @see #isParseIntegerOnly\r
486      * @stable ICU 2.0\r
487      */\r
488     public void setParseIntegerOnly(boolean value) {\r
489         parseIntegerOnly = value;\r
490     }\r
491 \r
492     /**\r
493      * Sets whether strict parsing is in effect.  When this is true, the\r
494      * following conditions cause a parse failure (examples use the pattern "#,##0.#"):<ul>\r
495      * <li>Leading zeros<br>\r
496      * '00', '0123' fail the parse, but '0' and '0.001' pass</li>\r
497      * <li>Leading or doubled grouping separators<br>\r
498      * ',123' and '1,,234" fail</li>\r
499      * <li>Groups of incorrect length when grouping is used<br>\r
500      * '1,23' and '1234,567' fail, but '1234' passes</li>\r
501      * <li>Grouping separators used in numbers followed by exponents<br>\r
502      * '1,234E5' fails, but '1234E5' and '1,234E' pass ('E' is not an exponent when\r
503      * not followed by a number)</li>\r
504      * </ul>\r
505      * When strict parsing is off, leading zeros and all grouping separators are ignored.\r
506      * This is the default behavior.\r
507      * @param value True to enable strict parsing.  Default is false.\r
508      * @see #isParseStrict\r
509      * @stable ICU 3.6\r
510      */\r
511     public void setParseStrict(boolean value) {\r
512         parseStrict = value;\r
513     }\r
514 \r
515     /**\r
516      * Return whether strict parsing is in effect.\r
517      * @return true if strict parsing is in effect\r
518      * @see #setParseStrict\r
519      * @stable ICU 3.6\r
520      */\r
521     public boolean isParseStrict() {\r
522         return parseStrict;\r
523     }\r
524 \r
525     //============== Locale Stuff =====================\r
526 \r
527     /**\r
528      * Returns the default number format for the current default locale.\r
529      * The default format is one of the styles provided by the other\r
530      * factory methods: getNumberInstance, getIntegerInstance,\r
531      * getCurrencyInstance or getPercentInstance.\r
532      * Exactly which one is locale-dependent.\r
533      * @stable ICU 2.0\r
534      */\r
535     //Bug 4408066 [Richard/GCL]\r
536     public final static NumberFormat getInstance() {\r
537         return getInstance(ULocale.getDefault(), NUMBERSTYLE);\r
538     }\r
539 \r
540     /**\r
541      * Returns the default number format for the specified locale.\r
542      * The default format is one of the styles provided by the other\r
543      * factory methods: getNumberInstance, getCurrencyInstance or getPercentInstance.\r
544      * Exactly which one is locale-dependent.\r
545      * @stable ICU 2.0\r
546      */\r
547     public static NumberFormat getInstance(Locale inLocale) {\r
548         return getInstance(ULocale.forLocale(inLocale), NUMBERSTYLE);\r
549     }\r
550 \r
551     /**\r
552      * Returns the default number format for the specified locale.\r
553      * The default format is one of the styles provided by the other\r
554      * factory methods: getNumberInstance, getCurrencyInstance or getPercentInstance.\r
555      * Exactly which one is locale-dependent.\r
556      * @stable ICU 3.2\r
557      */\r
558     public static NumberFormat getInstance(ULocale inLocale) {\r
559         return getInstance(inLocale, NUMBERSTYLE);\r
560     }\r
561 \r
562     /**\r
563      * Returns a specific style number format for default locale.\r
564      * @param style  number format style\r
565      * @draft ICU 4.2\r
566      * @provisional This API might change or be removed in a future release.\r
567      */\r
568     public final static NumberFormat getInstance(int style) {\r
569         return getInstance(ULocale.getDefault(), style);\r
570     }\r
571 \r
572     /**\r
573      * Returns a specific style number format for a specific locale.\r
574      * @param inLocale  the specific locale.\r
575      * @param style     number format style\r
576      * @draft ICU 4.2\r
577      * @provisional This API might change or be removed in a future release.\r
578      */\r
579     public static NumberFormat getInstance(Locale inLocale, int style) {\r
580         return getInstance(ULocale.forLocale(inLocale), style);\r
581     }\r
582 \r
583 \r
584     /**\r
585      * Returns a general-purpose number format for the current default locale.\r
586      * @stable ICU 2.0\r
587      */\r
588     public final static NumberFormat getNumberInstance() {\r
589         return getInstance(ULocale.getDefault(), NUMBERSTYLE);\r
590     }\r
591 \r
592     /**\r
593      * Returns a general-purpose number format for the specified locale.\r
594      * @stable ICU 2.0\r
595      */\r
596     public static NumberFormat getNumberInstance(Locale inLocale) {\r
597         return getInstance(ULocale.forLocale(inLocale), NUMBERSTYLE);\r
598     }\r
599 \r
600     /**\r
601      * Returns a general-purpose number format for the specified locale.\r
602      * @stable ICU 3.2\r
603      */\r
604     public static NumberFormat getNumberInstance(ULocale inLocale) {\r
605         return getInstance(inLocale, NUMBERSTYLE);\r
606     }\r
607 \r
608     /**\r
609      * Returns an integer number format for the current default locale. The\r
610      * returned number format is configured to round floating point numbers\r
611      * to the nearest integer using IEEE half-even rounding (see {@link \r
612      * com.ibm.icu.math.BigDecimal#ROUND_HALF_EVEN ROUND_HALF_EVEN}) for formatting,\r
613      * and to parse only the integer part of an input string (see {@link\r
614      * #isParseIntegerOnly isParseIntegerOnly}).\r
615      *\r
616      * @return a number format for integer values\r
617      * @stable ICU 2.0\r
618      */\r
619     //Bug 4408066 [Richard/GCL]\r
620     public final static NumberFormat getIntegerInstance() {\r
621         return getInstance(ULocale.getDefault(), INTEGERSTYLE);\r
622     }\r
623 \r
624     /**\r
625      * Returns an integer number format for the specified locale. The\r
626      * returned number format is configured to round floating point numbers\r
627      * to the nearest integer using IEEE half-even rounding (see {@link \r
628      * com.ibm.icu.math.BigDecimal#ROUND_HALF_EVEN ROUND_HALF_EVEN}) for formatting,\r
629      * and to parse only the integer part of an input string (see {@link\r
630      * #isParseIntegerOnly isParseIntegerOnly}).\r
631      *\r
632      * @param inLocale the locale for which a number format is needed\r
633      * @return a number format for integer values\r
634      * @stable ICU 2.0\r
635      */\r
636     //Bug 4408066 [Richard/GCL]\r
637     public static NumberFormat getIntegerInstance(Locale inLocale) {\r
638         return getInstance(ULocale.forLocale(inLocale), INTEGERSTYLE);\r
639     }\r
640 \r
641     /**\r
642      * Returns an integer number format for the specified locale. The\r
643      * returned number format is configured to round floating point numbers\r
644      * to the nearest integer using IEEE half-even rounding (see {@link \r
645      * com.ibm.icu.math.BigDecimal#ROUND_HALF_EVEN ROUND_HALF_EVEN}) for formatting,\r
646      * and to parse only the integer part of an input string (see {@link\r
647      * #isParseIntegerOnly isParseIntegerOnly}).\r
648      *\r
649      * @param inLocale the locale for which a number format is needed\r
650      * @return a number format for integer values\r
651      * @stable ICU 3.2\r
652      */\r
653     public static NumberFormat getIntegerInstance(ULocale inLocale) {\r
654         return getInstance(inLocale, INTEGERSTYLE);\r
655     }\r
656 \r
657     /**\r
658      * Returns a currency format for the current default locale.\r
659      * @return a number format for currency\r
660      * @stable ICU 2.0\r
661      */\r
662     public final static NumberFormat getCurrencyInstance() {\r
663         return getInstance(ULocale.getDefault(), CURRENCYSTYLE);\r
664     }\r
665 \r
666     /**\r
667      * Returns a currency format for the specified locale.\r
668      * @return a number format for currency\r
669      * @stable ICU 2.0\r
670      */\r
671     public static NumberFormat getCurrencyInstance(Locale inLocale) {\r
672         return getInstance(ULocale.forLocale(inLocale), CURRENCYSTYLE);\r
673     }\r
674 \r
675     /**\r
676      * Returns a currency format for the specified locale.\r
677      * @return a number format for currency\r
678      * @stable ICU 3.2\r
679      */\r
680     public static NumberFormat getCurrencyInstance(ULocale inLocale) {\r
681         return getInstance(inLocale, CURRENCYSTYLE);\r
682     }\r
683 \r
684     /**\r
685      * Returns a percentage format for the current default locale.\r
686      * @return a number format for percents\r
687      * @stable ICU 2.0\r
688      */\r
689     public final static NumberFormat getPercentInstance() {\r
690         return getInstance(ULocale.getDefault(), PERCENTSTYLE);\r
691     }\r
692 \r
693     /**\r
694      * Returns a percentage format for the specified locale.\r
695      * @return a number format for percents\r
696      * @stable ICU 2.0\r
697      */\r
698     public static NumberFormat getPercentInstance(Locale inLocale) {\r
699         return getInstance(ULocale.forLocale(inLocale), PERCENTSTYLE);\r
700     }\r
701 \r
702     /**\r
703      * Returns a percentage format for the specified locale.\r
704      * @return a number format for percents\r
705      * @stable ICU 3.2\r
706      */\r
707     public static NumberFormat getPercentInstance(ULocale inLocale) {\r
708         return getInstance(inLocale, PERCENTSTYLE);\r
709     }\r
710 \r
711     // [NEW]\r
712     /**\r
713      * Returns a scientific format for the current default locale.\r
714      * @return a scientific number format\r
715      * @stable ICU 2.0\r
716      */\r
717     public final static NumberFormat getScientificInstance() {\r
718         return getInstance(ULocale.getDefault(), SCIENTIFICSTYLE);\r
719     }\r
720 \r
721     // [NEW]\r
722     /**\r
723      * Returns a scientific format for the specified locale.\r
724      * @return a scientific number format\r
725      * @stable ICU 2.0\r
726      */\r
727     public static NumberFormat getScientificInstance(Locale inLocale) {\r
728         return getInstance(ULocale.forLocale(inLocale), SCIENTIFICSTYLE);\r
729     }\r
730 \r
731     // [NEW]\r
732     /**\r
733      * Returns a scientific format for the specified locale.\r
734      * @return a scientific number format\r
735      * @stable ICU 3.2\r
736      */\r
737     public static NumberFormat getScientificInstance(ULocale inLocale) {\r
738         return getInstance(inLocale, SCIENTIFICSTYLE);\r
739     }\r
740 \r
741     // ===== Factory stuff =====\r
742     /**\r
743      * A NumberFormatFactory is used to register new number formats.  The factory\r
744      * should be able to create any of the predefined formats for each locale it\r
745      * supports.  When registered, the locales it supports extend or override the\r
746      * locales already supported by ICU.\r
747      * <p><b>Note:</b> as of ICU4J 3.2, the default API for NumberFormatFactory uses\r
748      * ULocale instead of Locale.  Instead of overriding createFormat(Locale, int),\r
749      * new implementations should override createFactory(ULocale, int).  Note that\r
750      * one of these two methods <b>MUST</b> be overridden or else an infinite\r
751      * loop will occur.\r
752      *\r
753      * @stable ICU 2.6\r
754      */\r
755     public static abstract class NumberFormatFactory {\r
756         /**\r
757          * Value passed to format requesting a default number format.\r
758          * @stable ICU 2.6\r
759          */\r
760         public static final int FORMAT_NUMBER = NUMBERSTYLE;\r
761 \r
762         /**\r
763          * Value passed to format requesting a currency format.\r
764          * @stable ICU 2.6\r
765          */\r
766         public static final int FORMAT_CURRENCY = CURRENCYSTYLE;\r
767 \r
768         /**\r
769          * Value passed to format requesting a percent format.\r
770          * @stable ICU 2.6\r
771          */\r
772         public static final int FORMAT_PERCENT = PERCENTSTYLE;\r
773 \r
774         /**\r
775          * Value passed to format requesting a scientific format.\r
776          * @stable ICU 2.6\r
777          */\r
778         public static final int FORMAT_SCIENTIFIC = SCIENTIFICSTYLE;\r
779 \r
780         /**\r
781          * Value passed to format requesting an integer format.\r
782          * @stable ICU 2.6\r
783          */\r
784         public static final int FORMAT_INTEGER = INTEGERSTYLE;\r
785 \r
786         /**\r
787          * Returns true if this factory is visible.  Default is true.\r
788          * If not visible, the locales supported by this factory will not\r
789          * be listed by getAvailableLocales.  This value must not change.\r
790          * @return true if the factory is visible.\r
791          * @stable ICU 2.6\r
792          */\r
793         ///CLOVER:OFF\r
794         public boolean visible() {\r
795             return true;\r
796         }\r
797         ///CLOVER:ON\r
798 \r
799         /**\r
800          * Returns an immutable collection of the locale names directly \r
801          * supported by this factory.\r
802          * @return the supported locale names.\r
803          * @stable ICU 2.6\r
804          */\r
805          public abstract Set getSupportedLocaleNames();\r
806 \r
807         /**\r
808          * Returns a number format of the appropriate type.  If the locale\r
809          * is not supported, return null.  If the locale is supported, but\r
810          * the type is not provided by this service, return null.  Otherwise\r
811          * return an appropriate instance of NumberFormat.\r
812          * <b>Note:</b> as of ICU4J 3.2, implementations should override\r
813          * this method instead of createFormat(Locale, int).\r
814          * @param loc the locale for which to create the format\r
815          * @param formatType the type of format\r
816          * @return the NumberFormat, or null.\r
817          * @stable ICU 3.2\r
818          */\r
819         public NumberFormat createFormat(ULocale loc, int formatType) {\r
820             return createFormat(loc.toLocale(), formatType);\r
821         }\r
822 \r
823         /**\r
824          * Returns a number format of the appropriate type.  If the locale\r
825          * is not supported, return null.  If the locale is supported, but\r
826          * the type is not provided by this service, return null.  Otherwise\r
827          * return an appropriate instance of NumberFormat.\r
828          * <b>Note:</b> as of ICU4J 3.2, createFormat(ULocale, int) should be\r
829          * overridden instead of this method.  This method is no longer \r
830          * abstract and delegates to that method.\r
831          * @param loc the locale for which to create the format\r
832          * @param formatType the type of format\r
833          * @return the NumberFormat, or null.\r
834          * @stable ICU 2.6\r
835          */\r
836         public NumberFormat createFormat(Locale loc, int formatType) {\r
837             return createFormat(ULocale.forLocale(loc), formatType);\r
838         }\r
839 \r
840         /**\r
841          * @stable ICU 2.6\r
842          */\r
843         protected NumberFormatFactory() {\r
844         }\r
845     }\r
846 \r
847     /**\r
848      * A NumberFormatFactory that supports a single locale.  It can be visible or invisible.\r
849      * @stable ICU 2.6\r
850      */\r
851     public static abstract class SimpleNumberFormatFactory extends NumberFormatFactory {\r
852         final Set localeNames;\r
853         final boolean visible;\r
854 \r
855         /**\r
856          * Constructs a SimpleNumberFormatFactory with the given locale.\r
857          * @stable ICU 2.6\r
858          */\r
859         public SimpleNumberFormatFactory(Locale locale) {\r
860             this(locale, true);\r
861         }\r
862         \r
863         /**\r
864          * Constructs a SimpleNumberFormatFactory with the given locale and the\r
865          * visibility.\r
866          * @stable ICU 2.6\r
867          */\r
868         public SimpleNumberFormatFactory(Locale locale, boolean visible) {\r
869             localeNames = Collections.singleton(ULocale.forLocale(locale).getBaseName());\r
870             this.visible = visible;\r
871         }\r
872 \r
873         /**\r
874          * Constructs a SimpleNumberFormatFactory with the given locale.\r
875          * @stable ICU 3.2\r
876          */\r
877         public SimpleNumberFormatFactory(ULocale locale) {\r
878             this(locale, true);\r
879         }\r
880         \r
881         /**\r
882          * Constructs a SimpleNumberFormatFactory with the given locale and the\r
883          * visibility.\r
884          * @stable ICU 3.2\r
885          */\r
886         public SimpleNumberFormatFactory(ULocale locale, boolean visible) {\r
887             localeNames = Collections.singleton(locale.getBaseName());\r
888             this.visible = visible;\r
889         }\r
890 \r
891         /**\r
892          * {@inheritDoc}\r
893          * @stable ICU 2.6\r
894          */\r
895         public final boolean visible() {\r
896             return visible;\r
897         }\r
898 \r
899         /**\r
900          * {@inheritDoc}\r
901          * @stable ICU 2.6\r
902          */\r
903         public final Set getSupportedLocaleNames() {\r
904             return localeNames;\r
905         }\r
906     }\r
907 \r
908     // shim so we can build without service code\r
909     static abstract class NumberFormatShim {\r
910         abstract Locale[] getAvailableLocales();\r
911         abstract ULocale[] getAvailableULocales();\r
912         abstract Object registerFactory(NumberFormatFactory f);\r
913         abstract boolean unregister(Object k);\r
914         abstract NumberFormat createInstance(ULocale l, int k);\r
915     }\r
916 \r
917     private static NumberFormatShim shim;\r
918     private static NumberFormatShim getShim() {\r
919         // Note: this instantiation is safe on loose-memory-model configurations\r
920         // despite lack of synchronization, since the shim instance has no state--\r
921         // it's all in the class init.  The worst problem is we might instantiate\r
922         // two shim instances, but they'll share the same state so that's ok.\r
923         if (shim == null) {\r
924             try {\r
925                 Class cls = Class.forName("com.ibm.icu.text.NumberFormatServiceShim");\r
926                 shim = (NumberFormatShim)cls.newInstance();\r
927             }\r
928             catch (MissingResourceException e){\r
929                 throw e;\r
930             }\r
931             catch (Exception e) {\r
932                 ///CLOVER:OFF\r
933                // e.printStackTrace();\r
934                 throw new RuntimeException(e.getMessage());\r
935                 ///CLOVER:ON\r
936             }\r
937         }\r
938         return shim;\r
939     }\r
940 \r
941     /**\r
942      * Get the list of Locales for which NumberFormats are available.\r
943      * @return the available locales\r
944      * @stable ICU 2.0\r
945      */\r
946     public static Locale[] getAvailableLocales() {\r
947         if (shim == null) {\r
948             return ICUResourceBundle.getAvailableLocales(ICUResourceBundle.ICU_BASE_NAME);\r
949         }\r
950         return getShim().getAvailableLocales();\r
951     }\r
952 \r
953     /**\r
954      * Get the list of Locales for which NumberFormats are available.\r
955      * @return the available locales\r
956      * @draft ICU 3.2 (retain)\r
957      * @provisional This API might change or be removed in a future release.\r
958      */\r
959     public static ULocale[] getAvailableULocales() {\r
960         if (shim == null) {\r
961             return ICUResourceBundle.getAvailableULocales(ICUResourceBundle.ICU_BASE_NAME);\r
962         }\r
963         return getShim().getAvailableULocales();\r
964     }\r
965 \r
966     /**\r
967      * Registers a new NumberFormatFactory.  The factory is adopted by\r
968      * the service and must not be modified.  The returned object is a\r
969      * key that can be used to unregister this factory.\r
970      * @param factory the factory to register\r
971      * @return a key with which to unregister the factory\r
972      * @stable ICU 2.6 \r
973      */\r
974     public static Object registerFactory(NumberFormatFactory factory) {\r
975         if (factory == null) {\r
976             throw new IllegalArgumentException("factory must not be null");\r
977         }\r
978         return getShim().registerFactory(factory);\r
979     }\r
980 \r
981     /**\r
982      * Unregister the factory or instance associated with this key (obtained from\r
983      * registerInstance or registerFactory).\r
984      * @param registryKey a key obtained from registerFactory\r
985      * @return true if the object was successfully unregistered\r
986      * @stable ICU 2.6\r
987      */\r
988     public static boolean unregister(Object registryKey) {\r
989         if (registryKey == null) {\r
990             throw new IllegalArgumentException("registryKey must not be null");\r
991         }\r
992 \r
993         if (shim == null) {\r
994             return false;\r
995         }\r
996 \r
997         return shim.unregister(registryKey);\r
998     }\r
999 \r
1000     // ===== End of factory stuff =====\r
1001 \r
1002     /**\r
1003      * Overrides hashCode\r
1004      * @stable ICU 2.0\r
1005      */\r
1006     public int hashCode() {\r
1007         return maximumIntegerDigits * 37 + maxFractionDigits;\r
1008         // just enough fields for a reasonable distribution\r
1009     }\r
1010 \r
1011     /**\r
1012      * Overrides equals.  Two NumberFormats are equal if they are of the same class\r
1013      * and the settings (groupingUsed, parseIntegerOnly, maximumIntegerDigits, etc.\r
1014      * are equal.\r
1015      * @param obj the object to compare against\r
1016      * @return true if the object is equal to this.\r
1017      * @stable ICU 2.0\r
1018      */\r
1019     public boolean equals(Object obj) {\r
1020         if (obj == null) return false;\r
1021         if (this == obj)\r
1022             return true;\r
1023         if (getClass() != obj.getClass())\r
1024             return false;\r
1025         NumberFormat other = (NumberFormat) obj;\r
1026         return maximumIntegerDigits == other.maximumIntegerDigits\r
1027             && minimumIntegerDigits == other.minimumIntegerDigits\r
1028             && maximumFractionDigits == other.maximumFractionDigits\r
1029             && minimumFractionDigits == other.minimumFractionDigits\r
1030             && groupingUsed == other.groupingUsed\r
1031             && parseIntegerOnly == other.parseIntegerOnly\r
1032             && parseStrict == other.parseStrict;\r
1033     }\r
1034 \r
1035     /**\r
1036      * Overrides Cloneable.\r
1037      * @stable ICU 2.0\r
1038      */\r
1039     public Object clone()\r
1040     {\r
1041         NumberFormat other = (NumberFormat) super.clone();\r
1042         return other;\r
1043     }\r
1044 \r
1045     /**\r
1046      * Returns true if grouping is used in this format. For example, in the\r
1047      * en_US locale, with grouping on, the number 1234567 will be formatted\r
1048      * as "1,234,567". The grouping separator as well as the size of each group\r
1049      * is locale-dependent and is determined by subclasses of NumberFormat.\r
1050      * Grouping affects both parsing and formatting.\r
1051      * @return true if grouping is used\r
1052      * @see #setGroupingUsed\r
1053      * @stable ICU 2.0\r
1054      */\r
1055     public boolean isGroupingUsed() {\r
1056         return groupingUsed;\r
1057     }\r
1058 \r
1059     /**\r
1060      * Sets whether or not grouping will be used in this format.  Grouping\r
1061      * affects both parsing and formatting.\r
1062      * @see #isGroupingUsed\r
1063      * @param newValue true to use grouping.\r
1064      * @stable ICU 2.0\r
1065      */\r
1066     public void setGroupingUsed(boolean newValue) {\r
1067         groupingUsed = newValue;\r
1068     }\r
1069 \r
1070     /**\r
1071      * Returns the maximum number of digits allowed in the integer portion of a\r
1072      * number.  The default value is 40, which subclasses can override.\r
1073      * When formatting, the exact behavior when this value is exceeded is\r
1074      * subclass-specific.  When parsing, this has no effect.\r
1075      * @return the maximum number of integer digits\r
1076      * @see #setMaximumIntegerDigits\r
1077      * @stable ICU 2.0\r
1078      */\r
1079     public int getMaximumIntegerDigits() {\r
1080         return maximumIntegerDigits;\r
1081     }\r
1082 \r
1083     /**\r
1084      * Sets the maximum number of digits allowed in the integer portion of a\r
1085      * number. This must be >= minimumIntegerDigits.  If the\r
1086      * new value for maximumIntegerDigits is less than the current value\r
1087      * of minimumIntegerDigits, then minimumIntegerDigits will also be set to\r
1088      * the new value.\r
1089      * @param newValue the maximum number of integer digits to be shown; if\r
1090      * less than zero, then zero is used.  Subclasses might enforce an\r
1091      * upper limit to this value appropriate to the numeric type being formatted.\r
1092      * @see #getMaximumIntegerDigits\r
1093      * @stable ICU 2.0\r
1094      */\r
1095     public void setMaximumIntegerDigits(int newValue) {\r
1096         maximumIntegerDigits = Math.max(0,newValue);\r
1097         if (minimumIntegerDigits > maximumIntegerDigits)\r
1098             minimumIntegerDigits = maximumIntegerDigits;\r
1099     }\r
1100 \r
1101     /**\r
1102      * Returns the minimum number of digits allowed in the integer portion of a\r
1103      * number.  The default value is 1, which subclasses can override.\r
1104      * When formatting, if this value is not reached, numbers are padded on the\r
1105      * left with the locale-specific '0' character to ensure at least this\r
1106      * number of integer digits.  When parsing, this has no effect.\r
1107      * @return the minimum number of integer digits\r
1108      * @see #setMinimumIntegerDigits\r
1109      * @stable ICU 2.0\r
1110      */\r
1111     public int getMinimumIntegerDigits() {\r
1112         return minimumIntegerDigits;\r
1113     }\r
1114 \r
1115     /**\r
1116      * Sets the minimum number of digits allowed in the integer portion of a\r
1117      * number.  This must be <= maximumIntegerDigits.  If the\r
1118      * new value for minimumIntegerDigits is more than the current value\r
1119      * of maximumIntegerDigits, then maximumIntegerDigits will also be set to\r
1120      * the new value.\r
1121      * @param newValue the minimum number of integer digits to be shown; if\r
1122      * less than zero, then zero is used. Subclasses might enforce an\r
1123      * upper limit to this value appropriate to the numeric type being formatted.\r
1124      * @see #getMinimumIntegerDigits\r
1125      * @stable ICU 2.0\r
1126      */\r
1127     public void setMinimumIntegerDigits(int newValue) {\r
1128         minimumIntegerDigits = Math.max(0,newValue);\r
1129         if (minimumIntegerDigits > maximumIntegerDigits)\r
1130             maximumIntegerDigits = minimumIntegerDigits;\r
1131     }\r
1132 \r
1133     /**\r
1134      * Returns the maximum number of digits allowed in the fraction\r
1135      * portion of a number.  The default value is 3, which subclasses\r
1136      * can override.  When formatting, the exact behavior when this\r
1137      * value is exceeded is subclass-specific.  When parsing, this has \r
1138      * no effect.\r
1139      * @return the maximum number of fraction digits\r
1140      * @see #setMaximumFractionDigits\r
1141      * @stable ICU 2.0 \r
1142      */\r
1143     public int getMaximumFractionDigits() {\r
1144         return maximumFractionDigits;\r
1145     }\r
1146 \r
1147     /**\r
1148      * Sets the maximum number of digits allowed in the fraction portion of a\r
1149      * number. This must be >= minimumFractionDigits.  If the\r
1150      * new value for maximumFractionDigits is less than the current value\r
1151      * of minimumFractionDigits, then minimumFractionDigits will also be set to\r
1152      * the new value.\r
1153      * @param newValue the maximum number of fraction digits to be shown; if\r
1154      * less than zero, then zero is used. The concrete subclass may enforce an\r
1155      * upper limit to this value appropriate to the numeric type being formatted.\r
1156      * @see #getMaximumFractionDigits\r
1157      * @stable ICU 2.0\r
1158      */\r
1159     public void setMaximumFractionDigits(int newValue) {\r
1160         maximumFractionDigits = Math.max(0,newValue);\r
1161         if (maximumFractionDigits < minimumFractionDigits)\r
1162             minimumFractionDigits = maximumFractionDigits;\r
1163     }\r
1164 \r
1165     /**\r
1166      * Returns the minimum number of digits allowed in the fraction portion of a\r
1167      * number.  The default value is 0, which subclasses can override.\r
1168      * When formatting, if this value is not reached, numbers are padded on\r
1169      * the right with the locale-specific '0' character to ensure at least\r
1170      * this number of fraction digits.  When parsing, this has no effect.\r
1171      * @return the minimum number of fraction digits\r
1172      * @see #setMinimumFractionDigits\r
1173      * @stable ICU 2.0\r
1174      */\r
1175     public int getMinimumFractionDigits() {\r
1176         return minimumFractionDigits;\r
1177     }\r
1178 \r
1179     /**\r
1180      * Sets the minimum number of digits allowed in the fraction portion of a\r
1181      * number.  This must be <= maximumFractionDigits.  If the\r
1182      * new value for minimumFractionDigits exceeds the current value\r
1183      * of maximumFractionDigits, then maximumFractionDigits will also be set to\r
1184      * the new value.\r
1185      * @param newValue the minimum number of fraction digits to be shown; if\r
1186      * less than zero, then zero is used.  Subclasses might enforce an\r
1187      * upper limit to this value appropriate to the numeric type being formatted.\r
1188      * @see #getMinimumFractionDigits\r
1189      * @stable ICU 2.0\r
1190      */\r
1191     public void setMinimumFractionDigits(int newValue) {\r
1192         minimumFractionDigits = Math.max(0,newValue);\r
1193         if (maximumFractionDigits < minimumFractionDigits)\r
1194             maximumFractionDigits = minimumFractionDigits;\r
1195     }\r
1196 \r
1197     /**\r
1198      * Sets the <tt>Currency</tt> object used to display currency\r
1199      * amounts.  This takes effect immediately, if this format is a\r
1200      * currency format.  If this format is not a currency format, then\r
1201      * the currency object is used if and when this object becomes a\r
1202      * currency format.\r
1203      * @param theCurrency new currency object to use.  May be null for\r
1204      * some subclasses.\r
1205      * @stable ICU 2.6\r
1206      */\r
1207     public void setCurrency(Currency theCurrency) {\r
1208         currency = theCurrency;\r
1209     }\r
1210 \r
1211     /**\r
1212      * Gets the <tt>Currency</tt> object used to display currency\r
1213      * amounts.  This may be null.\r
1214      * @stable ICU 2.6\r
1215      */\r
1216     public Currency getCurrency() {\r
1217         return currency;\r
1218     }\r
1219     \r
1220     /**\r
1221      * Returns the currency in effect for this formatter.  Subclasses\r
1222      * should override this method as needed.  Unlike getCurrency(),\r
1223      * this method should never return null.\r
1224      * @return a non-null Currency\r
1225      * @internal\r
1226      * @deprecated This API is ICU internal only.\r
1227      */\r
1228     protected Currency getEffectiveCurrency() {\r
1229         Currency c = getCurrency();\r
1230         if (c == null) {\r
1231             ULocale uloc = getLocale(ULocale.VALID_LOCALE);\r
1232             if (uloc == null) {\r
1233                 uloc = ULocale.getDefault();\r
1234             }\r
1235             c = Currency.getInstance(uloc);\r
1236         }\r
1237         return c;\r
1238     }\r
1239 \r
1240     /**\r
1241      * Get the rounding mode used in this NumberFormat.  The default implementation of\r
1242      * tis method in NumberFormat always throws <code>UnsupportedOperationException</code>.\r
1243      * @return A rounding mode, between <code>BigDecimal.ROUND_UP</code>\r
1244      * and <code>BigDecimal.ROUND_UNNECESSARY</code>.\r
1245      * @see #setRoundingMode(int)\r
1246      * @stable ICU 4.0\r
1247      */\r
1248     public int getRoundingMode() {\r
1249         throw new UnsupportedOperationException("getRoundingMode must be implemented by the subclass implementation.");\r
1250     }\r
1251 \r
1252     /**\r
1253      * Set the rounding mode used in this NumberFormat.  The default implementation of\r
1254      * tis method in NumberFormat always throws <code>UnsupportedOperationException</code>.\r
1255      * @param roundingMode A rounding mode, between\r
1256      * <code>BigDecimal.ROUND_UP</code> and\r
1257      * <code>BigDecimal.ROUND_UNNECESSARY</code>.\r
1258      * @see #getRoundingMode()\r
1259      * @stable ICU 4.0\r
1260      */\r
1261     public void setRoundingMode(int roundingMode) {\r
1262         throw new UnsupportedOperationException("setRoundingMode must be implemented by the subclass implementation.");\r
1263     }\r
1264 \r
1265 \r
1266     /**\r
1267      * Returns a specific style number format for a specific locale.\r
1268      * @param desiredLocale  the specific locale.\r
1269      * @param choice         number format style\r
1270      * @throws IllegalArgumentException  if choice is not one of\r
1271      *                                   NUMBERSTYLE, CURRENCYSTYLE, \r
1272      *                                   PERCENTSTYLE, SCIENTIFICSTYLE, \r
1273      *                                   INTEGERSTYLE, \r
1274      *                                   ISOCURRENCYSTYLE, PLURALCURRENCYSTYLE,\r
1275      * @draft ICU 4.2\r
1276      * @provisional This API might change or be removed in a future release.\r
1277      */\r
1278     public static NumberFormat getInstance(ULocale desiredLocale, int choice) {\r
1279         if (choice < NUMBERSTYLE || choice > PLURALCURRENCYSTYLE) {\r
1280             throw new IllegalArgumentException("choice should be from NUMBERSTYLE to PLURALCURRENCYSTYLE");\r
1281         }       \r
1282 //          if (shim == null) {\r
1283 //              return createInstance(desiredLocale, choice);\r
1284 //          } else {\r
1285 //              // TODO: shims must call setLocale() on object they create\r
1286 //              return getShim().createInstance(desiredLocale, choice);\r
1287 //          }\r
1288         return getShim().createInstance(desiredLocale, choice);\r
1289     }\r
1290 \r
1291     // =======================privates===============================\r
1292     // Hook for service\r
1293     // [NEW]\r
1294     static NumberFormat createInstance(ULocale desiredLocale, int choice) {\r
1295         // If the choice is PLURALCURRENCYSTYLE, the pattern is not a single\r
1296         // pattern, it is a pattern set, so we do not need to get them here.\r
1297         // If the choice is ISOCURRENCYSTYLE, the pattern is the currrency\r
1298         // pattern in the locale but by replacing the single currency sign \r
1299         // with double currency sign.\r
1300         String pattern = getPattern(desiredLocale, choice);\r
1301         DecimalFormatSymbols symbols = new DecimalFormatSymbols(desiredLocale);\r
1302         \r
1303         // Here we assume that the locale passed in is in the canonical\r
1304         // form, e.g: pt_PT_@currency=PTE not pt_PT_PREEURO\r
1305         // This style wont work for currency plural format.\r
1306         // For currency plural format, the pattern is get from \r
1307         // the locale (from CurrencyUnitPatterns) without override.\r
1308         if(choice == CURRENCYSTYLE || choice == ISOCURRENCYSTYLE){\r
1309             String temp = symbols.getCurrencyPattern();\r
1310             if(temp!=null){\r
1311                 pattern = temp;\r
1312             }\r
1313         }\r
1314 \r
1315         // replace single currency sign in the pattern with double currency sign\r
1316         // if the choice is ISOCURRENCYSTYLE.\r
1317         if (choice == ISOCURRENCYSTYLE) {\r
1318             pattern = Utility.replace(pattern, "\u00A4", doubleCurrencyStr);\r
1319         }\r
1320 \r
1321         NumberingSystem ns = NumberingSystem.getInstance(desiredLocale);\r
1322         if ( ns == null ) {\r
1323             return null;\r
1324         }\r
1325 \r
1326         NumberFormat format;\r
1327 \r
1328         if ( ns != null && ns.isAlgorithmic()) {\r
1329             String nsDesc;\r
1330             String nsRuleSetGroup;\r
1331             String nsRuleSetName;\r
1332             ULocale nsLoc;\r
1333             int desiredRulesType = RuleBasedNumberFormat.NUMBERING_SYSTEM;\r
1334 \r
1335             nsDesc = ns.getDescription();\r
1336             int firstSlash = nsDesc.indexOf("/");\r
1337             int lastSlash = nsDesc.lastIndexOf("/");\r
1338 \r
1339             if ( lastSlash > firstSlash ) {\r
1340                String nsLocID = nsDesc.substring(0,firstSlash);\r
1341                nsRuleSetGroup = nsDesc.substring(firstSlash+1,lastSlash);\r
1342                nsRuleSetName = nsDesc.substring(lastSlash+1);\r
1343 \r
1344                nsLoc = new ULocale(nsLocID);\r
1345                if ( nsRuleSetGroup.equals("SpelloutRules")) {\r
1346                    desiredRulesType = RuleBasedNumberFormat.SPELLOUT;\r
1347                }\r
1348             } else {\r
1349                 nsLoc = desiredLocale;\r
1350                 nsRuleSetName = nsDesc;\r
1351             }\r
1352 \r
1353             RuleBasedNumberFormat r = new RuleBasedNumberFormat(nsLoc,desiredRulesType);\r
1354             r.setDefaultRuleSet(nsRuleSetName);\r
1355             format = r;\r
1356         } else {\r
1357             DecimalFormat f = new DecimalFormat(pattern, symbols, choice);\r
1358             // System.out.println("loc: " + desiredLocale + " choice: " + choice + " pat: " + pattern + " sym: " + symbols + " result: " + format);\r
1359                                  \r
1360             /*Bug 4408066\r
1361              Add codes for the new method getIntegerInstance() [Richard/GCL]\r
1362             */\r
1363             // TODO: revisit this -- this is almost certainly not the way we want\r
1364             // to do this.  aliu 1/6/2004\r
1365             if (choice == INTEGERSTYLE) {\r
1366                 f.setMaximumFractionDigits(0);\r
1367                 f.setDecimalSeparatorAlwaysShown(false);\r
1368                 f.setParseIntegerOnly(true);\r
1369             }\r
1370             format = f;\r
1371        } \r
1372         // TODO: the actual locale of the *pattern* may differ from that\r
1373         // for the *symbols*.  For now, we use the data for the symbols.\r
1374         // Revisit this.\r
1375         ULocale valid = symbols.getLocale(ULocale.VALID_LOCALE);\r
1376         ULocale actual = symbols.getLocale(ULocale.ACTUAL_LOCALE);\r
1377         format.setLocale(valid, actual);\r
1378         \r
1379         return format;\r
1380     }\r
1381 \r
1382     /**\r
1383      * Returns the pattern for the provided locale and choice.\r
1384      * @param forLocale the locale of the data.\r
1385      * @param choice the pattern format.\r
1386      * @return the pattern\r
1387      * @deprecated ICU 3.4 subclassers should override getPattern(ULocale, int) instead of this method.\r
1388      */\r
1389     protected static String getPattern(Locale forLocale, int choice) {\r
1390         return getPattern(ULocale.forLocale(forLocale), choice);\r
1391     }\r
1392 \r
1393     /**\r
1394      * Returns the pattern for the provided locale and choice.\r
1395      * @param forLocale the locale of the data.\r
1396      * @param choice the pattern format.\r
1397      * @return the pattern\r
1398      * @stable ICU 3.2\r
1399      */\r
1400     protected static String getPattern(ULocale forLocale, int choice) {\r
1401 \r
1402         /* The following code takes care of a few cases where the\r
1403          * resource data in the underlying JDK lags the new features\r
1404          * we have added to ICU4J: scientific notation, rounding, and\r
1405          * secondary grouping.\r
1406          *\r
1407          * We detect these cases here and return various hard-coded\r
1408          * resource data.  This is the simplest solution for now, but\r
1409          * it is not a good long-term mechanism.\r
1410          * \r
1411          * We should replace this code with a data-driven mechanism\r
1412          * that reads the bundle com.ibm.icu.impl.data.LocaleElements\r
1413          * and parses an exception table that overrides the standard\r
1414          * data at java.text.resource.LocaleElements*.java.\r
1415          * Alternatively, we should create our own copy of the\r
1416          * resource data, and use that exclusively.\r
1417          */\r
1418 \r
1419         // TEMPORARY, until we get scientific patterns into the main\r
1420         // resources:  Retrieve scientific patterns from our resources.\r
1421         if (choice == SCIENTIFICSTYLE) {\r
1422             // Temporarily hard code; retrieve from resource later\r
1423             /*For ICU compatibility [Richard/GCL]*/\r
1424             return "#E0";\r
1425             // return NumberFormat.getBaseStringArray("NumberPatterns")[SCIENTIFICSTYLE];\r
1426         }\r
1427         // TEMPORARY: Use rounding for Swiss currency\r
1428         //if (choice == CURRENCYSTYLE &&\r
1429         //    forLocale.getCountry().equals("CH")) {\r
1430         //    return "'Fr. '#,##0.05;'Fr.-'#,##0.05";\r
1431         //}\r
1432         // TEMPORARY: Special case IN number format\r
1433         //if (choice == NUMBERSTYLE &&\r
1434         //    forLocale.getCountry().equals("IN")) {\r
1435         //    return "#,##,##0.###";\r
1436         //}\r
1437 \r
1438         // {dlf}\r
1439         ICUResourceBundle rb = (ICUResourceBundle)UResourceBundle.\r
1440             getBundleInstance(ICUResourceBundle.ICU_BASE_NAME, forLocale);\r
1441         String[] numberPatterns = rb.getStringArray("NumberPatterns");\r
1442 \r
1443         /* {dlf}\r
1444         // Try the cache first\r
1445         String[] numberPatterns = (String[]) cachedLocaleData.get(forLocale);\r
1446         if (numberPatterns == null) {\r
1447             OverlayBundle resource = new OverlayBundle(new String[]\r
1448                 { "com.ibm.icu.impl.data.LocaleElements", RESOURCE_BASE }, forLocale);\r
1449             numberPatterns = resource.getStringArray("NumberPatterns");\r
1450             // Update the cache\r
1451             cachedLocaleData.put(forLocale, numberPatterns); \r
1452         }\r
1453         */\r
1454 \r
1455         /*Bug 4408066\r
1456          Add codes for the new method getIntegerInstance() [Richard/GCL]\r
1457         */\r
1458         /* for ISOCURRENCYSTYLE and PLURALCURRENCYSTYLE,\r
1459          * the pattern is the same as the pattern of CURRENCYSTYLE\r
1460          * but by replacing the single currency sign with\r
1461          * double currency sign or triple currency sign.\r
1462          */\r
1463         int entry = (choice == INTEGERSTYLE) ? NUMBERSTYLE : \r
1464                 ((choice == ISOCURRENCYSTYLE || choice == PLURALCURRENCYSTYLE)?\r
1465                 CURRENCYSTYLE : choice); //[Richard/GCL]\r
1466         return numberPatterns[entry]; //[Richard/GCL]\r
1467     }\r
1468 \r
1469     /**\r
1470      * First, read in the default serializable data.\r
1471      *\r
1472      * Then, if <code>serialVersionOnStream</code> is less than 1, indicating that\r
1473      * the stream was written by JDK 1.1,\r
1474      * set the <code>int</code> fields such as <code>maximumIntegerDigits</code>\r
1475      * to be equal to the <code>byte</code> fields such as <code>maxIntegerDigits</code>,\r
1476      * since the <code>int</code> fields were not present in JDK 1.1.\r
1477      * Finally, set serialVersionOnStream back to the maximum allowed value so that\r
1478      * default serialization will work properly if this object is streamed out again.\r
1479      */\r
1480     private void readObject(ObjectInputStream stream)\r
1481          throws IOException, ClassNotFoundException\r
1482     {\r
1483         stream.defaultReadObject();\r
1484         ///CLOVER:OFF\r
1485         // we don't have serialization data for this format\r
1486         if (serialVersionOnStream < 1) {\r
1487             // Didn't have additional int fields, reassign to use them.\r
1488             maximumIntegerDigits = maxIntegerDigits;\r
1489             minimumIntegerDigits = minIntegerDigits;\r
1490             maximumFractionDigits = maxFractionDigits;\r
1491             minimumFractionDigits = minFractionDigits;\r
1492         }\r
1493         ///CLOVER:ON\r
1494         /*Bug 4185761\r
1495           Validate the min and max fields [Richard/GCL]\r
1496         */\r
1497         if (minimumIntegerDigits > maximumIntegerDigits ||\r
1498             minimumFractionDigits > maximumFractionDigits ||\r
1499             minimumIntegerDigits < 0 || minimumFractionDigits < 0) {\r
1500             throw new InvalidObjectException("Digit count range invalid");\r
1501         }\r
1502         serialVersionOnStream = currentSerialVersion;\r
1503     }\r
1504 \r
1505     /**\r
1506      * Write out the default serializable data, after first setting\r
1507      * the <code>byte</code> fields such as <code>maxIntegerDigits</code> to be\r
1508      * equal to the <code>int</code> fields such as <code>maximumIntegerDigits</code>\r
1509      * (or to <code>Byte.MAX_VALUE</code>, whichever is smaller), for compatibility\r
1510      * with the JDK 1.1 version of the stream format.\r
1511      */\r
1512     private void writeObject(ObjectOutputStream stream)\r
1513          throws IOException\r
1514     {\r
1515         maxIntegerDigits = (maximumIntegerDigits > Byte.MAX_VALUE) ? Byte.MAX_VALUE :\r
1516             (byte)maximumIntegerDigits;\r
1517         minIntegerDigits = (minimumIntegerDigits > Byte.MAX_VALUE) ? Byte.MAX_VALUE :\r
1518             (byte)minimumIntegerDigits;\r
1519         maxFractionDigits = (maximumFractionDigits > Byte.MAX_VALUE) ? Byte.MAX_VALUE :\r
1520             (byte)maximumFractionDigits;\r
1521         minFractionDigits = (minimumFractionDigits > Byte.MAX_VALUE) ? Byte.MAX_VALUE :\r
1522             (byte)minimumFractionDigits;\r
1523         stream.defaultWriteObject();\r
1524     }\r
1525 \r
1526 // Unused -- Alan 2003-05\r
1527 //    /**\r
1528 //     * Cache to hold the NumberPatterns of a Locale.\r
1529 //     */\r
1530 //    private static final Hashtable cachedLocaleData = new Hashtable(3);\r
1531 \r
1532       private static final char[] doubleCurrencySign = {0xA4, 0xA4};\r
1533       private static final String doubleCurrencyStr = new String(doubleCurrencySign);\r
1534 \r
1535     /*Bug 4408066\r
1536       Add Field for the new method getIntegerInstance() [Richard/GCL]\r
1537     */\r
1538 \r
1539     /**\r
1540      * True if the the grouping (i.e. thousands) separator is used when\r
1541      * formatting and parsing numbers.\r
1542      *\r
1543      * @serial\r
1544      * @see #isGroupingUsed\r
1545      */\r
1546     private boolean groupingUsed = true;\r
1547 \r
1548     /**\r
1549      * The maximum number of digits allowed in the integer portion of a\r
1550      * number.  <code>maxIntegerDigits</code> must be greater than or equal to\r
1551      * <code>minIntegerDigits</code>.\r
1552      * <p>\r
1553      * <strong>Note:</strong> This field exists only for serialization\r
1554      * compatibility with JDK 1.1.  In JDK 1.2 and higher, the new\r
1555      * <code>int</code> field <code>maximumIntegerDigits</code> is used instead.\r
1556      * When writing to a stream, <code>maxIntegerDigits</code> is set to\r
1557      * <code>maximumIntegerDigits</code> or <code>Byte.MAX_VALUE</code>,\r
1558      * whichever is smaller.  When reading from a stream, this field is used\r
1559      * only if <code>serialVersionOnStream</code> is less than 1. \r
1560      *\r
1561      * @serial\r
1562      * @see #getMaximumIntegerDigits\r
1563      */\r
1564     private byte    maxIntegerDigits = 40;\r
1565 \r
1566     /**\r
1567      * The minimum number of digits allowed in the integer portion of a\r
1568      * number.  <code>minimumIntegerDigits</code> must be less than or equal to\r
1569      * <code>maximumIntegerDigits</code>.\r
1570      * <p>\r
1571      * <strong>Note:</strong> This field exists only for serialization\r
1572      * compatibility with JDK 1.1.  In JDK 1.2 and higher, the new\r
1573      * <code>int</code> field <code>minimumIntegerDigits</code> is used instead.\r
1574      * When writing to a stream, <code>minIntegerDigits</code> is set to\r
1575      * <code>minimumIntegerDigits</code> or <code>Byte.MAX_VALUE</code>,\r
1576      * whichever is smaller.  When reading from a stream, this field is used\r
1577      * only if <code>serialVersionOnStream</code> is less than 1. \r
1578      *\r
1579      * @serial\r
1580      * @see #getMinimumIntegerDigits\r
1581      */\r
1582     private byte    minIntegerDigits = 1;\r
1583 \r
1584     /**\r
1585      * The maximum number of digits allowed in the fractional portion of a\r
1586      * number.  <code>maximumFractionDigits</code> must be greater than or equal to\r
1587      * <code>minimumFractionDigits</code>.\r
1588      * <p>\r
1589      * <strong>Note:</strong> This field exists only for serialization\r
1590      * compatibility with JDK 1.1.  In JDK 1.2 and higher, the new\r
1591      * <code>int</code> field <code>maximumFractionDigits</code> is used instead.\r
1592      * When writing to a stream, <code>maxFractionDigits</code> is set to\r
1593      * <code>maximumFractionDigits</code> or <code>Byte.MAX_VALUE</code>,\r
1594      * whichever is smaller.  When reading from a stream, this field is used\r
1595      * only if <code>serialVersionOnStream</code> is less than 1. \r
1596      *\r
1597      * @serial\r
1598      * @see #getMaximumFractionDigits\r
1599      */\r
1600     private byte    maxFractionDigits = 3;    // invariant, >= minFractionDigits\r
1601 \r
1602     /**\r
1603      * The minimum number of digits allowed in the fractional portion of a\r
1604      * number.  <code>minimumFractionDigits</code> must be less than or equal to\r
1605      * <code>maximumFractionDigits</code>.\r
1606      * <p>\r
1607      * <strong>Note:</strong> This field exists only for serialization\r
1608      * compatibility with JDK 1.1.  In JDK 1.2 and higher, the new\r
1609      * <code>int</code> field <code>minimumFractionDigits</code> is used instead.\r
1610      * When writing to a stream, <code>minFractionDigits</code> is set to\r
1611      * <code>minimumFractionDigits</code> or <code>Byte.MAX_VALUE</code>,\r
1612      * whichever is smaller.  When reading from a stream, this field is used\r
1613      * only if <code>serialVersionOnStream</code> is less than 1. \r
1614      *\r
1615      * @serial\r
1616      * @see #getMinimumFractionDigits\r
1617      */\r
1618     private byte    minFractionDigits = 0;\r
1619 \r
1620     /**\r
1621      * True if this format will parse numbers as integers only.\r
1622      *\r
1623      * @serial\r
1624      * @see #isParseIntegerOnly\r
1625      */\r
1626     private boolean parseIntegerOnly = false;\r
1627 \r
1628     // new fields for 1.2.  byte is too small for integer digits.\r
1629 \r
1630     /**\r
1631      * The maximum number of digits allowed in the integer portion of a\r
1632      * number.  <code>maximumIntegerDigits</code> must be greater than or equal to\r
1633      * <code>minimumIntegerDigits</code>.\r
1634      *\r
1635      * @serial\r
1636      * @see #getMaximumIntegerDigits\r
1637      */\r
1638     private int    maximumIntegerDigits = 40;\r
1639 \r
1640     /**\r
1641      * The minimum number of digits allowed in the integer portion of a\r
1642      * number.  <code>minimumIntegerDigits</code> must be less than or equal to\r
1643      * <code>maximumIntegerDigits</code>.\r
1644      *\r
1645      * @serial\r
1646      * @see #getMinimumIntegerDigits\r
1647      */\r
1648     private int    minimumIntegerDigits = 1;\r
1649 \r
1650     /**\r
1651      * The maximum number of digits allowed in the fractional portion of a\r
1652      * number.  <code>maximumFractionDigits</code> must be greater than or equal to\r
1653      * <code>minimumFractionDigits</code>.\r
1654      *\r
1655      * @serial\r
1656      * @see #getMaximumFractionDigits\r
1657      */\r
1658     private int    maximumFractionDigits = 3;    // invariant, >= minFractionDigits\r
1659 \r
1660     /**\r
1661      * The minimum number of digits allowed in the fractional portion of a\r
1662      * number.  <code>minimumFractionDigits</code> must be less than or equal to\r
1663      * <code>maximumFractionDigits</code>.\r
1664      *\r
1665      * @serial\r
1666      * @see #getMinimumFractionDigits\r
1667      */\r
1668     private int    minimumFractionDigits = 0;\r
1669 \r
1670     /**\r
1671      * Currency object used to format currencies.  Subclasses may\r
1672      * ignore this if they are not currency formats.  This will be\r
1673      * null unless a subclass sets it to a non-null value.\r
1674      * @since ICU 2.6\r
1675      */\r
1676     private Currency currency;\r
1677 \r
1678     static final int currentSerialVersion = 1;\r
1679 \r
1680     /**\r
1681      * Describes the version of <code>NumberFormat</code> present on the stream.\r
1682      * Possible values are:\r
1683      * <ul>\r
1684      * <li><b>0</b> (or uninitialized): the JDK 1.1 version of the stream format.\r
1685      *     In this version, the <code>int</code> fields such as\r
1686      *     <code>maximumIntegerDigits</code> were not present, and the <code>byte</code>\r
1687      *     fields such as <code>maxIntegerDigits</code> are used instead.\r
1688      *\r
1689      * <li><b>1</b>: the JDK 1.2 version of the stream format.  The values of the\r
1690      *     <code>byte</code> fields such as <code>maxIntegerDigits</code> are ignored,\r
1691      *     and the <code>int</code> fields such as <code>maximumIntegerDigits</code>\r
1692      *     are used instead.\r
1693      * </ul>\r
1694      * When streaming out a <code>NumberFormat</code>, the most recent format\r
1695      * (corresponding to the highest allowable <code>serialVersionOnStream</code>)\r
1696      * is always written.\r
1697      *\r
1698      * @serial\r
1699      */\r
1700     private int serialVersionOnStream = currentSerialVersion;\r
1701 \r
1702     // Removed "implements Cloneable" clause.  Needs to update serialization\r
1703     // ID for backward compatibility.\r
1704     private static final long serialVersionUID = -2308460125733713944L;\r
1705 \r
1706     /**\r
1707      * Empty constructor.  Public for compatibily with JDK which lets the\r
1708      * compiler generate a default public constructor even though this is\r
1709      * an abstract class.\r
1710      * @stable ICU 2.6\r
1711      */\r
1712     public NumberFormat() {\r
1713     }\r
1714 \r
1715     // new in ICU4J 3.6\r
1716     private boolean parseStrict;\r
1717 \r
1718 //#if defined(FOUNDATION10) || defined(J2SE13)\r
1719 //#else\r
1720     /**\r
1721      * The instances of this inner class are used as attribute keys and values\r
1722      * in AttributedCharacterIterator that\r
1723      * NumberFormat.formatToCharacterIterator() method returns.\r
1724      * <p>\r
1725      * There is no public constructor to this class, the only instances are the\r
1726      * constants defined here.\r
1727      * <p>\r
1728      * @stable ICU 3.6\r
1729      */\r
1730     public static class Field extends Format.Field {\r
1731         // generated by serialver from JDK 1.4.1_01\r
1732         static final long serialVersionUID = -4516273749929385842L;\r
1733         \r
1734         /**\r
1735          * @stable ICU 3.6\r
1736          */\r
1737         public static final Field SIGN = new Field("sign");\r
1738 \r
1739         /**\r
1740          * @stable ICU 3.6\r
1741          */\r
1742         public static final Field INTEGER = new Field("integer");\r
1743 \r
1744         /**\r
1745          * @stable ICU 3.6\r
1746          */\r
1747         public static final Field FRACTION = new Field("fraction");\r
1748 \r
1749         /**\r
1750          * @stable ICU 3.6\r
1751          */\r
1752         public static final Field EXPONENT = new Field("exponent");\r
1753 \r
1754         /**\r
1755          * @stable ICU 3.6\r
1756          */\r
1757         public static final Field EXPONENT_SIGN = new Field("exponent sign");\r
1758 \r
1759         /**\r
1760          * @stable ICU 3.6\r
1761          */\r
1762         public static final Field EXPONENT_SYMBOL = new Field("exponent symbol");\r
1763 \r
1764         /**\r
1765          * @stable ICU 3.6\r
1766          */\r
1767         public static final Field DECIMAL_SEPARATOR = new Field("decimal separator");\r
1768         /**\r
1769          * @stable ICU 3.6\r
1770          */\r
1771         public static final Field GROUPING_SEPARATOR = new Field("grouping separator");\r
1772 \r
1773         /**\r
1774          * @stable ICU 3.6\r
1775          */\r
1776         public static final Field PERCENT = new Field("percent");\r
1777 \r
1778         /**\r
1779          * @stable ICU 3.6\r
1780          */\r
1781         public static final Field PERMILLE = new Field("per mille");\r
1782 \r
1783         /**\r
1784          * @stable ICU 3.6\r
1785          */\r
1786         public static final Field CURRENCY = new Field("currency");\r
1787 \r
1788         /**\r
1789          * Constructs a new instance of NumberFormat.Field with the given field\r
1790          * name.\r
1791          * @stable ICU 3.6\r
1792          */\r
1793         protected Field(String fieldName) {\r
1794             super(fieldName);\r
1795         }\r
1796 \r
1797         /**\r
1798          * serizalization method resolve instances to the constant\r
1799          * NumberFormat.Field values\r
1800          * @stable ICU 3.6\r
1801          */\r
1802         protected Object readResolve() throws InvalidObjectException {\r
1803             if (this.getName().equals(INTEGER.getName()))\r
1804                 return INTEGER;\r
1805             if (this.getName().equals(FRACTION.getName()))\r
1806                 return FRACTION;\r
1807             if (this.getName().equals(EXPONENT.getName()))\r
1808                 return EXPONENT;\r
1809             if (this.getName().equals(EXPONENT_SIGN.getName()))\r
1810                 return EXPONENT_SIGN;\r
1811             if (this.getName().equals(EXPONENT_SYMBOL.getName()))\r
1812                 return EXPONENT_SYMBOL;\r
1813             if (this.getName().equals(CURRENCY.getName()))\r
1814                 return CURRENCY;\r
1815             if (this.getName().equals(DECIMAL_SEPARATOR.getName()))\r
1816                 return DECIMAL_SEPARATOR;\r
1817             if (this.getName().equals(GROUPING_SEPARATOR.getName()))\r
1818                 return GROUPING_SEPARATOR;\r
1819             if (this.getName().equals(PERCENT.getName()))\r
1820                 return PERCENT;\r
1821             if (this.getName().equals(PERMILLE.getName()))\r
1822                 return PERMILLE;\r
1823             if (this.getName().equals(SIGN.getName()))\r
1824                 return SIGN;\r
1825 \r
1826             throw new InvalidObjectException("An invalid object.");\r
1827         }\r
1828     }\r
1829 //#endif\r
1830 }\r