1.1 --- a/task4/solution12/src/org/apidesign/apifest08/currency/Convertor.java Sat Oct 11 23:38:46 2008 +0200
1.2 +++ b/task4/solution12/src/org/apidesign/apifest08/currency/Convertor.java Fri Oct 17 17:39:18 2008 +0200
1.3 @@ -1,7 +1,9 @@
1.4 package org.apidesign.apifest08.currency;
1.5
1.6 import java.util.ArrayList;
1.7 +import java.util.Calendar;
1.8 import java.util.Currency;
1.9 +import java.util.Date;
1.10 import java.util.Hashtable;
1.11 import java.util.List;
1.12
1.13 @@ -18,9 +20,9 @@
1.14 */
1.15 public class Convertor {
1.16
1.17 - private static Hashtable<String, ExchangeRate> exchangeRates;
1.18 + private static Hashtable<String, List<ExchangeRate>> exchangeRates;
1.19
1.20 - private List<String> currencyConvertors;
1.21 + private List<ExchangeRateInstance> exchangeRateInstances;
1.22
1.23 /**
1.24 * Constructor. Checks if all selected currencies are not null and has defined exchange rates for both
1.25 @@ -30,7 +32,7 @@
1.26 * pair of currencies
1.27 */
1.28 private Convertor(Currency[] currencies) throws UnknownConvertorException {
1.29 - currencyConvertors = new ArrayList<String>();
1.30 + exchangeRateInstances = new ArrayList<ExchangeRateInstance>();
1.31
1.32 for (Currency currency1 : currencies) {
1.33 for (Currency currency2 : currencies) {
1.34 @@ -43,9 +45,9 @@
1.35 if (!exchangeRates.containsKey(key)) {
1.36 throw new UnknownConvertorException("Selected convertor (" + currency1.getCurrencyCode() + "->"
1.37 + currency2.getCurrencyCode() + ") has not defined exchange rates!!!");
1.38 - }
1.39 + }
1.40
1.41 - currencyConvertors.add(key);
1.42 + exchangeRateInstances.add(new ExchangeRateInstance(key, null, null));
1.43 }
1.44 }
1.45 }
1.46 @@ -73,16 +75,35 @@
1.47 }
1.48
1.49 if (exchangeRates == null) {
1.50 - exchangeRates = new Hashtable<String, ExchangeRate>();
1.51 + exchangeRates = new Hashtable<String, List<ExchangeRate>>();
1.52 }
1.53
1.54 String key12 = currency1.getCurrencyCode() + currency2.getCurrencyCode();
1.55 String key21 = currency2.getCurrencyCode() + currency1.getCurrencyCode();
1.56 double recountedRate = (unit / rate) * unit;
1.57
1.58 - exchangeRates.put(key12, new ExchangeRate(currency1, currency2, rate, unit));
1.59 - exchangeRates.put(key21, new ExchangeRate(currency2, currency1, recountedRate, unit));
1.60 + exchangeRates.put(key12, addNewExchangeRate(key12, currency1, currency2, rate, unit, null, null));
1.61 + exchangeRates.put(key21, addNewExchangeRate(key21, currency2, currency1, recountedRate, unit, null, null));
1.62 + }
1.63 +
1.64 + public static Convertor limitExchangeRatesValidity(Convertor convertor, Date validFrom, Date validTo) {
1.65 + if(convertor == null || validFrom == null || validTo == null) {
1.66 + throw new ConvertorException("None of parameters of method limitExchangeRatesValidity should be null!!!");
1.67 + }
1.68 +
1.69 + List<ExchangeRateInstance> exchangeRateInstances = convertor.getExchangeRateInstances();
1.70 + for (ExchangeRateInstance exchangeRateInstance : exchangeRateInstances) {
1.71 + // get actual convertor rates for actual validity
1.72 + ExchangeRate actualExchangeRate = getExchangeRate(exchangeRateInstance.getKey(), exchangeRateInstance.getValidFrom(), exchangeRateInstance.getValidTo());
1.73 + // set new validity for theese rates
1.74 + actualExchangeRate.setValidFrom(validFrom);
1.75 + actualExchangeRate.setValidTo(validTo);
1.76 + // and for selected currency convertor
1.77 + exchangeRateInstance.setValidFrom(validFrom);
1.78 + exchangeRateInstance.setValidTo(substractSecond(validTo));
1.79 + }
1.80
1.81 + return convertor;
1.82 }
1.83
1.84 /**
1.85 @@ -97,7 +118,7 @@
1.86 throw new ConvertorException("It's impossible to merge with null convertor!!!");
1.87 }
1.88
1.89 - currencyConvertors.addAll(convertor.getCurrencyConvertors());
1.90 + exchangeRateInstances.addAll(convertor.getExchangeRateInstances());
1.91 return this;
1.92 }
1.93
1.94 @@ -152,7 +173,8 @@
1.95 }
1.96
1.97 /**
1.98 - * Decides the direction of conversion and returns instance of actual exchange rate.
1.99 + * Decides the direction of conversion and returns actual exchange rate
1.100 + * for selected currencies and actual moment.
1.101 * @param actualCurrency
1.102 * actual currency we want to convert
1.103 * @return actual exchange rate of this convertor for selected currency
1.104 @@ -162,8 +184,9 @@
1.105
1.106 String key = originalCurrency.getCurrencyCode() + newCurrency.getCurrencyCode();
1.107
1.108 - if(currencyConvertors.contains(key)) {
1.109 - actualyUsedExchangeRate = exchangeRates.get(key);
1.110 + ExchangeRateInstance exchangeRateInstance = findExchangeRateInstance(key);
1.111 + if(exchangeRateInstance != null) {
1.112 + actualyUsedExchangeRate = getExchangeRate(exchangeRateInstance.getKey(), exchangeRateInstance.getValidFrom(), exchangeRateInstance.getValidTo());
1.113 } else {
1.114 throw new InvalidCurrencyException("This convertor could not be used for converting selected currencies (" + originalCurrency.getCurrencyCode() + "->"
1.115 + newCurrency.getCurrencyCode() + ") !!!");
1.116 @@ -173,11 +196,102 @@
1.117 }
1.118
1.119 /**
1.120 + * Finds instance of exchange rate for actual instance of convertor and actual moment.
1.121 + * @param key exchange rate instance key
1.122 + * @return exchange rate instance
1.123 + */
1.124 + private ExchangeRateInstance findExchangeRateInstance(String key) {
1.125 + ExchangeRateInstance instance = null;
1.126 +
1.127 + Date now = new Date();
1.128 + for (ExchangeRateInstance item : exchangeRateInstances) {
1.129 + if(item.getKey().equals(key) && item.getValidFrom() == null && item.getValidTo() == null) {
1.130 + instance = item;
1.131 + break;
1.132 + } else if(item.getKey().equals(key) && item.getValidFrom().compareTo(now) <= 0 && item.getValidTo().compareTo(now) >= 0) {
1.133 + instance = item;
1.134 + break;
1.135 + }
1.136 + }
1.137 +
1.138 + return instance;
1.139 + }
1.140 +
1.141 +
1.142 + /**
1.143 * Returns currency convertors for actual instance of convertor.
1.144 * @return currency convertors for actual instance of convertor
1.145 */
1.146 - List<String> getCurrencyConvertors() {
1.147 - return currencyConvertors;
1.148 + private List<ExchangeRateInstance> getExchangeRateInstances() {
1.149 + return exchangeRateInstances;
1.150 + }
1.151 +
1.152 + private static ExchangeRate getExchangeRate(String key, Date validFrom, Date validTo) {
1.153 + ExchangeRate exchangeRate = null;
1.154 +
1.155 + List<ExchangeRate> currencyExchangeRates = exchangeRates.get(key);
1.156 + for (ExchangeRate currencyExchangeRate : currencyExchangeRates) {
1.157 + Date actValidFrom = currencyExchangeRate.getValidFrom();
1.158 + Date actValidTo = currencyExchangeRate.getValidTo();
1.159 +
1.160 + if(actValidFrom == null && validFrom == null && actValidTo == null && validTo == null) {
1.161 + exchangeRate = currencyExchangeRate;
1.162 + break;
1.163 + } else if(actValidFrom != null && validFrom != null && actValidTo != null && validTo != null && actValidFrom.compareTo(validFrom) <= 0 && actValidTo.compareTo(validTo) > 0) {
1.164 + exchangeRate = currencyExchangeRate;
1.165 + break;
1.166 + }
1.167 + }
1.168 +
1.169 + if(exchangeRate == null) {
1.170 + throw new ConvertorException("Exchange rate for actual exchange rate instance not found!!!");
1.171 + }
1.172 +
1.173 + return exchangeRate;
1.174 + }
1.175 +
1.176 + private static List<ExchangeRate> addNewExchangeRate(String key, Currency currency1, Currency currency2, double rate, double unit, Date validFrom, Date validTo) {
1.177 + List<ExchangeRate> actualExchangeRates = new ArrayList<ExchangeRate>();
1.178 + ExchangeRate newExchangeRate = null;
1.179 +
1.180 + if(exchangeRates.containsKey(key)) {
1.181 + List<ExchangeRate> rates = exchangeRates.get(key);
1.182 + for (ExchangeRate exchangeRate : rates) {
1.183 + if(exchangeRate.getValidFrom() == null && exchangeRate.getValidTo() == null && validFrom == null && validTo == null) {
1.184 + newExchangeRate = exchangeRate;
1.185 + break;
1.186 + } else if(exchangeRate.getValidFrom() != null && exchangeRate.getValidTo() != null && validFrom != null && validTo != null) {
1.187 + if(exchangeRate.getValidFrom().compareTo(validFrom) == 0 && exchangeRate.getValidTo().compareTo(validTo) == 0) {
1.188 + newExchangeRate = exchangeRate;
1.189 + break;
1.190 + }
1.191 + }
1.192 + }
1.193 + actualExchangeRates.addAll(rates);
1.194 + }
1.195 +
1.196 + if(newExchangeRate == null) {
1.197 + actualExchangeRates.add(new ExchangeRate(currency1, currency2, rate, unit, validFrom, validTo));
1.198 + } else {
1.199 + newExchangeRate.setRate(rate);
1.200 + newExchangeRate.setUnit(unit);
1.201 + actualExchangeRates.add(newExchangeRate);
1.202 + }
1.203 +
1.204 + return actualExchangeRates;
1.205 + }
1.206 +
1.207 + /**
1.208 + * Substracts one second from selected date.
1.209 + * @param date date
1.210 + * @return date -1s
1.211 + */
1.212 + private static Date substractSecond(Date date) {
1.213 + Calendar calendar = Calendar.getInstance();
1.214 + calendar.setTime(date);
1.215 + calendar.set(Calendar.SECOND, -1);
1.216 +
1.217 + return calendar.getTime();
1.218 }
1.219
1.220 }