task4/solution13/src/org/apidesign/apifest08/currency/ExchangeRateProvider.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Sat, 11 Oct 2008 23:38:46 +0200
changeset 61 58ec6da75f6f
parent 58 task3/solution13/src/org/apidesign/apifest08/currency/ExchangeRateProvider.java@07c16ec15a25
child 63 20d332739f60
permissions -rw-r--r--
Copying structure for task4
japod@23
     1
package org.apidesign.apifest08.currency;
japod@23
     2
japod@23
     3
import java.math.BigDecimal;
japod@23
     4
import java.util.Date;
japod@41
     5
import java.util.HashMap;
japod@41
     6
import java.util.Map;
japod@23
     7
japod@23
     8
/**
japod@58
     9
 * Exchange rate provider. Provides  exchange rate for two currencies (method {@link #getExchangeRate(ConvertorCurrency, ConvertorCurrency)} ).
japod@58
    10
 * <p>
japod@58
    11
 * Several method can be created to create <code>ExchangeRateProvider</code>:
japod@58
    12
 * <ul>
japod@58
    13
 * <li>{@link #createExchangeRateProvider() } - create <em>simple</em> exchange rate provider using fixed echange rate.
japod@58
    14
 * <li>{@link #createExchangeRateProvider(IExchangeRateEngine) } - create exchange rate provider using custom {@link IExchangeRateEngine}.
japod@58
    15
 * </ul>
japod@58
    16
 * <p>
japod@41
    17
 * Date dependend exchange rate to be implemented.
japod@23
    18
 * 
japod@23
    19
 * @author arnostvalicek
japod@23
    20
 */
japod@23
    21
public class ExchangeRateProvider {
japod@58
    22
japod@58
    23
    IExchangeRateEngine exrateEngine;
japod@41
    24
    
japod@23
    25
    /**
japod@23
    26
     * Simple constructor for <code>ExchangeRateProviderM</code> which can provide fixed exchange rate.
japod@23
    27
     * 
japod@41
    28
     * Describes conversion <em>from ONE</em> to <em>to ONE</em> currency.
japod@23
    29
     * 
japod@23
    30
     * @param fromValue From value. BigDecimal value, precision should be set to currency precision.
japod@23
    31
     * @param fromCurrency From currency.
japod@23
    32
     * @param toValue To value. BigDecimal value, precision should be set to currency precision.
japod@23
    33
     * @param toCurrency To currency.
japod@41
    34
     * @deprecated deprecated since task2. Use {@link #createExchangeRateProvider() } instead of this constructor.
japod@23
    35
     */
japod@23
    36
    public ExchangeRateProvider(BigDecimal fromValue, ConvertorCurrency fromCurrency, BigDecimal toValue, ConvertorCurrency toCurrency) {
japod@58
    37
        this.exrateEngine = FixedOneExchangeRateEngine.createEngine(fromValue, fromCurrency, toValue, toCurrency);
japod@23
    38
    }
japod@58
    39
japod@41
    40
    private ExchangeRateProvider() {
japod@41
    41
    }
japod@58
    42
japod@41
    43
    /**
japod@41
    44
     * Static method to create new exchange rate provider. This exchange rate provider does not contain
japod@41
    45
     * any exchange rates (this is difference to public constructor).
japod@41
    46
     * @return New <code>ExchangeRateProvider</code>
japod@41
    47
     */
japod@41
    48
    public static ExchangeRateProvider createExchangeRateProvider() {
japod@41
    49
        ExchangeRateProvider provider = new ExchangeRateProvider();
japod@58
    50
        provider.exrateEngine = FixedExchangeRateEngine.createEngine();
japod@41
    51
        return provider;
japod@41
    52
    }
japod@58
    53
japod@41
    54
    /**
japod@58
    55
     * Static method to create exchange rate provider which is using provided <code>IExchangeRateEngine</code>. This exchange rate provider is using
japod@58
    56
     * <code>IExchangeRateEngine</code> to get actual exchange rate.
japod@58
    57
     * @param exchangeRateEngine <code>IExchangeRateEngine</code> used to get exchange rate.
japod@58
    58
     * @return Returns instance of <code>ExchangeRateProvider</code>
japod@58
    59
     */
japod@58
    60
    public static ExchangeRateProvider createExchangeRateProvider(IExchangeRateEngine exchangeRateEngine) {
japod@58
    61
        ExchangeRateProvider provider = new ExchangeRateProvider();
japod@58
    62
        provider.exrateEngine = exchangeRateEngine;
japod@58
    63
        return provider;
japod@58
    64
    }
japod@58
    65
japod@58
    66
    /**
japod@58
    67
     * Add new exchange rate to <code></code> to this <em>simple</em> exchange rate provider.
japod@41
    68
     * <p>
japod@41
    69
     * Example of specifiing conversion rate: 100 SKK == 80 CZK:<br>
japod@41
    70
     * <code>addFixedCurencyRate(ConvertorCurrency.getInstance("SKK"), new BigDecimal(100), ConvertorCurrency.getInstance("CZK"),  new BigDecimal(80));</code>
japod@41
    71
     * <p>
japod@58
    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>.
japod@41
    73
     * 
japod@41
    74
     * @param fromCurrency Source currency.
japod@41
    75
     * @param fromValue Valye for from currency.
japod@41
    76
     * @param toCurrency Target currency.
japod@41
    77
     * @param toValue Value for target currency.
japod@58
    78
     * @throws IllegalStateException Throws exception when adding fixed currency rate to exchange rate provider which is not created using {@link #createExchangeRateProvider() }.
japod@41
    79
     */
japod@41
    80
    public synchronized void addFixedCurencyRate(ConvertorCurrency fromCurrency, BigDecimal fromValue, ConvertorCurrency toCurrency, BigDecimal toValue) {
japod@58
    81
        if (exrateEngine instanceof FixedExchangeRateEngine) {
japod@58
    82
            ((FixedExchangeRateEngine) exrateEngine).addFixedCurencyRate(fromCurrency, fromValue, toCurrency, toValue);
japod@58
    83
        } else {
japod@58
    84
            throw new IllegalStateException("Cuurency rate can be added only to ExchangeRateProvider created with FixedExchangeRateEngine - using method createExchangeRateProvider()");
japod@41
    85
        }
japod@41
    86
    }
japod@58
    87
japod@23
    88
    /**
japod@23
    89
     * Get fixed exange rate for currencies (from->to).
japod@23
    90
     * @return Returns exchange rate.
japod@41
    91
     * @deprecated deprecated since task2. Use {@link #getExchangeRate(ConvertorCurrency, ConvertorCurrency) }
japod@23
    92
     */
japod@23
    93
    public ExchangeRate getExchangeRate() {
japod@58
    94
        //works only for FixedExchangeRateEngine
japod@58
    95
        if (exrateEngine instanceof FixedOneExchangeRateEngine) {
japod@58
    96
            FixedOneExchangeRateEngine engine = (FixedOneExchangeRateEngine) exrateEngine;
japod@58
    97
            return new ExchangeRate(engine.getFromValue(), engine.getToValue());
japod@58
    98
        } else {
japod@58
    99
            throw new IllegalStateException("Method supported only for MinimalFixedExchangeRateEngine. This method is deprecated");
japod@58
   100
        }
japod@58
   101
japod@23
   102
    }
japod@41
   103
japod@41
   104
    /**
japod@41
   105
     * Get fixed exange rate for currencies (from->to).
japod@41
   106
     * @return Returns exchange rate or <code>null</code> if exchange rate not found.
japod@41
   107
     */
japod@41
   108
    public ExchangeRate getExchangeRate(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency) {
japod@41
   109
        return getExchangeRateImpl(fromCurrency, toCurrency);
japod@41
   110
    }
japod@58
   111
japod@41
   112
    /**
japod@41
   113
     * Get fixed exange rate for currencies (from->to) or reversed exchange rate (to->from).
japod@41
   114
     * @return Returns exchange rate or <code>null</code> if exchange rate not found.
japod@41
   115
     */
japod@41
   116
    public ExchangeRate getReversibleExchangeRate(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency) {
japod@58
   117
        ExchangeRate rate = getExchangeRateImpl(fromCurrency, toCurrency);
japod@58
   118
        if (rate == null) {
japod@58
   119
            ExchangeRate revertedRate = getExchangeRateImpl(toCurrency, fromCurrency);
japod@58
   120
            if (revertedRate != null) {
japod@58
   121
                rate = ExchangeRate.createRevertedRate(revertedRate);
japod@58
   122
            }
japod@58
   123
        }
japod@58
   124
        return rate;
japod@41
   125
    }
japod@41
   126
japod@23
   127
    /**
japod@23
   128
     * Get exchange rate for currencies (from->to) based on provided date.
japod@23
   129
     * @param date Date for which exchange rate should be provided.
japod@23
   130
     * @return Returns exchange rate 
japod@41
   131
     * @deprecated deprecated since task2. No real implementation in version2.
japod@23
   132
     */
japod@23
   133
    public ExchangeRate getExchangeRate(Date date) {
japod@58
   134
        //works only for FixedExchangeRateEngine
japod@58
   135
        if (exrateEngine instanceof FixedOneExchangeRateEngine) {
japod@58
   136
            FixedOneExchangeRateEngine engine = (FixedOneExchangeRateEngine) exrateEngine;
japod@58
   137
            return new ExchangeRate(engine.getFromValue(), engine.getToValue());
japod@58
   138
        } else {
japod@58
   139
            throw new IllegalStateException("Method supported only for FixedOneExchangeRateEngine. This method is deprecated");
japod@58
   140
        }
japod@23
   141
    }
japod@23
   142
japod@23
   143
    ConvertorCurrency getFromCurrency() {
japod@58
   144
        if (exrateEngine instanceof FixedOneExchangeRateEngine) {
japod@58
   145
            FixedOneExchangeRateEngine engine = (FixedOneExchangeRateEngine) exrateEngine;
japod@58
   146
            return engine.getFromCurrency();
japod@58
   147
        } else {
japod@58
   148
            throw new IllegalStateException("Method supported only for FixedOneExchangeRateEngine. This method is deprecated");
japod@58
   149
        }
japod@23
   150
    }
japod@58
   151
japod@23
   152
    ConvertorCurrency getToCurrency() {
japod@58
   153
        if (exrateEngine instanceof FixedOneExchangeRateEngine) {
japod@58
   154
            FixedOneExchangeRateEngine engine = (FixedOneExchangeRateEngine) exrateEngine;
japod@58
   155
            return engine.getToCurrency();
japod@58
   156
        } else {
japod@58
   157
            throw new IllegalStateException("Method supported only for FixedOneExchangeRateEngine. This method is deprecated");
japod@58
   158
        }
japod@23
   159
    }
japod@41
   160
japod@41
   161
    private ExchangeRate getExchangeRateImpl(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency) {
japod@58
   162
        ExchangeRate result = exrateEngine.getExchangeRate(fromCurrency, toCurrency);
japod@58
   163
        return result;
japod@58
   164
    }
japod@58
   165
japod@58
   166
    private static class FixedOneExchangeRateEngine implements IExchangeRateEngine {
japod@58
   167
japod@58
   168
        BigDecimal fromValue;
japod@58
   169
        ConvertorCurrency fromCurrency;
japod@58
   170
        BigDecimal toValue;
japod@58
   171
        ConvertorCurrency toCurrency;
japod@58
   172
japod@58
   173
        private FixedOneExchangeRateEngine(BigDecimal fromValue, ConvertorCurrency fromCurrency, BigDecimal toValue, ConvertorCurrency toCurrency) {
japod@58
   174
            this.fromValue = fromValue;
japod@58
   175
            this.toValue = toValue;
japod@58
   176
            this.fromCurrency = fromCurrency;
japod@58
   177
            this.toCurrency = toCurrency;
japod@58
   178
        }
japod@58
   179
japod@58
   180
        /**
japod@58
   181
         * Create IExchangeRateEngine conveting from <code>fromCurrency</code> to <code>toCurrency</code>
japod@58
   182
         * with echange rate <code>fromValue:toValue</code>
japod@58
   183
         * @param fromValue
japod@58
   184
         * @param fromCurrency
japod@58
   185
         * @param toValue
japod@58
   186
         * @param toCurrency
japod@58
   187
         * @return Returns instance of <code>FixedOneExchangeRateEngine</code>.
japod@58
   188
         */
japod@58
   189
        private static IExchangeRateEngine createEngine(BigDecimal fromValue, ConvertorCurrency fromCurrency, BigDecimal toValue, ConvertorCurrency toCurrency) {
japod@58
   190
            return new FixedOneExchangeRateEngine(fromValue, fromCurrency, toValue, toCurrency);
japod@58
   191
        }
japod@58
   192
japod@58
   193
        private BigDecimal getFromValue() {
japod@58
   194
            return fromValue;
japod@58
   195
        }
japod@58
   196
japod@58
   197
        private BigDecimal getToValue() {
japod@58
   198
            return toValue;
japod@58
   199
        }
japod@58
   200
japod@58
   201
        private ConvertorCurrency getFromCurrency() {
japod@58
   202
            return fromCurrency;
japod@58
   203
        }
japod@58
   204
japod@58
   205
        private ConvertorCurrency getToCurrency() {
japod@58
   206
            return toCurrency;
japod@58
   207
        }
japod@58
   208
japod@58
   209
        public ExchangeRate getExchangeRate(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency) {
japod@58
   210
            if (!fromCurrency.equals(this.fromCurrency)) {
japod@58
   211
                return null;
japod@58
   212
            }
japod@58
   213
            if (!toCurrency.equals(this.toCurrency)) {
japod@58
   214
                return null;
japod@58
   215
            }
japod@41
   216
            return new ExchangeRate(fromValue, toValue);
japod@41
   217
        }
japod@58
   218
    }
japod@58
   219
japod@58
   220
    /**
japod@58
   221
     * Exchange rate engine able to hold several fixed exchange rates.
japod@58
   222
     * 
japod@58
   223
     * @author arnostvalicek
japod@58
   224
     */
japod@58
   225
    private static class FixedExchangeRateEngine implements IExchangeRateEngine {
japod@58
   226
japod@58
   227
        private Map exchangeRateMap = new HashMap();
japod@58
   228
japod@58
   229
        private FixedExchangeRateEngine() {
japod@41
   230
        }
japod@58
   231
japod@58
   232
        /**
japod@58
   233
         * Create instance of <code>FixedExchangeRateEngine</code>.
japod@58
   234
         * @return Returns instance of <code>FixedExchangeRateEngine</code>.
japod@58
   235
         */
japod@58
   236
        public static IExchangeRateEngine createEngine() {
japod@58
   237
            return new FixedExchangeRateEngine();
japod@58
   238
        }
japod@58
   239
japod@58
   240
        public ExchangeRate getExchangeRate(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency) {
japod@58
   241
            Map map2 = (Map) exchangeRateMap.get(fromCurrency);
japod@58
   242
            if (map2 == null) {
japod@58
   243
                return null;
japod@58
   244
            }
japod@58
   245
            ExchangeRate result = (ExchangeRate) map2.get(toCurrency);
japod@58
   246
            return result;
japod@58
   247
        }
japod@58
   248
japod@58
   249
        @SuppressWarnings("unchecked")
japod@58
   250
        public synchronized void addFixedCurencyRate(ConvertorCurrency fromCurrency, BigDecimal fromValue, ConvertorCurrency toCurrency, BigDecimal toValue) {
japod@58
   251
            if (fromValue == null) {
japod@58
   252
                throw new NullPointerException("fromValue can't be null");
japod@58
   253
            }
japod@58
   254
            if (toValue == null) {
japod@58
   255
                throw new NullPointerException("toValue can't be null");
japod@58
   256
            }
japod@58
   257
            Map map2 = (Map) exchangeRateMap.get(fromCurrency);
japod@58
   258
            if (map2 == null) {
japod@58
   259
                map2 = new HashMap();
japod@58
   260
                exchangeRateMap.put(fromCurrency, map2);
japod@58
   261
            }
japod@58
   262
japod@58
   263
            ExchangeRate rate = new ExchangeRate(fromValue, toValue);
japod@58
   264
            map2.put(toCurrency, rate);
japod@58
   265
        }
japod@41
   266
    }
japod@23
   267
}