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    }