• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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&nbsp;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