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