task1/solution02/src/org/apidesign/apifest08/currency/DefaultConvertor.java
author japod@localhost
Tue, 30 Sep 2008 11:47:02 +0200
changeset 16 2864c6d744c0
parent 6 97662396c0fd
permissions -rw-r--r--
solution 02 updated to 1.5
japod@6
     1
package org.apidesign.apifest08.currency;
japod@6
     2
japod@6
     3
import java.io.Serializable;
japod@6
     4
import java.math.BigDecimal;
japod@6
     5
import java.math.RoundingMode;
japod@6
     6
import java.util.Currency;
japod@6
     7
japod@6
     8
/**
japod@6
     9
 * Default {@link Convertor} implementation. Exchange rate is stored as equivalents. It means if we have USD to CZK convertor and USD1 = CZK17 
japod@6
    10
 * we store 1 in sourceEquivalent and 17 in destinationEquivalent. This class is immutable.
japod@6
    11
 * @author lukas
japod@6
    12
 *
japod@6
    13
 */
japod@6
    14
class DefaultConvertor implements Convertor, Serializable {
japod@6
    15
japod@6
    16
	private static final long serialVersionUID = -1754789142402148099L;
japod@6
    17
japod@6
    18
	/**
japod@6
    19
	 * Equivalent in source currency.
japod@6
    20
	 */
japod@6
    21
	private final BigDecimal sourceEquivalent;
japod@6
    22
	
japod@6
    23
	/**
japod@6
    24
	 * Equivalent in destination currency.
japod@6
    25
	 */
japod@6
    26
	private final BigDecimal destinationEquivalent;
japod@6
    27
	
japod@6
    28
	private final Currency sourceCurrency;
japod@6
    29
	
japod@6
    30
	private final Currency destinationCurrency;
japod@6
    31
	
japod@6
    32
	public DefaultConvertor(BigDecimal sourceEquivalent, BigDecimal destinationEquivalent, Currency sourceCurrency, Currency destinationCurrency) {
japod@6
    33
		super();
japod@16
    34
		if (BigDecimal.ZERO.compareTo(sourceEquivalent)==0)
japod@16
    35
		{
japod@16
    36
			throw new IllegalArgumentException("Source equivalent amount can not be 0.");
japod@16
    37
		}
japod@16
    38
		if (BigDecimal.ZERO.compareTo(destinationEquivalent)==0)
japod@16
    39
		{
japod@16
    40
			throw new IllegalArgumentException("Destination equivalent amount can not be 0.");
japod@16
    41
		}
japod@6
    42
		this.sourceEquivalent = sourceEquivalent;
japod@6
    43
		this.destinationEquivalent = destinationEquivalent;
japod@6
    44
		this.sourceCurrency = sourceCurrency;
japod@6
    45
		this.destinationCurrency = destinationCurrency;
japod@6
    46
	}
japod@6
    47
	
japod@16
    48
	public Money convert(Money amount, Currency destinationCurrency) {
japod@16
    49
		if (amount==null)
japod@6
    50
		{
japod@6
    51
			throw new NullPointerException("Money is null");
japod@6
    52
		}
japod@16
    53
		if (destinationCurrency==null)
japod@6
    54
		{
japod@16
    55
			throw new NullPointerException("destionationCurrency is null");
japod@6
    56
		}
japod@16
    57
		if (isConversionInOpositeDirection(amount, destinationCurrency))
japod@16
    58
		{
japod@16
    59
			return revert().convert(amount, destinationCurrency);
japod@16
    60
		}
japod@16
    61
		if (!amount.getCurrency().equals(getSourceCurrency()))
japod@16
    62
		{
japod@16
    63
			throw new IllegalArgumentException("Can not convert from "+amount.getCurrency()+". Converts between "+getSourceCurrency()+" and "+getDestinationCurrency());
japod@16
    64
		}
japod@16
    65
		if (!getDestinationCurrency().equals(destinationCurrency))
japod@16
    66
		{
japod@16
    67
			throw new IllegalArgumentException("Can not convert to "+destinationCurrency+". Converts between "+getSourceCurrency()+" and "+getDestinationCurrency());
japod@16
    68
		}
japod@16
    69
		BigDecimal sourceAmount = amount.getAmount();
japod@16
    70
		BigDecimal destinationAmount = sourceAmount.multiply(destinationEquivalent).divide(sourceEquivalent, 2, RoundingMode.HALF_UP);
japod@6
    71
		return new MoneyImpl(destinationAmount, getDestinationCurrency());
japod@6
    72
	}
japod@6
    73
japod@16
    74
	/**
japod@16
    75
	 * Returns true, if the conversion is in oposit direction.
japod@16
    76
	 * @param amount
japod@16
    77
	 * @param destinationCurrency
japod@16
    78
	 * @return
japod@16
    79
	 */
japod@16
    80
	private boolean isConversionInOpositeDirection(Money amount,	Currency destinationCurrency) {
japod@16
    81
		return amount.getCurrency().equals(getDestinationCurrency()) && destinationCurrency.equals(getSourceCurrency());
japod@16
    82
	}
japod@16
    83
japod@6
    84
japod@6
    85
	public Convertor revert() {
japod@6
    86
		return new DefaultConvertor(destinationEquivalent, sourceEquivalent, destinationCurrency, sourceCurrency);
japod@6
    87
	}
japod@6
    88
japod@6
    89
	public BigDecimal getSourceEquivalent() {
japod@6
    90
		return sourceEquivalent;
japod@6
    91
	}
japod@6
    92
japod@6
    93
	public BigDecimal getDestinationEquivalent() {
japod@6
    94
		return destinationEquivalent;
japod@6
    95
	}
japod@6
    96
japod@6
    97
	public Currency getSourceCurrency() {
japod@6
    98
		return sourceCurrency;
japod@6
    99
	}
japod@6
   100
japod@6
   101
	public Currency getDestinationCurrency() {
japod@6
   102
		return destinationCurrency;
japod@6
   103
	}
japod@6
   104
	
japod@6
   105
	@Override
japod@6
   106
	public String toString() {
japod@6
   107
		return getClass().getName()+" converts "+getSourceCurrency()+" to "+getDestinationCurrency()+" "
japod@6
   108
			+getSourceCurrency()+getSourceEquivalent()+"="+getDestinationCurrency()+getDestinationEquivalent();
japod@6
   109
	}
japod@6
   110
japod@6
   111
	@Override
japod@6
   112
	public int hashCode() {
japod@6
   113
		final int prime = 31;
japod@6
   114
		int result = 1;
japod@6
   115
		result = prime
japod@6
   116
				* result
japod@6
   117
				+ ((destinationCurrency == null) ? 0 : destinationCurrency
japod@6
   118
						.hashCode());
japod@6
   119
		result = prime
japod@6
   120
				* result
japod@6
   121
				+ ((destinationEquivalent == null) ? 0 : destinationEquivalent
japod@6
   122
						.hashCode());
japod@6
   123
		result = prime * result
japod@6
   124
				+ ((sourceCurrency == null) ? 0 : sourceCurrency.hashCode());
japod@6
   125
		result = prime
japod@6
   126
				* result
japod@6
   127
				+ ((sourceEquivalent == null) ? 0 : sourceEquivalent.hashCode());
japod@6
   128
		return result;
japod@6
   129
	}
japod@6
   130
japod@6
   131
	@Override
japod@6
   132
	public boolean equals(Object obj) {
japod@6
   133
		if (this == obj)
japod@6
   134
			return true;
japod@6
   135
		if (obj == null)
japod@6
   136
			return false;
japod@6
   137
		if (!(obj instanceof DefaultConvertor))
japod@6
   138
			return false;
japod@6
   139
		DefaultConvertor other = (DefaultConvertor) obj;
japod@6
   140
		if (destinationCurrency == null) {
japod@6
   141
			if (other.destinationCurrency != null)
japod@6
   142
				return false;
japod@6
   143
		} else if (!destinationCurrency.equals(other.destinationCurrency))
japod@6
   144
			return false;
japod@6
   145
		if (destinationEquivalent == null) {
japod@6
   146
			if (other.destinationEquivalent != null)
japod@6
   147
				return false;
japod@6
   148
		} else if (!destinationEquivalent.equals(other.destinationEquivalent))
japod@6
   149
			return false;
japod@6
   150
		if (sourceCurrency == null) {
japod@6
   151
			if (other.sourceCurrency != null)
japod@6
   152
				return false;
japod@6
   153
		} else if (!sourceCurrency.equals(other.sourceCurrency))
japod@6
   154
			return false;
japod@6
   155
		if (sourceEquivalent == null) {
japod@6
   156
			if (other.sourceEquivalent != null)
japod@6
   157
				return false;
japod@6
   158
		} else if (!sourceEquivalent.equals(other.sourceEquivalent))
japod@6
   159
			return false;
japod@6
   160
		return true;
japod@6
   161
	}
japod@6
   162
japod@6
   163
japod@6
   164
}