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