task4/solution11/src/org/apidesign/apifest08/currency/Convertor.java
author Jaroslav Tulach <jtulach@netbeans.org>
Sat, 25 Oct 2008 20:53:00 +0200
changeset 84 2ae6e4aa7aef
parent 61 58ec6da75f6f
permissions -rw-r--r--
Solutions by Petr Smid
japod@6
     1
package org.apidesign.apifest08.currency;
japod@6
     2
japod@37
     3
import java.util.ArrayList;
japod@37
     4
import java.util.Collection;
jaroslav@66
     5
import java.util.Date;
japod@37
     6
import java.util.HashSet;
japod@37
     7
import java.util.List;
japod@37
     8
import java.util.Set;
japod@6
     9
import org.apidesign.apifest08.currency.Computer.ComputerRequest;
japod@6
    10
import org.apidesign.apifest08.currency.Computer.ComputerResponse;
japod@6
    11
japod@6
    12
/**
japod@6
    13
 * Convertor.
japod@6
    14
 * 
japod@6
    15
 * In Task 1's version provides conversion between currency values
japod@6
    16
 * with amount stored in integer or double, that are identified
japod@6
    17
 * with string value. Exchange rates are immutable.
japod@6
    18
 * 
japod@37
    19
 * In Task2's version provides support for multiple exchange rates
japod@37
    20
 * between different currencies & merging exchange rates from
japod@37
    21
 * existing convertors into new convertor's instance.
japod@37
    22
 * No time for javadoc these features, sorry.
japod@37
    23
 * 
japod@53
    24
 * In Task3's version supports reading of current exchange rates
japod@53
    25
 * from data sources. Data sources are merged during convertors' merging
japod@53
    26
 * as well as static exchange rates.
japod@53
    27
 * No time for javadoc, again.
japod@53
    28
 * 
jaroslav@66
    29
 * In Task4's version takes into account validity range of data sources,
jaroslav@66
    30
 * can convert using an exchange rate value according to the specified instant
jaroslav@66
    31
 * of the time and provides a method for creating a new convertor with the same
jaroslav@66
    32
 * data sources as the old one, but with their validity ranges limited
jaroslav@66
    33
 * to the specified range.
jaroslav@66
    34
 * As usual, no time for javadoc.
jaroslav@66
    35
 * 
japod@6
    36
 * @author ked
japod@6
    37
 */
japod@6
    38
public final class Convertor<AmountType, IdentifierType> {
japod@6
    39
japod@6
    40
    Computer<AmountType> computer;
jaroslav@66
    41
    // each static exchange rate is a special case of an exchange rate data source
jaroslav@66
    42
    // historically separated
jaroslav@66
    43
    List<ExchangeRateDataSource<AmountType, IdentifierType>> staticExchangeRateDataSources =
jaroslav@66
    44
            new ArrayList<ExchangeRateDataSource<AmountType, IdentifierType>>();
jaroslav@66
    45
    List<ExchangeRateDataSource<AmountType, IdentifierType>> exchangeRateDataSources =
jaroslav@66
    46
            new ArrayList<ExchangeRateDataSource<AmountType, IdentifierType>>();
japod@6
    47
jaroslav@66
    48
    // ---
jaroslav@66
    49
    // BASICS
jaroslav@66
    50
    // ---
japod@53
    51
    Convertor(Computer<AmountType> computer) {
japod@37
    52
        this.computer = computer;
japod@53
    53
    }
jaroslav@66
    54
jaroslav@66
    55
    void addExchangeRateDataSources(
jaroslav@66
    56
            List<ExchangeRateDataSource<AmountType, IdentifierType>> target,
jaroslav@66
    57
            Collection<ExchangeRateDataSource<AmountType, IdentifierType>> exchangeRateDataSources) {
jaroslav@66
    58
        for (ExchangeRateDataSource<AmountType, IdentifierType> exchangeRateDataSource : exchangeRateDataSources) {
jaroslav@66
    59
            if (isOverlappingExchangeRate(
jaroslav@66
    60
                    exchangeRateDataSource.getCurrencyAIdentifier(),
jaroslav@66
    61
                    exchangeRateDataSource.getCurrencyBIdentifier(),
jaroslav@66
    62
                    exchangeRateDataSource.getValidFrom(),
jaroslav@66
    63
                    exchangeRateDataSource.getValidTill())) {
japod@37
    64
                throw new IllegalArgumentException("Duplicate exchange rate!");
japod@37
    65
            }
jaroslav@66
    66
            target.add(exchangeRateDataSource);
japod@19
    67
        }
japod@37
    68
    }
jaroslav@66
    69
japod@53
    70
    ExchangeRateValue<AmountType, IdentifierType> findExchangeRate(
japod@37
    71
            IdentifierType currencyA,
jaroslav@66
    72
            IdentifierType currencyB,
jaroslav@66
    73
            Date instant) {
jaroslav@66
    74
        ExchangeRateValue<AmountType, IdentifierType> result = null;
jaroslav@66
    75
        result = findExchangeRateInternal(staticExchangeRateDataSources, currencyA, currencyB, instant);
jaroslav@66
    76
        if (result != null) {
jaroslav@66
    77
            return result;
japod@37
    78
        }
jaroslav@66
    79
        result = findExchangeRateInternal(exchangeRateDataSources, currencyA, currencyB, instant);
jaroslav@66
    80
        return result;
jaroslav@66
    81
    }
jaroslav@66
    82
jaroslav@66
    83
    ExchangeRateValue<AmountType, IdentifierType> findExchangeRateInternal(
jaroslav@66
    84
            List<ExchangeRateDataSource<AmountType, IdentifierType>> where,
jaroslav@66
    85
            IdentifierType currencyA,
jaroslav@66
    86
            IdentifierType currencyB,
jaroslav@66
    87
            Date instant) {
jaroslav@66
    88
        for (ExchangeRateDataSource<AmountType, IdentifierType> exchangeRateDataSource : where) {
jaroslav@66
    89
            if (((exchangeRateDataSource.getCurrencyAIdentifier().equals(currencyA) && exchangeRateDataSource.getCurrencyBIdentifier().equals(currencyB)) ||
jaroslav@66
    90
                    (exchangeRateDataSource.getCurrencyAIdentifier().equals(currencyB) && exchangeRateDataSource.getCurrencyBIdentifier().equals(currencyA))) &&
jaroslav@66
    91
                    DateUtil.isInRange(instant, exchangeRateDataSource.getValidFrom(), exchangeRateDataSource.getValidTill())) {
japod@53
    92
                return exchangeRateDataSource.getExchangeRate();
japod@53
    93
            }
japod@53
    94
        }
japod@37
    95
        return null;
japod@6
    96
    }
jaroslav@66
    97
jaroslav@66
    98
    boolean isOverlappingExchangeRate(
japod@53
    99
            IdentifierType currencyA,
jaroslav@66
   100
            IdentifierType currencyB,
jaroslav@66
   101
            Date from,
jaroslav@66
   102
            Date to) {
jaroslav@66
   103
        boolean result = false;
jaroslav@66
   104
        result = isOverlappingExchangeRateInternal(staticExchangeRateDataSources, currencyA, currencyB, from, to);
jaroslav@66
   105
        if (result == true) {
jaroslav@66
   106
            return result;
japod@53
   107
        }
jaroslav@66
   108
        result = isOverlappingExchangeRateInternal(exchangeRateDataSources, currencyA, currencyB, from, to);
jaroslav@66
   109
        return result;
jaroslav@66
   110
    }
jaroslav@66
   111
jaroslav@66
   112
    boolean isOverlappingExchangeRateInternal(
jaroslav@66
   113
            List<ExchangeRateDataSource<AmountType, IdentifierType>> where,
jaroslav@66
   114
            IdentifierType currencyA,
jaroslav@66
   115
            IdentifierType currencyB,
jaroslav@66
   116
            Date from,
jaroslav@66
   117
            Date to) {
jaroslav@66
   118
        for (ExchangeRateDataSource<AmountType, IdentifierType> exchangeRateDataSource : where) {
jaroslav@66
   119
            if (((exchangeRateDataSource.getCurrencyAIdentifier().equals(currencyA) && exchangeRateDataSource.getCurrencyBIdentifier().equals(currencyB)) ||
jaroslav@66
   120
                    (exchangeRateDataSource.getCurrencyAIdentifier().equals(currencyB) && exchangeRateDataSource.getCurrencyBIdentifier().equals(currencyA))) &&
jaroslav@66
   121
                    DateUtil.isRangesOverlapping(from, to, exchangeRateDataSource.getValidFrom(), exchangeRateDataSource.getValidTill())) {
japod@53
   122
                return true;
japod@53
   123
            }
japod@53
   124
        }
japod@53
   125
        return false;
japod@53
   126
    }
japod@6
   127
japod@6
   128
    /**
japod@6
   129
     * Convert an amount of the one currency to an amount of the another one currency
japod@37
   130
     * with respect to previously specified exchange rates.
japod@6
   131
     * 
japod@19
   132
     * @param targetCurrency an identifier of the requested currency
japod@19
   133
     * @param currencyValue an amount of the another one currency
japod@19
   134
     * @return an amount of the requested currency
japod@6
   135
     */
japod@19
   136
    public CurrencyValue<AmountType, IdentifierType> convert(
japod@19
   137
            IdentifierType targetCurrency,
japod@19
   138
            CurrencyValue<AmountType, IdentifierType> currencyValue) {
jaroslav@66
   139
        return convert(targetCurrency, currencyValue, new Date()); // System.currentTimeMillis()
jaroslav@66
   140
    }
jaroslav@66
   141
jaroslav@66
   142
    public CurrencyValue<AmountType, IdentifierType> convert(
jaroslav@66
   143
            IdentifierType targetCurrency,
jaroslav@66
   144
            CurrencyValue<AmountType, IdentifierType> currencyValue,
jaroslav@66
   145
            Date instant) {
japod@37
   146
        ExchangeRateValue<AmountType, IdentifierType> exchangeRate =
jaroslav@66
   147
                findExchangeRate(currencyValue.getIdentifier(), targetCurrency, instant);
japod@37
   148
        if (exchangeRate == null) {
japod@19
   149
            throw new IllegalArgumentException("Inappropriate currencies to convert!");
japod@6
   150
        }
japod@37
   151
japod@37
   152
        ComputerRequest<AmountType> computerRequest = new ComputerRequest<AmountType>();
japod@37
   153
        computerRequest.setInput(currencyValue.getAmount());
japod@37
   154
japod@37
   155
        IdentifierType targetCurrencyRef; // just for backward compatibility :-(
japod@37
   156
        if (exchangeRate.getCurrencyA().getIdentifier().equals(targetCurrency)) {
japod@37
   157
            computerRequest.setInputCurrencyRatio(exchangeRate.getCurrencyB().getAmount());
japod@37
   158
            computerRequest.setOutputCurrencyRatio(exchangeRate.getCurrencyA().getAmount());
japod@37
   159
            targetCurrencyRef = exchangeRate.getCurrencyA().getIdentifier();
japod@37
   160
        } else {
japod@37
   161
            computerRequest.setInputCurrencyRatio(exchangeRate.getCurrencyA().getAmount());
japod@37
   162
            computerRequest.setOutputCurrencyRatio(exchangeRate.getCurrencyB().getAmount());
japod@37
   163
            targetCurrencyRef = exchangeRate.getCurrencyB().getIdentifier();
japod@37
   164
        }
japod@37
   165
japod@53
   166
        ComputerResponse<AmountType> computerResponse = new ComputerResponse<AmountType>();
japod@53
   167
        computer.compute(computerRequest, computerResponse);
japod@53
   168
japod@37
   169
        return CurrencyValue.getCurrencyValue(
japod@37
   170
                computerResponse.getResult(),
japod@37
   171
                targetCurrencyRef);
japod@37
   172
    }
japod@37
   173
japod@37
   174
    // ---
jaroslav@66
   175
    // LIMITING
jaroslav@66
   176
    // ---
jaroslav@66
   177
    Collection<ExchangeRateDataSource<AmountType, IdentifierType>> limitDataSources(
jaroslav@66
   178
            Collection<ExchangeRateDataSource<AmountType, IdentifierType>> source,
jaroslav@66
   179
            Date from, Date till) {
jaroslav@66
   180
        Collection<ExchangeRateDataSource<AmountType, IdentifierType>> result =
jaroslav@66
   181
                new ArrayList<ExchangeRateDataSource<AmountType, IdentifierType>>();
jaroslav@66
   182
jaroslav@66
   183
        for (ExchangeRateDataSource<AmountType, IdentifierType> dataSource : source) {
jaroslav@66
   184
            result.add(ExchangeRateDataSource.getExchangeRateDataSource(
jaroslav@66
   185
                    dataSource.getCurrencyAIdentifier(), dataSource.getCurrencyBIdentifier(),
jaroslav@66
   186
                    dataSource.getExchangeRateProvider(),
jaroslav@66
   187
                    DateUtil.getRangesIntersectionBottom(dataSource.getValidFrom(), from),
jaroslav@66
   188
                    DateUtil.getRangesIntersectionTop(dataSource.getValidTill(), till)));
jaroslav@66
   189
        }
jaroslav@66
   190
jaroslav@66
   191
        return result;
jaroslav@66
   192
    }
jaroslav@66
   193
jaroslav@66
   194
    public Convertor<AmountType, IdentifierType> limitConvertor(Date from, Date till) {
jaroslav@66
   195
        Collection<ExchangeRateDataSource<AmountType, IdentifierType>> limitedStatic =
jaroslav@66
   196
                limitDataSources(staticExchangeRateDataSources, from, till);
jaroslav@66
   197
        Collection<ExchangeRateDataSource<AmountType, IdentifierType>> limited =
jaroslav@66
   198
                limitDataSources(exchangeRateDataSources, from, till);
jaroslav@66
   199
jaroslav@66
   200
        Convertor<AmountType, IdentifierType> c = new Convertor<AmountType, IdentifierType>(computer);
jaroslav@66
   201
        c.addExchangeRateDataSources(c.staticExchangeRateDataSources, limitedStatic);
jaroslav@66
   202
        c.addExchangeRateDataSources(c.exchangeRateDataSources, limited);
jaroslav@66
   203
        return c;
jaroslav@66
   204
    }
jaroslav@66
   205
jaroslav@66
   206
    // ---
japod@37
   207
    // MERGING
japod@37
   208
    // ---
japod@37
   209
    static <AmountType, IdentifierType> Convertor<AmountType, IdentifierType> mergeConvertors(
japod@37
   210
            Computer<AmountType> computer,
japod@37
   211
            Collection<Convertor<AmountType, IdentifierType>> convertors) {
jaroslav@66
   212
        Set<ExchangeRateDataSource<AmountType, IdentifierType>> mergedStatic =
jaroslav@66
   213
                new HashSet<ExchangeRateDataSource<AmountType, IdentifierType>>();
jaroslav@66
   214
        Set<ExchangeRateDataSource<AmountType, IdentifierType>> merged =
jaroslav@66
   215
                new HashSet<ExchangeRateDataSource<AmountType, IdentifierType>>();
japod@37
   216
        for (Convertor<AmountType, IdentifierType> convertor : convertors) {
jaroslav@66
   217
            mergedStatic.addAll(convertor.staticExchangeRateDataSources);
japod@37
   218
        }
japod@53
   219
        for (Convertor<AmountType, IdentifierType> convertor : convertors) {
jaroslav@66
   220
            merged.addAll(convertor.exchangeRateDataSources);
japod@53
   221
        }
jaroslav@66
   222
japod@53
   223
        Convertor<AmountType, IdentifierType> c = new Convertor<AmountType, IdentifierType>(computer);
jaroslav@66
   224
        c.addExchangeRateDataSources(c.staticExchangeRateDataSources, mergedStatic);
jaroslav@66
   225
        c.addExchangeRateDataSources(c.exchangeRateDataSources, merged);
japod@53
   226
        return c;
japod@37
   227
    }
japod@37
   228
japod@37
   229
    static <AmountType, IdentifierType> Convertor<AmountType, IdentifierType> mergeConvertors(
japod@37
   230
            Computer<AmountType> computer,
japod@37
   231
            Convertor<AmountType, IdentifierType> convertorA,
japod@37
   232
            Convertor<AmountType, IdentifierType> convertorB) {
japod@37
   233
        Collection<Convertor<AmountType, IdentifierType>> convertors =
japod@37
   234
                new ArrayList<Convertor<AmountType, IdentifierType>>();
japod@37
   235
        convertors.add(convertorA);
japod@37
   236
        convertors.add(convertorB);
japod@37
   237
        return mergeConvertors(computer, convertors);
japod@37
   238
    }
japod@37
   239
japod@37
   240
    public static Convertor<Double, String> mergeConvertorsDoubleString(
japod@37
   241
            Collection<Convertor<Double, String>> convertors) {
japod@37
   242
        return mergeConvertors(DoubleComputer, convertors);
japod@37
   243
    }
japod@37
   244
japod@37
   245
    public static Convertor<Double, String> mergeConvertorsDoubleString(
japod@37
   246
            Convertor<Double, String> convertorA,
japod@37
   247
            Convertor<Double, String> convertorB) {
japod@37
   248
        return mergeConvertors(DoubleComputer, convertorA, convertorB);
japod@37
   249
    }
japod@37
   250
japod@37
   251
    public static Convertor<Integer, String> mergeConvertorsIntegerString(
japod@37
   252
            Collection<Convertor<Integer, String>> convertors) {
japod@37
   253
        return mergeConvertors(IntegerComputer, convertors);
japod@37
   254
    }
japod@37
   255
japod@37
   256
    public static Convertor<Integer, String> mergeConvertorsIntegerString(
japod@37
   257
            Convertor<Integer, String> convertorA,
japod@37
   258
            Convertor<Integer, String> convertorB) {
japod@37
   259
        return mergeConvertors(IntegerComputer, convertorA, convertorB);
japod@37
   260
    }
japod@37
   261
japod@37
   262
    // ---
japod@37
   263
    // CREATION
japod@37
   264
    // ---
japod@37
   265
    static <AmountType, IdentifierType> Convertor<AmountType, IdentifierType> getConvertor(
japod@37
   266
            Computer<AmountType> computer, Collection<ExchangeRateValue<AmountType, IdentifierType>> exchangeRates) {
japod@53
   267
        Convertor<AmountType, IdentifierType> c = new Convertor<AmountType, IdentifierType>(computer);
jaroslav@66
   268
        Collection<ExchangeRateDataSource<AmountType, IdentifierType>> exchangeRateDataSources =
jaroslav@66
   269
                new ArrayList<ExchangeRateDataSource<AmountType, IdentifierType>>();
jaroslav@66
   270
        for (ExchangeRateValue<AmountType, IdentifierType> exchangeRate : exchangeRates) {
jaroslav@66
   271
            exchangeRateDataSources.add(
jaroslav@66
   272
                    ExchangeRateDataSource.getExchangeRateDataSource(
jaroslav@66
   273
                    exchangeRate.getCurrencyA().getIdentifier(), exchangeRate.getCurrencyB().getIdentifier(),
jaroslav@66
   274
                    StaticExchangeRateProvider.getStaticExchangeRateProvider(exchangeRate)));
jaroslav@66
   275
        }
jaroslav@66
   276
        c.addExchangeRateDataSources(c.staticExchangeRateDataSources, exchangeRateDataSources);
japod@53
   277
        return c;
japod@6
   278
    }
japod@6
   279
japod@53
   280
    static <AmountType, IdentifierType> Convertor<AmountType, IdentifierType> getConvertorDataSource(
japod@53
   281
            Computer<AmountType> computer, Collection<ExchangeRateDataSource<AmountType, IdentifierType>> exchangeRateDataSources) {
japod@53
   282
        Convertor<AmountType, IdentifierType> c = new Convertor<AmountType, IdentifierType>(computer);
jaroslav@66
   283
        c.addExchangeRateDataSources(c.exchangeRateDataSources, exchangeRateDataSources);
japod@53
   284
        return c;
japod@53
   285
    }
jaroslav@66
   286
japod@6
   287
    static <AmountType, IdentifierType> Convertor<AmountType, IdentifierType> getConvertor(
japod@37
   288
            Computer<AmountType> computer, ExchangeRateValue<AmountType, IdentifierType> exchangeRate) {
japod@37
   289
        Collection<ExchangeRateValue<AmountType, IdentifierType>> exchangeRates =
japod@37
   290
                new ArrayList<ExchangeRateValue<AmountType, IdentifierType>>();
japod@37
   291
        exchangeRates.add(exchangeRate);
japod@37
   292
        return getConvertor(computer, exchangeRates);
japod@6
   293
    }
jaroslav@66
   294
japod@53
   295
    static <AmountType, IdentifierType> Convertor<AmountType, IdentifierType> getConvertorDataSource(
japod@53
   296
            Computer<AmountType> computer, ExchangeRateDataSource<AmountType, IdentifierType> exchangeRateDataSource) {
japod@53
   297
        Collection<ExchangeRateDataSource<AmountType, IdentifierType>> exchangeRateDataSources =
japod@53
   298
                new ArrayList<ExchangeRateDataSource<AmountType, IdentifierType>>();
japod@53
   299
        exchangeRateDataSources.add(exchangeRateDataSource);
japod@53
   300
        return getConvertorDataSource(computer, exchangeRateDataSources);
japod@53
   301
    }
jaroslav@66
   302
japod@37
   303
    public static Convertor<Double, String> getConvertorDoubleString(
japod@37
   304
            Collection<ExchangeRateValue<Double, String>> exchangeRates) {
japod@37
   305
        return getConvertor(DoubleComputer, exchangeRates);
japod@37
   306
    }
japod@6
   307
japod@37
   308
    public static Convertor<Double, String> getConvertorDoubleString(
japod@37
   309
            ExchangeRateValue<Double, String> exchangeRate) {
japod@37
   310
        return getConvertor(DoubleComputer, exchangeRate);
japod@37
   311
    }
jaroslav@66
   312
japod@53
   313
    public static Convertor<Double, String> getConvertorDataSourceDoubleString(
japod@53
   314
            Collection<ExchangeRateDataSource<Double, String>> exchangeRateDataSources) {
japod@53
   315
        return getConvertorDataSource(DoubleComputer, exchangeRateDataSources);
japod@53
   316
    }
japod@6
   317
japod@53
   318
    public static Convertor<Double, String> getConvertorDataSourceDoubleString(
japod@53
   319
            ExchangeRateDataSource<Double, String> exchangeRateDataSource) {
japod@53
   320
        return getConvertorDataSource(DoubleComputer, exchangeRateDataSource);
japod@53
   321
    }
jaroslav@66
   322
japod@37
   323
    public static Convertor<Integer, String> getConvertorIntegerString(
japod@37
   324
            Collection<ExchangeRateValue<Integer, String>> exchangeRates) {
japod@37
   325
        return getConvertor(IntegerComputer, exchangeRates);
japod@37
   326
    }
japod@37
   327
japod@37
   328
    public static Convertor<Integer, String> getConvertorIntegerString(
japod@37
   329
            ExchangeRateValue<Integer, String> exchangeRate) {
japod@37
   330
        return getConvertor(IntegerComputer, exchangeRate);
japod@37
   331
    }
jaroslav@66
   332
japod@53
   333
    public static Convertor<Integer, String> getConvertorDataSourceIntegerString(
japod@53
   334
            Collection<ExchangeRateDataSource<Integer, String>> exchangeRateDataSources) {
japod@53
   335
        return getConvertorDataSource(IntegerComputer, exchangeRateDataSources);
japod@53
   336
    }
japod@53
   337
japod@53
   338
    public static Convertor<Integer, String> getConvertorDataSourceIntegerString(
japod@53
   339
            ExchangeRateDataSource<Integer, String> exchangeRateDataSource) {
japod@53
   340
        return getConvertorDataSource(IntegerComputer, exchangeRateDataSource);
japod@53
   341
    }
japod@37
   342
japod@37
   343
    // ---
japod@37
   344
    // BACKWARD COMPATIBILITY - CREATION
japod@37
   345
    // ---
japod@6
   346
    /**
japod@6
   347
     * Creates convertor for Double|String values with specified exchange rate
japod@6
   348
     * between two currencies.
japod@6
   349
     * 
japod@6
   350
     * @param firstCurrencyExchangeRate first currency
japod@6
   351
     * @param secondCurrencyExchangeRate second currency
japod@6
   352
     * @return convertor
japod@6
   353
     */
japod@6
   354
    public static Convertor<Double, String> getConvertorDoubleString(
japod@6
   355
            CurrencyValue<Double, String> firstCurrencyExchangeRate,
japod@6
   356
            CurrencyValue<Double, String> secondCurrencyExchangeRate) {
japod@37
   357
        return getConvertorDoubleString(ExchangeRateValue.getExchangeRate(firstCurrencyExchangeRate, secondCurrencyExchangeRate));
japod@6
   358
    }
japod@6
   359
japod@6
   360
    /**
japod@6
   361
     * Creates convertor for Integer|String values with specified exchange rate
japod@6
   362
     * between two currencies.
japod@6
   363
     * 
japod@6
   364
     * @param firstCurrencyExchangeRate first currency
japod@6
   365
     * @param secondCurrencyExchangeRate second currency
japod@6
   366
     * @return convertor
japod@6
   367
     */
japod@6
   368
    public static Convertor<Integer, String> getConvertorIntegerString(
japod@6
   369
            CurrencyValue<Integer, String> firstCurrencyExchangeRate,
japod@6
   370
            CurrencyValue<Integer, String> secondCurrencyExchangeRate) {
japod@37
   371
        return getConvertorIntegerString(ExchangeRateValue.getExchangeRate(firstCurrencyExchangeRate, secondCurrencyExchangeRate));
japod@6
   372
    }
jaroslav@66
   373
japod@37
   374
    // ---
japod@37
   375
    // COMPUTERS
japod@37
   376
    // ---
japod@37
   377
    static final Computer<Double> DoubleComputer = new Computer<Double>() {
japod@37
   378
japod@53
   379
        public void compute(ComputerRequest<Double> request, ComputerResponse<Double> response) {
japod@37
   380
            response.setResult(request.getInput() * request.getOutputCurrencyRatio() / request.getInputCurrencyRatio());
japod@37
   381
        }
japod@37
   382
    };
japod@37
   383
    static final Computer<Integer> IntegerComputer = new Computer<Integer>() {
japod@37
   384
japod@53
   385
        public void compute(ComputerRequest<Integer> request, ComputerResponse<Integer> response) {
japod@37
   386
            response.setResult(request.getInput() * request.getOutputCurrencyRatio() / request.getInputCurrencyRatio());
japod@37
   387
        }
japod@37
   388
    };
japod@6
   389
}