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