Provide a default persistence delegate for currency objects, so they can be serialized and sent through the queues.
- ~
- jbidwatcher
- trunk
- src
- com
- jbidwatcher
- util
- Currency.java
| Currency.java |
|---|
cyberfox 1 package com.jbidwatcher.util; cyberfox 2 /* cyberfox 3 * Copyright (c) 2000-2007, CyberFOX Software, Inc. All Rights Reserved. cyberfox 4 * cyberfox 5 * Developed by mrs (Morgan Schweers) cyberfox 6 */ cyberfox 7 mrs 8 import com.jbidwatcher.util.config.JConfig; mrs 9 cyberfox 10 import java.text.NumberFormat; cyberfox 11 import java.util.Locale; mrs 12 import java.util.Map; mrs 13 import java.util.HashMap; mrs 14 import java.beans.PersistenceDelegate; mrs 15 import java.beans.DefaultPersistenceDelegate; cyberfox 16 cyberfox 17 public class Currency implements Comparable { cyberfox 18 private static NumberFormat df = NumberFormat.getNumberInstance(Locale.US); // We create a lot of these, so minimizing memory usage is good. cyberfox 19 public static final int NONE=0, US_DOLLAR=1, UK_POUND=2, JP_YEN=3, GER_MARK=4, FR_FRANC=5, CAN_DOLLAR=6; mrs 20 public static final int EURO=7, AU_DOLLAR=8, CH_FRANC=9, NT_DOLLAR=10, TW_DOLLAR=10, HK_DOLLAR=11; mrs 21 public static final int MY_REAL=12, SG_DOLLAR=13, IND_RUPEE=14; cyberfox 22 private static Currency _noValue = null; cyberfox 23 cyberfox 24 /** cyberfox 25 * @brief This provides a concept of a currency value that is cyberfox 26 * invalid, not just 'zero' in some arbitrary currency. cyberfox 27 * cyberfox 28 * @return A single, consistent, 'Empty Value', which indicates an cyberfox 29 * invalid currency. cyberfox 30 */ cyberfox 31 public static Currency NoValue() { cyberfox 32 if(_noValue == null) _noValue = new Currency(NONE, 0.0); cyberfox 33 cyberfox 34 return _noValue; cyberfox 35 } cyberfox 36 mrs 37 protected int mCurrencyType; mrs 38 protected double mValue; cyberfox 39 private static final char pound = '\u00A3'; mrs 40 private static final Character objPound = '\u00A3'; cyberfox 41 mrs 42 private static Map<Integer,Double> sCurrencyMap = new HashMap<Integer,Double>(); mrs 43 mrs 44 /** mrs 45 * Convert a non-US currency to USD, usually for sorting purposes. mrs 46 * mrs 47 * Takes two values (usd, non-usd) which are believed to be mrs 48 * equivalent, and a currency amount to convert based off the mrs 49 * ratio between the first two. If the USD amount is null or $0, mrs 50 * it looks in a table it keeps around for converting. If that fails, mrs 51 * it just returns the non-USD's value. mrs 52 * mrs 53 * @param usd - A sample US dollar amount. mrs 54 * @param nonusd - A non-US dollar amount that is equivalent to the usd paramter. mrs 55 * @param cvt - The non-USD amount to convert to USD. mrs 56 * mrs 57 * @return - 'cvt' converted by the ratio of usd:nonusd, or by an internal table if mrs 58 * it couldn't figure out the ratio, or just the non-usd's amount as a USD amount if mrs 59 * there wasn't even an entry in the table. mrs 60 */ cyberfox 61 public static Currency convertToUSD(Currency usd, Currency nonusd, Currency cvt) { cyberfox 62 if(cvt != null && !cvt.isNull() && cvt.getCurrencyType() != US_DOLLAR) { mrs 63 double multiple; mrs 64 if(usd == null || usd.isNull() || usd.getValue() == 0.0 || mrs 65 nonusd == null || nonusd.isNull() || nonusd.getValue() == 0.0) { mrs 66 if(sCurrencyMap.containsKey(cvt.getCurrencyType())) { mrs 67 multiple = sCurrencyMap.get(cvt.getCurrencyType()); mrs 68 } else { mrs 69 // If we have nothing else to go on, treat it as exactly equal to USD. mrs 70 multiple = 1.0; mrs 71 } mrs 72 } else { mrs 73 multiple = usd.getValue() / nonusd.getValue(); mrs 74 if(multiple != 0.0) sCurrencyMap.put(nonusd.getCurrencyType(), multiple); mrs 75 } cyberfox 76 return getCurrency(US_DOLLAR, multiple*cvt.getValue()); cyberfox 77 } cyberfox 78 cyberfox 79 return cvt; cyberfox 80 } cyberfox 81 cyberfox 82 /*!@class CurrencyTypeException cyberfox 83 * cyberfox 84 * @brief A class to yell about currency type comparison exceptions. cyberfox 85 * cyberfox 86 * This is used when comparing two currencies of disparate monies. cyberfox 87 */ mrs 88 public static class CurrencyTypeException extends Exception { cyberfox 89 String _associatedString; cyberfox 90 cyberfox 91 public CurrencyTypeException(String inString) { cyberfox 92 _associatedString = inString; cyberfox 93 } cyberfox 94 public String toString() { cyberfox 95 return _associatedString; cyberfox 96 } cyberfox 97 } cyberfox 98 mrs 99 private static final Integer CurDollar = US_DOLLAR; // American Dollar mrs 100 private static final Integer CurPound = UK_POUND; // British Pound mrs 101 private static final Integer CurYen = JP_YEN; // Japanese Yen mrs 102 private static final Integer CurMark = GER_MARK; // German Mark mrs 103 private static final Integer CurFranc = FR_FRANC; // French Franc mrs 104 private static final Integer CurSwiss = CH_FRANC; // Swiss Franc mrs 105 private static final Integer CurCan = CAN_DOLLAR; // Canadian Dollar mrs 106 private static final Integer CurEuro = EURO; // Euro mrs 107 private static final Integer CurAu = AU_DOLLAR; // Australian Dollar mrs 108 private static final Integer CurTaiwan = NT_DOLLAR; // New Taiwanese Dollar mrs 109 private static final Integer CurHK = HK_DOLLAR; // Hong Kong Dollar mrs 110 private static final Integer CurMyr = MY_REAL; // Malaysia Real(?) mrs 111 private static final Integer CurSGD = SG_DOLLAR; // Singapore Dollar mrs 112 private static final Integer CurRupee = IND_RUPEE; // Indian Rupee cyberfox 113 cyberfox 114 // The fundamental list of the textual representation for different cyberfox 115 // currencies, and the Currency type it translates to. cyberfox 116 private static final Object xlateTable[][] = { cyberfox 117 { "USD", CurDollar }, cyberfox 118 { "US $", CurDollar }, cyberfox 119 { "AU $", CurAu }, cyberfox 120 { "au$", CurAu }, cyberfox 121 { "AU", CurAu }, cyberfox 122 { "AUD", CurAu }, cyberfox 123 { "US", CurDollar }, cyberfox 124 { "USD $", CurDollar }, cyberfox 125 { "$", CurDollar }, cyberfox 126 { "C", CurCan }, cyberfox 127 { "C $", CurCan }, cyberfox 128 { "CAD", CurCan }, cyberfox 129 { "c$", CurCan }, cyberfox 130 { "GBP", CurPound }, cyberfox 131 { objPound.toString(), CurPound }, cyberfox 132 { "pound", CurPound }, cyberfox 133 { "\u00A3", CurPound }, cyberfox 134 { "£", CurPound }, cyberfox 135 { "Y", CurYen }, cyberfox 136 { "JPY", CurYen }, cyberfox 137 { "¥", CurYen }, cyberfox 138 { "\u00A5", CurYen }, cyberfox 139 { "DM", CurMark }, cyberfox 140 { "FRF", CurFranc }, cyberfox 141 { "fr", CurFranc }, cyberfox 142 { "CHF", CurSwiss }, cyberfox 143 { "chf", CurSwiss }, cyberfox 144 { "dm", CurMark }, cyberfox 145 { "\u20AC", CurEuro }, cyberfox 146 { "eur", CurEuro }, cyberfox 147 { "EUR", CurEuro }, cyberfox 148 { "Eur", CurEuro }, cyberfox 149 { "NT$", CurTaiwan }, cyberfox 150 { "nt$", CurTaiwan }, cyberfox 151 { "NTD", CurTaiwan }, cyberfox 152 { "HK$", CurHK }, cyberfox 153 { "hk$", CurHK }, mrs 154 { "HKD", CurHK }, mrs 155 { "MYR", CurMyr }, mrs 156 { "myr", CurMyr }, mrs 157 { "SGD", CurSGD }, mrs 158 { "sgd", CurSGD }, mrs 159 { "INR", CurRupee }, mrs 160 { "inr", CurRupee } cyberfox 161 }; cyberfox 162 cyberfox 163 /** cyberfox 164 * @brief Convert from a string containing a recognized symbol into cyberfox 165 * a currency type. cyberfox 166 * cyberfox 167 * @param symbol - The string representation of a currency. cyberfox 168 * cyberfox 169 * @return - The integer value associated with the provided cyberfox 170 * currency, or NONE for unrecognized currencies. cyberfox 171 */ cyberfox 172 private int xlateSymbolToType(String symbol) { mrs 173 for (Object[] aXlateTable : xlateTable) { mrs 174 if (symbol.equals(aXlateTable[0])) { mrs 175 return (Integer) aXlateTable[1]; cyberfox 176 } cyberfox 177 } cyberfox 178 cyberfox 179 return NONE; cyberfox 180 } cyberfox 181 cyberfox 182 private boolean isDigit(char ch) { cyberfox 183 return(ch>='0' && ch<='9'); cyberfox 184 } cyberfox 185 cyberfox 186 public static Currency getCurrency(String wholeValue) { mrs 187 if(wholeValue == null || wholeValue.length() == 0 || wholeValue.startsWith("UNK")) return NoValue(); cyberfox 188 cyberfox 189 return new Currency(wholeValue); cyberfox 190 } cyberfox 191 cyberfox 192 public static Currency getCurrency(int whatType, double startValue) { cyberfox 193 if(whatType == NONE) return NoValue(); cyberfox 194 cyberfox 195 return new Currency(whatType, startValue); cyberfox 196 } cyberfox 197 cyberfox 198 public static Currency getCurrency(String symbol, double startValue) { cyberfox 199 if(symbol == null || symbol.equalsIgnoreCase("UNK")) return NoValue(); cyberfox 200 cyberfox 201 return new Currency(symbol, startValue); cyberfox 202 } cyberfox 203 cyberfox 204 public static Currency getCurrency(String symbol, String startValue) { cyberfox 205 if(symbol == null || symbol.equalsIgnoreCase("UNK")) return NoValue(); cyberfox 206 cyberfox 207 return new Currency(symbol, startValue); cyberfox 208 } cyberfox 209 cyberfox 210 public Currency(String wholeValue) { cyberfox 211 setValues(wholeValue); cyberfox 212 } cyberfox 213 cyberfox 214 public Currency(int whatType, double startValue) { cyberfox 215 setValues(whatType, startValue); cyberfox 216 } cyberfox 217 cyberfox 218 public Currency(String symbol, double startValue) { cyberfox 219 setValues(symbol, startValue); cyberfox 220 } cyberfox 221 cyberfox 222 public Currency(String symbol, String startValue) { cyberfox 223 setValues(symbol, Double.parseDouble(startValue)); cyberfox 224 } cyberfox 225 cyberfox 226 private int checkLengthMatchStart(String value, String currencyName) { cyberfox 227 String lowVal = value.toLowerCase(); cyberfox 228 String curNam = currencyName.toLowerCase(); cyberfox 229 if(lowVal.startsWith(curNam + " ")) { cyberfox 230 return currencyName.length()+1; cyberfox 231 } cyberfox 232 if(lowVal.startsWith(curNam)) { cyberfox 233 int len = currencyName.length(); cyberfox 234 while(len < value.length() && !Character.isDigit(value.charAt(len))) len++; cyberfox 235 return len; cyberfox 236 } cyberfox 237 cyberfox 238 return 0; cyberfox 239 } cyberfox 240 cyberfox 241 /** cyberfox 242 * @brief Provided an entire string containing a currency prefix and cyberfox 243 * an amount, extract the two and set this object's value to equal cyberfox 244 * the result. cyberfox 245 * cyberfox 246 * Is there a reason this doesn't use xlateSymbolToType? cyberfox 247 * BUGBUG -- mrs: 03-January-2003 01:28 cyberfox 248 * cyberfox 249 * @param wholeValue - The string containing an entire currency+amount text. cyberfox 250 */ cyberfox 251 private void setValues(String wholeValue) { cyberfox 252 if(wholeValue == null || wholeValue.equals("null")) { cyberfox 253 setValues(Currency.NONE, 0.0); cyberfox 254 } else { mrs 255 char firstChar = wholeValue.charAt(0); cyberfox 256 mrs 257 int eurLen = checkLengthMatchStart(wholeValue, "EUR"); mrs 258 int gbpLen = checkLengthMatchStart(wholeValue, "GBP"); mrs 259 int frfLen = checkLengthMatchStart(wholeValue, "FRF"); mrs 260 int chfLen = checkLengthMatchStart(wholeValue, "CHF"); mrs 261 int cdnLen = checkLengthMatchStart(wholeValue, "CAD"); mrs 262 int ntdLen = checkLengthMatchStart(wholeValue, "NTD"); mrs 263 int audLen = checkLengthMatchStart(wholeValue, "AUD"); mrs 264 int usdLen = checkLengthMatchStart(wholeValue, "USD"); cyberfox 265 mrs 266 String parseCurrency; mrs 267 String valuePortion; cyberfox 268 if(wholeValue.startsWith("US $")) { cyberfox 269 parseCurrency = "US $"; cyberfox 270 valuePortion = wholeValue.substring(4); cyberfox 271 } else if(wholeValue.startsWith("USD $")) { cyberfox 272 // In case eBay ever corrects to the RIGHT currency code for USD. cyberfox 273 parseCurrency = "USD $"; cyberfox 274 valuePortion = wholeValue.substring(5); cyberfox 275 } else if(wholeValue.startsWith("AU $")) { cyberfox 276 parseCurrency = "AU $"; cyberfox 277 valuePortion = wholeValue.substring(4); cyberfox 278 } else if(usdLen != 0) { cyberfox 279 parseCurrency = "USD"; cyberfox 280 valuePortion = wholeValue.substring(usdLen); mrs 281 } else if(eurLen != 0) { cyberfox 282 parseCurrency = "EUR"; mrs 283 valuePortion = wholeValue.substring(eurLen); cyberfox 284 } else if(gbpLen != 0) { cyberfox 285 parseCurrency = "GBP"; cyberfox 286 valuePortion = wholeValue.substring(gbpLen); cyberfox 287 } else if(frfLen != 0) { cyberfox 288 parseCurrency = "FRF"; cyberfox 289 valuePortion = wholeValue.substring(frfLen); cyberfox 290 } else if(chfLen != 0) { cyberfox 291 parseCurrency = "CHF"; cyberfox 292 valuePortion = wholeValue.substring(chfLen); cyberfox 293 } else if(cdnLen != 0) { cyberfox 294 parseCurrency = "CAD"; cyberfox 295 valuePortion = wholeValue.substring(cdnLen); cyberfox 296 } else if(ntdLen != 0) { cyberfox 297 parseCurrency = "NTD"; cyberfox 298 valuePortion = wholeValue.substring(ntdLen); cyberfox 299 } else if(audLen != 0) { cyberfox 300 parseCurrency = "AUD"; cyberfox 301 valuePortion = wholeValue.substring(audLen); cyberfox 302 } else if(wholeValue.startsWith("NT$")) { cyberfox 303 parseCurrency = "NTD"; cyberfox 304 valuePortion = wholeValue.substring(3); mrs 305 } else if(wholeValue.startsWith("SGD")) { mrs 306 parseCurrency = "SGD"; mrs 307 valuePortion = wholeValue.substring(3); mrs 308 } else if(wholeValue.startsWith("sgd")) { mrs 309 parseCurrency = "SGD"; mrs 310 valuePortion = wholeValue.substring(3); mrs 311 } else if(wholeValue.startsWith("INR")) { mrs 312 parseCurrency = "INR"; mrs 313 valuePortion = wholeValue.substring(3); mrs 314 } else if(wholeValue.startsWith("inr")) { mrs 315 parseCurrency = "INR"; mrs 316 valuePortion = wholeValue.substring(3); cyberfox 317 } else if(wholeValue.startsWith("nt$")) { cyberfox 318 parseCurrency = "NTD"; cyberfox 319 valuePortion = wholeValue.substring(3); cyberfox 320 } else if(wholeValue.startsWith("au$")) { cyberfox 321 parseCurrency = "AUD"; cyberfox 322 valuePortion = wholeValue.substring(3); cyberfox 323 } else if(wholeValue.startsWith("C $")) { cyberfox 324 parseCurrency = "C $"; cyberfox 325 valuePortion = wholeValue.substring(3); cyberfox 326 } else if(wholeValue.charAt(0) == pound) { cyberfox 327 parseCurrency = "GBP"; cyberfox 328 valuePortion = wholeValue.substring(1); cyberfox 329 } else { cyberfox 330 if(!isDigit(firstChar) && firstChar != '$') { cyberfox 331 int semiIndex = wholeValue.indexOf(";"); cyberfox 332 if(semiIndex == -1) { cyberfox 333 semiIndex = wholeValue.indexOf(" "); cyberfox 334 } cyberfox 335 if(semiIndex != -1) { cyberfox 336 parseCurrency = wholeValue.substring(0, semiIndex); cyberfox 337 valuePortion = wholeValue.substring(parseCurrency.length()+1); cyberfox 338 } else { cyberfox 339 parseCurrency = "$"; cyberfox 340 valuePortion = wholeValue; cyberfox 341 } cyberfox 342 } else { cyberfox 343 parseCurrency = "$"; cyberfox 344 if(isDigit(firstChar)) { cyberfox 345 valuePortion = wholeValue; cyberfox 346 } else { cyberfox 347 valuePortion = wholeValue.substring(1); cyberfox 348 } cyberfox 349 } cyberfox 350 } cyberfox 351 cyberfox 352 // Kill off non-digit characters. mrs 353 while(valuePortion.length() != 0 && !Character.isDigit(valuePortion.charAt(0))) valuePortion = valuePortion.substring(1); cyberfox 354 cyberfox 355 // If anything's left, try and parse it. mrs 356 if(valuePortion.length() != 0) { mrs 357 double actualValue; cyberfox 358 try { mrs 359 String cvt = valuePortion; mrs 360 // Convert [###.###.]###,## to [###,###,]###.## mrs 361 if(cvt.length() > 2 && cvt.charAt(cvt.length()-3) == ',') { mrs 362 cvt = cvt.substring(0, cvt.length()-3).replaceAll("\\.",",") + '.' + cvt.substring(cvt.length()-2); mrs 363 // System.out.println("Converting '" + cvt + "': " + df.parse(cvt).doubleValue()); mrs 364 } mrs 365 actualValue = df.parse(cvt).doubleValue(); cyberfox 366 } catch(java.text.ParseException e) { mrs 367 JConfig.log().handleException("currency parse!", e); cyberfox 368 actualValue = 0.0; cyberfox 369 } cyberfox 370 cyberfox 371 setValues(parseCurrency, actualValue); cyberfox 372 } else { cyberfox 373 setValues(null); cyberfox 374 } cyberfox 375 } cyberfox 376 } cyberfox 377 cyberfox 378 /** cyberfox 379 * @brief If it's set as two seperate entries, then we use the MUCH cyberfox 380 * cleaner xlateSymbolToType function. cyberfox 381 * cyberfox 382 * This should be the basic method that setValues works also. cyberfox 383 * cyberfox 384 * @param symbol - The string form of a currency symbol. cyberfox 385 * @param startValue - The amount associated with the currency. cyberfox 386 */ cyberfox 387 private void setValues(String symbol, double startValue) { cyberfox 388 setValues(xlateSymbolToType(symbol), startValue); cyberfox 389 } cyberfox 390 cyberfox 391 /** cyberfox 392 * @brief The underlying setter that assigns the currency and amounts. cyberfox 393 * cyberfox 394 * @param whatType - The Currency type to set to. cyberfox 395 * @param startValue - The amount represented. cyberfox 396 */ cyberfox 397 private void setValues(int whatType, double startValue) { mrs 398 mCurrencyType = whatType; mrs 399 mValue = startValue; cyberfox 400 df.setMinimumFractionDigits(2); cyberfox 401 df.setMaximumFractionDigits(2); cyberfox 402 } cyberfox 403 cyberfox 404 /** cyberfox 405 * @brief Get the full, storable textual name for the currency type cyberfox 406 * of this object. cyberfox 407 * cyberfox 408 * @return A string containing a full ISO currency name. cyberfox 409 */ cyberfox 410 public String fullCurrencyName() { mrs 411 switch(mCurrencyType) { cyberfox 412 case US_DOLLAR: return("USD"); cyberfox 413 case AU_DOLLAR: return("AUD"); cyberfox 414 case NT_DOLLAR: return("NTD"); cyberfox 415 case HK_DOLLAR: return("HKD"); mrs 416 case MY_REAL: return("MYR"); mrs 417 case SG_DOLLAR: return("SGD"); mrs 418 case IND_RUPEE: return("INR"); cyberfox 419 case UK_POUND: return("GBP"); cyberfox 420 case JP_YEN: return("JPY"); cyberfox 421 case GER_MARK: return("DM"); cyberfox 422 case FR_FRANC: return("FRF"); cyberfox 423 case CH_FRANC: return("CHF"); cyberfox 424 case CAN_DOLLAR: return("CAD"); cyberfox 425 case EURO: return("EUR"); cyberfox 426 default: return("UNK"); cyberfox 427 } cyberfox 428 } cyberfox 429 mrs 430 public double getValue() { return mValue; } cyberfox 431 cyberfox 432 public String fullCurrency() { cyberfox 433 return fullCurrencyName() + " " + getValueString(); cyberfox 434 } cyberfox 435 cyberfox 436 /** cyberfox 437 * @brief Add two currencies and return a new currency containing cyberfox 438 * the result of the two added together. cyberfox 439 * cyberfox 440 * @param addValue - The currency value/amount to add. It must be cyberfox 441 * of the same currency type as 'this'. cyberfox 442 * cyberfox 443 * @return A new currency object containing the sum of the two cyberfox 444 * amounts provided, with the same currency type as them. cyberfox 445 * cyberfox 446 * @throws CurrencyTypeException if the two objects are of different currencies. cyberfox 447 */ cyberfox 448 public Currency add(Currency addValue) throws CurrencyTypeException { cyberfox 449 if(addValue == null) throw new CurrencyTypeException("Cannot add null Currency."); cyberfox 450 mrs 451 if(addValue.getCurrencyType() == mCurrencyType) { mrs 452 return new Currency(mCurrencyType, mValue + addValue.getValue()); cyberfox 453 } cyberfox 454 mrs 455 // If only one currency is known, return the result as the known currency. mrs 456 if (mCurrencyType == NONE) return new Currency(addValue.getCurrencyType(), mValue + addValue.getValue()); mrs 457 if (addValue.getCurrencyType() == NONE) return new Currency(mCurrencyType, mValue + addValue.getValue()); mrs 458 cyberfox 459 throw new CurrencyTypeException("Cannot add " + fullCurrencyName() + " to " + addValue.fullCurrencyName() + "."); cyberfox 460 } cyberfox 461 cyberfox 462 /** cyberfox 463 * @brief Subtract two currencies and return a new currency containing cyberfox 464 * the result of the passed value subtracted from this objects value. cyberfox 465 * cyberfox 466 * @param subValue - The currency value/amount to subtract. It must be cyberfox 467 * of the same currency type as 'this'. cyberfox 468 * cyberfox 469 * @return A new currency object containing the difference of the two cyberfox 470 * amounts provided, with the same currency type as them. cyberfox 471 * cyberfox 472 * @throws CurrencyTypeException if the two objects are of different currencies. cyberfox 473 */ cyberfox 474 public Currency subtract(Currency subValue) throws CurrencyTypeException { mrs 475 if(subValue == null) throw new CurrencyTypeException("Cannot subtract null Currency."); cyberfox 476 mrs 477 if(subValue.getCurrencyType() == mCurrencyType) { mrs 478 return new Currency(mCurrencyType, mValue - subValue.getValue()); cyberfox 479 } cyberfox 480 mrs 481 // If only one currency is known, return the result as the known currency. mrs 482 if(mCurrencyType == NONE) return new Currency(subValue.getCurrencyType(), mValue - subValue.getValue()); mrs 483 if(subValue.getCurrencyType() == NONE) return new Currency(mCurrencyType, mValue - subValue.getValue()); mrs 484 mrs 485 throw new CurrencyTypeException("Cannot subtract " + fullCurrencyName() + " from " + subValue.fullCurrencyName() + "."); cyberfox 486 } cyberfox 487 mrs 488 public int getCurrencyType() { return mCurrencyType; } cyberfox 489 cyberfox 490 public String getCurrencySymbol() { mrs 491 switch(mCurrencyType) { cyberfox 492 case US_DOLLAR: return("$"); cyberfox 493 case NT_DOLLAR: return("nt$"); cyberfox 494 case HK_DOLLAR: return("hk$"); mrs 495 case MY_REAL: return("myr"); mrs 496 case SG_DOLLAR: return("sgd"); mrs 497 case IND_RUPEE: return("Rs."); cyberfox 498 case UK_POUND: return(objPound.toString()); cyberfox 499 case JP_YEN: return("\u00A5"); // HACKHACK cyberfox 500 case FR_FRANC: return("fr"); cyberfox 501 case CH_FRANC: return("chf"); cyberfox 502 case GER_MARK: return("dm"); cyberfox 503 case CAN_DOLLAR: return("c$"); cyberfox 504 case AU_DOLLAR: return("au$"); cyberfox 505 case EURO: return("\u20AC"); cyberfox 506 default: return("unk"); cyberfox 507 } cyberfox 508 } cyberfox 509 cyberfox 510 /** cyberfox 511 * @brief Format the currency and amount as appropriate for the cyberfox 512 * current locale. cyberfox 513 * cyberfox 514 * This is kind of interesting, because it will display in one cyberfox 515 * fashion, but when it snipes or bids, it's all against the cyberfox 516 * US sites, so it's all operating in US forms at that point. cyberfox 517 * cyberfox 518 * @return A nicely formatted, locale-correct money value, prefixed cyberfox 519 * with the best currency symbol for the currency type. cyberfox 520 */ cyberfox 521 public String toString() { cyberfox 522 if(isNull()) { cyberfox 523 return("null"); cyberfox 524 } else { cyberfox 525 String cvtToString = getCurrencySymbol(); cyberfox 526 mrs 527 cvtToString += df.format(mValue); cyberfox 528 cyberfox 529 return(cvtToString); cyberfox 530 } cyberfox 531 } cyberfox 532 cyberfox 533 /** cyberfox 534 * @brief Format the amount as appropriate for the current locale. cyberfox 535 * cyberfox 536 * This is kind of interesting, because it will display in one cyberfox 537 * fashion, but when it snipes or bids, it's all against the cyberfox 538 * US sites, so it's all operating in US forms at that point. cyberfox 539 * cyberfox 540 * @return A nicely formatted, locale-correct money value, prefixed cyberfox 541 * with the best currency symbol for the currency type. cyberfox 542 */ cyberfox 543 public String getValueString() { cyberfox 544 if(isNull()) { cyberfox 545 return("null"); cyberfox 546 } else { mrs 547 return df.format(mValue); cyberfox 548 } cyberfox 549 } cyberfox 550 cyberfox 551 /** cyberfox 552 * @brief Implementing equals means I should implement hashCode(). cyberfox 553 * cyberfox 554 * @return - The hash code of the string consisting of the full cyberfox 555 * currency named followed by the value as a string. Null/invalid cyberfox 556 * currency entries return 0. cyberfox 557 */ cyberfox 558 public int hashCode() { cyberfox 559 if(isNull()) return 0; cyberfox 560 cyberfox 561 String tmp = fullCurrencyName() + getValueString(); cyberfox 562 return tmp.hashCode(); cyberfox 563 } cyberfox 564 cyberfox 565 /** cyberfox 566 * @brief Must be able to compare currency values for equality. cyberfox 567 * cyberfox 568 * @param inValue - The value to compare against. cyberfox 569 * cyberfox 570 * @return True if the two values are the same, or the currency and cyberfox 571 * amount are the same. False otherwise, including false if it is cyberfox 572 * an entirely different class. Differing currencies are always cyberfox 573 * unequal. cyberfox 574 */ cyberfox 575 public boolean equals(Object inValue) { cyberfox 576 // Be careful not to compare with null. cyberfox 577 if(inValue == null) return false; cyberfox 578 // Shortcut for this.equals(this) cyberfox 579 if(inValue == this) return true; cyberfox 580 // Is it this class even? cyberfox 581 if(!(inValue instanceof Currency)) return false; cyberfox 582 // Okay, now cast it because it's safe. mrs 583 Currency otherValue = (Currency) inValue; mrs 584 boolean sameCurrency = (otherValue.getCurrencyType() == mCurrencyType); mrs 585 boolean sameValue = ((int) (otherValue.getValue() * 1000)) == ((int) (mValue * 1000)); cyberfox 586 cyberfox 587 return(sameCurrency && sameValue); cyberfox 588 } cyberfox 589 cyberfox 590 /** cyberfox 591 * @brief Determine if (this < otherValue). cyberfox 592 * cyberfox 593 * This only works for items of the same currency type. cyberfox 594 * cyberfox 595 * @param otherValue - The value to compare against. cyberfox 596 * cyberfox 597 * @return - True if this amount is less than the otherValue amount cyberfox 598 * and both currency types are equal. If the otherValue is null, cyberfox 599 * the same object as this (this.less(this)), or this amount is cyberfox 600 * actually less, then it returns false. cyberfox 601 * cyberfox 602 * @throws CurrencyTypeException if you try to compare different currencies. cyberfox 603 */ cyberfox 604 public boolean less(Currency otherValue) throws CurrencyTypeException { cyberfox 605 // Be careful cyberfox 606 if(otherValue == null) return false; cyberfox 607 // Shortcut cyberfox 608 if(otherValue == this) return false; cyberfox 609 mrs 610 boolean sameCurrency = (otherValue.getCurrencyType() == mCurrencyType); cyberfox 611 if(!sameCurrency) { cyberfox 612 throw new CurrencyTypeException("Cannot compare different currencies."); cyberfox 613 } cyberfox 614 mrs 615 boolean lowerValue = Double.compare((double) ((int) (otherValue.getValue() * 1000)), (double) (int) (mValue * 1000)) == 1; cyberfox 616 cyberfox 617 return(lowerValue); cyberfox 618 } cyberfox 619 cyberfox 620 /** cyberfox 621 * @brief Utility function to check if this is a purely invalid currency. cyberfox 622 * cyberfox 623 * It should probably check against the invalid currency object first... cyberfox 624 * cyberfox 625 * @return True if this is a 'null currency' object. cyberfox 626 */ cyberfox 627 public boolean isNull() { mrs 628 return(mValue == 0.0 && mCurrencyType == NONE); cyberfox 629 } cyberfox 630 cyberfox 631 /** cyberfox 632 * @brief The comparable interface defines this, and so I'm cyberfox 633 * comparing using the well defined set of rules for Comparables. cyberfox 634 * cyberfox 635 * Defined with 'equals' and less', but both should be special cases cyberfox 636 * of this, since some checks are duplicated. cyberfox 637 * cyberfox 638 * @param o - The object to compare against. cyberfox 639 * cyberfox 640 * @return -1 if o's class is Currency, it's the same currency type, cyberfox 641 * and the amount of this is less than o's amount. cyberfox 642 * 0 if o's class is Currency, it's the same currency type, cyberfox 643 * and the amount of this is the same as o's amount. cyberfox 644 * 1 if o's class is Currency, it's the same currency type, cyberfox 645 * and the amount of this is greater than o's amount. cyberfox 646 * cyberfox 647 * @throws ClassCastException if you try to compareTo non-Currency classes. cyberfox 648 */ cyberfox 649 public int compareTo(Object o) { cyberfox 650 // We are always greater than null cyberfox 651 if(o == null) return 1; cyberfox 652 // We are always equal to ourselves cyberfox 653 if(o == this) return 0; cyberfox 654 // This is an incorrect usage and should be caught. cyberfox 655 if(!(o instanceof Currency)) throw new ClassCastException("Currency cannot compareTo different classes!"); cyberfox 656 cyberfox 657 // Okay, now cast it because it's safe. mrs 658 Currency otherValue = (Currency) o; cyberfox 659 cyberfox 660 if(otherValue.isNull()) return 1; cyberfox 661 if(isNull()) return -1; cyberfox 662 try { cyberfox 663 if(less(otherValue)) return -1; cyberfox 664 } catch(ClassCastException e) { cyberfox 665 /* This should be impossible */ cyberfox 666 throw new ClassCastException("Currency cannot compareTo different classes!\n" + e); cyberfox 667 } catch (CurrencyTypeException e) { cyberfox 668 // Can't re-throw (or not catch!) because Object.compareTo doesn't throw CurrencyTypeException! cyberfox 669 throw new ClassCastException("Currency cannot compareTo different currencies!\n" + e); cyberfox 670 } cyberfox 671 if(equals(otherValue)) return 0; cyberfox 672 return 1; cyberfox 673 } mrs 674 mrs 675 public static PersistenceDelegate getDelegate() { mrs 676 return new DefaultPersistenceDelegate(new String[]{"mCurrencyType", "mValue"}); mrs 677 } cyberfox 678 }
Check out the code: svn co jbidwatcher/trunk/src/com/jbidwatcher/util/Currency.java
