japod@6: package org.apidesign.apifest08.currency; japod@6: japod@6: import java.io.Serializable; japod@6: import java.math.BigDecimal; japod@6: import java.math.RoundingMode; japod@6: import java.util.Currency; japod@6: japod@6: /** japod@6: * Default {@link Convertor} implementation. Exchange rate is stored as equivalents. It means if we have USD to CZK convertor and USD1 = CZK17 japod@6: * we store 1 in sourceEquivalent and 17 in destinationEquivalent. This class is immutable. japod@6: * @author lukas japod@6: * japod@6: */ japod@34: class DefaultConvertor implements ExtendedConvertor, Serializable { japod@6: japod@34: private static final long serialVersionUID = 6660014633685135034L; japod@6: japod@6: /** japod@6: * Equivalent in source currency. japod@6: */ japod@6: private final BigDecimal sourceEquivalent; japod@6: japod@6: /** japod@6: * Equivalent in destination currency. japod@6: */ japod@6: private final BigDecimal destinationEquivalent; japod@6: japod@6: private final Currency sourceCurrency; japod@6: japod@6: private final Currency destinationCurrency; japod@6: japod@34: public DefaultConvertor(Money sourceEquivalent, Money destinationEquivalent) { japod@6: super(); japod@34: if (BigDecimal.ZERO.compareTo(sourceEquivalent.getAmount())==0) japod@16: { japod@16: throw new IllegalArgumentException("Source equivalent amount can not be 0."); japod@16: } japod@34: if (BigDecimal.ZERO.compareTo(destinationEquivalent.getAmount())==0) japod@16: { japod@16: throw new IllegalArgumentException("Destination equivalent amount can not be 0."); japod@16: } japod@34: this.sourceEquivalent = sourceEquivalent.getAmount(); japod@34: this.destinationEquivalent = destinationEquivalent.getAmount(); japod@34: this.sourceCurrency = sourceEquivalent.getCurrency(); japod@34: this.destinationCurrency = destinationEquivalent.getCurrency(); japod@6: } japod@6: japod@16: public Money convert(Money amount, Currency destinationCurrency) { japod@16: if (amount==null) japod@6: { japod@6: throw new NullPointerException("Money is null"); japod@6: } japod@16: if (destinationCurrency==null) japod@6: { japod@16: throw new NullPointerException("destionationCurrency is null"); japod@6: } japod@16: if (!amount.getCurrency().equals(getSourceCurrency())) japod@16: { japod@16: throw new IllegalArgumentException("Can not convert from "+amount.getCurrency()+". Converts between "+getSourceCurrency()+" and "+getDestinationCurrency()); japod@16: } japod@16: if (!getDestinationCurrency().equals(destinationCurrency)) japod@16: { japod@16: throw new IllegalArgumentException("Can not convert to "+destinationCurrency+". Converts between "+getSourceCurrency()+" and "+getDestinationCurrency()); japod@16: } japod@16: BigDecimal sourceAmount = amount.getAmount(); japod@16: BigDecimal destinationAmount = sourceAmount.multiply(destinationEquivalent).divide(sourceEquivalent, 2, RoundingMode.HALF_UP); japod@6: return new MoneyImpl(destinationAmount, getDestinationCurrency()); japod@6: } japod@34: japod@34: public boolean isConversionSupported(Currency from, Currency to) { japod@34: return sourceCurrency.equals(from) && destinationCurrency.equals(to); japod@6: } japod@6: japod@6: public BigDecimal getSourceEquivalent() { japod@6: return sourceEquivalent; japod@6: } japod@6: japod@6: public BigDecimal getDestinationEquivalent() { japod@6: return destinationEquivalent; japod@6: } japod@6: japod@6: public Currency getSourceCurrency() { japod@6: return sourceCurrency; japod@6: } japod@6: japod@6: public Currency getDestinationCurrency() { japod@6: return destinationCurrency; japod@6: } japod@6: japod@6: @Override japod@6: public String toString() { japod@6: return getClass().getName()+" converts "+getSourceCurrency()+" to "+getDestinationCurrency()+" " japod@6: +getSourceCurrency()+getSourceEquivalent()+"="+getDestinationCurrency()+getDestinationEquivalent(); japod@6: } japod@6: }