1.1 --- a/task1/solution06/src/org/apidesign/apifest08/currency/Amount.java Tue Sep 30 12:04:26 2008 +0200
1.2 +++ b/task1/solution06/src/org/apidesign/apifest08/currency/Amount.java Tue Sep 30 12:24:45 2008 +0200
1.3 @@ -1,9 +1,10 @@
1.4 package org.apidesign.apifest08.currency;
1.5
1.6 +import static org.apidesign.apifest08.currency.Assert.notNull;
1.7 +
1.8 import java.math.BigDecimal;
1.9 import java.math.RoundingMode;
1.10 import java.util.Currency;
1.11 -import static org.apidesign.apifest08.currency.Assert.*;
1.12
1.13 /**
1.14 * An amount representation. Amount is represented as composition of a value and
2.1 --- a/task1/solution06/src/org/apidesign/apifest08/currency/Assert.java Tue Sep 30 12:04:26 2008 +0200
2.2 +++ b/task1/solution06/src/org/apidesign/apifest08/currency/Assert.java Tue Sep 30 12:24:45 2008 +0200
2.3 @@ -1,9 +1,11 @@
2.4 package org.apidesign.apifest08.currency;
2.5
2.6 -public class Assert {
2.7 +public final class Assert {
2.8 static void notNull(Object value, String argumentName) {
2.9 if(value == null) {
2.10 throw new IllegalArgumentException("The argument '" + argumentName + "' connot not be null");
2.11 }
2.12 }
2.13 }
2.14 +
2.15 +
3.1 --- a/task1/solution06/src/org/apidesign/apifest08/currency/Convertor.java Tue Sep 30 12:04:26 2008 +0200
3.2 +++ b/task1/solution06/src/org/apidesign/apifest08/currency/Convertor.java Tue Sep 30 12:24:45 2008 +0200
3.3 @@ -1,23 +1,30 @@
3.4 package org.apidesign.apifest08.currency;
3.5
3.6 +import static org.apidesign.apifest08.currency.Assert.notNull;
3.7 +
3.8 import java.math.BigDecimal;
3.9 +import java.math.RoundingMode;
3.10 import java.util.Currency;
3.11
3.12 -public abstract class Convertor {
3.13 -
3.14 - /**
3.15 - * Converts an amount to another amount according to a given currency.
3.16 - *
3.17 - * @param from a source
3.18 - * @param toCurrency a target currency
3.19 - * @return a converted amount
3.20 - * @throws ConversionException if the conversion fails
3.21 - * @throws UnsupportedConversionException if the conversion between a given currencies is not supported.
3.22 - */
3.23 - public abstract Amount convert(Amount from, Currency toCurrency) throws ConversionException, UnsupportedConversionException;
3.24 +public final class Convertor {
3.25
3.26 + private final Currency first;
3.27 + private final Currency second;
3.28 + private final BigDecimal rateValue; // a rate between the first currency and the second currency
3.29 + public static final BigDecimal one = new BigDecimal(1);
3.30 +
3.31 + public Convertor(BigDecimal rateValue, Currency currencyFirst, Currency currencySecond) {
3.32 + notNull(currencyFirst, "currencyFirst");
3.33 + notNull(currencySecond, "currencySecond");
3.34 + notNull(rateValue, "rateValue");
3.35 +
3.36 + this.rateValue = rateValue;
3.37 + this.first = currencyFirst;
3.38 + this.second = currencySecond;
3.39 + }
3.40 +
3.41 /**
3.42 - * Converts an amount value between two currencies.
3.43 + * Converts an amount value between the two currencies of this converter.
3.44 *
3.45 * @param amount an amount
3.46 * @param fromCurrency an amount currency
3.47 @@ -27,6 +34,31 @@
3.48 * @throws ConversionException if the conversion fails
3.49 * @throws UnsupportedConversionException if the conversion between a given currencies is not supported.
3.50 */
3.51 - public abstract Amount convert(BigDecimal amount, Currency fromCurrency, Currency toCurrency) throws ConversionException, UnsupportedConversionException;
3.52 + public Amount convert(BigDecimal amount, Currency fromCurrency, Currency toCurrency) throws ConversionException {
3.53 + notNull(amount, "amount");
3.54 + notNull(fromCurrency, "fromCurrency");
3.55 + notNull(toCurrency, "toCurrency");
3.56 +
3.57 + if((fromCurrency != first && fromCurrency != second) || (toCurrency != first && toCurrency != second)) {
3.58 + throw new UnsupportedConversionException(fromCurrency, toCurrency);
3.59 + }
3.60
3.61 + BigDecimal rateValue = getRateValue(fromCurrency, toCurrency);
3.62 + BigDecimal result = rateValue.multiply(amount);
3.63 + return new Amount(result, toCurrency);
3.64 + }
3.65 +
3.66 + private BigDecimal getRateValue(Currency fromCurrency, Currency toCurrency) {
3.67 +
3.68 + BigDecimal retVal;
3.69 +
3.70 + if(first == fromCurrency) {
3.71 + retVal = rateValue;
3.72 + } else {
3.73 + //reverse rate
3.74 + retVal = one.divide(rateValue, 10 ,RoundingMode.HALF_UP);
3.75 + }
3.76 +
3.77 + return retVal;
3.78 + }
3.79 }
4.1 --- a/task1/solution06/src/org/apidesign/apifest08/currency/UnsupportedConversionException.java Tue Sep 30 12:04:26 2008 +0200
4.2 +++ b/task1/solution06/src/org/apidesign/apifest08/currency/UnsupportedConversionException.java Tue Sep 30 12:24:45 2008 +0200
4.3 @@ -2,7 +2,7 @@
4.4
4.5 import java.util.Currency;
4.6
4.7 -public class UnsupportedConversionException extends ConversionException{
4.8 +public final class UnsupportedConversionException extends ConversionException{
4.9
4.10 private static final long serialVersionUID = 1L;
4.11
4.12 @@ -10,7 +10,7 @@
4.13 private Currency to;
4.14
4.15 public UnsupportedConversionException(Currency from, Currency to) {
4.16 - super("Conversion from the currency " + from + " to the currency " + to + " or vice versa in not supported yet. Missing bid.");
4.17 + super("Conversion from the currency " + from + " to the currency " + to + " or vice versa in not supported.");
4.18 this.from = from;
4.19 this.to = to;
4.20 }
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/task1/solution06/test/org/apidesign/apifest08/test/Currencies.java Tue Sep 30 12:24:45 2008 +0200
5.3 @@ -0,0 +1,9 @@
5.4 +package org.apidesign.apifest08.test;
5.5 +
5.6 +import java.util.Currency;
5.7 +
5.8 +public class Currencies {
5.9 + public static final Currency CZK = Currency.getInstance("CZK");
5.10 + public static final Currency SKK = Currency.getInstance("SKK");
5.11 + public static final Currency USD = Currency.getInstance("USD");
5.12 +}
6.1 --- a/task1/solution06/test/org/apidesign/apifest08/test/Task1Test.java Tue Sep 30 12:04:26 2008 +0200
6.2 +++ b/task1/solution06/test/org/apidesign/apifest08/test/Task1Test.java Tue Sep 30 12:24:45 2008 +0200
6.3 @@ -1,16 +1,16 @@
6.4 package org.apidesign.apifest08.test;
6.5
6.6 -import static org.apidesign.apifest08.currency.Currencies.CZK;
6.7 -import static org.apidesign.apifest08.currency.Currencies.SKK;
6.8 -import static org.apidesign.apifest08.currency.Currencies.USD;
6.9 +import static org.apidesign.apifest08.test.Currencies.CZK;
6.10 +import static org.apidesign.apifest08.test.Currencies.SKK;
6.11 +import static org.apidesign.apifest08.test.Currencies.USD;
6.12
6.13 import java.math.BigDecimal;
6.14
6.15 import junit.framework.TestCase;
6.16
6.17 import org.apidesign.apifest08.currency.Amount;
6.18 +import org.apidesign.apifest08.currency.ConversionException;
6.19 import org.apidesign.apifest08.currency.Convertor;
6.20 -import org.apidesign.apifest08.currency.ConvertorFactory;
6.21 import org.apidesign.apifest08.currency.UnsupportedConversionException;
6.22
6.23 /** Finish the Convertor API, and then write bodies of methods inside
6.24 @@ -41,7 +41,7 @@
6.25 * @return prepared convertor ready for converting USD to CZK and CZK to USD
6.26 */
6.27 public static Convertor createCZKtoUSD() {
6.28 - return ConvertorFactory.newInstance();
6.29 + return new Convertor(new BigDecimal(17), USD, CZK);
6.30 }
6.31
6.32 /** Create convertor that understands two currencies, CZK and
6.33 @@ -53,7 +53,7 @@
6.34 * @return prepared convertor ready for converting SKK to CZK and CZK to SKK
6.35 */
6.36 public static Convertor createSKKtoCZK() {
6.37 - return ConvertorFactory.newInstance();
6.38 + return new Convertor(new BigDecimal("0.8"), SKK, CZK);
6.39 }
6.40
6.41 /** Use the convertor from <code>createCZKtoUSD</code> method and do few conversions
6.42 @@ -88,14 +88,49 @@
6.43 assertEquals("Result is 400 CZK", 400, result.getValue().intValue());
6.44 }
6.45
6.46 - public void testUnssuportedConversion(){
6.47 - Convertor c = ConvertorFactory.newInstance();
6.48 +
6.49 + /**
6.50 + * Verify that the CZK to USD convertor knows nothing about SKK.
6.51 + */
6.52 + public void testCannotConvertToSKKwithCZKUSDConvertor() throws Exception {
6.53 + Convertor c = createCZKtoUSD();
6.54 + // convert $5 to SKK, the API shall say this is not possible
6.55 + try {
6.56 + c.convert(new BigDecimal(5), USD, SKK);
6.57 + fail("convert $5 to SKK, the API shall say this is not possible");
6.58 + } catch (ConversionException e) {
6.59 + //expected
6.60 + }
6.61 +
6.62 + // convert 500 SKK to CZK, the API shall say this is not possible
6.63 +
6.64 + try {
6.65 + c.convert(new BigDecimal("500"), SKK, CZK);
6.66 + fail("convert 500 SKK to CZK, the API shall say this is not possible");
6.67 + } catch (ConversionException e) {
6.68 + //expected
6.69 + }
6.70 + }
6.71 +
6.72 + /**
6.73 + * Verify that the CZK to SKK convertor knows nothing about USD.
6.74 + */
6.75 + public void testCannotConvertToSKKwithCZKSKKConvertor() throws Exception {
6.76 + Convertor c = createSKKtoCZK();
6.77 + // convert $5 to SKK, the API shall say this is not possible
6.78 try {
6.79 c.convert(new BigDecimal(5), USD, SKK);
6.80 - fail();
6.81 - } catch(UnsupportedConversionException e) {
6.82 - //expected
6.83 - }
6.84 - }
6.85 + fail("convert $5 to SKK, the API shall say this is not possible");
6.86 + } catch(ConversionException e) {
6.87 + //expected
6.88 + }
6.89 +
6.90 + try {
6.91 + c.convert(new BigDecimal(500), CZK, USD);
6.92 + fail("convert 500 CZK to USD, the API shall say this is not possible");
6.93 + } catch(ConversionException e) {
6.94 + //expected
6.95 + }
6.96 + }
6.97 }
6.98