• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // © 2018 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 package com.ibm.icu.number;
4 
5 import java.io.IOException;
6 import java.math.BigDecimal;
7 import java.text.AttributedCharacterIterator;
8 import java.util.Arrays;
9 
10 import com.ibm.icu.impl.FormattedStringBuilder;
11 import com.ibm.icu.impl.FormattedValueStringBuilderImpl;
12 import com.ibm.icu.impl.number.DecimalQuantity;
13 import com.ibm.icu.number.NumberRangeFormatter.RangeIdentityResult;
14 import com.ibm.icu.text.ConstrainedFieldPosition;
15 import com.ibm.icu.text.FormattedValue;
16 import com.ibm.icu.text.PluralRules.IFixedDecimal;
17 import com.ibm.icu.util.ICUUncheckedIOException;
18 
19 /**
20  * The result of a number range formatting operation. This class allows the result to be exported in several data types,
21  * including a String, an AttributedCharacterIterator, and a BigDecimal.
22  *
23  * Instances of this class are immutable and thread-safe.
24  *
25  * @author sffc
26  * @stable ICU 63
27  * @see NumberRangeFormatter
28  */
29 public class FormattedNumberRange implements FormattedValue {
30     final FormattedStringBuilder string;
31     final DecimalQuantity quantity1;
32     final DecimalQuantity quantity2;
33     final RangeIdentityResult identityResult;
34 
FormattedNumberRange(FormattedStringBuilder string, DecimalQuantity quantity1, DecimalQuantity quantity2, RangeIdentityResult identityResult)35     FormattedNumberRange(FormattedStringBuilder string, DecimalQuantity quantity1, DecimalQuantity quantity2,
36             RangeIdentityResult identityResult) {
37         this.string = string;
38         this.quantity1 = quantity1;
39         this.quantity2 = quantity2;
40         this.identityResult = identityResult;
41     }
42 
43     /**
44      * {@inheritDoc}
45      *
46      * @stable ICU 63
47      */
48     @Override
toString()49     public String toString() {
50         return string.toString();
51     }
52 
53     /**
54      * {@inheritDoc}
55      *
56      * @stable ICU 63
57      */
58     @Override
appendTo(A appendable)59     public <A extends Appendable> A appendTo(A appendable) {
60         try {
61             appendable.append(string);
62         } catch (IOException e) {
63             // Throw as an unchecked exception to avoid users needing try/catch
64             throw new ICUUncheckedIOException(e);
65         }
66         return appendable;
67     }
68 
69     /**
70      * {@inheritDoc}
71      *
72      * @stable ICU 64
73      */
74     @Override
charAt(int index)75     public char charAt(int index) {
76         return string.charAt(index);
77     }
78 
79     /**
80      * {@inheritDoc}
81      *
82      * @stable ICU 64
83      */
84     @Override
length()85     public int length() {
86         return string.length();
87     }
88 
89     /**
90      * {@inheritDoc}
91      *
92      * @stable ICU 64
93      */
94     @Override
subSequence(int start, int end)95     public CharSequence subSequence(int start, int end) {
96         return string.subString(start, end);
97     }
98 
99     /**
100      * {@inheritDoc}
101      *
102      * @stable ICU 64
103      */
104     @Override
nextPosition(ConstrainedFieldPosition cfpos)105     public boolean nextPosition(ConstrainedFieldPosition cfpos) {
106         return FormattedValueStringBuilderImpl.nextPosition(string, cfpos, null);
107     }
108 
109     /**
110      * {@inheritDoc}
111      *
112      * @stable ICU 63
113      */
114     @Override
toCharacterIterator()115     public AttributedCharacterIterator toCharacterIterator() {
116         return FormattedValueStringBuilderImpl.toCharacterIterator(string, null);
117     }
118 
119     /**
120      * Export the first formatted number as a BigDecimal. This endpoint is useful for obtaining the exact number being
121      * printed after scaling and rounding have been applied by the number range formatting pipeline.
122      *
123      * @return A BigDecimal representation of the first formatted number.
124      * @stable ICU 63
125      * @see NumberRangeFormatter
126      * @see #getSecondBigDecimal
127      */
getFirstBigDecimal()128     public BigDecimal getFirstBigDecimal() {
129         return quantity1.toBigDecimal();
130     }
131 
132     /**
133      * Export the second formatted number as a BigDecimal. This endpoint is useful for obtaining the exact number being
134      * printed after scaling and rounding have been applied by the number range formatting pipeline.
135      *
136      * @return A BigDecimal representation of the second formatted number.
137      * @stable ICU 63
138      * @see NumberRangeFormatter
139      * @see #getFirstBigDecimal
140      */
getSecondBigDecimal()141     public BigDecimal getSecondBigDecimal() {
142         return quantity2.toBigDecimal();
143     }
144 
145     /**
146      * Returns whether the pair of numbers was successfully formatted as a range or whether an identity fallback was
147      * used. For example, if the first and second number were the same either before or after rounding occurred, an
148      * identity fallback was used.
149      *
150      * @return A RangeIdentityType indicating the resulting identity situation in the formatted number range.
151      * @stable ICU 63
152      * @see NumberRangeFormatter
153      * @see NumberRangeFormatter.RangeIdentityFallback
154      */
getIdentityResult()155     public RangeIdentityResult getIdentityResult() {
156         return identityResult;
157     }
158 
159     /**
160      * {@inheritDoc}
161      *
162      * @stable ICU 63
163      */
164     @Override
hashCode()165     public int hashCode() {
166         // FormattedStringBuilder and BigDecimal are mutable, so we can't call
167         // #equals() or #hashCode() on them directly.
168         return Arrays.hashCode(string.toCharArray()) ^ Arrays.hashCode(string.toFieldArray())
169                 ^ quantity1.toBigDecimal().hashCode() ^ quantity2.toBigDecimal().hashCode();
170     }
171 
172     /**
173      * {@inheritDoc}
174      *
175      * @stable ICU 63
176      */
177     @Override
equals(Object other)178     public boolean equals(Object other) {
179         if (this == other)
180             return true;
181         if (other == null)
182             return false;
183         if (!(other instanceof FormattedNumberRange))
184             return false;
185         // FormattedStringBuilder and BigDecimal are mutable, so we can't call
186         // #equals() or #hashCode() on them directly.
187         FormattedNumberRange _other = (FormattedNumberRange) other;
188         return string.contentEquals(_other.string)
189                 && quantity1.toBigDecimal().equals(_other.quantity1.toBigDecimal())
190                 && quantity2.toBigDecimal().equals(_other.quantity2.toBigDecimal());
191     }
192 
193     /**
194      * @internal
195      * @deprecated This API is ICU internal only.
196      */
197     @Deprecated
getFirstFixedDecimal()198     public IFixedDecimal getFirstFixedDecimal() {
199         return quantity1;
200     }
201 
202     /**
203      * @internal
204      * @deprecated This API is ICU internal only.
205      */
206     @Deprecated
getSecondFixedDecimal()207     public IFixedDecimal getSecondFixedDecimal() {
208         return quantity2;
209     }
210 }
211