1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/task2/solution04/src/org/apidesign/apifest08/currency/ConverterImpl.java Wed Oct 01 10:43:05 2008 +0200
1.3 @@ -0,0 +1,159 @@
1.4 +package org.apidesign.apifest08.currency;
1.5 +
1.6 +
1.7 +import java.math.BigDecimal;
1.8 +import java.math.MathContext;
1.9 +import java.math.RoundingMode;
1.10 +import java.util.Currency;
1.11 +
1.12 +
1.13 +/**
1.14 + * Convert between two currencies.
1.15 + *
1.16 + * @author D'Arcy Smith
1.17 + * @version 1.0
1.18 + */
1.19 +final class ConvertorImpl
1.20 + implements Convertor
1.21 +{
1.22 + /**
1.23 + * The currency to cvonvert from.
1.24 + */
1.25 + private final Currency currencyA;
1.26 +
1.27 + /**
1.28 + * The currency to cvonvert from.
1.29 + */
1.30 + private final Currency currencyB;
1.31 +
1.32 + /**
1.33 + * The echange rate between a and b.
1.34 + */
1.35 + private final BigDecimal currencyARate;
1.36 +
1.37 + /**
1.38 + * The echange rate between b and a.
1.39 + */
1.40 + private final BigDecimal currencyBRate;
1.41 +
1.42 + /**
1.43 + * Constructs a convertor with the specified currencies.
1.44 + *
1.45 + * @param a the currency to convert from.
1.46 + * @param aRate the exchage rage between from and to.
1.47 + * @param b the currency to convert to.
1.48 + * @param bRate the exchage rage between to and from.
1.49 + * @throws IllegalArgumentException if either any of the arguments are null or if either rate <= 0.
1.50 + */
1.51 + public ConvertorImpl(final Currency a,
1.52 + final BigDecimal aRate,
1.53 + final Currency b,
1.54 + final BigDecimal bRate)
1.55 + {
1.56 + if(a == null)
1.57 + {
1.58 + throw new IllegalArgumentException("a cannot be null");
1.59 + }
1.60 +
1.61 + if(b == null)
1.62 + {
1.63 + throw new IllegalArgumentException("b cannot be null");
1.64 + }
1.65 +
1.66 + if(aRate == null)
1.67 + {
1.68 + throw new IllegalArgumentException("aRate cannot be null");
1.69 + }
1.70 +
1.71 + if(bRate == null)
1.72 + {
1.73 + throw new IllegalArgumentException("bRate cannot be null");
1.74 + }
1.75 +
1.76 + if(aRate.compareTo(BigDecimal.ZERO) <= 0)
1.77 + {
1.78 + throw new IllegalArgumentException("aRate must be > 0, was: " + aRate);
1.79 + }
1.80 +
1.81 + if(bRate.compareTo(BigDecimal.ZERO) <= 0)
1.82 + {
1.83 + throw new IllegalArgumentException("bRate must be > 0, was: " + bRate);
1.84 + }
1.85 +
1.86 + currencyA = a;
1.87 + currencyB = b;
1.88 + currencyARate = aRate;
1.89 + currencyBRate = bRate;
1.90 + }
1.91 +
1.92 + /**
1.93 + * Convert an amount from one currency to another.
1.94 + *
1.95 + * @param from the currency to convert from.
1.96 + * @param to the currency to convert to.
1.97 + * @param amount the amount to convert.
1.98 + * @return the converted amount.
1.99 + * @throws IllegalArgumentException if any of the arguments are null.
1.100 + * @throws InvalidConversionException if either from or to are not equal to the currencies passed to the constructor.
1.101 + */
1.102 + public BigDecimal convert(final Currency from,
1.103 + final Currency to,
1.104 + final BigDecimal amount)
1.105 + throws InvalidConversionException
1.106 + {
1.107 + final BigDecimal result;
1.108 +
1.109 + if(amount == null)
1.110 + {
1.111 + throw new IllegalArgumentException("amount cannot be null");
1.112 + }
1.113 +
1.114 + if(from == null)
1.115 + {
1.116 + throw new IllegalArgumentException("from cannot be null");
1.117 + }
1.118 +
1.119 + if(to == null)
1.120 + {
1.121 + throw new IllegalArgumentException("to cannot be null");
1.122 + }
1.123 +
1.124 + if(!(from.equals(currencyA)) && (!(from.equals(currencyB))))
1.125 + {
1.126 + throw new InvalidConversionException("cannot convert from: " + from.getCurrencyCode(), from, currencyA, currencyB);
1.127 + }
1.128 +
1.129 + if(!(to.equals(currencyA)) && (!(to.equals(currencyB))))
1.130 + {
1.131 + throw new InvalidConversionException("cannot convert to: " + to.getCurrencyCode(), to, currencyA, currencyB);
1.132 + }
1.133 +
1.134 + // converting between the same currency is no converstion at all.
1.135 + if(from.equals(to))
1.136 + {
1.137 + result = amount;
1.138 + }
1.139 + else
1.140 + {
1.141 + final BigDecimal rateX;
1.142 + final BigDecimal rateY;
1.143 + final BigDecimal temp;
1.144 +
1.145 + if(from.equals(currencyA))
1.146 + {
1.147 + rateX = currencyARate;
1.148 + rateY = currencyBRate;
1.149 + }
1.150 + else
1.151 + {
1.152 + rateX = currencyBRate;
1.153 + rateY = currencyARate;
1.154 + }
1.155 +
1.156 + temp = amount.divide(rateX, MathContext.DECIMAL32);
1.157 + result = temp.multiply(rateY);
1.158 + }
1.159 +
1.160 + return (result.setScale(2, RoundingMode.HALF_DOWN));
1.161 + }
1.162 +}