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