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.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 {@link MonetaryRoundedFactoryBuilder#withScale(int)}
026 * @see {@link 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
040         * @return {@link 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
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 {@link MonetaryRoundedFactoryWithScaleBuilder#withPrecision(int)}
060         *@see {@link 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 {@link ScaleRoundedOperator}
077                 * @see {@link 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
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 {@link MonetaryRoundedFactoryWithPrecisionBuilder#withScale(int)}
102         *@see {@link 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
117                 * @return {@link 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 {@link PrecisionContextRoundedOperator}
130                 * @see {@link 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 {@link PrecisionContextRoundedOperator}
161                 * @see {@link 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                StringBuilder sb = new StringBuilder();
173                sb.append(MonetaryRoundedFactoryBuilder.class.getName()).append('{')
174                .append("roundingMode: ").append(roundingMode).append('}');
175                return sb.toString();
176        }
177
178}