001/*
002 * Copyright (c) 2012, 2013, Credit Suisse (Anatole Tresch), Werner Keil.
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;
020
021import javax.money.MonetaryAmount;
022import javax.money.MonetaryAdjuster;
023import javax.money.MonetaryAdjuster;
024import javax.money.MonetaryQuery;
025
026/**
027 * This singleton class provides access to the predefined monetary functions.
028 * <p>
029 * The class is thread-safe, which is also true for all functions returned by
030 * this class.
031 * 
032 * @author Anatole Tresch
033 */
034public final class MonetaryFunctions {
035        /** defaulkt Math context used. */
036        private static final MathContext DEFAULT_MATH_CONTEXT = initDefaultMathContext();
037        /** Shared reciprocal instance. */
038        private static final Reciprocal RECIPROCAL = new Reciprocal();
039
040        /**
041         * The shared instance of this class.
042         */
043        private static final MinorPart MINORPART = new MinorPart();
044        /** SHared minor units class. */
045        private static final MinorUnits MINORUNITS = new MinorUnits();
046        /** Shared major part instance. */
047        private static final MajorPart MAJORPART = new MajorPart();
048        /** Shared major units instance. */
049        private static final MajorUnits MAJORUNITS = new MajorUnits();
050
051
052        /**
053         * Private singleton constructor.
054         */
055        private MonetaryFunctions() {
056                // Singleton constructor
057        }
058
059        /**
060         * Get {@link MathContext} for {@link Permil} instances.
061         * 
062         * @return the {@link MathContext} to be used, by default
063         *         {@link MathContext#DECIMAL64}.
064         */
065        private static MathContext initDefaultMathContext() {
066                // TODO Initialize default, e.g. by system properties, or better:
067                // classpath properties!
068                return MathContext.DECIMAL64;
069        }
070
071        /**
072         * Return a {@link MonetaryAdjuster} realizing the recorpocal value of
073         * {@code f(R) = 1/R}.
074         * 
075         * @return the reciprocal operator, never {@code null}
076         */
077        public static MonetaryAdjuster reciprocal() {
078                return RECIPROCAL;
079        }
080
081        /**
082         * Factory method creating a new instance with the given {@code BigDecimal) permil value;
083         * @param decimal the decimal value of the permil operator being created.
084         * @return a new  {@code Permil} operator
085         */
086        public static MonetaryAdjuster permil(BigDecimal decimal) {
087                return new Permil(decimal);
088        }
089
090        /**
091         * Factory method creating a new instance with the given {@code Number) permil value;
092         * @param decimal the decimal value of the permil operator being created.
093         * @return a new  {@code Permil} operator
094         */
095        public static MonetaryAdjuster permil(Number number) {
096                return permil(number, DEFAULT_MATH_CONTEXT);
097        }
098
099        /**
100         * Factory method creating a new instance with the given {@code Number) permil value;
101         * @param decimal the decimal value of the permil operator being created.
102         * @return a new  {@code Permil} operator
103         */
104        public static MonetaryAdjuster permil(Number number, MathContext mathContext) {
105                return new Permil(getBigDecimal(number, mathContext));
106        }
107
108        /**
109         * Converts to {@link BigDecimal}, if necessary, or casts, if possible.
110         * 
111         * @param number
112         *            The {@link Number}
113         * @param mathContext
114         *            the {@link MathContext}
115         * @return the {@code number} as {@link BigDecimal}
116         */
117        private static final BigDecimal getBigDecimal(Number number,
118                        MathContext mathContext) {
119                if (number instanceof BigDecimal) {
120                        return (BigDecimal) number;
121                } else {
122                        return new BigDecimal(number.doubleValue(), mathContext);
123                }
124        }
125
126        /**
127         * Factory method creating a new instance with the given {@code BigDecimal) percent value;
128         * @param decimal the decimal value of the percent operator being created.
129         * @return a new  {@code Percent} operator
130         */
131        public static MonetaryAdjuster percent(BigDecimal decimal) {
132                return new Percent(decimal); // TODO caching, e.g. array for 1-100 might
133                                                                                // work.
134        }
135
136        /**
137         * Factory method creating a new instance with the given {@code Number) percent value;
138         * @param decimal the decimal value of the percent operator being created.
139         * 
140         * @return a new  {@code Percent} operator
141         */
142        public static MonetaryAdjuster percent(Number number) {
143                return percent(getBigDecimal(number, DEFAULT_MATH_CONTEXT));
144        }
145
146        /**
147         * Access the shared instance of {@link MinorPart} for use.
148         * 
149         * @return the shared instance, never {@code null}.
150         */
151        public static MonetaryAdjuster minorPart() {
152                return MINORPART;
153        }
154
155        /**
156         * Access the shared instance of {@link MajorPart} for use.
157         * 
158         * @return the shared instance, never {@code null}.
159         */
160        public static MonetaryAdjuster majorPart() {
161                return MAJORPART;
162        }
163
164        /**
165         * Access the shared instance of {@link MinorPart} for use.
166         * 
167         * @return the shared instance, never {@code null}.
168         */
169        public static MonetaryQuery<Long> minorUnits() {
170                return MINORUNITS;
171        }
172
173        /**
174         * Access the shared instance of {@link MinorPart} for use.
175         * 
176         * @return the shared instance, never {@code null}.
177         */
178        public static MonetaryQuery<Long> majorUnits() {
179                return MAJORUNITS;
180        }
181
182
183}