Author: objectiser
Date: 2010-11-16 15:45:11 -0500 (Tue, 16 Nov 2010)
New Revision: 1109
Added:
trunk/runtime/engine/src/main/java/org/jboss/soa/bpel/runtime/ws/ODEMessageAdapter.java
trunk/runtime/engine/src/main/java/org/jboss/soa/si/MessageAdapter.java
trunk/runtime/engine/src/main/java/org/jboss/soa/si/ws/SOAPMessageAdapter.java
Removed:
trunk/runtime/engine/src/main/java/org/jboss/soa/si/ws/SOAPMessageAdapter.java
Modified:
trunk/integration-tests/pom.xml
trunk/runtime/engine/src/main/java/org/jboss/soa/bpel/runtime/engine/ode/BPELEngineImpl.java
trunk/runtime/engine/src/main/java/org/jboss/soa/bpel/runtime/ws/WSInvocationAdapter.java
trunk/runtime/engine/src/main/java/org/jboss/soa/bpel/runtime/ws/WebServiceClient.java
trunk/runtime/engine/src/main/java/org/jboss/soa/si/InvocationAdapter.java
trunk/runtime/engine/src/main/java/org/jboss/soa/si/ws/BaseWebServiceEndpoint.java
trunk/runtime/jbossesb-bpel/src/main/java/org/jboss/internal/soa/esb/actions/bpel/ESBInvocationAdapter.java
Log:
To make InvocationAdapter independent of the ODE message, needed to create a
MessageAdapter to wrap the ODE message. Ideally we can simplify this whole mechanism, but
one issue is that ODE message needs to be initialised within the transaction controlled by
the BPELEngineImpl class - and ideally we don't want to create an intermediate class
just to carry the information.
Modified: trunk/integration-tests/pom.xml
===================================================================
--- trunk/integration-tests/pom.xml 2010-11-16 15:01:17 UTC (rev 1108)
+++ trunk/integration-tests/pom.xml 2010-11-16 20:45:11 UTC (rev 1109)
@@ -583,11 +583,11 @@
</systemProperties>
<testFailureIgnore>true</testFailureIgnore>
<includes>
+ <!--
<include>**/*TestCase.java</include>
<include>**/*Test.java</include>
- <!--
+ -->
<include>org/jboss/soa/bpel/tests/samples/QuickstartBPELHelloWorldTestCase.java</include>
- -->
</includes>
<!--
https://jira.jboss.org/jira/browse/RIFTSAW-34 -->
<excludes>
Modified:
trunk/runtime/engine/src/main/java/org/jboss/soa/bpel/runtime/engine/ode/BPELEngineImpl.java
===================================================================
---
trunk/runtime/engine/src/main/java/org/jboss/soa/bpel/runtime/engine/ode/BPELEngineImpl.java 2010-11-16
15:01:17 UTC (rev 1108)
+++
trunk/runtime/engine/src/main/java/org/jboss/soa/bpel/runtime/engine/ode/BPELEngineImpl.java 2010-11-16
20:45:11 UTC (rev 1109)
@@ -42,6 +42,7 @@
import org.apache.ode.utils.Properties;
import org.jboss.soa.bpel.runtime.engine.BPELEngine;
import org.jboss.soa.bpel.runtime.integration.ServerConfigFactory;
+import org.jboss.soa.bpel.runtime.ws.ODEMessageAdapter;
import org.jboss.soa.si.InvocationAdapter;
import org.w3c.dom.Element;
@@ -117,7 +118,7 @@
Message odeRequest =
odeMex.createMessage(odeMex.getOperation().getInput().getMessage().getQName());
// distinguish WS and ESB invocation
- invocationAdapter.parseRequest(odeMex, odeRequest);
+ invocationAdapter.initRequest(odeMex.getOperation(), new
ODEMessageAdapter(odeRequest));
// TODO: Might need to store session id/epr of caller?
//readHeader(msgContext, odeMex);
Added:
trunk/runtime/engine/src/main/java/org/jboss/soa/bpel/runtime/ws/ODEMessageAdapter.java
===================================================================
---
trunk/runtime/engine/src/main/java/org/jboss/soa/bpel/runtime/ws/ODEMessageAdapter.java
(rev 0)
+++
trunk/runtime/engine/src/main/java/org/jboss/soa/bpel/runtime/ws/ODEMessageAdapter.java 2010-11-16
20:45:11 UTC (rev 1109)
@@ -0,0 +1,43 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, Red Hat Middleware LLC, and others contributors as indicated
+ * by the @authors tag. All rights reserved.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ * You should have received a copy of the GNU Lesser General Public License,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+package org.jboss.soa.bpel.runtime.ws;
+
+import org.apache.ode.bpel.iapi.Message;
+import org.jboss.soa.si.MessageAdapter;
+
+public class ODEMessageAdapter implements MessageAdapter {
+
+ private Message m_message=null;
+
+ public ODEMessageAdapter(Message mesg) {
+ m_message = mesg;
+ }
+
+ public void setPart(String name, org.w3c.dom.Element elem) {
+ if (name == null) {
+ m_message.setMessage(elem);
+ } else {
+ m_message.setPart(name, elem);
+ }
+ }
+
+ public void setHeaderPart(String name, org.w3c.dom.Element elem) {
+ m_message.setHeaderPart(name, elem);
+ }
+
+}
Modified:
trunk/runtime/engine/src/main/java/org/jboss/soa/bpel/runtime/ws/WSInvocationAdapter.java
===================================================================
---
trunk/runtime/engine/src/main/java/org/jboss/soa/bpel/runtime/ws/WSInvocationAdapter.java 2010-11-16
15:01:17 UTC (rev 1108)
+++
trunk/runtime/engine/src/main/java/org/jboss/soa/bpel/runtime/ws/WSInvocationAdapter.java 2010-11-16
20:45:11 UTC (rev 1109)
@@ -24,6 +24,7 @@
import org.apache.ode.bpel.iapi.Message;
import org.apache.ode.bpel.iapi.MyRoleMessageExchange;
import org.jboss.soa.si.InvocationAdapter;
+import org.jboss.soa.si.MessageAdapter;
import org.jboss.soa.si.ws.SOAPMessageAdapter;
import javax.xml.namespace.QName;
@@ -69,12 +70,12 @@
return portName;
}
- public void parseRequest(MyRoleMessageExchange mex, Message request)
+ public void initRequest(javax.wsdl.Operation op, MessageAdapter request)
{
if(null==soapRequestMessage)
throw new IllegalArgumentException("No request SOAPMessage set");
- soapAdapter.parseSoapRequest(request, soapRequestMessage, mex.getOperation());
+ soapAdapter.parseSoapRequest(request, soapRequestMessage, op);
}
public void createResponse(MyRoleMessageExchange mex)
Modified:
trunk/runtime/engine/src/main/java/org/jboss/soa/bpel/runtime/ws/WebServiceClient.java
===================================================================
---
trunk/runtime/engine/src/main/java/org/jboss/soa/bpel/runtime/ws/WebServiceClient.java 2010-11-16
15:01:17 UTC (rev 1108)
+++
trunk/runtime/engine/src/main/java/org/jboss/soa/bpel/runtime/ws/WebServiceClient.java 2010-11-16
20:45:11 UTC (rev 1109)
@@ -279,7 +279,8 @@
}
else
{
-
messageAdapter.parseSoapResponse(odeResponse,soapResponseMessage,mex.getOperation());
+ messageAdapter.parseSoapResponse(new ODEMessageAdapter(odeResponse),
+ soapResponseMessage,mex.getOperation());
mex.reply(odeResponse);
}
Modified: trunk/runtime/engine/src/main/java/org/jboss/soa/si/InvocationAdapter.java
===================================================================
--- trunk/runtime/engine/src/main/java/org/jboss/soa/si/InvocationAdapter.java 2010-11-16
15:01:17 UTC (rev 1108)
+++ trunk/runtime/engine/src/main/java/org/jboss/soa/si/InvocationAdapter.java 2010-11-16
20:45:11 UTC (rev 1109)
@@ -50,7 +50,7 @@
* @param mex
* @param odeRequest
*/
- void parseRequest(MyRoleMessageExchange mex, Message odeRequest);
+ void initRequest(javax.wsdl.Operation op, MessageAdapter request);
/**
* Callback from the Engine towards the adapter when
Added: trunk/runtime/engine/src/main/java/org/jboss/soa/si/MessageAdapter.java
===================================================================
--- trunk/runtime/engine/src/main/java/org/jboss/soa/si/MessageAdapter.java
(rev 0)
+++ trunk/runtime/engine/src/main/java/org/jboss/soa/si/MessageAdapter.java 2010-11-16
20:45:11 UTC (rev 1109)
@@ -0,0 +1,26 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, Red Hat Middleware LLC, and others contributors as indicated
+ * by the @authors tag. All rights reserved.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ * You should have received a copy of the GNU Lesser General Public License,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+package org.jboss.soa.si;
+
+public interface MessageAdapter {
+
+ public void setPart(String name, org.w3c.dom.Element elem);
+
+ public void setHeaderPart(String name, org.w3c.dom.Element elem);
+
+}
Modified:
trunk/runtime/engine/src/main/java/org/jboss/soa/si/ws/BaseWebServiceEndpoint.java
===================================================================
---
trunk/runtime/engine/src/main/java/org/jboss/soa/si/ws/BaseWebServiceEndpoint.java 2010-11-16
15:01:17 UTC (rev 1108)
+++
trunk/runtime/engine/src/main/java/org/jboss/soa/si/ws/BaseWebServiceEndpoint.java 2010-11-16
20:45:11 UTC (rev 1109)
@@ -24,7 +24,6 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.jboss.soa.bpel.runtime.ws.ODEWebServiceFactory;
import org.jboss.soa.bpel.runtime.ws.WSInvocationAdapter;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
Deleted: trunk/runtime/engine/src/main/java/org/jboss/soa/si/ws/SOAPMessageAdapter.java
===================================================================
---
trunk/runtime/engine/src/main/java/org/jboss/soa/si/ws/SOAPMessageAdapter.java 2010-11-16
15:01:17 UTC (rev 1108)
+++
trunk/runtime/engine/src/main/java/org/jboss/soa/si/ws/SOAPMessageAdapter.java 2010-11-16
20:45:11 UTC (rev 1109)
@@ -1,644 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2006, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
- */
-package org.jboss.soa.si.ws;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.ode.bpel.iapi.Message;
-import org.apache.ode.utils.DOMUtils;
-import org.apache.ode.utils.stl.CollectionsX;
-import org.apache.ode.utils.wsdl.WsdlUtils;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-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.*;
-
-/**
- * Adopts {@link javax.xml.soap.SOAPMessage}'s to ODE's internal
- * {@link org.apache.ode.bpel.iapi.Message} representation and vice versa.
- *
- * @see org.jboss.soa.bpel.runtime.ws.WebServiceClient
- *
- * @author Heiko.Braun <heiko.braun(a)jboss.com>
- */
-public class SOAPMessageAdapter
-{
- protected final Log log = LogFactory.getLog(getClass());
-
- private Definition wsdl;
- private QName serviceName;
-
- private String portName;
- private Service serviceDef;
- private Binding binding;
-
- private Port port;
- private boolean isRPC;
-
- private SOAPBinding soapBinding;
-
- private SOAPFactory soapFactory;
-
- public SOAPMessageAdapter(Definition wsdl, QName serviceName, String portName)
- {
- this.wsdl = wsdl;
- this.serviceName = serviceName;
- this.portName = portName;
-
- serviceDef = wsdl.getService(serviceName);
- if (serviceDef == null)
- throw new RuntimeException("Service not found "+serviceName);
-
- port = serviceDef.getPort(portName);
- if (port == null)
- throw new RuntimeException("Port '"+portName+"' not found on
service: "+serviceName);
-
- binding = port.getBinding();
- if (binding == null)
- throw new RuntimeException("No binding for port "+portName);
-
- if (!WsdlUtils.useSOAPBinding(port)) {
- throw new RuntimeException("No SOAP binding for port"+portName);
- }
- soapBinding = (SOAPBinding) WsdlUtils.getBindingExtension(port);
-
-
- String style = soapBinding.getStyle();
- isRPC = style != null && style.equals("rpc");
-
- try
- {
- this.soapFactory = SOAPFactory.newInstance();
- }
- catch (SOAPException e)
- {
- throw new RuntimeException(e);
- }
- }
-
- /**
- * This method creates the SOAP request and returns the SOAPAction field.
- *
- * @param soapMessage
- * @param odeRequestMessage
- * @param wsdlOperation
- * @return The SOAP action
- */
- public String createSoapRequest(SOAPMessage soapMessage, Message odeRequestMessage,
Operation wsdlOperation)
- {
- String ret=null;
-
- BindingOperation bop = binding.getBindingOperation(wsdlOperation.getName(), null,
null);
- if (bop == null)
- throw new RuntimeException("Operation "+wsdlOperation.getName()+"not
found on "+serviceName+"/"+portName);
-
- BindingInput bi = bop.getBindingInput();
- if (bi == null)
- throw new RuntimeException("Binding input not found on
"+serviceName+"/"+portName);
-
- // Headers
- createSoapHeaders(
- soapMessage,
- getSOAPHeaders(bi),
- wsdlOperation.getInput().getMessage(),
- odeRequestMessage.getHeaderParts(),
- odeRequestMessage.getMessage()
- );
-
-
- // SOAP Body
- javax.wsdl.extensions.soap.SOAPBody wsdlSoapBody = getSOAPBody(bi);
-
- createSoapBody(
- soapMessage,
- wsdlSoapBody,
- wsdlOperation.getInput().getMessage(),
- odeRequestMessage.getMessage(),
- wsdlOperation.getName()
- );
-
- // Discover SOAPAction
- for (Object extension : bop.getExtensibilityElements()) {
- if (extension instanceof javax.wsdl.extensions.soap.SOAPOperation) {
- javax.wsdl.extensions.soap.SOAPOperation soapop=
- (javax.wsdl.extensions.soap.SOAPOperation)extension;
-
- if (soapop.getSoapActionURI() != null) {
- ret = soapop.getSoapActionURI();
- break;
- }
- }
- }
-
- return(ret);
- }
-
- public boolean isRPC()
- {
- return isRPC;
- }
-
- public void createSoapResponse(SOAPMessage soapMessage, Message odeResponseMessage,
Operation wsdlOperation)
- {
-
- BindingOperation bop =
binding.getBindingOperation(wsdlOperation.getName(),null,null);
- if (bop == null)
- throw new RuntimeException("Operation "+wsdlOperation.getName()+"not
found on "+serviceName+"/"+portName);
-
- BindingOutput bo = bop.getBindingOutput();
- if (bo == null)
- throw new RuntimeException("Binding output not found on
"+serviceName+"/"+portName);
-
- // Headers
- if (odeResponseMessage.getHeaderParts().size() > 0 || getSOAPHeaders(bo).size()
> 0)
- createSoapHeaders(
- soapMessage,
- getSOAPHeaders(bo),
- wsdlOperation.getOutput().getMessage(),
- odeResponseMessage.getHeaderParts(),
- odeResponseMessage.getMessage()
- );
-
-
- // SOAP Body
- javax.wsdl.extensions.soap.SOAPBody wsdlSOAPBody = getSOAPBody(bo);
- createSoapBody(
- soapMessage,
- wsdlSOAPBody,
- wsdlOperation.getOutput().getMessage(),
- odeResponseMessage.getMessage(),
- wsdlOperation.getName() + "Response"
- );
-
- }
-
- private void createSoapBody(SOAPMessage soapMessage,
- javax.wsdl.extensions.soap.SOAPBody wsdlSoapBody,
javax.wsdl.Message wsdlMessageDef,
- Element message, String operationName)
- {
- try
- {
- SOAPBody soapBody = soapMessage.getSOAPBody();
-
- SOAPElement partHolder = null;
- if(isRPC)
- {
- partHolder = soapFactory.createElement(new QName(wsdlSoapBody.getNamespaceURI(),
operationName, "odens"));
- }
- else
- {
- partHolder = soapBody;
- }
-
- List<Part> parts = wsdlMessageDef.getOrderedParts(wsdlSoapBody.getParts());
- for(Part part : parts)
- {
- Element srcPartEl = DOMUtils.findChildByName(message, new QName(null,
part.getName()));
- if (srcPartEl == null)
- throw new RuntimeException("Part is missing: " +part.getName());
-
- SOAPElement partElement = soapFactory.createElement(srcPartEl);
- if (isRPC)
- {
- partHolder.addChildElement(partElement);
- }
- else
- {
- for (Iterator<SOAPElement> i = partElement.getChildElements();
i.hasNext();) partHolder.addChildElement(i.next());
- }
- }
-
- // late bind
- if(isRPC)
- soapBody.addChildElement(partHolder);
- }
- catch (SOAPException e)
- {
- throw new RuntimeException("Failed to create soap body",e);
- }
- }
-
- private void createSoapHeaders(SOAPMessage soapMessage, List<SOAPHeader>
headers,
- javax.wsdl.Message wsdlMessageDef,
- Map<String, Node> headerParts, Element message)
- {
- try {
- javax.xml.soap.SOAPHeader soapHeader = soapMessage.getSOAPHeader();
- if (soapHeader==null) soapHeader =
soapMessage.getSOAPPart().getEnvelope().addHeader();
- for (Node headerNode : headerParts.values()) {
- //like we may have password header with null value.
- if(headerNode == null){
- continue;
- }
- if (Node.ELEMENT_NODE == headerNode.getNodeType()) {
- 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);
- }
- }
-
- //Add soap header according to binding.
- for (SOAPHeader header : headers) {
- Element headerEl = DOMUtils.findChildByName(message, new QName(null,
header.getPart()));
- if (headerEl != null) {
-
- // RIFTSAW-305 - don't think the part name should be added to the SOAP header
- //SOAPElement soapHeaderEl = soapFactory.createElement(new
QName(header.getMessage().getNamespaceURI(), header.getPart(),"odens"));
- NodeList list = headerEl.getChildNodes();
- for(int i=0; i< list.getLength(); i++) {
- SOAPElement partElement = soapFactory.createElement((Element)list.item(i));
- soapHeader.addChildElement(partElement);
- }
- //soapHeader.addChildElement(soapHeaderEl);
- }
- }
- } catch (SOAPException e) {
- throw new RuntimeException("Failed to create soap header",e);
- }
- }
-
- public void parseSoapResponse(org.apache.ode.bpel.iapi.Message odeMessage,
- SOAPMessage soapMessage, javax.wsdl.Operation
odeOperation) {
- BindingOperation bop = binding.getBindingOperation(odeOperation.getName(), null,
null);
- if (bop == null)
- throw new RuntimeException("Operation "+odeOperation.getName()+"not
found on "+serviceName+"/"+portName);
-
- BindingOutput bo = bop.getBindingOutput();
- if (bo == null)
- throw new RuntimeException("Binding output not found on
"+serviceName+"/"+portName);
-
- extractSoapBodyParts(odeMessage, soapMessage, getSOAPBody(bo),
odeOperation.getOutput().getMessage(), odeOperation.getName() + "Response");
- extractSoapHeaderParts(odeMessage, soapMessage, getSOAPHeaders(bo),
odeOperation.getOutput().getMessage());
- }
-
- public void parseSoapRequest(
- org.apache.ode.bpel.iapi.Message odeMessage,
- SOAPMessage soapMessage,
- Operation op)
- {
-
- BindingOperation bop = binding.getBindingOperation(op.getName(), null, null);
-
- if (bop == null)
- throw new RuntimeException("Binding operation not found
("+serviceName+"/"+portName);
-
- BindingInput bi = bop.getBindingInput();
- if (bi == null)
- throw new RuntimeException("Binding input not
found"+serviceName+"/"+portName);
-
- extractSoapBodyParts(odeMessage, soapMessage, getSOAPBody(bi),
op.getInput().getMessage(), op.getName());
- extractSoapHeaderParts(odeMessage, soapMessage, getSOAPHeaders(bi),
op.getInput().getMessage());
- }
-
- public void createSoapFault(SOAPMessage soapMessage, Element message, QName faultName,
Operation op)
- {
- try
- {
- Element detail = buildSoapDetail(message, faultName, op);
- SOAPFault fault = soapMessage.getSOAPBody().addFault();
- fault.setFaultCode(faultName);
- if(detail!=null)
- fault.addDetail().addChildElement(soapFactory.createElement(detail));
- }
- catch (SOAPException e)
- {
- throw new RuntimeException("Failed to create fault", e);
- }
- }
-
- private Element buildSoapDetail(Element message, QName faultName, Operation op)
- {
- if (faultName.getNamespaceURI() == null)
- return toFaultDetail(faultName, message);
- if (op == null) {
- return toFaultDetail(faultName, message);
- }
- Fault f = op.getFault(faultName.getLocalPart());
- if (f == null)
- return toFaultDetail(faultName, message);
-
- // For faults, there will be exactly one part.
- Part p = (Part)f.getMessage().getParts().values().iterator().next();
- if (p == null)
- return toFaultDetail(faultName, message);
- Element partEl= DOMUtils.findChildByName(message,new QName(null,p.getName()));
- if (partEl == null)
- return toFaultDetail(faultName, message);
- Element detail = DOMUtils.findChildByName(partEl, p.getElementName());
- if (detail == null)
- return toFaultDetail(faultName, message);
-
- return detail;
- }
-
- private Element toFaultDetail(QName fault, Element message) {
- if (message == null) return null;
- Element firstPart = DOMUtils.getFirstChildElement(message);
- if (firstPart == null) return null;
- Element detail = DOMUtils.getFirstChildElement(firstPart);
- if (detail == null) return firstPart;
- return detail;
- }
-
- private void extractSoapHeaderParts(Message odeMessage, SOAPMessage soapMessage,
List<SOAPHeader> headerDefs,javax.wsdl.Message wsdlMessageDef)
- {
- 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.
- if (soapHeader != null) {
- Iterator headersIter = soapHeader.getChildElements();
- while (headersIter.hasNext()) {
- Object obj=headersIter.next();
-
- // Should be SOAPHeaderElement, but CXF also returns javax.xml.soap.Text
- // objects aswell
- if (obj instanceof javax.xml.soap.SOAPHeaderElement) {
- javax.xml.soap.SOAPHeaderElement headerElem =
(javax.xml.soap.SOAPHeaderElement) obj;
- String partName = findHeaderPartName(headerDefs,
headerElem.getElementQName());
- Document doc = DOMUtils.newDocument();
-
- // RIFTSAW-74 - slight modification to avoid jbossws exception when
reconstructing the
- // SOAP message.
-
- //Element destPart = doc.createElementNS(null, partName);
- //destPart.appendChild(doc.importNode(headerElem, true));
- //odeMessage.setHeaderPart(partName, destPart);
- odeMessage.setHeaderPart(partName, (Element)doc.importNode(headerElem, true));
- }
- }
- }
- }
- 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() != null &&
- 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 ||
Boolean.TRUE.equals(headerdef.getRequired());
-
- if (header == null) {
- if (requiredHeader)
- throw new RuntimeException("Soap Header is missing a required field " +
headerdef.getElementType());
-
- 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;
-
- /* RIFTSAW-127 - this was duplicating the header part in the consolidated (merged)
message stored in the
- * BPEL process - but this code actually causes two levels of 'part' to be
defined - e.g.
- * <conversionId><conversationId><details ....
/></conversatioId></conversationId>
- 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,
- javax.wsdl.extensions.soap.SOAPBody wsdlSOAPBody,
- javax.wsdl.Message wsdlMessageDef, String operationName)
- {
- try
- {
- SOAPBody soapBody = soapMessage.getSOAPBody();
- List<Part> parts = wsdlMessageDef.getOrderedParts(wsdlSOAPBody.getParts());
-
- if(isRPC)
- {
- // In RPC the body element is the operation name, wrapping parts. Order
doesn't really matter as far as
- // we're concerned. All we need to do is copy the soap:body children, since
doc-lit rpc looks the same
- // in ode and soap.
-
- QName rpcWrapQName = new QName(wsdlSOAPBody.getNamespaceURI(), operationName);
- SOAPElement partWrapper = getFirstChildWithName(rpcWrapQName, soapBody);
-
- if (partWrapper == null)
- throw new RuntimeException("Expected part wrapper
'"+rpcWrapQName+"'missing on
service:"+serviceName+"/"+portName);
-
- for(Part part : parts)
- {
- SOAPElement srcPart = getFirstChildWithName(new QName(null, part.getName()),
partWrapper);
- if (srcPart == null)
- throw new RuntimeException("Soap body does not contain required part
+"+part.getName());
-
- odeMessage.setPart(srcPart.getLocalName(), srcPart);
- }
- }
- else
- {
- // In doc-literal style, we expect the elements in the body to correspond (in
order)
- // to the parts defined in the binding.
- // All the parts should be element-typed, otherwise it is a mess.
- List<SOAPElement> childElements = new ArrayList<SOAPElement>();
- final Iterator children = soapBody.getChildElements() ;
- while(children.hasNext())
- {
- final Node node = (Node)children.next() ;
- if (node instanceof SOAPElement)
- childElements.add((SOAPElement)node);
- }
-
- Iterator<SOAPElement> srcParts = childElements.iterator();
- for(Part part : parts)
- {
- SOAPElement srcPart = srcParts.next();
- Document doc = DOMUtils.newDocument();
- Element destPart = doc.createElementNS(null, part.getName());
- destPart.appendChild(doc.importNode(srcPart, true));
- odeMessage.setPart(part.getName(), destPart);
- }
- }
- }
- catch (SOAPException e)
- {
- throw new RuntimeException("Failed to extract soap body parts", e);
- }
- }
-
- private static SOAPElement getFirstChildWithName(QName name, SOAPElement parent)
- {
- SOAPElement match = null;
- Iterator iterator = parent.getChildElements(name);
- while(iterator.hasNext())
- {
- match= (SOAPElement)iterator.next();
- }
- return match;
- }
-
- /*private static Element cloneElement(Element source)
- {
- // TODO:
https://jira.jboss.org/jira/browse/RIFTSAW-38
- // For now create a deep copy (performance hit)
- try
- {
- DocumentBuilder builder =
DocumentBuilderFactory.newInstance().newDocumentBuilder();
- Document doc = builder.newDocument();
- return (Element)doc.importNode(source, true);
- }
- catch (ParserConfigurationException e)
- {
- throw new RuntimeException(e);
- }
- } */
-
- public static <T> T getFirstExtensibilityElement(ElementExtensible parent,
Class<T> cls) {
- Collection<T> ee = CollectionsX.filter(parent.getExtensibilityElements(),
cls);
-
- return ee.isEmpty() ? null : ee.iterator().next();
-
- }
-
- public static javax.wsdl.extensions.soap.SOAPBody getSOAPBody(ElementExtensible ee) {
- return getFirstExtensibilityElement(ee, javax.wsdl.extensions.soap.SOAPBody.class);
- }
-
- public static List<SOAPHeader> getSOAPHeaders(ElementExtensible eee) {
- return CollectionsX.filter(new ArrayList<SOAPHeader>(),
(Collection<Object>) eee.getExtensibilityElements(),
- SOAPHeader.class);
- }
-
- public static Fault parseSoapFault(
- Element odeMessage,
- SOAPMessage soapMessage,
- javax.wsdl.Operation operation)
- {
- Fault fdef = null;
- try
- {
- SOAPFault flt = soapMessage.getSOAPBody().getFault();
- Detail detail = flt.getDetail();
- fdef = inferFault(operation, flt);
- if(fdef!=null)
- {
- Part pdef = (Part)fdef.getMessage().getParts().values().iterator().next();
- Element partel =
odeMessage.getOwnerDocument().createElementNS(null,pdef.getName());
- odeMessage.appendChild(partel);
-
- Element childByName = DOMUtils.findChildByName(detail, pdef.getElementName());
- if (childByName != null)
- {
- partel.appendChild(odeMessage.getOwnerDocument().importNode(childByName,
true));
- }
- else
- {
- partel.appendChild(odeMessage.getOwnerDocument().importNode(detail,true));
- }
- }
- }
- catch (Exception e)
- {
- throw new RuntimeException("Failed to parse SOAP Fault",e);
- }
-
- return fdef;
- }
-
- public static Fault parseSoapFault(
- Element odeMessage,
- SOAPFault flt,
- javax.wsdl.Operation operation)
- {
- Fault fault=inferFault(operation, flt);
-
- if(fault!=null)
- {
- Detail detail = flt.getDetail();
- Part pdef = (Part)fault.getMessage().getParts().values().iterator().next();
- Element partel =
odeMessage.getOwnerDocument().createElementNS(null,pdef.getName());
- odeMessage.appendChild(partel);
-
- Element childByName = DOMUtils.findChildByName(detail, pdef.getElementName());
- if (childByName != null)
- {
- partel.appendChild(odeMessage.getOwnerDocument().importNode(childByName,
true));
- }
- else
- {
- partel.appendChild(odeMessage.getOwnerDocument().importNode(detail,true));
- }
- }
-
- return fault;
- }
-
- private static Fault inferFault(Operation operation, SOAPFault flt) {
- if (!flt.hasDetail())
- return null;
- // The detail is a dummy <detail> node containing the interesting fault
element
- Element element = DOMUtils.getFirstChildElement(flt.getDetail());
-
- if (element == null) {
- return(null);
- }
-
- QName elName=new QName(element.getNamespaceURI(), element.getLocalName());
- return WsdlUtils.inferFault(operation, elName);
- }
-}
Copied: trunk/runtime/engine/src/main/java/org/jboss/soa/si/ws/SOAPMessageAdapter.java
(from rev 1107,
trunk/runtime/engine/src/main/java/org/jboss/soa/si/ws/SOAPMessageAdapter.java)
===================================================================
--- trunk/runtime/engine/src/main/java/org/jboss/soa/si/ws/SOAPMessageAdapter.java
(rev 0)
+++
trunk/runtime/engine/src/main/java/org/jboss/soa/si/ws/SOAPMessageAdapter.java 2010-11-16
20:45:11 UTC (rev 1109)
@@ -0,0 +1,645 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.soa.si.ws;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ode.bpel.iapi.Message;
+import org.apache.ode.utils.DOMUtils;
+import org.apache.ode.utils.stl.CollectionsX;
+import org.apache.ode.utils.wsdl.WsdlUtils;
+import org.jboss.soa.bpel.runtime.ws.WebServiceClient;
+import org.jboss.soa.si.MessageAdapter;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+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.*;
+
+/**
+ * Adopts {@link javax.xml.soap.SOAPMessage}'s to ODE's internal
+ * {@link org.apache.ode.bpel.iapi.Message} representation and vice versa.
+ *
+ * @see org.jboss.soa.bpel.runtime.ws.WebServiceClient
+ *
+ * @author Heiko.Braun <heiko.braun(a)jboss.com>
+ */
+public class SOAPMessageAdapter
+{
+ protected final Log log = LogFactory.getLog(getClass());
+
+ private Definition wsdl;
+ private QName serviceName;
+
+ private String portName;
+ private Service serviceDef;
+ private Binding binding;
+
+ private Port port;
+ private boolean isRPC;
+
+ private SOAPBinding soapBinding;
+
+ private SOAPFactory soapFactory;
+
+ public SOAPMessageAdapter(Definition wsdl, QName serviceName, String portName)
+ {
+ this.wsdl = wsdl;
+ this.serviceName = serviceName;
+ this.portName = portName;
+
+ serviceDef = wsdl.getService(serviceName);
+ if (serviceDef == null)
+ throw new RuntimeException("Service not found "+serviceName);
+
+ port = serviceDef.getPort(portName);
+ if (port == null)
+ throw new RuntimeException("Port '"+portName+"' not found on
service: "+serviceName);
+
+ binding = port.getBinding();
+ if (binding == null)
+ throw new RuntimeException("No binding for port "+portName);
+
+ if (!WsdlUtils.useSOAPBinding(port)) {
+ throw new RuntimeException("No SOAP binding for port"+portName);
+ }
+ soapBinding = (SOAPBinding) WsdlUtils.getBindingExtension(port);
+
+
+ String style = soapBinding.getStyle();
+ isRPC = style != null && style.equals("rpc");
+
+ try
+ {
+ this.soapFactory = SOAPFactory.newInstance();
+ }
+ catch (SOAPException e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * This method creates the SOAP request and returns the SOAPAction field.
+ *
+ * @param soapMessage
+ * @param odeRequestMessage
+ * @param wsdlOperation
+ * @return The SOAP action
+ */
+ public String createSoapRequest(SOAPMessage soapMessage, Message odeRequestMessage,
Operation wsdlOperation)
+ {
+ String ret=null;
+
+ BindingOperation bop = binding.getBindingOperation(wsdlOperation.getName(), null,
null);
+ if (bop == null)
+ throw new RuntimeException("Operation "+wsdlOperation.getName()+"not
found on "+serviceName+"/"+portName);
+
+ BindingInput bi = bop.getBindingInput();
+ if (bi == null)
+ throw new RuntimeException("Binding input not found on
"+serviceName+"/"+portName);
+
+ // Headers
+ createSoapHeaders(
+ soapMessage,
+ getSOAPHeaders(bi),
+ wsdlOperation.getInput().getMessage(),
+ odeRequestMessage.getHeaderParts(),
+ odeRequestMessage.getMessage()
+ );
+
+
+ // SOAP Body
+ javax.wsdl.extensions.soap.SOAPBody wsdlSoapBody = getSOAPBody(bi);
+
+ createSoapBody(
+ soapMessage,
+ wsdlSoapBody,
+ wsdlOperation.getInput().getMessage(),
+ odeRequestMessage.getMessage(),
+ wsdlOperation.getName()
+ );
+
+ // Discover SOAPAction
+ for (Object extension : bop.getExtensibilityElements()) {
+ if (extension instanceof javax.wsdl.extensions.soap.SOAPOperation) {
+ javax.wsdl.extensions.soap.SOAPOperation soapop=
+ (javax.wsdl.extensions.soap.SOAPOperation)extension;
+
+ if (soapop.getSoapActionURI() != null) {
+ ret = soapop.getSoapActionURI();
+ break;
+ }
+ }
+ }
+
+ return(ret);
+ }
+
+ public boolean isRPC()
+ {
+ return isRPC;
+ }
+
+ public void createSoapResponse(SOAPMessage soapMessage, Message odeResponseMessage,
Operation wsdlOperation)
+ {
+
+ BindingOperation bop =
binding.getBindingOperation(wsdlOperation.getName(),null,null);
+ if (bop == null)
+ throw new RuntimeException("Operation "+wsdlOperation.getName()+"not
found on "+serviceName+"/"+portName);
+
+ BindingOutput bo = bop.getBindingOutput();
+ if (bo == null)
+ throw new RuntimeException("Binding output not found on
"+serviceName+"/"+portName);
+
+ // Headers
+ if (odeResponseMessage.getHeaderParts().size() > 0 || getSOAPHeaders(bo).size()
> 0)
+ createSoapHeaders(
+ soapMessage,
+ getSOAPHeaders(bo),
+ wsdlOperation.getOutput().getMessage(),
+ odeResponseMessage.getHeaderParts(),
+ odeResponseMessage.getMessage()
+ );
+
+
+ // SOAP Body
+ javax.wsdl.extensions.soap.SOAPBody wsdlSOAPBody = getSOAPBody(bo);
+ createSoapBody(
+ soapMessage,
+ wsdlSOAPBody,
+ wsdlOperation.getOutput().getMessage(),
+ odeResponseMessage.getMessage(),
+ wsdlOperation.getName() + "Response"
+ );
+
+ }
+
+ private void createSoapBody(SOAPMessage soapMessage,
+ javax.wsdl.extensions.soap.SOAPBody wsdlSoapBody,
javax.wsdl.Message wsdlMessageDef,
+ Element message, String operationName)
+ {
+ try
+ {
+ SOAPBody soapBody = soapMessage.getSOAPBody();
+
+ SOAPElement partHolder = null;
+ if(isRPC)
+ {
+ partHolder = soapFactory.createElement(new QName(wsdlSoapBody.getNamespaceURI(),
operationName, "odens"));
+ }
+ else
+ {
+ partHolder = soapBody;
+ }
+
+ List<Part> parts = wsdlMessageDef.getOrderedParts(wsdlSoapBody.getParts());
+ for(Part part : parts)
+ {
+ Element srcPartEl = DOMUtils.findChildByName(message, new QName(null,
part.getName()));
+ if (srcPartEl == null)
+ throw new RuntimeException("Part is missing: " +part.getName());
+
+ SOAPElement partElement = soapFactory.createElement(srcPartEl);
+ if (isRPC)
+ {
+ partHolder.addChildElement(partElement);
+ }
+ else
+ {
+ for (Iterator<SOAPElement> i = partElement.getChildElements();
i.hasNext();) partHolder.addChildElement(i.next());
+ }
+ }
+
+ // late bind
+ if(isRPC)
+ soapBody.addChildElement(partHolder);
+ }
+ catch (SOAPException e)
+ {
+ throw new RuntimeException("Failed to create soap body",e);
+ }
+ }
+
+ private void createSoapHeaders(SOAPMessage soapMessage, List<SOAPHeader>
headers,
+ javax.wsdl.Message wsdlMessageDef,
+ Map<String, Node> headerParts, Element message)
+ {
+ try {
+ javax.xml.soap.SOAPHeader soapHeader = soapMessage.getSOAPHeader();
+ if (soapHeader==null) soapHeader =
soapMessage.getSOAPPart().getEnvelope().addHeader();
+ for (Node headerNode : headerParts.values()) {
+ //like we may have password header with null value.
+ if(headerNode == null){
+ continue;
+ }
+ if (Node.ELEMENT_NODE == headerNode.getNodeType()) {
+ 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);
+ }
+ }
+
+ //Add soap header according to binding.
+ for (SOAPHeader header : headers) {
+ Element headerEl = DOMUtils.findChildByName(message, new QName(null,
header.getPart()));
+ if (headerEl != null) {
+
+ // RIFTSAW-305 - don't think the part name should be added to the SOAP header
+ //SOAPElement soapHeaderEl = soapFactory.createElement(new
QName(header.getMessage().getNamespaceURI(), header.getPart(),"odens"));
+ NodeList list = headerEl.getChildNodes();
+ for(int i=0; i< list.getLength(); i++) {
+ SOAPElement partElement = soapFactory.createElement((Element)list.item(i));
+ soapHeader.addChildElement(partElement);
+ }
+ //soapHeader.addChildElement(soapHeaderEl);
+ }
+ }
+ } catch (SOAPException e) {
+ throw new RuntimeException("Failed to create soap header",e);
+ }
+ }
+
+ public void parseSoapResponse(MessageAdapter odeMessage,
+ SOAPMessage soapMessage, javax.wsdl.Operation
odeOperation) {
+ BindingOperation bop = binding.getBindingOperation(odeOperation.getName(), null,
null);
+ if (bop == null)
+ throw new RuntimeException("Operation "+odeOperation.getName()+"not
found on "+serviceName+"/"+portName);
+
+ BindingOutput bo = bop.getBindingOutput();
+ if (bo == null)
+ throw new RuntimeException("Binding output not found on
"+serviceName+"/"+portName);
+
+ extractSoapBodyParts(odeMessage, soapMessage, getSOAPBody(bo),
odeOperation.getOutput().getMessage(), odeOperation.getName() + "Response");
+ extractSoapHeaderParts(odeMessage, soapMessage, getSOAPHeaders(bo),
odeOperation.getOutput().getMessage());
+ }
+
+ public void parseSoapRequest(MessageAdapter odeMessage,
+ SOAPMessage soapMessage,
+ Operation op)
+ {
+
+ BindingOperation bop = binding.getBindingOperation(op.getName(), null, null);
+
+ if (bop == null)
+ throw new RuntimeException("Binding operation not found
("+serviceName+"/"+portName);
+
+ BindingInput bi = bop.getBindingInput();
+ if (bi == null)
+ throw new RuntimeException("Binding input not
found"+serviceName+"/"+portName);
+
+ extractSoapBodyParts(odeMessage, soapMessage, getSOAPBody(bi),
op.getInput().getMessage(), op.getName());
+ extractSoapHeaderParts(odeMessage, soapMessage, getSOAPHeaders(bi),
op.getInput().getMessage());
+ }
+
+ public void createSoapFault(SOAPMessage soapMessage, Element message, QName faultName,
Operation op)
+ {
+ try
+ {
+ Element detail = buildSoapDetail(message, faultName, op);
+ SOAPFault fault = soapMessage.getSOAPBody().addFault();
+ fault.setFaultCode(faultName);
+ if(detail!=null)
+ fault.addDetail().addChildElement(soapFactory.createElement(detail));
+ }
+ catch (SOAPException e)
+ {
+ throw new RuntimeException("Failed to create fault", e);
+ }
+ }
+
+ private Element buildSoapDetail(Element message, QName faultName, Operation op)
+ {
+ if (faultName.getNamespaceURI() == null)
+ return toFaultDetail(faultName, message);
+ if (op == null) {
+ return toFaultDetail(faultName, message);
+ }
+ Fault f = op.getFault(faultName.getLocalPart());
+ if (f == null)
+ return toFaultDetail(faultName, message);
+
+ // For faults, there will be exactly one part.
+ Part p = (Part)f.getMessage().getParts().values().iterator().next();
+ if (p == null)
+ return toFaultDetail(faultName, message);
+ Element partEl= DOMUtils.findChildByName(message,new QName(null,p.getName()));
+ if (partEl == null)
+ return toFaultDetail(faultName, message);
+ Element detail = DOMUtils.findChildByName(partEl, p.getElementName());
+ if (detail == null)
+ return toFaultDetail(faultName, message);
+
+ return detail;
+ }
+
+ private Element toFaultDetail(QName fault, Element message) {
+ if (message == null) return null;
+ Element firstPart = DOMUtils.getFirstChildElement(message);
+ if (firstPart == null) return null;
+ Element detail = DOMUtils.getFirstChildElement(firstPart);
+ if (detail == null) return firstPart;
+ return detail;
+ }
+
+ private void extractSoapHeaderParts(MessageAdapter odeMessage, SOAPMessage soapMessage,
List<SOAPHeader> headerDefs,javax.wsdl.Message wsdlMessageDef)
+ {
+ 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.
+ if (soapHeader != null) {
+ Iterator headersIter = soapHeader.getChildElements();
+ while (headersIter.hasNext()) {
+ Object obj=headersIter.next();
+
+ // Should be SOAPHeaderElement, but CXF also returns javax.xml.soap.Text
+ // objects aswell
+ if (obj instanceof javax.xml.soap.SOAPHeaderElement) {
+ javax.xml.soap.SOAPHeaderElement headerElem =
(javax.xml.soap.SOAPHeaderElement) obj;
+ String partName = findHeaderPartName(headerDefs,
headerElem.getElementQName());
+ Document doc = DOMUtils.newDocument();
+
+ // RIFTSAW-74 - slight modification to avoid jbossws exception when
reconstructing the
+ // SOAP message.
+
+ //Element destPart = doc.createElementNS(null, partName);
+ //destPart.appendChild(doc.importNode(headerElem, true));
+ //odeMessage.setHeaderPart(partName, destPart);
+ odeMessage.setHeaderPart(partName, (Element)doc.importNode(headerElem, true));
+ }
+ }
+ }
+ }
+ 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() != null &&
+ p.getElementName().equals(elmtName)) return p.getName();
+ }
+ }
+ return elmtName.getLocalPart();
+ }
+
+ private void handleSoapHeaderPartDef(Object 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 ||
Boolean.TRUE.equals(headerdef.getRequired());
+
+ if (header == null) {
+ if (requiredHeader)
+ throw new RuntimeException("Soap Header is missing a required field " +
headerdef.getElementType());
+
+ 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;
+
+ /* RIFTSAW-127 - this was duplicating the header part in the consolidated (merged)
message stored in the
+ * BPEL process - but this code actually causes two levels of 'part' to be
defined - e.g.
+ * <conversionId><conversationId><details ....
/></conversatioId></conversationId>
+ 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(
+ MessageAdapter odeMessage,
+ SOAPMessage soapMessage,
+ javax.wsdl.extensions.soap.SOAPBody wsdlSOAPBody,
+ javax.wsdl.Message wsdlMessageDef, String operationName)
+ {
+ try
+ {
+ SOAPBody soapBody = soapMessage.getSOAPBody();
+ List<Part> parts = wsdlMessageDef.getOrderedParts(wsdlSOAPBody.getParts());
+
+ if(isRPC)
+ {
+ // In RPC the body element is the operation name, wrapping parts. Order
doesn't really matter as far as
+ // we're concerned. All we need to do is copy the soap:body children, since
doc-lit rpc looks the same
+ // in ode and soap.
+
+ QName rpcWrapQName = new QName(wsdlSOAPBody.getNamespaceURI(), operationName);
+ SOAPElement partWrapper = getFirstChildWithName(rpcWrapQName, soapBody);
+
+ if (partWrapper == null)
+ throw new RuntimeException("Expected part wrapper
'"+rpcWrapQName+"'missing on
service:"+serviceName+"/"+portName);
+
+ for(Part part : parts)
+ {
+ Element srcPart = getFirstChildWithName(new QName(null, part.getName()),
partWrapper);
+ if (srcPart == null)
+ throw new RuntimeException("Soap body does not contain required part
+"+part.getName());
+
+ odeMessage.setPart(srcPart.getLocalName(), srcPart);
+ }
+ }
+ else
+ {
+ // In doc-literal style, we expect the elements in the body to correspond (in
order)
+ // to the parts defined in the binding.
+ // All the parts should be element-typed, otherwise it is a mess.
+ List<SOAPElement> childElements = new ArrayList<SOAPElement>();
+ final Iterator children = soapBody.getChildElements() ;
+ while(children.hasNext())
+ {
+ final Node node = (Node)children.next() ;
+ if (node instanceof SOAPElement)
+ childElements.add((SOAPElement)node);
+ }
+
+ Iterator<SOAPElement> srcParts = childElements.iterator();
+ for(Part part : parts)
+ {
+ SOAPElement srcPart = srcParts.next();
+ Document doc = DOMUtils.newDocument();
+ Element destPart = doc.createElementNS(null, part.getName());
+ destPart.appendChild(doc.importNode(srcPart, true));
+ odeMessage.setPart(part.getName(), destPart);
+ }
+ }
+ }
+ catch (SOAPException e)
+ {
+ throw new RuntimeException("Failed to extract soap body parts", e);
+ }
+ }
+
+ private static SOAPElement getFirstChildWithName(QName name, SOAPElement parent)
+ {
+ SOAPElement match = null;
+ Iterator iterator = parent.getChildElements(name);
+ while(iterator.hasNext())
+ {
+ match= (SOAPElement)iterator.next();
+ }
+ return match;
+ }
+
+ /*private static Element cloneElement(Element source)
+ {
+ // TODO:
https://jira.jboss.org/jira/browse/RIFTSAW-38
+ // For now create a deep copy (performance hit)
+ try
+ {
+ DocumentBuilder builder =
DocumentBuilderFactory.newInstance().newDocumentBuilder();
+ Document doc = builder.newDocument();
+ return (Element)doc.importNode(source, true);
+ }
+ catch (ParserConfigurationException e)
+ {
+ throw new RuntimeException(e);
+ }
+ } */
+
+ public static <T> T getFirstExtensibilityElement(ElementExtensible parent,
Class<T> cls) {
+ Collection<T> ee = CollectionsX.filter(parent.getExtensibilityElements(),
cls);
+
+ return ee.isEmpty() ? null : ee.iterator().next();
+
+ }
+
+ public static javax.wsdl.extensions.soap.SOAPBody getSOAPBody(ElementExtensible ee) {
+ return getFirstExtensibilityElement(ee, javax.wsdl.extensions.soap.SOAPBody.class);
+ }
+
+ public static List<SOAPHeader> getSOAPHeaders(ElementExtensible eee) {
+ return CollectionsX.filter(new ArrayList<SOAPHeader>(),
(Collection<Object>) eee.getExtensibilityElements(),
+ SOAPHeader.class);
+ }
+
+ public static Fault parseSoapFault(
+ Element odeMessage,
+ SOAPMessage soapMessage,
+ javax.wsdl.Operation operation)
+ {
+ Fault fdef = null;
+ try
+ {
+ SOAPFault flt = soapMessage.getSOAPBody().getFault();
+ Detail detail = flt.getDetail();
+ fdef = inferFault(operation, flt);
+ if(fdef!=null)
+ {
+ Part pdef = (Part)fdef.getMessage().getParts().values().iterator().next();
+ Element partel =
odeMessage.getOwnerDocument().createElementNS(null,pdef.getName());
+ odeMessage.appendChild(partel);
+
+ Element childByName = DOMUtils.findChildByName(detail, pdef.getElementName());
+ if (childByName != null)
+ {
+ partel.appendChild(odeMessage.getOwnerDocument().importNode(childByName,
true));
+ }
+ else
+ {
+ partel.appendChild(odeMessage.getOwnerDocument().importNode(detail,true));
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException("Failed to parse SOAP Fault",e);
+ }
+
+ return fdef;
+ }
+
+ public static Fault parseSoapFault(
+ Element odeMessage,
+ SOAPFault flt,
+ javax.wsdl.Operation operation)
+ {
+ Fault fault=inferFault(operation, flt);
+
+ if(fault!=null)
+ {
+ Detail detail = flt.getDetail();
+ Part pdef = (Part)fault.getMessage().getParts().values().iterator().next();
+ Element partel =
odeMessage.getOwnerDocument().createElementNS(null,pdef.getName());
+ odeMessage.appendChild(partel);
+
+ Element childByName = DOMUtils.findChildByName(detail, pdef.getElementName());
+ if (childByName != null)
+ {
+ partel.appendChild(odeMessage.getOwnerDocument().importNode(childByName,
true));
+ }
+ else
+ {
+ partel.appendChild(odeMessage.getOwnerDocument().importNode(detail,true));
+ }
+ }
+
+ return fault;
+ }
+
+ private static Fault inferFault(Operation operation, SOAPFault flt) {
+ if (!flt.hasDetail())
+ return null;
+ // The detail is a dummy <detail> node containing the interesting fault
element
+ Element element = DOMUtils.getFirstChildElement(flt.getDetail());
+
+ if (element == null) {
+ return(null);
+ }
+
+ QName elName=new QName(element.getNamespaceURI(), element.getLocalName());
+ return WsdlUtils.inferFault(operation, elName);
+ }
+}
Modified:
trunk/runtime/jbossesb-bpel/src/main/java/org/jboss/internal/soa/esb/actions/bpel/ESBInvocationAdapter.java
===================================================================
---
trunk/runtime/jbossesb-bpel/src/main/java/org/jboss/internal/soa/esb/actions/bpel/ESBInvocationAdapter.java 2010-11-16
15:01:17 UTC (rev 1108)
+++
trunk/runtime/jbossesb-bpel/src/main/java/org/jboss/internal/soa/esb/actions/bpel/ESBInvocationAdapter.java 2010-11-16
20:45:11 UTC (rev 1109)
@@ -24,6 +24,7 @@
import org.apache.ode.bpel.iapi.Message;
import org.apache.ode.bpel.iapi.MyRoleMessageExchange;
import org.jboss.soa.si.InvocationAdapter;
+import org.jboss.soa.si.MessageAdapter;
import org.w3c.dom.Element;
import javax.xml.namespace.QName;
@@ -80,11 +81,11 @@
this.requestHeaderParts = headerParts;
}
- public void parseRequest(MyRoleMessageExchange mex, Message request)
+ public void initRequest(javax.wsdl.Operation op, MessageAdapter request)
{
if(null==this.requestXML)
throw new IllegalArgumentException("request XML not set");
- request.setMessage(this.requestXML);
+ request.setPart(null, this.requestXML);
if (requestHeaderParts != null) {
for (String part : requestHeaderParts.keySet()) {