• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* GENERATED SOURCE. DO NOT MODIFY. */
2 // © 2018 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 ohos.global.icu.impl.number.range.RangeMacroProps;
7 import ohos.global.icu.number.NumberRangeFormatter.RangeCollapse;
8 import ohos.global.icu.number.NumberRangeFormatter.RangeIdentityFallback;
9 import ohos.global.icu.util.ULocale;
10 
11 /**
12  * An abstract base class for specifying settings related to number formatting. This class is implemented by
13  * {@link UnlocalizedNumberRangeFormatter} and {@link LocalizedNumberRangeFormatter}. This class is not intended for
14  * public subclassing.
15  *
16  * @author sffc
17  * @see NumberRangeFormatter
18  * @hide exposed on OHOS
19  */
20 public abstract class NumberRangeFormatterSettings<T extends NumberRangeFormatterSettings<?>> {
21 
22     static final int KEY_MACROS = 0; // not used
23     static final int KEY_LOCALE = 1;
24     static final int KEY_FORMATTER_1 = 2;
25     static final int KEY_FORMATTER_2 = 3;
26     static final int KEY_SAME_FORMATTERS = 4;
27     static final int KEY_COLLAPSE = 5;
28     static final int KEY_IDENTITY_FALLBACK = 6;
29     static final int KEY_MAX = 7;
30 
31     private final NumberRangeFormatterSettings<?> parent;
32     private final int key;
33     private final Object value;
34     private volatile RangeMacroProps resolvedMacros;
35 
NumberRangeFormatterSettings(NumberRangeFormatterSettings<?> parent, int key, Object value)36     NumberRangeFormatterSettings(NumberRangeFormatterSettings<?> parent, int key, Object value) {
37         this.parent = parent;
38         this.key = key;
39         this.value = value;
40     }
41 
42     /**
43      * Sets the NumberFormatter instance to use for the numbers in the range. The same formatter is applied to both
44      * sides of the range.
45      * <p>
46      * The NumberFormatter instances must not have a locale applied yet; the locale specified on the
47      * NumberRangeFormatter will be used.
48      *
49      * @param formatter
50      *            The formatter to use for both numbers in the range.
51      * @return The fluent chain.
52      * @see NumberFormatter
53      * @see NumberRangeFormatter
54      */
55     @SuppressWarnings("unchecked")
numberFormatterBoth(UnlocalizedNumberFormatter formatter)56     public T numberFormatterBoth(UnlocalizedNumberFormatter formatter) {
57         return (T) create(KEY_SAME_FORMATTERS, true).create(KEY_FORMATTER_1, formatter);
58     }
59 
60     /**
61      * Sets the NumberFormatter instance to use for the first number in the range.
62      * <p>
63      * The NumberFormatter instance must not have a locale applied yet; the locale specified on the
64      * NumberRangeFormatter will be used.
65      *
66      * @param formatterFirst
67      *            The formatter to use for the first number in the range.
68      * @return The fluent chain.
69      * @see NumberFormatter
70      * @see NumberRangeFormatter
71      */
72     @SuppressWarnings("unchecked")
numberFormatterFirst(UnlocalizedNumberFormatter formatterFirst)73     public T numberFormatterFirst(UnlocalizedNumberFormatter formatterFirst) {
74         return (T) create(KEY_SAME_FORMATTERS, false).create(KEY_FORMATTER_1, formatterFirst);
75     }
76 
77     /**
78      * Sets the NumberFormatter instances to use for the second number in the range.
79      * <p>
80      * The NumberFormatter instance must not have a locale applied yet; the locale specified on the
81      * NumberRangeFormatter will be used.
82      *
83      * @param formatterSecond
84      *            The formatter to use for the second number in the range.
85      * @return The fluent chain.
86      * @see NumberFormatter
87      * @see NumberRangeFormatter
88      */
89     @SuppressWarnings("unchecked")
numberFormatterSecond(UnlocalizedNumberFormatter formatterSecond)90     public T numberFormatterSecond(UnlocalizedNumberFormatter formatterSecond) {
91         return (T) create(KEY_SAME_FORMATTERS, false).create(KEY_FORMATTER_2, formatterSecond);
92     }
93 
94     /**
95      * Sets the aggressiveness of "collapsing" fields across the range separator. Possible values:
96      * <ul>
97      * <li>ALL: "3-5K miles"</li>
98      * <li>UNIT: "3K - 5K miles"</li>
99      * <li>NONE: "3K miles - 5K miles"</li>
100      * <li>AUTO: usually UNIT or NONE, depending on the locale and formatter settings</li>
101      * </ul>
102      * <p>
103      * The default value is AUTO.
104      *
105      * @param collapse
106      *            The collapsing strategy to use for this range.
107      * @return The fluent chain.
108      * @see NumberRangeFormatter
109      */
collapse(RangeCollapse collapse)110     public T collapse(RangeCollapse collapse) {
111         return create(KEY_COLLAPSE, collapse);
112     }
113 
114     /**
115      * Sets the behavior when the two sides of the range are the same. This could happen if the same two numbers are
116      * passed to the formatRange function, or if different numbers are passed to the function but they become the same
117      * after rounding rules are applied. Possible values:
118      * <ul>
119      * <li>SINGLE_VALUE: "5 miles"</li>
120      * <li>APPROXIMATELY_OR_SINGLE_VALUE: "~5 miles" or "5 miles", depending on whether the number was the same before
121      * rounding was applied</li>
122      * <li>APPROXIMATELY: "~5 miles"</li>
123      * <li>RANGE: "5-5 miles" (with collapse=UNIT)</li>
124      * </ul>
125      * <p>
126      * The default value is APPROXIMATELY.
127      *
128      * @param identityFallback
129      *            The strategy to use when formatting two numbers that end up being the same.
130      * @return The fluent chain.
131      * @see NumberRangeFormatter
132      */
identityFallback(RangeIdentityFallback identityFallback)133     public T identityFallback(RangeIdentityFallback identityFallback) {
134         return create(KEY_IDENTITY_FALLBACK, identityFallback);
135     }
136 
create(int key, Object value)137     /* package-protected */ abstract T create(int key, Object value);
138 
resolve()139     RangeMacroProps resolve() {
140         if (resolvedMacros != null) {
141             return resolvedMacros;
142         }
143         // Although the linked-list fluent storage approach requires this method,
144         // my benchmarks show that linked-list is still faster than a full clone
145         // of a MacroProps object at each step.
146         // TODO: Remove the reference to the parent after the macros are resolved?
147         RangeMacroProps macros = new RangeMacroProps();
148         NumberRangeFormatterSettings<?> current = this;
149         while (current != null) {
150             switch (current.key) {
151             case KEY_MACROS:
152                 // ignored for now
153                 break;
154             case KEY_LOCALE:
155                 if (macros.loc == null) {
156                     macros.loc = (ULocale) current.value;
157                 }
158                 break;
159             case KEY_FORMATTER_1:
160                 if (macros.formatter1 == null) {
161                     macros.formatter1 = (UnlocalizedNumberFormatter) current.value;
162                 }
163                 break;
164             case KEY_FORMATTER_2:
165                 if (macros.formatter2 == null) {
166                     macros.formatter2 = (UnlocalizedNumberFormatter) current.value;
167                 }
168                 break;
169             case KEY_SAME_FORMATTERS:
170                 if (macros.sameFormatters == -1) {
171                     macros.sameFormatters = (boolean) current.value ? 1 : 0;
172                 }
173                 break;
174             case KEY_COLLAPSE:
175                 if (macros.collapse == null) {
176                     macros.collapse = (RangeCollapse) current.value;
177                 }
178                 break;
179             case KEY_IDENTITY_FALLBACK:
180                 if (macros.identityFallback == null) {
181                     macros.identityFallback = (RangeIdentityFallback) current.value;
182                 }
183                 break;
184             default:
185                 throw new AssertionError("Unknown key: " + current.key);
186             }
187             current = current.parent;
188         }
189         // Copy the locale into the children (see touchRangeLocales in C++)
190         if (macros.formatter1 != null) {
191             macros.formatter1.resolve().loc = macros.loc;
192         }
193         if (macros.formatter2 != null) {
194             macros.formatter2.resolve().loc = macros.loc;
195         }
196         resolvedMacros = macros;
197         return macros;
198     }
199 
200     /**
201      * {@inheritDoc}
202      */
203     @Override
hashCode()204     public int hashCode() {
205         return resolve().hashCode();
206     }
207 
208     /**
209      * {@inheritDoc}
210      */
211     @Override
equals(Object other)212     public boolean equals(Object other) {
213         if (this == other) {
214             return true;
215         }
216         if (other == null) {
217             return false;
218         }
219         if (!(other instanceof NumberRangeFormatterSettings)) {
220             return false;
221         }
222         return resolve().equals(((NumberRangeFormatterSettings<?>) other).resolve());
223     }
224 }
225