task4/solution07/src/org/apidesign/apifest08/currency/TimeRangeSpecificConvertor.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Fri, 17 Oct 2008 17:33:32 +0200
changeset 65 8482e36a7ad2
permissions -rw-r--r--
solution 7, task4
     1 package org.apidesign.apifest08.currency;
     2 
     3 import java.util.Currency;
     4 import java.util.Date;
     5 import org.apidesign.apifest08.currency.Convertor.ConversionRequest;
     6 import org.apidesign.apifest08.currency.Convertor.ConversionResult;
     7 
     8 /**
     9  * This {@link Convertor} delegates to an underlying one, provided that the request specifies time between from (included) and till (excluded).
    10  * Otherwise it just refuses to convert.
    11  * @author jdvorak
    12  */
    13 public class TimeRangeSpecificConvertor extends DelegatingConvertor {
    14 
    15     private final Date from;
    16     private final Date till;
    17 
    18     /**
    19      * A new time range specific convertor.
    20      * @param old the underlying convertor one delegates to
    21      * @param from the beginning of the time interval
    22      * @param till the end of the time interval
    23      * @throws IllegalArgumentException unless from comes before till
    24      */
    25     public TimeRangeSpecificConvertor( final Convertor old, final Date from, final Date till ) {
    26         super( old );
    27         this.from = from;
    28         this.till = till;
    29         if (! from.before( till ) ) {
    30             throw new IllegalArgumentException( "from must come before till" );
    31         }
    32     }
    33 
    34     /**
    35      * The beginning of the time interval.
    36      */
    37     public Date getFrom() {
    38         return from;
    39     }
    40 
    41     /**
    42      * The end of the time interval.
    43      */
    44     public Date getTill() {
    45         return till;
    46     }
    47 
    48     /**
    49      * The conversion method.
    50      * Takes a {@link TimeSpecificConversionRequest}, other {@link ConversionRequest}s will result in an exception being thrown.
    51      * @param req the request; must not be null; must be {@link TimeSpecificConversionRequest} or a subclass thereof
    52      * @return the response
    53      * @throws IllegalRequestSubtypeException iff req is not instance of {@link TimeSpecificConversionRequest}
    54      */
    55     @Override
    56     public ConversionResult convert( final ConversionRequest req ) {
    57         if ( req instanceof TimeSpecificConversionRequest ) {
    58             final Date time = ( (TimeSpecificConversionRequest) req ).getTime();
    59             if ( ( from == null || !from.after(time) ) && ( till == null || time.before(till) ) ) {
    60                 return super.convert( req );
    61             } else {
    62                 return new ConversionResult( null );
    63             }
    64         } else {
    65             throw new IllegalRequestSubtypeException( this.getClass().getName() + ".convert() requires a TimeSpecificConversionRequest to be passed in" );
    66         }
    67     }
    68 
    69     /**
    70      * The request for converting a monetary amount into another currency using the conditions that apply at a particular time.
    71      * Immutable.
    72      */
    73     public static class TimeSpecificConversionRequest extends Convertor.ConversionRequest {
    74 
    75         private final Date time;
    76 
    77         /**
    78          * A request to convert srcAmount into tgtCurrency at the current time.
    79          * @param srcAmount the source amount; must not be null
    80          * @param tgtCurrency the currency we want it in afterwards; must not be null
    81          */
    82         public TimeSpecificConversionRequest( final MonetaryAmount srcAmount, final Currency tgtCurrency ) {
    83             this( srcAmount, tgtCurrency, new Date() );
    84         }
    85 
    86         /**
    87          * A request to convert srcAmount into tgtCurrency at given time.
    88          * @param srcAmount the source amount; must not be null
    89          * @param tgtCurrency the currency we want it in afterwards; must not be null
    90          * @param time the time instant when the conversion is to be carried out
    91          */
    92         public TimeSpecificConversionRequest( final MonetaryAmount srcAmount, final Currency tgtCurrency, final Date time ) {
    93             super( srcAmount, tgtCurrency );
    94             this.time = time;
    95             if ( time == null ) {
    96                 throw new NullPointerException( "The time of conversion" );
    97             }
    98         }
    99 
   100         /**
   101          * The time as of which the conversion is to be carried out.
   102          */
   103         public Date getTime() {
   104             return time;
   105         }
   106 
   107     }
   108 
   109 }