task4/solution12/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 51 task3/solution12/src/org/apidesign/apifest08/currency/Convertor.java@221f1930cbfb
child 68 4de3a4b5445a
permissions -rw-r--r--
Copying structure for task4
     1 package org.apidesign.apifest08.currency;
     2 
     3 import java.util.ArrayList;
     4 import java.util.Currency;
     5 import java.util.Hashtable;
     6 import java.util.List;
     7 
     8 import org.apidesign.apifest08.currency.exceptions.ConvertorException;
     9 import org.apidesign.apifest08.currency.exceptions.InvalidCurrencyException;
    10 import org.apidesign.apifest08.currency.exceptions.UnknownConvertorException;
    11 
    12 /**
    13  * This is the skeleton class for your API. You need to make it public, so it is accessible to your client code
    14  * (currently in Task1Test.java) file.
    15  * <p>
    16  * Feel free to create additional classes or rename this one, just keep all the API and its implementation in this
    17  * package. Do not spread it outside to other packages.
    18  */
    19 public class Convertor {
    20 
    21   private static Hashtable<String, ExchangeRate> exchangeRates;
    22 
    23   private List<String> currencyConvertors; 
    24 
    25   /**
    26    * Constructor. Checks if all selected currencies are not null and has defined exchange rates for both
    27    * directions.
    28    * @param currencies currencies for new instance of convertor
    29    * @throws UnknownConvertorException if there are not defined exchange rates for both directions for each
    30    * pair of currencies
    31    */
    32   private Convertor(Currency[] currencies) throws UnknownConvertorException {
    33     currencyConvertors = new ArrayList<String>();
    34 
    35     for (Currency currency1 : currencies) {
    36       for (Currency currency2 : currencies) {
    37         if(currency1 == null || currency2 == null) {
    38           throw new ConvertorException("None of the currencies should be null!!!");
    39         }
    40           
    41         if(!currency1.getCurrencyCode().equals(currency2.getCurrencyCode())) {
    42           String key = currency1.getCurrencyCode() + currency2.getCurrencyCode();
    43           if (!exchangeRates.containsKey(key)) {
    44             throw new UnknownConvertorException("Selected convertor (" + currency1.getCurrencyCode() + "->"
    45                 + currency2.getCurrencyCode() + ") has not defined exchange rates!!!");
    46           } 
    47           
    48           currencyConvertors.add(key);            
    49         }
    50       }
    51     }
    52   }
    53 
    54   /**
    55    * Sets convertor rate for selected currencies.
    56    * @param currency1
    57    *          one of the currencies we want to convert to/from
    58    * @param currency2
    59    *          the other currency
    60    * @param rate
    61    *          exchange rate from currency1 to currency2
    62    * @param unit
    63    *          unit of exchangeRate (USD->CZK - unit=1, you exchange one dollar, SKK->CZK unit=100, exchange rate is for
    64    *          100SKK)
    65    */
    66   public static void setConvertorRates(Currency currency1, Currency currency2, double rate, double unit) {
    67     if (currency1 == null || currency2 == null) {
    68       throw new ConvertorException("None of the currencies should be null!!!");
    69     }
    70 
    71     if (rate <= 0 || unit <= 0) {
    72       throw new ConvertorException("Rate(" + rate + ") and unit(" + unit + ") has to be grater then zero!!!");
    73     }
    74 
    75     if (exchangeRates == null) {
    76       exchangeRates = new Hashtable<String, ExchangeRate>();
    77     }
    78 
    79     String key12 = currency1.getCurrencyCode() + currency2.getCurrencyCode();
    80     String key21 = currency2.getCurrencyCode() + currency1.getCurrencyCode();
    81     double recountedRate = (unit / rate) * unit;
    82 
    83     exchangeRates.put(key12, new ExchangeRate(currency1, currency2, rate, unit));
    84     exchangeRates.put(key21, new ExchangeRate(currency2, currency1, recountedRate, unit));
    85 
    86   }
    87   
    88   /**
    89    * Merge exchange rates of actual convertor with exchange rates from selected 
    90    * convertor. If there are same currencies in both convertors, these from selected
    91    * convertor rewrites these in actual convertor.
    92    * @param convertor convertor to merge with actual one
    93    * @return convertor with merged exchange rates 
    94    */
    95   public Convertor merge(Convertor convertor) {
    96     if(convertor == null) {
    97       throw new ConvertorException("It's impossible to merge with null convertor!!!");
    98     }
    99     
   100     currencyConvertors.addAll(convertor.getCurrencyConvertors());
   101 	  return this;
   102   }
   103 
   104   /**
   105    * Creates new instance of convertor.
   106    * @param currency1
   107    *          one of the currencies we want to convert to/from
   108    * @param currency2
   109    *          the other currency
   110    * @return new instance of convertor
   111    * @throws UnknownConvertorException
   112    *           thrown if convertor for selected currencies has not been defined
   113    */
   114   public static Convertor getConvertorInstance(Currency... currencies) throws UnknownConvertorException {
   115    	if(currencies.length < 2) {
   116    		throw new ConvertorException("To get convertor instance, you have to select at least two currencies!!!");
   117    	}
   118     
   119     return new Convertor(currencies);
   120   }
   121 
   122   /**
   123    * Converts selected amout of selected currency to other currency of this convertor instance.
   124    * @param amount
   125    *          amount to convert
   126    * @param originalCurrency
   127    *          currency of this amount
   128    * @param newCurrency
   129    *          currency to which we want convert
   130    * @return converted amount
   131    * @throws InvalidCurrencyException
   132    *           while one or both currencies doesn't fit for this convertor
   133    */
   134   public double convert(double amount, Currency originalCurrency, Currency newCurrency) throws InvalidCurrencyException {
   135     ExchangeRate actualyUsedExchangeRate = null;
   136 
   137     if (originalCurrency == null) {
   138       throw new ConvertorException("Original currency is null!!!");
   139     }
   140 
   141     if (newCurrency == null) {
   142       throw new ConvertorException("Destination currency is null!!!");
   143     }
   144 
   145     actualyUsedExchangeRate = getExchangeRate(originalCurrency, newCurrency);
   146 
   147     return countResult(actualyUsedExchangeRate, amount);
   148   }
   149 
   150   private double countResult(ExchangeRate actualyUsedExchangeRate, double amount) {
   151     return amount * actualyUsedExchangeRate.getRate() / actualyUsedExchangeRate.getUnit();
   152   }
   153 
   154   /**
   155    * Decides the direction of conversion and returns instance of actual exchange rate.
   156    * @param actualCurrency
   157    *          actual currency we want to convert
   158    * @return actual exchange rate of this convertor for selected currency
   159    */
   160   private ExchangeRate getExchangeRate(Currency originalCurrency, Currency newCurrency) throws InvalidCurrencyException {
   161     ExchangeRate actualyUsedExchangeRate = null;
   162     
   163     String key = originalCurrency.getCurrencyCode() + newCurrency.getCurrencyCode();
   164 
   165     if(currencyConvertors.contains(key)) {
   166       actualyUsedExchangeRate = exchangeRates.get(key);
   167     } else {
   168       throw new InvalidCurrencyException("This convertor could not be used for converting selected currencies (" + originalCurrency.getCurrencyCode() + "->"
   169           + newCurrency.getCurrencyCode() + ") !!!");
   170     }
   171 
   172     return actualyUsedExchangeRate;
   173   }
   174   
   175   /**
   176    * Returns currency convertors for actual instance of convertor.
   177    * @return currency convertors for actual instance of convertor
   178    */
   179   List<String> getCurrencyConvertors() {
   180 	  return currencyConvertors;
   181   }
   182   
   183 }