* @param synCtx current message
* @param synLog the logger to be used
*/
private void performXSLT(MessageContext synCtx, SynapseLog synLog) {
OMNode sourceNode = source.selectOMNode(synCtx, synLog);
boolean isSoapEnvelope = (sourceNode == synCtx.getEnvelope());
boolean isSoapBody = (sourceNode == synCtx.getEnvelope().getBody());
boolean isSoapHeader = (sourceNode == synCtx.getEnvelope().getHeader());
// Derive actual key from message context
String generatedXsltKey = xsltKey.evaluateValue(synCtx);
// get templates from generatedXsltKey
Templates cachedTemplates = null;
if (synLog.isTraceTraceEnabled()) {
synLog.traceTrace("Transformation source : " + sourceNode.toString());
}
// determine if it is needed to create or create the template
if (isCreationOrRecreationRequired(synCtx)) {
// many threads can see this and come here for acquiring the lock
synchronized (transformerLock) {
// only first thread should create the template
if (isCreationOrRecreationRequired(synCtx)) {
cachedTemplates = createTemplate(synCtx, synLog, generatedXsltKey);
}
}
}
else{
//If already cached template then load it from cachedTemplatesMap
synchronized (transformerLock){
cachedTemplates = cachedTemplatesMap.get(generatedXsltKey);
}
}
try {
// perform transformation
Transformer transformer = null;
try {
transformer = cachedTemplates.newTransformer();
} catch (NullPointerException ex) {
handleException("Unable to create Transformer using cached template", ex, synCtx);
}
if (!properties.isEmpty()) {
// set the parameters which will pass to the Transformation
applyProperties(transformer, synCtx, synLog);
}
transformer.setErrorListener(new ErrorListenerImpl(synLog, "XSLT transformation"));
String outputMethod = transformer.getOutputProperty(OutputKeys.METHOD);
String encoding = transformer.getOutputProperty(OutputKeys.ENCODING);
if (synLog.isTraceOrDebugEnabled()) {
synLog.traceOrDebug("output method: " + outputMethod
+ "; encoding: " + encoding);
}
ResultBuilderFactory.Output output;
if ("text".equals(outputMethod)) {
synLog.traceOrDebug("Processing non SOAP/XML (text) transformation result");
output = ResultBuilderFactory.Output.TEXT;
} else if (isSoapEnvelope) {
output = ResultBuilderFactory.Output.SOAP_ENVELOPE;
} else {
output = ResultBuilderFactory.Output.ELEMENT;
}
SynapseEnvironment synEnv = synCtx.getEnvironment();
ResultBuilder resultBuilder =
resultBuilderFactory.createResultBuilder(synEnv, output);
SourceBuilder sourceBuilder = sourceBuilderFactory.createSourceBuilder(synEnv);
if (synLog.isTraceOrDebugEnabled()) {
synLog.traceOrDebug("Using " + sourceBuilder.getClass().getName());
synLog.traceOrDebug("Using " + resultBuilder.getClass().getName());
}
try {
transformer.transform(sourceBuilder.getSource((OMElement)sourceNode),
resultBuilder.getResult());
} finally {
sourceBuilder.release();
}
synLog.traceOrDebug("Transformation completed - processing result");
// get the result OMElement
OMElement result =
resultBuilder.getNode(encoding == null ? null : Charset.forName(encoding));
if (synLog.isTraceTraceEnabled()) {
synLog.traceTrace("Transformation result : " + result.toString());
}
if (targetPropertyName != null) {
// add result XML as a message context property to the message
if (synLog.isTraceOrDebugEnabled()) {
synLog.traceOrDebug("Adding result as message context property : " +
targetPropertyName);
}
synCtx.setProperty(targetPropertyName, result);
} else {
if (synLog.isTraceOrDebugEnabled()) {
synLog.traceOrDebug("Replace " +
(isSoapEnvelope ? "SOAP envelope" : isSoapBody ? "SOAP body" : "node")
+ " with result");
}
if (isSoapEnvelope) {
try {
synCtx.setEnvelope((SOAPEnvelope) result);
} catch (AxisFault ex) {
handleException("Unable to replace SOAP envelope with result", ex, synCtx);
}
} else if (isSoapBody) {
for (Iterator itr = synCtx.getEnvelope().getBody().getChildElements();
itr.hasNext(); ) {
OMElement child = (OMElement) itr.next();
child.detach();
}
for (Iterator itr = result.getChildElements(); itr.hasNext(); ) {
OMElement child = (OMElement) itr.next();
synCtx.getEnvelope().getBody().addChild(child);
}
} else if (isSoapHeader) {
for (Iterator itr = synCtx.getEnvelope().getHeader().getChildElements();
itr.hasNext();) {
OMElement child = (OMElement) itr.next();
child.detach();
}
for (Iterator itr = result.getChildElements(); itr.hasNext();) {
OMElement child = (OMElement) itr.next();
synCtx.getEnvelope().getHeader().addChild(child);
}
} else {
sourceNode.insertSiblingAfter(result);
sourceNode.detach();
}
}
} catch (TransformerException e) {
handleException("Error performing XSLT transformation using : " + xsltKey, e, synCtx);