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}.
17 * Date dependend exchange rate to be implemented.
19 * @author arnostvalicek
21 public class ExchangeRateProvider {
23 IExchangeRateEngine exrateEngine;
26 * Simple constructor for <code>ExchangeRateProviderM</code> which can provide fixed exchange rate.
28 * Describes conversion <em>from ONE</em> to <em>to ONE</em> currency.
30 * @param fromValue From value. BigDecimal value, precision should be set to currency precision.
31 * @param fromCurrency From currency.
32 * @param toValue To value. BigDecimal value, precision should be set to currency precision.
33 * @param toCurrency To currency.
34 * @deprecated deprecated since task2. Use {@link #createExchangeRateProvider() } instead of this constructor.
36 public ExchangeRateProvider(BigDecimal fromValue, ConvertorCurrency fromCurrency, BigDecimal toValue, ConvertorCurrency toCurrency) {
37 this.exrateEngine = FixedOneExchangeRateEngine.createEngine(fromValue, fromCurrency, toValue, toCurrency);
40 private ExchangeRateProvider() {
44 * Static method to create new exchange rate provider. This exchange rate provider does not contain
45 * any exchange rates (this is difference to public constructor).
46 * @return New <code>ExchangeRateProvider</code>
48 public static ExchangeRateProvider createExchangeRateProvider() {
49 ExchangeRateProvider provider = new ExchangeRateProvider();
50 provider.exrateEngine = FixedExchangeRateEngine.createEngine();
55 * Static method to create exchange rate provider which is using provided <code>IExchangeRateEngine</code>. This exchange rate provider is using
56 * <code>IExchangeRateEngine</code> to get actual exchange rate.
57 * @param exchangeRateEngine <code>IExchangeRateEngine</code> used to get exchange rate.
58 * @return Returns instance of <code>ExchangeRateProvider</code>
60 public static ExchangeRateProvider createExchangeRateProvider(IExchangeRateEngine exchangeRateEngine) {
61 ExchangeRateProvider provider = new ExchangeRateProvider();
62 provider.exrateEngine = exchangeRateEngine;
67 * Add new exchange rate to <code></code> to this <em>simple</em> exchange rate provider.
69 * Example of specifiing conversion rate: 100 SKK == 80 CZK:<br>
70 * <code>addFixedCurencyRate(ConvertorCurrency.getInstance("SKK"), new BigDecimal(100), ConvertorCurrency.getInstance("CZK"), new BigDecimal(80));</code>
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>.
74 * @param fromCurrency Source currency.
75 * @param fromValue Valye for from currency.
76 * @param toCurrency Target currency.
77 * @param toValue Value for target currency.
78 * @throws IllegalStateException Throws exception when adding fixed currency rate to exchange rate provider which is not created using {@link #createExchangeRateProvider() }.
80 public synchronized void addFixedCurencyRate(ConvertorCurrency fromCurrency, BigDecimal fromValue, ConvertorCurrency toCurrency, BigDecimal toValue) {
81 if (exrateEngine instanceof FixedExchangeRateEngine) {
82 ((FixedExchangeRateEngine) exrateEngine).addFixedCurencyRate(fromCurrency, fromValue, toCurrency, toValue);
84 throw new IllegalStateException("Cuurency rate can be added only to ExchangeRateProvider created with FixedExchangeRateEngine - using method createExchangeRateProvider()");
89 * Get fixed exange rate for currencies (from->to).
90 * @return Returns exchange rate.
91 * @deprecated deprecated since task2. Use {@link #getExchangeRate(ConvertorCurrency, ConvertorCurrency) }
93 public ExchangeRate getExchangeRate() {
94 //works only for FixedExchangeRateEngine
95 if (exrateEngine instanceof FixedOneExchangeRateEngine) {
96 FixedOneExchangeRateEngine engine = (FixedOneExchangeRateEngine) exrateEngine;
97 return new ExchangeRate(engine.getFromValue(), engine.getToValue());
99 throw new IllegalStateException("Method supported only for MinimalFixedExchangeRateEngine. This method is deprecated");
105 * Get fixed exange rate for currencies (from->to).
106 * @return Returns exchange rate or <code>null</code> if exchange rate not found.
108 public ExchangeRate getExchangeRate(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency) {
109 return getExchangeRateImpl(fromCurrency, toCurrency);
113 * Get fixed exange rate for currencies (from->to) or reversed exchange rate (to->from).
114 * @return Returns exchange rate or <code>null</code> if exchange rate not found.
116 public ExchangeRate getReversibleExchangeRate(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency) {
117 ExchangeRate rate = getExchangeRateImpl(fromCurrency, toCurrency);
119 ExchangeRate revertedRate = getExchangeRateImpl(toCurrency, fromCurrency);
120 if (revertedRate != null) {
121 rate = ExchangeRate.createRevertedRate(revertedRate);
128 * Get exchange rate for currencies (from->to) based on provided date.
129 * @param date Date for which exchange rate should be provided.
130 * @return Returns exchange rate
131 * @deprecated deprecated since task2. No real implementation in version2.
133 public ExchangeRate getExchangeRate(Date date) {
134 //works only for FixedExchangeRateEngine
135 if (exrateEngine instanceof FixedOneExchangeRateEngine) {
136 FixedOneExchangeRateEngine engine = (FixedOneExchangeRateEngine) exrateEngine;
137 return new ExchangeRate(engine.getFromValue(), engine.getToValue());
139 throw new IllegalStateException("Method supported only for FixedOneExchangeRateEngine. This method is deprecated");
143 ConvertorCurrency getFromCurrency() {
144 if (exrateEngine instanceof FixedOneExchangeRateEngine) {
145 FixedOneExchangeRateEngine engine = (FixedOneExchangeRateEngine) exrateEngine;
146 return engine.getFromCurrency();
148 throw new IllegalStateException("Method supported only for FixedOneExchangeRateEngine. This method is deprecated");
152 ConvertorCurrency getToCurrency() {
153 if (exrateEngine instanceof FixedOneExchangeRateEngine) {
154 FixedOneExchangeRateEngine engine = (FixedOneExchangeRateEngine) exrateEngine;
155 return engine.getToCurrency();
157 throw new IllegalStateException("Method supported only for FixedOneExchangeRateEngine. This method is deprecated");
161 private ExchangeRate getExchangeRateImpl(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency) {
162 ExchangeRate result = exrateEngine.getExchangeRate(fromCurrency, toCurrency);
166 private static class FixedOneExchangeRateEngine implements IExchangeRateEngine {
168 BigDecimal fromValue;
169 ConvertorCurrency fromCurrency;
171 ConvertorCurrency toCurrency;
173 private FixedOneExchangeRateEngine(BigDecimal fromValue, ConvertorCurrency fromCurrency, BigDecimal toValue, ConvertorCurrency toCurrency) {
174 this.fromValue = fromValue;
175 this.toValue = toValue;
176 this.fromCurrency = fromCurrency;
177 this.toCurrency = toCurrency;
181 * Create IExchangeRateEngine conveting from <code>fromCurrency</code> to <code>toCurrency</code>
182 * with echange rate <code>fromValue:toValue</code>
184 * @param fromCurrency
187 * @return Returns instance of <code>FixedOneExchangeRateEngine</code>.
189 private static IExchangeRateEngine createEngine(BigDecimal fromValue, ConvertorCurrency fromCurrency, BigDecimal toValue, ConvertorCurrency toCurrency) {
190 return new FixedOneExchangeRateEngine(fromValue, fromCurrency, toValue, toCurrency);
193 private BigDecimal getFromValue() {
197 private BigDecimal getToValue() {
201 private ConvertorCurrency getFromCurrency() {
205 private ConvertorCurrency getToCurrency() {
209 public ExchangeRate getExchangeRate(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency) {
210 if (!fromCurrency.equals(this.fromCurrency)) {
213 if (!toCurrency.equals(this.toCurrency)) {
216 return new ExchangeRate(fromValue, toValue);
221 * Exchange rate engine able to hold several fixed exchange rates.
223 * @author arnostvalicek
225 private static class FixedExchangeRateEngine implements IExchangeRateEngine {
227 private Map exchangeRateMap = new HashMap();
229 private FixedExchangeRateEngine() {
233 * Create instance of <code>FixedExchangeRateEngine</code>.
234 * @return Returns instance of <code>FixedExchangeRateEngine</code>.
236 public static IExchangeRateEngine createEngine() {
237 return new FixedExchangeRateEngine();
240 public ExchangeRate getExchangeRate(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency) {
241 Map map2 = (Map) exchangeRateMap.get(fromCurrency);
245 ExchangeRate result = (ExchangeRate) map2.get(toCurrency);
249 @SuppressWarnings("unchecked")
250 public synchronized void addFixedCurencyRate(ConvertorCurrency fromCurrency, BigDecimal fromValue, ConvertorCurrency toCurrency, BigDecimal toValue) {
251 if (fromValue == null) {
252 throw new NullPointerException("fromValue can't be null");
254 if (toValue == null) {
255 throw new NullPointerException("toValue can't be null");
257 Map map2 = (Map) exchangeRateMap.get(fromCurrency);
259 map2 = new HashMap();
260 exchangeRateMap.put(fromCurrency, map2);
263 ExchangeRate rate = new ExchangeRate(fromValue, toValue);
264 map2.put(toCurrency, rate);