1 package org.apidesign.apifest08.currency;
3 import java.util.ArrayList;
4 import java.util.Collection;
5 import java.util.Collections;
6 import java.util.HashSet;
10 /** This is the skeleton class for your API. You need to make it public, so
11 * it is accessible to your client code (currently in Task1Test.java) file.
13 * Feel free to create additional classes or rename this one, just keep all
14 * the API and its implementation in this package. Do not spread it outside
17 public final class Convertor {
20 private String currency1 = null;
21 private String currency2 = null;
22 private Rate rate = null;
25 private List<CurrencyRate> currencyRates = null;
27 //version - for compatible mode
28 private int instanceVersion = 0; //compatible mode because of problem with empty currency and CZE -> CZE (1:2) rate
30 Convertor(String currency1, String currency2, Rate rate) {
32 if ((currency1 == null) || (currency2 == null) || (rate == null)) {
33 throw new IllegalArgumentException("All arguments have to be non-null.");
35 this.currency1 = currency1;
36 this.currency2 = currency2;
40 Convertor(final CurrencyRate ... currencyRate) {
43 if (currencyRate == null) {
44 throw new IllegalArgumentException("Parameter cannot be null.");
46 if (currencyRate.length == 0) {
47 throw new IllegalArgumentException("CurrencyRates cannot be empty.");
49 Set<Pair<String,String>> currencies = new HashSet<Pair<String,String>>();
50 List<CurrencyRate> curRates = new ArrayList<CurrencyRate>();
51 for (int i = 0; i < currencyRate.length; i++) {
52 CurrencyRate curRat = currencyRate[i];
54 throw new IllegalArgumentException("Parameter cannot be null.");
56 //check that currencyRate is not defined twice
57 Pair<String, String> curPair= new Pair<String, String>(curRat.getCurrency1(), curRat.getCurrency2());
58 if (currencies.contains(curPair)) {
59 throw new IllegalArgumentException("Pair of currencies in a currency rate cannot be defined twice");
61 currencies.add(curPair);
65 this.currencyRates = Collections.unmodifiableList(curRates);
68 public double convert(String fromCurrency, String toCurrency, int amount) {
69 if (instanceVersion == 1) {
70 if ((fromCurrency == null) || (toCurrency == null)) {
71 throw new IllegalArgumentException("All arguments have to be non-null.");
74 if (currency1.equals(fromCurrency) && currency2.equals(toCurrency)) {
75 return rate.convertAtoB(amount);
76 } else if (currency2.equals(fromCurrency) && currency1.equals(toCurrency)) {
77 return rate.convertBtoA(amount);
79 throw new IllegalArgumentException("Convertor " + this.toString() +
80 " cannot work with currencies " + fromCurrency + " and " + toCurrency + ".");
82 } else { //instanceVersion >= 2
83 //find suitable convertor
84 for (CurrencyRate curRate : currencyRates) {
85 if ((curRate.getCurrency1().equals(fromCurrency))&&
86 (curRate.getCurrency2().equals(toCurrency)))
88 return curRate.getRate().convertAtoB(amount);
91 //suitable convertor not found, try to find inverse convertor
92 for (CurrencyRate curRate : currencyRates) {
93 if ((curRate.getCurrency2().equals(fromCurrency))&&
94 (curRate.getCurrency1().equals(toCurrency)))
96 return curRate.getRate().convertBtoA(amount);
99 //even inverse convertor not found
100 throw new IllegalArgumentException("Cannot work with selected currencies.");
104 public double convert(String fromCurrency, String toCurrency, double amount) {
105 if (instanceVersion == 1) {
106 if ((fromCurrency == null) || (toCurrency == null)) {
107 throw new IllegalArgumentException("All arguments have to be non-null.");
110 if (currency1.equals(fromCurrency) && currency2.equals(toCurrency)) {
111 return rate.convertAtoB(amount);
112 } else if (currency2.equals(fromCurrency) && currency1.equals(toCurrency)) {
113 return rate.convertBtoA(amount);
115 throw new IllegalArgumentException("Convertor " + this.toString() +
116 " cannot work with currencies " + fromCurrency + " and " + toCurrency + ".");
118 } else { //instanceVersion >= 2
119 //find suitable convertor
120 for (CurrencyRate curRate : currencyRates) {
121 if ((curRate.getCurrency1().equals(fromCurrency))&&
122 (curRate.getCurrency2().equals(toCurrency)))
124 return curRate.getRate().convertAtoB(amount);
127 //suitable convertor not found, try to find inverse convertor
128 for (CurrencyRate curRate : currencyRates) {
129 if ((curRate.getCurrency2().equals(fromCurrency))&&
130 (curRate.getCurrency1().equals(toCurrency)))
132 return curRate.getRate().convertBtoA(amount);
135 //even inverse convertor not found
136 throw new IllegalArgumentException("Cannot work with selected currencies.");
141 * Returns currency rates. If instantiated with constructor from vesion 1
142 * it creates new collection with one CurrencyRate.
143 * Note, it can cause exception because of empty currencies or same currencies.
145 public Collection<CurrencyRate> getCurrencyRates() {
146 if (instanceVersion == 1) {
147 List<CurrencyRate> ret = new ArrayList<CurrencyRate>();
148 ret.add(new CurrencyRateImpl(currency1, currency2, rate)); //here it checks that currency rate is not nonsense
149 return Collections.unmodifiableCollection(ret);
150 } else { //instanceVersion >= 2
151 return currencyRates;
156 public String toString() {
157 if (instanceVersion == 1) {
158 return currency1 + currency2;
159 } else { //instanceVersion == 2
160 return super.toString(); //better be compatible in future :-)
165 public boolean equals(Object obj) {
166 if (instanceVersion == 1) {
170 if (getClass() != obj.getClass()) {
173 final Convertor other = (Convertor) obj;
174 if (this.currency1 != other.currency1 && (this.currency1 == null || !this.currency1.equals(other.currency1))) {
177 if (this.currency2 != other.currency2 && (this.currency2 == null || !this.currency2.equals(other.currency2))) {
180 if (this.rate != other.rate && (this.rate == null || !this.rate.equals(other.rate))) {
184 } else { //instanceVersion == 2
185 return super.equals(obj); //better be compatible in future :-)
190 public int hashCode() {
191 if (instanceVersion == 1) {
193 hash = 67 * hash + (this.currency1 != null ? this.currency1.hashCode() : 0);
194 hash = 67 * hash + (this.currency2 != null ? this.currency2.hashCode() : 0);
195 hash = 67 * hash + (this.rate != null ? this.rate.hashCode() : 0);
197 } else { //instanceVersion == 2
198 return super.hashCode(); //better be compatible in future :-)