japod@6: package org.apidesign.apifest08.currency; japod@6: japod@6: import java.util.Currency; japod@6: japod@6: /** This is the skeleton class for your API. You need to make it public, so japod@6: * it is accessible to your client code (currently in Task1Test.java) file. japod@6: *

japod@6: * Feel free to create additional classes or rename this one, just keep all japod@6: * the API and its implementation in this package. Do not spread it outside japod@6: * to other packages. japod@6: */ japod@6: public interface Convertor { japod@6: japod@6: /** japod@6: * Converts by taking a request and producing a response. japod@6: * If a convertor finds it cannot perform the requested conversion, japod@6: * it should return a non-null {@link ConversionResult} that has null {@link ConversionResult#getNetAmount()}. japod@6: * A convertor must not convert to a different currency than the one specified in the request. japod@6: *

japod@6: * When the need comes to extend the semantics, one subclasses the ConversionRequest and/or ConversionResult classes. japod@6: *

japod@6: * This method can be called as many times as you like. japod@18: * A {@link Convertor} shall be considered immutable wrt calls to {@link #convert(org.apidesign.apifest08.currency.Convertor.ConversionRequest). japod@6: * This method of a single {@link Convertor} can be called from many threads concurrently. japod@6: * @param req the conversion request; mustn't be null japod@6: * @return the result of carrying out the conversion request; never null japod@6: * @throws IllegalRequestSubtypeException when the particular implementation cannot handle a specific ConversionRequest type japod@6: */ japod@6: public ConversionResult convert( final ConversionRequest req ) throws IllegalRequestSubtypeException; japod@6: japod@6: /** japod@6: * The request for converting a monetary amout into another currency. japod@6: * Immutable. japod@6: */ japod@6: public class ConversionRequest { japod@6: japod@6: private final MonetaryAmount srcAmount; japod@6: private final Currency tgtCurrency; japod@6: japod@6: /** japod@6: * A request to convert srcAmount into tgtCurrency. japod@6: * @param srcAmount the source amount; must not be null japod@6: * @param tgtCurrency the currency we want it in afterwards; must not be null japod@6: */ japod@6: public ConversionRequest( final MonetaryAmount srcAmount, final Currency tgtCurrency ) { japod@6: this.srcAmount = srcAmount; japod@6: this.tgtCurrency = tgtCurrency; japod@6: if ( srcAmount == null ) { japod@6: throw new NullPointerException( "The source amount" ); japod@6: } japod@6: if ( tgtCurrency == null ) { japod@6: throw new NullPointerException( "The target currency" ); japod@6: } japod@6: if ( srcAmount.getCurrency().equals( tgtCurrency ) ) { japod@6: throw new IllegalArgumentException( "Cannot request conversion from " + srcAmount.getCurrency() + " to " + tgtCurrency ); japod@6: } japod@6: } japod@6: japod@6: /** japod@6: * The source amount. japod@6: */ japod@6: public MonetaryAmount getSrcAmount() { japod@6: return srcAmount; japod@6: } japod@6: japod@6: /** japod@6: * The target currency. japod@6: */ japod@6: public Currency getTgtCurrency() { japod@6: return tgtCurrency; japod@6: } japod@6: japod@6: } japod@6: japod@6: /** japod@6: * The result of converting a monetary amount into another currency. japod@6: * For now it records just the net amount one recieves from the conversion. japod@6: * Immutable. japod@6: *

japod@6: * Extension note: japod@6: * Other items can be added further down the road, as the need for them arises. japod@6: * These items might provide info on other aspects of the conversion, japod@6: * such as the fee or a reason why the conversion might not be admissible. japod@6: */ japod@6: public class ConversionResult { japod@6: japod@6: private final MonetaryAmount netAmount; japod@6: japod@6: /** japod@6: * A new conversion result. japod@6: * @param netAmount the amount one recieves from the conversion; japod@6: * null means the conversion was not admissible japod@6: */ japod@6: public ConversionResult( final MonetaryAmount netAmount ) { japod@6: this.netAmount = netAmount; japod@6: } japod@6: japod@6: /** japod@6: * The amount one recieves from the conversion. japod@6: * If null, the conversion is not admissible. japod@6: * @return the amount japod@6: */ japod@6: public MonetaryAmount getNetAmount() { japod@6: return netAmount; japod@6: } japod@6: japod@6: } japod@6: japod@6: }