1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/task2/solution11/src/org/apidesign/apifest08/currency/Convertor.java Wed Oct 01 10:43:05 2008 +0200
1.3 @@ -0,0 +1,129 @@
1.4 +package org.apidesign.apifest08.currency;
1.5 +
1.6 +import org.apidesign.apifest08.currency.Computer.ComputerRequest;
1.7 +import org.apidesign.apifest08.currency.Computer.ComputerResponse;
1.8 +
1.9 +/**
1.10 + * Convertor.
1.11 + *
1.12 + * In Task 1's version provides conversion between currency values
1.13 + * with amount stored in integer or double, that are identified
1.14 + * with string value. Exchange rates are immutable.
1.15 + *
1.16 + * @author ked
1.17 + */
1.18 +public final class Convertor<AmountType, IdentifierType> {
1.19 +
1.20 + Computer<AmountType> computer;
1.21 + CurrencyValue<AmountType, IdentifierType> firstCurrencyExchangeRate;
1.22 + CurrencyValue<AmountType, IdentifierType> secondCurrencyExchangeRate;
1.23 +
1.24 + Convertor(
1.25 + Computer<AmountType> computer,
1.26 + CurrencyValue<AmountType, IdentifierType> firstCurrencyExchangeRate,
1.27 + CurrencyValue<AmountType, IdentifierType> secondCurrencyExchangeRate) {
1.28 + if (firstCurrencyExchangeRate.getIdentifier() == null ||
1.29 + secondCurrencyExchangeRate.getIdentifier() == null ||
1.30 + firstCurrencyExchangeRate.getIdentifier().equals(secondCurrencyExchangeRate.getIdentifier())) {
1.31 + throw new IllegalArgumentException("Inappropriate exchange rates' identifiers!");
1.32 + }
1.33 + this.computer = computer;
1.34 + this.firstCurrencyExchangeRate = firstCurrencyExchangeRate;
1.35 + this.secondCurrencyExchangeRate = secondCurrencyExchangeRate;
1.36 + }
1.37 +
1.38 + /**
1.39 + * Convert an amount of the one currency to an amount of the another one currency
1.40 + * with respect to previously specified exchange rate.
1.41 + *
1.42 + * @param targetCurrency an identifier of the requested currency
1.43 + * @param currencyValue an amount of the another one currency
1.44 + * @return an amount of the requested currency
1.45 + */
1.46 + public CurrencyValue<AmountType, IdentifierType> convert(
1.47 + IdentifierType targetCurrency,
1.48 + CurrencyValue<AmountType, IdentifierType> currencyValue) {
1.49 + if (firstCurrencyExchangeRate.getIdentifier().equals(targetCurrency) &&
1.50 + secondCurrencyExchangeRate.getIdentifier().equals(currencyValue.getIdentifier())) {
1.51 + ComputerRequest<AmountType> computerRequest = new ComputerRequest<AmountType>();
1.52 + computerRequest.setInput(currencyValue.getAmount());
1.53 + computerRequest.setInputCurrencyRatio(secondCurrencyExchangeRate.getAmount());
1.54 + computerRequest.setOutputCurrencyRatio(firstCurrencyExchangeRate.getAmount());
1.55 + ComputerResponse<AmountType> computerResponse = computer.compute(computerRequest);
1.56 +
1.57 + return CurrencyValue.getCurrencyValue(
1.58 + computerResponse.getResult(),
1.59 + firstCurrencyExchangeRate.getIdentifier());
1.60 + } else if (secondCurrencyExchangeRate.getIdentifier().equals(targetCurrency) &&
1.61 + firstCurrencyExchangeRate.getIdentifier().equals(currencyValue.getIdentifier())) {
1.62 + ComputerRequest<AmountType> computerRequest = new ComputerRequest<AmountType>();
1.63 + computerRequest.setInput(currencyValue.getAmount());
1.64 + computerRequest.setInputCurrencyRatio(firstCurrencyExchangeRate.getAmount());
1.65 + computerRequest.setOutputCurrencyRatio(secondCurrencyExchangeRate.getAmount());
1.66 + ComputerResponse<AmountType> computerResponse = computer.compute(computerRequest);
1.67 +
1.68 + return CurrencyValue.getCurrencyValue(
1.69 + computerResponse.getResult(),
1.70 + secondCurrencyExchangeRate.getIdentifier());
1.71 + } else {
1.72 + throw new IllegalArgumentException("Inappropriate currencies to convert!");
1.73 + }
1.74 + }
1.75 +
1.76 + static <AmountType, IdentifierType> Convertor<AmountType, IdentifierType> getConvertor(
1.77 + Computer<AmountType> computer,
1.78 + CurrencyValue<AmountType, IdentifierType> firstCurrencyExchangeRate,
1.79 + CurrencyValue<AmountType, IdentifierType> secondCurrencyExchangeRate) {
1.80 + return new Convertor<AmountType, IdentifierType>(
1.81 + computer,
1.82 + firstCurrencyExchangeRate,
1.83 + secondCurrencyExchangeRate);
1.84 + }
1.85 +
1.86 + static final Computer<Double> DoubleComputer = new Computer<Double>() {
1.87 +
1.88 + public ComputerResponse<Double> compute(ComputerRequest<Double> request) {
1.89 + ComputerResponse<Double> response = new ComputerResponse<Double>();
1.90 + response.setResult(request.getInput() * request.getOutputCurrencyRatio() / request.getInputCurrencyRatio());
1.91 + return response;
1.92 + }
1.93 + };
1.94 +
1.95 + /**
1.96 + * Creates convertor for Double|String values with specified exchange rate
1.97 + * between two currencies.
1.98 + *
1.99 + * @param firstCurrencyExchangeRate first currency
1.100 + * @param secondCurrencyExchangeRate second currency
1.101 + * @return convertor
1.102 + */
1.103 +
1.104 + public static Convertor<Double, String> getConvertorDoubleString(
1.105 + CurrencyValue<Double, String> firstCurrencyExchangeRate,
1.106 + CurrencyValue<Double, String> secondCurrencyExchangeRate) {
1.107 + return getConvertor(DoubleComputer, firstCurrencyExchangeRate, secondCurrencyExchangeRate);
1.108 + }
1.109 +
1.110 + static final Computer<Integer> IntegerComputer = new Computer<Integer>() {
1.111 +
1.112 + public ComputerResponse<Integer> compute(ComputerRequest<Integer> request) {
1.113 + ComputerResponse<Integer> response = new ComputerResponse<Integer>();
1.114 + response.setResult(request.getInput() * request.getOutputCurrencyRatio() / request.getInputCurrencyRatio());
1.115 + return response;
1.116 + }
1.117 + };
1.118 +
1.119 + /**
1.120 + * Creates convertor for Integer|String values with specified exchange rate
1.121 + * between two currencies.
1.122 + *
1.123 + * @param firstCurrencyExchangeRate first currency
1.124 + * @param secondCurrencyExchangeRate second currency
1.125 + * @return convertor
1.126 + */
1.127 + public static Convertor<Integer, String> getConvertorIntegerString(
1.128 + CurrencyValue<Integer, String> firstCurrencyExchangeRate,
1.129 + CurrencyValue<Integer, String> secondCurrencyExchangeRate) {
1.130 + return getConvertor(IntegerComputer, firstCurrencyExchangeRate, secondCurrencyExchangeRate);
1.131 + }
1.132 +}