1 7 8 package java.util; 9 10 import java.io.Serializable ; 11 import java.security.AccessController ; 12 import java.security.PrivilegedAction ; 13 import sun.text.resources.LocaleData; 14 15 16 30 public final class Currency implements Serializable { 31 32 private static final long serialVersionUID = -158308464356906721L; 33 34 39 private final String currencyCode; 40 41 45 transient private final int defaultFractionDigits; 46 47 48 50 private static HashMap instances = new HashMap (7); 51 52 53 89 static String mainTable; 90 static long[] scCutOverTimes; 91 static String [] scOldCurrencies; 92 static String [] scNewCurrencies; 93 static int[] scOldCurrenciesDFD; 94 static int[] scNewCurrenciesDFD; 95 static String otherCurrencies; 96 static int[] otherCurrenciesDFD; 97 98 private static final int A_TO_Z = ('Z' - 'A') + 1; 101 private static final int INVALID_COUNTRY_ENTRY = 0x007F; 103 private static final int COUNTRY_WITHOUT_CURRENCY_ENTRY = 0x0080; 105 private static final int SIMPLE_CASE_COUNTRY_MASK = 0x0000; 107 private static final int SIMPLE_CASE_COUNTRY_FINAL_CHAR_MASK = 0x001F; 109 private static final int SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_MASK = 0x0060; 111 private static final int SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_SHIFT = 5; 113 private static final int SPECIAL_CASE_COUNTRY_MASK = 0x0080; 115 private static final int SPECIAL_CASE_COUNTRY_INDEX_MASK = 0x001F; 117 private static final int SPECIAL_CASE_COUNTRY_INDEX_DELTA = 1; 119 private static final int COUNTRY_TYPE_MASK = SIMPLE_CASE_COUNTRY_MASK | SPECIAL_CASE_COUNTRY_MASK; 121 122 static { 123 AccessController.doPrivileged(new PrivilegedAction () { 124 public Object run() { 125 try { 126 Class data = Class.forName("java.util.CurrencyData"); 127 mainTable = (String ) data.getDeclaredField("mainTable").get(data); 128 scCutOverTimes = (long[]) data.getDeclaredField("scCutOverTimes").get(data); 129 scOldCurrencies = (String []) data.getDeclaredField("scOldCurrencies").get(data); 130 scNewCurrencies = (String []) data.getDeclaredField("scNewCurrencies").get(data); 131 scOldCurrenciesDFD = (int[]) data.getDeclaredField("scOldCurrenciesDFD").get(data); 132 scNewCurrenciesDFD = (int[]) data.getDeclaredField("scNewCurrenciesDFD").get(data); 133 otherCurrencies = (String ) data.getDeclaredField("otherCurrencies").get(data); 134 otherCurrenciesDFD = (int[]) data.getDeclaredField("otherCurrenciesDFD").get(data); 135 } catch (ClassNotFoundException e) { 136 throw new InternalError (); 137 } catch (NoSuchFieldException e) { 138 throw new InternalError (); 139 } catch (IllegalAccessException e) { 140 throw new InternalError (); 141 } 142 return null; 143 } 144 }); 145 } 146 147 148 153 private Currency(String currencyCode, int defaultFractionDigits) { 154 this.currencyCode = currencyCode; 155 this.defaultFractionDigits = defaultFractionDigits; 156 } 157 158 167 public static Currency getInstance(String currencyCode) { 168 return getInstance(currencyCode, Integer.MIN_VALUE); 169 } 170 171 private static Currency getInstance(String currencyCode, int defaultFractionDigits) { 172 synchronized (instances) { 173 Currency instance = (Currency ) instances.get(currencyCode); 177 if (instance != null) { 178 return instance; 179 } 180 181 if (defaultFractionDigits == Integer.MIN_VALUE) { 182 if (currencyCode.length() != 3) { 186 throw new IllegalArgumentException (); 187 } 188 char char1 = currencyCode.charAt(0); 189 char char2 = currencyCode.charAt(1); 190 int tableEntry = getMainTableEntry(char1, char2); 191 if ((tableEntry & COUNTRY_TYPE_MASK) == SIMPLE_CASE_COUNTRY_MASK 192 && tableEntry != INVALID_COUNTRY_ENTRY 193 && currencyCode.charAt(2) - 'A' == (tableEntry & SIMPLE_CASE_COUNTRY_FINAL_CHAR_MASK)) { 194 defaultFractionDigits = (tableEntry & SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_MASK) >> SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_SHIFT; 195 } else { 196 if (currencyCode.charAt(2) == '-') { 198 throw new IllegalArgumentException (); 199 } 200 int index = otherCurrencies.indexOf(currencyCode); 201 if (index == -1) { 202 throw new IllegalArgumentException (); 203 } 204 defaultFractionDigits = otherCurrenciesDFD[index / 4]; 205 } 206 } 207 208 instance = new Currency (currencyCode, defaultFractionDigits); 209 instances.put(currencyCode, instance); 210 return instance; 211 } 212 } 213 214 235 public static Currency getInstance(Locale locale) { 236 String country = locale.getCountry(); 237 if (country == null) { 238 throw new NullPointerException (); 239 } 240 241 if (country.length() != 2) { 242 throw new IllegalArgumentException (); 243 } 244 245 char char1 = country.charAt(0); 246 char char2 = country.charAt(1); 247 int tableEntry = getMainTableEntry(char1, char2); 248 if ((tableEntry & COUNTRY_TYPE_MASK) == SIMPLE_CASE_COUNTRY_MASK 249 && tableEntry != INVALID_COUNTRY_ENTRY) { 250 char finalChar = (char) ((tableEntry & SIMPLE_CASE_COUNTRY_FINAL_CHAR_MASK) + 'A'); 251 int defaultFractionDigits = (tableEntry & SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_MASK) >> SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_SHIFT; 252 StringBuffer sb = new StringBuffer (country); 253 sb.append(finalChar); 254 return getInstance(sb.toString(), defaultFractionDigits); 255 } else { 256 if (tableEntry == INVALID_COUNTRY_ENTRY) { 258 throw new IllegalArgumentException (); 259 } 260 if (tableEntry == COUNTRY_WITHOUT_CURRENCY_ENTRY) { 261 return null; 262 } else { 263 int index = (tableEntry & SPECIAL_CASE_COUNTRY_INDEX_MASK) - SPECIAL_CASE_COUNTRY_INDEX_DELTA; 264 if (scCutOverTimes[index] == Long.MAX_VALUE || System.currentTimeMillis() < scCutOverTimes[index]) { 265 return getInstance(scOldCurrencies[index], scOldCurrenciesDFD[index]); 266 } else { 267 return getInstance(scNewCurrencies[index], scNewCurrenciesDFD[index]); 268 } 269 } 270 } 271 } 272 273 278 public String getCurrencyCode() { 279 return currencyCode; 280 } 281 282 290 public String getSymbol() { 291 return getSymbol(Locale.getDefault()); 292 } 293 294 305 public String getSymbol(Locale locale) { 306 ResourceBundle bundle; 307 try { 308 bundle = LocaleData.getLocaleElements(locale); 309 } catch (MissingResourceException e) { 310 return currencyCode; 312 } 313 String [][] symbols = 314 (String [][]) bundle.getObject("CurrencySymbols"); 315 if (symbols != null) { 316 for (int i = 0; i < symbols.length; i++) { 317 if (symbols[i][0].equals(currencyCode)) { 318 return symbols[i][1]; 319 } 320 } 321 } 322 return currencyCode; 324 } 325 326 335 public int getDefaultFractionDigits() { 336 return defaultFractionDigits; 337 } 338 339 344 public String toString() { 345 return currencyCode; 346 } 347 348 351 private Object readResolve() { 352 return getInstance(currencyCode); 353 } 354 355 359 private static int getMainTableEntry(char char1, char char2) { 360 if (char1 < 'A' || char1 > 'Z' || char2 < 'A' || char2 > 'Z') { 361 throw new IllegalArgumentException (); 362 } 363 return mainTable.charAt((char1 - 'A') * A_TO_Z + (char2 - 'A')); 364 } 365 } 366 | Popular Tags |