1 package org.apidesign.apifest08.currency;
3 import java.util.ArrayList;
4 import java.util.Currency;
5 import java.util.Hashtable;
8 import org.apidesign.apifest08.currency.exceptions.ConvertorException;
9 import org.apidesign.apifest08.currency.exceptions.InvalidCurrencyException;
10 import org.apidesign.apifest08.currency.exceptions.UnknownConvertorException;
13 * This is the skeleton class for your API. You need to make it public, so it is accessible to your client code
14 * (currently in Task1Test.java) file.
16 * Feel free to create additional classes or rename this one, just keep all the API and its implementation in this
17 * package. Do not spread it outside to other packages.
19 public class Convertor {
21 private static Hashtable<String, ExchangeRate> exchangeRates;
23 private Hashtable<String, ExchangeRate> convertorInstanceExchangeRates;
25 private Convertor(List<Currency> currencies) throws UnknownConvertorException {
26 convertorInstanceExchangeRates = new Hashtable<String, ExchangeRate>();
27 for (Currency currency1 : currencies) {
28 for (Currency currency2 : currencies) {
29 if(!currency1.getCurrencyCode().equals(currency2.getCurrencyCode())) {
30 String key = currency1.getCurrencyCode() + currency2.getCurrencyCode();
31 ExchangeRate exchangeRate = exchangeRates.get(key);
32 convertorInstanceExchangeRates.put(key, exchangeRate);
39 * Sets convertor rate for selected currencies.
41 * one of the currencies we want to convert to/from
45 * exchange rate from currency1 to currency2
47 * unit of exchangeRate (USD->CZK - unit=1, you exchange one dollar, SKK->CZK unit=100, exchange rate is for
50 public static void setConvertorRates(Currency currency1, Currency currency2, double rate, double unit) {
51 if (currency1 == null || currency2 == null) {
52 throw new ConvertorException("None of the currencies should be null!!!");
55 if (rate <= 0 || unit <= 0) {
56 throw new ConvertorException("Rate(" + rate + ") and unit(" + unit + ") has to be grater then zero!!!");
59 if (exchangeRates == null) {
60 exchangeRates = new Hashtable<String, ExchangeRate>();
63 String key12 = currency1.getCurrencyCode() + currency2.getCurrencyCode();
64 String key21 = currency2.getCurrencyCode() + currency1.getCurrencyCode();
65 double recountedRate = (unit / rate) * unit;
67 exchangeRates.put(key12, new ExchangeRate(currency1, currency2, rate, unit));
68 exchangeRates.put(key21, new ExchangeRate(currency2, currency1, recountedRate, unit));
73 * Merge exchange rates of actual convertor with exchange rates from selected
74 * convertor. If there are same currencies in both convertors, these from selected
75 * convertor rewrites these in actual convertor.
76 * @param convertor convertor to merge with actual one
77 * @return convertor with merged exchange rates
79 public Convertor merge(Convertor convertor) {
80 convertorInstanceExchangeRates.putAll(convertor.getInstanceExchangeRates());
85 * Creates new instance of convertor.
87 * one of the currencies we want to convert to/from
90 * @return new instance of convertor
91 * @throws UnknownConvertorException
92 * thrown if convertor for selected currencies has not been defined
94 public static Convertor getConvertorInstance(Currency... currencies) throws UnknownConvertorException {
95 List<Currency> currencyList = new ArrayList<Currency>();
97 if(currencies.length < 2) {
98 throw new ConvertorException("To get convertor instance, you have to select at least two currencies!!!");
101 for (Currency currency1 : currencies) {
102 for (Currency currency2 : currencies) {
103 if(currency1 == null || currency2 == null) {
104 throw new ConvertorException("None of the currencies should be null!!!");
107 if(!currency1.getCurrencyCode().equals(currency2.getCurrencyCode())) {
108 String key12 = currency1.getCurrencyCode() + currency2.getCurrencyCode();
109 String key21 = currency2.getCurrencyCode() + currency1.getCurrencyCode();
110 if (!(exchangeRates.containsKey(key12) && exchangeRates.containsKey(key21))) {
111 throw new UnknownConvertorException("Selected convertor (" + currency1.getCurrencyCode() + "<->"
112 + currency2.getCurrencyCode() + ") has not defined exchange rates!!!");
117 currencyList.add(currency1);
120 return new Convertor(currencyList);
124 * Converts selected amout of selected currency to other currency of this convertor instance.
127 * @param originalCurrency
128 * currency of this amount
130 * currency to which we want convert
131 * @return converted amount
132 * @throws InvalidCurrencyException
133 * while one or both currencies doesn't fit for this convertor
135 public double convert(double amount, Currency originalCurrency, Currency newCurrency) throws InvalidCurrencyException {
136 ExchangeRate actualyUsedExchangeRate = null;
138 if (originalCurrency == null) {
139 throw new ConvertorException("Original currency is null!!!");
142 if (newCurrency == null) {
143 throw new ConvertorException("Destination currency is null!!!");
146 actualyUsedExchangeRate = getExchangeRate(originalCurrency, newCurrency);
148 return countResult(actualyUsedExchangeRate, amount);
151 private double countResult(ExchangeRate actualyUsedExchangeRate, double amount) {
152 return amount * actualyUsedExchangeRate.getRate() / actualyUsedExchangeRate.getUnit();
156 * Decides the direction of conversion and returns instance of actual exchange rate.
157 * @param actualCurrency
158 * actual currency we want to convert
159 * @return actual exchange rate of this convertor for selected currency
161 private ExchangeRate getExchangeRate(Currency originalCurrency, Currency newCurrency) throws InvalidCurrencyException {
162 ExchangeRate actualyUsedExchangeRate = null;
164 String key = originalCurrency.getCurrencyCode() + newCurrency.getCurrencyCode();
166 if(convertorInstanceExchangeRates.containsKey(key)) {
167 actualyUsedExchangeRate = convertorInstanceExchangeRates.get(key);
169 throw new InvalidCurrencyException("This convertor could not be used for converting selected currencies (" + originalCurrency.getCurrencyCode() + "->"
170 + newCurrency.getCurrencyCode() + ") !!!");
173 return actualyUsedExchangeRate;
177 * Returns exchange rates for actual instance of convertor.
178 * @return exchange rates for actual instance of convertor
180 Hashtable<String, ExchangeRate> getInstanceExchangeRates() {
181 return convertorInstanceExchangeRates;