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 java.math.BigDecimal;
019import java.math.MathContext;
020import java.math.RoundingMode;
021import java.util.Objects;
022
023import javax.money.MonetaryAmount;
024import javax.money.MonetaryOperator;
025
026import org.javamoney.moneta.RoundedMoney;
027
028/**
029 * <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>
030 * <p>The derived class will implements the {@link RoundedMoney} with this rounding monetary operator</p>
031 *  <pre>
032 *   {@code
033 *
034 *     MonetaryOperator monetaryOperator = ScaleRoundedOperator.of(scale, RoundingMode.HALF_EVEN);
035 *     CurrencyUnit real = Monetary.getCurrency("BRL");
036 *     MonetaryAmount money = Money.of(BigDecimal.valueOf(35.34567), real);
037 *     MonetaryAmount result = monetaryOperator.apply(money); // BRL 35.3457
038 *
039 *    }
040* </pre>
041 * <p>Case the parameter in {@link MonetaryOperator#apply(MonetaryAmount)} be null, the apply will return a {@link NullPointerException}</p>
042 * @author Otavio Santana
043 * @see {@link ScaleRoundedOperator#of(MathContext)}
044 * @see {@link RoundedMoney}
045 * @see {@link MonetaryOperator}
046 * @see {@link BigDecimal#scale()}
047 * @deprecated Do not use, access is only provided for backward compatibility and will be removed.
048 */
049@Deprecated
050public final class ScaleRoundedOperator implements MonetaryOperator {
051
052        private final int scale;
053
054        private final RoundingMode roundingMode;
055
056        private ScaleRoundedOperator(int scale, RoundingMode roundingMode) {
057                this.scale = scale;
058                this.roundingMode = roundingMode;
059        }
060
061        /**
062         * Creates the rounded Operator from scale and roundingMode
063         * @param mathContext
064         * @return the {@link MonetaryOperator} using the scale and {@link roundingMode} used in parameter
065         * @throws NullPointerException when the {@link MathContext} is null
066         * @see {@linkplain RoundingMode}
067         */
068        public static ScaleRoundedOperator of(int scale, RoundingMode roundingMode) {
069
070                Objects.requireNonNull(roundingMode);
071
072                if(RoundingMode.UNNECESSARY.equals(roundingMode)) {
073                   throw new IllegalStateException("To create the ScaleRoundedOperator you cannot use the RoundingMode.UNNECESSARY");
074                }
075                return new ScaleRoundedOperator(scale, roundingMode);
076        }
077
078        @Override
079        public MonetaryAmount apply(MonetaryAmount amount) {
080                RoundedMoney roundedMoney = RoundedMoney.from(Objects.requireNonNull(amount));
081                BigDecimal numberValue = roundedMoney.getNumber().numberValue(BigDecimal.class);
082                BigDecimal numberRounded = numberValue.setScale(scale, roundingMode);
083                return RoundedMoney.of(numberRounded, roundedMoney.getCurrency(), this);
084        }
085
086        public int getScale() {
087                return scale;
088        }
089
090        public RoundingMode getRoundingMode() {
091                return roundingMode;
092        }
093
094        @Override
095        public String toString() {
096                StringBuilder sb = new StringBuilder();
097                sb.append(ScaleRoundedOperator.class.getName()).append('{')
098                .append("scale:").append(Integer.toString(scale)).append(',')
099                .append("roundingMode:").append(roundingMode).append('}');
100                return sb.toString();
101        }
102
103}