    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     */
    017    package org.apache.commons.lang3;
    018
    019    import 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</code> input gracefully.
    025     * An exception will not be thrown for a <code>null</code> input.
    026     * Each method documents its behaviour in more detail.</p>
    027     *
    028     * <p>#ThreadSafe#</p>
    029     * @author Apache Software Foundation
    030     * @author Matthew Hawthorne
    031     * @author Gary Gregory
    032     * @since 2.0
    033     * @version $Id: BooleanUtils.java 966173 2010-07-21 10:51:50Z sebb $
    034     */
    035    public class BooleanUtils {
    036
    037        /**
    038         * <p><code>BooleanUtils</code> instances should NOT be constructed in standard programming.
    039         * Instead, the class should be used as <code>BooleanUtils.negate(true);</code>.</p>
    040         *
    041         * <p>This constructor is public to permit tools that require a JavaBean instance
    042         * to operate.</p>
    043         */
    044        public BooleanUtils() {
    045          super();
    046        }
    047
    048        // Boolean utilities
    049        //--------------------------------------------------------------------------
    050        /**
    051         * <p>Negates the specified boolean.</p>
    052         *
    053         * <p>If <code>null</code> is passed in, <code>null</code> will be returned.</p>
    054         *
    055         * <pre>
    056         *   BooleanUtils.negate(Boolean.TRUE)  = Boolean.FALSE;
    057         *   BooleanUtils.negate(Boolean.FALSE) = Boolean.TRUE;
    058         *   BooleanUtils.negate(null)          = null;
    059         * </pre>
    060         *
    061         * @param bool  the Boolean to negate, may be null
    062         * @return the negated Boolean, or <code>null</code> if <code>null</code> input
    063         */
    064        public static Boolean negate(Boolean bool) {
    065            if (bool == null) {
    066                return null;
    067            }
    068            return (bool.booleanValue() ? Boolean.FALSE : Boolean.TRUE);
    069        }
    070
    071        // boolean Boolean methods
    072        //-----------------------------------------------------------------------
    073        /**
    074         * <p>Checks if a <code>Boolean</code> value is <code>true</code>,
    075         * handling <code>null</code> by returning <code>false</code>.</p>
    076         *
    077         * <pre>
    078         *   BooleanUtils.isTrue(Boolean.TRUE)  = true
    079         *   BooleanUtils.isTrue(Boolean.FALSE) = false
    080         *   BooleanUtils.isTrue(null)          = false
    081         * </pre>
    082         *
    083         * @param bool  the boolean to check, null returns <code>false</code>
    084         * @return <code>true</code> only if the input is non-null and true
    085         * @since 2.1
    086         */
    087        public static boolean isTrue(Boolean bool) {
    088            if (bool == null) {
    089                return false;
    090            }
    091            return bool.booleanValue() ? true : false;
    092        }
    093
    094        /**
    095         * <p>Checks if a <code>Boolean</code> value is <i>not</i> <code>true</code>,
    096         * handling <code>null</code> by returning <code>true</code>.</p>
    097         *
    098         * <pre>
    099         *   BooleanUtils.isNotTrue(Boolean.TRUE)  = false
    100         *   BooleanUtils.isNotTrue(Boolean.FALSE) = true
    101         *   BooleanUtils.isNotTrue(null)          = true
    102         * </pre>
    103         *
    104         * @param bool  the boolean to check, null returns <code>true</code>
    105         * @return <code>true</code> if the input is null or false
    106         * @since 2.3
    107         */
    108        public static boolean isNotTrue(Boolean bool) {
    109            return !isTrue(bool);
    110        }
    111
    112        /**
    113         * <p>Checks if a <code>Boolean</code> value is <code>false</code>,
    114         * handling <code>null</code> by returning <code>false</code>.</p>
    115         *
    116         * <pre>
    117         *   BooleanUtils.isFalse(Boolean.TRUE)  = false
    118         *   BooleanUtils.isFalse(Boolean.FALSE) = true
    119         *   BooleanUtils.isFalse(null)          = false
    120         * </pre>
    121         *
    122         * @param bool  the boolean to check, null returns <code>false</code>
    123         * @return <code>true</code> only if the input is non-null and false
    124         * @since 2.1
    125         */
    126        public static boolean isFalse(Boolean bool) {
    127            if (bool == null) {
    128                return false;
    129            }
    130            return bool.booleanValue() ? false : true;
    131        }
    132
    133        /**
    134         * <p>Checks if a <code>Boolean</code> value is <i>not</i> <code>false</code>,
    135         * handling <code>null</code> by returning <code>true</code>.</p>
    136         *
    137         * <pre>
    138         *   BooleanUtils.isNotFalse(Boolean.TRUE)  = true
    139         *   BooleanUtils.isNotFalse(Boolean.FALSE) = false
    140         *   BooleanUtils.isNotFalse(null)          = true
    141         * </pre>
    142         *
    143         * @param bool  the boolean to check, null returns <code>true</code>
    144         * @return <code>true</code> if the input is null or true
    145         * @since 2.3
    146         */
    147        public static boolean isNotFalse(Boolean bool) {
    148            return !isFalse(bool);
    149        }
    150
    151        //-----------------------------------------------------------------------
    152        /**
    153         * <p>Converts a Boolean to a boolean handling <code>null</code>
    154         * by returning <code>false</code>.</p>
    155         *
    156         * <pre>
    157         *   BooleanUtils.toBoolean(Boolean.TRUE)  = true
    158         *   BooleanUtils.toBoolean(Boolean.FALSE) = false
    159         *   BooleanUtils.toBoolean(null)          = false
    160         * </pre>
    161         *
    162         * @param bool  the boolean to convert
    163         * @return <code>true</code> or <code>false</code>,
    164         *  <code>null</code> returns <code>false</code>
    165         */
    166        public static boolean toBoolean(Boolean bool) {
    167            if (bool == null) {
    168                return false;
    169            }
    170            return bool.booleanValue() ? true : false;
    171        }
    172
    173        /**
    174         * <p>Converts a Boolean to a boolean handling <code>null</code>.</p>
    175         *
    176         * <pre>
    177         *   BooleanUtils.toBooleanDefaultIfNull(Boolean.TRUE, false) = true
    178         *   BooleanUtils.toBooleanDefaultIfNull(Boolean.FALSE, true) = false
    179         *   BooleanUtils.toBooleanDefaultIfNull(null, true)          = true
    180         * </pre>
    181         *
    182         * @param bool  the boolean to convert
    183         * @param valueIfNull  the boolean value to return if <code>null</code>
    184         * @return <code>true</code> or <code>false</code>
    185         */
    186        public static boolean toBooleanDefaultIfNull(Boolean bool, boolean valueIfNull) {
    187            if (bool == null) {
    188                return valueIfNull;
    189            }
    190            return bool.booleanValue() ? true : false;
    191        }
    192
    193        // Integer to Boolean methods
    194        //-----------------------------------------------------------------------
    195        /**
    196         * <p>Converts an int to a boolean using the convention that <code>zero</code>
    197         * is <code>false</code>.</p>
    198         *
    199         * <pre>
    200         *   BooleanUtils.toBoolean(0) = false
    201         *   BooleanUtils.toBoolean(1) = true
    202         *   BooleanUtils.toBoolean(2) = true
    203         * </pre>
    204         *
    205         * @param value  the int to convert
    206         * @return <code>true</code> if non-zero, <code>false</code>
    207         *  if zero
    208         */
    209        public static boolean toBoolean(int value) {
    210            return value == 0 ? false : true;
    211        }
    212
    213        /**
    214         * <p>Converts an int to a Boolean using the convention that <code>zero</code>
    215         * is <code>false</code>.</p>
    216         *
    217         * <pre>
    218         *   BooleanUtils.toBoolean(0) = Boolean.FALSE
    219         *   BooleanUtils.toBoolean(1) = Boolean.TRUE
    220         *   BooleanUtils.toBoolean(2) = Boolean.TRUE
    221         * </pre>
    222         *
    223         * @param value  the int to convert
    224         * @return Boolean.TRUE if non-zero, Boolean.FALSE if zero,
    225         *  <code>null</code> if <code>null</code>
    226         */
    227        public static Boolean toBooleanObject(int value) {
    228            return value == 0 ? Boolean.FALSE : Boolean.TRUE;
    229        }
    230
    231        /**
    232         * <p>Converts an Integer to a Boolean using the convention that <code>zero</code>
    233         * is <code>false</code>.</p>
    234         *
    235         * <p><code>null</code> will be converted to <code>null</code>.</p>
    236         *
    237         * <pre>
    238         *   BooleanUtils.toBoolean(new Integer(0))    = Boolean.FALSE
    239         *   BooleanUtils.toBoolean(new Integer(1))    = Boolean.TRUE
    240         *   BooleanUtils.toBoolean(new Integer(null)) = null
    241         * </pre>
    242         *
    243         * @param value  the Integer to convert
    244         * @return Boolean.TRUE if non-zero, Boolean.FALSE if zero,
    245         *  <code>null</code> if <code>null</code> input
    246         */
    247        public static Boolean toBooleanObject(Integer value) {
    248            if (value == null) {
    249                return null;
    250            }
    251            return value.intValue() == 0 ? Boolean.FALSE : Boolean.TRUE;
    252        }
    253
    254        /**
    255         * <p>Converts an int to a boolean specifying the conversion values.</p>
    256         *
    257         * <pre>
    258         *   BooleanUtils.toBoolean(0, 1, 0) = false
    259         *   BooleanUtils.toBoolean(1, 1, 0) = true
    260         *   BooleanUtils.toBoolean(2, 1, 2) = false
    261         *   BooleanUtils.toBoolean(2, 2, 0) = true
    262         * </pre>
    263         *
    264         * @param value  the Integer to convert
    265         * @param trueValue  the value to match for <code>true</code>
    266         * @param falseValue  the value to match for <code>false</code>
    267         * @return <code>true</code> or <code>false</code>
    268         * @throws IllegalArgumentException if no match
    269         */
    270        public static boolean toBoolean(int value, int trueValue, int falseValue) {
    271            if (value == trueValue) {
    272                return true;
    273            } else if (value == falseValue) {
    274                return false;
    275            }
    276            // no match
    277            throw new IllegalArgumentException("The Integer did not match either specified value");
    278        }
    279
    280        /**
    281         * <p>Converts an Integer to a boolean specifying the conversion values.</p>
    282         *
    283         * <pre>
    284         *   BooleanUtils.toBoolean(new Integer(0), new Integer(1), new Integer(0)) = false
    285         *   BooleanUtils.toBoolean(new Integer(1), new Integer(1), new Integer(0)) = true
    286         *   BooleanUtils.toBoolean(new Integer(2), new Integer(1), new Integer(2)) = false
    287         *   BooleanUtils.toBoolean(new Integer(2), new Integer(2), new Integer(0)) = true
    288         *   BooleanUtils.toBoolean(null, null, new Integer(0))                     = true
    289         * </pre>
    290         *
    291         * @param value  the Integer to convert
    292         * @param trueValue  the value to match for <code>true</code>,
    293         *  may be <code>null</code>
    294         * @param falseValue  the value to match for <code>false</code>,
    295         *  may be <code>null</code>
    296         * @return <code>true</code> or <code>false</code>
    297         * @throws IllegalArgumentException if no match
    298         */
    299        public static boolean toBoolean(Integer value, Integer trueValue, Integer falseValue) {
    300            if (value == null) {
    301                if (trueValue == null) {
    302                    return true;
    303                } else if (falseValue == null) {
    304                    return false;
    305                }
    306            } else if (value.equals(trueValue)) {
    307                return true;
    308            } else if (value.equals(falseValue)) {
    309                return false;
    310            }
    311            // no match
    312            throw new IllegalArgumentException("The Integer did not match either specified value");
    313        }
    314
    315        /**
    316         * <p>Converts an int to a Boolean specifying the conversion values.</p>
    317         *
    318         * <pre>
    319         *   BooleanUtils.toBooleanObject(0, 0, 2, 3) = Boolean.TRUE
    320         *   BooleanUtils.toBooleanObject(2, 1, 2, 3) = Boolean.FALSE
    321         *   BooleanUtils.toBooleanObject(3, 1, 2, 3) = null
    322         * </pre>
    323         *
    324         * @param value  the Integer to convert
    325         * @param trueValue  the value to match for <code>true</code>
    326         * @param falseValue  the value to match for <code>false</code>
    327         * @param nullValue  the value to to match for <code>null</code>
    328         * @return Boolean.TRUE, Boolean.FALSE, or <code>null</code>
    329         * @throws IllegalArgumentException if no match
    330         */
    331        public static Boolean toBooleanObject(int value, int trueValue, int falseValue, int nullValue) {
    332            if (value == trueValue) {
    333                return Boolean.TRUE;
    334            } else if (value == falseValue) {
    335                return Boolean.FALSE;
    336            } else if (value == nullValue) {
    337                return null;
    338            }
    339            // no match
    340            throw new IllegalArgumentException("The Integer did not match any specified value");
    341        }
    342
    343        /**
    344         * <p>Converts an Integer to a Boolean specifying the conversion values.</p>
    345         *
    346         * <pre>
    347         *   BooleanUtils.toBooleanObject(new Integer(0), new Integer(0), new Integer(2), new Integer(3)) = Boolean.TRUE
    348         *   BooleanUtils.toBooleanObject(new Integer(2), new Integer(1), new Integer(2), new Integer(3)) = Boolean.FALSE
    349         *   BooleanUtils.toBooleanObject(new Integer(3), new Integer(1), new Integer(2), new Integer(3)) = null
    350         * </pre>
    351         *
    352         * @param value  the Integer to convert
    353         * @param trueValue  the value to match for <code>true</code>,
    354         *  may be <code>null</code>
    355         * @param falseValue  the value to match for <code>false</code>,
    356         *  may be <code>null</code>
    357         * @param nullValue  the value to to match for <code>null</code>,
    358         *  may be <code>null</code>
    359         * @return Boolean.TRUE, Boolean.FALSE, or <code>null</code>
    360         * @throws IllegalArgumentException if no match
    361         */
    362        public static Boolean toBooleanObject(Integer value, Integer trueValue, Integer falseValue, Integer nullValue) {
    363            if (value == null) {
    364                if (trueValue == null) {
    365                    return Boolean.TRUE;
    366                } else if (falseValue == null) {
    367                    return Boolean.FALSE;
    368                } else if (nullValue == null) {
    369                    return null;
    370                }
    371            } else if (value.equals(trueValue)) {
    372                return Boolean.TRUE;
    373            } else if (value.equals(falseValue)) {
    374                return Boolean.FALSE;
    375            } else if (value.equals(nullValue)) {
    376                return null;
    377            }
    378            // no match
    379            throw new IllegalArgumentException("The Integer did not match any specified value");
    380        }
    381
    382        // Boolean to Integer methods
    383        //-----------------------------------------------------------------------
    384        /**
    385         * <p>Converts a boolean to an int using the convention that
    386         * <code>zero</code> is <code>false</code>.</p>
    387         *
    388         * <pre>
    389         *   BooleanUtils.toInteger(true)  = 1
    390         *   BooleanUtils.toInteger(false) = 0
    391         * </pre>
    392         *
    393         * @param bool  the boolean to convert
    394         * @return one if <code>true</code>, zero if <code>false</code>
    395         */
    396        public static int toInteger(boolean bool) {
    397            return bool ? 1 : 0;
    398        }
    399
    400        /**
    401         * <p>Converts a boolean to an Integer using the convention that
    402         * <code>zero</code> is <code>false</code>.</p>
    403         *
    404         * <pre>
    405         *   BooleanUtils.toIntegerObject(true)  = new Integer(1)
    406         *   BooleanUtils.toIntegerObject(false) = new Integer(0)
    407         * </pre>
    408         *
    409         * @param bool  the boolean to convert
    410         * @return one if <code>true</code>, zero if <code>false</code>
    411         */
    412        public static Integer toIntegerObject(boolean bool) {
    413            return bool ? NumberUtils.INTEGER_ONE : NumberUtils.INTEGER_ZERO;
    414        }
    415
    416        /**
    417         * <p>Converts a Boolean to a Integer using the convention that
    418         * <code>zero</code> is <code>false</code>.</p>
    419         *
    420         * <p><code>null</code> will be converted to <code>null</code>.</p>
    421         *
    422         * <pre>
    423         *   BooleanUtils.toIntegerObject(Boolean.TRUE)  = new Integer(1)
    424         *   BooleanUtils.toIntegerObject(Boolean.FALSE) = new Integer(0)
    425         * </pre>
    426         *
    427         * @param bool  the Boolean to convert
    428         * @return one if Boolean.TRUE, zero if Boolean.FALSE, <code>null</code> if <code>null</code>
    429         */
    430        public static Integer toIntegerObject(Boolean bool) {
    431            if (bool == null) {
    432                return null;
    433            }
    434            return bool.booleanValue() ? NumberUtils.INTEGER_ONE : NumberUtils.INTEGER_ZERO;
    435        }
    436
    437        /**
    438         * <p>Converts a boolean to an int specifying the conversion values.</p>
    439         *
    440         * <pre>
    441         *   BooleanUtils.toInteger(true, 1, 0)  = 1
    442         *   BooleanUtils.toInteger(false, 1, 0) = 0
    443         * </pre>
    444         *
    445         * @param bool  the to convert
    446         * @param trueValue  the value to return if <code>true</code>
    447         * @param falseValue  the value to return if <code>false</code>
    448         * @return the appropriate value
    449         */
    450        public static int toInteger(boolean bool, int trueValue, int falseValue) {
    451            return bool ? trueValue : falseValue;
    452        }
    453
    454        /**
    455         * <p>Converts a Boolean to an int specifying the conversion values.</p>
    456         *
    457         * <pre>
    458         *   BooleanUtils.toInteger(Boolean.TRUE, 1, 0, 2)  = 1
    459         *   BooleanUtils.toInteger(Boolean.FALSE, 1, 0, 2) = 0
    460         *   BooleanUtils.toInteger(null, 1, 0, 2)          = 2
    461         * </pre>
    462         *
    463         * @param bool  the Boolean to convert
    464         * @param trueValue  the value to return if <code>true</code>
    465         * @param falseValue  the value to return if <code>false</code>
    466         * @param nullValue  the value to return if <code>null</code>
    467         * @return the appropriate value
    468         */
    469        public static int toInteger(Boolean bool, int trueValue, int falseValue, int nullValue) {
    470            if (bool == null) {
    471                return nullValue;
    472            }
    473            return bool.booleanValue() ? trueValue : falseValue;
    474        }
    475
    476        /**
    477         * <p>Converts a boolean to an Integer specifying the conversion values.</p>
    478         *
    479         * <pre>
    480         *   BooleanUtils.toIntegerObject(true, new Integer(1), new Integer(0))  = new Integer(1)
    481         *   BooleanUtils.toIntegerObject(false, new Integer(1), new Integer(0)) = new Integer(0)
    482         * </pre>
    483         *
    484         * @param bool  the to convert
    485         * @param trueValue  the value to return if <code>true</code>,
    486         *  may be <code>null</code>
    487         * @param falseValue  the value to return if <code>false</code>,
    488         *  may be <code>null</code>
    489         * @return the appropriate value
    490         */
    491        public static Integer toIntegerObject(boolean bool, Integer trueValue, Integer falseValue) {
    492            return bool ? trueValue : falseValue;
    493        }
    494
    495        /**
    496         * <p>Converts a Boolean to an Integer specifying the conversion values.</p>
    497         *
    498         * <pre>
    499         *   BooleanUtils.toIntegerObject(Boolean.TRUE, new Integer(1), new Integer(0), new Integer(2))  = new Integer(1)
    500         *   BooleanUtils.toIntegerObject(Boolean.FALSE, new Integer(1), new Integer(0), new Integer(2)) = new Integer(0)
    501         *   BooleanUtils.toIntegerObject(null, new Integer(1), new Integer(0), new Integer(2))          = new Integer(2)
    502         * </pre>
    503         *
    504         * @param bool  the Boolean to convert
    505         * @param trueValue  the value to return if <code>true</code>,
    506         *  may be <code>null</code>
    507         * @param falseValue  the value to return if <code>false</code>,
    508         *  may be <code>null</code>
    509         * @param nullValue  the value to return if <code>null</code>,
    510         *  may be <code>null</code>
    511         * @return the appropriate value
    512         */
    513        public static Integer toIntegerObject(Boolean bool, Integer trueValue, Integer falseValue, Integer nullValue) {
    514            if (bool == null) {
    515                return nullValue;
    516            }
    517            return bool.booleanValue() ? trueValue : falseValue;
    518        }
    519
    520        // String to Boolean methods
    521        //-----------------------------------------------------------------------
    522        /**
    523         * <p>Converts a String to a Boolean.</p>
    524         *
    525         * <p><code>'true'</code>, <code>'on'</code> or <code>'yes'</code>
    526         * (case insensitive) will return <code>true</code>.
    527         * <code>'false'</code>, <code>'off'</code> or <code>'no'</code>
    528         * (case insensitive) will return <code>false</code>.
    529         * Otherwise, <code>null</code> is returned.</p>
    530         *
    531         * <pre>
    532         *   BooleanUtils.toBooleanObject(null)    = null
    533         *   BooleanUtils.toBooleanObject("true")  = Boolean.TRUE
    534         *   BooleanUtils.toBooleanObject("false") = Boolean.FALSE
    535         *   BooleanUtils.toBooleanObject("on")    = Boolean.TRUE
    536         *   BooleanUtils.toBooleanObject("ON")    = Boolean.TRUE
    537         *   BooleanUtils.toBooleanObject("off")   = Boolean.FALSE
    538         *   BooleanUtils.toBooleanObject("oFf")   = Boolean.FALSE
    539         *   BooleanUtils.toBooleanObject("blue")  = null
    540         * </pre>
    541         *
    542         * @param str  the String to check
    543         * @return the Boolean value of the string,
    544         *  <code>null</code> if no match or <code>null</code> input
    545         */
    546        public static Boolean toBooleanObject(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 2: {
    561                    char ch0 = str.charAt(0);
    562                    char ch1 = str.charAt(1);
    563                    if ((ch0 == 'o' || ch0 == 'O') &&
    564                        (ch1 == 'n' || ch1 == 'N') )
    565                    {
    566                        return Boolean.TRUE;
    567                    }
    568                    if ((ch0 == 'n' || ch0 == 'N') &&
    569                        (ch1 == 'o' || ch1 == 'O') )
    570                    {
    571                        return Boolean.FALSE;
    572                    }
    573                    break;
    574                }
    575                case 3: {
    576                    char ch0 = str.charAt(0);
    577                    char ch1 = str.charAt(1);
    578                    char ch2 = str.charAt(2);
    579                    if ((ch0 == 'y' || ch0 == 'Y') &&
    580                        (ch1 == 'e' || ch1 == 'E') &&
    581                        (ch2 == 's' || ch2 == 'S') )
    582                    {
    583                        return Boolean.TRUE;
    584                    }
    585                    if ((ch0 == 'o' || ch0 == 'O') &&
    586                        (ch1 == 'f' || ch1 == 'F') &&
    587                        (ch2 == 'f' || ch2 == 'F') )
    588                    {
    589                        return Boolean.FALSE;
    590                    }
    591                    break;
    592                }
    593                case 4: {
    594                    char ch0 = str.charAt(0);
    595                    char ch1 = str.charAt(1);
    596                    char ch2 = str.charAt(2);
    597                    char ch3 = str.charAt(3);
    598                    if ((ch0 == 't' || ch0 == 'T') &&
    599                        (ch1 == 'r' || ch1 == 'R') &&
    600                        (ch2 == 'u' || ch2 == 'U') &&
    601                        (ch3 == 'e' || ch3 == 'E') )
    602                    {
    603                        return Boolean.TRUE;
    604                    }
    605                    break;
    606                }
    607                case 5: {
    608                    char ch0 = str.charAt(0);
    609                    char ch1 = str.charAt(1);
    610                    char ch2 = str.charAt(2);
    611                    char ch3 = str.charAt(3);
    612                    char ch4 = str.charAt(4);
    613                    if ((ch0 == 'f' || ch0 == 'F') &&
    614                        (ch1 == 'a' || ch1 == 'A') &&
    615                        (ch2 == 'l' || ch2 == 'L') &&
    616                        (ch3 == 's' || ch3 == 'S') &&
    617                        (ch4 == 'e' || ch4 == 'E') )
    618                    {
    619                        return Boolean.FALSE;
    620                    }
    621                    break;
    622                }
    623            }
    624
    625            return null;
    626        }
    627
    628        /**
    629         * <p>Converts a String to a Boolean throwing an exception if no match.</p>
    630         *
    631         * <pre>
    632         *   BooleanUtils.toBooleanObject("true", "true", "false", "null")  = Boolean.TRUE
    633         *   BooleanUtils.toBooleanObject("false", "true", "false", "null") = Boolean.FALSE
    634         *   BooleanUtils.toBooleanObject("null", "true", "false", "null")  = null
    635         * </pre>
    636         *
    637         * @param str  the String to check
    638         * @param trueString  the String to match for <code>true</code>
    639         *  (case sensitive), may be <code>null</code>
    640         * @param falseString  the String to match for <code>false</code>
    641         *  (case sensitive), may be <code>null</code>
    642         * @param nullString  the String to match for <code>null</code>
    643         *  (case sensitive), may be <code>null</code>
    644         * @return the Boolean value of the string,
    645         *  <code>null</code> if either the String matches <code>nullString</code>
    646         *  or if <code>null</code> input and <code>nullString</code> is
    647         *  <code>null</code>
    648         * @throws IllegalArgumentException if the String doesn't match
    649         */
    650        public static Boolean toBooleanObject(String str, String trueString, String falseString, String nullString) {
    651            if (str == null) {
    652                if (trueString == null) {
    653                    return Boolean.TRUE;
    654                } else if (falseString == null) {
    655                    return Boolean.FALSE;
    656                } else if (nullString == null) {
    657                    return null;
    658                }
    659            } else if (str.equals(trueString)) {
    660                return Boolean.TRUE;
    661            } else if (str.equals(falseString)) {
    662                return Boolean.FALSE;
    663            } else if (str.equals(nullString)) {
    664                return null;
    665            }
    666            // no match
    667            throw new IllegalArgumentException("The String did not match any specified value");
    668        }
    669
    670        // String to boolean methods
    671        //-----------------------------------------------------------------------
    672        /**
    673         * <p>Converts a String to a boolean (optimised for performance).</p>
    674         *
    675         * <p><code>'true'</code>, <code>'on'</code> or <code>'yes'</code>
    676         * (case insensitive) will return <code>true</code>. Otherwise,
    677         * <code>false</code> is returned.</p>
    678         *
    679         * <p>This method performs 4 times faster (JDK1.4) than
    680         * <code>Boolean.valueOf(String)</code>. However, this method accepts
    681         * 'on' and 'yes' as true values.
    682         *
    683         * <pre>
    684         *   BooleanUtils.toBoolean(null)    = false
    685         *   BooleanUtils.toBoolean("true")  = true
    686         *   BooleanUtils.toBoolean("TRUE")  = true
    687         *   BooleanUtils.toBoolean("tRUe")  = true
    688         *   BooleanUtils.toBoolean("on")    = true
    689         *   BooleanUtils.toBoolean("yes")   = true
    690         *   BooleanUtils.toBoolean("false") = false
    691         *   BooleanUtils.toBoolean("x gti") = false
    692         * </pre>
    693         *
    694         * @param str  the String to check
    695         * @return the boolean value of the string, <code>false</code> if no match or the String is null
    696         */
    697        public static boolean toBoolean(String str) {
    698            return toBooleanObject(str) == Boolean.TRUE;
    699        }
    700
    701        /**
    702         * <p>Converts a String to a Boolean throwing an exception if no match found.</p>
    703         *
    704         * <p>null is returned if there is no match.</p>
    705         *
    706         * <pre>
    707         *   BooleanUtils.toBoolean("true", "true", "false")  = true
    708         *   BooleanUtils.toBoolean("false", "true", "false") = false
    709         * </pre>
    710         *
    711         * @param str  the String to check
    712         * @param trueString  the String to match for <code>true</code>
    713         *  (case sensitive), may be <code>null</code>
    714         * @param falseString  the String to match for <code>false</code>
    715         *  (case sensitive), may be <code>null</code>
    716         * @return the boolean value of the string
    717         * @throws IllegalArgumentException if the String doesn't match
    718         */
    719        public static boolean toBoolean(String str, String trueString, String falseString) {
    720            if (str == null) {
    721                if (trueString == null) {
    722                    return true;
    723                } else if (falseString == null) {
    724                    return false;
    725                }
    726            } else if (str.equals(trueString)) {
    727                return true;
    728            } else if (str.equals(falseString)) {
    729                return false;
    730            }
    731            // no match
    732            throw new IllegalArgumentException("The String did not match either specified value");
    733        }
    734
    735        // Boolean to String methods
    736        //-----------------------------------------------------------------------
    737        /**
    738         * <p>Converts a Boolean to a String returning <code>'true'</code>,
    739         * <code>'false'</code>, or <code>null</code>.</p>
    740         *
    741         * <pre>
    742         *   BooleanUtils.toStringTrueFalse(Boolean.TRUE)  = "true"
    743         *   BooleanUtils.toStringTrueFalse(Boolean.FALSE) = "false"
    744         *   BooleanUtils.toStringTrueFalse(null)          = null;
    745         * </pre>
    746         *
    747         * @param bool  the Boolean to check
    748         * @return <code>'true'</code>, <code>'false'</code>,
    749         *  or <code>null</code>
    750         */
    751        public static String toStringTrueFalse(Boolean bool) {
    752            return toString(bool, "true", "false", null);
    753        }
    754
    755        /**
    756         * <p>Converts a Boolean to a String returning <code>'on'</code>,
    757         * <code>'off'</code>, or <code>null</code>.</p>
    758         *
    759         * <pre>
    760         *   BooleanUtils.toStringOnOff(Boolean.TRUE)  = "on"
    761         *   BooleanUtils.toStringOnOff(Boolean.FALSE) = "off"
    762         *   BooleanUtils.toStringOnOff(null)          = null;
    763         * </pre>
    764         *
    765         * @param bool  the Boolean to check
    766         * @return <code>'on'</code>, <code>'off'</code>,
    767         *  or <code>null</code>
    768         */
    769        public static String toStringOnOff(Boolean bool) {
    770            return toString(bool, "on", "off", null);
    771        }
    772
    773        /**
    774         * <p>Converts a Boolean to a String returning <code>'yes'</code>,
    775         * <code>'no'</code>, or <code>null</code>.</p>
    776         *
    777         * <pre>
    778         *   BooleanUtils.toStringYesNo(Boolean.TRUE)  = "yes"
    779         *   BooleanUtils.toStringYesNo(Boolean.FALSE) = "no"
    780         *   BooleanUtils.toStringYesNo(null)          = null;
    781         * </pre>
    782         *
    783         * @param bool  the Boolean to check
    784         * @return <code>'yes'</code>, <code>'no'</code>,
    785         *  or <code>null</code>
    786         */
    787        public static String toStringYesNo(Boolean bool) {
    788            return toString(bool, "yes", "no", null);
    789        }
    790
    791        /**
    792         * <p>Converts a Boolean to a String returning one of the input Strings.</p>
    793         *
    794         * <pre>
    795         *   BooleanUtils.toString(Boolean.TRUE, "true", "false", null)   = "true"
    796         *   BooleanUtils.toString(Boolean.FALSE, "true", "false", null)  = "false"
    797         *   BooleanUtils.toString(null, "true", "false", null)           = null;
    798         * </pre>
    799         *
    800         * @param bool  the Boolean to check
    801         * @param trueString  the String to return if <code>true</code>,
    802         *  may be <code>null</code>
    803         * @param falseString  the String to return if <code>false</code>,
    804         *  may be <code>null</code>
    805         * @param nullString  the String to return if <code>null</code>,
    806         *  may be <code>null</code>
    807         * @return one of the three input Strings
    808         */
    809        public static String toString(Boolean bool, String trueString, String falseString, String nullString) {
    810            if (bool == null) {
    811                return nullString;
    812            }
    813            return bool.booleanValue() ? trueString : falseString;
    814        }
    815
    816        // boolean to String methods
    817        //-----------------------------------------------------------------------
    818        /**
    819         * <p>Converts a boolean to a String returning <code>'true'</code>
    820         * or <code>'false'</code>.</p>
    821         *
    822         * <pre>
    823         *   BooleanUtils.toStringTrueFalse(true)   = "true"
    824         *   BooleanUtils.toStringTrueFalse(false)  = "false"
    825         * </pre>
    826         *
    827         * @param bool  the Boolean to check
    828         * @return <code>'true'</code>, <code>'false'</code>,
    829         *  or <code>null</code>
    830         */
    831        public static String toStringTrueFalse(boolean bool) {
    832            return toString(bool, "true", "false");
    833        }
    834
    835        /**
    836         * <p>Converts a boolean to a String returning <code>'on'</code>
    837         * or <code>'off'</code>.</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>, <code>'off'</code>,
    846         *  or <code>null</code>
    847         */
    848        public static String toStringOnOff(boolean bool) {
    849            return toString(bool, "on", "off");
    850        }
    851
    852        /**
    853         * <p>Converts a boolean to a String returning <code>'yes'</code>
    854         * or <code>'no'</code>.</p>
    855         *
    856         * <pre>
    857         *   BooleanUtils.toStringYesNo(true)   = "yes"
    858         *   BooleanUtils.toStringYesNo(false)  = "no"
    859         * </pre>
    860         *
    861         * @param bool  the Boolean to check
    862         * @return <code>'yes'</code>, <code>'no'</code>,
    863         *  or <code>null</code>
    864         */
    865        public static String toStringYesNo(boolean bool) {
    866            return toString(bool, "yes", "no");
    867        }
    868
    869        /**
    870         * <p>Converts a boolean to a String returning one of the input Strings.</p>
    871         *
    872         * <pre>
    873         *   BooleanUtils.toString(true, "true", "false")   = "true"
    874         *   BooleanUtils.toString(false, "true", "false")  = "false"
    875         * </pre>
    876         *
    877         * @param bool  the Boolean to check
    878         * @param trueString  the String to return if <code>true</code>,
    879         *  may be <code>null</code>
    880         * @param falseString  the String to return if <code>false</code>,
    881         *  may be <code>null</code>
    882         * @return one of the two input Strings
    883         */
    884        public static String toString(boolean bool, String trueString, String falseString) {
    885            return bool ? trueString : falseString;
    886        }
    887
    888        // xor methods
    889        // ----------------------------------------------------------------------
    890        /**
    891         * <p>Performs an xor on a set of booleans.</p>
    892         *
    893         * <pre>
    894         *   BooleanUtils.xor(new boolean[] { true, true })   = false
    895         *   BooleanUtils.xor(new boolean[] { false, false }) = false
    896         *   BooleanUtils.xor(new boolean[] { true, false })  = true
    897         * </pre>
    898         *
    899         * @param array  an array of <code>boolean<code>s
    900         * @return <code>true</code> if the xor is successful.
    901         * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
    902         * @throws IllegalArgumentException if <code>array</code> is empty.
    903         */
    904        public static boolean xor(boolean... array) {
    905            // Validates input
    906            if (array == null) {
    907                throw new IllegalArgumentException("The Array must not be null");
    908            } else if (array.length == 0) {
    909                throw new IllegalArgumentException("Array is empty");
    910            }
    911
    912            // Loops through array, comparing each item
    913            int trueCount = 0;
    914            for (boolean element : array) {
    915                // If item is true, and trueCount is < 1, increments count
    916                // Else, xor fails
    917                if (element) {
    918                    if (trueCount < 1) {
    919                        trueCount++;
    920                    } else {
    921                        return false;
    922                    }
    923                }
    924            }
    925
    926            // Returns true if there was exactly 1 true item
    927            return trueCount == 1;
    928        }
    929
    930        /**
    931         * <p>Performs an xor on an array of Booleans.</p>
    932         *
    933         * <pre>
    934         *   BooleanUtils.xor(new Boolean[] { Boolean.TRUE, Boolean.TRUE })   = Boolean.FALSE
    935         *   BooleanUtils.xor(new Boolean[] { Boolean.FALSE, Boolean.FALSE }) = Boolean.FALSE
    936         *   BooleanUtils.xor(new Boolean[] { Boolean.TRUE, Boolean.FALSE })  = Boolean.TRUE
    937         * </pre>
    938         *
    939         * @param array  an array of <code>Boolean<code>s
    940         * @return <code>true</code> if the xor is successful.
    941         * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
    942         * @throws IllegalArgumentException if <code>array</code> is empty.
    943         * @throws IllegalArgumentException if <code>array</code> contains a <code>null</code>
    944         */
    945        public static Boolean xor(Boolean... array) {
    946            if (array == null) {
    947                throw new IllegalArgumentException("The Array must not be null");
    948            } else if (array.length == 0) {
    949                throw new IllegalArgumentException("Array is empty");
    950            }
    951            boolean[] primitive = null;
    952            try {
    953                primitive = ArrayUtils.toPrimitive(array);
    954            } catch (NullPointerException ex) {
    955                throw new IllegalArgumentException("The array must not contain any null elements");
    956            }
    957            return xor(primitive) ? Boolean.TRUE : Boolean.FALSE;
    958        }
    959
    960    }