1.1 --- a/task4/solution13/src/org/apidesign/apifest08/currency/ConversionNotSupportedException.java Sat Oct 11 23:46:05 2008 +0200
1.2 +++ b/task4/solution13/src/org/apidesign/apifest08/currency/ConversionNotSupportedException.java Fri Oct 17 17:31:48 2008 +0200
1.3 @@ -46,9 +46,9 @@
1.4 public String toString() {
1.5 if (from!=null && to !=null) {
1.6 if (reversed) {
1.7 - return "Neither onversion nor reverted conversion from " + from + " to " + to + " is not supported,";
1.8 + return "Neither conversion nor reverted conversion from " + from + " to " + to + " is supported,";
1.9 } else {
1.10 - return "Conversion from " + from + " to " + to + " is not supported,";
1.11 + return "Conversion from " + from + " to " + to + " is not supported,";
1.12 }
1.13 } else {
1.14 return super.toString();
2.1 --- a/task4/solution13/src/org/apidesign/apifest08/currency/ConversionResult.java Sat Oct 11 23:46:05 2008 +0200
2.2 +++ b/task4/solution13/src/org/apidesign/apifest08/currency/ConversionResult.java Fri Oct 17 17:31:48 2008 +0200
2.3 @@ -46,4 +46,11 @@
2.4 this.remainder = remainder;
2.5 }
2.6
2.7 + @Override
2.8 + public String toString() {
2.9 + return getClass().getSimpleName()+": converter:"+getConverted()+", remainder:"+getRemainder();
2.10 + }
2.11 +
2.12 +
2.13 +
2.14 }
3.1 --- a/task4/solution13/src/org/apidesign/apifest08/currency/Convertor.java Sat Oct 11 23:46:05 2008 +0200
3.2 +++ b/task4/solution13/src/org/apidesign/apifest08/currency/Convertor.java Fri Oct 17 17:31:48 2008 +0200
3.3 @@ -3,6 +3,7 @@
3.4 import java.math.BigDecimal;
3.5 import java.math.MathContext;
3.6 import java.math.RoundingMode;
3.7 +import java.util.Date;
3.8
3.9 /** Convertor able to convert amount from one currency to other currency.
3.10 * <p>
3.11 @@ -20,6 +21,11 @@
3.12 */
3.13 public class Convertor {
3.14 private Convertor[] convertors;
3.15 + private IDateProviderEngine dateProvider;
3.16 + boolean remainderAllowed = true; //if false, remained is not allowed (should be true ideally, but can't handle it now)
3.17 + private ExchangeRateProvider exchangeRateProvider;
3.18 + private Date fromDate;
3.19 + private Date toDate;
3.20
3.21 /** Create new <code>Convertor</code> as merge of provided convertors. Merged convertor will use
3.22 * provided convertors to convert between currencies.
3.23 @@ -32,21 +38,26 @@
3.24 * @return Returns new convertor instance.
3.25 */
3.26 public static Convertor createConvertorAsMerge(Convertor[] convertors) {
3.27 + for (int i=0;i<convertors.length;i++) {
3.28 + if (convertors[i]==null) {
3.29 + throw new NullPointerException("Convertor at index "+i+" can't be null");
3.30 + }
3.31 + }
3.32 return new Convertor(convertors);
3.33 }
3.34
3.35 - boolean remainderAllowed = true; //if false, remained is not allowed (should be true ideally, but can't handle it now)
3.36 - ExchangeRateProvider exchangeRateProvider;
3.37
3.38 /** Create simle convertor.
3.39 */
3.40 private Convertor() {
3.41 + setDateProvider(DateProvider.createCurrentDateProvider());
3.42 this.convertors=new Convertor[0];
3.43 }
3.44
3.45 /** Create merge convertor.
3.46 */
3.47 private Convertor(Convertor[] convertors) {
3.48 + this();
3.49 this.convertors = convertors;
3.50 }
3.51
3.52 @@ -75,7 +86,7 @@
3.53 * @deprecated since version2. Use {@link #convert(ConvertorCurrency, ConvertorCurrency, BigDecimal) } - explicitly specify conversion currencies.
3.54 */
3.55 public ConversionResult convert(BigDecimal amount) {
3.56 - return convertValue(exchangeRateProvider.getFromCurrency(), exchangeRateProvider.getToCurrency(),amount, false,false);
3.57 + return convertValue(exchangeRateProvider.getFromCurrency(), exchangeRateProvider.getToCurrency(),amount, false,false,null);
3.58 }
3.59
3.60 /**
3.61 @@ -88,32 +99,36 @@
3.62 * @deprecated since version2. Use {@link #convert(ConvertorCurrency, ConvertorCurrency, BigDecimal) } - explicitly specify conversion currencies.
3.63 */
3.64 public ConversionResult convertBack(BigDecimal amount) {
3.65 - return convertValue(exchangeRateProvider.getFromCurrency(), exchangeRateProvider.getToCurrency(),amount, true,false);
3.66 + return convertValue(exchangeRateProvider.getFromCurrency(), exchangeRateProvider.getToCurrency(),amount, true,false,null);
3.67 }
3.68
3.69 - private ConversionResult convertUsingSimpleConvertor(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency, boolean reversibleExRate, BigDecimal amount, boolean convertBack) throws ConversionNotSupportedException, RuntimeException {
3.70 - ConversionResult result = new ConversionResult();
3.71 + private ConversionResult convertUsingSimpleConvertor(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency, boolean reversibleExRate, BigDecimal amount, boolean convertBack,Date date) throws ConversionNotSupportedException, RuntimeException {
3.72 + if (date == null) {
3.73 + date = dateProvider.getCurrentDate();
3.74 + }
3.75
3.76 - //ExchangeRate rate = exchangeRateProvider.getExchangeRate();
3.77 ExchangeRate rate;
3.78 if (reversibleExRate) {
3.79 - rate = exchangeRateProvider.getReversibleExchangeRate(fromCurrency, toCurrency);
3.80 + rate = exchangeRateProvider.getReversibleExchangeRate(fromCurrency, toCurrency, date);
3.81 } else {
3.82 - rate = exchangeRateProvider.getExchangeRate(fromCurrency, toCurrency);
3.83 + rate = exchangeRateProvider.getExchangeRate(fromCurrency, toCurrency, date);
3.84 }
3.85 if (rate == null) {
3.86 return null;
3.87 }
3.88 + ConversionResult result = new ConversionResult();
3.89
3.90 int fromFranctionDigits = fromCurrency.getDefaultFractionDigits();
3.91 int toFractionDigits = toCurrency.getDefaultFractionDigits();
3.92 +
3.93 + int usedFractionDigits = Math.max(fromFranctionDigits, toFractionDigits);
3.94
3.95 - if (toFractionDigits != 2) {
3.96 - throw new ConvertorException("Can't process currency with defaultFractionDigits!=2, " + exchangeRateProvider.getToCurrency() + " has " + toFractionDigits + " defaultFractionDigits");
3.97 - }
3.98 - if (fromFranctionDigits != 2) {
3.99 - throw new ConvertorException("Can't process currency with defaultFractionDigits!=2, " + exchangeRateProvider.getFromCurrency() + " has " + fromFranctionDigits + " defaultFractionDigits");
3.100 - }
3.101 + //if (toFractionDigits != 2) {
3.102 + // throw new ConvertorException("Can't process currency with defaultFractionDigits!=2, " + toCurrency + " has " + toFractionDigits + " defaultFractionDigits");
3.103 + //}
3.104 + //if (fromFranctionDigits != 2) {
3.105 + // throw new ConvertorException("Can't process currency with defaultFractionDigits!=2, " + fromCurrency + " has " + fromFranctionDigits + " defaultFractionDigits");
3.106 + //}
3.107
3.108 if (amount.signum() == -1) {
3.109 throw new RuntimeException("Can convert only non-negative value, current value is " + amount);
3.110 @@ -134,7 +149,7 @@
3.111 to = rate.getToValue();
3.112 }
3.113
3.114 - BigDecimal amountCent = amount.movePointRight(toFractionDigits);
3.115 + BigDecimal amountCent = amount.movePointRight(usedFractionDigits);
3.116
3.117 final BigDecimal multiplied = amountCent.multiply(to, context);
3.118 BigDecimal[] division = multiplied.divideAndRemainder(from, context);
3.119 @@ -142,26 +157,33 @@
3.120 if (!remainderAllowed && !(BigDecimal.ZERO.equals(division[1]))) {
3.121 throw new RuntimeException("Remained is not allowed - remaining amount is " + division[1] + " cents");
3.122 } else {
3.123 - result.setRemainder(BigDecimal.ZERO);
3.124 + result.setRemainder(BigDecimal.ZERO.setScale(fromFranctionDigits));
3.125 }
3.126
3.127 - BigDecimal converted = division[0].movePointLeft(toFractionDigits);
3.128 - converted = converted.setScale(toFractionDigits); //XXX ugly
3.129 + BigDecimal converted = division[0].movePointLeft(usedFractionDigits);
3.130 + converted = converted.setScale(toFractionDigits,RoundingMode.DOWN); //XXX ugly
3.131 result.setConverted(converted);
3.132 - //result.setRemainder(...);
3.133 + BigDecimal[] convertedInBase = converted.multiply(from).divideAndRemainder(to);
3.134 + BigDecimal x2 = convertedInBase[0].add(convertedInBase[1]);
3.135 + BigDecimal remainder = amount.subtract(x2);
3.136 + result.setRemainder(remainder);
3.137 + //System.out.println("ConvertedInBase="+Arrays.asList(convertedInBase)+":"+x2 +" ("+amount+") ["+converted+"] <"+from+","+to+"> ->"+remainder);
3.138 return result;
3.139 }
3.140
3.141
3.142 - private ConversionResult convertValue(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency,BigDecimal amount, boolean convertBack,boolean reversibleExRate) throws RuntimeException {
3.143 + private ConversionResult convertValue(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency,BigDecimal amount, boolean convertBack,boolean reversibleExRate,Date date) throws RuntimeException {
3.144 //result.setRemainder(...);
3.145 + if (!dateIsInLimit(date)) {
3.146 + return null;
3.147 + }
3.148 if (convertors.length==0) {
3.149 - return convertUsingSimpleConvertor(fromCurrency, toCurrency, reversibleExRate, amount, convertBack);
3.150 + return convertUsingSimpleConvertor(fromCurrency, toCurrency, reversibleExRate, amount, convertBack,date);
3.151 } else {
3.152 ConversionResult result = null;
3.153 for (int i = 0;i<convertors.length;i++) {
3.154 Convertor subConvertor = convertors[i];
3.155 - result = subConvertor.convertValue(fromCurrency, toCurrency, amount, convertBack, reversibleExRate);
3.156 + result = subConvertor.convertValue(fromCurrency, toCurrency, amount, convertBack, reversibleExRate,date);
3.157 if (result!=null) {
3.158 break;
3.159 }
3.160 @@ -175,6 +197,8 @@
3.161 * <p>
3.162 * Exchange rate is provided by exchange rate provider which was specified when Convertor was created.
3.163 * This method is using only exchange rate from->to and not trying to use reverted excange rate to->from.
3.164 + * <p>
3.165 + * This method is using date from <code>IDateProviderEngine</code> to get exchange rate (see {@link #getDateProvider() }.
3.166 *
3.167 * @param fromCurrency Source currency to convert from.
3.168 * @param toCurrency Target currency to convert to.
3.169 @@ -184,19 +208,40 @@
3.170 * @throws ConversionNotSupportedException If conversion from <code>fromCurrency</code> to <code>toCurrency</code> is not supported.
3.171 */
3.172 public ConversionResult convert(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency, BigDecimal value) {
3.173 - ConversionResult result = convertValue(fromCurrency, toCurrency, value, false,false);
3.174 + Date defaultDate = dateProvider.getCurrentDate();
3.175 + ConversionResult result = convertValue(fromCurrency, toCurrency, value, false,false,defaultDate);
3.176 if (result==null) {
3.177 //throw new ConversionNotSupportedException("Conversion from " + fromCurrency + " to " + toCurrency + " is not supported");
3.178 throw new ConversionNotSupportedException(fromCurrency.getCurrencyCode(),toCurrency.getCurrencyCode(),false);
3.179 }
3.180 return result;
3.181 }
3.182 + /**
3.183 + * Same as {@link #convert(ConvertorCurrency, ConvertorCurrency, java.math.BigDecimal)} but using provided rate instead of
3.184 + * <code>IDateProviderEngine</code>.
3.185 + *
3.186 + * @param fromCurrency Source currency to convert from.
3.187 + * @param toCurrency Target currency to convert to.
3.188 + * @param value Value in source currency which should be converted.
3.189 + * @return Return conversion result.
3.190 + * @param date Conversion date
3.191 + * @return Return conversion result.
3.192 + */
3.193 + public ConversionResult convert(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency, BigDecimal value, Date date) {
3.194 + ConversionResult result = convertValue(fromCurrency, toCurrency, value, false,false,date);
3.195 + if (result==null) {
3.196 + throw new ConversionNotSupportedException(fromCurrency.getCurrencyCode(),toCurrency.getCurrencyCode(),false);
3.197 + }
3.198 + return result;
3.199 + }
3.200
3.201 /**
3.202 * Convert <code>value</code> from <code>fromCurrency</code> to <code>toCurrency</code>.
3.203 * Exchange rate is provided by exchange rate provider which was specified when Convertor was created.
3.204 * <p>
3.205 * This method is using only exchange rate from->to and if not found, it is trying to use reverted excange rate to->from.
3.206 + * <p>
3.207 + * This method is using date from <code>IDateProviderEngine</code> to get exchange rate (see {@link #getDateProvider() }.
3.208 *
3.209 * @param fromCurrency Source currency to convert from.
3.210 * @param toCurrency Target currency to convert to.
3.211 @@ -207,7 +252,8 @@
3.212 * is not supported and neither conversion from <code>toCurrency</code> to <code>fromCurrency</code> is not supported.
3.213 */
3.214 public ConversionResult convertWithReversibleRates(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency, BigDecimal value) {
3.215 - ConversionResult result = convertValue(fromCurrency, toCurrency, value, false,true);
3.216 + Date defaultDate = dateProvider.getCurrentDate();
3.217 + ConversionResult result = convertValue(fromCurrency, toCurrency, value, false,true,defaultDate);
3.218 if (result==null) {
3.219 //throw new ConversionNotSupportedException("Neither onversion nor reverted conversion from " + fromCurrency + " to " + toCurrency + " is not supported,");
3.220 throw new ConversionNotSupportedException(fromCurrency.getCurrencyCode(),toCurrency.getCurrencyCode(),true);
3.221 @@ -215,4 +261,75 @@
3.222 return result;
3.223 }
3.224
3.225 + /**
3.226 + * Same as {@link #convertWithReversibleRates(ConvertorCurrency, ConvertorCurrency, java.math.BigDecimal)} but using provided rate instead of
3.227 + * <code>IDateProviderEngine</code>.
3.228 + *
3.229 + * @param fromCurrency Source currency to convert from.
3.230 + * @param toCurrency Target currency to convert to.
3.231 + * @param value Value in source currency which should be converted.
3.232 + * @return Return conversion result.
3.233 + * @param date Conversion date
3.234 + * @return Return conversion result.
3.235 + */
3.236 + public ConversionResult convertWithReversibleRates(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency, BigDecimal value, Date date) {
3.237 + ConversionResult result = convertValue(fromCurrency, toCurrency, value, false,true,date);
3.238 + if (result==null) {
3.239 + throw new ConversionNotSupportedException(fromCurrency.getCurrencyCode(),toCurrency.getCurrencyCode(),true);
3.240 + }
3.241 + return result;
3.242 + }
3.243 +
3.244 + private boolean dateIsInLimit(Date date) {
3.245 + boolean result;
3.246 +// if (date==null) {
3.247 +// result = true;
3.248 +// } else
3.249 + if (fromDate == null && toDate == null) {
3.250 + result = true;
3.251 + } else if (fromDate.getTime()<=date.getTime() && date.getTime()<=toDate.getTime()) {
3.252 + result = true;
3.253 + } else {
3.254 + result = false;
3.255 + }
3.256 +
3.257 + return result;
3.258 + }
3.259 +
3.260 +
3.261 + public void limitAllowedDates(Date from, Date till) {
3.262 + if (from==null) {
3.263 + throw new NullPointerException("from Date can't be null");
3.264 + }
3.265 + if (till==null) {
3.266 + throw new NullPointerException("till Date can't be null");
3.267 + }
3.268 + if (from.getTime()>till.getTime()) {
3.269 + throw new IllegalArgumentException("From date "+from+" must be before tii date "+till);
3.270 + }
3.271 + this.fromDate = from;
3.272 + this.toDate = till;
3.273 + }
3.274 +
3.275 +
3.276 + /** Return current date provider.
3.277 + * @return Returns current date provider.
3.278 + */
3.279 + public IDateProviderEngine getDateProvider() {
3.280 + return dateProvider;
3.281 + }
3.282 +
3.283 +
3.284 + /**
3.285 + * Set date provider. Date provider is used to get "current date". Current date
3.286 + * is used by methods {@link #convert(ConvertorCurrency, ConvertorCurrency, java.math.BigDecimal)} and
3.287 + * {@link #convertWithReversibleRates(ConvertorCurrency, ConvertorCurrency, java.math.BigDecimal)}.
3.288 + *
3.289 + * @param dateProvider Date provider which should be used by Convertor.
3.290 + */
3.291 + public void setDateProvider(IDateProviderEngine dateProvider) {
3.292 + this.dateProvider = dateProvider;
3.293 + }
3.294 +
3.295 +
3.296 }
4.1 --- a/task4/solution13/src/org/apidesign/apifest08/currency/ConvertorCurrency.java Sat Oct 11 23:46:05 2008 +0200
4.2 +++ b/task4/solution13/src/org/apidesign/apifest08/currency/ConvertorCurrency.java Fri Oct 17 17:31:48 2008 +0200
4.3 @@ -12,22 +12,38 @@
4.4 * @author arnostvalicek
4.5 */
4.6 public class ConvertorCurrency {
4.7 + private String currencyCode;
4.8 + private int fractionDigits;
4.9
4.10 - private Currency currency;
4.11 -
4.12 - private void setJavaCurrency(Currency javaCurrency) {
4.13 - this.currency = javaCurrency;
4.14 - }
4.15
4.16 /**
4.17 - * Static method providing instance of <code>ConvertorCurrency</code> base of currency code.
4.18 + * Static method providing instance of <code>ConvertorCurrency</code> based on currency code.
4.19 + * <p>
4.20 + * <code>currencyCode</code> is one of codes supported by Java class {@link java.util.Currency}.
4.21 *
4.22 * @param currencyCode Code of required currency.
4.23 * @return Returns required <code>ConvertorCurrency</code>
4.24 */
4.25 public static ConvertorCurrency getInstance(String currencyCode) {
4.26 ConvertorCurrency convertorCurrency = new ConvertorCurrency();
4.27 - convertorCurrency.setJavaCurrency(Currency.getInstance(currencyCode));
4.28 + Currency currency = Currency.getInstance(currencyCode);
4.29 + convertorCurrency.setCurrencyCode(currency.getCurrencyCode());
4.30 + convertorCurrency.setDefaultFractionDigits(currency.getDefaultFractionDigits());
4.31 + return convertorCurrency;
4.32 + }
4.33 +
4.34 + /**
4.35 + * Static method providing instance of <code>ConvertorCurrency</code> base of currency code.
4.36 + *
4.37 + * @param currencyCode Code of required currency.
4.38 + * @param fractionDigits Number of fraction digits for currency.
4.39 + * @return Returns required <code>ConvertorCurrency</code>
4.40 + * @since version4
4.41 + */
4.42 + public static ConvertorCurrency getInstance(String currencyCode, int fractionDigits) {
4.43 + ConvertorCurrency convertorCurrency = new ConvertorCurrency();
4.44 + convertorCurrency.setCurrencyCode(currencyCode);
4.45 + convertorCurrency.setDefaultFractionDigits(fractionDigits);
4.46 return convertorCurrency;
4.47 }
4.48
4.49 @@ -36,7 +52,23 @@
4.50 * @return Returns the default number of fraction digits used with this currency.
4.51 */
4.52 public int getDefaultFractionDigits() {
4.53 - return currency.getDefaultFractionDigits();
4.54 + return fractionDigits;
4.55 + }
4.56 +
4.57 + private void setDefaultFractionDigits(int value) {
4.58 + this.fractionDigits = value;
4.59 + }
4.60 +
4.61 + /**
4.62 + * Get currency code.
4.63 + * @return Returns currency code.
4.64 + */
4.65 + public String getCurrencyCode() {
4.66 + return currencyCode;
4.67 + }
4.68 +
4.69 + private void setCurrencyCode(String value) {
4.70 + currencyCode = value;
4.71 }
4.72
4.73 @Override
4.74 @@ -44,7 +76,7 @@
4.75 boolean result;
4.76 if (obj instanceof ConvertorCurrency) {
4.77 ConvertorCurrency that = (ConvertorCurrency) obj;
4.78 - result = currency.equals(that.currency);
4.79 + result = getCurrencyCode().equals(that.getCurrencyCode()) && getDefaultFractionDigits()==that.getDefaultFractionDigits();
4.80 } else {
4.81 result = false;
4.82 }
4.83 @@ -53,18 +85,13 @@
4.84
4.85 @Override
4.86 public int hashCode() {
4.87 - return currency==null ? 47/*??*/ : currency.hashCode();
4.88 + return currencyCode==null ? 47/*??*/ : currencyCode.hashCode();
4.89 }
4.90 -
4.91 -
4.92 -
4.93 +
4.94
4.95 @Override
4.96 public String toString() {
4.97 - return "ConvertorCurrency[" + (currency != null ? currency.toString() : "NO-BASE-CURRENCY")+"]";
4.98 + return "ConvertorCurrency[" + (currencyCode != null ? currencyCode : "NO-BASE-CURRENCY")+"]";
4.99 }
4.100 -
4.101 - String getCurrencyCode() {
4.102 - return currency.getCurrencyCode();
4.103 - }
4.104 -}
4.105 +
4.106 +}
4.107 \ No newline at end of file
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/task4/solution13/src/org/apidesign/apifest08/currency/DateProvider.java Fri Oct 17 17:31:48 2008 +0200
5.3 @@ -0,0 +1,36 @@
5.4 +package org.apidesign.apifest08.currency;
5.5 +
5.6 +import java.util.Date;
5.7 +
5.8 +/**
5.9 + * Provider for current date.
5.10 + *
5.11 + * @author arnostvalicek
5.12 + * @since version4.
5.13 + */
5.14 +public class DateProvider {
5.15 + private DateProvider() {
5.16 +
5.17 + }
5.18 +
5.19 + /**
5.20 + * Create date provider based on current system time.
5.21 + * @see java.lang.System#currentTimeMillis()
5.22 + */
5.23 + public static IDateProviderEngine createCurrentDateProvider() {
5.24 + return new CurrentDateProvider();
5.25 + }
5.26 +
5.27 + /**
5.28 + * Date provider based on current system time.
5.29 + * @see java.lang.System#currentTimeMillis()
5.30 + */
5.31 + private static class CurrentDateProvider implements IDateProviderEngine {
5.32 +
5.33 + public Date getCurrentDate() {
5.34 + return new Date();
5.35 + }
5.36 +
5.37 + }
5.38 +
5.39 +}
6.1 --- a/task4/solution13/src/org/apidesign/apifest08/currency/ExchangeRateProvider.java Sat Oct 11 23:46:05 2008 +0200
6.2 +++ b/task4/solution13/src/org/apidesign/apifest08/currency/ExchangeRateProvider.java Fri Oct 17 17:31:48 2008 +0200
6.3 @@ -12,6 +12,7 @@
6.4 * <ul>
6.5 * <li>{@link #createExchangeRateProvider() } - create <em>simple</em> exchange rate provider using fixed echange rate.
6.6 * <li>{@link #createExchangeRateProvider(IExchangeRateEngine) } - create exchange rate provider using custom {@link IExchangeRateEngine}.
6.7 + * <li>{@link #createDateExchangeRateProvider(IDateExchangeRateEngine) } - create exchange rate provider using custom {@link IDateExchangeRateEngine}.
6.8 * </ul>
6.9 * <p>
6.10 * Date dependend exchange rate to be implemented.
6.11 @@ -21,6 +22,7 @@
6.12 public class ExchangeRateProvider {
6.13
6.14 IExchangeRateEngine exrateEngine;
6.15 + IDateExchangeRateEngine dateExrateEngine;
6.16
6.17 /**
6.18 * Simple constructor for <code>ExchangeRateProviderM</code> which can provide fixed exchange rate.
6.19 @@ -62,6 +64,18 @@
6.20 provider.exrateEngine = exchangeRateEngine;
6.21 return provider;
6.22 }
6.23 +
6.24 + /**
6.25 + * Static method to create exchange rate provider which is using provided <code>IExIDateExchangeRateEnginechangeRateEngine</code>. This exchange rate provider is using
6.26 + * <code>IExchangeRateEngine</code> to get actual exchange rate.
6.27 + * @param exchangeRateEngine <code>IDateExchangeRateEngine</code> used to get exchange rate.
6.28 + * @return Returns instance of <code>ExchangeRateProvider</code>
6.29 + */
6.30 + public static ExchangeRateProvider createDateExchangeRateProvider(IDateExchangeRateEngine exchangeRateEngine) {
6.31 + ExchangeRateProvider provider = new ExchangeRateProvider();
6.32 + provider.dateExrateEngine = exchangeRateEngine;
6.33 + return provider;
6.34 + }
6.35
6.36 /**
6.37 * Add new exchange rate to <code></code> to this <em>simple</em> exchange rate provider.
6.38 @@ -103,25 +117,44 @@
6.39
6.40 /**
6.41 * Get fixed exange rate for currencies (from->to).
6.42 + * @param fromCurrency Source currency.
6.43 + * @param toCurrency Target currency.
6.44 * @return Returns exchange rate or <code>null</code> if exchange rate not found.
6.45 */
6.46 public ExchangeRate getExchangeRate(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency) {
6.47 - return getExchangeRateImpl(fromCurrency, toCurrency);
6.48 + return getExchangeRateImpl(fromCurrency, toCurrency,null);
6.49 + }
6.50 +
6.51 + /**
6.52 + * Get exange rate for currencies (from->to) for date.
6.53 + * @param fromCurrency Source currency.
6.54 + * @param toCurrency Target currency.
6.55 + * @param date Conversion date.
6.56 + * @return Returns exchange rate or <code>null</code> if exchange rate not found.
6.57 + */
6.58 + public ExchangeRate getExchangeRate(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency, Date date) {
6.59 + return getExchangeRateImpl(fromCurrency, toCurrency,date);
6.60 }
6.61
6.62 /**
6.63 * Get fixed exange rate for currencies (from->to) or reversed exchange rate (to->from).
6.64 + * @param fromCurrency Source currency.
6.65 + * @param toCurrency Target currency.
6.66 * @return Returns exchange rate or <code>null</code> if exchange rate not found.
6.67 */
6.68 public ExchangeRate getReversibleExchangeRate(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency) {
6.69 - ExchangeRate rate = getExchangeRateImpl(fromCurrency, toCurrency);
6.70 - if (rate == null) {
6.71 - ExchangeRate revertedRate = getExchangeRateImpl(toCurrency, fromCurrency);
6.72 - if (revertedRate != null) {
6.73 - rate = ExchangeRate.createRevertedRate(revertedRate);
6.74 - }
6.75 - }
6.76 - return rate;
6.77 + return getReversibleExrateImpl(fromCurrency, toCurrency,null);
6.78 + }
6.79 +
6.80 + /**
6.81 + * Get exange rate for currencies (from->to) or reversed exchange rate (to->from) for date.
6.82 + * @param fromCurrency Source currency.
6.83 + * @param toCurrency Target currency.
6.84 + * @param date Conversion date.
6.85 + * @return Returns exchange rate or <code>null</code> if exchange rate not found.
6.86 + */
6.87 + public ExchangeRate getReversibleExchangeRate(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency, Date date) {
6.88 + return getReversibleExrateImpl(fromCurrency, toCurrency, date);
6.89 }
6.90
6.91 /**
6.92 @@ -157,9 +190,28 @@
6.93 throw new IllegalStateException("Method supported only for FixedOneExchangeRateEngine. This method is deprecated");
6.94 }
6.95 }
6.96 +
6.97
6.98 - private ExchangeRate getExchangeRateImpl(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency) {
6.99 - ExchangeRate result = exrateEngine.getExchangeRate(fromCurrency, toCurrency);
6.100 + private ExchangeRate getReversibleExrateImpl(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency,Date date) {
6.101 + ExchangeRate rate = getExchangeRateImpl(fromCurrency, toCurrency, date);
6.102 + if (rate == null) {
6.103 + ExchangeRate revertedRate = getExchangeRateImpl(toCurrency, fromCurrency, date);
6.104 + if (revertedRate != null) {
6.105 + rate = ExchangeRate.createRevertedRate(revertedRate);
6.106 + }
6.107 + }
6.108 + return rate;
6.109 + }
6.110 +
6.111 + private ExchangeRate getExchangeRateImpl(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency,Date date) {
6.112 + ExchangeRate result;
6.113 + if (exrateEngine!=null) {
6.114 + result = exrateEngine.getExchangeRate(fromCurrency, toCurrency);
6.115 + } else if (dateExrateEngine!=null) {
6.116 + result = dateExrateEngine.getExchangeRate(fromCurrency, toCurrency, date);
6.117 + } else {
6.118 + throw new IllegalStateException("No exchange rate engine provided");
6.119 + }
6.120 return result;
6.121 }
6.122
6.123 @@ -224,7 +276,7 @@
6.124 */
6.125 private static class FixedExchangeRateEngine implements IExchangeRateEngine {
6.126
6.127 - private Map exchangeRateMap = new HashMap();
6.128 + private Map<ConvertorCurrency, Map<ConvertorCurrency, ExchangeRate>> exchangeRateMap = new HashMap<ConvertorCurrency, Map<ConvertorCurrency, ExchangeRate>>();
6.129
6.130 private FixedExchangeRateEngine() {
6.131 }
6.132 @@ -238,15 +290,14 @@
6.133 }
6.134
6.135 public ExchangeRate getExchangeRate(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency) {
6.136 - Map map2 = (Map) exchangeRateMap.get(fromCurrency);
6.137 + Map<ConvertorCurrency,ExchangeRate> map2 = exchangeRateMap.get(fromCurrency);
6.138 if (map2 == null) {
6.139 return null;
6.140 }
6.141 - ExchangeRate result = (ExchangeRate) map2.get(toCurrency);
6.142 + ExchangeRate result = map2.get(toCurrency);
6.143 return result;
6.144 }
6.145
6.146 - @SuppressWarnings("unchecked")
6.147 public synchronized void addFixedCurencyRate(ConvertorCurrency fromCurrency, BigDecimal fromValue, ConvertorCurrency toCurrency, BigDecimal toValue) {
6.148 if (fromValue == null) {
6.149 throw new NullPointerException("fromValue can't be null");
6.150 @@ -254,9 +305,9 @@
6.151 if (toValue == null) {
6.152 throw new NullPointerException("toValue can't be null");
6.153 }
6.154 - Map map2 = (Map) exchangeRateMap.get(fromCurrency);
6.155 + Map<ConvertorCurrency,ExchangeRate> map2 = exchangeRateMap.get(fromCurrency);
6.156 if (map2 == null) {
6.157 - map2 = new HashMap();
6.158 + map2 = new HashMap<ConvertorCurrency,ExchangeRate>();
6.159 exchangeRateMap.put(fromCurrency, map2);
6.160 }
6.161
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/task4/solution13/src/org/apidesign/apifest08/currency/IDateExchangeRateEngine.java Fri Oct 17 17:31:48 2008 +0200
7.3 @@ -0,0 +1,21 @@
7.4 +package org.apidesign.apifest08.currency;
7.5 +
7.6 +import java.util.Date;
7.7 +
7.8 +/**
7.9 + * Interface for exchange rate engine using dates.
7.10 + *
7.11 + * @author arnostvalicek
7.12 + */
7.13 +public interface IDateExchangeRateEngine {
7.14 + /**
7.15 + * Get exchange rate for conversion from <code>fromCurrency</code> to <code>toCurrency</code> at <code>date</code>.
7.16 + *
7.17 + * @param fromCurrency From currency.
7.18 + * @param toCurrency To currency.
7.19 + * @param date Conversion date.
7.20 + * @return Returns <code>ExchangeRate</code> if exchange rate is known or <code>null</code> if exchanger rate is not known.
7.21 + */
7.22 + public ExchangeRate getExchangeRate(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency, Date date);
7.23 +
7.24 +}
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
8.2 +++ b/task4/solution13/src/org/apidesign/apifest08/currency/IDateProviderEngine.java Fri Oct 17 17:31:48 2008 +0200
8.3 @@ -0,0 +1,19 @@
8.4 +package org.apidesign.apifest08.currency;
8.5 +
8.6 +import java.util.Date;
8.7 +
8.8 +/**
8.9 + * Date provider - provides current date.
8.10 + * @see DateProvider#createCurrentDateProvider()
8.11 + * @see Convertor#setDateProvider(IDateProviderEngine)
8.12 + * @author arnostvalicek
8.13 + * @since version4
8.14 + */
8.15 +public interface IDateProviderEngine {
8.16 + /**
8.17 + * Get current date.
8.18 + * @return Return current date.
8.19 + */
8.20 + public Date getCurrentDate();
8.21 +
8.22 +}
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
9.2 +++ b/task4/solution13/test/org/apidesign/apifest08/test/ConvertorWithDateExchangeRateTest.java Fri Oct 17 17:31:48 2008 +0200
9.3 @@ -0,0 +1,109 @@
9.4 +/*
9.5 + * To change this template, choose Tools | Templates
9.6 + * and open the template in the editor.
9.7 + */
9.8 +package org.apidesign.apifest08.test;
9.9 +
9.10 +import java.math.BigDecimal;
9.11 +import java.text.ParseException;
9.12 +import java.text.SimpleDateFormat;
9.13 +import java.util.Date;
9.14 +import junit.framework.TestCase;
9.15 +import org.apidesign.apifest08.currency.ConversionResult;
9.16 +import org.apidesign.apifest08.currency.Convertor;
9.17 +import org.apidesign.apifest08.currency.ConvertorCurrency;
9.18 +import org.apidesign.apifest08.currency.ExchangeRate;
9.19 +import org.apidesign.apifest08.currency.ExchangeRateProvider;
9.20 +import org.apidesign.apifest08.currency.IDateExchangeRateEngine;
9.21 +import org.apidesign.apifest08.currency.IDateProviderEngine;
9.22 +
9.23 +/**
9.24 + *
9.25 + * @author arnostvalicek
9.26 + */
9.27 +public class ConvertorWithDateExchangeRateTest extends TestCase {
9.28 +
9.29 + private static ConvertorCurrency CZK = ConvertorCurrency.getInstance("CZK");
9.30 + private static ConvertorCurrency SKK = ConvertorCurrency.getInstance("SKK");
9.31 + private static ConvertorCurrency USD = ConvertorCurrency.getInstance("USD");
9.32 + private SimpleDateFormat df;
9.33 +
9.34 + @Override
9.35 + protected void setUp() throws Exception {
9.36 + super.setUp();
9.37 + df = new SimpleDateFormat("yyyy-MM-dd HH:mm zzzz");
9.38 + }
9.39 +
9.40 + @Override
9.41 + protected void tearDown() throws Exception {
9.42 + super.tearDown();
9.43 + df = null;
9.44 + }
9.45 +
9.46 + private IDateExchangeRateEngine createDateEngine() {
9.47 + IDateExchangeRateEngine engine = new IDateExchangeRateEngine() {
9.48 +
9.49 + public ExchangeRate getExchangeRate(ConvertorCurrency fromCurrency, ConvertorCurrency toCurrency, Date date) {
9.50 + int day = date.getDay();
9.51 + if (day >= 1 && day <= 5) {
9.52 + //weekday
9.53 + return new ExchangeRate(new BigDecimal(1), new BigDecimal(2));
9.54 + } else {
9.55 + //weekend
9.56 + return new ExchangeRate(new BigDecimal(1), new BigDecimal(3));
9.57 + }
9.58 + }
9.59 + };
9.60 + return engine;
9.61 + }
9.62 +
9.63 + private Convertor createConvertor() {
9.64 + ExchangeRateProvider exchangeRateProvider = ExchangeRateProvider.createDateExchangeRateProvider(createDateEngine());
9.65 + Convertor c = Convertor.createConvertor(exchangeRateProvider);
9.66 + return c;
9.67 + }
9.68 +
9.69 + public void testConvertuUsingDifferentRatesForDays() throws ParseException {
9.70 + Convertor c = createConvertor();
9.71 + {
9.72 + Date d1 = df.parse("2008-10-15 9:00 GMT"); //Wednesday
9.73 + ConversionResult resultWeekday = c.convert(CZK, SKK, new BigDecimal("2.3"), d1);
9.74 + assertEquals("Weekday conversion", new BigDecimal("4.60"), resultWeekday.getConverted());
9.75 + }
9.76 + {
9.77 + Date d1 = df.parse("2008-10-18 9:00 GMT"); //Saturday
9.78 + ConversionResult resultWeekday = c.convert(CZK, SKK, new BigDecimal("2.3"), d1);
9.79 + assertEquals("Weekday conversion", new BigDecimal("6.90"), resultWeekday.getConverted());
9.80 + }
9.81 + }
9.82 +
9.83 + public void testConvertUsingDifferenDefaultDay() throws ParseException {
9.84 + class MyDateProvider implements IDateProviderEngine {
9.85 +
9.86 + private Date date;
9.87 +
9.88 + void setDate(Date date) {
9.89 + this.date = date;
9.90 + }
9.91 +
9.92 + public Date getCurrentDate() {
9.93 + return date;
9.94 + }
9.95 + }
9.96 +
9.97 + Convertor c = createConvertor();
9.98 + MyDateProvider dp = new MyDateProvider();
9.99 + c.setDateProvider(dp);
9.100 +
9.101 + {
9.102 + dp.setDate(df.parse("2008-10-15 9:00 GMT")); //Wednesday
9.103 + ConversionResult resultWeekday = c.convert(CZK, SKK, new BigDecimal("2.3"));
9.104 + assertEquals("Weekday conversion", new BigDecimal("4.60"), resultWeekday.getConverted());
9.105 + }
9.106 + {
9.107 + dp.setDate(df.parse("2008-10-18 9:00 GMT")); //Saturday
9.108 + ConversionResult resultWeekday = c.convert(CZK, SKK, new BigDecimal("2.3"));
9.109 + assertEquals("Weekday conversion", new BigDecimal("6.90"), resultWeekday.getConverted());
9.110 + }
9.111 + }
9.112 +}
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
10.2 +++ b/task4/solution13/test/org/apidesign/apifest08/test/RemainderTest.java Fri Oct 17 17:31:48 2008 +0200
10.3 @@ -0,0 +1,80 @@
10.4 +/*
10.5 + * To change this template, choose Tools | Templates
10.6 + * and open the template in the editor.
10.7 + */
10.8 +
10.9 +package org.apidesign.apifest08.test;
10.10 +
10.11 +import java.math.BigDecimal;
10.12 +import java.text.SimpleDateFormat;
10.13 +import junit.framework.TestCase;
10.14 +import org.apidesign.apifest08.currency.ConversionResult;
10.15 +import org.apidesign.apifest08.currency.Convertor;
10.16 +import org.apidesign.apifest08.currency.ConvertorCurrency;
10.17 +import org.apidesign.apifest08.currency.ExchangeRateProvider;
10.18 +
10.19 +/**
10.20 + *
10.21 + * @author arnostvalicek
10.22 + */
10.23 +public class RemainderTest extends TestCase {
10.24 + private static ConvertorCurrency CZK = ConvertorCurrency.getInstance("CZK");
10.25 + private static ConvertorCurrency SKK = ConvertorCurrency.getInstance("SKK");
10.26 + private static ConvertorCurrency USD = ConvertorCurrency.getInstance("USD");
10.27 + private SimpleDateFormat df;
10.28 +
10.29 + @Override
10.30 + protected void setUp() throws Exception {
10.31 + super.setUp();
10.32 + df = new SimpleDateFormat("yyyy-MM-dd HH:mm zzzz");
10.33 +
10.34 + }
10.35 +
10.36 + @Override
10.37 + protected void tearDown() throws Exception {
10.38 + super.tearDown();
10.39 + }
10.40 +
10.41 + public void testRemainder1() {
10.42 + Convertor c = Task2Test.createUsdToSkkConvertor();
10.43 + {
10.44 + final BigDecimal convertedValue = new BigDecimal("12.34");
10.45 + ConversionResult result = c.convertWithReversibleRates(SKK,USD,convertedValue);
10.46 + //System.out.println("Result = "+result);
10.47 + assertEquals("Converted", new BigDecimal("0.61"),result.getConverted());
10.48 + assertEquals("Remainder", new BigDecimal("0.14"),result.getRemainder());
10.49 +
10.50 + ConversionResult resultBack = c.convertWithReversibleRates(USD, SKK, result.getConverted());
10.51 + assertEquals("Conversion back", convertedValue, resultBack.getConverted().add(result.getRemainder()));
10.52 +
10.53 + }
10.54 + {
10.55 + ConversionResult result = c.convertWithReversibleRates(SKK,USD,new BigDecimal("20.00"));
10.56 + //System.out.println("Result = "+result);
10.57 + }
10.58 +
10.59 + {
10.60 + ConversionResult result = c.convertWithReversibleRates(USD,SKK,new BigDecimal("1.00"));
10.61 + //System.out.println("Result = "+result);
10.62 + }
10.63 +
10.64 + }
10.65 +
10.66 + public void testRemainderStripCents() {
10.67 + ConvertorCurrency CZK_cents=ConvertorCurrency.getInstance("CZK", 2);
10.68 + ConvertorCurrency CZK_nocents=ConvertorCurrency.getInstance("CZK", 0);
10.69 +
10.70 +
10.71 + ExchangeRateProvider exchangeRateProvider = ExchangeRateProvider.createExchangeRateProvider();
10.72 + exchangeRateProvider.addFixedCurencyRate(CZK_cents, new BigDecimal(1), CZK_nocents, new BigDecimal(1));
10.73 +
10.74 + Convertor c = Convertor.createConvertor(exchangeRateProvider);
10.75 +
10.76 + ConversionResult result = c.convertWithReversibleRates(CZK_cents, CZK_nocents, new BigDecimal("2.34"));
10.77 + assertEquals("Converted",new BigDecimal("2"),result.getConverted());
10.78 + assertEquals("Remainder",new BigDecimal("0.34"),result.getRemainder());
10.79 + }
10.80 +
10.81 +
10.82 +
10.83 +}
11.1 --- a/task4/solution13/test/org/apidesign/apifest08/test/Task1Test.java Sat Oct 11 23:46:05 2008 +0200
11.2 +++ b/task4/solution13/test/org/apidesign/apifest08/test/Task1Test.java Fri Oct 17 17:31:48 2008 +0200
11.3 @@ -78,35 +78,35 @@
11.4 // convert $1 to CZK using c:
11.5 ConversionResult result = convertCzkUsd.convertBack(new BigDecimal(1));
11.6 assertEquals("Result is 17 CZK", new BigDecimal("17.00"), result.getConverted());
11.7 - assertEquals("No Remainer", BigDecimal.ZERO, result.getRemainder());
11.8 + assertEquals("No Remainer", new BigDecimal("00.00").setScale(2), result.getRemainder());
11.9 }
11.10
11.11 {
11.12 // convert 17CKZ to $ using c:
11.13 ConversionResult result = convertCzkUsd.convert(new BigDecimal(17));
11.14 assertEquals("Result is 1 $", new BigDecimal("1.00"), result.getConverted());
11.15 - assertEquals("No Remainer", BigDecimal.ZERO, result.getRemainder());
11.16 + assertEquals("No Remainer", new BigDecimal("00.00").setScale(2), result.getRemainder());
11.17 }
11.18
11.19 {
11.20 // convert $5 to CZK using c:
11.21 ConversionResult result = convertCzkUsd.convertBack(new BigDecimal(5));
11.22 assertEquals("Result is 85 CZK", new BigDecimal("85.00"), result.getConverted());
11.23 - assertEquals("No Remainer", BigDecimal.ZERO, result.getRemainder());
11.24 + assertEquals("No Remainer", BigDecimal.ZERO.setScale(2), result.getRemainder());
11.25 }
11.26
11.27 {
11.28 // convert $8 to CZK
11.29 ConversionResult result = convertCzkUsd.convertBack(new BigDecimal(8));
11.30 assertEquals("Result is 136 CZK", new BigDecimal("136.00"), result.getConverted());
11.31 - assertEquals("No Remainer", BigDecimal.ZERO, result.getRemainder());
11.32 + assertEquals("No Remainer", BigDecimal.ZERO.setScale(2), result.getRemainder());
11.33 }
11.34
11.35 {
11.36 // convert 1003CZK to USD
11.37 ConversionResult result = convertCzkUsd.convert(new BigDecimal(1003));
11.38 assertEquals("Result is 59 USD", new BigDecimal("59.00"), result.getConverted());
11.39 - assertEquals("No Remainer", BigDecimal.ZERO, result.getRemainder());
11.40 + assertEquals("No Remainer", BigDecimal.ZERO.setScale(2), result.getRemainder());
11.41 }
11.42 }
11.43
11.44 @@ -136,14 +136,14 @@
11.45 // convert 500SKK to CZK
11.46 ConversionResult result = convertSkkCzk.convert(new BigDecimal(500));
11.47 assertEquals("Result is 400 CZK", new BigDecimal("400.00"), result.getConverted());
11.48 - assertEquals("No Remainer", BigDecimal.ZERO, result.getRemainder());
11.49 + assertEquals("No Remainer", BigDecimal.ZERO.setScale(2), result.getRemainder());
11.50 }
11.51
11.52 {
11.53 // convert 501SKK to CZK
11.54 ConversionResult result = convertSkkCzk.convert(new BigDecimal(501));
11.55 assertEquals("Result is 400 CZK", new BigDecimal("400.80"), result.getConverted());
11.56 - assertEquals("No Remainer", BigDecimal.ZERO, result.getRemainder());
11.57 + assertEquals("No Remainer", BigDecimal.ZERO.setScale(2), result.getRemainder());
11.58
11.59 }
11.60 }
12.1 --- a/task4/solution13/test/org/apidesign/apifest08/test/Task2Test.java Sat Oct 11 23:46:05 2008 +0200
12.2 +++ b/task4/solution13/test/org/apidesign/apifest08/test/Task2Test.java Fri Oct 17 17:31:48 2008 +0200
12.3 @@ -38,7 +38,7 @@
12.4
12.5 public static Convertor createUsdToSkkConvertor() {
12.6 ConvertorCurrency fromCurrency = currencyUSD;
12.7 - ConvertorCurrency toCurrency = currencyUSD;
12.8 + ConvertorCurrency toCurrency = currencySKK;
12.9 ExchangeRateProvider exchangeRateProvider = new ExchangeRateProvider(new BigDecimal(1), fromCurrency, new BigDecimal(20), toCurrency);
12.10
12.11 return Convertor.createConvertor(exchangeRateProvider);
13.1 --- a/task4/solution13/test/org/apidesign/apifest08/test/Task4Test.java Sat Oct 11 23:46:05 2008 +0200
13.2 +++ b/task4/solution13/test/org/apidesign/apifest08/test/Task4Test.java Fri Oct 17 17:31:48 2008 +0200
13.3 @@ -1,8 +1,13 @@
13.4 package org.apidesign.apifest08.test;
13.5
13.6 +import java.math.BigDecimal;
13.7 +import java.text.SimpleDateFormat;
13.8 import java.util.Date;
13.9 import junit.framework.TestCase;
13.10 +import org.apidesign.apifest08.currency.ConversionNotSupportedException;
13.11 import org.apidesign.apifest08.currency.Convertor;
13.12 +import org.apidesign.apifest08.currency.ConvertorCurrency;
13.13 +import org.apidesign.apifest08.currency.ExchangeRateProvider;
13.14
13.15 /** The exchange rates are not always the same. They are changing. However
13.16 * as in order to predict the future, one needs to understand own past. That is
13.17 @@ -18,16 +23,26 @@
13.18 * System.currentTimeMillis() as default date.
13.19 */
13.20 public class Task4Test extends TestCase {
13.21 + private static ConvertorCurrency CZK = ConvertorCurrency.getInstance("CZK");
13.22 + private static ConvertorCurrency SKK = ConvertorCurrency.getInstance("SKK");
13.23 + private static ConvertorCurrency USD = ConvertorCurrency.getInstance("USD");
13.24 + private SimpleDateFormat df;
13.25 +
13.26 +
13.27 public Task4Test(String testName) {
13.28 super(testName);
13.29 }
13.30
13.31 @Override
13.32 protected void setUp() throws Exception {
13.33 + super.setUp();
13.34 + df = new SimpleDateFormat("yyyy-MM-dd HH:mm zzzz");
13.35 }
13.36
13.37 @Override
13.38 protected void tearDown() throws Exception {
13.39 + super.tearDown();
13.40 + df = null;
13.41 }
13.42
13.43 // Backward compatibly enhance your existing API to support following
13.44 @@ -45,19 +60,22 @@
13.45 * @return new convertor
13.46 */
13.47 public static Convertor limitTo(Convertor old, Date from, Date till) {
13.48 - return null;
13.49 + Convertor c = Convertor.createConvertorAsMerge(new Convertor[]{old});
13.50 + c.limitAllowedDates(from, till);
13.51 + return c;
13.52 }
13.53
13.54
13.55 public void testCompositionOfLimitedConvertors() throws Exception {
13.56 - if (Boolean.getBoolean("ignore.failing")) {
13.57 - // implement me! then delete this if statement
13.58 - return;
13.59 - }
13.60 +// if (Boolean.getBoolean("ignore.failing")) {
13.61 +// // implement me! then delete this if statement
13.62 +// return;
13.63 +// }
13.64 +
13.65
13.66 - Date d1 = null; // 2008-10-01 0:00 GMT
13.67 - Date d2 = null; // 2008-10-02 0:00 GMT
13.68 - Date d3 = null; // 2008-10-03 0:00 GMT
13.69 + Date d1 = df.parse("2008-10-01 0:00 GMT");
13.70 + Date d2 = df.parse("2008-10-02 0:00 GMT");
13.71 + Date d3 = df.parse("2008-10-03 0:00 GMT");
13.72
13.73 Convertor c = Task2Test.merge(
13.74 limitTo(Task1Test.createCZKtoUSD(), d1, d2),
13.75 @@ -66,36 +84,81 @@
13.76
13.77 // convert $5 to CZK using c:
13.78 // cannot convert as no rate is applicable to current date
13.79 + try {
13.80 + c.convert(USD, CZK, new BigDecimal(5));
13.81 + fail();
13.82 + } catch (ConversionNotSupportedException e) {
13.83 + //exception expected
13.84 + }
13.85
13.86 // convert $8 to CZK using c:
13.87 // cannot convert as no rate is applicable to current date
13.88 + try {
13.89 + c.convert(USD, CZK, new BigDecimal(8));
13.90 + fail();
13.91 + } catch (ConversionNotSupportedException e) {
13.92 + //exception expected
13.93 + }
13.94 +
13.95
13.96 // convert 1003CZK to USD using c:
13.97 // cannot convert as no rate is applicable to current date
13.98 + try {
13.99 + c.convert(CZK, USD, new BigDecimal(1003));
13.100 + fail();
13.101 + } catch (ConversionNotSupportedException e) {
13.102 + //exception expected
13.103 + }
13.104
13.105 // convert 16CZK using c:
13.106 // cannot convert as no rate is applicable to current date
13.107 + // ???
13.108 + try {
13.109 + c.convert(CZK, USD, new BigDecimal(16));
13.110 + fail();
13.111 + } catch (ConversionNotSupportedException e) {
13.112 + //exception expected
13.113 + }
13.114
13.115 // convert 500SKK to CZK using c:
13.116 // cannot convert as no rate is applicable to current date
13.117 + try {
13.118 + c.convert(SKK, CZK, new BigDecimal(500));
13.119 + fail();
13.120 + } catch (ConversionNotSupportedException e) {
13.121 + //exception expected
13.122 + }
13.123 +
13.124
13.125 // convert $5 to CZK using c at 2008-10-01 6:00 GMT:
13.126 // assertEquals("Result is 85 CZK");
13.127 + 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());
13.128
13.129 // convert $8 to CZK using c at 2008-10-01 6:00 GMT:
13.130 // assertEquals("Result is 136 CZK");
13.131 + 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());
13.132
13.133 // convert 1003CZK to USD using c at 2008-10-01 6:00 GMT:
13.134 // assertEquals("Result is 59 USD");
13.135 + 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());
13.136
13.137 // convert 16CZK using c at 2008-10-02 9:00 GMT:
13.138 // assertEquals("Result is 20 SKK");
13.139 + 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());
13.140
13.141 // convert 500SKK to CZK using c at 2008-10-02 9:00 GMT:
13.142 // assertEquals("Result is 400 CZK");
13.143 + 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());
13.144
13.145 // convert 500SKK to CZK using c at 2008-10-01 6:00 GMT:
13.146 // cannot convert as no rate is applicable to current date
13.147 + try {
13.148 + c.convertWithReversibleRates(SKK, CZK , new BigDecimal("500"),df.parse("2008-10-01 6:00 GMT")).getConverted();
13.149 + fail();
13.150 + } catch (ConversionNotSupportedException e) {
13.151 + //exception expected
13.152 + }
13.153 +
13.154 }
13.155
13.156 /** Create convertor that understands two currencies, CZK and
13.157 @@ -104,18 +167,17 @@
13.158 * @return prepared convertor ready for converting SKK to CZK and CZK to SKK
13.159 */
13.160 public static Convertor createSKKtoCZK2() {
13.161 - return null;
13.162 + ExchangeRateProvider exchangeRateProvider = ExchangeRateProvider.createExchangeRateProvider();
13.163 + exchangeRateProvider.addFixedCurencyRate(SKK, new BigDecimal("100.00"), CZK, new BigDecimal("90.00"));
13.164 + Convertor c = Convertor.createConvertor(exchangeRateProvider);
13.165 + return c;
13.166 }
13.167
13.168 public void testDateConvetorWithTwoDifferentRates() throws Exception {
13.169 - if (Boolean.getBoolean("ignore.failing")) {
13.170 - // implement me! then delete this if statement
13.171 - return;
13.172 - }
13.173
13.174 - Date d1 = null; // 2008-10-01 0:00 GMT
13.175 - Date d2 = null; // 2008-10-02 0:00 GMT
13.176 - Date d3 = null; // 2008-10-03 0:00 GMT
13.177 + Date d1 = df.parse("2008-10-01 0:00 GMT");
13.178 + Date d2 = df.parse("2008-10-02 0:00 GMT");
13.179 + Date d3 = df.parse("2008-10-03 0:00 GMT");
13.180
13.181 Convertor c = Task2Test.merge(
13.182 limitTo(createSKKtoCZK2(), d1, d2),
13.183 @@ -123,10 +185,10 @@
13.184 );
13.185
13.186 // convert 500SKK to CZK using c at 2008-10-02 9:00 GMT:
13.187 - // assertEquals("Result is 400 CZK");
13.188 + 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());
13.189
13.190 // convert 500SKK to CZK using c at 2008-10-01 6:00 GMT:
13.191 - // assertEquals("Result is 450 CZK");
13.192 + 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());
13.193 }
13.194
13.195 }