antelder 2003/01/07 04:03:02
Modified: java/src/org/apache/wsif/providers/soap/apacheaxis
MIMEHelper.java WSIFOperation_ApacheAxis.java
Log:
More changes to get attachments with docstyle messaging to work
Revision Changes Path
1.2 +12 -0
xml-axis-wsif/java/src/org/apache/wsif/providers/soap/apacheaxis/MIMEHelper.java
Index: MIMEHelper.java
===================================================================
RCS file:
/home/cvs/xml-axis-wsif/java/src/org/apache/wsif/providers/soap/apacheaxis/MIMEHelper.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- MIMEHelper.java 16 Dec 2002 17:54:16 -0000 1.1
+++ MIMEHelper.java 7 Jan 2003 12:03:02 -0000 1.2
@@ -112,6 +112,18 @@
return ok;
}
+ public static AttachmentPart getAttachementPart(Object o) throws WSIFException {
+ Trc.entry(null, o);
+ AttachmentPart ap = null;
+ if (o instanceof DataHandler) {
+ ap = new AttachmentPart((DataHandler) o);
+ } else {
+ throw new WSIFException("Object is not a DataHandler: " + o);
+ }
+ Trc.exit(ap);
+ return ap;
+ }
+
public static void setMIMEMessagePart(
WSIFMessage msg,
String name,
1.54 +300 -30
xml-axis-wsif/java/src/org/apache/wsif/providers/soap/apacheaxis/WSIFOperation_ApacheAxis.java
Index: WSIFOperation_ApacheAxis.java
===================================================================
RCS file:
/home/cvs/xml-axis-wsif/java/src/org/apache/wsif/providers/soap/apacheaxis/WSIFOperation_ApacheAxis.java,v
retrieving revision 1.53
retrieving revision 1.54
diff -u -r1.53 -r1.54
--- WSIFOperation_ApacheAxis.java 2 Jan 2003 15:36:07 -0000 1.53
+++ WSIFOperation_ApacheAxis.java 7 Jan 2003 12:03:02 -0000 1.54
@@ -57,6 +57,8 @@
package org.apache.wsif.providers.soap.apacheaxis;
+import java.io.IOException;
+import java.io.StringReader;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.HashMap;
@@ -87,11 +89,13 @@
import javax.wsdl.extensions.soap.SOAPOperation;
import javax.xml.namespace.QName;
import javax.xml.rpc.ParameterMode;
+import javax.xml.soap.SOAPException;
import org.apache.axis.AxisEngine;
import org.apache.axis.AxisFault;
import org.apache.axis.Message;
import org.apache.axis.MessageContext;
+import org.apache.axis.attachments.AttachmentPart;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.axis.client.Transport;
@@ -126,7 +130,10 @@
import org.apache.wsif.util.jms.WSIFJMSDestination;
import org.apache.wsif.wsdl.extensions.jms.JMSProperty;
import org.apache.wsif.wsdl.extensions.jms.JMSPropertyValue;
+import org.apache.xerces.parsers.DOMParser;
import org.w3c.dom.Element;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
import com.ibm.wsdl.extensions.mime.MIMEConstants;
@@ -1349,7 +1356,8 @@
" call object ",
call);
- response = call.invoke(getInputNamespace(), name,
inputValues);
+ response = call.invoke(getInputNamespace(), name, inputValues);
+
} catch (AxisFault e) {
Trc.exception(e);
response = e;
@@ -1463,6 +1471,88 @@
}
}
+ /**
+ * This tells AXIS the name and type of the input, return, and output
parameters.
+ */
+ private void setCallParameterNames2(Call call) throws WSIFException {
+
+ String inputNamespace = getInputNamespace();
+ String outputNamespace = "";
+
+ List soapParts;
+ // style=wrapped uses the unwrapped parts
+ if (WSIFAXISConstants.AXIS_STYLE_WRAPPED.equals(operationStyle)) {
+ soapParts = inputUnwrappedSOAPParts;
+ } else {
+ soapParts = inputSOAPParts;
+ }
+
+ // setup the input SOAP parts
+ for (int i = 0; i < soapParts.size(); i++) {
+ Part p = (Part) soapParts.get(i);
+ String partName = p.getName();
+ if (!inJmsProps.containsKey(partName)) {
+ if (WSIFAXISConstants.STYLE_DOCUMENT.equals(operationStyle)) {
+ QName qn = p.getElementName();
+ if (qn != null) {
+ partName = qn.getLocalPart();
+ }
+ }
+ QName name = new QName(inputNamespace, partName);
+ QName type = getPartType(p);
+ call.addParameter(name, type, ParameterMode.IN);
+ }
+ }
+// // setup the input MIME parts
+// for (int i = 0; i < inputMIMEParts.size(); i++) {
+// Part p = (Part) inputMIMEParts.get(i);
+// QName name = new QName(inputNamespace, p.getName());
+// QName type = getPartType(p);
+// call.addParameter(name, type, ParameterMode.IN);
+// }
+
+ // style=wrapped uses the unwrapped parts
+ if (WSIFAXISConstants.AXIS_STYLE_WRAPPED.equals(operationStyle)) {
+ soapParts = outputUnwrappedSOAPParts;
+ } else {
+ soapParts = outputSOAPParts;
+ }
+
+ // setup the return part
+ Part returnPart = null;
+ if (soapParts.size() > 0) {
+ returnPart = (Part)soapParts.get(0);
+ }
+// } else if (outputMIMEParts.size() > 0) {
+// returnPart = (Part)outputMIMEParts.get(0);
+// }
+ if (returnPart == null) {
+ call.setReturnType(org.apache.axis.encoding.XMLType.AXIS_VOID);
+ } else {
+ QName type = getPartType(returnPart);
+ call.setReturnType(type);
+ }
+
+ // setup output SOAP parts
+ // from 1 to skip the return part
+ for (int i = 1; i < soapParts.size(); i++) {
+ Part p = (Part) soapParts.get(i);
+ QName name = new QName(outputNamespace, p.getName());
+ QName type = getPartType(p);
+ call.addParameter(name, type, ParameterMode.OUT);
+ }
+
+// // setup the output MIME parts
+// // if no soap parts dont add 1st as its the return part
+// int startMIMEIndex = (soapParts.size() > 0) ? 0 : 1;
+// for (int i = startMIMEIndex; i < outputMIMEParts.size(); i++) {
+// Part p = (Part) outputMIMEParts.get(i);
+// QName name = new QName(outputNamespace, p.getName());
+// QName type = getPartType(p);
+// call.addParameter(name, type, ParameterMode.OUT);
+// }
+ }
+
/**
* Gets the type of a Part, if the Part doesn't have a type,
* then gets the Element name as WSIF treats this as the same thing.
@@ -1685,21 +1775,30 @@
boolean workedOK = false;
- Object[] inputValues = getInputMessageValues(inMsg, null);
+ Object[] inputValues = getInputMessageValues2(inMsg, null);
ArrayList soapBodies = new ArrayList();
for (int i = 0; i < inputValues.length; i++) {
if (inputValues[i] instanceof Element) {
soapBodies.add(new SOAPBodyElement((Element)
inputValues[i]));
- } else if (!MIMEHelper.addAttachementIfMIMEPart(call,
inputValues[i])){
+ } else {
throw new WSIFException(
"unexpected input type: " + inputValues[i]);
}
}
+
+ List attachments = addAttachments(inMsg, call);
+ int mimePartIndex = 0;
+ for (Iterator i = attachments.iterator(); i.hasNext(); ) {
+ AttachmentPart attachment = (AttachmentPart) i.next();
+ Part part = (Part) inputMIMEParts.get(mimePartIndex);
+ Element el = makeSOAPBodyPart(part, attachment);
+ soapBodies.add(new SOAPBodyElement(el));
+ }
+
Object[] axisInputs = soapBodies.toArray();
- call.setOperationStyle(WSIFAXISConstants.AXIS_STYLE_MESSAGE);
Trc.event(this, "Invoking AXIS call", call, axisInputs);
- Object axisResponse;
+ Object axisResponse; // the response should be a Vector of RPCElement
objects
try {
axisResponse = call.invoke(axisInputs);
} catch (RemoteException ex) {
@@ -1715,6 +1814,39 @@
return workedOK;
}
+ /**
+ * This makes a DOM Element href part referencing an attachment
+ * The SOAP body has an href referencing each attachment:
+ * <soapenv:Body>
+ * <file href="cid:B4953A2DF527FD54DBA115A9BA32050D"
xmlns="http://webservices.eraserver.net/"/>
+ * </soapenv:Body>
+ * With AXIS when making the SOAPBody out of DOM Elements and
+ * adding attachments with Call.addAttachment, this part must
+ * be added manually to the SOAP body (an AXIS bug?)
+ */
+ private Element makeSOAPBodyPart(Part part, AttachmentPart attachment) throws
WSIFException {
+
+ StringBuffer sb = new StringBuffer("<");
+ sb.append(part.getName());
+ sb.append(" href=\"cid:");
+ sb.append(attachment.getContentId());
+ sb.append("\" xmlns=\"");
+ sb.append(inputNamespace);
+ sb.append("\"/>");
+
+ DOMParser parser = new DOMParser();
+ try {
+ parser.parse(new InputSource(new StringReader(sb.toString())));
+ } catch (SAXException e) {
+ throw new WSIFException("SAXException making attachment href", e);
+ } catch (IOException e) {
+ throw new WSIFException("IOException making attachment href", e);
+ }
+ Element el = parser.getDocument().getDocumentElement();
+
+ return el;
+ }
+
/**
* Prepares this operation.
* The intention of this is to setup everything that can be
@@ -1856,7 +1988,75 @@
return axisInputs.toArray();
}
- //TODO: this must do output MIME parts as well!
+ /**
+ * This is the same as getInputMessageValues but it ignores MIME attachments
+ * Only used by invokeAXISMessaging as the attachments are added with the Call
+ * addAttachmentPart method.
+ * TODO: merge this with getInputMessageValues()
+ */
+ private Object[] getInputMessageValues2(WSIFMessage inMsg, WSIFJMSDestination
dest) throws WSIFException {
+ ArrayList axisInputs = new ArrayList();
+ List soapParts;
+
+ // style=wrapped uses the unwrapped parts
+ if (WSIFAXISConstants.AXIS_STYLE_WRAPPED.equals(operationStyle)) {
+ soapParts = inputUnwrappedSOAPParts;
+ } else {
+ soapParts = inputSOAPParts;
+ }
+
+ for (int i = 0; i < soapParts.size(); i++) {
+ Part p = (Part) soapParts.get(i);
+ String partName = p.getName();
+ Object value;
+ try {
+ value = inMsg.getObjectPart(partName);
+ } catch (WSIFException e) {
+ Trc.ignoredException(e);
+ value = null; // missing part values default to null
+ }
+ if (inJmsProps.containsKey(partName) && dest != null) {
+ String name = (String) (inJmsProps.get(partName));
+ if (!timeoutProperty(dest, name, value)) {
+ dest.setProperty(name, value);
+ }
+ } else {
+ axisInputs.add(value);
+ }
+
+ }
+ return axisInputs.toArray();
+ }
+
+ /**
+ * adds all the attachments to the AXIS call
+ * returns a List of all the AttachmentPart so that href parts
+ * can be made for each attachment later if required.
+ */
+ private List addAttachments(WSIFMessage inMsg, Call call) throws WSIFException
{
+ ArrayList attachments = new ArrayList();
+ for (int i = 0; i < inputMIMEParts.size(); i++) {
+ Part p = (Part) inputMIMEParts.get(i);
+ try {
+ String partName = p.getName();
+ Object value = inMsg.getObjectPart(partName);
+ AttachmentPart ap = MIMEHelper.getAttachementPart(value);
+ call.addAttachmentPart(ap);
+ attachments.add(ap);
+ } catch (WSIFException e) {
+ throw new WSIFException("attachment part '" +
p.getName() + "' not in input WSIFMessage");
+ }
+ }
+ return attachments;
+ }
+
+ /**
+ * This extracts the values from the AXIS response when using messaging
+ * The response could have DOM elements for the SOAP parts, or
+ * AttachmentParts for the attachments.
+ * TODO: only tested with a single response part - either SOAP or MIME
+ * need to test with multiple outputs as probably doesn't work yet.
+ */
private void setOutputMessageValues(
Object axisResponse,
WSIFMessage outMsg)
@@ -1866,29 +2066,20 @@
"expect response type of java.util.Vector of
SOAPBodyElement, found: "
+ axisResponse);
}
- int j = 0;
+
Vector v = (Vector) axisResponse;
for (int i = 0; i < v.size(); i++) {
- if (v.elementAt(i) instanceof SOAPBodyElement) {
- SOAPBodyElement sbe = (SOAPBodyElement) v.elementAt(i);
- Element respEl;
- try {
- respEl = sbe.getAsDOM();
- } catch (Exception e) {
- throw new WSIFException(
- "exception getting soap body as DOM: " +
- e.getLocalizedMessage(),
- e);
- }
-
- String partName;
- if (j < outputSOAPParts.size()) {
- Part p = (Part) outputSOAPParts.get(j++);
- partName = p.getName();
+ if (v.elementAt(i) instanceof RPCElement) {
+ RPCElement rpcEl = (RPCElement) v.elementAt(i);
+
+ QName qn = new QName(rpcEl.getNamespaceURI(),
rpcEl.getName());
+ Part p = findPart(outputSOAPParts, qn);
+ if (p != null) {
+ setSOAPPart(outMsg, rpcEl, p);
} else {
- partName = sbe.getName();
+ setAttachmentPart(outMsg, rpcEl);
}
- outMsg.setObjectPart(partName, respEl);
+
} else {
throw new WSIFException(
"expecting response type org.w3c.dom.Element,
found: "
@@ -1897,8 +2088,90 @@
}
}
+ /**
+ * Extract a SOAP part from response and put in the output WSIFMessage
+ */
+ private void setSOAPPart(WSIFMessage outMsg, RPCElement rpcEl, Part p) throws
WSIFException {
+ Object responseValue = null;
+ try {
+ responseValue = rpcEl.getAsDOM();
+ } catch (Exception e) {
+ throw new WSIFException(
+ "exception getting soap body as DOM: " +
+ e.getLocalizedMessage(),
+ e);
+ }
+ String partName = p.getName();
+ outMsg.setObjectPart(partName, responseValue);
+ }
+
+ /**
+ * Extract an attachment DataHandler from response and put in the output
WSIFMessage
+ */
+ private void setAttachmentPart(WSIFMessage outMsg, RPCElement rpcEl) throws
WSIFException {
+
+ Vector params;
+ try {
+ params = rpcEl.getParams();
+ } catch (SAXException e) {
+ throw new WSIFException(
+ "SAXException getting response MIME part: " +
+ e.getLocalizedMessage(),
+ e);
+ }
+
+ if (params == null || params.size() < 1) {
+ throw new WSIFException(
+ "no attachments found in response element: " + rpcEl);
+ }
+
+ //TODO: will there ever be more than 1?
+ RPCParam rpcParam = (RPCParam) params.get(0);
+
+ QName qn = rpcParam.getQName();
+ Part p = findPart(outputMIMEParts, qn);
+ if (p != null) {
+ Object responseValue = rpcParam.getValue();
+ if (responseValue instanceof AttachmentPart) {
+ try {
+ Object attachment =
((AttachmentPart)responseValue).getDataHandler();
+ String partName = p.getName();
+ outMsg.setObjectPart(partName, attachment);
+ } catch (SOAPException e) {
+ throw new WSIFException(
+ "SOAPException getting DataHandler from AttachmentPart: "
+
+ e.getLocalizedMessage(),
+ e);
+ }
+ } else {
+ throw new WSIFException(
+ "expecting response AttachmentPart but found: " +
responseValue);
+ }
+ } else {
+ throw new WSIFException("cannot find a WSDL output MIME part for
response element: " + rpcEl);
+ }
+
+ }
+
+ /**
+ * Searches the list of parts for one that matches the name.
+ * The list of parts will be the outputSOAPParts or outputMIMEParts
+ */
+ private Part findPart(List partsList, QName partName) {
+ Part part = null;
+ for (Iterator i = partsList.iterator(); i.hasNext() && part == null; ) {
+ Part p = (Part) i.next();
+ if (partName.equals(p.getElementName())) {
+ part = p;
+ } else if (partName.getLocalPart().equals(p.getName())) {
+ part = p;
+ }
+ }
+ return part;
+ }
+
/**
- * Automatically register mime types as DataHandler.
+ * Automatically register MIME types as DataHandler.
*/
private void registerMIMETypes(
List mimeParts,
@@ -1906,10 +2179,7 @@
if (mimeParts != null && !mimeParts.isEmpty()) {
for (Iterator i = mimeParts.iterator(); i.hasNext(); ) {
Part p = (Part) i.next();
- QName type = p.getTypeName();
- if (type == null) {
- type = p.getElementName();
- }
+ QName type = getPartType(p);
MIMEHelper.registerAttachmentType(call, type);
}
}