japod@23
|
1 |
package org.apidesign.apifest08.currency;
|
japod@23
|
2 |
|
japod@23
|
3 |
import java.math.BigDecimal;
|
japod@23
|
4 |
import java.util.Date;
|
japod@41
|
5 |
import java.util.HashMap;
|
japod@41
|
6 |
import java.util.Map;
|
japod@23
|
7 |
|
japod@23
|
8 |
/**
|
japod@58
|
9 |
* Exchange rate provider. Provides exchange rate for two currencies (method {@link #getExchangeRate(ConvertorCurrency, ConvertorCurrency)} ).
|
japod@58
|
10 |
* <p>
|
japod@58
|
11 |
* Several method can be created to create <code>ExchangeRateProvider</code>:
|
japod@58
|
12 |
* <ul>
|
japod@58
|
13 |
* <li>{@link #createExchangeRateProvider() } - create <em>simple</em> exchange rate provider using fixed echange rate.
|
japod@58
|
14 |
* <li>{@link #createExchangeRateProvider(IExchangeRateEngine) } - create exchange rate provider using custom {@link IExchangeRateEngine}.
|
japod@58
|
15 |
* </ul>
|
japod@58
|
16 |
* <p>
|
japod@41
|
17 |
* Date dependend exchange rate to be implemented.
|
japod@23
|
18 |
*
|
japod@23
|
19 |
* @author arnostvalicek
|
japod@23
|
20 |
*/
|
japod@23
|
21 |
public class ExchangeRateProvider {
|
japod@58
|
22 |
|
japod@58
|
23 |
IExchangeRateEngine exrateEngine;
|
japod@41
|
24 |
|
japod@23
|
25 |
/**
|
japod@23
|
26 |
* Simple constructor for <code>ExchangeRateProviderM</code> which can provide fixed exchange rate.
|
japod@23
|
27 |
*
|
japod@41
|
28 |
* Describes conversion <em>from ONE</em> to <em>to ONE</em> currency.
|
japod@23
|
29 |
*
|
japod@23
|
30 |
* @param fromValue From value. BigDecimal value, precision should be set to currency precision.
|
japod@23
|
31 |
* @param fromCurrency From currency.
|
japod@23
|
32 |
* @param toValue To value. BigDecimal value, precision should be set to currency precision.
|
japod@23
|
33 |
* @param toCurrency To currency.
|
japod@41
|
34 |
* @deprecated deprecated since task2. Use {@link #createExchangeRateProvider() } instead of this constructor.
|
japod@23
|
35 |
*/
|
japod@23
|
36 |
public ExchangeRateProvider(BigDecimal fromValue, ConvertorCurrency fromCurrency, BigDecimal toValue, ConvertorCurrency toCurrency) {
|
japod@58
|
37 |
this.exrateEngine = FixedOneExchangeRateEngine.createEngine(fromValue, fromCurrency, toValue, toCurrency);
|
japod@23
|
38 |
}
|
japod@58
|
39 |
|
japod@41
|
40 |
private ExchangeRateProvider() {
|
japod@41
|
41 |
}
|
japod@58
|
42 |
|
japod@41
|
43 |
/**
|
japod@41
|
44 |
* Static method to create new exchange rate provider. This exchange rate provider does not contain
|
japod@41
|
45 |
* any exchange rates (this is difference to public constructor).
|
japod@41
|
46 |
* @return New <code>ExchangeRateProvider</code>
|
japod@41
|
47 |
*/
|
japod@41
|
48 |
public static ExchangeRateProvider createExchangeRateProvider() {
|
japod@41
|
49 |
ExchangeRateProvider provider = new ExchangeRateProvider();
|
japod@58
|
50 |
provider.exrateEngine = FixedExchangeRateEngine.createEngine();
|
japod@41
|
51 |
return provider;
|
japod@41
|
52 |
}
|
japod@58
|
53 |
|
japod@41
|
54 |
/**
|
japod@58
|
55 |
* Static method to create exchange rate provider which is using provided <code>IExchangeRateEngine</code>. This exchange rate provider is using
|
japod@58
|
56 |
* <code>IExchangeRateEngine</code> to get actual exchange rate.
|
japod@58
|
57 |
* @param exchangeRateEngine <code>IExchangeRateEngine</code> used to get exchange rate.
|
japod@58
|
58 |
* @return Returns instance of <code>ExchangeRateProvider</code>
|
japod@58
|
59 |
*/
|
japod@58
|
60 |
public static ExchangeRateProvider createExchangeRateProvider(IExchangeRateEngine exchangeRateEngine) {
|
japod@58
|
61 |
ExchangeRateProvider provider = new ExchangeRateProvider();
|
japod@58
|
62 |
provider.exrateEngine = exchangeRateEngine;
|
japod@58
|
63 |
return provider;
|
japod@58
|
64 |
}
|
japod@58
|
65 |
|
japod@58
|
66 |
/**
|
japod@58
|
67 |
* Add new exchange rate to <code></code> to this <em>simple</em> exchange rate provider.
|
japod@41
|
68 |
* <p>
|
japod@41
|
69 |
* Example of specifiing conversion rate: 100 SKK == 80 CZK:<br>
|
japod@41
|
70 |
* <code>addFixedCurencyRate(ConvertorCurrency.getInstance("SKK"), new BigDecimal(100), ConvertorCurrency.getInstance("CZK"), new BigDecimal(80));</code>
|
japod@41
|
71 |
* <p>
|
japod@58
|
72 |
* This method may be used <em>only</em> when <code>ExchangeRateProvider</code> is created using {@link #createExchangeRateProvider() } - creating exchange rate provider without external <code>IExchangeRateEngine</code>.
|
japod@41
|
73 |
*
|
japod@41
|
74 |
* @param fromCurrency Source currency.
|
japod@41
|
75 |
* @param fromValue Valye for from currency.
|
japod@41
|
76 |
* @param toCurrency Target currency.
|
japod@41
|
77 |
* @param toValue Value for target currency.
|
japod@58
|
78 |
* @throws IllegalStateException Throws exception when adding fixed currency rate to exchange rate provider which is not created using {@link #createExchangeRateProvider() }.
|
japod@41
|
79 |
*/
|
japod@41
|
80 |
public synchronized void addFixedCurencyRate(ConvertorCurrency fromCurrency, BigDecimal fromValue, ConvertorCurrency toCurrency, BigDecimal toValue) {
|
japod@58
|
81 |
if (exrateEngine instanceof FixedExchangeRateEngine) {
|
japod@58
|
82 |
((FixedExchangeRateEngine) exrateEngine).addFixedCurencyRate(fromCurrency, fromValue, toCurrency, toValue);
|
japod@58
|
83 |
} else {
|
japod@58
|
84 |
throw new IllegalStateException("Cuurency rate can be added only to ExchangeRateProvider created with FixedExchangeRateEngine - using method createExchangeRateProvider()");
|
japod@41
|
85 |
}
|
japod@41
|
86 |
}
|
japod@58
|
87 |
|
japod@23
|
88 |
/**
|
japod@23
|
89 |
* Get fixed exange rate for currencies (from->to).
|
japod@23
|
90 |
* @return Returns exchange rate.
|
japod@41
|
91 |
* @deprecated deprecated since task2. Use {@link #getExchangeRate(ConvertorCurrency, ConvertorCurrency) }
|
japod@23
|
92 |
*/
|
japod@23
|
93 |
public ExchangeRate getExchangeRate() {
|
japod@58
|
94 |
//works only for FixedExchangeRateEngine
|
japod@58
|
95 |
if (exrateEngine instanceof FixedOneExchangeRateEngine) {
|
japod@58
|
96 |
FixedOneExchangeRateEngine engine = (FixedOneExchangeRateEngine) exrateEngine;
|
japod@58
|
97 |
return new ExchangeRate(engine.getFromValue(), engine.getToValue());
|
japod@58
|
98 |
} else {
|
japod@58
|
99 |
throw new IllegalStateException("Method supported only for MinimalFixedExchangeRateEngine. This method is deprecated");
|
japod@58
|
100 |
}
|
japod@58
|
101 |
|
japod@23
|
102 |
}
|
japod@41
|
103 |
|
japod@41
|
104 |
/**
|
japod@41
|
105 |
* Get fixed exange rate for currencies (from->to).
|
japod@41
|
106 |
* @return Returns exchange rate or <code>null</code> if exchange rate not found.
|
japod@41
|
107 |
*/
|
japod@41
|
108 |
public ExchangeRate getExchangeRate(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency) {
|
japod@41
|
109 |
return getExchangeRateImpl(fromCurrency, toCurrency);
|
japod@41
|
110 |
}
|
japod@58
|
111 |
|
japod@41
|
112 |
/**
|
japod@41
|
113 |
* Get fixed exange rate for currencies (from->to) or reversed exchange rate (to->from).
|
japod@41
|
114 |
* @return Returns exchange rate or <code>null</code> if exchange rate not found.
|
japod@41
|
115 |
*/
|
japod@41
|
116 |
public ExchangeRate getReversibleExchangeRate(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency) {
|
japod@58
|
117 |
ExchangeRate rate = getExchangeRateImpl(fromCurrency, toCurrency);
|
japod@58
|
118 |
if (rate == null) {
|
japod@58
|
119 |
ExchangeRate revertedRate = getExchangeRateImpl(toCurrency, fromCurrency);
|
japod@58
|
120 |
if (revertedRate != null) {
|
japod@58
|
121 |
rate = ExchangeRate.createRevertedRate(revertedRate);
|
japod@58
|
122 |
}
|
japod@58
|
123 |
}
|
japod@58
|
124 |
return rate;
|
japod@41
|
125 |
}
|
japod@41
|
126 |
|
japod@23
|
127 |
/**
|
japod@23
|
128 |
* Get exchange rate for currencies (from->to) based on provided date.
|
japod@23
|
129 |
* @param date Date for which exchange rate should be provided.
|
japod@23
|
130 |
* @return Returns exchange rate
|
japod@41
|
131 |
* @deprecated deprecated since task2. No real implementation in version2.
|
japod@23
|
132 |
*/
|
japod@23
|
133 |
public ExchangeRate getExchangeRate(Date date) {
|
japod@58
|
134 |
//works only for FixedExchangeRateEngine
|
japod@58
|
135 |
if (exrateEngine instanceof FixedOneExchangeRateEngine) {
|
japod@58
|
136 |
FixedOneExchangeRateEngine engine = (FixedOneExchangeRateEngine) exrateEngine;
|
japod@58
|
137 |
return new ExchangeRate(engine.getFromValue(), engine.getToValue());
|
japod@58
|
138 |
} else {
|
japod@58
|
139 |
throw new IllegalStateException("Method supported only for FixedOneExchangeRateEngine. This method is deprecated");
|
japod@58
|
140 |
}
|
japod@23
|
141 |
}
|
japod@23
|
142 |
|
japod@23
|
143 |
ConvertorCurrency getFromCurrency() {
|
japod@58
|
144 |
if (exrateEngine instanceof FixedOneExchangeRateEngine) {
|
japod@58
|
145 |
FixedOneExchangeRateEngine engine = (FixedOneExchangeRateEngine) exrateEngine;
|
japod@58
|
146 |
return engine.getFromCurrency();
|
japod@58
|
147 |
} else {
|
japod@58
|
148 |
throw new IllegalStateException("Method supported only for FixedOneExchangeRateEngine. This method is deprecated");
|
japod@58
|
149 |
}
|
japod@23
|
150 |
}
|
japod@58
|
151 |
|
japod@23
|
152 |
ConvertorCurrency getToCurrency() {
|
japod@58
|
153 |
if (exrateEngine instanceof FixedOneExchangeRateEngine) {
|
japod@58
|
154 |
FixedOneExchangeRateEngine engine = (FixedOneExchangeRateEngine) exrateEngine;
|
japod@58
|
155 |
return engine.getToCurrency();
|
japod@58
|
156 |
} else {
|
japod@58
|
157 |
throw new IllegalStateException("Method supported only for FixedOneExchangeRateEngine. This method is deprecated");
|
japod@58
|
158 |
}
|
japod@23
|
159 |
}
|
japod@41
|
160 |
|
japod@41
|
161 |
private ExchangeRate getExchangeRateImpl(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency) {
|
japod@58
|
162 |
ExchangeRate result = exrateEngine.getExchangeRate(fromCurrency, toCurrency);
|
japod@58
|
163 |
return result;
|
japod@58
|
164 |
}
|
japod@58
|
165 |
|
japod@58
|
166 |
private static class FixedOneExchangeRateEngine implements IExchangeRateEngine {
|
japod@58
|
167 |
|
japod@58
|
168 |
BigDecimal fromValue;
|
japod@58
|
169 |
ConvertorCurrency fromCurrency;
|
japod@58
|
170 |
BigDecimal toValue;
|
japod@58
|
171 |
ConvertorCurrency toCurrency;
|
japod@58
|
172 |
|
japod@58
|
173 |
private FixedOneExchangeRateEngine(BigDecimal fromValue, ConvertorCurrency fromCurrency, BigDecimal toValue, ConvertorCurrency toCurrency) {
|
japod@58
|
174 |
this.fromValue = fromValue;
|
japod@58
|
175 |
this.toValue = toValue;
|
japod@58
|
176 |
this.fromCurrency = fromCurrency;
|
japod@58
|
177 |
this.toCurrency = toCurrency;
|
japod@58
|
178 |
}
|
japod@58
|
179 |
|
japod@58
|
180 |
/**
|
japod@58
|
181 |
* Create IExchangeRateEngine conveting from <code>fromCurrency</code> to <code>toCurrency</code>
|
japod@58
|
182 |
* with echange rate <code>fromValue:toValue</code>
|
japod@58
|
183 |
* @param fromValue
|
japod@58
|
184 |
* @param fromCurrency
|
japod@58
|
185 |
* @param toValue
|
japod@58
|
186 |
* @param toCurrency
|
japod@58
|
187 |
* @return Returns instance of <code>FixedOneExchangeRateEngine</code>.
|
japod@58
|
188 |
*/
|
japod@58
|
189 |
private static IExchangeRateEngine createEngine(BigDecimal fromValue, ConvertorCurrency fromCurrency, BigDecimal toValue, ConvertorCurrency toCurrency) {
|
japod@58
|
190 |
return new FixedOneExchangeRateEngine(fromValue, fromCurrency, toValue, toCurrency);
|
japod@58
|
191 |
}
|
japod@58
|
192 |
|
japod@58
|
193 |
private BigDecimal getFromValue() {
|
japod@58
|
194 |
return fromValue;
|
japod@58
|
195 |
}
|
japod@58
|
196 |
|
japod@58
|
197 |
private BigDecimal getToValue() {
|
japod@58
|
198 |
return toValue;
|
japod@58
|
199 |
}
|
japod@58
|
200 |
|
japod@58
|
201 |
private ConvertorCurrency getFromCurrency() {
|
japod@58
|
202 |
return fromCurrency;
|
japod@58
|
203 |
}
|
japod@58
|
204 |
|
japod@58
|
205 |
private ConvertorCurrency getToCurrency() {
|
japod@58
|
206 |
return toCurrency;
|
japod@58
|
207 |
}
|
japod@58
|
208 |
|
japod@58
|
209 |
public ExchangeRate getExchangeRate(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency) {
|
japod@58
|
210 |
if (!fromCurrency.equals(this.fromCurrency)) {
|
japod@58
|
211 |
return null;
|
japod@58
|
212 |
}
|
japod@58
|
213 |
if (!toCurrency.equals(this.toCurrency)) {
|
japod@58
|
214 |
return null;
|
japod@58
|
215 |
}
|
japod@41
|
216 |
return new ExchangeRate(fromValue, toValue);
|
japod@41
|
217 |
}
|
japod@58
|
218 |
}
|
japod@58
|
219 |
|
japod@58
|
220 |
/**
|
japod@58
|
221 |
* Exchange rate engine able to hold several fixed exchange rates.
|
japod@58
|
222 |
*
|
japod@58
|
223 |
* @author arnostvalicek
|
japod@58
|
224 |
*/
|
japod@58
|
225 |
private static class FixedExchangeRateEngine implements IExchangeRateEngine {
|
japod@58
|
226 |
|
japod@58
|
227 |
private Map exchangeRateMap = new HashMap();
|
japod@58
|
228 |
|
japod@58
|
229 |
private FixedExchangeRateEngine() {
|
japod@41
|
230 |
}
|
japod@58
|
231 |
|
japod@58
|
232 |
/**
|
japod@58
|
233 |
* Create instance of <code>FixedExchangeRateEngine</code>.
|
japod@58
|
234 |
* @return Returns instance of <code>FixedExchangeRateEngine</code>.
|
japod@58
|
235 |
*/
|
japod@58
|
236 |
public static IExchangeRateEngine createEngine() {
|
japod@58
|
237 |
return new FixedExchangeRateEngine();
|
japod@58
|
238 |
}
|
japod@58
|
239 |
|
japod@58
|
240 |
public ExchangeRate getExchangeRate(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency) {
|
japod@58
|
241 |
Map map2 = (Map) exchangeRateMap.get(fromCurrency);
|
japod@58
|
242 |
if (map2 == null) {
|
japod@58
|
243 |
return null;
|
japod@58
|
244 |
}
|
japod@58
|
245 |
ExchangeRate result = (ExchangeRate) map2.get(toCurrency);
|
japod@58
|
246 |
return result;
|
japod@58
|
247 |
}
|
japod@58
|
248 |
|
japod@58
|
249 |
@SuppressWarnings("unchecked")
|
japod@58
|
250 |
public synchronized void addFixedCurencyRate(ConvertorCurrency fromCurrency, BigDecimal fromValue, ConvertorCurrency toCurrency, BigDecimal toValue) {
|
japod@58
|
251 |
if (fromValue == null) {
|
japod@58
|
252 |
throw new NullPointerException("fromValue can't be null");
|
japod@58
|
253 |
}
|
japod@58
|
254 |
if (toValue == null) {
|
japod@58
|
255 |
throw new NullPointerException("toValue can't be null");
|
japod@58
|
256 |
}
|
japod@58
|
257 |
Map map2 = (Map) exchangeRateMap.get(fromCurrency);
|
japod@58
|
258 |
if (map2 == null) {
|
japod@58
|
259 |
map2 = new HashMap();
|
japod@58
|
260 |
exchangeRateMap.put(fromCurrency, map2);
|
japod@58
|
261 |
}
|
japod@58
|
262 |
|
japod@58
|
263 |
ExchangeRate rate = new ExchangeRate(fromValue, toValue);
|
japod@58
|
264 |
map2.put(toCurrency, rate);
|
japod@58
|
265 |
}
|
japod@41
|
266 |
}
|
japod@23
|
267 |
}
|