1 package org.apidesign.apifest08.currency;
4 import java.math.BigDecimal;
5 import java.math.MathContext;
6 import java.math.RoundingMode;
7 import java.util.Currency;
11 * Convert between two currencies.
13 * @author D'Arcy Smith
16 final class ConvertorImpl
20 * The currency to cvonvert from.
22 private final Currency currencyA;
25 * The currency to cvonvert from.
27 private final Currency currencyB;
30 * The echange rate between a and b.
32 private final BigDecimal currencyARate;
35 * The echange rate between b and a.
37 private final BigDecimal currencyBRate;
40 * Constructs a convertor with the specified currencies.
42 * @param a the currency to convert from.
43 * @param aRate the exchage rage between from and to.
44 * @param b the currency to convert to.
45 * @param bRate the exchage rage between to and from.
46 * @throws IllegalArgumentException if either any of the arguments are null or if either rate <= 0.
48 public ConvertorImpl(final Currency a,
49 final BigDecimal aRate,
51 final BigDecimal bRate)
55 throw new IllegalArgumentException("a cannot be null");
60 throw new IllegalArgumentException("b cannot be null");
65 throw new IllegalArgumentException("aRate cannot be null");
70 throw new IllegalArgumentException("bRate cannot be null");
73 if(aRate.compareTo(BigDecimal.ZERO) <= 0)
75 throw new IllegalArgumentException("aRate must be > 0, was: " + aRate);
78 if(bRate.compareTo(BigDecimal.ZERO) <= 0)
80 throw new IllegalArgumentException("bRate must be > 0, was: " + bRate);
85 currencyARate = aRate;
86 currencyBRate = bRate;
90 * Convert an amount from one currency to another.
92 * @param from the currency to convert from.
93 * @param to the currency to convert to.
94 * @param amount the amount to convert.
95 * @return the converted amount.
96 * @throws IllegalArgumentException if any of the arguments are null.
97 * @throws InvalidConversionException if either from or to are not equal to the currencies passed to the constructor.
99 public BigDecimal convert(final Currency from,
101 final BigDecimal amount)
102 throws InvalidConversionException
104 final BigDecimal result;
108 throw new IllegalArgumentException("amount cannot be null");
113 throw new IllegalArgumentException("from cannot be null");
118 throw new IllegalArgumentException("to cannot be null");
121 if(!(from.equals(currencyA)) && (!(from.equals(currencyB))))
123 throw new InvalidConversionException("cannot convert from: " + from.getCurrencyCode(), from, currencyA, currencyB);
126 if(!(to.equals(currencyA)) && (!(to.equals(currencyB))))
128 throw new InvalidConversionException("cannot convert to: " + to.getCurrencyCode(), to, currencyA, currencyB);
131 // converting between the same currency is no converstion at all.
138 final BigDecimal rateX;
139 final BigDecimal rateY;
140 final BigDecimal temp;
142 if(from.equals(currencyA))
144 rateX = currencyARate;
145 rateY = currencyBRate;
149 rateX = currencyBRate;
150 rateY = currencyARate;
153 temp = amount.divide(rateX, MathContext.DECIMAL32);
154 result = temp.multiply(rateY);
157 return (result.setScale(2, RoundingMode.HALF_DOWN));