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: 555845 $ $Date: 2007-07-13 03:52:05 +0100 (Fri, 13 Jul 2007) $
053: * @since 1.3
054: */
055: public final class BooleanConverter extends AbstractConverter {
056:
057: // ----------------------------------------------------------- Constructors
058:
059: /**
060: * Create a {@link org.apache.commons.beanutils.Converter} that will throw a {@link ConversionException}
061: * if a conversion error occurs, ie the string value being converted is
062: * not one of the known true strings, nor one of the known false strings.
063: */
064: public BooleanConverter() {
065: super (Boolean.class);
066: }
067:
068: /**
069: * Create a {@link org.apache.commons.beanutils.Converter} that will return the specified default value
070: * if a conversion error occurs, ie the string value being converted is
071: * not one of the known true strings, nor one of the known false strings.
072: *
073: * @param defaultValue The default value to be returned if the value
074: * being converted is not recognised. This value may be null, in which
075: * case null will be returned on conversion failure. When non-null, it is
076: * expected that this value will be either Boolean.TRUE or Boolean.FALSE.
077: * The special value BooleanConverter.NO_DEFAULT can also be passed here,
078: * in which case this constructor acts like the no-argument one.
079: */
080: public BooleanConverter(Object defaultValue) {
081: super (Boolean.class);
082: if (defaultValue != NO_DEFAULT) {
083: setDefaultValue(defaultValue);
084: }
085: }
086:
087: /**
088: * Create a {@link org.apache.commons.beanutils.Converter} that will throw a {@link ConversionException}
089: * if a conversion error occurs, ie the string value being converted is
090: * not one of the known true strings, nor one of the known false strings.
091: * <p>
092: * The provided string arrays are copied, so that changes to the elements
093: * of the array after this call is made do not affect this object.
094: *
095: * @param trueStrings is the set of strings which should convert to the
096: * value Boolean.TRUE. The value null must not be present. Case is
097: * ignored.
098: *
099: * @param falseStrings is the set of strings which should convert to the
100: * value Boolean.TRUE. The value null must not be present. Case is
101: * ignored.
102: */
103: public BooleanConverter(String[] trueStrings, String[] falseStrings) {
104: super (Boolean.class);
105: this .trueStrings = copyStrings(trueStrings);
106: this .falseStrings = copyStrings(falseStrings);
107: }
108:
109: /**
110: * Create a {@link org.apache.commons.beanutils.Converter} that will return
111: * the specified default value if a conversion error occurs.
112: * <p>
113: * The provided string arrays are copied, so that changes to the elements
114: * of the array after this call is made do not affect this object.
115: *
116: * @param trueStrings is the set of strings which should convert to the
117: * value Boolean.TRUE. The value null must not be present. Case is
118: * ignored.
119: *
120: * @param falseStrings is the set of strings which should convert to the
121: * value Boolean.TRUE. The value null must not be present. Case is
122: * ignored.
123: *
124: * @param defaultValue The default value to be returned if the value
125: * being converted is not recognised. This value may be null, in which
126: * case null will be returned on conversion failure. When non-null, it is
127: * expected that this value will be either Boolean.TRUE or Boolean.FALSE.
128: * The special value BooleanConverter.NO_DEFAULT can also be passed here,
129: * in which case an exception will be thrown on conversion failure.
130: */
131: public BooleanConverter(String[] trueStrings,
132: String[] falseStrings, Object defaultValue) {
133: super (Boolean.class);
134: this .trueStrings = copyStrings(trueStrings);
135: this .falseStrings = copyStrings(falseStrings);
136: if (defaultValue != NO_DEFAULT) {
137: setDefaultValue(defaultValue);
138: }
139: }
140:
141: // ----------------------------------------------------- Static Variables
142:
143: /**
144: * This is a special reference that can be passed as the "default object"
145: * to the constructor to indicate that no default is desired. Note that
146: * the value 'null' cannot be used for this purpose, as the caller may
147: * want a null to be returned as the default.
148: * @deprecated Use constructors without default value.
149: */
150: public static final Object NO_DEFAULT = new Object();
151:
152: // ----------------------------------------------------- Instance Variables
153:
154: /**
155: * The set of strings that are known to map to Boolean.TRUE.
156: */
157: private String[] trueStrings = { "true", "yes", "y", "on", "1" };
158:
159: /**
160: * The set of strings that are known to map to Boolean.FALSE.
161: */
162: private String[] falseStrings = { "false", "no", "n", "off", "0" };
163:
164: // --------------------------------------------------------- Protected Methods
165:
166: /**
167: * Convert the specified input object into an output object of the
168: * specified type.
169: *
170: * @param type is the type to which this value should be converted. In the
171: * case of this BooleanConverter class, this value is ignored.
172: *
173: * @param value is the input value to be converted. The toString method
174: * shall be invoked on this object, and the result compared (ignoring
175: * case) against the known "true" and "false" string values.
176: *
177: * @return Boolean.TRUE if the value was a recognised "true" value,
178: * Boolean.FALSE if the value was a recognised "false" value, or
179: * the default value if the value was not recognised and the constructor
180: * was provided with a default value.
181: *
182: * @throws Throwable if an error occurs converting to the specified type
183: */
184: protected Object convertToType(Class type, Object value)
185: throws Throwable {
186:
187: // All the values in the trueStrings and falseStrings arrays are
188: // guaranteed to be lower-case. By converting the input value
189: // to lowercase too, we can use the efficient String.equals method
190: // instead of the less-efficient String.equalsIgnoreCase method.
191: String stringValue = value.toString().toLowerCase();
192:
193: for (int i = 0; i < trueStrings.length; ++i) {
194: if (trueStrings[i].equals(stringValue)) {
195: return Boolean.TRUE;
196: }
197: }
198:
199: for (int i = 0; i < falseStrings.length; ++i) {
200: if (falseStrings[i].equals(stringValue)) {
201: return Boolean.FALSE;
202: }
203: }
204:
205: throw new ConversionException("Cna't convert value '" + value
206: + "' to a Boolean");
207: }
208:
209: /**
210: * This method creates a copy of the provided array, and ensures that
211: * all the strings in the newly created array contain only lower-case
212: * letters.
213: * <p>
214: * Using this method to copy string arrays means that changes to the
215: * src array do not modify the dst array.
216: */
217: private static String[] copyStrings(String[] src) {
218: String[] dst = new String[src.length];
219: for (int i = 0; i < src.length; ++i) {
220: dst[i] = src[i].toLowerCase();
221: }
222: return dst;
223: }
224: }
|