japod@17
|
1 |
package org.apidesign.apifest08.currency;
|
japod@17
|
2 |
|
japod@17
|
3 |
|
japod@17
|
4 |
import java.math.BigDecimal;
|
japod@17
|
5 |
import java.math.MathContext;
|
japod@17
|
6 |
import java.math.RoundingMode;
|
japod@17
|
7 |
import java.util.Currency;
|
japod@17
|
8 |
|
japod@17
|
9 |
|
japod@17
|
10 |
/**
|
japod@17
|
11 |
* Convert between two currencies.
|
japod@17
|
12 |
*
|
japod@17
|
13 |
* @author D'Arcy Smith
|
japod@17
|
14 |
* @version 1.0
|
japod@17
|
15 |
*/
|
japod@17
|
16 |
final class ConvertorImpl
|
japod@17
|
17 |
implements Convertor
|
japod@17
|
18 |
{
|
japod@17
|
19 |
/**
|
japod@17
|
20 |
* The currency to cvonvert from.
|
japod@17
|
21 |
*/
|
japod@17
|
22 |
private final Currency currencyA;
|
japod@17
|
23 |
|
japod@17
|
24 |
/**
|
japod@17
|
25 |
* The currency to cvonvert from.
|
japod@17
|
26 |
*/
|
japod@17
|
27 |
private final Currency currencyB;
|
japod@17
|
28 |
|
japod@17
|
29 |
/**
|
japod@17
|
30 |
* The echange rate between a and b.
|
japod@17
|
31 |
*/
|
japod@17
|
32 |
private final BigDecimal currencyARate;
|
japod@17
|
33 |
|
japod@17
|
34 |
/**
|
japod@17
|
35 |
* The echange rate between b and a.
|
japod@17
|
36 |
*/
|
japod@17
|
37 |
private final BigDecimal currencyBRate;
|
japod@17
|
38 |
|
japod@17
|
39 |
/**
|
japod@17
|
40 |
* Constructs a convertor with the specified currencies.
|
japod@17
|
41 |
*
|
japod@17
|
42 |
* @param a the currency to convert from.
|
japod@17
|
43 |
* @param aRate the exchage rage between from and to.
|
japod@17
|
44 |
* @param b the currency to convert to.
|
japod@17
|
45 |
* @param bRate the exchage rage between to and from.
|
japod@17
|
46 |
* @throws IllegalArgumentException if either any of the arguments are null or if either rate <= 0.
|
japod@17
|
47 |
*/
|
japod@17
|
48 |
public ConvertorImpl(final Currency a,
|
japod@17
|
49 |
final BigDecimal aRate,
|
japod@17
|
50 |
final Currency b,
|
japod@17
|
51 |
final BigDecimal bRate)
|
japod@17
|
52 |
{
|
japod@17
|
53 |
if(a == null)
|
japod@17
|
54 |
{
|
japod@17
|
55 |
throw new IllegalArgumentException("a cannot be null");
|
japod@17
|
56 |
}
|
japod@17
|
57 |
|
japod@17
|
58 |
if(b == null)
|
japod@17
|
59 |
{
|
japod@17
|
60 |
throw new IllegalArgumentException("b cannot be null");
|
japod@17
|
61 |
}
|
japod@17
|
62 |
|
japod@17
|
63 |
if(aRate == null)
|
japod@17
|
64 |
{
|
japod@17
|
65 |
throw new IllegalArgumentException("aRate cannot be null");
|
japod@17
|
66 |
}
|
japod@17
|
67 |
|
japod@17
|
68 |
if(bRate == null)
|
japod@17
|
69 |
{
|
japod@17
|
70 |
throw new IllegalArgumentException("bRate cannot be null");
|
japod@17
|
71 |
}
|
japod@17
|
72 |
|
japod@17
|
73 |
if(aRate.compareTo(BigDecimal.ZERO) <= 0)
|
japod@17
|
74 |
{
|
japod@17
|
75 |
throw new IllegalArgumentException("aRate must be > 0, was: " + aRate);
|
japod@17
|
76 |
}
|
japod@17
|
77 |
|
japod@17
|
78 |
if(bRate.compareTo(BigDecimal.ZERO) <= 0)
|
japod@17
|
79 |
{
|
japod@17
|
80 |
throw new IllegalArgumentException("bRate must be > 0, was: " + bRate);
|
japod@17
|
81 |
}
|
japod@17
|
82 |
|
japod@17
|
83 |
currencyA = a;
|
japod@17
|
84 |
currencyB = b;
|
japod@17
|
85 |
currencyARate = aRate;
|
japod@17
|
86 |
currencyBRate = bRate;
|
japod@17
|
87 |
}
|
japod@17
|
88 |
|
japod@17
|
89 |
/**
|
japod@17
|
90 |
* Convert an amount from one currency to another.
|
japod@17
|
91 |
*
|
japod@17
|
92 |
* @param from the currency to convert from.
|
japod@17
|
93 |
* @param to the currency to convert to.
|
japod@17
|
94 |
* @param amount the amount to convert.
|
japod@17
|
95 |
* @return the converted amount.
|
japod@17
|
96 |
* @throws IllegalArgumentException if any of the arguments are null.
|
japod@17
|
97 |
* @throws InvalidConversionException if either from or to are not equal to the currencies passed to the constructor.
|
japod@17
|
98 |
*/
|
japod@17
|
99 |
public BigDecimal convert(final Currency from,
|
japod@17
|
100 |
final Currency to,
|
japod@17
|
101 |
final BigDecimal amount)
|
japod@17
|
102 |
throws InvalidConversionException
|
japod@17
|
103 |
{
|
japod@17
|
104 |
final BigDecimal result;
|
japod@17
|
105 |
|
japod@17
|
106 |
if(amount == null)
|
japod@17
|
107 |
{
|
japod@17
|
108 |
throw new IllegalArgumentException("amount cannot be null");
|
japod@17
|
109 |
}
|
japod@17
|
110 |
|
japod@17
|
111 |
if(from == null)
|
japod@17
|
112 |
{
|
japod@17
|
113 |
throw new IllegalArgumentException("from cannot be null");
|
japod@17
|
114 |
}
|
japod@17
|
115 |
|
japod@17
|
116 |
if(to == null)
|
japod@17
|
117 |
{
|
japod@17
|
118 |
throw new IllegalArgumentException("to cannot be null");
|
japod@17
|
119 |
}
|
japod@17
|
120 |
|
japod@17
|
121 |
if(!(from.equals(currencyA)) && (!(from.equals(currencyB))))
|
japod@17
|
122 |
{
|
japod@17
|
123 |
throw new InvalidConversionException("cannot convert from: " + from.getCurrencyCode(), from, currencyA, currencyB);
|
japod@17
|
124 |
}
|
japod@17
|
125 |
|
japod@17
|
126 |
if(!(to.equals(currencyA)) && (!(to.equals(currencyB))))
|
japod@17
|
127 |
{
|
japod@17
|
128 |
throw new InvalidConversionException("cannot convert to: " + to.getCurrencyCode(), to, currencyA, currencyB);
|
japod@17
|
129 |
}
|
japod@17
|
130 |
|
japod@17
|
131 |
// converting between the same currency is no converstion at all.
|
japod@17
|
132 |
if(from.equals(to))
|
japod@17
|
133 |
{
|
japod@17
|
134 |
result = amount;
|
japod@17
|
135 |
}
|
japod@17
|
136 |
else
|
japod@17
|
137 |
{
|
japod@17
|
138 |
final BigDecimal rateX;
|
japod@17
|
139 |
final BigDecimal rateY;
|
japod@17
|
140 |
final BigDecimal temp;
|
japod@17
|
141 |
|
japod@17
|
142 |
if(from.equals(currencyA))
|
japod@17
|
143 |
{
|
japod@17
|
144 |
rateX = currencyARate;
|
japod@17
|
145 |
rateY = currencyBRate;
|
japod@17
|
146 |
}
|
japod@17
|
147 |
else
|
japod@17
|
148 |
{
|
japod@17
|
149 |
rateX = currencyBRate;
|
japod@17
|
150 |
rateY = currencyARate;
|
japod@17
|
151 |
}
|
japod@17
|
152 |
|
japod@17
|
153 |
temp = amount.divide(rateX, MathContext.DECIMAL32);
|
japod@17
|
154 |
result = temp.multiply(rateY);
|
japod@17
|
155 |
}
|
japod@17
|
156 |
|
japod@17
|
157 |
return (result.setScale(2, RoundingMode.HALF_DOWN));
|
japod@17
|
158 |
}
|
japod@17
|
159 |
}
|