class MoneyBag implements IMoney
1: package junit.samples.money;
2:
3: import java.util.*;
4:
5: /**
6: * A MoneyBag defers exchange rate conversions. For example adding
7: * 12 Swiss Francs to 14 US Dollars is represented as a bag
8: * containing the two Monies 12 CHF and 14 USD. Adding another
9: * 10 Swiss francs gives a bag with 22 CHF and 14 USD. Due to
10: * the deferred exchange rate conversion we can later value a
11: * MoneyBag with different exchange rates.
12: *
13: * A MoneyBag is represented as a list of Monies and provides
14: * different constructors to create a MoneyBag.
15: */
16: class MoneyBag implements IMoney {
17: private Vector fMonies= new Vector(5);
18:
19: static IMoney create(IMoney m1, IMoney m2) {
20: MoneyBag result= new MoneyBag();
21: m1.appendTo(result);
22: m2.appendTo(result);
23: return result.simplify();
24: }
25: public IMoney add(IMoney m) {
26: return m.addMoneyBag(this);
27: }
28: public IMoney addMoney(Money m) {
29: return MoneyBag.create(m, this);
30: }
31: public IMoney addMoneyBag(MoneyBag s) {
32: return MoneyBag.create(s, this);
33: }
34: void appendBag(MoneyBag aBag) {
35: for (Enumeration e= aBag.fMonies.elements(); e.hasMoreElements(); )
36: appendMoney((Money)e.nextElement());
37: }
38: void appendMoney(Money aMoney) {
39: if (aMoney.isZero()) return;
40: IMoney old= findMoney(aMoney.currency());
41: if (old == null) {
42: fMonies.addElement(aMoney);
43: return;
44: }
45: fMonies.removeElement(old);
46: IMoney sum= old.add(aMoney);
47: if (sum.isZero())
48: return;
49: fMonies.addElement(sum);
50: }
51: public boolean equals(Object anObject) {
52: if (isZero())
53: if (anObject instanceof IMoney)
54: return ((IMoney)anObject).isZero();
55:
56: if (anObject instanceof MoneyBag) {
57: MoneyBag aMoneyBag= (MoneyBag)anObject;
58: if (aMoneyBag.fMonies.size() != fMonies.size())
59: return false;
60:
61: for (Enumeration e= fMonies.elements(); e.hasMoreElements(); ) {
62: Money m= (Money) e.nextElement();
63: if (!aMoneyBag.contains(m))
64: return false;
65: }
66: return true;
67: }
68: return false;
69: }
70: private Money findMoney(String currency) {
71: for (Enumeration e= fMonies.elements(); e.hasMoreElements(); ) {
72: Money m= (Money) e.nextElement();
73: if (m.currency().equals(currency))
74: return m;
75: }
76: return null;
77: }
78: private boolean contains(Money m) {
79: Money found= findMoney(m.currency());
80: if (found == null) return false;
81: return found.amount() == m.amount();
82: }
83: public int hashCode() {
84: int hash= 0;
85: for (Enumeration e= fMonies.elements(); e.hasMoreElements(); ) {
86: Object m= e.nextElement();
87: hash^= m.hashCode();
88: }
89: return hash;
90: }
91: public boolean isZero() {
92: return fMonies.size() == 0;
93: }
94: public IMoney multiply(int factor) {
95: MoneyBag result= new MoneyBag();
96: if (factor != 0) {
97: for (Enumeration e= fMonies.elements(); e.hasMoreElements(); ) {
98: Money m= (Money) e.nextElement();
99: result.appendMoney((Money)m.multiply(factor));
100: }
101: }
102: return result;
103: }
104: public IMoney negate() {
105: MoneyBag result= new MoneyBag();
106: for (Enumeration e= fMonies.elements(); e.hasMoreElements(); ) {
107: Money m= (Money) e.nextElement();
108: result.appendMoney((Money)m.negate());
109: }
110: return result;
111: }
112: private IMoney simplify() {
113: if (fMonies.size() == 1)
114: return (IMoney)fMonies.elements().nextElement();
115: return this;
116: }
117: public IMoney subtract(IMoney m) {
118: return add(m.negate());
119: }
120: public String toString() {
121: StringBuffer buffer = new StringBuffer();
122: buffer.append("{");
123: for (Enumeration e= fMonies.elements(); e.hasMoreElements(); )
124: buffer.append(e.nextElement());
125: buffer.append("}");
126: return buffer.toString();
127: }
128: public void appendTo(MoneyBag m) {
129: m.appendBag(this);
130: }
131: }