Author: kurtstam
Date: 2009-11-25 16:39:25 -0500 (Wed, 25 Nov 2009)
New Revision: 332
Modified:
trunk/runtime/engine/src/main/java/org/jboss/soa/bpel/runtime/ws/SOAPMessageAdapter.java
Log:
RIFTSAW-74, adding parsing of SOAPHeaders
Modified:
trunk/runtime/engine/src/main/java/org/jboss/soa/bpel/runtime/ws/SOAPMessageAdapter.java
===================================================================
---
trunk/runtime/engine/src/main/java/org/jboss/soa/bpel/runtime/ws/SOAPMessageAdapter.java 2009-11-25
13:56:46 UTC (rev 331)
+++
trunk/runtime/engine/src/main/java/org/jboss/soa/bpel/runtime/ws/SOAPMessageAdapter.java 2009-11-25
21:39:25 UTC (rev 332)
@@ -34,6 +34,7 @@
import javax.wsdl.*;
import javax.wsdl.extensions.ElementExtensible;
import javax.wsdl.extensions.soap.SOAPBinding;
+import javax.wsdl.extensions.soap.SOAPHeader;
import javax.xml.namespace.QName;
import javax.xml.soap.*;
import java.util.*;
@@ -101,7 +102,7 @@
}
}
- public void createSoapRequest(SOAPMessage soapMessage, Message odeRequestMessage,
Operation wsdlOperation)
+ public void createSoapRequest(SOAPMessage soapMessage, Message odeRequestMessage,
Operation wsdlOperation)
{
BindingOperation bop = binding.getBindingOperation(wsdlOperation.getName(), null,
null);
if (bop == null)
@@ -213,7 +214,7 @@
}
catch (SOAPException e)
{
- throw new RuntimeException("Failed ot create soap body",e);
+ throw new RuntimeException("Failed to create soap body",e);
}
}
@@ -221,7 +222,22 @@
javax.wsdl.Message wsdlMessageDef,
Map<String, Node> headerParts)
{
- log.warn("createSoapHeaders() not implemented");
+ try {
+ javax.xml.soap.SOAPHeader soapHeader = soapMessage.getSOAPHeader();
+ if (soapHeader==null) soapHeader =
soapMessage.getSOAPPart().getEnvelope().addHeader();
+ for (Node headerNode : headerParts.values()) {
+ if (headerNode.getNodeType() == Node.ELEMENT_NODE) {
+ if (getFirstChildWithName(new QName(headerNode.getNamespaceURI(),
headerNode.getLocalName()),soapHeader) == null) {
+ SOAPElement partElement = soapFactory.createElement((Element) headerNode);
+ soapHeader.addChildElement(partElement);
+ }
+ } else {
+ throw new RuntimeException("SOAP header must be a node_element " +
headerNode);
+ }
+ }
+ } catch (SOAPException e) {
+ throw new RuntimeException("Failed to create soap header",e);
+ }
}
public void parseSoapResponse(org.apache.ode.bpel.iapi.Message odeMessage,
@@ -235,7 +251,7 @@
throw new RuntimeException("Binding output not found on
"+serviceName+"/"+portName);
extractSoapBodyParts(odeMessage, soapMessage, getSOAPBody(bo),
odeOperation.getOutput().getMessage(), odeOperation.getName() + "Response");
- extractSoapHeaderParts(odeMessage, soapMessage,
odeOperation.getOutput().getMessage());
+ extractSoapHeaderParts(odeMessage, soapMessage, getSOAPHeaders(bo),
odeOperation.getOutput().getMessage());
}
public void parseSoapRequest(
@@ -254,7 +270,7 @@
throw new RuntimeException("Binding input not
found"+serviceName+"/"+portName);
extractSoapBodyParts(odeMessage, soapMessage, getSOAPBody(bi),
op.getInput().getMessage(), op.getName());
- extractSoapHeaderParts(odeMessage, soapMessage, op.getInput().getMessage());
+ extractSoapHeaderParts(odeMessage, soapMessage, getSOAPHeaders(bi),
op.getInput().getMessage());
}
public void createSoapFault(SOAPMessage soapMessage, Element message, QName faultName,
Operation op)
@@ -307,11 +323,74 @@
return detail;
}
- private void extractSoapHeaderParts(Message odeMessage, SOAPMessage soapMessage,
javax.wsdl.Message wsdlMessageDef)
+ private void extractSoapHeaderParts(Message odeMessage, SOAPMessage soapMessage,
List<SOAPHeader> headerDefs,javax.wsdl.Message wsdlMessageDef)
{
- log.warn("extractSoapHeaderParts() not implemented");
+ try {
+ javax.xml.soap.SOAPHeader soapHeader = soapMessage.getSOAPHeader();
+ // Checking that the definitions we have are at least there
+ for (SOAPHeader headerDef : headerDefs)
+ handleSoapHeaderPartDef(odeMessage, soapHeader, headerDef, wsdlMessageDef);
+
+ // Extracting whatever header elements we find in the message, binding and
abstract parts
+ // aren't reliable enough given what people do out there.
+ Iterator headersIter = soapHeader.getChildElements();
+ while (headersIter.hasNext()) {
+ javax.xml.soap.SOAPHeader header = (javax.xml.soap.SOAPHeader)
headersIter.next();
+ String partName = findHeaderPartName(headerDefs, header.getElementQName());
+ Document doc = DOMUtils.newDocument();
+ Element destPart = doc.createElementNS(null, partName);
+ destPart.appendChild(doc.importNode(header, true));
+ odeMessage.setHeaderPart(partName, destPart);
+ }
+ }
+ catch (SOAPException e)
+ {
+ throw new RuntimeException("Failed to extracts header parts",e);
+ }
}
+
+ private String findHeaderPartName(List<SOAPHeader> headerDefs, QName elmtName) {
+ for (SOAPHeader headerDef : headerDefs) {
+ javax.wsdl.Message hdrMsg = wsdl.getMessage(headerDef.getMessage());
+ for (Object o : hdrMsg.getParts().values()) {
+ Part p = (Part) o;
+ if (p.getElementName().equals(elmtName)) return p.getName();
+ }
+ }
+ return elmtName.getLocalPart();
+ }
+
+ private void handleSoapHeaderPartDef(Message odeMessage, javax.xml.soap.SOAPHeader
header, SOAPHeader headerdef,
+ javax.wsdl.Message msgType) {
+ // Is this header part of the "payload" messsage?
+ boolean payloadMessageHeader = headerdef.getMessage() == null ||
headerdef.getMessage().equals(msgType.getQName());
+ boolean requiredHeader = payloadMessageHeader || (headerdef.getRequired() != null
&& headerdef.getRequired());
+ if (requiredHeader && header == null)
+ throw new RuntimeException("Soap Header is missing a required field " +
headerdef.getElementType());
+
+ if (header == null)
+ return;
+
+ javax.wsdl.Message hdrMsg = wsdl.getMessage(headerdef.getMessage());
+ if (hdrMsg == null)
+ return;
+ Part p = hdrMsg.getPart(headerdef.getPart());
+ if (p == null || p.getElementName() == null)
+ return;
+
+ SOAPElement headerEl = getFirstChildWithName(p.getElementName(), header);
+ if (requiredHeader && headerEl == null)
+ throw new RuntimeException("Soap Header is missing a required field "
+ headerdef.getElementType());
+
+ if (headerEl == null) return;
+
+ Document doc = DOMUtils.newDocument();
+ Element destPart = doc.createElementNS(null, p.getName());
+ destPart.appendChild(doc.importNode(headerEl, true));
+ odeMessage.setHeaderPart(p.getName(), destPart);
+ }
+
private void extractSoapBodyParts(
Message odeMessage,
SOAPMessage soapMessage,