View Javadoc

1   // Copyright (C) 2005 - 2009 Philip Aston
2   // All rights reserved.
3   //
4   // This file is part of The Grinder software distribution. Refer to
5   // the file LICENSE which is part of The Grinder distribution for
6   // licensing details. The Grinder distribution is available on the
7   // Internet at http://grinder.sourceforge.net/
8   //
9   // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
10  // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
11  // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
12  // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
13  // COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
14  // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
15  // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
16  // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
17  // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
18  // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
19  // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
20  // OF THE POSSIBILITY OF SUCH DAMAGE.
21  
22  package net.grinder.util;
23  
24  import java.beans.IntrospectionException;
25  import java.beans.PropertyDescriptor;
26  import java.lang.reflect.InvocationTargetException;
27  import java.lang.reflect.Method;
28  
29  import net.grinder.common.GrinderException;
30  
31  
32  /**
33   * Introspects a boolean property of a Java Bean and provides setter
34   * and getter methods.
35   *
36   * @author Philip Aston
37   */
38  public final class BooleanProperty {
39    private final Object m_bean;
40    private final Class<?> m_beanClass;
41    private final PropertyDescriptor m_propertyDescriptor;
42  
43    /**
44     * Constructor.
45     *
46     * @param bean Bean to introspect.
47     * @param propertyName The property.
48     * @throws PropertyException If a boolean property of the given name
49     * could not be found.
50     */
51    public BooleanProperty(Object bean, String propertyName)
52      throws PropertyException {
53  
54      m_bean = bean;
55      m_beanClass = bean.getClass();
56  
57      try {
58        m_propertyDescriptor = new PropertyDescriptor(propertyName, m_beanClass);
59      }
60      catch (IntrospectionException e) {
61        throw new PropertyException(
62          "Could not find property '" + propertyName + "' in class '" +
63          m_beanClass + "'", e);
64      }
65  
66      final Class<?> propertyType = m_propertyDescriptor.getPropertyType();
67  
68      if (!propertyType.equals(Boolean.TYPE) &&
69          !propertyType.equals(Boolean.class)) {
70        throw new PropertyException(toString() + ": property is not boolean");
71      }
72    }
73  
74    /**
75     * Getter method.
76     *
77     * @return The current value of the property.
78     * @throws PropertyException If the value could not be read.
79     */
80    public boolean get() throws PropertyException {
81  
82      // Despite what the JavaDoc for PropertyDescriptor.getReadMethod()
83      // says, this is guaranteed to be non-null if the property name is
84      // non-null.
85      final Method readMethod = m_propertyDescriptor.getReadMethod();
86  
87      try {
88        final Boolean result = (Boolean)readMethod.invoke(m_bean, new Object[0]);
89        return result.booleanValue();
90      }
91      catch (IllegalAccessException e) {
92        throw new PropertyException(toString() + ": could not read", e);
93      }
94      catch (InvocationTargetException e) {
95        throw new PropertyException(toString() + ": could not read",
96                                    e.getTargetException());
97      }
98    }
99  
100   /**
101    * Setter method.
102    *
103    * @param value The new value of the property.
104    * @throws PropertyException If the value could not be written.
105    */
106   public void set(boolean value) throws PropertyException {
107     // Despite what the JavaDoc for
108     // PropertyDescriptor.getWriteMethod() says, this is guaranteed to
109     // be non-null if the property name is non-null.
110     final Method writeMethod = m_propertyDescriptor.getWriteMethod();
111 
112     try {
113       writeMethod.invoke(
114         m_bean, new Object[] { value ? Boolean.TRUE : Boolean.FALSE });
115     }
116     catch (IllegalAccessException e) {
117       throw new PropertyException(toString() + ": could not write", e);
118     }
119     catch (InvocationTargetException e) {
120       throw new PropertyException(toString() + ": could not write",
121                                   e.getTargetException());
122     }
123   }
124 
125   /**
126    * Describe the property.
127    *
128    * @return  A description of the property.
129    */
130   public String toString() {
131     return m_beanClass.getName() + "." + m_propertyDescriptor.getName();
132   }
133 
134   /**
135    * Indicates a problem with accessing the property.
136    */
137   public static final class PropertyException extends GrinderException {
138 
139     private PropertyException(String message) {
140       super(message);
141     }
142 
143     private PropertyException(String message, Throwable t) {
144       super(message, t);
145     }
146   }
147 }