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