1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/task3/solution12/src/org/apidesign/apifest08/currency/Convertor.java Tue Oct 07 11:05:34 2008 +0200
1.3 @@ -0,0 +1,184 @@
1.4 +package org.apidesign.apifest08.currency;
1.5 +
1.6 +import java.util.ArrayList;
1.7 +import java.util.Currency;
1.8 +import java.util.Hashtable;
1.9 +import java.util.List;
1.10 +
1.11 +import org.apidesign.apifest08.currency.exceptions.ConvertorException;
1.12 +import org.apidesign.apifest08.currency.exceptions.InvalidCurrencyException;
1.13 +import org.apidesign.apifest08.currency.exceptions.UnknownConvertorException;
1.14 +
1.15 +/**
1.16 + * This is the skeleton class for your API. You need to make it public, so it is accessible to your client code
1.17 + * (currently in Task1Test.java) file.
1.18 + * <p>
1.19 + * Feel free to create additional classes or rename this one, just keep all the API and its implementation in this
1.20 + * package. Do not spread it outside to other packages.
1.21 + */
1.22 +public class Convertor {
1.23 +
1.24 + private static Hashtable<String, ExchangeRate> exchangeRates;
1.25 +
1.26 + private Hashtable<String, ExchangeRate> convertorInstanceExchangeRates;
1.27 +
1.28 + private Convertor(List<Currency> currencies) throws UnknownConvertorException {
1.29 + convertorInstanceExchangeRates = new Hashtable<String, ExchangeRate>();
1.30 + for (Currency currency1 : currencies) {
1.31 + for (Currency currency2 : currencies) {
1.32 + if(!currency1.getCurrencyCode().equals(currency2.getCurrencyCode())) {
1.33 + String key = currency1.getCurrencyCode() + currency2.getCurrencyCode();
1.34 + ExchangeRate exchangeRate = exchangeRates.get(key);
1.35 + convertorInstanceExchangeRates.put(key, exchangeRate);
1.36 + }
1.37 + }
1.38 + }
1.39 + }
1.40 +
1.41 + /**
1.42 + * Sets convertor rate for selected currencies.
1.43 + * @param currency1
1.44 + * one of the currencies we want to convert to/from
1.45 + * @param currency2
1.46 + * the other currency
1.47 + * @param rate
1.48 + * exchange rate from currency1 to currency2
1.49 + * @param unit
1.50 + * unit of exchangeRate (USD->CZK - unit=1, you exchange one dollar, SKK->CZK unit=100, exchange rate is for
1.51 + * 100SKK)
1.52 + */
1.53 + public static void setConvertorRates(Currency currency1, Currency currency2, double rate, double unit) {
1.54 + if (currency1 == null || currency2 == null) {
1.55 + throw new ConvertorException("None of the currencies should be null!!!");
1.56 + }
1.57 +
1.58 + if (rate <= 0 || unit <= 0) {
1.59 + throw new ConvertorException("Rate(" + rate + ") and unit(" + unit + ") has to be grater then zero!!!");
1.60 + }
1.61 +
1.62 + if (exchangeRates == null) {
1.63 + exchangeRates = new Hashtable<String, ExchangeRate>();
1.64 + }
1.65 +
1.66 + String key12 = currency1.getCurrencyCode() + currency2.getCurrencyCode();
1.67 + String key21 = currency2.getCurrencyCode() + currency1.getCurrencyCode();
1.68 + double recountedRate = (unit / rate) * unit;
1.69 +
1.70 + exchangeRates.put(key12, new ExchangeRate(currency1, currency2, rate, unit));
1.71 + exchangeRates.put(key21, new ExchangeRate(currency2, currency1, recountedRate, unit));
1.72 +
1.73 + }
1.74 +
1.75 + /**
1.76 + * Merge exchange rates of actual convertor with exchange rates from selected
1.77 + * convertor. If there are same currencies in both convertors, these from selected
1.78 + * convertor rewrites these in actual convertor.
1.79 + * @param convertor convertor to merge with actual one
1.80 + * @return convertor with merged exchange rates
1.81 + */
1.82 + public Convertor merge(Convertor convertor) {
1.83 + convertorInstanceExchangeRates.putAll(convertor.getInstanceExchangeRates());
1.84 + return this;
1.85 + }
1.86 +
1.87 + /**
1.88 + * Creates new instance of convertor.
1.89 + * @param currency1
1.90 + * one of the currencies we want to convert to/from
1.91 + * @param currency2
1.92 + * the other currency
1.93 + * @return new instance of convertor
1.94 + * @throws UnknownConvertorException
1.95 + * thrown if convertor for selected currencies has not been defined
1.96 + */
1.97 + public static Convertor getConvertorInstance(Currency... currencies) throws UnknownConvertorException {
1.98 + List<Currency> currencyList = new ArrayList<Currency>();
1.99 +
1.100 + if(currencies.length < 2) {
1.101 + throw new ConvertorException("To get convertor instance, you have to select at least two currencies!!!");
1.102 + }
1.103 +
1.104 + for (Currency currency1 : currencies) {
1.105 + for (Currency currency2 : currencies) {
1.106 + if(currency1 == null || currency2 == null) {
1.107 + throw new ConvertorException("None of the currencies should be null!!!");
1.108 + }
1.109 +
1.110 + if(!currency1.getCurrencyCode().equals(currency2.getCurrencyCode())) {
1.111 + String key12 = currency1.getCurrencyCode() + currency2.getCurrencyCode();
1.112 + String key21 = currency2.getCurrencyCode() + currency1.getCurrencyCode();
1.113 + if (!(exchangeRates.containsKey(key12) && exchangeRates.containsKey(key21))) {
1.114 + throw new UnknownConvertorException("Selected convertor (" + currency1.getCurrencyCode() + "<->"
1.115 + + currency2.getCurrencyCode() + ") has not defined exchange rates!!!");
1.116 + }
1.117 + }
1.118 + }
1.119 +
1.120 + currencyList.add(currency1);
1.121 + }
1.122 +
1.123 + return new Convertor(currencyList);
1.124 + }
1.125 +
1.126 + /**
1.127 + * Converts selected amout of selected currency to other currency of this convertor instance.
1.128 + * @param amount
1.129 + * amount to convert
1.130 + * @param originalCurrency
1.131 + * currency of this amount
1.132 + * @param newCurrency
1.133 + * currency to which we want convert
1.134 + * @return converted amount
1.135 + * @throws InvalidCurrencyException
1.136 + * while one or both currencies doesn't fit for this convertor
1.137 + */
1.138 + public double convert(double amount, Currency originalCurrency, Currency newCurrency) throws InvalidCurrencyException {
1.139 + ExchangeRate actualyUsedExchangeRate = null;
1.140 +
1.141 + if (originalCurrency == null) {
1.142 + throw new ConvertorException("Original currency is null!!!");
1.143 + }
1.144 +
1.145 + if (newCurrency == null) {
1.146 + throw new ConvertorException("Destination currency is null!!!");
1.147 + }
1.148 +
1.149 + actualyUsedExchangeRate = getExchangeRate(originalCurrency, newCurrency);
1.150 +
1.151 + return countResult(actualyUsedExchangeRate, amount);
1.152 + }
1.153 +
1.154 + private double countResult(ExchangeRate actualyUsedExchangeRate, double amount) {
1.155 + return amount * actualyUsedExchangeRate.getRate() / actualyUsedExchangeRate.getUnit();
1.156 + }
1.157 +
1.158 + /**
1.159 + * Decides the direction of conversion and returns instance of actual exchange rate.
1.160 + * @param actualCurrency
1.161 + * actual currency we want to convert
1.162 + * @return actual exchange rate of this convertor for selected currency
1.163 + */
1.164 + private ExchangeRate getExchangeRate(Currency originalCurrency, Currency newCurrency) throws InvalidCurrencyException {
1.165 + ExchangeRate actualyUsedExchangeRate = null;
1.166 +
1.167 + String key = originalCurrency.getCurrencyCode() + newCurrency.getCurrencyCode();
1.168 +
1.169 + if(convertorInstanceExchangeRates.containsKey(key)) {
1.170 + actualyUsedExchangeRate = convertorInstanceExchangeRates.get(key);
1.171 + } else {
1.172 + throw new InvalidCurrencyException("This convertor could not be used for converting selected currencies (" + originalCurrency.getCurrencyCode() + "->"
1.173 + + newCurrency.getCurrencyCode() + ") !!!");
1.174 + }
1.175 +
1.176 + return actualyUsedExchangeRate;
1.177 + }
1.178 +
1.179 + /**
1.180 + * Returns exchange rates for actual instance of convertor.
1.181 + * @return exchange rates for actual instance of convertor
1.182 + */
1.183 + Hashtable<String, ExchangeRate> getInstanceExchangeRates() {
1.184 + return convertorInstanceExchangeRates;
1.185 + }
1.186 +
1.187 +}