1.1 --- a/task4/solution04/src/org/apidesign/apifest08/currency/ExchangeRate.java Sat Oct 11 23:38:46 2008 +0200
1.2 +++ b/task4/solution04/src/org/apidesign/apifest08/currency/ExchangeRate.java Fri Oct 17 17:40:14 2008 +0200
1.3 @@ -2,14 +2,18 @@
1.4
1.5
1.6 import java.math.BigDecimal;
1.7 +import java.math.RoundingMode;
1.8 +import java.util.Collections;
1.9 import java.util.Currency;
1.10 +import java.util.HashSet;
1.11 +import java.util.Set;
1.12
1.13
1.14 /**
1.15 * The exchange rate between two currencies.
1.16 *
1.17 * @author D'Arcy Smith
1.18 - * @version 1.0
1.19 + * @version 1.1
1.20 */
1.21 public final class ExchangeRate
1.22 {
1.23 @@ -122,4 +126,201 @@
1.24 {
1.25 return rateBtoA;
1.26 }
1.27 +
1.28 + public static ExchangeRate getExchangeRate(final Currency a,
1.29 + final Currency b,
1.30 + final BigDecimal va,
1.31 + final BigDecimal vb)
1.32 + {
1.33 + final BigDecimal rateAtoB;
1.34 + final BigDecimal rateBtoA;
1.35 + final ExchangeRate rate;
1.36 +
1.37 + if(a == null)
1.38 + {
1.39 + throw new IllegalArgumentException("a cannot be null");
1.40 + }
1.41 +
1.42 + if(b == null)
1.43 + {
1.44 + throw new IllegalArgumentException("b cannot be null");
1.45 + }
1.46 +
1.47 + if(a.equals(b))
1.48 + {
1.49 + rateAtoB = BigDecimal.ONE;
1.50 + rateBtoA = BigDecimal.ONE;
1.51 + }
1.52 + else
1.53 + {
1.54 + rateAtoB = vb.divide(va, 20, RoundingMode.HALF_DOWN);
1.55 + rateBtoA = va.divide(vb, 20, RoundingMode.HALF_DOWN);
1.56 + }
1.57 +
1.58 + rate = new ExchangeRate(a,
1.59 + b,
1.60 + rateAtoB.setScale(20, RoundingMode.HALF_EVEN),
1.61 + rateBtoA.setScale(20, RoundingMode.HALF_EVEN));
1.62 +
1.63 + return (rate);
1.64 + }
1.65 +
1.66 + public BigDecimal convert(final Currency from,
1.67 + final Currency to,
1.68 + final BigDecimal amount)
1.69 + throws InvalidConversionException
1.70 + {
1.71 + final BigDecimal result;
1.72 +
1.73 + if(amount == null)
1.74 + {
1.75 + throw new IllegalArgumentException("amount cannot be null");
1.76 + }
1.77 +
1.78 + if(from == null)
1.79 + {
1.80 + throw new IllegalArgumentException("from cannot be null");
1.81 + }
1.82 +
1.83 + if(to == null)
1.84 + {
1.85 + throw new IllegalArgumentException("to cannot be null");
1.86 + }
1.87 +
1.88 + if(!(from.equals(currencyA)) && (!(from.equals(currencyB))))
1.89 + {
1.90 + throw new InvalidConversionException("cannot convert from: " + from.getCurrencyCode(), from, currencyA, currencyB);
1.91 + }
1.92 +
1.93 + if(!(to.equals(currencyA)) && (!(to.equals(currencyB))))
1.94 + {
1.95 + throw new InvalidConversionException("cannot convert to: " + to.getCurrencyCode(), to, currencyA, currencyB);
1.96 + }
1.97 +
1.98 + result = amount.multiply(getConversionRate(from, to));
1.99 +
1.100 + return (result.setScale(2, RoundingMode.HALF_DOWN));
1.101 + }
1.102 +
1.103 + /**
1.104 + * Check to see if converting between the two currencies is possible.
1.105 + *
1.106 + * @param from the currency to convert from.
1.107 + * @param to the currency to convert to.
1.108 + * @return true if the conversion is possible.
1.109 + * @throws IllegalArgumentException if either from or to are null.
1.110 + */
1.111 + public boolean canConvert(final Currency from, final Currency to)
1.112 + {
1.113 + if(from == null)
1.114 + {
1.115 + throw new IllegalArgumentException("from cannot be null");
1.116 + }
1.117 +
1.118 + if(to == null)
1.119 + {
1.120 + throw new IllegalArgumentException("to cannot be null");
1.121 + }
1.122 +
1.123 + return ((from.equals(currencyA) || from.equals(currencyB)) &&
1.124 + (to.equals(currencyA) || to.equals(currencyB)));
1.125 + }
1.126 + /**
1.127 + * Get the currencies that the convertor supports.
1.128 + *
1.129 + * @return the supported currencies.
1.130 + */
1.131 + public Set<Currency> getCurrencies()
1.132 + {
1.133 + final Set<Currency> currencies;
1.134 +
1.135 + currencies = new HashSet<Currency>();
1.136 + currencies.add(currencyA);
1.137 + currencies.add(currencyB);
1.138 +
1.139 + return (Collections.unmodifiableSet(currencies));
1.140 + }
1.141 +
1.142 + /**
1.143 + * Get the conversion rate between two currencies.
1.144 + *
1.145 + * @param from the currency to convert from.
1.146 + * @param to the currency to convert to.
1.147 + * @return the conversion rate between the two currencies.
1.148 + * @throws InvalidConversionException if canConvert would return false.
1.149 + * @throws IllegalArgumentException if either from or to are null.
1.150 + */
1.151 + public BigDecimal getConversionRate(final Currency from,
1.152 + final Currency to)
1.153 + throws InvalidConversionException
1.154 + {
1.155 + final BigDecimal rate;
1.156 +
1.157 + if(from == null)
1.158 + {
1.159 + throw new IllegalArgumentException("from cannot be null");
1.160 + }
1.161 +
1.162 + if(to == null)
1.163 + {
1.164 + throw new IllegalArgumentException("to cannot be null");
1.165 + }
1.166 +
1.167 + if(from.equals(to))
1.168 + {
1.169 + rate = BigDecimal.ONE;
1.170 + }
1.171 + else
1.172 + {
1.173 + if(from.equals(currencyA))
1.174 + {
1.175 + rate = rateAtoB;
1.176 + }
1.177 + else
1.178 + {
1.179 + rate = rateBtoA;
1.180 + }
1.181 + }
1.182 +
1.183 + return (rate);
1.184 + }
1.185 +
1.186 + public String toString()
1.187 + {
1.188 + return (rateAtoB + " : " + rateBtoA);
1.189 + }
1.190 +
1.191 + @Override
1.192 + public boolean equals(Object obj) {
1.193 + if (obj == null) {
1.194 + return false;
1.195 + }
1.196 + if (getClass() != obj.getClass()) {
1.197 + return false;
1.198 + }
1.199 + final ExchangeRate other = (ExchangeRate) obj;
1.200 + if (this.currencyA != other.currencyA && (this.currencyA == null || !this.currencyA.equals(other.currencyA))) {
1.201 + return false;
1.202 + }
1.203 + if (this.currencyB != other.currencyB && (this.currencyB == null || !this.currencyB.equals(other.currencyB))) {
1.204 + return false;
1.205 + }
1.206 + if (this.rateAtoB != other.rateAtoB && (this.rateAtoB == null || !this.rateAtoB.equals(other.rateAtoB))) {
1.207 + return false;
1.208 + }
1.209 + if (this.rateBtoA != other.rateBtoA && (this.rateBtoA == null || !this.rateBtoA.equals(other.rateBtoA))) {
1.210 + return false;
1.211 + }
1.212 + return true;
1.213 + }
1.214 +
1.215 + @Override
1.216 + public int hashCode() {
1.217 + int hash = 7;
1.218 + hash = 97 * hash + (this.currencyA != null ? this.currencyA.hashCode() : 0);
1.219 + hash = 97 * hash + (this.currencyB != null ? this.currencyB.hashCode() : 0);
1.220 + hash = 97 * hash + (this.rateAtoB != null ? this.rateAtoB.hashCode() : 0);
1.221 + hash = 97 * hash + (this.rateBtoA != null ? this.rateBtoA.hashCode() : 0);
1.222 + return hash;
1.223 + }
1.224 }