japod@6
|
1 |
package org.apidesign.apifest08.currency;
|
japod@6
|
2 |
|
japod@6
|
3 |
import java.util.Currency;
|
japod@6
|
4 |
import java.util.HashMap;
|
japod@6
|
5 |
import java.util.Map;
|
japod@6
|
6 |
|
japod@6
|
7 |
/**
|
japod@6
|
8 |
* A {@link Convertor} that works from a pre-set conversion table.
|
japod@6
|
9 |
* First use {@link #putIntoTable(org.apidesign.apifest08.currency.ConversionRate)} to set the conversion table.
|
japod@6
|
10 |
* Then invoke the {@link #convert(org.apidesign.apifest08.currency.Convertor.ConversionRequest)} method as many times as you wish.
|
japod@6
|
11 |
* @author jdvorak
|
japod@6
|
12 |
*/
|
japod@6
|
13 |
public class TableConvertor implements Convertor {
|
japod@6
|
14 |
|
japod@6
|
15 |
private final Map<Currency, Map<Currency, ConversionRate>> conversionTable = new HashMap<Currency, Map<Currency, ConversionRate>>();
|
japod@6
|
16 |
|
japod@6
|
17 |
public TableConvertor() {
|
japod@6
|
18 |
}
|
japod@6
|
19 |
|
japod@6
|
20 |
/**
|
japod@6
|
21 |
* Puts a rate into the table.
|
japod@6
|
22 |
* @param rate
|
japod@6
|
23 |
*/
|
japod@6
|
24 |
public void putIntoTable( final ConversionRate rate ) {
|
japod@6
|
25 |
final Currency srcCurrency = rate.getSrcUnitAmount().getCurrency();
|
japod@6
|
26 |
final Currency tgtCurrency = rate.getTgtUnitAmount().getCurrency();
|
japod@6
|
27 |
synchronized ( conversionTable ) {
|
japod@6
|
28 |
Map<Currency, ConversionRate> targetTable = conversionTable.get( srcCurrency );
|
japod@6
|
29 |
if ( targetTable == null ) {
|
japod@6
|
30 |
targetTable = new HashMap<Currency, ConversionRate>();
|
japod@6
|
31 |
conversionTable.put( srcCurrency, targetTable );
|
japod@6
|
32 |
}
|
japod@6
|
33 |
targetTable.put( tgtCurrency, rate );
|
japod@6
|
34 |
}
|
japod@6
|
35 |
}
|
japod@6
|
36 |
|
japod@6
|
37 |
/**
|
japod@6
|
38 |
* Carries out the conversion.
|
japod@6
|
39 |
* If the table does not contain a conversion from the source currency to the target one,
|
japod@6
|
40 |
* a {@link ConversionResult} is returned that has null netAmount.
|
japod@6
|
41 |
* This implementation works with any {@link ConversionRequest}, it won't throw {@link IllegalRequestSubtypeException}.
|
japod@6
|
42 |
* @param req the conversion request
|
japod@6
|
43 |
* @return the conversion result
|
japod@6
|
44 |
*/
|
japod@6
|
45 |
public ConversionResult convert( final ConversionRequest req ) {
|
japod@6
|
46 |
final Currency srcCurrency = req.getSrcAmount().getCurrency();
|
japod@6
|
47 |
final Currency tgtCurrency = req.getTgtCurrency();
|
japod@6
|
48 |
final ConversionRate rate = findConversionRate( srcCurrency, tgtCurrency );
|
japod@6
|
49 |
if ( rate != null ) {
|
japod@6
|
50 |
final MonetaryAmount tgtAmount = rate.convert( req.getSrcAmount() );
|
japod@6
|
51 |
return new ConversionResult( tgtAmount );
|
japod@6
|
52 |
} else {
|
japod@6
|
53 |
return new ConversionResult( null ); // did not find the pair of currencies in the table
|
japod@6
|
54 |
}
|
japod@6
|
55 |
}
|
japod@6
|
56 |
|
japod@6
|
57 |
/**
|
japod@6
|
58 |
* Looks up the conversion between the given currencies in the table.
|
japod@6
|
59 |
* @param srcCurrency the source currency
|
japod@6
|
60 |
* @param tgtCurrency the target currency
|
japod@6
|
61 |
* @return the conversion rate; null means no conversion between the currencies was found in the table
|
japod@6
|
62 |
*/
|
japod@6
|
63 |
protected ConversionRate findConversionRate( final Currency srcCurrency, final Currency tgtCurrency ) {
|
japod@6
|
64 |
synchronized ( conversionTable ) {
|
japod@6
|
65 |
final Map<Currency, ConversionRate> targetTable = conversionTable.get(srcCurrency);
|
japod@6
|
66 |
final ConversionRate rate = (targetTable != null) ? targetTable.get(tgtCurrency) : null;
|
japod@6
|
67 |
return rate;
|
japod@6
|
68 |
}
|
japod@6
|
69 |
}
|
japod@6
|
70 |
|
japod@6
|
71 |
}
|