1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/task4/solution12/src/org/apidesign/apifest08/currency/Convertor.java Sat Oct 11 23:38:46 2008 +0200
1.3 @@ -0,0 +1,183 @@
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 List<String> currencyConvertors;
1.27 +
1.28 + /**
1.29 + * Constructor. Checks if all selected currencies are not null and has defined exchange rates for both
1.30 + * directions.
1.31 + * @param currencies currencies for new instance of convertor
1.32 + * @throws UnknownConvertorException if there are not defined exchange rates for both directions for each
1.33 + * pair of currencies
1.34 + */
1.35 + private Convertor(Currency[] currencies) throws UnknownConvertorException {
1.36 + currencyConvertors = new ArrayList<String>();
1.37 +
1.38 + for (Currency currency1 : currencies) {
1.39 + for (Currency currency2 : currencies) {
1.40 + if(currency1 == null || currency2 == null) {
1.41 + throw new ConvertorException("None of the currencies should be null!!!");
1.42 + }
1.43 +
1.44 + if(!currency1.getCurrencyCode().equals(currency2.getCurrencyCode())) {
1.45 + String key = currency1.getCurrencyCode() + currency2.getCurrencyCode();
1.46 + if (!exchangeRates.containsKey(key)) {
1.47 + throw new UnknownConvertorException("Selected convertor (" + currency1.getCurrencyCode() + "->"
1.48 + + currency2.getCurrencyCode() + ") has not defined exchange rates!!!");
1.49 + }
1.50 +
1.51 + currencyConvertors.add(key);
1.52 + }
1.53 + }
1.54 + }
1.55 + }
1.56 +
1.57 + /**
1.58 + * Sets convertor rate for selected currencies.
1.59 + * @param currency1
1.60 + * one of the currencies we want to convert to/from
1.61 + * @param currency2
1.62 + * the other currency
1.63 + * @param rate
1.64 + * exchange rate from currency1 to currency2
1.65 + * @param unit
1.66 + * unit of exchangeRate (USD->CZK - unit=1, you exchange one dollar, SKK->CZK unit=100, exchange rate is for
1.67 + * 100SKK)
1.68 + */
1.69 + public static void setConvertorRates(Currency currency1, Currency currency2, double rate, double unit) {
1.70 + if (currency1 == null || currency2 == null) {
1.71 + throw new ConvertorException("None of the currencies should be null!!!");
1.72 + }
1.73 +
1.74 + if (rate <= 0 || unit <= 0) {
1.75 + throw new ConvertorException("Rate(" + rate + ") and unit(" + unit + ") has to be grater then zero!!!");
1.76 + }
1.77 +
1.78 + if (exchangeRates == null) {
1.79 + exchangeRates = new Hashtable<String, ExchangeRate>();
1.80 + }
1.81 +
1.82 + String key12 = currency1.getCurrencyCode() + currency2.getCurrencyCode();
1.83 + String key21 = currency2.getCurrencyCode() + currency1.getCurrencyCode();
1.84 + double recountedRate = (unit / rate) * unit;
1.85 +
1.86 + exchangeRates.put(key12, new ExchangeRate(currency1, currency2, rate, unit));
1.87 + exchangeRates.put(key21, new ExchangeRate(currency2, currency1, recountedRate, unit));
1.88 +
1.89 + }
1.90 +
1.91 + /**
1.92 + * Merge exchange rates of actual convertor with exchange rates from selected
1.93 + * convertor. If there are same currencies in both convertors, these from selected
1.94 + * convertor rewrites these in actual convertor.
1.95 + * @param convertor convertor to merge with actual one
1.96 + * @return convertor with merged exchange rates
1.97 + */
1.98 + public Convertor merge(Convertor convertor) {
1.99 + if(convertor == null) {
1.100 + throw new ConvertorException("It's impossible to merge with null convertor!!!");
1.101 + }
1.102 +
1.103 + currencyConvertors.addAll(convertor.getCurrencyConvertors());
1.104 + return this;
1.105 + }
1.106 +
1.107 + /**
1.108 + * Creates new instance of convertor.
1.109 + * @param currency1
1.110 + * one of the currencies we want to convert to/from
1.111 + * @param currency2
1.112 + * the other currency
1.113 + * @return new instance of convertor
1.114 + * @throws UnknownConvertorException
1.115 + * thrown if convertor for selected currencies has not been defined
1.116 + */
1.117 + public static Convertor getConvertorInstance(Currency... currencies) throws UnknownConvertorException {
1.118 + if(currencies.length < 2) {
1.119 + throw new ConvertorException("To get convertor instance, you have to select at least two currencies!!!");
1.120 + }
1.121 +
1.122 + return new Convertor(currencies);
1.123 + }
1.124 +
1.125 + /**
1.126 + * Converts selected amout of selected currency to other currency of this convertor instance.
1.127 + * @param amount
1.128 + * amount to convert
1.129 + * @param originalCurrency
1.130 + * currency of this amount
1.131 + * @param newCurrency
1.132 + * currency to which we want convert
1.133 + * @return converted amount
1.134 + * @throws InvalidCurrencyException
1.135 + * while one or both currencies doesn't fit for this convertor
1.136 + */
1.137 + public double convert(double amount, Currency originalCurrency, Currency newCurrency) throws InvalidCurrencyException {
1.138 + ExchangeRate actualyUsedExchangeRate = null;
1.139 +
1.140 + if (originalCurrency == null) {
1.141 + throw new ConvertorException("Original currency is null!!!");
1.142 + }
1.143 +
1.144 + if (newCurrency == null) {
1.145 + throw new ConvertorException("Destination currency is null!!!");
1.146 + }
1.147 +
1.148 + actualyUsedExchangeRate = getExchangeRate(originalCurrency, newCurrency);
1.149 +
1.150 + return countResult(actualyUsedExchangeRate, amount);
1.151 + }
1.152 +
1.153 + private double countResult(ExchangeRate actualyUsedExchangeRate, double amount) {
1.154 + return amount * actualyUsedExchangeRate.getRate() / actualyUsedExchangeRate.getUnit();
1.155 + }
1.156 +
1.157 + /**
1.158 + * Decides the direction of conversion and returns instance of actual exchange rate.
1.159 + * @param actualCurrency
1.160 + * actual currency we want to convert
1.161 + * @return actual exchange rate of this convertor for selected currency
1.162 + */
1.163 + private ExchangeRate getExchangeRate(Currency originalCurrency, Currency newCurrency) throws InvalidCurrencyException {
1.164 + ExchangeRate actualyUsedExchangeRate = null;
1.165 +
1.166 + String key = originalCurrency.getCurrencyCode() + newCurrency.getCurrencyCode();
1.167 +
1.168 + if(currencyConvertors.contains(key)) {
1.169 + actualyUsedExchangeRate = exchangeRates.get(key);
1.170 + } else {
1.171 + throw new InvalidCurrencyException("This convertor could not be used for converting selected currencies (" + originalCurrency.getCurrencyCode() + "->"
1.172 + + newCurrency.getCurrencyCode() + ") !!!");
1.173 + }
1.174 +
1.175 + return actualyUsedExchangeRate;
1.176 + }
1.177 +
1.178 + /**
1.179 + * Returns currency convertors for actual instance of convertor.
1.180 + * @return currency convertors for actual instance of convertor
1.181 + */
1.182 + List<String> getCurrencyConvertors() {
1.183 + return currencyConvertors;
1.184 + }
1.185 +
1.186 +}