Author: indika
Date: Thu Jul 5 04:43:14 2007
New Revision: 553464
URL: http://svn.apache.org/viewvc?view=rev&rev=553464
Log:
Performance improvement to the XSLT transformation (using xsltc and translets
)
add setting features to the TransformerFactory
enable passing parameters to the XSLT transformation
use tread-safe Templates
add a new feature to switch transformation between DOM and Stream...
feature name : http://ws.apache.org/ns/synapse/transform/dom/feature
if value is true ,then use DOM
now xslt mediator configuration seems
<xslt>
<porperty {name }{value }>*
<feature {name }{value }>*
<xslt>
Modified:
webservices/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/XSLTMediatorFactory.java
webservices/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/XSLTMediatorSerializer.java
webservices/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/transform/XSLTMediator.java
webservices/synapse/trunk/java/modules/extensions/src/test/java/org/apache/synapse/mediators/transform/XSLTMediatorTest.java
webservices/synapse/trunk/java/pom.xml
Modified:
webservices/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/XSLTMediatorFactory.java
URL:
http://svn.apache.org/viewvc/webservices/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/XSLTMediatorFactory.java?view=diff&rev=553464&r1=553463&r2=553464
==============================================================================
---
webservices/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/XSLTMediatorFactory.java
(original)
+++
webservices/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/XSLTMediatorFactory.java
Thu Jul 5 04:43:14 2007
@@ -34,6 +34,7 @@
import org.jaxen.JaxenException;
import javax.xml.namespace.QName;
+import java.util.Iterator;
/**
* Creates a XSLT mediator from the given XML
@@ -48,6 +49,9 @@
private static final Log log =
LogFactory.getLog(XSLTMediatorFactory.class);
private static final QName TAG_NAME = new
QName(Constants.SYNAPSE_NAMESPACE, "xslt");
+ public static final QName ATT_NAME_Q = new
QName(Constants.NULL_NAMESPACE, "name");
+ public static final QName ATT_VALUE_Q = new
QName(Constants.NULL_NAMESPACE, "value");
+
public QName getTagQName() {
return TAG_NAME;
@@ -79,8 +83,33 @@
}
// after successfully creating the mediator
// set its common attributes such as tracing etc
- initMediator(transformMediator,elem);
-
+ initMediator(transformMediator, elem);
+ // set the features
+ Iterator iter = elem.getChildrenWithName(new
QName(Constants.SYNAPSE_NAMESPACE, "feature"));
+ while (iter.hasNext()) {
+ OMElement featureElem = (OMElement) iter.next();
+ OMAttribute attName = featureElem.getAttribute(ATT_NAME_Q);
+ OMAttribute attValue = featureElem.getAttribute(ATT_VALUE_Q);
+ if (attName != null && attValue != null) {
+ String name = attName.getAttributeValue();
+ String value = attValue.getAttributeValue();
+ if (name != null && value != null) {
+ if ("true".equals(value.trim())) {
+ transformMediator.addFeature(name.trim(),
+ true);
+ } else if ("false".equals(value.trim())) {
+ transformMediator.addFeature(name.trim(),
+ false);
+ } else {
+ handleException("The feature must have value true or
false");
+ }
+ } else {
+ handleException("The valid values for both of the name and
value are need");
+ }
+ } else {
+ handleException("Both of the name and value attribute are
required for a feature");
+ }
+ }
transformMediator.addAllProperties(
MediatorPropertyFactory.getMediatorProperties(elem));
Modified:
webservices/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/XSLTMediatorSerializer.java
URL:
http://svn.apache.org/viewvc/webservices/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/XSLTMediatorSerializer.java?view=diff&rev=553464&r1=553463&r2=553464
==============================================================================
---
webservices/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/XSLTMediatorSerializer.java
(original)
+++
webservices/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/XSLTMediatorSerializer.java
Thu Jul 5 04:43:14 2007
@@ -25,8 +25,14 @@
import org.apache.synapse.SynapseException;
import org.apache.synapse.Mediator;
import org.apache.synapse.mediators.transform.XSLTMediator;
+import org.apache.synapse.mediators.MediatorProperty;
import org.apache.synapse.config.xml.AbstractMediatorSerializer;
+import java.util.Map;
+import java.util.Set;
+import java.util.Iterator;
+import java.util.List;
+
/**
* <pre>
* <xslt key="property-key" [source="xpath"]>
@@ -61,9 +67,24 @@
"source", nullNS, mediator.getSource().toString()));
serializeNamespaces(xslt, mediator.getSource());
}
-
serializeProperties(xslt, mediator.getProperties());
-
+ List features = mediator.getFeatures();
+ if (!features.isEmpty()) {
+ for (Iterator iter = features.iterator(); iter.hasNext();) {
+ MediatorProperty mp = (MediatorProperty) iter.next();
+ OMElement prop = fac.createOMElement("feature", synNS, xslt);
+ if (mp.getName() != null) {
+ prop.addAttribute(fac.createOMAttribute("name", nullNS,
mp.getName()));
+ } else {
+ handleException("The Feature name is missing");
+ }
+ if (mp.getValue() != null) {
+ prop.addAttribute(fac.createOMAttribute("value", nullNS,
mp.getValue()));
+ } else {
+ handleException("The Feature value is missing");
+ }
+ }
+ }
if (parent != null) {
parent.addChild(xslt);
}
Modified:
webservices/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/transform/XSLTMediator.java
URL:
http://svn.apache.org/viewvc/webservices/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/transform/XSLTMediator.java?view=diff&rev=553464&r1=553463&r2=553464
==============================================================================
---
webservices/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/transform/XSLTMediator.java
(original)
+++
webservices/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/transform/XSLTMediator.java
Thu Jul 5 04:43:14 2007
@@ -19,33 +19,41 @@
package org.apache.synapse.mediators.transform;
+import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMNode;
+import org.apache.axiom.om.util.ElementHelper;
import org.apache.axiom.om.impl.builder.StAXOMBuilder;
+import org.apache.axiom.om.impl.dom.DOOMAbstractFactory;
+import org.apache.axiom.om.impl.dom.jaxp.DocumentBuilderFactoryImpl;
import org.apache.axiom.om.xpath.AXIOMXPath;
import org.apache.axiom.soap.SOAP11Constants;
import org.apache.axiom.soap.SOAP12Constants;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.synapse.Constants;
import org.apache.synapse.MessageContext;
import org.apache.synapse.SynapseException;
-import org.apache.synapse.Constants;
-import org.apache.synapse.config.Util;
import org.apache.synapse.config.Entry;
+import org.apache.synapse.config.Util;
import org.apache.synapse.mediators.AbstractMediator;
import org.apache.synapse.mediators.MediatorProperty;
import org.jaxen.JaxenException;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
-import javax.xml.stream.XMLOutputFactory;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.XMLStreamWriter;
+import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.*;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
-import java.io.ByteArrayInputStream;
+import javax.xml.transform.dom.DOMResult;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.stream.XMLStreamWriter;
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamException;
+import java.util.*;
import java.io.ByteArrayOutputStream;
-import java.util.ArrayList;
-import java.util.List;
+import java.io.ByteArrayInputStream;
/**
* The XSLT mediator performs an XSLT transformation requested, using
@@ -60,6 +68,12 @@
private static final Log trace = LogFactory.getLog(Constants.TRACE_LOGGER);
/**
+ * The feature for which deciding swiching between DOM and Stream during
the
+ * transformation process
+ */
+ public static final String FEATURE =
+ "http://ws.apache.org/ns/synapse/transform/dom/feature";
+ /**
* The resource key/name which refers to the XSLT to be used for the
transformation
*/
private String xsltKey = null;
@@ -75,20 +89,46 @@
private List properties = new ArrayList();
/**
- * The Transformer instance used to perform XSLT transformations. This is
not thread-safe
+ * Any features which should be set to the TransformerFactory by explicitly
+ */
+ private List explicityFeatures= new ArrayList();
+
+ /**
+ * The Template instance used to create a Transformer object. This is
thread-safe
*
- * @see javax.xml.transform.Transformer
+ * @see javax.xml.transform.Templates
+ */
+ private Templates cachedTemplates = null;
+
+ /**
+ * The TransformerFactory instance which use to create Templates...This is
not thread-safe.
+ * @see javax.xml.transform.TransformerFactory
*/
- private Transformer transformer = null;
+ private final TransformerFactory transFact =
TransformerFactory.newInstance();
/**
* Lock used to ensure thread-safe creation and use of the above
Transformer
*/
private final Object transformerLock = new Object();
+ /**
+ * Is it need to use DOMSource and DOMResult?
+ */
+ private boolean isDOMRequired = false;
+
public static final String DEFAULT_XPATH =
"//s11:Envelope/s11:Body/child::*[position()=1] | " +
"//s12:Envelope/s12:Body/child::*[position()=1]";
+ static {
+ // Set the TransformerFactory system property to generate and use
translets.
+ // Note: To make this sample more flexible, need to load properties
from a properties file.
+ String key = "javax.xml.transform.TransformerFactory";
+ String value = "org.apache.xalan.xsltc.trax.TransformerFactoryImpl";
+ Properties props = System.getProperties();
+ props.put(key, value);
+ System.setProperties(props);
+ }
+
public XSLTMediator() {
// create the default XPath
try {
@@ -127,13 +167,7 @@
}
private void performXLST(MessageContext msgCtx, boolean shouldTrace) {
-
- Source transformSrc = null;
- ByteArrayOutputStream baosForTarget = new ByteArrayOutputStream();
-
- // create a new Stream result over a new BAOS..
- StreamResult transformTgt = new StreamResult(baosForTarget);
-
+ boolean reCreate = false;
OMNode sourceNode = getTransformSource(msgCtx);
if (shouldTrace) {
trace.trace("Transformation source : " + sourceNode.toString());
@@ -141,68 +175,107 @@
if (log.isDebugEnabled()) {
log.debug("Transformation source : " + sourceNode);
}
+ Source transformSrc = null;
+ Result transformTgt = null;
+ ByteArrayOutputStream baosForTarget = new ByteArrayOutputStream();
+ if (isDOMRequired) { // for past transformation create a DOMSource
+ transformSrc = new DOMSource(
+ ((Element) ElementHelper.importOMElement((OMElement)
sourceNode,
+
DOOMAbstractFactory.getOMFactory())).getOwnerDocument());
+ DocumentBuilderFactoryImpl.setDOOMRequired(true);
+ try {
+ transformTgt = new
DOMResult(DocumentBuilderFactoryImpl.newInstance().
+ newDocumentBuilder().newDocument());
+ } catch (ParserConfigurationException e) {
+ handleException("Error creating DOMResult ", e);
+ }
+ } else {
+ try {
+ // create a byte array output stream and serialize the source
node into it
+ ByteArrayOutputStream baosForSource = new
ByteArrayOutputStream();
+ XMLStreamWriter xsWriterForSource =
XMLOutputFactory.newInstance().
+ createXMLStreamWriter(baosForSource);
+
+ sourceNode.serialize(xsWriterForSource);
+ transformSrc = new StreamSource(
+ new ByteArrayInputStream(baosForSource.toByteArray()));
+ // create a new Stream result over a new BAOS..
+ transformTgt = new StreamResult(baosForTarget);
- try {
- // create a byte array output stream and serialize the source node
into it
- ByteArrayOutputStream baosForSource = new ByteArrayOutputStream();
- XMLStreamWriter xsWriterForSource = XMLOutputFactory.newInstance().
- createXMLStreamWriter(baosForSource);
-
- sourceNode.serialize(xsWriterForSource);
- transformSrc = new StreamSource(new
ByteArrayInputStream(baosForSource.toByteArray()));
-
- } catch (XMLStreamException e) {
- handleException("Error gettting transform source " +
e.getMessage(), e);
+ } catch (XMLStreamException e) {
+ handleException("Error gettting transform source " +
e.getMessage(), e);
+ }
+ }
+ if (transformTgt == null) {
+ return;
}
-
// build transformer - if necessary
Entry dp = msgCtx.getConfiguration().getEntryDefinition(xsltKey);
// if the xsltKey refers to a dynamic resource
if (dp != null && dp.isDynamic()) {
if (!dp.isCached() || dp.isExpired()) {
- synchronized (transformerLock) {
- try {
- transformer = TransformerFactory.newInstance().
- newTransformer(Util.getStreamSource(
- msgCtx.getEntry(xsltKey)
- ));
- } catch (TransformerConfigurationException e) {
- handleException("Error creating XSLT transformer using
: " + xsltKey, e);
- }
- }
+ reCreate = true;
}
+ }
+ if (reCreate || cachedTemplates == null) {
+ synchronized (transformerLock) {
+ try {
+ cachedTemplates = transFact.newTemplates(
+ Util.getStreamSource(
+ msgCtx.getEntry(xsltKey)));
- // if the resource is not a dynamic, we will create a transformer
only once
- } else {
- if (transformer == null) {
- synchronized (transformerLock) {
- try {
- transformer = TransformerFactory.newInstance().
- newTransformer(
- Util.getStreamSource(
- msgCtx.getEntry(xsltKey)));
- } catch (TransformerConfigurationException e) {
- handleException("Error creating XSLT transformer using
: " + xsltKey, e);
- }
+ } catch (TransformerConfigurationException e) {
+ handleException("Error creating XSLT transformer using : "
+ xsltKey, e);
}
}
}
-
try {
// perform transformation
+ Transformer transformer = cachedTemplates.newTransformer();
+ if (!properties.isEmpty()) {
+ // set the parameters which will pass to the Transformation
+ for (int i = 0; i < properties.size(); i++) {
+ MediatorProperty prop = (MediatorProperty)
properties.get(i);
+ if (prop != null) {
+ transformer.setParameter(prop.getName(),
prop.getValue());
+ }
+ }
+ }
transformer.transform(transformSrc, transformTgt);
-
- StAXOMBuilder builder = new StAXOMBuilder(
- new ByteArrayInputStream(baosForTarget.toByteArray()));
- OMElement result = builder.getDocumentElement();
+ // get the result OMElement
+ OMElement result;
+ if (transformTgt instanceof DOMResult) {
+ Node node = ((DOMResult) transformTgt).getNode();
+ if (node == null) {
+ return;
+ }
+ Node resultNode = node.getFirstChild();
+ if (resultNode == null) {
+ if (log.isDebugEnabled()) {
+ log.debug("Transformation result is null");
+ }
+ return;
+ }
+ result = ElementHelper.importOMElement((OMElement) resultNode,
+ OMAbstractFactory.getOMFactory());
+ } else {
+ StAXOMBuilder builder = new StAXOMBuilder(
+ new ByteArrayInputStream(baosForTarget.toByteArray()));
+ result = builder.getDocumentElement();
+ }
+ if (result == null) {
+ if (log.isDebugEnabled()) {
+ log.debug("Transformation result is null ");
+ }
+ return;
+ }
if (shouldTrace) {
trace.trace("Transformation result : " + result.toString());
}
if (log.isDebugEnabled()) {
log.debug("Transformation result : " + result);
}
-
// replace the sourceNode with the result.
sourceNode.insertSiblingAfter(result);
sourceNode.detach();
@@ -214,7 +287,6 @@
}
}
-
/**
* Return the OMNode to be used for the transformation. If a source XPath
is not specified,
* this will default to the first child of the SOAP body i.e. -
//*:Envelope/*:Body/child::*
@@ -268,6 +340,36 @@
public void addProperty(MediatorProperty p) {
properties.add(p);
+ }
+
+ /**
+ * to add a features which need to set to the TransformerFactory
+ * @param featureName The name of the feature
+ * @param isFeatureEnable should this feature enable?
+ */
+
+ public void addFeature(String featureName, boolean isFeatureEnable) {
+ try {
+ MediatorProperty mp = new MediatorProperty();
+ mp.setName(featureName);
+ if (isFeatureEnable) {
+ mp.setValue("true");
+ } else {
+ mp.setValue("false");
+ }
+ explicityFeatures.add(mp);
+ if (FEATURE.equals(featureName)) {
+ isDOMRequired = isFeatureEnable;
+ } else {
+ transFact.setFeature(featureName, isFeatureEnable);
+ }
+ } catch (TransformerConfigurationException e) {
+ handleException("Error occured when setting features to the
TransformerFactory",e);
+ }
+ }
+
+ public List getFeatures(){
+ return explicityFeatures;
}
public void addAllProperties(List list) {
Modified:
webservices/synapse/trunk/java/modules/extensions/src/test/java/org/apache/synapse/mediators/transform/XSLTMediatorTest.java
URL:
http://svn.apache.org/viewvc/webservices/synapse/trunk/java/modules/extensions/src/test/java/org/apache/synapse/mediators/transform/XSLTMediatorTest.java?view=diff&rev=553464&r1=553463&r2=553464
==============================================================================
---
webservices/synapse/trunk/java/modules/extensions/src/test/java/org/apache/synapse/mediators/transform/XSLTMediatorTest.java
(original)
+++
webservices/synapse/trunk/java/modules/extensions/src/test/java/org/apache/synapse/mediators/transform/XSLTMediatorTest.java
Thu Jul 5 04:43:14 2007
@@ -24,12 +24,15 @@
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.xpath.AXIOMXPath;
import org.apache.synapse.mediators.TestUtils;
+import org.apache.synapse.mediators.MediatorProperty;
import org.apache.synapse.mediators.transform.XSLTMediator;
import org.apache.synapse.config.Entry;
import org.apache.synapse.MessageContext;
import java.util.HashMap;
import java.util.Map;
+import java.util.List;
+import java.util.ArrayList;
import java.net.URL;
public class XSLTMediatorTest extends TestCase {
@@ -60,7 +63,12 @@
// set XSLT transformation URL
transformMediator.setXsltKey("xslt-key");
-
+ List list = new ArrayList();
+ MediatorProperty mp = new MediatorProperty();
+ mp.setName("parama1");
+ mp.setValue("value1");
+ list.add(mp);
+ transformMediator.addAllProperties(list);
Map props = new HashMap();
Entry prop = new Entry();
prop.setType(Entry.URL_SRC);
Modified: webservices/synapse/trunk/java/pom.xml
URL:
http://svn.apache.org/viewvc/webservices/synapse/trunk/java/pom.xml?view=diff&rev=553464&r1=553463&r2=553464
==============================================================================
--- webservices/synapse/trunk/java/pom.xml (original)
+++ webservices/synapse/trunk/java/pom.xml Thu Jul 5 04:43:14 2007
@@ -615,6 +615,28 @@
<version>${bcprov.jdk15.version}</version>
</dependency>
+ <!-- dependencies for xsltc in xalan -->
+ <dependency>
+ <groupId>org.apache.bcel</groupId>
+ <artifactId>bcel</artifactId>
+ <version>${bcel.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>jakarta-regexp</groupId>
+ <artifactId>jakarta-regexp</artifactId>
+ <version>${regexp.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>java-cup</groupId>
+ <artifactId>java-cup</artifactId>
+ <version>${java-cup.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>JLex</groupId>
+ <artifactId>JLex</artifactId>
+ <version>${JLex.version}</version>
+ </dependency>
+
</dependencies>
<reporting>
@@ -724,8 +746,13 @@
<xerces.version>2.8.1</xerces.version>
<xalan.version>2.7.0</xalan.version>
- <js.version>1.6R5</js.version>
+ <js.version>1.6R5</js.version>
+ <!-- xalan xsltc -->
+ <bcel.version>5.2</bcel.version>
+ <regexp.version>1.4</regexp.version>
+ <java-cup.version>0.0</java-cup.version>
+ <JLex.version>0.0</JLex.version>
<!-- misc -->
<junit.version>3.8.2</junit.version>
<log4j.version>1.2.13</log4j.version>
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]