This section describes how to install and configure XMLC 2.1. See for information on the XMLC authoring model.

Installing and Configuring XMLC

Like Velocity, XMLC doesn't come with J2EE app servers (except Enhydra). Thus we need to distribute it ourselves with our app. The /lib/runtime/xmlc directory of the download contains the binaries for XMLC 2.1. XMLC requires not only supporting libraries such as GNU regular expression library, but patched versions of common products such as the Apache Xerces XML parser. This directory includes the following files:

All these files need to be included in the /WEB-INF/lib directory of web apps using XMLC. Again, the sample app's Ant build script handles this.


Whether or not the need for patched versions of common libraries causes compatibility problems may depend on your app server. If the app server supports the Servlet 2.3 recommendation for "inverted" class loading (WAR first) discussed in , there's unlikely to be a problem. However, if it follows normal Java language class loading behavior (system classes first) the necessary patches may not be loaded, meaning patching of the app server's own libraries or abandoning XMLC. Hopefully this issue will soon be resolved with later releases of XMLC and the libraries in question.

Like Velocity, XMLC needs to be configured before it can be used in a web app. Although we were able to configure Velocity using a bean in our app context, we need to use a servlet to configure XMLC. The XMLCContext object can only be configured by a servlet; the ServletContext isn't sufficient. Our MVC framework provides the com. interface21 .web. servlet .view .xmlc .XmlcConfigServlet to configure XMLC, which must be set to load on app startup. The XmlcConfigServlet configures XMLC as follows:

 XMLCContext xmlcc = XMLCContext.getContext(this);

When using XMLC, the following servlet definition element must be included in each web app's web.xml to load the XmlcConfigServlet on startup:


Set the <load-on-startup> value according to the number of pre-initialized servlets your app requires.

Implementing the View Interface for XMLC

Let's look at the framework's abstract implementation of the com.interface21.web.servlet.View interface for XMLC, which app-specific XMLC views should extend. With XMLC, as with any generation library approach, we need a distinct Java object for each view. At run time the HTML template is no longer required, but we need one view implementation for each XMLC-generated view. The framework provides a common superclass for all XMLC views, com.interface21.web.servlet.view.xmlc.AbstractXmlcView, which extends com.interface21.web.servlet.view.AbstractView and uses the Template Method design pattern to conceal the necessary plumbing from subclasses and leave them only the task of creating and manipulating the relevant XMLC object. The implementation of the protected renderMergedOutputModel() method from AbstractView uses the org.enhydra.xml.xmlc.servlet.XMLCContext object created by the XmlcConfigServlet, which can be used to create new templates. The following is a partial listing:

 public abstract class AbstractXmlcView extends AbstractView {

 private XMLCContext xmlcContext;

The following overridden method from AbstractView caches the XMLCContext, throwing an exception if XMLC has not been configured:

 protected void onSetContext() throws appContextException {
 this. xmlcContext = (XMLCContext) getWebappContext() .
 getServletContext(). getAttribute (XMLCContext . CONTEXT_ATTRIBUTE ) ;
 if (this .xmlcContext == null)
 throw new appContextException(
 "No XMLCContext inited. Use XMLCConfigServlet with loadOnStartup");

The implementation of the protected renderMergedOutputModel() template method invokes a protected template method to create the app-specific XMLObject, before using the XMLCContext to output its data to the response:

 protected final void renderMergedOutputModel (Map model, 
 HttpServletRequest request,
 HttpServletResponse response)
 throws ServletException, IOException {

 XMLObject xo = createXMLObject (model, request, response,
 this.xmlcContext) ;
 response. setContentType (getContentType() ) ;
 this .xmlcContext. writeDOM(request, response, xo) ;

Subclasses must implement the following protected method to create an app-specific XMLCObject and manipulate it according to the data in the model parameter:

 protected abstract XMLObject createXMLObject(
 Map model,
 HttpServletRequest request,
 HttpServletResponse response,
 XMLCContext context)
 throws ServletException;

Defining XMLC Views for Use in an app

As the AbstractXmlcView class exposes no bean properties beyond those inherited from AbstractView, all we need to do to define an XMLC view is to specify an app-specific concrete subclass, as follows:

 showReservation. class=

Of course, subclasses may themselves add view properties, which can then be set in the same way as framework properties. One of the virtues of JavaBean-based configuration is that it automatically works with any class, not just classes that are known to the framework.