solution13 task3
authorjapod@localhost
Fri, 10 Oct 2008 22:24:52 +0200
changeset 5807c16ec15a25
parent 57 be49855c7fa2
child 59 c1d43bc1e9c0
solution13 task3
task3/solution13/nbproject/project.properties
task3/solution13/src/org/apidesign/apifest08/currency/ConversionNotSupportedException.java
task3/solution13/src/org/apidesign/apifest08/currency/Convertor.java
task3/solution13/src/org/apidesign/apifest08/currency/ConvertorCurrency.java
task3/solution13/src/org/apidesign/apifest08/currency/ExchangeRateProvider.java
task3/solution13/src/org/apidesign/apifest08/currency/IExchangeRateEngine.java
task3/solution13/test/org/apidesign/apifest08/test/BouncingExchangeRateEngine.java
task3/solution13/test/org/apidesign/apifest08/test/Task3Test.java
     1.1 --- a/task3/solution13/nbproject/project.properties	Fri Oct 10 22:10:25 2008 +0200
     1.2 +++ b/task3/solution13/nbproject/project.properties	Fri Oct 10 22:24:52 2008 +0200
     1.3 @@ -27,7 +27,7 @@
     1.4  jar.compress=false
     1.5  javac.classpath=
     1.6  # Space-separated list of extra javac options
     1.7 -javac.compilerargs=
     1.8 +javac.compilerargs=-Xlint:unchecked
     1.9  javac.deprecation=false
    1.10  javac.source=1.5
    1.11  javac.target=1.5
     2.1 --- a/task3/solution13/src/org/apidesign/apifest08/currency/ConversionNotSupportedException.java	Fri Oct 10 22:10:25 2008 +0200
     2.2 +++ b/task3/solution13/src/org/apidesign/apifest08/currency/ConversionNotSupportedException.java	Fri Oct 10 22:24:52 2008 +0200
     2.3 @@ -71,10 +71,10 @@
     2.4      }
     2.5       
     2.6      /**
     2.7 -     * Returns if one way of two way conversion is not supported.
     2.8 +     * Returns if one way or two way conversion is not supported.
     2.9       * 
    2.10 -     * Value <code>false</code> means one way conversion is not supported. Value <code>true</code> means
    2.11 -     * that two way conversio is not supported.
    2.12 +     * Value <code>false</code> means one way conversion is not supported. 
    2.13 +     * Value <code>true</code> means that neither direct nor back conversion is not supported.
    2.14       * 
    2.15       * @return Returs <code>false</code> for one way conversion, <code>true</code> for two way conversion.
    2.16       */ 
     3.1 --- a/task3/solution13/src/org/apidesign/apifest08/currency/Convertor.java	Fri Oct 10 22:10:25 2008 +0200
     3.2 +++ b/task3/solution13/src/org/apidesign/apifest08/currency/Convertor.java	Fri Oct 10 22:24:52 2008 +0200
     3.3 @@ -8,8 +8,12 @@
     3.4   * <p>
     3.5   * Conversion method are:
     3.6   * <ul>
     3.7 - * <li>{@link #convert(ConvertorCurrency, ConvertorCurrency, BigDecimal)} - convert using exchange rate specified in exchange rate provide. <em>Do not try use reverted excahnage rate</em>. 
     3.8 - * <li>{@link #convertWithReversibleRates(ConvertorCurrency, ConvertorCurrency, BigDecimal)} - convert using exchange rate specified in exchange rate provide. <em>Try use reverted excahnage rate</em>. 
     3.9 + * <li>{@link #convert(ConvertorCurrency, ConvertorCurrency, BigDecimal)} - convert
    3.10 + * using exchange rate specified in exchange rate provide. This method is not try 
    3.11 + * use reverted excahnage rate. 
    3.12 + * <li>{@link #convertWithReversibleRates(ConvertorCurrency, ConvertorCurrency, BigDecimal)} - 
    3.13 + * convert using exchange rate specified in exchange rate provide. This method
    3.14 + * is not trying to use reverted exchange rate.
    3.15   * </ul>
    3.16   * 
    3.17   * Exchange rate is provided by {@link ExchangeRateProvider}.
    3.18 @@ -130,7 +134,7 @@
    3.19              to = rate.getToValue();
    3.20          }
    3.21  
    3.22 -        BigDecimal amountCent = amount.movePointRight(2);
    3.23 +        BigDecimal amountCent = amount.movePointRight(toFractionDigits);
    3.24  
    3.25          final BigDecimal multiplied = amountCent.multiply(to, context);
    3.26          BigDecimal[] division = multiplied.divideAndRemainder(from, context);
    3.27 @@ -141,7 +145,8 @@
    3.28              result.setRemainder(BigDecimal.ZERO);
    3.29          }
    3.30  
    3.31 -        final BigDecimal converted = division[0].movePointLeft(2);
    3.32 +        BigDecimal converted = division[0].movePointLeft(toFractionDigits);
    3.33 +        converted = converted.setScale(toFractionDigits); //XXX ugly
    3.34          result.setConverted(converted);
    3.35          //result.setRemainder(...);
    3.36          return result;
     4.1 --- a/task3/solution13/src/org/apidesign/apifest08/currency/ConvertorCurrency.java	Fri Oct 10 22:10:25 2008 +0200
     4.2 +++ b/task3/solution13/src/org/apidesign/apifest08/currency/ConvertorCurrency.java	Fri Oct 10 22:24:52 2008 +0200
     4.3 @@ -50,6 +50,13 @@
     4.4          }
     4.5          return result;
     4.6      }
     4.7 +
     4.8 +    @Override
     4.9 +    public int hashCode() {
    4.10 +        return currency==null ? 47/*??*/ : currency.hashCode();
    4.11 +    }
    4.12 +    
    4.13 +    
    4.14      
    4.15  
    4.16      @Override
     5.1 --- a/task3/solution13/src/org/apidesign/apifest08/currency/ExchangeRateProvider.java	Fri Oct 10 22:10:25 2008 +0200
     5.2 +++ b/task3/solution13/src/org/apidesign/apifest08/currency/ExchangeRateProvider.java	Fri Oct 10 22:24:52 2008 +0200
     5.3 @@ -1,4 +1,3 @@
     5.4 -
     5.5  package org.apidesign.apifest08.currency;
     5.6  
     5.7  import java.math.BigDecimal;
     5.8 @@ -7,19 +6,22 @@
     5.9  import java.util.Map;
    5.10  
    5.11  /**
    5.12 - * Exchange rate provider. Provides fixed exchange rate which does not depend
    5.13 - * on date (method {@link #getExchangeRate()} ).
    5.14 - * 
    5.15 + * Exchange rate provider. Provides  exchange rate for two currencies (method {@link #getExchangeRate(ConvertorCurrency, ConvertorCurrency)} ).
    5.16 + * <p>
    5.17 + * Several method can be created to create <code>ExchangeRateProvider</code>:
    5.18 + * <ul>
    5.19 + * <li>{@link #createExchangeRateProvider() } - create <em>simple</em> exchange rate provider using fixed echange rate.
    5.20 + * <li>{@link #createExchangeRateProvider(IExchangeRateEngine) } - create exchange rate provider using custom {@link IExchangeRateEngine}.
    5.21 + * </ul>
    5.22 + * <p>
    5.23   * Date dependend exchange rate to be implemented.
    5.24   * 
    5.25   * @author arnostvalicek
    5.26   */
    5.27  public class ExchangeRateProvider {
    5.28 -    BigDecimal fromValue, toValue;
    5.29 -    ConvertorCurrency fromCurrency, toCurrency;
    5.30 +
    5.31 +    IExchangeRateEngine exrateEngine;
    5.32      
    5.33 -    Map exchangeRateMap = new HashMap();
    5.34 -
    5.35      /**
    5.36       * Simple constructor for <code>ExchangeRateProviderM</code> which can provide fixed exchange rate.
    5.37       * 
    5.38 @@ -32,16 +34,12 @@
    5.39       * @deprecated deprecated since task2. Use {@link #createExchangeRateProvider() } instead of this constructor.
    5.40       */
    5.41      public ExchangeRateProvider(BigDecimal fromValue, ConvertorCurrency fromCurrency, BigDecimal toValue, ConvertorCurrency toCurrency) {
    5.42 -        this.fromValue = fromValue;
    5.43 -        this.toValue = toValue;
    5.44 -        this.fromCurrency = fromCurrency;
    5.45 -        this.toCurrency = toCurrency;
    5.46 +        this.exrateEngine = FixedOneExchangeRateEngine.createEngine(fromValue, fromCurrency, toValue, toCurrency);
    5.47      }
    5.48 -    
    5.49 +
    5.50      private ExchangeRateProvider() {
    5.51 -        
    5.52      }
    5.53 -    
    5.54 +
    5.55      /**
    5.56       * Static method to create new exchange rate provider. This exchange rate provider does not contain
    5.57       * any exchange rates (this is difference to public constructor).
    5.58 @@ -49,48 +47,60 @@
    5.59       */
    5.60      public static ExchangeRateProvider createExchangeRateProvider() {
    5.61          ExchangeRateProvider provider = new ExchangeRateProvider();
    5.62 +        provider.exrateEngine = FixedExchangeRateEngine.createEngine();
    5.63          return provider;
    5.64      }
    5.65 -    
    5.66 +
    5.67      /**
    5.68 -     * Add new exchange rate to <code></code> to this exchange rate provider.
    5.69 +     * Static method to create exchange rate provider which is using provided <code>IExchangeRateEngine</code>. This exchange rate provider is using
    5.70 +     * <code>IExchangeRateEngine</code> to get actual exchange rate.
    5.71 +     * @param exchangeRateEngine <code>IExchangeRateEngine</code> used to get exchange rate.
    5.72 +     * @return Returns instance of <code>ExchangeRateProvider</code>
    5.73 +     */
    5.74 +    public static ExchangeRateProvider createExchangeRateProvider(IExchangeRateEngine exchangeRateEngine) {
    5.75 +        ExchangeRateProvider provider = new ExchangeRateProvider();
    5.76 +        provider.exrateEngine = exchangeRateEngine;
    5.77 +        return provider;
    5.78 +    }
    5.79 +
    5.80 +    /**
    5.81 +     * Add new exchange rate to <code></code> to this <em>simple</em> exchange rate provider.
    5.82       * <p>
    5.83       * Example of specifiing conversion rate: 100 SKK == 80 CZK:<br>
    5.84       * <code>addFixedCurencyRate(ConvertorCurrency.getInstance("SKK"), new BigDecimal(100), ConvertorCurrency.getInstance("CZK"),  new BigDecimal(80));</code>
    5.85       * <p>
    5.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>.
    5.87       * 
    5.88       * @param fromCurrency Source currency.
    5.89       * @param fromValue Valye for from currency.
    5.90       * @param toCurrency Target currency.
    5.91       * @param toValue Value for target currency.
    5.92 +     * @throws IllegalStateException Throws exception when adding fixed currency rate to exchange rate provider which is not created using {@link #createExchangeRateProvider() }.
    5.93       */
    5.94      public synchronized void addFixedCurencyRate(ConvertorCurrency fromCurrency, BigDecimal fromValue, ConvertorCurrency toCurrency, BigDecimal toValue) {
    5.95 -        if (fromValue==null) {
    5.96 -            throw new NullPointerException("fromValue can't be null");
    5.97 +        if (exrateEngine instanceof FixedExchangeRateEngine) {
    5.98 +            ((FixedExchangeRateEngine) exrateEngine).addFixedCurencyRate(fromCurrency, fromValue, toCurrency, toValue);
    5.99 +        } else {
   5.100 +            throw new IllegalStateException("Cuurency rate can be added only to ExchangeRateProvider created with FixedExchangeRateEngine - using method createExchangeRateProvider()");
   5.101          }
   5.102 -        if (toValue==null) {
   5.103 -            throw new NullPointerException("toValue can't be null");
   5.104 -        }
   5.105 -        Map map2 = (Map) exchangeRateMap.get(fromCurrency);
   5.106 -        if (map2==null) {
   5.107 -            map2 = new HashMap();
   5.108 -            exchangeRateMap.put(fromCurrency, map2);
   5.109 -        }
   5.110 -        
   5.111 -        ExchangeRate rate = new ExchangeRate(fromValue, toValue);
   5.112 -        map2.put(toCurrency, rate);
   5.113      }
   5.114 -    
   5.115 +
   5.116      /**
   5.117       * Get fixed exange rate for currencies (from->to).
   5.118       * @return Returns exchange rate.
   5.119       * @deprecated deprecated since task2. Use {@link #getExchangeRate(ConvertorCurrency, ConvertorCurrency) }
   5.120       */
   5.121      public ExchangeRate getExchangeRate() {
   5.122 -        return new ExchangeRate(fromValue, toValue);
   5.123 +        //works only for FixedExchangeRateEngine
   5.124 +        if (exrateEngine instanceof FixedOneExchangeRateEngine) {
   5.125 +            FixedOneExchangeRateEngine engine = (FixedOneExchangeRateEngine) exrateEngine;
   5.126 +            return new ExchangeRate(engine.getFromValue(), engine.getToValue());
   5.127 +        } else {
   5.128 +            throw new IllegalStateException("Method supported only for MinimalFixedExchangeRateEngine. This method is deprecated");
   5.129 +        }
   5.130 +
   5.131      }
   5.132  
   5.133 -    
   5.134      /**
   5.135       * Get fixed exange rate for currencies (from->to).
   5.136       * @return Returns exchange rate or <code>null</code> if exchange rate not found.
   5.137 @@ -98,24 +108,22 @@
   5.138      public ExchangeRate getExchangeRate(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency) {
   5.139          return getExchangeRateImpl(fromCurrency, toCurrency);
   5.140      }
   5.141 -    
   5.142 +
   5.143      /**
   5.144       * Get fixed exange rate for currencies (from->to) or reversed exchange rate (to->from).
   5.145       * @return Returns exchange rate or <code>null</code> if exchange rate not found.
   5.146       */
   5.147      public ExchangeRate getReversibleExchangeRate(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency) {
   5.148 -       ExchangeRate rate = getExchangeRateImpl(fromCurrency, toCurrency);
   5.149 -       if (rate==null) {
   5.150 -           ExchangeRate revertedRate = getExchangeRateImpl(toCurrency, fromCurrency);
   5.151 -           if (revertedRate!=null) {
   5.152 -            rate = ExchangeRate.createRevertedRate(revertedRate);
   5.153 -           }
   5.154 -       }
   5.155 -       return rate;
   5.156 +        ExchangeRate rate = getExchangeRateImpl(fromCurrency, toCurrency);
   5.157 +        if (rate == null) {
   5.158 +            ExchangeRate revertedRate = getExchangeRateImpl(toCurrency, fromCurrency);
   5.159 +            if (revertedRate != null) {
   5.160 +                rate = ExchangeRate.createRevertedRate(revertedRate);
   5.161 +            }
   5.162 +        }
   5.163 +        return rate;
   5.164      }
   5.165 -        
   5.166  
   5.167 -    
   5.168      /**
   5.169       * Get exchange rate for currencies (from->to) based on provided date.
   5.170       * @param date Date for which exchange rate should be provided.
   5.171 @@ -123,30 +131,137 @@
   5.172       * @deprecated deprecated since task2. No real implementation in version2.
   5.173       */
   5.174      public ExchangeRate getExchangeRate(Date date) {
   5.175 -        return new ExchangeRate(fromValue, toValue);
   5.176 +        //works only for FixedExchangeRateEngine
   5.177 +        if (exrateEngine instanceof FixedOneExchangeRateEngine) {
   5.178 +            FixedOneExchangeRateEngine engine = (FixedOneExchangeRateEngine) exrateEngine;
   5.179 +            return new ExchangeRate(engine.getFromValue(), engine.getToValue());
   5.180 +        } else {
   5.181 +            throw new IllegalStateException("Method supported only for FixedOneExchangeRateEngine. This method is deprecated");
   5.182 +        }
   5.183      }
   5.184 -    
   5.185  
   5.186      ConvertorCurrency getFromCurrency() {
   5.187 -        return fromCurrency;
   5.188 +        if (exrateEngine instanceof FixedOneExchangeRateEngine) {
   5.189 +            FixedOneExchangeRateEngine engine = (FixedOneExchangeRateEngine) exrateEngine;
   5.190 +            return engine.getFromCurrency();
   5.191 +        } else {
   5.192 +            throw new IllegalStateException("Method supported only for FixedOneExchangeRateEngine. This method is deprecated");
   5.193 +        }
   5.194      }
   5.195 -    
   5.196 +
   5.197      ConvertorCurrency getToCurrency() {
   5.198 -        return toCurrency;
   5.199 +        if (exrateEngine instanceof FixedOneExchangeRateEngine) {
   5.200 +            FixedOneExchangeRateEngine engine = (FixedOneExchangeRateEngine) exrateEngine;
   5.201 +            return engine.getToCurrency();
   5.202 +        } else {
   5.203 +            throw new IllegalStateException("Method supported only for FixedOneExchangeRateEngine. This method is deprecated");
   5.204 +        }
   5.205      }
   5.206  
   5.207      private ExchangeRate getExchangeRateImpl(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency) {
   5.208 -        if (fromValue != null && toValue != null && fromCurrency.equals(this.fromCurrency) && toCurrency.equals(this.toCurrency)) {
   5.209 +        ExchangeRate result = exrateEngine.getExchangeRate(fromCurrency, toCurrency);
   5.210 +        return result;
   5.211 +    }
   5.212 +
   5.213 +    private static class FixedOneExchangeRateEngine implements IExchangeRateEngine {
   5.214 +
   5.215 +        BigDecimal fromValue;
   5.216 +        ConvertorCurrency fromCurrency;
   5.217 +        BigDecimal toValue;
   5.218 +        ConvertorCurrency toCurrency;
   5.219 +
   5.220 +        private FixedOneExchangeRateEngine(BigDecimal fromValue, ConvertorCurrency fromCurrency, BigDecimal toValue, ConvertorCurrency toCurrency) {
   5.221 +            this.fromValue = fromValue;
   5.222 +            this.toValue = toValue;
   5.223 +            this.fromCurrency = fromCurrency;
   5.224 +            this.toCurrency = toCurrency;
   5.225 +        }
   5.226 +
   5.227 +        /**
   5.228 +         * Create IExchangeRateEngine conveting from <code>fromCurrency</code> to <code>toCurrency</code>
   5.229 +         * with echange rate <code>fromValue:toValue</code>
   5.230 +         * @param fromValue
   5.231 +         * @param fromCurrency
   5.232 +         * @param toValue
   5.233 +         * @param toCurrency
   5.234 +         * @return Returns instance of <code>FixedOneExchangeRateEngine</code>.
   5.235 +         */
   5.236 +        private static IExchangeRateEngine createEngine(BigDecimal fromValue, ConvertorCurrency fromCurrency, BigDecimal toValue, ConvertorCurrency toCurrency) {
   5.237 +            return new FixedOneExchangeRateEngine(fromValue, fromCurrency, toValue, toCurrency);
   5.238 +        }
   5.239 +
   5.240 +        private BigDecimal getFromValue() {
   5.241 +            return fromValue;
   5.242 +        }
   5.243 +
   5.244 +        private BigDecimal getToValue() {
   5.245 +            return toValue;
   5.246 +        }
   5.247 +
   5.248 +        private ConvertorCurrency getFromCurrency() {
   5.249 +            return fromCurrency;
   5.250 +        }
   5.251 +
   5.252 +        private ConvertorCurrency getToCurrency() {
   5.253 +            return toCurrency;
   5.254 +        }
   5.255 +
   5.256 +        public ExchangeRate getExchangeRate(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency) {
   5.257 +            if (!fromCurrency.equals(this.fromCurrency)) {
   5.258 +                return null;
   5.259 +            }
   5.260 +            if (!toCurrency.equals(this.toCurrency)) {
   5.261 +                return null;
   5.262 +            }
   5.263              return new ExchangeRate(fromValue, toValue);
   5.264          }
   5.265 -        //return new ExchangeRate(fromValue, toValue);
   5.266 -        Map map2 = (Map) exchangeRateMap.get(fromCurrency);
   5.267 -        if (map2 == null) {
   5.268 -            return null;
   5.269 +    }
   5.270 +
   5.271 +    /**
   5.272 +     * Exchange rate engine able to hold several fixed exchange rates.
   5.273 +     * 
   5.274 +     * @author arnostvalicek
   5.275 +     */
   5.276 +    private static class FixedExchangeRateEngine implements IExchangeRateEngine {
   5.277 +
   5.278 +        private Map exchangeRateMap = new HashMap();
   5.279 +
   5.280 +        private FixedExchangeRateEngine() {
   5.281          }
   5.282 -        ExchangeRate result = (ExchangeRate) map2.get(toCurrency);
   5.283 -        return result;
   5.284 +
   5.285 +        /**
   5.286 +         * Create instance of <code>FixedExchangeRateEngine</code>.
   5.287 +         * @return Returns instance of <code>FixedExchangeRateEngine</code>.
   5.288 +         */
   5.289 +        public static IExchangeRateEngine createEngine() {
   5.290 +            return new FixedExchangeRateEngine();
   5.291 +        }
   5.292 +
   5.293 +        public ExchangeRate getExchangeRate(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency) {
   5.294 +            Map map2 = (Map) exchangeRateMap.get(fromCurrency);
   5.295 +            if (map2 == null) {
   5.296 +                return null;
   5.297 +            }
   5.298 +            ExchangeRate result = (ExchangeRate) map2.get(toCurrency);
   5.299 +            return result;
   5.300 +        }
   5.301 +
   5.302 +        @SuppressWarnings("unchecked")
   5.303 +        public synchronized void addFixedCurencyRate(ConvertorCurrency fromCurrency, BigDecimal fromValue, ConvertorCurrency toCurrency, BigDecimal toValue) {
   5.304 +            if (fromValue == null) {
   5.305 +                throw new NullPointerException("fromValue can't be null");
   5.306 +            }
   5.307 +            if (toValue == null) {
   5.308 +                throw new NullPointerException("toValue can't be null");
   5.309 +            }
   5.310 +            Map map2 = (Map) exchangeRateMap.get(fromCurrency);
   5.311 +            if (map2 == null) {
   5.312 +                map2 = new HashMap();
   5.313 +                exchangeRateMap.put(fromCurrency, map2);
   5.314 +            }
   5.315 +
   5.316 +            ExchangeRate rate = new ExchangeRate(fromValue, toValue);
   5.317 +            map2.put(toCurrency, rate);
   5.318 +        }
   5.319      }
   5.320 -    
   5.321 -
   5.322  }
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/task3/solution13/src/org/apidesign/apifest08/currency/IExchangeRateEngine.java	Fri Oct 10 22:24:52 2008 +0200
     6.3 @@ -0,0 +1,18 @@
     6.4 +package org.apidesign.apifest08.currency;
     6.5 +
     6.6 +/**
     6.7 + * Interface for exchange rate engine.
     6.8 + * 
     6.9 + * @author arnostvalicek
    6.10 + */
    6.11 +public interface IExchangeRateEngine {
    6.12 +    
    6.13 +    /**
    6.14 +     * Get exchange rate for conversion from <code>fromCurrency</code> to <code>toCurrency</code>.
    6.15 +     * 
    6.16 +     * @param fromCurrency From currency.
    6.17 +     * @param toCurrency To currency.
    6.18 +     * @return Returns <code>ExchangeRate</code> if exchange rate is known or <code>null</code> if exchanger rate is not known.
    6.19 +     */
    6.20 +    public ExchangeRate getExchangeRate(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency);
    6.21 +}
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/task3/solution13/test/org/apidesign/apifest08/test/BouncingExchangeRateEngine.java	Fri Oct 10 22:24:52 2008 +0200
     7.3 @@ -0,0 +1,79 @@
     7.4 +package org.apidesign.apifest08.test;
     7.5 +
     7.6 +import java.math.BigDecimal;
     7.7 +import org.apidesign.apifest08.currency.ConvertorCurrency;
     7.8 +import org.apidesign.apifest08.currency.ExchangeRate;
     7.9 +import org.apidesign.apifest08.currency.IExchangeRateEngine;
    7.10 +
    7.11 +/** Exchange rate engine which is periodicaly changing echange rate.
    7.12 + *  See <a href="http://wiki.apidesign.org/wiki/APIFest08:Task3">http://wiki.apidesign.org/wiki/APIFest08:Task3</a> for further description.
    7.13 + *
    7.14 + * @author arnostvalicek
    7.15 + */
    7.16 +public class BouncingExchangeRateEngine implements IExchangeRateEngine {
    7.17 +    
    7.18 +    ConvertorCurrency fromCurrency;
    7.19 +    BigDecimal fromValue;
    7.20 +    ConvertorCurrency toCurrency;
    7.21 +    BigDecimal toValueStart;
    7.22 +    BigDecimal toValueStop;
    7.23 +    BigDecimal step;
    7.24 +    
    7.25 +    BigDecimal toValue;
    7.26 +
    7.27 +    
    7.28 +    
    7.29 +    
    7.30 +    private BouncingExchangeRateEngine(ConvertorCurrency fromCurrency, BigDecimal fromValue, ConvertorCurrency toCurrency, BigDecimal toValueStart, BigDecimal toValueStop, BigDecimal step) {
    7.31 +        this.fromCurrency = fromCurrency;
    7.32 +        this.fromValue = fromValue;
    7.33 +        this.toCurrency = toCurrency;
    7.34 +        this.toValueStart = toValueStart;
    7.35 +        this.toValueStop = toValueStop;
    7.36 +        this.step = step;
    7.37 +        this.toValue = toValueStart;
    7.38 +    }
    7.39 +
    7.40 +
    7.41 +    public static IExchangeRateEngine create(ConvertorCurrency fromCurrency, BigDecimal fromValue, ConvertorCurrency toCurrency, BigDecimal toValueStart, BigDecimal toValueStop, BigDecimal step) {
    7.42 +        return new BouncingExchangeRateEngine(fromCurrency, fromValue, toCurrency, toValueStart, toValueStop, step);
    7.43 +    }
    7.44 +
    7.45 +    public ExchangeRate getExchangeRate(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency) {
    7.46 +        if (!fromCurrency.equals(this.fromCurrency)) {
    7.47 +            return null;
    7.48 +        }
    7.49 +        if (!toCurrency.equals(this.toCurrency)) {
    7.50 +            return null;
    7.51 +        }
    7.52 +        
    7.53 +        ExchangeRate result = new ExchangeRate(fromValue, toValue);
    7.54 +        
    7.55 +        toValue = toValue.add(step);
    7.56 +        
    7.57 +//        if (step.signum()==1 && toValueStop.compareTo(toValue)==0) {
    7.58 +//            System.out.println("A");
    7.59 +//            toValue=toValueStop;
    7.60 +//            step = step.negate();
    7.61 +//            BigDecimal x = toValueStart;
    7.62 +//            toValueStart=toValueStop;
    7.63 +//            toValueStop=x;
    7.64 +//        } else if (step.signum()==-1 && toValueStop.compareTo(toValue)==0) {
    7.65 +//            System.out.println("B");
    7.66 +//            toValue=toValueStop;
    7.67 +//            step = step.negate();
    7.68 +//            BigDecimal x = toValueStart;
    7.69 +//            toValueStart=toValueStop;
    7.70 +//            toValueStop=x;
    7.71 +//        }
    7.72 +        if (toValueStop.compareTo(toValue)==0) {
    7.73 +            toValue=toValueStop;
    7.74 +            step = step.negate();
    7.75 +            BigDecimal x = toValueStart;
    7.76 +            toValueStart=toValueStop;
    7.77 +            toValueStop=x;
    7.78 +        }        
    7.79 +        return result;
    7.80 +    }
    7.81 +
    7.82 +}
     8.1 --- a/task3/solution13/test/org/apidesign/apifest08/test/Task3Test.java	Fri Oct 10 22:10:25 2008 +0200
     8.2 +++ b/task3/solution13/test/org/apidesign/apifest08/test/Task3Test.java	Fri Oct 10 22:24:52 2008 +0200
     8.3 @@ -1,7 +1,11 @@
     8.4  package org.apidesign.apifest08.test;
     8.5  
     8.6 +import java.math.BigDecimal;
     8.7  import junit.framework.TestCase;
     8.8  import org.apidesign.apifest08.currency.Convertor;
     8.9 +import org.apidesign.apifest08.currency.ConvertorCurrency;
    8.10 +import org.apidesign.apifest08.currency.ExchangeRateProvider;
    8.11 +import org.apidesign.apifest08.currency.IExchangeRateEngine;
    8.12  
    8.13  /** The exchange rates are not always the same. They are changing. Day by day,
    8.14   * hour by hour, minute by minute. For every bank it is important to always
    8.15 @@ -16,6 +20,11 @@
    8.16   * to be used.
    8.17   */
    8.18  public class Task3Test extends TestCase {
    8.19 +    
    8.20 +    private static ConvertorCurrency currencyCZK = ConvertorCurrency.getInstance("CZK");
    8.21 +    private static ConvertorCurrency currencySKK = ConvertorCurrency.getInstance("SKK");
    8.22 +    private static ConvertorCurrency currencyUSD = ConvertorCurrency.getInstance("USD");
    8.23 +    
    8.24      public Task3Test(String testName) {
    8.25          super(testName);
    8.26      }
    8.27 @@ -51,7 +60,14 @@
    8.28          // then 1USD = 15.02CZK
    8.29          // and so on and on up to 1USD = 16CZK
    8.30          // and then another round to 15, etc.
    8.31 -        return null;
    8.32 +        IExchangeRateEngine engine = BouncingExchangeRateEngine.create(
    8.33 +                currencyUSD,  new BigDecimal(1),
    8.34 +                currencyCZK, 
    8.35 +                new BigDecimal(16),new BigDecimal(15),
    8.36 +                new BigDecimal("-0.01"));
    8.37 +        ExchangeRateProvider exRateProvider = ExchangeRateProvider.createExchangeRateProvider(engine);
    8.38 +        Convertor convertor = Convertor.createConvertor(exRateProvider);
    8.39 +        return convertor;
    8.40      }
    8.41  
    8.42      public void testFewQueriesForOnlineConvertor() {
    8.43 @@ -66,18 +82,18 @@
    8.44  
    8.45      static void doFewQueriesForOnlineConvertor(Convertor c) {
    8.46          // convert $5 to CZK using c:
    8.47 -        //assertEquals("Result is 80 CZK");
    8.48 +        assertEquals("Result is 80 CZK", new BigDecimal("80.00"), c.convertWithReversibleRates(currencyUSD, currencyCZK, new BigDecimal(5)).getConverted());
    8.49  
    8.50          // convert $8 to CZK using c:
    8.51 -        //assertEquals("Result is 127.92 CZK");
    8.52 +        assertEquals("Result is 127.92 CZK", new BigDecimal("127.92"), c.convertWithReversibleRates(currencyUSD, currencyCZK, new BigDecimal(8)).getConverted());
    8.53  
    8.54          // convert $1 to CZK using c:
    8.55 -        //assertEquals("Result is 15.98 CZK");
    8.56 +        assertEquals("Result is 15.98 CZK", new BigDecimal("15.98"), c.convertWithReversibleRates(currencyUSD, currencyCZK, new BigDecimal(1)).getConverted());
    8.57  
    8.58          // convert 15.97CZK to USD using c:
    8.59 -        //assertEquals("Result is 1$");
    8.60 +        assertEquals("Result is 15.98 CZK", new BigDecimal("1.00"), c.convertWithReversibleRates(currencyCZK, currencyUSD , new BigDecimal("15.97")).getConverted());
    8.61  
    8.62 -        fail("Implement me!");
    8.63 +        //fail("Implement me!");
    8.64      }
    8.65  
    8.66      /** Join the convertors and show they behave sane.
    8.67 @@ -94,11 +110,25 @@
    8.68          );
    8.69  
    8.70          // convert 16CZK to SKK using c:
    8.71 -        // assertEquals("Result is 20 SKK");
    8.72 +        assertEquals("Result is 20 CZK", new BigDecimal("20.00"), c.convertWithReversibleRates(currencyCZK, currencySKK , new BigDecimal("16")).getConverted());
    8.73  
    8.74          // convert 500SKK to CZK using c:
    8.75 -        // assertEquals("Result is 400 CZK");
    8.76 +        assertEquals("Result is 400 CZK", new BigDecimal("400.00"), c.convertWithReversibleRates(currencySKK, currencyCZK , new BigDecimal("500")).getConverted());
    8.77  
    8.78          doFewQueriesForOnlineConvertor(c);
    8.79      }
    8.80 +    
    8.81 +//    public void testBouncing() {
    8.82 +//        Convertor c=createOnlineCZKUSDConvertor();
    8.83 +//        
    8.84 +//        IExchangeRateEngine engine = BouncingExchangeRateEngine.create(
    8.85 +//                currencyUSD,  new BigDecimal(1),
    8.86 +//                currencyCZK, 
    8.87 +//                new BigDecimal("16.00"),new BigDecimal("15.00"),
    8.88 +//                new BigDecimal("-0.01"));        
    8.89 +//        
    8.90 +//        for (int i=0;i<300;i++) {
    8.91 +//            System.out.println(engine.getExchangeRate(currencyUSD, currencyCZK).getToValue());
    8.92 +//        }
    8.93 +//    }
    8.94  }