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.number; 5 6 import java.math.RoundingMode; 7 8 import ohos.global.icu.impl.number.MacroProps; 9 import ohos.global.icu.impl.number.Padder; 10 import ohos.global.icu.number.NumberFormatter.DecimalSeparatorDisplay; 11 import ohos.global.icu.number.NumberFormatter.GroupingStrategy; 12 import ohos.global.icu.number.NumberFormatter.SignDisplay; 13 import ohos.global.icu.number.NumberFormatter.UnitWidth; 14 import ohos.global.icu.text.DecimalFormatSymbols; 15 import ohos.global.icu.text.NumberingSystem; 16 import ohos.global.icu.util.Currency; 17 import ohos.global.icu.util.Measure; 18 import ohos.global.icu.util.MeasureUnit; 19 import ohos.global.icu.util.NoUnit; 20 import ohos.global.icu.util.ULocale; 21 22 /** 23 * An abstract base class for specifying settings related to number formatting. This class is implemented 24 * by {@link UnlocalizedNumberFormatter} and {@link LocalizedNumberFormatter}. This class is not intended 25 * for public subclassing. 26 * 27 * @see NumberFormatter 28 * @hide exposed on OHOS 29 */ 30 public abstract class NumberFormatterSettings<T extends NumberFormatterSettings<?>> { 31 32 static final int KEY_MACROS = 0; 33 static final int KEY_LOCALE = 1; 34 static final int KEY_NOTATION = 2; 35 static final int KEY_UNIT = 3; 36 static final int KEY_PRECISION = 4; 37 static final int KEY_ROUNDING_MODE = 5; 38 static final int KEY_GROUPING = 6; 39 static final int KEY_PADDER = 7; 40 static final int KEY_INTEGER = 8; 41 static final int KEY_SYMBOLS = 9; 42 static final int KEY_UNIT_WIDTH = 10; 43 static final int KEY_SIGN = 11; 44 static final int KEY_DECIMAL = 12; 45 static final int KEY_SCALE = 13; 46 static final int KEY_THRESHOLD = 14; 47 static final int KEY_PER_UNIT = 15; 48 static final int KEY_MAX = 16; 49 50 private final NumberFormatterSettings<?> parent; 51 private final int key; 52 private final Object value; 53 private volatile MacroProps resolvedMacros; 54 NumberFormatterSettings(NumberFormatterSettings<?> parent, int key, Object value)55 NumberFormatterSettings(NumberFormatterSettings<?> parent, int key, Object value) { 56 this.parent = parent; 57 this.key = key; 58 this.value = value; 59 } 60 61 /** 62 * Specifies the notation style (simple, scientific, or compact) for rendering numbers. 63 * 64 * <ul> 65 * <li>Simple notation: "12,300" 66 * <li>Scientific notation: "1.23E4" 67 * <li>Compact notation: "12K" 68 * </ul> 69 * 70 * <p> 71 * All notation styles will be properly localized with locale data, and all notation styles are 72 * compatible with units, rounding strategies, and other number formatter settings. 73 * 74 * <p> 75 * Pass this method the return value of a {@link Notation} factory method. For example: 76 * 77 * <pre> 78 * NumberFormatter.with().notation(Notation.compactShort()) 79 * </pre> 80 * 81 * The default is to use simple notation. 82 * 83 * @param notation 84 * The notation strategy to use. 85 * @return The fluent chain. 86 * @see Notation 87 */ notation(Notation notation)88 public T notation(Notation notation) { 89 return create(KEY_NOTATION, notation); 90 } 91 92 /** 93 * Specifies the unit (unit of measure, currency, or percent) to associate with rendered numbers. 94 * 95 * <ul> 96 * <li>Unit of measure: "12.3 meters" 97 * <li>Currency: "$12.30" 98 * <li>Percent: "12.3%" 99 * </ul> 100 * 101 * <p> 102 * <strong>Note:</strong> The unit can also be specified by passing a {@link Measure} to 103 * {@link LocalizedNumberFormatter#format(Measure)}. Units specified via the format method take 104 * precedence over units specified here. This setter is designed for situations when the unit is 105 * constant for the duration of the number formatting process. 106 * 107 * <p> 108 * All units will be properly localized with locale data, and all units are compatible with notation 109 * styles, rounding strategies, and other number formatter settings. 110 * 111 * <p> 112 * Pass this method any instance of {@link MeasureUnit}. For units of measure: 113 * 114 * <pre> 115 * NumberFormatter.with().unit(MeasureUnit.METER) 116 * </pre> 117 * 118 * Currency: 119 * 120 * <pre> 121 * NumberFormatter.with().unit(Currency.getInstance("USD")) 122 * </pre> 123 * 124 * Percent: 125 * 126 * <pre> 127 * NumberFormatter.with().unit(NoUnit.PERCENT) 128 * </pre> 129 * 130 * <p> 131 * See {@link #perUnit} for information on how to format strings like "5 meters per second". 132 * 133 * <p> 134 * The default is to render without units (equivalent to {@link NoUnit#BASE}). 135 * 136 * @param unit 137 * The unit to render. 138 * @return The fluent chain. 139 * @see MeasureUnit 140 * @see Currency 141 * @see NoUnit 142 * @see #perUnit 143 */ unit(MeasureUnit unit)144 public T unit(MeasureUnit unit) { 145 return create(KEY_UNIT, unit); 146 } 147 148 /** 149 * Sets a unit to be used in the denominator. For example, to format "3 m/s", pass METER to the unit 150 * and SECOND to the perUnit. 151 * 152 * <p> 153 * Pass this method any instance of {@link MeasureUnit}. For example: 154 * 155 * <pre> 156 * NumberFormatter.with().unit(MeasureUnit.METER).perUnit(MeasureUnit.SECOND) 157 * </pre> 158 * 159 * <p> 160 * The default is not to display any unit in the denominator. 161 * 162 * <p> 163 * If a per-unit is specified without a primary unit via {@link #unit}, the behavior is undefined. 164 * 165 * @param perUnit 166 * The unit to render in the denominator. 167 * @return The fluent chain 168 * @see #unit 169 */ perUnit(MeasureUnit perUnit)170 public T perUnit(MeasureUnit perUnit) { 171 return create(KEY_PER_UNIT, perUnit); 172 } 173 174 /** 175 * Specifies the rounding precision to use when formatting numbers. 176 * 177 * <ul> 178 * <li>Round to 3 decimal places: "3.142" 179 * <li>Round to 3 significant figures: "3.14" 180 * <li>Round to the closest nickel: "3.15" 181 * <li>Do not perform rounding: "3.1415926..." 182 * </ul> 183 * 184 * <p> 185 * Pass this method the return value of one of the factory methods on {@link Precision}. For example: 186 * 187 * <pre> 188 * NumberFormatter.with().precision(Precision.fixedFraction(2)) 189 * </pre> 190 * 191 * <p> 192 * In most cases, the default rounding precision is to round to 6 fraction places; i.e., 193 * <code>Precision.maxFraction(6)</code>. The exceptions are if compact notation is being used, then 194 * the compact notation rounding precision is used (see {@link Notation#compactShort} for details), or 195 * if the unit is a currency, then standard currency rounding is used, which varies from currency to 196 * currency (see {@link Precision#currency} for details). 197 * 198 * @param precision 199 * The rounding precision to use. 200 * @return The fluent chain. 201 * @see Precision 202 */ precision(Precision precision)203 public T precision(Precision precision) { 204 return create(KEY_PRECISION, precision); 205 } 206 207 /** 208 * Specifies how to determine the direction to round a number when it has more digits than fit in the 209 * desired precision. When formatting 1.235: 210 * 211 * <ul> 212 * <li>Ceiling rounding mode with integer precision: "2" 213 * <li>Half-down rounding mode with 2 fixed fraction digits: "1.23" 214 * <li>Half-up rounding mode with 2 fixed fraction digits: "1.24" 215 * </ul> 216 * 217 * The default is HALF_EVEN. For more information on rounding mode, see the ICU userguide here: 218 * 219 * http://userguide.icu-project.org/formatparse/numbers/rounding-modes 220 * 221 * @param roundingMode 222 * The rounding mode to use. 223 * @return The fluent chain. 224 * @see Precision 225 */ roundingMode(RoundingMode roundingMode)226 public T roundingMode(RoundingMode roundingMode) { 227 return create(KEY_ROUNDING_MODE, roundingMode); 228 } 229 230 /** 231 * Specifies the grouping strategy to use when formatting numbers. 232 * 233 * <ul> 234 * <li>Default grouping: "12,300" and "1,230" 235 * <li>Grouping with at least 2 digits: "12,300" and "1230" 236 * <li>No grouping: "12300" and "1230" 237 * </ul> 238 * 239 * <p> 240 * The exact grouping widths will be chosen based on the locale. 241 * 242 * <p> 243 * Pass this method an element from the {@link GroupingStrategy} enum. For example: 244 * 245 * <pre> 246 * NumberFormatter.with().grouping(GroupingStrategy.MIN2) 247 * </pre> 248 * 249 * The default is to perform grouping according to locale data; most locales, but not all locales, 250 * enable it by default. 251 * 252 * @param strategy 253 * The grouping strategy to use. 254 * @return The fluent chain. 255 * @see GroupingStrategy 256 */ grouping(GroupingStrategy strategy)257 public T grouping(GroupingStrategy strategy) { 258 return create(KEY_GROUPING, strategy); 259 } 260 261 /** 262 * Specifies the minimum and maximum number of digits to render before the decimal mark. 263 * 264 * <ul> 265 * <li>Zero minimum integer digits: ".08" 266 * <li>One minimum integer digit: "0.08" 267 * <li>Two minimum integer digits: "00.08" 268 * </ul> 269 * 270 * <p> 271 * Pass this method the return value of {@link IntegerWidth#zeroFillTo(int)}. For example: 272 * 273 * <pre> 274 * NumberFormatter.with().integerWidth(IntegerWidth.zeroFillTo(2)) 275 * </pre> 276 * 277 * The default is to have one minimum integer digit. 278 * 279 * @param style 280 * The integer width to use. 281 * @return The fluent chain. 282 * @see IntegerWidth 283 */ integerWidth(IntegerWidth style)284 public T integerWidth(IntegerWidth style) { 285 return create(KEY_INTEGER, style); 286 } 287 288 /** 289 * Specifies the symbols (decimal separator, grouping separator, percent sign, numerals, etc.) to use 290 * when rendering numbers. 291 * 292 * <ul> 293 * <li><em>en_US</em> symbols: "12,345.67" 294 * <li><em>fr_FR</em> symbols: "12 345,67" 295 * <li><em>de_CH</em> symbols: "12’345.67" 296 * <li><em>my_MY</em> symbols: "၁၂,၃၄၅.၆၇" 297 * </ul> 298 * 299 * <p> 300 * Pass this method an instance of {@link DecimalFormatSymbols}. For example: 301 * 302 * <pre> 303 * NumberFormatter.with().symbols(DecimalFormatSymbols.getInstance(new ULocale("de_CH"))) 304 * </pre> 305 * 306 * <p> 307 * <strong>Note:</strong> DecimalFormatSymbols automatically chooses the best numbering system based 308 * on the locale. In the examples above, the first three are using the Latin numbering system, and 309 * the fourth is using the Myanmar numbering system. 310 * 311 * <p> 312 * <strong>Note:</strong> The instance of DecimalFormatSymbols will be copied: changes made to the 313 * symbols object after passing it into the fluent chain will not be seen. 314 * 315 * <p> 316 * <strong>Note:</strong> Calling this method will override the NumberingSystem previously specified 317 * in {@link #symbols(NumberingSystem)}. 318 * 319 * <p> 320 * The default is to choose the symbols based on the locale specified in the fluent chain. 321 * 322 * @param symbols 323 * The DecimalFormatSymbols to use. 324 * @return The fluent chain. 325 * @see DecimalFormatSymbols 326 */ symbols(DecimalFormatSymbols symbols)327 public T symbols(DecimalFormatSymbols symbols) { 328 symbols = (DecimalFormatSymbols) symbols.clone(); 329 return create(KEY_SYMBOLS, symbols); 330 } 331 332 /** 333 * Specifies that the given numbering system should be used when fetching symbols. 334 * 335 * <ul> 336 * <li>Latin numbering system: "12,345" 337 * <li>Myanmar numbering system: "၁၂,၃၄၅" 338 * <li>Math Sans Bold numbering system: "," 339 * </ul> 340 * 341 * <p> 342 * Pass this method an instance of {@link NumberingSystem}. For example, to force the locale to 343 * always use the Latin alphabet numbering system (ASCII digits): 344 * 345 * <pre> 346 * NumberFormatter.with().symbols(NumberingSystem.LATIN) 347 * </pre> 348 * 349 * <p> 350 * <strong>Note:</strong> Calling this method will override the DecimalFormatSymbols previously 351 * specified in {@link #symbols(DecimalFormatSymbols)}. 352 * 353 * <p> 354 * The default is to choose the best numbering system for the locale. 355 * 356 * @param ns 357 * The NumberingSystem to use. 358 * @return The fluent chain. 359 * @see NumberingSystem 360 */ symbols(NumberingSystem ns)361 public T symbols(NumberingSystem ns) { 362 return create(KEY_SYMBOLS, ns); 363 } 364 365 /** 366 * Sets the width of the unit (measure unit or currency). Most common values: 367 * 368 * <ul> 369 * <li>Short: "$12.00", "12 m" 370 * <li>ISO Code: "USD 12.00" 371 * <li>Full name: "12.00 US dollars", "12 meters" 372 * </ul> 373 * 374 * <p> 375 * Pass an element from the {@link UnitWidth} enum to this setter. For example: 376 * 377 * <pre> 378 * NumberFormatter.with().unitWidth(UnitWidth.FULL_NAME) 379 * </pre> 380 * 381 * <p> 382 * The default is the SHORT width. 383 * 384 * @param style 385 * The width to use when rendering numbers. 386 * @return The fluent chain 387 * @see UnitWidth 388 */ unitWidth(UnitWidth style)389 public T unitWidth(UnitWidth style) { 390 return create(KEY_UNIT_WIDTH, style); 391 } 392 393 /** 394 * Sets the plus/minus sign display strategy. Most common values: 395 * 396 * <ul> 397 * <li>Auto: "123", "-123" 398 * <li>Always: "+123", "-123" 399 * <li>Accounting: "$123", "($123)" 400 * </ul> 401 * 402 * <p> 403 * Pass an element from the {@link SignDisplay} enum to this setter. For example: 404 * 405 * <pre> 406 * NumberFormatter.with().sign(SignDisplay.ALWAYS) 407 * </pre> 408 * 409 * <p> 410 * The default is AUTO sign display. 411 * 412 * @param style 413 * The sign display strategy to use when rendering numbers. 414 * @return The fluent chain 415 * @see SignDisplay 416 */ sign(SignDisplay style)417 public T sign(SignDisplay style) { 418 return create(KEY_SIGN, style); 419 } 420 421 /** 422 * Sets the decimal separator display strategy. This affects integer numbers with no fraction part. 423 * Most common values: 424 * 425 * <ul> 426 * <li>Auto: "1" 427 * <li>Always: "1." 428 * </ul> 429 * 430 * <p> 431 * Pass an element from the {@link DecimalSeparatorDisplay} enum to this setter. For example: 432 * 433 * <pre> 434 * NumberFormatter.with().decimal(DecimalSeparatorDisplay.ALWAYS) 435 * </pre> 436 * 437 * <p> 438 * The default is AUTO decimal separator display. 439 * 440 * @param style 441 * The decimal separator display strategy to use when rendering numbers. 442 * @return The fluent chain 443 * @see DecimalSeparatorDisplay 444 */ decimal(DecimalSeparatorDisplay style)445 public T decimal(DecimalSeparatorDisplay style) { 446 return create(KEY_DECIMAL, style); 447 } 448 449 /** 450 * Sets a scale (multiplier) to be used to scale the number by an arbitrary amount before formatting. 451 * Most common values: 452 * 453 * <ul> 454 * <li>Multiply by 100: useful for percentages. 455 * <li>Multiply by an arbitrary value: useful for unit conversions. 456 * </ul> 457 * 458 * <p> 459 * Pass an element from a {@link Scale} factory method to this setter. For example: 460 * 461 * <pre> 462 * NumberFormatter.with().scale(Scale.powerOfTen(2)) 463 * </pre> 464 * 465 * <p> 466 * The default is to not apply any multiplier. 467 * 468 * @param scale 469 * An amount to be multiplied against numbers before formatting. 470 * @return The fluent chain 471 * @see Scale 472 */ scale(Scale scale)473 public T scale(Scale scale) { 474 return create(KEY_SCALE, scale); 475 } 476 477 /** 478 * Internal method to set a starting macros. 479 * 480 * @deprecated ICU 60 This API is ICU internal only. 481 * @hide draft / provisional / internal are hidden on OHOS 482 */ 483 @Deprecated macros(MacroProps macros)484 public T macros(MacroProps macros) { 485 return create(KEY_MACROS, macros); 486 } 487 488 /** 489 * Set the padding strategy. May be added to ICU 61; see #13338. 490 * 491 * @deprecated ICU 60 This API is ICU internal only. 492 * @hide draft / provisional / internal are hidden on OHOS 493 */ 494 @Deprecated padding(Padder padder)495 public T padding(Padder padder) { 496 return create(KEY_PADDER, padder); 497 } 498 499 /** 500 * Internal fluent setter to support a custom regulation threshold. A threshold of 1 causes the data 501 * structures to be built right away. A threshold of 0 prevents the data structures from being built. 502 * 503 * @deprecated ICU 60 This API is ICU internal only. 504 * @hide draft / provisional / internal are hidden on OHOS 505 */ 506 @Deprecated threshold(Long threshold)507 public T threshold(Long threshold) { 508 return create(KEY_THRESHOLD, threshold); 509 } 510 511 /** 512 * Creates a skeleton string representation of this number formatter. A skeleton string is a 513 * locale-agnostic serialized form of a number formatter. 514 * <p> 515 * Not all options are capable of being represented in the skeleton string; for example, a 516 * DecimalFormatSymbols object. If any such option is encountered, an 517 * {@link UnsupportedOperationException} is thrown. 518 * <p> 519 * The returned skeleton is in normalized form, such that two number formatters with equivalent 520 * behavior should produce the same skeleton. 521 * 522 * @return A number skeleton string with behavior corresponding to this number formatter. 523 * @throws UnsupportedOperationException 524 * If the number formatter has an option that cannot be represented in a skeleton string. 525 */ toSkeleton()526 public String toSkeleton() { 527 return NumberSkeletonImpl.generate(resolve()); 528 } 529 create(int key, Object value)530 /* package-protected */ abstract T create(int key, Object value); 531 resolve()532 MacroProps resolve() { 533 if (resolvedMacros != null) { 534 return resolvedMacros; 535 } 536 // Although the linked-list fluent storage approach requires this method, 537 // my benchmarks show that linked-list is still faster than a full clone 538 // of a MacroProps object at each step. 539 // TODO: Remove the reference to the parent after the macros are resolved? 540 MacroProps macros = new MacroProps(); 541 NumberFormatterSettings<?> current = this; 542 while (current != null) { 543 switch (current.key) { 544 case KEY_MACROS: 545 macros.fallback((MacroProps) current.value); 546 break; 547 case KEY_LOCALE: 548 if (macros.loc == null) { 549 macros.loc = (ULocale) current.value; 550 } 551 break; 552 case KEY_NOTATION: 553 if (macros.notation == null) { 554 macros.notation = (Notation) current.value; 555 } 556 break; 557 case KEY_UNIT: 558 if (macros.unit == null) { 559 macros.unit = (MeasureUnit) current.value; 560 } 561 break; 562 case KEY_PRECISION: 563 if (macros.precision == null) { 564 macros.precision = (Precision) current.value; 565 } 566 break; 567 case KEY_ROUNDING_MODE: 568 if (macros.roundingMode == null) { 569 macros.roundingMode = (RoundingMode) current.value; 570 } 571 break; 572 case KEY_GROUPING: 573 if (macros.grouping == null) { 574 macros.grouping = /* (Object) */ current.value; 575 } 576 break; 577 case KEY_PADDER: 578 if (macros.padder == null) { 579 macros.padder = (Padder) current.value; 580 } 581 break; 582 case KEY_INTEGER: 583 if (macros.integerWidth == null) { 584 macros.integerWidth = (IntegerWidth) current.value; 585 } 586 break; 587 case KEY_SYMBOLS: 588 if (macros.symbols == null) { 589 macros.symbols = /* (Object) */ current.value; 590 } 591 break; 592 case KEY_UNIT_WIDTH: 593 if (macros.unitWidth == null) { 594 macros.unitWidth = (UnitWidth) current.value; 595 } 596 break; 597 case KEY_SIGN: 598 if (macros.sign == null) { 599 macros.sign = (SignDisplay) current.value; 600 } 601 break; 602 case KEY_DECIMAL: 603 if (macros.decimal == null) { 604 macros.decimal = (DecimalSeparatorDisplay) current.value; 605 } 606 break; 607 case KEY_SCALE: 608 if (macros.scale == null) { 609 macros.scale = (Scale) current.value; 610 } 611 break; 612 case KEY_THRESHOLD: 613 if (macros.threshold == null) { 614 macros.threshold = (Long) current.value; 615 } 616 break; 617 case KEY_PER_UNIT: 618 if (macros.perUnit == null) { 619 macros.perUnit = (MeasureUnit) current.value; 620 } 621 break; 622 default: 623 throw new AssertionError("Unknown key: " + current.key); 624 } 625 current = current.parent; 626 } 627 resolvedMacros = macros; 628 return macros; 629 } 630 631 /** 632 * {@inheritDoc} 633 */ 634 @Override hashCode()635 public int hashCode() { 636 return resolve().hashCode(); 637 } 638 639 /** 640 * {@inheritDoc} 641 */ 642 @Override equals(Object other)643 public boolean equals(Object other) { 644 if (this == other) { 645 return true; 646 } 647 if (other == null) { 648 return false; 649 } 650 if (!(other instanceof NumberFormatterSettings)) { 651 return false; 652 } 653 return resolve().equals(((NumberFormatterSettings<?>) other).resolve()); 654 } 655 } 656