1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/task4/solution13/src/org/apidesign/apifest08/currency/ExchangeRateProvider.java Sat Oct 11 23:38:46 2008 +0200
1.3 @@ -0,0 +1,267 @@
1.4 +package org.apidesign.apifest08.currency;
1.5 +
1.6 +import java.math.BigDecimal;
1.7 +import java.util.Date;
1.8 +import java.util.HashMap;
1.9 +import java.util.Map;
1.10 +
1.11 +/**
1.12 + * Exchange rate provider. Provides exchange rate for two currencies (method {@link #getExchangeRate(ConvertorCurrency, ConvertorCurrency)} ).
1.13 + * <p>
1.14 + * Several method can be created to create <code>ExchangeRateProvider</code>:
1.15 + * <ul>
1.16 + * <li>{@link #createExchangeRateProvider() } - create <em>simple</em> exchange rate provider using fixed echange rate.
1.17 + * <li>{@link #createExchangeRateProvider(IExchangeRateEngine) } - create exchange rate provider using custom {@link IExchangeRateEngine}.
1.18 + * </ul>
1.19 + * <p>
1.20 + * Date dependend exchange rate to be implemented.
1.21 + *
1.22 + * @author arnostvalicek
1.23 + */
1.24 +public class ExchangeRateProvider {
1.25 +
1.26 + IExchangeRateEngine exrateEngine;
1.27 +
1.28 + /**
1.29 + * Simple constructor for <code>ExchangeRateProviderM</code> which can provide fixed exchange rate.
1.30 + *
1.31 + * Describes conversion <em>from ONE</em> to <em>to ONE</em> currency.
1.32 + *
1.33 + * @param fromValue From value. BigDecimal value, precision should be set to currency precision.
1.34 + * @param fromCurrency From currency.
1.35 + * @param toValue To value. BigDecimal value, precision should be set to currency precision.
1.36 + * @param toCurrency To currency.
1.37 + * @deprecated deprecated since task2. Use {@link #createExchangeRateProvider() } instead of this constructor.
1.38 + */
1.39 + public ExchangeRateProvider(BigDecimal fromValue, ConvertorCurrency fromCurrency, BigDecimal toValue, ConvertorCurrency toCurrency) {
1.40 + this.exrateEngine = FixedOneExchangeRateEngine.createEngine(fromValue, fromCurrency, toValue, toCurrency);
1.41 + }
1.42 +
1.43 + private ExchangeRateProvider() {
1.44 + }
1.45 +
1.46 + /**
1.47 + * Static method to create new exchange rate provider. This exchange rate provider does not contain
1.48 + * any exchange rates (this is difference to public constructor).
1.49 + * @return New <code>ExchangeRateProvider</code>
1.50 + */
1.51 + public static ExchangeRateProvider createExchangeRateProvider() {
1.52 + ExchangeRateProvider provider = new ExchangeRateProvider();
1.53 + provider.exrateEngine = FixedExchangeRateEngine.createEngine();
1.54 + return provider;
1.55 + }
1.56 +
1.57 + /**
1.58 + * Static method to create exchange rate provider which is using provided <code>IExchangeRateEngine</code>. This exchange rate provider is using
1.59 + * <code>IExchangeRateEngine</code> to get actual exchange rate.
1.60 + * @param exchangeRateEngine <code>IExchangeRateEngine</code> used to get exchange rate.
1.61 + * @return Returns instance of <code>ExchangeRateProvider</code>
1.62 + */
1.63 + public static ExchangeRateProvider createExchangeRateProvider(IExchangeRateEngine exchangeRateEngine) {
1.64 + ExchangeRateProvider provider = new ExchangeRateProvider();
1.65 + provider.exrateEngine = exchangeRateEngine;
1.66 + return provider;
1.67 + }
1.68 +
1.69 + /**
1.70 + * Add new exchange rate to <code></code> to this <em>simple</em> exchange rate provider.
1.71 + * <p>
1.72 + * Example of specifiing conversion rate: 100 SKK == 80 CZK:<br>
1.73 + * <code>addFixedCurencyRate(ConvertorCurrency.getInstance("SKK"), new BigDecimal(100), ConvertorCurrency.getInstance("CZK"), new BigDecimal(80));</code>
1.74 + * <p>
1.75 + * 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>.
1.76 + *
1.77 + * @param fromCurrency Source currency.
1.78 + * @param fromValue Valye for from currency.
1.79 + * @param toCurrency Target currency.
1.80 + * @param toValue Value for target currency.
1.81 + * @throws IllegalStateException Throws exception when adding fixed currency rate to exchange rate provider which is not created using {@link #createExchangeRateProvider() }.
1.82 + */
1.83 + public synchronized void addFixedCurencyRate(ConvertorCurrency fromCurrency, BigDecimal fromValue, ConvertorCurrency toCurrency, BigDecimal toValue) {
1.84 + if (exrateEngine instanceof FixedExchangeRateEngine) {
1.85 + ((FixedExchangeRateEngine) exrateEngine).addFixedCurencyRate(fromCurrency, fromValue, toCurrency, toValue);
1.86 + } else {
1.87 + throw new IllegalStateException("Cuurency rate can be added only to ExchangeRateProvider created with FixedExchangeRateEngine - using method createExchangeRateProvider()");
1.88 + }
1.89 + }
1.90 +
1.91 + /**
1.92 + * Get fixed exange rate for currencies (from->to).
1.93 + * @return Returns exchange rate.
1.94 + * @deprecated deprecated since task2. Use {@link #getExchangeRate(ConvertorCurrency, ConvertorCurrency) }
1.95 + */
1.96 + public ExchangeRate getExchangeRate() {
1.97 + //works only for FixedExchangeRateEngine
1.98 + if (exrateEngine instanceof FixedOneExchangeRateEngine) {
1.99 + FixedOneExchangeRateEngine engine = (FixedOneExchangeRateEngine) exrateEngine;
1.100 + return new ExchangeRate(engine.getFromValue(), engine.getToValue());
1.101 + } else {
1.102 + throw new IllegalStateException("Method supported only for MinimalFixedExchangeRateEngine. This method is deprecated");
1.103 + }
1.104 +
1.105 + }
1.106 +
1.107 + /**
1.108 + * Get fixed exange rate for currencies (from->to).
1.109 + * @return Returns exchange rate or <code>null</code> if exchange rate not found.
1.110 + */
1.111 + public ExchangeRate getExchangeRate(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency) {
1.112 + return getExchangeRateImpl(fromCurrency, toCurrency);
1.113 + }
1.114 +
1.115 + /**
1.116 + * Get fixed exange rate for currencies (from->to) or reversed exchange rate (to->from).
1.117 + * @return Returns exchange rate or <code>null</code> if exchange rate not found.
1.118 + */
1.119 + public ExchangeRate getReversibleExchangeRate(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency) {
1.120 + ExchangeRate rate = getExchangeRateImpl(fromCurrency, toCurrency);
1.121 + if (rate == null) {
1.122 + ExchangeRate revertedRate = getExchangeRateImpl(toCurrency, fromCurrency);
1.123 + if (revertedRate != null) {
1.124 + rate = ExchangeRate.createRevertedRate(revertedRate);
1.125 + }
1.126 + }
1.127 + return rate;
1.128 + }
1.129 +
1.130 + /**
1.131 + * Get exchange rate for currencies (from->to) based on provided date.
1.132 + * @param date Date for which exchange rate should be provided.
1.133 + * @return Returns exchange rate
1.134 + * @deprecated deprecated since task2. No real implementation in version2.
1.135 + */
1.136 + public ExchangeRate getExchangeRate(Date date) {
1.137 + //works only for FixedExchangeRateEngine
1.138 + if (exrateEngine instanceof FixedOneExchangeRateEngine) {
1.139 + FixedOneExchangeRateEngine engine = (FixedOneExchangeRateEngine) exrateEngine;
1.140 + return new ExchangeRate(engine.getFromValue(), engine.getToValue());
1.141 + } else {
1.142 + throw new IllegalStateException("Method supported only for FixedOneExchangeRateEngine. This method is deprecated");
1.143 + }
1.144 + }
1.145 +
1.146 + ConvertorCurrency getFromCurrency() {
1.147 + if (exrateEngine instanceof FixedOneExchangeRateEngine) {
1.148 + FixedOneExchangeRateEngine engine = (FixedOneExchangeRateEngine) exrateEngine;
1.149 + return engine.getFromCurrency();
1.150 + } else {
1.151 + throw new IllegalStateException("Method supported only for FixedOneExchangeRateEngine. This method is deprecated");
1.152 + }
1.153 + }
1.154 +
1.155 + ConvertorCurrency getToCurrency() {
1.156 + if (exrateEngine instanceof FixedOneExchangeRateEngine) {
1.157 + FixedOneExchangeRateEngine engine = (FixedOneExchangeRateEngine) exrateEngine;
1.158 + return engine.getToCurrency();
1.159 + } else {
1.160 + throw new IllegalStateException("Method supported only for FixedOneExchangeRateEngine. This method is deprecated");
1.161 + }
1.162 + }
1.163 +
1.164 + private ExchangeRate getExchangeRateImpl(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency) {
1.165 + ExchangeRate result = exrateEngine.getExchangeRate(fromCurrency, toCurrency);
1.166 + return result;
1.167 + }
1.168 +
1.169 + private static class FixedOneExchangeRateEngine implements IExchangeRateEngine {
1.170 +
1.171 + BigDecimal fromValue;
1.172 + ConvertorCurrency fromCurrency;
1.173 + BigDecimal toValue;
1.174 + ConvertorCurrency toCurrency;
1.175 +
1.176 + private FixedOneExchangeRateEngine(BigDecimal fromValue, ConvertorCurrency fromCurrency, BigDecimal toValue, ConvertorCurrency toCurrency) {
1.177 + this.fromValue = fromValue;
1.178 + this.toValue = toValue;
1.179 + this.fromCurrency = fromCurrency;
1.180 + this.toCurrency = toCurrency;
1.181 + }
1.182 +
1.183 + /**
1.184 + * Create IExchangeRateEngine conveting from <code>fromCurrency</code> to <code>toCurrency</code>
1.185 + * with echange rate <code>fromValue:toValue</code>
1.186 + * @param fromValue
1.187 + * @param fromCurrency
1.188 + * @param toValue
1.189 + * @param toCurrency
1.190 + * @return Returns instance of <code>FixedOneExchangeRateEngine</code>.
1.191 + */
1.192 + private static IExchangeRateEngine createEngine(BigDecimal fromValue, ConvertorCurrency fromCurrency, BigDecimal toValue, ConvertorCurrency toCurrency) {
1.193 + return new FixedOneExchangeRateEngine(fromValue, fromCurrency, toValue, toCurrency);
1.194 + }
1.195 +
1.196 + private BigDecimal getFromValue() {
1.197 + return fromValue;
1.198 + }
1.199 +
1.200 + private BigDecimal getToValue() {
1.201 + return toValue;
1.202 + }
1.203 +
1.204 + private ConvertorCurrency getFromCurrency() {
1.205 + return fromCurrency;
1.206 + }
1.207 +
1.208 + private ConvertorCurrency getToCurrency() {
1.209 + return toCurrency;
1.210 + }
1.211 +
1.212 + public ExchangeRate getExchangeRate(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency) {
1.213 + if (!fromCurrency.equals(this.fromCurrency)) {
1.214 + return null;
1.215 + }
1.216 + if (!toCurrency.equals(this.toCurrency)) {
1.217 + return null;
1.218 + }
1.219 + return new ExchangeRate(fromValue, toValue);
1.220 + }
1.221 + }
1.222 +
1.223 + /**
1.224 + * Exchange rate engine able to hold several fixed exchange rates.
1.225 + *
1.226 + * @author arnostvalicek
1.227 + */
1.228 + private static class FixedExchangeRateEngine implements IExchangeRateEngine {
1.229 +
1.230 + private Map exchangeRateMap = new HashMap();
1.231 +
1.232 + private FixedExchangeRateEngine() {
1.233 + }
1.234 +
1.235 + /**
1.236 + * Create instance of <code>FixedExchangeRateEngine</code>.
1.237 + * @return Returns instance of <code>FixedExchangeRateEngine</code>.
1.238 + */
1.239 + public static IExchangeRateEngine createEngine() {
1.240 + return new FixedExchangeRateEngine();
1.241 + }
1.242 +
1.243 + public ExchangeRate getExchangeRate(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency) {
1.244 + Map map2 = (Map) exchangeRateMap.get(fromCurrency);
1.245 + if (map2 == null) {
1.246 + return null;
1.247 + }
1.248 + ExchangeRate result = (ExchangeRate) map2.get(toCurrency);
1.249 + return result;
1.250 + }
1.251 +
1.252 + @SuppressWarnings("unchecked")
1.253 + public synchronized void addFixedCurencyRate(ConvertorCurrency fromCurrency, BigDecimal fromValue, ConvertorCurrency toCurrency, BigDecimal toValue) {
1.254 + if (fromValue == null) {
1.255 + throw new NullPointerException("fromValue can't be null");
1.256 + }
1.257 + if (toValue == null) {
1.258 + throw new NullPointerException("toValue can't be null");
1.259 + }
1.260 + Map map2 = (Map) exchangeRateMap.get(fromCurrency);
1.261 + if (map2 == null) {
1.262 + map2 = new HashMap();
1.263 + exchangeRateMap.put(fromCurrency, map2);
1.264 + }
1.265 +
1.266 + ExchangeRate rate = new ExchangeRate(fromValue, toValue);
1.267 + map2.put(toCurrency, rate);
1.268 + }
1.269 + }
1.270 +}