1
1
/*
2
- * Copyright 2001-2004 The Apache Software Foundation.
2
+ * Copyright 2001-2005 The Apache Software Foundation.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
17
17
18
18
package org .apache .commons .beanutils .converters ;
19
19
20
-
21
20
import org .apache .commons .beanutils .ConversionException ;
22
21
import org .apache .commons .beanutils .Converter ;
23
22
28
27
* default value or throwing a {@link ConversionException} if a conversion
29
28
* error occurs.</p>
30
29
*
30
+ * <p>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
+ *
31
51
* @author Craig R. McClanahan
32
52
* @version $Revision$ $Date$
33
53
* @since 1.3
@@ -41,57 +61,133 @@ public final class BooleanConverter implements Converter {
41
61
42
62
/**
43
63
* Create a {@link Converter} that will throw a {@link ConversionException}
44
- * if a conversion error occurs.
64
+ * if a conversion error occurs, ie the string value being converted is
65
+ * not one of the known true strings, nor one of the known false strings.
45
66
*/
46
67
public BooleanConverter () {
47
68
48
- this .defaultValue = null ;
49
69
this .useDefault = false ;
50
70
51
71
}
52
72
53
73
54
74
/**
55
75
* Create a {@link Converter} that will return the specified default value
56
- * if a conversion error occurs.
76
+ * if a conversion error occurs, ie the string value being converted is
77
+ * not one of the known true strings, nor one of the known false strings.
57
78
*
58
- * @param defaultValue The default value to be returned
79
+ * @param defaultValue The default value to be returned if the value
80
+ * being converted is not recognised. This value may be null, in which
81
+ * case null will be returned on conversion failure. When non-null, it is
82
+ * expected that this value will be either Boolean.TRUE or Boolean.FALSE.
83
+ * The special value BooleanConverter.NO_DEFAULT can also be passed here,
84
+ * in which case this constructor acts like the no-argument one.
59
85
*/
60
86
public BooleanConverter (Object defaultValue ) {
61
87
62
- this .defaultValue = defaultValue ;
63
- this .useDefault = true ;
88
+ if (defaultValue == NO_DEFAULT ) {
89
+ this .useDefault = false ;
90
+ } else {
91
+ this .defaultValue = defaultValue ;
92
+ this .useDefault = true ;
93
+ }
94
+
95
+ }
96
+
97
+ /**
98
+ * Create a {@link Converter} that will return the specified default value
99
+ * if a conversion error occurs.
100
+ * <p>
101
+ * The provided string arrays are copied, so that changes to the elements
102
+ * of the array after this call is made do not affect this object.
103
+ *
104
+ * @param trueStrings is the set of strings which should convert to the
105
+ * value Boolean.TRUE. The value null must not be present. Case is
106
+ * ignored.
107
+ *
108
+ * @param falseStrings is the set of strings which should convert to the
109
+ * value Boolean.TRUE. The value null must not be present. Case is
110
+ * ignored.
111
+ *
112
+ * @param defaultValue The default value to be returned if the value
113
+ * being converted is not recognised. This value may be null, in which
114
+ * case null will be returned on conversion failure. When non-null, it is
115
+ * expected that this value will be either Boolean.TRUE or Boolean.FALSE.
116
+ * The special value BooleanConverter.NO_DEFAULT can also be passed here,
117
+ * in which case an exception will be thrown on conversion failure.
118
+ */
119
+ public BooleanConverter (String [] trueStrings , String [] falseStrings ,
120
+ Object defaultValue ) {
121
+
122
+ this .trueStrings = copyStrings (trueStrings );
123
+ this .falseStrings = copyStrings (falseStrings );
124
+
125
+ if (defaultValue == NO_DEFAULT ) {
126
+ this .useDefault = false ;
127
+ } else {
128
+ this .defaultValue = defaultValue ;
129
+ this .useDefault = true ;
130
+ }
64
131
65
132
}
66
133
67
134
135
+ // ----------------------------------------------------- Static Variables
136
+
137
+
138
+ /**
139
+ * This is a special reference that can be passed as the "default object"
140
+ * to the constructor to indicate that no default is desired. Note that
141
+ * the value 'null' cannot be used for this purpose, as the caller may
142
+ * want a null to be returned as the default.
143
+ */
144
+ public static final Object NO_DEFAULT = new Object ();
145
+
146
+
68
147
// ----------------------------------------------------- Instance Variables
69
148
70
149
71
150
/**
72
151
* The default value specified to our Constructor, if any.
73
152
*/
74
- private Object defaultValue = null ;
75
-
153
+ private Object defaultValue ;
76
154
77
155
/**
78
156
* Should we return the default value on conversion errors?
79
157
*/
80
- private boolean useDefault = true ;
158
+ private boolean useDefault ;
81
159
160
+ /**
161
+ * The set of strings that are known to map to Boolean.TRUE.
162
+ */
163
+ private String [] trueStrings = {"yes" , "y" , "true" , "on" , "1" };
82
164
83
- // --------------------------------------------------------- Public Methods
165
+ /**
166
+ * The set of strings that are known to map to Boolean.FALSE.
167
+ */
168
+ private String [] falseStrings = {"no" , "n" , "false" , "off" , "0" };
84
169
170
+ // --------------------------------------------------------- Public Methods
85
171
86
172
/**
87
173
* Convert the specified input object into an output object of the
88
174
* specified type.
89
175
*
90
- * @param type Data type to which this value should be converted
91
- * @param value The input value to be converted
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.
92
187
*
93
188
* @exception ConversionException if conversion cannot be performed
94
- * successfully
189
+ * successfully and the constructor was not provided with a default
190
+ * value to return on conversion failure.
95
191
*/
96
192
public Object convert (Class type , Object value ) {
97
193
@@ -107,34 +203,42 @@ public Object convert(Class type, Object value) {
107
203
return (value );
108
204
}
109
205
110
- try {
111
- String stringValue = value .toString ();
112
- if (stringValue .equalsIgnoreCase ("yes" ) ||
113
- stringValue .equalsIgnoreCase ("y" ) ||
114
- stringValue .equalsIgnoreCase ("true" ) ||
115
- stringValue .equalsIgnoreCase ("on" ) ||
116
- stringValue .equalsIgnoreCase ("1" )) {
117
- return (Boolean .TRUE );
118
- } else if (stringValue .equalsIgnoreCase ("no" ) ||
119
- stringValue .equalsIgnoreCase ("n" ) ||
120
- stringValue .equalsIgnoreCase ("false" ) ||
121
- stringValue .equalsIgnoreCase ("off" ) ||
122
- stringValue .equalsIgnoreCase ("0" )) {
123
- return (Boolean .FALSE );
124
- } else if (useDefault ) {
125
- return (defaultValue );
126
- } else {
127
- throw new ConversionException (stringValue );
128
- }
129
- } catch (ClassCastException e ) {
130
- if (useDefault ) {
131
- return (defaultValue );
132
- } else {
133
- throw new ConversionException (e );
134
- }
206
+ // All the values in the trueStrings and falseStrings arrays are
207
+ // guaranteed to be lower-case. By converting the input value
208
+ // to lowercase too, we can use the efficient String.equals method
209
+ // instead of the less-efficient String.equalsIgnoreCase method.
210
+ String stringValue = value .toString ().toLowerCase ();
211
+
212
+ for (int i =0 ; i <trueStrings .length ; ++i ) {
213
+ if (trueStrings [i ].equals (stringValue ))
214
+ return Boolean .TRUE ;
135
215
}
136
216
137
- }
217
+ for (int i =0 ; i <falseStrings .length ; ++i ) {
218
+ if (falseStrings [i ].equals (stringValue ))
219
+ return Boolean .FALSE ;
220
+ }
221
+
222
+ if (useDefault ) {
223
+ return defaultValue ;
224
+ }
138
225
226
+ throw new ConversionException (value .toString ());
227
+ }
139
228
229
+ /**
230
+ * This method creates a copy of the provided array, and ensures that
231
+ * all the strings in the newly created array contain only lower-case
232
+ * letters.
233
+ * <p>
234
+ * Using this method to copy string arrays means that changes to the
235
+ * src array do not modify the dst array.
236
+ */
237
+ private static String [] copyStrings (String [] src ) {
238
+ String [] dst = new String [src .length ];
239
+ for (int i =0 ; i <src .length ; ++i ) {
240
+ dst [i ] = src [i ].toLowerCase ();
241
+ }
242
+ return dst ;
243
+ }
140
244
}
0 commit comments