1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package org.apache.commons.beanutils2.converters; 18 19 /** 20 * {@link org.apache.commons.beanutils2.Converter} implementation that handles conversion to and from <strong>Boolean</strong> objects. 21 * {@link org.apache.commons.beanutils2.Converter} implementation that handles conversion to and from {@link Boolean} objects. 22 * <p> 23 * Can be configured to either return a <em>default value</em> or throw a {@code ConversionException} if a conversion error occurs. 24 * </p> 25 * <p> 26 * By default any object whose string representation is one of the values {"yes", "y", "true", "on", "1"} is converted to Boolean.TRUE, and string 27 * representations {"no", "n", "false", "off", "0"} are converted to Boolean.FALSE. The recognized true/false strings can be changed by: 28 * </p> 29 * 30 * <pre> 31 * String[] trueStrings = { "oui", "o", "1" }; 32 * String[] falseStrings = { "non", "n", "0" }; 33 * Converter bc = new BooleanConverter(trueStrings, falseStrings); 34 * ConvertUtils.register(bc, Boolean.class); 35 * ConvertUtils.register(bc, Boolean.TYPE); 36 * </pre> 37 * 38 * <p> 39 * Case is ignored when converting values to true or false. 40 * </p> 41 * 42 * @since 1.3 43 */ 44 public final class BooleanConverter extends AbstractConverter<Boolean> { 45 46 /** 47 * Copies the provided array, and ensures that all the strings in the newly created array contain only lower-case letters. 48 * <p> 49 * Using this method to copy string arrays means that changes to the src array do not modify the dst array. 50 * </p> 51 */ 52 private static String[] copyStrings(final String[] src) { 53 final String[] dst = new String[src.length]; 54 for (int i = 0; i < src.length; ++i) { 55 dst[i] = toLowerCase(src[i]); 56 } 57 return dst; 58 } 59 60 /** 61 * The set of strings that are known to map to Boolean.TRUE. 62 */ 63 private String[] trueStrings = { "true", "yes", "y", "on", "1" }; 64 65 /** 66 * The set of strings that are known to map to Boolean.FALSE. 67 */ 68 private String[] falseStrings = { "false", "no", "n", "off", "0" }; 69 70 /** 71 * Constructs a {@link org.apache.commons.beanutils2.Converter} that will throw a {@link org.apache.commons.beanutils2.ConversionException} if a conversion 72 * error occurs, that is, if the string value being converted is not one of the known true strings, nor one of the known false strings. 73 */ 74 public BooleanConverter() { 75 } 76 77 /** 78 * Constructs a {@link org.apache.commons.beanutils2.Converter} that will return the specified default value if a conversion error occurs, that is, the 79 * string value being converted is not one of the known true strings, nor one of the known false strings. 80 * 81 * @param defaultValue The default value to be returned if the value being converted is not recognized. This value may be null, in which case null will be 82 * returned on conversion failure. When non-null, it is expected that this value will be either Boolean.TRUE or Boolean.FALSE. The 83 * special value BooleanConverter.NO_DEFAULT can also be passed here, in which case this constructor acts like the no-argument one. 84 */ 85 public BooleanConverter(final Boolean defaultValue) { 86 super(defaultValue); 87 } 88 89 /** 90 * Constructs a {@link org.apache.commons.beanutils2.Converter} that will throw a {@link org.apache.commons.beanutils2.ConversionException} if a conversion 91 * error occurs, that is, the string value being converted is not one of the known true strings, nor one of the known false strings. 92 * <p> 93 * The provided string arrays are copied, so that changes to the elements of the array after this call is made do not affect this object. 94 * 95 * @param trueStrings is the set of strings which should convert to the value Boolean.TRUE. The value null must not be present. Case is ignored. 96 * @param falseStrings is the set of strings which should convert to the value Boolean.TRUE. The value null must not be present. Case is ignored. 97 * @since 1.8.0 98 */ 99 public BooleanConverter(final String[] trueStrings, final String[] falseStrings) { 100 this.trueStrings = copyStrings(trueStrings); 101 this.falseStrings = copyStrings(falseStrings); 102 } 103 104 /** 105 * Constructs a {@link org.apache.commons.beanutils2.Converter} that will return the specified default value if a conversion error occurs. 106 * <p> 107 * The provided string arrays are copied, so that changes to the elements of the array after this call is made do not affect this object. 108 * 109 * @param trueStrings is the set of strings which should convert to the value Boolean.TRUE. The value null must not be present. Case is ignored. 110 * @param falseStrings is the set of strings which should convert to the value Boolean.TRUE. The value null must not be present. Case is ignored. 111 * @param defaultValue The default value to be returned if the value being converted is not recognized. This value may be null, in which case null will be 112 * returned on conversion failure. When non-null, it is expected that this value will be either Boolean.TRUE or Boolean.FALSE. The 113 * special value BooleanConverter.NO_DEFAULT can also be passed here, in which case an exception will be thrown on conversion failure. 114 * @since 1.8.0 115 */ 116 public BooleanConverter(final String[] trueStrings, final String[] falseStrings, final Boolean defaultValue) { 117 super(defaultValue); 118 this.trueStrings = copyStrings(trueStrings); 119 this.falseStrings = copyStrings(falseStrings); 120 } 121 122 /** 123 * Converts the specified input object into an output object of the specified type. 124 * 125 * @param <T> Target type of the conversion. 126 * @param type is the type to which this value should be converted. In the case of this BooleanConverter class, this value is ignored. 127 * @param value is the input value to be converted. The toString method shall be invoked on this object, and the result compared (ignoring case) against the 128 * known "true" and "false" string values. 129 * 130 * @return Boolean.TRUE if the value was a recognized "true" value, Boolean.FALSE if the value was a recognized "false" value, or the default value if the 131 * value was not recognized and the constructor was provided with a default value. 132 * 133 * @throws Throwable if an error occurs converting to the specified type 134 * @since 1.8.0 135 */ 136 @Override 137 protected <T> T convertToType(final Class<T> type, final Object value) throws Throwable { 138 if (Boolean.class.equals(type) || Boolean.TYPE.equals(type)) { 139 // All the values in the trueStrings and falseStrings arrays are 140 // guaranteed to be lower-case. By converting the input value 141 // to lowercase too, we can use the efficient String.equals method 142 // instead of the less-efficient String.equalsIgnoreCase method. 143 final String stringValue = toLowerCase(value); 144 145 for (final String trueString : trueStrings) { 146 if (trueString.equals(stringValue)) { 147 return type.cast(Boolean.TRUE); 148 } 149 } 150 151 for (final String falseString : falseStrings) { 152 if (falseString.equals(stringValue)) { 153 return type.cast(Boolean.FALSE); 154 } 155 } 156 } 157 158 throw conversionException(type, value); 159 } 160 161 /** 162 * Gets the default type this {@code Converter} handles. 163 * 164 * @return The default type this {@code Converter} handles. 165 * @since 1.8.0 166 */ 167 @Override 168 protected Class<Boolean> getDefaultType() { 169 return Boolean.class; 170 } 171 }