task2/solution04/src/org/apidesign/apifest08/currency/ConverterImpl.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Wed, 01 Oct 2008 10:43:05 +0200
changeset 29 f6073056b9fe
parent 17 task1/solution04/src/org/apidesign/apifest08/currency/ConverterImpl.java@37c9921c653e
child 35 8898c620fe96
permissions -rw-r--r--
Getting ready for task2: copying all solutions to new locations
     1 package org.apidesign.apifest08.currency;
     2 
     3 
     4 import java.math.BigDecimal;
     5 import java.math.MathContext;
     6 import java.math.RoundingMode;
     7 import java.util.Currency;
     8 
     9 
    10 /**
    11  * Convert between two currencies.
    12  *
    13  * @author D'Arcy Smith
    14  * @version 1.0
    15  */
    16 final class ConvertorImpl
    17     implements Convertor
    18 {
    19     /**
    20      * The currency to cvonvert from.
    21      */
    22     private final Currency currencyA;
    23 
    24     /**
    25      * The currency to cvonvert from.
    26      */
    27     private final Currency currencyB;
    28 
    29     /**
    30      * The echange rate between a and b.
    31      */
    32     private final BigDecimal currencyARate;
    33 
    34     /**
    35      * The echange rate between b and a.
    36      */
    37     private final BigDecimal currencyBRate;
    38     
    39     /**
    40      * Constructs a convertor with the specified currencies.
    41      * 
    42      * @param a the currency to convert from.
    43      * @param aRate the exchage rage between from and to.
    44      * @param b the currency to convert to.
    45      * @param bRate the exchage rage between to and from.
    46      * @throws IllegalArgumentException if either any of the arguments are null or if either rate <= 0.
    47      */
    48     public ConvertorImpl(final Currency   a,
    49                          final BigDecimal aRate,
    50                          final Currency   b,
    51                          final BigDecimal bRate)
    52     {
    53         if(a == null)
    54         {
    55             throw new IllegalArgumentException("a cannot be null");
    56         }
    57 
    58         if(b == null)
    59         {
    60             throw new IllegalArgumentException("b cannot be null");
    61         }
    62 
    63         if(aRate == null)
    64         {
    65             throw new IllegalArgumentException("aRate cannot be null");
    66         }
    67 
    68         if(bRate == null)
    69         {
    70             throw new IllegalArgumentException("bRate cannot be null");
    71         }
    72                 
    73         if(aRate.compareTo(BigDecimal.ZERO) <= 0)
    74         {
    75             throw new IllegalArgumentException("aRate must be > 0, was: " + aRate);
    76         }
    77                 
    78         if(bRate.compareTo(BigDecimal.ZERO) <= 0)
    79         {
    80             throw new IllegalArgumentException("bRate must be > 0, was: " + bRate);
    81         }
    82         
    83         currencyA     = a;
    84         currencyB     = b;
    85         currencyARate = aRate;
    86         currencyBRate = bRate;
    87     }
    88     
    89     /**
    90      * Convert an amount from one currency to another.
    91      * 
    92      * @param from the currency to convert from.
    93      * @param to the currency to convert to.
    94      * @param amount the amount to convert.
    95      * @return the converted amount.
    96      * @throws IllegalArgumentException if any of the arguments are null.
    97      * @throws InvalidConversionException if either from or to are not equal to the currencies passed to the constructor.
    98      */
    99     public BigDecimal convert(final Currency   from,
   100                               final Currency   to,
   101                               final BigDecimal amount)
   102         throws InvalidConversionException
   103     {
   104         final BigDecimal result;
   105         
   106         if(amount == null)
   107         {
   108             throw new IllegalArgumentException("amount cannot be null");
   109         }
   110         
   111         if(from == null)
   112         {
   113             throw new IllegalArgumentException("from cannot be null");
   114         }
   115         
   116         if(to == null)
   117         {
   118             throw new IllegalArgumentException("to cannot be null");
   119         }
   120         
   121         if(!(from.equals(currencyA)) && (!(from.equals(currencyB))))
   122         {
   123             throw new InvalidConversionException("cannot convert from: " + from.getCurrencyCode(), from, currencyA, currencyB);
   124         }
   125         
   126         if(!(to.equals(currencyA)) && (!(to.equals(currencyB))))
   127         {
   128             throw new InvalidConversionException("cannot convert to: " + to.getCurrencyCode(), to, currencyA, currencyB);
   129         }
   130 
   131         // converting between the same currency is no converstion at all.
   132         if(from.equals(to))
   133         {
   134             result = amount;
   135         }
   136         else
   137         {
   138             final BigDecimal rateX;
   139             final BigDecimal rateY;
   140             final BigDecimal temp;
   141             
   142             if(from.equals(currencyA))
   143             {
   144                 rateX = currencyARate;
   145                 rateY = currencyBRate;
   146             }
   147             else
   148             {
   149                 rateX = currencyBRate;
   150                 rateY = currencyARate;
   151             }
   152 
   153             temp   = amount.divide(rateX, MathContext.DECIMAL32);
   154             result = temp.multiply(rateY);
   155         }
   156 
   157         return (result.setScale(2, RoundingMode.HALF_DOWN));
   158     }
   159 }