diff -r 251d0ed461fb -r 58ec6da75f6f task4/solution07/src/org/apidesign/apifest08/currency/ConversionRate.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/task4/solution07/src/org/apidesign/apifest08/currency/ConversionRate.java Sat Oct 11 23:38:46 2008 +0200 @@ -0,0 +1,91 @@ +package org.apidesign.apifest08.currency; + +import java.math.BigDecimal; +import java.math.RoundingMode; + +/** + * A rate of conversion from one currency to another. + * @author jdvorak + */ +public class ConversionRate { + + private final MonetaryAmount srcUnitAmount; + private final MonetaryAmount tgtUnitAmount; + private final int tgtScale; + private final RoundingMode roundingMode; + + /** + * A new conversion rate that gives tgtUnitAmount per every srcUnitAmount. + * @param srcUnitAmount the amount of source currency + * @param tgtUnitAmount the corresponding amount of target currency + * @param tgtScale the scale of the target amounts + * @param roundingMode the rounding mode to use when producing the target amounts + */ + public ConversionRate( final MonetaryAmount srcUnitAmount, final MonetaryAmount tgtUnitAmount, final int targetScale, final RoundingMode roundingMode ) { + this.srcUnitAmount = srcUnitAmount; + this.tgtUnitAmount = tgtUnitAmount; + this.tgtScale = targetScale; + this.roundingMode = roundingMode; + } + + /** + * A new conversion rate that gives tgtUnitAmount per every srcUnitAmount, default number of fraction digits and the given rounding mode. + * @param srcUnitAmount the amount of source currency + * @param tgtUnitAmount the corresponding amount of target currency + * @param roundingMode the rounding mode to use + */ + public ConversionRate( final MonetaryAmount srcUnitAmount, final MonetaryAmount tgtUnitAmount, final RoundingMode roundingMode ) { + this( srcUnitAmount, tgtUnitAmount, tgtUnitAmount.getCurrency().getDefaultFractionDigits(), roundingMode ); + } + + /** + * A new conversion rate that gives tgtUnitAmount per every srcUnitAmount, default number of fraction digits and {@link RoundingMode#HALF_EVEN}. + * @param srcUnitAmount the amount of source currency + * @param tgtUnitAmount the corresponding amount of target currency + */ + public ConversionRate( final MonetaryAmount srcUnitAmount, final MonetaryAmount tgtUnitAmount ) { + this( srcUnitAmount, tgtUnitAmount, RoundingMode.HALF_EVEN ); + } + + public RoundingMode getRoundingMode() { + return roundingMode; + } + + public MonetaryAmount getSrcUnitAmount() { + return srcUnitAmount; + } + + public int getTgtScale() { + return tgtScale; + } + + public MonetaryAmount getTgtUnitAmount() { + return tgtUnitAmount; + } + + /** + * Multiplies the given amount with the given rate. + * @param srcAmount + * @return + */ + public BigDecimal convert( final BigDecimal srcAmount ) { + return srcAmount + .multiply( tgtUnitAmount.getAmount() ) + .divide( srcUnitAmount.getAmount(), tgtScale, roundingMode ); + } + + /** + * Creates a monetary amount that corresponds to the given source amount multiplied by the rate. + * @param srcAmount the source amount + * @return the monetary amount in the target currency + * @throws IllegalArgumentException if the currency of srcAmount is not equal to the source currency of this rate + */ + public MonetaryAmount convert( final MonetaryAmount srcAmount ) { + if ( srcUnitAmount.getCurrency().equals( srcAmount.getCurrency() ) ) { + return new MonetaryAmount( convert( srcAmount.getAmount() ), tgtUnitAmount.getCurrency() ); + } else { + throw new IllegalArgumentException( "This rate converts from " + srcUnitAmount.getCurrency() + ", but a conversion from " + srcAmount.getCurrency() + " is attempted" ); + } + } + +}