whitlock 2002/11/06 08:13:38 Modified: java/test/proposals/mime MimeTest.java java/src/org/apache/wsif/providers/soap/apacheaxis WSIFJmsSender.java WSIFOperation_ApacheAxis.java WSIFPort_ApacheAxis.java Removed: java/test/proposals/mime WSIFJmsSender.java WSIFDynamicProvider_ApacheAxis.java WSIFJmsTransport.java WSIFPort_ApacheAxis.java WSIFOperation_ApacheAxis.java Log: Move mime support from proposals into the source tree Revision Changes Path 1.8 +2 -3 xml-axis-wsif/java/test/proposals/mime/MimeTest.java Index: MimeTest.java =================================================================== RCS file: /home/cvs/xml-axis-wsif/java/test/proposals/mime/MimeTest.java,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- MimeTest.java 6 Nov 2002 14:12:35 -0000 1.7 +++ MimeTest.java 6 Nov 2002 16:13:37 -0000 1.8 @@ -238,11 +238,10 @@ */ private void doit(String portName, String cmd, boolean blocking) { - WSIFDynamicProvider_ApacheAxis provider = - new WSIFDynamicProvider_ApacheAxis(); WSIFPluggableProviders.overrideDefaultProvider( "http://schemas.xmlsoap.org/wsdl/soap/", - provider); + new org.apache.wsif.providers.soap.apacheaxis + .WSIFDynamicProvider_ApacheAxis()); try { WSIFServiceFactory factory = WSIFServiceFactory.newInstance(); 1.9 +19 -5 xml-axis-wsif/java/src/org/apache/wsif/providers/soap/apacheaxis/WSIFJmsSender.java Index: WSIFJmsSender.java =================================================================== RCS file: /home/cvs/xml-axis-wsif/java/src/org/apache/wsif/providers/soap/apacheaxis/WSIFJmsSender.java,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- WSIFJmsSender.java 30 Oct 2002 15:42:22 -0000 1.8 +++ WSIFJmsSender.java 6 Nov 2002 16:13:38 -0000 1.9 @@ -57,8 +57,12 @@ package org.apache.wsif.providers.soap.apacheaxis; +import java.io.ByteArrayOutputStream; +import java.io.IOException; import java.io.Serializable; +import javax.xml.soap.SOAPException; + import org.apache.axis.AxisFault; import org.apache.axis.Message; import org.apache.axis.MessageContext; @@ -99,7 +103,15 @@ : transportSyncTimeoutValue.longValue(); Message message = messageContext.getRequestMessage(); - String contents = message.getSOAPPartAsString(); + + // The next line has the desired side effect of setting + // up MIME attachements correctly. MIME attachments using + // AxisJms still don't work, because it falls over later. + message.getContentType(messageContext.getSOAPConstants()); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + message.writeTo(baos); + String contents = baos.toString(); if (asyncMode) { performAsyncSend(messageContext, dest, contents); @@ -109,10 +121,12 @@ Message responseMessage = new Message(response); messageContext.setResponseMessage(responseMessage); } - } catch (WSIFException we) { - Trc.exception(we); - throw new AxisFault(we.toString()); - } + } catch (IOException ioe) { + Trc.exception(ioe); + throw new AxisFault(ioe.toString()); + } catch (SOAPException se) { + Trc.exception(se); + throw new AxisFault(se.toString()); } Trc.exit(); } 1.30 +225 -70 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.29 retrieving revision 1.30 diff -u -r1.29 -r1.30 --- WSIFOperation_ApacheAxis.java 4 Nov 2002 16:55:16 -0000 1.29 +++ WSIFOperation_ApacheAxis.java 6 Nov 2002 16:13:38 -0000 1.30 @@ -57,6 +57,9 @@ package org.apache.wsif.providers.soap.apacheaxis; +import java.awt.Image; +import java.io.IOException; +import java.io.InputStream; import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; @@ -65,13 +68,23 @@ import java.util.Map; import java.util.Vector; +import javax.activation.DataHandler; import javax.jms.TextMessage; +import javax.mail.MessagingException; +import javax.mail.internet.MimeMultipart; +import javax.swing.ImageIcon; import javax.wsdl.Definition; import javax.wsdl.Input; import javax.wsdl.Operation; import javax.wsdl.Output; import javax.wsdl.Part; import javax.xml.namespace.QName; +import javax.xml.soap.AttachmentPart; +import javax.xml.soap.SOAPException; +import javax.xml.transform.Source; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.sax.SAXSource; +import javax.xml.transform.stream.StreamSource; import org.apache.axis.AxisFault; import org.apache.axis.Message; @@ -82,6 +95,8 @@ import org.apache.axis.encoding.TypeMappingRegistry; import org.apache.axis.encoding.ser.BeanDeserializerFactory; import org.apache.axis.encoding.ser.BeanSerializerFactory; +import org.apache.axis.encoding.ser.JAFDataHandlerDeserializerFactory; +import org.apache.axis.encoding.ser.JAFDataHandlerSerializerFactory; import org.apache.axis.message.RPCElement; import org.apache.axis.message.RPCParam; import org.apache.axis.message.SOAPEnvelope; @@ -115,7 +130,9 @@ transient protected Operation operation; transient protected Definition definition; transient protected List partNames; - transient protected String names[]; + transient protected List soapPartNames; + transient protected List mimePartNames; + transient protected String names[]; transient protected Class types[]; transient protected String inputEncodingStyle; transient protected String inputNamespace; @@ -165,7 +182,7 @@ op.setInputNamespace(getInputNamespace()); op.setInputEncodingStyle(getInputEncodingStyle()); op.setOutputEncodingStyle(getOutputEncodingStyle()); - op.setPartNames(getPartNames()); + op.setPartNames(soapPartNames,mimePartNames); op.setReturnName(getReturnName()); op.setAsyncOperation(isAsyncOperation()); op.setResponseHandler(getResponseHandler()); @@ -522,25 +539,11 @@ */ private void populateOutMsgReturnPart(Object resp, WSIFMessage outMsg) throws WSIFException { - if (outMsg != null) { - if (returnName != null) { - if (resp == null) { - // Service returned null. This may be the a correct return value - // and so set the output message part value to null - } else if ( - returnType != null // will be null for async responses - && !returnType.isPrimitive() - && !(returnType.isAssignableFrom(resp.getClass()))) { - throw new WSIFException( - "return value " - + resp - + " has unexpected type " - + resp.getClass() - + " instead of " - + returnType); - } - outMsg.setObjectPart(returnName, resp); - } + if (outMsg != null && returnName != null) { + // If resp==null then the service returned null. + // This may be the a correct return value + // and so set the output message part value to null + setMessagePart(outMsg, returnName, resp, returnType); } } @@ -560,7 +563,7 @@ ) { name = (String) i.next(); value = respParms.get(name); - outMsg.setObjectPart(name, value); + setMessagePart(outMsg, name, value, value.getClass()); wsdlOutParams.remove(name); } } @@ -571,6 +574,97 @@ } } + private static void setMessagePart( + WSIFMessage msg, + String name, + Object value, + Class type) + throws WSIFException { + Trc.entry(null, msg, name, value, type); + + try { + if (DataHandler.class.equals(type) + && AttachmentPart.class.isAssignableFrom(value.getClass())) { + AttachmentPart ap = (AttachmentPart) value; + DataHandler dh = ap.getDataHandler(); + msg.setObjectPart(name, dh); + } else if ( + (String.class.equals(type) + || Image.class.equals(type) + || StreamSource.class.equals(type) + || DOMSource.class.equals(type) + || SAXSource.class.equals(type) + || MimeMultipart.class.equals(type)) + && AttachmentPart.class.isAssignableFrom(value.getClass())) { + + AttachmentPart ap = (AttachmentPart) value; + InputStream is = ap.getDataHandler().getInputStream(); + + if (String.class.equals(type)) { + byte[] bBuff = new byte[is.available()]; + is.read(bBuff); + msg.setObjectPart(name, new String(bBuff)); + } else if (Image.class.equals(type)) { + byte[] bBuff = new byte[is.available()]; + is.read(bBuff); + msg.setObjectPart(name, new ImageIcon(bBuff).getImage()); + } else if (StreamSource.class.equals(type)) + // Warning: this next line of code has never been tested. + msg.setObjectPart(name, new StreamSource(is)); + else if (DOMSource.class.equals(type)) + throw new WSIFException("DOMSource is not supported"); + else if (SAXSource.class.equals(type)) + throw new WSIFException("SAXSource is not supported"); + else if (MimeMultipart.class.equals(type)) + // Warning: this next line of code has never been tested. + msg.setObjectPart( + name, + new MimeMultipart(ap.getDataHandler().getDataSource())); + } else if ( + type != null // will be null for async responses + && !type.isPrimitive() + && !(type.isAssignableFrom(value.getClass()))) { + throw new WSIFException( + "return value " + + value + + " has unexpected type " + + value.getClass() + + " instead of " + + type); + } else + msg.setObjectPart(name, value); + } catch (SOAPException se) { + Trc.exception(se); + throw new WSIFException( + "WSIFOperation_ApacheAxis.setMessagePart messageName=" + + (msg.getName() == null ? "null" : msg.getName()) + + " partName=" + + name + + " caught " + + se); + } catch (IOException ioe) { + Trc.exception(ioe); + throw new WSIFException( + "WSIFOperation_ApacheAxis.setMessagePart messageName=" + + (msg.getName() == null ? "null" : msg.getName()) + + " partName=" + + name + + " caught " + + ioe); + } catch (MessagingException me) { + Trc.exception(me); + throw new WSIFException( + "WSIFOperation_ApacheAxis.setMessagePart messageName=" + + (msg.getName() == null ? "null" : msg.getName()) + + " partName=" + + name + + " caught " + + me); + } + + Trc.exit(); + } + public boolean executeRequestResponseOperation( WSIFMessage wsifmessage, WSIFMessage wsifmessage1, @@ -730,11 +824,44 @@ && !namespaceURI.equals(WSIFConstants.NS_URI_SOAP_ENC)) { localPart = wsifdynamictypemapping.getXmlType().getLocalPart(); QName qn = new QName(namespaceURI, localPart); - BeanSerializerFactory bsf = - new BeanSerializerFactory(objClass, qn); - BeanDeserializerFactory bdf = - new BeanDeserializerFactory(objClass, qn); - call.registerTypeMapping(objClass, qn, bsf, bdf); + + if (DataHandler.class.equals(objClass)) { + call.registerTypeMapping( + objClass, + qn, + JAFDataHandlerSerializerFactory.class, + JAFDataHandlerDeserializerFactory.class); + } else if (Image.class.equals(objClass)) { + call.registerTypeMapping( + Image.class, + qn, + JAFDataHandlerSerializerFactory.class, + JAFDataHandlerDeserializerFactory.class); + } else if (String.class.equals(objClass)) { + call.registerTypeMapping( + String.class, + qn, + JAFDataHandlerSerializerFactory.class, + JAFDataHandlerDeserializerFactory.class); + } else if (Source.class.equals(objClass)) { + call.registerTypeMapping( + Source.class, + qn, + JAFDataHandlerSerializerFactory.class, + JAFDataHandlerDeserializerFactory.class); + } else if (MimeMultipart.class.equals(objClass)) { + call.registerTypeMapping( + MimeMultipart.class, + qn, + JAFDataHandlerSerializerFactory.class, + JAFDataHandlerDeserializerFactory.class); + } else { + BeanSerializerFactory bsf = + new BeanSerializerFactory(objClass, qn); + BeanDeserializerFactory bdf = + new BeanDeserializerFactory(objClass, qn); + call.registerTypeMapping(objClass, qn, bsf, bdf); + } } } @@ -760,7 +887,15 @@ } else { obj = input.getMessage().getOrderedParts(null); } - int i = ((List) (obj)).size(); + + javax.xml.rpc.encoding.TypeMapping tm1 = + registry.getTypeMapping( + "http://schemas.xmlsoap.org/soap/encoding/"); + org.apache.axis.encoding.TypeMapping tm2 = null; + if (tm1 instanceof org.apache.axis.encoding.TypeMapping) + tm2 = (org.apache.axis.encoding.TypeMapping) tm1; + + int i = ((List) (obj)).size(); names = new String[i]; types = new Class[i]; for (int j = 0; j < i; j++) { @@ -771,29 +906,26 @@ throw new WSIFException( "part " + names[j] + " must have type name declared"); - javax.xml.rpc.encoding.TypeMapping tm = - registry.getTypeMapping( - "http://schemas.xmlsoap.org/soap/encoding/"); - if (tm instanceof org.apache.axis.encoding.TypeMapping) { - types[j] = - ( - ( - org - .apache - .axis - .encoding - .TypeMapping) tm) - .getClassForQName( - new QName( - qname1.getNamespaceURI(), - qname1.getLocalPart())); - } + if (tm2 != null) + types[j] = tm2.getClassForQName(qname1); + + // Automatically register mime types as DataHandler (unless + // the user has already typemapped them explicitly). + if (types[j] == null && mimePartNames.contains(names[j])) { + types[j] = DataHandler.class; + call.registerTypeMapping( + DataHandler.class, + qname1, + JAFDataHandlerSerializerFactory.class, + JAFDataHandlerDeserializerFactory.class); + } } } else { names = new String[0]; types = new Class[0]; } + Output output = operation.getOutput(); if (output != null) { Part part = null; @@ -812,26 +944,29 @@ returnName = part.getName(); } } - if (part != null) { - QName qname = part.getTypeName(); - javax.xml.rpc.encoding.TypeMapping tm = - registry.getTypeMapping( - "http://schemas.xmlsoap.org/soap/encoding/"); - if (tm instanceof org.apache.axis.encoding.TypeMapping) { - returnType = - ( - ( - org - .apache - .axis - .encoding - .TypeMapping) tm) - .getClassForQName( - new QName( - qname.getNamespaceURI(), - qname.getLocalPart())); - } - } + + if (part != null) { + QName qname = part.getTypeName(); + javax.xml.rpc.encoding.TypeMapping tm1 = + registry.getTypeMapping("http://schemas.xmlsoap.org/soap/encoding/"); + if (tm1 instanceof org.apache.axis.encoding.TypeMapping) { + org.apache.axis.encoding.TypeMapping tm2 = + (org.apache.axis.encoding.TypeMapping) tm1; + returnType = tm2.getClassForQName(qname); + } + + // Automatically register mime types as DataHandler (unless + // the user has already typemapped them explicitly). + if (returnType == null && mimePartNames.contains(returnName)) { + returnType = DataHandler.class; + call.registerTypeMapping( + DataHandler.class, + qname, + JAFDataHandlerSerializerFactory.class, + JAFDataHandlerDeserializerFactory.class); + } + } + // setup any output paramter part names defined in the WSDL List list = output.getMessage().getOrderedParts(null); if (list.size() > 1) { @@ -911,11 +1046,29 @@ Trc.exit(); } - public void setPartNames(List list) { - Trc.entry(this, list); - partNames = list; - Trc.exit(); - } + public void setPartNames(List soapList, List mimeList) { + Trc.entry(this, soapList, mimeList); + if (soapList != null && !soapList.isEmpty()) + soapPartNames = soapList; + else + soapPartNames = null; + + if (mimeList != null && !mimeList.isEmpty()) + mimePartNames = mimeList; + else + mimePartNames = null; + + if (soapPartNames != null || mimePartNames != null) { + partNames = new Vector(); + if (mimeList != null) + partNames.addAll(mimeList); + if (soapList != null) + partNames.addAll(soapList); + } else + partNames = null; + + Trc.exit(); + } public void setReturnName(String s) { Trc.entry(this, s); @@ -1190,6 +1343,8 @@ buff += " operation:" + Trc.brief(operation); buff += " definition:" + Trc.brief(definition); buff += " partNames:" + partNames; + buff += " soapPartNames:" + soapPartNames; + buff += " mimePartNames:" + mimePartNames; buff += " names:" + names; buff += " types:" + types; buff += " inputEncodingStyle:" + inputEncodingStyle; 1.14 +132 -18 xml-axis-wsif/java/src/org/apache/wsif/providers/soap/apacheaxis/WSIFPort_ApacheAxis.java Index: WSIFPort_ApacheAxis.java =================================================================== RCS file: /home/cvs/xml-axis-wsif/java/src/org/apache/wsif/providers/soap/apacheaxis/WSIFPort_ApacheAxis.java,v retrieving revision 1.13 retrieving revision 1.14 diff -u -r1.13 -r1.14 --- WSIFPort_ApacheAxis.java 24 Oct 2002 17:22:19 -0000 1.13 +++ WSIFPort_ApacheAxis.java 6 Nov 2002 16:13:38 -0000 1.14 @@ -63,6 +63,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Vector; import javax.wsdl.Binding; import javax.wsdl.BindingFault; @@ -76,6 +77,9 @@ import javax.wsdl.Port; import javax.wsdl.PortType; import javax.wsdl.Service; +import javax.wsdl.extensions.mime.MIMEContent; +import javax.wsdl.extensions.mime.MIMEMultipartRelated; +import javax.wsdl.extensions.mime.MIMEPart; import javax.wsdl.extensions.soap.SOAPAddress; import javax.wsdl.extensions.soap.SOAPBinding; import javax.wsdl.extensions.soap.SOAPBody; @@ -100,6 +104,8 @@ import org.apache.wsif.wsdl.extensions.jms.JMSProperty; import org.apache.wsif.wsdl.extensions.jms.JMSPropertyValue; +import com.ibm.wsdl.extensions.mime.MIMEConstants; + /** * @author Mark Whitlock <[EMAIL PROTECTED]> * @author Ant Elder <[EMAIL PROTECTED]> @@ -264,26 +270,29 @@ + s3 + " binding has not style property"); BindingInput bindinginput = bindingoperation.getBindingInput(); + List inExtElems = bindinginput.getExtensibilityElements(); SOAPBody soapbody = (SOAPBody) getExtElem(bindinginput, javax.wsdl.extensions.soap.SOAPBody.class, - bindinginput.getExtensibilityElements()); + inExtElems); if (soapbody != null) { - String s6 = soapbody.getNamespaceURI(); - wsifoperation_apacheaxis.setInputNamespace(s6); - String s7 = soapbody.getUse(); - if (!"encoded".equals(s7)) - throw new WSIFException("unsupported use " + s7 + " in " + soapoperation); - List list1 = soapbody.getEncodingStyles(); - if (list1 != null) { - list1.size(); - wsifoperation_apacheaxis.setInputEncodingStyle((String) list1.get(0)); - } - List list2 = soapbody.getParts(); + List list2 = parseSoapBody(wsifoperation_apacheaxis,soapoperation,soapbody,true); if (list2 != null) - wsifoperation_apacheaxis.setPartNames(list2); + wsifoperation_apacheaxis.setPartNames(list2,null); + } else { + MIMEMultipartRelated mimeMultipart = + (MIMEMultipartRelated) getExtElem(bindinginput, + MIMEMultipartRelated.class, + inExtElems); + if (mimeMultipart != null) + parseMimeMultipart( + mimeMultipart, + bindingoperation, + wsifoperation_apacheaxis, + soapoperation, + true); } - + SOAPHeader soapheader = (SOAPHeader) getExtElem(bindinginput, javax.wsdl.extensions.soap.SOAPHeader.class, @@ -318,10 +327,12 @@ javax.wsdl.extensions.soap.SOAPBody.class, bindingoutput.getExtensibilityElements()); if (soapbody1 != null) { - String s8 = soapbody1.getUse(); - if (!"encoded".equals(s8)) - throw new WSIFException("unsupported use " + s8 + " in " + soapoperation); - List list3 = soapbody1.getParts(); + List list3 = + parseSoapBody( + wsifoperation_apacheaxis, + soapoperation, + soapbody1, + false); if (list3 != null && list3.size() > 0) wsifoperation_apacheaxis.setReturnName((String) list3.get(0)); } @@ -358,6 +369,109 @@ if (Trc.ON) Trc.exit(deep()); + } + + + private List parseSoapBody( + WSIFOperation_ApacheAxis op, + SOAPOperation soapoperation, + SOAPBody soapbody, + boolean isInput) + throws WSIFException { + + Trc.entry(this, op, soapoperation, soapbody, new Boolean(isInput)); + + if (isInput) { + String s6 = soapbody.getNamespaceURI(); + op.setInputNamespace(s6); + } + + String s7 = soapbody.getUse(); + if (!"encoded".equals(s7)) + throw new WSIFException( + "unsupported use " + s7 + " in " + soapoperation); + + if (isInput) { + List list1 = soapbody.getEncodingStyles(); + if (list1 != null) { + list1.size(); + op.setInputEncodingStyle((String) list1.get(0)); + } + } + + List list2 = soapbody.getParts(); + Trc.exit(list2); + return list2; + } + + private void parseMimeMultipart( + MIMEMultipartRelated mimeMultipart, + BindingOperation bindingoperation, + WSIFOperation_ApacheAxis wsifoperation_apacheaxis, + SOAPOperation soapoperation, + boolean isInput) + throws WSIFException { + + Trc.entry( + this, + mimeMultipart, + bindingoperation, + wsifoperation_apacheaxis, + soapoperation); + + Vector mimePartNames = new Vector(); + Vector soapPartNames = new Vector(); + + List mimeParts = mimeMultipart.getMIMEParts(); + Iterator mimePartIt = mimeParts.iterator(); + while (mimePartIt.hasNext()) { + Object nextMimePart = mimePartIt.next(); + if (nextMimePart instanceof MIMEPart) { + MIMEPart mimePart = (MIMEPart) nextMimePart; + if (!MIMEConstants + .NS_URI_MIME + .equals(mimePart.getElementType().getNamespaceURI())) + throw new WSIFException( + "A MIME part in binding operation " + + bindingoperation.getName() + + " did not have the correct namespace URI of " + + MIMEConstants.NS_URI_MIME + + "."); + + List mimeContents = mimePart.getExtensibilityElements(); + Iterator mimeContentIt = mimeContents.iterator(); + while (mimeContentIt.hasNext()) { + Object nextChild = mimeContentIt.next(); + if (nextChild instanceof MIMEContent) { + MIMEContent mimeContent = (MIMEContent) nextChild; + if (!MIMEConstants + .NS_URI_MIME + .equals( + mimePart.getElementType().getNamespaceURI())) + throw new WSIFException( + "A MIME part in binding operation " + + bindingoperation.getName() + + " did not have the correct namespace URI of " + + MIMEConstants.NS_URI_MIME + + "."); + + mimePartNames.addElement(mimeContent.getPart()); + } else if (nextChild instanceof SOAPBody) { + List soapPartNameList = + parseSoapBody( + wsifoperation_apacheaxis, + soapoperation, + (SOAPBody) nextChild, + true); + if (soapPartNameList != null) + soapPartNames.addAll(soapPartNameList); + } + } + } + } + wsifoperation_apacheaxis.setPartNames(soapPartNames, mimePartNames); + + Trc.exit(); } public Definition getDefinition() {