
net.adamjenkins.sxe.elements.SOAP Maven / Gradle / Ivy
/*
* Copyright 2020 Adam Norman Jenkins.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* under the License.
*/
package net.adamjenkins.sxe.elements;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Map;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.MimeHeaders;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPConnection;
import javax.xml.soap.SOAPConnectionFactory;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPFault;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart;
import javax.xml.transform.TransformerException;
import net.adamjenkins.sxe.util.XSLTErrorListener;
import org.apache.xalan.extensions.XSLProcessorContext;
import org.apache.xalan.templates.ElemExtensionCall;
import org.apache.xml.utils.DOMBuilder;
/**
* Element for calling SOAP web services from XSLT and incorporating the results into the processing tree.
*
* Read This First: Introduction to SXE Elements
*
*
* SXE SOAP Framework
* This framework provides the ability to send a SOAP message to a server, and incorporate the response into the context
* of the document being processed.
*
* To register it with the xslt processor, add it to the root element thus:
*
*
* <xsl:stylesheet ... xmlns:soap="xalan://net.adamjenkins.sxe.elements.SOAP" extension-element-prefixes="soap" ... >
*
*
* @author Adam Norman Jenkins
*/
public class SOAP extends AbstractExtensionElement{
private Map envelopesUnderDevelopment = new HashMap();
/**
* Invokes a SOAP service and incorporates the response into the XSLT context.
*
* Example Usage:
*
*
* <xsl:template match="company">
* <soap:invoke endPoint="http://somecompany.com/someservice">
* <soap:header>
* <wsse:Security>
* <wsse:UsernameToken>
* <wsse:Username><xsl:value-of select="/contact/login/@user"/></wsse:Username>
* <wsse:Password><xsl:value-of select="/contact/login/@pass"/></wsse:Password>
* </wsse:UsernameToken>
* </wsse:Security>
* </soap:header>
* <soap:body>
* <someSoapMessage/>
* </soap:body>
* </soap:invoke>
* </xsl:template>
*
*
*
* Attribute Name Type Description Mandatory?
* endPoint Template The soap endpoint. Yes
* action Template The soap action. No
*
* @param context
* @param extensionElement
*/
public void invoke(XSLProcessorContext context, ElemExtensionCall extensionElement) throws SOAPException, TransformerException, MalformedURLException, FileNotFoundException, IOException{
if(!passesAttributeValidation(extensionElement, context, "endPoint")) return;
String destination = getAttribute("endPoint", context, extensionElement);
swapErrorListener(context);
SOAPConnectionFactory soapConnFactory = SOAPConnectionFactory.newInstance();
SOAPConnection connection = soapConnFactory.createConnection();
MessageFactory messageFactory = MessageFactory.newInstance();
SOAPMessage message = messageFactory.createMessage();
if(hasAttribute(extensionElement, "action")){
MimeHeaders hd = message.getMimeHeaders();
hd.addHeader("SOAPAction", getAttribute("action", context, extensionElement));
}
SOAPPart soapPart = message.getSOAPPart();
SOAPEnvelope envelope = soapPart.getEnvelope();
envelopesUnderDevelopment.put(Thread.currentThread(), envelope);
DOMBuilder handler = new DOMBuilder(envelope.getOwnerDocument(), envelope);
context.getTransformer().executeChildTemplates(extensionElement, handler);
message.saveChanges();
envelopesUnderDevelopment.remove(Thread.currentThread());
XSLTErrorListener listener = resetErrorListener(context);
if(listener.getAllErrors().size() > 0){
listener.transferTo(context.getTransformer().getErrorListener());
logError(this.getClass(),
extensionElement,
"Could not invoke soap service, errors occured during message transformation",
listener);
return;
}
SOAPMessage response = connection.call(message, destination);
connection.close();
if(response.getSOAPBody().hasFault()){
SOAPFault fault = response.getSOAPBody().getFault();
logError(this.getClass(),
extensionElement,
"Soap Fault: [" + fault.getFaultCode() + "] from [" + fault.getFaultActor() + "]: " + fault.getFaultString(),
context);
}else{
context.outputToResultTree(context.getStylesheet(), response.getSOAPBody().getFirstChild());
}
}
/**
* The soap header element (see the invoke method documentation for examples).
*
* @param context
* @param extensionElement
*/
public void header(XSLProcessorContext context, ElemExtensionCall extensionElement) throws SOAPException, TransformerException{
SOAPEnvelope envelope = envelopesUnderDevelopment.get(Thread.currentThread());
SOAPHeader header = envelope.getHeader();
DOMBuilder handler = new DOMBuilder(header.getOwnerDocument(), header);
context.getTransformer().executeChildTemplates(extensionElement, handler);
}
/**
* The soap body element (see the invoke method documentation for examples).
* @param context
* @param extensionElement
*/
public void body(XSLProcessorContext context, ElemExtensionCall extensionElement) throws SOAPException, TransformerException{
SOAPEnvelope envelope = envelopesUnderDevelopment.get(Thread.currentThread());
SOAPBody body = envelope.getBody();
DOMBuilder handler = new DOMBuilder(body.getOwnerDocument(), body);
context.getTransformer().executeChildTemplates(extensionElement, handler);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy