[jboss-svn-commits] JBL Code SVN: r38321 - in labs/jbossesb/trunk/product/rosetta: tests/src/org/jboss/soa/esb/actions/transformation/xslt and 1 other directory.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Fri Apr 19 10:15:56 EDT 2013


Author: tadayosi
Date: 2013-04-19 10:15:55 -0400 (Fri, 19 Apr 2013)
New Revision: 38321

Added:
   labs/jbossesb/trunk/product/rosetta/tests/src/org/jboss/soa/esb/actions/transformation/xslt/example2.xml
   labs/jbossesb/trunk/product/rosetta/tests/src/org/jboss/soa/esb/actions/transformation/xslt/expected1.xml
   labs/jbossesb/trunk/product/rosetta/tests/src/org/jboss/soa/esb/actions/transformation/xslt/test3.xsl
Modified:
   labs/jbossesb/trunk/product/rosetta/src/org/jboss/soa/esb/actions/transformation/xslt/XsltAction.java
   labs/jbossesb/trunk/product/rosetta/tests/src/org/jboss/soa/esb/actions/transformation/xslt/XsltActionUnitTest.java
Log:
JBESB-3587
Commit David van Balen's patch to enable XSLT parameters support in XsltAction.
Properties "xslt-params" and "object-paths" are added to XsltAction configuration by this patch.

Modified: labs/jbossesb/trunk/product/rosetta/src/org/jboss/soa/esb/actions/transformation/xslt/XsltAction.java
===================================================================
--- labs/jbossesb/trunk/product/rosetta/src/org/jboss/soa/esb/actions/transformation/xslt/XsltAction.java	2013-04-18 17:58:13 UTC (rev 38320)
+++ labs/jbossesb/trunk/product/rosetta/src/org/jboss/soa/esb/actions/transformation/xslt/XsltAction.java	2013-04-19 14:15:55 UTC (rev 38321)
@@ -24,6 +24,10 @@
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.concurrent.ArrayBlockingQueue;
@@ -80,6 +84,14 @@
  *    <property name="schemaFile" value="/sample.xsd"/>
  *    <property name="schemaLanguage" value="http://www.w3.org/2001/XMLSchema"/>
  *    <property name="resultType" value="STRING"/>
+ *    <property name="xslt-params">
+ *       <xslt-param name="xsltParam1" value="valueOfXsltParam1"/>
+ *       <xslt-param name="xsltParam2" value="valueOfXsltParam2"/>
+ *    </property>
+ *    <property name="object-paths">
+ *       <object-path esb="bodyParam1"/>
+ *       <object-path esb="bodyParam2"/>
+ *    </property>
  * </action>
  * }<pre>
  * 
@@ -422,6 +434,41 @@
     private ArrayBlockingQueue<Transformer> transformers;
     
     /**
+     * Static key value pairs list of XSLT parameters defined in action configuration.
+     */
+    private Map<String, String> staticXsltParams = null;
+    
+    /**
+     * List of message body locations that should contain XSLT parameters
+     */
+    private List<String> xsltParameterLocations = null;
+    
+    /**
+     * Name for config tree children that contain message body locations for xslt parameters
+     */
+    private static final String MESSAGE_BODY_CHILDREN = "object-path";
+    
+    /**
+     * Name of attribute on config tree "body-path" children that will refer to locations on the message body
+     */
+    private static final String MESSAGE_BODY_ATTRIB = "esb";
+    
+    /**
+     * Name for config tree children that contain key/value pairs for xslt parameters
+     */
+    private static final String XSLT_PARAM_CHILDREN = "xslt-param";
+    
+    /**
+     * Name of attribute on config tree "xslt-param" children that will refer to the xslt parameter's name
+     */
+    private static final String XSLT_PARAM_NAME_ATTRIB = "name";
+    
+    /**
+     * Name of attribute on config tree "xslt-param" children that will refer to the xslt parameter's name
+     */
+    private static final String XSLT_PARAM_VALUE_ATTRIB = "value";
+    
+    /**
      * Sole constructor that parses the passed-in {@link ConfigTree} for 
      * mandatory attributes and sets the fields of this instance.
      * 
@@ -438,6 +485,8 @@
         schemaLanguage = config.getAttribute("schemaLanguage");
         payloadProxy = new MessagePayloadProxy(config);
         transformerPoolSize = getMaxThreadsFromParentConfigTree(config);
+        // Figure out which xslt parameters, if any, were specified in the action's configuration
+        initialiseXsltParameters(config);
     }
     
     /**
@@ -509,8 +558,12 @@
                 result = ResultFactory.getInstance().createResult(transformerConfig.getResultType());
             }
             
+            // Attempt to fetch the value of each xslt parameter that was specified
+            // in the action configuration as stored on the message body
+            Map<String, String> xsltParams = createXsltParameters(message);
+            
             // Perform the transformation.
-            transform(source, result);
+            transform(source, result, xsltParams);
             
             // Check for validation errors.
             if (validationHandler != null)
@@ -541,12 +594,21 @@
         }
     }
 
-    private void transform (final Source source, final Result result) throws TransformerException, ActionProcessingException
+    private void transform(final Source source, final Result result, Map<String, String> xsltParams) throws TransformerException, ActionProcessingException
     {
         Transformer transformer = null;
         try
         {
             transformer = transformers.take();
+            
+            // Add XSLT parameters specified through action configuration
+            for (String key : xsltParams.keySet()) {
+                String value = xsltParams.get(key);
+                if (log.isDebugEnabled()) {
+                    log.debug("Adding XSLT parameter to transformer with key: " + key + " and value: " + value);
+                }
+                transformer.setParameter(key, value);
+            }
         }
         catch (final InterruptedException e)
         {
@@ -602,6 +664,72 @@
         } 
     }
     
+    /**
+     * Processes XSLT parameter name/value pairs specified in action's configuration, and
+     * stores message body locations specified as containing XSLT parameters for runtime processing.
+     * Should be called only from constructor.
+     * 
+     * @throws ConfigurationException
+     * 
+     */
+    private void initialiseXsltParameters(ConfigTree config) throws ConfigurationException {
+        if (log.isDebugEnabled()) {
+            log.debug("Processing XSLT parameters, if any.");
+        }
+        
+        ConfigTree[] xsltParamConfigs = config.getChildren(XSLT_PARAM_CHILDREN);
+        if (log.isDebugEnabled()) {
+            log.debug("Number of XSLT parameters with values specified: " + xsltParamConfigs.length);
+        }
+        Map<String, String> xsltParams = new HashMap<String, String>();
+        for (ConfigTree xsltParamConfig : xsltParamConfigs) {
+            String name = xsltParamConfig.getAttribute(XSLT_PARAM_NAME_ATTRIB);
+            String value = xsltParamConfig.getAttribute(XSLT_PARAM_VALUE_ATTRIB);
+            if (log.isDebugEnabled()) {
+                log.debug("xslt param key: " + name + " value: " + value);
+            }
+            xsltParams.put(name, value);
+        }
+        staticXsltParams = Collections.unmodifiableMap(xsltParams);
+        
+        ConfigTree[] objectPathConfigs = config.getChildren(MESSAGE_BODY_CHILDREN);
+        if (log.isDebugEnabled()) {
+            log.debug("Number of message body locations for XSLT parameters specified: " + objectPathConfigs.length);
+        }
+        List<String> paramLocations = new ArrayList<String>();
+        for (ConfigTree objectPathConfig : objectPathConfigs) {
+            String bodyLoc = (String) objectPathConfig.getRequiredAttribute(MESSAGE_BODY_ATTRIB);
+            if (log.isDebugEnabled()) {
+                log.debug("Got xslt-param: " + bodyLoc);
+            }
+            paramLocations.add(bodyLoc);
+        }
+        xsltParameterLocations = Collections.unmodifiableList(paramLocations);
+        
+        if (log.isDebugEnabled()) {
+            log.debug("Done processing XSLT parameters.");
+        }
+    }
+    
+    /**
+     * Creates new XSLT parameters by merging the static XSLT parameters with XSLT parameters that,
+     * according to the action's configuration, should be stored in specified locations on the message body.
+     */
+    private Map<String, String> createXsltParameters(Message message) {
+        Map<String, String> params = new HashMap<String, String>(staticXsltParams);
+        for (String key : xsltParameterLocations) {
+            Object value = message.getBody().get(key);
+            if (value == null) {
+                log.warn("No XSLT parameter value found on message body for key " + key);
+            } else if (!(value instanceof String)) {
+                log.warn("Parameter value for key '" + key + "' is not String: " + value.getClass());
+            } else {
+                params.put(key, (String) value);
+            }
+        }
+        return params;
+    }
+    
     private void addFeatures(final Map<String, Boolean> features, final TransformerFactory factory) throws TransformerConfigurationException
     {
         for (Entry<String, Boolean> entry : features.entrySet())

Modified: labs/jbossesb/trunk/product/rosetta/tests/src/org/jboss/soa/esb/actions/transformation/xslt/XsltActionUnitTest.java
===================================================================
--- labs/jbossesb/trunk/product/rosetta/tests/src/org/jboss/soa/esb/actions/transformation/xslt/XsltActionUnitTest.java	2013-04-18 17:58:13 UTC (rev 38320)
+++ labs/jbossesb/trunk/product/rosetta/tests/src/org/jboss/soa/esb/actions/transformation/xslt/XsltActionUnitTest.java	2013-04-19 14:15:55 UTC (rev 38321)
@@ -67,11 +67,14 @@
     private static final String PACKAGE_PATH = "/org/jboss/soa/esb/actions/transformation/xslt";
     private static final String TEST_XSL_1 = PACKAGE_PATH + "/test1.xsl";
     private static final String TEST_XSL_2 = PACKAGE_PATH + "/test2.xsl";
+    private static final String TEST_XSL_3 = PACKAGE_PATH + "/test3.xsl";
     private static final String TEST_XSD_2 = PACKAGE_PATH + "/test2.xsd";
     private static final String TEST_XML_1 = PACKAGE_PATH + "/example1.xml";
+    private static final String TEST_XML_2 = PACKAGE_PATH + "/example2.xml";
     private static final String MALFORMED_XML_1 = PACKAGE_PATH + "/malformed1.xml";
     private static final String DTD_VALID_XML_1 = PACKAGE_PATH + "/dtd-valid1.xml";
     private static final String DTD_INVALID_XML_1 = PACKAGE_PATH + "/dtd-invalid1.xml";
+    private static final String EXPECTED_XML_1 = PACKAGE_PATH + "/expected1.xml";
     
     @Test (expected = ConfigurationException.class)
     public void shouldThrowIfNoTemplateIsConfigured() throws ConfigurationException
@@ -427,6 +430,28 @@
         assertTrue("XML Comparison", XMLHelper.compareXMLContent("<xxx/>", ((StreamResult) processed.getBody().get()).getWriter().toString()));
     }
     
+    // JBESB-3587
+    @Test public void processXsltStringWithXsltParams() throws Exception
+    {
+        ConfigBuilder confBuilder = new ConfigBuilder().templateFile(TEST_XSL_3).resultType(ResultType.STRING);
+        confBuilder.xsltParam("bar1", "my_value_holder1").xsltParam("bar2", "my_value_holder2");
+        confBuilder.objectPath("foo1").objectPath("foo2");
+        final XsltAction action = new XsltAction(confBuilder.build());
+        action.initialise();
+        
+        final String xml = StreamUtils.getResourceAsString(TEST_XML_2, "UTF-8");
+        
+        final Message message = MessageFactory.getInstance().getMessage();
+        message.getBody().add(xml);
+        message.getBody().add("foo1", "MY_VALUE_HOLDER1");
+        message.getBody().add("foo2", "MY_VALUE_HOLDER2");
+        
+        Message processed = action.process(message);
+        
+        String expected = StreamUtils.getResourceAsString(EXPECTED_XML_1, "UTF-8");
+        assertTrue("XML Comparison", XMLHelper.compareXMLContent(expected, (String) processed.getBody().get()));
+    }
+    
     public static class MockUriResolver implements URIResolver
     {
         public Source resolve(String href, String base) throws TransformerException
@@ -504,6 +529,21 @@
             return this;
         }
         
+        public ConfigBuilder xsltParam(final String name, final String value)
+        {
+            ConfigTree xsltParam = new ConfigTree("xslt-param", config);
+            xsltParam.setAttribute("name", name);
+            xsltParam.setAttribute("value", value);
+            return this;
+        }
+        
+        public ConfigBuilder objectPath(final String location)
+        {
+            ConfigTree xsltParam = new ConfigTree("object-path", config);
+            xsltParam.setAttribute("esb", location);
+            return this;
+        }
+        
         public ConfigTree build()
         {
             return config;

Added: labs/jbossesb/trunk/product/rosetta/tests/src/org/jboss/soa/esb/actions/transformation/xslt/example2.xml
===================================================================
--- labs/jbossesb/trunk/product/rosetta/tests/src/org/jboss/soa/esb/actions/transformation/xslt/example2.xml	                        (rev 0)
+++ labs/jbossesb/trunk/product/rosetta/tests/src/org/jboss/soa/esb/actions/transformation/xslt/example2.xml	2013-04-19 14:15:55 UTC (rev 38321)
@@ -0,0 +1,11 @@
+<?xml version="1.0"?>
+<ARTICLE>
+  <TITLE>A Sample Article</TITLE>
+  <SECT>The First Major Section
+    <PARA>This section will introduce a subsection.</PARA>
+    <SECT>The Subsection Heading
+      <PARA>This is the text of the subsection.
+      </PARA>
+    </SECT>
+  </SECT>
+</ARTICLE> 
\ No newline at end of file


Property changes on: labs/jbossesb/trunk/product/rosetta/tests/src/org/jboss/soa/esb/actions/transformation/xslt/example2.xml
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: labs/jbossesb/trunk/product/rosetta/tests/src/org/jboss/soa/esb/actions/transformation/xslt/expected1.xml
===================================================================
--- labs/jbossesb/trunk/product/rosetta/tests/src/org/jboss/soa/esb/actions/transformation/xslt/expected1.xml	                        (rev 0)
+++ labs/jbossesb/trunk/product/rosetta/tests/src/org/jboss/soa/esb/actions/transformation/xslt/expected1.xml	2013-04-19 14:15:55 UTC (rev 38321)
@@ -0,0 +1,13 @@
+<html>
+  <body>
+    <parameters>MY_VALUE_HOLDER1my_value_holder2</parameters>
+    <h1 align="center">A Sample Article</h1>
+    <sectparams>my_value_holder1</sectparams>
+    <h2>The First Major Section</h2>
+    <p>This section will introduce a subsection.</p>
+    <paraparams>MY_VALUE_HOLDER2</paraparams>
+    <h3>The Subsection Heading</h3>
+    <p>This is the text of the subsection.</p>
+    <paraparams>MY_VALUE_HOLDER2</paraparams>
+  </body>
+</html>
\ No newline at end of file


Property changes on: labs/jbossesb/trunk/product/rosetta/tests/src/org/jboss/soa/esb/actions/transformation/xslt/expected1.xml
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: labs/jbossesb/trunk/product/rosetta/tests/src/org/jboss/soa/esb/actions/transformation/xslt/test3.xsl
===================================================================
--- labs/jbossesb/trunk/product/rosetta/tests/src/org/jboss/soa/esb/actions/transformation/xslt/test3.xsl	                        (rev 0)
+++ labs/jbossesb/trunk/product/rosetta/tests/src/org/jboss/soa/esb/actions/transformation/xslt/test3.xsl	2013-04-19 14:15:55 UTC (rev 38321)
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<xsl:stylesheet 
+  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
+  version="1.0"
+  >
+  <xsl:output method="html"/> 
+  <xsl:strip-space elements="SECT"/>
+  
+  <xsl:param name="foo1" />
+  <xsl:param name="foo2" />
+  <xsl:param name="bar2" />
+  <xsl:param name="bar1" />
+ 
+  <xsl:template match="/">
+    <html><body>
+       <xsl:apply-templates/>
+    </body></html>
+  </xsl:template>
+
+  <xsl:template match="/ARTICLE/TITLE">
+    <parameters><xsl:value-of select="$foo1" /><xsl:value-of select="$bar2" /></parameters>
+    <h1 align="center"> <xsl:apply-templates/> </h1>
+  </xsl:template>
+
+  <!-- Top Level Heading -->
+  <xsl:template match="/ARTICLE/SECT">
+  	  <sectparams><xsl:value-of select="$bar1" /></sectparams>
+      <h2> <xsl:apply-templates select="text()|B|I|U|DEF|LINK"/> </h2>
+      <xsl:apply-templates select="SECT|PARA|LIST|NOTE"/>
+  </xsl:template>
+    
+  <!-- Second-Level Heading -->
+  <xsl:template match="/ARTICLE/SECT/SECT">
+      <h3> <xsl:apply-templates select="text()|B|I|U|DEF|LINK"/> </h3>
+      <xsl:apply-templates select="SECT|PARA|LIST|NOTE"/>
+  </xsl:template>
+
+  <!-- Third-Level Heading -->
+  <xsl:template match="/ARTICLE/SECT/SECT/SECT">
+     <xsl:message terminate="yes">Error: Sections can only be nested 2 deep.</xsl:message>
+  </xsl:template>
+
+  <!-- Paragraph -->
+  <xsl:template match="PARA">
+      <p><xsl:apply-templates/></p>
+      <paraparams><xsl:value-of select="$foo2" /></paraparams>
+  </xsl:template>
+  
+  <xsl:template match="text()">
+    <xsl:value-of select="normalize-space()"/>
+  </xsl:template>
+
+</xsl:stylesheet>
+


Property changes on: labs/jbossesb/trunk/product/rosetta/tests/src/org/jboss/soa/esb/actions/transformation/xslt/test3.xsl
___________________________________________________________________
Added: svn:mime-type
   + text/plain



More information about the jboss-svn-commits mailing list