Skip to content

Commit

Permalink
Adds src/main/java/org/javamoney/moneta/ScaleRoundedOperator.java
Browse files Browse the repository at this point in the history
  • Loading branch information
otaviojava committed Apr 22, 2015
1 parent fc92435 commit 434f06b
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,18 @@
/**
* <p>This implementation uses a {@link MathContext} to does the rounding operations. The implementation will use the <b>precision</b>, in other words, the total number of digits in a number</p>
* <p>The derived class will implements the {@link RoundedMoney} with this rounding monetary operator</p>
* <p>Case the parameter in {@link MonetaryOperator#apply(MonetaryAmount)} be null, the apply will return a {@link NullPointerException}</p>
* <pre>
* {@code
*
* MathContext mathContext = new MathContext(4, RoundingMode.HALF_EVEN);
* MonetaryOperator monetaryOperator = MathContextRoundedOperator.of(mathContext);
* CurrencyUnit real = Monetary.getCurrency("BRL");
* MonetaryAmount money = Money.of(BigDecimal.valueOf(35.34567), real);
* MonetaryAmount result = monetaryOperator.apply(money); // BRL 35.35
*
* }
* </pre>
* <p>Case the parameter in {@link MonetaryOperator#apply(MonetaryAmount)} be null, the apply will return a {@link NullPointerException}</p>
* @author Otavio Santana
* @see {@link MathContextRoundedOperator#of(MathContext)}
* @see {@link RoundedMoney}
Expand Down
70 changes: 70 additions & 0 deletions src/main/java/org/javamoney/moneta/ScaleRoundedOperator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package org.javamoney.moneta;

import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.util.Objects;

import javax.money.MonetaryAmount;
import javax.money.MonetaryOperator;

/**
* <p>This implementation uses a scale and {@link RoundingMode} to does the rounding operations. The implementation will use the <b>scale</b>, in other words, the number of digits to the right of the decimal point</p>
* <p>The derived class will implements the {@link RoundedMoney} with this rounding monetary operator</p>
* <pre>
* {@code
*
* MonetaryOperator monetaryOperator = ScaleRoundedOperator.of(scale, RoundingMode.HALF_EVEN);
* CurrencyUnit real = Monetary.getCurrency("BRL");
* MonetaryAmount money = Money.of(BigDecimal.valueOf(35.34567), real);
* MonetaryAmount result = monetaryOperator.apply(money); // BRL 35.3457
*
* }
* </pre>
* <p>Case the parameter in {@link MonetaryOperator#apply(MonetaryAmount)} be null, the apply will return a {@link NullPointerException}</p>
* @author Otavio Santana
* @see {@link ScaleRoundedOperator#of(MathContext)}
* @see {@link RoundedMoney}
* @see {@link MonetaryOperator}
* @see {@link BigDecimal#scale()}
*/
public final class ScaleRoundedOperator implements MonetaryOperator {

private final int scale;

private final RoundingMode roundingMode;

private ScaleRoundedOperator(int scale, RoundingMode roundingMode) {
this.scale = scale;
this.roundingMode = roundingMode;
}

/**
* Creates the rounded Operator from scale and roundingMode
* @param mathContext
* @return the {@link MonetaryOperator} using the scale and {@link roundingMode} used in parameter
* @throws NullPointerException when the {@link MathContext} is null
* @see {@linkplain RoundingMode}
*/
public static ScaleRoundedOperator of(int scale, RoundingMode roundingMode) {
return new ScaleRoundedOperator(scale, Objects.requireNonNull(roundingMode));
}

@Override
public MonetaryAmount apply(MonetaryAmount amount) {
RoundedMoney roundedMoney = RoundedMoney.from(Objects.requireNonNull(amount));
BigDecimal numberValue = roundedMoney.getNumber().numberValue(BigDecimal.class);
BigDecimal numberRounded = numberValue.setScale(scale, roundingMode);
return RoundedMoney.of(numberRounded, roundedMoney.getCurrency(), this);
}

@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(ScaleRoundedOperator.class.getName()).append('{')
.append("scale:").append(Integer.toString(scale)).append(',')
.append("roundingMode:").append(roundingMode).append('}');
return sb.toString();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,18 @@ public void shouldReturnErrorWhenParameterIsNUll() {

@Test
public void shouldRoundedMonetaryOperatorWhenTheImplementationIsMoney() {
int scale = 2;
int scale = 4;
MathContext mathContext = new MathContext(scale, RoundingMode.HALF_EVEN);

CurrencyUnit real = Monetary.getCurrency("BRL");
Money money = Money.of(BigDecimal.valueOf(130002.56895), real);
MonetaryAmount money = Money.of(BigDecimal.valueOf(35.34567), real);

MathContextRoundedOperator monetaryOperator = MathContextRoundedOperator.of(mathContext);
MonetaryAmount result = monetaryOperator.apply(money);
assertTrue(RoundedMoney.class.isInstance(result));
assertEquals(result.getCurrency(), real);
assertEquals(result.getNumber().getPrecision(), scale);
assertEquals(BigDecimal.valueOf(35.35), result.getNumber().numberValue(BigDecimal.class));



Expand Down
48 changes: 48 additions & 0 deletions src/test/java/org/javamoney/moneta/ScaleRoundedOperatorTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package org.javamoney.moneta;

import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;

import java.math.BigDecimal;
import java.math.RoundingMode;

import javax.money.CurrencyUnit;
import javax.money.Monetary;
import javax.money.MonetaryAmount;

import org.testng.annotations.Test;

public class ScaleRoundedOperatorTest {

@Test(expectedExceptions = NullPointerException.class)
public void shouldReturnNullPointerExceptionWhenParameterIsNull() {
ScaleRoundedOperator.of(0, null);
fail();
}

@Test(expectedExceptions = NullPointerException.class)
public void shouldReturnErrorWhenParameterIsNUll() {
ScaleRoundedOperator monetaryOperator = ScaleRoundedOperator.of(0, RoundingMode.HALF_EVEN);
monetaryOperator.apply(null);
fail();
}

@Test
public void shouldRoundedMonetaryOperatorWhenTheImplementationIsMoney() {
int scale = 4;

CurrencyUnit real = Monetary.getCurrency("BRL");
MonetaryAmount money = Money.of(BigDecimal.valueOf(35.34567), real);

ScaleRoundedOperator monetaryOperator = ScaleRoundedOperator.of(scale, RoundingMode.HALF_EVEN);
MonetaryAmount result = monetaryOperator.apply(money);
assertTrue(RoundedMoney.class.isInstance(result));
assertEquals(result.getCurrency(), real);
assertEquals(result.getNumber().getScale(), scale);
assertEquals(BigDecimal.valueOf(35.3457), result.getNumber().numberValue(BigDecimal.class));



}
}

0 comments on commit 434f06b

Please sign in to comment.