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