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