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