KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > util > property > MethodBoundPropertyListener


1 /*
2   * JBoss, Home of Professional Open Source
3   * Copyright 2005, JBoss Inc., and individual contributors as indicated
4   * by the @authors tag. See the copyright.txt in the distribution for a
5   * full listing of individual contributors.
6   *
7   * This is free software; you can redistribute it and/or modify it
8   * under the terms of the GNU Lesser General Public License as
9   * published by the Free Software Foundation; either version 2.1 of
10   * the License, or (at your option) any later version.
11   *
12   * This software is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15   * Lesser General Public License for more details.
16   *
17   * You should have received a copy of the GNU Lesser General Public
18   * License along with this software; if not, write to the Free
19   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21   */

22 package org.jboss.util.property;
23
24 import java.beans.BeanInfo JavaDoc;
25 import java.beans.IntrospectionException JavaDoc;
26 import java.beans.Introspector JavaDoc;
27 import java.beans.PropertyDescriptor JavaDoc;
28 import java.beans.PropertyEditor JavaDoc;
29 import java.lang.reflect.InvocationTargetException JavaDoc;
30 import java.lang.reflect.Method JavaDoc;
31
32 import org.jboss.util.ThrowableHandler;
33 import org.jboss.util.propertyeditor.PropertyEditors;
34
35 /**
36  * Binds property values to class methods.
37  *
38  * @version <tt>$Revision: 1958 $</tt>
39  * @author <a HREF="mailto:jason@planet57.com">Jason Dillon</a>
40  */

41 public class MethodBoundPropertyListener
42    extends BoundPropertyAdapter
43 {
44    /** Property name which we are bound to */
45    protected final String JavaDoc propertyName;
46
47    /** Instance object that contains setter method */
48    protected final Object JavaDoc instance;
49
50    /** Property setter method */
51    protected final Method JavaDoc setter;
52
53    /** Property descriptor */
54    protected final PropertyDescriptor JavaDoc descriptor;
55
56    /**
57     * Construct a MethodBoundPropertyListener.
58     *
59     * @param instance Instance object that contains setter method.
60     * @param propertyName The name of the property which will be bound.
61     * @param beanPropertyName The name of the property setter method.
62     *
63     * @throws PropertyException
64     */

65    public MethodBoundPropertyListener(final Object JavaDoc instance,
66                                       final String JavaDoc propertyName,
67                                       final String JavaDoc beanPropertyName)
68    {
69       this.instance = instance;
70       this.propertyName = propertyName;
71
72       try {
73          descriptor = getPropertyDescriptor(beanPropertyName);
74          if (descriptor == null) {
75             throw new PropertyException
76                ("missing method for: " + beanPropertyName);
77          }
78
79          setter = descriptor.getWriteMethod();
80          if (setter == null) {
81             throw new PropertyException
82                ("missing setter method for: " + beanPropertyName);
83          }
84          try {
85             setter.setAccessible(true);
86          }
87          catch (SecurityException JavaDoc e) {
88             ThrowableHandler.add(e);
89          }
90       }
91       catch (IntrospectionException JavaDoc e) {
92          throw new PropertyException(e);
93       }
94    }
95
96    /**
97     * Get the <tt>PropertyDescriptor</tt> for the given bean property name.
98     *
99     * @param beanPropertyName Bean property name.
100     * @return <tt>PropertyDescriptor</tt>.
101     */

102    private PropertyDescriptor JavaDoc getPropertyDescriptor(final String JavaDoc beanPropertyName)
103       throws IntrospectionException JavaDoc
104    {
105       Class JavaDoc instanceType = instance.getClass();
106       BeanInfo JavaDoc beanInfo = Introspector.getBeanInfo(instanceType);
107       PropertyDescriptor JavaDoc descriptors[] = beanInfo.getPropertyDescriptors();
108       PropertyDescriptor JavaDoc descriptor = null;
109
110       for (int i=0; i<descriptors.length; i++) {
111          if (descriptors[i].getName().equals(beanPropertyName)) {
112             descriptor = descriptors[i];
113             break;
114          }
115       }
116
117       return descriptor;
118    }
119
120    /**
121     * Construct a MethodBoundPropertyListener.
122     *
123     * @param instance Instance object that contains setter method.
124     * @param propertyName The name of the property which will be bound.
125     */

126    public MethodBoundPropertyListener(final Object JavaDoc instance,
127                                       final String JavaDoc propertyName)
128    {
129       this(instance, propertyName, propertyName);
130    }
131
132    /**
133     * Get the property name which this listener is bound to.
134     *
135     * @return Property name.
136     */

137    public final String JavaDoc getPropertyName() {
138       return propertyName;
139    }
140
141    /**
142     * Coerce and invoke the property setter method on the instance.
143     *
144     * @param value Method value.
145     *
146     * @throws PropertyException Failed to invoke setter method.
147     */

148    protected void invokeSetter(String JavaDoc value) {
149       try {
150          // coerce value to field type
151
Class JavaDoc type = descriptor.getPropertyType();
152          PropertyEditor JavaDoc editor = PropertyEditors.findEditor(type);
153          editor.setAsText(value);
154          Object JavaDoc coerced = editor.getValue();
155          // System.out.println("type: " + type);
156
// System.out.println("coerced: " + coerced);
157

158          // invoke the setter method
159
setter.invoke(instance, new Object JavaDoc[] { coerced });
160       }
161       catch (InvocationTargetException JavaDoc e) {
162          Throwable JavaDoc target = e.getTargetException();
163          if (target instanceof PropertyException) {
164             throw (PropertyException)target;
165          }
166          else {
167             throw new PropertyException(target);
168          }
169       }
170       catch (Exception JavaDoc e) {
171          throw new PropertyException(e);
172       }
173    }
174
175    /**
176     * Notifies that a property has been added.
177     *
178     * @param event Property event.
179     */

180    public void propertyAdded(final PropertyEvent event) {
181       invokeSetter(event.getPropertyValue());
182    }
183
184    /**
185     * Notifies that a property has changed.
186     *
187     * @param event Property event.
188     */

189    public void propertyChanged(final PropertyEvent event) {
190       invokeSetter(event.getPropertyValue());
191    }
192
193    /**
194     * Notifies that this listener was bound to a property.
195     *
196     * @param map PropertyMap which contains property bound to.
197     */

198    public void propertyBound(final PropertyMap map) {
199       // only set the field if the map contains the property already
200
if (map.containsProperty(propertyName)) {
201          invokeSetter(map.getProperty(propertyName));
202       }
203    }
204 }
205
Popular Tags