KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > xdoclet > tagshandler > PropertyTagsHandler


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

5 package xdoclet.tagshandler;
6
7 import java.util.*;
8
9 import org.apache.commons.logging.Log;
10
11 import xjavadoc.*;
12
13 import xdoclet.XDocletException;
14 import xdoclet.util.LogUtil;
15
16 /**
17  * Tags relating to properties. Properties are identified by javabean-style naming of getters & setters.
18  *
19  * @author <a HREF="mailto:d_jencks@users.sourceforge.net">David Jencks</a>
20  * @created Wed Feb 27 21:53:15 2002
21  * @xdoclet.taghandler namespace="Property"
22  * @version $Revision: 1.13 $
23  */

24 public class PropertyTagsHandler extends AbstractProgramElementTagsHandler
25 {
26     /**
27      * Searches for the XMethod of the method with name methodName and returns it. Copied from MethodTagsHandler
28      *
29      * @param methodName The method to search for
30      * @return The matching XMethod or null if not found
31      */

32     public static XMethod getXMethodForMethodName(String JavaDoc methodName)
33     {
34         return getXMethodForMethodName(methodName, false);
35     }
36
37     /**
38      * Searches for the XMethod of the method with name methodName and returns it. Copied from MethodTagsHandler
39      *
40      * @param methodName The method to search for
41      * @param superclasses Whether to also search superclasses
42      * @return The matching XMethod or null if not found
43      */

44     public static XMethod getXMethodForMethodName(String JavaDoc methodName, boolean superclasses)
45     {
46         if (methodName != null) {
47             return extractXMethod(getCurrentClass(), methodName, superclasses);
48         }
49
50         return null;
51     }
52
53     /**
54      * Extracts the <code>XMethod</code> from the specified <code>XClass</code>.
55      *
56      * @param clazz the class to search
57      * @param methodName the method name to look for
58      * @param superclasses <code>true</code> if super classes are to be searched; <code>false</code> otherwise
59      * @return the <code>XMethod</code> or <code>null</code> if it wasn't found
60      */

61     private static XMethod extractXMethod(XClass clazz, String JavaDoc methodName, boolean superclasses)
62     {
63         Collection methods = clazz.getMethods();
64
65         for (Iterator i = methods.iterator(); i.hasNext(); ) {
66             XMethod method = (XMethod) i.next();
67
68             if (method.getName().equals(methodName)) {
69                 return method;
70             }
71         }
72
73         if (superclasses) {
74             if (clazz.getSuperclass() != null) {
75                 return extractXMethod(clazz.getSuperclass(), methodName, superclasses);
76             }
77         }
78
79         return null;
80     }
81
82     /**
83      * Evaluates the body block for each property of current mbean. You may set whether superclasses are examined also
84      * with the superclass attribute. Finds properties with getter, setter, or both. The getter and setter should have
85      * javabean naming convention. Only methods with the supplied tag are considered in looking for properties.
86      *
87      * @param template The body of the block tag
88      * @param attributes The attributes of the template tag
89      * @exception XDocletException Description of Exception
90      * @doc.tag type="block"
91      * @doc.param name="superclasses" optional="true" values="true,false" description="Include
92      * properties of superclasses. True by default."
93      * @doc.param name="tagName" optional="false" description="The required tag for methods to be
94      * considered a getter or setter. For example, jmx.managed-attribute."
95      * @todo i18n
96      */

97     public void forAllPropertiesWithTag(String JavaDoc template, Properties attributes) throws XDocletException
98     {
99         Log log = LogUtil.getLog(PropertyTagsHandler.class, "forAllPropertiesWithTag");
100
101         log.debug("in forAllPropertiesWithTag");
102
103         String JavaDoc requiredTag = attributes.getProperty("tagName");
104
105         if (requiredTag == null) {
106             throw new XDocletException("missing required tag parameter in forAllPropertiesHavingTag");
107         }
108
109         XClass oldClass = getCurrentClass();
110         XClass superclass = null;
111         Collection already = new ArrayList();
112
113         // loop over superclasses
114
do {
115             XMethod oldCurrentMethod = getCurrentMethod();
116
117             Collection methods = getCurrentClass().getMethods();
118
119             for (Iterator j = methods.iterator(); j.hasNext(); ) {
120                 XMethod currentMethod = (XMethod) j.next();
121
122                 log.debug("looking at method " + currentMethod.getName());
123                 if (currentMethod.getDoc().hasTag(requiredTag)) {
124                     setCurrentMethod(currentMethod);
125
126                     String JavaDoc propertyName = currentMethod.getPropertyName();
127
128                     log.debug("property identified " + propertyName);
129
130                     if (!already.contains(propertyName)) {
131                         generate(template);
132
133                         already.add(propertyName);
134                     }
135                 }
136
137                 setCurrentMethod(oldCurrentMethod);
138             }
139             // Add super class info
140
superclass = getCurrentClass().getSuperclass();
141
142             if (superclass != null) {
143                 pushCurrentClass(superclass);
144             }
145
146         } while (superclass != null);
147
148         setCurrentClass(oldClass);
149     }
150
151     /**
152      * The block tag <code>ifHasGetMethodWithTag</code> looks for a get method based on the attribute name from the
153      * current method, sets the current method to that get method, and applies the template if found. This is used to
154      * look for getters for mbean managed attributes. The get method found may be the current method.
155      *
156      * @param template The body of the block tag
157      * @param attributes The attributes of the template tag
158      * @exception XDocletException if an error occurs
159      * @doc.tag type="block"
160      * @doc.param name="tagName" optional="false" description="The required tag for methods to be
161      * considered a getter or setter. For example, jmx.managed-attribute."
162      */

163     public void ifHasGetMethodWithTag(String JavaDoc template, Properties attributes) throws XDocletException
164     {
165         XMethod getMethod = getGetMethodWithTag(attributes);
166
167         if (getMethod != null) {
168             XMethod oldMethod = getCurrentMethod();
169
170             setCurrentMethod(getMethod);
171             try {
172                 generate(template);
173             }
174             finally {
175                 setCurrentMethod(oldMethod);
176             }
177         }
178     }
179
180     /**
181      * The block tag <code>ifHasSetMethodWithTag</code> looks for a set method based on the attribute name from the
182      * current method, sets the current method to that set method, and applies the template if found. This is used to
183      * look for setters for mbean managed attributes. The set method found may be the current method.
184      *
185      * @param template The body of the block tag
186      * @param attributes The attributes of the template tag
187      * @exception XDocletException if an error occurs
188      * @doc.tag type="block"
189      * @doc.param name="tagName" optional="false" description="The required tag for methods to be
190      * considered a getter or setter. For example, jmx.managed-attribute."
191      */

192     public void ifHasSetMethodWithTag(String JavaDoc template, Properties attributes) throws XDocletException
193     {
194         XMethod setMethod = getSetMethodWithTag(attributes);
195
196         if (setMethod != null) {
197             XMethod oldMethod = getCurrentMethod();
198
199             setCurrentMethod(setMethod);
200
201             try {
202                 generate(template);
203             }
204             finally {
205                 setCurrentMethod(oldMethod);
206             }
207         }
208     }
209
210     /**
211      * The <code>propertyTypeWithTag</code> method figures out the type for the current property with tag by looking for
212      * a getter, then a setter.
213      *
214      * @param attributes a <code>Properties</code> value including the tagName required.
215      * @return the <code>String</code> fully qualified name of the property type.
216      * @exception XDocletException if an error occurs
217      * @doc.tag type="content"
218      * @doc.param name="tagName" optional="false" description="The required tag for methods to be
219      * considered a getter or setter. For example, jmx:managed-attribute."
220      * @todo i18n
221      */

222     public String JavaDoc propertyTypeWithTag(Properties attributes) throws XDocletException
223     {
224         XMethod getter = getGetMethodWithTag(attributes);
225
226         if (getter != null) {
227             return MethodTagsHandler.getMethodTypeFor(getter);
228         }
229
230         XMethod setter = getSetMethodWithTag(attributes);
231
232         if (setter != null) {
233             XParameter parameter = (XParameter) setter.getParameters().iterator().next();
234
235             return parameter.getType().getQualifiedName();
236         }
237         throw new XDocletException("no current property found for method " + getCurrentMethod().getName());
238     }
239
240
241     /**
242      * Looks for a get or set method with the required tag for the current property that also has the requested
243      * parameter, and returns the value of the requested parameter if present.
244      *
245      * @param attributes The attributes of the template tag
246      * @return Description of the Returned Value
247      * @exception XDocletException Description of Exception
248      * @doc.tag type="content"
249      * @doc.param name="tagName" optional="false" description="The tag name required for a getter or
250      * setter to belong to a property."
251      * @doc.param name="paramName" description="The parameter name. Required for property parameter
252      * values. content of the tag is returned."
253      * @doc.param name="default" description="The default value is returned if there is no value for
254      * the parameter requested.
255      */

256     public String JavaDoc paramValueWithTag(Properties attributes) throws XDocletException
257     {
258
259         XMethod oldMethod = getCurrentMethod();
260
261         XMethod getter = getGetMethodWithTag(attributes);
262
263         if (getter != null) {
264             setCurrentMethod(getter);
265
266             String JavaDoc value = delimit(getTagValue(attributes, FOR_METHOD), attributes);
267
268             if (value != null) {
269                 setCurrentMethod(oldMethod);
270                 return value;
271             }
272             // end of if ()
273
}
274
275         XMethod setter = getSetMethodWithTag(attributes);
276
277         if (setter != null) {
278             setCurrentMethod(setter);
279
280             String JavaDoc value = delimit(getTagValue(attributes, FOR_METHOD), attributes);
281
282             if (value != null) {
283                 setCurrentMethod(oldMethod);
284                 return value;
285             }
286             // end of if ()
287
}
288         setCurrentMethod(oldMethod);
289         return attributes.getProperty("default");
290     }
291
292     /**
293      * Determines if there is a get or set method with the required tag for the current property that also has the
294      * requested parameter.
295      *
296      * @param attributes The attributes of the template tag
297      * @param template The body of the block tag
298      * @exception XDocletException Description of Exception
299      * @doc.tag type="block"
300      * @doc.param name="tagName" optional="false" description="The tag name required for a getter or
301      * setter to belong to a property."
302      * @doc.param name="paramName" description="The parameter name. Required for property parameter
303      * values. content of the tag is returned."
304      */

305     public void ifHasParamWithTag(String JavaDoc template, Properties attributes) throws XDocletException
306     {
307
308         XMethod oldMethod = getCurrentMethod();
309
310         XMethod getter = getGetMethodWithTag(attributes);
311
312         if (getter != null) {
313             setCurrentMethod(getter);
314
315             boolean value = hasTag(attributes, FOR_METHOD);
316
317             if (value) {
318                 setCurrentMethod(oldMethod);
319                 generate(template);
320                 return;
321             }
322
323         }
324
325         XMethod setter = getSetMethodWithTag(attributes);
326
327         if (setter != null) {
328             setCurrentMethod(setter);
329
330             boolean value = hasTag(attributes, FOR_METHOD);
331
332             if (value) {
333                 setCurrentMethod(oldMethod);
334                 generate(template);
335                 return;
336             }
337         }
338         setCurrentMethod(oldMethod);
339     }
340
341
342     /**
343      * Gets the GetMethodWithTag attribute of the PropertyTagsHandler object
344      *
345      * @param attributes The attributes of the template tag
346      * @return The GetMethodWithTag value
347      * @exception XDocletException Describe the exception
348      * @todo i18n
349      */

350     private XMethod getGetMethodWithTag(Properties attributes) throws XDocletException
351     {
352         String JavaDoc requiredTag = attributes.getProperty("tagName");
353
354         if (requiredTag == null) {
355             throw new XDocletException("missing required tag parameter in forAllPropertiesHavingTag");
356         }
357
358         XMethod currentMethod = getCurrentMethod();
359
360         if (currentMethod.getName().startsWith("get") || currentMethod.getName().startsWith("is")) {
361             if (currentMethod.getDoc().hasTag(requiredTag)) {
362                 return currentMethod;
363             }
364
365             return null;
366         }
367
368         String JavaDoc attributeName = MethodTagsHandler.getMethodNameWithoutPrefixFor(currentMethod);
369         XMethod getter = getXMethodForMethodName("get" + attributeName);
370
371         if (getter != null) {
372             if (getter.getDoc().hasTag(requiredTag)) {
373
374                 return getter;
375             }
376
377             return null;
378         }
379         getter = getXMethodForMethodName("is" + attributeName);
380
381         // not too safe.. should check it's boolean.
382
if (getter != null && getter.getDoc().hasTag(requiredTag)) {
383             return getter;
384         }
385         return null;
386     }
387
388     /**
389      * Gets the SetMethodWithTag attribute of the PropertyTagsHandler object
390      *
391      * @param attributes The attributes of the template tag
392      * @return The SetMethodWithTag value
393      * @exception XDocletException Describe the exception
394      * @todo i18n
395      */

396     private XMethod getSetMethodWithTag(Properties attributes) throws XDocletException
397     {
398         String JavaDoc requiredTag = attributes.getProperty("tagName");
399
400         if (requiredTag == null) {
401             throw new XDocletException("missing required tag parameter in forAllPropertiesHavingTag");
402         }
403
404         XMethod currentMethod = getCurrentMethod();
405
406         if (currentMethod.getName().startsWith("set")) {
407             if (currentMethod.getDoc().hasTag(requiredTag)) {
408                 return currentMethod;
409             }
410
411             return null;
412         }
413
414         String JavaDoc attributeName = MethodTagsHandler.getMethodNameWithoutPrefixFor(currentMethod);
415         XMethod setter = getXMethodForMethodName("set" + attributeName);
416
417         if (setter != null && setter.getDoc().hasTag(requiredTag)) {
418             return setter;
419         }
420
421         return null;
422     }
423 }
424
Popular Tags