001/*
002  Copyright (c) 2012, 2014, 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.MathContext;
019import java.math.RoundingMode;
020
021/**
022 * Builder to {@link MonetaryRoundedFactory} once the {@link RoundingMode}, is possible
023 * choose the <b>scale</b>, the number of digits to the right of the decimal point, and the <b>precision</b>, the total number of digits in a number or both.
024 * @author Otavio Santana
025 * @see MonetaryRoundedFactoryBuilder#withScale(int)
026 * @see MonetaryRoundedFactoryBuilder#withPrecision(int)
027 * @since 1.0.1
028 */
029public final class MonetaryRoundedFactoryBuilder {
030
031        private final RoundingMode roundingMode;
032
033        MonetaryRoundedFactoryBuilder(RoundingMode roundingMode) {
034                this.roundingMode = roundingMode;
035        }
036
037        /**
038         * Set the number of digits to the right of the decimal point
039         * @param scale the scale to use.
040         * @return MonetaryRoundedFactoryWithScaleBuilder
041         */
042        public MonetaryRoundedFactoryWithScaleBuilder withScale(int scale) {
043                return new MonetaryRoundedFactoryWithScaleBuilder(roundingMode, scale);
044        }
045
046        /**
047         * Set the total number of digits in a number
048         * @param precision the precision to use.
049         * @return {@link MonetaryRoundedFactoryWithPrecisionBuilder}
050         */
051        public MonetaryRoundedFactoryWithPrecisionBuilder withPrecision(int precision) {
052                return new MonetaryRoundedFactoryWithPrecisionBuilder(roundingMode, precision);
053        }
054
055        /**
056         * Once the {@link RoundingMode} and scale informed, is possible create a {@link MonetaryRoundedFactory}
057         * or set the number of precision.
058         * @author Otavio Santana
059         *@see MonetaryRoundedFactoryWithScaleBuilder#withPrecision(int)
060         *@see MonetaryRoundedFactoryWithScaleBuilder#build()
061         */
062        public static class MonetaryRoundedFactoryWithScaleBuilder {
063
064                private final RoundingMode roundingMode;
065
066                private final int scale;
067
068                private MonetaryRoundedFactoryWithScaleBuilder(RoundingMode roundingMode, int scale) {
069                        this.roundingMode = roundingMode;
070                        this.scale = scale;
071                }
072
073                /**
074                 * Make the {@link MonetaryRoundedFactory} using the {@link ScaleRoundedOperator} as rounding operator.
075                 * @return {@link MonetaryRoundedFactory} with {@link ScaleRoundedOperator}
076                 * @see ScaleRoundedOperator
077                 * @see MonetaryRoundedFactory
078                 */
079                public MonetaryRoundedFactory build() {
080                        return new DefaultMonetaryRoundedFactory(ScaleRoundedOperator.of(scale, roundingMode));
081                }
082
083                /**
084                 * Set the total number of digits in a number
085                 * @param precision the precision to use.
086                 * @return {@link MonetaryRoundedFactoryWithPrecisionBuilder}
087                 */
088                public MonetaryRoundedFactoryWithPrecisionScaleBuilder withPrecision(int precision) {
089                        MonetaryRoundedFactoryWithPrecisionScaleBuilder builder = new MonetaryRoundedFactoryWithPrecisionScaleBuilder(roundingMode);
090                        builder.scale = this.scale;
091                        builder.precision = precision;
092                        return builder;
093                }
094
095        }
096
097        /**
098         * Once the {@link RoundingMode} and precision informed, is possible create a {@link MonetaryRoundedFactory}
099         * or set the number of scale.
100         * @author Otavio Santana
101         *@see MonetaryRoundedFactoryWithPrecisionBuilder#withScale(int)
102         *@see MonetaryRoundedFactoryWithPrecisionBuilder#build()
103         */
104        public static class MonetaryRoundedFactoryWithPrecisionBuilder {
105
106                private final int precision;
107
108                private final RoundingMode roundingMode;
109
110                private MonetaryRoundedFactoryWithPrecisionBuilder(RoundingMode roundingMode, int precision) {
111                        this.roundingMode = roundingMode;
112                        this.precision = precision;
113                }
114                /**
115                 * Set the number of digits to the right of the decimal point
116                 * @param scale the scale to use.
117                 * @return MonetaryRoundedFactoryWithPrecisionScaleBuilder
118                 */
119                public MonetaryRoundedFactoryWithPrecisionScaleBuilder withScale(int scale) {
120                        MonetaryRoundedFactoryWithPrecisionScaleBuilder builder = new MonetaryRoundedFactoryWithPrecisionScaleBuilder(roundingMode);
121                        builder.precision = this.precision;
122                        builder.scale = scale;
123                        return builder;
124                }
125
126                /**
127                 * Make the {@link MonetaryRoundedFactory} using the {@link PrecisionContextRoundedOperator} as rounding operator.
128                 * @return {@link MonetaryRoundedFactory} with {@link PrecisionContextRoundedOperator}
129                 * @see PrecisionContextRoundedOperator
130                 * @see MonetaryRoundedFactory
131                 */
132                public MonetaryRoundedFactory build() {
133                        MathContext mathContext = new MathContext(precision, roundingMode);
134                        return new DefaultMonetaryRoundedFactory(PrecisionContextRoundedOperator.of(mathContext));
135                }
136
137        }
138
139        /**
140         * Once the {@link RoundingMode}, precision and scale informed, the next step will build a {@link MonetaryRoundedFactory}
141         * with all these information.
142         * @author Otavio Santana
143         */
144        public static class MonetaryRoundedFactoryWithPrecisionScaleBuilder {
145
146                private int scale;
147
148                private int precision;
149
150                private final RoundingMode roundingMode;
151
152                public MonetaryRoundedFactoryWithPrecisionScaleBuilder(
153                                RoundingMode roundingMode) {
154                        this.roundingMode = roundingMode;
155                }
156
157                /**
158                 * Make the {@link MonetaryRoundedFactory} using the {@link PrecisionScaleRoundedOperator} as rounding operator.
159                 * @return {@link MonetaryRoundedFactory} with {@link PrecisionScaleRoundedOperator}
160                 * @see PrecisionContextRoundedOperator
161                 * @see PrecisionScaleRoundedOperator
162                 */
163                public MonetaryRoundedFactory build() {
164                        MathContext mathContext = new MathContext(precision, roundingMode);
165                        return new DefaultMonetaryRoundedFactory(PrecisionScaleRoundedOperator.of(scale, mathContext));
166                }
167
168        }
169
170        @Override
171        public String toString() {
172                String sb = MonetaryRoundedFactoryBuilder.class.getName() + '{' +
173                                "roundingMode: " + roundingMode + '}';
174                return sb;
175        }
176
177}