001/** 002 * Copyright (c) 2012, 2015, Credit Suisse (Anatole Tresch), Werner Keil and others by the @author tag. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 005 * use this file except in compliance with the License. You may obtain a copy of 006 * the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 012 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 013 * License for the specific language governing permissions and limitations under 014 * the License. 015 */ 016package org.javamoney.moneta.function; 017 018import static java.util.Objects.requireNonNull; 019 020import java.math.BigDecimal; 021import java.math.MathContext; 022import java.math.RoundingMode; 023import java.util.Objects; 024 025import javax.money.MonetaryAmount; 026import javax.money.MonetaryOperator; 027 028/** 029 * <p>This implementation uses a scale and {@link RoundingMode} and precision to does the rounding operations. The implementation will use both the <b>scale</b> and <b>precision</b>, in other words, the number of digits to the right of the decimal point and the number of digits.</p> 030 * <p>The derived class will implements the {@link org.javamoney.moneta.RoundedMoney} with this rounding monetary operator</p> 031 * <pre> 032 * {@code 033 * int scale = 3; 034 * int precision = 5; 035 * MathContext mathContext = new MathContext(precision, RoundingMode.HALF_EVEN); 036 * MonetaryOperator monetaryOperator = PrecisionScaleRoundedOperator.of(scale, mathContext); 037 * CurrencyUnit real = Monetary.getCurrency("BRL"); 038 * MonetaryAmount money = Money.of(BigDecimal.valueOf(35.34567), real); 039 * MonetaryAmount result = monetaryOperator.apply(money); // BRL 35.346 040 * 041 * } 042* </pre> 043 * <p>Case the parameter in {@link MonetaryOperator#apply(MonetaryAmount)} be null, the apply will return a {@link NullPointerException}</p> 044 * @author Otavio Santana 045 * @see {@link PrecisionScaleRoundedOperator#of(int, MathContext)} 046 * @see {@link org.javamoney.moneta.RoundedMoney} 047 * @see {@link MonetaryOperator} 048 * @see {@link BigDecimal#scale()} 049 * @see {@link MathContext} 050 * @see {@link BigDecimal#precision()} 051 * @since 1.0.1 052 * @deprecated Do not use, access is only provided for backward compatibility and will be removed. 053 */ 054@Deprecated 055public final class PrecisionScaleRoundedOperator implements MonetaryOperator { 056 057 private final PrecisionContextRoundedOperator mathContextOperator; 058 059 private final ScaleRoundedOperator scaleRoundedOperator; 060 061 private final int scale; 062 063 private final MathContext mathContext; 064 065 private PrecisionScaleRoundedOperator(int scale, MathContext mathContext) { 066 this.scale = scale; 067 this.mathContext = mathContext; 068 this.mathContextOperator = PrecisionContextRoundedOperator.of(mathContext); 069 this.scaleRoundedOperator = ScaleRoundedOperator.of(scale, mathContext.getRoundingMode()); 070 } 071 072 /** 073 * Creates the rounded Operator from scale and roundingMode 074 * @param mathContext 075 * @return the {@link MonetaryOperator} using the scale and {@link RoundingMode} used in parameter 076 * @throws NullPointerException when the {@link MathContext} is null 077 * @throws IllegalArgumentException if {@link MathContext#getPrecision()} is lesser than zero 078 * @throws IllegalArgumentException if {@link MathContext#getRoundingMode()} is {@link RoundingMode#UNNECESSARY} 079 * @see {@linkplain RoundingMode} 080 */ 081 public static PrecisionScaleRoundedOperator of(int scale, MathContext mathContext) { 082 083 Objects.requireNonNull(mathContext); 084 085 if(RoundingMode.UNNECESSARY.equals(mathContext.getRoundingMode())) { 086 throw new IllegalArgumentException("To create the ScaleRoundedOperator you cannot use the RoundingMode.UNNECESSARY on MathContext"); 087 } 088 089 if(mathContext.getPrecision() <= 0) { 090 throw new IllegalArgumentException("To create the ScaleRoundedOperator you cannot use the zero precision on MathContext"); 091 } 092 return new PrecisionScaleRoundedOperator(scale, mathContext); 093 } 094 095 @Override 096 public MonetaryAmount apply(MonetaryAmount amount) { 097 return scaleRoundedOperator.apply(requireNonNull(amount)).with(mathContextOperator); 098 } 099 100 public int getScale() { 101 return scale; 102 } 103 104 public MathContext getMathContext() { 105 return mathContext; 106 } 107 108 @Override 109 public String toString() { 110 StringBuilder sb = new StringBuilder(); 111 sb.append(PrecisionScaleRoundedOperator.class.getName()).append('{') 112 .append("scale:").append(Integer.toString(scale)).append(',') 113 .append("mathContext:").append(mathContext).append('}'); 114 return sb.toString(); 115 } 116 117}