View Javadoc

    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.beanutils.converters;
    18
    19  import org.apache.commons.beanutils.ConversionException;
    20
    21  /***
    22   * {@link org.apache.commons.beanutils.Converter} implementaion that handles conversion
    23   * to and from <b>Boolean</b> objects.
    24   * {@link org.apache.commons.beanutils.Converter} implementaion that
    25   * handles conversion to and from <b>java.lang.Boolean</b> objects.
    26   * <p>
    27   * Can be configured to either return a <i>default value</i> or throw a
    28   * <code>ConversionException</code> if a conversion error occurs.
    29   * <p>
    30   * By default any object whose string representation is one of the values
    31   * {"yes", "y", "true", "on", "1"} is converted to Boolean.TRUE, and
    32   * string representations {"no", "n", "false", "off", "0"} are converted
    33   * to Boolean.FALSE. The recognised true/false strings can be changed by:
    34   * <pre>
    35   *  String[] trueStrings = {"oui", "o", "1"};
    36   *  String[] falseStrings = {"non", "n", "0"};
    37   *  Converter bc = new BooleanConverter(trueStrings, falseStrings);
    38   *  ConvertUtils.register(bc, Boolean.class);
    39   *  ConvertUtils.register(bc, Boolean.TYPE);
    40   * </pre>
    41   * In addition, it is recommended that the BooleanArrayConverter also be
    42   * modified to recognise the same set of values:
    43   * <pre>
    44   *   Converter bac = new BooleanArrayConverter(bc, BooleanArrayConverter.NO_DEFAULT);
    45   *   ConvertUtils.register(bac, bac.MODEL);
    46   * </pre>
    47   * </p>
    48   *
    49   * <p>Case is ignored when converting values to true or false.</p>
    50   *
    51   * @author Craig R. McClanahan
    52   * @version $Revision: 555845 $ $Date: 2007-07-13 03:52:05 +0100 (Fri, 13 Jul 2007) $
    53   * @since 1.3
    54   */
    55  public final class BooleanConverter extends AbstractConverter {
    56
    57
    58      // ----------------------------------------------------------- Constructors
    59
    60
    61      /***
    62       * Create a {@link org.apache.commons.beanutils.Converter} that will throw a {@link ConversionException}
    63       * if a conversion error occurs, ie the string value being converted is
    64       * not one of the known true strings, nor one of the known false strings.
    65       */
    66      public BooleanConverter() {
    67          super(Boolean.class);
    68      }
    69
    70
    71      /***
    72       * Create a {@link org.apache.commons.beanutils.Converter} that will return the specified default value
    73       * if a conversion error occurs, ie the string value being converted is
    74       * not one of the known true strings, nor one of the known false strings.
    75       *
    76       * @param defaultValue The default value to be returned if the value
    77       *  being converted is not recognised. This value may be null, in which
    78       *  case null will be returned on conversion failure. When non-null, it is
    79       *  expected that this value will be either Boolean.TRUE or Boolean.FALSE.
    80       *  The special value BooleanConverter.NO_DEFAULT can also be passed here,
    81       *  in which case this constructor acts like the no-argument one.
    82       */
    83      public BooleanConverter(Object defaultValue) {
    84          super(Boolean.class);
    85          if (defaultValue != NO_DEFAULT) {
    86              setDefaultValue(defaultValue);
    87          }
    88      }
    89
    90      /***
    91       * Create a {@link org.apache.commons.beanutils.Converter} that will throw a {@link ConversionException}
    92       * if a conversion error occurs, ie the string value being converted is
    93       * not one of the known true strings, nor one of the known false strings.
    94       * <p>
    95       * The provided string arrays are copied, so that changes to the elements
    96       * of the array after this call is made do not affect this object.
    97       *
    98       * @param trueStrings is the set of strings which should convert to the
    99       *  value Boolean.TRUE. The value null must not be present. Case is
    100      *  ignored.
    101      *
    102      * @param falseStrings is the set of strings which should convert to the
    103      *  value Boolean.TRUE. The value null must not be present. Case is
    104      *  ignored.
    105      */
    106     public BooleanConverter(String[] trueStrings, String[] falseStrings) {
    107         super(Boolean.class);
    108         this.trueStrings = copyStrings(trueStrings);
    109         this.falseStrings = copyStrings(falseStrings);
    110     }
    111
    112     /***
    113      * Create a {@link org.apache.commons.beanutils.Converter} that will return
    114      * the specified default value if a conversion error occurs.
    115      * <p>
    116      * The provided string arrays are copied, so that changes to the elements
    117      * of the array after this call is made do not affect this object.
    118      *
    119      * @param trueStrings is the set of strings which should convert to the
    120      *  value Boolean.TRUE. The value null must not be present. Case is
    121      *  ignored.
    122      *
    123      * @param falseStrings is the set of strings which should convert to the
    124      *  value Boolean.TRUE. The value null must not be present. Case is
    125      *  ignored.
    126      *
    127      * @param defaultValue The default value to be returned if the value
    128      *  being converted is not recognised. This value may be null, in which
    129      *  case null will be returned on conversion failure. When non-null, it is
    130      *  expected that this value will be either Boolean.TRUE or Boolean.FALSE.
    131      *  The special value BooleanConverter.NO_DEFAULT can also be passed here,
    132      *  in which case an exception will be thrown on conversion failure.
    133      */
    134     public BooleanConverter(String[] trueStrings, String[] falseStrings,
    135                 Object defaultValue) {
    136         super(Boolean.class);
    137         this.trueStrings = copyStrings(trueStrings);
    138         this.falseStrings = copyStrings(falseStrings);
    139         if (defaultValue != NO_DEFAULT) {
    140             setDefaultValue(defaultValue);
    141         }
    142     }
    143
    144
    145     // ----------------------------------------------------- Static Variables
    146
    147
    148     /***
    149      * This is a special reference that can be passed as the "default object"
    150      * to the constructor to indicate that no default is desired. Note that
    151      * the value 'null' cannot be used for this purpose, as the caller may
    152      * want a null to be returned as the default.
    153      * @deprecated Use constructors without default value.
    154      */
    155     public static final Object NO_DEFAULT = new Object();
    156
    157
    158     // ----------------------------------------------------- Instance Variables
    159
    160     /***
    161      * The set of strings that are known to map to Boolean.TRUE.
    162      */
    163     private String[] trueStrings = {"true", "yes", "y", "on", "1"};
    164
    165     /***
    166      * The set of strings that are known to map to Boolean.FALSE.
    167      */
    168     private String[] falseStrings = {"false", "no", "n", "off", "0"};
    169
    170     // --------------------------------------------------------- Protected Methods
    171
    172     /***
    173      * Convert the specified input object into an output object of the
    174      * specified type.
    175      *
    176      * @param type is the type to which this value should be converted. In the
    177      *  case of this BooleanConverter class, this value is ignored.
    178      *
    179      * @param value is the input value to be converted. The toString method
    180      *  shall be invoked on this object, and the result compared (ignoring
    181      *  case) against the known "true" and "false" string values.
    182      *
    183      * @return Boolean.TRUE if the value was a recognised "true" value,
    184      *  Boolean.FALSE if the value was a recognised "false" value, or
    185      *  the default value if the value was not recognised and the constructor
    186      *  was provided with a default value.
    187      *
    188      * @throws Throwable if an error occurs converting to the specified type
    189      */
    190     protected Object convertToType(Class type, Object value) throws Throwable {
    191
    192         // All the values in the trueStrings and falseStrings arrays are
    193         // guaranteed to be lower-case. By converting the input value
    194         // to lowercase too, we can use the efficient String.equals method
    195         // instead of the less-efficient String.equalsIgnoreCase method.
    196         String stringValue = value.toString().toLowerCase();
    197
    198         for(int i=0; i<trueStrings.length; ++i) {
    199             if (trueStrings[i].equals(stringValue)) {
    200                 return Boolean.TRUE;
    201             }
    202         }
    203
    204         for(int i=0; i<falseStrings.length; ++i) {
    205             if (falseStrings[i].equals(stringValue)) {
    206                 return Boolean.FALSE;
    207             }
    208         }
    209
    210         throw new ConversionException("Cna't convert value '" + value + "' to a Boolean");
    211     }
    212
    213     /***
    214      * This method creates a copy of the provided array, and ensures that
    215      * all the strings in the newly created array contain only lower-case
    216      * letters.
    217      * <p>
    218      * Using this method to copy string arrays means that changes to the
    219      * src array do not modify the dst array.
    220      */
    221     private static String[] copyStrings(String[] src) {
    222         String[] dst = new String[src.length];
    223         for(int i=0; i<src.length; ++i) {
    224             dst[i] = src[i].toLowerCase();
    225         }
    226         return dst;
    227     }
    228 }