KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > uitags > tagutil > bean > TagBeanInfo


1 /**
2  * Nov 12, 2004
3  *
4  * Copyright 2004 uitags
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */

18 package net.sf.uitags.tagutil.bean;
19
20 import java.beans.IntrospectionException JavaDoc;
21 import java.beans.PropertyDescriptor JavaDoc;
22 import java.beans.SimpleBeanInfo JavaDoc;
23 import java.lang.reflect.Method JavaDoc;
24 import java.util.ArrayList JavaDoc;
25 import java.util.Iterator JavaDoc;
26 import java.util.List JavaDoc;
27
28 import org.apache.commons.logging.Log;
29 import org.apache.commons.logging.LogFactory;
30
31 /**
32  * Provides explicit JavaBean information about a particular tag handler.
33  * Tag handlers whose JavaBean properties are to be explicitly
34  * described should have a <code>BeanInfo</code> class defined.
35  * It's enough to simply have such <code>BeanInfo</code> class extend
36  * this class without providing further implementation, leaving the child
37  * class empty. The name of the child class must be the same as the name of
38  * the tag handler it describes and end with the string "BeanInfo".
39  *
40  * @see #getPropertyDescriptors()
41  * @author jonni
42  * @version $Id$
43  */

44 public abstract class TagBeanInfo extends SimpleBeanInfo JavaDoc {
45   ///////////////////////////////
46
////////// Constants //////////
47
///////////////////////////////
48

49   /**
50    * The number of characters in the string "BeanInfo": 8!
51    */

52   private static final int BEANINFO_CHAR_COUNT = 8;
53
54   /**
55    * The string that prefixes the name of setter methods.
56    */

57   private static final String JavaDoc SETTER_PREFIX = "set";
58
59   /**
60    * The length of <code>SETTER_PREFIX</code>.
61    */

62   private static final int SETTER_PREFIX_LENGTH = SETTER_PREFIX.length();
63
64   /**
65    * How many parameters does a setter method have?
66    */

67   private static final int SETTER_PARAM_COUNT = 1;
68
69
70
71   ////////////////////////////
72
////////// Fields //////////
73
////////////////////////////
74

75   /**
76    * Logger
77    */

78   private static Log log = LogFactory.getLog(TagBeanInfo.class);
79
80
81
82   //////////////////////////////////
83
////////// Constructors //////////
84
//////////////////////////////////
85

86   /**
87    * Default constructor.
88    */

89   public TagBeanInfo() {
90     super();
91   }
92
93
94
95   ////////////////////////////////////////
96
////////// Overridden methods //////////
97
////////////////////////////////////////
98

99   /**
100    * Exposes only the setter methods. This is necessary to hide tag
101    * handlers' <code>Object.getClass</code> method. Without this, it's
102    * impossible to have a tag attribute called "class".
103    *
104    * @return descriptor for the setter methods
105    */

106   // This implementation depends on {@link #getTagHandlerSetters()} to
107
// get a list of <code>Method</code>s to convert to
108
// <code>PropertyDescriptor</code>s.
109
public final PropertyDescriptor JavaDoc[] getPropertyDescriptors() {
110     List JavaDoc methods = getTagHandlerSetters();
111
112     List JavaDoc props = new ArrayList JavaDoc();
113     for (Iterator JavaDoc i = methods.iterator(); i.hasNext(); ) {
114       props.add(createPropertyDescriptor((Method JavaDoc) i.next()));
115     }
116
117     if (log.isDebugEnabled()) {
118       log.debug("Property descriptors: '" + props + "'.");
119     }
120
121     return (PropertyDescriptor JavaDoc[])
122        props.toArray(new PropertyDescriptor JavaDoc[props.size()]);
123   }
124
125
126
127   ////////////////////////////////////
128
////////// Helper methods //////////
129
////////////////////////////////////
130

131   /**
132    * Returns setter methods of the tag handler.
133    *
134    * @return setter methods of the tag handler (list of <code>Method</code>s)
135    * @throws RuntimeException if the tag handler class was not found
136    */

137   List JavaDoc getTagHandlerSetters() {
138     String JavaDoc beanInfoClassName = getClass().getName();
139
140     // Name of the tag handler is without the trailing "BeanInfo" string
141
String JavaDoc tagHandlerClassName = beanInfoClassName.substring(
142         0, beanInfoClassName.length() - BEANINFO_CHAR_COUNT);
143
144     Class JavaDoc tagHandlerClass;
145     try {
146       tagHandlerClass = Class.forName(tagHandlerClassName);
147     }
148     catch (ClassNotFoundException JavaDoc e) {
149       throw new RuntimeException JavaDoc(e);
150     }
151
152     Method JavaDoc[] methods = tagHandlerClass.getMethods();
153     List JavaDoc setters = new ArrayList JavaDoc();
154     for (int i = 0; i < methods.length; i++) {
155       if (isSetter(methods[i])) {
156         setters.add(methods[i]);
157       }
158     }
159
160     return setters;
161   }
162
163   /**
164    * Returns <code>true</code> if the supplied method is a setter method.
165    *
166    * @param method the method to test
167    * @return <code>true</code> if the supplied method is a setter method,
168    * <code>false</code> otherwise
169    */

170   private boolean isSetter(Method JavaDoc method) {
171     String JavaDoc methodName = method.getName();
172     return methodName.length() > SETTER_PREFIX_LENGTH &&
173         methodName.startsWith(SETTER_PREFIX) &&
174         Character.isUpperCase(methodName.charAt(SETTER_PREFIX_LENGTH)) &&
175         method.getParameterTypes().length == SETTER_PARAM_COUNT;
176   }
177
178   /**
179    * Returns a property descriptor for the given <i>setter</i> method.
180    *
181    * @param setterMethod the setter method for which a property descriptor is
182    * to be created
183    * @return a property descriptor for the supplied method
184    * @throws RuntimeException if introspection failed
185    */

186   private PropertyDescriptor JavaDoc createPropertyDescriptor(Method JavaDoc setterMethod) {
187     String JavaDoc methodName = setterMethod.getName();
188     String JavaDoc propName = String.valueOf(
189         Character.toLowerCase(methodName.charAt(SETTER_PREFIX_LENGTH))) +
190         methodName.substring(SETTER_PREFIX_LENGTH + 1);
191     try {
192       return new PropertyDescriptor JavaDoc(propName, null, setterMethod);
193     }
194     catch (IntrospectionException JavaDoc e) {
195       throw new RuntimeException JavaDoc(e);
196     }
197   }
198 }
Popular Tags