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