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