Struts + XDoclet (webdoclet) and integration with Eclipse

XDoclet is a tool that proclaims the DRY (Don’t Repeat Yourself) principle: you code everything in one file once, as opposed to the practice of modern software development, where information & tokens must be repeated in executable code, configuration files as well as deployment descriptors (of course, this has not been invented to hamper us, but allows for greater flexibility in deployment and portability).

Examples of such technologies include e.g. Struts (struts-config.xml and Java source code), Hibernate (POJOs and mapping files), or EJBS (interfaces (local/remote), implementation and deployment descriptors).

Without a code generation tool such as Xdoclet, such technologies quickly become a maintenance nightmare at best, and unworkable at worse. If you are (rather) new to XDoclet, you are referred to my previous post on Attribute-Oriented programming.

In this post, we focus on the use of XDoclet in the Struts framework. The XDoclet module that is used in this case is webdoclet, which can also be employed for other model 2 (that is, MVC-based) frameworks such as WebWork. Finally, we show how to use Xdoclet in Eclipse. Although webdoclet and Struts are paid attention to in particular, this tutorial should get you started employing Xdoclet proficiently in Eclipse in general, using the generic Xdoclet capabilities offered by the JBoss-IDE plug-in.

XDoclet and Struts

Let us now focus on the Struts specific artifacts that need to be generated. These include the web.xml, the struts-config.xml and the validation.xml.

First the web.xml file. The Struts controller servlet (StrutsActionServlet) needs to be put in the web.xml, as well as the corresponding servlet mapping entry. The nice thing is that the Struts framework provided the implementation for this controller servlet for us, but the drawback is that we cannot place a @struts.tag in the code anymore.

This problem is solved by making use of the so-called merge points of webdoclet. At predefined places in the generation procedure, pieces of generic code can be merged into the generation process. The code is generic in the sense that it does not belong to a particular class, method or field, hence it couldn’t be put in the Java sources at a logical place/xdoclet tag.

The merge points defined for the generation of web.xml can be found on XDoclet’s home location. By the way, all the files to be used in the merge process reside in the “merge dir”, to be specified in the build.xml. The names of these files determine their “merge point” during the code generation process.

There are also merge points that are specific to the struts-config.xml file. Typically, these merge points are used to define global forwards, global exceptions, a controller element, message resource elements, and plug-in elements. For the sake of completeness, I re-list the table I found on the Internet, containing the XDoclet Struts Config merge files:

  • struts-data-sources.xml, an XML document containing the optional data-sources element.
  • struts-forms.xml, an XML unparsed entity containing form-bean elements, for additional non-XDoclet forms.
  • global-exceptions.xml, an XML document containing the optional global-exceptions element.
  • global-forwards.xml, an XML document containing the optional global-forwards element.
  • struts-actions.xml, an XML unparsed entity containing action elements, for additional non-XDoclet actions.
  • struts-controller.xml, an XML document containing the optional controller element.
  • struts-message-resources.xml, an XML unparsed entity containing any message-resources elements.
  • struts-plugins.xml, an XML unparsed entity containing any plug-in elements.

In addition to these merge points, we can make use of Xdoclet tags. For example, the class-scope @struts.action-tag enables us to associate an struts-config.xml action to a class as follows:

/**
 * @struts.action
 *    name="submitForm"
 *    path="/submitData"
 *    scope="request"
 *    validate="false"
 *    parameter="action"
 *    input="pages/inputPage.jsp"
 *
 * @struts.action-exception
 *    type="nl.amis.package.exception.ApplicationException"
 *    key="app.exception"
 *    path="pages/error.jsp"
 *
 * @struts.action-forward
 *    name="success"
 *    path="pages/next.jsp"
 */
public class SubmitAction extends Action
{
    public ActionForward execute(
        ActionMapping mapping,
        ActionForm form,
        HttpServletRequest request,
        HttpServletResponse response) throws IOException, ServletExceptioni
    {
        return mapping.findForward("success");
    }
}

The corresponding ActionForm could look like

/**
 * @author zeger
 *
 * @struts.form
 *     name="nl.amis.package.form.SubmitForm"
 */
public class SubmitForm extends ActionForm
{
    private String name;
    private String email;

    public String getEmail()
    {
        return email;
    }

    /**
     * @struts.validator
     *     type="required"
     *
     * @struts.validator
     *     type="email"
     */
    public void setEmail(String email)
    {
        this.email = email;
    }

    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
    }
}

For more info on Struts specific tags, the reader is referred to the references at the end of this post.

In the following it will be shown how to invoke the webdoclet module to generate the configuration files from Ant and Eclipse, the latter using the JBoss-IDE plug-in.

2 Comments

  1. viralpatel December 9, 2008
  2. Pingback: Credit Report Offers April 26, 2007
  3. Pingback: Tripods For Less April 24, 2007
  4. Pingback: Debt Consultation April 22, 2007
  5. Nagendra April 19, 2006