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