1 /* GENERATED SOURCE. DO NOT MODIFY. */ 2 // © 2017 and later: Unicode, Inc. and others. 3 // License & terms of use: http://www.unicode.org/copyright.html#License 4 package ohos.global.icu.impl.number; 5 6 import java.io.IOException; 7 import java.io.ObjectInputStream; 8 import java.io.ObjectOutputStream; 9 import java.io.Serializable; 10 import java.lang.reflect.Field; 11 import java.lang.reflect.Modifier; 12 import java.math.BigDecimal; 13 import java.math.MathContext; 14 import java.math.RoundingMode; 15 import java.text.ParsePosition; 16 import java.util.ArrayList; 17 import java.util.Map; 18 19 import ohos.global.icu.impl.number.Padder.PadPosition; 20 import ohos.global.icu.text.CompactDecimalFormat.CompactStyle; 21 import ohos.global.icu.text.CurrencyPluralInfo; 22 import ohos.global.icu.text.PluralRules; 23 import ohos.global.icu.util.Currency; 24 import ohos.global.icu.util.Currency.CurrencyUsage; 25 26 /** 27 * @hide exposed on OHOS 28 */ 29 public class DecimalFormatProperties implements Cloneable, Serializable { 30 31 private static final DecimalFormatProperties DEFAULT = new DecimalFormatProperties(); 32 33 /** Auto-generated. */ 34 private static final long serialVersionUID = 4095518955889349243L; 35 36 /** Controls the set of rules for parsing a string from the old DecimalFormat API. 37 * @hide exposed on OHOS*/ 38 public static enum ParseMode { 39 /** 40 * Lenient mode should be used if you want to accept malformed user input. It will use heuristics 41 * to attempt to parse through typographical errors in the string. 42 */ 43 LENIENT, 44 45 /** 46 * Strict mode should be used if you want to require that the input is well-formed. More 47 * specifically, it differs from lenient mode in the following ways: 48 * 49 * <ul> 50 * <li>Grouping widths must match the grouping settings. For example, "12,3,45" will fail if the 51 * grouping width is 3, as in the pattern "#,##0". 52 * <li>The string must contain a complete prefix and suffix. For example, if the pattern is 53 * "{#};(#)", then "{123}" or "(123)" would match, but "{123", "123}", and "123" would all fail. 54 * (The latter strings would be accepted in lenient mode.) 55 * <li>Whitespace may not appear at arbitrary places in the string. In lenient mode, whitespace 56 * is allowed to occur arbitrarily before and after prefixes and exponent separators. 57 * <li>Leading grouping separators are not allowed, as in ",123". 58 * <li>Minus and plus signs can only appear if specified in the pattern. In lenient mode, a plus 59 * or minus sign can always precede a number. 60 * <li>The set of characters that can be interpreted as a decimal or grouping separator is 61 * smaller. 62 * <li><strong>If currency parsing is enabled,</strong> currencies must only appear where 63 * specified in either the current pattern string or in a valid pattern string for the current 64 * locale. For example, if the pattern is "¤0.00", then "$1.23" would match, but "1.23$" would 65 * fail to match. 66 * </ul> 67 */ 68 STRICT, 69 70 /** 71 * Internal parse mode for increased compatibility with java.text.DecimalFormat. 72 * Used by Android libcore. To enable this feature, java.text.DecimalFormat holds an instance of 73 * ICU4J's DecimalFormat and enable it by calling setParseStrictMode(ParseMode.JAVA_COMPATIBILITY). 74 */ 75 JAVA_COMPATIBILITY, 76 } 77 78 // The setters in this class should NOT have any side-effects or perform any validation. It is 79 // up to the consumer of the property bag to deal with property validation. 80 81 // The fields are all marked "transient" because custom serialization is being used. 82 83 /*--------------------------------------------------------------------------------------------+/ 84 /| IMPORTANT! |/ 85 /| WHEN ADDING A NEW PROPERTY, add it here, in #_clear(), in #_copyFrom(), in #equals(), |/ 86 /| and in #_hashCode(). |/ 87 /| |/ 88 /| The unit test PropertiesTest will catch if you forget to add it to #clear(), #copyFrom(), |/ 89 /| or #equals(), but it will NOT catch if you forget to add it to #hashCode(). |/ 90 /+--------------------------------------------------------------------------------------------*/ 91 92 private transient Map<String, Map<String, String>> compactCustomData; // ICU4J-only 93 private transient CompactStyle compactStyle; 94 private transient Currency currency; 95 private transient CurrencyPluralInfo currencyPluralInfo; 96 private transient CurrencyUsage currencyUsage; 97 private transient boolean decimalPatternMatchRequired; 98 private transient boolean decimalSeparatorAlwaysShown; 99 private transient boolean exponentSignAlwaysShown; 100 private transient int formatWidth; 101 private transient int groupingSize; 102 private transient boolean groupingUsed; 103 private transient int magnitudeMultiplier; 104 private transient MathContext mathContext; // ICU4J-only 105 private transient int maximumFractionDigits; 106 private transient int maximumIntegerDigits; 107 private transient int maximumSignificantDigits; 108 private transient int minimumExponentDigits; 109 private transient int minimumFractionDigits; 110 private transient int minimumGroupingDigits; 111 private transient int minimumIntegerDigits; 112 private transient int minimumSignificantDigits; 113 private transient BigDecimal multiplier; 114 private transient String negativePrefix; 115 private transient String negativePrefixPattern; 116 private transient String negativeSuffix; 117 private transient String negativeSuffixPattern; 118 private transient PadPosition padPosition; 119 private transient String padString; 120 private transient boolean parseCaseSensitive; 121 private transient boolean parseIntegerOnly; 122 private transient ParseMode parseMode; 123 private transient boolean parseNoExponent; 124 private transient boolean parseToBigDecimal; 125 private transient PluralRules pluralRules; 126 private transient String positivePrefix; 127 private transient String positivePrefixPattern; 128 private transient String positiveSuffix; 129 private transient String positiveSuffixPattern; 130 private transient BigDecimal roundingIncrement; 131 private transient RoundingMode roundingMode; 132 private transient int secondaryGroupingSize; 133 private transient boolean signAlwaysShown; 134 135 /*--------------------------------------------------------------------------------------------+/ 136 /| IMPORTANT! |/ 137 /| WHEN ADDING A NEW PROPERTY, add it here, in #_clear(), in #_copyFrom(), in #equals(), |/ 138 /| and in #_hashCode(). |/ 139 /| |/ 140 /| The unit test PropertiesTest will catch if you forget to add it to #clear(), #copyFrom(), |/ 141 /| or #equals(), but it will NOT catch if you forget to add it to #hashCode(). |/ 142 /+--------------------------------------------------------------------------------------------*/ 143 DecimalFormatProperties()144 public DecimalFormatProperties() { 145 clear(); 146 } 147 148 /** 149 * Sets all properties to their defaults (unset). 150 * 151 * <p> 152 * All integers default to -1 EXCEPT FOR MAGNITUDE MULTIPLIER which has a default of 0 (since 153 * negative numbers are important). 154 * 155 * <p> 156 * All booleans default to false. 157 * 158 * <p> 159 * All non-primitive types default to null. 160 * 161 * @return The property bag, for chaining. 162 */ _clear()163 private DecimalFormatProperties _clear() { 164 compactCustomData = null; 165 compactStyle = null; 166 currency = null; 167 currencyPluralInfo = null; 168 currencyUsage = null; 169 decimalPatternMatchRequired = false; 170 decimalSeparatorAlwaysShown = false; 171 exponentSignAlwaysShown = false; 172 formatWidth = -1; 173 groupingSize = -1; 174 groupingUsed = true; 175 magnitudeMultiplier = 0; 176 mathContext = null; 177 maximumFractionDigits = -1; 178 maximumIntegerDigits = -1; 179 maximumSignificantDigits = -1; 180 minimumExponentDigits = -1; 181 minimumFractionDigits = -1; 182 minimumGroupingDigits = -1; 183 minimumIntegerDigits = -1; 184 minimumSignificantDigits = -1; 185 multiplier = null; 186 negativePrefix = null; 187 negativePrefixPattern = null; 188 negativeSuffix = null; 189 negativeSuffixPattern = null; 190 padPosition = null; 191 padString = null; 192 parseCaseSensitive = false; 193 parseIntegerOnly = false; 194 parseMode = null; 195 parseNoExponent = false; 196 parseToBigDecimal = false; 197 pluralRules = null; 198 positivePrefix = null; 199 positivePrefixPattern = null; 200 positiveSuffix = null; 201 positiveSuffixPattern = null; 202 roundingIncrement = null; 203 roundingMode = null; 204 secondaryGroupingSize = -1; 205 signAlwaysShown = false; 206 return this; 207 } 208 _copyFrom(DecimalFormatProperties other)209 private DecimalFormatProperties _copyFrom(DecimalFormatProperties other) { 210 compactCustomData = other.compactCustomData; 211 compactStyle = other.compactStyle; 212 currency = other.currency; 213 currencyPluralInfo = other.currencyPluralInfo; 214 currencyUsage = other.currencyUsage; 215 decimalPatternMatchRequired = other.decimalPatternMatchRequired; 216 decimalSeparatorAlwaysShown = other.decimalSeparatorAlwaysShown; 217 exponentSignAlwaysShown = other.exponentSignAlwaysShown; 218 formatWidth = other.formatWidth; 219 groupingSize = other.groupingSize; 220 groupingUsed = other.groupingUsed; 221 magnitudeMultiplier = other.magnitudeMultiplier; 222 mathContext = other.mathContext; 223 maximumFractionDigits = other.maximumFractionDigits; 224 maximumIntegerDigits = other.maximumIntegerDigits; 225 maximumSignificantDigits = other.maximumSignificantDigits; 226 minimumExponentDigits = other.minimumExponentDigits; 227 minimumFractionDigits = other.minimumFractionDigits; 228 minimumGroupingDigits = other.minimumGroupingDigits; 229 minimumIntegerDigits = other.minimumIntegerDigits; 230 minimumSignificantDigits = other.minimumSignificantDigits; 231 multiplier = other.multiplier; 232 negativePrefix = other.negativePrefix; 233 negativePrefixPattern = other.negativePrefixPattern; 234 negativeSuffix = other.negativeSuffix; 235 negativeSuffixPattern = other.negativeSuffixPattern; 236 padPosition = other.padPosition; 237 padString = other.padString; 238 parseCaseSensitive = other.parseCaseSensitive; 239 parseIntegerOnly = other.parseIntegerOnly; 240 parseMode = other.parseMode; 241 parseNoExponent = other.parseNoExponent; 242 parseToBigDecimal = other.parseToBigDecimal; 243 pluralRules = other.pluralRules; 244 positivePrefix = other.positivePrefix; 245 positivePrefixPattern = other.positivePrefixPattern; 246 positiveSuffix = other.positiveSuffix; 247 positiveSuffixPattern = other.positiveSuffixPattern; 248 roundingIncrement = other.roundingIncrement; 249 roundingMode = other.roundingMode; 250 secondaryGroupingSize = other.secondaryGroupingSize; 251 signAlwaysShown = other.signAlwaysShown; 252 return this; 253 } 254 _equals(DecimalFormatProperties other)255 private boolean _equals(DecimalFormatProperties other) { 256 boolean eq = true; 257 eq = eq && _equalsHelper(compactCustomData, other.compactCustomData); 258 eq = eq && _equalsHelper(compactStyle, other.compactStyle); 259 eq = eq && _equalsHelper(currency, other.currency); 260 eq = eq && _equalsHelper(currencyPluralInfo, other.currencyPluralInfo); 261 eq = eq && _equalsHelper(currencyUsage, other.currencyUsage); 262 eq = eq && _equalsHelper(decimalPatternMatchRequired, other.decimalPatternMatchRequired); 263 eq = eq && _equalsHelper(decimalSeparatorAlwaysShown, other.decimalSeparatorAlwaysShown); 264 eq = eq && _equalsHelper(exponentSignAlwaysShown, other.exponentSignAlwaysShown); 265 eq = eq && _equalsHelper(formatWidth, other.formatWidth); 266 eq = eq && _equalsHelper(groupingSize, other.groupingSize); 267 eq = eq && _equalsHelper(groupingUsed, other.groupingUsed); 268 eq = eq && _equalsHelper(magnitudeMultiplier, other.magnitudeMultiplier); 269 eq = eq && _equalsHelper(mathContext, other.mathContext); 270 eq = eq && _equalsHelper(maximumFractionDigits, other.maximumFractionDigits); 271 eq = eq && _equalsHelper(maximumIntegerDigits, other.maximumIntegerDigits); 272 eq = eq && _equalsHelper(maximumSignificantDigits, other.maximumSignificantDigits); 273 eq = eq && _equalsHelper(minimumExponentDigits, other.minimumExponentDigits); 274 eq = eq && _equalsHelper(minimumFractionDigits, other.minimumFractionDigits); 275 eq = eq && _equalsHelper(minimumGroupingDigits, other.minimumGroupingDigits); 276 eq = eq && _equalsHelper(minimumIntegerDigits, other.minimumIntegerDigits); 277 eq = eq && _equalsHelper(minimumSignificantDigits, other.minimumSignificantDigits); 278 eq = eq && _equalsHelper(multiplier, other.multiplier); 279 eq = eq && _equalsHelper(negativePrefix, other.negativePrefix); 280 eq = eq && _equalsHelper(negativePrefixPattern, other.negativePrefixPattern); 281 eq = eq && _equalsHelper(negativeSuffix, other.negativeSuffix); 282 eq = eq && _equalsHelper(negativeSuffixPattern, other.negativeSuffixPattern); 283 eq = eq && _equalsHelper(padPosition, other.padPosition); 284 eq = eq && _equalsHelper(padString, other.padString); 285 eq = eq && _equalsHelper(parseCaseSensitive, other.parseCaseSensitive); 286 eq = eq && _equalsHelper(parseIntegerOnly, other.parseIntegerOnly); 287 eq = eq && _equalsHelper(parseMode, other.parseMode); 288 eq = eq && _equalsHelper(parseNoExponent, other.parseNoExponent); 289 eq = eq && _equalsHelper(parseToBigDecimal, other.parseToBigDecimal); 290 eq = eq && _equalsHelper(pluralRules, other.pluralRules); 291 eq = eq && _equalsHelper(positivePrefix, other.positivePrefix); 292 eq = eq && _equalsHelper(positivePrefixPattern, other.positivePrefixPattern); 293 eq = eq && _equalsHelper(positiveSuffix, other.positiveSuffix); 294 eq = eq && _equalsHelper(positiveSuffixPattern, other.positiveSuffixPattern); 295 eq = eq && _equalsHelper(roundingIncrement, other.roundingIncrement); 296 eq = eq && _equalsHelper(roundingMode, other.roundingMode); 297 eq = eq && _equalsHelper(secondaryGroupingSize, other.secondaryGroupingSize); 298 eq = eq && _equalsHelper(signAlwaysShown, other.signAlwaysShown); 299 return eq; 300 } 301 _equalsHelper(boolean mine, boolean theirs)302 private boolean _equalsHelper(boolean mine, boolean theirs) { 303 return mine == theirs; 304 } 305 _equalsHelper(int mine, int theirs)306 private boolean _equalsHelper(int mine, int theirs) { 307 return mine == theirs; 308 } 309 _equalsHelper(Object mine, Object theirs)310 private boolean _equalsHelper(Object mine, Object theirs) { 311 if (mine == theirs) 312 return true; 313 if (mine == null) 314 return false; 315 return mine.equals(theirs); 316 } 317 _hashCode()318 private int _hashCode() { 319 int hashCode = 0; 320 hashCode ^= _hashCodeHelper(compactCustomData); 321 hashCode ^= _hashCodeHelper(compactStyle); 322 hashCode ^= _hashCodeHelper(currency); 323 hashCode ^= _hashCodeHelper(currencyPluralInfo); 324 hashCode ^= _hashCodeHelper(currencyUsage); 325 hashCode ^= _hashCodeHelper(decimalPatternMatchRequired); 326 hashCode ^= _hashCodeHelper(decimalSeparatorAlwaysShown); 327 hashCode ^= _hashCodeHelper(exponentSignAlwaysShown); 328 hashCode ^= _hashCodeHelper(formatWidth); 329 hashCode ^= _hashCodeHelper(groupingSize); 330 hashCode ^= _hashCodeHelper(groupingUsed); 331 hashCode ^= _hashCodeHelper(magnitudeMultiplier); 332 hashCode ^= _hashCodeHelper(mathContext); 333 hashCode ^= _hashCodeHelper(maximumFractionDigits); 334 hashCode ^= _hashCodeHelper(maximumIntegerDigits); 335 hashCode ^= _hashCodeHelper(maximumSignificantDigits); 336 hashCode ^= _hashCodeHelper(minimumExponentDigits); 337 hashCode ^= _hashCodeHelper(minimumFractionDigits); 338 hashCode ^= _hashCodeHelper(minimumGroupingDigits); 339 hashCode ^= _hashCodeHelper(minimumIntegerDigits); 340 hashCode ^= _hashCodeHelper(minimumSignificantDigits); 341 hashCode ^= _hashCodeHelper(multiplier); 342 hashCode ^= _hashCodeHelper(negativePrefix); 343 hashCode ^= _hashCodeHelper(negativePrefixPattern); 344 hashCode ^= _hashCodeHelper(negativeSuffix); 345 hashCode ^= _hashCodeHelper(negativeSuffixPattern); 346 hashCode ^= _hashCodeHelper(padPosition); 347 hashCode ^= _hashCodeHelper(padString); 348 hashCode ^= _hashCodeHelper(parseCaseSensitive); 349 hashCode ^= _hashCodeHelper(parseIntegerOnly); 350 hashCode ^= _hashCodeHelper(parseMode); 351 hashCode ^= _hashCodeHelper(parseNoExponent); 352 hashCode ^= _hashCodeHelper(parseToBigDecimal); 353 hashCode ^= _hashCodeHelper(pluralRules); 354 hashCode ^= _hashCodeHelper(positivePrefix); 355 hashCode ^= _hashCodeHelper(positivePrefixPattern); 356 hashCode ^= _hashCodeHelper(positiveSuffix); 357 hashCode ^= _hashCodeHelper(positiveSuffixPattern); 358 hashCode ^= _hashCodeHelper(roundingIncrement); 359 hashCode ^= _hashCodeHelper(roundingMode); 360 hashCode ^= _hashCodeHelper(secondaryGroupingSize); 361 hashCode ^= _hashCodeHelper(signAlwaysShown); 362 return hashCode; 363 } 364 _hashCodeHelper(boolean value)365 private int _hashCodeHelper(boolean value) { 366 return value ? 1 : 0; 367 } 368 _hashCodeHelper(int value)369 private int _hashCodeHelper(int value) { 370 return value * 13; 371 } 372 _hashCodeHelper(Object value)373 private int _hashCodeHelper(Object value) { 374 if (value == null) 375 return 0; 376 return value.hashCode(); 377 } 378 clear()379 public DecimalFormatProperties clear() { 380 return _clear(); 381 } 382 383 /** Creates and returns a shallow copy of the property bag. */ 384 @Override clone()385 public DecimalFormatProperties clone() { 386 // super.clone() returns a shallow copy. 387 try { 388 return (DecimalFormatProperties) super.clone(); 389 } catch (CloneNotSupportedException e) { 390 // Should never happen since super is Object 391 throw new UnsupportedOperationException(e); 392 } 393 } 394 395 /** 396 * Shallow-copies the properties from the given property bag into this property bag. 397 * 398 * @param other 399 * The property bag from which to copy and which will not be modified. 400 * @return The current property bag (the one modified by this operation), for chaining. 401 */ copyFrom(DecimalFormatProperties other)402 public DecimalFormatProperties copyFrom(DecimalFormatProperties other) { 403 return _copyFrom(other); 404 } 405 406 @Override equals(Object other)407 public boolean equals(Object other) { 408 if (other == null) 409 return false; 410 if (this == other) 411 return true; 412 if (!(other instanceof DecimalFormatProperties)) 413 return false; 414 return _equals((DecimalFormatProperties) other); 415 } 416 417 /// BEGIN GETTERS/SETTERS /// 418 getCompactCustomData()419 public Map<String, Map<String, String>> getCompactCustomData() { 420 return compactCustomData; 421 } 422 getCompactStyle()423 public CompactStyle getCompactStyle() { 424 return compactStyle; 425 } 426 getCurrency()427 public Currency getCurrency() { 428 return currency; 429 } 430 getCurrencyPluralInfo()431 public CurrencyPluralInfo getCurrencyPluralInfo() { 432 return currencyPluralInfo; 433 } 434 getCurrencyUsage()435 public CurrencyUsage getCurrencyUsage() { 436 return currencyUsage; 437 } 438 getDecimalPatternMatchRequired()439 public boolean getDecimalPatternMatchRequired() { 440 return decimalPatternMatchRequired; 441 } 442 getDecimalSeparatorAlwaysShown()443 public boolean getDecimalSeparatorAlwaysShown() { 444 return decimalSeparatorAlwaysShown; 445 } 446 getExponentSignAlwaysShown()447 public boolean getExponentSignAlwaysShown() { 448 return exponentSignAlwaysShown; 449 } 450 getFormatWidth()451 public int getFormatWidth() { 452 return formatWidth; 453 } 454 getGroupingSize()455 public int getGroupingSize() { 456 return groupingSize; 457 } 458 getGroupingUsed()459 public boolean getGroupingUsed() { 460 return groupingUsed; 461 } 462 getMagnitudeMultiplier()463 public int getMagnitudeMultiplier() { 464 return magnitudeMultiplier; 465 } 466 getMathContext()467 public MathContext getMathContext() { 468 return mathContext; 469 } 470 getMaximumFractionDigits()471 public int getMaximumFractionDigits() { 472 return maximumFractionDigits; 473 } 474 getMaximumIntegerDigits()475 public int getMaximumIntegerDigits() { 476 return maximumIntegerDigits; 477 } 478 getMaximumSignificantDigits()479 public int getMaximumSignificantDigits() { 480 return maximumSignificantDigits; 481 } 482 getMinimumExponentDigits()483 public int getMinimumExponentDigits() { 484 return minimumExponentDigits; 485 } 486 getMinimumFractionDigits()487 public int getMinimumFractionDigits() { 488 return minimumFractionDigits; 489 } 490 getMinimumGroupingDigits()491 public int getMinimumGroupingDigits() { 492 return minimumGroupingDigits; 493 } 494 getMinimumIntegerDigits()495 public int getMinimumIntegerDigits() { 496 return minimumIntegerDigits; 497 } 498 getMinimumSignificantDigits()499 public int getMinimumSignificantDigits() { 500 return minimumSignificantDigits; 501 } 502 getMultiplier()503 public BigDecimal getMultiplier() { 504 return multiplier; 505 } 506 getNegativePrefix()507 public String getNegativePrefix() { 508 return negativePrefix; 509 } 510 getNegativePrefixPattern()511 public String getNegativePrefixPattern() { 512 return negativePrefixPattern; 513 } 514 getNegativeSuffix()515 public String getNegativeSuffix() { 516 return negativeSuffix; 517 } 518 getNegativeSuffixPattern()519 public String getNegativeSuffixPattern() { 520 return negativeSuffixPattern; 521 } 522 getPadPosition()523 public PadPosition getPadPosition() { 524 return padPosition; 525 } 526 getPadString()527 public String getPadString() { 528 return padString; 529 } 530 getParseCaseSensitive()531 public boolean getParseCaseSensitive() { 532 return parseCaseSensitive; 533 } 534 getParseIntegerOnly()535 public boolean getParseIntegerOnly() { 536 return parseIntegerOnly; 537 } 538 getParseMode()539 public ParseMode getParseMode() { 540 return parseMode; 541 } 542 getParseNoExponent()543 public boolean getParseNoExponent() { 544 return parseNoExponent; 545 } 546 getParseToBigDecimal()547 public boolean getParseToBigDecimal() { 548 return parseToBigDecimal; 549 } 550 getPluralRules()551 public PluralRules getPluralRules() { 552 return pluralRules; 553 } 554 getPositivePrefix()555 public String getPositivePrefix() { 556 return positivePrefix; 557 } 558 getPositivePrefixPattern()559 public String getPositivePrefixPattern() { 560 return positivePrefixPattern; 561 } 562 getPositiveSuffix()563 public String getPositiveSuffix() { 564 return positiveSuffix; 565 } 566 getPositiveSuffixPattern()567 public String getPositiveSuffixPattern() { 568 return positiveSuffixPattern; 569 } 570 getRoundingIncrement()571 public BigDecimal getRoundingIncrement() { 572 return roundingIncrement; 573 } 574 getRoundingMode()575 public RoundingMode getRoundingMode() { 576 return roundingMode; 577 } 578 getSecondaryGroupingSize()579 public int getSecondaryGroupingSize() { 580 return secondaryGroupingSize; 581 } 582 getSignAlwaysShown()583 public boolean getSignAlwaysShown() { 584 return signAlwaysShown; 585 } 586 587 @Override hashCode()588 public int hashCode() { 589 return _hashCode(); 590 } 591 592 /** Custom serialization: re-create object from serialized properties. */ readObject(ObjectInputStream ois)593 private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { 594 readObjectImpl(ois); 595 } 596 readObjectImpl(ObjectInputStream ois)597 /* package-private */ void readObjectImpl(ObjectInputStream ois) 598 throws IOException, ClassNotFoundException { 599 ois.defaultReadObject(); 600 601 // Initialize to empty 602 clear(); 603 604 // Extra int for possible future use 605 ois.readInt(); 606 607 // 1) How many fields were serialized? 608 int count = ois.readInt(); 609 610 // 2) Read each field by its name and value 611 for (int i = 0; i < count; i++) { 612 String name = (String) ois.readObject(); 613 Object value = ois.readObject(); 614 615 // Get the field reference 616 Field field = null; 617 try { 618 field = DecimalFormatProperties.class.getDeclaredField(name); 619 } catch (NoSuchFieldException e) { 620 // The field name does not exist! Possibly corrupted serialization. Ignore this entry. 621 continue; 622 } catch (SecurityException e) { 623 // Should not happen 624 throw new AssertionError(e); 625 } 626 627 // NOTE: If the type of a field were changed in the future, this would be the place to check: 628 // If the variable `value` is the old type, perform any conversions necessary. 629 630 // Save value into the field 631 try { 632 field.set(this, value); 633 } catch (IllegalArgumentException e) { 634 // Should not happen 635 throw new AssertionError(e); 636 } catch (IllegalAccessException e) { 637 // Should not happen 638 throw new AssertionError(e); 639 } 640 } 641 } 642 643 /** 644 * Specifies custom data to be used instead of CLDR data when constructing a CompactDecimalFormat. 645 * The argument should be a map with the following structure: 646 * 647 * <pre> 648 * { 649 * "1000": { 650 * "one": "0 thousand", 651 * "other": "0 thousand" 652 * }, 653 * "10000": { 654 * "one": "00 thousand", 655 * "other": "00 thousand" 656 * }, 657 * // ... 658 * } 659 * </pre> 660 * 661 * This API endpoint is used by the CLDR Survey Tool. 662 * 663 * @param compactCustomData 664 * A map with the above structure. 665 * @return The property bag, for chaining. 666 */ setCompactCustomData( Map<String, Map<String, String>> compactCustomData)667 public DecimalFormatProperties setCompactCustomData( 668 Map<String, Map<String, String>> compactCustomData) { 669 // TODO: compactCustomData is not immutable. 670 this.compactCustomData = compactCustomData; 671 return this; 672 } 673 674 /** 675 * Use compact decimal formatting with the specified {@link CompactStyle}. CompactStyle.SHORT 676 * produces output like "10K" in locale <em>en-US</em>, whereas CompactStyle.LONG produces output 677 * like "10 thousand" in that locale. 678 * 679 * @param compactStyle 680 * The style of prefixes/suffixes to append. 681 * @return The property bag, for chaining. 682 */ setCompactStyle(CompactStyle compactStyle)683 public DecimalFormatProperties setCompactStyle(CompactStyle compactStyle) { 684 this.compactStyle = compactStyle; 685 return this; 686 } 687 688 /** 689 * Use the specified currency to substitute currency placeholders ('¤') in the pattern string. 690 * 691 * @param currency 692 * The currency. 693 * @return The property bag, for chaining. 694 */ setCurrency(Currency currency)695 public DecimalFormatProperties setCurrency(Currency currency) { 696 this.currency = currency; 697 return this; 698 } 699 700 /** 701 * Use the specified {@link CurrencyPluralInfo} instance when formatting currency long names. 702 * 703 * @param currencyPluralInfo 704 * The currency plural info object. 705 * @return The property bag, for chaining. 706 */ setCurrencyPluralInfo(CurrencyPluralInfo currencyPluralInfo)707 public DecimalFormatProperties setCurrencyPluralInfo(CurrencyPluralInfo currencyPluralInfo) { 708 // TODO: In order to maintain immutability, we have to perform a clone here. 709 // It would be better to just retire CurrencyPluralInfo entirely. 710 if (currencyPluralInfo != null) { 711 currencyPluralInfo = (CurrencyPluralInfo) currencyPluralInfo.clone(); 712 } 713 this.currencyPluralInfo = currencyPluralInfo; 714 return this; 715 } 716 717 /** 718 * Use the specified {@link CurrencyUsage} instance, which provides default rounding rules for the 719 * currency in two styles, CurrencyUsage.CASH and CurrencyUsage.STANDARD. 720 * 721 * <p> 722 * The CurrencyUsage specified here will not be used unless there is a currency placeholder in the 723 * pattern. 724 * 725 * @param currencyUsage 726 * The currency usage. Defaults to CurrencyUsage.STANDARD. 727 * @return The property bag, for chaining. 728 */ setCurrencyUsage(CurrencyUsage currencyUsage)729 public DecimalFormatProperties setCurrencyUsage(CurrencyUsage currencyUsage) { 730 this.currencyUsage = currencyUsage; 731 return this; 732 } 733 734 /** 735 * PARSING: Whether to require that the presence of decimal point matches the pattern. If a decimal 736 * point is not present, but the pattern contained a decimal point, parse will not succeed: null will 737 * be returned from <code>parse()</code>, and an error index will be set in the 738 * {@link ParsePosition}. 739 * 740 * @param decimalPatternMatchRequired 741 * true to set an error if decimal is not present 742 * @return The property bag, for chaining. 743 */ setDecimalPatternMatchRequired(boolean decimalPatternMatchRequired)744 public DecimalFormatProperties setDecimalPatternMatchRequired(boolean decimalPatternMatchRequired) { 745 this.decimalPatternMatchRequired = decimalPatternMatchRequired; 746 return this; 747 } 748 749 /** 750 * Sets whether to always show the decimal point, even if the number doesn't require one. For 751 * example, if always show decimal is true, the number 123 would be formatted as "123." in locale 752 * <em>en-US</em>. 753 * 754 * @param alwaysShowDecimal 755 * Whether to show the decimal point when it is optional. 756 * @return The property bag, for chaining. 757 */ setDecimalSeparatorAlwaysShown(boolean alwaysShowDecimal)758 public DecimalFormatProperties setDecimalSeparatorAlwaysShown(boolean alwaysShowDecimal) { 759 this.decimalSeparatorAlwaysShown = alwaysShowDecimal; 760 return this; 761 } 762 763 /** 764 * Sets whether to show the plus sign in the exponent part of numbers with a zero or positive 765 * exponent. For example, the number "1200" with the pattern "0.0E0" would be formatted as "1.2E+3" 766 * instead of "1.2E3" in <em>en-US</em>. 767 * 768 * @param exponentSignAlwaysShown 769 * Whether to show the plus sign in positive exponents. 770 * @return The property bag, for chaining. 771 */ setExponentSignAlwaysShown(boolean exponentSignAlwaysShown)772 public DecimalFormatProperties setExponentSignAlwaysShown(boolean exponentSignAlwaysShown) { 773 this.exponentSignAlwaysShown = exponentSignAlwaysShown; 774 return this; 775 } 776 777 /** 778 * Sets the minimum width of the string output by the formatting pipeline. For example, if padding is 779 * enabled and paddingWidth is set to 6, formatting the number "3.14159" with the pattern "0.00" will 780 * result in "··3.14" if '·' is your padding string. 781 * 782 * <p> 783 * If the number is longer than your padding width, the number will display as if no padding width 784 * had been specified, which may result in strings longer than the padding width. 785 * 786 * <p> 787 * Width is counted in UTF-16 code units. 788 * 789 * @param paddingWidth 790 * The output width. 791 * @return The property bag, for chaining. 792 * @see #setPadPosition 793 * @see #setPadString 794 */ setFormatWidth(int paddingWidth)795 public DecimalFormatProperties setFormatWidth(int paddingWidth) { 796 this.formatWidth = paddingWidth; 797 return this; 798 } 799 800 /** 801 * Sets the number of digits between grouping separators. For example, the <em>en-US</em> locale uses 802 * a grouping size of 3, so the number 1234567 would be formatted as "1,234,567". For locales whose 803 * grouping sizes vary with magnitude, see {@link #setSecondaryGroupingSize(int)}. 804 * 805 * @param groupingSize 806 * The primary grouping size. 807 * @return The property bag, for chaining. 808 */ setGroupingSize(int groupingSize)809 public DecimalFormatProperties setGroupingSize(int groupingSize) { 810 this.groupingSize = groupingSize; 811 return this; 812 } 813 814 /** 815 * Sets whether to enable grouping when formatting. 816 * 817 * @param groupingUsed 818 * true to enable the display of grouping separators; false to disable. 819 * @return The property bag, for chaining. 820 */ setGroupingUsed(boolean groupingUsed)821 public DecimalFormatProperties setGroupingUsed(boolean groupingUsed) { 822 this.groupingUsed = groupingUsed; 823 return this; 824 } 825 826 /** 827 * Multiply all numbers by this power of ten before formatting. Negative multipliers reduce the 828 * magnitude and make numbers smaller (closer to zero). 829 * 830 * @param magnitudeMultiplier 831 * The number of powers of ten to scale. 832 * @return The property bag, for chaining. 833 * @see #setMultiplier 834 */ setMagnitudeMultiplier(int magnitudeMultiplier)835 public DecimalFormatProperties setMagnitudeMultiplier(int magnitudeMultiplier) { 836 this.magnitudeMultiplier = magnitudeMultiplier; 837 return this; 838 } 839 840 /** 841 * Sets the {@link MathContext} to be used during math and rounding operations. A MathContext 842 * encapsulates a RoundingMode and the number of significant digits in the output. 843 * 844 * @param mathContext 845 * The math context to use when rounding is required. 846 * @return The property bag, for chaining. 847 * @see MathContext 848 * @see #setRoundingMode 849 */ setMathContext(MathContext mathContext)850 public DecimalFormatProperties setMathContext(MathContext mathContext) { 851 this.mathContext = mathContext; 852 return this; 853 } 854 855 /** 856 * Sets the maximum number of digits to display after the decimal point. If the number has fewer than 857 * this number of digits, the number will be rounded off using the rounding mode specified by 858 * {@link #setRoundingMode(RoundingMode)}. The pattern "#00.0#", for example, corresponds to 2 859 * maximum fraction digits, and the number 456.789 would be formatted as "456.79" in locale 860 * <em>en-US</em> with the default rounding mode. Note that the number 456.999 would be formatted as 861 * "457.0" given the same configurations. 862 * 863 * @param maximumFractionDigits 864 * The maximum number of fraction digits to output. 865 * @return The property bag, for chaining. 866 */ setMaximumFractionDigits(int maximumFractionDigits)867 public DecimalFormatProperties setMaximumFractionDigits(int maximumFractionDigits) { 868 this.maximumFractionDigits = maximumFractionDigits; 869 return this; 870 } 871 872 /** 873 * Sets the maximum number of digits to display before the decimal point. If the number has more than 874 * this number of digits, the extra digits will be truncated. For example, if maximum integer digits 875 * is 2, and you attempt to format the number 1970, you will get "70" in locale <em>en-US</em>. It is 876 * not possible to specify the maximum integer digits using a pattern string, except in the special 877 * case of a scientific format pattern. 878 * 879 * @param maximumIntegerDigits 880 * The maximum number of integer digits to output. 881 * @return The property bag, for chaining. 882 */ setMaximumIntegerDigits(int maximumIntegerDigits)883 public DecimalFormatProperties setMaximumIntegerDigits(int maximumIntegerDigits) { 884 this.maximumIntegerDigits = maximumIntegerDigits; 885 return this; 886 } 887 888 /** 889 * Sets the maximum number of significant digits to display. The number of significant digits is 890 * equal to the number of digits counted from the leftmost nonzero digit through the rightmost 891 * nonzero digit; for example, the number "2010" has 3 significant digits. If the number has more 892 * significant digits than specified here, the extra significant digits will be rounded off using the 893 * rounding mode specified by {@link #setRoundingMode(RoundingMode)}. For example, if maximum 894 * significant digits is 3, the number 1234.56 will be formatted as "1230" in locale <em>en-US</em> 895 * with the default rounding mode. 896 * 897 * <p> 898 * If both maximum significant digits and maximum integer/fraction digits are set at the same time, 899 * the behavior is undefined. 900 * 901 * <p> 902 * The number of significant digits can be specified in a pattern string using the '@' character. For 903 * example, the pattern "@@#" corresponds to a minimum of 2 and a maximum of 3 significant digits. 904 * 905 * @param maximumSignificantDigits 906 * The maximum number of significant digits to display. 907 * @return The property bag, for chaining. 908 */ setMaximumSignificantDigits(int maximumSignificantDigits)909 public DecimalFormatProperties setMaximumSignificantDigits(int maximumSignificantDigits) { 910 this.maximumSignificantDigits = maximumSignificantDigits; 911 return this; 912 } 913 914 /** 915 * Sets the minimum number of digits to display in the exponent. For example, the number "1200" with 916 * the pattern "0.0E00", which has 2 exponent digits, would be formatted as "1.2E03" in 917 * <em>en-US</em>. 918 * 919 * @param minimumExponentDigits 920 * The minimum number of digits to display in the exponent field. 921 * @return The property bag, for chaining. 922 */ setMinimumExponentDigits(int minimumExponentDigits)923 public DecimalFormatProperties setMinimumExponentDigits(int minimumExponentDigits) { 924 this.minimumExponentDigits = minimumExponentDigits; 925 return this; 926 } 927 928 /** 929 * Sets the minimum number of digits to display after the decimal point. If the number has fewer than 930 * this number of digits, the number will be padded with zeros. The pattern "#00.0#", for example, 931 * corresponds to 1 minimum fraction digit, and the number 456 would be formatted as "456.0" in 932 * locale <em>en-US</em>. 933 * 934 * @param minimumFractionDigits 935 * The minimum number of fraction digits to output. 936 * @return The property bag, for chaining. 937 */ setMinimumFractionDigits(int minimumFractionDigits)938 public DecimalFormatProperties setMinimumFractionDigits(int minimumFractionDigits) { 939 this.minimumFractionDigits = minimumFractionDigits; 940 return this; 941 } 942 943 /** 944 * Sets the minimum number of digits required to be beyond the first grouping separator in order to 945 * enable grouping. For example, if the minimum grouping digits is 2, then 1234 would be formatted as 946 * "1234" but 12345 would be formatted as "12,345" in <em>en-US</em>. Note that 1234567 would still 947 * be formatted as "1,234,567", not "1234,567". 948 * 949 * @param minimumGroupingDigits 950 * How many digits must appear before a grouping separator before enabling grouping. 951 * @return The property bag, for chaining. 952 */ setMinimumGroupingDigits(int minimumGroupingDigits)953 public DecimalFormatProperties setMinimumGroupingDigits(int minimumGroupingDigits) { 954 this.minimumGroupingDigits = minimumGroupingDigits; 955 return this; 956 } 957 958 /** 959 * Sets the minimum number of digits to display before the decimal point. If the number has fewer 960 * than this number of digits, the number will be padded with zeros. The pattern "#00.0#", for 961 * example, corresponds to 2 minimum integer digits, and the number 5.3 would be formatted as "05.3" 962 * in locale <em>en-US</em>. 963 * 964 * @param minimumIntegerDigits 965 * The minimum number of integer digits to output. 966 * @return The property bag, for chaining. 967 */ setMinimumIntegerDigits(int minimumIntegerDigits)968 public DecimalFormatProperties setMinimumIntegerDigits(int minimumIntegerDigits) { 969 this.minimumIntegerDigits = minimumIntegerDigits; 970 return this; 971 } 972 973 /** 974 * Sets the minimum number of significant digits to display. If, after rounding to the number of 975 * significant digits specified by {@link #setMaximumSignificantDigits}, the number of remaining 976 * significant digits is less than the minimum, the number will be padded with zeros. For example, if 977 * minimum significant digits is 3, the number 5.8 will be formatted as "5.80" in locale 978 * <em>en-US</em>. Note that minimum significant digits is relevant only when numbers have digits 979 * after the decimal point. 980 * 981 * <p> 982 * If both minimum significant digits and minimum integer/fraction digits are set at the same time, 983 * both values will be respected, and the one that results in the greater number of padding zeros 984 * will be used. For example, formatting the number 73 with 3 minimum significant digits and 2 985 * minimum fraction digits will produce "73.00". 986 * 987 * <p> 988 * The number of significant digits can be specified in a pattern string using the '@' character. For 989 * example, the pattern "@@#" corresponds to a minimum of 2 and a maximum of 3 significant digits. 990 * 991 * @param minimumSignificantDigits 992 * The minimum number of significant digits to display. 993 * @return The property bag, for chaining. 994 */ setMinimumSignificantDigits(int minimumSignificantDigits)995 public DecimalFormatProperties setMinimumSignificantDigits(int minimumSignificantDigits) { 996 this.minimumSignificantDigits = minimumSignificantDigits; 997 return this; 998 } 999 1000 /** 1001 * Multiply all numbers by this amount before formatting. 1002 * 1003 * @param multiplier 1004 * The amount to multiply by. 1005 * @return The property bag, for chaining. 1006 * @see #setMagnitudeMultiplier 1007 */ setMultiplier(BigDecimal multiplier)1008 public DecimalFormatProperties setMultiplier(BigDecimal multiplier) { 1009 this.multiplier = multiplier; 1010 return this; 1011 } 1012 1013 /** 1014 * Sets the prefix to prepend to negative numbers. The prefix will be interpreted literally. For 1015 * example, if you set a negative prefix of <code>n</code>, then the number -123 will be formatted as 1016 * "n123" in the locale <em>en-US</em>. Note that if the negative prefix is left unset, the locale's 1017 * minus sign is used. 1018 * 1019 * <p> 1020 * For more information on prefixes and suffixes, see {@link MutablePatternModifier}. 1021 * 1022 * @param negativePrefix 1023 * The CharSequence to prepend to negative numbers. 1024 * @return The property bag, for chaining. 1025 * @see #setNegativePrefixPattern 1026 */ setNegativePrefix(String negativePrefix)1027 public DecimalFormatProperties setNegativePrefix(String negativePrefix) { 1028 this.negativePrefix = negativePrefix; 1029 return this; 1030 } 1031 1032 /** 1033 * Sets the prefix to prepend to negative numbers. Locale-specific symbols will be substituted into 1034 * the string according to Unicode Technical Standard #35 (LDML). 1035 * 1036 * <p> 1037 * For more information on prefixes and suffixes, see {@link MutablePatternModifier}. 1038 * 1039 * @param negativePrefixPattern 1040 * The CharSequence to prepend to negative numbers after locale symbol substitutions take 1041 * place. 1042 * @return The property bag, for chaining. 1043 * @see #setNegativePrefix 1044 */ setNegativePrefixPattern(String negativePrefixPattern)1045 public DecimalFormatProperties setNegativePrefixPattern(String negativePrefixPattern) { 1046 this.negativePrefixPattern = negativePrefixPattern; 1047 return this; 1048 } 1049 1050 /** 1051 * Sets the suffix to append to negative numbers. The suffix will be interpreted literally. For 1052 * example, if you set a suffix prefix of <code>n</code>, then the number -123 will be formatted as 1053 * "-123n" in the locale <em>en-US</em>. Note that the minus sign is prepended by default unless 1054 * otherwise specified in either the pattern string or in one of the {@link #setNegativePrefix} 1055 * methods. 1056 * 1057 * <p> 1058 * For more information on prefixes and suffixes, see {@link MutablePatternModifier}. 1059 * 1060 * @param negativeSuffix 1061 * The CharSequence to append to negative numbers. 1062 * @return The property bag, for chaining. 1063 * @see #setNegativeSuffixPattern 1064 */ setNegativeSuffix(String negativeSuffix)1065 public DecimalFormatProperties setNegativeSuffix(String negativeSuffix) { 1066 this.negativeSuffix = negativeSuffix; 1067 return this; 1068 } 1069 1070 /** 1071 * Sets the suffix to append to negative numbers. Locale-specific symbols will be substituted into 1072 * the string according to Unicode Technical Standard #35 (LDML). 1073 * 1074 * <p> 1075 * For more information on prefixes and suffixes, see {@link MutablePatternModifier}. 1076 * 1077 * @param negativeSuffixPattern 1078 * The CharSequence to append to negative numbers after locale symbol substitutions take 1079 * place. 1080 * @return The property bag, for chaining. 1081 * @see #setNegativeSuffix 1082 */ setNegativeSuffixPattern(String negativeSuffixPattern)1083 public DecimalFormatProperties setNegativeSuffixPattern(String negativeSuffixPattern) { 1084 this.negativeSuffixPattern = negativeSuffixPattern; 1085 return this; 1086 } 1087 1088 /** 1089 * Sets the location where the padding string is to be inserted to maintain the padding width: one of 1090 * BEFORE_PREFIX, AFTER_PREFIX, BEFORE_SUFFIX, or AFTER_SUFFIX. 1091 * 1092 * <p> 1093 * Must be used in conjunction with {@link #setFormatWidth}. 1094 * 1095 * @param paddingLocation 1096 * The output width. 1097 * @return The property bag, for chaining. 1098 * @see #setFormatWidth 1099 */ setPadPosition(PadPosition paddingLocation)1100 public DecimalFormatProperties setPadPosition(PadPosition paddingLocation) { 1101 this.padPosition = paddingLocation; 1102 return this; 1103 } 1104 1105 /** 1106 * Sets the string used for padding. The string should contain a single character or grapheme 1107 * cluster. 1108 * 1109 * <p> 1110 * Must be used in conjunction with {@link #setFormatWidth}. 1111 * 1112 * @param paddingString 1113 * The padding string. Defaults to an ASCII space (U+0020). 1114 * @return The property bag, for chaining. 1115 * @see #setFormatWidth 1116 */ setPadString(String paddingString)1117 public DecimalFormatProperties setPadString(String paddingString) { 1118 this.padString = paddingString; 1119 return this; 1120 } 1121 1122 /** 1123 * Whether to require cases to match when parsing strings; default is true. Case sensitivity applies 1124 * to prefixes, suffixes, the exponent separator, the symbol "NaN", and the infinity symbol. Grouping 1125 * separators, decimal separators, and padding are always case-sensitive. Currencies are always 1126 * case-insensitive. 1127 * 1128 * <p> 1129 * This setting is ignored in fast mode. In fast mode, strings are always compared in a 1130 * case-sensitive way. 1131 * 1132 * @param parseCaseSensitive 1133 * true to be case-sensitive when parsing; false to allow any case. 1134 * @return The property bag, for chaining. 1135 */ setParseCaseSensitive(boolean parseCaseSensitive)1136 public DecimalFormatProperties setParseCaseSensitive(boolean parseCaseSensitive) { 1137 this.parseCaseSensitive = parseCaseSensitive; 1138 return this; 1139 } 1140 1141 /** 1142 * Whether to ignore the fractional part of numbers. For example, parses "123.4" to "123" instead of 1143 * "123.4". 1144 * 1145 * @param parseIntegerOnly 1146 * true to parse integers only; false to parse integers with their fraction parts 1147 * @return The property bag, for chaining. 1148 */ setParseIntegerOnly(boolean parseIntegerOnly)1149 public DecimalFormatProperties setParseIntegerOnly(boolean parseIntegerOnly) { 1150 this.parseIntegerOnly = parseIntegerOnly; 1151 return this; 1152 } 1153 1154 /** 1155 * Controls certain rules for how strict this parser is when reading strings. See 1156 * {@link ParseMode#LENIENT} and {@link ParseMode#STRICT}. 1157 * 1158 * @param parseMode 1159 * Either {@link ParseMode#LENIENT} or {@link ParseMode#STRICT}. 1160 * @return The property bag, for chaining. 1161 */ setParseMode(ParseMode parseMode)1162 public DecimalFormatProperties setParseMode(ParseMode parseMode) { 1163 this.parseMode = parseMode; 1164 return this; 1165 } 1166 1167 /** 1168 * Whether to ignore the exponential part of numbers. For example, parses "123E4" to "123" instead of 1169 * "1230000". 1170 * 1171 * @param parseNoExponent 1172 * true to ignore exponents; false to parse them. 1173 * @return The property bag, for chaining. 1174 */ setParseNoExponent(boolean parseNoExponent)1175 public DecimalFormatProperties setParseNoExponent(boolean parseNoExponent) { 1176 this.parseNoExponent = parseNoExponent; 1177 return this; 1178 } 1179 1180 /** 1181 * Whether to always return a BigDecimal from parse methods. By default, a Long or a BigInteger are 1182 * returned when possible. 1183 * 1184 * @param parseToBigDecimal 1185 * true to always return a BigDecimal; false to return a Long or a BigInteger when 1186 * possible. 1187 * @return The property bag, for chaining. 1188 */ setParseToBigDecimal(boolean parseToBigDecimal)1189 public DecimalFormatProperties setParseToBigDecimal(boolean parseToBigDecimal) { 1190 this.parseToBigDecimal = parseToBigDecimal; 1191 return this; 1192 } 1193 1194 /** 1195 * Sets the PluralRules object to use instead of the default for the locale. 1196 * 1197 * @param pluralRules 1198 * The object to reference. 1199 * @return The property bag, for chaining. 1200 */ setPluralRules(PluralRules pluralRules)1201 public DecimalFormatProperties setPluralRules(PluralRules pluralRules) { 1202 this.pluralRules = pluralRules; 1203 return this; 1204 } 1205 1206 /** 1207 * Sets the prefix to prepend to positive numbers. The prefix will be interpreted literally. For 1208 * example, if you set a positive prefix of <code>p</code>, then the number 123 will be formatted as 1209 * "p123" in the locale <em>en-US</em>. 1210 * 1211 * <p> 1212 * For more information on prefixes and suffixes, see {@link MutablePatternModifier}. 1213 * 1214 * @param positivePrefix 1215 * The CharSequence to prepend to positive numbers. 1216 * @return The property bag, for chaining. 1217 * @see #setPositivePrefixPattern 1218 */ setPositivePrefix(String positivePrefix)1219 public DecimalFormatProperties setPositivePrefix(String positivePrefix) { 1220 this.positivePrefix = positivePrefix; 1221 return this; 1222 } 1223 1224 /** 1225 * Sets the prefix to prepend to positive numbers. Locale-specific symbols will be substituted into 1226 * the string according to Unicode Technical Standard #35 (LDML). 1227 * 1228 * <p> 1229 * For more information on prefixes and suffixes, see {@link MutablePatternModifier}. 1230 * 1231 * @param positivePrefixPattern 1232 * The CharSequence to prepend to positive numbers after locale symbol substitutions take 1233 * place. 1234 * @return The property bag, for chaining. 1235 * @see #setPositivePrefix 1236 */ setPositivePrefixPattern(String positivePrefixPattern)1237 public DecimalFormatProperties setPositivePrefixPattern(String positivePrefixPattern) { 1238 this.positivePrefixPattern = positivePrefixPattern; 1239 return this; 1240 } 1241 1242 /** 1243 * Sets the suffix to append to positive numbers. The suffix will be interpreted literally. For 1244 * example, if you set a positive suffix of <code>p</code>, then the number 123 will be formatted as 1245 * "123p" in the locale <em>en-US</em>. 1246 * 1247 * <p> 1248 * For more information on prefixes and suffixes, see {@link MutablePatternModifier}. 1249 * 1250 * @param positiveSuffix 1251 * The CharSequence to append to positive numbers. 1252 * @return The property bag, for chaining. 1253 * @see #setPositiveSuffixPattern 1254 */ setPositiveSuffix(String positiveSuffix)1255 public DecimalFormatProperties setPositiveSuffix(String positiveSuffix) { 1256 this.positiveSuffix = positiveSuffix; 1257 return this; 1258 } 1259 1260 /** 1261 * Sets the suffix to append to positive numbers. Locale-specific symbols will be substituted into 1262 * the string according to Unicode Technical Standard #35 (LDML). 1263 * 1264 * <p> 1265 * For more information on prefixes and suffixes, see {@link MutablePatternModifier}. 1266 * 1267 * @param positiveSuffixPattern 1268 * The CharSequence to append to positive numbers after locale symbol substitutions take 1269 * place. 1270 * @return The property bag, for chaining. 1271 * @see #setPositiveSuffix 1272 */ setPositiveSuffixPattern(String positiveSuffixPattern)1273 public DecimalFormatProperties setPositiveSuffixPattern(String positiveSuffixPattern) { 1274 this.positiveSuffixPattern = positiveSuffixPattern; 1275 return this; 1276 } 1277 1278 /** 1279 * Sets the increment to which to round numbers. For example, with a rounding interval of 0.05, the 1280 * number 11.17 would be formatted as "11.15" in locale <em>en-US</em> with the default rounding 1281 * mode. 1282 * 1283 * <p> 1284 * You can use either a rounding increment or significant digits, but not both at the same time. 1285 * 1286 * <p> 1287 * The rounding increment can be specified in a pattern string. For example, the pattern "#,##0.05" 1288 * corresponds to a rounding interval of 0.05 with 1 minimum integer digit and a grouping size of 3. 1289 * 1290 * @param roundingIncrement 1291 * The interval to which to round. 1292 * @return The property bag, for chaining. 1293 */ setRoundingIncrement(BigDecimal roundingIncrement)1294 public DecimalFormatProperties setRoundingIncrement(BigDecimal roundingIncrement) { 1295 this.roundingIncrement = roundingIncrement; 1296 return this; 1297 } 1298 1299 /** 1300 * Sets the rounding mode, which determines under which conditions extra decimal places are rounded 1301 * either up or down. See {@link RoundingMode} for details on the choices of rounding mode. The 1302 * default if not set explicitly is {@link RoundingMode#HALF_EVEN}. 1303 * 1304 * <p> 1305 * This setting is ignored if {@link #setMathContext} is used. 1306 * 1307 * @param roundingMode 1308 * The rounding mode to use when rounding is required. 1309 * @return The property bag, for chaining. 1310 * @see RoundingMode 1311 * @see #setMathContext 1312 */ setRoundingMode(RoundingMode roundingMode)1313 public DecimalFormatProperties setRoundingMode(RoundingMode roundingMode) { 1314 this.roundingMode = roundingMode; 1315 return this; 1316 } 1317 1318 /** 1319 * Sets the number of digits between grouping separators higher than the least-significant grouping 1320 * separator. For example, the locale <em>hi</em> uses a primary grouping size of 3 and a secondary 1321 * grouping size of 2, so the number 1234567 would be formatted as "12,34,567". 1322 * 1323 * <p> 1324 * The two levels of grouping separators can be specified in the pattern string. For example, the 1325 * <em>hi</em> locale's default decimal format pattern is "#,##,##0.###". 1326 * 1327 * @param secondaryGroupingSize 1328 * The secondary grouping size. 1329 * @return The property bag, for chaining. 1330 */ setSecondaryGroupingSize(int secondaryGroupingSize)1331 public DecimalFormatProperties setSecondaryGroupingSize(int secondaryGroupingSize) { 1332 this.secondaryGroupingSize = secondaryGroupingSize; 1333 return this; 1334 } 1335 1336 /** 1337 * Sets whether to always display of a plus sign on positive numbers. 1338 * 1339 * <p> 1340 * If the location of the negative sign is specified by the decimal format pattern (or by the 1341 * negative prefix/suffix pattern methods), a plus sign is substituted into that location, in 1342 * accordance with Unicode Technical Standard #35 (LDML) section 3.2.1. Otherwise, the plus sign is 1343 * prepended to the number. For example, if the decimal format pattern <code>#;#-</code> is used, 1344 * then formatting 123 would result in "123+" in the locale <em>en-US</em>. 1345 * 1346 * <p> 1347 * This method should be used <em>instead of</em> setting the positive prefix/suffix. The behavior is 1348 * undefined if alwaysShowPlusSign is set but the positive prefix/suffix already contains a plus 1349 * sign. 1350 * 1351 * @param signAlwaysShown 1352 * Whether positive numbers should display a plus sign. 1353 * @return The property bag, for chaining. 1354 */ setSignAlwaysShown(boolean signAlwaysShown)1355 public DecimalFormatProperties setSignAlwaysShown(boolean signAlwaysShown) { 1356 this.signAlwaysShown = signAlwaysShown; 1357 return this; 1358 } 1359 1360 @Override toString()1361 public String toString() { 1362 StringBuilder result = new StringBuilder(); 1363 result.append("<Properties"); 1364 toStringBare(result); 1365 result.append(">"); 1366 return result.toString(); 1367 } 1368 1369 /** 1370 * Appends a string containing properties that differ from the default, but without being surrounded 1371 * by <Properties>. 1372 */ toStringBare(StringBuilder result)1373 public void toStringBare(StringBuilder result) { 1374 Field[] fields = DecimalFormatProperties.class.getDeclaredFields(); 1375 for (Field field : fields) { 1376 Object myValue, defaultValue; 1377 try { 1378 myValue = field.get(this); 1379 defaultValue = field.get(DEFAULT); 1380 } catch (IllegalArgumentException e) { 1381 e.printStackTrace(); 1382 continue; 1383 } catch (IllegalAccessException e) { 1384 e.printStackTrace(); 1385 continue; 1386 } 1387 if (myValue == null && defaultValue == null) { 1388 continue; 1389 } else if (myValue == null || defaultValue == null) { 1390 result.append(" " + field.getName() + ":" + myValue); 1391 } else if (!myValue.equals(defaultValue)) { 1392 result.append(" " + field.getName() + ":" + myValue); 1393 } 1394 } 1395 } 1396 1397 /** 1398 * Custom serialization: save fields along with their name, so that fields can be easily added in the 1399 * future in any order. Only save fields that differ from their default value. 1400 */ writeObject(ObjectOutputStream oos)1401 private void writeObject(ObjectOutputStream oos) throws IOException { 1402 writeObjectImpl(oos); 1403 } 1404 writeObjectImpl(ObjectOutputStream oos)1405 /* package-private */ void writeObjectImpl(ObjectOutputStream oos) throws IOException { 1406 oos.defaultWriteObject(); 1407 1408 // Extra int for possible future use 1409 oos.writeInt(0); 1410 1411 ArrayList<Field> fieldsToSerialize = new ArrayList<>(); 1412 ArrayList<Object> valuesToSerialize = new ArrayList<>(); 1413 Field[] fields = DecimalFormatProperties.class.getDeclaredFields(); 1414 for (Field field : fields) { 1415 if (Modifier.isStatic(field.getModifiers())) { 1416 continue; 1417 } 1418 try { 1419 Object myValue = field.get(this); 1420 if (myValue == null) { 1421 // All *Object* values default to null; no need to serialize. 1422 continue; 1423 } 1424 Object defaultValue = field.get(DEFAULT); 1425 if (!myValue.equals(defaultValue)) { 1426 fieldsToSerialize.add(field); 1427 valuesToSerialize.add(myValue); 1428 } 1429 } catch (IllegalArgumentException e) { 1430 // Should not happen 1431 throw new AssertionError(e); 1432 } catch (IllegalAccessException e) { 1433 // Should not happen 1434 throw new AssertionError(e); 1435 } 1436 } 1437 1438 // 1) How many fields are to be serialized? 1439 int count = fieldsToSerialize.size(); 1440 oos.writeInt(count); 1441 1442 // 2) Write each field with its name and value 1443 for (int i = 0; i < count; i++) { 1444 Field field = fieldsToSerialize.get(i); 1445 Object value = valuesToSerialize.get(i); 1446 oos.writeObject(field.getName()); 1447 oos.writeObject(value); 1448 } 1449 } 1450 } 1451