Author: asankha
Date: Thu Sep 6 01:59:22 2007
New Revision: 573186
URL: http://svn.apache.org/viewvc?rev=573186&view=rev
Log:
fixes to XSLT mediator to handle non XML responses and to do better tracing and
debug logs - need more cleanup
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/mediators/transform/XSLTMediator.java
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?rev=573186&r1=573185&r2=573186&view=diff
==============================================================================
---
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 Sep 6 01:59:22 2007
@@ -72,6 +72,7 @@
if (attSource != null) {
try {
+
transformMediator.setSourceXPathString(attSource.getAttributeValue());
AXIOMXPath xp = new AXIOMXPath(attSource.getAttributeValue());
OMElementUtils.addNameSpaces(xp, elem, log);
transformMediator.setSource(xp);
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?rev=573186&r1=573185&r2=573186&view=diff
==============================================================================
---
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 Sep 6 01:59:22 2007
@@ -22,22 +22,30 @@
import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMNode;
+import org.apache.axiom.om.OMFactory;
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.impl.llom.OMTextImpl;
import org.apache.axiom.om.util.ElementHelper;
import org.apache.axiom.om.xpath.AXIOMXPath;
import org.apache.axiom.soap.SOAP11Constants;
import org.apache.axiom.soap.SOAP12Constants;
+import org.apache.axiom.soap.SOAPFactory;
+import org.apache.axiom.soap.SOAPEnvelope;
+import org.apache.axiom.soap.impl.llom.soap11.SOAP11Factory;
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.core.axis2.Axis2MessageContext;
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.apache.axis2.transport.base.BaseConstants;
+import org.apache.axis2.AxisFault;
import org.jaxen.JaxenException;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
@@ -51,6 +59,7 @@
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
+import javax.xml.namespace.QName;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
@@ -61,11 +70,13 @@
* The XSLT mediator performs an XSLT transformation requested, using
* the current message. The source attribute (if available) spcifies the
source element
* on which the transformation would be applied. It will default to the first
child of
- * the messages' SOAP body, if it is omitted. Additional properties passed
into this
- * mediator would become parameters for XSLT.Additional features passed inot
this mediator would
- * become features except
"http://ws.apache.org/ns/synapse/transform/feature/dom" for the Transformer
Factory.
- * The "http://ws.apache.org/ns/synapse/transform/feature/dom" feature is used
to deciding swiching
- * between DOM and Stream during the transformation process
+ * the messages' SOAP body, if it is omitted.
+ *
+ * Additional properties passed into this mediator would become parameters for
XSLT.
+ * Additional features passed into this mediator would become features except
for
+ * "http://ws.apache.org/ns/synapse/transform/feature/dom" for the Transformer
Factory, which
+ * is used to decide between using DOM and Streams during the transformation
process. By default
+ * this is turned on as an optimization, but should be set to false if issues
are detected
*/
public class XSLTMediator extends AbstractMediator {
@@ -83,6 +94,9 @@
*/
private String xsltKey = null;
+ /** Variable to hold source XPath string to use for debugging */
+ private String sourceXPathString = null;
+
/**
* The (optional) XPath expression which yeilds the source element for a
transformation
*/
@@ -96,7 +110,7 @@
/**
* Any features which should be set to the TransformerFactory by explicitly
*/
- private List explicityFeatures= new ArrayList();
+ private List explicitFeatures = new ArrayList();
/**
* The Template instance used to create a Transformer object. This is
thread-safe
@@ -157,28 +171,32 @@
*/
public boolean mediate(MessageContext synCtx) {
try {
- if (log.isDebugEnabled()) {
- log.debug("XSLT mediator mediate()");
- }
boolean shouldTrace = shouldTrace(synCtx.getTracingState());
if (shouldTrace) {
- trace.trace("Start : XSLT mediator");
+ trace.trace("Start : XSLT mediator : Using style sheet with
key : " + xsltKey +
+ (sourceXPathString == null ? "" : " against source XPath :
" + sourceXPathString));
}
if (log.isDebugEnabled()) {
- log.debug("Performing XSLT transformation against resource
with key : " + xsltKey);
+ log.debug("Performing XSLT using style sheet with key : " +
xsltKey +
+ (sourceXPathString == null ? "" : " against source XPath :
" + sourceXPathString));
}
+
performXLST(synCtx, shouldTrace);
+
if (shouldTrace) {
- trace.trace("Start : XSLT mediator");
+ trace.trace("End : XSLT mediator");
}
return true;
+
} catch (Exception e) {
- handleException("Unable to do the transformation");
+ handleException("Unable to perform transformation. XSLT : " +
xsltKey +
+ (sourceXPathString == null ? "" : " source XPath : " +
sourceXPathString), e);
}
return false;
}
private void performXLST(MessageContext msgCtx, boolean shouldTrace) {
+
boolean reCreate = false;
OMNode sourceNode = getTransformSource(msgCtx);
if (shouldTrace) {
@@ -187,30 +205,49 @@
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
+
+ if (isDOMRequired) {
+ if (log.isDebugEnabled()) {
+ log.debug("Using a DOMSource for transformation");
+ }
+ if (shouldTrace) {
+ trace.debug("Using a DOMSource for transformation");
+ }
+
+ // for fast transformations create a DOMSource - ** may not work
always though **
transformSrc = new DOMSource(
((Element) ElementHelper.importOMElement((OMElement)
sourceNode,
DOOMAbstractFactory.getOMFactory())).getOwnerDocument());
DocumentBuilderFactoryImpl.setDOOMRequired(true);
try {
transformTgt = new
DOMResult(DocumentBuilderFactoryImpl.newInstance().
- newDocumentBuilder().newDocument());
+ newDocumentBuilder().newDocument());
} catch (ParserConfigurationException e) {
- handleException("Error creating DOMResult ", e);
+ handleException("Error creating a DOMResult ", e);
}
+
} else {
+ if (log.isDebugEnabled()) {
+ log.debug("Using byte array serialization");
+ }
+ if (shouldTrace) {
+ trace.trace("Using byte array serialization");
+ }
+
try {
// create a byte array output stream and serialize the source
node into it
ByteArrayOutputStream baosForSource = new
ByteArrayOutputStream();
XMLStreamWriter xsWriterForSource =
XMLOutputFactory.newInstance().
- createXMLStreamWriter(baosForSource);
+ createXMLStreamWriter(baosForSource);
sourceNode.serialize(xsWriterForSource);
transformSrc = new StreamSource(
- new ByteArrayInputStream(baosForSource.toByteArray()));
+ new ByteArrayInputStream(baosForSource.toByteArray()));
+
// create a new Stream result over a new BAOS..
transformTgt = new StreamResult(baosForTarget);
@@ -218,9 +255,15 @@
handleException("Error gettting transform source " +
e.getMessage(), e);
}
}
+
if (transformTgt == null) {
+ log.error("Was unable to get a transformation target created");
+ if (shouldTrace) {
+ trace.trace("Was unable to get a transformation target
created");
+ }
return;
}
+
// build transformer - if necessary
Entry dp = msgCtx.getConfiguration().getEntryDefinition(xsltKey);
@@ -230,18 +273,19 @@
reCreate = true;
}
}
+
synchronized (transformerLock) {
if (reCreate || cachedTemplates == null) {
try {
cachedTemplates = transFact.newTemplates(
- Util.getStreamSource(
- msgCtx.getEntry(xsltKey)));
+ Util.getStreamSource(msgCtx.getEntry(xsltKey)));
} catch (TransformerConfigurationException e) {
handleException("Error creating XSLT transformer using : "
+ xsltKey, e);
}
}
}
+
try {
// perform transformation
Transformer transformer = cachedTemplates.newTransformer();
@@ -250,52 +294,61 @@
for (int i = 0; i < properties.size(); i++) {
MediatorProperty prop = (MediatorProperty)
properties.get(i);
if (prop != null) {
- transformer.setParameter(prop.getName(),
prop.getValue());
+ if (prop.getValue() != null) {
+ transformer.setParameter(prop.getName(),
prop.getValue());
+ } else {
+ transformer.setParameter(prop.getName(),
+
Axis2MessageContext.getStringValue(prop.getExpression(), msgCtx));
+ }
}
}
}
+
transformer.transform(transformSrc, transformTgt);
+ debugLogAndTrace("Transformation completed. Processing result",
shouldTrace);
+
// get the result OMElement
- OMElement result;
+ OMElement result = null;
if (transformTgt instanceof DOMResult) {
Node node = ((DOMResult) transformTgt).getNode();
if (node == null) {
+ debugLogAndTrace("Transformation result was null",
shouldTrace);
return;
}
Node resultNode = node.getFirstChild();
if (resultNode == null) {
- if (log.isDebugEnabled()) {
- log.debug("Transformation result is null");
- }
+ debugLogAndTrace("Transformation result was empty",
shouldTrace);
return;
}
+
result = ElementHelper.importOMElement((OMElement) resultNode,
OMAbstractFactory.getOMFactory());
+
} else {
- StAXOMBuilder builder = new StAXOMBuilder(
+ try {
+ StAXOMBuilder builder = new StAXOMBuilder(
new ByteArrayInputStream(baosForTarget.toByteArray()));
- result = builder.getDocumentElement();
+ result = builder.getDocumentElement();
+ } catch (XMLStreamException e) {
+ handleException("Error building result from XSLT
transformation", e);
+ } catch (Exception e) {
+ result = handleNonXMLResult(baosForTarget.toString(),
shouldTrace);
+ }
}
+
if (result == null) {
- if (log.isDebugEnabled()) {
- log.debug("Transformation result is null ");
- }
+ debugLogAndTrace("Transformation result is null", shouldTrace);
return;
}
- if (shouldTrace) {
- trace.trace("Transformation result : " + result.toString());
- }
- if (log.isDebugEnabled()) {
- log.debug("Transformation result : " + result);
- }
+
+ debugLogAndTrace("Transformation result : " + result.toString(),
shouldTrace);
+
// replace the sourceNode with the result.
sourceNode.insertSiblingAfter(result);
sourceNode.detach();
} catch (TransformerException e) {
handleException("Error performing XSLT transformation " + xsltKey,
e);
- } catch (XMLStreamException e) {
- handleException("Error building result from XSLT transformation",
e);
}
}
@@ -369,7 +422,7 @@
} else {
mp.setValue("false");
}
- explicityFeatures.add(mp);
+ explicitFeatures.add(mp);
if (FEATURE.equals(featureName)) {
isDOMRequired = isFeatureEnable;
} else {
@@ -380,12 +433,33 @@
}
}
+ private OMElement handleNonXMLResult(String textPayload, boolean
shouldTrace) {
+
+ OMFactory fac = OMAbstractFactory.getOMFactory();
+ QName wrapperQName = null;
+ OMElement wrapper = null;
+
+ debugLogAndTrace("Processing non SOAP/XML transformation result",
shouldTrace);
+
+ if (textPayload != null) {
+ OMTextImpl textData = (OMTextImpl) fac.createOMText(textPayload);
+
+ if (wrapperQName == null) {
+ wrapperQName = BaseConstants.DEFAULT_TEXT_WRAPPER;
+ }
+ wrapper = fac.createOMElement(wrapperQName, null);
+ wrapper.addChild(textData);
+ }
+
+ return wrapper;
+ }
+
/**
*
* @return Returns the features explicitly set to the TransformerFactory
through this mediator
*/
public List getFeatures(){
- return explicityFeatures;
+ return explicitFeatures;
}
public void addAllProperties(List list) {
@@ -394,6 +468,19 @@
public List getProperties() {
return properties;
+ }
+
+ public void setSourceXPathString(String sourceXPathString) {
+ this.sourceXPathString = sourceXPathString;
+ }
+
+ private void debugLogAndTrace(String msg, boolean shouldTrace) {
+ if (log.isDebugEnabled()) {
+ log.debug(msg);
+ }
+ if (shouldTrace) {
+ trace.trace(msg);
+ }
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]