001    /*
002     *  Copyright 2009-2013 Stephen Colebourne
003     *
004     *  Licensed under the Apache License, Version 2.0 (the "License");
005     *  you may not use this file except in compliance with the License.
006     *  You may obtain a copy of 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,
012     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     *  See the License for the specific language governing permissions and
014     *  limitations under the License.
015     */
016    package org.joda.money;
017    
018    /**
019     * Utilities for working with monetary values that handle null.
020     * <p>
021     * This utility class contains thread-safe static methods.
022     */
023    public final class MoneyUtils {
024    
025        /**
026         * Validates that the object specified is not null.
027         *
028         * @param object  the object to check, not null
029         * @throws NullPointerException if the input value is null
030         */
031        static void checkNotNull(Object object, String message) {
032            if (object == null) {
033                throw new NullPointerException(message);
034            }
035        }
036    
037        //-----------------------------------------------------------------------
038        /**
039         * Private constructor.
040         */
041        private MoneyUtils() {
042        }
043    
044        //-----------------------------------------------------------------------
045        /**
046         * Checks if the monetary value is zero, treating null as zero.
047         * <p>
048         * This method accepts any implementation of {@code BigMoneyProvider}.
049         * 
050         * @param moneyProvider  the money to check, null returns zero
051         * @return true if the money is null or zero
052         */
053        public static boolean isZero(BigMoneyProvider moneyProvider) {
054            return (moneyProvider == null || moneyProvider.toBigMoney().isZero());
055        }
056    
057        /**
058         * Checks if the monetary value is positive and non-zero, treating null as zero.
059         * <p>
060         * This method accepts any implementation of {@code BigMoneyProvider}.
061         * 
062         * @param moneyProvider  the money to check, null returns false
063         * @return true if the money is non-null and positive
064         */
065        public static boolean isPositive(BigMoneyProvider moneyProvider) {
066            return (moneyProvider != null && moneyProvider.toBigMoney().isPositive());
067        }
068    
069        /**
070         * Checks if the monetary value is positive or zero, treating null as zero.
071         * <p>
072         * This method accepts any implementation of {@code BigMoneyProvider}.
073         * 
074         * @param moneyProvider  the money to check, null returns true
075         * @return true if the money is null, zero or positive
076         */
077        public static boolean isPositiveOrZero(BigMoneyProvider moneyProvider) {
078            return (moneyProvider == null || moneyProvider.toBigMoney().isPositiveOrZero());
079        }
080    
081        /**
082         * Checks if the monetary value is negative and non-zero, treating null as zero.
083         * <p>
084         * This method accepts any implementation of {@code BigMoneyProvider}.
085         * 
086         * @param moneyProvider  the money to check, null returns false
087         * @return true if the money is non-null and negative
088         */
089        public static boolean isNegative(BigMoneyProvider moneyProvider) {
090            return (moneyProvider != null && moneyProvider.toBigMoney().isNegative());
091        }
092    
093        /**
094         * Checks if the monetary value is negative or zero, treating null as zero.
095         * <p>
096         * This method accepts any implementation of {@code BigMoneyProvider}.
097         * 
098         * @param moneyProvider  the money to check, null returns true
099         * @return true if the money is null, zero or negative
100         */
101        public static boolean isNegativeOrZero(BigMoneyProvider moneyProvider) {
102            return (moneyProvider == null || moneyProvider.toBigMoney().isNegativeOrZero());
103        }
104    
105        //-----------------------------------------------------------------------
106        /**
107         * Finds the maximum {@code Money} value, handing null.
108         * <p>
109         * This returns the greater of money1 or money2 where null is ignored.
110         * If both input values are null, then null is returned.
111         * 
112         * @param money1  the first money instance, null returns money2
113         * @param money2  the first money instance, null returns money1
114         * @return the maximum value, null if both inputs are null
115         * @throws CurrencyMismatchException if the currencies differ
116         */
117        public static Money max(Money money1, Money money2) {
118            if (money1 == null) {
119                return money2;
120            }
121            if (money2 == null) {
122                return money1;
123            }
124            return money1.compareTo(money2) > 0 ? money1 : money2;
125        }
126    
127        /**
128         * Finds the minimum {@code Money} value, handing null.
129         * <p>
130         * This returns the greater of money1 or money2 where null is ignored.
131         * If both input values are null, then null is returned.
132         * 
133         * @param money1  the first money instance, null returns money2
134         * @param money2  the first money instance, null returns money1
135         * @return the minimum value, null if both inputs are null
136         * @throws CurrencyMismatchException if the currencies differ
137         */
138        public static Money min(Money money1, Money money2) {
139            if (money1 == null) {
140                return money2;
141            }
142            if (money2 == null) {
143                return money1;
144            }
145            return money1.compareTo(money2) < 0 ? money1 : money2;
146        }
147    
148        //-----------------------------------------------------------------------
149        /**
150         * Adds two {@code Money} objects, handling null.
151         * <p>
152         * This returns {@code money1 + money2} where null is ignored.
153         * If both input values are null, then null is returned.
154         * 
155         * @param money1  the first money instance, null returns money2
156         * @param money2  the first money instance, null returns money1
157         * @return the total, where null is ignored, null if both inputs are null
158         * @throws CurrencyMismatchException if the currencies differ
159         */
160        public static Money add(Money money1, Money money2) {
161            if (money1 == null) {
162                return money2;
163            }
164            if (money2 == null) {
165                return money1;
166            }
167            return money1.plus(money2);
168        }
169    
170        //-----------------------------------------------------------------------
171        /**
172         * Subtracts the second {@code Money} from the first, handling null.
173         * <p>
174         * This returns {@code money1 - money2} where null is ignored.
175         * If both input values are null, then null is returned.
176         * 
177         * @param money1  the first money instance, null treated as zero
178         * @param money2  the first money instance, null returns money1
179         * @return the total, where null is ignored, null if both inputs are null
180         * @throws CurrencyMismatchException if the currencies differ
181         */
182        public static Money subtract(Money money1, Money money2) {
183            if (money2 == null) {
184                return money1;
185            }
186            if (money1 == null) {
187                return money2.negated();
188            }
189            return money1.minus(money2);
190        }
191    
192        //-----------------------------------------------------------------------
193        /**
194         * Finds the maximum {@code BigMoney} value, handing null.
195         * <p>
196         * This returns the greater of money1 or money2 where null is ignored.
197         * If both input values are null, then null is returned.
198         * 
199         * @param money1  the first money instance, null returns money2
200         * @param money2  the first money instance, null returns money1
201         * @return the maximum value, null if both inputs are null
202         * @throws CurrencyMismatchException if the currencies differ
203         */
204        public static BigMoney max(BigMoney money1, BigMoney money2) {
205            if (money1 == null) {
206                return money2;
207            }
208            if (money2 == null) {
209                return money1;
210            }
211            return money1.compareTo(money2) > 0 ? money1 : money2;
212        }
213    
214        /**
215         * Finds the minimum {@code BigMoney} value, handing null.
216         * <p>
217         * This returns the greater of money1 or money2 where null is ignored.
218         * If both input values are null, then null is returned.
219         * 
220         * @param money1  the first money instance, null returns money2
221         * @param money2  the first money instance, null returns money1
222         * @return the minimum value, null if both inputs are null
223         * @throws CurrencyMismatchException if the currencies differ
224         */
225        public static BigMoney min(BigMoney money1, BigMoney money2) {
226            if (money1 == null) {
227                return money2;
228            }
229            if (money2 == null) {
230                return money1;
231            }
232            return money1.compareTo(money2) < 0 ? money1 : money2;
233        }
234    
235        //-----------------------------------------------------------------------
236        /**
237         * Adds two {@code BigMoney} objects, handling null.
238         * <p>
239         * This returns {@code money1 + money2} where null is ignored.
240         * If both input values are null, then null is returned.
241         * 
242         * @param money1  the first money instance, null returns money2
243         * @param money2  the first money instance, null returns money1
244         * @return the total, where null is ignored, null if both inputs are null
245         * @throws CurrencyMismatchException if the currencies differ
246         */
247        public static BigMoney add(BigMoney money1, BigMoney money2) {
248            if (money1 == null) {
249                return money2;
250            }
251            if (money2 == null) {
252                return money1;
253            }
254            return money1.plus(money2);
255        }
256    
257        //-----------------------------------------------------------------------
258        /**
259         * Subtracts the second {@code BigMoney} from the first, handling null.
260         * <p>
261         * This returns {@code money1 - money2} where null is ignored.
262         * If both input values are null, then null is returned.
263         * 
264         * @param money1  the first money instance, null treated as zero
265         * @param money2  the first money instance, null returns money1
266         * @return the total, where null is ignored, null if both inputs are null
267         * @throws CurrencyMismatchException if the currencies differ
268         */
269        public static BigMoney subtract(BigMoney money1, BigMoney money2) {
270            if (money2 == null) {
271                return money1;
272            }
273            if (money1 == null) {
274                return money2.negated();
275            }
276            return money1.minus(money2);
277        }
278    
279    }