1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/task4/solution14/src/org/apidesign/apifest08/currency/Convertor.java Sat Oct 11 23:38:46 2008 +0200
1.3 @@ -0,0 +1,201 @@
1.4 +package org.apidesign.apifest08.currency;
1.5 +
1.6 +import java.util.ArrayList;
1.7 +import java.util.Collection;
1.8 +import java.util.Collections;
1.9 +import java.util.HashSet;
1.10 +import java.util.List;
1.11 +import java.util.Set;
1.12 +
1.13 +/** This is the skeleton class for your API. You need to make it public, so
1.14 + * it is accessible to your client code (currently in Task1Test.java) file.
1.15 + * <p>
1.16 + * Feel free to create additional classes or rename this one, just keep all
1.17 + * the API and its implementation in this package. Do not spread it outside
1.18 + * to other packages.
1.19 + */
1.20 +public final class Convertor {
1.21 + //version 1 fields
1.22 +
1.23 + private String currency1 = null;
1.24 + private String currency2 = null;
1.25 + private Rate rate = null;
1.26 +
1.27 + //version 2 field
1.28 + private List<CurrencyRate> currencyRates = null;
1.29 +
1.30 + //version - for compatible mode
1.31 + private int instanceVersion = 0; //compatible mode because of problem with empty currency and CZE -> CZE (1:2) rate
1.32 +
1.33 + Convertor(String currency1, String currency2, Rate rate) {
1.34 + instanceVersion = 1;
1.35 + if ((currency1 == null) || (currency2 == null) || (rate == null)) {
1.36 + throw new IllegalArgumentException("All arguments have to be non-null.");
1.37 + }
1.38 + this.currency1 = currency1;
1.39 + this.currency2 = currency2;
1.40 + this.rate = rate;
1.41 + }
1.42 +
1.43 + Convertor(final CurrencyRate ... currencyRate) {
1.44 + instanceVersion = 2;
1.45 +
1.46 + if (currencyRate == null) {
1.47 + throw new IllegalArgumentException("Parameter cannot be null.");
1.48 + }
1.49 + if (currencyRate.length == 0) {
1.50 + throw new IllegalArgumentException("CurrencyRates cannot be empty.");
1.51 + }
1.52 + Set<Pair<String,String>> currencies = new HashSet<Pair<String,String>>();
1.53 + List<CurrencyRate> curRates = new ArrayList<CurrencyRate>();
1.54 + for (int i = 0; i < currencyRate.length; i++) {
1.55 + CurrencyRate curRat = currencyRate[i];
1.56 + if (curRat == null) {
1.57 + throw new IllegalArgumentException("Parameter cannot be null.");
1.58 + }
1.59 + //check that currencyRate is not defined twice
1.60 + Pair<String, String> curPair= new Pair<String, String>(curRat.getCurrency1(), curRat.getCurrency2());
1.61 + if (currencies.contains(curPair)) {
1.62 + throw new IllegalArgumentException("Pair of currencies in a currency rate cannot be defined twice");
1.63 + }
1.64 + currencies.add(curPair);
1.65 +
1.66 + curRates.add(curRat);
1.67 + }
1.68 + this.currencyRates = Collections.unmodifiableList(curRates);
1.69 + }
1.70 +
1.71 + public double convert(String fromCurrency, String toCurrency, int amount) {
1.72 + if (instanceVersion == 1) {
1.73 + if ((fromCurrency == null) || (toCurrency == null)) {
1.74 + throw new IllegalArgumentException("All arguments have to be non-null.");
1.75 + }
1.76 +
1.77 + if (currency1.equals(fromCurrency) && currency2.equals(toCurrency)) {
1.78 + return rate.convertAtoB(amount);
1.79 + } else if (currency2.equals(fromCurrency) && currency1.equals(toCurrency)) {
1.80 + return rate.convertBtoA(amount);
1.81 + } else {
1.82 + throw new IllegalArgumentException("Convertor " + this.toString() +
1.83 + " cannot work with currencies " + fromCurrency + " and " + toCurrency + ".");
1.84 + }
1.85 + } else { //instanceVersion >= 2
1.86 + //find suitable convertor
1.87 + for (CurrencyRate curRate : currencyRates) {
1.88 + if ((curRate.getCurrency1().equals(fromCurrency))&&
1.89 + (curRate.getCurrency2().equals(toCurrency)))
1.90 + {
1.91 + return curRate.getRate().convertAtoB(amount);
1.92 + }
1.93 + }
1.94 + //suitable convertor not found, try to find inverse convertor
1.95 + for (CurrencyRate curRate : currencyRates) {
1.96 + if ((curRate.getCurrency2().equals(fromCurrency))&&
1.97 + (curRate.getCurrency1().equals(toCurrency)))
1.98 + {
1.99 + return curRate.getRate().convertBtoA(amount);
1.100 + }
1.101 + }
1.102 + //even inverse convertor not found
1.103 + throw new IllegalArgumentException("Cannot work with selected currencies.");
1.104 + }
1.105 + }
1.106 +
1.107 + public double convert(String fromCurrency, String toCurrency, double amount) {
1.108 + if (instanceVersion == 1) {
1.109 + if ((fromCurrency == null) || (toCurrency == null)) {
1.110 + throw new IllegalArgumentException("All arguments have to be non-null.");
1.111 + }
1.112 +
1.113 + if (currency1.equals(fromCurrency) && currency2.equals(toCurrency)) {
1.114 + return rate.convertAtoB(amount);
1.115 + } else if (currency2.equals(fromCurrency) && currency1.equals(toCurrency)) {
1.116 + return rate.convertBtoA(amount);
1.117 + } else {
1.118 + throw new IllegalArgumentException("Convertor " + this.toString() +
1.119 + " cannot work with currencies " + fromCurrency + " and " + toCurrency + ".");
1.120 + }
1.121 + } else { //instanceVersion >= 2
1.122 + //find suitable convertor
1.123 + for (CurrencyRate curRate : currencyRates) {
1.124 + if ((curRate.getCurrency1().equals(fromCurrency))&&
1.125 + (curRate.getCurrency2().equals(toCurrency)))
1.126 + {
1.127 + return curRate.getRate().convertAtoB(amount);
1.128 + }
1.129 + }
1.130 + //suitable convertor not found, try to find inverse convertor
1.131 + for (CurrencyRate curRate : currencyRates) {
1.132 + if ((curRate.getCurrency2().equals(fromCurrency))&&
1.133 + (curRate.getCurrency1().equals(toCurrency)))
1.134 + {
1.135 + return curRate.getRate().convertBtoA(amount);
1.136 + }
1.137 + }
1.138 + //even inverse convertor not found
1.139 + throw new IllegalArgumentException("Cannot work with selected currencies.");
1.140 + }
1.141 + }
1.142 +
1.143 + /**
1.144 + * Returns currency rates. If instantiated with constructor from vesion 1
1.145 + * it creates new collection with one CurrencyRate.
1.146 + * Note, it can cause exception because of empty currencies or same currencies.
1.147 + */
1.148 + public Collection<CurrencyRate> getCurrencyRates() {
1.149 + if (instanceVersion == 1) {
1.150 + List<CurrencyRate> ret = new ArrayList<CurrencyRate>();
1.151 + ret.add(new CurrencyRateImpl(currency1, currency2, rate)); //here it checks that currency rate is not nonsense
1.152 + return Collections.unmodifiableCollection(ret);
1.153 + } else { //instanceVersion >= 2
1.154 + return currencyRates;
1.155 + }
1.156 + }
1.157 +
1.158 + @Override
1.159 + public String toString() {
1.160 + if (instanceVersion == 1) {
1.161 + return currency1 + currency2;
1.162 + } else { //instanceVersion == 2
1.163 + return super.toString(); //better be compatible in future :-)
1.164 + }
1.165 + }
1.166 +
1.167 + @Override
1.168 + public boolean equals(Object obj) {
1.169 + if (instanceVersion == 1) {
1.170 + if (obj == null) {
1.171 + return false;
1.172 + }
1.173 + if (getClass() != obj.getClass()) {
1.174 + return false;
1.175 + }
1.176 + final Convertor other = (Convertor) obj;
1.177 + if (this.currency1 != other.currency1 && (this.currency1 == null || !this.currency1.equals(other.currency1))) {
1.178 + return false;
1.179 + }
1.180 + if (this.currency2 != other.currency2 && (this.currency2 == null || !this.currency2.equals(other.currency2))) {
1.181 + return false;
1.182 + }
1.183 + if (this.rate != other.rate && (this.rate == null || !this.rate.equals(other.rate))) {
1.184 + return false;
1.185 + }
1.186 + return true;
1.187 + } else { //instanceVersion == 2
1.188 + return super.equals(obj); //better be compatible in future :-)
1.189 + }
1.190 + }
1.191 +
1.192 + @Override
1.193 + public int hashCode() {
1.194 + if (instanceVersion == 1) {
1.195 + int hash = 5;
1.196 + hash = 67 * hash + (this.currency1 != null ? this.currency1.hashCode() : 0);
1.197 + hash = 67 * hash + (this.currency2 != null ? this.currency2.hashCode() : 0);
1.198 + hash = 67 * hash + (this.rate != null ? this.rate.hashCode() : 0);
1.199 + return hash;
1.200 + } else { //instanceVersion == 2
1.201 + return super.hashCode(); //better be compatible in future :-)
1.202 + }
1.203 + }
1.204 +}