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