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