japod@55: package org.apidesign.apifest08.currency; japod@55: japod@55: japod@55: import java.math.BigDecimal; japod@55: import java.util.Currency; japod@55: import java.util.Set; japod@55: japod@55: japod@55: /** japod@55: * A Convertor that looks up the exchange rate with each call to "convert". japod@55: * japod@55: * @author D'Arcy Smith japod@55: * @version 1.0 japod@55: */ japod@55: public class OnlineConvertor japod@55: implements Convertor japod@55: { japod@55: /** japod@55: * The currency to convert from. japod@55: */ japod@55: private final Currency currencyA; japod@55: japod@55: /** japod@55: * The currency to convert to. japod@55: */ japod@55: private final Currency currencyB; japod@55: japod@55: /** japod@55: * Used to find the current exchange rate. japod@55: */ japod@55: private final ExchangeRateFinder finder; japod@55: japod@55: /** japod@55: * The convertor to perform the conversion. japod@55: */ japod@55: private Convertor realConvertor; japod@55: japod@55: /** japod@55: * Constructs an OnlinConvertor with the specified currencies. japod@55: * japod@55: * @param a the currency to convert from. japod@55: * @param b the currency to convert to. japod@55: * @param f the finder used to obtanin the current exchange rate. japod@55: * @throws IllegalArgumentException if either a or b are null. japod@55: */ japod@55: public OnlineConvertor(final Currency a, japod@55: final Currency b, japod@55: final ExchangeRateFinder f) japod@55: { japod@55: if(a == null) japod@55: { japod@55: throw new IllegalArgumentException("a cannot be null"); japod@55: } japod@55: japod@55: if(b == null) japod@55: { japod@55: throw new IllegalArgumentException("b cannot be null"); japod@55: } japod@55: japod@55: if(f == null) japod@55: { japod@55: throw new IllegalArgumentException("f cannot be null"); japod@55: } japod@55: japod@55: currencyA = a; japod@55: currencyB = b; japod@55: finder = f; japod@55: realConvertor = lookupRate(); japod@55: } japod@55: japod@55: /** japod@55: * Convert an amount from one currency to another. Before the conversion takes place japod@55: * the current exchange rate is looked up. japod@55: * japod@55: * @param from the currency to convert from. japod@55: * @param to the currency to convert to. japod@55: * @param amount the amount to convert. japod@55: * @return the converted amount. japod@55: * @throws IllegalArgumentException if any of the arguments are null. japod@55: * @throws InvalidConversionException if either from or to are not equal to the currencies passed to the constructor. japod@55: */ japod@55: public BigDecimal convert(final Currency from, japod@55: final Currency to, japod@55: final BigDecimal amount) japod@55: throws InvalidConversionException japod@55: { japod@55: final BigDecimal value; japod@55: japod@55: synchronized(this) japod@55: { japod@55: realConvertor = lookupRate(); japod@55: value = realConvertor.convert(from, to, amount); japod@55: } japod@55: japod@55: return (value); japod@55: } japod@55: japod@55: /** japod@55: * Lookup the current exchange rate. japod@55: * japod@55: * @return japod@55: */ japod@55: private final Convertor lookupRate() japod@55: { japod@55: final Convertor convertor; japod@55: final ExchangeRate rate; japod@55: japod@55: rate = finder.findRate(currencyA, currencyB); japod@55: convertor = ConvertorFactory.getConvertor(rate.getCurrencyA(), rate.getRateAtoB(), rate.getCurrencyB(), rate.getRateBtoA()); japod@55: japod@55: return (convertor); japod@55: } japod@55: japod@55: /** japod@55: * Check to see if converting between the two currencies is possible. japod@55: * japod@55: * @param from the currency to convert from. japod@55: * @param to the currency to convert to. japod@55: * @return true if the conversion is possible. japod@55: * @throws IllegalArgumentException if either from or to are null. japod@55: */ japod@55: public boolean canConvert(final Currency from, japod@55: final Currency to) japod@55: { japod@55: if(from == null) japod@55: { japod@55: throw new IllegalArgumentException("from cannot be null"); japod@55: } japod@55: japod@55: if(to == null) japod@55: { japod@55: throw new IllegalArgumentException("to cannot be null"); japod@55: } japod@55: japod@55: return (realConvertor.canConvert(from, to)); japod@55: } japod@55: japod@55: /** japod@55: * Get the currencies that the convertor supports. japod@55: * japod@55: * @return the supported currencies. japod@55: */ japod@55: public Set getCurrencies() japod@55: { japod@55: return (realConvertor.getCurrencies()); japod@55: } japod@55: japod@55: /** japod@55: * Get the conversion rate between two currencies. This does not lookup the current japod@55: * conversion rate (it probably should, but given the way the contest works that might japod@55: * not be a good idea - if it were the real world way it might be a good idea). japod@55: * japod@55: * @param from the currency to convert from. japod@55: * @param to the currency to convert to. japod@55: * @return the conversion rate between the two currencies. japod@55: * @throws InvalidConversionException if canConvert would return false. japod@55: * @throws IllegalArgumentException if either from or to are null. japod@55: */ japod@55: public BigDecimal getConversionRate(final Currency from, japod@55: final Currency to) japod@55: throws InvalidConversionException japod@55: { japod@55: if(from == null) japod@55: { japod@55: throw new IllegalArgumentException("from cannot be null"); japod@55: } japod@55: japod@55: if(to == null) japod@55: { japod@55: throw new IllegalArgumentException("to cannot be null"); japod@55: } japod@55: japod@55: return (realConvertor.getConversionRate(from, to)); japod@55: } japod@55: }