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