Version 4

    Here's a very basic content filter, based on XSL


    import java.util.HashMap;
    import java.util.Map;
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.jboss.soa.esb.actions.AbstractActionPipelineProcessor;
    import org.jboss.soa.esb.actions.ActionProcessingException;
    import org.jboss.soa.esb.helpers.ConfigTree;
    import org.jboss.soa.esb.message.Message;
    import org.jboss.soa.esb.message.MessagePayloadProxy;
    import XSLTransformer;
     * Simple ActionProcessor that runs a XSL transformation on the input message
     * The advantages of relying on 'native' XSL versus using the Smooks
     * transformation engine is one of size: In order to support its fragment based
     * transformation, Smooks will read everything into a DOM and do transformations
     * based on that.
     * This action expects input in DEFAULT_LOCATION and also places its output
     * there
     * @author runmol
    public class XSLActionProcessor extends AbstractActionPipelineProcessor {
         private static final Log LOG = LogFactory.getLog(XSLActionProcessor.class);
         private static Map<String, String> cache = new HashMap<String, String>();
         private String xsl;
         private MessagePayloadProxy payloadProxy;
         public XSLActionProcessor(ConfigTree configTree) {
              xsl = configTree.getAttribute("xsl");
              payloadProxy =  new MessagePayloadProxy(configTree);
         public Message process(Message message) throws ActionProcessingException {
              try {
                   // actual processing delegated to XSLTransformer class
                   XSLTransformer transformer = new XSLTransformer();
                   byte[] bytes = (byte[]) payloadProxy.getPayload(message);
                   ByteArrayInputStream input = new ByteArrayInputStream(bytes);
                   ByteArrayOutputStream output = (ByteArrayOutputStream) transformer
                             .transform(input, getStylesheet(xsl));
                   payloadProxy.setPayload(message, output.toByteArray());
                   return message;
              } catch (Exception e) {
                   throw new ActionProcessingException(e);
          * Loads a stylesheet from cache or from a file
          * @return
          * @throws IOException
         private String getStylesheet(String stylesheetFileName) throws IOException {
              String result = null;
              synchronized (cache) {
                   result = cache.get(stylesheetFileName);
                   if (result == null) {
              "Loading stylesheet from file " + stylesheetFileName);
                        InputStream in = this.getClass().getClassLoader()
                        StringBuilder sb = new StringBuilder();
                        BufferedReader buf = new BufferedReader(new InputStreamReader(
                        String line;
                        while ((line = buf.readLine()) != null) {
                        result = sb.toString();
                        cache.put(stylesheetFileName, result);
                   } else {
              "Stylesheet retrieved from cache");
                   return result;



    And here is the XSLTransformer class:


    import javax.xml.transform.Transformer;
    import javax.xml.transform.TransformerException;
    import javax.xml.transform.TransformerFactory;
     * XSL transformer action on the ESB
     * @author runmol
    public class XSLTransformer {
         private static TransformerFactory tf = TransformerFactory.newInstance(); 
          * Runs a XSL transformation
          * @param input stream of input data
          * @param xsl XSL stylesheet (not a filename, but the actual stylesheet
          * @return The transformed data
          * @throws TransformerException
         public OutputStream transform(InputStream input,
                   String xsl) throws TransformerException {
              if (input == null || xsl == null)
                   throw new IllegalArgumentException("input cannot be null");
              Transformer t = tf.newTransformer(new StreamSource(
                        new StringReader(xsl)));
              ByteArrayOutputStream output = new ByteArrayOutputStream(4096);
              t.transform(new StreamSource(input), new StreamResult(output));
              return output;


    Example configuration:


                        <action name="ContentFilter" class="x.y.z.XSLActionProcessor">
                             <property name="xsl" value="cancelledfilter.xsl"></property>


    And finally here's the stylesheet used in the example. The objective is to filter out all element with the value 'true'


    <xsl:stylesheet version="1.0" 
    <xsl:template match="@*|node()">
          <xsl:apply-templates select="@*|node()"></xsl:apply-templates>
    <xsl:template match="sd:operation[sd:cancelled='true']"></xsl:template>