BooleanConverter.java

  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.  * {@link org.apache.commons.beanutils2.Converter} implementation that handles conversion to and from <strong>Boolean</strong> objects.
  20.  * {@link org.apache.commons.beanutils2.Converter} implementation that handles conversion to and from {@link Boolean} objects.
  21.  * <p>
  22.  * Can be configured to either return a <em>default value</em> or throw a {@code ConversionException} if a conversion error occurs.
  23.  * </p>
  24.  * <p>
  25.  * By default any object whose string representation is one of the values {"yes", "y", "true", "on", "1"} is converted to Boolean.TRUE, and string
  26.  * representations {"no", "n", "false", "off", "0"} are converted to Boolean.FALSE. The recognized true/false strings can be changed by:
  27.  * </p>
  28.  *
  29.  * <pre>
  30.  * String[] trueStrings = { "oui", "o", "1" };
  31.  * String[] falseStrings = { "non", "n", "0" };
  32.  * Converter bc = new BooleanConverter(trueStrings, falseStrings);
  33.  * ConvertUtils.register(bc, Boolean.class);
  34.  * ConvertUtils.register(bc, Boolean.TYPE);
  35.  * </pre>
  36.  *
  37.  * <p>
  38.  * Case is ignored when converting values to true or false.
  39.  * </p>
  40.  *
  41.  * @since 1.3
  42.  */
  43. public final class BooleanConverter extends AbstractConverter<Boolean> {

  44.     /**
  45.      * Copies the provided array, and ensures that all the strings in the newly created array contain only lower-case letters.
  46.      * <p>
  47.      * Using this method to copy string arrays means that changes to the src array do not modify the dst array.
  48.      * </p>
  49.      */
  50.     private static String[] copyStrings(final String[] src) {
  51.         final String[] dst = new String[src.length];
  52.         for (int i = 0; i < src.length; ++i) {
  53.             dst[i] = toLowerCase(src[i]);
  54.         }
  55.         return dst;
  56.     }

  57.     /**
  58.      * The set of strings that are known to map to Boolean.TRUE.
  59.      */
  60.     private String[] trueStrings = { "true", "yes", "y", "on", "1" };

  61.     /**
  62.      * The set of strings that are known to map to Boolean.FALSE.
  63.      */
  64.     private String[] falseStrings = { "false", "no", "n", "off", "0" };

  65.     /**
  66.      * Constructs a {@link org.apache.commons.beanutils2.Converter} that will throw a {@link org.apache.commons.beanutils2.ConversionException} if a conversion
  67.      * 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.
  68.      */
  69.     public BooleanConverter() {
  70.     }

  71.     /**
  72.      * Constructs a {@link org.apache.commons.beanutils2.Converter} that will return the specified default value if a conversion error occurs, that is, the
  73.      * string value being converted is not one of the known true strings, nor one of the known false strings.
  74.      *
  75.      * @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
  76.      *                     returned on conversion failure. When non-null, it is expected that this value will be either Boolean.TRUE or Boolean.FALSE. The
  77.      *                     special value BooleanConverter.NO_DEFAULT can also be passed here, in which case this constructor acts like the no-argument one.
  78.      */
  79.     public BooleanConverter(final Boolean defaultValue) {
  80.         super(defaultValue);
  81.     }

  82.     /**
  83.      * Constructs a {@link org.apache.commons.beanutils2.Converter} that will throw a {@link org.apache.commons.beanutils2.ConversionException} if a conversion
  84.      * error occurs, that is, the string value being converted is not one of the known true strings, nor one of the known false strings.
  85.      * <p>
  86.      * 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.
  87.      *
  88.      * @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.
  89.      * @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.
  90.      * @since 1.8.0
  91.      */
  92.     public BooleanConverter(final String[] trueStrings, final String[] falseStrings) {
  93.         this.trueStrings = copyStrings(trueStrings);
  94.         this.falseStrings = copyStrings(falseStrings);
  95.     }

  96.     /**
  97.      * Constructs a {@link org.apache.commons.beanutils2.Converter} that will return the specified default value if a conversion error occurs.
  98.      * <p>
  99.      * 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.
  100.      *
  101.      * @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.
  102.      * @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.
  103.      * @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
  104.      *                     returned on conversion failure. When non-null, it is expected that this value will be either Boolean.TRUE or Boolean.FALSE. The
  105.      *                     special value BooleanConverter.NO_DEFAULT can also be passed here, in which case an exception will be thrown on conversion failure.
  106.      * @since 1.8.0
  107.      */
  108.     public BooleanConverter(final String[] trueStrings, final String[] falseStrings, final Boolean defaultValue) {
  109.         super(defaultValue);
  110.         this.trueStrings = copyStrings(trueStrings);
  111.         this.falseStrings = copyStrings(falseStrings);
  112.     }

  113.     /**
  114.      * Converts the specified input object into an output object of the specified type.
  115.      *
  116.      * @param <T>   Target type of the conversion.
  117.      * @param type  is the type to which this value should be converted. In the case of this BooleanConverter class, this value is ignored.
  118.      * @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
  119.      *              known "true" and "false" string values.
  120.      *
  121.      * @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
  122.      *         value was not recognized and the constructor was provided with a default value.
  123.      *
  124.      * @throws Throwable if an error occurs converting to the specified type
  125.      * @since 1.8.0
  126.      */
  127.     @Override
  128.     protected <T> T convertToType(final Class<T> type, final Object value) throws Throwable {
  129.         if (Boolean.class.equals(type) || Boolean.TYPE.equals(type)) {
  130.             // All the values in the trueStrings and falseStrings arrays are
  131.             // guaranteed to be lower-case. By converting the input value
  132.             // to lowercase too, we can use the efficient String.equals method
  133.             // instead of the less-efficient String.equalsIgnoreCase method.
  134.             final String stringValue = toLowerCase(value);

  135.             for (final String trueString : trueStrings) {
  136.                 if (trueString.equals(stringValue)) {
  137.                     return type.cast(Boolean.TRUE);
  138.                 }
  139.             }

  140.             for (final String falseString : falseStrings) {
  141.                 if (falseString.equals(stringValue)) {
  142.                     return type.cast(Boolean.FALSE);
  143.                 }
  144.             }
  145.         }

  146.         throw conversionException(type, value);
  147.     }

  148.     /**
  149.      * Gets the default type this {@code Converter} handles.
  150.      *
  151.      * @return The default type this {@code Converter} handles.
  152.      * @since 1.8.0
  153.      */
  154.     @Override
  155.     protected Class<Boolean> getDefaultType() {
  156.         return Boolean.class;
  157.     }
  158. }