1 package org.apidesign.apifest08.currency;
3 import java.math.BigDecimal;
4 import java.util.Currency;
8 * Create convertors using a flyweight to reduce the number of repetative creations of the same convertor.
10 * @author D'Arcy Smith
13 public final class ConvertorFactory
16 * flyweight so that only one vestion of each converter is created at a time.
17 private final static Map<String, WeakReference<Convertor>> convertors;
21 convertors = new WeakHashMap<String, WeakReference<Convertor>>();
26 * Prevent accidental construction.
28 private ConvertorFactory()
33 * Get the convertor for the specified currencies. The currency name format
34 * must be acceptable to java.util.Currency.getInstance(String)
36 * @param a the currency to convert from.
37 * @param aRate the exchange rate for a to b.
38 * @param b the currency to convert to.
39 * @param bRate the echante rate for b to a.
40 * @return the convertor for the specified currencies.
41 * @throws IllegalArgumentException if any of the arguments are null.
43 public static Convertor getConvertor(final String a,
44 final BigDecimal aRate,
46 final BigDecimal bRate)
48 final Currency currencyA;
49 final Currency currencyB;
50 final Convertor convertor;
52 currencyA = Currency.getInstance(a);
53 currencyB = Currency.getInstance(b);
54 convertor = getConvertor(currencyA, aRate, currencyB, bRate);
60 * Get the convertor for the specified currencies.
62 * @param a the currency to convert from.
63 * @param aRate the exchange rate for a to b.
64 * @param b the currency to convert to.
65 * @param bRate the echante rate for b to a.
66 * @return the convertor for the specified currencies.
67 * @throws IllegalArgumentException if either any of the arguments are null or if either rate <= 0.
69 public static Convertor getConvertor(final Currency a,
70 final BigDecimal aRate,
72 final BigDecimal bRate)
79 throw new IllegalArgumentException("a cannot be null");
84 throw new IllegalArgumentException("b cannot be null");
89 throw new IllegalArgumentException("aRate cannot be null");
94 throw new IllegalArgumentException("bRate cannot be null");
98 key = a.getCurrencyCode() + aRate + b.getCurrencyCode() + bRate;
100 // make sure that we don't try to overwrite one
101 synchronized(convertors)
103 if(!(convertors.containsKey(key)))
105 convertor = new ConvertorImpl(a, aRate, b, bRate);
106 convertors.put(key, new WeakReference(convertor));
109 convertor = convertors.get(key).get();
113 convertor = new ConvertorImpl(a, aRate, b, bRate);
118 public static Convertor mergeConvertors(final Convertor ... cs)
125 // ISSUE: only takes into account the names... not the rates...
128 // make sure that we don't try to overwrite one
129 synchronized(convertors)
131 if(!(convertors.containsKey(key)))
133 convertor = new CompositeConvertorImpl(cs);
134 convertors.put(key, new WeakReference(convertor));
137 convertor = convertors.get(key).get();
141 convertor = new CompositeConvertorImpl(cs);
147 private static String getKey(final Convertor ... cs)
149 final Set<Currency> currencies;
150 final StringBuilder builder;
152 currencies = new HashSet<Currency>();
154 for(final Convertor convertor : cs)
156 final Set<Currency> c;
158 c = convertor.getCurrencies();
159 currencies.addAll(c);
162 builder = new StringBuilder();
164 for(final Currency currency : currencies)
166 builder.append(currency.getCurrencyCode());
169 return (builder.toString());