History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/java/text/DecimalFormatSymbols.java (1 of 18352 files). Show all

Unified · Split

java/pkg/java/text/DecimalFormatSymbols.java+837−0
@@ -0,0 +1,837 @@
1+/*
2+ * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+
26+/*
27+ * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
28+ * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
29+ *
30+ * The original version of this source code and documentation is copyrighted
31+ * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
32+ * materials are provided under terms of a License Agreement between Taligent
33+ * and Sun. This technology is protected by multiple US and International
34+ * patents. This notice and attribution to Taligent may not be removed.
35+ * Taligent is a registered trademark of Taligent, Inc.
36+ *
37+ */
38+
39+package java.text;
40+
41+import java.io.IOException;
42+import java.io.ObjectInputStream;
43+import java.io.Serializable;
44+import java.text.spi.DecimalFormatSymbolsProvider;
45+import java.util.Currency;
46+import java.util.Locale;
47+import java.util.ResourceBundle;
48+import java.util.concurrent.ConcurrentHashMap;
49+
50+import sun.util.LocaleServiceProviderPool;
51+import sun.util.resources.LocaleData;
52+
53+/**
54+ * This class represents the set of symbols (such as the decimal separator,
55+ * the grouping separator, and so on) needed by <code>DecimalFormat</code>
56+ * to format numbers. <code>DecimalFormat</code> creates for itself an instance of
57+ * <code>DecimalFormatSymbols</code> from its locale data. If you need to change any
58+ * of these symbols, you can get the <code>DecimalFormatSymbols</code> object from
59+ * your <code>DecimalFormat</code> and modify it.
60+ *
61+ * @see java.util.Locale
62+ * @see DecimalFormat
63+ * @author Mark Davis
64+ * @author Alan Liu
65+ */
66+
67+public class DecimalFormatSymbols implements Cloneable, Serializable {
68+
69+ /**
70+ * Create a DecimalFormatSymbols object for the default locale.
71+ * This constructor can only construct instances for the locales
72+ * supported by the Java runtime environment, not for those
73+ * supported by installed
74+ * {@link java.text.spi.DecimalFormatSymbolsProvider DecimalFormatSymbolsProvider}
75+ * implementations. For full locale coverage, use the
76+ * {@link #getInstance(Locale) getInstance} method.
77+ */
78+ public DecimalFormatSymbols() {
79+ initialize( Locale.getDefault(Locale.Category.FORMAT) );
80+ }
81+
82+ /**
83+ * Create a DecimalFormatSymbols object for the given locale.
84+ * This constructor can only construct instances for the locales
85+ * supported by the Java runtime environment, not for those
86+ * supported by installed
87+ * {@link java.text.spi.DecimalFormatSymbolsProvider DecimalFormatSymbolsProvider}
88+ * implementations. For full locale coverage, use the
89+ * {@link #getInstance(Locale) getInstance} method.
90+ *
91+ * @exception NullPointerException if <code>locale</code> is null
92+ */
93+ public DecimalFormatSymbols( Locale locale ) {
94+ initialize( locale );
95+ }
96+
97+ /**
98+ * Returns an array of all locales for which the
99+ * <code>getInstance</code> methods of this class can return
100+ * localized instances.
101+ * The returned array represents the union of locales supported by the Java
102+ * runtime and by installed
103+ * {@link java.text.spi.DecimalFormatSymbolsProvider DecimalFormatSymbolsProvider}
104+ * implementations. It must contain at least a <code>Locale</code>
105+ * instance equal to {@link java.util.Locale#US Locale.US}.
106+ *
107+ * @return An array of locales for which localized
108+ * <code>DecimalFormatSymbols</code> instances are available.
109+ * @since 1.6
110+ */
111+ public static Locale[] getAvailableLocales() {
112+ LocaleServiceProviderPool pool =
113+ LocaleServiceProviderPool.getPool(DecimalFormatSymbolsProvider.class);
114+ return pool.getAvailableLocales();
115+ }
116+
117+ /**
118+ * Gets the <code>DecimalFormatSymbols</code> instance for the default
119+ * locale. This method provides access to <code>DecimalFormatSymbols</code>
120+ * instances for locales supported by the Java runtime itself as well
121+ * as for those supported by installed
122+ * {@link java.text.spi.DecimalFormatSymbolsProvider
123+ * DecimalFormatSymbolsProvider} implementations.
124+ * @return a <code>DecimalFormatSymbols</code> instance.
125+ * @since 1.6
126+ */
127+ public static final DecimalFormatSymbols getInstance() {
128+ return getInstance(Locale.getDefault(Locale.Category.FORMAT));
129+ }
130+
131+ /**
132+ * Gets the <code>DecimalFormatSymbols</code> instance for the specified
133+ * locale. This method provides access to <code>DecimalFormatSymbols</code>
134+ * instances for locales supported by the Java runtime itself as well
135+ * as for those supported by installed
136+ * {@link java.text.spi.DecimalFormatSymbolsProvider
137+ * DecimalFormatSymbolsProvider} implementations.
138+ * @param locale the desired locale.
139+ * @return a <code>DecimalFormatSymbols</code> instance.
140+ * @exception NullPointerException if <code>locale</code> is null
141+ * @since 1.6
142+ */
143+ public static final DecimalFormatSymbols getInstance(Locale locale) {
144+
145+ // Check whether a provider can provide an implementation that's closer
146+ // to the requested locale than what the Java runtime itself can provide.
147+ LocaleServiceProviderPool pool =
148+ LocaleServiceProviderPool.getPool(DecimalFormatSymbolsProvider.class);
149+ if (pool.hasProviders()) {
150+ DecimalFormatSymbols providersInstance = pool.getLocalizedObject(
151+ DecimalFormatSymbolsGetter.INSTANCE, locale);
152+ if (providersInstance != null) {
153+ return providersInstance;
154+ }
155+ }
156+
157+ return new DecimalFormatSymbols(locale);
158+ }
159+
160+ /**
161+ * Gets the character used for zero. Different for Arabic, etc.
162+ */
163+ public char getZeroDigit() {
164+ return zeroDigit;
165+ }
166+
167+ /**
168+ * Sets the character used for zero. Different for Arabic, etc.
169+ */
170+ public void setZeroDigit(char zeroDigit) {
171+ this.zeroDigit = zeroDigit;
172+ }
173+
174+ /**
175+ * Gets the character used for thousands separator. Different for French, etc.
176+ */
177+ public char getGroupingSeparator() {
178+ return groupingSeparator;
179+ }
180+
181+ /**
182+ * Sets the character used for thousands separator. Different for French, etc.
183+ */
184+ public void setGroupingSeparator(char groupingSeparator) {
185+ this.groupingSeparator = groupingSeparator;
186+ }
187+
188+ /**
189+ * Gets the character used for decimal sign. Different for French, etc.
190+ */
191+ public char getDecimalSeparator() {
192+ return decimalSeparator;
193+ }
194+
195+ /**
196+ * Sets the character used for decimal sign. Different for French, etc.
197+ */
198+ public void setDecimalSeparator(char decimalSeparator) {
199+ this.decimalSeparator = decimalSeparator;
200+ }
201+
202+ /**
203+ * Gets the character used for per mille sign. Different for Arabic, etc.
204+ */
205+ public char getPerMill() {
206+ return perMill;
207+ }
208+
209+ /**
210+ * Sets the character used for per mille sign. Different for Arabic, etc.
211+ */
212+ public void setPerMill(char perMill) {
213+ this.perMill = perMill;
214+ }
215+
216+ /**
217+ * Gets the character used for percent sign. Different for Arabic, etc.
218+ */
219+ public char getPercent() {
220+ return percent;
221+ }
222+
223+ /**
224+ * Sets the character used for percent sign. Different for Arabic, etc.
225+ */
226+ public void setPercent(char percent) {
227+ this.percent = percent;
228+ }
229+
230+ /**
231+ * Gets the character used for a digit in a pattern.
232+ */
233+ public char getDigit() {
234+ return digit;
235+ }
236+
237+ /**
238+ * Sets the character used for a digit in a pattern.
239+ */
240+ public void setDigit(char digit) {
241+ this.digit = digit;
242+ }
243+
244+ /**
245+ * Gets the character used to separate positive and negative subpatterns
246+ * in a pattern.
247+ */
248+ public char getPatternSeparator() {
249+ return patternSeparator;
250+ }
251+
252+ /**
253+ * Sets the character used to separate positive and negative subpatterns
254+ * in a pattern.
255+ */
256+ public void setPatternSeparator(char patternSeparator) {
257+ this.patternSeparator = patternSeparator;
258+ }
259+
260+ /**
261+ * Gets the string used to represent infinity. Almost always left
262+ * unchanged.
263+ */
264+ public String getInfinity() {
265+ return infinity;
266+ }
267+
268+ /**
269+ * Sets the string used to represent infinity. Almost always left
270+ * unchanged.
271+ */
272+ public void setInfinity(String infinity) {
273+ this.infinity = infinity;
274+ }
275+
276+ /**
277+ * Gets the string used to represent "not a number". Almost always left
278+ * unchanged.
279+ */
280+ public String getNaN() {
281+ return NaN;
282+ }
283+
284+ /**
285+ * Sets the string used to represent "not a number". Almost always left
286+ * unchanged.
287+ */
288+ public void setNaN(String NaN) {
289+ this.NaN = NaN;
290+ }
291+
292+ /**
293+ * Gets the character used to represent minus sign. If no explicit
294+ * negative format is specified, one is formed by prefixing
295+ * minusSign to the positive format.
296+ */
297+ public char getMinusSign() {
298+ return minusSign;
299+ }
300+
301+ /**
302+ * Sets the character used to represent minus sign. If no explicit
303+ * negative format is specified, one is formed by prefixing
304+ * minusSign to the positive format.
305+ */
306+ public void setMinusSign(char minusSign) {
307+ this.minusSign = minusSign;
308+ }
309+
310+ /**
311+ * Returns the currency symbol for the currency of these
312+ * DecimalFormatSymbols in their locale.
313+ * @since 1.2
314+ */
315+ public String getCurrencySymbol()
316+ {
317+ return currencySymbol;
318+ }
319+
320+ /**
321+ * Sets the currency symbol for the currency of these
322+ * DecimalFormatSymbols in their locale.
323+ * @since 1.2
324+ */
325+ public void setCurrencySymbol(String currency)
326+ {
327+ currencySymbol = currency;
328+ }
329+
330+ /**
331+ * Returns the ISO 4217 currency code of the currency of these
332+ * DecimalFormatSymbols.
333+ * @since 1.2
334+ */
335+ public String getInternationalCurrencySymbol()
336+ {
337+ return intlCurrencySymbol;
338+ }
339+
340+ /**
341+ * Sets the ISO 4217 currency code of the currency of these
342+ * DecimalFormatSymbols.
343+ * If the currency code is valid (as defined by
344+ * {@link java.util.Currency#getInstance(java.lang.String) Currency.getInstance}),
345+ * this also sets the currency attribute to the corresponding Currency
346+ * instance and the currency symbol attribute to the currency's symbol
347+ * in the DecimalFormatSymbols' locale. If the currency code is not valid,
348+ * then the currency attribute is set to null and the currency symbol
349+ * attribute is not modified.
350+ *
351+ * @see #setCurrency
352+ * @see #setCurrencySymbol
353+ * @since 1.2
354+ */
355+ public void setInternationalCurrencySymbol(String currencyCode)
356+ {
357+ intlCurrencySymbol = currencyCode;
358+ currency = null;
359+ if (currencyCode != null) {
360+ try {
361+ currency = Currency.getInstance(currencyCode);
362+ currencySymbol = currency.getSymbol();
363+ } catch (IllegalArgumentException e) {
364+ }
365+ }
366+ }
367+
368+ /**
369+ * Gets the currency of these DecimalFormatSymbols. May be null if the
370+ * currency symbol attribute was previously set to a value that's not
371+ * a valid ISO 4217 currency code.
372+ *
373+ * @return the currency used, or null
374+ * @since 1.4
375+ */
376+ public Currency getCurrency() {
377+ return currency;
378+ }
379+
380+ /**
381+ * Sets the currency of these DecimalFormatSymbols.
382+ * This also sets the currency symbol attribute to the currency's symbol
383+ * in the DecimalFormatSymbols' locale, and the international currency
384+ * symbol attribute to the currency's ISO 4217 currency code.
385+ *
386+ * @param currency the new currency to be used
387+ * @exception NullPointerException if <code>currency</code> is null
388+ * @since 1.4
389+ * @see #setCurrencySymbol
390+ * @see #setInternationalCurrencySymbol
391+ */
392+ public void setCurrency(Currency currency) {
393+ if (currency == null) {
394+ throw new NullPointerException();
395+ }
396+ this.currency = currency;
397+ intlCurrencySymbol = currency.getCurrencyCode();
398+ currencySymbol = currency.getSymbol(locale);
399+ }
400+
401+
402+ /**
403+ * Returns the monetary decimal separator.
404+ * @since 1.2
405+ */
406+ public char getMonetaryDecimalSeparator()
407+ {
408+ return monetarySeparator;
409+ }
410+
411+ /**
412+ * Sets the monetary decimal separator.
413+ * @since 1.2
414+ */
415+ public void setMonetaryDecimalSeparator(char sep)
416+ {
417+ monetarySeparator = sep;
418+ }
419+
420+ //------------------------------------------------------------
421+ // BEGIN Package Private methods ... to be made public later
422+ //------------------------------------------------------------
423+
424+ /**
425+ * Returns the character used to separate the mantissa from the exponent.
426+ */
427+ char getExponentialSymbol()
428+ {
429+ return exponential;
430+ }
431+ /**
432+ * Returns the string used to separate the mantissa from the exponent.
433+ * Examples: "x10^" for 1.23x10^4, "E" for 1.23E4.
434+ *
435+ * @return the exponent separator string
436+ * @see #setExponentSeparator(java.lang.String)
437+ * @since 1.6
438+ */
439+ public String getExponentSeparator()
440+ {
441+ return exponentialSeparator;
442+ }
443+
444+ /**
445+ * Sets the character used to separate the mantissa from the exponent.
446+ */
447+ void setExponentialSymbol(char exp)
448+ {
449+ exponential = exp;
450+ }
451+
452+ /**
453+ * Sets the string used to separate the mantissa from the exponent.
454+ * Examples: "x10^" for 1.23x10^4, "E" for 1.23E4.
455+ *
456+ * @param exp the exponent separator string
457+ * @exception NullPointerException if <code>exp</code> is null
458+ * @see #getExponentSeparator()
459+ * @since 1.6
460+ */
461+ public void setExponentSeparator(String exp)
462+ {
463+ if (exp == null) {
464+ throw new NullPointerException();
465+ }
466+ exponentialSeparator = exp;
467+ }
468+
469+
470+ //------------------------------------------------------------
471+ // END Package Private methods ... to be made public later
472+ //------------------------------------------------------------
473+
474+ /**
475+ * Standard override.
476+ */
477+ public Object clone() {
478+ try {
479+ return (DecimalFormatSymbols)super.clone();
480+ // other fields are bit-copied
481+ } catch (CloneNotSupportedException e) {
482+ throw new InternalError();
483+ }
484+ }
485+
486+ /**
487+ * Override equals.
488+ */
489+ public boolean equals(Object obj) {
490+ if (obj == null) return false;
491+ if (this == obj) return true;
492+ if (getClass() != obj.getClass()) return false;
493+ DecimalFormatSymbols other = (DecimalFormatSymbols) obj;
494+ return (zeroDigit == other.zeroDigit &&
495+ groupingSeparator == other.groupingSeparator &&
496+ decimalSeparator == other.decimalSeparator &&
497+ percent == other.percent &&
498+ perMill == other.perMill &&
499+ digit == other.digit &&
500+ minusSign == other.minusSign &&
501+ patternSeparator == other.patternSeparator &&
502+ infinity.equals(other.infinity) &&
503+ NaN.equals(other.NaN) &&
504+ currencySymbol.equals(other.currencySymbol) &&
505+ intlCurrencySymbol.equals(other.intlCurrencySymbol) &&
506+ currency == other.currency &&
507+ monetarySeparator == other.monetarySeparator &&
508+ exponentialSeparator.equals(other.exponentialSeparator) &&
509+ locale.equals(other.locale));
510+ }
511+
512+ /**
513+ * Override hashCode.
514+ */
515+ public int hashCode() {
516+ int result = zeroDigit;
517+ result = result * 37 + groupingSeparator;
518+ result = result * 37 + decimalSeparator;
519+ return result;
520+ }
521+
522+ /**
523+ * Initializes the symbols from the FormatData resource bundle.
524+ */
525+ private void initialize( Locale locale ) {
526+ this.locale = locale;
527+
528+ // get resource bundle data - try the cache first
529+ boolean needCacheUpdate = false;
530+ Object[] data = cachedLocaleData.get(locale);
531+ if (data == null) { /* cache miss */
532+ // When numbering system is thai (Locale's extension contains u-nu-thai),
533+ // we read the data from th_TH_TH.
534+ Locale lookupLocale = locale;
535+ String numberType = locale.getUnicodeLocaleType("nu");
536+ if (numberType != null && numberType.equals("thai")) {
537+ lookupLocale = new Locale("th", "TH", "TH");
538+ }
539+ data = new Object[3];
540+ ResourceBundle rb = LocaleData.getNumberFormatData(lookupLocale);
541+ data[0] = rb.getStringArray("NumberElements");
542+ needCacheUpdate = true;
543+ }
544+
545+ String[] numberElements = (String[]) data[0];
546+
547+ decimalSeparator = numberElements[0].charAt(0);
548+ groupingSeparator = numberElements[1].charAt(0);
549+ patternSeparator = numberElements[2].charAt(0);
550+ percent = numberElements[3].charAt(0);
551+ zeroDigit = numberElements[4].charAt(0); //different for Arabic,etc.
552+ digit = numberElements[5].charAt(0);
553+ minusSign = numberElements[6].charAt(0);
554+ exponential = numberElements[7].charAt(0);
555+ exponentialSeparator = numberElements[7]; //string representation new since 1.6
556+ perMill = numberElements[8].charAt(0);
557+ infinity = numberElements[9];
558+ NaN = numberElements[10];
559+
560+ // Try to obtain the currency used in the locale's country.
561+ // Check for empty country string separately because it's a valid
562+ // country ID for Locale (and used for the C locale), but not a valid
563+ // ISO 3166 country code, and exceptions are expensive.
564+ if (!"".equals(locale.getCountry())) {
565+ try {
566+ currency = Currency.getInstance(locale);
567+ } catch (IllegalArgumentException e) {
568+ // use default values below for compatibility
569+ }
570+ }
571+ if (currency != null) {
572+ intlCurrencySymbol = currency.getCurrencyCode();
573+ if (data[1] != null && data[1] == intlCurrencySymbol) {
574+ currencySymbol = (String) data[2];
575+ } else {
576+ currencySymbol = currency.getSymbol(locale);
577+ data[1] = intlCurrencySymbol;
578+ data[2] = currencySymbol;
579+ needCacheUpdate = true;
580+ }
581+ } else {
582+ // default values
583+ intlCurrencySymbol = "XXX";
584+ try {
585+ currency = Currency.getInstance(intlCurrencySymbol);
586+ } catch (IllegalArgumentException e) {
587+ }
588+ currencySymbol = "\u00A4";
589+ }
590+ // Currently the monetary decimal separator is the same as the
591+ // standard decimal separator for all locales that we support.
592+ // If that changes, add a new entry to NumberElements.
593+ monetarySeparator = decimalSeparator;
594+
595+ if (needCacheUpdate) {
596+ cachedLocaleData.putIfAbsent(locale, data);
597+ }
598+ }
599+
600+ /**
601+ * Reads the default serializable fields, provides default values for objects
602+ * in older serial versions, and initializes non-serializable fields.
603+ * If <code>serialVersionOnStream</code>
604+ * is less than 1, initializes <code>monetarySeparator</code> to be
605+ * the same as <code>decimalSeparator</code> and <code>exponential</code>
606+ * to be 'E'.
607+ * If <code>serialVersionOnStream</code> is less than 2,
608+ * initializes <code>locale</code>to the root locale, and initializes
609+ * If <code>serialVersionOnStream</code> is less than 3, it initializes
610+ * <code>exponentialSeparator</code> using <code>exponential</code>.
611+ * Sets <code>serialVersionOnStream</code> back to the maximum allowed value so that
612+ * default serialization will work properly if this object is streamed out again.
613+ * Initializes the currency from the intlCurrencySymbol field.
614+ *
615+ * @since JDK 1.1.6
616+ */
617+ private void readObject(ObjectInputStream stream)
618+ throws IOException, ClassNotFoundException {
619+ stream.defaultReadObject();
620+ if (serialVersionOnStream < 1) {
621+ // Didn't have monetarySeparator or exponential field;
622+ // use defaults.
623+ monetarySeparator = decimalSeparator;
624+ exponential = 'E';
625+ }
626+ if (serialVersionOnStream < 2) {
627+ // didn't have locale; use root locale
628+ locale = Locale.ROOT;
629+ }
630+ if (serialVersionOnStream < 3) {
631+ // didn't have exponentialSeparator. Create one using exponential
632+ exponentialSeparator = Character.toString(exponential);
633+ }
634+ serialVersionOnStream = currentSerialVersion;
635+
636+ if (intlCurrencySymbol != null) {
637+ try {
638+ currency = Currency.getInstance(intlCurrencySymbol);
639+ } catch (IllegalArgumentException e) {
640+ }
641+ }
642+ }
643+
644+ /**
645+ * Character used for zero.
646+ *
647+ * @serial
648+ * @see #getZeroDigit
649+ */
650+ private char zeroDigit;
651+
652+ /**
653+ * Character used for thousands separator.
654+ *
655+ * @serial
656+ * @see #getGroupingSeparator
657+ */
658+ private char groupingSeparator;
659+
660+ /**
661+ * Character used for decimal sign.
662+ *
663+ * @serial
664+ * @see #getDecimalSeparator
665+ */
666+ private char decimalSeparator;
667+
668+ /**
669+ * Character used for per mille sign.
670+ *
671+ * @serial
672+ * @see #getPerMill
673+ */
674+ private char perMill;
675+
676+ /**
677+ * Character used for percent sign.
678+ * @serial
679+ * @see #getPercent
680+ */
681+ private char percent;
682+
683+ /**
684+ * Character used for a digit in a pattern.
685+ *
686+ * @serial
687+ * @see #getDigit
688+ */
689+ private char digit;
690+
691+ /**
692+ * Character used to separate positive and negative subpatterns
693+ * in a pattern.
694+ *
695+ * @serial
696+ * @see #getPatternSeparator
697+ */
698+ private char patternSeparator;
699+
700+ /**
701+ * String used to represent infinity.
702+ * @serial
703+ * @see #getInfinity
704+ */
705+ private String infinity;
706+
707+ /**
708+ * String used to represent "not a number".
709+ * @serial
710+ * @see #getNaN
711+ */
712+ private String NaN;
713+
714+ /**
715+ * Character used to represent minus sign.
716+ * @serial
717+ * @see #getMinusSign
718+ */
719+ private char minusSign;
720+
721+ /**
722+ * String denoting the local currency, e.g. "$".
723+ * @serial
724+ * @see #getCurrencySymbol
725+ */
726+ private String currencySymbol;
727+
728+ /**
729+ * ISO 4217 currency code denoting the local currency, e.g. "USD".
730+ * @serial
731+ * @see #getInternationalCurrencySymbol
732+ */
733+ private String intlCurrencySymbol;
734+
735+ /**
736+ * The decimal separator used when formatting currency values.
737+ * @serial
738+ * @since JDK 1.1.6
739+ * @see #getMonetaryDecimalSeparator
740+ */
741+ private char monetarySeparator; // Field new in JDK 1.1.6
742+
743+ /**
744+ * The character used to distinguish the exponent in a number formatted
745+ * in exponential notation, e.g. 'E' for a number such as "1.23E45".
746+ * <p>
747+ * Note that the public API provides no way to set this field,
748+ * even though it is supported by the implementation and the stream format.
749+ * The intent is that this will be added to the API in the future.
750+ *
751+ * @serial
752+ * @since JDK 1.1.6
753+ */
754+ private char exponential; // Field new in JDK 1.1.6
755+
756+ /**
757+ * The string used to separate the mantissa from the exponent.
758+ * Examples: "x10^" for 1.23x10^4, "E" for 1.23E4.
759+ * <p>
760+ * If both <code>exponential</code> and <code>exponentialSeparator</code>
761+ * exist, this <code>exponentialSeparator</code> has the precedence.
762+ *
763+ * @serial
764+ * @since 1.6
765+ */
766+ private String exponentialSeparator; // Field new in JDK 1.6
767+
768+ /**
769+ * The locale of these currency format symbols.
770+ *
771+ * @serial
772+ * @since 1.4
773+ */
774+ private Locale locale;
775+
776+ // currency; only the ISO code is serialized.
777+ private transient Currency currency;
778+
779+ // Proclaim JDK 1.1 FCS compatibility
780+ static final long serialVersionUID = 5772796243397350300L;
781+
782+ // The internal serial version which says which version was written
783+ // - 0 (default) for version up to JDK 1.1.5
784+ // - 1 for version from JDK 1.1.6, which includes two new fields:
785+ // monetarySeparator and exponential.
786+ // - 2 for version from J2SE 1.4, which includes locale field.
787+ // - 3 for version from J2SE 1.6, which includes exponentialSeparator field.
788+ private static final int currentSerialVersion = 3;
789+
790+ /**
791+ * Describes the version of <code>DecimalFormatSymbols</code> present on the stream.
792+ * Possible values are:
793+ * <ul>
794+ * <li><b>0</b> (or uninitialized): versions prior to JDK 1.1.6.
795+ *
796+ * <li><b>1</b>: Versions written by JDK 1.1.6 or later, which include
797+ * two new fields: <code>monetarySeparator</code> and <code>exponential</code>.
798+ * <li><b>2</b>: Versions written by J2SE 1.4 or later, which include a
799+ * new <code>locale</code> field.
800+ * <li><b>3</b>: Versions written by J2SE 1.6 or later, which include a
801+ * new <code>exponentialSeparator</code> field.
802+ * </ul>
803+ * When streaming out a <code>DecimalFormatSymbols</code>, the most recent format
804+ * (corresponding to the highest allowable <code>serialVersionOnStream</code>)
805+ * is always written.
806+ *
807+ * @serial
808+ * @since JDK 1.1.6
809+ */
810+ private int serialVersionOnStream = currentSerialVersion;
811+
812+ /**
813+ * cache to hold the NumberElements and the Currency
814+ * of a Locale.
815+ */
816+ private static final ConcurrentHashMap<Locale, Object[]> cachedLocaleData = new ConcurrentHashMap<Locale, Object[]>(3);
817+
818+ /**
819+ * Obtains a DecimalFormatSymbols instance from a DecimalFormatSymbolsProvider
820+ * implementation.
821+ */
822+ private static class DecimalFormatSymbolsGetter
823+ implements LocaleServiceProviderPool.LocalizedObjectGetter<DecimalFormatSymbolsProvider,
824+ DecimalFormatSymbols> {
825+ private static final DecimalFormatSymbolsGetter INSTANCE =
826+ new DecimalFormatSymbolsGetter();
827+
828+ public DecimalFormatSymbols getObject(
829+ DecimalFormatSymbolsProvider decimalFormatSymbolsProvider,
830+ Locale locale,
831+ String key,
832+ Object... params) {
833+ assert params.length == 0;
834+ return decimalFormatSymbolsProvider.getInstance(locale);
835+ }
836+ }
837+}