japod@6
|
1 |
package org.apidesign.apifest08.currency;
|
japod@6
|
2 |
|
japod@33
|
3 |
import java.util.ArrayList;
|
japod@6
|
4 |
import java.util.Currency;
|
japod@20
|
5 |
import java.util.Hashtable;
|
japod@33
|
6 |
import java.util.List;
|
japod@20
|
7 |
|
japod@20
|
8 |
import org.apidesign.apifest08.currency.exceptions.ConvertorException;
|
japod@20
|
9 |
import org.apidesign.apifest08.currency.exceptions.InvalidCurrencyException;
|
japod@20
|
10 |
import org.apidesign.apifest08.currency.exceptions.UnknownConvertorException;
|
japod@6
|
11 |
|
japod@6
|
12 |
/**
|
japod@6
|
13 |
* This is the skeleton class for your API. You need to make it public, so it is accessible to your client code
|
japod@6
|
14 |
* (currently in Task1Test.java) file.
|
japod@6
|
15 |
* <p>
|
japod@6
|
16 |
* Feel free to create additional classes or rename this one, just keep all the API and its implementation in this
|
japod@6
|
17 |
* package. Do not spread it outside to other packages.
|
japod@6
|
18 |
*/
|
japod@6
|
19 |
public class Convertor {
|
japod@6
|
20 |
|
japod@20
|
21 |
private static Hashtable<String, ExchangeRate> exchangeRates;
|
japod@6
|
22 |
|
japod@33
|
23 |
private Hashtable<String, ExchangeRate> convertorInstanceExchangeRates;
|
japod@20
|
24 |
|
japod@33
|
25 |
private Convertor(List<Currency> currencies) throws UnknownConvertorException {
|
japod@33
|
26 |
convertorInstanceExchangeRates = new Hashtable<String, ExchangeRate>();
|
japod@33
|
27 |
for (Currency currency1 : currencies) {
|
japod@33
|
28 |
for (Currency currency2 : currencies) {
|
japod@33
|
29 |
if(!currency1.getCurrencyCode().equals(currency2.getCurrencyCode())) {
|
japod@33
|
30 |
String key = currency1.getCurrencyCode() + currency2.getCurrencyCode();
|
japod@33
|
31 |
ExchangeRate exchangeRate = exchangeRates.get(key);
|
japod@33
|
32 |
convertorInstanceExchangeRates.put(key, exchangeRate);
|
japod@33
|
33 |
}
|
japod@33
|
34 |
}
|
japod@33
|
35 |
}
|
japod@20
|
36 |
}
|
japod@20
|
37 |
|
japod@20
|
38 |
/**
|
japod@20
|
39 |
* Sets convertor rate for selected currencies.
|
japod@20
|
40 |
* @param currency1
|
japod@20
|
41 |
* one of the currencies we want to convert to/from
|
japod@20
|
42 |
* @param currency2
|
japod@20
|
43 |
* the other currency
|
japod@20
|
44 |
* @param rate
|
japod@20
|
45 |
* exchange rate from currency1 to currency2
|
japod@20
|
46 |
* @param unit
|
japod@20
|
47 |
* unit of exchangeRate (USD->CZK - unit=1, you exchange one dollar, SKK->CZK unit=100, exchange rate is for
|
japod@20
|
48 |
* 100SKK)
|
japod@20
|
49 |
*/
|
japod@20
|
50 |
public static void setConvertorRates(Currency currency1, Currency currency2, double rate, double unit) {
|
japod@20
|
51 |
if (currency1 == null || currency2 == null) {
|
japod@20
|
52 |
throw new ConvertorException("None of the currencies should be null!!!");
|
japod@20
|
53 |
}
|
japod@20
|
54 |
|
japod@20
|
55 |
if (rate <= 0 || unit <= 0) {
|
japod@20
|
56 |
throw new ConvertorException("Rate(" + rate + ") and unit(" + unit + ") has to be grater then zero!!!");
|
japod@20
|
57 |
}
|
japod@20
|
58 |
|
japod@20
|
59 |
if (exchangeRates == null) {
|
japod@20
|
60 |
exchangeRates = new Hashtable<String, ExchangeRate>();
|
japod@20
|
61 |
}
|
japod@20
|
62 |
|
japod@20
|
63 |
String key12 = currency1.getCurrencyCode() + currency2.getCurrencyCode();
|
japod@20
|
64 |
String key21 = currency2.getCurrencyCode() + currency1.getCurrencyCode();
|
japod@20
|
65 |
double recountedRate = (unit / rate) * unit;
|
japod@20
|
66 |
|
japod@20
|
67 |
exchangeRates.put(key12, new ExchangeRate(currency1, currency2, rate, unit));
|
japod@20
|
68 |
exchangeRates.put(key21, new ExchangeRate(currency2, currency1, recountedRate, unit));
|
japod@20
|
69 |
|
japod@6
|
70 |
}
|
japod@33
|
71 |
|
japod@33
|
72 |
/**
|
japod@33
|
73 |
* Merge exchange rates of actual convertor with exchange rates from selected
|
japod@33
|
74 |
* convertor. If there are same currencies in both convertors, these from selected
|
japod@33
|
75 |
* convertor rewrites these in actual convertor.
|
japod@33
|
76 |
* @param convertor convertor to merge with actual one
|
japod@33
|
77 |
* @return convertor with merged exchange rates
|
japod@33
|
78 |
*/
|
japod@33
|
79 |
public Convertor merge(Convertor convertor) {
|
japod@33
|
80 |
convertorInstanceExchangeRates.putAll(convertor.getInstanceExchangeRates());
|
japod@33
|
81 |
return this;
|
japod@33
|
82 |
}
|
japod@6
|
83 |
|
japod@6
|
84 |
/**
|
japod@6
|
85 |
* Creates new instance of convertor.
|
japod@6
|
86 |
* @param currency1
|
japod@6
|
87 |
* one of the currencies we want to convert to/from
|
japod@6
|
88 |
* @param currency2
|
japod@6
|
89 |
* the other currency
|
japod@6
|
90 |
* @return new instance of convertor
|
japod@20
|
91 |
* @throws UnknownConvertorException
|
japod@20
|
92 |
* thrown if convertor for selected currencies has not been defined
|
japod@6
|
93 |
*/
|
japod@33
|
94 |
public static Convertor getConvertorInstance(Currency... currencies) throws UnknownConvertorException {
|
japod@33
|
95 |
List<Currency> currencyList = new ArrayList<Currency>();
|
japod@33
|
96 |
|
japod@33
|
97 |
if(currencies.length < 2) {
|
japod@33
|
98 |
throw new ConvertorException("To get convertor instance, you have to select at least two currencies!!!");
|
japod@33
|
99 |
}
|
japod@33
|
100 |
|
japod@33
|
101 |
for (Currency currency1 : currencies) {
|
japod@33
|
102 |
for (Currency currency2 : currencies) {
|
japod@33
|
103 |
if(currency1 == null || currency2 == null) {
|
japod@33
|
104 |
throw new ConvertorException("None of the currencies should be null!!!");
|
japod@33
|
105 |
}
|
japod@33
|
106 |
|
japod@33
|
107 |
if(!currency1.getCurrencyCode().equals(currency2.getCurrencyCode())) {
|
japod@33
|
108 |
String key12 = currency1.getCurrencyCode() + currency2.getCurrencyCode();
|
japod@33
|
109 |
String key21 = currency2.getCurrencyCode() + currency1.getCurrencyCode();
|
japod@33
|
110 |
if (!(exchangeRates.containsKey(key12) && exchangeRates.containsKey(key21))) {
|
japod@33
|
111 |
throw new UnknownConvertorException("Selected convertor (" + currency1.getCurrencyCode() + "<->"
|
japod@33
|
112 |
+ currency2.getCurrencyCode() + ") has not defined exchange rates!!!");
|
japod@33
|
113 |
}
|
japod@33
|
114 |
}
|
japod@33
|
115 |
}
|
japod@33
|
116 |
|
japod@33
|
117 |
currencyList.add(currency1);
|
japod@33
|
118 |
}
|
japod@33
|
119 |
|
japod@33
|
120 |
return new Convertor(currencyList);
|
japod@6
|
121 |
}
|
japod@6
|
122 |
|
japod@6
|
123 |
/**
|
japod@6
|
124 |
* Converts selected amout of selected currency to other currency of this convertor instance.
|
japod@6
|
125 |
* @param amount
|
japod@6
|
126 |
* amount to convert
|
japod@20
|
127 |
* @param originalCurrency
|
japod@6
|
128 |
* currency of this amount
|
japod@20
|
129 |
* @param newCurrency
|
japod@20
|
130 |
* currency to which we want convert
|
japod@6
|
131 |
* @return converted amount
|
japod@20
|
132 |
* @throws InvalidCurrencyException
|
japod@20
|
133 |
* while one or both currencies doesn't fit for this convertor
|
japod@6
|
134 |
*/
|
japod@20
|
135 |
public double convert(double amount, Currency originalCurrency, Currency newCurrency) throws InvalidCurrencyException {
|
japod@20
|
136 |
ExchangeRate actualyUsedExchangeRate = null;
|
japod@6
|
137 |
|
japod@20
|
138 |
if (originalCurrency == null) {
|
japod@20
|
139 |
throw new ConvertorException("Original currency is null!!!");
|
japod@6
|
140 |
}
|
japod@6
|
141 |
|
japod@20
|
142 |
if (newCurrency == null) {
|
japod@20
|
143 |
throw new ConvertorException("Destination currency is null!!!");
|
japod@6
|
144 |
}
|
japod@6
|
145 |
|
japod@20
|
146 |
actualyUsedExchangeRate = getExchangeRate(originalCurrency, newCurrency);
|
japod@20
|
147 |
|
japod@20
|
148 |
return countResult(actualyUsedExchangeRate, amount);
|
japod@6
|
149 |
}
|
japod@6
|
150 |
|
japod@20
|
151 |
private double countResult(ExchangeRate actualyUsedExchangeRate, double amount) {
|
japod@20
|
152 |
return amount * actualyUsedExchangeRate.getRate() / actualyUsedExchangeRate.getUnit();
|
japod@6
|
153 |
}
|
japod@6
|
154 |
|
japod@6
|
155 |
/**
|
japod@6
|
156 |
* Decides the direction of conversion and returns instance of actual exchange rate.
|
japod@6
|
157 |
* @param actualCurrency
|
japod@6
|
158 |
* actual currency we want to convert
|
japod@6
|
159 |
* @return actual exchange rate of this convertor for selected currency
|
japod@6
|
160 |
*/
|
japod@20
|
161 |
private ExchangeRate getExchangeRate(Currency originalCurrency, Currency newCurrency) throws InvalidCurrencyException {
|
japod@20
|
162 |
ExchangeRate actualyUsedExchangeRate = null;
|
japod@33
|
163 |
|
japod@33
|
164 |
String key = originalCurrency.getCurrencyCode() + newCurrency.getCurrencyCode();
|
japod@6
|
165 |
|
japod@33
|
166 |
if(convertorInstanceExchangeRates.containsKey(key)) {
|
japod@33
|
167 |
actualyUsedExchangeRate = convertorInstanceExchangeRates.get(key);
|
japod@20
|
168 |
} else {
|
japod@33
|
169 |
throw new InvalidCurrencyException("This convertor could not be used for converting selected currencies (" + originalCurrency.getCurrencyCode() + "->"
|
japod@20
|
170 |
+ newCurrency.getCurrencyCode() + ") !!!");
|
japod@6
|
171 |
}
|
japod@6
|
172 |
|
japod@20
|
173 |
return actualyUsedExchangeRate;
|
japod@6
|
174 |
}
|
japod@33
|
175 |
|
japod@33
|
176 |
/**
|
japod@33
|
177 |
* Returns exchange rates for actual instance of convertor.
|
japod@33
|
178 |
* @return exchange rates for actual instance of convertor
|
japod@33
|
179 |
*/
|
japod@33
|
180 |
Hashtable<String, ExchangeRate> getInstanceExchangeRates() {
|
japod@33
|
181 |
return convertorInstanceExchangeRates;
|
japod@6
|
182 |
}
|
japod@33
|
183 |
|
japod@6
|
184 |
}
|