task4/solution14/src/org/apidesign/apifest08/currency/Convertor.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Sat, 11 Oct 2008 23:38:46 +0200
changeset 61 58ec6da75f6f
parent 54 task3/solution14/src/org/apidesign/apifest08/currency/Convertor.java@1b300c79f4ce
child 67 bf7622ec1713
permissions -rw-r--r--
Copying structure for task4
     1 package org.apidesign.apifest08.currency;
     2 
     3 import java.util.ArrayList;
     4 import java.util.Collection;
     5 import java.util.Collections;
     6 import java.util.HashSet;
     7 import java.util.List;
     8 import java.util.Set;
     9 
    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.
    12  * <p>
    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
    15  * to other packages.
    16  */
    17 public final class Convertor {
    18     //version 1 fields
    19 
    20     private String currency1 = null;
    21     private String currency2 = null;
    22     private Rate rate = null;
    23 
    24     //version 2 field
    25     private List<CurrencyRate> currencyRates = null;
    26 
    27     //version - for compatible mode
    28     private int instanceVersion = 0; //compatible mode because of problem with empty currency and CZE -> CZE (1:2) rate
    29 
    30     Convertor(String currency1, String currency2, Rate rate) {
    31         instanceVersion = 1;
    32         if ((currency1 == null) || (currency2 == null) || (rate == null)) {
    33             throw new IllegalArgumentException("All arguments have to be non-null.");
    34         }
    35         this.currency1 = currency1;
    36         this.currency2 = currency2;
    37         this.rate = rate;
    38     }
    39 
    40     Convertor(final CurrencyRate ... currencyRate) {
    41         instanceVersion = 2;
    42 
    43         if (currencyRate == null) {
    44             throw new IllegalArgumentException("Parameter cannot be null.");
    45         }
    46         if (currencyRate.length == 0) {
    47             throw new IllegalArgumentException("CurrencyRates cannot be empty.");
    48         }
    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];
    53             if (curRat == null) {
    54                 throw new IllegalArgumentException("Parameter cannot be null.");
    55             }
    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");
    60             }
    61             currencies.add(curPair);
    62             
    63             curRates.add(curRat);
    64         }
    65         this.currencyRates = Collections.unmodifiableList(curRates);
    66     }
    67 
    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.");
    72             }
    73 
    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);
    78             } else {
    79                 throw new IllegalArgumentException("Convertor " + this.toString() +
    80                         " cannot work with currencies " + fromCurrency + " and " + toCurrency + ".");
    81             }
    82         } else { //instanceVersion >= 2
    83             //find suitable convertor
    84             for (CurrencyRate curRate : currencyRates) {
    85                 if ((curRate.getCurrency1().equals(fromCurrency))&& 
    86                         (curRate.getCurrency2().equals(toCurrency))) 
    87                 {
    88                     return curRate.getRate().convertAtoB(amount);
    89                 }
    90             }
    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)))
    95                 {
    96                     return curRate.getRate().convertBtoA(amount);
    97                 }
    98             }            
    99             //even inverse convertor not found
   100             throw new IllegalArgumentException("Cannot work with selected currencies.");
   101         }
   102     }
   103 
   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.");
   108             }
   109 
   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);
   114             } else {
   115                 throw new IllegalArgumentException("Convertor " + this.toString() +
   116                         " cannot work with currencies " + fromCurrency + " and " + toCurrency + ".");
   117             }
   118         } else { //instanceVersion >= 2
   119             //find suitable convertor
   120             for (CurrencyRate curRate : currencyRates) {
   121                 if ((curRate.getCurrency1().equals(fromCurrency))&& 
   122                         (curRate.getCurrency2().equals(toCurrency))) 
   123                 {
   124                     return curRate.getRate().convertAtoB(amount);
   125                 }
   126             }
   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)))
   131                 {
   132                     return curRate.getRate().convertBtoA(amount);
   133                 }
   134             }            
   135             //even inverse convertor not found
   136             throw new IllegalArgumentException("Cannot work with selected currencies.");
   137         }
   138     }
   139 
   140     /**
   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.
   144      */
   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;
   152         }
   153     }
   154 
   155     @Override
   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 :-)
   161         }
   162     }
   163 
   164     @Override
   165     public boolean equals(Object obj) {
   166         if (instanceVersion == 1) {
   167             if (obj == null) {
   168                 return false;
   169             }
   170             if (getClass() != obj.getClass()) {
   171                 return false;
   172             }
   173             final Convertor other = (Convertor) obj;
   174             if (this.currency1 != other.currency1 && (this.currency1 == null || !this.currency1.equals(other.currency1))) {
   175                 return false;
   176             }
   177             if (this.currency2 != other.currency2 && (this.currency2 == null || !this.currency2.equals(other.currency2))) {
   178                 return false;
   179             }
   180             if (this.rate != other.rate && (this.rate == null || !this.rate.equals(other.rate))) {
   181                 return false;
   182             }
   183             return true;
   184         } else { //instanceVersion == 2
   185             return super.equals(obj); //better be compatible in future :-)
   186         }
   187     }
   188 
   189     @Override
   190     public int hashCode() {
   191         if (instanceVersion == 1) {
   192             int hash = 5;
   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);
   196         return hash;
   197         } else { //instanceVersion == 2
   198             return super.hashCode(); //better be compatible in future :-)
   199         }
   200     }
   201 }