task4/solution07/src/org/apidesign/apifest08/currency/TableConvertor.java
changeset 61 58ec6da75f6f
parent 45 251d0ed461fb
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/task4/solution07/src/org/apidesign/apifest08/currency/TableConvertor.java	Sat Oct 11 23:38:46 2008 +0200
     1.3 @@ -0,0 +1,71 @@
     1.4 +package org.apidesign.apifest08.currency;
     1.5 +
     1.6 +import java.util.Currency;
     1.7 +import java.util.HashMap;
     1.8 +import java.util.Map;
     1.9 +
    1.10 +/**
    1.11 + * A {@link Convertor} that works from a pre-set conversion table.
    1.12 + * First use {@link #putIntoTable(org.apidesign.apifest08.currency.ConversionRate)} to set the conversion table.
    1.13 + * Then invoke the {@link #convert(org.apidesign.apifest08.currency.Convertor.ConversionRequest)} method as many times as you wish.
    1.14 + * @author jdvorak
    1.15 + */
    1.16 +public class TableConvertor implements Convertor {
    1.17 +
    1.18 +    private final Map<Currency, Map<Currency, ConversionRate>> conversionTable = new HashMap<Currency, Map<Currency, ConversionRate>>();
    1.19 +    
    1.20 +    public TableConvertor() {
    1.21 +    }
    1.22 +
    1.23 +    /**
    1.24 +     * Puts a rate into the table.
    1.25 +     * @param rate
    1.26 +     */
    1.27 +    public void putIntoTable( final ConversionRate rate ) {
    1.28 +        final Currency srcCurrency = rate.getSrcUnitAmount().getCurrency();
    1.29 +        final Currency tgtCurrency = rate.getTgtUnitAmount().getCurrency();
    1.30 +        synchronized ( conversionTable ) {
    1.31 +            Map<Currency, ConversionRate> targetTable = conversionTable.get( srcCurrency );
    1.32 +            if ( targetTable == null ) {
    1.33 +                targetTable = new HashMap<Currency, ConversionRate>();
    1.34 +                conversionTable.put( srcCurrency, targetTable );
    1.35 +            }
    1.36 +            targetTable.put( tgtCurrency, rate );
    1.37 +        }
    1.38 +    }
    1.39 +    
    1.40 +    /**
    1.41 +     * Carries out the conversion.
    1.42 +     * If the table does not contain a conversion from the source currency to the target one,
    1.43 +     * a {@link ConversionResult} is returned that has null netAmount.
    1.44 +     * This implementation works with any {@link ConversionRequest}, it won't throw {@link IllegalRequestSubtypeException}.
    1.45 +     * @param req the conversion request
    1.46 +     * @return the conversion result
    1.47 +     */
    1.48 +    public ConversionResult convert( final ConversionRequest req ) {
    1.49 +        final Currency srcCurrency = req.getSrcAmount().getCurrency();
    1.50 +        final Currency tgtCurrency = req.getTgtCurrency();
    1.51 +        final ConversionRate rate = findConversionRate( srcCurrency, tgtCurrency );
    1.52 +        if ( rate != null ) {
    1.53 +            final MonetaryAmount tgtAmount = rate.convert( req.getSrcAmount() );
    1.54 +            return new ConversionResult( tgtAmount );
    1.55 +        } else {
    1.56 +            return new ConversionResult( null );    // did not find the pair of currencies in the table
    1.57 +        }
    1.58 +    }
    1.59 +
    1.60 +    /**
    1.61 +     * Looks up the conversion between the given currencies in the table.
    1.62 +     * @param srcCurrency the source currency
    1.63 +     * @param tgtCurrency the target currency
    1.64 +     * @return the conversion rate; null means no conversion between the currencies was found in the table
    1.65 +     */
    1.66 +    protected ConversionRate findConversionRate( final Currency srcCurrency, final Currency tgtCurrency ) {
    1.67 +        synchronized ( conversionTable ) {
    1.68 +            final Map<Currency, ConversionRate> targetTable = conversionTable.get(srcCurrency);
    1.69 +            final ConversionRate rate = (targetTable != null) ? targetTable.get(tgtCurrency) : null;
    1.70 +            return rate;
    1.71 +        }
    1.72 +    }
    1.73 +
    1.74 +}