src/java.base/share/classes/java/text/CompactNumberFormat.java
author darcy
Thu, 29 Aug 2019 16:31:34 -0700
changeset 57956 e0b8b019d2f5
parent 54252 83deaa8f0c8e
child 58242 94bb65cb37d3
permissions -rw-r--r--
8229997: Apply java.io.Serial annotations in java.base Reviewed-by: alanb, rriggs
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
52869
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
     1
/*
54050
95978e7e8da0 8217254: CompactNumberFormat:: CompactNumberFormat​() constructor does not comply with spec.
nishjain
parents: 53018
diff changeset
     2
 * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
52869
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
     4
 *
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    10
 *
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    15
 * accompanied this code).
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    16
 *
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    20
 *
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    23
 * questions.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    24
 */
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    25
package java.text;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    26
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    27
import java.io.IOException;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    28
import java.io.InvalidObjectException;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    29
import java.io.ObjectInputStream;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    30
import java.math.BigDecimal;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    31
import java.math.BigInteger;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    32
import java.math.RoundingMode;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    33
import java.util.ArrayList;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    34
import java.util.Arrays;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    35
import java.util.List;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    36
import java.util.Locale;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    37
import java.util.Objects;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    38
import java.util.concurrent.atomic.AtomicInteger;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    39
import java.util.concurrent.atomic.AtomicLong;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    40
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    41
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    42
/**
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    43
 * <p>
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    44
 * {@code CompactNumberFormat} is a concrete subclass of {@code NumberFormat}
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    45
 * that formats a decimal number in its compact form.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    46
 *
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    47
 * The compact number formatting is designed for the environment where the space
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    48
 * is limited, and the formatted string can be displayed in that limited space.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    49
 * It is defined by LDML's specification for
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    50
 * <a href = "http://unicode.org/reports/tr35/tr35-numbers.html#Compact_Number_Formats">
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    51
 * Compact Number Formats</a>. A compact number formatting refers
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    52
 * to the representation of a number in a shorter form, based on the patterns
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    53
 * provided for a given locale.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    54
 *
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    55
 * <p>
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    56
 * For example:
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    57
 * <br>In the {@link java.util.Locale#US US locale}, {@code 1000} can be formatted
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    58
 * as {@code "1K"}, and {@code 1000000} as {@code "1M"}, depending upon the
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    59
 * <a href = "#compact_number_style" >style</a> used.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    60
 * <br>In the {@code "hi_IN"} locale, {@code 1000} can be formatted as
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    61
 * "1 \u0939\u091C\u093C\u093E\u0930", and {@code 50000000} as "5 \u0915.",
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    62
 * depending upon the <a href = "#compact_number_style" >style</a> used.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    63
 *
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    64
 * <p>
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    65
 * To obtain a {@code CompactNumberFormat} for a locale, use one
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    66
 * of the factory methods given by {@code NumberFormat} for compact number
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    67
 * formatting. For example,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    68
 * {@link NumberFormat#getCompactNumberInstance(Locale, Style)}.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    69
 *
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    70
 * <blockquote><pre>
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    71
 * NumberFormat fmt = NumberFormat.getCompactNumberInstance(
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    72
 *                             new Locale("hi", "IN"), NumberFormat.Style.SHORT);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    73
 * String result = fmt.format(1000);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    74
 * </pre></blockquote>
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    75
 *
54206
003cc64366da 8220249: fix headings in java.compiler
jjg
parents: 54050
diff changeset
    76
 * <h2><a id="compact_number_style">Style</a></h2>
52869
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    77
 * <p>
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    78
 * A number can be formatted in the compact forms with two different
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    79
 * styles, {@link NumberFormat.Style#SHORT SHORT}
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    80
 * and {@link NumberFormat.Style#LONG LONG}. Use
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    81
 * {@link NumberFormat#getCompactNumberInstance(Locale, Style)} for formatting and
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    82
 * parsing a number in {@link NumberFormat.Style#SHORT SHORT} or
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    83
 * {@link NumberFormat.Style#LONG LONG} compact form,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    84
 * where the given {@code Style} parameter requests the desired
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    85
 * format. A {@link NumberFormat.Style#SHORT SHORT} style
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    86
 * compact number instance in the {@link java.util.Locale#US US locale} formats
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    87
 * {@code 10000} as {@code "10K"}. However, a
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    88
 * {@link NumberFormat.Style#LONG LONG} style instance in same locale
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    89
 * formats {@code 10000} as {@code "10 thousand"}.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    90
 *
54206
003cc64366da 8220249: fix headings in java.compiler
jjg
parents: 54050
diff changeset
    91
 * <h2><a id="compact_number_patterns">Compact Number Patterns</a></h2>
52869
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    92
 * <p>
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    93
 * The compact number patterns are represented in a series of patterns where each
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    94
 * pattern is used to format a range of numbers. An example of
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    95
 * {@link NumberFormat.Style#SHORT SHORT} styled compact number patterns
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    96
 * for the {@link java.util.Locale#US US locale} is {@code {"", "", "", "0K",
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    97
 * "00K", "000K", "0M", "00M", "000M", "0B", "00B", "000B", "0T", "00T", "000T"}},
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    98
 * ranging from {@code 10}<sup>{@code 0}</sup> to {@code 10}<sup>{@code 14}</sup>.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
    99
 * There can be any number of patterns and they are
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   100
 * strictly index based starting from the range {@code 10}<sup>{@code 0}</sup>.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   101
 * For example, in the above patterns, pattern at index 3
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   102
 * ({@code "0K"}) is used for formatting {@code number >= 1000 and number < 10000},
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   103
 * pattern at index 4 ({@code "00K"}) is used for formatting
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   104
 * {@code number >= 10000 and number < 100000} and so on. In most of the locales,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   105
 * patterns with the range
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   106
 * {@code 10}<sup>{@code 0}</sup>-{@code 10}<sup>{@code 2}</sup> are empty
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   107
 * strings, which implicitly means a special pattern {@code "0"}.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   108
 * A special pattern {@code "0"} is used for any range which does not contain
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   109
 * a compact pattern. This special pattern can appear explicitly for any specific
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   110
 * range, or considered as a default pattern for an empty string.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   111
 * <p>
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   112
 * A compact pattern has the following syntax:
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   113
 * <blockquote><pre>
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   114
 * <i>Pattern:</i>
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   115
 *         <i>PositivePattern</i>
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   116
 *         <i>PositivePattern</i> <i>[; NegativePattern]<sub>optional</sub></i>
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   117
 * <i>PositivePattern:</i>
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   118
 *         <i>Prefix<sub>optional</sub></i> <i>MinimumInteger</i> <i>Suffix<sub>optional</sub></i>
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   119
 * <i>NegativePattern:</i>
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   120
 *        <i>Prefix<sub>optional</sub></i> <i>MinimumInteger</i> <i>Suffix<sub>optional</sub></i>
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   121
 * <i>Prefix:</i>
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   122
 *      Any Unicode characters except &#92;uFFFE, &#92;uFFFF, and
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   123
 *      <a href = "DecimalFormat.html#special_pattern_character">special characters</a>
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   124
 * <i>Suffix:</i>
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   125
 *      Any Unicode characters except &#92;uFFFE, &#92;uFFFF, and
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   126
 *      <a href = "DecimalFormat.html#special_pattern_character">special characters</a>
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   127
 * <i>MinimumInteger:</i>
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   128
 *      0
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   129
 *      0 <i>MinimumInteger</i>
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   130
 * </pre></blockquote>
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   131
 *
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   132
 * A compact pattern contains a positive and negative subpattern
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   133
 * separated by a subpattern boundary character {@code ';' (U+003B)},
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   134
 * for example, {@code "0K;-0K"}. Each subpattern has a prefix,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   135
 * minimum integer digits, and suffix. The negative subpattern
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   136
 * is optional, if absent, then the positive subpattern prefixed with the
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   137
 * minus sign ({@code '-' U+002D HYPHEN-MINUS}) is used as the negative
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   138
 * subpattern. That is, {@code "0K"} alone is equivalent to {@code "0K;-0K"}.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   139
 * If there is an explicit negative subpattern, it serves only to specify
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   140
 * the negative prefix and suffix. The number of minimum integer digits,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   141
 * and other characteristics are all the same as the positive pattern.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   142
 * That means that {@code "0K;-00K"} produces precisely the same behavior
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   143
 * as {@code "0K;-0K"}.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   144
 *
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   145
 * <p>
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   146
 * Many characters in a compact pattern are taken literally, they are matched
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   147
 * during parsing and output unchanged during formatting.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   148
 * <a href = "DecimalFormat.html#special_pattern_character">Special characters</a>,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   149
 * on the other hand, stand for other characters, strings, or classes of
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   150
 * characters. They must be quoted, using single quote {@code ' (U+0027)}
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   151
 * unless noted otherwise, if they are to appear in the prefix or suffix
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   152
 * as literals. For example, 0\u0915'.'.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   153
 *
54206
003cc64366da 8220249: fix headings in java.compiler
jjg
parents: 54050
diff changeset
   154
 * <h2>Formatting</h2>
52869
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   155
 * The default formatting behavior returns a formatted string with no fractional
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   156
 * digits, however users can use the {@link #setMinimumFractionDigits(int)}
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   157
 * method to include the fractional part.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   158
 * The number {@code 1000.0} or {@code 1000} is formatted as {@code "1K"}
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   159
 * not {@code "1.00K"} (in the {@link java.util.Locale#US US locale}). For this
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   160
 * reason, the patterns provided for formatting contain only the minimum
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   161
 * integer digits, prefix and/or suffix, but no fractional part.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   162
 * For example, patterns used are {@code {"", "", "", 0K, 00K, ...}}. If the pattern
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   163
 * selected for formatting a number is {@code "0"} (special pattern),
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   164
 * either explicit or defaulted, then the general number formatting provided by
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   165
 * {@link java.text.DecimalFormat DecimalFormat}
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   166
 * for the specified locale is used.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   167
 *
54206
003cc64366da 8220249: fix headings in java.compiler
jjg
parents: 54050
diff changeset
   168
 * <h2>Parsing</h2>
52869
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   169
 * The default parsing behavior does not allow a grouping separator until
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   170
 * grouping used is set to {@code true} by using
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   171
 * {@link #setGroupingUsed(boolean)}. The parsing of the fractional part
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   172
 * depends on the {@link #isParseIntegerOnly()}. For example, if the
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   173
 * parse integer only is set to true, then the fractional part is skipped.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   174
 *
54206
003cc64366da 8220249: fix headings in java.compiler
jjg
parents: 54050
diff changeset
   175
 * <h2>Rounding</h2>
52869
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   176
 * {@code CompactNumberFormat} provides rounding modes defined in
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   177
 * {@link java.math.RoundingMode} for formatting.  By default, it uses
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   178
 * {@link java.math.RoundingMode#HALF_EVEN RoundingMode.HALF_EVEN}.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   179
 *
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   180
 * @see CompactNumberFormat.Style
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   181
 * @see NumberFormat
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   182
 * @see DecimalFormat
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   183
 * @since 12
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   184
 */
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   185
public final class CompactNumberFormat extends NumberFormat {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   186
57956
e0b8b019d2f5 8229997: Apply java.io.Serial annotations in java.base
darcy
parents: 54252
diff changeset
   187
    @java.io.Serial
52869
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   188
    private static final long serialVersionUID = 7128367218649234678L;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   189
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   190
    /**
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   191
     * The patterns for compact form of numbers for this
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   192
     * {@code CompactNumberFormat}. A possible example is
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   193
     * {@code {"", "", "", "0K", "00K", "000K", "0M", "00M", "000M", "0B",
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   194
     * "00B", "000B", "0T", "00T", "000T"}} ranging from
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   195
     * {@code 10}<sup>{@code 0}</sup>-{@code 10}<sup>{@code 14}</sup>,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   196
     * where each pattern is used to format a range of numbers.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   197
     * For example, {@code "0K"} is used for formatting
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   198
     * {@code number >= 1000 and number < 10000}, {@code "00K"} is used for
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   199
     * formatting {@code number >= 10000 and number < 100000} and so on.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   200
     * This field must not be {@code null}.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   201
     *
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   202
     * @serial
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   203
     */
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   204
    private String[] compactPatterns;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   205
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   206
    /**
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   207
     * List of positive prefix patterns of this formatter's
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   208
     * compact number patterns.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   209
     */
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   210
    private transient List<String> positivePrefixPatterns;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   211
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   212
    /**
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   213
     * List of negative prefix patterns of this formatter's
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   214
     * compact number patterns.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   215
     */
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   216
    private transient List<String> negativePrefixPatterns;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   217
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   218
    /**
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   219
     * List of positive suffix patterns of this formatter's
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   220
     * compact number patterns.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   221
     */
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   222
    private transient List<String> positiveSuffixPatterns;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   223
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   224
    /**
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   225
     * List of negative suffix patterns of this formatter's
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   226
     * compact number patterns.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   227
     */
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   228
    private transient List<String> negativeSuffixPatterns;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   229
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   230
    /**
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   231
     * List of divisors of this formatter's compact number patterns.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   232
     * Divisor can be either Long or BigInteger (if the divisor value goes
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   233
     * beyond long boundary)
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   234
     */
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   235
    private transient List<Number> divisors;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   236
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   237
    /**
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   238
     * The {@code DecimalFormatSymbols} object used by this format.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   239
     * It contains the symbols used to format numbers. For example,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   240
     * the grouping separator, decimal separator, and so on.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   241
     * This field must not be {@code null}.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   242
     *
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   243
     * @serial
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   244
     * @see DecimalFormatSymbols
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   245
     */
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   246
    private DecimalFormatSymbols symbols;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   247
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   248
    /**
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   249
     * The decimal pattern which is used for formatting the numbers
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   250
     * matching special pattern "0". This field must not be {@code null}.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   251
     *
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   252
     * @serial
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   253
     * @see DecimalFormat
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   254
     */
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   255
    private final String decimalPattern;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   256
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   257
    /**
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   258
     * A {@code DecimalFormat} used by this format for getting corresponding
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   259
     * general number formatting behavior for compact numbers.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   260
     *
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   261
     */
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   262
    private transient DecimalFormat decimalFormat;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   263
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   264
    /**
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   265
     * A {@code DecimalFormat} used by this format for getting general number
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   266
     * formatting behavior for the numbers which can't be represented as compact
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   267
     * numbers. For example, number matching the special pattern "0" are
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   268
     * formatted through general number format pattern provided by
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   269
     * {@link java.text.DecimalFormat DecimalFormat}
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   270
     * for the specified locale.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   271
     *
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   272
     */
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   273
    private transient DecimalFormat defaultDecimalFormat;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   274
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   275
    /**
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   276
     * The number of digits between grouping separators in the integer portion
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   277
     * of a compact number. For the grouping to work while formatting, this
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   278
     * field needs to be greater than 0 with grouping used set as true.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   279
     * This field must not be negative.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   280
     *
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   281
     * @serial
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   282
     */
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   283
    private byte groupingSize = 0;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   284
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   285
    /**
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   286
     * Returns whether the {@link #parse(String, ParsePosition)}
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   287
     * method returns {@code BigDecimal}.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   288
     *
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   289
     * @serial
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   290
     */
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   291
    private boolean parseBigDecimal = false;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   292
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   293
    /**
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   294
     * The {@code RoundingMode} used in this compact number format.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   295
     * This field must not be {@code null}.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   296
     *
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   297
     * @serial
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   298
     */
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   299
    private RoundingMode roundingMode = RoundingMode.HALF_EVEN;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   300
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   301
    /**
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   302
     * Special pattern used for compact numbers
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   303
     */
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   304
    private static final String SPECIAL_PATTERN = "0";
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   305
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   306
    /**
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   307
     * Multiplier for compact pattern range. In
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   308
     * the list compact patterns each compact pattern
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   309
     * specify the range with the multiplication factor of 10
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   310
     * of its previous compact pattern range.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   311
     * For example, 10^0, 10^1, 10^2, 10^3, 10^4...
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   312
     *
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   313
     */
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   314
    private static final int RANGE_MULTIPLIER = 10;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   315
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   316
    /**
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   317
     * Creates a {@code CompactNumberFormat} using the given decimal pattern,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   318
     * decimal format symbols and compact patterns.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   319
     * To obtain the instance of {@code CompactNumberFormat} with the standard
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   320
     * compact patterns for a {@code Locale} and {@code Style},
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   321
     * it is recommended to use the factory methods given by
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   322
     * {@code NumberFormat} for compact number formatting. For example,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   323
     * {@link NumberFormat#getCompactNumberInstance(Locale, Style)}.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   324
     *
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   325
     * @param decimalPattern a decimal pattern for general number formatting
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   326
     * @param symbols the set of symbols to be used
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   327
     * @param compactPatterns an array of
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   328
     *        <a href = "CompactNumberFormat.html#compact_number_patterns">
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   329
     *        compact number patterns</a>
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   330
     * @throws NullPointerException if any of the given arguments is
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   331
     *                                 {@code null}
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   332
     * @throws IllegalArgumentException if the given {@code decimalPattern} or the
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   333
     *                     {@code compactPatterns} array contains an invalid pattern
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   334
     *                     or if a {@code null} appears in the array of compact
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   335
     *                     patterns
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   336
     * @see DecimalFormat#DecimalFormat(java.lang.String, DecimalFormatSymbols)
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   337
     * @see DecimalFormatSymbols
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   338
     */
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   339
    public CompactNumberFormat(String decimalPattern,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   340
            DecimalFormatSymbols symbols, String[] compactPatterns) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   341
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   342
        Objects.requireNonNull(decimalPattern, "decimalPattern");
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   343
        Objects.requireNonNull(symbols, "symbols");
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   344
        Objects.requireNonNull(compactPatterns, "compactPatterns");
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   345
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   346
        this.symbols = symbols;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   347
        // Instantiating the DecimalFormat with "0" pattern; this acts just as a
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   348
        // basic pattern; the properties (For example, prefix/suffix)
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   349
        // are later computed based on the compact number formatting process.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   350
        decimalFormat = new DecimalFormat(SPECIAL_PATTERN, this.symbols);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   351
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   352
        // Initializing the super class state with the decimalFormat values
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   353
        // to represent this CompactNumberFormat.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   354
        // For setting the digits counts, use overridden setXXX methods of this
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   355
        // CompactNumberFormat, as it performs check with the max range allowed
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   356
        // for compact number formatting
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   357
        setMaximumIntegerDigits(decimalFormat.getMaximumIntegerDigits());
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   358
        setMinimumIntegerDigits(decimalFormat.getMinimumIntegerDigits());
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   359
        setMaximumFractionDigits(decimalFormat.getMaximumFractionDigits());
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   360
        setMinimumFractionDigits(decimalFormat.getMinimumFractionDigits());
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   361
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   362
        super.setGroupingUsed(decimalFormat.isGroupingUsed());
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   363
        super.setParseIntegerOnly(decimalFormat.isParseIntegerOnly());
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   364
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   365
        this.compactPatterns = compactPatterns;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   366
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   367
        // DecimalFormat used for formatting numbers with special pattern "0".
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   368
        // Formatting is delegated to the DecimalFormat's number formatting
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   369
        // with no fraction digits
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   370
        this.decimalPattern = decimalPattern;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   371
        defaultDecimalFormat = new DecimalFormat(this.decimalPattern,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   372
                this.symbols);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   373
        defaultDecimalFormat.setMaximumFractionDigits(0);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   374
        // Process compact patterns to extract the prefixes, suffixes and
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   375
        // divisors
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   376
        processCompactPatterns();
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   377
    }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   378
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   379
    /**
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   380
     * Formats a number to produce a string representing its compact form.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   381
     * The number can be of any subclass of {@link java.lang.Number}.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   382
     * @param number     the number to format
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   383
     * @param toAppendTo the {@code StringBuffer} to which the formatted
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   384
     *                   text is to be appended
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   385
     * @param fieldPosition    keeps track on the position of the field within
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   386
     *                         the returned string. For example, for formatting
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   387
     *                         a number {@code 123456789} in the
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   388
     *                         {@link java.util.Locale#US US locale},
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   389
     *                         if the given {@code fieldPosition} is
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   390
     *                         {@link NumberFormat#INTEGER_FIELD}, the begin
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   391
     *                         index and end index of {@code fieldPosition}
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   392
     *                         will be set to 0 and 3, respectively for the
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   393
     *                         output string {@code 123M}. Similarly, positions
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   394
     *                         of the prefix and the suffix fields can be
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   395
     *                         obtained using {@link NumberFormat.Field#PREFIX}
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   396
     *                         and {@link NumberFormat.Field#SUFFIX} respectively.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   397
     * @return           the {@code StringBuffer} passed in as {@code toAppendTo}
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   398
     * @throws           IllegalArgumentException if {@code number} is
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   399
     *                   {@code null} or not an instance of {@code Number}
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   400
     * @throws           NullPointerException if {@code toAppendTo} or
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   401
     *                   {@code fieldPosition} is {@code null}
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   402
     * @throws           ArithmeticException if rounding is needed with rounding
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   403
     *                   mode being set to {@code RoundingMode.UNNECESSARY}
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   404
     * @see              FieldPosition
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   405
     */
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   406
    @Override
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   407
    public final StringBuffer format(Object number,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   408
            StringBuffer toAppendTo,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   409
            FieldPosition fieldPosition) {
54050
95978e7e8da0 8217254: CompactNumberFormat:: CompactNumberFormat​() constructor does not comply with spec.
nishjain
parents: 53018
diff changeset
   410
95978e7e8da0 8217254: CompactNumberFormat:: CompactNumberFormat​() constructor does not comply with spec.
nishjain
parents: 53018
diff changeset
   411
        if (number == null) {
95978e7e8da0 8217254: CompactNumberFormat:: CompactNumberFormat​() constructor does not comply with spec.
nishjain
parents: 53018
diff changeset
   412
            throw new IllegalArgumentException("Cannot format null as a number");
95978e7e8da0 8217254: CompactNumberFormat:: CompactNumberFormat​() constructor does not comply with spec.
nishjain
parents: 53018
diff changeset
   413
        }
95978e7e8da0 8217254: CompactNumberFormat:: CompactNumberFormat​() constructor does not comply with spec.
nishjain
parents: 53018
diff changeset
   414
52869
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   415
        if (number instanceof Long || number instanceof Integer
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   416
                || number instanceof Short || number instanceof Byte
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   417
                || number instanceof AtomicInteger
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   418
                || number instanceof AtomicLong
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   419
                || (number instanceof BigInteger
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   420
                && ((BigInteger) number).bitLength() < 64)) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   421
            return format(((Number) number).longValue(), toAppendTo,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   422
                    fieldPosition);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   423
        } else if (number instanceof BigDecimal) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   424
            return format((BigDecimal) number, toAppendTo, fieldPosition);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   425
        } else if (number instanceof BigInteger) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   426
            return format((BigInteger) number, toAppendTo, fieldPosition);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   427
        } else if (number instanceof Number) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   428
            return format(((Number) number).doubleValue(), toAppendTo, fieldPosition);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   429
        } else {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   430
            throw new IllegalArgumentException("Cannot format "
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   431
                    + number.getClass().getName() + " as a number");
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   432
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   433
    }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   434
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   435
    /**
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   436
     * Formats a double to produce a string representing its compact form.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   437
     * @param number    the double number to format
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   438
     * @param result    where the text is to be appended
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   439
     * @param fieldPosition    keeps track on the position of the field within
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   440
     *                         the returned string. For example, to format
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   441
     *                         a number {@code 1234567.89} in the
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   442
     *                         {@link java.util.Locale#US US locale}
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   443
     *                         if the given {@code fieldPosition} is
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   444
     *                         {@link NumberFormat#INTEGER_FIELD}, the begin
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   445
     *                         index and end index of {@code fieldPosition}
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   446
     *                         will be set to 0 and 1, respectively for the
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   447
     *                         output string {@code 1M}. Similarly, positions
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   448
     *                         of the prefix and the suffix fields can be
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   449
     *                         obtained using {@link NumberFormat.Field#PREFIX}
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   450
     *                         and {@link NumberFormat.Field#SUFFIX} respectively.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   451
     * @return    the {@code StringBuffer} passed in as {@code result}
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   452
     * @throws NullPointerException if {@code result} or
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   453
     *            {@code fieldPosition} is {@code null}
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   454
     * @throws ArithmeticException if rounding is needed with rounding
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   455
     *            mode being set to {@code RoundingMode.UNNECESSARY}
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   456
     * @see FieldPosition
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   457
     */
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   458
    @Override
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   459
    public StringBuffer format(double number, StringBuffer result,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   460
            FieldPosition fieldPosition) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   461
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   462
        fieldPosition.setBeginIndex(0);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   463
        fieldPosition.setEndIndex(0);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   464
        return format(number, result, fieldPosition.getFieldDelegate());
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   465
    }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   466
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   467
    private StringBuffer format(double number, StringBuffer result,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   468
            FieldDelegate delegate) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   469
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   470
        boolean nanOrInfinity = decimalFormat.handleNaN(number, result, delegate);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   471
        if (nanOrInfinity) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   472
            return result;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   473
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   474
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   475
        boolean isNegative = ((number < 0.0)
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   476
                || (number == 0.0 && 1 / number < 0.0));
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   477
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   478
        nanOrInfinity = decimalFormat.handleInfinity(number, result, delegate, isNegative);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   479
        if (nanOrInfinity) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   480
            return result;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   481
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   482
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   483
        // Round the double value with min fraction digits, the integer
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   484
        // part of the rounded value is used for matching the compact
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   485
        // number pattern
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   486
        // For example, if roundingMode is HALF_UP with min fraction
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   487
        // digits = 0, the number 999.6 should round up
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   488
        // to 1000 and outputs 1K/thousand in "en_US" locale
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   489
        DigitList dList = new DigitList();
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   490
        dList.setRoundingMode(getRoundingMode());
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   491
        number = isNegative ? -number : number;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   492
        dList.set(isNegative, number, getMinimumFractionDigits());
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   493
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   494
        double roundedNumber = dList.getDouble();
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   495
        int compactDataIndex = selectCompactPattern((long) roundedNumber);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   496
        if (compactDataIndex != -1) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   497
            String prefix = isNegative ? negativePrefixPatterns.get(compactDataIndex)
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   498
                    : positivePrefixPatterns.get(compactDataIndex);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   499
            String suffix = isNegative ? negativeSuffixPatterns.get(compactDataIndex)
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   500
                    : positiveSuffixPatterns.get(compactDataIndex);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   501
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   502
            if (!prefix.isEmpty() || !suffix.isEmpty()) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   503
                appendPrefix(result, prefix, delegate);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   504
                long divisor = (Long) divisors.get(compactDataIndex);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   505
                roundedNumber = roundedNumber / divisor;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   506
                decimalFormat.setDigitList(roundedNumber, isNegative, getMaximumFractionDigits());
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   507
                decimalFormat.subformatNumber(result, delegate, isNegative,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   508
                        false, getMaximumIntegerDigits(), getMinimumIntegerDigits(),
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   509
                        getMaximumFractionDigits(), getMinimumFractionDigits());
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   510
                appendSuffix(result, suffix, delegate);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   511
            } else {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   512
                defaultDecimalFormat.doubleSubformat(number, result, delegate, isNegative);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   513
            }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   514
        } else {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   515
            defaultDecimalFormat.doubleSubformat(number, result, delegate, isNegative);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   516
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   517
        return result;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   518
    }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   519
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   520
    /**
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   521
     * Formats a long to produce a string representing its compact form.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   522
     * @param number    the long number to format
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   523
     * @param result    where the text is to be appended
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   524
     * @param fieldPosition    keeps track on the position of the field within
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   525
     *                         the returned string. For example, to format
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   526
     *                         a number {@code 123456789} in the
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   527
     *                         {@link java.util.Locale#US US locale},
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   528
     *                         if the given {@code fieldPosition} is
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   529
     *                         {@link NumberFormat#INTEGER_FIELD}, the begin
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   530
     *                         index and end index of {@code fieldPosition}
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   531
     *                         will be set to 0 and 3, respectively for the
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   532
     *                         output string {@code 123M}. Similarly, positions
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   533
     *                         of the prefix and the suffix fields can be
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   534
     *                         obtained using {@link NumberFormat.Field#PREFIX}
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   535
     *                         and {@link NumberFormat.Field#SUFFIX} respectively.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   536
     * @return       the {@code StringBuffer} passed in as {@code result}
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   537
     * @throws       NullPointerException if {@code result} or
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   538
     *               {@code fieldPosition} is {@code null}
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   539
     * @throws       ArithmeticException if rounding is needed with rounding
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   540
     *               mode being set to {@code RoundingMode.UNNECESSARY}
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   541
     * @see FieldPosition
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   542
     */
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   543
    @Override
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   544
    public StringBuffer format(long number, StringBuffer result,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   545
            FieldPosition fieldPosition) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   546
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   547
        fieldPosition.setBeginIndex(0);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   548
        fieldPosition.setEndIndex(0);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   549
        return format(number, result, fieldPosition.getFieldDelegate());
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   550
    }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   551
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   552
    private StringBuffer format(long number, StringBuffer result, FieldDelegate delegate) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   553
        boolean isNegative = (number < 0);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   554
        if (isNegative) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   555
            number = -number;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   556
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   557
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   558
        if (number < 0) { // LONG_MIN
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   559
            BigInteger bigIntegerValue = BigInteger.valueOf(number);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   560
            return format(bigIntegerValue, result, delegate, true);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   561
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   562
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   563
        int compactDataIndex = selectCompactPattern(number);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   564
        if (compactDataIndex != -1) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   565
            String prefix = isNegative ? negativePrefixPatterns.get(compactDataIndex)
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   566
                    : positivePrefixPatterns.get(compactDataIndex);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   567
            String suffix = isNegative ? negativeSuffixPatterns.get(compactDataIndex)
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   568
                    : positiveSuffixPatterns.get(compactDataIndex);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   569
            if (!prefix.isEmpty() || !suffix.isEmpty()) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   570
                appendPrefix(result, prefix, delegate);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   571
                long divisor = (Long) divisors.get(compactDataIndex);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   572
                if ((number % divisor == 0)) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   573
                    number = number / divisor;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   574
                    decimalFormat.setDigitList(number, isNegative, 0);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   575
                    decimalFormat.subformatNumber(result, delegate,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   576
                            isNegative, true, getMaximumIntegerDigits(),
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   577
                            getMinimumIntegerDigits(), getMaximumFractionDigits(),
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   578
                            getMinimumFractionDigits());
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   579
                } else {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   580
                    // To avoid truncation of fractional part store
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   581
                    // the value in double and follow double path instead of
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   582
                    // long path
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   583
                    double dNumber = (double) number / divisor;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   584
                    decimalFormat.setDigitList(dNumber, isNegative, getMaximumFractionDigits());
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   585
                    decimalFormat.subformatNumber(result, delegate,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   586
                            isNegative, false, getMaximumIntegerDigits(),
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   587
                            getMinimumIntegerDigits(), getMaximumFractionDigits(),
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   588
                            getMinimumFractionDigits());
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   589
                }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   590
                appendSuffix(result, suffix, delegate);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   591
            } else {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   592
                number = isNegative ? -number : number;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   593
                defaultDecimalFormat.format(number, result, delegate);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   594
            }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   595
        } else {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   596
            number = isNegative ? -number : number;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   597
            defaultDecimalFormat.format(number, result, delegate);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   598
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   599
        return result;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   600
    }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   601
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   602
    /**
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   603
     * Formats a BigDecimal to produce a string representing its compact form.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   604
     * @param number    the BigDecimal number to format
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   605
     * @param result    where the text is to be appended
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   606
     * @param fieldPosition    keeps track on the position of the field within
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   607
     *                         the returned string. For example, to format
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   608
     *                         a number {@code 1234567.89} in the
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   609
     *                         {@link java.util.Locale#US US locale},
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   610
     *                         if the given {@code fieldPosition} is
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   611
     *                         {@link NumberFormat#INTEGER_FIELD}, the begin
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   612
     *                         index and end index of {@code fieldPosition}
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   613
     *                         will be set to 0 and 1, respectively for the
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   614
     *                         output string {@code 1M}. Similarly, positions
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   615
     *                         of the prefix and the suffix fields can be
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   616
     *                         obtained using {@link NumberFormat.Field#PREFIX}
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   617
     *                         and {@link NumberFormat.Field#SUFFIX} respectively.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   618
     * @return        the {@code StringBuffer} passed in as {@code result}
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   619
     * @throws        ArithmeticException if rounding is needed with rounding
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   620
     *                mode being set to {@code RoundingMode.UNNECESSARY}
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   621
     * @throws        NullPointerException if any of the given parameter
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   622
     *                is {@code null}
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   623
     * @see FieldPosition
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   624
     */
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   625
    private StringBuffer format(BigDecimal number, StringBuffer result,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   626
            FieldPosition fieldPosition) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   627
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   628
        Objects.requireNonNull(number);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   629
        fieldPosition.setBeginIndex(0);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   630
        fieldPosition.setEndIndex(0);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   631
        return format(number, result, fieldPosition.getFieldDelegate());
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   632
    }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   633
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   634
    private StringBuffer format(BigDecimal number, StringBuffer result,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   635
            FieldDelegate delegate) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   636
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   637
        boolean isNegative = number.signum() == -1;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   638
        if (isNegative) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   639
            number = number.negate();
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   640
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   641
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   642
        // Round the value with min fraction digits, the integer
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   643
        // part of the rounded value is used for matching the compact
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   644
        // number pattern
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   645
        // For example, If roundingMode is HALF_UP with min fraction digits = 0,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   646
        // the number 999.6 should round up
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   647
        // to 1000 and outputs 1K/thousand in "en_US" locale
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   648
        number = number.setScale(getMinimumFractionDigits(), getRoundingMode());
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   649
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   650
        int compactDataIndex;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   651
        if (number.toBigInteger().bitLength() < 64) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   652
            compactDataIndex = selectCompactPattern(number.toBigInteger().longValue());
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   653
        } else {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   654
            compactDataIndex = selectCompactPattern(number.toBigInteger());
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   655
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   656
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   657
        if (compactDataIndex != -1) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   658
            String prefix = isNegative ? negativePrefixPatterns.get(compactDataIndex)
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   659
                    : positivePrefixPatterns.get(compactDataIndex);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   660
            String suffix = isNegative ? negativeSuffixPatterns.get(compactDataIndex)
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   661
                    : positiveSuffixPatterns.get(compactDataIndex);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   662
            if (!prefix.isEmpty() || !suffix.isEmpty()) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   663
                appendPrefix(result, prefix, delegate);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   664
                Number divisor = divisors.get(compactDataIndex);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   665
                number = number.divide(new BigDecimal(divisor.toString()), getRoundingMode());
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   666
                decimalFormat.setDigitList(number, isNegative, getMaximumFractionDigits());
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   667
                decimalFormat.subformatNumber(result, delegate, isNegative,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   668
                        false, getMaximumIntegerDigits(), getMinimumIntegerDigits(),
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   669
                        getMaximumFractionDigits(), getMinimumFractionDigits());
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   670
                appendSuffix(result, suffix, delegate);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   671
            } else {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   672
                number = isNegative ? number.negate() : number;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   673
                defaultDecimalFormat.format(number, result, delegate);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   674
            }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   675
        } else {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   676
            number = isNegative ? number.negate() : number;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   677
            defaultDecimalFormat.format(number, result, delegate);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   678
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   679
        return result;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   680
    }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   681
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   682
    /**
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   683
     * Formats a BigInteger to produce a string representing its compact form.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   684
     * @param number    the BigInteger number to format
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   685
     * @param result    where the text is to be appended
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   686
     * @param fieldPosition    keeps track on the position of the field within
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   687
     *                         the returned string. For example, to format
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   688
     *                         a number {@code 123456789} in the
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   689
     *                         {@link java.util.Locale#US US locale},
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   690
     *                         if the given {@code fieldPosition} is
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   691
     *                         {@link NumberFormat#INTEGER_FIELD}, the begin index
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   692
     *                         and end index of {@code fieldPosition} will be set
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   693
     *                         to 0 and 3, respectively for the output string
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   694
     *                         {@code 123M}. Similarly, positions of the
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   695
     *                         prefix and the suffix fields can be obtained
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   696
     *                         using {@link NumberFormat.Field#PREFIX} and
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   697
     *                         {@link NumberFormat.Field#SUFFIX} respectively.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   698
     * @return        the {@code StringBuffer} passed in as {@code result}
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   699
     * @throws        ArithmeticException if rounding is needed with rounding
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   700
     *                mode being set to {@code RoundingMode.UNNECESSARY}
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   701
     * @throws        NullPointerException if any of the given parameter
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   702
     *                is {@code null}
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   703
     * @see FieldPosition
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   704
     */
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   705
    private StringBuffer format(BigInteger number, StringBuffer result,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   706
            FieldPosition fieldPosition) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   707
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   708
        Objects.requireNonNull(number);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   709
        fieldPosition.setBeginIndex(0);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   710
        fieldPosition.setEndIndex(0);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   711
        return format(number, result, fieldPosition.getFieldDelegate(), false);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   712
    }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   713
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   714
    private StringBuffer format(BigInteger number, StringBuffer result,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   715
            FieldDelegate delegate, boolean formatLong) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   716
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   717
        boolean isNegative = number.signum() == -1;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   718
        if (isNegative) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   719
            number = number.negate();
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   720
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   721
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   722
        int compactDataIndex = selectCompactPattern(number);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   723
        if (compactDataIndex != -1) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   724
            String prefix = isNegative ? negativePrefixPatterns.get(compactDataIndex)
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   725
                    : positivePrefixPatterns.get(compactDataIndex);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   726
            String suffix = isNegative ? negativeSuffixPatterns.get(compactDataIndex)
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   727
                    : positiveSuffixPatterns.get(compactDataIndex);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   728
            if (!prefix.isEmpty() || !suffix.isEmpty()) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   729
                appendPrefix(result, prefix, delegate);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   730
                Number divisor = divisors.get(compactDataIndex);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   731
                if (number.mod(new BigInteger(divisor.toString()))
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   732
                        .compareTo(BigInteger.ZERO) == 0) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   733
                    number = number.divide(new BigInteger(divisor.toString()));
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   734
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   735
                    decimalFormat.setDigitList(number, isNegative, 0);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   736
                    decimalFormat.subformatNumber(result, delegate,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   737
                            isNegative, true, getMaximumIntegerDigits(),
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   738
                            getMinimumIntegerDigits(), getMaximumFractionDigits(),
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   739
                            getMinimumFractionDigits());
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   740
                } else {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   741
                    // To avoid truncation of fractional part store the value in
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   742
                    // BigDecimal and follow BigDecimal path instead of
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   743
                    // BigInteger path
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   744
                    BigDecimal nDecimal = new BigDecimal(number)
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   745
                            .divide(new BigDecimal(divisor.toString()), getRoundingMode());
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   746
                    decimalFormat.setDigitList(nDecimal, isNegative, getMaximumFractionDigits());
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   747
                    decimalFormat.subformatNumber(result, delegate,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   748
                            isNegative, false, getMaximumIntegerDigits(),
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   749
                            getMinimumIntegerDigits(), getMaximumFractionDigits(),
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   750
                            getMinimumFractionDigits());
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   751
                }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   752
                appendSuffix(result, suffix, delegate);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   753
            } else {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   754
                number = isNegative ? number.negate() : number;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   755
                defaultDecimalFormat.format(number, result, delegate, formatLong);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   756
            }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   757
        } else {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   758
            number = isNegative ? number.negate() : number;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   759
            defaultDecimalFormat.format(number, result, delegate, formatLong);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   760
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   761
        return result;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   762
    }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   763
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   764
    /**
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   765
     * Appends the {@code prefix} to the {@code result} and also set the
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   766
     * {@code NumberFormat.Field.SIGN} and {@code NumberFormat.Field.PREFIX}
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   767
     * field positions.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   768
     * @param result the resulting string, where the pefix is to be appended
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   769
     * @param prefix prefix to append
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   770
     * @param delegate notified of the locations of
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   771
     *                 {@code NumberFormat.Field.SIGN} and
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   772
     *                 {@code NumberFormat.Field.PREFIX} fields
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   773
     */
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   774
    private void appendPrefix(StringBuffer result, String prefix,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   775
            FieldDelegate delegate) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   776
        append(result, expandAffix(prefix), delegate,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   777
                getFieldPositions(prefix, NumberFormat.Field.PREFIX));
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   778
    }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   779
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   780
    /**
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   781
     * Appends {@code suffix} to the {@code result} and also set the
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   782
     * {@code NumberFormat.Field.SIGN} and {@code NumberFormat.Field.SUFFIX}
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   783
     * field positions.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   784
     * @param result the resulting string, where the suffix is to be appended
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   785
     * @param suffix suffix to append
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   786
     * @param delegate notified of the locations of
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   787
     *                 {@code NumberFormat.Field.SIGN} and
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   788
     *                 {@code NumberFormat.Field.SUFFIX} fields
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   789
     */
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   790
    private void appendSuffix(StringBuffer result, String suffix,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   791
            FieldDelegate delegate) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   792
        append(result, expandAffix(suffix), delegate,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   793
                getFieldPositions(suffix, NumberFormat.Field.SUFFIX));
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   794
    }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   795
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   796
    /**
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   797
     * Appends the {@code string} to the {@code result}.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   798
     * {@code delegate} is notified of SIGN, PREFIX and/or SUFFIX
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   799
     * field positions.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   800
     * @param result the resulting string, where the text is to be appended
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   801
     * @param string the text to append
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   802
     * @param delegate notified of the locations of sub fields
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   803
     * @param positions a list of {@code FieldPostion} in the given
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   804
     *                  string
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   805
     */
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   806
    private void append(StringBuffer result, String string,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   807
            FieldDelegate delegate, List<FieldPosition> positions) {
53018
8bf9268df0e2 8215281: Use String.isEmpty() when applicable in java.base
redestad
parents: 52869
diff changeset
   808
        if (!string.isEmpty()) {
52869
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   809
            int start = result.length();
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   810
            result.append(string);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   811
            for (int counter = 0; counter < positions.size(); counter++) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   812
                FieldPosition fp = positions.get(counter);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   813
                Format.Field attribute = fp.getFieldAttribute();
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   814
                delegate.formatted(attribute, attribute,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   815
                        start + fp.getBeginIndex(),
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   816
                        start + fp.getEndIndex(), result);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   817
            }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   818
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   819
    }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   820
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   821
    /**
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   822
     * Expands an affix {@code pattern} into a string of literals.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   823
     * All characters in the pattern are literals unless prefixed by QUOTE.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   824
     * The character prefixed by QUOTE is replaced with its respective
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   825
     * localized literal.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   826
     * @param pattern a compact number pattern affix
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   827
     * @return an expanded affix
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   828
     */
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   829
    private String expandAffix(String pattern) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   830
        // Return if no quoted character exists
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   831
        if (pattern.indexOf(QUOTE) < 0) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   832
            return pattern;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   833
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   834
        StringBuilder sb = new StringBuilder();
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   835
        for (int index = 0; index < pattern.length();) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   836
            char ch = pattern.charAt(index++);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   837
            if (ch == QUOTE) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   838
                ch = pattern.charAt(index++);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   839
                if (ch == MINUS_SIGN) {
54252
83deaa8f0c8e 8220224: With CLDR provider, NumberFormat.format could not handle locale with number extension correctly.
naoto
parents: 54206
diff changeset
   840
                    sb.append(symbols.getMinusSignText());
83deaa8f0c8e 8220224: With CLDR provider, NumberFormat.format could not handle locale with number extension correctly.
naoto
parents: 54206
diff changeset
   841
                    continue;
52869
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   842
                }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   843
            }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   844
            sb.append(ch);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   845
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   846
        return sb.toString();
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   847
    }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   848
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   849
    /**
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   850
     * Returns a list of {@code FieldPostion} in the given {@code pattern}.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   851
     * @param pattern the pattern to be parsed for {@code FieldPosition}
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   852
     * @param field whether a PREFIX or SUFFIX field
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   853
     * @return a list of {@code FieldPostion}
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   854
     */
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   855
    private List<FieldPosition> getFieldPositions(String pattern, Field field) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   856
        List<FieldPosition> positions = new ArrayList<>();
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   857
        StringBuilder affix = new StringBuilder();
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   858
        int stringIndex = 0;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   859
        for (int index = 0; index < pattern.length();) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   860
            char ch = pattern.charAt(index++);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   861
            if (ch == QUOTE) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   862
                ch = pattern.charAt(index++);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   863
                if (ch == MINUS_SIGN) {
54252
83deaa8f0c8e 8220224: With CLDR provider, NumberFormat.format could not handle locale with number extension correctly.
naoto
parents: 54206
diff changeset
   864
                    String minusText = symbols.getMinusSignText();
52869
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   865
                    FieldPosition fp = new FieldPosition(NumberFormat.Field.SIGN);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   866
                    fp.setBeginIndex(stringIndex);
54252
83deaa8f0c8e 8220224: With CLDR provider, NumberFormat.format could not handle locale with number extension correctly.
naoto
parents: 54206
diff changeset
   867
                    fp.setEndIndex(stringIndex + minusText.length());
52869
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   868
                    positions.add(fp);
54252
83deaa8f0c8e 8220224: With CLDR provider, NumberFormat.format could not handle locale with number extension correctly.
naoto
parents: 54206
diff changeset
   869
                    stringIndex += minusText.length();
83deaa8f0c8e 8220224: With CLDR provider, NumberFormat.format could not handle locale with number extension correctly.
naoto
parents: 54206
diff changeset
   870
                    affix.append(minusText);
83deaa8f0c8e 8220224: With CLDR provider, NumberFormat.format could not handle locale with number extension correctly.
naoto
parents: 54206
diff changeset
   871
                    continue;
52869
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   872
                }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   873
            }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   874
            stringIndex++;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   875
            affix.append(ch);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   876
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   877
        if (affix.length() != 0) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   878
            FieldPosition fp = new FieldPosition(field);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   879
            fp.setBeginIndex(0);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   880
            fp.setEndIndex(affix.length());
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   881
            positions.add(fp);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   882
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   883
        return positions;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   884
    }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   885
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   886
    /**
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   887
     * Select the index of the matched compact number pattern for
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   888
     * the given {@code long} {@code number}.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   889
     *
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   890
     * @param number number to be formatted
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   891
     * @return index of matched compact pattern;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   892
     *         -1 if no compact patterns specified
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   893
     */
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   894
    private int selectCompactPattern(long number) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   895
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   896
        if (compactPatterns.length == 0) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   897
            return -1;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   898
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   899
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   900
        // Minimum index can be "0", max index can be "size - 1"
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   901
        int dataIndex = number <= 1 ? 0 : (int) Math.log10(number);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   902
        dataIndex = Math.min(dataIndex, compactPatterns.length - 1);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   903
        return dataIndex;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   904
    }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   905
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   906
    /**
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   907
     * Select the index of the matched compact number
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   908
     * pattern for the given {@code BigInteger} {@code number}.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   909
     *
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   910
     * @param number number to be formatted
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   911
     * @return index of matched compact pattern;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   912
     *         -1 if no compact patterns specified
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   913
     */
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   914
    private int selectCompactPattern(BigInteger number) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   915
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   916
        int matchedIndex = -1;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   917
        if (compactPatterns.length == 0) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   918
            return matchedIndex;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   919
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   920
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   921
        BigInteger currentValue = BigInteger.ONE;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   922
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   923
        // For formatting a number, the greatest type less than
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   924
        // or equal to number is used
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   925
        for (int index = 0; index < compactPatterns.length; index++) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   926
            if (number.compareTo(currentValue) > 0) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   927
                // Input number is greater than current type; try matching with
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   928
                // the next
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   929
                matchedIndex = index;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   930
                currentValue = currentValue.multiply(BigInteger.valueOf(RANGE_MULTIPLIER));
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   931
                continue;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   932
            }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   933
            if (number.compareTo(currentValue) < 0) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   934
                // Current type is greater than the input number;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   935
                // take the previous pattern
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   936
                break;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   937
            } else {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   938
                // Equal
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   939
                matchedIndex = index;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   940
                break;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   941
            }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   942
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   943
        return matchedIndex;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   944
    }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   945
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   946
    /**
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   947
     * Formats an Object producing an {@code AttributedCharacterIterator}.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   948
     * The returned {@code AttributedCharacterIterator} can be used
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   949
     * to build the resulting string, as well as to determine information
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   950
     * about the resulting string.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   951
     * <p>
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   952
     * Each attribute key of the {@code AttributedCharacterIterator} will
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   953
     * be of type {@code NumberFormat.Field}, with the attribute value
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   954
     * being the same as the attribute key. The prefix and the suffix
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   955
     * parts of the returned iterator (if present) are represented by
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   956
     * the attributes {@link NumberFormat.Field#PREFIX} and
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   957
     * {@link NumberFormat.Field#SUFFIX} respectively.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   958
     *
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   959
     *
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   960
     * @throws NullPointerException if obj is null
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   961
     * @throws IllegalArgumentException when the Format cannot format the
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   962
     *         given object
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   963
     * @throws ArithmeticException if rounding is needed with rounding
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   964
     *         mode being set to {@code RoundingMode.UNNECESSARY}
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   965
     * @param obj The object to format
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   966
     * @return an {@code AttributedCharacterIterator} describing the
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   967
     *         formatted value
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   968
     */
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   969
    @Override
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   970
    public AttributedCharacterIterator formatToCharacterIterator(Object obj) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   971
        CharacterIteratorFieldDelegate delegate
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   972
                = new CharacterIteratorFieldDelegate();
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   973
        StringBuffer sb = new StringBuffer();
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   974
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   975
        if (obj instanceof Double || obj instanceof Float) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   976
            format(((Number) obj).doubleValue(), sb, delegate);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   977
        } else if (obj instanceof Long || obj instanceof Integer
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   978
                || obj instanceof Short || obj instanceof Byte
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   979
                || obj instanceof AtomicInteger || obj instanceof AtomicLong) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   980
            format(((Number) obj).longValue(), sb, delegate);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   981
        } else if (obj instanceof BigDecimal) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   982
            format((BigDecimal) obj, sb, delegate);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   983
        } else if (obj instanceof BigInteger) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   984
            format((BigInteger) obj, sb, delegate, false);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   985
        } else if (obj == null) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   986
            throw new NullPointerException(
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   987
                    "formatToCharacterIterator must be passed non-null object");
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   988
        } else {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   989
            throw new IllegalArgumentException(
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   990
                    "Cannot format given Object as a Number");
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   991
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   992
        return delegate.getIterator(sb.toString());
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   993
    }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   994
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   995
    /**
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   996
     * Computes the divisor using minimum integer digits and
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   997
     * matched pattern index.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   998
     * @param minIntDigits string of 0s in compact pattern
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
   999
     * @param patternIndex index of matched compact pattern
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1000
     * @return divisor value for the number matching the compact
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1001
     *         pattern at given {@code patternIndex}
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1002
     */
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1003
    private Number computeDivisor(String minIntDigits, int patternIndex) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1004
        int count = minIntDigits.length() - 1;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1005
        Number matchedValue;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1006
        // The divisor value can go above long range, if the compact patterns
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1007
        // goes above index 18, divisor may need to be stored as BigInteger,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1008
        // since long can't store numbers >= 10^19,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1009
        if (patternIndex < 19) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1010
            matchedValue = (long) Math.pow(RANGE_MULTIPLIER, patternIndex);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1011
        } else {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1012
            matchedValue = BigInteger.valueOf(RANGE_MULTIPLIER).pow(patternIndex);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1013
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1014
        Number divisor = matchedValue;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1015
        if (count != 0) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1016
            if (matchedValue instanceof BigInteger) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1017
                BigInteger bigValue = (BigInteger) matchedValue;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1018
                if (bigValue.compareTo(BigInteger.valueOf((long) Math.pow(RANGE_MULTIPLIER, count))) < 0) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1019
                    throw new IllegalArgumentException("Invalid Pattern"
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1020
                            + " [" + compactPatterns[patternIndex]
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1021
                            + "]: min integer digits specified exceeds the limit"
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1022
                            + " for the index " + patternIndex);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1023
                }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1024
                divisor = bigValue.divide(BigInteger.valueOf((long) Math.pow(RANGE_MULTIPLIER, count)));
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1025
            } else {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1026
                long longValue = (long) matchedValue;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1027
                if (longValue < (long) Math.pow(RANGE_MULTIPLIER, count)) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1028
                    throw new IllegalArgumentException("Invalid Pattern"
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1029
                            + " [" + compactPatterns[patternIndex]
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1030
                            + "]: min integer digits specified exceeds the limit"
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1031
                            + " for the index " + patternIndex);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1032
                }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1033
                divisor = longValue / (long) Math.pow(RANGE_MULTIPLIER, count);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1034
            }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1035
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1036
        return divisor;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1037
    }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1038
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1039
    /**
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1040
     * Process the series of compact patterns to compute the
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1041
     * series of prefixes, suffixes and their respective divisor
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1042
     * value.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1043
     *
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1044
     */
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1045
    private void processCompactPatterns() {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1046
        int size = compactPatterns.length;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1047
        positivePrefixPatterns = new ArrayList<>(size);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1048
        negativePrefixPatterns = new ArrayList<>(size);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1049
        positiveSuffixPatterns = new ArrayList<>(size);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1050
        negativeSuffixPatterns = new ArrayList<>(size);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1051
        divisors = new ArrayList<>(size);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1052
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1053
        for (int index = 0; index < size; index++) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1054
            applyPattern(compactPatterns[index], index);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1055
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1056
    }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1057
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1058
    /**
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1059
     * Process a compact pattern at a specific {@code index}
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1060
     * @param pattern the compact pattern to be processed
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1061
     * @param index index in the array of compact patterns
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1062
     *
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1063
     */
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1064
    private void applyPattern(String pattern, int index) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1065
54050
95978e7e8da0 8217254: CompactNumberFormat:: CompactNumberFormat​() constructor does not comply with spec.
nishjain
parents: 53018
diff changeset
  1066
        if (pattern == null) {
95978e7e8da0 8217254: CompactNumberFormat:: CompactNumberFormat​() constructor does not comply with spec.
nishjain
parents: 53018
diff changeset
  1067
            throw new IllegalArgumentException("A null compact pattern" +
95978e7e8da0 8217254: CompactNumberFormat:: CompactNumberFormat​() constructor does not comply with spec.
nishjain
parents: 53018
diff changeset
  1068
                    " encountered at index: " + index);
95978e7e8da0 8217254: CompactNumberFormat:: CompactNumberFormat​() constructor does not comply with spec.
nishjain
parents: 53018
diff changeset
  1069
        }
95978e7e8da0 8217254: CompactNumberFormat:: CompactNumberFormat​() constructor does not comply with spec.
nishjain
parents: 53018
diff changeset
  1070
52869
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1071
        int start = 0;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1072
        boolean gotNegative = false;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1073
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1074
        String positivePrefix = "";
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1075
        String positiveSuffix = "";
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1076
        String negativePrefix = "";
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1077
        String negativeSuffix = "";
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1078
        String zeros = "";
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1079
        for (int j = 1; j >= 0 && start < pattern.length(); --j) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1080
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1081
            StringBuffer prefix = new StringBuffer();
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1082
            StringBuffer suffix = new StringBuffer();
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1083
            boolean inQuote = false;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1084
            // The phase ranges from 0 to 2.  Phase 0 is the prefix.  Phase 1 is
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1085
            // the section of the pattern with digits. Phase 2 is the suffix.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1086
            // The separation of the characters into phases is
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1087
            // strictly enforced; if phase 1 characters are to appear in the
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1088
            // suffix, for example, they must be quoted.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1089
            int phase = 0;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1090
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1091
            // The affix is either the prefix or the suffix.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1092
            StringBuffer affix = prefix;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1093
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1094
            for (int pos = start; pos < pattern.length(); ++pos) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1095
                char ch = pattern.charAt(pos);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1096
                switch (phase) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1097
                    case 0:
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1098
                    case 2:
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1099
                        // Process the prefix / suffix characters
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1100
                        if (inQuote) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1101
                            // A quote within quotes indicates either the closing
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1102
                            // quote or two quotes, which is a quote literal. That
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1103
                            // is, we have the second quote in 'do' or 'don''t'.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1104
                            if (ch == QUOTE) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1105
                                if ((pos + 1) < pattern.length()
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1106
                                        && pattern.charAt(pos + 1) == QUOTE) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1107
                                    ++pos;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1108
                                    affix.append("''"); // 'don''t'
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1109
                                } else {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1110
                                    inQuote = false; // 'do'
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1111
                                }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1112
                                continue;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1113
                            }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1114
                        } else {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1115
                            // Process unquoted characters seen in prefix or suffix
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1116
                            // phase.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1117
                            switch (ch) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1118
                                case ZERO_DIGIT:
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1119
                                    phase = 1;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1120
                                    --pos; // Reprocess this character
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1121
                                    continue;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1122
                                case QUOTE:
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1123
                                    // A quote outside quotes indicates either the
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1124
                                    // opening quote or two quotes, which is a quote
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1125
                                    // literal. That is, we have the first quote in 'do'
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1126
                                    // or o''clock.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1127
                                    if ((pos + 1) < pattern.length()
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1128
                                            && pattern.charAt(pos + 1) == QUOTE) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1129
                                        ++pos;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1130
                                        affix.append("''"); // o''clock
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1131
                                    } else {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1132
                                        inQuote = true; // 'do'
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1133
                                    }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1134
                                    continue;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1135
                                case SEPARATOR:
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1136
                                    // Don't allow separators before we see digit
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1137
                                    // characters of phase 1, and don't allow separators
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1138
                                    // in the second pattern (j == 0).
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1139
                                    if (phase == 0 || j == 0) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1140
                                        throw new IllegalArgumentException(
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1141
                                                "Unquoted special character '"
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1142
                                                + ch + "' in pattern \"" + pattern + "\"");
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1143
                                    }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1144
                                    start = pos + 1;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1145
                                    pos = pattern.length();
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1146
                                    continue;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1147
                                case MINUS_SIGN:
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1148
                                    affix.append("'-");
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1149
                                    continue;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1150
                                case DECIMAL_SEPARATOR:
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1151
                                case GROUPING_SEPARATOR:
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1152
                                case DIGIT:
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1153
                                case PERCENT:
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1154
                                case PER_MILLE:
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1155
                                case CURRENCY_SIGN:
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1156
                                    throw new IllegalArgumentException(
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1157
                                            "Unquoted special character '" + ch
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1158
                                            + "' in pattern \"" + pattern + "\"");
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1159
                                default:
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1160
                                    break;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1161
                            }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1162
                        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1163
                        // Note that if we are within quotes, or if this is an
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1164
                        // unquoted, non-special character, then we usually fall
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1165
                        // through to here.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1166
                        affix.append(ch);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1167
                        break;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1168
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1169
                    case 1:
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1170
                        // The negative subpattern (j = 0) serves only to specify the
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1171
                        // negative prefix and suffix, so all the phase 1 characters,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1172
                        // for example, digits, zeroDigit, groupingSeparator,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1173
                        // decimalSeparator, exponent are ignored
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1174
                        if (j == 0) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1175
                            while (pos < pattern.length()) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1176
                                char negPatternChar = pattern.charAt(pos);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1177
                                if (negPatternChar == ZERO_DIGIT) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1178
                                    ++pos;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1179
                                } else {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1180
                                    // Not a phase 1 character, consider it as
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1181
                                    // suffix and parse it in phase 2
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1182
                                    --pos; //process it again in outer loop
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1183
                                    phase = 2;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1184
                                    affix = suffix;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1185
                                    break;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1186
                                }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1187
                            }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1188
                            continue;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1189
                        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1190
                        // Consider only '0' as valid pattern char which can appear
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1191
                        // in number part, rest can be either suffix or prefix
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1192
                        if (ch == ZERO_DIGIT) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1193
                            zeros = zeros + "0";
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1194
                        } else {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1195
                            phase = 2;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1196
                            affix = suffix;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1197
                            --pos;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1198
                        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1199
                        break;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1200
                }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1201
            }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1202
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1203
            if (inQuote) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1204
                throw new IllegalArgumentException("Invalid single quote"
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1205
                        + " in pattern \"" + pattern + "\"");
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1206
            }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1207
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1208
            if (j == 1) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1209
                positivePrefix = prefix.toString();
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1210
                positiveSuffix = suffix.toString();
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1211
                negativePrefix = positivePrefix;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1212
                negativeSuffix = positiveSuffix;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1213
            } else {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1214
                negativePrefix = prefix.toString();
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1215
                negativeSuffix = suffix.toString();
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1216
                gotNegative = true;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1217
            }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1218
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1219
            // If there is no negative pattern, or if the negative pattern is
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1220
            // identical to the positive pattern, then prepend the minus sign to
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1221
            // the positive pattern to form the negative pattern.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1222
            if (!gotNegative
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1223
                    || (negativePrefix.equals(positivePrefix)
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1224
                    && negativeSuffix.equals(positiveSuffix))) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1225
                negativeSuffix = positiveSuffix;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1226
                negativePrefix = "'-" + positivePrefix;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1227
            }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1228
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1229
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1230
        // If no 0s are specified in a non empty pattern, it is invalid
53018
8bf9268df0e2 8215281: Use String.isEmpty() when applicable in java.base
redestad
parents: 52869
diff changeset
  1231
        if (!pattern.isEmpty() && zeros.isEmpty()) {
52869
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1232
            throw new IllegalArgumentException("Invalid pattern"
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1233
                    + " [" + pattern + "]: all patterns must include digit"
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1234
                    + " placement 0s");
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1235
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1236
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1237
        // Only if positive affix exists; else put empty strings
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1238
        if (!positivePrefix.isEmpty() || !positiveSuffix.isEmpty()) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1239
            positivePrefixPatterns.add(positivePrefix);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1240
            negativePrefixPatterns.add(negativePrefix);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1241
            positiveSuffixPatterns.add(positiveSuffix);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1242
            negativeSuffixPatterns.add(negativeSuffix);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1243
            divisors.add(computeDivisor(zeros, index));
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1244
        } else {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1245
            positivePrefixPatterns.add("");
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1246
            negativePrefixPatterns.add("");
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1247
            positiveSuffixPatterns.add("");
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1248
            negativeSuffixPatterns.add("");
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1249
            divisors.add(1L);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1250
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1251
    }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1252
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1253
    private final transient DigitList digitList = new DigitList();
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1254
    private static final int STATUS_INFINITE = 0;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1255
    private static final int STATUS_POSITIVE = 1;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1256
    private static final int STATUS_LENGTH   = 2;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1257
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1258
    private static final char ZERO_DIGIT = '0';
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1259
    private static final char DIGIT = '#';
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1260
    private static final char DECIMAL_SEPARATOR = '.';
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1261
    private static final char GROUPING_SEPARATOR = ',';
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1262
    private static final char MINUS_SIGN = '-';
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1263
    private static final char PERCENT = '%';
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1264
    private static final char PER_MILLE = '\u2030';
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1265
    private static final char SEPARATOR = ';';
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1266
    private static final char CURRENCY_SIGN = '\u00A4';
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1267
    private static final char QUOTE = '\'';
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1268
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1269
    // Expanded form of positive/negative prefix/suffix,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1270
    // the expanded form contains special characters in
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1271
    // its localized form, which are used for matching
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1272
    // while parsing a string to number
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1273
    private transient List<String> positivePrefixes;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1274
    private transient List<String> negativePrefixes;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1275
    private transient List<String> positiveSuffixes;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1276
    private transient List<String> negativeSuffixes;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1277
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1278
    private void expandAffixPatterns() {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1279
        positivePrefixes = new ArrayList<>(compactPatterns.length);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1280
        negativePrefixes = new ArrayList<>(compactPatterns.length);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1281
        positiveSuffixes = new ArrayList<>(compactPatterns.length);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1282
        negativeSuffixes = new ArrayList<>(compactPatterns.length);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1283
        for (int index = 0; index < compactPatterns.length; index++) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1284
            positivePrefixes.add(expandAffix(positivePrefixPatterns.get(index)));
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1285
            negativePrefixes.add(expandAffix(negativePrefixPatterns.get(index)));
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1286
            positiveSuffixes.add(expandAffix(positiveSuffixPatterns.get(index)));
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1287
            negativeSuffixes.add(expandAffix(negativeSuffixPatterns.get(index)));
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1288
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1289
    }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1290
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1291
    /**
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1292
     * Parses a compact number from a string to produce a {@code Number}.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1293
     * <p>
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1294
     * The method attempts to parse text starting at the index given by
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1295
     * {@code pos}.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1296
     * If parsing succeeds, then the index of {@code pos} is updated
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1297
     * to the index after the last character used (parsing does not necessarily
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1298
     * use all characters up to the end of the string), and the parsed
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1299
     * number is returned. The updated {@code pos} can be used to
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1300
     * indicate the starting point for the next call to this method.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1301
     * If an error occurs, then the index of {@code pos} is not
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1302
     * changed, the error index of {@code pos} is set to the index of
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1303
     * the character where the error occurred, and {@code null} is returned.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1304
     * <p>
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1305
     * The value is the numeric part in the given text multiplied
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1306
     * by the numeric equivalent of the affix attached
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1307
     * (For example, "K" = 1000 in {@link java.util.Locale#US US locale}).
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1308
     * The subclass returned depends on the value of
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1309
     * {@link #isParseBigDecimal}.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1310
     * <ul>
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1311
     * <li>If {@link #isParseBigDecimal()} is false (the default),
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1312
     *     most integer values are returned as {@code Long}
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1313
     *     objects, no matter how they are written: {@code "17K"} and
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1314
     *     {@code "17.000K"} both parse to {@code Long.valueOf(17000)}.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1315
     *     If the value cannot fit into {@code Long}, then the result is
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1316
     *     returned as {@code Double}. This includes values with a
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1317
     *     fractional part, infinite values, {@code NaN},
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1318
     *     and the value -0.0.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1319
     *     <p>
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1320
     *     Callers may use the {@code Number} methods {@code doubleValue},
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1321
     *     {@code longValue}, etc., to obtain the type they want.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1322
     *
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1323
     * <li>If {@link #isParseBigDecimal()} is true, values are returned
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1324
     *     as {@code BigDecimal} objects. The special cases negative
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1325
     *     and positive infinity and NaN are returned as {@code Double}
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1326
     *     instances holding the values of the corresponding
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1327
     *     {@code Double} constants.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1328
     * </ul>
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1329
     * <p>
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1330
     * {@code CompactNumberFormat} parses all Unicode characters that represent
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1331
     * decimal digits, as defined by {@code Character.digit()}. In
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1332
     * addition, {@code CompactNumberFormat} also recognizes as digits the ten
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1333
     * consecutive characters starting with the localized zero digit defined in
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1334
     * the {@code DecimalFormatSymbols} object.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1335
     * <p>
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1336
     * {@code CompactNumberFormat} parse does not allow parsing scientific
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1337
     * notations. For example, parsing a string {@code "1.05E4K"} in
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1338
     * {@link java.util.Locale#US US locale} breaks at character 'E'
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1339
     * and returns 1.05.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1340
     *
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1341
     * @param text the string to be parsed
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1342
     * @param pos  a {@code ParsePosition} object with index and error
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1343
     *             index information as described above
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1344
     * @return the parsed value, or {@code null} if the parse fails
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1345
     * @exception  NullPointerException if {@code text} or
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1346
     *             {@code pos} is null
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1347
     *
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1348
     */
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1349
    @Override
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1350
    public Number parse(String text, ParsePosition pos) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1351
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1352
        Objects.requireNonNull(text);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1353
        Objects.requireNonNull(pos);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1354
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1355
        // Lazily expanding the affix patterns, on the first parse
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1356
        // call on this instance
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1357
        // If not initialized, expand and load all affixes
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1358
        if (positivePrefixes == null) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1359
            expandAffixPatterns();
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1360
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1361
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1362
        // The compact number multiplier for parsed string.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1363
        // Its value is set on parsing prefix and suffix. For example,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1364
        // in the {@link java.util.Locale#US US locale} parsing {@code "1K"}
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1365
        // sets its value to 1000, as K (thousand) is abbreviated form of 1000.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1366
        Number cnfMultiplier = 1L;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1367
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1368
        // Special case NaN
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1369
        if (text.regionMatches(pos.index, symbols.getNaN(),
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1370
                0, symbols.getNaN().length())) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1371
            pos.index = pos.index + symbols.getNaN().length();
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1372
            return Double.NaN;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1373
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1374
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1375
        int position = pos.index;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1376
        int oldStart = pos.index;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1377
        boolean gotPositive = false;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1378
        boolean gotNegative = false;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1379
        int matchedPosIndex = -1;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1380
        int matchedNegIndex = -1;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1381
        String matchedPosPrefix = "";
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1382
        String matchedNegPrefix = "";
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1383
        String defaultPosPrefix = defaultDecimalFormat.getPositivePrefix();
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1384
        String defaultNegPrefix = defaultDecimalFormat.getNegativePrefix();
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1385
        // Prefix matching
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1386
        for (int compactIndex = 0; compactIndex < compactPatterns.length; compactIndex++) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1387
            String positivePrefix = positivePrefixes.get(compactIndex);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1388
            String negativePrefix = negativePrefixes.get(compactIndex);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1389
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1390
            // Do not break if a match occur; there is a possibility that the
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1391
            // subsequent affixes may match the longer subsequence in the given
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1392
            // string.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1393
            // For example, matching "Mdx 3" with "M", "Md" as prefix should
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1394
            // match with "Md"
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1395
            boolean match = matchAffix(text, position, positivePrefix,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1396
                    defaultPosPrefix, matchedPosPrefix);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1397
            if (match) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1398
                matchedPosIndex = compactIndex;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1399
                matchedPosPrefix = positivePrefix;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1400
                gotPositive = true;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1401
            }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1402
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1403
            match = matchAffix(text, position, negativePrefix,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1404
                    defaultNegPrefix, matchedNegPrefix);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1405
            if (match) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1406
                matchedNegIndex = compactIndex;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1407
                matchedNegPrefix = negativePrefix;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1408
                gotNegative = true;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1409
            }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1410
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1411
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1412
        // Given text does not match the non empty valid compact prefixes
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1413
        // check with the default prefixes
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1414
        if (!gotPositive && !gotNegative) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1415
            if (text.regionMatches(pos.index, defaultPosPrefix, 0,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1416
                    defaultPosPrefix.length())) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1417
                // Matches the default positive prefix
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1418
                matchedPosPrefix = defaultPosPrefix;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1419
                gotPositive = true;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1420
            }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1421
            if (text.regionMatches(pos.index, defaultNegPrefix, 0,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1422
                    defaultNegPrefix.length())) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1423
                // Matches the default negative prefix
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1424
                matchedNegPrefix = defaultNegPrefix;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1425
                gotNegative = true;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1426
            }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1427
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1428
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1429
        // If both match, take the longest one
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1430
        if (gotPositive && gotNegative) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1431
            if (matchedPosPrefix.length() > matchedNegPrefix.length()) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1432
                gotNegative = false;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1433
            } else if (matchedPosPrefix.length() < matchedNegPrefix.length()) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1434
                gotPositive = false;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1435
            }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1436
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1437
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1438
        // Update the position and take compact multiplier
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1439
        // only if it matches the compact prefix, not the default
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1440
        // prefix; else multiplier should be 1
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1441
        if (gotPositive) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1442
            position += matchedPosPrefix.length();
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1443
            cnfMultiplier = matchedPosIndex != -1
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1444
                    ? divisors.get(matchedPosIndex) : 1L;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1445
        } else if (gotNegative) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1446
            position += matchedNegPrefix.length();
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1447
            cnfMultiplier = matchedNegIndex != -1
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1448
                    ? divisors.get(matchedNegIndex) : 1L;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1449
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1450
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1451
        digitList.setRoundingMode(getRoundingMode());
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1452
        boolean[] status = new boolean[STATUS_LENGTH];
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1453
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1454
        // Call DecimalFormat.subparseNumber() method to parse the
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1455
        // number part of the input text
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1456
        position = decimalFormat.subparseNumber(text, position,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1457
                digitList, false, false, status);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1458
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1459
        if (position == -1) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1460
            // Unable to parse the number successfully
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1461
            pos.index = oldStart;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1462
            pos.errorIndex = oldStart;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1463
            return null;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1464
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1465
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1466
        // If parse integer only is true and the parsing is broken at
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1467
        // decimal point, then pass/ignore all digits and move pointer
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1468
        // at the start of suffix, to process the suffix part
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1469
        if (isParseIntegerOnly()
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1470
                && text.charAt(position) == symbols.getDecimalSeparator()) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1471
            position++; // Pass decimal character
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1472
            for (; position < text.length(); ++position) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1473
                char ch = text.charAt(position);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1474
                int digit = ch - symbols.getZeroDigit();
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1475
                if (digit < 0 || digit > 9) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1476
                    digit = Character.digit(ch, 10);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1477
                    // Parse all digit characters
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1478
                    if (!(digit >= 0 && digit <= 9)) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1479
                        break;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1480
                    }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1481
                }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1482
            }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1483
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1484
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1485
        // Number parsed successfully; match prefix and
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1486
        // suffix to obtain multiplier
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1487
        pos.index = position;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1488
        Number multiplier = computeParseMultiplier(text, pos,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1489
                gotPositive ? matchedPosPrefix : matchedNegPrefix,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1490
                status, gotPositive, gotNegative);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1491
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1492
        if (multiplier.longValue() == -1L) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1493
            return null;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1494
        } else if (multiplier.longValue() != 1L) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1495
            cnfMultiplier = multiplier;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1496
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1497
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1498
        // Special case INFINITY
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1499
        if (status[STATUS_INFINITE]) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1500
            if (status[STATUS_POSITIVE]) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1501
                return Double.POSITIVE_INFINITY;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1502
            } else {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1503
                return Double.NEGATIVE_INFINITY;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1504
            }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1505
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1506
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1507
        if (isParseBigDecimal()) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1508
            BigDecimal bigDecimalResult = digitList.getBigDecimal();
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1509
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1510
            if (cnfMultiplier.longValue() != 1) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1511
                bigDecimalResult = bigDecimalResult
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1512
                        .multiply(new BigDecimal(cnfMultiplier.toString()));
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1513
            }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1514
            if (!status[STATUS_POSITIVE]) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1515
                bigDecimalResult = bigDecimalResult.negate();
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1516
            }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1517
            return bigDecimalResult;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1518
        } else {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1519
            Number cnfResult;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1520
            if (digitList.fitsIntoLong(status[STATUS_POSITIVE], isParseIntegerOnly())) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1521
                long longResult = digitList.getLong();
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1522
                cnfResult = generateParseResult(longResult, false,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1523
                        longResult < 0, status, cnfMultiplier);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1524
            } else {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1525
                cnfResult = generateParseResult(digitList.getDouble(),
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1526
                        true, false, status, cnfMultiplier);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1527
            }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1528
            return cnfResult;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1529
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1530
    }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1531
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1532
    /**
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1533
     * Returns the parsed result by multiplying the parsed number
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1534
     * with the multiplier representing the prefix and suffix.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1535
     *
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1536
     * @param number parsed number component
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1537
     * @param gotDouble whether the parsed number contains decimal
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1538
     * @param gotLongMin whether the parsed number is Long.MIN
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1539
     * @param status boolean status flags indicating whether the
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1540
     *               value is infinite and whether it is positive
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1541
     * @param cnfMultiplier compact number multiplier
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1542
     * @return parsed result
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1543
     */
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1544
    private Number generateParseResult(Number number, boolean gotDouble,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1545
            boolean gotLongMin, boolean[] status, Number cnfMultiplier) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1546
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1547
        if (gotDouble) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1548
            if (cnfMultiplier.longValue() != 1L) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1549
                double doubleResult = number.doubleValue() * cnfMultiplier.doubleValue();
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1550
                doubleResult = (double) convertIfNegative(doubleResult, status, gotLongMin);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1551
                // Check if a double can be represeneted as a long
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1552
                long longResult = (long) doubleResult;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1553
                gotDouble = ((doubleResult != (double) longResult)
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1554
                        || (doubleResult == 0.0 && 1 / doubleResult < 0.0));
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1555
                return gotDouble ? (Number) doubleResult : (Number) longResult;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1556
            }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1557
        } else {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1558
            if (cnfMultiplier.longValue() != 1L) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1559
                Number result;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1560
                if ((cnfMultiplier instanceof Long) && !gotLongMin) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1561
                    long longMultiplier = (long) cnfMultiplier;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1562
                    try {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1563
                        result = Math.multiplyExact(number.longValue(),
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1564
                                longMultiplier);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1565
                    } catch (ArithmeticException ex) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1566
                        // If number * longMultiplier can not be represented
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1567
                        // as long return as double
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1568
                        result = number.doubleValue() * cnfMultiplier.doubleValue();
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1569
                    }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1570
                } else {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1571
                    // cnfMultiplier can not be stored into long or the number
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1572
                    // part is Long.MIN, return as double
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1573
                    result = number.doubleValue() * cnfMultiplier.doubleValue();
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1574
                }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1575
                return convertIfNegative(result, status, gotLongMin);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1576
            }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1577
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1578
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1579
        // Default number
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1580
        return convertIfNegative(number, status, gotLongMin);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1581
    }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1582
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1583
    /**
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1584
     * Negate the parsed value if the positive status flag is false
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1585
     * and the value is not a Long.MIN
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1586
     * @param number parsed value
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1587
     * @param status boolean status flags indicating whether the
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1588
     *               value is infinite and whether it is positive
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1589
     * @param gotLongMin whether the parsed number is Long.MIN
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1590
     * @return the resulting value
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1591
     */
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1592
    private Number convertIfNegative(Number number, boolean[] status,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1593
            boolean gotLongMin) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1594
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1595
        if (!status[STATUS_POSITIVE] && !gotLongMin) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1596
            if (number instanceof Long) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1597
                return -(long) number;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1598
            } else {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1599
                return -(double) number;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1600
            }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1601
        } else {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1602
            return number;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1603
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1604
    }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1605
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1606
    /**
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1607
     * Attempts to match the given {@code affix} in the
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1608
     * specified {@code text}.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1609
     */
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1610
    private boolean matchAffix(String text, int position, String affix,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1611
            String defaultAffix, String matchedAffix) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1612
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1613
        // Check with the compact affixes which are non empty and
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1614
        // do not match with default affix
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1615
        if (!affix.isEmpty() && !affix.equals(defaultAffix)) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1616
            // Look ahead only for the longer match than the previous match
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1617
            if (matchedAffix.length() < affix.length()) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1618
                if (text.regionMatches(position, affix, 0, affix.length())) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1619
                    return true;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1620
                }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1621
            }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1622
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1623
        return false;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1624
    }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1625
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1626
    /**
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1627
     * Attempts to match given {@code prefix} and {@code suffix} in
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1628
     * the specified {@code text}.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1629
     */
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1630
    private boolean matchPrefixAndSuffix(String text, int position, String prefix,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1631
            String matchedPrefix, String defaultPrefix, String suffix,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1632
            String matchedSuffix, String defaultSuffix) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1633
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1634
        // Check the compact pattern suffix only if there is a
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1635
        // compact prefix match or a default prefix match
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1636
        // because the compact prefix and suffix should match at the same
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1637
        // index to obtain the multiplier.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1638
        // The prefix match is required because of the possibility of
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1639
        // same prefix at multiple index, in which case matching the suffix
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1640
        // is used to obtain the single match
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1641
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1642
        if (prefix.equals(matchedPrefix)
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1643
                || matchedPrefix.equals(defaultPrefix)) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1644
            return matchAffix(text, position, suffix, defaultSuffix, matchedSuffix);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1645
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1646
        return false;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1647
    }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1648
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1649
    /**
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1650
     * Computes multiplier by matching the given {@code matchedPrefix}
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1651
     * and suffix in the specified {@code text} from the lists of
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1652
     * prefixes and suffixes extracted from compact patterns.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1653
     *
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1654
     * @param text the string to parse
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1655
     * @param parsePosition the {@code ParsePosition} object representing the
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1656
     *                      index and error index of the parse string
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1657
     * @param matchedPrefix prefix extracted which needs to be matched to
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1658
     *                      obtain the multiplier
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1659
     * @param status upon return contains boolean status flags indicating
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1660
     *               whether the value is positive
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1661
     * @param gotPositive based on the prefix parsed; whether the number is positive
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1662
     * @param gotNegative based on the prefix parsed; whether the number is negative
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1663
     * @return the multiplier matching the prefix and suffix; -1 otherwise
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1664
     */
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1665
    private Number computeParseMultiplier(String text, ParsePosition parsePosition,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1666
            String matchedPrefix, boolean[] status, boolean gotPositive,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1667
            boolean gotNegative) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1668
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1669
        int position = parsePosition.index;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1670
        boolean gotPos = false;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1671
        boolean gotNeg = false;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1672
        int matchedPosIndex = -1;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1673
        int matchedNegIndex = -1;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1674
        String matchedPosSuffix = "";
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1675
        String matchedNegSuffix = "";
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1676
        for (int compactIndex = 0; compactIndex < compactPatterns.length; compactIndex++) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1677
            String positivePrefix = positivePrefixes.get(compactIndex);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1678
            String negativePrefix = negativePrefixes.get(compactIndex);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1679
            String positiveSuffix = positiveSuffixes.get(compactIndex);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1680
            String negativeSuffix = negativeSuffixes.get(compactIndex);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1681
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1682
            // Do not break if a match occur; there is a possibility that the
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1683
            // subsequent affixes may match the longer subsequence in the given
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1684
            // string.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1685
            // For example, matching "3Mdx" with "M", "Md" should match with "Md"
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1686
            boolean match = matchPrefixAndSuffix(text, position, positivePrefix, matchedPrefix,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1687
                    defaultDecimalFormat.getPositivePrefix(), positiveSuffix,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1688
                    matchedPosSuffix, defaultDecimalFormat.getPositiveSuffix());
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1689
            if (match) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1690
                matchedPosIndex = compactIndex;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1691
                matchedPosSuffix = positiveSuffix;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1692
                gotPos = true;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1693
            }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1694
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1695
            match = matchPrefixAndSuffix(text, position, negativePrefix, matchedPrefix,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1696
                    defaultDecimalFormat.getNegativePrefix(), negativeSuffix,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1697
                    matchedNegSuffix, defaultDecimalFormat.getNegativeSuffix());
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1698
            if (match) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1699
                matchedNegIndex = compactIndex;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1700
                matchedNegSuffix = negativeSuffix;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1701
                gotNeg = true;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1702
            }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1703
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1704
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1705
        // Suffix in the given text does not match with the compact
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1706
        // patterns suffixes; match with the default suffix
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1707
        if (!gotPos && !gotNeg) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1708
            String positiveSuffix = defaultDecimalFormat.getPositiveSuffix();
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1709
            String negativeSuffix = defaultDecimalFormat.getNegativeSuffix();
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1710
            if (text.regionMatches(position, positiveSuffix, 0,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1711
                    positiveSuffix.length())) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1712
                // Matches the default positive prefix
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1713
                matchedPosSuffix = positiveSuffix;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1714
                gotPos = true;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1715
            }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1716
            if (text.regionMatches(position, negativeSuffix, 0,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1717
                    negativeSuffix.length())) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1718
                // Matches the default negative suffix
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1719
                matchedNegSuffix = negativeSuffix;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1720
                gotNeg = true;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1721
            }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1722
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1723
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1724
        // If both matches, take the longest one
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1725
        if (gotPos && gotNeg) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1726
            if (matchedPosSuffix.length() > matchedNegSuffix.length()) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1727
                gotNeg = false;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1728
            } else if (matchedPosSuffix.length() < matchedNegSuffix.length()) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1729
                gotPos = false;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1730
            } else {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1731
                // If longest comparison fails; take the positive and negative
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1732
                // sign of matching prefix
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1733
                gotPos = gotPositive;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1734
                gotNeg = gotNegative;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1735
            }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1736
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1737
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1738
        // Fail if neither or both
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1739
        if (gotPos == gotNeg) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1740
            parsePosition.errorIndex = position;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1741
            return -1L;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1742
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1743
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1744
        Number cnfMultiplier;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1745
        // Update the parse position index and take compact multiplier
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1746
        // only if it matches the compact suffix, not the default
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1747
        // suffix; else multiplier should be 1
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1748
        if (gotPos) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1749
            parsePosition.index = position + matchedPosSuffix.length();
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1750
            cnfMultiplier = matchedPosIndex != -1
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1751
                    ? divisors.get(matchedPosIndex) : 1L;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1752
        } else {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1753
            parsePosition.index = position + matchedNegSuffix.length();
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1754
            cnfMultiplier = matchedNegIndex != -1
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1755
                    ? divisors.get(matchedNegIndex) : 1L;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1756
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1757
        status[STATUS_POSITIVE] = gotPos;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1758
        return cnfMultiplier;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1759
    }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1760
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1761
    /**
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1762
     * Reconstitutes this {@code CompactNumberFormat} from a stream
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1763
     * (that is, deserializes it) after performing some validations.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1764
     * This method throws InvalidObjectException, if the stream data is invalid
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1765
     * because of the following reasons,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1766
     * <ul>
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1767
     * <li> If any of the {@code decimalPattern}, {@code compactPatterns},
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1768
     * {@code symbols} or {@code roundingMode} is {@code null}.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1769
     * <li> If the {@code decimalPattern} or the {@code compactPatterns} array
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1770
     * contains an invalid pattern or if a {@code null} appears in the array of
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1771
     * compact patterns.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1772
     * <li> If the {@code minimumIntegerDigits} is greater than the
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1773
     * {@code maximumIntegerDigits} or the {@code minimumFractionDigits} is
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1774
     * greater than the {@code maximumFractionDigits}. This check is performed
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1775
     * by superclass's Object.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1776
     * <li> If any of the minimum/maximum integer/fraction digit count is
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1777
     * negative. This check is performed by superclass's readObject.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1778
     * <li> If the minimum or maximum integer digit count is larger than 309 or
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1779
     * if the minimum or maximum fraction digit count is larger than 340.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1780
     * <li> If the grouping size is negative or larger than 127.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1781
     * </ul>
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1782
     *
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1783
     * @param inStream the stream
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1784
     * @throws IOException if an I/O error occurs
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1785
     * @throws ClassNotFoundException if the class of a serialized object
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1786
     *         could not be found
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1787
     */
57956
e0b8b019d2f5 8229997: Apply java.io.Serial annotations in java.base
darcy
parents: 54252
diff changeset
  1788
    @java.io.Serial
52869
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1789
    private void readObject(ObjectInputStream inStream) throws IOException,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1790
            ClassNotFoundException {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1791
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1792
        inStream.defaultReadObject();
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1793
        if (decimalPattern == null || compactPatterns == null
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1794
                || symbols == null || roundingMode == null) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1795
            throw new InvalidObjectException("One of the 'decimalPattern',"
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1796
                    + " 'compactPatterns', 'symbols' or 'roundingMode'"
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1797
                    + " is null");
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1798
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1799
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1800
        // Check only the maximum counts because NumberFormat.readObject has
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1801
        // already ensured that the maximum is greater than the minimum count.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1802
        if (getMaximumIntegerDigits() > DecimalFormat.DOUBLE_INTEGER_DIGITS
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1803
                || getMaximumFractionDigits() > DecimalFormat.DOUBLE_FRACTION_DIGITS) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1804
            throw new InvalidObjectException("Digit count out of range");
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1805
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1806
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1807
        // Check if the grouping size is negative, on an attempt to
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1808
        // put value > 127, it wraps around, so check just negative value
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1809
        if (groupingSize < 0) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1810
            throw new InvalidObjectException("Grouping size is negative");
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1811
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1812
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1813
        try {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1814
            processCompactPatterns();
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1815
        } catch (IllegalArgumentException ex) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1816
            throw new InvalidObjectException(ex.getMessage());
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1817
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1818
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1819
        decimalFormat = new DecimalFormat(SPECIAL_PATTERN, symbols);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1820
        decimalFormat.setMaximumFractionDigits(getMaximumFractionDigits());
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1821
        decimalFormat.setMinimumFractionDigits(getMinimumFractionDigits());
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1822
        decimalFormat.setMaximumIntegerDigits(getMaximumIntegerDigits());
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1823
        decimalFormat.setMinimumIntegerDigits(getMinimumIntegerDigits());
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1824
        decimalFormat.setRoundingMode(getRoundingMode());
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1825
        decimalFormat.setGroupingSize(getGroupingSize());
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1826
        decimalFormat.setGroupingUsed(isGroupingUsed());
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1827
        decimalFormat.setParseIntegerOnly(isParseIntegerOnly());
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1828
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1829
        try {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1830
            defaultDecimalFormat = new DecimalFormat(decimalPattern, symbols);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1831
            defaultDecimalFormat.setMaximumFractionDigits(0);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1832
        } catch (IllegalArgumentException ex) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1833
            throw new InvalidObjectException(ex.getMessage());
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1834
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1835
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1836
    }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1837
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1838
    /**
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1839
     * Sets the maximum number of digits allowed in the integer portion of a
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1840
     * number.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1841
     * The maximum allowed integer range is 309, if the {@code newValue} &gt; 309,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1842
     * then the maximum integer digits count is set to 309. Negative input
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1843
     * values are replaced with 0.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1844
     *
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1845
     * @param newValue the maximum number of integer digits to be shown
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1846
     * @see #getMaximumIntegerDigits()
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1847
     */
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1848
    @Override
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1849
    public void setMaximumIntegerDigits(int newValue) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1850
        // The maximum integer digits is checked with the allowed range before calling
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1851
        // the DecimalFormat.setMaximumIntegerDigits, which performs the negative check
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1852
        // on the given newValue while setting it as max integer digits.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1853
        // For example, if a negative value is specified, it is replaced with 0
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1854
        decimalFormat.setMaximumIntegerDigits(Math.min(newValue,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1855
                DecimalFormat.DOUBLE_INTEGER_DIGITS));
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1856
        super.setMaximumIntegerDigits(decimalFormat.getMaximumIntegerDigits());
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1857
        if (decimalFormat.getMinimumIntegerDigits() > decimalFormat.getMaximumIntegerDigits()) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1858
            decimalFormat.setMinimumIntegerDigits(decimalFormat.getMaximumIntegerDigits());
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1859
            super.setMinimumIntegerDigits(decimalFormat.getMinimumIntegerDigits());
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1860
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1861
    }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1862
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1863
    /**
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1864
     * Sets the minimum number of digits allowed in the integer portion of a
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1865
     * number.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1866
     * The maximum allowed integer range is 309, if the {@code newValue} &gt; 309,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1867
     * then the minimum integer digits count is set to 309. Negative input
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1868
     * values are replaced with 0.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1869
     *
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1870
     * @param newValue the minimum number of integer digits to be shown
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1871
     * @see #getMinimumIntegerDigits()
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1872
     */
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1873
    @Override
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1874
    public void setMinimumIntegerDigits(int newValue) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1875
        // The minimum integer digits is checked with the allowed range before calling
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1876
        // the DecimalFormat.setMinimumIntegerDigits, which performs check on the given
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1877
        // newValue while setting it as min integer digits. For example, if a negative
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1878
        // value is specified, it is replaced with 0
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1879
        decimalFormat.setMinimumIntegerDigits(Math.min(newValue,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1880
                DecimalFormat.DOUBLE_INTEGER_DIGITS));
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1881
        super.setMinimumIntegerDigits(decimalFormat.getMinimumIntegerDigits());
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1882
        if (decimalFormat.getMinimumIntegerDigits() > decimalFormat.getMaximumIntegerDigits()) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1883
            decimalFormat.setMaximumIntegerDigits(decimalFormat.getMinimumIntegerDigits());
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1884
            super.setMaximumIntegerDigits(decimalFormat.getMaximumIntegerDigits());
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1885
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1886
    }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1887
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1888
    /**
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1889
     * Sets the minimum number of digits allowed in the fraction portion of a
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1890
     * number.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1891
     * The maximum allowed fraction range is 340, if the {@code newValue} &gt; 340,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1892
     * then the minimum fraction digits count is set to 340. Negative input
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1893
     * values are replaced with 0.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1894
     *
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1895
     * @param newValue the minimum number of fraction digits to be shown
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1896
     * @see #getMinimumFractionDigits()
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1897
     */
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1898
    @Override
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1899
    public void setMinimumFractionDigits(int newValue) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1900
        // The minimum fraction digits is checked with the allowed range before
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1901
        // calling the DecimalFormat.setMinimumFractionDigits, which performs
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1902
        // check on the given newValue while setting it as min fraction
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1903
        // digits. For example, if a negative value is specified, it is
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1904
        // replaced with 0
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1905
        decimalFormat.setMinimumFractionDigits(Math.min(newValue,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1906
                DecimalFormat.DOUBLE_FRACTION_DIGITS));
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1907
        super.setMinimumFractionDigits(decimalFormat.getMinimumFractionDigits());
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1908
        if (decimalFormat.getMinimumFractionDigits() > decimalFormat.getMaximumFractionDigits()) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1909
            decimalFormat.setMaximumFractionDigits(decimalFormat.getMinimumFractionDigits());
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1910
            super.setMaximumFractionDigits(decimalFormat.getMaximumFractionDigits());
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1911
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1912
    }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1913
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1914
    /**
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1915
     * Sets the maximum number of digits allowed in the fraction portion of a
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1916
     * number.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1917
     * The maximum allowed fraction range is 340, if the {@code newValue} &gt; 340,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1918
     * then the maximum fraction digits count is set to 340. Negative input
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1919
     * values are replaced with 0.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1920
     *
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1921
     * @param newValue the maximum number of fraction digits to be shown
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1922
     * @see #getMaximumFractionDigits()
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1923
     */
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1924
    @Override
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1925
    public void setMaximumFractionDigits(int newValue) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1926
        // The maximum fraction digits is checked with the allowed range before
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1927
        // calling the DecimalFormat.setMaximumFractionDigits, which performs
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1928
        // check on the given newValue while setting it as max fraction digits.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1929
        // For example, if a negative value is specified, it is replaced with 0
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1930
        decimalFormat.setMaximumFractionDigits(Math.min(newValue,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1931
                DecimalFormat.DOUBLE_FRACTION_DIGITS));
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1932
        super.setMaximumFractionDigits(decimalFormat.getMaximumFractionDigits());
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1933
        if (decimalFormat.getMinimumFractionDigits() > decimalFormat.getMaximumFractionDigits()) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1934
            decimalFormat.setMinimumFractionDigits(decimalFormat.getMaximumFractionDigits());
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1935
            super.setMinimumFractionDigits(decimalFormat.getMinimumFractionDigits());
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1936
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1937
    }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1938
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1939
    /**
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1940
     * Gets the {@link java.math.RoundingMode} used in this
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1941
     * {@code CompactNumberFormat}.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1942
     *
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1943
     * @return the {@code RoundingMode} used for this
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1944
     *         {@code CompactNumberFormat}
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1945
     * @see #setRoundingMode(RoundingMode)
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1946
     */
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1947
    @Override
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1948
    public RoundingMode getRoundingMode() {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1949
        return roundingMode;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1950
    }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1951
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1952
    /**
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1953
     * Sets the {@link java.math.RoundingMode} used in this
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1954
     * {@code CompactNumberFormat}.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1955
     *
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1956
     * @param roundingMode the {@code RoundingMode} to be used
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1957
     * @see #getRoundingMode()
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1958
     * @throws NullPointerException if {@code roundingMode} is {@code null}
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1959
     */
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1960
    @Override
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1961
    public void setRoundingMode(RoundingMode roundingMode) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1962
        decimalFormat.setRoundingMode(roundingMode);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1963
        this.roundingMode = roundingMode;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1964
    }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1965
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1966
    /**
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1967
     * Returns the grouping size. Grouping size is the number of digits between
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1968
     * grouping separators in the integer portion of a number. For example,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1969
     * in the compact number {@code "12,347 trillion"} for the
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1970
     * {@link java.util.Locale#US US locale}, the grouping size is 3.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1971
     *
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1972
     * @return the grouping size
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1973
     * @see #setGroupingSize
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1974
     * @see java.text.NumberFormat#isGroupingUsed
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1975
     * @see java.text.DecimalFormatSymbols#getGroupingSeparator
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1976
     */
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1977
    public int getGroupingSize() {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1978
        return groupingSize;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1979
    }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1980
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1981
    /**
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1982
     * Sets the grouping size. Grouping size is the number of digits between
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1983
     * grouping separators in the integer portion of a number. For example,
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1984
     * in the compact number {@code "12,347 trillion"} for the
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1985
     * {@link java.util.Locale#US US locale}, the grouping size is 3. The grouping
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1986
     * size must be greater than or equal to zero and less than or equal to 127.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1987
     *
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1988
     * @param newValue the new grouping size
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1989
     * @see #getGroupingSize
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1990
     * @see java.text.NumberFormat#setGroupingUsed
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1991
     * @see java.text.DecimalFormatSymbols#setGroupingSeparator
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1992
     * @throws IllegalArgumentException if {@code newValue} is negative or
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1993
     * larger than 127
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1994
     */
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1995
    public void setGroupingSize(int newValue) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1996
        if (newValue < 0 || newValue > 127) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1997
            throw new IllegalArgumentException(
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1998
                    "The value passed is negative or larger than 127");
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  1999
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2000
        groupingSize = (byte) newValue;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2001
        decimalFormat.setGroupingSize(groupingSize);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2002
    }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2003
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2004
    /**
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2005
     * Returns true if grouping is used in this format. For example, with
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2006
     * grouping on and grouping size set to 3, the number {@code 12346567890987654}
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2007
     * can be formatted as {@code "12,347 trillion"} in the
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2008
     * {@link java.util.Locale#US US locale}.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2009
     * The grouping separator is locale dependent.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2010
     *
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2011
     * @return {@code true} if grouping is used;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2012
     *         {@code false} otherwise
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2013
     * @see #setGroupingUsed
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2014
     */
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2015
    @Override
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2016
    public boolean isGroupingUsed() {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2017
        return super.isGroupingUsed();
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2018
    }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2019
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2020
    /**
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2021
     * Sets whether or not grouping will be used in this format.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2022
     *
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2023
     * @param newValue {@code true} if grouping is used;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2024
     *                 {@code false} otherwise
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2025
     * @see #isGroupingUsed
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2026
     */
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2027
    @Override
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2028
    public void setGroupingUsed(boolean newValue) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2029
        decimalFormat.setGroupingUsed(newValue);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2030
        super.setGroupingUsed(newValue);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2031
    }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2032
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2033
    /**
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2034
     * Returns true if this format parses only an integer from the number
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2035
     * component of a compact number.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2036
     * Parsing an integer means that only an integer is considered from the
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2037
     * number component, prefix/suffix is still considered to compute the
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2038
     * resulting output.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2039
     * For example, in the {@link java.util.Locale#US US locale}, if this method
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2040
     * returns {@code true}, the string {@code "1234.78 thousand"} would be
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2041
     * parsed as the value {@code 1234000} (1234 (integer part) * 1000
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2042
     * (thousand)) and the fractional part would be skipped.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2043
     * The exact format accepted by the parse operation is locale dependent.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2044
     *
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2045
     * @return {@code true} if compact numbers should be parsed as integers
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2046
     *         only; {@code false} otherwise
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2047
     */
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2048
    @Override
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2049
    public boolean isParseIntegerOnly() {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2050
        return super.isParseIntegerOnly();
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2051
    }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2052
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2053
    /**
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2054
     * Sets whether or not this format parses only an integer from the number
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2055
     * component of a compact number.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2056
     *
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2057
     * @param value {@code true} if compact numbers should be parsed as
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2058
     *              integers only; {@code false} otherwise
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2059
     * @see #isParseIntegerOnly
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2060
     */
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2061
    @Override
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2062
    public void setParseIntegerOnly(boolean value) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2063
        decimalFormat.setParseIntegerOnly(value);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2064
        super.setParseIntegerOnly(value);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2065
    }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2066
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2067
    /**
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2068
     * Returns whether the {@link #parse(String, ParsePosition)}
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2069
     * method returns {@code BigDecimal}. The default value is false.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2070
     *
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2071
     * @return {@code true} if the parse method returns BigDecimal;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2072
     *         {@code false} otherwise
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2073
     * @see #setParseBigDecimal
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2074
     *
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2075
     */
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2076
    public boolean isParseBigDecimal() {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2077
        return parseBigDecimal;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2078
    }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2079
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2080
    /**
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2081
     * Sets whether the {@link #parse(String, ParsePosition)}
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2082
     * method returns {@code BigDecimal}.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2083
     *
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2084
     * @param newValue {@code true} if the parse method returns BigDecimal;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2085
     *                 {@code false} otherwise
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2086
     * @see #isParseBigDecimal
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2087
     *
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2088
     */
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2089
    public void setParseBigDecimal(boolean newValue) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2090
        parseBigDecimal = newValue;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2091
    }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2092
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2093
    /**
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2094
     * Checks if this {@code CompactNumberFormat} is equal to the
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2095
     * specified {@code obj}. The objects of type {@code CompactNumberFormat}
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2096
     * are compared, other types return false; obeys the general contract of
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2097
     * {@link java.lang.Object#equals(java.lang.Object) Object.equals}.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2098
     *
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2099
     * @param obj the object to compare with
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2100
     * @return true if this is equal to the other {@code CompactNumberFormat}
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2101
     */
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2102
    @Override
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2103
    public boolean equals(Object obj) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2104
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2105
        if (!super.equals(obj)) {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2106
            return false;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2107
        }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2108
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2109
        CompactNumberFormat other = (CompactNumberFormat) obj;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2110
        return decimalPattern.equals(other.decimalPattern)
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2111
                && symbols.equals(other.symbols)
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2112
                && Arrays.equals(compactPatterns, other.compactPatterns)
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2113
                && roundingMode.equals(other.roundingMode)
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2114
                && groupingSize == other.groupingSize
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2115
                && parseBigDecimal == other.parseBigDecimal;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2116
    }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2117
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2118
    /**
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2119
     * Returns the hash code for this {@code CompactNumberFormat} instance.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2120
     *
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2121
     * @return hash code for this {@code CompactNumberFormat}
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2122
     */
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2123
    @Override
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2124
    public int hashCode() {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2125
        return 31 * super.hashCode() +
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2126
                Objects.hash(decimalPattern, symbols, roundingMode)
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2127
                + Arrays.hashCode(compactPatterns) + groupingSize
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2128
                + Boolean.hashCode(parseBigDecimal);
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2129
    }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2130
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2131
    /**
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2132
     * Creates and returns a copy of this {@code CompactNumberFormat}
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2133
     * instance.
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2134
     *
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2135
     * @return a clone of this instance
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2136
     */
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2137
    @Override
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2138
    public CompactNumberFormat clone() {
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2139
        CompactNumberFormat other = (CompactNumberFormat) super.clone();
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2140
        other.compactPatterns = compactPatterns.clone();
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2141
        other.symbols = (DecimalFormatSymbols) symbols.clone();
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2142
        return other;
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2143
    }
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2144
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2145
}
c5c0db0b7c2f 8177552: Compact Number Formatting support
nishjain
parents:
diff changeset
  2146