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.beanutils.converters;
018
019 import org.apache.commons.beanutils.ConversionException;
020
021 /**
022 * {@link org.apache.commons.beanutils.Converter} implementaion that handles conversion
023 * to and from <b>Boolean</b> objects.
024 * {@link org.apache.commons.beanutils.Converter} implementaion that
025 * handles conversion to and from <b>java.lang.Boolean</b> objects.
026 * <p>
027 * Can be configured to either return a <i>default value</i> or throw a
028 * <code>ConversionException</code> if a conversion error occurs.
029 * <p>
030 * By default any object whose string representation is one of the values
031 * {"yes", "y", "true", "on", "1"} is converted to Boolean.TRUE, and
032 * string representations {"no", "n", "false", "off", "0"} are converted
033 * to Boolean.FALSE. The recognised true/false strings can be changed by:
034 * <pre>
035 * String[] trueStrings = {"oui", "o", "1"};
036 * String[] falseStrings = {"non", "n", "0"};
037 * Converter bc = new BooleanConverter(trueStrings, falseStrings);
038 * ConvertUtils.register(bc, Boolean.class);
039 * ConvertUtils.register(bc, Boolean.TYPE);
040 * </pre>
041 * In addition, it is recommended that the BooleanArrayConverter also be
042 * modified to recognise the same set of values:
043 * <pre>
044 * Converter bac = new BooleanArrayConverter(bc, BooleanArrayConverter.NO_DEFAULT);
045 * ConvertUtils.register(bac, bac.MODEL);
046 * </pre>
047 * </p>
048 *
049 * <p>Case is ignored when converting values to true or false.</p>
050 *
051 * @author Craig R. McClanahan
052 * @version $Revision: 640131 $ $Date: 2008-03-23 02:10:31 +0000 (Sun, 23 Mar 2008) $
053 * @since 1.3
054 */
055 public final class BooleanConverter extends AbstractConverter {
056
057
058 // ----------------------------------------------------------- Constructors
059
060
061 /**
062 * Create a {@link org.apache.commons.beanutils.Converter} that will throw a {@link ConversionException}
063 * if a conversion error occurs, ie the string value being converted is
064 * not one of the known true strings, nor one of the known false strings.
065 */
066 public BooleanConverter() {
067 super();
068 }
069
070
071 /**
072 * Create a {@link org.apache.commons.beanutils.Converter} that will return the specified default value
073 * if a conversion error occurs, ie the string value being converted is
074 * not one of the known true strings, nor one of the known false strings.
075 *
076 * @param defaultValue The default value to be returned if the value
077 * being converted is not recognised. This value may be null, in which
078 * case null will be returned on conversion failure. When non-null, it is
079 * expected that this value will be either Boolean.TRUE or Boolean.FALSE.
080 * The special value BooleanConverter.NO_DEFAULT can also be passed here,
081 * in which case this constructor acts like the no-argument one.
082 */
083 public BooleanConverter(Object defaultValue) {
084 super();
085 if (defaultValue != NO_DEFAULT) {
086 setDefaultValue(defaultValue);
087 }
088 }
089
090 /**
091 * Create a {@link org.apache.commons.beanutils.Converter} that will throw a {@link ConversionException}
092 * if a conversion error occurs, ie the string value being converted is
093 * not one of the known true strings, nor one of the known false strings.
094 * <p>
095 * The provided string arrays are copied, so that changes to the elements
096 * of the array after this call is made do not affect this object.
097 *
098 * @param trueStrings is the set of strings which should convert to the
099 * 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();
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();
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 * Return the default type this <code>Converter</code> handles.
174 *
175 * @return The default type this <code>Converter</code> handles.
176 */
177 protected Class getDefaultType() {
178 return Boolean.class;
179 }
180
181 /**
182 * Convert the specified input object into an output object of the
183 * specified type.
184 *
185 * @param type is the type to which this value should be converted. In the
186 * case of this BooleanConverter class, this value is ignored.
187 *
188 * @param value is the input value to be converted. The toString method
189 * shall be invoked on this object, and the result compared (ignoring
190 * case) against the known "true" and "false" string values.
191 *
192 * @return Boolean.TRUE if the value was a recognised "true" value,
193 * Boolean.FALSE if the value was a recognised "false" value, or
194 * the default value if the value was not recognised and the constructor
195 * was provided with a default value.
196 *
197 * @throws Throwable if an error occurs converting to the specified type
198 */
199 protected Object convertToType(Class type, Object value) throws Throwable {
200
201 // All the values in the trueStrings and falseStrings arrays are
202 // guaranteed to be lower-case. By converting the input value
203 // to lowercase too, we can use the efficient String.equals method
204 // instead of the less-efficient String.equalsIgnoreCase method.
205 String stringValue = value.toString().toLowerCase();
206
207 for(int i=0; i<trueStrings.length; ++i) {
208 if (trueStrings[i].equals(stringValue)) {
209 return Boolean.TRUE;
210 }
211 }
212
213 for(int i=0; i<falseStrings.length; ++i) {
214 if (falseStrings[i].equals(stringValue)) {
215 return Boolean.FALSE;
216 }
217 }
218
219 throw new ConversionException("Cna't convert value '" + value + "' to a Boolean");
220 }
221
222 /**
223 * This method creates a copy of the provided array, and ensures that
224 * all the strings in the newly created array contain only lower-case
225 * letters.
226 * <p>
227 * Using this method to copy string arrays means that changes to the
228 * src array do not modify the dst array.
229 */
230 private static String[] copyStrings(String[] src) {
231 String[] dst = new String[src.length];
232 for(int i=0; i<src.length; ++i) {
233 dst[i] = src[i].toLowerCase();
234 }
235 return dst;
236 }
237 }