diff -r 07c16ec15a25 -r 58ec6da75f6f task4/solution13/src/org/apidesign/apifest08/currency/ExchangeRateProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/task4/solution13/src/org/apidesign/apifest08/currency/ExchangeRateProvider.java Sat Oct 11 23:38:46 2008 +0200 @@ -0,0 +1,267 @@ +package org.apidesign.apifest08.currency; + +import java.math.BigDecimal; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +/** + * Exchange rate provider. Provides exchange rate for two currencies (method {@link #getExchangeRate(ConvertorCurrency, ConvertorCurrency)} ). + *

+ * Several method can be created to create ExchangeRateProvider: + *

+ *

+ * Date dependend exchange rate to be implemented. + * + * @author arnostvalicek + */ +public class ExchangeRateProvider { + + IExchangeRateEngine exrateEngine; + + /** + * Simple constructor for ExchangeRateProviderM which can provide fixed exchange rate. + * + * Describes conversion from ONE to to ONE currency. + * + * @param fromValue From value. BigDecimal value, precision should be set to currency precision. + * @param fromCurrency From currency. + * @param toValue To value. BigDecimal value, precision should be set to currency precision. + * @param toCurrency To currency. + * @deprecated deprecated since task2. Use {@link #createExchangeRateProvider() } instead of this constructor. + */ + public ExchangeRateProvider(BigDecimal fromValue, ConvertorCurrency fromCurrency, BigDecimal toValue, ConvertorCurrency toCurrency) { + this.exrateEngine = FixedOneExchangeRateEngine.createEngine(fromValue, fromCurrency, toValue, toCurrency); + } + + private ExchangeRateProvider() { + } + + /** + * Static method to create new exchange rate provider. This exchange rate provider does not contain + * any exchange rates (this is difference to public constructor). + * @return New ExchangeRateProvider + */ + public static ExchangeRateProvider createExchangeRateProvider() { + ExchangeRateProvider provider = new ExchangeRateProvider(); + provider.exrateEngine = FixedExchangeRateEngine.createEngine(); + return provider; + } + + /** + * Static method to create exchange rate provider which is using provided IExchangeRateEngine. This exchange rate provider is using + * IExchangeRateEngine to get actual exchange rate. + * @param exchangeRateEngine IExchangeRateEngine used to get exchange rate. + * @return Returns instance of ExchangeRateProvider + */ + public static ExchangeRateProvider createExchangeRateProvider(IExchangeRateEngine exchangeRateEngine) { + ExchangeRateProvider provider = new ExchangeRateProvider(); + provider.exrateEngine = exchangeRateEngine; + return provider; + } + + /** + * Add new exchange rate to to this simple exchange rate provider. + *

+ * Example of specifiing conversion rate: 100 SKK == 80 CZK:
+ * addFixedCurencyRate(ConvertorCurrency.getInstance("SKK"), new BigDecimal(100), ConvertorCurrency.getInstance("CZK"), new BigDecimal(80)); + *

+ * This method may be used only when ExchangeRateProvider is created using {@link #createExchangeRateProvider() } - creating exchange rate provider without external IExchangeRateEngine. + * + * @param fromCurrency Source currency. + * @param fromValue Valye for from currency. + * @param toCurrency Target currency. + * @param toValue Value for target currency. + * @throws IllegalStateException Throws exception when adding fixed currency rate to exchange rate provider which is not created using {@link #createExchangeRateProvider() }. + */ + public synchronized void addFixedCurencyRate(ConvertorCurrency fromCurrency, BigDecimal fromValue, ConvertorCurrency toCurrency, BigDecimal toValue) { + if (exrateEngine instanceof FixedExchangeRateEngine) { + ((FixedExchangeRateEngine) exrateEngine).addFixedCurencyRate(fromCurrency, fromValue, toCurrency, toValue); + } else { + throw new IllegalStateException("Cuurency rate can be added only to ExchangeRateProvider created with FixedExchangeRateEngine - using method createExchangeRateProvider()"); + } + } + + /** + * Get fixed exange rate for currencies (from->to). + * @return Returns exchange rate. + * @deprecated deprecated since task2. Use {@link #getExchangeRate(ConvertorCurrency, ConvertorCurrency) } + */ + public ExchangeRate getExchangeRate() { + //works only for FixedExchangeRateEngine + if (exrateEngine instanceof FixedOneExchangeRateEngine) { + FixedOneExchangeRateEngine engine = (FixedOneExchangeRateEngine) exrateEngine; + return new ExchangeRate(engine.getFromValue(), engine.getToValue()); + } else { + throw new IllegalStateException("Method supported only for MinimalFixedExchangeRateEngine. This method is deprecated"); + } + + } + + /** + * Get fixed exange rate for currencies (from->to). + * @return Returns exchange rate or null if exchange rate not found. + */ + public ExchangeRate getExchangeRate(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency) { + return getExchangeRateImpl(fromCurrency, toCurrency); + } + + /** + * Get fixed exange rate for currencies (from->to) or reversed exchange rate (to->from). + * @return Returns exchange rate or null if exchange rate not found. + */ + public ExchangeRate getReversibleExchangeRate(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency) { + ExchangeRate rate = getExchangeRateImpl(fromCurrency, toCurrency); + if (rate == null) { + ExchangeRate revertedRate = getExchangeRateImpl(toCurrency, fromCurrency); + if (revertedRate != null) { + rate = ExchangeRate.createRevertedRate(revertedRate); + } + } + return rate; + } + + /** + * Get exchange rate for currencies (from->to) based on provided date. + * @param date Date for which exchange rate should be provided. + * @return Returns exchange rate + * @deprecated deprecated since task2. No real implementation in version2. + */ + public ExchangeRate getExchangeRate(Date date) { + //works only for FixedExchangeRateEngine + if (exrateEngine instanceof FixedOneExchangeRateEngine) { + FixedOneExchangeRateEngine engine = (FixedOneExchangeRateEngine) exrateEngine; + return new ExchangeRate(engine.getFromValue(), engine.getToValue()); + } else { + throw new IllegalStateException("Method supported only for FixedOneExchangeRateEngine. This method is deprecated"); + } + } + + ConvertorCurrency getFromCurrency() { + if (exrateEngine instanceof FixedOneExchangeRateEngine) { + FixedOneExchangeRateEngine engine = (FixedOneExchangeRateEngine) exrateEngine; + return engine.getFromCurrency(); + } else { + throw new IllegalStateException("Method supported only for FixedOneExchangeRateEngine. This method is deprecated"); + } + } + + ConvertorCurrency getToCurrency() { + if (exrateEngine instanceof FixedOneExchangeRateEngine) { + FixedOneExchangeRateEngine engine = (FixedOneExchangeRateEngine) exrateEngine; + return engine.getToCurrency(); + } else { + throw new IllegalStateException("Method supported only for FixedOneExchangeRateEngine. This method is deprecated"); + } + } + + private ExchangeRate getExchangeRateImpl(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency) { + ExchangeRate result = exrateEngine.getExchangeRate(fromCurrency, toCurrency); + return result; + } + + private static class FixedOneExchangeRateEngine implements IExchangeRateEngine { + + BigDecimal fromValue; + ConvertorCurrency fromCurrency; + BigDecimal toValue; + ConvertorCurrency toCurrency; + + private FixedOneExchangeRateEngine(BigDecimal fromValue, ConvertorCurrency fromCurrency, BigDecimal toValue, ConvertorCurrency toCurrency) { + this.fromValue = fromValue; + this.toValue = toValue; + this.fromCurrency = fromCurrency; + this.toCurrency = toCurrency; + } + + /** + * Create IExchangeRateEngine conveting from fromCurrency to toCurrency + * with echange rate fromValue:toValue + * @param fromValue + * @param fromCurrency + * @param toValue + * @param toCurrency + * @return Returns instance of FixedOneExchangeRateEngine. + */ + private static IExchangeRateEngine createEngine(BigDecimal fromValue, ConvertorCurrency fromCurrency, BigDecimal toValue, ConvertorCurrency toCurrency) { + return new FixedOneExchangeRateEngine(fromValue, fromCurrency, toValue, toCurrency); + } + + private BigDecimal getFromValue() { + return fromValue; + } + + private BigDecimal getToValue() { + return toValue; + } + + private ConvertorCurrency getFromCurrency() { + return fromCurrency; + } + + private ConvertorCurrency getToCurrency() { + return toCurrency; + } + + public ExchangeRate getExchangeRate(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency) { + if (!fromCurrency.equals(this.fromCurrency)) { + return null; + } + if (!toCurrency.equals(this.toCurrency)) { + return null; + } + return new ExchangeRate(fromValue, toValue); + } + } + + /** + * Exchange rate engine able to hold several fixed exchange rates. + * + * @author arnostvalicek + */ + private static class FixedExchangeRateEngine implements IExchangeRateEngine { + + private Map exchangeRateMap = new HashMap(); + + private FixedExchangeRateEngine() { + } + + /** + * Create instance of FixedExchangeRateEngine. + * @return Returns instance of FixedExchangeRateEngine. + */ + public static IExchangeRateEngine createEngine() { + return new FixedExchangeRateEngine(); + } + + public ExchangeRate getExchangeRate(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency) { + Map map2 = (Map) exchangeRateMap.get(fromCurrency); + if (map2 == null) { + return null; + } + ExchangeRate result = (ExchangeRate) map2.get(toCurrency); + return result; + } + + @SuppressWarnings("unchecked") + public synchronized void addFixedCurencyRate(ConvertorCurrency fromCurrency, BigDecimal fromValue, ConvertorCurrency toCurrency, BigDecimal toValue) { + if (fromValue == null) { + throw new NullPointerException("fromValue can't be null"); + } + if (toValue == null) { + throw new NullPointerException("toValue can't be null"); + } + Map map2 = (Map) exchangeRateMap.get(fromCurrency); + if (map2 == null) { + map2 = new HashMap(); + exchangeRateMap.put(fromCurrency, map2); + } + + ExchangeRate rate = new ExchangeRate(fromValue, toValue); + map2.put(toCurrency, rate); + } + } +}