task1/solution04/src/org/apidesign/apifest08/currency/CurrencyValues.java
author japod@localhost
Sun, 28 Sep 2008 14:12:38 +0200
changeset 6 97662396c0fd
permissions -rw-r--r--
Adding solutions received for task1
japod@6
     1
package org.apidesign.apifest08.currency;
japod@6
     2
japod@6
     3
japod@6
     4
import java.math.BigDecimal;
japod@6
     5
import java.util.Currency;
japod@6
     6
import java.util.HashMap;
japod@6
     7
import java.util.Map;
japod@6
     8
import java.util.Timer;
japod@6
     9
import java.util.TimerTask;
japod@6
    10
japod@6
    11
japod@6
    12
/**
japod@6
    13
 * Keeps track of the current value for each currency as USD.  
japod@6
    14
 * 
japod@6
    15
 * @author D'Arcy Smith
japod@6
    16
 * @version 1.0
japod@6
    17
 */
japod@6
    18
class CurrencyValues
japod@6
    19
{
japod@6
    20
    /**
japod@6
    21
     * The values expressed in USD.
japod@6
    22
     */
japod@6
    23
    private static Map<Currency, BigDecimal> values;
japod@6
    24
    
japod@6
    25
    /**
japod@6
    26
     * Update the values periodically
japod@6
    27
     */
japod@6
    28
    private static final Timer refresher;
japod@6
    29
japod@6
    30
    static
japod@6
    31
    {
japod@6
    32
        final Refresher refresherTask;
japod@6
    33
        final long delay;
japod@6
    34
japod@6
    35
        // load the map NOW! (don't use the scheduler to do it just because we want
japod@6
    36
        // to be 100% certain it is loaded before anything else can be called.
japod@6
    37
        refresh();
japod@6
    38
japod@6
    39
        refresherTask = new Refresher();
japod@6
    40
        refresher = new Timer("CurrencyValues Refresher", true);
japod@6
    41
japod@6
    42
        // update once an hour
japod@6
    43
        delay = 1000 * 60 * 60;
japod@6
    44
        refresher.scheduleAtFixedRate(refresherTask, delay, delay);
japod@6
    45
    }
japod@6
    46
    
japod@6
    47
    /**
japod@6
    48
     * Prevent accidental creation.
japod@6
    49
     */
japod@6
    50
    private CurrencyValues()
japod@6
    51
    {
japod@6
    52
    }
japod@6
    53
        
japod@6
    54
    /**
japod@6
    55
     * Refresh the currency values.
japod@6
    56
     */
japod@6
    57
    static void refresh()
japod@6
    58
    {
japod@6
    59
        Map<Currency, BigDecimal> newValues;    
japod@6
    60
        Currency                  currency;
japod@6
    61
        
japod@6
    62
        newValues = new HashMap<Currency, BigDecimal>();
japod@6
    63
japod@6
    64
        // these would update from a data source, database, web service, something...
japod@6
    65
        currency = Currency.getInstance("USD");
japod@6
    66
        newValues.put(currency, BigDecimal.valueOf(1.0).setScale(2));
japod@6
    67
        
japod@6
    68
        currency = Currency.getInstance("CZK");
japod@6
    69
        newValues.put(currency, BigDecimal.valueOf(17.0));
japod@6
    70
        
japod@6
    71
        currency = Currency.getInstance("SKK");
japod@6
    72
        newValues.put(currency, BigDecimal.valueOf(21.25));
japod@6
    73
        
japod@6
    74
        // don't sycnhronize all of it because clients can use slightly out of
japod@6
    75
        // date information.
japod@6
    76
        synchronized(CurrencyValues.class)
japod@6
    77
        {
japod@6
    78
            values = newValues;
japod@6
    79
        }
japod@6
    80
    }
japod@6
    81
japod@6
    82
    /**
japod@6
    83
     * Get the value of the specified currency in USD.
japod@6
    84
     * 
japod@6
    85
     * @param currency the corrency to get.
japod@6
    86
     * @return the value of the currency in USD.
japod@6
    87
     * @throws IllegalArgumentException if currency is null.
japod@6
    88
     */
japod@6
    89
    static BigDecimal getValue(final Currency currency)
japod@6
    90
    {
japod@6
    91
        final BigDecimal value;
japod@6
    92
japod@6
    93
        if(currency == null)
japod@6
    94
        {
japod@6
    95
            throw new IllegalArgumentException("currencyName cannot be null");
japod@6
    96
        }
japod@6
    97
japod@6
    98
        // make sure we are not updating the map right now
japod@6
    99
        synchronized(CurrencyValues.class)
japod@6
   100
        {
japod@6
   101
            value = values.get(currency);
japod@6
   102
        }
japod@6
   103
japod@6
   104
        return (value);
japod@6
   105
    }
japod@6
   106
    
japod@6
   107
    /**
japod@6
   108
     * Used to update the currency map periodically.
japod@6
   109
     */
japod@6
   110
    private static class Refresher
japod@6
   111
        extends TimerTask
japod@6
   112
    {
japod@6
   113
        /**
japod@6
   114
         * call the refresh method.
japod@6
   115
         */
japod@6
   116
        @Override
japod@6
   117
        public void run() 
japod@6
   118
        {
japod@6
   119
            refresh();
japod@6
   120
        }
japod@6
   121
    }
japod@6
   122
}