1.1 --- a/task2/solution14/src/org/apidesign/apifest08/currency/Convertor.java Wed Oct 01 10:43:05 2008 +0200
1.2 +++ b/task2/solution14/src/org/apidesign/apifest08/currency/Convertor.java Wed Oct 08 12:51:52 2008 +0200
1.3 @@ -1,5 +1,12 @@
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 @@ -8,12 +15,21 @@
1.17 * to other packages.
1.18 */
1.19 public final class Convertor {
1.20 - private String currency1;
1.21 - private String currency2;
1.22 - private Rate rate;
1.23 -
1.24 + //version 1 fields
1.25 +
1.26 + private String currency1 = null;
1.27 + private String currency2 = null;
1.28 + private Rate rate = null;
1.29 +
1.30 + //version 2 field
1.31 + private List<CurrencyRate> currencyRates = null;
1.32 +
1.33 + //version - for compatible mode
1.34 + private int instanceVersion = 0; //compatible mode because of problem with empty currency and CZE -> CZE (1:2) rate
1.35 +
1.36 Convertor(String currency1, String currency2, Rate rate) {
1.37 - if ((currency1 == null)||(currency2 == null)||(rate == null)) {
1.38 + instanceVersion = 1;
1.39 + if ((currency1 == null) || (currency2 == null) || (rate == null)) {
1.40 throw new IllegalArgumentException("All arguments have to be non-null.");
1.41 }
1.42 this.currency1 = currency1;
1.43 @@ -21,68 +37,165 @@
1.44 this.rate = rate;
1.45 }
1.46
1.47 + Convertor(final CurrencyRate ... currencyRate) {
1.48 + instanceVersion = 2;
1.49 +
1.50 + if (currencyRate == null) {
1.51 + throw new IllegalArgumentException("Parameter cannot be null.");
1.52 + }
1.53 + if (currencyRate.length == 0) {
1.54 + throw new IllegalArgumentException("CurrencyRates cannot be empty.");
1.55 + }
1.56 + Set<Pair<String,String>> currencies = new HashSet<Pair<String,String>>();
1.57 + List<CurrencyRate> curRates = new ArrayList<CurrencyRate>();
1.58 + for (int i = 0; i < currencyRate.length; i++) {
1.59 + CurrencyRate curRat = currencyRate[i];
1.60 + if (curRat == null) {
1.61 + throw new IllegalArgumentException("Parameter cannot be null.");
1.62 + }
1.63 + //check that currencyRate is not defined twice
1.64 + Pair<String, String> curPair= new Pair<String, String>(curRat.getCurrency1(), curRat.getCurrency2());
1.65 + if (currencies.contains(curPair)) {
1.66 + throw new IllegalArgumentException("Pair of currencies in a currency rate cannot be defined twice");
1.67 + }
1.68 + currencies.add(curPair);
1.69 +
1.70 + curRates.add(curRat);
1.71 + }
1.72 + this.currencyRates = Collections.unmodifiableList(curRates);
1.73 + }
1.74 +
1.75 public double convert(String fromCurrency, String toCurrency, int amount) {
1.76 - if ((fromCurrency == null)||(toCurrency == null)) {
1.77 - throw new IllegalArgumentException("All arguments have to be non-null.");
1.78 - }
1.79 -
1.80 - if (currency1.equals(fromCurrency) && currency2.equals(toCurrency)) {
1.81 - return rate.convertAtoB(amount);
1.82 - } else if (currency2.equals(fromCurrency) && currency1.equals(toCurrency)) {
1.83 - return rate.convertBtoA(amount);
1.84 - } else {
1.85 - throw new IllegalArgumentException("Convertor " + this.toString() +
1.86 - " cannot work with currencies " + fromCurrency + " and " + toCurrency + ".");
1.87 + if (instanceVersion == 1) {
1.88 + if ((fromCurrency == null) || (toCurrency == null)) {
1.89 + throw new IllegalArgumentException("All arguments have to be non-null.");
1.90 + }
1.91 +
1.92 + if (currency1.equals(fromCurrency) && currency2.equals(toCurrency)) {
1.93 + return rate.convertAtoB(amount);
1.94 + } else if (currency2.equals(fromCurrency) && currency1.equals(toCurrency)) {
1.95 + return rate.convertBtoA(amount);
1.96 + } else {
1.97 + throw new IllegalArgumentException("Convertor " + this.toString() +
1.98 + " cannot work with currencies " + fromCurrency + " and " + toCurrency + ".");
1.99 + }
1.100 + } else { //instanceVersion == 2
1.101 + //find suitable convertor
1.102 + for (CurrencyRate curRate : currencyRates) {
1.103 + if ((curRate.getCurrency1().equals(fromCurrency))&&
1.104 + (curRate.getCurrency2().equals(toCurrency)))
1.105 + {
1.106 + return curRate.getRate().convertAtoB(amount);
1.107 + }
1.108 + }
1.109 + //suitable convertor not found, try to find inverse convertor
1.110 + for (CurrencyRate curRate : currencyRates) {
1.111 + if ((curRate.getCurrency2().equals(fromCurrency))&&
1.112 + (curRate.getCurrency1().equals(toCurrency)))
1.113 + {
1.114 + return curRate.getRate().convertBtoA(amount);
1.115 + }
1.116 + }
1.117 + //even inverse convertor not found
1.118 + throw new IllegalArgumentException("Cannot work with selected currencies.");
1.119 }
1.120 }
1.121
1.122 public double convert(String fromCurrency, String toCurrency, double amount) {
1.123 - if ((fromCurrency == null)||(toCurrency == null)) {
1.124 - throw new IllegalArgumentException("All arguments have to be non-null.");
1.125 - }
1.126 -
1.127 - if (currency1.equals(fromCurrency) && currency2.equals(toCurrency)) {
1.128 - return rate.convertAtoB(amount);
1.129 - } else if (currency2.equals(fromCurrency) && currency1.equals(toCurrency)) {
1.130 - return rate.convertBtoA(amount);
1.131 - } else {
1.132 - throw new IllegalArgumentException("Convertor " + this.toString() +
1.133 - " cannot work with currencies " + fromCurrency + " and " + toCurrency + ".");
1.134 + if (instanceVersion == 1) {
1.135 + if ((fromCurrency == null) || (toCurrency == null)) {
1.136 + throw new IllegalArgumentException("All arguments have to be non-null.");
1.137 + }
1.138 +
1.139 + if (currency1.equals(fromCurrency) && currency2.equals(toCurrency)) {
1.140 + return rate.convertAtoB(amount);
1.141 + } else if (currency2.equals(fromCurrency) && currency1.equals(toCurrency)) {
1.142 + return rate.convertBtoA(amount);
1.143 + } else {
1.144 + throw new IllegalArgumentException("Convertor " + this.toString() +
1.145 + " cannot work with currencies " + fromCurrency + " and " + toCurrency + ".");
1.146 + }
1.147 + } else { //instanceVersion == 2
1.148 + //find suitable convertor
1.149 + for (CurrencyRate curRate : currencyRates) {
1.150 + if ((curRate.getCurrency1().equals(fromCurrency))&&
1.151 + (curRate.getCurrency2().equals(toCurrency)))
1.152 + {
1.153 + return curRate.getRate().convertAtoB(amount);
1.154 + }
1.155 + }
1.156 + //suitable convertor not found, try to find inverse convertor
1.157 + for (CurrencyRate curRate : currencyRates) {
1.158 + if ((curRate.getCurrency2().equals(fromCurrency))&&
1.159 + (curRate.getCurrency1().equals(toCurrency)))
1.160 + {
1.161 + return curRate.getRate().convertBtoA(amount);
1.162 + }
1.163 + }
1.164 + //even inverse convertor not found
1.165 + throw new IllegalArgumentException("Cannot work with selected currencies.");
1.166 }
1.167 }
1.168 -
1.169 +
1.170 + /**
1.171 + * Returns currency rates. If instantiated with constructor from vesion 1
1.172 + * it creates new collection with one CurrencyRate.
1.173 + * Note, it can cause exception because of empty currencies or same currencies.
1.174 + */
1.175 + public Collection<CurrencyRate> getCurrencyRates() {
1.176 + if (instanceVersion == 1) {
1.177 + List<CurrencyRate> ret = new ArrayList<CurrencyRate>();
1.178 + ret.add(new CurrencyRateImpl(currency1, currency2, rate));
1.179 + return Collections.unmodifiableCollection(ret);
1.180 + } else { //instanceVersion == 2
1.181 + return currencyRates;
1.182 + }
1.183 + }
1.184 +
1.185 @Override
1.186 public String toString() {
1.187 - return currency1+currency2;
1.188 + if (instanceVersion == 1) {
1.189 + return currency1 + currency2;
1.190 + } else { //instanceVersion == 2
1.191 + return super.toString(); //better be compatible in future :-)
1.192 + }
1.193 }
1.194 -
1.195 +
1.196 @Override
1.197 public boolean equals(Object obj) {
1.198 - if (obj == null) {
1.199 - return false;
1.200 + if (instanceVersion == 1) {
1.201 + if (obj == null) {
1.202 + return false;
1.203 + }
1.204 + if (getClass() != obj.getClass()) {
1.205 + return false;
1.206 + }
1.207 + final Convertor other = (Convertor) obj;
1.208 + if (this.currency1 != other.currency1 && (this.currency1 == null || !this.currency1.equals(other.currency1))) {
1.209 + return false;
1.210 + }
1.211 + if (this.currency2 != other.currency2 && (this.currency2 == null || !this.currency2.equals(other.currency2))) {
1.212 + return false;
1.213 + }
1.214 + if (this.rate != other.rate && (this.rate == null || !this.rate.equals(other.rate))) {
1.215 + return false;
1.216 + }
1.217 + return true;
1.218 + } else { //instanceVersion == 2
1.219 + return super.equals(obj); //better be compatible in future :-)
1.220 }
1.221 - if (getClass() != obj.getClass()) {
1.222 - return false;
1.223 - }
1.224 - final Convertor other = (Convertor) obj;
1.225 - if (this.currency1 != other.currency1 && (this.currency1 == null || !this.currency1.equals(other.currency1))) {
1.226 - return false;
1.227 - }
1.228 - if (this.currency2 != other.currency2 && (this.currency2 == null || !this.currency2.equals(other.currency2))) {
1.229 - return false;
1.230 - }
1.231 - if (this.rate != other.rate && (this.rate == null || !this.rate.equals(other.rate))) {
1.232 - return false;
1.233 - }
1.234 - return true;
1.235 }
1.236
1.237 @Override
1.238 public int hashCode() {
1.239 - int hash = 5;
1.240 - hash = 67 * hash + (this.currency1 != null ? this.currency1.hashCode() : 0);
1.241 - hash = 67 * hash + (this.currency2 != null ? this.currency2.hashCode() : 0);
1.242 - hash = 67 * hash + (this.rate != null ? this.rate.hashCode() : 0);
1.243 + if (instanceVersion == 1) {
1.244 + int hash = 5;
1.245 + hash = 67 * hash + (this.currency1 != null ? this.currency1.hashCode() : 0);
1.246 + hash = 67 * hash + (this.currency2 != null ? this.currency2.hashCode() : 0);
1.247 + hash = 67 * hash + (this.rate != null ? this.rate.hashCode() : 0);
1.248 return hash;
1.249 + } else { //instanceVersion == 2
1.250 + return super.hashCode(); //better be compatible in future :-)
1.251 + }
1.252 }
1.253 }