1 package org.apidesign.apifest08.currency;
3 import java.io.Serializable;
4 import java.math.BigDecimal;
5 import java.math.RoundingMode;
6 import java.util.Currency;
9 * Default {@link Convertor} implementation. Exchange rate is stored as equivalents. It means if we have USD to CZK convertor and USD1 = CZK17
10 * we store 1 in sourceEquivalent and 17 in destinationEquivalent. This class is immutable.
14 class DefaultConvertor implements ExtendedConvertor, Serializable {
16 private static final long serialVersionUID = 6660014633685135034L;
19 * Equivalent in source currency.
21 private final BigDecimal sourceEquivalent;
24 * Equivalent in destination currency.
26 private final BigDecimal destinationEquivalent;
28 private final Currency sourceCurrency;
30 private final Currency destinationCurrency;
32 public DefaultConvertor(Money sourceEquivalent, Money destinationEquivalent) {
34 if (BigDecimal.ZERO.compareTo(sourceEquivalent.getAmount())==0)
36 throw new IllegalArgumentException("Source equivalent amount can not be 0.");
38 if (BigDecimal.ZERO.compareTo(destinationEquivalent.getAmount())==0)
40 throw new IllegalArgumentException("Destination equivalent amount can not be 0.");
42 this.sourceEquivalent = sourceEquivalent.getAmount();
43 this.destinationEquivalent = destinationEquivalent.getAmount();
44 this.sourceCurrency = sourceEquivalent.getCurrency();
45 this.destinationCurrency = destinationEquivalent.getCurrency();
48 public Money convert(Money amount, Currency destinationCurrency) {
51 throw new NullPointerException("Money is null");
53 if (destinationCurrency==null)
55 throw new NullPointerException("destionationCurrency is null");
57 if (!amount.getCurrency().equals(getSourceCurrency()))
59 throw new IllegalArgumentException("Can not convert from "+amount.getCurrency()+". Converts between "+getSourceCurrency()+" and "+getDestinationCurrency());
61 if (!getDestinationCurrency().equals(destinationCurrency))
63 throw new IllegalArgumentException("Can not convert to "+destinationCurrency+". Converts between "+getSourceCurrency()+" and "+getDestinationCurrency());
65 BigDecimal sourceAmount = amount.getAmount();
66 BigDecimal destinationAmount = sourceAmount.multiply(destinationEquivalent).divide(sourceEquivalent, 2, RoundingMode.HALF_UP);
67 return new MoneyImpl(destinationAmount, getDestinationCurrency());
70 public boolean isConversionSupported(Currency from, Currency to) {
71 return sourceCurrency.equals(from) && destinationCurrency.equals(to);
74 public BigDecimal getSourceEquivalent() {
75 return sourceEquivalent;
78 public BigDecimal getDestinationEquivalent() {
79 return destinationEquivalent;
82 public Currency getSourceCurrency() {
83 return sourceCurrency;
86 public Currency getDestinationCurrency() {
87 return destinationCurrency;
91 public String toString() {
92 return getClass().getName()+" converts "+getSourceCurrency()+" to "+getDestinationCurrency()+" "
93 +getSourceCurrency()+getSourceEquivalent()+"="+getDestinationCurrency()+getDestinationEquivalent();