Code Smarter, Not Harder, With XDoclet, Page 3
Many content tags, such as the <Xdtpackage:packageOf> tag shown at the top of the listing, provide information that is obtained through introspection of the class files being processed. In the case of the <XdtPackage:packageOf> tag, the tag processes the fully qualified class name passed into the tag to obtain the same package name as the class being processed. Information about packages, classes, method signatures, and almost anything that can be learned through introspection, can be obtained by using an Xdoclet template tag.
For the block tags, the result of the processing depends on the function of the tag. For example, the <XdtMethod:forAllMethods> tag will iterate through all methods within the current class. This is useful because the <XdtMethod:methodTagValue> template tag can then be used to extract the parameter values from each method with a @jsp:attribute tag, for example, to be used within the template.
In the case of the <XdtMethod:ifHasMethodTag> template tag, the code within the opening and closing template tag is only generated if a doclet tag matching the specified tag name and parameter name is found for the current method. Thus, methods without the tag are skipped during processing. Likewise, template tags are available that would only generate code if a method doesn't have a particular doclet tag.
Generating the Tag Documentation
To demonstrate one of the potential uses for XDoclet beyond Java code generation and creation of XML configuration files, we will generate tag documentation for each custom JSP tag within the application. For each tag, a template is used to generate that tag's documentation, and a table of contents for the entire tag library is also generated. Because we have already looked at most of the template tags used in the tagdoc.j template file in the earlier template discussion, we will not discuss it here. However, the tagdoc_toc.j template, shown below, has one interesting feature. A listing of the tagdoc_toc.j template is shown below.
<html> <head> <title>Taglib Index</title> </head> <body> <p> <table width="100%"> <XDtClass:forAllClasses> <XDtClass:ifHasClassTag tagName="jsp:tag"> <td align="left" valign="top" width="100%"> <a href="<XDtPackage:packageNameAsPath/>/ <XDtClass:className/>.html"><XDtClass:className/></a> </td> </XDtClass:ifHasClassTag> </XDtClass:forAllClasses> </table> </p> </body> </html>
The table of contents is a simple table containing hyperlinks to all of the individual tag documentation files. Unlike the TagExtraInfo template, this template only generates one output file for all of the source files being processed. The <XdtClass:forAllClasses> tag iterates through all of the source files specified in the <fileset> tag of the Ant task that invokes the template. Also, the <XDtClass:ifHasClassTag tagName="jsp:tag"> tag processes the class tags at the top of each class file, generating a table entry only for those classes with a @jsp:tag doclet tag at the class level.
Building the Application
To try XDoclet for yourself, download the sample application here and unzip it within the webapps directory of your servlet container. The application contains the following directories within the XDoclet-examples/web-inf directory.
- classes—Destination for all compiled Java classes
- doc—Javadocs directory for source code
- lib—Jar files directory
- src/java—The Java source code
- src/merge—The location of the taglib-settings.xml merge file mentioned earlier
- src/Templates—The location of the *.j template files
- src/build.xml—The Ant build file for this application
To build the project, change to the XDoclet-examples/web-inf/src directory and run Ant. You will see the three steps of XDoclet code generation executing. After the code is generated, all of the code, both generated and manually created, will be compiled to the classes directory.
After the project is built successfully, check out the generated code.
- taglib.tld—Generated taglib descriptor
- src/generated—Generated TagExtraInfo classes
- tagdocs—Tag documentation
Testing the Code
To test the application, and see that the generated code actually works, start your servlet container and click on http://localhost:8080/XDoclet-examples/index.jsp. You will see the output from the <hello> and <goodbye> tags displayed. If you are using a servlet container other than Tomcat, consult the documentation for your servlet container regarding deployment of the XDoclet-examples.war file created during the build process. The URL or port for the test link above may also be different.
Although XDoclet comes with a rich library of template tags, it is possible to extend XDoclet by creating your own template tags. To do so, you will need to extend the XDoclet.template.TemplateTagHandler class.
It might also prove useful to create your own custom Ant tasks, rather than using the <taskdef> tag to define a task each time one is needed. The <webdoclet> tag is an example of this approach. To create your own task, you will need to extend XDoclet.DocletTask, and perhaps XDoclet.DocletSubTask, if the task will require multiple steps.
Consult the XDoclet API documentation for more information on using these classes.
XDoclet is a powerful code generation tool. With the large amount of grunt work required to code EJBs and J2EE configuration files, XDoclet is a great way to save time and effort. In this article, you have seen how to generate descriptor files, code, and HTML from doclet tags. The code you can generate is limited only by your imagination.
XDoclet download: http://sourceforge.net/projects/xdoclet/
Sample Application: xdoclet-examples.zip
Ant Download: http://ant.apache.org/
J2SDK Download: http://java.sun.com/
About the Author
David Thurmond is a Sun Certified Developer with over eleven years of
software development experience. He has worked in the agriculture,
construction equipment, financial, and home improvement industries.