1.1 --- a/task3/solution11/src/org/apidesign/apifest08/currency/Computer.java Fri Oct 10 21:54:39 2008 +0200
1.2 +++ b/task3/solution11/src/org/apidesign/apifest08/currency/Computer.java Fri Oct 10 21:58:12 2008 +0200
1.3 @@ -11,12 +11,8 @@
1.4 */
1.5 interface Computer<AmountType> {
1.6
1.7 - ComputerResponse<AmountType> compute(ComputerRequest<AmountType> request);
1.8 + void compute(ComputerRequest<AmountType> request, ComputerResponse<AmountType> response);
1.9
1.10 - /**
1.11 - *
1.12 - * @param <AmountType>
1.13 - */
1.14 final class ComputerRequest<AmountType> {
1.15
1.16 private AmountType input;
2.1 --- a/task3/solution11/src/org/apidesign/apifest08/currency/Convertor.java Fri Oct 10 21:54:39 2008 +0200
2.2 +++ b/task3/solution11/src/org/apidesign/apifest08/currency/Convertor.java Fri Oct 10 21:58:12 2008 +0200
2.3 @@ -20,31 +20,47 @@
2.4 * existing convertors into new convertor's instance.
2.5 * No time for javadoc these features, sorry.
2.6 *
2.7 + * In Task3's version supports reading of current exchange rates
2.8 + * from data sources. Data sources are merged during convertors' merging
2.9 + * as well as static exchange rates.
2.10 + * No time for javadoc, again.
2.11 + *
2.12 * @author ked
2.13 */
2.14 public final class Convertor<AmountType, IdentifierType> {
2.15
2.16 Computer<AmountType> computer;
2.17 + // each static exchange rate could be a special case of an exchange rate data source
2.18 List<ExchangeRateValue<AmountType, IdentifierType>> exchangeRates = new ArrayList<ExchangeRateValue<AmountType, IdentifierType>>();
2.19 + List<ExchangeRateDataSource<AmountType, IdentifierType>> exchangeRateDataSources = new ArrayList<ExchangeRateDataSource<AmountType, IdentifierType>>();
2.20
2.21 - Convertor(
2.22 - Computer<AmountType> computer,
2.23 - Collection<ExchangeRateValue<AmountType, IdentifierType>> exchangeRates) {
2.24 + Convertor(Computer<AmountType> computer) {
2.25 this.computer = computer;
2.26 -
2.27 + }
2.28 +
2.29 + void addExchangeRates(Collection<ExchangeRateValue<AmountType, IdentifierType>> exchangeRates) {
2.30 for (ExchangeRateValue<AmountType, IdentifierType> exchangeRate : exchangeRates) {
2.31 - if (findExchangeRate(
2.32 - this.exchangeRates,
2.33 + if (isExchangeRate(
2.34 exchangeRate.getCurrencyA().getIdentifier(),
2.35 - exchangeRate.getCurrencyB().getIdentifier()) != null) {
2.36 + exchangeRate.getCurrencyB().getIdentifier())) {
2.37 throw new IllegalArgumentException("Duplicate exchange rate!");
2.38 }
2.39 this.exchangeRates.add(exchangeRate);
2.40 }
2.41 }
2.42 -
2.43 - private ExchangeRateValue<AmountType, IdentifierType> findExchangeRate(
2.44 - Collection<ExchangeRateValue<AmountType, IdentifierType>> exchangeRates,
2.45 +
2.46 + void addExchangeRateDataSources(Collection<ExchangeRateDataSource<AmountType, IdentifierType>> exchangeRateDataSources) {
2.47 + for (ExchangeRateDataSource<AmountType, IdentifierType> exchangeRateDataSource : exchangeRateDataSources) {
2.48 + if (isExchangeRate(
2.49 + exchangeRateDataSource.getCurrencyAIdentifier(),
2.50 + exchangeRateDataSource.getCurrencyBIdentifier())) {
2.51 + throw new IllegalArgumentException("Duplicate exchange rate!");
2.52 + }
2.53 + this.exchangeRateDataSources.add(exchangeRateDataSource);
2.54 + }
2.55 + }
2.56 +
2.57 + ExchangeRateValue<AmountType, IdentifierType> findExchangeRate(
2.58 IdentifierType currencyA,
2.59 IdentifierType currencyB) {
2.60 for (ExchangeRateValue<AmountType, IdentifierType> exchangeRate : exchangeRates) {
2.61 @@ -53,8 +69,32 @@
2.62 return exchangeRate;
2.63 }
2.64 }
2.65 + for (ExchangeRateDataSource<AmountType, IdentifierType> exchangeRateDataSource : exchangeRateDataSources) {
2.66 + if ((exchangeRateDataSource.getCurrencyAIdentifier().equals(currencyA) && exchangeRateDataSource.getCurrencyBIdentifier().equals(currencyB)) ||
2.67 + (exchangeRateDataSource.getCurrencyAIdentifier().equals(currencyB) && exchangeRateDataSource.getCurrencyBIdentifier().equals(currencyA))) {
2.68 + return exchangeRateDataSource.getExchangeRate();
2.69 + }
2.70 + }
2.71 return null;
2.72 }
2.73 +
2.74 + boolean isExchangeRate(
2.75 + IdentifierType currencyA,
2.76 + IdentifierType currencyB) {
2.77 + for (ExchangeRateValue<AmountType, IdentifierType> exchangeRate : exchangeRates) {
2.78 + if ((exchangeRate.getCurrencyA().getIdentifier().equals(currencyA) && exchangeRate.getCurrencyB().getIdentifier().equals(currencyB)) ||
2.79 + (exchangeRate.getCurrencyA().getIdentifier().equals(currencyB) && exchangeRate.getCurrencyB().getIdentifier().equals(currencyA))) {
2.80 + return true;
2.81 + }
2.82 + }
2.83 + for (ExchangeRateDataSource<AmountType, IdentifierType> exchangeRateDataSource : exchangeRateDataSources) {
2.84 + if ((exchangeRateDataSource.getCurrencyAIdentifier().equals(currencyA) && exchangeRateDataSource.getCurrencyBIdentifier().equals(currencyB)) ||
2.85 + (exchangeRateDataSource.getCurrencyAIdentifier().equals(currencyB) && exchangeRateDataSource.getCurrencyBIdentifier().equals(currencyA))) {
2.86 + return true;
2.87 + }
2.88 + }
2.89 + return false;
2.90 + }
2.91
2.92 /**
2.93 * Convert an amount of the one currency to an amount of the another one currency
2.94 @@ -68,7 +108,7 @@
2.95 IdentifierType targetCurrency,
2.96 CurrencyValue<AmountType, IdentifierType> currencyValue) {
2.97 ExchangeRateValue<AmountType, IdentifierType> exchangeRate =
2.98 - findExchangeRate(exchangeRates, currencyValue.getIdentifier(), targetCurrency);
2.99 + findExchangeRate(currencyValue.getIdentifier(), targetCurrency);
2.100 if (exchangeRate == null) {
2.101 throw new IllegalArgumentException("Inappropriate currencies to convert!");
2.102 }
2.103 @@ -87,7 +127,9 @@
2.104 targetCurrencyRef = exchangeRate.getCurrencyB().getIdentifier();
2.105 }
2.106
2.107 - ComputerResponse<AmountType> computerResponse = computer.compute(computerRequest);
2.108 + ComputerResponse<AmountType> computerResponse = new ComputerResponse<AmountType>();
2.109 + computer.compute(computerRequest, computerResponse);
2.110 +
2.111 return CurrencyValue.getCurrencyValue(
2.112 computerResponse.getResult(),
2.113 targetCurrencyRef);
2.114 @@ -100,10 +142,18 @@
2.115 Computer<AmountType> computer,
2.116 Collection<Convertor<AmountType, IdentifierType>> convertors) {
2.117 Set<ExchangeRateValue<AmountType, IdentifierType>> exchangeRatesSet = new HashSet<ExchangeRateValue<AmountType, IdentifierType>>();
2.118 + Set<ExchangeRateDataSource<AmountType, IdentifierType>> exchangeRateDataSourcesSet = new HashSet<ExchangeRateDataSource<AmountType, IdentifierType>>();
2.119 for (Convertor<AmountType, IdentifierType> convertor : convertors) {
2.120 exchangeRatesSet.addAll(convertor.exchangeRates);
2.121 }
2.122 - return getConvertor(computer, exchangeRatesSet);
2.123 + for (Convertor<AmountType, IdentifierType> convertor : convertors) {
2.124 + exchangeRateDataSourcesSet.addAll(convertor.exchangeRateDataSources);
2.125 + }
2.126 +
2.127 + Convertor<AmountType, IdentifierType> c = new Convertor<AmountType, IdentifierType>(computer);
2.128 + c.addExchangeRates(exchangeRatesSet);
2.129 + c.addExchangeRateDataSources(exchangeRateDataSourcesSet);
2.130 + return c;
2.131 }
2.132
2.133 static <AmountType, IdentifierType> Convertor<AmountType, IdentifierType> mergeConvertors(
2.134 @@ -144,9 +194,18 @@
2.135 // ---
2.136 static <AmountType, IdentifierType> Convertor<AmountType, IdentifierType> getConvertor(
2.137 Computer<AmountType> computer, Collection<ExchangeRateValue<AmountType, IdentifierType>> exchangeRates) {
2.138 - return new Convertor<AmountType, IdentifierType>(computer, exchangeRates);
2.139 + Convertor<AmountType, IdentifierType> c = new Convertor<AmountType, IdentifierType>(computer);
2.140 + c.addExchangeRates(exchangeRates);
2.141 + return c;
2.142 }
2.143
2.144 + static <AmountType, IdentifierType> Convertor<AmountType, IdentifierType> getConvertorDataSource(
2.145 + Computer<AmountType> computer, Collection<ExchangeRateDataSource<AmountType, IdentifierType>> exchangeRateDataSources) {
2.146 + Convertor<AmountType, IdentifierType> c = new Convertor<AmountType, IdentifierType>(computer);
2.147 + c.addExchangeRateDataSources(exchangeRateDataSources);
2.148 + return c;
2.149 + }
2.150 +
2.151 static <AmountType, IdentifierType> Convertor<AmountType, IdentifierType> getConvertor(
2.152 Computer<AmountType> computer, ExchangeRateValue<AmountType, IdentifierType> exchangeRate) {
2.153 Collection<ExchangeRateValue<AmountType, IdentifierType>> exchangeRates =
2.154 @@ -155,6 +214,14 @@
2.155 return getConvertor(computer, exchangeRates);
2.156 }
2.157
2.158 + static <AmountType, IdentifierType> Convertor<AmountType, IdentifierType> getConvertorDataSource(
2.159 + Computer<AmountType> computer, ExchangeRateDataSource<AmountType, IdentifierType> exchangeRateDataSource) {
2.160 + Collection<ExchangeRateDataSource<AmountType, IdentifierType>> exchangeRateDataSources =
2.161 + new ArrayList<ExchangeRateDataSource<AmountType, IdentifierType>>();
2.162 + exchangeRateDataSources.add(exchangeRateDataSource);
2.163 + return getConvertorDataSource(computer, exchangeRateDataSources);
2.164 + }
2.165 +
2.166 public static Convertor<Double, String> getConvertorDoubleString(
2.167 Collection<ExchangeRateValue<Double, String>> exchangeRates) {
2.168 return getConvertor(DoubleComputer, exchangeRates);
2.169 @@ -164,7 +231,17 @@
2.170 ExchangeRateValue<Double, String> exchangeRate) {
2.171 return getConvertor(DoubleComputer, exchangeRate);
2.172 }
2.173 +
2.174 + public static Convertor<Double, String> getConvertorDataSourceDoubleString(
2.175 + Collection<ExchangeRateDataSource<Double, String>> exchangeRateDataSources) {
2.176 + return getConvertorDataSource(DoubleComputer, exchangeRateDataSources);
2.177 + }
2.178
2.179 + public static Convertor<Double, String> getConvertorDataSourceDoubleString(
2.180 + ExchangeRateDataSource<Double, String> exchangeRateDataSource) {
2.181 + return getConvertorDataSource(DoubleComputer, exchangeRateDataSource);
2.182 + }
2.183 +
2.184 public static Convertor<Integer, String> getConvertorIntegerString(
2.185 Collection<ExchangeRateValue<Integer, String>> exchangeRates) {
2.186 return getConvertor(IntegerComputer, exchangeRates);
2.187 @@ -174,6 +251,16 @@
2.188 ExchangeRateValue<Integer, String> exchangeRate) {
2.189 return getConvertor(IntegerComputer, exchangeRate);
2.190 }
2.191 +
2.192 + public static Convertor<Integer, String> getConvertorDataSourceIntegerString(
2.193 + Collection<ExchangeRateDataSource<Integer, String>> exchangeRateDataSources) {
2.194 + return getConvertorDataSource(IntegerComputer, exchangeRateDataSources);
2.195 + }
2.196 +
2.197 + public static Convertor<Integer, String> getConvertorDataSourceIntegerString(
2.198 + ExchangeRateDataSource<Integer, String> exchangeRateDataSource) {
2.199 + return getConvertorDataSource(IntegerComputer, exchangeRateDataSource);
2.200 + }
2.201
2.202 // ---
2.203 // BACKWARD COMPATIBILITY - CREATION
2.204 @@ -211,18 +298,14 @@
2.205 // ---
2.206 static final Computer<Double> DoubleComputer = new Computer<Double>() {
2.207
2.208 - public ComputerResponse<Double> compute(ComputerRequest<Double> request) {
2.209 - ComputerResponse<Double> response = new ComputerResponse<Double>();
2.210 + public void compute(ComputerRequest<Double> request, ComputerResponse<Double> response) {
2.211 response.setResult(request.getInput() * request.getOutputCurrencyRatio() / request.getInputCurrencyRatio());
2.212 - return response;
2.213 }
2.214 };
2.215 static final Computer<Integer> IntegerComputer = new Computer<Integer>() {
2.216
2.217 - public ComputerResponse<Integer> compute(ComputerRequest<Integer> request) {
2.218 - ComputerResponse<Integer> response = new ComputerResponse<Integer>();
2.219 + public void compute(ComputerRequest<Integer> request, ComputerResponse<Integer> response) {
2.220 response.setResult(request.getInput() * request.getOutputCurrencyRatio() / request.getInputCurrencyRatio());
2.221 - return response;
2.222 }
2.223 };
2.224 }
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/task3/solution11/src/org/apidesign/apifest08/currency/ExchangeRateDataSource.java Fri Oct 10 21:58:12 2008 +0200
3.3 @@ -0,0 +1,103 @@
3.4 +package org.apidesign.apifest08.currency;
3.5 +
3.6 +import org.apidesign.apifest08.currency.ExchangeRateProvider.ExchangeRateRequest;
3.7 +import org.apidesign.apifest08.currency.ExchangeRateProvider.ExchangeRateResponse;
3.8 +
3.9 +/**
3.10 + * Exchange rate data source.
3.11 + *
3.12 + * @author ked
3.13 + */
3.14 +public final class ExchangeRateDataSource<AmountType, IdentifierType> {
3.15 +
3.16 + private final IdentifierType currencyAIdentifier;
3.17 +
3.18 + private final IdentifierType currencyBIdentifier;
3.19 +
3.20 + private final ExchangeRateProvider<AmountType, IdentifierType> exchangeRateProvider;
3.21 +
3.22 + private ExchangeRateDataSource(
3.23 + IdentifierType currencyAIdentifier,
3.24 + IdentifierType currencyBIdentifier,
3.25 + ExchangeRateProvider<AmountType, IdentifierType> exchangeRateProvider) {
3.26 + if (currencyAIdentifier == null ||
3.27 + currencyBIdentifier == null ||
3.28 + currencyAIdentifier.equals(currencyBIdentifier)) {
3.29 + throw new IllegalArgumentException("Inappropriate exchange rates' identifiers!");
3.30 + }
3.31 + this.currencyAIdentifier = currencyAIdentifier;
3.32 + this.currencyBIdentifier = currencyBIdentifier;
3.33 + this.exchangeRateProvider = exchangeRateProvider;
3.34 + }
3.35 +
3.36 + public IdentifierType getCurrencyAIdentifier() {
3.37 + return currencyAIdentifier;
3.38 + }
3.39 +
3.40 + public IdentifierType getCurrencyBIdentifier() {
3.41 + return currencyBIdentifier;
3.42 + }
3.43 +
3.44 + public ExchangeRateValue<AmountType, IdentifierType> getExchangeRate() {
3.45 + ExchangeRateRequest<AmountType, IdentifierType> request =
3.46 + new ExchangeRateRequest<AmountType, IdentifierType>();
3.47 + ExchangeRateResponse<AmountType, IdentifierType> response =
3.48 + new ExchangeRateResponse<AmountType, IdentifierType>();
3.49 +
3.50 + request.setCurrencyAIdentifier(currencyAIdentifier);
3.51 + request.setCurrencyBIdentifier(currencyBIdentifier);
3.52 +
3.53 + exchangeRateProvider.getExchangeRate(request, response);
3.54 +
3.55 + if (response.getExchangeRate().getCurrencyA().getIdentifier().equals(currencyAIdentifier) &&
3.56 + response.getExchangeRate().getCurrencyB().getIdentifier().equals(currencyBIdentifier)) {
3.57 + return response.getExchangeRate();
3.58 + } else {
3.59 + throw new IllegalStateException("Data source's provider returned inappropriate exchange rate!");
3.60 + }
3.61 + }
3.62 +
3.63 + public static <AmountType, IdentifierType> ExchangeRateDataSource<AmountType, IdentifierType> getExchangeRateDataSource(
3.64 + IdentifierType currencyAIdentifier,
3.65 + IdentifierType currencyBIdentifier,
3.66 + ExchangeRateProvider<AmountType, IdentifierType> exchangeRateProvider) {
3.67 + return new ExchangeRateDataSource<AmountType, IdentifierType>(
3.68 + currencyAIdentifier,
3.69 + currencyBIdentifier,
3.70 + exchangeRateProvider);
3.71 + }
3.72 +
3.73 + @Override
3.74 + public boolean equals(Object obj) {
3.75 + if (obj == null) {
3.76 + return false;
3.77 + }
3.78 + if (getClass() != obj.getClass()) {
3.79 + return false;
3.80 + }
3.81 + final ExchangeRateDataSource other =
3.82 + (ExchangeRateDataSource) obj;
3.83 + if (this.currencyAIdentifier != other.currencyAIdentifier &&
3.84 + (this.currencyAIdentifier == null || !this.currencyAIdentifier.equals(other.currencyAIdentifier))) {
3.85 + return false;
3.86 + }
3.87 + if (this.currencyBIdentifier != other.currencyBIdentifier &&
3.88 + (this.currencyBIdentifier == null || !this.currencyBIdentifier.equals(other.currencyBIdentifier))) {
3.89 + return false;
3.90 + }
3.91 + if (this.exchangeRateProvider != other.exchangeRateProvider &&
3.92 + (this.exchangeRateProvider == null || !this.exchangeRateProvider.equals(other.exchangeRateProvider))) {
3.93 + return false;
3.94 + }
3.95 + return true;
3.96 + }
3.97 +
3.98 + @Override
3.99 + public int hashCode() {
3.100 + int hash = 7;
3.101 + hash = 83 * hash + (this.currencyAIdentifier != null ? this.currencyAIdentifier.hashCode() : 0);
3.102 + hash = 83 * hash + (this.currencyBIdentifier != null ? this.currencyBIdentifier.hashCode() : 0);
3.103 + hash = 83 * hash + (this.exchangeRateProvider != null ? this.exchangeRateProvider.hashCode() : 0);
3.104 + return hash;
3.105 + }
3.106 +}
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/task3/solution11/src/org/apidesign/apifest08/currency/ExchangeRateProvider.java Fri Oct 10 21:58:12 2008 +0200
4.3 @@ -0,0 +1,55 @@
4.4 +package org.apidesign.apifest08.currency;
4.5 +
4.6 +/**
4.7 + * Exchange rate provider.
4.8 + *
4.9 + * @author ked
4.10 + * @see http://wiki.apidesign.org/wiki/APIDesignPatterns:ResponseReply
4.11 + */
4.12 +public interface ExchangeRateProvider<AmountType, IdentifierType> {
4.13 +
4.14 + public void getExchangeRate(
4.15 + ExchangeRateRequest<AmountType, IdentifierType> request,
4.16 + ExchangeRateResponse<AmountType, IdentifierType> response);
4.17 +
4.18 + public final class ExchangeRateRequest<AmountType, IdentifierType> {
4.19 +
4.20 + private IdentifierType currencyAIdentifier;
4.21 + private IdentifierType currencyBIdentifier;
4.22 +
4.23 + ExchangeRateRequest() {
4.24 + }
4.25 +
4.26 + public IdentifierType getCurrencyAIdentifier() {
4.27 + return currencyAIdentifier;
4.28 + }
4.29 +
4.30 + void setCurrencyAIdentifier(IdentifierType currencyAIdentifier) {
4.31 + this.currencyAIdentifier = currencyAIdentifier;
4.32 + }
4.33 +
4.34 + public IdentifierType getCurrencyBIdentifier() {
4.35 + return currencyBIdentifier;
4.36 + }
4.37 +
4.38 + void setCurrencyBIdentifier(IdentifierType currencyBIdentifier) {
4.39 + this.currencyBIdentifier = currencyBIdentifier;
4.40 + }
4.41 + }
4.42 +
4.43 + public final class ExchangeRateResponse<AmountType, IdentifierType> {
4.44 +
4.45 + private ExchangeRateValue<AmountType, IdentifierType> exchangeRate;
4.46 +
4.47 + ExchangeRateResponse() {
4.48 + }
4.49 +
4.50 + ExchangeRateValue<AmountType, IdentifierType> getExchangeRate() {
4.51 + return exchangeRate;
4.52 + }
4.53 +
4.54 + public void setExchangeRate(ExchangeRateValue<AmountType, IdentifierType> exchangeRate) {
4.55 + this.exchangeRate = exchangeRate;
4.56 + }
4.57 + }
4.58 +}
5.1 --- a/task3/solution11/test/org/apidesign/apifest08/test/Task1Test.java Fri Oct 10 21:54:39 2008 +0200
5.2 +++ b/task3/solution11/test/org/apidesign/apifest08/test/Task1Test.java Fri Oct 10 21:58:12 2008 +0200
5.3 @@ -42,10 +42,10 @@
5.4 *
5.5 * @return prepared convertor ready for converting USD to CZK and CZK to USD
5.6 */
5.7 - public static Convertor<Integer, String> createCZKtoUSD() {
5.8 - return Convertor.getConvertorIntegerString(
5.9 - CurrencyValue.getCurrencyValue(1, "USD"),
5.10 - CurrencyValue.getCurrencyValue(17, "CZK")
5.11 + public static Convertor<Double, String> createCZKtoUSD() {
5.12 + return Convertor.getConvertorDoubleString(
5.13 + CurrencyValue.getCurrencyValue(1d, "USD"),
5.14 + CurrencyValue.getCurrencyValue(17d, "CZK")
5.15 );
5.16 }
5.17
5.18 @@ -61,10 +61,10 @@
5.19 *
5.20 * @return prepared convertor ready for converting SKK to CZK and CZK to SKK
5.21 */
5.22 - public static Convertor<Integer, String> createSKKtoCZK() {
5.23 - return Convertor.getConvertorIntegerString(
5.24 - CurrencyValue.getCurrencyValue(100, "SKK"),
5.25 - CurrencyValue.getCurrencyValue(80, "CZK")
5.26 + public static Convertor<Double, String> createSKKtoCZK() {
5.27 + return Convertor.getConvertorDoubleString(
5.28 + CurrencyValue.getCurrencyValue(100d, "SKK"),
5.29 + CurrencyValue.getCurrencyValue(80d, "CZK")
5.30 );
5.31 }
5.32
5.33 @@ -79,62 +79,60 @@
5.34 * with it.
5.35 */
5.36 public void testCurrencyCZKUSD() throws Exception {
5.37 - Convertor<Integer, String> c = createCZKtoUSD();
5.38 + Convertor<Double, String> c = createCZKtoUSD();
5.39
5.40 - CurrencyValue<Integer, String> result;
5.41 + CurrencyValue<Double, String> result;
5.42
5.43 // convert $5 to CZK using c:
5.44 // assertEquals("Result is 85 CZK");
5.45 - result = c.convert("CZK", CurrencyValue.getCurrencyValue(5, "USD"));
5.46 - assertEquals(CurrencyValue.getCurrencyValue(85, "CZK"), result);
5.47 + result = c.convert("CZK", CurrencyValue.getCurrencyValue(5d, "USD"));
5.48 + assertEquals(CurrencyValue.getCurrencyValue(85d, "CZK"), result);
5.49
5.50 // convert $8 to CZK
5.51 // assertEquals("Result is 136 CZK");
5.52 - result = c.convert("CZK", CurrencyValue.getCurrencyValue(8, "USD"));
5.53 - assertEquals(CurrencyValue.getCurrencyValue(136, "CZK"), result);
5.54 + result = c.convert("CZK", CurrencyValue.getCurrencyValue(8d, "USD"));
5.55 + assertEquals(CurrencyValue.getCurrencyValue(136d, "CZK"), result);
5.56
5.57 // convert 1003CZK to USD
5.58 // assertEquals("Result is 59 USD");
5.59 - result = c.convert("USD", CurrencyValue.getCurrencyValue(1003, "CZK"));
5.60 - assertEquals(CurrencyValue.getCurrencyValue(59, "USD"), result);
5.61 + result = c.convert("USD", CurrencyValue.getCurrencyValue(1003d, "CZK"));
5.62 + assertEquals(CurrencyValue.getCurrencyValue(59d, "USD"), result);
5.63 }
5.64
5.65 /** Use the convertor from <code>createSKKtoCZK</code> method and do few conversions
5.66 * with it.
5.67 */
5.68 public void testCurrencySKKCZK() throws Exception {
5.69 - Convertor<Integer, String> c = createSKKtoCZK();
5.70 + Convertor<Double, String> c = createSKKtoCZK();
5.71
5.72 - CurrencyValue<Integer, String> result;
5.73 + CurrencyValue<Double, String> result;
5.74
5.75 // convert 16CZK using c:
5.76 // assertEquals("Result is 20 SKK");
5.77 - result = c.convert("SKK", CurrencyValue.getCurrencyValue(16, "CZK"));
5.78 - assertEquals(CurrencyValue.getCurrencyValue(20, "SKK"), result);
5.79 + result = c.convert("SKK", CurrencyValue.getCurrencyValue(16d, "CZK"));
5.80 + assertEquals(CurrencyValue.getCurrencyValue(20d, "SKK"), result);
5.81
5.82 // convert 500SKK to CZK
5.83 // assertEquals("Result is 400 CZK");
5.84 - result = c.convert("CZK", CurrencyValue.getCurrencyValue(500, "SKK"));
5.85 - assertEquals(CurrencyValue.getCurrencyValue(400, "CZK"), result);
5.86 + result = c.convert("CZK", CurrencyValue.getCurrencyValue(500d, "SKK"));
5.87 + assertEquals(CurrencyValue.getCurrencyValue(400d, "CZK"), result);
5.88 }
5.89
5.90 /** Verify that the CZK to USD convertor knows nothing about SKK.
5.91 */
5.92 public void testCannotConvertToSKKwithCZKUSDConvertor() throws Exception {
5.93 - Convertor<Integer, String> c = createCZKtoUSD();
5.94 + Convertor<Double, String> c = createCZKtoUSD();
5.95 try {
5.96 // convert $5 to SKK, the API shall say this is not possible
5.97 - c.convert("SKK", CurrencyValue.getCurrencyValue(16, "CZK"));
5.98 - assertTrue("Should not convert", false);
5.99 + c.convert("SKK", CurrencyValue.getCurrencyValue(16d, "CZK"));
5.100 + fail("Should not convert");
5.101 } catch (Exception e) {
5.102 - assertTrue(true);
5.103 }
5.104 try {
5.105 // convert 500 SKK to CZK, the API shall say this is not possible
5.106 - c.convert("CZK", CurrencyValue.getCurrencyValue(500, "SKK"));
5.107 - assertTrue("Should not convert", false);
5.108 + c.convert("CZK", CurrencyValue.getCurrencyValue(500d, "SKK"));
5.109 + fail("Should not convert");
5.110 } catch (Exception e) {
5.111 - assertTrue(true);
5.112 }
5.113
5.114 }
5.115 @@ -142,20 +140,18 @@
5.116 /** Verify that the CZK to SKK convertor knows nothing about USD.
5.117 */
5.118 public void testCannotConvertToUSDwithSKKCZKConvertor() throws Exception {
5.119 - Convertor<Integer, String> c = createSKKtoCZK();
5.120 + Convertor<Double, String> c = createSKKtoCZK();
5.121 try {
5.122 // convert $5 to SKK, the API shall say this is not possible
5.123 - c.convert("SKK", CurrencyValue.getCurrencyValue(5, "USD"));
5.124 - assertTrue("Should not convert", false);
5.125 + c.convert("SKK", CurrencyValue.getCurrencyValue(5d, "USD"));
5.126 + fail("Should not convert");
5.127 } catch (Exception e) {
5.128 - assertTrue(true);
5.129 }
5.130 try {
5.131 // convert 500 CZK to USD, the API shall say this is not possible
5.132 - c.convert("USD", CurrencyValue.getCurrencyValue(500, "CZK"));
5.133 - assertTrue("Should not convert", false);
5.134 + c.convert("USD", CurrencyValue.getCurrencyValue(500d, "CZK"));
5.135 + fail("Should not convert");
5.136 } catch (Exception e) {
5.137 - assertTrue(true);
5.138 }
5.139 }
5.140 }
6.1 --- a/task3/solution11/test/org/apidesign/apifest08/test/Task2Test.java Fri Oct 10 21:54:39 2008 +0200
6.2 +++ b/task3/solution11/test/org/apidesign/apifest08/test/Task2Test.java Fri Oct 10 21:58:12 2008 +0200
6.3 @@ -49,49 +49,49 @@
6.4 * any other method being called previously. The API itself shall know
6.5 * nothing about any rates, before this method is called.
6.6 */
6.7 - public static Convertor<Integer, String> createTripleConvertor() {
6.8 + public static Convertor<Double, String> createTripleConvertor() {
6.9 // Rates: 1USD = 15CZK
6.10 // Rates: 1USD = 20SKK
6.11 // Rates: 75CZK = 100SKK
6.12 - Collection<ExchangeRateValue<Integer, String>> exchangeRates =
6.13 - new ArrayList<ExchangeRateValue<Integer, String>>();
6.14 + Collection<ExchangeRateValue<Double, String>> exchangeRates =
6.15 + new ArrayList<ExchangeRateValue<Double, String>>();
6.16 exchangeRates.add(ExchangeRateValue.getExchangeRate(
6.17 - CurrencyValue.getCurrencyValue(1, "USD"),
6.18 - CurrencyValue.getCurrencyValue(15, "CZK")));
6.19 + CurrencyValue.getCurrencyValue(1d, "USD"),
6.20 + CurrencyValue.getCurrencyValue(15d, "CZK")));
6.21 exchangeRates.add(ExchangeRateValue.getExchangeRate(
6.22 - CurrencyValue.getCurrencyValue(1, "USD"),
6.23 - CurrencyValue.getCurrencyValue(20, "SKK")));
6.24 + CurrencyValue.getCurrencyValue(1d, "USD"),
6.25 + CurrencyValue.getCurrencyValue(20d, "SKK")));
6.26 exchangeRates.add(ExchangeRateValue.getExchangeRate(
6.27 - CurrencyValue.getCurrencyValue(75, "CZK"),
6.28 - CurrencyValue.getCurrencyValue(100, "SKK")));
6.29 - return Convertor.getConvertorIntegerString(exchangeRates);
6.30 + CurrencyValue.getCurrencyValue(75d, "CZK"),
6.31 + CurrencyValue.getCurrencyValue(100d, "SKK")));
6.32 + return Convertor.getConvertorDoubleString(exchangeRates);
6.33 }
6.34
6.35 /** Define convertor that understands three currencies. Use it.
6.36 */
6.37 public void testConvertorForUSDandCZKandSKK() throws Exception {
6.38 - Convertor<Integer, String> c = createTripleConvertor();
6.39 + Convertor<Double, String> c = createTripleConvertor();
6.40
6.41 - CurrencyValue<Integer, String> result;
6.42 + CurrencyValue<Double, String> result;
6.43 // convert $5 to CZK using c:
6.44 // assertEquals("Result is 75 CZK");
6.45 - result = c.convert("CZK", CurrencyValue.getCurrencyValue(5, "USD"));
6.46 - assertEquals(CurrencyValue.getCurrencyValue(75, "CZK"), result);
6.47 + result = c.convert("CZK", CurrencyValue.getCurrencyValue(5d, "USD"));
6.48 + assertEquals(CurrencyValue.getCurrencyValue(75d, "CZK"), result);
6.49
6.50 // convert $5 to SKK using c:
6.51 // assertEquals("Result is 100 SKK");
6.52 - result = c.convert("SKK", CurrencyValue.getCurrencyValue(5, "USD"));
6.53 - assertEquals(CurrencyValue.getCurrencyValue(100, "SKK"), result);
6.54 + result = c.convert("SKK", CurrencyValue.getCurrencyValue(5d, "USD"));
6.55 + assertEquals(CurrencyValue.getCurrencyValue(100d, "SKK"), result);
6.56
6.57 // convert 200SKK to CZK using c:
6.58 // assertEquals("Result is 150 CZK");
6.59 - result = c.convert("CZK", CurrencyValue.getCurrencyValue(200, "SKK"));
6.60 - assertEquals(CurrencyValue.getCurrencyValue(150, "CZK"), result);
6.61 + result = c.convert("CZK", CurrencyValue.getCurrencyValue(200d, "SKK"));
6.62 + assertEquals(CurrencyValue.getCurrencyValue(150d, "CZK"), result);
6.63
6.64 // convert 200SKK to USK using c:
6.65 // assertEquals("Result is 10 USD");
6.66 - result = c.convert("USD", CurrencyValue.getCurrencyValue(200, "SKK"));
6.67 - assertEquals(CurrencyValue.getCurrencyValue(10, "USD"), result);
6.68 + result = c.convert("USD", CurrencyValue.getCurrencyValue(200d, "SKK"));
6.69 + assertEquals(CurrencyValue.getCurrencyValue(10d, "USD"), result);
6.70 }
6.71
6.72 /** Merge all currency rates of convertor 1 with convertor 2.
6.73 @@ -99,42 +99,42 @@
6.74 * into some API method which does the actual work, without requiring
6.75 * API clients to code anything complex.
6.76 */
6.77 - public static Convertor<Integer, String> merge(Convertor<Integer, String> one, Convertor<Integer, String> two) {
6.78 - return Convertor.mergeConvertorsIntegerString(one, two);
6.79 + public static Convertor<Double, String> merge(Convertor<Double, String> one, Convertor<Double, String> two) {
6.80 + return Convertor.mergeConvertorsDoubleString(one, two);
6.81 }
6.82
6.83 /** Join the convertors from previous task, Task1Test and show that it
6.84 * can be used to do reasonable conversions.
6.85 */
6.86 public void testConvertorComposition() throws Exception {
6.87 - Convertor<Integer, String> c = merge(
6.88 + Convertor<Double, String> c = merge(
6.89 Task1Test.createCZKtoUSD(),
6.90 Task1Test.createSKKtoCZK());
6.91
6.92 - CurrencyValue<Integer, String> result;
6.93 + CurrencyValue<Double, String> result;
6.94 // convert $5 to CZK using c:
6.95 // assertEquals("Result is 85 CZK");
6.96 - result = c.convert("CZK", CurrencyValue.getCurrencyValue(5, "USD"));
6.97 - assertEquals(CurrencyValue.getCurrencyValue(85, "CZK"), result);
6.98 + result = c.convert("CZK", CurrencyValue.getCurrencyValue(5d, "USD"));
6.99 + assertEquals(CurrencyValue.getCurrencyValue(85d, "CZK"), result);
6.100
6.101 // convert $8 to CZK using c:
6.102 // assertEquals("Result is 136 CZK");
6.103 - result = c.convert("CZK", CurrencyValue.getCurrencyValue(8, "USD"));
6.104 - assertEquals(CurrencyValue.getCurrencyValue(136, "CZK"), result);
6.105 + result = c.convert("CZK", CurrencyValue.getCurrencyValue(8d, "USD"));
6.106 + assertEquals(CurrencyValue.getCurrencyValue(136d, "CZK"), result);
6.107
6.108 // convert 1003CZK to USD using c:
6.109 // assertEquals("Result is 59 USD");
6.110 - result = c.convert("USD", CurrencyValue.getCurrencyValue(1003, "CZK"));
6.111 - assertEquals(CurrencyValue.getCurrencyValue(59, "USD"), result);
6.112 + result = c.convert("USD", CurrencyValue.getCurrencyValue(1003d, "CZK"));
6.113 + assertEquals(CurrencyValue.getCurrencyValue(59d, "USD"), result);
6.114
6.115 // convert 16CZK using c:
6.116 // assertEquals("Result is 20 SKK");
6.117 - result = c.convert("SKK", CurrencyValue.getCurrencyValue(16, "CZK"));
6.118 - assertEquals(CurrencyValue.getCurrencyValue(20, "SKK"), result);
6.119 + result = c.convert("SKK", CurrencyValue.getCurrencyValue(16d, "CZK"));
6.120 + assertEquals(CurrencyValue.getCurrencyValue(20d, "SKK"), result);
6.121
6.122 // convert 500SKK to CZK using c:
6.123 // assertEquals("Result is 400 CZK");
6.124 - result = c.convert("CZK", CurrencyValue.getCurrencyValue(500, "SKK"));
6.125 - assertEquals(CurrencyValue.getCurrencyValue(400, "CZK"), result);
6.126 + result = c.convert("CZK", CurrencyValue.getCurrencyValue(500d, "SKK"));
6.127 + assertEquals(CurrencyValue.getCurrencyValue(400d, "CZK"), result);
6.128 }
6.129 }
7.1 --- a/task3/solution11/test/org/apidesign/apifest08/test/Task3Test.java Fri Oct 10 21:54:39 2008 +0200
7.2 +++ b/task3/solution11/test/org/apidesign/apifest08/test/Task3Test.java Fri Oct 10 21:58:12 2008 +0200
7.3 @@ -2,6 +2,12 @@
7.4
7.5 import junit.framework.TestCase;
7.6 import org.apidesign.apifest08.currency.Convertor;
7.7 +import org.apidesign.apifest08.currency.CurrencyValue;
7.8 +import org.apidesign.apifest08.currency.ExchangeRateDataSource;
7.9 +import org.apidesign.apifest08.currency.ExchangeRateProvider;
7.10 +import org.apidesign.apifest08.currency.ExchangeRateProvider.ExchangeRateRequest;
7.11 +import org.apidesign.apifest08.currency.ExchangeRateProvider.ExchangeRateResponse;
7.12 +import org.apidesign.apifest08.currency.ExchangeRateValue;
7.13
7.14 /** The exchange rates are not always the same. They are changing. Day by day,
7.15 * hour by hour, minute by minute. For every bank it is important to always
7.16 @@ -16,6 +22,7 @@
7.17 * to be used.
7.18 */
7.19 public class Task3Test extends TestCase {
7.20 +
7.21 public Task3Test(String testName) {
7.22 super(testName);
7.23 }
7.24 @@ -31,8 +38,6 @@
7.25 // Backward compatibly enhance your existing API to support following
7.26 // usecases:
7.27 //
7.28 -
7.29 -
7.30 /** Without knowing anything about the surrounding system, write an
7.31 * implementation of convertor that will return different rates everytime
7.32 * it is queried. Convert USD to CZK and vice versa. Start with the rate of
7.33 @@ -42,7 +47,7 @@
7.34 *
7.35 * @return new instance of "online" USD and CZK convertor starting with rate 1USD = 16CZK
7.36 */
7.37 - public static Convertor createOnlineCZKUSDConvertor() {
7.38 + public static Convertor<Double, String> createOnlineCZKUSDConvertor() {
7.39 // initial rate: 1USD = 16CZK
7.40 // 2nd query 1USD = 15.99CZK
7.41 // 3rd query 1USD = 15.98CZK
7.42 @@ -51,53 +56,80 @@
7.43 // then 1USD = 15.02CZK
7.44 // and so on and on up to 1USD = 16CZK
7.45 // and then another round to 15, etc.
7.46 - return null;
7.47 + return Convertor.getConvertorDataSourceDoubleString(
7.48 + ExchangeRateDataSource.getExchangeRateDataSource(
7.49 + "USD", "CZK", new ExchangeRateProvider<Double, String>() {
7.50 +
7.51 + double currentRate = 16d;
7.52 + double step;
7.53 +
7.54 + public void getExchangeRate(ExchangeRateRequest<Double, String> request,
7.55 + ExchangeRateResponse<Double, String> response) {
7.56 + if ((request.getCurrencyAIdentifier().equals("CZK") && request.getCurrencyBIdentifier().equals("USD")) ||
7.57 + (request.getCurrencyAIdentifier().equals("USD") && request.getCurrencyBIdentifier().equals("CZK"))) {
7.58 + response.setExchangeRate(ExchangeRateValue.getExchangeRate(
7.59 + CurrencyValue.getCurrencyValue(1d, "USD"),
7.60 + CurrencyValue.getCurrencyValue(currentRate, "CZK")));
7.61 +
7.62 + if (currentRate == 16d) {
7.63 + step = -0.01;
7.64 + }
7.65 + if (currentRate == 15d) {
7.66 + step = 0.01;
7.67 + }
7.68 + currentRate += step;
7.69 + } else {
7.70 + throw new IllegalArgumentException("No exchange rate for requested currencies!");
7.71 + }
7.72 + }
7.73 + }));
7.74 }
7.75
7.76 public void testFewQueriesForOnlineConvertor() {
7.77 - if (Boolean.getBoolean("ignore.failing")) {
7.78 - // implement me!
7.79 - return;
7.80 - }
7.81 -
7.82 - Convertor c = createOnlineCZKUSDConvertor();
7.83 + Convertor<Double, String> c = createOnlineCZKUSDConvertor();
7.84 doFewQueriesForOnlineConvertor(c);
7.85 }
7.86
7.87 - static void doFewQueriesForOnlineConvertor(Convertor c) {
7.88 + static void doFewQueriesForOnlineConvertor(Convertor<Double, String> c) {
7.89 + CurrencyValue<Double, String> result;
7.90 // convert $5 to CZK using c:
7.91 //assertEquals("Result is 80 CZK");
7.92 + result = c.convert("CZK", CurrencyValue.getCurrencyValue(5d, "USD"));
7.93 + assertEquals(CurrencyValue.getCurrencyValue(80d, "CZK"), result);
7.94
7.95 // convert $8 to CZK using c:
7.96 //assertEquals("Result is 127.92 CZK");
7.97 + result = c.convert("CZK", CurrencyValue.getCurrencyValue(8d, "USD"));
7.98 + assertEquals(CurrencyValue.getCurrencyValue(127.92d, "CZK"), result);
7.99
7.100 // convert $1 to CZK using c:
7.101 //assertEquals("Result is 15.98 CZK");
7.102 + result = c.convert("CZK", CurrencyValue.getCurrencyValue(1d, "USD"));
7.103 + assertEquals(CurrencyValue.getCurrencyValue(15.98d, "CZK"), result);
7.104
7.105 // convert 15.97CZK to USD using c:
7.106 //assertEquals("Result is 1$");
7.107 -
7.108 - fail("Implement me!");
7.109 + result = c.convert("USD", CurrencyValue.getCurrencyValue(15.97d, "CZK"));
7.110 + assertEquals(CurrencyValue.getCurrencyValue(1d, "USD"), result);
7.111 }
7.112
7.113 /** Join the convertors and show they behave sane.
7.114 */
7.115 public void testOnlineConvertorComposition() throws Exception {
7.116 - if (Boolean.getBoolean("ignore.failing")) {
7.117 - // implement me!
7.118 - return;
7.119 - }
7.120 -
7.121 - Convertor c = Task2Test.merge(
7.122 - createOnlineCZKUSDConvertor(),
7.123 - Task1Test.createSKKtoCZK()
7.124 - );
7.125 + Convertor<Double, String> c = Task2Test.merge(
7.126 + createOnlineCZKUSDConvertor(),
7.127 + Task1Test.createSKKtoCZK());
7.128
7.129 + CurrencyValue<Double, String> result;
7.130 // convert 16CZK to SKK using c:
7.131 // assertEquals("Result is 20 SKK");
7.132 + result = c.convert("SKK", CurrencyValue.getCurrencyValue(16d, "CZK"));
7.133 + assertEquals(CurrencyValue.getCurrencyValue(20d, "SKK"), result);
7.134
7.135 // convert 500SKK to CZK using c:
7.136 // assertEquals("Result is 400 CZK");
7.137 + result = c.convert("CZK", CurrencyValue.getCurrencyValue(500d, "SKK"));
7.138 + assertEquals(CurrencyValue.getCurrencyValue(400d, "CZK"), result);
7.139
7.140 doFewQueriesForOnlineConvertor(c);
7.141 }