task2/solution12/src/org/apidesign/apifest08/currency/Convertor.java
author japod@localhost
Tue, 07 Oct 2008 00:17:07 +0200
changeset 33 80f2d8751f35
parent 29 f6073056b9fe
permissions -rw-r--r--
adding solution12 for task 2
     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 Hashtable<String, ExchangeRate> convertorInstanceExchangeRates; 
    24 
    25   private Convertor(List<Currency> currencies) throws UnknownConvertorException {
    26 	  convertorInstanceExchangeRates = new Hashtable<String, ExchangeRate>();
    27 	  for (Currency currency1 : currencies) {
    28 		for (Currency currency2 : currencies) {
    29 			if(!currency1.getCurrencyCode().equals(currency2.getCurrencyCode())) {
    30 				String key = currency1.getCurrencyCode() + currency2.getCurrencyCode();
    31 				ExchangeRate exchangeRate = exchangeRates.get(key);
    32 				convertorInstanceExchangeRates.put(key, exchangeRate);
    33 			}
    34 		}
    35 	}
    36   }
    37 
    38   /**
    39    * Sets convertor rate for selected currencies.
    40    * @param currency1
    41    *          one of the currencies we want to convert to/from
    42    * @param currency2
    43    *          the other currency
    44    * @param rate
    45    *          exchange rate from currency1 to currency2
    46    * @param unit
    47    *          unit of exchangeRate (USD->CZK - unit=1, you exchange one dollar, SKK->CZK unit=100, exchange rate is for
    48    *          100SKK)
    49    */
    50   public static void setConvertorRates(Currency currency1, Currency currency2, double rate, double unit) {
    51     if (currency1 == null || currency2 == null) {
    52       throw new ConvertorException("None of the currencies should be null!!!");
    53     }
    54 
    55     if (rate <= 0 || unit <= 0) {
    56       throw new ConvertorException("Rate(" + rate + ") and unit(" + unit + ") has to be grater then zero!!!");
    57     }
    58 
    59     if (exchangeRates == null) {
    60       exchangeRates = new Hashtable<String, ExchangeRate>();
    61     }
    62 
    63     String key12 = currency1.getCurrencyCode() + currency2.getCurrencyCode();
    64     String key21 = currency2.getCurrencyCode() + currency1.getCurrencyCode();
    65     double recountedRate = (unit / rate) * unit;
    66 
    67     exchangeRates.put(key12, new ExchangeRate(currency1, currency2, rate, unit));
    68     exchangeRates.put(key21, new ExchangeRate(currency2, currency1, recountedRate, unit));
    69 
    70   }
    71   
    72   /**
    73    * Merge exchange rates of actual convertor with exchange rates from selected 
    74    * convertor. If there are same currencies in both convertors, these from selected
    75    * convertor rewrites these in actual convertor.
    76    * @param convertor convertor to merge with actual one
    77    * @return convertor with merged exchange rates 
    78    */
    79   public Convertor merge(Convertor convertor) {
    80 	  convertorInstanceExchangeRates.putAll(convertor.getInstanceExchangeRates());
    81 	  return this;
    82   }
    83 
    84   /**
    85    * Creates new instance of convertor.
    86    * @param currency1
    87    *          one of the currencies we want to convert to/from
    88    * @param currency2
    89    *          the other currency
    90    * @return new instance of convertor
    91    * @throws UnknownConvertorException
    92    *           thrown if convertor for selected currencies has not been defined
    93    */
    94   public static Convertor getConvertorInstance(Currency... currencies) throws UnknownConvertorException {
    95    	List<Currency> currencyList = new ArrayList<Currency>();
    96    	
    97    	if(currencies.length < 2) {
    98    		throw new ConvertorException("To get convertor instance, you have to select at least two currencies!!!");
    99    	}
   100 
   101    	for (Currency currency1 : currencies) {
   102    		for (Currency currency2 : currencies) {
   103    	   		if(currency1 == null || currency2 == null) {
   104    	   			throw new ConvertorException("None of the currencies should be null!!!");
   105    	   		}
   106    	   		
   107    			if(!currency1.getCurrencyCode().equals(currency2.getCurrencyCode())) {
   108    				String key12 = currency1.getCurrencyCode() + currency2.getCurrencyCode();
   109    				String key21 = currency2.getCurrencyCode() + currency1.getCurrencyCode();
   110    				if (!(exchangeRates.containsKey(key12) && exchangeRates.containsKey(key21))) {
   111    					throw new UnknownConvertorException("Selected convertor (" + currency1.getCurrencyCode() + "<->"
   112    		    			+ currency2.getCurrencyCode() + ") has not defined exchange rates!!!");
   113    				}
   114    			}
   115 		}
   116    		
   117    		currencyList.add(currency1);
   118 	}
   119     
   120     return new Convertor(currencyList);
   121   }
   122 
   123   /**
   124    * Converts selected amout of selected currency to other currency of this convertor instance.
   125    * @param amount
   126    *          amount to convert
   127    * @param originalCurrency
   128    *          currency of this amount
   129    * @param newCurrency
   130    *          currency to which we want convert
   131    * @return converted amount
   132    * @throws InvalidCurrencyException
   133    *           while one or both currencies doesn't fit for this convertor
   134    */
   135   public double convert(double amount, Currency originalCurrency, Currency newCurrency) throws InvalidCurrencyException {
   136     ExchangeRate actualyUsedExchangeRate = null;
   137 
   138     if (originalCurrency == null) {
   139       throw new ConvertorException("Original currency is null!!!");
   140     }
   141 
   142     if (newCurrency == null) {
   143       throw new ConvertorException("Destination currency is null!!!");
   144     }
   145 
   146     actualyUsedExchangeRate = getExchangeRate(originalCurrency, newCurrency);
   147 
   148     return countResult(actualyUsedExchangeRate, amount);
   149   }
   150 
   151   private double countResult(ExchangeRate actualyUsedExchangeRate, double amount) {
   152     return amount * actualyUsedExchangeRate.getRate() / actualyUsedExchangeRate.getUnit();
   153   }
   154 
   155   /**
   156    * Decides the direction of conversion and returns instance of actual exchange rate.
   157    * @param actualCurrency
   158    *          actual currency we want to convert
   159    * @return actual exchange rate of this convertor for selected currency
   160    */
   161   private ExchangeRate getExchangeRate(Currency originalCurrency, Currency newCurrency) throws InvalidCurrencyException {
   162     ExchangeRate actualyUsedExchangeRate = null;
   163     
   164     String key = originalCurrency.getCurrencyCode() + newCurrency.getCurrencyCode();
   165 
   166     if(convertorInstanceExchangeRates.containsKey(key)) {
   167       actualyUsedExchangeRate = convertorInstanceExchangeRates.get(key);
   168     } else {
   169       throw new InvalidCurrencyException("This convertor could not be used for converting selected currencies (" + originalCurrency.getCurrencyCode() + "->"
   170           + newCurrency.getCurrencyCode() + ") !!!");
   171     }
   172 
   173     return actualyUsedExchangeRate;
   174   }
   175   
   176   /**
   177    * Returns exchange rates for actual instance of convertor.
   178    * @return exchange rates for actual instance of convertor
   179    */
   180   Hashtable<String, ExchangeRate> getInstanceExchangeRates() {
   181 	  return convertorInstanceExchangeRates;
   182   }
   183   
   184 }