001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.lang3;
018
019import org.apache.commons.lang3.math.NumberUtils;
020
021/**
022 * <p>Operations on boolean primitives and Boolean objects.</p>
023 *
024 * <p>This class tries to handle {@code null} input gracefully.
025 * An exception will not be thrown for a {@code null} input.
026 * Each method documents its behavior in more detail.</p>
027 *
028 * <p>#ThreadSafe#</p>
029 * @since 2.0
030 */
031public class BooleanUtils {
032    /**
033     * The false String {@code "false"}.
034     *
035     * @since 3.12.0
036     */
037    public static final String FALSE = "false";
038
039    /**
040     * The no String {@code "no"}.
041     *
042     * @since 3.12.0
043     */
044    public static final String NO = "no";
045
046    /**
047     * The off String {@code "off"}.
048     *
049     * @since 3.12.0
050     */
051    public static final String OFF = "off";
052
053    /**
054     * The on String {@code "on"}.
055     *
056     * @since 3.12.0
057     */
058    public static final String ON = "on";
059
060    /**
061     * The true String {@code "true"}.
062     *
063     * @since 3.12.0
064     */
065    public static final String TRUE = "true";
066
067    /**
068     * The yes String {@code "yes"}.
069     *
070     * @since 3.12.0
071     */
072    public static final String YES = "yes";
073
074    /**
075     * <p>Performs an 'and' operation on a set of booleans.</p>
076     *
077     * <pre>
078     *   BooleanUtils.and(true, true)         = true
079     *   BooleanUtils.and(false, false)       = false
080     *   BooleanUtils.and(true, false)        = false
081     *   BooleanUtils.and(true, true, false)  = false
082     *   BooleanUtils.and(true, true, true)   = true
083     * </pre>
084     *
085     * @param array  an array of {@code boolean}s
086     * @return the result of the logical 'and' operation. That is {@code false}
087     * if any of the parameters is {@code false} and {@code true} otherwise.
088     * @throws NullPointerException if {@code array} is {@code null}
089     * @throws IllegalArgumentException if {@code array} is empty.
090     * @since 3.0.1
091     */
092    public static boolean and(final boolean... array) {
093        ObjectUtils.requireNonEmpty(array, "array");
094        for (final boolean element : array) {
095            if (!element) {
096                return false;
097            }
098        }
099        return true;
100    }
101
102    /**
103     * <p>Performs an 'and' operation on an array of Booleans.</p>
104     *
105     * <pre>
106     *   BooleanUtils.and(Boolean.TRUE, Boolean.TRUE)                 = Boolean.TRUE
107     *   BooleanUtils.and(Boolean.FALSE, Boolean.FALSE)               = Boolean.FALSE
108     *   BooleanUtils.and(Boolean.TRUE, Boolean.FALSE)                = Boolean.FALSE
109     *   BooleanUtils.and(Boolean.TRUE, Boolean.TRUE, Boolean.TRUE)   = Boolean.TRUE
110     *   BooleanUtils.and(Boolean.FALSE, Boolean.FALSE, Boolean.TRUE) = Boolean.FALSE
111     *   BooleanUtils.and(Boolean.TRUE, Boolean.FALSE, Boolean.TRUE)  = Boolean.FALSE
112     * </pre>
113     *
114     * @param array  an array of {@code Boolean}s
115     * @return the result of the logical 'and' operation. That is {@code false}
116     * if any of the parameters is {@code false} and {@code true} otherwise.
117     * @throws NullPointerException if {@code array} is {@code null}
118     * @throws IllegalArgumentException if {@code array} is empty.
119     * @throws IllegalArgumentException if {@code array} contains a {@code null}
120     * @since 3.0.1
121     */
122    public static Boolean and(final Boolean... array) {
123        ObjectUtils.requireNonEmpty(array, "array");
124        try {
125            final boolean[] primitive = ArrayUtils.toPrimitive(array);
126            return and(primitive) ? Boolean.TRUE : Boolean.FALSE;
127        } catch (final NullPointerException ex) {
128            throw new IllegalArgumentException("The array must not contain any null elements");
129        }
130    }
131
132    /**
133     * Returns a new array of possible values (like an enum would).
134     * @return a new array of possible values (like an enum would).
135     * @since 3.12.0
136     */
137    public static Boolean[] booleanValues() {
138        return new Boolean[] {Boolean.FALSE, Boolean.TRUE};
139    }
140
141    /**
142     * <p>Compares two {@code boolean} values. This is the same functionality as provided in Java 7.</p>
143     *
144     * @param x the first {@code boolean} to compare
145     * @param y the second {@code boolean} to compare
146     * @return the value {@code 0} if {@code x == y};
147     *         a value less than {@code 0} if {@code !x && y}; and
148     *         a value greater than {@code 0} if {@code x && !y}
149     * @since 3.4
150     */
151    public static int compare(final boolean x, final boolean y) {
152        if (x == y) {
153            return 0;
154        }
155        return x ? 1 : -1;
156    }
157
158    /**
159     * <p>Checks if a {@code Boolean} value is {@code false},
160     * handling {@code null} by returning {@code false}.</p>
161     *
162     * <pre>
163     *   BooleanUtils.isFalse(Boolean.TRUE)  = false
164     *   BooleanUtils.isFalse(Boolean.FALSE) = true
165     *   BooleanUtils.isFalse(null)          = false
166     * </pre>
167     *
168     * @param bool  the boolean to check, null returns {@code false}
169     * @return {@code true} only if the input is non-{@code null} and {@code false}
170     * @since 2.1
171     */
172    public static boolean isFalse(final Boolean bool) {
173        return Boolean.FALSE.equals(bool);
174    }
175
176    /**
177     * <p>Checks if a {@code Boolean} value is <i>not</i> {@code false},
178     * handling {@code null} by returning {@code true}.</p>
179     *
180     * <pre>
181     *   BooleanUtils.isNotFalse(Boolean.TRUE)  = true
182     *   BooleanUtils.isNotFalse(Boolean.FALSE) = false
183     *   BooleanUtils.isNotFalse(null)          = true
184     * </pre>
185     *
186     * @param bool  the boolean to check, null returns {@code true}
187     * @return {@code true} if the input is {@code null} or {@code true}
188     * @since 2.3
189     */
190    public static boolean isNotFalse(final Boolean bool) {
191        return !isFalse(bool);
192    }
193
194    /**
195     * <p>Checks if a {@code Boolean} value is <i>not</i> {@code true},
196     * handling {@code null} by returning {@code true}.</p>
197     *
198     * <pre>
199     *   BooleanUtils.isNotTrue(Boolean.TRUE)  = false
200     *   BooleanUtils.isNotTrue(Boolean.FALSE) = true
201     *   BooleanUtils.isNotTrue(null)          = true
202     * </pre>
203     *
204     * @param bool  the boolean to check, null returns {@code true}
205     * @return {@code true} if the input is null or false
206     * @since 2.3
207     */
208    public static boolean isNotTrue(final Boolean bool) {
209        return !isTrue(bool);
210    }
211
212    /**
213     * <p>Checks if a {@code Boolean} value is {@code true},
214     * handling {@code null} by returning {@code false}.</p>
215     *
216     * <pre>
217     *   BooleanUtils.isTrue(Boolean.TRUE)  = true
218     *   BooleanUtils.isTrue(Boolean.FALSE) = false
219     *   BooleanUtils.isTrue(null)          = false
220     * </pre>
221     *
222     * @param bool the boolean to check, {@code null} returns {@code false}
223     * @return {@code true} only if the input is non-null and true
224     * @since 2.1
225     */
226    public static boolean isTrue(final Boolean bool) {
227        return Boolean.TRUE.equals(bool);
228    }
229
230    /**
231     * <p>Negates the specified boolean.</p>
232     *
233     * <p>If {@code null} is passed in, {@code null} will be returned.</p>
234     *
235     * <p>NOTE: This returns {@code null} and will throw a {@code NullPointerException}
236     * if unboxed to a boolean. </p>
237     *
238     * <pre>
239     *   BooleanUtils.negate(Boolean.TRUE)  = Boolean.FALSE;
240     *   BooleanUtils.negate(Boolean.FALSE) = Boolean.TRUE;
241     *   BooleanUtils.negate(null)          = null;
242     * </pre>
243     *
244     * @param bool  the Boolean to negate, may be null
245     * @return the negated Boolean, or {@code null} if {@code null} input
246     */
247    public static Boolean negate(final Boolean bool) {
248        if (bool == null) {
249            return null;
250        }
251        return bool.booleanValue() ? Boolean.FALSE : Boolean.TRUE;
252    }
253    /**
254     * <p>Performs an 'or' operation on a set of booleans.</p>
255     *
256     * <pre>
257     *   BooleanUtils.or(true, true)          = true
258     *   BooleanUtils.or(false, false)        = false
259     *   BooleanUtils.or(true, false)         = true
260     *   BooleanUtils.or(true, true, false)   = true
261     *   BooleanUtils.or(true, true, true)    = true
262     *   BooleanUtils.or(false, false, false) = false
263     * </pre>
264     *
265     * @param array  an array of {@code boolean}s
266     * @return {@code true} if any of the arguments is {@code true}, and it returns {@code false} otherwise.
267     * @throws NullPointerException if {@code array} is {@code null}
268     * @throws IllegalArgumentException if {@code array} is empty.
269     * @since 3.0.1
270     */
271    public static boolean or(final boolean... array) {
272        ObjectUtils.requireNonEmpty(array, "array");
273        for (final boolean element : array) {
274            if (element) {
275                return true;
276            }
277        }
278        return false;
279    }
280
281    /**
282     * <p>Performs an 'or' operation on an array of Booleans.</p>
283     *
284     * <pre>
285     *   BooleanUtils.or(Boolean.TRUE, Boolean.TRUE)                  = Boolean.TRUE
286     *   BooleanUtils.or(Boolean.FALSE, Boolean.FALSE)                = Boolean.FALSE
287     *   BooleanUtils.or(Boolean.TRUE, Boolean.FALSE)                 = Boolean.TRUE
288     *   BooleanUtils.or(Boolean.TRUE, Boolean.TRUE, Boolean.TRUE)    = Boolean.TRUE
289     *   BooleanUtils.or(Boolean.FALSE, Boolean.FALSE, Boolean.TRUE)  = Boolean.TRUE
290     *   BooleanUtils.or(Boolean.TRUE, Boolean.FALSE, Boolean.TRUE)   = Boolean.TRUE
291     *   BooleanUtils.or(Boolean.FALSE, Boolean.FALSE, Boolean.FALSE) = Boolean.FALSE
292     * </pre>
293     *
294     * @param array  an array of {@code Boolean}s
295     * @return {@code true} if any of the arguments is {@code true}, and it returns {@code false} otherwise.
296     * @throws NullPointerException if {@code array} is {@code null}
297     * @throws IllegalArgumentException if {@code array} is empty.
298     * @throws IllegalArgumentException if {@code array} contains a {@code null}
299     * @since 3.0.1
300     */
301    public static Boolean or(final Boolean... array) {
302        ObjectUtils.requireNonEmpty(array, "array");
303        try {
304            final boolean[] primitive = ArrayUtils.toPrimitive(array);
305            return or(primitive) ? Boolean.TRUE : Boolean.FALSE;
306        } catch (final NullPointerException ex) {
307            throw new IllegalArgumentException("The array must not contain any null elements");
308        }
309    }
310
311    /**
312     * Returns a new array of possible values (like an enum would).
313     * @return a new array of possible values (like an enum would).
314     * @since 3.12.0
315     */
316    public static boolean[] primitiveValues() {
317        return new boolean[] {false, true};
318    }
319
320    /**
321     * <p>Converts a Boolean to a boolean handling {@code null}
322     * by returning {@code false}.</p>
323     *
324     * <pre>
325     *   BooleanUtils.toBoolean(Boolean.TRUE)  = true
326     *   BooleanUtils.toBoolean(Boolean.FALSE) = false
327     *   BooleanUtils.toBoolean(null)          = false
328     * </pre>
329     *
330     * @param bool  the boolean to convert
331     * @return {@code true} or {@code false}, {@code null} returns {@code false}
332     */
333    public static boolean toBoolean(final Boolean bool) {
334        return bool != null && bool.booleanValue();
335    }
336
337    /**
338     * <p>Converts an int to a boolean using the convention that {@code zero}
339     * is {@code false}, everything else is {@code true}.</p>
340     *
341     * <pre>
342     *   BooleanUtils.toBoolean(0) = false
343     *   BooleanUtils.toBoolean(1) = true
344     *   BooleanUtils.toBoolean(2) = true
345     * </pre>
346     *
347     * @param value  the int to convert
348     * @return {@code true} if non-zero, {@code false}
349     *  if zero
350     */
351    public static boolean toBoolean(final int value) {
352        return value != 0;
353    }
354
355    /**
356     * <p>Converts an int to a boolean specifying the conversion values.</p>
357     *
358     * <p>If the {@code trueValue} and {@code falseValue} are the same number then
359     * the return value will be {@code true} in case {@code value} matches it.</p>
360     *
361     * <pre>
362     *   BooleanUtils.toBoolean(0, 1, 0) = false
363     *   BooleanUtils.toBoolean(1, 1, 0) = true
364     *   BooleanUtils.toBoolean(1, 1, 1) = true
365     *   BooleanUtils.toBoolean(2, 1, 2) = false
366     *   BooleanUtils.toBoolean(2, 2, 0) = true
367     * </pre>
368     *
369     * @param value  the {@code Integer} to convert
370     * @param trueValue  the value to match for {@code true}
371     * @param falseValue  the value to match for {@code false}
372     * @return {@code true} or {@code false}
373     * @throws IllegalArgumentException if {@code value} does not match neither
374     * {@code trueValue} no {@code falseValue}
375     */
376    public static boolean toBoolean(final int value, final int trueValue, final int falseValue) {
377        if (value == trueValue) {
378            return true;
379        }
380        if (value == falseValue) {
381            return false;
382        }
383        throw new IllegalArgumentException("The Integer did not match either specified value");
384    }
385
386    /**
387     * <p>Converts an Integer to a boolean specifying the conversion values.</p>
388     *
389     * <pre>
390     *   BooleanUtils.toBoolean(Integer.valueOf(0), Integer.valueOf(1), Integer.valueOf(0)) = false
391     *   BooleanUtils.toBoolean(Integer.valueOf(1), Integer.valueOf(1), Integer.valueOf(0)) = true
392     *   BooleanUtils.toBoolean(Integer.valueOf(2), Integer.valueOf(1), Integer.valueOf(2)) = false
393     *   BooleanUtils.toBoolean(Integer.valueOf(2), Integer.valueOf(2), Integer.valueOf(0)) = true
394     *   BooleanUtils.toBoolean(null, null, Integer.valueOf(0))                     = true
395     * </pre>
396     *
397     * @param value  the Integer to convert
398     * @param trueValue  the value to match for {@code true}, may be {@code null}
399     * @param falseValue  the value to match for {@code false}, may be {@code null}
400     * @return {@code true} or {@code false}
401     * @throws IllegalArgumentException if no match
402     */
403    public static boolean toBoolean(final Integer value, final Integer trueValue, final Integer falseValue) {
404        if (value == null) {
405            if (trueValue == null) {
406                return true;
407            }
408            if (falseValue == null) {
409                return false;
410            }
411        } else if (value.equals(trueValue)) {
412            return true;
413        } else if (value.equals(falseValue)) {
414            return false;
415        }
416        throw new IllegalArgumentException("The Integer did not match either specified value");
417    }
418
419    /**
420     * <p>Converts a String to a boolean (optimised for performance).</p>
421     *
422     * <p>{@code 'true'}, {@code 'on'}, {@code 'y'}, {@code 't'} or {@code 'yes'}
423     * (case insensitive) will return {@code true}. Otherwise,
424     * {@code false} is returned.</p>
425     *
426     * <p>This method performs 4 times faster (JDK1.4) than
427     * {@code Boolean.valueOf(String)}. However, this method accepts
428     * 'on' and 'yes', 't', 'y' as true values.
429     *
430     * <pre>
431     *   BooleanUtils.toBoolean(null)    = false
432     *   BooleanUtils.toBoolean("true")  = true
433     *   BooleanUtils.toBoolean("TRUE")  = true
434     *   BooleanUtils.toBoolean("tRUe")  = true
435     *   BooleanUtils.toBoolean("on")    = true
436     *   BooleanUtils.toBoolean("yes")   = true
437     *   BooleanUtils.toBoolean("false") = false
438     *   BooleanUtils.toBoolean("x gti") = false
439     *   BooleanUtils.toBoolean("y") = true
440     *   BooleanUtils.toBoolean("n") = false
441     *   BooleanUtils.toBoolean("t") = true
442     *   BooleanUtils.toBoolean("f") = false
443     * </pre>
444     *
445     * @param str  the String to check
446     * @return the boolean value of the string, {@code false} if no match or the String is null
447     */
448    public static boolean toBoolean(final String str) {
449        return toBooleanObject(str) == Boolean.TRUE;
450    }
451
452    /**
453     * <p>Converts a String to a Boolean throwing an exception if no match found.</p>
454     *
455     * <pre>
456     *   BooleanUtils.toBoolean("true", "true", "false")  = true
457     *   BooleanUtils.toBoolean("false", "true", "false") = false
458     * </pre>
459     *
460     * @param str  the String to check
461     * @param trueString  the String to match for {@code true} (case sensitive), may be {@code null}
462     * @param falseString  the String to match for {@code false} (case sensitive), may be {@code null}
463     * @return the boolean value of the string
464     * @throws IllegalArgumentException if the String doesn't match
465     */
466    public static boolean toBoolean(final String str, final String trueString, final String falseString) {
467        if (str == trueString) {
468            return true;
469        } else if (str == falseString) {
470            return false;
471        } else if (str != null) {
472            if (str.equals(trueString)) {
473                return true;
474            } else if (str.equals(falseString)) {
475                return false;
476            }
477        }
478        throw new IllegalArgumentException("The String did not match either specified value");
479    }
480
481    /**
482     * <p>Converts a Boolean to a boolean handling {@code null}.</p>
483     *
484     * <pre>
485     *   BooleanUtils.toBooleanDefaultIfNull(Boolean.TRUE, false)  = true
486     *   BooleanUtils.toBooleanDefaultIfNull(Boolean.TRUE, true)   = true
487     *   BooleanUtils.toBooleanDefaultIfNull(Boolean.FALSE, true)  = false
488     *   BooleanUtils.toBooleanDefaultIfNull(Boolean.FALSE, false) = false
489     *   BooleanUtils.toBooleanDefaultIfNull(null, true)           = true
490     *   BooleanUtils.toBooleanDefaultIfNull(null, false)          = false
491     * </pre>
492     *
493     * @param bool  the boolean object to convert to primitive
494     * @param valueIfNull  the boolean value to return if the parameter {@code bool} is {@code null}
495     * @return {@code true} or {@code false}
496     */
497    public static boolean toBooleanDefaultIfNull(final Boolean bool, final boolean valueIfNull) {
498        if (bool == null) {
499            return valueIfNull;
500        }
501        return bool.booleanValue();
502    }
503
504    /**
505     * <p>Converts an int to a Boolean using the convention that {@code zero}
506     * is {@code false}, everything else is {@code true}.</p>
507     *
508     * <pre>
509     *   BooleanUtils.toBoolean(0) = Boolean.FALSE
510     *   BooleanUtils.toBoolean(1) = Boolean.TRUE
511     *   BooleanUtils.toBoolean(2) = Boolean.TRUE
512     * </pre>
513     *
514     * @param value  the int to convert
515     * @return Boolean.TRUE if non-zero, Boolean.FALSE if zero,
516     *  {@code null} if {@code null}
517     */
518    public static Boolean toBooleanObject(final int value) {
519        return value == 0 ? Boolean.FALSE : Boolean.TRUE;
520    }
521
522    /**
523     * <p>Converts an int to a Boolean specifying the conversion values.</p>
524     *
525     * <p>NOTE: This method may return {@code null} and may throw a {@code NullPointerException}
526     * if unboxed to a {@code boolean}.</p>
527     *
528     * <p>The checks are done first for the {@code trueValue}, then for the {@code falseValue} and
529     * finally for the {@code nullValue}.</p>
530     *
531     * <pre>
532     *   BooleanUtils.toBooleanObject(0, 0, 2, 3) = Boolean.TRUE
533     *   BooleanUtils.toBooleanObject(0, 0, 0, 3) = Boolean.TRUE
534     *   BooleanUtils.toBooleanObject(0, 0, 0, 0) = Boolean.TRUE
535     *   BooleanUtils.toBooleanObject(2, 1, 2, 3) = Boolean.FALSE
536     *   BooleanUtils.toBooleanObject(2, 1, 2, 2) = Boolean.FALSE
537     *   BooleanUtils.toBooleanObject(3, 1, 2, 3) = null
538     * </pre>
539     *
540     * @param value  the Integer to convert
541     * @param trueValue  the value to match for {@code true}
542     * @param falseValue  the value to match for {@code false}
543     * @param nullValue  the value to to match for {@code null}
544     * @return Boolean.TRUE, Boolean.FALSE, or {@code null}
545     * @throws IllegalArgumentException if no match
546     */
547    public static Boolean toBooleanObject(final int value, final int trueValue, final int falseValue, final int nullValue) {
548        if (value == trueValue) {
549            return Boolean.TRUE;
550        }
551        if (value == falseValue) {
552            return Boolean.FALSE;
553        }
554        if (value == nullValue) {
555            return null;
556        }
557        throw new IllegalArgumentException("The Integer did not match any specified value");
558    }
559
560    /**
561     * <p>Converts an Integer to a Boolean using the convention that {@code zero}
562     * is {@code false}, every other numeric value is {@code true}.</p>
563     *
564     * <p>{@code null} will be converted to {@code null}.</p>
565     *
566     * <p>NOTE: This method may return {@code null} and may throw a {@code NullPointerException}
567     * if unboxed to a {@code boolean}.</p>
568     *
569     * <pre>
570     *   BooleanUtils.toBooleanObject(Integer.valueOf(0))    = Boolean.FALSE
571     *   BooleanUtils.toBooleanObject(Integer.valueOf(1))    = Boolean.TRUE
572     *   BooleanUtils.toBooleanObject(Integer.valueOf(null)) = null
573     * </pre>
574     *
575     * @param value  the Integer to convert
576     * @return Boolean.TRUE if non-zero, Boolean.FALSE if zero,
577     *  {@code null} if {@code null} input
578     */
579    public static Boolean toBooleanObject(final Integer value) {
580        if (value == null) {
581            return null;
582        }
583        return value.intValue() == 0 ? Boolean.FALSE : Boolean.TRUE;
584    }
585
586    /**
587     * <p>Converts an Integer to a Boolean specifying the conversion values.</p>
588     *
589     * <p>NOTE: This method may return {@code null} and may throw a {@code NullPointerException}
590     * if unboxed to a {@code boolean}.</p>
591     *
592     * <p>The checks are done first for the {@code trueValue}, then for the {@code falseValue} and
593     * finally for the {@code nullValue}.</p>
594     **
595     * <pre>
596     *   BooleanUtils.toBooleanObject(Integer.valueOf(0), Integer.valueOf(0), Integer.valueOf(2), Integer.valueOf(3)) = Boolean.TRUE
597     *   BooleanUtils.toBooleanObject(Integer.valueOf(0), Integer.valueOf(0), Integer.valueOf(0), Integer.valueOf(3)) = Boolean.TRUE
598     *   BooleanUtils.toBooleanObject(Integer.valueOf(0), Integer.valueOf(0), Integer.valueOf(0), Integer.valueOf(0)) = Boolean.TRUE
599     *   BooleanUtils.toBooleanObject(Integer.valueOf(2), Integer.valueOf(1), Integer.valueOf(2), Integer.valueOf(3)) = Boolean.FALSE
600     *   BooleanUtils.toBooleanObject(Integer.valueOf(2), Integer.valueOf(1), Integer.valueOf(2), Integer.valueOf(2)) = Boolean.FALSE
601     *   BooleanUtils.toBooleanObject(Integer.valueOf(3), Integer.valueOf(1), Integer.valueOf(2), Integer.valueOf(3)) = null
602     * </pre>
603     *
604     * @param value  the Integer to convert
605     * @param trueValue  the value to match for {@code true}, may be {@code null}
606     * @param falseValue  the value to match for {@code false}, may be {@code null}
607     * @param nullValue  the value to to match for {@code null}, may be {@code null}
608     * @return Boolean.TRUE, Boolean.FALSE, or {@code null}
609     * @throws IllegalArgumentException if no match
610     */
611    public static Boolean toBooleanObject(final Integer value, final Integer trueValue, final Integer falseValue, final Integer nullValue) {
612        if (value == null) {
613            if (trueValue == null) {
614                return Boolean.TRUE;
615            }
616            if (falseValue == null) {
617                return Boolean.FALSE;
618            }
619            if (nullValue == null) {
620                return null;
621            }
622        } else if (value.equals(trueValue)) {
623            return Boolean.TRUE;
624        } else if (value.equals(falseValue)) {
625            return Boolean.FALSE;
626        } else if (value.equals(nullValue)) {
627            return null;
628        }
629        throw new IllegalArgumentException("The Integer did not match any specified value");
630    }
631
632    /**
633     * <p>Converts a String to a Boolean.</p>
634     *
635     * <p>{@code 'true'}, {@code 'on'}, {@code 'y'}, {@code 't'}, {@code 'yes'}
636     * or {@code '1'} (case insensitive) will return {@code true}.
637     * {@code 'false'}, {@code 'off'}, {@code 'n'}, {@code 'f'}, {@code 'no'}
638     * or {@code '0'} (case insensitive) will return {@code false}.
639     * Otherwise, {@code null} is returned.</p>
640     *
641     * <p>NOTE: This method may return {@code null} and may throw a {@code NullPointerException}
642     * if unboxed to a {@code boolean}.</p>
643     *
644     * <pre>
645     *   // N.B. case is not significant
646     *   BooleanUtils.toBooleanObject(null)    = null
647     *   BooleanUtils.toBooleanObject("true")  = Boolean.TRUE
648     *   BooleanUtils.toBooleanObject("T")     = Boolean.TRUE // i.e. T[RUE]
649     *   BooleanUtils.toBooleanObject("false") = Boolean.FALSE
650     *   BooleanUtils.toBooleanObject("f")     = Boolean.FALSE // i.e. f[alse]
651     *   BooleanUtils.toBooleanObject("No")    = Boolean.FALSE
652     *   BooleanUtils.toBooleanObject("n")     = Boolean.FALSE // i.e. n[o]
653     *   BooleanUtils.toBooleanObject("on")    = Boolean.TRUE
654     *   BooleanUtils.toBooleanObject("ON")    = Boolean.TRUE
655     *   BooleanUtils.toBooleanObject("off")   = Boolean.FALSE
656     *   BooleanUtils.toBooleanObject("oFf")   = Boolean.FALSE
657     *   BooleanUtils.toBooleanObject("yes")   = Boolean.TRUE
658     *   BooleanUtils.toBooleanObject("Y")     = Boolean.TRUE // i.e. Y[ES]
659     *   BooleanUtils.toBooleanObject("1")     = Boolean.TRUE
660     *   BooleanUtils.toBooleanObject("0")     = Boolean.FALSE
661     *   BooleanUtils.toBooleanObject("blue")  = null
662     *   BooleanUtils.toBooleanObject("true ") = null // trailing space (too long)
663     *   BooleanUtils.toBooleanObject("ono")   = null // does not match on or no
664     * </pre>
665     *
666     * @param str  the String to check; upper and lower case are treated as the same
667     * @return the Boolean value of the string, {@code null} if no match or {@code null} input
668     */
669    public static Boolean toBooleanObject(final String str) {
670        // Previously used equalsIgnoreCase, which was fast for interned 'true'.
671        // Non interned 'true' matched 15 times slower.
672        //
673        // Optimisation provides same performance as before for interned 'true'.
674        // Similar performance for null, 'false', and other strings not length 2/3/4.
675        // 'true'/'TRUE' match 4 times slower, 'tRUE'/'True' 7 times slower.
676        if (str == TRUE) {
677            return Boolean.TRUE;
678        }
679        if (str == null) {
680            return null;
681        }
682        switch (str.length()) {
683            case 1: {
684                final char ch0 = str.charAt(0);
685                if (ch0 == 'y' || ch0 == 'Y' ||
686                    ch0 == 't' || ch0 == 'T' ||
687                    ch0 == '1') {
688                    return Boolean.TRUE;
689                }
690                if (ch0 == 'n' || ch0 == 'N' ||
691                    ch0 == 'f' || ch0 == 'F' ||
692                    ch0 == '0') {
693                    return Boolean.FALSE;
694                }
695                break;
696            }
697            case 2: {
698                final char ch0 = str.charAt(0);
699                final char ch1 = str.charAt(1);
700                if ((ch0 == 'o' || ch0 == 'O') &&
701                    (ch1 == 'n' || ch1 == 'N') ) {
702                    return Boolean.TRUE;
703                }
704                if ((ch0 == 'n' || ch0 == 'N') &&
705                    (ch1 == 'o' || ch1 == 'O') ) {
706                    return Boolean.FALSE;
707                }
708                break;
709            }
710            case 3: {
711                final char ch0 = str.charAt(0);
712                final char ch1 = str.charAt(1);
713                final char ch2 = str.charAt(2);
714                if ((ch0 == 'y' || ch0 == 'Y') &&
715                    (ch1 == 'e' || ch1 == 'E') &&
716                    (ch2 == 's' || ch2 == 'S') ) {
717                    return Boolean.TRUE;
718                }
719                if ((ch0 == 'o' || ch0 == 'O') &&
720                    (ch1 == 'f' || ch1 == 'F') &&
721                    (ch2 == 'f' || ch2 == 'F') ) {
722                    return Boolean.FALSE;
723                }
724                break;
725            }
726            case 4: {
727                final char ch0 = str.charAt(0);
728                final char ch1 = str.charAt(1);
729                final char ch2 = str.charAt(2);
730                final char ch3 = str.charAt(3);
731                if ((ch0 == 't' || ch0 == 'T') &&
732                    (ch1 == 'r' || ch1 == 'R') &&
733                    (ch2 == 'u' || ch2 == 'U') &&
734                    (ch3 == 'e' || ch3 == 'E') ) {
735                    return Boolean.TRUE;
736                }
737                break;
738            }
739            case 5: {
740                final char ch0 = str.charAt(0);
741                final char ch1 = str.charAt(1);
742                final char ch2 = str.charAt(2);
743                final char ch3 = str.charAt(3);
744                final char ch4 = str.charAt(4);
745                if ((ch0 == 'f' || ch0 == 'F') &&
746                    (ch1 == 'a' || ch1 == 'A') &&
747                    (ch2 == 'l' || ch2 == 'L') &&
748                    (ch3 == 's' || ch3 == 'S') &&
749                    (ch4 == 'e' || ch4 == 'E') ) {
750                    return Boolean.FALSE;
751                }
752                break;
753            }
754        default:
755            break;
756        }
757
758        return null;
759    }
760
761    /**
762     * <p>Converts a String to a Boolean throwing an exception if no match.</p>
763     *
764     * <p>NOTE: This method may return {@code null} and may throw a {@code NullPointerException}
765     * if unboxed to a {@code boolean}.</p>
766     *
767     * <pre>
768     *   BooleanUtils.toBooleanObject("true", "true", "false", "null")   = Boolean.TRUE
769     *   BooleanUtils.toBooleanObject(null, null, "false", "null")       = Boolean.TRUE
770     *   BooleanUtils.toBooleanObject(null, null, null, "null")          = Boolean.TRUE
771     *   BooleanUtils.toBooleanObject(null, null, null, null)            = Boolean.TRUE
772     *   BooleanUtils.toBooleanObject("false", "true", "false", "null")  = Boolean.FALSE
773     *   BooleanUtils.toBooleanObject("false", "true", "false", "false") = Boolean.FALSE
774     *   BooleanUtils.toBooleanObject(null, "true", null, "false")       = Boolean.FALSE
775     *   BooleanUtils.toBooleanObject(null, "true", null, null)          = Boolean.FALSE
776     *   BooleanUtils.toBooleanObject("null", "true", "false", "null")   = null
777     * </pre>
778     *
779     * @param str  the String to check
780     * @param trueString  the String to match for {@code true} (case sensitive), may be {@code null}
781     * @param falseString  the String to match for {@code false} (case sensitive), may be {@code null}
782     * @param nullString  the String to match for {@code null} (case sensitive), may be {@code null}
783     * @return the Boolean value of the string, {@code null} if either the String matches {@code nullString}
784     *  or if {@code null} input and {@code nullString} is {@code null}
785     * @throws IllegalArgumentException if the String doesn't match
786     */
787    public static Boolean toBooleanObject(final String str, final String trueString, final String falseString, final String nullString) {
788        if (str == null) {
789            if (trueString == null) {
790                return Boolean.TRUE;
791            }
792            if (falseString == null) {
793                return Boolean.FALSE;
794            }
795            if (nullString == null) {
796                return null;
797            }
798        } else if (str.equals(trueString)) {
799            return Boolean.TRUE;
800        } else if (str.equals(falseString)) {
801            return Boolean.FALSE;
802        } else if (str.equals(nullString)) {
803            return null;
804        }
805        // no match
806        throw new IllegalArgumentException("The String did not match any specified value");
807    }
808
809    /**
810     * <p>Converts a boolean to an int using the convention that
811     * {@code true} is {@code 1} and {@code false} is {@code 0}.</p>
812     *
813     * <pre>
814     *   BooleanUtils.toInteger(true)  = 1
815     *   BooleanUtils.toInteger(false) = 0
816     * </pre>
817     *
818     * @param bool  the boolean to convert
819     * @return one if {@code true}, zero if {@code false}
820     */
821    public static int toInteger(final boolean bool) {
822        return bool ? 1 : 0;
823    }
824
825    /**
826     * <p>Converts a boolean to an int specifying the conversion values.</p>
827     *
828     * <pre>
829     *   BooleanUtils.toInteger(true, 1, 0)  = 1
830     *   BooleanUtils.toInteger(false, 1, 0) = 0
831     * </pre>
832     *
833     * @param bool  the to convert
834     * @param trueValue  the value to return if {@code true}
835     * @param falseValue  the value to return if {@code false}
836     * @return the appropriate value
837     */
838    public static int toInteger(final boolean bool, final int trueValue, final int falseValue) {
839        return bool ? trueValue : falseValue;
840    }
841
842    /**
843     * <p>Converts a Boolean to an int specifying the conversion values.</p>
844     *
845     * <pre>
846     *   BooleanUtils.toInteger(Boolean.TRUE, 1, 0, 2)  = 1
847     *   BooleanUtils.toInteger(Boolean.FALSE, 1, 0, 2) = 0
848     *   BooleanUtils.toInteger(null, 1, 0, 2)          = 2
849     * </pre>
850     *
851     * @param bool  the Boolean to convert
852     * @param trueValue  the value to return if {@code true}
853     * @param falseValue  the value to return if {@code false}
854     * @param nullValue  the value to return if {@code null}
855     * @return the appropriate value
856     */
857    public static int toInteger(final Boolean bool, final int trueValue, final int falseValue, final int nullValue) {
858        if (bool == null) {
859            return nullValue;
860        }
861        return bool.booleanValue() ? trueValue : falseValue;
862    }
863
864    /**
865     * <p>Converts a boolean to an Integer using the convention that
866     * {@code true} is {@code 1} and {@code false} is {@code 0}.</p>
867     *
868     * <pre>
869     *   BooleanUtils.toIntegerObject(true)  = Integer.valueOf(1)
870     *   BooleanUtils.toIntegerObject(false) = Integer.valueOf(0)
871     * </pre>
872     *
873     * @param bool  the boolean to convert
874     * @return one if {@code true}, zero if {@code false}
875     */
876    public static Integer toIntegerObject(final boolean bool) {
877        return bool ? NumberUtils.INTEGER_ONE : NumberUtils.INTEGER_ZERO;
878    }
879
880    /**
881     * <p>Converts a boolean to an Integer specifying the conversion values.</p>
882     *
883     * <pre>
884     *   BooleanUtils.toIntegerObject(true, Integer.valueOf(1), Integer.valueOf(0))  = Integer.valueOf(1)
885     *   BooleanUtils.toIntegerObject(false, Integer.valueOf(1), Integer.valueOf(0)) = Integer.valueOf(0)
886     * </pre>
887     *
888     * @param bool  the to convert
889     * @param trueValue  the value to return if {@code true}, may be {@code null}
890     * @param falseValue  the value to return if {@code false}, may be {@code null}
891     * @return the appropriate value
892     */
893    public static Integer toIntegerObject(final boolean bool, final Integer trueValue, final Integer falseValue) {
894        return bool ? trueValue : falseValue;
895    }
896
897    /**
898     * <p>Converts a Boolean to a Integer using the convention that
899     * {@code zero} is {@code false}.</p>
900     *
901     * <p>{@code null} will be converted to {@code null}.</p>
902     *
903     * <pre>
904     *   BooleanUtils.toIntegerObject(Boolean.TRUE)  = Integer.valueOf(1)
905     *   BooleanUtils.toIntegerObject(Boolean.FALSE) = Integer.valueOf(0)
906     * </pre>
907     *
908     * @param bool  the Boolean to convert
909     * @return one if Boolean.TRUE, zero if Boolean.FALSE, {@code null} if {@code null}
910     */
911    public static Integer toIntegerObject(final Boolean bool) {
912        if (bool == null) {
913            return null;
914        }
915        return bool.booleanValue() ? NumberUtils.INTEGER_ONE : NumberUtils.INTEGER_ZERO;
916    }
917
918    /**
919     * <p>Converts a Boolean to an Integer specifying the conversion values.</p>
920     *
921     * <pre>
922     *   BooleanUtils.toIntegerObject(Boolean.TRUE, Integer.valueOf(1), Integer.valueOf(0), Integer.valueOf(2))  = Integer.valueOf(1)
923     *   BooleanUtils.toIntegerObject(Boolean.FALSE, Integer.valueOf(1), Integer.valueOf(0), Integer.valueOf(2)) = Integer.valueOf(0)
924     *   BooleanUtils.toIntegerObject(null, Integer.valueOf(1), Integer.valueOf(0), Integer.valueOf(2))          = Integer.valueOf(2)
925     * </pre>
926     *
927     * @param bool  the Boolean to convert
928     * @param trueValue  the value to return if {@code true}, may be {@code null}
929     * @param falseValue  the value to return if {@code false}, may be {@code null}
930     * @param nullValue  the value to return if {@code null}, may be {@code null}
931     * @return the appropriate value
932     */
933    public static Integer toIntegerObject(final Boolean bool, final Integer trueValue, final Integer falseValue, final Integer nullValue) {
934        if (bool == null) {
935            return nullValue;
936        }
937        return bool.booleanValue() ? trueValue : falseValue;
938    }
939
940    /**
941     * <p>Converts a boolean to a String returning one of the input Strings.</p>
942     *
943     * <pre>
944     *   BooleanUtils.toString(true, "true", "false")   = "true"
945     *   BooleanUtils.toString(false, "true", "false")  = "false"
946     * </pre>
947     *
948     * @param bool  the Boolean to check
949     * @param trueString  the String to return if {@code true}, may be {@code null}
950     * @param falseString  the String to return if {@code false}, may be {@code null}
951     * @return one of the two input Strings
952     */
953    public static String toString(final boolean bool, final String trueString, final String falseString) {
954        return bool ? trueString : falseString;
955    }
956
957    /**
958     * <p>Converts a Boolean to a String returning one of the input Strings.</p>
959     *
960     * <pre>
961     *   BooleanUtils.toString(Boolean.TRUE, "true", "false", null)   = "true"
962     *   BooleanUtils.toString(Boolean.FALSE, "true", "false", null)  = "false"
963     *   BooleanUtils.toString(null, "true", "false", null)           = null;
964     * </pre>
965     *
966     * @param bool  the Boolean to check
967     * @param trueString  the String to return if {@code true}, may be {@code null}
968     * @param falseString  the String to return if {@code false}, may be {@code null}
969     * @param nullString  the String to return if {@code null}, may be {@code null}
970     * @return one of the three input Strings
971     */
972    public static String toString(final Boolean bool, final String trueString, final String falseString, final String nullString) {
973        if (bool == null) {
974            return nullString;
975        }
976        return bool.booleanValue() ? trueString : falseString;
977    }
978
979    /**
980     * <p>Converts a boolean to a String returning {@code 'on'}
981     * or {@code 'off'}.</p>
982     *
983     * <pre>
984     *   BooleanUtils.toStringOnOff(true)   = "on"
985     *   BooleanUtils.toStringOnOff(false)  = "off"
986     * </pre>
987     *
988     * @param bool  the Boolean to check
989     * @return {@code 'on'}, {@code 'off'}, or {@code null}
990     */
991    public static String toStringOnOff(final boolean bool) {
992        return toString(bool, ON, OFF);
993    }
994
995    /**
996     * <p>Converts a Boolean to a String returning {@code 'on'},
997     * {@code 'off'}, or {@code null}.</p>
998     *
999     * <pre>
1000     *   BooleanUtils.toStringOnOff(Boolean.TRUE)  = "on"
1001     *   BooleanUtils.toStringOnOff(Boolean.FALSE) = "off"
1002     *   BooleanUtils.toStringOnOff(null)          = null;
1003     * </pre>
1004     *
1005     * @param bool  the Boolean to check
1006     * @return {@code 'on'}, {@code 'off'}, or {@code null}
1007     */
1008    public static String toStringOnOff(final Boolean bool) {
1009        return toString(bool, ON, OFF, null);
1010    }
1011
1012    /**
1013     * <p>Converts a boolean to a String returning {@code 'true'}
1014     * or {@code 'false'}.</p>
1015     *
1016     * <pre>
1017     *   BooleanUtils.toStringTrueFalse(true)   = "true"
1018     *   BooleanUtils.toStringTrueFalse(false)  = "false"
1019     * </pre>
1020     *
1021     * @param bool  the Boolean to check
1022     * @return {@code 'true'}, {@code 'false'}, or {@code null}
1023     */
1024    public static String toStringTrueFalse(final boolean bool) {
1025        return toString(bool, TRUE, FALSE);
1026    }
1027
1028    /**
1029     * <p>Converts a Boolean to a String returning {@code 'true'},
1030     * {@code 'false'}, or {@code null}.</p>
1031     *
1032     * <pre>
1033     *   BooleanUtils.toStringTrueFalse(Boolean.TRUE)  = "true"
1034     *   BooleanUtils.toStringTrueFalse(Boolean.FALSE) = "false"
1035     *   BooleanUtils.toStringTrueFalse(null)          = null;
1036     * </pre>
1037     *
1038     * @param bool  the Boolean to check
1039     * @return {@code 'true'}, {@code 'false'}, or {@code null}
1040     */
1041    public static String toStringTrueFalse(final Boolean bool) {
1042        return toString(bool, TRUE, FALSE, null);
1043    }
1044
1045    /**
1046     * <p>Converts a boolean to a String returning {@code 'yes'}
1047     * or {@code 'no'}.</p>
1048     *
1049     * <pre>
1050     *   BooleanUtils.toStringYesNo(true)   = "yes"
1051     *   BooleanUtils.toStringYesNo(false)  = "no"
1052     * </pre>
1053     *
1054     * @param bool  the Boolean to check
1055     * @return {@code 'yes'}, {@code 'no'}, or {@code null}
1056     */
1057    public static String toStringYesNo(final boolean bool) {
1058        return toString(bool, YES, NO);
1059    }
1060
1061    /**
1062     * <p>Converts a Boolean to a String returning {@code 'yes'},
1063     * {@code 'no'}, or {@code null}.</p>
1064     *
1065     * <pre>
1066     *   BooleanUtils.toStringYesNo(Boolean.TRUE)  = "yes"
1067     *   BooleanUtils.toStringYesNo(Boolean.FALSE) = "no"
1068     *   BooleanUtils.toStringYesNo(null)          = null;
1069     * </pre>
1070     *
1071     * @param bool  the Boolean to check
1072     * @return {@code 'yes'}, {@code 'no'}, or {@code null}
1073     */
1074    public static String toStringYesNo(final Boolean bool) {
1075        return toString(bool, YES, NO, null);
1076    }
1077
1078    /**
1079     * <p>Performs an xor on a set of booleans.</p>
1080     *
1081     * <pre>
1082     *   BooleanUtils.xor(true, true)   = false
1083     *   BooleanUtils.xor(false, false) = false
1084     *   BooleanUtils.xor(true, false)  = true
1085     * </pre>
1086     *
1087     * @param array  an array of {@code boolean}s
1088     * @return the result of the xor operations
1089     * @throws NullPointerException if {@code array} is {@code null}
1090     * @throws IllegalArgumentException if {@code array} is empty.
1091     */
1092    public static boolean xor(final boolean... array) {
1093        ObjectUtils.requireNonEmpty(array, "array");
1094        // false if the neutral element of the xor operator
1095        boolean result = false;
1096        for (final boolean element : array) {
1097            result ^= element;
1098        }
1099
1100        return result;
1101    }
1102
1103    /**
1104     * <p>Performs an xor on an array of Booleans.</p>
1105     *
1106     * <pre>
1107     *   BooleanUtils.xor(new Boolean[] { Boolean.TRUE, Boolean.TRUE })   = Boolean.FALSE
1108     *   BooleanUtils.xor(new Boolean[] { Boolean.FALSE, Boolean.FALSE }) = Boolean.FALSE
1109     *   BooleanUtils.xor(new Boolean[] { Boolean.TRUE, Boolean.FALSE })  = Boolean.TRUE
1110     *   BooleanUtils.xor(Boolean.TRUE, Boolean.FALSE, Boolean.FALSE)     = Boolean.TRUE
1111     * </pre>
1112     *
1113     * @param array  an array of {@code Boolean}s
1114     * @return the result of the xor operations
1115     * @throws NullPointerException if {@code array} is {@code null}
1116     * @throws IllegalArgumentException if {@code array} is empty.
1117     * @throws IllegalArgumentException if {@code array} contains a {@code null}
1118     */
1119    public static Boolean xor(final Boolean... array) {
1120        ObjectUtils.requireNonEmpty(array, "array");
1121        try {
1122            final boolean[] primitive = ArrayUtils.toPrimitive(array);
1123            return xor(primitive) ? Boolean.TRUE : Boolean.FALSE;
1124        } catch (final NullPointerException ex) {
1125            throw new IllegalArgumentException("The array must not contain any null elements");
1126        }
1127    }
1128
1129    /**
1130     * <p>{@code BooleanUtils} instances should NOT be constructed in standard programming.
1131     * Instead, the class should be used as {@code BooleanUtils.negate(true);}.</p>
1132     *
1133     * <p>This constructor is public to permit tools that require a JavaBean instance
1134     * to operate.</p>
1135     */
1136    public BooleanUtils() {
1137    }
1138
1139}