# HG changeset patch # User Jaroslav Tulach # Date 1224257508 -7200 # Node ID 20d332739f60c856e82a585b310ca1540576200e # Parent f711ecd374f348a14acaf6fb036d9d644f8978be Solution 13 for task4 diff -r f711ecd374f3 -r 20d332739f60 task4/solution13/src/org/apidesign/apifest08/currency/ConversionNotSupportedException.java --- a/task4/solution13/src/org/apidesign/apifest08/currency/ConversionNotSupportedException.java Sat Oct 11 23:46:05 2008 +0200 +++ b/task4/solution13/src/org/apidesign/apifest08/currency/ConversionNotSupportedException.java Fri Oct 17 17:31:48 2008 +0200 @@ -46,9 +46,9 @@ public String toString() { if (from!=null && to !=null) { if (reversed) { - return "Neither onversion nor reverted conversion from " + from + " to " + to + " is not supported,"; + return "Neither conversion nor reverted conversion from " + from + " to " + to + " is supported,"; } else { - return "Conversion from " + from + " to " + to + " is not supported,"; + return "Conversion from " + from + " to " + to + " is not supported,"; } } else { return super.toString(); diff -r f711ecd374f3 -r 20d332739f60 task4/solution13/src/org/apidesign/apifest08/currency/ConversionResult.java --- a/task4/solution13/src/org/apidesign/apifest08/currency/ConversionResult.java Sat Oct 11 23:46:05 2008 +0200 +++ b/task4/solution13/src/org/apidesign/apifest08/currency/ConversionResult.java Fri Oct 17 17:31:48 2008 +0200 @@ -46,4 +46,11 @@ this.remainder = remainder; } + @Override + public String toString() { + return getClass().getSimpleName()+": converter:"+getConverted()+", remainder:"+getRemainder(); + } + + + } diff -r f711ecd374f3 -r 20d332739f60 task4/solution13/src/org/apidesign/apifest08/currency/Convertor.java --- a/task4/solution13/src/org/apidesign/apifest08/currency/Convertor.java Sat Oct 11 23:46:05 2008 +0200 +++ b/task4/solution13/src/org/apidesign/apifest08/currency/Convertor.java Fri Oct 17 17:31:48 2008 +0200 @@ -3,6 +3,7 @@ import java.math.BigDecimal; import java.math.MathContext; import java.math.RoundingMode; +import java.util.Date; /** Convertor able to convert amount from one currency to other currency. *

@@ -20,6 +21,11 @@ */ public class Convertor { private Convertor[] convertors; + private IDateProviderEngine dateProvider; + boolean remainderAllowed = true; //if false, remained is not allowed (should be true ideally, but can't handle it now) + private ExchangeRateProvider exchangeRateProvider; + private Date fromDate; + private Date toDate; /** Create new Convertor as merge of provided convertors. Merged convertor will use * provided convertors to convert between currencies. @@ -32,21 +38,26 @@ * @return Returns new convertor instance. */ public static Convertor createConvertorAsMerge(Convertor[] convertors) { + for (int i=0;i ->"+remainder); return result; } - private ConversionResult convertValue(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency,BigDecimal amount, boolean convertBack,boolean reversibleExRate) throws RuntimeException { + private ConversionResult convertValue(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency,BigDecimal amount, boolean convertBack,boolean reversibleExRate,Date date) throws RuntimeException { //result.setRemainder(...); + if (!dateIsInLimit(date)) { + return null; + } if (convertors.length==0) { - return convertUsingSimpleConvertor(fromCurrency, toCurrency, reversibleExRate, amount, convertBack); + return convertUsingSimpleConvertor(fromCurrency, toCurrency, reversibleExRate, amount, convertBack,date); } else { ConversionResult result = null; for (int i = 0;i * Exchange rate is provided by exchange rate provider which was specified when Convertor was created. * This method is using only exchange rate from->to and not trying to use reverted excange rate to->from. + *

+ * This method is using date from IDateProviderEngine to get exchange rate (see {@link #getDateProvider() }. * * @param fromCurrency Source currency to convert from. * @param toCurrency Target currency to convert to. @@ -184,19 +208,40 @@ * @throws ConversionNotSupportedException If conversion from fromCurrency to toCurrency is not supported. */ public ConversionResult convert(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency, BigDecimal value) { - ConversionResult result = convertValue(fromCurrency, toCurrency, value, false,false); + Date defaultDate = dateProvider.getCurrentDate(); + ConversionResult result = convertValue(fromCurrency, toCurrency, value, false,false,defaultDate); if (result==null) { //throw new ConversionNotSupportedException("Conversion from " + fromCurrency + " to " + toCurrency + " is not supported"); throw new ConversionNotSupportedException(fromCurrency.getCurrencyCode(),toCurrency.getCurrencyCode(),false); } return result; } + /** + * Same as {@link #convert(ConvertorCurrency, ConvertorCurrency, java.math.BigDecimal)} but using provided rate instead of + * IDateProviderEngine. + * + * @param fromCurrency Source currency to convert from. + * @param toCurrency Target currency to convert to. + * @param value Value in source currency which should be converted. + * @return Return conversion result. + * @param date Conversion date + * @return Return conversion result. + */ + public ConversionResult convert(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency, BigDecimal value, Date date) { + ConversionResult result = convertValue(fromCurrency, toCurrency, value, false,false,date); + if (result==null) { + throw new ConversionNotSupportedException(fromCurrency.getCurrencyCode(),toCurrency.getCurrencyCode(),false); + } + return result; + } /** * Convert value from fromCurrency to toCurrency. * Exchange rate is provided by exchange rate provider which was specified when Convertor was created. *

* This method is using only exchange rate from->to and if not found, it is trying to use reverted excange rate to->from. + *

+ * This method is using date from IDateProviderEngine to get exchange rate (see {@link #getDateProvider() }. * * @param fromCurrency Source currency to convert from. * @param toCurrency Target currency to convert to. @@ -207,7 +252,8 @@ * is not supported and neither conversion from toCurrency to fromCurrency is not supported. */ public ConversionResult convertWithReversibleRates(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency, BigDecimal value) { - ConversionResult result = convertValue(fromCurrency, toCurrency, value, false,true); + Date defaultDate = dateProvider.getCurrentDate(); + ConversionResult result = convertValue(fromCurrency, toCurrency, value, false,true,defaultDate); if (result==null) { //throw new ConversionNotSupportedException("Neither onversion nor reverted conversion from " + fromCurrency + " to " + toCurrency + " is not supported,"); throw new ConversionNotSupportedException(fromCurrency.getCurrencyCode(),toCurrency.getCurrencyCode(),true); @@ -215,4 +261,75 @@ return result; } + /** + * Same as {@link #convertWithReversibleRates(ConvertorCurrency, ConvertorCurrency, java.math.BigDecimal)} but using provided rate instead of + * IDateProviderEngine. + * + * @param fromCurrency Source currency to convert from. + * @param toCurrency Target currency to convert to. + * @param value Value in source currency which should be converted. + * @return Return conversion result. + * @param date Conversion date + * @return Return conversion result. + */ + public ConversionResult convertWithReversibleRates(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency, BigDecimal value, Date date) { + ConversionResult result = convertValue(fromCurrency, toCurrency, value, false,true,date); + if (result==null) { + throw new ConversionNotSupportedException(fromCurrency.getCurrencyCode(),toCurrency.getCurrencyCode(),true); + } + return result; + } + + private boolean dateIsInLimit(Date date) { + boolean result; +// if (date==null) { +// result = true; +// } else + if (fromDate == null && toDate == null) { + result = true; + } else if (fromDate.getTime()<=date.getTime() && date.getTime()<=toDate.getTime()) { + result = true; + } else { + result = false; + } + + return result; + } + + + public void limitAllowedDates(Date from, Date till) { + if (from==null) { + throw new NullPointerException("from Date can't be null"); + } + if (till==null) { + throw new NullPointerException("till Date can't be null"); + } + if (from.getTime()>till.getTime()) { + throw new IllegalArgumentException("From date "+from+" must be before tii date "+till); + } + this.fromDate = from; + this.toDate = till; + } + + + /** Return current date provider. + * @return Returns current date provider. + */ + public IDateProviderEngine getDateProvider() { + return dateProvider; + } + + + /** + * Set date provider. Date provider is used to get "current date". Current date + * is used by methods {@link #convert(ConvertorCurrency, ConvertorCurrency, java.math.BigDecimal)} and + * {@link #convertWithReversibleRates(ConvertorCurrency, ConvertorCurrency, java.math.BigDecimal)}. + * + * @param dateProvider Date provider which should be used by Convertor. + */ + public void setDateProvider(IDateProviderEngine dateProvider) { + this.dateProvider = dateProvider; + } + + } diff -r f711ecd374f3 -r 20d332739f60 task4/solution13/src/org/apidesign/apifest08/currency/ConvertorCurrency.java --- a/task4/solution13/src/org/apidesign/apifest08/currency/ConvertorCurrency.java Sat Oct 11 23:46:05 2008 +0200 +++ b/task4/solution13/src/org/apidesign/apifest08/currency/ConvertorCurrency.java Fri Oct 17 17:31:48 2008 +0200 @@ -12,22 +12,38 @@ * @author arnostvalicek */ public class ConvertorCurrency { + private String currencyCode; + private int fractionDigits; - private Currency currency; - - private void setJavaCurrency(Currency javaCurrency) { - this.currency = javaCurrency; - } /** - * Static method providing instance of ConvertorCurrency base of currency code. + * Static method providing instance of ConvertorCurrency based on currency code. + *

+ * currencyCode is one of codes supported by Java class {@link java.util.Currency}. * * @param currencyCode Code of required currency. * @return Returns required ConvertorCurrency */ public static ConvertorCurrency getInstance(String currencyCode) { ConvertorCurrency convertorCurrency = new ConvertorCurrency(); - convertorCurrency.setJavaCurrency(Currency.getInstance(currencyCode)); + Currency currency = Currency.getInstance(currencyCode); + convertorCurrency.setCurrencyCode(currency.getCurrencyCode()); + convertorCurrency.setDefaultFractionDigits(currency.getDefaultFractionDigits()); + return convertorCurrency; + } + + /** + * Static method providing instance of ConvertorCurrency base of currency code. + * + * @param currencyCode Code of required currency. + * @param fractionDigits Number of fraction digits for currency. + * @return Returns required ConvertorCurrency + * @since version4 + */ + public static ConvertorCurrency getInstance(String currencyCode, int fractionDigits) { + ConvertorCurrency convertorCurrency = new ConvertorCurrency(); + convertorCurrency.setCurrencyCode(currencyCode); + convertorCurrency.setDefaultFractionDigits(fractionDigits); return convertorCurrency; } @@ -36,7 +52,23 @@ * @return Returns the default number of fraction digits used with this currency. */ public int getDefaultFractionDigits() { - return currency.getDefaultFractionDigits(); + return fractionDigits; + } + + private void setDefaultFractionDigits(int value) { + this.fractionDigits = value; + } + + /** + * Get currency code. + * @return Returns currency code. + */ + public String getCurrencyCode() { + return currencyCode; + } + + private void setCurrencyCode(String value) { + currencyCode = value; } @Override @@ -44,7 +76,7 @@ boolean result; if (obj instanceof ConvertorCurrency) { ConvertorCurrency that = (ConvertorCurrency) obj; - result = currency.equals(that.currency); + result = getCurrencyCode().equals(that.getCurrencyCode()) && getDefaultFractionDigits()==that.getDefaultFractionDigits(); } else { result = false; } @@ -53,18 +85,13 @@ @Override public int hashCode() { - return currency==null ? 47/*??*/ : currency.hashCode(); + return currencyCode==null ? 47/*??*/ : currencyCode.hashCode(); } - - - + @Override public String toString() { - return "ConvertorCurrency[" + (currency != null ? currency.toString() : "NO-BASE-CURRENCY")+"]"; + return "ConvertorCurrency[" + (currencyCode != null ? currencyCode : "NO-BASE-CURRENCY")+"]"; } - - String getCurrencyCode() { - return currency.getCurrencyCode(); - } -} + +} \ No newline at end of file diff -r f711ecd374f3 -r 20d332739f60 task4/solution13/src/org/apidesign/apifest08/currency/DateProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/task4/solution13/src/org/apidesign/apifest08/currency/DateProvider.java Fri Oct 17 17:31:48 2008 +0200 @@ -0,0 +1,36 @@ +package org.apidesign.apifest08.currency; + +import java.util.Date; + +/** + * Provider for current date. + * + * @author arnostvalicek + * @since version4. + */ +public class DateProvider { + private DateProvider() { + + } + + /** + * Create date provider based on current system time. + * @see java.lang.System#currentTimeMillis() + */ + public static IDateProviderEngine createCurrentDateProvider() { + return new CurrentDateProvider(); + } + + /** + * Date provider based on current system time. + * @see java.lang.System#currentTimeMillis() + */ + private static class CurrentDateProvider implements IDateProviderEngine { + + public Date getCurrentDate() { + return new Date(); + } + + } + +} diff -r f711ecd374f3 -r 20d332739f60 task4/solution13/src/org/apidesign/apifest08/currency/ExchangeRateProvider.java --- a/task4/solution13/src/org/apidesign/apifest08/currency/ExchangeRateProvider.java Sat Oct 11 23:46:05 2008 +0200 +++ b/task4/solution13/src/org/apidesign/apifest08/currency/ExchangeRateProvider.java Fri Oct 17 17:31:48 2008 +0200 @@ -12,6 +12,7 @@ *

*

* Date dependend exchange rate to be implemented. @@ -21,6 +22,7 @@ public class ExchangeRateProvider { IExchangeRateEngine exrateEngine; + IDateExchangeRateEngine dateExrateEngine; /** * Simple constructor for ExchangeRateProviderM which can provide fixed exchange rate. @@ -62,6 +64,18 @@ provider.exrateEngine = exchangeRateEngine; return provider; } + + /** + * Static method to create exchange rate provider which is using provided IExIDateExchangeRateEnginechangeRateEngine. This exchange rate provider is using + * IExchangeRateEngine to get actual exchange rate. + * @param exchangeRateEngine IDateExchangeRateEngine used to get exchange rate. + * @return Returns instance of ExchangeRateProvider + */ + public static ExchangeRateProvider createDateExchangeRateProvider(IDateExchangeRateEngine exchangeRateEngine) { + ExchangeRateProvider provider = new ExchangeRateProvider(); + provider.dateExrateEngine = exchangeRateEngine; + return provider; + } /** * Add new exchange rate to to this simple exchange rate provider. @@ -103,25 +117,44 @@ /** * Get fixed exange rate for currencies (from->to). + * @param fromCurrency Source currency. + * @param toCurrency Target currency. * @return Returns exchange rate or null if exchange rate not found. */ public ExchangeRate getExchangeRate(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency) { - return getExchangeRateImpl(fromCurrency, toCurrency); + return getExchangeRateImpl(fromCurrency, toCurrency,null); + } + + /** + * Get exange rate for currencies (from->to) for date. + * @param fromCurrency Source currency. + * @param toCurrency Target currency. + * @param date Conversion date. + * @return Returns exchange rate or null if exchange rate not found. + */ + public ExchangeRate getExchangeRate(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency, Date date) { + return getExchangeRateImpl(fromCurrency, toCurrency,date); } /** * Get fixed exange rate for currencies (from->to) or reversed exchange rate (to->from). + * @param fromCurrency Source currency. + * @param toCurrency Target currency. * @return Returns exchange rate or null if exchange rate not found. */ public ExchangeRate getReversibleExchangeRate(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency) { - ExchangeRate rate = getExchangeRateImpl(fromCurrency, toCurrency); - if (rate == null) { - ExchangeRate revertedRate = getExchangeRateImpl(toCurrency, fromCurrency); - if (revertedRate != null) { - rate = ExchangeRate.createRevertedRate(revertedRate); - } - } - return rate; + return getReversibleExrateImpl(fromCurrency, toCurrency,null); + } + + /** + * Get exange rate for currencies (from->to) or reversed exchange rate (to->from) for date. + * @param fromCurrency Source currency. + * @param toCurrency Target currency. + * @param date Conversion date. + * @return Returns exchange rate or null if exchange rate not found. + */ + public ExchangeRate getReversibleExchangeRate(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency, Date date) { + return getReversibleExrateImpl(fromCurrency, toCurrency, date); } /** @@ -157,9 +190,28 @@ throw new IllegalStateException("Method supported only for FixedOneExchangeRateEngine. This method is deprecated"); } } + - private ExchangeRate getExchangeRateImpl(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency) { - ExchangeRate result = exrateEngine.getExchangeRate(fromCurrency, toCurrency); + private ExchangeRate getReversibleExrateImpl(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency,Date date) { + ExchangeRate rate = getExchangeRateImpl(fromCurrency, toCurrency, date); + if (rate == null) { + ExchangeRate revertedRate = getExchangeRateImpl(toCurrency, fromCurrency, date); + if (revertedRate != null) { + rate = ExchangeRate.createRevertedRate(revertedRate); + } + } + return rate; + } + + private ExchangeRate getExchangeRateImpl(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency,Date date) { + ExchangeRate result; + if (exrateEngine!=null) { + result = exrateEngine.getExchangeRate(fromCurrency, toCurrency); + } else if (dateExrateEngine!=null) { + result = dateExrateEngine.getExchangeRate(fromCurrency, toCurrency, date); + } else { + throw new IllegalStateException("No exchange rate engine provided"); + } return result; } @@ -224,7 +276,7 @@ */ private static class FixedExchangeRateEngine implements IExchangeRateEngine { - private Map exchangeRateMap = new HashMap(); + private Map> exchangeRateMap = new HashMap>(); private FixedExchangeRateEngine() { } @@ -238,15 +290,14 @@ } public ExchangeRate getExchangeRate(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency) { - Map map2 = (Map) exchangeRateMap.get(fromCurrency); + Map map2 = exchangeRateMap.get(fromCurrency); if (map2 == null) { return null; } - ExchangeRate result = (ExchangeRate) map2.get(toCurrency); + ExchangeRate result = map2.get(toCurrency); return result; } - @SuppressWarnings("unchecked") public synchronized void addFixedCurencyRate(ConvertorCurrency fromCurrency, BigDecimal fromValue, ConvertorCurrency toCurrency, BigDecimal toValue) { if (fromValue == null) { throw new NullPointerException("fromValue can't be null"); @@ -254,9 +305,9 @@ if (toValue == null) { throw new NullPointerException("toValue can't be null"); } - Map map2 = (Map) exchangeRateMap.get(fromCurrency); + Map map2 = exchangeRateMap.get(fromCurrency); if (map2 == null) { - map2 = new HashMap(); + map2 = new HashMap(); exchangeRateMap.put(fromCurrency, map2); } diff -r f711ecd374f3 -r 20d332739f60 task4/solution13/src/org/apidesign/apifest08/currency/IDateExchangeRateEngine.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/task4/solution13/src/org/apidesign/apifest08/currency/IDateExchangeRateEngine.java Fri Oct 17 17:31:48 2008 +0200 @@ -0,0 +1,21 @@ +package org.apidesign.apifest08.currency; + +import java.util.Date; + +/** + * Interface for exchange rate engine using dates. + * + * @author arnostvalicek + */ +public interface IDateExchangeRateEngine { + /** + * Get exchange rate for conversion from fromCurrency to toCurrency at date. + * + * @param fromCurrency From currency. + * @param toCurrency To currency. + * @param date Conversion date. + * @return Returns ExchangeRate if exchange rate is known or null if exchanger rate is not known. + */ + public ExchangeRate getExchangeRate(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency, Date date); + +} diff -r f711ecd374f3 -r 20d332739f60 task4/solution13/src/org/apidesign/apifest08/currency/IDateProviderEngine.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/task4/solution13/src/org/apidesign/apifest08/currency/IDateProviderEngine.java Fri Oct 17 17:31:48 2008 +0200 @@ -0,0 +1,19 @@ +package org.apidesign.apifest08.currency; + +import java.util.Date; + +/** + * Date provider - provides current date. + * @see DateProvider#createCurrentDateProvider() + * @see Convertor#setDateProvider(IDateProviderEngine) + * @author arnostvalicek + * @since version4 + */ +public interface IDateProviderEngine { + /** + * Get current date. + * @return Return current date. + */ + public Date getCurrentDate(); + +} diff -r f711ecd374f3 -r 20d332739f60 task4/solution13/test/org/apidesign/apifest08/test/ConvertorWithDateExchangeRateTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/task4/solution13/test/org/apidesign/apifest08/test/ConvertorWithDateExchangeRateTest.java Fri Oct 17 17:31:48 2008 +0200 @@ -0,0 +1,109 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package org.apidesign.apifest08.test; + +import java.math.BigDecimal; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import junit.framework.TestCase; +import org.apidesign.apifest08.currency.ConversionResult; +import org.apidesign.apifest08.currency.Convertor; +import org.apidesign.apifest08.currency.ConvertorCurrency; +import org.apidesign.apifest08.currency.ExchangeRate; +import org.apidesign.apifest08.currency.ExchangeRateProvider; +import org.apidesign.apifest08.currency.IDateExchangeRateEngine; +import org.apidesign.apifest08.currency.IDateProviderEngine; + +/** + * + * @author arnostvalicek + */ +public class ConvertorWithDateExchangeRateTest extends TestCase { + + private static ConvertorCurrency CZK = ConvertorCurrency.getInstance("CZK"); + private static ConvertorCurrency SKK = ConvertorCurrency.getInstance("SKK"); + private static ConvertorCurrency USD = ConvertorCurrency.getInstance("USD"); + private SimpleDateFormat df; + + @Override + protected void setUp() throws Exception { + super.setUp(); + df = new SimpleDateFormat("yyyy-MM-dd HH:mm zzzz"); + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + df = null; + } + + private IDateExchangeRateEngine createDateEngine() { + IDateExchangeRateEngine engine = new IDateExchangeRateEngine() { + + public ExchangeRate getExchangeRate(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency, Date date) { + int day = date.getDay(); + if (day >= 1 && day <= 5) { + //weekday + return new ExchangeRate(new BigDecimal(1), new BigDecimal(2)); + } else { + //weekend + return new ExchangeRate(new BigDecimal(1), new BigDecimal(3)); + } + } + }; + return engine; + } + + private Convertor createConvertor() { + ExchangeRateProvider exchangeRateProvider = ExchangeRateProvider.createDateExchangeRateProvider(createDateEngine()); + Convertor c = Convertor.createConvertor(exchangeRateProvider); + return c; + } + + public void testConvertuUsingDifferentRatesForDays() throws ParseException { + Convertor c = createConvertor(); + { + Date d1 = df.parse("2008-10-15 9:00 GMT"); //Wednesday + ConversionResult resultWeekday = c.convert(CZK, SKK, new BigDecimal("2.3"), d1); + assertEquals("Weekday conversion", new BigDecimal("4.60"), resultWeekday.getConverted()); + } + { + Date d1 = df.parse("2008-10-18 9:00 GMT"); //Saturday + ConversionResult resultWeekday = c.convert(CZK, SKK, new BigDecimal("2.3"), d1); + assertEquals("Weekday conversion", new BigDecimal("6.90"), resultWeekday.getConverted()); + } + } + + public void testConvertUsingDifferenDefaultDay() throws ParseException { + class MyDateProvider implements IDateProviderEngine { + + private Date date; + + void setDate(Date date) { + this.date = date; + } + + public Date getCurrentDate() { + return date; + } + } + + Convertor c = createConvertor(); + MyDateProvider dp = new MyDateProvider(); + c.setDateProvider(dp); + + { + dp.setDate(df.parse("2008-10-15 9:00 GMT")); //Wednesday + ConversionResult resultWeekday = c.convert(CZK, SKK, new BigDecimal("2.3")); + assertEquals("Weekday conversion", new BigDecimal("4.60"), resultWeekday.getConverted()); + } + { + dp.setDate(df.parse("2008-10-18 9:00 GMT")); //Saturday + ConversionResult resultWeekday = c.convert(CZK, SKK, new BigDecimal("2.3")); + assertEquals("Weekday conversion", new BigDecimal("6.90"), resultWeekday.getConverted()); + } + } +} diff -r f711ecd374f3 -r 20d332739f60 task4/solution13/test/org/apidesign/apifest08/test/RemainderTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/task4/solution13/test/org/apidesign/apifest08/test/RemainderTest.java Fri Oct 17 17:31:48 2008 +0200 @@ -0,0 +1,80 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package org.apidesign.apifest08.test; + +import java.math.BigDecimal; +import java.text.SimpleDateFormat; +import junit.framework.TestCase; +import org.apidesign.apifest08.currency.ConversionResult; +import org.apidesign.apifest08.currency.Convertor; +import org.apidesign.apifest08.currency.ConvertorCurrency; +import org.apidesign.apifest08.currency.ExchangeRateProvider; + +/** + * + * @author arnostvalicek + */ +public class RemainderTest extends TestCase { + private static ConvertorCurrency CZK = ConvertorCurrency.getInstance("CZK"); + private static ConvertorCurrency SKK = ConvertorCurrency.getInstance("SKK"); + private static ConvertorCurrency USD = ConvertorCurrency.getInstance("USD"); + private SimpleDateFormat df; + + @Override + protected void setUp() throws Exception { + super.setUp(); + df = new SimpleDateFormat("yyyy-MM-dd HH:mm zzzz"); + + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + } + + public void testRemainder1() { + Convertor c = Task2Test.createUsdToSkkConvertor(); + { + final BigDecimal convertedValue = new BigDecimal("12.34"); + ConversionResult result = c.convertWithReversibleRates(SKK,USD,convertedValue); + //System.out.println("Result = "+result); + assertEquals("Converted", new BigDecimal("0.61"),result.getConverted()); + assertEquals("Remainder", new BigDecimal("0.14"),result.getRemainder()); + + ConversionResult resultBack = c.convertWithReversibleRates(USD, SKK, result.getConverted()); + assertEquals("Conversion back", convertedValue, resultBack.getConverted().add(result.getRemainder())); + + } + { + ConversionResult result = c.convertWithReversibleRates(SKK,USD,new BigDecimal("20.00")); + //System.out.println("Result = "+result); + } + + { + ConversionResult result = c.convertWithReversibleRates(USD,SKK,new BigDecimal("1.00")); + //System.out.println("Result = "+result); + } + + } + + public void testRemainderStripCents() { + ConvertorCurrency CZK_cents=ConvertorCurrency.getInstance("CZK", 2); + ConvertorCurrency CZK_nocents=ConvertorCurrency.getInstance("CZK", 0); + + + ExchangeRateProvider exchangeRateProvider = ExchangeRateProvider.createExchangeRateProvider(); + exchangeRateProvider.addFixedCurencyRate(CZK_cents, new BigDecimal(1), CZK_nocents, new BigDecimal(1)); + + Convertor c = Convertor.createConvertor(exchangeRateProvider); + + ConversionResult result = c.convertWithReversibleRates(CZK_cents, CZK_nocents, new BigDecimal("2.34")); + assertEquals("Converted",new BigDecimal("2"),result.getConverted()); + assertEquals("Remainder",new BigDecimal("0.34"),result.getRemainder()); + } + + + +} diff -r f711ecd374f3 -r 20d332739f60 task4/solution13/test/org/apidesign/apifest08/test/Task1Test.java --- a/task4/solution13/test/org/apidesign/apifest08/test/Task1Test.java Sat Oct 11 23:46:05 2008 +0200 +++ b/task4/solution13/test/org/apidesign/apifest08/test/Task1Test.java Fri Oct 17 17:31:48 2008 +0200 @@ -78,35 +78,35 @@ // convert $1 to CZK using c: ConversionResult result = convertCzkUsd.convertBack(new BigDecimal(1)); assertEquals("Result is 17 CZK", new BigDecimal("17.00"), result.getConverted()); - assertEquals("No Remainer", BigDecimal.ZERO, result.getRemainder()); + assertEquals("No Remainer", new BigDecimal("00.00").setScale(2), result.getRemainder()); } { // convert 17CKZ to $ using c: ConversionResult result = convertCzkUsd.convert(new BigDecimal(17)); assertEquals("Result is 1 $", new BigDecimal("1.00"), result.getConverted()); - assertEquals("No Remainer", BigDecimal.ZERO, result.getRemainder()); + assertEquals("No Remainer", new BigDecimal("00.00").setScale(2), result.getRemainder()); } { // convert $5 to CZK using c: ConversionResult result = convertCzkUsd.convertBack(new BigDecimal(5)); assertEquals("Result is 85 CZK", new BigDecimal("85.00"), result.getConverted()); - assertEquals("No Remainer", BigDecimal.ZERO, result.getRemainder()); + assertEquals("No Remainer", BigDecimal.ZERO.setScale(2), result.getRemainder()); } { // convert $8 to CZK ConversionResult result = convertCzkUsd.convertBack(new BigDecimal(8)); assertEquals("Result is 136 CZK", new BigDecimal("136.00"), result.getConverted()); - assertEquals("No Remainer", BigDecimal.ZERO, result.getRemainder()); + assertEquals("No Remainer", BigDecimal.ZERO.setScale(2), result.getRemainder()); } { // convert 1003CZK to USD ConversionResult result = convertCzkUsd.convert(new BigDecimal(1003)); assertEquals("Result is 59 USD", new BigDecimal("59.00"), result.getConverted()); - assertEquals("No Remainer", BigDecimal.ZERO, result.getRemainder()); + assertEquals("No Remainer", BigDecimal.ZERO.setScale(2), result.getRemainder()); } } @@ -136,14 +136,14 @@ // convert 500SKK to CZK ConversionResult result = convertSkkCzk.convert(new BigDecimal(500)); assertEquals("Result is 400 CZK", new BigDecimal("400.00"), result.getConverted()); - assertEquals("No Remainer", BigDecimal.ZERO, result.getRemainder()); + assertEquals("No Remainer", BigDecimal.ZERO.setScale(2), result.getRemainder()); } { // convert 501SKK to CZK ConversionResult result = convertSkkCzk.convert(new BigDecimal(501)); assertEquals("Result is 400 CZK", new BigDecimal("400.80"), result.getConverted()); - assertEquals("No Remainer", BigDecimal.ZERO, result.getRemainder()); + assertEquals("No Remainer", BigDecimal.ZERO.setScale(2), result.getRemainder()); } } diff -r f711ecd374f3 -r 20d332739f60 task4/solution13/test/org/apidesign/apifest08/test/Task2Test.java --- a/task4/solution13/test/org/apidesign/apifest08/test/Task2Test.java Sat Oct 11 23:46:05 2008 +0200 +++ b/task4/solution13/test/org/apidesign/apifest08/test/Task2Test.java Fri Oct 17 17:31:48 2008 +0200 @@ -38,7 +38,7 @@ public static Convertor createUsdToSkkConvertor() { ConvertorCurrency fromCurrency = currencyUSD; - ConvertorCurrency toCurrency = currencyUSD; + ConvertorCurrency toCurrency = currencySKK; ExchangeRateProvider exchangeRateProvider = new ExchangeRateProvider(new BigDecimal(1), fromCurrency, new BigDecimal(20), toCurrency); return Convertor.createConvertor(exchangeRateProvider); diff -r f711ecd374f3 -r 20d332739f60 task4/solution13/test/org/apidesign/apifest08/test/Task4Test.java --- a/task4/solution13/test/org/apidesign/apifest08/test/Task4Test.java Sat Oct 11 23:46:05 2008 +0200 +++ b/task4/solution13/test/org/apidesign/apifest08/test/Task4Test.java Fri Oct 17 17:31:48 2008 +0200 @@ -1,8 +1,13 @@ package org.apidesign.apifest08.test; +import java.math.BigDecimal; +import java.text.SimpleDateFormat; import java.util.Date; import junit.framework.TestCase; +import org.apidesign.apifest08.currency.ConversionNotSupportedException; import org.apidesign.apifest08.currency.Convertor; +import org.apidesign.apifest08.currency.ConvertorCurrency; +import org.apidesign.apifest08.currency.ExchangeRateProvider; /** The exchange rates are not always the same. They are changing. However * as in order to predict the future, one needs to understand own past. That is @@ -18,16 +23,26 @@ * System.currentTimeMillis() as default date. */ public class Task4Test extends TestCase { + private static ConvertorCurrency CZK = ConvertorCurrency.getInstance("CZK"); + private static ConvertorCurrency SKK = ConvertorCurrency.getInstance("SKK"); + private static ConvertorCurrency USD = ConvertorCurrency.getInstance("USD"); + private SimpleDateFormat df; + + public Task4Test(String testName) { super(testName); } @Override protected void setUp() throws Exception { + super.setUp(); + df = new SimpleDateFormat("yyyy-MM-dd HH:mm zzzz"); } @Override protected void tearDown() throws Exception { + super.tearDown(); + df = null; } // Backward compatibly enhance your existing API to support following @@ -45,19 +60,22 @@ * @return new convertor */ public static Convertor limitTo(Convertor old, Date from, Date till) { - return null; + Convertor c = Convertor.createConvertorAsMerge(new Convertor[]{old}); + c.limitAllowedDates(from, till); + return c; } public void testCompositionOfLimitedConvertors() throws Exception { - if (Boolean.getBoolean("ignore.failing")) { - // implement me! then delete this if statement - return; - } +// if (Boolean.getBoolean("ignore.failing")) { +// // implement me! then delete this if statement +// return; +// } + - Date d1 = null; // 2008-10-01 0:00 GMT - Date d2 = null; // 2008-10-02 0:00 GMT - Date d3 = null; // 2008-10-03 0:00 GMT + Date d1 = df.parse("2008-10-01 0:00 GMT"); + Date d2 = df.parse("2008-10-02 0:00 GMT"); + Date d3 = df.parse("2008-10-03 0:00 GMT"); Convertor c = Task2Test.merge( limitTo(Task1Test.createCZKtoUSD(), d1, d2), @@ -66,36 +84,81 @@ // convert $5 to CZK using c: // cannot convert as no rate is applicable to current date + try { + c.convert(USD, CZK, new BigDecimal(5)); + fail(); + } catch (ConversionNotSupportedException e) { + //exception expected + } // convert $8 to CZK using c: // cannot convert as no rate is applicable to current date + try { + c.convert(USD, CZK, new BigDecimal(8)); + fail(); + } catch (ConversionNotSupportedException e) { + //exception expected + } + // convert 1003CZK to USD using c: // cannot convert as no rate is applicable to current date + try { + c.convert(CZK, USD, new BigDecimal(1003)); + fail(); + } catch (ConversionNotSupportedException e) { + //exception expected + } // convert 16CZK using c: // cannot convert as no rate is applicable to current date + // ??? + try { + c.convert(CZK, USD, new BigDecimal(16)); + fail(); + } catch (ConversionNotSupportedException e) { + //exception expected + } // convert 500SKK to CZK using c: // cannot convert as no rate is applicable to current date + try { + c.convert(SKK, CZK, new BigDecimal(500)); + fail(); + } catch (ConversionNotSupportedException e) { + //exception expected + } + // convert $5 to CZK using c at 2008-10-01 6:00 GMT: // assertEquals("Result is 85 CZK"); + assertEquals("Result is 85 CZK", new BigDecimal("85.00"), c.convertWithReversibleRates(USD, CZK , new BigDecimal("5"),df.parse("2008-10-01 6:00 GMT")).getConverted()); // convert $8 to CZK using c at 2008-10-01 6:00 GMT: // assertEquals("Result is 136 CZK"); + assertEquals("Result is 136 CZK", new BigDecimal("136.00"), c.convertWithReversibleRates(USD, CZK , new BigDecimal("8"),df.parse("2008-10-01 6:00 GMT")).getConverted()); // convert 1003CZK to USD using c at 2008-10-01 6:00 GMT: // assertEquals("Result is 59 USD"); + assertEquals("Result is 59 USD", new BigDecimal("59.00"), c.convertWithReversibleRates(CZK, USD , new BigDecimal("1003"),df.parse("2008-10-01 6:00 GMT")).getConverted()); // convert 16CZK using c at 2008-10-02 9:00 GMT: // assertEquals("Result is 20 SKK"); + assertEquals("Result is 20 SKK", new BigDecimal("20.00"), c.convertWithReversibleRates(CZK, SKK , new BigDecimal("16"),df.parse("2008-10-02 9:00 GMT")).getConverted()); // convert 500SKK to CZK using c at 2008-10-02 9:00 GMT: // assertEquals("Result is 400 CZK"); + assertEquals("Result is 400 SKK", new BigDecimal("400.00"), c.convertWithReversibleRates(SKK, CZK , new BigDecimal("500"),df.parse("2008-10-02 9:00 GMT")).getConverted()); // convert 500SKK to CZK using c at 2008-10-01 6:00 GMT: // cannot convert as no rate is applicable to current date + try { + c.convertWithReversibleRates(SKK, CZK , new BigDecimal("500"),df.parse("2008-10-01 6:00 GMT")).getConverted(); + fail(); + } catch (ConversionNotSupportedException e) { + //exception expected + } + } /** Create convertor that understands two currencies, CZK and @@ -104,18 +167,17 @@ * @return prepared convertor ready for converting SKK to CZK and CZK to SKK */ public static Convertor createSKKtoCZK2() { - return null; + ExchangeRateProvider exchangeRateProvider = ExchangeRateProvider.createExchangeRateProvider(); + exchangeRateProvider.addFixedCurencyRate(SKK, new BigDecimal("100.00"), CZK, new BigDecimal("90.00")); + Convertor c = Convertor.createConvertor(exchangeRateProvider); + return c; } public void testDateConvetorWithTwoDifferentRates() throws Exception { - if (Boolean.getBoolean("ignore.failing")) { - // implement me! then delete this if statement - return; - } - Date d1 = null; // 2008-10-01 0:00 GMT - Date d2 = null; // 2008-10-02 0:00 GMT - Date d3 = null; // 2008-10-03 0:00 GMT + Date d1 = df.parse("2008-10-01 0:00 GMT"); + Date d2 = df.parse("2008-10-02 0:00 GMT"); + Date d3 = df.parse("2008-10-03 0:00 GMT"); Convertor c = Task2Test.merge( limitTo(createSKKtoCZK2(), d1, d2), @@ -123,10 +185,10 @@ ); // convert 500SKK to CZK using c at 2008-10-02 9:00 GMT: - // assertEquals("Result is 400 CZK"); + assertEquals("Result is 400 CZK", new BigDecimal("400.00"), c.convertWithReversibleRates(SKK, CZK , new BigDecimal("500"),df.parse("2008-10-02 9:00 GMT")).getConverted()); // convert 500SKK to CZK using c at 2008-10-01 6:00 GMT: - // assertEquals("Result is 450 CZK"); + assertEquals("Result is 450 CZK", new BigDecimal("450.00"), c.convertWithReversibleRates(SKK, CZK , new BigDecimal("500"),df.parse("2008-10-01 9:00 GMT")).getConverted()); } }