japod@6: package org.apidesign.apifest08.currency; japod@6: japod@33: import java.util.ArrayList; japod@6: import java.util.Currency; japod@20: import java.util.Hashtable; japod@33: import java.util.List; japod@20: japod@20: import org.apidesign.apifest08.currency.exceptions.ConvertorException; japod@20: import org.apidesign.apifest08.currency.exceptions.InvalidCurrencyException; japod@20: import org.apidesign.apifest08.currency.exceptions.UnknownConvertorException; japod@6: japod@6: /** japod@6: * This is the skeleton class for your API. You need to make it public, so it is accessible to your client code japod@6: * (currently in Task1Test.java) file. japod@6: *

japod@6: * Feel free to create additional classes or rename this one, just keep all the API and its implementation in this japod@6: * package. Do not spread it outside to other packages. japod@6: */ japod@6: public class Convertor { japod@6: japod@20: private static Hashtable exchangeRates; japod@6: japod@33: private Hashtable convertorInstanceExchangeRates; japod@20: japod@33: private Convertor(List currencies) throws UnknownConvertorException { japod@33: convertorInstanceExchangeRates = new Hashtable(); japod@33: for (Currency currency1 : currencies) { japod@33: for (Currency currency2 : currencies) { japod@33: if(!currency1.getCurrencyCode().equals(currency2.getCurrencyCode())) { japod@33: String key = currency1.getCurrencyCode() + currency2.getCurrencyCode(); japod@33: ExchangeRate exchangeRate = exchangeRates.get(key); japod@33: convertorInstanceExchangeRates.put(key, exchangeRate); japod@33: } japod@33: } japod@33: } japod@20: } japod@20: japod@20: /** japod@20: * Sets convertor rate for selected currencies. japod@20: * @param currency1 japod@20: * one of the currencies we want to convert to/from japod@20: * @param currency2 japod@20: * the other currency japod@20: * @param rate japod@20: * exchange rate from currency1 to currency2 japod@20: * @param unit japod@20: * unit of exchangeRate (USD->CZK - unit=1, you exchange one dollar, SKK->CZK unit=100, exchange rate is for japod@20: * 100SKK) japod@20: */ japod@20: public static void setConvertorRates(Currency currency1, Currency currency2, double rate, double unit) { japod@20: if (currency1 == null || currency2 == null) { japod@20: throw new ConvertorException("None of the currencies should be null!!!"); japod@20: } japod@20: japod@20: if (rate <= 0 || unit <= 0) { japod@20: throw new ConvertorException("Rate(" + rate + ") and unit(" + unit + ") has to be grater then zero!!!"); japod@20: } japod@20: japod@20: if (exchangeRates == null) { japod@20: exchangeRates = new Hashtable(); japod@20: } japod@20: japod@20: String key12 = currency1.getCurrencyCode() + currency2.getCurrencyCode(); japod@20: String key21 = currency2.getCurrencyCode() + currency1.getCurrencyCode(); japod@20: double recountedRate = (unit / rate) * unit; japod@20: japod@20: exchangeRates.put(key12, new ExchangeRate(currency1, currency2, rate, unit)); japod@20: exchangeRates.put(key21, new ExchangeRate(currency2, currency1, recountedRate, unit)); japod@20: japod@6: } japod@33: japod@33: /** japod@33: * Merge exchange rates of actual convertor with exchange rates from selected japod@33: * convertor. If there are same currencies in both convertors, these from selected japod@33: * convertor rewrites these in actual convertor. japod@33: * @param convertor convertor to merge with actual one japod@33: * @return convertor with merged exchange rates japod@33: */ japod@33: public Convertor merge(Convertor convertor) { japod@33: convertorInstanceExchangeRates.putAll(convertor.getInstanceExchangeRates()); japod@33: return this; japod@33: } japod@6: japod@6: /** japod@6: * Creates new instance of convertor. japod@6: * @param currency1 japod@6: * one of the currencies we want to convert to/from japod@6: * @param currency2 japod@6: * the other currency japod@6: * @return new instance of convertor japod@20: * @throws UnknownConvertorException japod@20: * thrown if convertor for selected currencies has not been defined japod@6: */ japod@33: public static Convertor getConvertorInstance(Currency... currencies) throws UnknownConvertorException { japod@33: List currencyList = new ArrayList(); japod@33: japod@33: if(currencies.length < 2) { japod@33: throw new ConvertorException("To get convertor instance, you have to select at least two currencies!!!"); japod@33: } japod@33: japod@33: for (Currency currency1 : currencies) { japod@33: for (Currency currency2 : currencies) { japod@33: if(currency1 == null || currency2 == null) { japod@33: throw new ConvertorException("None of the currencies should be null!!!"); japod@33: } japod@33: japod@33: if(!currency1.getCurrencyCode().equals(currency2.getCurrencyCode())) { japod@33: String key12 = currency1.getCurrencyCode() + currency2.getCurrencyCode(); japod@33: String key21 = currency2.getCurrencyCode() + currency1.getCurrencyCode(); japod@33: if (!(exchangeRates.containsKey(key12) && exchangeRates.containsKey(key21))) { japod@33: throw new UnknownConvertorException("Selected convertor (" + currency1.getCurrencyCode() + "<->" japod@33: + currency2.getCurrencyCode() + ") has not defined exchange rates!!!"); japod@33: } japod@33: } japod@33: } japod@33: japod@33: currencyList.add(currency1); japod@33: } japod@33: japod@33: return new Convertor(currencyList); japod@6: } japod@6: japod@6: /** japod@6: * Converts selected amout of selected currency to other currency of this convertor instance. japod@6: * @param amount japod@6: * amount to convert japod@20: * @param originalCurrency japod@6: * currency of this amount japod@20: * @param newCurrency japod@20: * currency to which we want convert japod@6: * @return converted amount japod@20: * @throws InvalidCurrencyException japod@20: * while one or both currencies doesn't fit for this convertor japod@6: */ japod@20: public double convert(double amount, Currency originalCurrency, Currency newCurrency) throws InvalidCurrencyException { japod@20: ExchangeRate actualyUsedExchangeRate = null; japod@6: japod@20: if (originalCurrency == null) { japod@20: throw new ConvertorException("Original currency is null!!!"); japod@6: } japod@6: japod@20: if (newCurrency == null) { japod@20: throw new ConvertorException("Destination currency is null!!!"); japod@6: } japod@6: japod@20: actualyUsedExchangeRate = getExchangeRate(originalCurrency, newCurrency); japod@20: japod@20: return countResult(actualyUsedExchangeRate, amount); japod@6: } japod@6: japod@20: private double countResult(ExchangeRate actualyUsedExchangeRate, double amount) { japod@20: return amount * actualyUsedExchangeRate.getRate() / actualyUsedExchangeRate.getUnit(); japod@6: } japod@6: japod@6: /** japod@6: * Decides the direction of conversion and returns instance of actual exchange rate. japod@6: * @param actualCurrency japod@6: * actual currency we want to convert japod@6: * @return actual exchange rate of this convertor for selected currency japod@6: */ japod@20: private ExchangeRate getExchangeRate(Currency originalCurrency, Currency newCurrency) throws InvalidCurrencyException { japod@20: ExchangeRate actualyUsedExchangeRate = null; japod@33: japod@33: String key = originalCurrency.getCurrencyCode() + newCurrency.getCurrencyCode(); japod@6: japod@33: if(convertorInstanceExchangeRates.containsKey(key)) { japod@33: actualyUsedExchangeRate = convertorInstanceExchangeRates.get(key); japod@20: } else { japod@33: throw new InvalidCurrencyException("This convertor could not be used for converting selected currencies (" + originalCurrency.getCurrencyCode() + "->" japod@20: + newCurrency.getCurrencyCode() + ") !!!"); japod@6: } japod@6: japod@20: return actualyUsedExchangeRate; japod@6: } japod@33: japod@33: /** japod@33: * Returns exchange rates for actual instance of convertor. japod@33: * @return exchange rates for actual instance of convertor japod@33: */ japod@33: Hashtable getInstanceExchangeRates() { japod@33: return convertorInstanceExchangeRates; japod@6: } japod@33: japod@6: }