task2/solution10/src/org/apidesign/apifest08/currency/OfflineConverterProvider.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Wed, 01 Oct 2008 10:43:05 +0200
changeset 29 f6073056b9fe
parent 6 task1/solution10/src/org/apidesign/apifest08/currency/OfflineConverterProvider.java@97662396c0fd
permissions -rw-r--r--
Getting ready for task2: copying all solutions to new locations
japod@6
     1
package org.apidesign.apifest08.currency;
japod@6
     2
japod@6
     3
import java.util.*;
japod@6
     4
japod@6
     5
/**
japod@6
     6
 * ConvertorProvider class is introduced to handle
japod@6
     7
 */
japod@6
     8
public final class OfflineConverterProvider implements CurrencyConverterProvider {
japod@6
     9
japod@6
    10
japod@6
    11
	// we can't synchronize on DEFAULT as it's not final and can even be null in synchronized section
japod@6
    12
	private static final Object LOCK = new Object();
japod@6
    13
	private static CurrencyConverterProvider DEFAULT;
japod@6
    14
japod@6
    15
	// this is not nice and could be static, but future usage is uncertain and it's pretty easy to create
japod@6
    16
	private final Map<Currency, Double> rates;
japod@6
    17
japod@6
    18
	private OfflineConverterProvider() {
japod@6
    19
		rates = new HashMap<Currency, Double>();
japod@6
    20
		// simple initialization just for Task1Test
japod@6
    21
		rates.put(Currency.getInstance("USD"), 100.0);
japod@6
    22
		rates.put(Currency.getInstance("CZK"), 1700.0);
japod@6
    23
		rates.put(Currency.getInstance("SKK"), 2125.0);
japod@6
    24
	}
japod@6
    25
japod@6
    26
	/**
japod@6
    27
	 * Provides default implementation of ConvertorProvider. This Converter does nos not ensure accuracy
japod@6
    28
	 * of exchange rates, but should be functional at any circumstances including being offline.
japod@6
    29
	 *
japod@6
    30
	 * @return
japod@6
    31
	 */
japod@6
    32
	public static CurrencyConverterProvider getInstance() {
japod@6
    33
		// should be necessary in current implementation as creating CurrencyConverterProvider is cheap, but for future
japod@6
    34
		if (DEFAULT == null)
japod@6
    35
			synchronized (LOCK) {
japod@6
    36
				if (DEFAULT == null)
japod@6
    37
					DEFAULT = new OfflineConverterProvider();
japod@6
    38
			}
japod@6
    39
		return DEFAULT;
japod@6
    40
	}
japod@6
    41
japod@6
    42
	@Override
japod@6
    43
	public CurrencyConverter getConverter(double amount1, /*@NotNull*/ String currency1,
japod@6
    44
									   double amount2, /*@NotNull*/ String currency2)
japod@6
    45
			throws IllegalArgumentException {
japod@6
    46
japod@6
    47
		return getConverter(amount1, Currency.getInstance(currency2), amount2, Currency.getInstance(currency1));
japod@6
    48
	}
japod@6
    49
japod@6
    50
	/**
japod@6
    51
	 * Retrieves converter that is capable of converting values between currency1 and currency2. The exchange is
japod@6
    52
	 * specified in easy to understand way. By specifying values in two currencies that are equal. For example
japod@6
    53
	 * CurrencyConverter.getConverter(25, "CZK", 1, "EUR"); means 25CKZ is equal to 1EUR. This enables user to
japod@6
    54
	 * use this method without having to calculate anything. In general this can be expressed by formula
japod@6
    55
	 * amount1[currency1] = amount2[currency2].
japod@6
    56
	 *
japod@6
    57
	 * @param amount1
japod@6
    58
	 * @param currency1
japod@6
    59
	 * @param amount2
japod@6
    60
	 * @param currency2
japod@6
    61
	 *
japod@6
    62
	 * @return
japod@6
    63
	 *
japod@6
    64
	 * @throws IllegalArgumentException
japod@6
    65
	 * @throws CurrencyNotAvailableException
japod@6
    66
	 *
japod@6
    67
	 */
japod@6
    68
	@Override
japod@6
    69
	public CurrencyConverter getConverter(double amount1, /*@NotNull*/ Currency currency1,
japod@6
    70
									   double amount2, /*@NotNull*/ Currency currency2)
japod@6
    71
			throws IllegalArgumentException, CurrencyNotAvailableException {
japod@6
    72
		if (amount1 <= 0.0 || amount2 <= 0.0)
japod@6
    73
			throw new IllegalArgumentException(
japod@6
    74
					String.format("The specified currency values (%1$s, %2$s)", amount1, amount2));
japod@6
    75
		return new ConstantRateConverter(currency2, currency1, amount2 / amount1);
japod@6
    76
	}
japod@6
    77
japod@6
    78
	/**
japod@6
    79
	 * Creates a new converter that is able to convert between all specified currencies.
japod@6
    80
	 *
japod@6
    81
	 * @param currencies that the converter should be created for
japod@6
    82
	 *
japod@6
    83
	 * @return converter able to convert between all specified currencies
japod@6
    84
	 *
japod@6
    85
	 * @throws CurrencyNotAvailableException
japod@6
    86
	 *          thrown when one of the currencies is not available
japod@6
    87
	 */
japod@6
    88
	@Override
japod@6
    89
	public CurrencyConverter getConverter(/*@NotNull*/ Currency... currencies) throws CurrencyNotAvailableException {
japod@6
    90
		for (Currency c : currencies) {
japod@6
    91
			if (c == null)
japod@6
    92
				throw new NullPointerException("One of the specified currencies is null");
japod@6
    93
			if (!rates.containsKey(c))
japod@6
    94
				throw new CurrencyNotAvailableException(c);
japod@6
    95
		}
japod@6
    96
		return new MultiCurrencyConstantRateConverter(rates);
japod@6
    97
	}
japod@6
    98
japod@6
    99
	/**
japod@6
   100
	 * Creates a new converter that is able to convert between all specified currencies.
japod@6
   101
	 *
japod@6
   102
	 * @param currencies that the converter should be created for
japod@6
   103
	 *
japod@6
   104
	 * @return converter able to convert between all specified currencies
japod@6
   105
	 *
japod@6
   106
	 * @throws CurrencyNotAvailableException
japod@6
   107
	 *                                  thrown when one of the currencies is not available
japod@6
   108
	 * @throws NullPointerException	 if any of the specified currencies is null
japod@6
   109
	 * @throws IllegalArgumentException if any of the specified currencies is not a valid ISO code
japod@6
   110
	 */
japod@6
   111
	@Override
japod@6
   112
	public CurrencyConverter getConverter(/*@NotNull*/ String... currencies)
japod@6
   113
			throws CurrencyNotAvailableException, IllegalArgumentException, NullPointerException {
japod@6
   114
japod@6
   115
		Currency[] c2 = new Currency[currencies.length];
japod@6
   116
		for (int i = 0; i < c2.length; i++)
japod@6
   117
			c2[i] = Currency.getInstance(currencies[i]);
japod@6
   118
		return getConverter(c2);
japod@6
   119
	}
japod@6
   120
}