Merge from mainline (gomp-merge-2005-02-26).
[official-gcc.git] / libjava / java / util / Currency.java
blobffe593dfcc447f2415fa9f8847b0022b8928f9c4
1 /* Currency.java -- Representation of a currency
2 Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
38 package java.util;
40 import java.io.ObjectStreamException;
41 import java.io.Serializable;
42 import java.text.NumberFormat;
44 /**
45 * Representation of a currency for a particular locale. Each currency
46 * is identified by its ISO 4217 code, and only one instance of this
47 * class exists per currency. As a result, instances are created
48 * via the <code>getInstance()</code> methods rather than by using
49 * a constructor.
51 * @see java.util.Locale
52 * @author Guilhem Lavaux (guilhem.lavaux@free.fr)
53 * @author Dalibor Topic (robilad@kaffe.org)
54 * @author Bryce McKinlay (mckinlay@redhat.com)
55 * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
56 * @since 1.4
58 public final class Currency
59 implements Serializable
61 /**
62 * For compatability with Sun's JDK
64 static final long serialVersionUID = -158308464356906721L;
66 /**
67 * The locale associated with this currency.
69 * @see #Currency(java.util.Locale)
70 * @see #getInstance(java.util.Locale)
71 * @see #getSymbol(java.util.Locale)
72 * @serial ignored.
74 private transient Locale locale;
76 /**
77 * The resource bundle which maps the currency to
78 * a ISO 4217 currency code.
80 * @see #getCurrencyCode()
81 * @serial ignored.
83 private transient ResourceBundle res;
85 /**
86 * The ISO 4217 currency code associated with this
87 * particular instance.
89 * @see #getCurrencyCode()
90 * @serial the ISO 4217 currency code
92 private String currencyCode;
94 /**
95 * A cache of <code>Currency</code> instances to
96 * ensure the singleton nature of this class. The key
97 * is the locale of the currency.
99 * @see #getInstance(java.util.Locale)
100 * @see #readResolve()
101 * @serial ignored.
103 private static transient Map cache;
106 * Instantiates the cache.
108 static
110 cache = new HashMap();
114 * Default constructor for deserialization
116 private Currency ()
121 * Constructor to create a <code>Currency</code> object
122 * for a particular <code>Locale</code>.
123 * All components of the given locale, other than the
124 * country code, are ignored. The results of calling this
125 * method may vary over time, as the currency associated with
126 * a particular country changes. For countries without
127 * a given currency (e.g. Antarctica), the result is null.
129 * @param loc the locale for the new currency.
131 private Currency (Locale loc)
133 this.locale = loc;
134 this.res = ResourceBundle.getBundle ("gnu.java.locale.LocaleInformation",
135 locale, ClassLoader.getSystemClassLoader());
136 /* Retrieve the ISO4217 currency code */
139 currencyCode = res.getString ("intlCurrencySymbol");
141 catch (Exception _)
143 currencyCode = null;
148 * Returns the ISO4217 currency code of this currency.
150 * @return a <code>String</code> containing currency code.
152 public String getCurrencyCode ()
154 return currencyCode;
158 * Returns the number of digits which occur after the decimal point
159 * for this particular currency. For example, currencies such
160 * as the U.S. dollar, the Euro and the Great British pound have two
161 * digits following the decimal point to indicate the value which exists
162 * in the associated lower-valued coinage (cents in the case of the first
163 * two, pennies in the latter). Some currencies such as the Japanese
164 * Yen have no digits after the decimal point. In the case of pseudo
165 * currencies, such as IMF Special Drawing Rights, -1 is returned.
167 * @return the number of digits after the decimal separator for this currency.
169 public int getDefaultFractionDigits ()
171 NumberFormat currency = NumberFormat.getCurrencyInstance (locale);
173 return currency.getMaximumFractionDigits();
177 * Builds a new currency instance for this locale.
178 * All components of the given locale, other than the
179 * country code, are ignored. The results of calling this
180 * method may vary over time, as the currency associated with
181 * a particular country changes. For countries without
182 * a given currency (e.g. Antarctica), the result is null.
184 * @param locale a <code>Locale</code> instance.
185 * @return a new <code>Currency</code> instance.
186 * @throws NullPointerException if the locale or its
187 * country code is null.
188 * @throws IllegalArgumentException if the country of
189 * the given locale is not a supported ISO3166 code.
191 public static Currency getInstance (Locale locale)
194 * The new instance must be the only available instance
195 * for the currency it supports. We ensure this happens,
196 * while maintaining a suitable performance level, by
197 * creating the appropriate object on the first call to
198 * this method, and returning the cached instance on
199 * later calls.
201 Currency newCurrency;
203 /* Attempt to get the currency from the cache */
204 newCurrency = (Currency) cache.get(locale);
205 if (newCurrency == null)
207 /* Create the currency for this locale */
208 newCurrency = new Currency (locale);
209 /* Cache it */
210 cache.put(locale, newCurrency);
212 /* Return the instance */
213 return newCurrency;
217 * Builds the currency corresponding to the specified currency code.
219 * @param currencyCode a string representing a currency code.
220 * @return a new <code>Currency</code> instance.
221 * @throws NullPointerException if currencyCode is null.
222 * @throws IllegalArgumentException if the supplied currency code
223 * is not a supported ISO 4217 code.
225 public static Currency getInstance (String currencyCode)
227 Locale[] allLocales = Locale.getAvailableLocales ();
229 for (int i = 0;i < allLocales.length; i++)
231 Currency testCurrency = getInstance (allLocales[i]);
233 if (testCurrency.getCurrencyCode() != null &&
234 testCurrency.getCurrencyCode().equals(currencyCode))
235 return testCurrency;
238 * If we get this far, the code is not supported by any of
239 * our locales.
241 throw new IllegalArgumentException("The currency code, " + currencyCode +
242 ", is not supported.");
246 * This method returns the symbol which precedes or follows a
247 * value in this particular currency. In cases where there is no
248 * such symbol for the currency, the ISO 4217 currency
249 * code is returned.
251 * @return the currency symbol, or the ISO 4217 currency code if
252 * one doesn't exist.
254 public String getSymbol()
258 /* What does this return if there is no mapping? */
259 return res.getString ("currencySymbol");
261 catch (Exception _)
263 return null;
268 * <p>
269 * This method returns the symbol which precedes or follows a
270 * value in this particular currency. The returned value is
271 * the symbol used to denote the currency in the specified locale.
272 * </p>
273 * <p>
274 * For example, a supplied locale may specify a different symbol
275 * for the currency, due to conflicts with its own currency.
276 * This would be the case with the American currency, the dollar.
277 * Locales that also use a dollar-based currency (e.g. Canada, Australia)
278 * need to differentiate the American dollar using 'US$' rather than '$'.
279 * So, supplying one of these locales to <code>getSymbol()</code> would
280 * return this value, rather than the standard '$'.
281 * </p>
282 * <p>
283 * In cases where there is no such symbol for a particular currency,
284 * the ISO 4217 currency code is returned.
285 * </p>
287 * @param locale the locale to express the symbol in.
288 * @return the currency symbol, or the ISO 4217 currency code if
289 * one doesn't exist.
290 * @throws NullPointerException if the locale is null.
292 public String getSymbol(Locale locale)
294 // TODO. The behaviour is unclear if locale != this.locale.
295 // First we need to implement fully LocaleInformation*.java
298 * FIXME: My reading of how this method works has this implementation
299 * as wrong. It should return a value relating to how the specified
300 * locale handles the symbol for this currency. This implementation
301 * seems to just do a variation of getInstance(locale).
305 ResourceBundle localeResource =
306 ResourceBundle.getBundle ("gnu.java.locale.LocaleInformation",
307 locale, Currency.class.getClassLoader());
309 if (localeResource.equals(res))
310 return localeResource.getString ("currencySymbol");
311 else
312 return localeResource.getString ("intlCurrencySymbol");
314 catch (Exception e1)
318 return res.getString ("intlCurrencySymbol");
320 catch (Exception e2)
322 return null;
328 * Returns the international ISO4217 currency code of this currency.
330 * @return a <code>String</code> containing the ISO4217 currency code.
332 public String toString()
334 return getCurrencyCode();
338 * Resolves the deserialized object to the singleton instance for its
339 * particular currency. The currency code of the deserialized instance
340 * is used to return the correct instance.
342 * @return the singleton instance for the currency specified by the
343 * currency code of the deserialized object. This replaces
344 * the deserialized object as the returned object from
345 * deserialization.
346 * @throws ObjectStreamException if a problem occurs with deserializing
347 * the object.
349 private Object readResolve()
350 throws ObjectStreamException
352 return getInstance(currencyCode);