View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.beanutils.converters;
18  
19  import org.apache.commons.beanutils.ConversionException;
20  
21  /***
22   * {@link org.apache.commons.beanutils.Converter} implementaion that handles conversion
23   * to and from <b>Boolean</b> objects.
24   * {@link org.apache.commons.beanutils.Converter} implementaion that
25   * handles conversion to and from <b>java.lang.Boolean</b> objects.
26   * <p>
27   * Can be configured to either return a <i>default value</i> or throw a
28   * <code>ConversionException</code> if a conversion error occurs.
29   * <p>
30   * By default any object whose string representation is one of the values
31   * {"yes", "y", "true", "on", "1"} is converted to Boolean.TRUE, and 
32   * string representations {"no", "n", "false", "off", "0"} are converted
33   * to Boolean.FALSE. The recognised true/false strings can be changed by:
34   * <pre>
35   *  String[] trueStrings = {"oui", "o", "1"};
36   *  String[] falseStrings = {"non", "n", "0"};
37   *  Converter bc = new BooleanConverter(trueStrings, falseStrings);
38   *  ConvertUtils.register(bc, Boolean.class);
39   *  ConvertUtils.register(bc, Boolean.TYPE);
40   * </pre>
41   * In addition, it is recommended that the BooleanArrayConverter also be
42   * modified to recognise the same set of values:
43   * <pre>
44   *   Converter bac = new BooleanArrayConverter(bc, BooleanArrayConverter.NO_DEFAULT);
45   *   ConvertUtils.register(bac, bac.MODEL);
46   * </pre>
47   * </p>
48   * 
49   * <p>Case is ignored when converting values to true or false.</p>
50   *
51   * @author Craig R. McClanahan
52   * @version $Revision: 555845 $ $Date: 2007-07-13 03:52:05 +0100 (Fri, 13 Jul 2007) $
53   * @since 1.3
54   */
55  public final class BooleanConverter extends AbstractConverter {
56  
57  
58      // ----------------------------------------------------------- Constructors
59  
60  
61      /***
62       * Create a {@link org.apache.commons.beanutils.Converter} that will throw a {@link ConversionException}
63       * if a conversion error occurs, ie the string value being converted is
64       * not one of the known true strings, nor one of the known false strings.
65       */
66      public BooleanConverter() {
67          super(Boolean.class);
68      }
69  
70  
71      /***
72       * Create a {@link org.apache.commons.beanutils.Converter} that will return the specified default value
73       * if a conversion error occurs, ie the string value being converted is
74       * not one of the known true strings, nor one of the known false strings.
75       *
76       * @param defaultValue The default value to be returned if the value
77       *  being converted is not recognised. This value may be null, in which
78       *  case null will be returned on conversion failure. When non-null, it is
79       *  expected that this value will be either Boolean.TRUE or Boolean.FALSE.
80       *  The special value BooleanConverter.NO_DEFAULT can also be passed here,
81       *  in which case this constructor acts like the no-argument one.
82       */
83      public BooleanConverter(Object defaultValue) {
84          super(Boolean.class);
85          if (defaultValue != NO_DEFAULT) {
86              setDefaultValue(defaultValue);
87          }
88      }
89  
90      /***
91       * Create a {@link org.apache.commons.beanutils.Converter} that will throw a {@link ConversionException}
92       * if a conversion error occurs, ie the string value being converted is
93       * not one of the known true strings, nor one of the known false strings.
94       * <p>
95       * The provided string arrays are copied, so that changes to the elements
96       * of the array after this call is made do not affect this object.
97       *
98       * @param trueStrings is the set of strings which should convert to the
99       *  value Boolean.TRUE. The value null must not be present. Case is
100      *  ignored.
101      *
102      * @param falseStrings is the set of strings which should convert to the
103      *  value Boolean.TRUE. The value null must not be present. Case is
104      *  ignored.
105      */
106     public BooleanConverter(String[] trueStrings, String[] falseStrings) {
107         super(Boolean.class);
108         this.trueStrings = copyStrings(trueStrings);
109         this.falseStrings = copyStrings(falseStrings);
110     }
111 
112     /***
113      * Create a {@link org.apache.commons.beanutils.Converter} that will return
114      * the specified default value if a conversion error occurs.
115      * <p>
116      * The provided string arrays are copied, so that changes to the elements
117      * of the array after this call is made do not affect this object.
118      *
119      * @param trueStrings is the set of strings which should convert to the
120      *  value Boolean.TRUE. The value null must not be present. Case is
121      *  ignored.
122      *
123      * @param falseStrings is the set of strings which should convert to the
124      *  value Boolean.TRUE. The value null must not be present. Case is
125      *  ignored.
126      *
127      * @param defaultValue The default value to be returned if the value
128      *  being converted is not recognised. This value may be null, in which
129      *  case null will be returned on conversion failure. When non-null, it is
130      *  expected that this value will be either Boolean.TRUE or Boolean.FALSE.
131      *  The special value BooleanConverter.NO_DEFAULT can also be passed here,
132      *  in which case an exception will be thrown on conversion failure.
133      */
134     public BooleanConverter(String[] trueStrings, String[] falseStrings, 
135                 Object defaultValue) {
136         super(Boolean.class);
137         this.trueStrings = copyStrings(trueStrings);
138         this.falseStrings = copyStrings(falseStrings);
139         if (defaultValue != NO_DEFAULT) {
140             setDefaultValue(defaultValue);
141         }
142     }
143 
144 
145     // ----------------------------------------------------- Static Variables
146 
147 
148     /***
149      * This is a special reference that can be passed as the "default object"
150      * to the constructor to indicate that no default is desired. Note that
151      * the value 'null' cannot be used for this purpose, as the caller may
152      * want a null to be returned as the default.
153      * @deprecated Use constructors without default value.
154      */
155     public static final Object NO_DEFAULT = new Object();
156 
157 
158     // ----------------------------------------------------- Instance Variables
159 
160     /***
161      * The set of strings that are known to map to Boolean.TRUE.
162      */
163     private String[] trueStrings = {"true", "yes", "y", "on", "1"};
164 
165     /***
166      * The set of strings that are known to map to Boolean.FALSE.
167      */
168     private String[] falseStrings = {"false", "no", "n", "off", "0"};
169 
170     // --------------------------------------------------------- Protected Methods
171 
172     /***
173      * Convert the specified input object into an output object of the
174      * specified type.
175      *
176      * @param type is the type to which this value should be converted. In the
177      *  case of this BooleanConverter class, this value is ignored.
178      *
179      * @param value is the input value to be converted. The toString method
180      *  shall be invoked on this object, and the result compared (ignoring
181      *  case) against the known "true" and "false" string values.
182      *
183      * @return Boolean.TRUE if the value was a recognised "true" value, 
184      *  Boolean.FALSE if the value was a recognised "false" value, or
185      *  the default value if the value was not recognised and the constructor
186      *  was provided with a default value.
187      *
188      * @throws Throwable if an error occurs converting to the specified type
189      */
190     protected Object convertToType(Class type, Object value) throws Throwable {
191 
192         // All the values in the trueStrings and falseStrings arrays are
193         // guaranteed to be lower-case. By converting the input value
194         // to lowercase too, we can use the efficient String.equals method
195         // instead of the less-efficient String.equalsIgnoreCase method.
196         String stringValue = value.toString().toLowerCase();
197 
198         for(int i=0; i<trueStrings.length; ++i) {
199             if (trueStrings[i].equals(stringValue)) {
200                 return Boolean.TRUE;
201             }
202         }
203 
204         for(int i=0; i<falseStrings.length; ++i) {
205             if (falseStrings[i].equals(stringValue)) {
206                 return Boolean.FALSE;
207             }
208         }
209         
210         throw new ConversionException("Cna't convert value '" + value + "' to a Boolean");
211     }
212 
213     /***
214      * This method creates a copy of the provided array, and ensures that
215      * all the strings in the newly created array contain only lower-case
216      * letters.
217      * <p>
218      * Using this method to copy string arrays means that changes to the
219      * src array do not modify the dst array.
220      */
221     private static String[] copyStrings(String[] src) {
222         String[] dst = new String[src.length];
223         for(int i=0; i<src.length; ++i) {
224             dst[i] = src[i].toLowerCase();
225         }
226         return dst;
227     }
228 }