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         * @return true if the money is null or zero
051         */
052        public static boolean isZero(BigMoneyProvider moneyProvider) {
053            return (moneyProvider == null || moneyProvider.toBigMoney().isZero());
054        }
055    
056        /**
057         * Checks if the monetary value is positive and non-zero, treating null as zero.
058         * <p>
059         * This method accepts any implementation of {@code BigMoneyProvider}.
060         * 
061         * @return true if the money is non-null and positive
062         */
063        public static boolean isPositive(BigMoneyProvider moneyProvider) {
064            return (moneyProvider != null && moneyProvider.toBigMoney().isPositive());
065        }
066    
067        /**
068         * Checks if the monetary value is positive or zero, treating null as zero.
069         * <p>
070         * This method accepts any implementation of {@code BigMoneyProvider}.
071         * 
072         * @return true if the money is null, zero or positive
073         */
074        public static boolean isPositiveOrZero(BigMoneyProvider moneyProvider) {
075            return (moneyProvider == null || moneyProvider.toBigMoney().isPositiveOrZero());
076        }
077    
078        /**
079         * Checks if the monetary value is negative and non-zero, treating null as zero.
080         * <p>
081         * This method accepts any implementation of {@code BigMoneyProvider}.
082         * 
083         * @return true if the money is non-null and negative
084         */
085        public static boolean isNegative(BigMoneyProvider moneyProvider) {
086            return (moneyProvider != null && moneyProvider.toBigMoney().isNegative());
087        }
088    
089        /**
090         * Checks if the monetary value is negative or zero, treating null as zero.
091         * <p>
092         * This method accepts any implementation of {@code BigMoneyProvider}.
093         * 
094         * @return true if the money is null, zero or negative
095         */
096        public static boolean isNegativeOrZero(BigMoneyProvider moneyProvider) {
097            return (moneyProvider == null || moneyProvider.toBigMoney().isNegativeOrZero());
098        }
099    
100        //-----------------------------------------------------------------------
101        /**
102         * Finds the maximum {@code Money} value, handing null.
103         * <p>
104         * This returns the greater of money1 or money2 where null is ignored.
105         * If both input values are null, then null is returned.
106         * 
107         * @param money1  the first money instance, null returns money2
108         * @param money2  the first money instance, null returns money1
109         * @return the maximum value, null if both inputs are null
110         * @throws CurrencyMismatchException if the currencies differ
111         */
112        public static Money max(Money money1, Money money2) {
113            if (money1 == null) {
114                return money2;
115            }
116            if (money2 == null) {
117                return money1;
118            }
119            return money1.compareTo(money2) > 0 ? money1 : money2;
120        }
121    
122        /**
123         * Finds the minimum {@code Money} value, handing null.
124         * <p>
125         * This returns the greater of money1 or money2 where null is ignored.
126         * If both input values are null, then null is returned.
127         * 
128         * @param money1  the first money instance, null returns money2
129         * @param money2  the first money instance, null returns money1
130         * @return the minimum value, null if both inputs are null
131         * @throws CurrencyMismatchException if the currencies differ
132         */
133        public static Money min(Money money1, Money money2) {
134            if (money1 == null) {
135                return money2;
136            }
137            if (money2 == null) {
138                return money1;
139            }
140            return money1.compareTo(money2) < 0 ? money1 : money2;
141        }
142    
143        //-----------------------------------------------------------------------
144        /**
145         * Adds two {@code Money} objects, handling null.
146         * <p>
147         * This returns {@code money1 + money2} where null is ignored.
148         * If both input values are null, then null is returned.
149         * 
150         * @param money1  the first money instance, null returns money2
151         * @param money2  the first money instance, null returns money1
152         * @return the total, where null is ignored, null if both inputs are null
153         * @throws CurrencyMismatchException if the currencies differ
154         */
155        public static Money add(Money money1, Money money2) {
156            if (money1 == null) {
157                return money2;
158            }
159            if (money2 == null) {
160                return money1;
161            }
162            return money1.plus(money2);
163        }
164    
165        //-----------------------------------------------------------------------
166        /**
167         * Subtracts the second {@code Money} from the first, handling null.
168         * <p>
169         * This returns {@code money1 - money2} where null is ignored.
170         * If both input values are null, then null is returned.
171         * 
172         * @param money1  the first money instance, null treated as zero
173         * @param money2  the first money instance, null returns money1
174         * @return the total, where null is ignored, null if both inputs are null
175         * @throws CurrencyMismatchException if the currencies differ
176         */
177        public static Money subtract(Money money1, Money money2) {
178            if (money2 == null) {
179                return money1;
180            }
181            if (money1 == null) {
182                return money2.negated();
183            }
184            return money1.minus(money2);
185        }
186    
187        //-----------------------------------------------------------------------
188        /**
189         * Finds the maximum {@code BigMoney} value, handing null.
190         * <p>
191         * This returns the greater of money1 or money2 where null is ignored.
192         * If both input values are null, then null is returned.
193         * 
194         * @param money1  the first money instance, null returns money2
195         * @param money2  the first money instance, null returns money1
196         * @return the maximum value, null if both inputs are null
197         * @throws CurrencyMismatchException if the currencies differ
198         */
199        public static BigMoney max(BigMoney money1, BigMoney money2) {
200            if (money1 == null) {
201                return money2;
202            }
203            if (money2 == null) {
204                return money1;
205            }
206            return money1.compareTo(money2) > 0 ? money1 : money2;
207        }
208    
209        /**
210         * Finds the minimum {@code BigMoney} value, handing null.
211         * <p>
212         * This returns the greater of money1 or money2 where null is ignored.
213         * If both input values are null, then null is returned.
214         * 
215         * @param money1  the first money instance, null returns money2
216         * @param money2  the first money instance, null returns money1
217         * @return the minimum value, null if both inputs are null
218         * @throws CurrencyMismatchException if the currencies differ
219         */
220        public static BigMoney min(BigMoney money1, BigMoney money2) {
221            if (money1 == null) {
222                return money2;
223            }
224            if (money2 == null) {
225                return money1;
226            }
227            return money1.compareTo(money2) < 0 ? money1 : money2;
228        }
229    
230        //-----------------------------------------------------------------------
231        /**
232         * Adds two {@code BigMoney} objects, handling null.
233         * <p>
234         * This returns {@code money1 + money2} where null is ignored.
235         * If both input values are null, then null is returned.
236         * 
237         * @param money1  the first money instance, null returns money2
238         * @param money2  the first money instance, null returns money1
239         * @return the total, where null is ignored, null if both inputs are null
240         * @throws CurrencyMismatchException if the currencies differ
241         */
242        public static BigMoney add(BigMoney money1, BigMoney money2) {
243            if (money1 == null) {
244                return money2;
245            }
246            if (money2 == null) {
247                return money1;
248            }
249            return money1.plus(money2);
250        }
251    
252        //-----------------------------------------------------------------------
253        /**
254         * Subtracts the second {@code BigMoney} from the first, handling null.
255         * <p>
256         * This returns {@code money1 - money2} where null is ignored.
257         * If both input values are null, then null is returned.
258         * 
259         * @param money1  the first money instance, null treated as zero
260         * @param money2  the first money instance, null returns money1
261         * @return the total, where null is ignored, null if both inputs are null
262         * @throws CurrencyMismatchException if the currencies differ
263         */
264        public static BigMoney subtract(BigMoney money1, BigMoney money2) {
265            if (money2 == null) {
266                return money1;
267            }
268            if (money1 == null) {
269                return money2.negated();
270            }
271            return money1.minus(money2);
272        }
273    
274    }