KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > xdoclet > modules > java > javabean > JavaBeanTagsHandler


1 /*
2  * Copyright (c) 2001, 2002 The XDoclet team
3  * All rights reserved.
4  */

5 package xdoclet.modules.java.javabean;
6
7 import java.beans.Introspector JavaDoc;
8 import java.text.MessageFormat JavaDoc;
9 import java.util.Properties JavaDoc;
10
11 import org.apache.commons.collections.Predicate;
12 import org.apache.commons.logging.Log;
13 import xjavadoc.XClass;
14 import xjavadoc.XMethod;
15 import xjavadoc.XParameter;
16 import xjavadoc.XTag;
17 import xjavadoc.XType;
18
19 import xdoclet.XDocletException;
20 import xdoclet.XDocletTagSupport;
21 import xdoclet.util.LogUtil;
22
23 /**
24  * Specific tags handler to make the template easy.
25  *
26  * @author Laurent Etiemble (letiemble@users.sourceforge.net)
27  * @author Ryan Ovrevik
28  * @created June 20, 2002
29  * @version $Revision: 1.5 $
30  * @xdoclet.taghandler namespace="JavaBean"
31  */

32 public class JavaBeanTagsHandler extends XDocletTagSupport
33 {
34     public static String JavaDoc getBeanInfoClassFor(XClass clazz) throws XDocletException
35     {
36         XTag beanTag = clazz.getDoc().getTag("javabean.class");
37         String JavaDoc className = null;
38
39         if (beanTag != null) {
40             // be paranoid...
41
className = beanTag.getAttributeValue("class");
42         }
43
44         if (className == null) {
45             className = clazz.getQualifiedName();
46         }
47
48         return MessageFormat.format(BeanInfoSubTask.GENERATED_BEANINFO_CLASS_NAME, new Object JavaDoc[]{className});
49     }
50
51     /**
52      * Returns true is the current method meets the minimum requirements for a property accessor. Essentially this means
53      * that it takes no arguments and does not return void. This different from XMethod.getAccessor() like functionality
54      * in that stricly speeking the XMethod is dealling stricly with the "Simple" naming convention.
55      *
56      * @param method
57      * @return
58      */

59     private static boolean isPossiblePropertyAccessor(XMethod method)
60     {
61         return (method.getParameters().size() == 0 && !method.getReturnType().getType().isA("void"));
62     }
63
64     private static boolean isPossiblePropertyAccessor(XMethod method, XType propertyType)
65     {
66         return isPossiblePropertyAccessor(method) && method.getReturnType().getType().equals(propertyType);
67     }
68
69
70     /**
71      * Returns true is the current method meets the minimum requirements for a property mutator. Essentially this means
72      * that it takes one and only one argument and returns void.
73      *
74      * @param method
75      * @return
76      */

77     private static boolean isPossiblePropertyMutator(XMethod method)
78     {
79         return (method.getParameters().size() == 1);
80     }
81
82     private static boolean isPossiblePropertyMutator(XMethod method, XType propertyType)
83     {
84         if (isPossiblePropertyMutator(method)) {
85             XParameter firstParam = (XParameter) method.getParameters().get(0);
86
87             return firstParam.getType().equals(propertyType);
88         }
89         return false;
90     }
91
92     private static boolean isExplicitlyReadOnlyProperty(XMethod method)
93     {
94         XTag tag = method.getDoc().getTag("javabean.property");
95
96         return "true".equalsIgnoreCase(tag.getAttributeValue("readonly"));
97     }
98
99
100     /**
101      * The current method must be a valid property accessor (return the property type takes not args) or mutator (return
102      * void and takes the property type as the single arg)
103      *
104      * @param method
105      * @return
106      */

107     private static XType getPropertyType(XMethod method)
108     {
109         XType result = null;
110
111         //does the method have an explicit name attribute
112
String JavaDoc name = method.getDoc().getTag("javabean.property").getAttributeValue("name");
113
114         if ((name == null) || (name.length() <= 0)) {
115             if (isPossiblePropertyMutator(method)) {
116                 XParameter parameter = (XParameter) method.getParameters().get(0);
117
118                 result = parameter.getType();
119             }
120             else if (isPossiblePropertyAccessor(method)) {
121                 result = method.getReturnType().getType();
122             }
123         }
124         else {
125             result = method.getPropertyType().getType();
126         }
127         return result;
128     }
129
130     /**
131      * Get the getter method for the current method. Will return null if this method is not a property (determined by
132      * the getPropertyName method). Will return null if this is a write only property. A property is write only if an
133      * accessor method does not exist. Attempt to find a property accessor that matches an explicitly named getter
134      * method. The named method must satisfy the requirements of a property accessor (take no params and return the
135      * correct type) The current method could be an accessor or a mutator attempt the use the current method if it
136      * satisfies Simple property accessor requirements.
137      *
138      * @param propertyName
139      * @param propertyType
140      * @param method
141      * @return the method that will serve as the getter method for this property Will return null if the
142      * current method is not a property method
143      */

144     private static XMethod getGetterMethod(final String JavaDoc propertyName, final XType propertyType, XMethod method)
145     {
146         Log log = LogUtil.getLog(JavaBeanTagsHandler.class, "getGetterMethod");
147
148         //do some parameter checking
149
if ((propertyName == null) || (propertyName.length() == 0)) {
150             log.error("invalid property name: " + propertyName);
151             return null;
152         }
153         if (propertyType == null) {
154             log.error("invalid property type: " + propertyType);
155             return null;
156         }
157         if (method == null) {
158             log.error("invalid method: " + method);
159             return null;
160         }
161
162         //get on with the real business
163
if (log.isInfoEnabled()) {
164             log.info("===find getter method===");
165             log.info("method name: " + method.getName());
166             log.info("property name: " + propertyName);
167             log.info("property type: " + propertyType);
168         }
169
170         XMethod getterMethod = null;
171
172         //attempt to find an explicitly named getter method
173
final String JavaDoc explicitMethodName = method.getDoc().getTag("javabean.property").getAttributeValue("getter");
174
175         if ((explicitMethodName != null) && (explicitMethodName.length() > 0)) {
176             //the method has an explicit attribute
177
//there must be a bean property method with the given name
178
java.util.List JavaDoc methodList = getCurrentClass().getMethods(
179                 new Predicate()
180                 {
181                     public boolean evaluate(Object JavaDoc obj)
182                     {
183                         XMethod method = (XMethod) obj;
184
185                         return isPossiblePropertyAccessor(method, propertyType) &&
186                             method.getName().equals(explicitMethodName);
187                     }
188                 }, false);
189
190             //the method name, return, and arguments are known... there can be [0, 1]
191

192             if (methodList.size() == 1) {
193                 getterMethod = (XMethod) methodList.get(0);
194                 if (log.isInfoEnabled()) {
195                     log.info("found explicit getter " + getterMethod.getName());
196                 }
197                 if (isPossiblePropertyAccessor(method, propertyType)
198                     && (getterMethod != method)) {
199                     log.warn("explicit getter " + getterMethod.getName() + " (should be passed method)");
200                 }
201             }
202             else {
203                 //they gave an explicit method name but it could not be found
204
log.warn("no explicit getter " + explicitMethodName);
205             }
206         }
207         else if (isPossiblePropertyAccessor(method, propertyType)) {
208             //this was put on the an accessor assume it was what they wanted
209
getterMethod = method;
210             log.info("using the passed method");
211         }
212         else {
213             //attempt to find the standard bean method (Simple property JavaBeans API specification 8.3.1)
214
//takes no params (isPropertyAccessor)
215
java.util.List JavaDoc methodList = getCurrentClass().getMethods(
216                 new Predicate()
217                 {
218                     public boolean evaluate(Object JavaDoc obj)
219                     {
220                         XMethod method = (XMethod) obj;
221
222                         return isPossiblePropertyAccessor(method, propertyType) &&
223                             method.getPropertyName().equals(propertyName);
224                     }
225                 }, false);
226
227             if (methodList.size() == 1) {
228                 getterMethod = (XMethod) methodList.get(0);
229                 if (log.isInfoEnabled()) {
230                     log.info("found standard getter " + getterMethod.getName());
231                 }
232             }
233             else {
234                 log.warn("no standard getter");
235             }
236         }
237         return getterMethod;
238     }
239
240     private static XMethod getSetterMethod(final String JavaDoc propertyName, final XType propertyType, XMethod method)
241     {
242         Log log = LogUtil.getLog(JavaBeanTagsHandler.class, "getSetterMethod");
243
244         //do some parameter checking
245
if ((propertyName == null) || (propertyName.length() == 0)) {
246             log.error("invalid property name: " + propertyName);
247             return null;
248         }
249         if (propertyType == null) {
250             log.error("invalid property type: " + propertyType);
251             return null;
252         }
253         if (method == null) {
254             log.error("invalid method: " + method);
255             return null;
256         }
257
258         //get on with the real business
259
XMethod setterMethod = null;
260
261         if (log.isInfoEnabled()) {
262             log.info("===find setter method===");
263             log.info("method name: " + method.getName());
264             log.info("property name: " + propertyName);
265             log.info("property type: " + propertyType);
266         }
267
268         //attempt to find an explicitly named setter method
269
final String JavaDoc explicitMethodName = method.getDoc().getTag("javabean.property").getAttributeValue("setter");
270
271         if (isExplicitlyReadOnlyProperty(method)) {
272             log.info("explicit read only");
273         }
274         else if ((explicitMethodName != null) && (explicitMethodName.length() > 0)) {
275             //the method has an explicit attribute
276
//there must be a bean property method with the given name
277
java.util.List JavaDoc methodList = getCurrentClass().getMethods(
278                 new Predicate()
279                 {
280                     public boolean evaluate(Object JavaDoc obj)
281                     {
282                         XMethod method = (XMethod) obj;
283
284                         return isPossiblePropertyMutator(method, propertyType) &&
285                             method.getName().equals(explicitMethodName);
286                     }
287                 }, false);
288
289             if (methodList.size() == 1) {
290                 setterMethod = (XMethod) methodList.get(0);
291                 if (log.isInfoEnabled()) {
292                     log.info("found explicit setter " + setterMethod.getName());
293                 }
294                 if (isPossiblePropertyMutator(method, propertyType)
295                     && (setterMethod != method)) {
296                     log.warn("explicit setter " + setterMethod.getName() + " (should be passed method)");
297                 }
298             }
299             else {
300                 //they gave an explicit method name but it could not be found
301
log.warn("no explicit setter " + explicitMethodName);
302             }
303         }
304         else if (isPossiblePropertyMutator(method, propertyType)) {
305             //this was put on a mutator assume it was what they wanted?
306
setterMethod = method;
307             log.info("using the passed method");
308         }
309         else {
310             //attempt to find the standard bean method (Simple property JavaBeans API specification 8.3.1)
311
//takes one param
312
java.util.List JavaDoc methodList = getCurrentClass().getMethods(
313                 new Predicate()
314                 {
315                     public boolean evaluate(Object JavaDoc obj)
316                     {
317                         XMethod method = (XMethod) obj;
318
319                         return isPossiblePropertyMutator(method, propertyType) &&
320                             propertyName.equals(method.getPropertyName());
321                     }
322                 }, false);
323
324             if (methodList.size() == 1) {
325                 setterMethod = (XMethod) methodList.get(0);
326                 if (log.isInfoEnabled()) {
327                     log.info("found standard setter " + setterMethod.getName());
328                 }
329             }
330             else {
331                 log.info("no standard setter (not tagged readonly)");
332             }
333         }
334         return setterMethod;
335     }
336
337     /**
338      * Return the getter prefix according to the class tag that contains a class.
339      *
340      * @param attributes XDoclet attributes
341      * @return The getter prefix
342      * @exception XDocletException Thrown in case of problem
343      */

344     public String JavaDoc getterPrefix(Properties JavaDoc attributes) throws XDocletException
345     {
346         String JavaDoc name = getTagValue(attributes, FOR_CLASS);
347
348         if ("boolean".equals(name)) {
349             return "is";
350         }
351         if ("java.lang.Boolean".equals(name)) {
352             return "is";
353         }
354         return "get";
355     }
356
357     /**
358      * Get the getter method for the current method
359      *
360      * @return
361      */

362     public String JavaDoc getGetterMethodNameQuoted()
363     {
364         XMethod currentMethod = getCurrentMethod();
365         String JavaDoc propertyName = getPropertyName(currentMethod);
366         XType propertyType = getPropertyType(currentMethod);
367
368         if (propertyName != null) {
369         }
370
371         XMethod getterMethod = getGetterMethod(propertyName, propertyType, currentMethod);
372
373
374         if (getterMethod == null) {
375             return "null";
376         }
377         else {
378             return "\"" + getterMethod.getName() + "\"";
379         }
380     }
381
382     /**
383      * Get the setter method for the current method
384      *
385      * @return
386      */

387     public String JavaDoc getSetterMethodNameQuoted()
388     {
389         XMethod currentMethod = getCurrentMethod();
390         String JavaDoc propertyName = getPropertyName(currentMethod);
391         XType propertyType = getPropertyType(currentMethod);
392
393         XMethod setterMethod = getSetterMethod(propertyName, propertyType, currentMethod);
394
395         if (setterMethod == null) {
396             return "null";
397         }
398         else {
399             return "\"" + setterMethod.getName() + "\"";
400         }
401     }
402
403     /**
404      * Get the property name for the current method xxx rlo the is fucked
405      *
406      * @return
407      */

408     public String JavaDoc getPropertyNameQuoted()
409     {
410         String JavaDoc name = getPropertyName(getCurrentMethod());
411
412         if (name == null) {
413             return "null";
414         }
415         else {
416             return "\"" + name + "\"";
417         }
418     }
419
420     /**
421      * return configured bean class name or current class name
422      *
423      * @param attributes XDoclet attributes
424      * @return The getter prefix
425      * @exception XDocletException Thrown in case of problem
426      */

427     public String JavaDoc beanClass(Properties JavaDoc attributes) throws XDocletException
428     {
429         if (getTagValue(FOR_CLASS, "javabean.class", "class", null, null, false, false) != null) {
430             return getTagValue(FOR_CLASS, "javabean.class", "class", null, null, false, false);
431         }
432         else {
433             return getCurrentClass().getQualifiedName();
434         }
435     }
436
437     /**
438      * Capitalize the first letter of a class tag (i.e countToken => CountToken)
439      *
440      * @param attributes XDoclet attributes
441      * @return The class tag capitalized
442      * @exception XDocletException Thrown in case of problem
443      */

444     public String JavaDoc capitalizeClassTag(Properties JavaDoc attributes) throws XDocletException
445     {
446         String JavaDoc name = getTagValue(attributes, FOR_CLASS);
447
448         if (name == null || name.length() == 0) {
449             return name;
450         }
451         if (name.length() > 1 && Character.isUpperCase(name.charAt(1)) &&
452             Character.isUpperCase(name.charAt(0))) {
453             return name;
454         }
455
456         char chars[] = name.toCharArray();
457
458         chars[0] = Character.toUpperCase(chars[0]);
459         return new String JavaDoc(chars);
460     }
461
462     /**
463      * Get the property name for the current method xxx rlo the is fucked
464      *
465      * @param currentMethod
466      * @return
467      */

468     private String JavaDoc getPropertyName(XMethod currentMethod)
469     {
470         String JavaDoc name = null;
471         XTag tag = currentMethod.getDoc().getTag("javabean.property");
472
473         if (tag != null) {
474             //the method is a property
475
name = tag.getAttributeValue("name");
476             //does the method have an explicit attribute
477
if ((name == null) || (name.length() <= 0)) {
478                 //figure out the name from the method
479
//must be a standard bean method
480
name = getCurrentMethod().getPropertyName();
481             }
482             else {
483                 name = Introspector.decapitalize(name);
484             }
485         }
486         return name;
487     }
488 }
489
Popular Tags