1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/rt/emul/compact/src/main/java/java/text/NumberFormat.java Thu Oct 03 15:40:35 2013 +0200
1.3 @@ -0,0 +1,1162 @@
1.4 +/*
1.5 + * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
1.7 + *
1.8 + * This code is free software; you can redistribute it and/or modify it
1.9 + * under the terms of the GNU General Public License version 2 only, as
1.10 + * published by the Free Software Foundation. Oracle designates this
1.11 + * particular file as subject to the "Classpath" exception as provided
1.12 + * by Oracle in the LICENSE file that accompanied this code.
1.13 + *
1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
1.17 + * version 2 for more details (a copy is included in the LICENSE file that
1.18 + * accompanied this code).
1.19 + *
1.20 + * You should have received a copy of the GNU General Public License version
1.21 + * 2 along with this work; if not, write to the Free Software Foundation,
1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1.23 + *
1.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
1.25 + * or visit www.oracle.com if you need additional information or have any
1.26 + * questions.
1.27 + */
1.28 +
1.29 +/*
1.30 + * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
1.31 + * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
1.32 + *
1.33 + * The original version of this source code and documentation is copyrighted
1.34 + * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
1.35 + * materials are provided under terms of a License Agreement between Taligent
1.36 + * and Sun. This technology is protected by multiple US and International
1.37 + * patents. This notice and attribution to Taligent may not be removed.
1.38 + * Taligent is a registered trademark of Taligent, Inc.
1.39 + *
1.40 + */
1.41 +
1.42 +package java.text;
1.43 +
1.44 +import java.io.InvalidObjectException;
1.45 +import java.io.IOException;
1.46 +import java.io.ObjectInputStream;
1.47 +import java.io.ObjectOutputStream;
1.48 +import java.math.BigInteger;
1.49 +import java.math.RoundingMode;
1.50 +import java.text.spi.NumberFormatProvider;
1.51 +import java.util.Currency;
1.52 +import java.util.HashMap;
1.53 +import java.util.Hashtable;
1.54 +import java.util.Locale;
1.55 +import java.util.Map;
1.56 +import java.util.ResourceBundle;
1.57 +import java.util.concurrent.atomic.AtomicInteger;
1.58 +import java.util.concurrent.atomic.AtomicLong;
1.59 +import java.util.spi.LocaleServiceProvider;
1.60 +import sun.util.LocaleServiceProviderPool;
1.61 +import sun.util.resources.LocaleData;
1.62 +
1.63 +/**
1.64 + * <code>NumberFormat</code> is the abstract base class for all number
1.65 + * formats. This class provides the interface for formatting and parsing
1.66 + * numbers. <code>NumberFormat</code> also provides methods for determining
1.67 + * which locales have number formats, and what their names are.
1.68 + *
1.69 + * <p>
1.70 + * <code>NumberFormat</code> helps you to format and parse numbers for any locale.
1.71 + * Your code can be completely independent of the locale conventions for
1.72 + * decimal points, thousands-separators, or even the particular decimal
1.73 + * digits used, or whether the number format is even decimal.
1.74 + *
1.75 + * <p>
1.76 + * To format a number for the current Locale, use one of the factory
1.77 + * class methods:
1.78 + * <blockquote>
1.79 + * <pre>
1.80 + * myString = NumberFormat.getInstance().format(myNumber);
1.81 + * </pre>
1.82 + * </blockquote>
1.83 + * If you are formatting multiple numbers, it is
1.84 + * more efficient to get the format and use it multiple times so that
1.85 + * the system doesn't have to fetch the information about the local
1.86 + * language and country conventions multiple times.
1.87 + * <blockquote>
1.88 + * <pre>
1.89 + * NumberFormat nf = NumberFormat.getInstance();
1.90 + * for (int i = 0; i < myNumber.length; ++i) {
1.91 + * output.println(nf.format(myNumber[i]) + "; ");
1.92 + * }
1.93 + * </pre>
1.94 + * </blockquote>
1.95 + * To format a number for a different Locale, specify it in the
1.96 + * call to <code>getInstance</code>.
1.97 + * <blockquote>
1.98 + * <pre>
1.99 + * NumberFormat nf = NumberFormat.getInstance(Locale.FRENCH);
1.100 + * </pre>
1.101 + * </blockquote>
1.102 + * You can also use a <code>NumberFormat</code> to parse numbers:
1.103 + * <blockquote>
1.104 + * <pre>
1.105 + * myNumber = nf.parse(myString);
1.106 + * </pre>
1.107 + * </blockquote>
1.108 + * Use <code>getInstance</code> or <code>getNumberInstance</code> to get the
1.109 + * normal number format. Use <code>getIntegerInstance</code> to get an
1.110 + * integer number format. Use <code>getCurrencyInstance</code> to get the
1.111 + * currency number format. And use <code>getPercentInstance</code> to get a
1.112 + * format for displaying percentages. With this format, a fraction like
1.113 + * 0.53 is displayed as 53%.
1.114 + *
1.115 + * <p>
1.116 + * You can also control the display of numbers with such methods as
1.117 + * <code>setMinimumFractionDigits</code>.
1.118 + * If you want even more control over the format or parsing,
1.119 + * or want to give your users more control,
1.120 + * you can try casting the <code>NumberFormat</code> you get from the factory methods
1.121 + * to a <code>DecimalFormat</code>. This will work for the vast majority
1.122 + * of locales; just remember to put it in a <code>try</code> block in case you
1.123 + * encounter an unusual one.
1.124 + *
1.125 + * <p>
1.126 + * NumberFormat and DecimalFormat are designed such that some controls
1.127 + * work for formatting and others work for parsing. The following is
1.128 + * the detailed description for each these control methods,
1.129 + * <p>
1.130 + * setParseIntegerOnly : only affects parsing, e.g.
1.131 + * if true, "3456.78" -> 3456 (and leaves the parse position just after index 6)
1.132 + * if false, "3456.78" -> 3456.78 (and leaves the parse position just after index 8)
1.133 + * This is independent of formatting. If you want to not show a decimal point
1.134 + * where there might be no digits after the decimal point, use
1.135 + * setDecimalSeparatorAlwaysShown.
1.136 + * <p>
1.137 + * setDecimalSeparatorAlwaysShown : only affects formatting, and only where
1.138 + * there might be no digits after the decimal point, such as with a pattern
1.139 + * like "#,##0.##", e.g.,
1.140 + * if true, 3456.00 -> "3,456."
1.141 + * if false, 3456.00 -> "3456"
1.142 + * This is independent of parsing. If you want parsing to stop at the decimal
1.143 + * point, use setParseIntegerOnly.
1.144 + *
1.145 + * <p>
1.146 + * You can also use forms of the <code>parse</code> and <code>format</code>
1.147 + * methods with <code>ParsePosition</code> and <code>FieldPosition</code> to
1.148 + * allow you to:
1.149 + * <ul>
1.150 + * <li> progressively parse through pieces of a string
1.151 + * <li> align the decimal point and other areas
1.152 + * </ul>
1.153 + * For example, you can align numbers in two ways:
1.154 + * <ol>
1.155 + * <li> If you are using a monospaced font with spacing for alignment,
1.156 + * you can pass the <code>FieldPosition</code> in your format call, with
1.157 + * <code>field</code> = <code>INTEGER_FIELD</code>. On output,
1.158 + * <code>getEndIndex</code> will be set to the offset between the
1.159 + * last character of the integer and the decimal. Add
1.160 + * (desiredSpaceCount - getEndIndex) spaces at the front of the string.
1.161 + *
1.162 + * <li> If you are using proportional fonts,
1.163 + * instead of padding with spaces, measure the width
1.164 + * of the string in pixels from the start to <code>getEndIndex</code>.
1.165 + * Then move the pen by
1.166 + * (desiredPixelWidth - widthToAlignmentPoint) before drawing the text.
1.167 + * It also works where there is no decimal, but possibly additional
1.168 + * characters at the end, e.g., with parentheses in negative
1.169 + * numbers: "(12)" for -12.
1.170 + * </ol>
1.171 + *
1.172 + * <h4><a name="synchronization">Synchronization</a></h4>
1.173 + *
1.174 + * <p>
1.175 + * Number formats are generally not synchronized.
1.176 + * It is recommended to create separate format instances for each thread.
1.177 + * If multiple threads access a format concurrently, it must be synchronized
1.178 + * externally.
1.179 + *
1.180 + * @see DecimalFormat
1.181 + * @see ChoiceFormat
1.182 + * @author Mark Davis
1.183 + * @author Helena Shih
1.184 + */
1.185 +public abstract class NumberFormat extends Format {
1.186 +
1.187 + /**
1.188 + * Field constant used to construct a FieldPosition object. Signifies that
1.189 + * the position of the integer part of a formatted number should be returned.
1.190 + * @see java.text.FieldPosition
1.191 + */
1.192 + public static final int INTEGER_FIELD = 0;
1.193 +
1.194 + /**
1.195 + * Field constant used to construct a FieldPosition object. Signifies that
1.196 + * the position of the fraction part of a formatted number should be returned.
1.197 + * @see java.text.FieldPosition
1.198 + */
1.199 + public static final int FRACTION_FIELD = 1;
1.200 +
1.201 + /**
1.202 + * Sole constructor. (For invocation by subclass constructors, typically
1.203 + * implicit.)
1.204 + */
1.205 + protected NumberFormat() {
1.206 + }
1.207 +
1.208 + /**
1.209 + * Formats a number and appends the resulting text to the given string
1.210 + * buffer.
1.211 + * The number can be of any subclass of {@link java.lang.Number}.
1.212 + * <p>
1.213 + * This implementation extracts the number's value using
1.214 + * {@link java.lang.Number#longValue()} for all integral type values that
1.215 + * can be converted to <code>long</code> without loss of information,
1.216 + * including <code>BigInteger</code> values with a
1.217 + * {@link java.math.BigInteger#bitLength() bit length} of less than 64,
1.218 + * and {@link java.lang.Number#doubleValue()} for all other types. It
1.219 + * then calls
1.220 + * {@link #format(long,java.lang.StringBuffer,java.text.FieldPosition)}
1.221 + * or {@link #format(double,java.lang.StringBuffer,java.text.FieldPosition)}.
1.222 + * This may result in loss of magnitude information and precision for
1.223 + * <code>BigInteger</code> and <code>BigDecimal</code> values.
1.224 + * @param number the number to format
1.225 + * @param toAppendTo the <code>StringBuffer</code> to which the formatted
1.226 + * text is to be appended
1.227 + * @param pos On input: an alignment field, if desired.
1.228 + * On output: the offsets of the alignment field.
1.229 + * @return the value passed in as <code>toAppendTo</code>
1.230 + * @exception IllegalArgumentException if <code>number</code> is
1.231 + * null or not an instance of <code>Number</code>.
1.232 + * @exception NullPointerException if <code>toAppendTo</code> or
1.233 + * <code>pos</code> is null
1.234 + * @exception ArithmeticException if rounding is needed with rounding
1.235 + * mode being set to RoundingMode.UNNECESSARY
1.236 + * @see java.text.FieldPosition
1.237 + */
1.238 + public StringBuffer format(Object number,
1.239 + StringBuffer toAppendTo,
1.240 + FieldPosition pos) {
1.241 + if (number instanceof Long || number instanceof Integer ||
1.242 + number instanceof Short || number instanceof Byte ||
1.243 + number instanceof AtomicInteger || number instanceof AtomicLong ||
1.244 + (number instanceof BigInteger &&
1.245 + ((BigInteger)number).bitLength() < 64)) {
1.246 + return format(((Number)number).longValue(), toAppendTo, pos);
1.247 + } else if (number instanceof Number) {
1.248 + return format(((Number)number).doubleValue(), toAppendTo, pos);
1.249 + } else {
1.250 + throw new IllegalArgumentException("Cannot format given Object as a Number");
1.251 + }
1.252 + }
1.253 +
1.254 + /**
1.255 + * Parses text from a string to produce a <code>Number</code>.
1.256 + * <p>
1.257 + * The method attempts to parse text starting at the index given by
1.258 + * <code>pos</code>.
1.259 + * If parsing succeeds, then the index of <code>pos</code> is updated
1.260 + * to the index after the last character used (parsing does not necessarily
1.261 + * use all characters up to the end of the string), and the parsed
1.262 + * number is returned. The updated <code>pos</code> can be used to
1.263 + * indicate the starting point for the next call to this method.
1.264 + * If an error occurs, then the index of <code>pos</code> is not
1.265 + * changed, the error index of <code>pos</code> is set to the index of
1.266 + * the character where the error occurred, and null is returned.
1.267 + * <p>
1.268 + * See the {@link #parse(String, ParsePosition)} method for more information
1.269 + * on number parsing.
1.270 + *
1.271 + * @param source A <code>String</code>, part of which should be parsed.
1.272 + * @param pos A <code>ParsePosition</code> object with index and error
1.273 + * index information as described above.
1.274 + * @return A <code>Number</code> parsed from the string. In case of
1.275 + * error, returns null.
1.276 + * @exception NullPointerException if <code>pos</code> is null.
1.277 + */
1.278 + public final Object parseObject(String source, ParsePosition pos) {
1.279 + return parse(source, pos);
1.280 + }
1.281 +
1.282 + /**
1.283 + * Specialization of format.
1.284 + * @exception ArithmeticException if rounding is needed with rounding
1.285 + * mode being set to RoundingMode.UNNECESSARY
1.286 + * @see java.text.Format#format
1.287 + */
1.288 + public final String format(double number) {
1.289 + return format(number, new StringBuffer(),
1.290 + DontCareFieldPosition.INSTANCE).toString();
1.291 + }
1.292 +
1.293 + /**
1.294 + * Specialization of format.
1.295 + * @exception ArithmeticException if rounding is needed with rounding
1.296 + * mode being set to RoundingMode.UNNECESSARY
1.297 + * @see java.text.Format#format
1.298 + */
1.299 + public final String format(long number) {
1.300 + return format(number, new StringBuffer(),
1.301 + DontCareFieldPosition.INSTANCE).toString();
1.302 + }
1.303 +
1.304 + /**
1.305 + * Specialization of format.
1.306 + * @exception ArithmeticException if rounding is needed with rounding
1.307 + * mode being set to RoundingMode.UNNECESSARY
1.308 + * @see java.text.Format#format
1.309 + */
1.310 + public abstract StringBuffer format(double number,
1.311 + StringBuffer toAppendTo,
1.312 + FieldPosition pos);
1.313 +
1.314 + /**
1.315 + * Specialization of format.
1.316 + * @exception ArithmeticException if rounding is needed with rounding
1.317 + * mode being set to RoundingMode.UNNECESSARY
1.318 + * @see java.text.Format#format
1.319 + */
1.320 + public abstract StringBuffer format(long number,
1.321 + StringBuffer toAppendTo,
1.322 + FieldPosition pos);
1.323 +
1.324 + /**
1.325 + * Returns a Long if possible (e.g., within the range [Long.MIN_VALUE,
1.326 + * Long.MAX_VALUE] and with no decimals), otherwise a Double.
1.327 + * If IntegerOnly is set, will stop at a decimal
1.328 + * point (or equivalent; e.g., for rational numbers "1 2/3", will stop
1.329 + * after the 1).
1.330 + * Does not throw an exception; if no object can be parsed, index is
1.331 + * unchanged!
1.332 + * @see java.text.NumberFormat#isParseIntegerOnly
1.333 + * @see java.text.Format#parseObject
1.334 + */
1.335 + public abstract Number parse(String source, ParsePosition parsePosition);
1.336 +
1.337 + /**
1.338 + * Parses text from the beginning of the given string to produce a number.
1.339 + * The method may not use the entire text of the given string.
1.340 + * <p>
1.341 + * See the {@link #parse(String, ParsePosition)} method for more information
1.342 + * on number parsing.
1.343 + *
1.344 + * @param source A <code>String</code> whose beginning should be parsed.
1.345 + * @return A <code>Number</code> parsed from the string.
1.346 + * @exception ParseException if the beginning of the specified string
1.347 + * cannot be parsed.
1.348 + */
1.349 + public Number parse(String source) throws ParseException {
1.350 + ParsePosition parsePosition = new ParsePosition(0);
1.351 + Number result = parse(source, parsePosition);
1.352 + if (parsePosition.index == 0) {
1.353 + throw new ParseException("Unparseable number: \"" + source + "\"",
1.354 + parsePosition.errorIndex);
1.355 + }
1.356 + return result;
1.357 + }
1.358 +
1.359 + /**
1.360 + * Returns true if this format will parse numbers as integers only.
1.361 + * For example in the English locale, with ParseIntegerOnly true, the
1.362 + * string "1234." would be parsed as the integer value 1234 and parsing
1.363 + * would stop at the "." character. Of course, the exact format accepted
1.364 + * by the parse operation is locale dependant and determined by sub-classes
1.365 + * of NumberFormat.
1.366 + */
1.367 + public boolean isParseIntegerOnly() {
1.368 + return parseIntegerOnly;
1.369 + }
1.370 +
1.371 + /**
1.372 + * Sets whether or not numbers should be parsed as integers only.
1.373 + * @see #isParseIntegerOnly
1.374 + */
1.375 + public void setParseIntegerOnly(boolean value) {
1.376 + parseIntegerOnly = value;
1.377 + }
1.378 +
1.379 + //============== Locale Stuff =====================
1.380 +
1.381 + /**
1.382 + * Returns a general-purpose number format for the current default locale.
1.383 + * This is the same as calling
1.384 + * {@link #getNumberInstance() getNumberInstance()}.
1.385 + */
1.386 + public final static NumberFormat getInstance() {
1.387 + return getInstance(Locale.getDefault(Locale.Category.FORMAT), NUMBERSTYLE);
1.388 + }
1.389 +
1.390 + /**
1.391 + * Returns a general-purpose number format for the specified locale.
1.392 + * This is the same as calling
1.393 + * {@link #getNumberInstance(java.util.Locale) getNumberInstance(inLocale)}.
1.394 + */
1.395 + public static NumberFormat getInstance(Locale inLocale) {
1.396 + return getInstance(inLocale, NUMBERSTYLE);
1.397 + }
1.398 +
1.399 + /**
1.400 + * Returns a general-purpose number format for the current default locale.
1.401 + */
1.402 + public final static NumberFormat getNumberInstance() {
1.403 + return getInstance(Locale.getDefault(Locale.Category.FORMAT), NUMBERSTYLE);
1.404 + }
1.405 +
1.406 + /**
1.407 + * Returns a general-purpose number format for the specified locale.
1.408 + */
1.409 + public static NumberFormat getNumberInstance(Locale inLocale) {
1.410 + return getInstance(inLocale, NUMBERSTYLE);
1.411 + }
1.412 +
1.413 + /**
1.414 + * Returns an integer number format for the current default locale. The
1.415 + * returned number format is configured to round floating point numbers
1.416 + * to the nearest integer using half-even rounding (see {@link
1.417 + * java.math.RoundingMode#HALF_EVEN RoundingMode.HALF_EVEN}) for formatting,
1.418 + * and to parse only the integer part of an input string (see {@link
1.419 + * #isParseIntegerOnly isParseIntegerOnly}).
1.420 + *
1.421 + * @see #getRoundingMode()
1.422 + * @return a number format for integer values
1.423 + * @since 1.4
1.424 + */
1.425 + public final static NumberFormat getIntegerInstance() {
1.426 + return getInstance(Locale.getDefault(Locale.Category.FORMAT), INTEGERSTYLE);
1.427 + }
1.428 +
1.429 + /**
1.430 + * Returns an integer number format for the specified locale. The
1.431 + * returned number format is configured to round floating point numbers
1.432 + * to the nearest integer using half-even rounding (see {@link
1.433 + * java.math.RoundingMode#HALF_EVEN RoundingMode.HALF_EVEN}) for formatting,
1.434 + * and to parse only the integer part of an input string (see {@link
1.435 + * #isParseIntegerOnly isParseIntegerOnly}).
1.436 + *
1.437 + * @see #getRoundingMode()
1.438 + * @return a number format for integer values
1.439 + * @since 1.4
1.440 + */
1.441 + public static NumberFormat getIntegerInstance(Locale inLocale) {
1.442 + return getInstance(inLocale, INTEGERSTYLE);
1.443 + }
1.444 +
1.445 + /**
1.446 + * Returns a currency format for the current default locale.
1.447 + */
1.448 + public final static NumberFormat getCurrencyInstance() {
1.449 + return getInstance(Locale.getDefault(Locale.Category.FORMAT), CURRENCYSTYLE);
1.450 + }
1.451 +
1.452 + /**
1.453 + * Returns a currency format for the specified locale.
1.454 + */
1.455 + public static NumberFormat getCurrencyInstance(Locale inLocale) {
1.456 + return getInstance(inLocale, CURRENCYSTYLE);
1.457 + }
1.458 +
1.459 + /**
1.460 + * Returns a percentage format for the current default locale.
1.461 + */
1.462 + public final static NumberFormat getPercentInstance() {
1.463 + return getInstance(Locale.getDefault(Locale.Category.FORMAT), PERCENTSTYLE);
1.464 + }
1.465 +
1.466 + /**
1.467 + * Returns a percentage format for the specified locale.
1.468 + */
1.469 + public static NumberFormat getPercentInstance(Locale inLocale) {
1.470 + return getInstance(inLocale, PERCENTSTYLE);
1.471 + }
1.472 +
1.473 + /**
1.474 + * Returns a scientific format for the current default locale.
1.475 + */
1.476 + /*public*/ final static NumberFormat getScientificInstance() {
1.477 + return getInstance(Locale.getDefault(Locale.Category.FORMAT), SCIENTIFICSTYLE);
1.478 + }
1.479 +
1.480 + /**
1.481 + * Returns a scientific format for the specified locale.
1.482 + */
1.483 + /*public*/ static NumberFormat getScientificInstance(Locale inLocale) {
1.484 + return getInstance(inLocale, SCIENTIFICSTYLE);
1.485 + }
1.486 +
1.487 + /**
1.488 + * Returns an array of all locales for which the
1.489 + * <code>get*Instance</code> methods of this class can return
1.490 + * localized instances.
1.491 + * The returned array represents the union of locales supported by the Java
1.492 + * runtime and by installed
1.493 + * {@link java.text.spi.NumberFormatProvider NumberFormatProvider} implementations.
1.494 + * It must contain at least a <code>Locale</code> instance equal to
1.495 + * {@link java.util.Locale#US Locale.US}.
1.496 + *
1.497 + * @return An array of locales for which localized
1.498 + * <code>NumberFormat</code> instances are available.
1.499 + */
1.500 + public static Locale[] getAvailableLocales() {
1.501 + LocaleServiceProviderPool pool =
1.502 + LocaleServiceProviderPool.getPool(NumberFormatProvider.class);
1.503 + return pool.getAvailableLocales();
1.504 + }
1.505 +
1.506 + /**
1.507 + * Overrides hashCode
1.508 + */
1.509 + public int hashCode() {
1.510 + return maximumIntegerDigits * 37 + maxFractionDigits;
1.511 + // just enough fields for a reasonable distribution
1.512 + }
1.513 +
1.514 + /**
1.515 + * Overrides equals
1.516 + */
1.517 + public boolean equals(Object obj) {
1.518 + if (obj == null) {
1.519 + return false;
1.520 + }
1.521 + if (this == obj) {
1.522 + return true;
1.523 + }
1.524 + if (getClass() != obj.getClass()) {
1.525 + return false;
1.526 + }
1.527 + NumberFormat other = (NumberFormat) obj;
1.528 + return (maximumIntegerDigits == other.maximumIntegerDigits
1.529 + && minimumIntegerDigits == other.minimumIntegerDigits
1.530 + && maximumFractionDigits == other.maximumFractionDigits
1.531 + && minimumFractionDigits == other.minimumFractionDigits
1.532 + && groupingUsed == other.groupingUsed
1.533 + && parseIntegerOnly == other.parseIntegerOnly);
1.534 + }
1.535 +
1.536 + /**
1.537 + * Overrides Cloneable
1.538 + */
1.539 + public Object clone() {
1.540 + NumberFormat other = (NumberFormat) super.clone();
1.541 + return other;
1.542 + }
1.543 +
1.544 + /**
1.545 + * Returns true if grouping is used in this format. For example, in the
1.546 + * English locale, with grouping on, the number 1234567 might be formatted
1.547 + * as "1,234,567". The grouping separator as well as the size of each group
1.548 + * is locale dependant and is determined by sub-classes of NumberFormat.
1.549 + * @see #setGroupingUsed
1.550 + */
1.551 + public boolean isGroupingUsed() {
1.552 + return groupingUsed;
1.553 + }
1.554 +
1.555 + /**
1.556 + * Set whether or not grouping will be used in this format.
1.557 + * @see #isGroupingUsed
1.558 + */
1.559 + public void setGroupingUsed(boolean newValue) {
1.560 + groupingUsed = newValue;
1.561 + }
1.562 +
1.563 + /**
1.564 + * Returns the maximum number of digits allowed in the integer portion of a
1.565 + * number.
1.566 + * @see #setMaximumIntegerDigits
1.567 + */
1.568 + public int getMaximumIntegerDigits() {
1.569 + return maximumIntegerDigits;
1.570 + }
1.571 +
1.572 + /**
1.573 + * Sets the maximum number of digits allowed in the integer portion of a
1.574 + * number. maximumIntegerDigits must be >= minimumIntegerDigits. If the
1.575 + * new value for maximumIntegerDigits is less than the current value
1.576 + * of minimumIntegerDigits, then minimumIntegerDigits will also be set to
1.577 + * the new value.
1.578 + * @param newValue the maximum number of integer digits to be shown; if
1.579 + * less than zero, then zero is used. The concrete subclass may enforce an
1.580 + * upper limit to this value appropriate to the numeric type being formatted.
1.581 + * @see #getMaximumIntegerDigits
1.582 + */
1.583 + public void setMaximumIntegerDigits(int newValue) {
1.584 + maximumIntegerDigits = Math.max(0,newValue);
1.585 + if (minimumIntegerDigits > maximumIntegerDigits) {
1.586 + minimumIntegerDigits = maximumIntegerDigits;
1.587 + }
1.588 + }
1.589 +
1.590 + /**
1.591 + * Returns the minimum number of digits allowed in the integer portion of a
1.592 + * number.
1.593 + * @see #setMinimumIntegerDigits
1.594 + */
1.595 + public int getMinimumIntegerDigits() {
1.596 + return minimumIntegerDigits;
1.597 + }
1.598 +
1.599 + /**
1.600 + * Sets the minimum number of digits allowed in the integer portion of a
1.601 + * number. minimumIntegerDigits must be <= maximumIntegerDigits. If the
1.602 + * new value for minimumIntegerDigits exceeds the current value
1.603 + * of maximumIntegerDigits, then maximumIntegerDigits will also be set to
1.604 + * the new value
1.605 + * @param newValue the minimum number of integer digits to be shown; if
1.606 + * less than zero, then zero is used. The concrete subclass may enforce an
1.607 + * upper limit to this value appropriate to the numeric type being formatted.
1.608 + * @see #getMinimumIntegerDigits
1.609 + */
1.610 + public void setMinimumIntegerDigits(int newValue) {
1.611 + minimumIntegerDigits = Math.max(0,newValue);
1.612 + if (minimumIntegerDigits > maximumIntegerDigits) {
1.613 + maximumIntegerDigits = minimumIntegerDigits;
1.614 + }
1.615 + }
1.616 +
1.617 + /**
1.618 + * Returns the maximum number of digits allowed in the fraction portion of a
1.619 + * number.
1.620 + * @see #setMaximumFractionDigits
1.621 + */
1.622 + public int getMaximumFractionDigits() {
1.623 + return maximumFractionDigits;
1.624 + }
1.625 +
1.626 + /**
1.627 + * Sets the maximum number of digits allowed in the fraction portion of a
1.628 + * number. maximumFractionDigits must be >= minimumFractionDigits. If the
1.629 + * new value for maximumFractionDigits is less than the current value
1.630 + * of minimumFractionDigits, then minimumFractionDigits will also be set to
1.631 + * the new value.
1.632 + * @param newValue the maximum number of fraction digits to be shown; if
1.633 + * less than zero, then zero is used. The concrete subclass may enforce an
1.634 + * upper limit to this value appropriate to the numeric type being formatted.
1.635 + * @see #getMaximumFractionDigits
1.636 + */
1.637 + public void setMaximumFractionDigits(int newValue) {
1.638 + maximumFractionDigits = Math.max(0,newValue);
1.639 + if (maximumFractionDigits < minimumFractionDigits) {
1.640 + minimumFractionDigits = maximumFractionDigits;
1.641 + }
1.642 + }
1.643 +
1.644 + /**
1.645 + * Returns the minimum number of digits allowed in the fraction portion of a
1.646 + * number.
1.647 + * @see #setMinimumFractionDigits
1.648 + */
1.649 + public int getMinimumFractionDigits() {
1.650 + return minimumFractionDigits;
1.651 + }
1.652 +
1.653 + /**
1.654 + * Sets the minimum number of digits allowed in the fraction portion of a
1.655 + * number. minimumFractionDigits must be <= maximumFractionDigits. If the
1.656 + * new value for minimumFractionDigits exceeds the current value
1.657 + * of maximumFractionDigits, then maximumIntegerDigits will also be set to
1.658 + * the new value
1.659 + * @param newValue the minimum number of fraction digits to be shown; if
1.660 + * less than zero, then zero is used. The concrete subclass may enforce an
1.661 + * upper limit to this value appropriate to the numeric type being formatted.
1.662 + * @see #getMinimumFractionDigits
1.663 + */
1.664 + public void setMinimumFractionDigits(int newValue) {
1.665 + minimumFractionDigits = Math.max(0,newValue);
1.666 + if (maximumFractionDigits < minimumFractionDigits) {
1.667 + maximumFractionDigits = minimumFractionDigits;
1.668 + }
1.669 + }
1.670 +
1.671 + /**
1.672 + * Gets the currency used by this number format when formatting
1.673 + * currency values. The initial value is derived in a locale dependent
1.674 + * way. The returned value may be null if no valid
1.675 + * currency could be determined and no currency has been set using
1.676 + * {@link #setCurrency(java.util.Currency) setCurrency}.
1.677 + * <p>
1.678 + * The default implementation throws
1.679 + * <code>UnsupportedOperationException</code>.
1.680 + *
1.681 + * @return the currency used by this number format, or <code>null</code>
1.682 + * @exception UnsupportedOperationException if the number format class
1.683 + * doesn't implement currency formatting
1.684 + * @since 1.4
1.685 + */
1.686 + public Currency getCurrency() {
1.687 + throw new UnsupportedOperationException();
1.688 + }
1.689 +
1.690 + /**
1.691 + * Sets the currency used by this number format when formatting
1.692 + * currency values. This does not update the minimum or maximum
1.693 + * number of fraction digits used by the number format.
1.694 + * <p>
1.695 + * The default implementation throws
1.696 + * <code>UnsupportedOperationException</code>.
1.697 + *
1.698 + * @param currency the new currency to be used by this number format
1.699 + * @exception UnsupportedOperationException if the number format class
1.700 + * doesn't implement currency formatting
1.701 + * @exception NullPointerException if <code>currency</code> is null
1.702 + * @since 1.4
1.703 + */
1.704 + public void setCurrency(Currency currency) {
1.705 + throw new UnsupportedOperationException();
1.706 + }
1.707 +
1.708 + /**
1.709 + * Gets the {@link java.math.RoundingMode} used in this NumberFormat.
1.710 + * The default implementation of this method in NumberFormat
1.711 + * always throws {@link java.lang.UnsupportedOperationException}.
1.712 + * Subclasses which handle different rounding modes should override
1.713 + * this method.
1.714 + *
1.715 + * @exception UnsupportedOperationException The default implementation
1.716 + * always throws this exception
1.717 + * @return The <code>RoundingMode</code> used for this NumberFormat.
1.718 + * @see #setRoundingMode(RoundingMode)
1.719 + * @since 1.6
1.720 + */
1.721 + public RoundingMode getRoundingMode() {
1.722 + throw new UnsupportedOperationException();
1.723 + }
1.724 +
1.725 + /**
1.726 + * Sets the {@link java.math.RoundingMode} used in this NumberFormat.
1.727 + * The default implementation of this method in NumberFormat always
1.728 + * throws {@link java.lang.UnsupportedOperationException}.
1.729 + * Subclasses which handle different rounding modes should override
1.730 + * this method.
1.731 + *
1.732 + * @exception UnsupportedOperationException The default implementation
1.733 + * always throws this exception
1.734 + * @exception NullPointerException if <code>roundingMode</code> is null
1.735 + * @param roundingMode The <code>RoundingMode</code> to be used
1.736 + * @see #getRoundingMode()
1.737 + * @since 1.6
1.738 + */
1.739 + public void setRoundingMode(RoundingMode roundingMode) {
1.740 + throw new UnsupportedOperationException();
1.741 + }
1.742 +
1.743 + // =======================privates===============================
1.744 +
1.745 + private static NumberFormat getInstance(Locale desiredLocale,
1.746 + int choice) {
1.747 + // Check whether a provider can provide an implementation that's closer
1.748 + // to the requested locale than what the Java runtime itself can provide.
1.749 + LocaleServiceProviderPool pool =
1.750 + LocaleServiceProviderPool.getPool(NumberFormatProvider.class);
1.751 + if (pool.hasProviders()) {
1.752 + NumberFormat providersInstance = pool.getLocalizedObject(
1.753 + NumberFormatGetter.INSTANCE,
1.754 + desiredLocale,
1.755 + choice);
1.756 + if (providersInstance != null) {
1.757 + return providersInstance;
1.758 + }
1.759 + }
1.760 +
1.761 + /* try the cache first */
1.762 + String[] numberPatterns = (String[])cachedLocaleData.get(desiredLocale);
1.763 + if (numberPatterns == null) { /* cache miss */
1.764 + ResourceBundle resource = LocaleData.getNumberFormatData(desiredLocale);
1.765 + numberPatterns = resource.getStringArray("NumberPatterns");
1.766 + /* update cache */
1.767 + cachedLocaleData.put(desiredLocale, numberPatterns);
1.768 + }
1.769 +
1.770 + DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance(desiredLocale);
1.771 + int entry = (choice == INTEGERSTYLE) ? NUMBERSTYLE : choice;
1.772 + DecimalFormat format = new DecimalFormat(numberPatterns[entry], symbols);
1.773 +
1.774 + if (choice == INTEGERSTYLE) {
1.775 + format.setMaximumFractionDigits(0);
1.776 + format.setDecimalSeparatorAlwaysShown(false);
1.777 + format.setParseIntegerOnly(true);
1.778 + } else if (choice == CURRENCYSTYLE) {
1.779 + format.adjustForCurrencyDefaultFractionDigits();
1.780 + }
1.781 +
1.782 + return format;
1.783 + }
1.784 +
1.785 + /**
1.786 + * First, read in the default serializable data.
1.787 + *
1.788 + * Then, if <code>serialVersionOnStream</code> is less than 1, indicating that
1.789 + * the stream was written by JDK 1.1,
1.790 + * set the <code>int</code> fields such as <code>maximumIntegerDigits</code>
1.791 + * to be equal to the <code>byte</code> fields such as <code>maxIntegerDigits</code>,
1.792 + * since the <code>int</code> fields were not present in JDK 1.1.
1.793 + * Finally, set serialVersionOnStream back to the maximum allowed value so that
1.794 + * default serialization will work properly if this object is streamed out again.
1.795 + *
1.796 + * <p>If <code>minimumIntegerDigits</code> is greater than
1.797 + * <code>maximumIntegerDigits</code> or <code>minimumFractionDigits</code>
1.798 + * is greater than <code>maximumFractionDigits</code>, then the stream data
1.799 + * is invalid and this method throws an <code>InvalidObjectException</code>.
1.800 + * In addition, if any of these values is negative, then this method throws
1.801 + * an <code>InvalidObjectException</code>.
1.802 + *
1.803 + * @since 1.2
1.804 + */
1.805 + private void readObject(ObjectInputStream stream)
1.806 + throws IOException, ClassNotFoundException
1.807 + {
1.808 + stream.defaultReadObject();
1.809 + if (serialVersionOnStream < 1) {
1.810 + // Didn't have additional int fields, reassign to use them.
1.811 + maximumIntegerDigits = maxIntegerDigits;
1.812 + minimumIntegerDigits = minIntegerDigits;
1.813 + maximumFractionDigits = maxFractionDigits;
1.814 + minimumFractionDigits = minFractionDigits;
1.815 + }
1.816 + if (minimumIntegerDigits > maximumIntegerDigits ||
1.817 + minimumFractionDigits > maximumFractionDigits ||
1.818 + minimumIntegerDigits < 0 || minimumFractionDigits < 0) {
1.819 + throw new InvalidObjectException("Digit count range invalid");
1.820 + }
1.821 + serialVersionOnStream = currentSerialVersion;
1.822 + }
1.823 +
1.824 + /**
1.825 + * Write out the default serializable data, after first setting
1.826 + * the <code>byte</code> fields such as <code>maxIntegerDigits</code> to be
1.827 + * equal to the <code>int</code> fields such as <code>maximumIntegerDigits</code>
1.828 + * (or to <code>Byte.MAX_VALUE</code>, whichever is smaller), for compatibility
1.829 + * with the JDK 1.1 version of the stream format.
1.830 + *
1.831 + * @since 1.2
1.832 + */
1.833 + private void writeObject(ObjectOutputStream stream)
1.834 + throws IOException
1.835 + {
1.836 + maxIntegerDigits = (maximumIntegerDigits > Byte.MAX_VALUE) ?
1.837 + Byte.MAX_VALUE : (byte)maximumIntegerDigits;
1.838 + minIntegerDigits = (minimumIntegerDigits > Byte.MAX_VALUE) ?
1.839 + Byte.MAX_VALUE : (byte)minimumIntegerDigits;
1.840 + maxFractionDigits = (maximumFractionDigits > Byte.MAX_VALUE) ?
1.841 + Byte.MAX_VALUE : (byte)maximumFractionDigits;
1.842 + minFractionDigits = (minimumFractionDigits > Byte.MAX_VALUE) ?
1.843 + Byte.MAX_VALUE : (byte)minimumFractionDigits;
1.844 + stream.defaultWriteObject();
1.845 + }
1.846 +
1.847 + /**
1.848 + * Cache to hold the NumberPatterns of a Locale.
1.849 + */
1.850 + private static final Hashtable cachedLocaleData = new Hashtable(3);
1.851 +
1.852 + // Constants used by factory methods to specify a style of format.
1.853 + private static final int NUMBERSTYLE = 0;
1.854 + private static final int CURRENCYSTYLE = 1;
1.855 + private static final int PERCENTSTYLE = 2;
1.856 + private static final int SCIENTIFICSTYLE = 3;
1.857 + private static final int INTEGERSTYLE = 4;
1.858 +
1.859 + /**
1.860 + * True if the grouping (i.e. thousands) separator is used when
1.861 + * formatting and parsing numbers.
1.862 + *
1.863 + * @serial
1.864 + * @see #isGroupingUsed
1.865 + */
1.866 + private boolean groupingUsed = true;
1.867 +
1.868 + /**
1.869 + * The maximum number of digits allowed in the integer portion of a
1.870 + * number. <code>maxIntegerDigits</code> must be greater than or equal to
1.871 + * <code>minIntegerDigits</code>.
1.872 + * <p>
1.873 + * <strong>Note:</strong> This field exists only for serialization
1.874 + * compatibility with JDK 1.1. In Java platform 2 v1.2 and higher, the new
1.875 + * <code>int</code> field <code>maximumIntegerDigits</code> is used instead.
1.876 + * When writing to a stream, <code>maxIntegerDigits</code> is set to
1.877 + * <code>maximumIntegerDigits</code> or <code>Byte.MAX_VALUE</code>,
1.878 + * whichever is smaller. When reading from a stream, this field is used
1.879 + * only if <code>serialVersionOnStream</code> is less than 1.
1.880 + *
1.881 + * @serial
1.882 + * @see #getMaximumIntegerDigits
1.883 + */
1.884 + private byte maxIntegerDigits = 40;
1.885 +
1.886 + /**
1.887 + * The minimum number of digits allowed in the integer portion of a
1.888 + * number. <code>minimumIntegerDigits</code> must be less than or equal to
1.889 + * <code>maximumIntegerDigits</code>.
1.890 + * <p>
1.891 + * <strong>Note:</strong> This field exists only for serialization
1.892 + * compatibility with JDK 1.1. In Java platform 2 v1.2 and higher, the new
1.893 + * <code>int</code> field <code>minimumIntegerDigits</code> is used instead.
1.894 + * When writing to a stream, <code>minIntegerDigits</code> is set to
1.895 + * <code>minimumIntegerDigits</code> or <code>Byte.MAX_VALUE</code>,
1.896 + * whichever is smaller. When reading from a stream, this field is used
1.897 + * only if <code>serialVersionOnStream</code> is less than 1.
1.898 + *
1.899 + * @serial
1.900 + * @see #getMinimumIntegerDigits
1.901 + */
1.902 + private byte minIntegerDigits = 1;
1.903 +
1.904 + /**
1.905 + * The maximum number of digits allowed in the fractional portion of a
1.906 + * number. <code>maximumFractionDigits</code> must be greater than or equal to
1.907 + * <code>minimumFractionDigits</code>.
1.908 + * <p>
1.909 + * <strong>Note:</strong> This field exists only for serialization
1.910 + * compatibility with JDK 1.1. In Java platform 2 v1.2 and higher, the new
1.911 + * <code>int</code> field <code>maximumFractionDigits</code> is used instead.
1.912 + * When writing to a stream, <code>maxFractionDigits</code> is set to
1.913 + * <code>maximumFractionDigits</code> or <code>Byte.MAX_VALUE</code>,
1.914 + * whichever is smaller. When reading from a stream, this field is used
1.915 + * only if <code>serialVersionOnStream</code> is less than 1.
1.916 + *
1.917 + * @serial
1.918 + * @see #getMaximumFractionDigits
1.919 + */
1.920 + private byte maxFractionDigits = 3; // invariant, >= minFractionDigits
1.921 +
1.922 + /**
1.923 + * The minimum number of digits allowed in the fractional portion of a
1.924 + * number. <code>minimumFractionDigits</code> must be less than or equal to
1.925 + * <code>maximumFractionDigits</code>.
1.926 + * <p>
1.927 + * <strong>Note:</strong> This field exists only for serialization
1.928 + * compatibility with JDK 1.1. In Java platform 2 v1.2 and higher, the new
1.929 + * <code>int</code> field <code>minimumFractionDigits</code> is used instead.
1.930 + * When writing to a stream, <code>minFractionDigits</code> is set to
1.931 + * <code>minimumFractionDigits</code> or <code>Byte.MAX_VALUE</code>,
1.932 + * whichever is smaller. When reading from a stream, this field is used
1.933 + * only if <code>serialVersionOnStream</code> is less than 1.
1.934 + *
1.935 + * @serial
1.936 + * @see #getMinimumFractionDigits
1.937 + */
1.938 + private byte minFractionDigits = 0;
1.939 +
1.940 + /**
1.941 + * True if this format will parse numbers as integers only.
1.942 + *
1.943 + * @serial
1.944 + * @see #isParseIntegerOnly
1.945 + */
1.946 + private boolean parseIntegerOnly = false;
1.947 +
1.948 + // new fields for 1.2. byte is too small for integer digits.
1.949 +
1.950 + /**
1.951 + * The maximum number of digits allowed in the integer portion of a
1.952 + * number. <code>maximumIntegerDigits</code> must be greater than or equal to
1.953 + * <code>minimumIntegerDigits</code>.
1.954 + *
1.955 + * @serial
1.956 + * @since 1.2
1.957 + * @see #getMaximumIntegerDigits
1.958 + */
1.959 + private int maximumIntegerDigits = 40;
1.960 +
1.961 + /**
1.962 + * The minimum number of digits allowed in the integer portion of a
1.963 + * number. <code>minimumIntegerDigits</code> must be less than or equal to
1.964 + * <code>maximumIntegerDigits</code>.
1.965 + *
1.966 + * @serial
1.967 + * @since 1.2
1.968 + * @see #getMinimumIntegerDigits
1.969 + */
1.970 + private int minimumIntegerDigits = 1;
1.971 +
1.972 + /**
1.973 + * The maximum number of digits allowed in the fractional portion of a
1.974 + * number. <code>maximumFractionDigits</code> must be greater than or equal to
1.975 + * <code>minimumFractionDigits</code>.
1.976 + *
1.977 + * @serial
1.978 + * @since 1.2
1.979 + * @see #getMaximumFractionDigits
1.980 + */
1.981 + private int maximumFractionDigits = 3; // invariant, >= minFractionDigits
1.982 +
1.983 + /**
1.984 + * The minimum number of digits allowed in the fractional portion of a
1.985 + * number. <code>minimumFractionDigits</code> must be less than or equal to
1.986 + * <code>maximumFractionDigits</code>.
1.987 + *
1.988 + * @serial
1.989 + * @since 1.2
1.990 + * @see #getMinimumFractionDigits
1.991 + */
1.992 + private int minimumFractionDigits = 0;
1.993 +
1.994 + static final int currentSerialVersion = 1;
1.995 +
1.996 + /**
1.997 + * Describes the version of <code>NumberFormat</code> present on the stream.
1.998 + * Possible values are:
1.999 + * <ul>
1.1000 + * <li><b>0</b> (or uninitialized): the JDK 1.1 version of the stream format.
1.1001 + * In this version, the <code>int</code> fields such as
1.1002 + * <code>maximumIntegerDigits</code> were not present, and the <code>byte</code>
1.1003 + * fields such as <code>maxIntegerDigits</code> are used instead.
1.1004 + *
1.1005 + * <li><b>1</b>: the 1.2 version of the stream format. The values of the
1.1006 + * <code>byte</code> fields such as <code>maxIntegerDigits</code> are ignored,
1.1007 + * and the <code>int</code> fields such as <code>maximumIntegerDigits</code>
1.1008 + * are used instead.
1.1009 + * </ul>
1.1010 + * When streaming out a <code>NumberFormat</code>, the most recent format
1.1011 + * (corresponding to the highest allowable <code>serialVersionOnStream</code>)
1.1012 + * is always written.
1.1013 + *
1.1014 + * @serial
1.1015 + * @since 1.2
1.1016 + */
1.1017 + private int serialVersionOnStream = currentSerialVersion;
1.1018 +
1.1019 + // Removed "implements Cloneable" clause. Needs to update serialization
1.1020 + // ID for backward compatibility.
1.1021 + static final long serialVersionUID = -2308460125733713944L;
1.1022 +
1.1023 +
1.1024 + //
1.1025 + // class for AttributedCharacterIterator attributes
1.1026 + //
1.1027 + /**
1.1028 + * Defines constants that are used as attribute keys in the
1.1029 + * <code>AttributedCharacterIterator</code> returned
1.1030 + * from <code>NumberFormat.formatToCharacterIterator</code> and as
1.1031 + * field identifiers in <code>FieldPosition</code>.
1.1032 + *
1.1033 + * @since 1.4
1.1034 + */
1.1035 + public static class Field extends Format.Field {
1.1036 +
1.1037 + // Proclaim serial compatibility with 1.4 FCS
1.1038 + private static final long serialVersionUID = 7494728892700160890L;
1.1039 +
1.1040 + // table of all instances in this class, used by readResolve
1.1041 + private static final Map instanceMap = new HashMap(11);
1.1042 +
1.1043 + /**
1.1044 + * Creates a Field instance with the specified
1.1045 + * name.
1.1046 + *
1.1047 + * @param name Name of the attribute
1.1048 + */
1.1049 + protected Field(String name) {
1.1050 + super(name);
1.1051 + if (this.getClass() == NumberFormat.Field.class) {
1.1052 + instanceMap.put(name, this);
1.1053 + }
1.1054 + }
1.1055 +
1.1056 + /**
1.1057 + * Resolves instances being deserialized to the predefined constants.
1.1058 + *
1.1059 + * @throws InvalidObjectException if the constant could not be resolved.
1.1060 + * @return resolved NumberFormat.Field constant
1.1061 + */
1.1062 + protected Object readResolve() throws InvalidObjectException {
1.1063 + if (this.getClass() != NumberFormat.Field.class) {
1.1064 + throw new InvalidObjectException("subclass didn't correctly implement readResolve");
1.1065 + }
1.1066 +
1.1067 + Object instance = instanceMap.get(getName());
1.1068 + if (instance != null) {
1.1069 + return instance;
1.1070 + } else {
1.1071 + throw new InvalidObjectException("unknown attribute name");
1.1072 + }
1.1073 + }
1.1074 +
1.1075 + /**
1.1076 + * Constant identifying the integer field.
1.1077 + */
1.1078 + public static final Field INTEGER = new Field("integer");
1.1079 +
1.1080 + /**
1.1081 + * Constant identifying the fraction field.
1.1082 + */
1.1083 + public static final Field FRACTION = new Field("fraction");
1.1084 +
1.1085 + /**
1.1086 + * Constant identifying the exponent field.
1.1087 + */
1.1088 + public static final Field EXPONENT = new Field("exponent");
1.1089 +
1.1090 + /**
1.1091 + * Constant identifying the decimal separator field.
1.1092 + */
1.1093 + public static final Field DECIMAL_SEPARATOR =
1.1094 + new Field("decimal separator");
1.1095 +
1.1096 + /**
1.1097 + * Constant identifying the sign field.
1.1098 + */
1.1099 + public static final Field SIGN = new Field("sign");
1.1100 +
1.1101 + /**
1.1102 + * Constant identifying the grouping separator field.
1.1103 + */
1.1104 + public static final Field GROUPING_SEPARATOR =
1.1105 + new Field("grouping separator");
1.1106 +
1.1107 + /**
1.1108 + * Constant identifying the exponent symbol field.
1.1109 + */
1.1110 + public static final Field EXPONENT_SYMBOL = new
1.1111 + Field("exponent symbol");
1.1112 +
1.1113 + /**
1.1114 + * Constant identifying the percent field.
1.1115 + */
1.1116 + public static final Field PERCENT = new Field("percent");
1.1117 +
1.1118 + /**
1.1119 + * Constant identifying the permille field.
1.1120 + */
1.1121 + public static final Field PERMILLE = new Field("per mille");
1.1122 +
1.1123 + /**
1.1124 + * Constant identifying the currency field.
1.1125 + */
1.1126 + public static final Field CURRENCY = new Field("currency");
1.1127 +
1.1128 + /**
1.1129 + * Constant identifying the exponent sign field.
1.1130 + */
1.1131 + public static final Field EXPONENT_SIGN = new Field("exponent sign");
1.1132 + }
1.1133 +
1.1134 + /**
1.1135 + * Obtains a NumberFormat instance from a NumberFormatProvider implementation.
1.1136 + */
1.1137 + private static class NumberFormatGetter
1.1138 + implements LocaleServiceProviderPool.LocalizedObjectGetter<NumberFormatProvider,
1.1139 + NumberFormat> {
1.1140 + private static final NumberFormatGetter INSTANCE = new NumberFormatGetter();
1.1141 +
1.1142 + public NumberFormat getObject(NumberFormatProvider numberFormatProvider,
1.1143 + Locale locale,
1.1144 + String key,
1.1145 + Object... params) {
1.1146 + assert params.length == 1;
1.1147 + int choice = (Integer)params[0];
1.1148 +
1.1149 + switch (choice) {
1.1150 + case NUMBERSTYLE:
1.1151 + return numberFormatProvider.getNumberInstance(locale);
1.1152 + case PERCENTSTYLE:
1.1153 + return numberFormatProvider.getPercentInstance(locale);
1.1154 + case CURRENCYSTYLE:
1.1155 + return numberFormatProvider.getCurrencyInstance(locale);
1.1156 + case INTEGERSTYLE:
1.1157 + return numberFormatProvider.getIntegerInstance(locale);
1.1158 + default:
1.1159 + assert false : choice;
1.1160 + }
1.1161 +
1.1162 + return null;
1.1163 + }
1.1164 + }
1.1165 +}