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;
+ }
+
+}