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 |
}
|