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