XDoclet is an extended Javadoc Doclet engine, which enables Attribute-Oriented Programming for Java. It's a generic Java tool that lets you create custom Javadoc @tags and based on those @tags generate source code or xml deployment descriptors using a template engine that it provides. XDoclet is a metadata driven code generation engine for Java. It generates deployment descriptors, interfaces, framework classes, and other utility classes your project requires from simple Javadoc style comments (@tags).
XDoclet parses source files and generates many artifacts like XML descriptors and source code from it. You don't have to worry about out dating deployment metadata whenever you touch the code. The deployment metadata is continuously integrated. If you have written an Enterprise Java Bean, a single EJB can consist of more than one file. With XDoclet you only maintain one of them, and rest of them are generated. In short, you dramatically reduce your development time and only concentrate on business logic by using the XDoclet utility. The focus of this article is to demonstrate how XDoclet is useful in making Struts development even faster.
XDoclet functions as a collection of Ant tasks, each with a nested set of subtasks that perform a specific type of generation.
XDoclet and Struts fit perfectly with each other. I will start explaining how; with a simple example. It's out of this article's scope to explain Struts in detail. Prior knowledge of Struts is required in order to understand this article.
You have a GUI form which has a few input fields. When you use Struts, you will need a form bean with getter and setter methods for each input field, a JSP page which uses Struts tag libraries to build an UI (HTML form), and action which routes the submitted form.
The heart of the Struts framework, which binds all of the
above components together, is the struts-config.xml file.
Struts-config.xml is nothing but a deployment descriptor
that includes classname mappings of all the form beans in
the software, the mappings of URI's to Struts Action classes
and also forwarding JSP pages. Following is the snippet
of how struts-config.xml will look like:
<form-beans>
<form-bean name="searchForm"
type="com.ui.actionform.SearchForm" />
</form-beans>
You must be thinking this is damn easy to create manually.
(Remember anything manual is not error-prone in software
industry). They're are more than a few issues to consider
when you create above code by hand. What happens if beans
are removed from software? You would have to remove them
manually from the struts-config.xml file. What happens when
you add new forms to the software? You would have to add
them manually in struts-config.xml. What happens if you
move SearchForm to a different package? You will end up
editing struts-config.xml manually and specify new path.
Here where XDoclet comes into picture. Following is the
code for SearchForm.java
import org.apache.struts.validator.ValidatorForm;
/**
* Search query entry form.
*
* @struts.form name="searchForm"
*/
public class SearchForm extends ValidatorForm{
private String query;
/**
* Sets the query attribute
of the SearchForm object
*
* @struts.validator type="required"
msgkey="query.required"
*/
public void setQuery(String query){
this.query
= query;
}
public String getQuery(){
return query;
}
}
We just put the custom @tag in the class-level Javadoc comments
like the one shown in the above example. Just by simply
putting the @tag Javadoc comment, our code now tells XDoclet
engine to generate form bean definition and XDoclet does
the remaining.
Also, make a note of the @tag Javadoc comment before setQuery() method in the class. @struts.validator type="required" msgkey="query.required". This tag will generate validation.xml validation file for struts. Which saves your time even in generating validation.xml file.
Now let's see how it generates Action mappings automatically
in struts-config.xml from @tags of Action subclasses.
import java.io.IOException;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionForm;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/** @struts.action name="searchForm" path="/searchUser"
* scope="request"
* validate="false" parameter="action"
input="mainMenu"
*
* @struts.action-forward name="success"
path="/next.jsp"
*/
public class SearchAction extends Action{
public ActionForward
execute(ActionMapping mapping,ActionForm form,HttpServletRequest
request, HttpServletResponse response) throws IOException,ServletException{
return mapping.findForward("success");
}
}
Above Java code explains how to put @tag at class-level in Action file to generate action mappings automatically while XDoclet generates struts-config.xml.
Now you will need to know what modification you need to make in your build file build.xml, in order to use XDoclet tasks. First of all download XDoclet from www. XDoclet.org and also Ant version 1.5.3 or later (In attached code I have used ant version 1.6).
Following section will explain how XDoclet generates struts-config.xml
and validation.xml files.
You have to specify directory path for required jar files
while executing build file.
<taskdef name="webdoclet"
classname="Xdoclet.modules.web.WebDocletTask"
classpathref="xdocpath">
</taskdef>
<webdoclet destdir="WEB-INF"
mergedir="metadata/web" excludedtags="@version,@author"
verbose="true">
<fileset
dir="WEB-INF/src">
<include
name="**/*Form.java" />
<include
name="**/*Action.java" />
<include
name="**/*Servlet.java" />
</fileset>
<deploymentdescriptor
validatexml="true"
servletspec="2.3"
sessiontimeout="60"
destdir="WEB-INF"
distributable="false">
</deploymentdescriptor>
<strutsconfigxml
validatexml="true" version="1.1"/>
<strutsvalidationxml/>
</webdoclet>
<webdoclet/>: This task allows you to generate various
web-related files using nested subtasks and template files.
In above snippet I am also generating web.xml for Servlet.
<strutsconfigxml />: The <strutsconfigxml />
subtask is a subtask of the <webdoclet/> task. It
parses the source directories for Action and Form classes
that contain @struts: tags and generates a struts-config.xml
based on that data. It also relies on merging for additional
global config options.
Also with <strutsform/> subtask you can generate form
beans from entity beans.
The same information is coded in the source code and deployment
descriptors, requires developers to perform maintenance
on multiple files, which is completely not acceptable in
software industry. In this article I exemplified how DRY
(Don't Repeat Yourself) principle can be implemented. Now
contentedly you can say that you have dramatically reduced
your development time and rationalized development process.
About the Author
|
Vikas Pandya is a Sun-certified
Java software engineer. He has several years of extensive
hands-on experience on Java, XML, Webservices technologies. He currently works as J2EE,XML/XSL engineer for Framework Inc. in New York.He writes articles on Java, XML and related technologies for different web-sites. He has a passion of exploring new technologies. Contact him at vikasdp@yahoo.com. |
![]() |