KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > text > DecimalFormatSymbols


1 /*
2  * @(#)DecimalFormatSymbols.java 1.41 04/05/10
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 /*
9  * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
10  * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
11  *
12  * The original version of this source code and documentation is copyrighted
13  * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
14  * materials are provided under terms of a License Agreement between Taligent
15  * and Sun. This technology is protected by multiple US and International
16  * patents. This notice and attribution to Taligent may not be removed.
17  * Taligent is a registered trademark of Taligent, Inc.
18  *
19  */

20
21 package java.text;
22
23 import java.io.IOException JavaDoc;
24 import java.io.ObjectInputStream JavaDoc;
25 import java.io.Serializable JavaDoc;
26 import java.util.Currency JavaDoc;
27 import java.util.Hashtable JavaDoc;
28 import java.util.Locale JavaDoc;
29 import java.util.ResourceBundle JavaDoc;
30 import sun.text.resources.LocaleData;
31
32 /**
33  * This class represents the set of symbols (such as the decimal separator,
34  * the grouping separator, and so on) needed by <code>DecimalFormat</code>
35  * to format numbers. <code>DecimalFormat</code> creates for itself an instance of
36  * <code>DecimalFormatSymbols</code> from its locale data. If you need to change any
37  * of these symbols, you can get the <code>DecimalFormatSymbols</code> object from
38  * your <code>DecimalFormat</code> and modify it.
39  *
40  * @see java.util.Locale
41  * @see DecimalFormat
42  * @version 1.41, 05/10/04
43  * @author Mark Davis
44  * @author Alan Liu
45  */

46
47 final public class DecimalFormatSymbols implements Cloneable JavaDoc, Serializable JavaDoc {
48
49     /**
50      * Create a DecimalFormatSymbols object for the default locale.
51      */

52     public DecimalFormatSymbols() {
53         initialize( Locale.getDefault() );
54     }
55
56     /**
57      * Create a DecimalFormatSymbols object for the given locale.
58      *
59      * @exception NullPointerException if <code>locale</code> is null
60      */

61     public DecimalFormatSymbols( Locale JavaDoc locale ) {
62         initialize( locale );
63     }
64
65     /**
66      * Gets the character used for zero. Different for Arabic, etc.
67      */

68     public char getZeroDigit() {
69         return zeroDigit;
70     }
71
72     /**
73      * Sets the character used for zero. Different for Arabic, etc.
74      */

75     public void setZeroDigit(char zeroDigit) {
76         this.zeroDigit = zeroDigit;
77     }
78
79     /**
80      * Gets the character used for thousands separator. Different for French, etc.
81      */

82     public char getGroupingSeparator() {
83         return groupingSeparator;
84     }
85
86     /**
87      * Sets the character used for thousands separator. Different for French, etc.
88      */

89     public void setGroupingSeparator(char groupingSeparator) {
90         this.groupingSeparator = groupingSeparator;
91     }
92
93     /**
94      * Gets the character used for decimal sign. Different for French, etc.
95      */

96     public char getDecimalSeparator() {
97         return decimalSeparator;
98     }
99
100     /**
101      * Sets the character used for decimal sign. Different for French, etc.
102      */

103     public void setDecimalSeparator(char decimalSeparator) {
104         this.decimalSeparator = decimalSeparator;
105     }
106
107     /**
108      * Gets the character used for per mille sign. Different for Arabic, etc.
109      */

110     public char getPerMill() {
111         return perMill;
112     }
113
114     /**
115      * Sets the character used for per mille sign. Different for Arabic, etc.
116      */

117     public void setPerMill(char perMill) {
118         this.perMill = perMill;
119     }
120
121     /**
122      * Gets the character used for percent sign. Different for Arabic, etc.
123      */

124     public char getPercent() {
125         return percent;
126     }
127
128     /**
129      * Sets the character used for percent sign. Different for Arabic, etc.
130      */

131     public void setPercent(char percent) {
132         this.percent = percent;
133     }
134
135     /**
136      * Gets the character used for a digit in a pattern.
137      */

138     public char getDigit() {
139         return digit;
140     }
141
142     /**
143      * Sets the character used for a digit in a pattern.
144      */

145     public void setDigit(char digit) {
146         this.digit = digit;
147     }
148
149     /**
150      * Gets the character used to separate positive and negative subpatterns
151      * in a pattern.
152      */

153     public char getPatternSeparator() {
154         return patternSeparator;
155     }
156
157     /**
158      * Sets the character used to separate positive and negative subpatterns
159      * in a pattern.
160      */

161     public void setPatternSeparator(char patternSeparator) {
162         this.patternSeparator = patternSeparator;
163     }
164
165     /**
166      * Gets the string used to represent infinity. Almost always left
167      * unchanged.
168      */

169     public String JavaDoc getInfinity() {
170         return infinity;
171     }
172
173     /**
174      * Sets the string used to represent infinity. Almost always left
175      * unchanged.
176      */

177     public void setInfinity(String JavaDoc infinity) {
178         this.infinity = infinity;
179     }
180
181     /**
182      * Gets the string used to represent "not a number". Almost always left
183      * unchanged.
184      */

185     public String JavaDoc getNaN() {
186         return NaN;
187     }
188
189     /**
190      * Sets the string used to represent "not a number". Almost always left
191      * unchanged.
192      */

193     public void setNaN(String JavaDoc NaN) {
194         this.NaN = NaN;
195     }
196
197     /**
198      * Gets the character used to represent minus sign. If no explicit
199      * negative format is specified, one is formed by prefixing
200      * minusSign to the positive format.
201      */

202     public char getMinusSign() {
203         return minusSign;
204     }
205
206     /**
207      * Sets the character used to represent minus sign. If no explicit
208      * negative format is specified, one is formed by prefixing
209      * minusSign to the positive format.
210      */

211     public void setMinusSign(char minusSign) {
212         this.minusSign = minusSign;
213     }
214
215     /**
216      * Returns the currency symbol for the currency of these
217      * DecimalFormatSymbols in their locale.
218      * @since 1.2
219      */

220     public String JavaDoc getCurrencySymbol()
221     {
222         return currencySymbol;
223     }
224
225     /**
226      * Sets the currency symbol for the currency of these
227      * DecimalFormatSymbols in their locale.
228      * @since 1.2
229      */

230     public void setCurrencySymbol(String JavaDoc currency)
231     {
232         currencySymbol = currency;
233     }
234
235     /**
236      * Returns the ISO 4217 currency code of the currency of these
237      * DecimalFormatSymbols.
238      * @since 1.2
239      */

240     public String JavaDoc getInternationalCurrencySymbol()
241     {
242         return intlCurrencySymbol;
243     }
244
245     /**
246      * Sets the ISO 4217 currency code of the currency of these
247      * DecimalFormatSymbols.
248      * If the currency code is valid (as defined by
249      * {@link java.util.Currency#getInstance(java.lang.String) Currency.getInstance}),
250      * this also sets the currency attribute to the corresponding Currency
251      * instance and the currency symbol attribute to the currency's symbol
252      * in the DecimalFormatSymbols' locale. If the currency code is not valid,
253      * then the currency attribute is set to null and the currency symbol
254      * attribute is not modified.
255      *
256      * @see #setCurrency
257      * @see #setCurrencySymbol
258      * @since 1.2
259      */

260     public void setInternationalCurrencySymbol(String JavaDoc currencyCode)
261     {
262         intlCurrencySymbol = currencyCode;
263         currency = null;
264         if (currencyCode != null) {
265             try {
266                 currency = Currency.getInstance(currencyCode);
267                 currencySymbol = currency.getSymbol();
268             } catch (IllegalArgumentException JavaDoc e) {
269             }
270         }
271     }
272     
273     /**
274      * Gets the currency of these DecimalFormatSymbols. May be null if the
275      * currency symbol attribute was previously set to a value that's not
276      * a valid ISO 4217 currency code.
277      *
278      * @return the currency used, or null
279      * @since 1.4
280      */

281     public Currency JavaDoc getCurrency() {
282         return currency;
283     }
284     
285     /**
286      * Sets the currency of these DecimalFormatSymbols.
287      * This also sets the currency symbol attribute to the currency's symbol
288      * in the DecimalFormatSymbols' locale, and the international currency
289      * symbol attribute to the currency's ISO 4217 currency code.
290      *
291      * @param currency the new currency to be used
292      * @exception NullPointerException if <code>currency</code> is null
293      * @since 1.4
294      * @see #setCurrencySymbol
295      * @see #setInternationalCurrencySymbol
296      */

297     public void setCurrency(Currency JavaDoc currency) {
298         if (currency == null) {
299             throw new NullPointerException JavaDoc();
300         }
301         this.currency = currency;
302         intlCurrencySymbol = currency.getCurrencyCode();
303         currencySymbol = currency.getSymbol(locale);
304     }
305     
306
307     /**
308      * Returns the monetary decimal separator.
309      * @since 1.2
310      */

311     public char getMonetaryDecimalSeparator()
312     {
313         return monetarySeparator;
314     }
315
316     /**
317      * Sets the monetary decimal separator.
318      * @since 1.2
319      */

320     public void setMonetaryDecimalSeparator(char sep)
321     {
322         monetarySeparator = sep;
323     }
324
325     //------------------------------------------------------------
326
// BEGIN Package Private methods ... to be made public later
327
//------------------------------------------------------------
328

329     /**
330      * Returns the character used to separate the mantissa from the exponent.
331      */

332     char getExponentialSymbol()
333     {
334         return exponential;
335     }
336
337     /**
338      * Sets the character used to separate the mantissa from the exponent.
339      */

340     void setExponentialSymbol(char exp)
341     {
342         exponential = exp;
343     }
344
345
346     //------------------------------------------------------------
347
// END Package Private methods ... to be made public later
348
//------------------------------------------------------------
349

350     /**
351      * Standard override.
352      */

353     public Object JavaDoc clone() {
354         try {
355             return (DecimalFormatSymbols JavaDoc)super.clone();
356             // other fields are bit-copied
357
} catch (CloneNotSupportedException JavaDoc e) {
358             throw new InternalError JavaDoc();
359         }
360     }
361
362     /**
363      * Override equals.
364      */

365     public boolean equals(Object JavaDoc obj) {
366         if (obj == null) return false;
367         if (this == obj) return true;
368         if (getClass() != obj.getClass()) return false;
369         DecimalFormatSymbols JavaDoc other = (DecimalFormatSymbols JavaDoc) obj;
370         return (zeroDigit == other.zeroDigit &&
371         groupingSeparator == other.groupingSeparator &&
372         decimalSeparator == other.decimalSeparator &&
373         percent == other.percent &&
374         perMill == other.perMill &&
375         digit == other.digit &&
376         minusSign == other.minusSign &&
377         patternSeparator == other.patternSeparator &&
378         infinity.equals(other.infinity) &&
379         NaN.equals(other.NaN) &&
380         currencySymbol.equals(other.currencySymbol) &&
381         intlCurrencySymbol.equals(other.intlCurrencySymbol) &&
382         currency == other.currency &&
383         monetarySeparator == other.monetarySeparator &&
384         locale.equals(other.locale));
385     }
386
387     /**
388      * Override hashCode.
389      */

390     public int hashCode() {
391             int result = zeroDigit;
392             result = result * 37 + groupingSeparator;
393             result = result * 37 + decimalSeparator;
394             return result;
395     }
396
397     /**
398      * Initializes the symbols from the LocaleElements resource bundle.
399      */

400     private void initialize( Locale JavaDoc locale ) {
401         this.locale = locale;
402
403         // get resource bundle data - try the cache first
404
boolean needCacheUpdate = false;
405         Object JavaDoc[] data = (Object JavaDoc[]) cachedLocaleData.get(locale);
406         if (data == null) { /* cache miss */
407             data = new Object JavaDoc[3];
408             ResourceBundle JavaDoc rb = LocaleData.getLocaleElements(locale);
409             data[0] = rb.getStringArray("NumberElements");
410             needCacheUpdate = true;
411         }
412
413         String JavaDoc[] numberElements = (String JavaDoc[]) data[0];;
414
415         decimalSeparator = numberElements[0].charAt(0);
416         groupingSeparator = numberElements[1].charAt(0);
417         patternSeparator = numberElements[2].charAt(0);
418         percent = numberElements[3].charAt(0);
419         zeroDigit = numberElements[4].charAt(0); //different for Arabic,etc.
420
digit = numberElements[5].charAt(0);
421         minusSign = numberElements[6].charAt(0);
422         exponential = numberElements[7].charAt(0);
423         perMill = numberElements[8].charAt(0);
424         infinity = numberElements[9];
425         NaN = numberElements[10];
426         
427         // Try to obtain the currency used in the locale's country.
428
// Check for empty country string separately because it's a valid
429
// country ID for Locale (and used for the C locale), but not a valid
430
// ISO 3166 country code, and exceptions are expensive.
431
if (!"".equals(locale.getCountry())) {
432             try {
433                 currency = Currency.getInstance(locale);
434             } catch (IllegalArgumentException JavaDoc e) {
435                 // use default values below for compatibility
436
}
437         }
438         if (currency != null) {
439             intlCurrencySymbol = currency.getCurrencyCode();
440             if (data[1] != null && data[1] == intlCurrencySymbol) {
441                 currencySymbol = (String JavaDoc) data[2];
442             } else {
443                 currencySymbol = currency.getSymbol(locale);
444                 data[1] = intlCurrencySymbol;
445                 data[2] = currencySymbol;
446                 needCacheUpdate = true;
447             }
448         } else {
449             // default values
450
intlCurrencySymbol = "XXX";
451             try {
452                 currency = Currency.getInstance(intlCurrencySymbol);
453             } catch (IllegalArgumentException JavaDoc e) {
454             }
455             currencySymbol = "\u00A4";
456         }
457         // Currently the monetary decimal separator is the same as the
458
// standard decimal separator for all locales that we support.
459
// If that changes, add a new entry to NumberElements.
460
monetarySeparator = decimalSeparator;
461         
462         if (needCacheUpdate) {
463             cachedLocaleData.put(locale, data);
464         }
465     }
466
467     /**
468      * Reads the default serializable fields, provides default values for objects
469      * in older serial versions, and initializes non-serializable fields.
470      * If <code>serialVersionOnStream</code>
471      * is less than 1, initializes <code>monetarySeparator</code> to be
472      * the same as <code>decimalSeparator</code> and <code>exponential</code>
473      * to be 'E'.
474      * If <code>serialVersionOnStream</code> is less then 2,
475      * initializes <code>locale</code>to the root locale.
476      * Sets <code>serialVersionOnStream</code> back to the maximum allowed value so that
477      * default serialization will work properly if this object is streamed out again.
478      * Initializes the currency from the intlCurrencySymbol field.
479      *
480      * @since JDK 1.1.6
481      */

482     private void readObject(ObjectInputStream JavaDoc stream)
483             throws IOException JavaDoc, ClassNotFoundException JavaDoc {
484         stream.defaultReadObject();
485         if (serialVersionOnStream < 1) {
486             // Didn't have monetarySeparator or exponential field;
487
// use defaults.
488
monetarySeparator = decimalSeparator;
489             exponential = 'E';
490         }
491         if (serialVersionOnStream < 2) {
492             // didn't have locale; use root locale
493
locale = new Locale JavaDoc("");
494         }
495         serialVersionOnStream = currentSerialVersion;
496
497         if (intlCurrencySymbol != null) {
498             try {
499                  currency = Currency.getInstance(intlCurrencySymbol);
500             } catch (IllegalArgumentException JavaDoc e) {
501             }
502         }
503     }
504
505     /**
506      * Character used for zero.
507      *
508      * @serial
509      * @see #getZeroDigit
510      */

511     private char zeroDigit;
512
513     /**
514      * Character used for thousands separator.
515      *
516      * @serial
517      * @see #getGroupingSeparator
518      */

519     private char groupingSeparator;
520
521     /**
522      * Character used for decimal sign.
523      *
524      * @serial
525      * @see #getDecimalSeparator
526      */

527     private char decimalSeparator;
528
529     /**
530      * Character used for per mille sign.
531      *
532      * @serial
533      * @see #getPerMill
534      */

535     private char perMill;
536
537     /**
538      * Character used for percent sign.
539      * @serial
540      * @see #getPercent
541      */

542     private char percent;
543
544     /**
545      * Character used for a digit in a pattern.
546      *
547      * @serial
548      * @see #getDigit
549      */

550     private char digit;
551
552     /**
553      * Character used to separate positive and negative subpatterns
554      * in a pattern.
555      *
556      * @serial
557      * @see #getPatternSeparator
558      */

559     private char patternSeparator;
560
561     /**
562      * String used to represent infinity.
563      * @serial
564      * @see #getInfinity
565      */

566     private String JavaDoc infinity;
567
568     /**
569      * String used to represent "not a number".
570      * @serial
571      * @see #getNaN
572      */

573     private String JavaDoc NaN;
574
575     /**
576      * Character used to represent minus sign.
577      * @serial
578      * @see #getMinusSign
579      */

580     private char minusSign;
581
582     /**
583      * String denoting the local currency, e.g. "$".
584      * @serial
585      * @see #getCurrencySymbol
586      */

587     private String JavaDoc currencySymbol;
588
589     /**
590      * ISO 4217 currency code denoting the local currency, e.g. "USD".
591      * @serial
592      * @see #getInternationalCurrencySymbol
593      */

594     private String JavaDoc intlCurrencySymbol;
595
596     /**
597      * The decimal separator used when formatting currency values.
598      * @serial
599      * @since JDK 1.1.6
600      * @see #getMonetaryDecimalSeparator
601      */

602     private char monetarySeparator; // Field new in JDK 1.1.6
603

604     /**
605      * The character used to distinguish the exponent in a number formatted
606      * in exponential notation, e.g. 'E' for a number such as "1.23E45".
607      * <p>
608      * Note that the public API provides no way to set this field,
609      * even though it is supported by the implementation and the stream format.
610      * The intent is that this will be added to the API in the future.
611      *
612      * @serial
613      * @since JDK 1.1.6
614      */

615     private char exponential; // Field new in JDK 1.1.6
616

617     /**
618      * The locale of these currency format symbols.
619      *
620      * @serial
621      * @since 1.4
622      */

623     private Locale JavaDoc locale;
624     
625     // currency; only the ISO code is serialized.
626
private transient Currency JavaDoc currency;
627
628     // Proclaim JDK 1.1 FCS compatibility
629
static final long serialVersionUID = 5772796243397350300L;
630
631     // The internal serial version which says which version was written
632
// - 0 (default) for version up to JDK 1.1.5
633
// - 1 for version from JDK 1.1.6, which includes two new fields:
634
// monetarySeparator and exponential.
635
// - 2 for version from J2SE 1.4, which includes locale field.
636
private static final int currentSerialVersion = 2;
637     
638     /**
639      * Describes the version of <code>DecimalFormatSymbols</code> present on the stream.
640      * Possible values are:
641      * <ul>
642      * <li><b>0</b> (or uninitialized): versions prior to JDK 1.1.6.
643      *
644      * <li><b>1</b>: Versions written by JDK 1.1.6 or later, which include
645      * two new fields: <code>monetarySeparator</code> and <code>exponential</code>.
646      * <li><b>2</b>: Versions written by J2SE 1.4 or later, which include a
647      * new <code>locale</code> field.
648      * </ul>
649      * When streaming out a <code>DecimalFormatSymbols</code>, the most recent format
650      * (corresponding to the highest allowable <code>serialVersionOnStream</code>)
651      * is always written.
652      *
653      * @serial
654      * @since JDK 1.1.6
655      */

656     private int serialVersionOnStream = currentSerialVersion;
657
658     /**
659      * cache to hold the NumberElements and the Currency
660      * of a Locale.
661      */

662     private static final Hashtable JavaDoc cachedLocaleData = new Hashtable JavaDoc(3);
663 }
664
Popular Tags