task2/solution14/src/org/apidesign/apifest08/currency/Convertor.java
changeset 49 de033c457bed
parent 29 f6073056b9fe
     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  }