Version 4

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

     

    import java.io.BufferedReader;
    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    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) {
                        LOG.info("Loading stylesheet from file " + stylesheetFileName);
    
                        InputStream in = this.getClass().getClassLoader()
                                  .getResourceAsStream(xsl);
    
                        StringBuilder sb = new StringBuilder();
    
                        BufferedReader buf = new BufferedReader(new InputStreamReader(
                                  in));
    
                        String line;
    
                        while ((line = buf.readLine()) != null) {
                             sb.append(line);
                        }
    
                        in.close();
    
                        result = sb.toString();
    
                        cache.put(stylesheetFileName, result);
                   } else {
                        LOG.info("Stylesheet retrieved from cache");
                   }
    
                   return result;
              }
         }
    
    }
    

     

    -


    And here is the XSLTransformer class:

     

    import java.io.ByteArrayOutputStream;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.io.StringReader;
    
    import javax.xml.transform.Transformer;
    import javax.xml.transform.TransformerException;
    import javax.xml.transform.TransformerFactory;
    import javax.xml.transform.stream.StreamResult;
    import javax.xml.transform.stream.StreamSource;
    
    /**
     * 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>
                        </action>
    
    

    -


    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" 
         xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
         xmlns:sd="http://www.cph.dk/sap/sd/v1-0">
    
    <xsl:template match="@*|node()">
       <xsl:copy>
          <xsl:apply-templates select="@*|node()"></xsl:apply-templates>
       </xsl:copy>
    </xsl:template>
    
    <xsl:template match="sd:operation[sd:cancelled='true']"></xsl:template>
    
    </xsl:stylesheet>