diff -r 221f1930cbfb -r 58ec6da75f6f task4/solution12/src/org/apidesign/apifest08/currency/Convertor.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/task4/solution12/src/org/apidesign/apifest08/currency/Convertor.java Sat Oct 11 23:38:46 2008 +0200 @@ -0,0 +1,183 @@ +package org.apidesign.apifest08.currency; + +import java.util.ArrayList; +import java.util.Currency; +import java.util.Hashtable; +import java.util.List; + +import org.apidesign.apifest08.currency.exceptions.ConvertorException; +import org.apidesign.apifest08.currency.exceptions.InvalidCurrencyException; +import org.apidesign.apifest08.currency.exceptions.UnknownConvertorException; + +/** + * This is the skeleton class for your API. You need to make it public, so it is accessible to your client code + * (currently in Task1Test.java) file. + *

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