Source code: junit/samples/money/MoneyBag.java
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 }