Reloadable XSLT Transformer in Mule

One of the main functions of a Mule ESB application (besides transporting messages) is transforming messages to another format. Nowadays a lot of messages are XML based so a lot of transformations are done by using XSLT, or in Mule terminology, an XSLT Transformer. In our current project this is no different.

To create our XSLT we happily using Altova Mapforce for this. But this also means that a lot of changes and issues during the development are being solved by modifying the XSLT. In our Mule ESB setup we have deployed our Mule applications as a WAR in Tomcat. So this means to take our modified XSLT into account we have to redeploy the WAR or at least, stop and start the WAR in Tomcat. And as we found out, if the Mule application is inside a JAR inside the WAR we had to stop and start the complete Tomcat instance for our changes to be picked up.

To solve this issue we have created our own instance of the Xslt Transformer in Mule. Our implementation checks for the timestamp of the XSLT file and reloads it if there is found a newer XSLT file. This way we don’t have to restart our Tomcat if a newer version is in place. In a production environment you might want to discard this functionality to avoid unexpected behaviour of the running applications but I leave that up to you. In this post I will show you how our implementation of the XSLT Transformer works.
The example I use in this pots is the same as I had in the previous post. I have an XSD that describes an Order and I transform it with a XSL file to an Invoice. Here you can find the complete code of our version of the XSL Transformer. Next I show just the important parts that we have changed

package net.pascalalma.mule.transformers;

import …

/**
* This class is mainly a copy of the XsltTransformer supplied by Mule.
* Checks are added for the XSLT file timestamp, so if the XSLT file is changed
* , the pool will be reloaded, so the new version of the XSLT is used.
*
* @author Pascal Alma
*/
public class XsltTransformer extends AbstractXmlTransformer implements MuleContextAware
{
...
  /* added by Redstream */
  private long lastModified;

...
  @Override
  public void initialise() throws InitialisationException
  {
    try
    {
      // Set XSLT timestamp
      java.net.URL url = IOUtils.getResourceAsUrl(xslFile, getClass());
      File file = null;

      try
      {
        file = new File(url.toURI());
      }
      catch (URISyntaxException e)
      {
        file = new File(url.getPath());
      }
      if (file != null)
      {
        this.lastModified = file.lastModified();
      }
      transformerPool.addObject();
    }
    catch (Throwable te)
    {
      throw new InitialisationException(te, this);
    }
  }
...
  protected void doTransform(String encoding, Source sourceDoc, Result result)
    throws Exception
  {
    DefaultErrorListener errorListener = new DefaultErrorListener(this);
    javax.xml.transform.Transformer transformer = null;

    // Check XSLT timestamp and reload
    java.net.URL url = IOUtils.getResourceAsUrl(xslFile, getClass());
    File file = null;
    try
    {
      file = new File(url.toURI());
    }
    catch (URISyntaxException e)
    {
      file = new File(url.getPath());
    }
    if (file != null && file.lastModified() > this.lastModified)
    {
      if (logger.isDebugEnabled())
      {
        logger.debug("Reloading " + file.getAbsolutePath());
      }
      this.transformerPool.clear();
      this.transformerPool.addObject();

      this.lastModified = file.lastModified();
    }
    ...
  }
...
}

About Pascal Alma

Pascal is a senior IT consultant and has been working in IT since 1997. He is monitoring the latest development in new technologies (Mobile, Cloud, Big Data) closely and particularly interested in Java open source tool stacks, cloud related technologies like AWS and mobile development like building iOS apps with Swift. Specialties: Java/JEE/Spring Amazon AWS API/REST Big Data Continuous Delivery Swift/iOS
This entry was posted in Mule, XML/ XSD/ XSLT and tagged , , . Bookmark the permalink.

One Response to Reloadable XSLT Transformer in Mule

  1. John Doe says:

    Tnx!! I was just looking for this. Worked like a charm.

Comments are closed.