# HG changeset patch # User japod@localhost # Date 1223668692 -7200 # Node ID 09d690bb97f60667c3053921975bb0a92984ef07 # Parent c38391fb9b38633778d02684a83f512d6c90d9bd solution11 task3 diff -r c38391fb9b38 -r 09d690bb97f6 task3/solution11/src/org/apidesign/apifest08/currency/Computer.java --- a/task3/solution11/src/org/apidesign/apifest08/currency/Computer.java Fri Oct 10 21:54:39 2008 +0200 +++ b/task3/solution11/src/org/apidesign/apifest08/currency/Computer.java Fri Oct 10 21:58:12 2008 +0200 @@ -11,12 +11,8 @@ */ interface Computer { - ComputerResponse compute(ComputerRequest request); + void compute(ComputerRequest request, ComputerResponse response); - /** - * - * @param - */ final class ComputerRequest { private AmountType input; diff -r c38391fb9b38 -r 09d690bb97f6 task3/solution11/src/org/apidesign/apifest08/currency/Convertor.java --- a/task3/solution11/src/org/apidesign/apifest08/currency/Convertor.java Fri Oct 10 21:54:39 2008 +0200 +++ b/task3/solution11/src/org/apidesign/apifest08/currency/Convertor.java Fri Oct 10 21:58:12 2008 +0200 @@ -20,31 +20,47 @@ * existing convertors into new convertor's instance. * No time for javadoc these features, sorry. * + * In Task3's version supports reading of current exchange rates + * from data sources. Data sources are merged during convertors' merging + * as well as static exchange rates. + * No time for javadoc, again. + * * @author ked */ public final class Convertor { Computer computer; + // each static exchange rate could be a special case of an exchange rate data source List> exchangeRates = new ArrayList>(); + List> exchangeRateDataSources = new ArrayList>(); - Convertor( - Computer computer, - Collection> exchangeRates) { + Convertor(Computer computer) { this.computer = computer; - + } + + void addExchangeRates(Collection> exchangeRates) { for (ExchangeRateValue exchangeRate : exchangeRates) { - if (findExchangeRate( - this.exchangeRates, + if (isExchangeRate( exchangeRate.getCurrencyA().getIdentifier(), - exchangeRate.getCurrencyB().getIdentifier()) != null) { + exchangeRate.getCurrencyB().getIdentifier())) { throw new IllegalArgumentException("Duplicate exchange rate!"); } this.exchangeRates.add(exchangeRate); } } - - private ExchangeRateValue findExchangeRate( - Collection> exchangeRates, + + void addExchangeRateDataSources(Collection> exchangeRateDataSources) { + for (ExchangeRateDataSource exchangeRateDataSource : exchangeRateDataSources) { + if (isExchangeRate( + exchangeRateDataSource.getCurrencyAIdentifier(), + exchangeRateDataSource.getCurrencyBIdentifier())) { + throw new IllegalArgumentException("Duplicate exchange rate!"); + } + this.exchangeRateDataSources.add(exchangeRateDataSource); + } + } + + ExchangeRateValue findExchangeRate( IdentifierType currencyA, IdentifierType currencyB) { for (ExchangeRateValue exchangeRate : exchangeRates) { @@ -53,8 +69,32 @@ return exchangeRate; } } + for (ExchangeRateDataSource exchangeRateDataSource : exchangeRateDataSources) { + if ((exchangeRateDataSource.getCurrencyAIdentifier().equals(currencyA) && exchangeRateDataSource.getCurrencyBIdentifier().equals(currencyB)) || + (exchangeRateDataSource.getCurrencyAIdentifier().equals(currencyB) && exchangeRateDataSource.getCurrencyBIdentifier().equals(currencyA))) { + return exchangeRateDataSource.getExchangeRate(); + } + } return null; } + + boolean isExchangeRate( + IdentifierType currencyA, + IdentifierType currencyB) { + for (ExchangeRateValue exchangeRate : exchangeRates) { + if ((exchangeRate.getCurrencyA().getIdentifier().equals(currencyA) && exchangeRate.getCurrencyB().getIdentifier().equals(currencyB)) || + (exchangeRate.getCurrencyA().getIdentifier().equals(currencyB) && exchangeRate.getCurrencyB().getIdentifier().equals(currencyA))) { + return true; + } + } + for (ExchangeRateDataSource exchangeRateDataSource : exchangeRateDataSources) { + if ((exchangeRateDataSource.getCurrencyAIdentifier().equals(currencyA) && exchangeRateDataSource.getCurrencyBIdentifier().equals(currencyB)) || + (exchangeRateDataSource.getCurrencyAIdentifier().equals(currencyB) && exchangeRateDataSource.getCurrencyBIdentifier().equals(currencyA))) { + return true; + } + } + return false; + } /** * Convert an amount of the one currency to an amount of the another one currency @@ -68,7 +108,7 @@ IdentifierType targetCurrency, CurrencyValue currencyValue) { ExchangeRateValue exchangeRate = - findExchangeRate(exchangeRates, currencyValue.getIdentifier(), targetCurrency); + findExchangeRate(currencyValue.getIdentifier(), targetCurrency); if (exchangeRate == null) { throw new IllegalArgumentException("Inappropriate currencies to convert!"); } @@ -87,7 +127,9 @@ targetCurrencyRef = exchangeRate.getCurrencyB().getIdentifier(); } - ComputerResponse computerResponse = computer.compute(computerRequest); + ComputerResponse computerResponse = new ComputerResponse(); + computer.compute(computerRequest, computerResponse); + return CurrencyValue.getCurrencyValue( computerResponse.getResult(), targetCurrencyRef); @@ -100,10 +142,18 @@ Computer computer, Collection> convertors) { Set> exchangeRatesSet = new HashSet>(); + Set> exchangeRateDataSourcesSet = new HashSet>(); for (Convertor convertor : convertors) { exchangeRatesSet.addAll(convertor.exchangeRates); } - return getConvertor(computer, exchangeRatesSet); + for (Convertor convertor : convertors) { + exchangeRateDataSourcesSet.addAll(convertor.exchangeRateDataSources); + } + + Convertor c = new Convertor(computer); + c.addExchangeRates(exchangeRatesSet); + c.addExchangeRateDataSources(exchangeRateDataSourcesSet); + return c; } static Convertor mergeConvertors( @@ -144,9 +194,18 @@ // --- static Convertor getConvertor( Computer computer, Collection> exchangeRates) { - return new Convertor(computer, exchangeRates); + Convertor c = new Convertor(computer); + c.addExchangeRates(exchangeRates); + return c; } + static Convertor getConvertorDataSource( + Computer computer, Collection> exchangeRateDataSources) { + Convertor c = new Convertor(computer); + c.addExchangeRateDataSources(exchangeRateDataSources); + return c; + } + static Convertor getConvertor( Computer computer, ExchangeRateValue exchangeRate) { Collection> exchangeRates = @@ -155,6 +214,14 @@ return getConvertor(computer, exchangeRates); } + static Convertor getConvertorDataSource( + Computer computer, ExchangeRateDataSource exchangeRateDataSource) { + Collection> exchangeRateDataSources = + new ArrayList>(); + exchangeRateDataSources.add(exchangeRateDataSource); + return getConvertorDataSource(computer, exchangeRateDataSources); + } + public static Convertor getConvertorDoubleString( Collection> exchangeRates) { return getConvertor(DoubleComputer, exchangeRates); @@ -164,7 +231,17 @@ ExchangeRateValue exchangeRate) { return getConvertor(DoubleComputer, exchangeRate); } + + public static Convertor getConvertorDataSourceDoubleString( + Collection> exchangeRateDataSources) { + return getConvertorDataSource(DoubleComputer, exchangeRateDataSources); + } + public static Convertor getConvertorDataSourceDoubleString( + ExchangeRateDataSource exchangeRateDataSource) { + return getConvertorDataSource(DoubleComputer, exchangeRateDataSource); + } + public static Convertor getConvertorIntegerString( Collection> exchangeRates) { return getConvertor(IntegerComputer, exchangeRates); @@ -174,6 +251,16 @@ ExchangeRateValue exchangeRate) { return getConvertor(IntegerComputer, exchangeRate); } + + public static Convertor getConvertorDataSourceIntegerString( + Collection> exchangeRateDataSources) { + return getConvertorDataSource(IntegerComputer, exchangeRateDataSources); + } + + public static Convertor getConvertorDataSourceIntegerString( + ExchangeRateDataSource exchangeRateDataSource) { + return getConvertorDataSource(IntegerComputer, exchangeRateDataSource); + } // --- // BACKWARD COMPATIBILITY - CREATION @@ -211,18 +298,14 @@ // --- static final Computer DoubleComputer = new Computer() { - public ComputerResponse compute(ComputerRequest request) { - ComputerResponse response = new ComputerResponse(); + public void compute(ComputerRequest request, ComputerResponse response) { response.setResult(request.getInput() * request.getOutputCurrencyRatio() / request.getInputCurrencyRatio()); - return response; } }; static final Computer IntegerComputer = new Computer() { - public ComputerResponse compute(ComputerRequest request) { - ComputerResponse response = new ComputerResponse(); + public void compute(ComputerRequest request, ComputerResponse response) { response.setResult(request.getInput() * request.getOutputCurrencyRatio() / request.getInputCurrencyRatio()); - return response; } }; } diff -r c38391fb9b38 -r 09d690bb97f6 task3/solution11/src/org/apidesign/apifest08/currency/ExchangeRateDataSource.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/task3/solution11/src/org/apidesign/apifest08/currency/ExchangeRateDataSource.java Fri Oct 10 21:58:12 2008 +0200 @@ -0,0 +1,103 @@ +package org.apidesign.apifest08.currency; + +import org.apidesign.apifest08.currency.ExchangeRateProvider.ExchangeRateRequest; +import org.apidesign.apifest08.currency.ExchangeRateProvider.ExchangeRateResponse; + +/** + * Exchange rate data source. + * + * @author ked + */ +public final class ExchangeRateDataSource { + + private final IdentifierType currencyAIdentifier; + + private final IdentifierType currencyBIdentifier; + + private final ExchangeRateProvider exchangeRateProvider; + + private ExchangeRateDataSource( + IdentifierType currencyAIdentifier, + IdentifierType currencyBIdentifier, + ExchangeRateProvider exchangeRateProvider) { + if (currencyAIdentifier == null || + currencyBIdentifier == null || + currencyAIdentifier.equals(currencyBIdentifier)) { + throw new IllegalArgumentException("Inappropriate exchange rates' identifiers!"); + } + this.currencyAIdentifier = currencyAIdentifier; + this.currencyBIdentifier = currencyBIdentifier; + this.exchangeRateProvider = exchangeRateProvider; + } + + public IdentifierType getCurrencyAIdentifier() { + return currencyAIdentifier; + } + + public IdentifierType getCurrencyBIdentifier() { + return currencyBIdentifier; + } + + public ExchangeRateValue getExchangeRate() { + ExchangeRateRequest request = + new ExchangeRateRequest(); + ExchangeRateResponse response = + new ExchangeRateResponse(); + + request.setCurrencyAIdentifier(currencyAIdentifier); + request.setCurrencyBIdentifier(currencyBIdentifier); + + exchangeRateProvider.getExchangeRate(request, response); + + if (response.getExchangeRate().getCurrencyA().getIdentifier().equals(currencyAIdentifier) && + response.getExchangeRate().getCurrencyB().getIdentifier().equals(currencyBIdentifier)) { + return response.getExchangeRate(); + } else { + throw new IllegalStateException("Data source's provider returned inappropriate exchange rate!"); + } + } + + public static ExchangeRateDataSource getExchangeRateDataSource( + IdentifierType currencyAIdentifier, + IdentifierType currencyBIdentifier, + ExchangeRateProvider exchangeRateProvider) { + return new ExchangeRateDataSource( + currencyAIdentifier, + currencyBIdentifier, + exchangeRateProvider); + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final ExchangeRateDataSource other = + (ExchangeRateDataSource) obj; + if (this.currencyAIdentifier != other.currencyAIdentifier && + (this.currencyAIdentifier == null || !this.currencyAIdentifier.equals(other.currencyAIdentifier))) { + return false; + } + if (this.currencyBIdentifier != other.currencyBIdentifier && + (this.currencyBIdentifier == null || !this.currencyBIdentifier.equals(other.currencyBIdentifier))) { + return false; + } + if (this.exchangeRateProvider != other.exchangeRateProvider && + (this.exchangeRateProvider == null || !this.exchangeRateProvider.equals(other.exchangeRateProvider))) { + return false; + } + return true; + } + + @Override + public int hashCode() { + int hash = 7; + hash = 83 * hash + (this.currencyAIdentifier != null ? this.currencyAIdentifier.hashCode() : 0); + hash = 83 * hash + (this.currencyBIdentifier != null ? this.currencyBIdentifier.hashCode() : 0); + hash = 83 * hash + (this.exchangeRateProvider != null ? this.exchangeRateProvider.hashCode() : 0); + return hash; + } +} diff -r c38391fb9b38 -r 09d690bb97f6 task3/solution11/src/org/apidesign/apifest08/currency/ExchangeRateProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/task3/solution11/src/org/apidesign/apifest08/currency/ExchangeRateProvider.java Fri Oct 10 21:58:12 2008 +0200 @@ -0,0 +1,55 @@ +package org.apidesign.apifest08.currency; + +/** + * Exchange rate provider. + * + * @author ked + * @see http://wiki.apidesign.org/wiki/APIDesignPatterns:ResponseReply + */ +public interface ExchangeRateProvider { + + public void getExchangeRate( + ExchangeRateRequest request, + ExchangeRateResponse response); + + public final class ExchangeRateRequest { + + private IdentifierType currencyAIdentifier; + private IdentifierType currencyBIdentifier; + + ExchangeRateRequest() { + } + + public IdentifierType getCurrencyAIdentifier() { + return currencyAIdentifier; + } + + void setCurrencyAIdentifier(IdentifierType currencyAIdentifier) { + this.currencyAIdentifier = currencyAIdentifier; + } + + public IdentifierType getCurrencyBIdentifier() { + return currencyBIdentifier; + } + + void setCurrencyBIdentifier(IdentifierType currencyBIdentifier) { + this.currencyBIdentifier = currencyBIdentifier; + } + } + + public final class ExchangeRateResponse { + + private ExchangeRateValue exchangeRate; + + ExchangeRateResponse() { + } + + ExchangeRateValue getExchangeRate() { + return exchangeRate; + } + + public void setExchangeRate(ExchangeRateValue exchangeRate) { + this.exchangeRate = exchangeRate; + } + } +} diff -r c38391fb9b38 -r 09d690bb97f6 task3/solution11/test/org/apidesign/apifest08/test/Task1Test.java --- a/task3/solution11/test/org/apidesign/apifest08/test/Task1Test.java Fri Oct 10 21:54:39 2008 +0200 +++ b/task3/solution11/test/org/apidesign/apifest08/test/Task1Test.java Fri Oct 10 21:58:12 2008 +0200 @@ -42,10 +42,10 @@ * * @return prepared convertor ready for converting USD to CZK and CZK to USD */ - public static Convertor createCZKtoUSD() { - return Convertor.getConvertorIntegerString( - CurrencyValue.getCurrencyValue(1, "USD"), - CurrencyValue.getCurrencyValue(17, "CZK") + public static Convertor createCZKtoUSD() { + return Convertor.getConvertorDoubleString( + CurrencyValue.getCurrencyValue(1d, "USD"), + CurrencyValue.getCurrencyValue(17d, "CZK") ); } @@ -61,10 +61,10 @@ * * @return prepared convertor ready for converting SKK to CZK and CZK to SKK */ - public static Convertor createSKKtoCZK() { - return Convertor.getConvertorIntegerString( - CurrencyValue.getCurrencyValue(100, "SKK"), - CurrencyValue.getCurrencyValue(80, "CZK") + public static Convertor createSKKtoCZK() { + return Convertor.getConvertorDoubleString( + CurrencyValue.getCurrencyValue(100d, "SKK"), + CurrencyValue.getCurrencyValue(80d, "CZK") ); } @@ -79,62 +79,60 @@ * with it. */ public void testCurrencyCZKUSD() throws Exception { - Convertor c = createCZKtoUSD(); + Convertor c = createCZKtoUSD(); - CurrencyValue result; + CurrencyValue result; // convert $5 to CZK using c: // assertEquals("Result is 85 CZK"); - result = c.convert("CZK", CurrencyValue.getCurrencyValue(5, "USD")); - assertEquals(CurrencyValue.getCurrencyValue(85, "CZK"), result); + result = c.convert("CZK", CurrencyValue.getCurrencyValue(5d, "USD")); + assertEquals(CurrencyValue.getCurrencyValue(85d, "CZK"), result); // convert $8 to CZK // assertEquals("Result is 136 CZK"); - result = c.convert("CZK", CurrencyValue.getCurrencyValue(8, "USD")); - assertEquals(CurrencyValue.getCurrencyValue(136, "CZK"), result); + result = c.convert("CZK", CurrencyValue.getCurrencyValue(8d, "USD")); + assertEquals(CurrencyValue.getCurrencyValue(136d, "CZK"), result); // convert 1003CZK to USD // assertEquals("Result is 59 USD"); - result = c.convert("USD", CurrencyValue.getCurrencyValue(1003, "CZK")); - assertEquals(CurrencyValue.getCurrencyValue(59, "USD"), result); + result = c.convert("USD", CurrencyValue.getCurrencyValue(1003d, "CZK")); + assertEquals(CurrencyValue.getCurrencyValue(59d, "USD"), result); } /** Use the convertor from createSKKtoCZK method and do few conversions * with it. */ public void testCurrencySKKCZK() throws Exception { - Convertor c = createSKKtoCZK(); + Convertor c = createSKKtoCZK(); - CurrencyValue result; + CurrencyValue result; // convert 16CZK using c: // assertEquals("Result is 20 SKK"); - result = c.convert("SKK", CurrencyValue.getCurrencyValue(16, "CZK")); - assertEquals(CurrencyValue.getCurrencyValue(20, "SKK"), result); + result = c.convert("SKK", CurrencyValue.getCurrencyValue(16d, "CZK")); + assertEquals(CurrencyValue.getCurrencyValue(20d, "SKK"), result); // convert 500SKK to CZK // assertEquals("Result is 400 CZK"); - result = c.convert("CZK", CurrencyValue.getCurrencyValue(500, "SKK")); - assertEquals(CurrencyValue.getCurrencyValue(400, "CZK"), result); + result = c.convert("CZK", CurrencyValue.getCurrencyValue(500d, "SKK")); + assertEquals(CurrencyValue.getCurrencyValue(400d, "CZK"), result); } /** Verify that the CZK to USD convertor knows nothing about SKK. */ public void testCannotConvertToSKKwithCZKUSDConvertor() throws Exception { - Convertor c = createCZKtoUSD(); + Convertor c = createCZKtoUSD(); try { // convert $5 to SKK, the API shall say this is not possible - c.convert("SKK", CurrencyValue.getCurrencyValue(16, "CZK")); - assertTrue("Should not convert", false); + c.convert("SKK", CurrencyValue.getCurrencyValue(16d, "CZK")); + fail("Should not convert"); } catch (Exception e) { - assertTrue(true); } try { // convert 500 SKK to CZK, the API shall say this is not possible - c.convert("CZK", CurrencyValue.getCurrencyValue(500, "SKK")); - assertTrue("Should not convert", false); + c.convert("CZK", CurrencyValue.getCurrencyValue(500d, "SKK")); + fail("Should not convert"); } catch (Exception e) { - assertTrue(true); } } @@ -142,20 +140,18 @@ /** Verify that the CZK to SKK convertor knows nothing about USD. */ public void testCannotConvertToUSDwithSKKCZKConvertor() throws Exception { - Convertor c = createSKKtoCZK(); + Convertor c = createSKKtoCZK(); try { // convert $5 to SKK, the API shall say this is not possible - c.convert("SKK", CurrencyValue.getCurrencyValue(5, "USD")); - assertTrue("Should not convert", false); + c.convert("SKK", CurrencyValue.getCurrencyValue(5d, "USD")); + fail("Should not convert"); } catch (Exception e) { - assertTrue(true); } try { // convert 500 CZK to USD, the API shall say this is not possible - c.convert("USD", CurrencyValue.getCurrencyValue(500, "CZK")); - assertTrue("Should not convert", false); + c.convert("USD", CurrencyValue.getCurrencyValue(500d, "CZK")); + fail("Should not convert"); } catch (Exception e) { - assertTrue(true); } } } diff -r c38391fb9b38 -r 09d690bb97f6 task3/solution11/test/org/apidesign/apifest08/test/Task2Test.java --- a/task3/solution11/test/org/apidesign/apifest08/test/Task2Test.java Fri Oct 10 21:54:39 2008 +0200 +++ b/task3/solution11/test/org/apidesign/apifest08/test/Task2Test.java Fri Oct 10 21:58:12 2008 +0200 @@ -49,49 +49,49 @@ * any other method being called previously. The API itself shall know * nothing about any rates, before this method is called. */ - public static Convertor createTripleConvertor() { + public static Convertor createTripleConvertor() { // Rates: 1USD = 15CZK // Rates: 1USD = 20SKK // Rates: 75CZK = 100SKK - Collection> exchangeRates = - new ArrayList>(); + Collection> exchangeRates = + new ArrayList>(); exchangeRates.add(ExchangeRateValue.getExchangeRate( - CurrencyValue.getCurrencyValue(1, "USD"), - CurrencyValue.getCurrencyValue(15, "CZK"))); + CurrencyValue.getCurrencyValue(1d, "USD"), + CurrencyValue.getCurrencyValue(15d, "CZK"))); exchangeRates.add(ExchangeRateValue.getExchangeRate( - CurrencyValue.getCurrencyValue(1, "USD"), - CurrencyValue.getCurrencyValue(20, "SKK"))); + CurrencyValue.getCurrencyValue(1d, "USD"), + CurrencyValue.getCurrencyValue(20d, "SKK"))); exchangeRates.add(ExchangeRateValue.getExchangeRate( - CurrencyValue.getCurrencyValue(75, "CZK"), - CurrencyValue.getCurrencyValue(100, "SKK"))); - return Convertor.getConvertorIntegerString(exchangeRates); + CurrencyValue.getCurrencyValue(75d, "CZK"), + CurrencyValue.getCurrencyValue(100d, "SKK"))); + return Convertor.getConvertorDoubleString(exchangeRates); } /** Define convertor that understands three currencies. Use it. */ public void testConvertorForUSDandCZKandSKK() throws Exception { - Convertor c = createTripleConvertor(); + Convertor c = createTripleConvertor(); - CurrencyValue result; + CurrencyValue result; // convert $5 to CZK using c: // assertEquals("Result is 75 CZK"); - result = c.convert("CZK", CurrencyValue.getCurrencyValue(5, "USD")); - assertEquals(CurrencyValue.getCurrencyValue(75, "CZK"), result); + result = c.convert("CZK", CurrencyValue.getCurrencyValue(5d, "USD")); + assertEquals(CurrencyValue.getCurrencyValue(75d, "CZK"), result); // convert $5 to SKK using c: // assertEquals("Result is 100 SKK"); - result = c.convert("SKK", CurrencyValue.getCurrencyValue(5, "USD")); - assertEquals(CurrencyValue.getCurrencyValue(100, "SKK"), result); + result = c.convert("SKK", CurrencyValue.getCurrencyValue(5d, "USD")); + assertEquals(CurrencyValue.getCurrencyValue(100d, "SKK"), result); // convert 200SKK to CZK using c: // assertEquals("Result is 150 CZK"); - result = c.convert("CZK", CurrencyValue.getCurrencyValue(200, "SKK")); - assertEquals(CurrencyValue.getCurrencyValue(150, "CZK"), result); + result = c.convert("CZK", CurrencyValue.getCurrencyValue(200d, "SKK")); + assertEquals(CurrencyValue.getCurrencyValue(150d, "CZK"), result); // convert 200SKK to USK using c: // assertEquals("Result is 10 USD"); - result = c.convert("USD", CurrencyValue.getCurrencyValue(200, "SKK")); - assertEquals(CurrencyValue.getCurrencyValue(10, "USD"), result); + result = c.convert("USD", CurrencyValue.getCurrencyValue(200d, "SKK")); + assertEquals(CurrencyValue.getCurrencyValue(10d, "USD"), result); } /** Merge all currency rates of convertor 1 with convertor 2. @@ -99,42 +99,42 @@ * into some API method which does the actual work, without requiring * API clients to code anything complex. */ - public static Convertor merge(Convertor one, Convertor two) { - return Convertor.mergeConvertorsIntegerString(one, two); + public static Convertor merge(Convertor one, Convertor two) { + return Convertor.mergeConvertorsDoubleString(one, two); } /** Join the convertors from previous task, Task1Test and show that it * can be used to do reasonable conversions. */ public void testConvertorComposition() throws Exception { - Convertor c = merge( + Convertor c = merge( Task1Test.createCZKtoUSD(), Task1Test.createSKKtoCZK()); - CurrencyValue result; + CurrencyValue result; // convert $5 to CZK using c: // assertEquals("Result is 85 CZK"); - result = c.convert("CZK", CurrencyValue.getCurrencyValue(5, "USD")); - assertEquals(CurrencyValue.getCurrencyValue(85, "CZK"), result); + result = c.convert("CZK", CurrencyValue.getCurrencyValue(5d, "USD")); + assertEquals(CurrencyValue.getCurrencyValue(85d, "CZK"), result); // convert $8 to CZK using c: // assertEquals("Result is 136 CZK"); - result = c.convert("CZK", CurrencyValue.getCurrencyValue(8, "USD")); - assertEquals(CurrencyValue.getCurrencyValue(136, "CZK"), result); + result = c.convert("CZK", CurrencyValue.getCurrencyValue(8d, "USD")); + assertEquals(CurrencyValue.getCurrencyValue(136d, "CZK"), result); // convert 1003CZK to USD using c: // assertEquals("Result is 59 USD"); - result = c.convert("USD", CurrencyValue.getCurrencyValue(1003, "CZK")); - assertEquals(CurrencyValue.getCurrencyValue(59, "USD"), result); + result = c.convert("USD", CurrencyValue.getCurrencyValue(1003d, "CZK")); + assertEquals(CurrencyValue.getCurrencyValue(59d, "USD"), result); // convert 16CZK using c: // assertEquals("Result is 20 SKK"); - result = c.convert("SKK", CurrencyValue.getCurrencyValue(16, "CZK")); - assertEquals(CurrencyValue.getCurrencyValue(20, "SKK"), result); + result = c.convert("SKK", CurrencyValue.getCurrencyValue(16d, "CZK")); + assertEquals(CurrencyValue.getCurrencyValue(20d, "SKK"), result); // convert 500SKK to CZK using c: // assertEquals("Result is 400 CZK"); - result = c.convert("CZK", CurrencyValue.getCurrencyValue(500, "SKK")); - assertEquals(CurrencyValue.getCurrencyValue(400, "CZK"), result); + result = c.convert("CZK", CurrencyValue.getCurrencyValue(500d, "SKK")); + assertEquals(CurrencyValue.getCurrencyValue(400d, "CZK"), result); } } diff -r c38391fb9b38 -r 09d690bb97f6 task3/solution11/test/org/apidesign/apifest08/test/Task3Test.java --- a/task3/solution11/test/org/apidesign/apifest08/test/Task3Test.java Fri Oct 10 21:54:39 2008 +0200 +++ b/task3/solution11/test/org/apidesign/apifest08/test/Task3Test.java Fri Oct 10 21:58:12 2008 +0200 @@ -2,6 +2,12 @@ import junit.framework.TestCase; import org.apidesign.apifest08.currency.Convertor; +import org.apidesign.apifest08.currency.CurrencyValue; +import org.apidesign.apifest08.currency.ExchangeRateDataSource; +import org.apidesign.apifest08.currency.ExchangeRateProvider; +import org.apidesign.apifest08.currency.ExchangeRateProvider.ExchangeRateRequest; +import org.apidesign.apifest08.currency.ExchangeRateProvider.ExchangeRateResponse; +import org.apidesign.apifest08.currency.ExchangeRateValue; /** The exchange rates are not always the same. They are changing. Day by day, * hour by hour, minute by minute. For every bank it is important to always @@ -16,6 +22,7 @@ * to be used. */ public class Task3Test extends TestCase { + public Task3Test(String testName) { super(testName); } @@ -31,8 +38,6 @@ // Backward compatibly enhance your existing API to support following // usecases: // - - /** Without knowing anything about the surrounding system, write an * implementation of convertor that will return different rates everytime * it is queried. Convert USD to CZK and vice versa. Start with the rate of @@ -42,7 +47,7 @@ * * @return new instance of "online" USD and CZK convertor starting with rate 1USD = 16CZK */ - public static Convertor createOnlineCZKUSDConvertor() { + public static Convertor createOnlineCZKUSDConvertor() { // initial rate: 1USD = 16CZK // 2nd query 1USD = 15.99CZK // 3rd query 1USD = 15.98CZK @@ -51,53 +56,80 @@ // then 1USD = 15.02CZK // and so on and on up to 1USD = 16CZK // and then another round to 15, etc. - return null; + return Convertor.getConvertorDataSourceDoubleString( + ExchangeRateDataSource.getExchangeRateDataSource( + "USD", "CZK", new ExchangeRateProvider() { + + double currentRate = 16d; + double step; + + public void getExchangeRate(ExchangeRateRequest request, + ExchangeRateResponse response) { + if ((request.getCurrencyAIdentifier().equals("CZK") && request.getCurrencyBIdentifier().equals("USD")) || + (request.getCurrencyAIdentifier().equals("USD") && request.getCurrencyBIdentifier().equals("CZK"))) { + response.setExchangeRate(ExchangeRateValue.getExchangeRate( + CurrencyValue.getCurrencyValue(1d, "USD"), + CurrencyValue.getCurrencyValue(currentRate, "CZK"))); + + if (currentRate == 16d) { + step = -0.01; + } + if (currentRate == 15d) { + step = 0.01; + } + currentRate += step; + } else { + throw new IllegalArgumentException("No exchange rate for requested currencies!"); + } + } + })); } public void testFewQueriesForOnlineConvertor() { - if (Boolean.getBoolean("ignore.failing")) { - // implement me! - return; - } - - Convertor c = createOnlineCZKUSDConvertor(); + Convertor c = createOnlineCZKUSDConvertor(); doFewQueriesForOnlineConvertor(c); } - static void doFewQueriesForOnlineConvertor(Convertor c) { + static void doFewQueriesForOnlineConvertor(Convertor c) { + CurrencyValue result; // convert $5 to CZK using c: //assertEquals("Result is 80 CZK"); + result = c.convert("CZK", CurrencyValue.getCurrencyValue(5d, "USD")); + assertEquals(CurrencyValue.getCurrencyValue(80d, "CZK"), result); // convert $8 to CZK using c: //assertEquals("Result is 127.92 CZK"); + result = c.convert("CZK", CurrencyValue.getCurrencyValue(8d, "USD")); + assertEquals(CurrencyValue.getCurrencyValue(127.92d, "CZK"), result); // convert $1 to CZK using c: //assertEquals("Result is 15.98 CZK"); + result = c.convert("CZK", CurrencyValue.getCurrencyValue(1d, "USD")); + assertEquals(CurrencyValue.getCurrencyValue(15.98d, "CZK"), result); // convert 15.97CZK to USD using c: //assertEquals("Result is 1$"); - - fail("Implement me!"); + result = c.convert("USD", CurrencyValue.getCurrencyValue(15.97d, "CZK")); + assertEquals(CurrencyValue.getCurrencyValue(1d, "USD"), result); } /** Join the convertors and show they behave sane. */ public void testOnlineConvertorComposition() throws Exception { - if (Boolean.getBoolean("ignore.failing")) { - // implement me! - return; - } - - Convertor c = Task2Test.merge( - createOnlineCZKUSDConvertor(), - Task1Test.createSKKtoCZK() - ); + Convertor c = Task2Test.merge( + createOnlineCZKUSDConvertor(), + Task1Test.createSKKtoCZK()); + CurrencyValue result; // convert 16CZK to SKK using c: // assertEquals("Result is 20 SKK"); + result = c.convert("SKK", CurrencyValue.getCurrencyValue(16d, "CZK")); + assertEquals(CurrencyValue.getCurrencyValue(20d, "SKK"), result); // convert 500SKK to CZK using c: // assertEquals("Result is 400 CZK"); + result = c.convert("CZK", CurrencyValue.getCurrencyValue(500d, "SKK")); + assertEquals(CurrencyValue.getCurrencyValue(400d, "CZK"), result); doFewQueriesForOnlineConvertor(c); }