    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}