You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by an...@apache.org on 2003/01/07 13:03:02 UTC

cvs commit: xml-axis-wsif/java/src/org/apache/wsif/providers/soap/apacheaxis MIMEHelper.java WSIFOperation_ApacheAxis.java

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);
   			}
   		}