1 package org.apidesign.apifest08.currency;
3 import java.math.BigDecimal;
5 import java.util.HashMap;
9 * Exchange rate provider. Provides exchange rate for two currencies (method {@link #getExchangeRate(ConvertorCurrency, ConvertorCurrency)} ).
11 * Several method can be created to create <code>ExchangeRateProvider</code>:
13 * <li>{@link #createExchangeRateProvider() } - create <em>simple</em> exchange rate provider using fixed echange rate.
14 * <li>{@link #createExchangeRateProvider(IExchangeRateEngine) } - create exchange rate provider using custom {@link IExchangeRateEngine}.
15 * <li>{@link #createDateExchangeRateProvider(IDateExchangeRateEngine) } - create exchange rate provider using custom {@link IDateExchangeRateEngine}.
18 * Date dependend exchange rate to be implemented.
20 * @author arnostvalicek
22 public class ExchangeRateProvider {
24 IExchangeRateEngine exrateEngine;
25 IDateExchangeRateEngine dateExrateEngine;
28 * Simple constructor for <code>ExchangeRateProviderM</code> which can provide fixed exchange rate.
30 * Describes conversion <em>from ONE</em> to <em>to ONE</em> currency.
32 * @param fromValue From value. BigDecimal value, precision should be set to currency precision.
33 * @param fromCurrency From currency.
34 * @param toValue To value. BigDecimal value, precision should be set to currency precision.
35 * @param toCurrency To currency.
36 * @deprecated deprecated since task2. Use {@link #createExchangeRateProvider() } instead of this constructor.
38 public ExchangeRateProvider(BigDecimal fromValue, ConvertorCurrency fromCurrency, BigDecimal toValue, ConvertorCurrency toCurrency) {
39 this.exrateEngine = FixedOneExchangeRateEngine.createEngine(fromValue, fromCurrency, toValue, toCurrency);
42 private ExchangeRateProvider() {
46 * Static method to create new exchange rate provider. This exchange rate provider does not contain
47 * any exchange rates (this is difference to public constructor).
48 * @return New <code>ExchangeRateProvider</code>
50 public static ExchangeRateProvider createExchangeRateProvider() {
51 ExchangeRateProvider provider = new ExchangeRateProvider();
52 provider.exrateEngine = FixedExchangeRateEngine.createEngine();
57 * Static method to create exchange rate provider which is using provided <code>IExchangeRateEngine</code>. This exchange rate provider is using
58 * <code>IExchangeRateEngine</code> to get actual exchange rate.
59 * @param exchangeRateEngine <code>IExchangeRateEngine</code> used to get exchange rate.
60 * @return Returns instance of <code>ExchangeRateProvider</code>
62 public static ExchangeRateProvider createExchangeRateProvider(IExchangeRateEngine exchangeRateEngine) {
63 ExchangeRateProvider provider = new ExchangeRateProvider();
64 provider.exrateEngine = exchangeRateEngine;
69 * Static method to create exchange rate provider which is using provided <code>IExIDateExchangeRateEnginechangeRateEngine</code>. This exchange rate provider is using
70 * <code>IExchangeRateEngine</code> to get actual exchange rate.
71 * @param exchangeRateEngine <code>IDateExchangeRateEngine</code> used to get exchange rate.
72 * @return Returns instance of <code>ExchangeRateProvider</code>
74 public static ExchangeRateProvider createDateExchangeRateProvider(IDateExchangeRateEngine exchangeRateEngine) {
75 ExchangeRateProvider provider = new ExchangeRateProvider();
76 provider.dateExrateEngine = exchangeRateEngine;
81 * Add new exchange rate to <code></code> to this <em>simple</em> exchange rate provider.
83 * Example of specifiing conversion rate: 100 SKK == 80 CZK:<br>
84 * <code>addFixedCurencyRate(ConvertorCurrency.getInstance("SKK"), new BigDecimal(100), ConvertorCurrency.getInstance("CZK"), new BigDecimal(80));</code>
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>.
88 * @param fromCurrency Source currency.
89 * @param fromValue Valye for from currency.
90 * @param toCurrency Target currency.
91 * @param toValue Value for target currency.
92 * @throws IllegalStateException Throws exception when adding fixed currency rate to exchange rate provider which is not created using {@link #createExchangeRateProvider() }.
94 public synchronized void addFixedCurencyRate(ConvertorCurrency fromCurrency, BigDecimal fromValue, ConvertorCurrency toCurrency, BigDecimal toValue) {
95 if (exrateEngine instanceof FixedExchangeRateEngine) {
96 ((FixedExchangeRateEngine) exrateEngine).addFixedCurencyRate(fromCurrency, fromValue, toCurrency, toValue);
98 throw new IllegalStateException("Cuurency rate can be added only to ExchangeRateProvider created with FixedExchangeRateEngine - using method createExchangeRateProvider()");
103 * Get fixed exange rate for currencies (from->to).
104 * @return Returns exchange rate.
105 * @deprecated deprecated since task2. Use {@link #getExchangeRate(ConvertorCurrency, ConvertorCurrency) }
107 public ExchangeRate getExchangeRate() {
108 //works only for FixedExchangeRateEngine
109 if (exrateEngine instanceof FixedOneExchangeRateEngine) {
110 FixedOneExchangeRateEngine engine = (FixedOneExchangeRateEngine) exrateEngine;
111 return new ExchangeRate(engine.getFromValue(), engine.getToValue());
113 throw new IllegalStateException("Method supported only for MinimalFixedExchangeRateEngine. This method is deprecated");
119 * Get fixed exange rate for currencies (from->to).
120 * @param fromCurrency Source currency.
121 * @param toCurrency Target currency.
122 * @return Returns exchange rate or <code>null</code> if exchange rate not found.
124 public ExchangeRate getExchangeRate(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency) {
125 return getExchangeRateImpl(fromCurrency, toCurrency,null);
129 * Get exange rate for currencies (from->to) for date.
130 * @param fromCurrency Source currency.
131 * @param toCurrency Target currency.
132 * @param date Conversion date.
133 * @return Returns exchange rate or <code>null</code> if exchange rate not found.
135 public ExchangeRate getExchangeRate(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency, Date date) {
136 return getExchangeRateImpl(fromCurrency, toCurrency,date);
140 * Get fixed exange rate for currencies (from->to) or reversed exchange rate (to->from).
141 * @param fromCurrency Source currency.
142 * @param toCurrency Target currency.
143 * @return Returns exchange rate or <code>null</code> if exchange rate not found.
145 public ExchangeRate getReversibleExchangeRate(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency) {
146 return getReversibleExrateImpl(fromCurrency, toCurrency,null);
150 * Get exange rate for currencies (from->to) or reversed exchange rate (to->from) for date.
151 * @param fromCurrency Source currency.
152 * @param toCurrency Target currency.
153 * @param date Conversion date.
154 * @return Returns exchange rate or <code>null</code> if exchange rate not found.
156 public ExchangeRate getReversibleExchangeRate(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency, Date date) {
157 return getReversibleExrateImpl(fromCurrency, toCurrency, date);
161 * Get exchange rate for currencies (from->to) based on provided date.
162 * @param date Date for which exchange rate should be provided.
163 * @return Returns exchange rate
164 * @deprecated deprecated since task2. No real implementation in version2.
166 public ExchangeRate getExchangeRate(Date date) {
167 //works only for FixedExchangeRateEngine
168 if (exrateEngine instanceof FixedOneExchangeRateEngine) {
169 FixedOneExchangeRateEngine engine = (FixedOneExchangeRateEngine) exrateEngine;
170 return new ExchangeRate(engine.getFromValue(), engine.getToValue());
172 throw new IllegalStateException("Method supported only for FixedOneExchangeRateEngine. This method is deprecated");
176 ConvertorCurrency getFromCurrency() {
177 if (exrateEngine instanceof FixedOneExchangeRateEngine) {
178 FixedOneExchangeRateEngine engine = (FixedOneExchangeRateEngine) exrateEngine;
179 return engine.getFromCurrency();
181 throw new IllegalStateException("Method supported only for FixedOneExchangeRateEngine. This method is deprecated");
185 ConvertorCurrency getToCurrency() {
186 if (exrateEngine instanceof FixedOneExchangeRateEngine) {
187 FixedOneExchangeRateEngine engine = (FixedOneExchangeRateEngine) exrateEngine;
188 return engine.getToCurrency();
190 throw new IllegalStateException("Method supported only for FixedOneExchangeRateEngine. This method is deprecated");
195 private ExchangeRate getReversibleExrateImpl(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency,Date date) {
196 ExchangeRate rate = getExchangeRateImpl(fromCurrency, toCurrency, date);
198 ExchangeRate revertedRate = getExchangeRateImpl(toCurrency, fromCurrency, date);
199 if (revertedRate != null) {
200 rate = ExchangeRate.createRevertedRate(revertedRate);
206 private ExchangeRate getExchangeRateImpl(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency,Date date) {
208 if (exrateEngine!=null) {
209 result = exrateEngine.getExchangeRate(fromCurrency, toCurrency);
210 } else if (dateExrateEngine!=null) {
211 result = dateExrateEngine.getExchangeRate(fromCurrency, toCurrency, date);
213 throw new IllegalStateException("No exchange rate engine provided");
218 private static class FixedOneExchangeRateEngine implements IExchangeRateEngine {
220 BigDecimal fromValue;
221 ConvertorCurrency fromCurrency;
223 ConvertorCurrency toCurrency;
225 private FixedOneExchangeRateEngine(BigDecimal fromValue, ConvertorCurrency fromCurrency, BigDecimal toValue, ConvertorCurrency toCurrency) {
226 this.fromValue = fromValue;
227 this.toValue = toValue;
228 this.fromCurrency = fromCurrency;
229 this.toCurrency = toCurrency;
233 * Create IExchangeRateEngine conveting from <code>fromCurrency</code> to <code>toCurrency</code>
234 * with echange rate <code>fromValue:toValue</code>
236 * @param fromCurrency
239 * @return Returns instance of <code>FixedOneExchangeRateEngine</code>.
241 private static IExchangeRateEngine createEngine(BigDecimal fromValue, ConvertorCurrency fromCurrency, BigDecimal toValue, ConvertorCurrency toCurrency) {
242 return new FixedOneExchangeRateEngine(fromValue, fromCurrency, toValue, toCurrency);
245 private BigDecimal getFromValue() {
249 private BigDecimal getToValue() {
253 private ConvertorCurrency getFromCurrency() {
257 private ConvertorCurrency getToCurrency() {
261 public ExchangeRate getExchangeRate(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency) {
262 if (!fromCurrency.equals(this.fromCurrency)) {
265 if (!toCurrency.equals(this.toCurrency)) {
268 return new ExchangeRate(fromValue, toValue);
273 * Exchange rate engine able to hold several fixed exchange rates.
275 * @author arnostvalicek
277 private static class FixedExchangeRateEngine implements IExchangeRateEngine {
279 private Map<ConvertorCurrency, Map<ConvertorCurrency, ExchangeRate>> exchangeRateMap = new HashMap<ConvertorCurrency, Map<ConvertorCurrency, ExchangeRate>>();
281 private FixedExchangeRateEngine() {
285 * Create instance of <code>FixedExchangeRateEngine</code>.
286 * @return Returns instance of <code>FixedExchangeRateEngine</code>.
288 public static IExchangeRateEngine createEngine() {
289 return new FixedExchangeRateEngine();
292 public ExchangeRate getExchangeRate(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency) {
293 Map<ConvertorCurrency,ExchangeRate> map2 = exchangeRateMap.get(fromCurrency);
297 ExchangeRate result = map2.get(toCurrency);
301 public synchronized void addFixedCurencyRate(ConvertorCurrency fromCurrency, BigDecimal fromValue, ConvertorCurrency toCurrency, BigDecimal toValue) {
302 if (fromValue == null) {
303 throw new NullPointerException("fromValue can't be null");
305 if (toValue == null) {
306 throw new NullPointerException("toValue can't be null");
308 Map<ConvertorCurrency,ExchangeRate> map2 = exchangeRateMap.get(fromCurrency);
310 map2 = new HashMap<ConvertorCurrency,ExchangeRate>();
311 exchangeRateMap.put(fromCurrency, map2);
314 ExchangeRate rate = new ExchangeRate(fromValue, toValue);
315 map2.put(toCurrency, rate);