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 */ 017package org.apache.commons.beanutils.converters; 018 019/** 020 * {@link org.apache.commons.beanutils.Converter} implementation that handles conversion 021 * to and from <b>Boolean</b> objects. 022 * {@link org.apache.commons.beanutils.Converter} implementation that 023 * handles conversion to and from <b>java.lang.Boolean</b> objects. 024 * <p> 025 * Can be configured to either return a <i>default value</i> or throw a 026 * <code>ConversionException</code> if a conversion error occurs. 027 * </p> 028 * <p> 029 * By default any object whose string representation is one of the values 030 * {"yes", "y", "true", "on", "1"} is converted to Boolean.TRUE, and 031 * string representations {"no", "n", "false", "off", "0"} are converted 032 * to Boolean.FALSE. The recognized true/false strings can be changed by: 033 * </p> 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 * <p>In addition, it is recommended that the BooleanArrayConverter also be 042 * modified to recognise the same set of values:</p> 043 * <pre> 044 * Converter bac = new BooleanArrayConverter(bc, BooleanArrayConverter.NO_DEFAULT); 045 * ConvertUtils.register(bac, bac.MODEL); 046 * </pre> 047 * 048 * 049 * <p>Case is ignored when converting values to true or false.</p> 050 * 051 * @version $Id$ 052 * @since 1.3 053 */ 054public final class BooleanConverter extends AbstractConverter { 055 056 057 // ----------------------------------------------------------- Constructors 058 059 060 /** 061 * Create a {@link org.apache.commons.beanutils.Converter} that will throw a 062 * {@link org.apache.commons.beanutils.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 recognized. 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(final 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 092 * {@link org.apache.commons.beanutils.ConversionException} 093 * if a conversion error occurs, ie the string value being converted is 094 * not one of the known true strings, nor one of the known false strings. 095 * <p> 096 * The provided string arrays are copied, so that changes to the elements 097 * of the array after this call is made do not affect this object. 098 * 099 * @param trueStrings 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 * @param falseStrings is the set of strings which should convert to the 104 * value Boolean.TRUE. The value null must not be present. Case is 105 * ignored. 106 * @since 1.8.0 107 */ 108 public BooleanConverter(final String[] trueStrings, final String[] falseStrings) { 109 super(); 110 this.trueStrings = copyStrings(trueStrings); 111 this.falseStrings = copyStrings(falseStrings); 112 } 113 114 /** 115 * Create a {@link org.apache.commons.beanutils.Converter} that will return 116 * the specified default value if a conversion error occurs. 117 * <p> 118 * The provided string arrays are copied, so that changes to the elements 119 * of the array after this call is made do not affect this object. 120 * 121 * @param trueStrings is the set of strings which should convert to the 122 * value Boolean.TRUE. The value null must not be present. Case is 123 * ignored. 124 * 125 * @param falseStrings is the set of strings which should convert to the 126 * value Boolean.TRUE. The value null must not be present. Case is 127 * ignored. 128 * 129 * @param defaultValue The default value to be returned if the value 130 * being converted is not recognized. This value may be null, in which 131 * case null will be returned on conversion failure. When non-null, it is 132 * expected that this value will be either Boolean.TRUE or Boolean.FALSE. 133 * The special value BooleanConverter.NO_DEFAULT can also be passed here, 134 * in which case an exception will be thrown on conversion failure. 135 * @since 1.8.0 136 */ 137 public BooleanConverter(final String[] trueStrings, final String[] falseStrings, 138 final Object defaultValue) { 139 super(); 140 this.trueStrings = copyStrings(trueStrings); 141 this.falseStrings = copyStrings(falseStrings); 142 if (defaultValue != NO_DEFAULT) { 143 setDefaultValue(defaultValue); 144 } 145 } 146 147 148 // ----------------------------------------------------- Static Variables 149 150 151 /** 152 * This is a special reference that can be passed as the "default object" 153 * to the constructor to indicate that no default is desired. Note that 154 * the value 'null' cannot be used for this purpose, as the caller may 155 * want a null to be returned as the default. 156 * @deprecated Use constructors without default value. 157 */ 158 @Deprecated 159 public static final Object NO_DEFAULT = new Object(); 160 161 162 // ----------------------------------------------------- Instance Variables 163 164 /** 165 * The set of strings that are known to map to Boolean.TRUE. 166 */ 167 private String[] trueStrings = {"true", "yes", "y", "on", "1"}; 168 169 /** 170 * The set of strings that are known to map to Boolean.FALSE. 171 */ 172 private String[] falseStrings = {"false", "no", "n", "off", "0"}; 173 174 // --------------------------------------------------------- Protected Methods 175 176 /** 177 * Return the default type this <code>Converter</code> handles. 178 * 179 * @return The default type this <code>Converter</code> handles. 180 * @since 1.8.0 181 */ 182 @Override 183 protected Class<Boolean> getDefaultType() { 184 return Boolean.class; 185 } 186 187 /** 188 * Convert the specified input object into an output object of the 189 * specified type. 190 * 191 * @param <T> Target type of the conversion. 192 * @param type is the type to which this value should be converted. In the 193 * case of this BooleanConverter class, this value is ignored. 194 * 195 * @param value is the input value to be converted. The toString method 196 * shall be invoked on this object, and the result compared (ignoring 197 * case) against the known "true" and "false" string values. 198 * 199 * @return Boolean.TRUE if the value was a recognized "true" value, 200 * Boolean.FALSE if the value was a recognized "false" value, or 201 * the default value if the value was not recognized and the constructor 202 * was provided with a default value. 203 * 204 * @throws Throwable if an error occurs converting to the specified type 205 * @since 1.8.0 206 */ 207 @Override 208 protected <T> T convertToType(final Class<T> type, final Object value) throws Throwable { 209 210 if (Boolean.class.equals(type) || Boolean.TYPE.equals(type)) { 211 // All the values in the trueStrings and falseStrings arrays are 212 // guaranteed to be lower-case. By converting the input value 213 // to lowercase too, we can use the efficient String.equals method 214 // instead of the less-efficient String.equalsIgnoreCase method. 215 final String stringValue = value.toString().toLowerCase(); 216 217 for (String trueString : trueStrings) { 218 if (trueString.equals(stringValue)) { 219 return type.cast(Boolean.TRUE); 220 } 221 } 222 223 for (String falseString : falseStrings) { 224 if (falseString.equals(stringValue)) { 225 return type.cast(Boolean.FALSE); 226 } 227 } 228 } 229 230 throw conversionException(type, value); 231 } 232 233 /** 234 * This method creates a copy of the provided array, and ensures that 235 * all the strings in the newly created array contain only lower-case 236 * letters. 237 * <p> 238 * Using this method to copy string arrays means that changes to the 239 * src array do not modify the dst array. 240 */ 241 private static String[] copyStrings(final String[] src) { 242 final String[] dst = new String[src.length]; 243 for(int i=0; i<src.length; ++i) { 244 dst[i] = src[i].toLowerCase(); 245 } 246 return dst; 247 } 248}