Cooking with Java XP, Part 3
Pages: 1, 2
9.8 Creating and Executing a Custom Template
Problem
You want to write and execute a custom XDoclet template file (.xdt).
Solution
Create an .xdt file that contains the necessary
XDoclet template tags to generate the desired output. Finally, update
your Ant buildfile to execute the template subtask
via the xdoclet.DocletTask task.
Discussion
Using XDoclet to generate EJB files is fairly straightforward because the templates are already written. The challenge occurs when you want to create a custom template to generate a specific file. Knowing where to look up information on custom templates and deciphering that information can be a difficult task.
XDoclet templates are at the core of XDoclet's extensibility, and XDoclet provides a plethora of built-in template tags for us to use. Template tags control how and what information is generated. Template tags are broken down into two categories, block and content.
Block
Block tags are used for iterating and
performing logic, which is synonymous with for
loops and if statements. The snippet below shows
how to iterate through all classes using the built-in
Class template tag:
<XDtClass:forAllClasses>
</XDtClass:forAllClasses>
The next snippet shows how to check if a method contains a specific
@ tag using the built-in Method
template tag. In this example we are checking for
"deprecated":
<XDtMethod:ifHasMethodTag tagName="deprecated">
</XDtMethod:ifHasMethodTag>
Content
Content tags are used for outputting
information. These tags are synonymous with getter methods that
return a string. Content tags never contain nested information. The
snippet below shows how to output the current method name using the
built-in Method template tag.
<XDtMethod:methodName/>
A template tag is very similar to an XML tag. The first part of the
tag represents the namespace. For example,
XDtMethod is a namespace. The part directly after
the namespace represents the tag name. For example,
methodName is a tag name. By convention all
namespaces begin with "XDt". This
prefix is not directly part of the namespace and is stripped off by
XDoclet when the template is being parsed.
Now, let's delve into creating a custom template.
Example 9-9 shows a custom template used to generate
a code-deprecation report. The custom template uses template tags
defined by XDoclet. The first step is to create a new template file
and add it to your project. This recipe creates a new template file
called deprecation-report.xdt and places it in
the resources directory. This template generates
a report of all classes and methods marked as deprecated. Take note
that the tagName attribute omits the @
character.
Example 9-9. deprecation-report.xdt template file
Deprecated Classes and Methods
------------------------------
<XDtClass:forAllClasses>
+++ <XDtClass:fullClassName/>
<XDtClass:ifHasClassTag tagName="deprecated">
WARNING: This class is deprecated.
NOTE: <XDtClass:classTagValue tagName="deprecated"/>
</XDtClass:ifHasClassTag>
<XDtClass:ifDoesntHaveClassTag tagName="deprecated">
DEPRECATED METHODS
------------------
<XDtMethod:forAllMethods>
<XDtMethod:ifHasMethodTag tagName="deprecated">
METHOD: <XDtMethod:methodName/>(<XDtParameter:parameterList/>)
NOTE: <XDtMethod:methodTagValue tagName="deprecated"/>
</XDtMethod:ifHasMethodTag>
</XDtMethod:forAllMethods>
</XDtClass:ifDoesntHaveClassTag>
</XDtClass:forAllClasses>
Example 9-10 shows an updated Ant buildfile that executes the new template.
Example 9-10. Executing a custom template
<target name="deprecation.report"
description="Generates a Deprecation Report."
depends="prepare">
<taskdef name="deprecateddoclet" classname="xdoclet.DocletTask">
<classpath>
<pathelement path="${env.XDOCLET_HOME}/lib/xdoclet.jar"/>
<pathelement path="${env.XDOCLET_HOME}/lib/xjavadoc.jar"/>
<pathelement location="${dir.lib}/commons-logging-1.0.jar"/>
</classpath>
</taskdef>
<deprecateddoclet
destdir="${dir.build}">
<fileset dir="${dir.src}">
<include name="**/deprecation/"/>
</fileset>
<template
templateFile="${dir.build}/${deprecation.template}"
destinationFile="deprecation-report.txt"/>
</deprecateddoclet>
</target>
The first step is to set up a task definition called
deprecateddoclet for the class
xdoclet.DocletTask. The
DocletTask is the base class for all Ant XDoclet
tasks. This class can be used directly to execute a custom template
file when a subclass is not required.
The fileset specifies which files should be
included or excluded from the generation process.
Finally, the template subtask specifies which
template file to use and the name of the file to generate.
This subtask is used to apply generic
templates (in this example it is the template file
deprecation-report.xdt) to produce any type of
text output.
Here is what an example report might look like:
Deprecated Classes and Methods
------------------------------
+++ com.oreilly.javaxp.xdoclet.deprecation.Employee
DEPRECATED METHODS
------------------
METHOD: getEmployeeId( )
NOTE: use {@link #getId}.
METHOD: setEmployeeId(long)
NOTE: use {@link #setId}.
+++ com.oreilly.javaxp.xdoclet.deprecation.Person
WARNING: This class is deprecated.
NOTE: No replacement for this class.
See Also
The tags used in this recipe only scratch the surface of what XDoclet provides. For a complete listing of all XDoclet template tags, see http://xdoclet.sourceforge.net/1.2beta/templates/index.html.
Eric M. Burke is an O'Reilly author and a principal software engineer with Object Computing, Inc. in St. Louis, MO.
Brian M. Coyner is coauthor of the Java Extreme Programming Cookbook and a Senior Software Engineer with Object Computing, Inc. in St. Louis, Missouri.
Return to ONJava.com.