package junit.samples.money; import java.util.*; /** * A MoneyBag defers exchange rate conversions. For example adding * 12 Swiss Francs to 14 US Dollars is represented as a bag * containing the two Monies 12 CHF and 14 USD. Adding another * 10 Swiss francs gives a bag with 22 CHF and 14 USD. Due to * the deferred exchange rate conversion we can later value a * MoneyBag with different exchange rates. * * A MoneyBag is represented as a list of Monies and provides * different constructors to create a MoneyBag. */ class MoneyBag implements IMoney { private Vector fMonies= new Vector(5); static IMoney create(IMoney m1, IMoney m2) { MoneyBag result= new MoneyBag(); m1.appendTo(result); m2.appendTo(result); return result.simplify(); } public IMoney add(IMoney m) { return m.addMoneyBag(this); } public IMoney addMoney(Money m) { return MoneyBag.create(m, this); } public IMoney addMoneyBag(MoneyBag s) { return MoneyBag.create(s, this); } void appendBag(MoneyBag aBag) { for (Enumeration e= aBag.fMonies.elements(); e.hasMoreElements(); ) appendMoney((Money)e.nextElement()); } void appendMoney(Money aMoney) { if (aMoney.isZero()) return; IMoney old= findMoney(aMoney.currency()); if (old == null) { fMonies.addElement(aMoney); return; } fMonies.removeElement(old); IMoney sum= old.add(aMoney); if (sum.isZero()) return; fMonies.addElement(sum); } public boolean equals(Object anObject) { if (isZero()) if (anObject instanceof IMoney) return ((IMoney)anObject).isZero(); if (anObject instanceof MoneyBag) { MoneyBag aMoneyBag= (MoneyBag)anObject; if (aMoneyBag.fMonies.size() != fMonies.size()) return false; for (Enumeration e= fMonies.elements(); e.hasMoreElements(); ) { Money m= (Money) e.nextElement(); if (!aMoneyBag.contains(m)) return false; } return true; } return false; } private Money findMoney(String currency) { for (Enumeration e= fMonies.elements(); e.hasMoreElements(); ) { Money m= (Money) e.nextElement(); if (m.currency().equals(currency)) return m; } return null; } private boolean contains(Money m) { Money found= findMoney(m.currency()); if (found == null) return false; return found.amount() == m.amount(); } public int hashCode() { int hash= 0; for (Enumeration e= fMonies.elements(); e.hasMoreElements(); ) { Object m= e.nextElement(); hash^= m.hashCode(); } return hash; } public boolean isZero() { return fMonies.size() == 0; } public IMoney multiply(int factor) { MoneyBag result= new MoneyBag(); if (factor != 0) { for (Enumeration e= fMonies.elements(); e.hasMoreElements(); ) { Money m= (Money) e.nextElement(); result.appendMoney((Money)m.multiply(factor)); } } return result; } public IMoney negate() { MoneyBag result= new MoneyBag(); for (Enumeration e= fMonies.elements(); e.hasMoreElements(); ) { Money m= (Money) e.nextElement(); result.appendMoney((Money)m.negate()); } return result; } private IMoney simplify() { if (fMonies.size() == 1) return (IMoney)fMonies.elements().nextElement(); return this; } public IMoney subtract(IMoney m) { return add(m.negate()); } public String toString() { StringBuffer buffer = new StringBuffer(); buffer.append("{"); for (Enumeration e= fMonies.elements(); e.hasMoreElements(); ) buffer.append(e.nextElement()); buffer.append("}"); return buffer.toString(); } public void appendTo(MoneyBag m) { m.appendBag(this); } }