1.1 --- a/task3/solution04/src/org/apidesign/apifest08/currency/CompositeConvertorImpl.java Fri Oct 10 22:02:31 2008 +0200
1.2 +++ b/task3/solution04/src/org/apidesign/apifest08/currency/CompositeConvertorImpl.java Fri Oct 10 22:05:15 2008 +0200
1.3 @@ -16,7 +16,7 @@
1.4 * A composite convertor will build all possible conversions that are allowed by the underlying set of convertors.
1.5 *
1.6 * @author D'Arcy Smith
1.7 - * @verson 1.0
1.8 + * @verson 1.1
1.9 */
1.10 final class CompositeConvertorImpl
1.11 implements Convertor
1.12 @@ -220,6 +220,38 @@
1.13 return (convertor.getConversionRate(from, to));
1.14 }
1.15
1.16 + private Convertor getConvertor(final Currency from, final Currency to)
1.17 + throws InvalidConversionException
1.18 + {
1.19 + final Map<Currency, Convertor> possible;
1.20 + Convertor convertor;
1.21 +
1.22 + if(from == null)
1.23 + {
1.24 + throw new IllegalArgumentException("from cannot be null");
1.25 + }
1.26 +
1.27 + if(to == null)
1.28 + {
1.29 + throw new IllegalArgumentException("to cannot be null");
1.30 + }
1.31 +
1.32 + if(!(canConvert(from, to)))
1.33 + {
1.34 + throw new InvalidConversionException("cannot convert", to);
1.35 + }
1.36 +
1.37 + possible = possibleConversions.get(from);
1.38 + convertor = possible.get(to);
1.39 +
1.40 + if(convertor == null)
1.41 + {
1.42 + throw new Error();
1.43 + }
1.44 +
1.45 + return (convertor);
1.46 + }
1.47 +
1.48 /**
1.49 * Convert an amount from one currency to another.
1.50 *
1.51 @@ -236,6 +268,7 @@
1.52 throws InvalidConversionException
1.53 {
1.54 final BigDecimal result;
1.55 + final Convertor convertor;
1.56
1.57 if(amount == null)
1.58 {
1.59 @@ -252,7 +285,11 @@
1.60 throw new IllegalArgumentException("to cannot be null");
1.61 }
1.62
1.63 - result = amount.multiply(getConversionRate(from, to));
1.64 + // fixed a bug from Task2 that showed up in Task3... before we did the conversion here,
1.65 + // but that meant that the underlying covnerter convert method never got called... which
1.66 + // meant that in Task3 the exchange rate never changed.
1.67 + convertor = getConvertor(from, to);
1.68 + result = convertor.convert(from, to, amount);
1.69
1.70 return (result.setScale(2, RoundingMode.HALF_DOWN));
1.71 }
1.72 @@ -300,8 +337,7 @@
1.73
1.74 fromRate = fromIntermediary.getConversionRate(from, intermediary);
1.75 toRate = toIntermediary.getConversionRate(intermediary, to);
1.76 - rate = fromRate.multiply(toRate);
1.77 -
1.78 + rate = fromRate.multiply(toRate);
1.79 convertor = ConvertorFactory.getConvertor(from, BigDecimal.ONE, to, rate);
1.80
1.81 return (convertor);
2.1 --- a/task3/solution04/src/org/apidesign/apifest08/currency/ConverterImpl.java Fri Oct 10 22:02:31 2008 +0200
2.2 +++ b/task3/solution04/src/org/apidesign/apifest08/currency/ConverterImpl.java Fri Oct 10 22:05:15 2008 +0200
2.3 @@ -20,12 +20,12 @@
2.4 implements Convertor
2.5 {
2.6 /**
2.7 - * The currency to cvonvert from.
2.8 + * The currency to convert from.
2.9 */
2.10 private final Currency currencyA;
2.11
2.12 /**
2.13 - * The currency to cvonvert from.
2.14 + * The currency to convert to.
2.15 */
2.16 private final Currency currencyB;
2.17
2.18 @@ -142,9 +142,20 @@
2.19 * @param from the currency to convert from.
2.20 * @param to the currency to convert to.
2.21 * @return true if the conversion is possible.
2.22 + * @throws IllegalArgumentException if either from or to are null.
2.23 */
2.24 public boolean canConvert(final Currency from, final Currency to)
2.25 {
2.26 + if(from == null)
2.27 + {
2.28 + throw new IllegalArgumentException("from cannot be null");
2.29 + }
2.30 +
2.31 + if(to == null)
2.32 + {
2.33 + throw new IllegalArgumentException("to cannot be null");
2.34 + }
2.35 +
2.36 return ((from.equals(currencyA) || from.equals(currencyB)) &&
2.37 (to.equals(currencyA) || to.equals(currencyB)));
2.38 }
2.39 @@ -172,12 +183,23 @@
2.40 * @param to the currency to convert to.
2.41 * @return the conversion rate between the two currencies.
2.42 * @throws InvalidConversionException if canConvert would return false.
2.43 + * @throws IllegalArgumentException if either from or to are null.
2.44 */
2.45 public BigDecimal getConversionRate(final Currency from,
2.46 final Currency to)
2.47 throws InvalidConversionException
2.48 - {
2.49 + {
2.50 final BigDecimal rate;
2.51 +
2.52 + if(from == null)
2.53 + {
2.54 + throw new IllegalArgumentException("from cannot be null");
2.55 + }
2.56 +
2.57 + if(to == null)
2.58 + {
2.59 + throw new IllegalArgumentException("to cannot be null");
2.60 + }
2.61
2.62 if(from.equals(to))
2.63 {
3.1 --- a/task3/solution04/src/org/apidesign/apifest08/currency/ConvertorFactory.java Fri Oct 10 22:02:31 2008 +0200
3.2 +++ b/task3/solution04/src/org/apidesign/apifest08/currency/ConvertorFactory.java Fri Oct 10 22:05:15 2008 +0200
3.3 @@ -115,6 +115,11 @@
3.4 return (convertor);
3.5 }
3.6
3.7 + /**
3.8 + *
3.9 + * @param cs
3.10 + * @return
3.11 + */
3.12 public static Convertor mergeConvertors(final Convertor ... cs)
3.13 {
3.14 Convertor convertor;
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/task3/solution04/src/org/apidesign/apifest08/currency/ExchangeRate.java Fri Oct 10 22:05:15 2008 +0200
4.3 @@ -0,0 +1,125 @@
4.4 +package org.apidesign.apifest08.currency;
4.5 +
4.6 +
4.7 +import java.math.BigDecimal;
4.8 +import java.util.Currency;
4.9 +
4.10 +
4.11 +/**
4.12 + * The exchange rate between two currencies.
4.13 + *
4.14 + * @author D'Arcy Smith
4.15 + * @version 1.0
4.16 + */
4.17 +public final class ExchangeRate
4.18 +{
4.19 + /**
4.20 + *
4.21 + */
4.22 + private final Currency currencyA;
4.23 +
4.24 + /**
4.25 + *
4.26 + */
4.27 + private final Currency currencyB;
4.28 +
4.29 + /**
4.30 + *
4.31 + */
4.32 + private final BigDecimal rateAtoB;
4.33 +
4.34 + /**
4.35 + *
4.36 + */
4.37 + private final BigDecimal rateBtoA;
4.38 +
4.39 + /**
4.40 + * Construct an ExchangeRate with the specified values.
4.41 + *
4.42 + * @param a the first currency
4.43 + * @param b the second currency
4.44 + * @param ra the rate to convert a to b
4.45 + * @param rb the rate to covertt b to a
4.46 + * @throws IllegalArgumentException if any parameter is null.
4.47 + */
4.48 + public ExchangeRate(final Currency a,
4.49 + final Currency b,
4.50 + final BigDecimal ra,
4.51 + final BigDecimal rb)
4.52 + {
4.53 + if(a == null)
4.54 + {
4.55 + throw new IllegalArgumentException("a cannot be null");
4.56 + }
4.57 +
4.58 + if(b == null)
4.59 + {
4.60 + throw new IllegalArgumentException("b cannot be null");
4.61 + }
4.62 +
4.63 + if(ra == null)
4.64 + {
4.65 + throw new IllegalArgumentException("ra cannot be null");
4.66 + }
4.67 +
4.68 + if(rb == null)
4.69 + {
4.70 + throw new IllegalArgumentException("rb cannot be null");
4.71 + }
4.72 +
4.73 + if(ra.compareTo(BigDecimal.ZERO) <= 0)
4.74 + {
4.75 + throw new IllegalArgumentException("ra cannot be <= 0, was: " + ra);
4.76 + }
4.77 +
4.78 + if(rb.compareTo(BigDecimal.ZERO) <= 0)
4.79 + {
4.80 + throw new IllegalArgumentException("rb cannot be <= 0, was: " + ra);
4.81 + }
4.82 +
4.83 + currencyA = a;
4.84 + currencyB = b;
4.85 + rateAtoB = ra;
4.86 + rateBtoA = rb;
4.87 + }
4.88 +
4.89 + /**
4.90 + * Get the first currency.
4.91 + *
4.92 + * @return the first currency.
4.93 + */
4.94 + public Currency getCurrencyA()
4.95 + {
4.96 + return currencyA;
4.97 + }
4.98 +
4.99 + /**
4.100 + * Get the second currency.
4.101 + *
4.102 + * @return the second currency.
4.103 + */
4.104 + public Currency getCurrencyB()
4.105 + {
4.106 + return currencyB;
4.107 + }
4.108 +
4.109 + /**
4.110 + * Get the conversion rate from currencyA to currencyB.
4.111 + *
4.112 + * @return the conversion rate from currencyA to currencyB.
4.113 + */
4.114 + public BigDecimal getRateAtoB()
4.115 + {
4.116 + return rateAtoB;
4.117 + }
4.118 +
4.119 + /**
4.120 + * Get the conversion rate from currencyB to currencyA.
4.121 + *
4.122 + * @return the conversion rate from currencyB to currencyA.
4.123 + */
4.124 + public BigDecimal getRateBtoA()
4.125 + {
4.126 + return rateBtoA;
4.127 + }
4.128 +}
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/task3/solution04/src/org/apidesign/apifest08/currency/ExchangeRateFinder.java Fri Oct 10 22:05:15 2008 +0200
5.3 @@ -0,0 +1,22 @@
5.4 +package org.apidesign.apifest08.currency;
5.5 +
5.6 +import java.util.Currency;
5.7 +
5.8 +
5.9 +/**
5.10 + * Used to look up the exchange rate between two currencies.
5.11 + *
5.12 + * @author D'Arcy Smith
5.13 + * @version 1.0
5.14 + */
5.15 +public interface ExchangeRateFinder
5.16 +{
5.17 + /**
5.18 + * Find the exchange rate between two currencies.
5.19 + *
5.20 + * @param a the currency to convert from.
5.21 + * @param b the currency to convert to.
5.22 + * @return the exchange rate for conversions between the two currencies.
5.23 + */
5.24 + ExchangeRate findRate(Currency a, Currency b);
5.25 +}
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/task3/solution04/src/org/apidesign/apifest08/currency/OnlineConvertor.java Fri Oct 10 22:05:15 2008 +0200
6.3 @@ -0,0 +1,175 @@
6.4 +package org.apidesign.apifest08.currency;
6.5 +
6.6 +
6.7 +import java.math.BigDecimal;
6.8 +import java.util.Currency;
6.9 +import java.util.Set;
6.10 +
6.11 +
6.12 +/**
6.13 + * A Convertor that looks up the exchange rate with each call to "convert".
6.14 + *
6.15 + * @author D'Arcy Smith
6.16 + * @version 1.0
6.17 + */
6.18 +public class OnlineConvertor
6.19 + implements Convertor
6.20 +{
6.21 + /**
6.22 + * The currency to convert from.
6.23 + */
6.24 + private final Currency currencyA;
6.25 +
6.26 + /**
6.27 + * The currency to convert to.
6.28 + */
6.29 + private final Currency currencyB;
6.30 +
6.31 + /**
6.32 + * Used to find the current exchange rate.
6.33 + */
6.34 + private final ExchangeRateFinder finder;
6.35 +
6.36 + /**
6.37 + * The convertor to perform the conversion.
6.38 + */
6.39 + private Convertor realConvertor;
6.40 +
6.41 + /**
6.42 + * Constructs an OnlinConvertor with the specified currencies.
6.43 + *
6.44 + * @param a the currency to convert from.
6.45 + * @param b the currency to convert to.
6.46 + * @param f the finder used to obtanin the current exchange rate.
6.47 + * @throws IllegalArgumentException if either a or b are null.
6.48 + */
6.49 + public OnlineConvertor(final Currency a,
6.50 + final Currency b,
6.51 + final ExchangeRateFinder f)
6.52 + {
6.53 + if(a == null)
6.54 + {
6.55 + throw new IllegalArgumentException("a cannot be null");
6.56 + }
6.57 +
6.58 + if(b == null)
6.59 + {
6.60 + throw new IllegalArgumentException("b cannot be null");
6.61 + }
6.62 +
6.63 + if(f == null)
6.64 + {
6.65 + throw new IllegalArgumentException("f cannot be null");
6.66 + }
6.67 +
6.68 + currencyA = a;
6.69 + currencyB = b;
6.70 + finder = f;
6.71 + realConvertor = lookupRate();
6.72 + }
6.73 +
6.74 + /**
6.75 + * Convert an amount from one currency to another. Before the conversion takes place
6.76 + * the current exchange rate is looked up.
6.77 + *
6.78 + * @param from the currency to convert from.
6.79 + * @param to the currency to convert to.
6.80 + * @param amount the amount to convert.
6.81 + * @return the converted amount.
6.82 + * @throws IllegalArgumentException if any of the arguments are null.
6.83 + * @throws InvalidConversionException if either from or to are not equal to the currencies passed to the constructor.
6.84 + */
6.85 + public BigDecimal convert(final Currency from,
6.86 + final Currency to,
6.87 + final BigDecimal amount)
6.88 + throws InvalidConversionException
6.89 + {
6.90 + final BigDecimal value;
6.91 +
6.92 + synchronized(this)
6.93 + {
6.94 + realConvertor = lookupRate();
6.95 + value = realConvertor.convert(from, to, amount);
6.96 + }
6.97 +
6.98 + return (value);
6.99 + }
6.100 +
6.101 + /**
6.102 + * Lookup the current exchange rate.
6.103 + *
6.104 + * @return
6.105 + */
6.106 + private final Convertor lookupRate()
6.107 + {
6.108 + final Convertor convertor;
6.109 + final ExchangeRate rate;
6.110 +
6.111 + rate = finder.findRate(currencyA, currencyB);
6.112 + convertor = ConvertorFactory.getConvertor(rate.getCurrencyA(), rate.getRateAtoB(), rate.getCurrencyB(), rate.getRateBtoA());
6.113 +
6.114 + return (convertor);
6.115 + }
6.116 +
6.117 + /**
6.118 + * Check to see if converting between the two currencies is possible.
6.119 + *
6.120 + * @param from the currency to convert from.
6.121 + * @param to the currency to convert to.
6.122 + * @return true if the conversion is possible.
6.123 + * @throws IllegalArgumentException if either from or to are null.
6.124 + */
6.125 + public boolean canConvert(final Currency from,
6.126 + final Currency to)
6.127 + {
6.128 + if(from == null)
6.129 + {
6.130 + throw new IllegalArgumentException("from cannot be null");
6.131 + }
6.132 +
6.133 + if(to == null)
6.134 + {
6.135 + throw new IllegalArgumentException("to cannot be null");
6.136 + }
6.137 +
6.138 + return (realConvertor.canConvert(from, to));
6.139 + }
6.140 +
6.141 + /**
6.142 + * Get the currencies that the convertor supports.
6.143 + *
6.144 + * @return the supported currencies.
6.145 + */
6.146 + public Set<Currency> getCurrencies()
6.147 + {
6.148 + return (realConvertor.getCurrencies());
6.149 + }
6.150 +
6.151 + /**
6.152 + * Get the conversion rate between two currencies. This does not lookup the current
6.153 + * conversion rate (it probably should, but given the way the contest works that might
6.154 + * not be a good idea - if it were the real world way it might be a good idea).
6.155 + *
6.156 + * @param from the currency to convert from.
6.157 + * @param to the currency to convert to.
6.158 + * @return the conversion rate between the two currencies.
6.159 + * @throws InvalidConversionException if canConvert would return false.
6.160 + * @throws IllegalArgumentException if either from or to are null.
6.161 + */
6.162 + public BigDecimal getConversionRate(final Currency from,
6.163 + final Currency to)
6.164 + throws InvalidConversionException
6.165 + {
6.166 + if(from == null)
6.167 + {
6.168 + throw new IllegalArgumentException("from cannot be null");
6.169 + }
6.170 +
6.171 + if(to == null)
6.172 + {
6.173 + throw new IllegalArgumentException("to cannot be null");
6.174 + }
6.175 +
6.176 + return (realConvertor.getConversionRate(from, to));
6.177 + }
6.178 +}
7.1 --- a/task3/solution04/test/org/apidesign/apifest08/test/Task3Test.java Fri Oct 10 22:02:31 2008 +0200
7.2 +++ b/task3/solution04/test/org/apidesign/apifest08/test/Task3Test.java Fri Oct 10 22:05:15 2008 +0200
7.3 @@ -1,7 +1,11 @@
7.4 package org.apidesign.apifest08.test;
7.5
7.6 +import java.math.BigDecimal;
7.7 +import java.util.Currency;
7.8 import junit.framework.TestCase;
7.9 import org.apidesign.apifest08.currency.Convertor;
7.10 +import org.apidesign.apifest08.currency.InvalidConversionException;
7.11 +import org.apidesign.apifest08.currency.OnlineConvertor;
7.12
7.13 /** The exchange rates are not always the same. They are changing. Day by day,
7.14 * hour by hour, minute by minute. For every bank it is important to always
7.15 @@ -15,17 +19,33 @@
7.16 * he does not know how the whole system looks and how the convertor is supposed
7.17 * to be used.
7.18 */
7.19 -public class Task3Test extends TestCase {
7.20 - public Task3Test(String testName) {
7.21 +public class Task3Test
7.22 + extends TestCase
7.23 +{
7.24 + private final static Currency CZK;
7.25 + private final static Currency SKK;
7.26 + private final static Currency USD;
7.27 +
7.28 + static
7.29 + {
7.30 + CZK = Currency.getInstance("CZK");
7.31 + SKK = Currency.getInstance("SKK");
7.32 + USD = Currency.getInstance("USD");
7.33 + }
7.34 +
7.35 + public Task3Test(String testName)
7.36 + {
7.37 super(testName);
7.38 }
7.39
7.40 @Override
7.41 - protected void setUp() throws Exception {
7.42 + protected void setUp() throws Exception
7.43 + {
7.44 }
7.45
7.46 @Override
7.47 - protected void tearDown() throws Exception {
7.48 + protected void tearDown() throws Exception
7.49 + {
7.50 }
7.51
7.52 // Backward compatibly enhance your existing API to support following
7.53 @@ -41,8 +61,21 @@
7.54 * until you reach 1USD = 16CZK
7.55 *
7.56 * @return new instance of "online" USD and CZK convertor starting with rate 1USD = 16CZK
7.57 + * @throws InvalidConversionException
7.58 */
7.59 - public static Convertor createOnlineCZKUSDConvertor() {
7.60 + public static Convertor createOnlineCZKUSDConvertor()
7.61 + throws InvalidConversionException
7.62 + {
7.63 + final Convertor convertor;
7.64 +
7.65 + convertor = new OnlineConvertor(USD,
7.66 + CZK,
7.67 + new TestExchangeRateFinder(new BigDecimal("15.00"),
7.68 + new BigDecimal("16.00"),
7.69 + new BigDecimal("16.00"),
7.70 + new BigDecimal("0.01"),
7.71 + new BigDecimal("-0.01")));
7.72 +
7.73 // initial rate: 1USD = 16CZK
7.74 // 2nd query 1USD = 15.99CZK
7.75 // 3rd query 1USD = 15.98CZK
7.76 @@ -51,10 +84,12 @@
7.77 // then 1USD = 15.02CZK
7.78 // and so on and on up to 1USD = 16CZK
7.79 // and then another round to 15, etc.
7.80 - return null;
7.81 + return convertor;
7.82 }
7.83
7.84 - public void testFewQueriesForOnlineConvertor() {
7.85 + public void testFewQueriesForOnlineConvertor()
7.86 + throws InvalidConversionException
7.87 + {
7.88 if (Boolean.getBoolean("ignore.failing")) {
7.89 // implement me!
7.90 return;
7.91 @@ -64,25 +99,37 @@
7.92 doFewQueriesForOnlineConvertor(c);
7.93 }
7.94
7.95 - static void doFewQueriesForOnlineConvertor(Convertor c) {
7.96 + static void doFewQueriesForOnlineConvertor(Convertor c)
7.97 + throws InvalidConversionException
7.98 + {
7.99 + BigDecimal amount;
7.100 +
7.101 // convert $5 to CZK using c:
7.102 //assertEquals("Result is 80 CZK");
7.103 + amount = c.convert(USD, CZK, new BigDecimal("5.00"));
7.104 + assertEquals(new BigDecimal("80.00"), amount);
7.105
7.106 // convert $8 to CZK using c:
7.107 //assertEquals("Result is 127.92 CZK");
7.108 + amount = c.convert(USD, CZK, new BigDecimal("8.00"));
7.109 + assertEquals(new BigDecimal("127.92"), amount);
7.110
7.111 // convert $1 to CZK using c:
7.112 //assertEquals("Result is 15.98 CZK");
7.113 + amount = c.convert(USD, CZK, new BigDecimal("1.00"));
7.114 + assertEquals(new BigDecimal("15.98"), amount);
7.115
7.116 // convert 15.97CZK to USD using c:
7.117 //assertEquals("Result is 1$");
7.118 -
7.119 - fail("Implement me!");
7.120 + amount = c.convert(CZK, USD, new BigDecimal("15.97"));
7.121 + assertEquals(new BigDecimal("1.00"), amount);
7.122 }
7.123
7.124 /** Join the convertors and show they behave sane.
7.125 */
7.126 public void testOnlineConvertorComposition() throws Exception {
7.127 + BigDecimal amount;
7.128 +
7.129 if (Boolean.getBoolean("ignore.failing")) {
7.130 // implement me!
7.131 return;
7.132 @@ -95,9 +142,13 @@
7.133
7.134 // convert 16CZK to SKK using c:
7.135 // assertEquals("Result is 20 SKK");
7.136 -
7.137 + amount = c.convert(CZK, SKK, new BigDecimal("16.00"));
7.138 + assertEquals(new BigDecimal("20.00"), amount);
7.139 +
7.140 // convert 500SKK to CZK using c:
7.141 // assertEquals("Result is 400 CZK");
7.142 + amount = c.convert(SKK, CZK, new BigDecimal("500.00"));
7.143 + assertEquals(new BigDecimal("400.00"), amount);
7.144
7.145 doFewQueriesForOnlineConvertor(c);
7.146 }
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
8.2 +++ b/task3/solution04/test/org/apidesign/apifest08/test/TestExchangeRateFinder.java Fri Oct 10 22:05:15 2008 +0200
8.3 @@ -0,0 +1,61 @@
8.4 +package org.apidesign.apifest08.test;
8.5 +
8.6 +
8.7 +import java.math.BigDecimal;
8.8 +import java.util.Currency;
8.9 +import org.apidesign.apifest08.currency.ExchangeRate;
8.10 +import org.apidesign.apifest08.currency.ExchangeRateFinder;
8.11 +
8.12 +
8.13 +class TestExchangeRateFinder
8.14 + implements ExchangeRateFinder
8.15 +{
8.16 + private final BigDecimal min;
8.17 + private final BigDecimal max;
8.18 + private final BigDecimal stepUp;
8.19 + private final BigDecimal stepDown;
8.20 + private BigDecimal step;
8.21 + private BigDecimal rate;
8.22 + private boolean firstCall;
8.23 +
8.24 + TestExchangeRateFinder(final BigDecimal mn,
8.25 + final BigDecimal mx,
8.26 + final BigDecimal start,
8.27 + final BigDecimal up,
8.28 + final BigDecimal down)
8.29 + {
8.30 + min = mn;
8.31 + max = mx;
8.32 + rate = start;
8.33 + stepUp = up;
8.34 + stepDown = down;
8.35 + firstCall = true;
8.36 + }
8.37 +
8.38 + public ExchangeRate findRate(Currency a, Currency b)
8.39 + {
8.40 + final ExchangeRate value;
8.41 +
8.42 + if(rate.equals(max))
8.43 + {
8.44 + step = stepDown;
8.45 + }
8.46 + else if(rate.equals(min))
8.47 + {
8.48 + step = stepUp;
8.49 + }
8.50 +
8.51 + value = new ExchangeRate(a, b, BigDecimal.ONE, rate);
8.52 +
8.53 + if(firstCall)
8.54 + {
8.55 + firstCall = false;
8.56 + }
8.57 + else
8.58 + {
8.59 + rate = rate.add(step);
8.60 + }
8.61 +
8.62 + return (value);
8.63 + }
8.64 +}