antelder 2002/11/15 01:32:37 Modified: java/src/org/apache/wsif/providers/soap/apacheaxis WSIFPort_ApacheAxis.java WSIFOperation_ApacheAxis.java Log: First cut at adding document style support to the wsif axis provider Revision Changes Path 1.17 +39 -9 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.16 retrieving revision 1.17 diff -u -r1.16 -r1.17 --- WSIFPort_ApacheAxis.java 14 Nov 2002 13:49:33 -0000 1.16 +++ WSIFPort_ApacheAxis.java 15 Nov 2002 09:32:36 -0000 1.17 @@ -86,6 +86,7 @@ import javax.wsdl.extensions.soap.SOAPFault; import javax.wsdl.extensions.soap.SOAPHeader; import javax.wsdl.extensions.soap.SOAPOperation; +import javax.xml.namespace.QName; import javax.xml.rpc.JAXRPCException; import org.apache.axis.client.Call; @@ -122,6 +123,7 @@ protected Transport st; protected List jmsAddressPropVals = null; protected Call call; + protected String style; private static final int HTTP_TRANSPORT = 1; private static final int JMS_TRANSPORT = 2; @@ -191,7 +193,7 @@ binding.getExtensibilityElements()); if (soapbinding != null) { s1 = soapbinding.getStyle(); - if (!"rpc".equals(s1)) + if (!"rpc".equals(s1) && !"document".equals(s1)) throw new WSIFException("unsupported style " + s1 + " for " + soapbinding); String s2 = soapbinding.getTransportURI(); if ("http://schemas.xmlsoap.org/soap/http".equals(s2)) { @@ -218,8 +220,11 @@ ((WSIFJmsTransport) st).setDestination(jmsDestination); } - if (s1 == null) - s1 = "document"; + if (s1 == null) { + style = "document"; + } else { + style = s1; + } PortType porttype = binding.getPortType(); List list = porttype.getOperations(); Operation operation; @@ -263,13 +268,20 @@ String s4 = soapoperation.getSoapActionURI(); wsifoperation_apacheaxis.setSoapActionURI(s4); String s5 = soapoperation.getStyle(); - if (s5 != null && !"rpc".equals(s5)) + if (s5 != null && !"rpc".equals(s5) && !"document".equals(s5)) throw new WSIFException("unsupported style " + s1 + " for operation " + s3); - if (!"rpc".equals(s1)) + if (!"rpc".equals(s1) && !"document".equals(s1)) throw new WSIFException( - "default soap style must be rpc if operation " + "default soap style must be rpc or document if operation " + s3 + " binding has not style property"); + if (s5 != null) { + style = s5; + } + QName bindingQN = binding.getQName(); + if (bindingQN != null) { + wsifoperation_apacheaxis.setInputNamespace(bindingQN.getNamespaceURI()); + } BindingInput bindinginput = bindingoperation.getBindingInput(); List inExtElems = bindinginput.getExtensibilityElements(); SOAPBody soapbody = @@ -393,11 +405,15 @@ Trc.entry(this, op, soapoperation, soapbody, new Boolean(isInput)); - if (isInput) - op.setInputNamespace(soapbody.getNamespaceURI()); + if (isInput) { + String ns = soapbody.getNamespaceURI(); + if (ns != null) { + op.setInputNamespace(soapbody.getNamespaceURI()); + } + } String use = soapbody.getUse(); - if (!"encoded".equals(use)) + if (!"encoded".equals(use) && !"literal".equals(use)) throw new WSIFException( "unsupported use " + use + " in " + soapoperation); @@ -538,6 +554,9 @@ } } } + if (operation != null ) { + operation.setStyle(style); + } Trc.exit(operation); return operation; @@ -657,6 +676,17 @@ Trc.exit(false); return false; } + } + + /** + * Closes the port. All methods are invalid after calling this method. + */ + public void close() throws WSIFException { + Trc.entry(this); + if (st != null && st instanceof WSIFJmsTransport) { + ((WSIFJmsTransport) st).close(); + } + Trc.exit(); } public String deep() { 1.33 +716 -246 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.32 retrieving revision 1.33 diff -u -r1.32 -r1.33 --- WSIFOperation_ApacheAxis.java 14 Nov 2002 13:49:33 -0000 1.32 +++ WSIFOperation_ApacheAxis.java 15 Nov 2002 09:32:36 -0000 1.33 @@ -60,7 +60,8 @@ import java.awt.Image; import java.io.IOException; import java.io.InputStream; -import java.io.Serializable; +import java.io.StringWriter; +import java.rmi.RemoteException; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; @@ -79,6 +80,7 @@ import javax.wsdl.Output; import javax.wsdl.Part; import javax.xml.namespace.QName; +import javax.xml.rpc.ServiceException; import javax.xml.soap.AttachmentPart; import javax.xml.soap.SOAPException; import javax.xml.transform.Source; @@ -86,12 +88,14 @@ import javax.xml.transform.sax.SAXSource; import javax.xml.transform.stream.StreamSource; +import org.apache.axis.AxisEngine; import org.apache.axis.AxisFault; import org.apache.axis.Message; import org.apache.axis.MessageContext; import org.apache.axis.client.Call; import org.apache.axis.client.Service; import org.apache.axis.client.Transport; +import org.apache.axis.encoding.TypeMapping; import org.apache.axis.encoding.TypeMappingRegistry; import org.apache.axis.encoding.ser.BeanDeserializerFactory; import org.apache.axis.encoding.ser.BeanSerializerFactory; @@ -99,6 +103,7 @@ import org.apache.axis.encoding.ser.JAFDataHandlerSerializerFactory; import org.apache.axis.message.RPCElement; import org.apache.axis.message.RPCParam; +import org.apache.axis.message.SOAPBodyElement; import org.apache.axis.message.SOAPEnvelope; import org.apache.axis.message.SOAPFaultElement; import org.apache.axis.message.SOAPHeaderElement; @@ -106,24 +111,24 @@ import org.apache.wsif.WSIFCorrelationId; import org.apache.wsif.WSIFException; import org.apache.wsif.WSIFMessage; -import org.apache.wsif.WSIFOperation; import org.apache.wsif.WSIFResponseHandler; import org.apache.wsif.base.WSIFDefaultMessage; import org.apache.wsif.base.WSIFDefaultOperation; import org.apache.wsif.logging.Trc; import org.apache.wsif.providers.WSIFDynamicTypeMap; import org.apache.wsif.providers.WSIFDynamicTypeMapping; +import org.apache.wsif.util.WSIFUtils; import org.apache.wsif.util.jms.WSIFJMSDestination; +import org.apache.xml.serialize.OutputFormat; +import org.apache.xml.serialize.XMLSerializer; import org.w3c.dom.Element; /** * @author Mark Whitlock <[EMAIL PROTECTED]> * @author Ant Elder <[EMAIL PROTECTED]> */ -public class WSIFOperation_ApacheAxis - extends WSIFDefaultOperation - implements WSIFOperation, Serializable { - +public class WSIFOperation_ApacheAxis extends WSIFDefaultOperation { + private static final long serialVersionUID = 1L; transient protected WSIFPort_ApacheAxis portInstance; @@ -131,12 +136,9 @@ transient protected Definition definition; transient protected List soapPartNames; transient protected List mimePartNames; - transient protected String names[]; - transient protected Class types[]; transient protected String inputEncodingStyle; transient protected String inputNamespace; transient protected String actionUri; - transient protected Class returnType = null; transient protected HashMap outParams; // for async operation @@ -148,7 +150,18 @@ protected String returnName = null; protected String outputEncodingStyle; protected WSIFDynamicTypeMap typeMap; - protected ArrayList wsdlOutParams; + protected String style; + + transient protected String[] inputPartNames; + transient protected QName[] inputPartQNs; + transient protected Class[] inputPartTypes; + transient protected QName[] inputPartTypeQNs; + + protected String[] outputPartNames; + protected QName[] outputPartQNs; + protected Class[] outputPartTypes; + protected QName[] outputPartTypeQNs; + protected int returnPartIndex; public WSIFOperation_ApacheAxis( WSIFPort_ApacheAxis wsifport_apacheaxis, @@ -170,6 +183,8 @@ /** * Create a new copy of this object. This is not a clone, since * it does not copy the referenced objects as well. + * TODO: should this also copy the inputxxx/outputxxx arrays? + * then prepare results would be cached? */ public WSIFOperation_ApacheAxis copy() throws WSIFException { Trc.entry(this); @@ -188,7 +203,8 @@ op.setResponseHandler(getResponseHandler()); op.setInputJmsProperties(getInputJmsProperties()); op.setOutputJmsProperties(getOutputJmsProperties()); - op.setInputJmsPropertyValues(getInputJmsPropertyValues()); + op.setInputJmsPropertyValues(getInputJmsPropertyValues()); + op.setStyle(getStyle()); if (Trc.ON) Trc.exit(op.deep()); @@ -280,6 +296,78 @@ } /** + * Returns the style. + * @return String + */ + public String getStyle() { + return style; + } + + /** + * Returns the inputPartNames. + * @return String[] + */ + private String[] getInputPartNames() { + return inputPartNames; + } + + /** + * Returns the inputPartQNs. + * @return QName[] + */ + private QName[] getInputPartQNs() { + return inputPartQNs; + } + + /** + * Returns the inputPartTypeQNs. + * @return QName[] + */ + private QName[] getInputPartTypeQNs() { + return inputPartTypeQNs; + } + + /** + * Returns the inputPartTypes. + * @return Class[] + */ + private Class[] getInputPartTypes() { + return inputPartTypes; + } + + /** + * Returns the outputPartNames. + * @return String[] + */ + private String[] getOutputPartNames() { + return outputPartNames; + } + + /** + * Returns the outputPartQNs. + * @return QName[] + */ + private QName[] getOutputPartQNs() { + return outputPartQNs; + } + + /** + * Returns the outputPartTypeQNs. + * @return QName[] + */ + private QName[] getOutputPartTypeQNs() { + return outputPartTypeQNs; + } + + /** + * Returns the outputPartTypes. + * @return Class[] + */ + private Class[] getOutputPartTypes() { + return outputPartTypes; + } + + /** * Tests if the currently executing request is an asynchronous request. * * @return true if the current request is a asynchronous request, @@ -291,13 +379,6 @@ return asyncOperation; } - // package visable as it's used by WSIFJmsTransport - void setAsyncRequestID(WSIFCorrelationId asyncRequestID) { - Trc.entry(this, asyncRequestID); - this.asyncRequestID = asyncRequestID; - Trc.exit(); - } - public void executeInputOnlyOperation(WSIFMessage wsifmessage) throws WSIFException { Trc.entry(this, wsifmessage); @@ -347,6 +428,9 @@ if (!portInstance.supportsAsync()) { throw new WSIFException("asynchronous operations not available"); } + if ("document".equals(style)) { + throw new WSIFException("docstyle asynchronous operations not implemented yet"); + } setAsyncOperation(true); setResponseHandler(handler); @@ -422,7 +506,8 @@ } /** - * This deserialises and unmarshalls the response message. + * Deserialise and unmarshall the JMS response message. + * Used to process the response to an asynchronous request. * This is copied, with minor changes, from the 2nd half * of the Apache Axis Call class invoke method. */ @@ -444,6 +529,8 @@ msgContext.setResponseMessage(responseMessage); // This registerTypeMapping code is duplicated in prepare + //registerTypeMappings(call); + //TODO: need to sort out this duplicated code TypeMappingRegistry tmr = msgContext.getTypeMappingRegistry(); org.apache.axis.encoding.TypeMapping tm = (org.apache.axis.encoding.TypeMapping) tmr.getTypeMapping( @@ -545,11 +632,11 @@ */ private void populateOutMsgReturnPart(Object resp, WSIFMessage outMsg) throws WSIFException { - if (outMsg != null && returnName != null) { + if (outMsg != null && outputPartNames.length > 0) { // 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); + setMessagePart(outMsg, outputPartNames[returnPartIndex], resp, outputPartTypes[returnPartIndex]); } } @@ -560,7 +647,14 @@ private void populateOutMsgParts(WSIFMessage outMsg) throws WSIFException { if (outMsg != null) { HashMap respParms = getResponseMsgParams(); - ArrayList wsdlOutParams = getWSDLOutParams(); + + ArrayList wsdlOutParts = new ArrayList(); + for (int i=0; i<outputPartNames.length; i++) { + if (i != returnPartIndex) { + wsdlOutParts.add(outputPartNames[i]); + } + } + if (respParms != null) { String name; Object value; @@ -575,11 +669,11 @@ name, value, value == null ? null : value.getClass()); - wsdlOutParams.remove(name); + wsdlOutParts.remove(name); } } // init any other parts to null - for (Iterator i = wsdlOutParams.iterator(); i.hasNext();) { + for (Iterator i = wsdlOutParts.iterator(); i.hasNext();) { outMsg.setObjectPart((String) i.next(), null); } } @@ -681,20 +775,23 @@ } public boolean executeRequestResponseOperation( - WSIFMessage wsifmessage, - WSIFMessage wsifmessage1, - WSIFMessage wsifmessage2) + WSIFMessage inMsg, + WSIFMessage outMsg, + WSIFMessage faultMsg) throws WSIFException { - Trc.entry(this, wsifmessage, wsifmessage1, wsifmessage2); + Trc.entry(this, inMsg, outMsg, faultMsg); close(); setAsyncOperation(false); - boolean succ = - invokeRequestResponseOperation( - wsifmessage, - wsifmessage1, - wsifmessage2); + boolean succ; + if ("document".equals(style)) { + succ = + invokeRequestResponseOperationDocument(inMsg, outMsg, faultMsg); + } else { + succ = invokeRequestResponseOperation(inMsg, outMsg, faultMsg); + } + Trc.exit(succ); return succ; } @@ -721,8 +818,9 @@ } } - if (names == null) + if (inputPartNames == null) { prepare(call); + } if (inJmsPropVals != null && !inJmsPropVals.isEmpty()) { checkForTimeoutProperties(inJmsPropVals, dest); @@ -730,32 +828,32 @@ } ArrayList objects = new ArrayList(); - for (int i = 0; i < names.length; i++) { + for (int i = 0; i < inputPartNames.length; i++) { Object obj; try { - obj = wsifmessage.getObjectPart(names[i]); + obj = wsifmessage.getObjectPart(inputPartNames[i]); } catch (WSIFException ex) { Trc.exception(ex); obj = null; } if (obj != null) { - if (types[i] == null) - throw new WSIFException("Cannot map type " + names[i]); + if (inputPartTypes[i] == null) + throw new WSIFException("Cannot map type " + inputPartNames[i]); - if (!isPrimitiveOf(obj.getClass(), types[i]) - && !types[i].isAssignableFrom(obj.getClass())) { + if (!isPrimitiveOf(obj.getClass(), inputPartTypes[i]) + && !inputPartTypes[i].isAssignableFrom(obj.getClass())) { throw new WSIFException( "value " + obj + " has unexpected type " + obj.getClass() + " instead of " - + types[i]); + + inputPartTypes[i]); } } - if (inJmsProps.containsKey(names[i]) && dest != null) { - String name = (String) (inJmsProps.get(names[i])); + if (inJmsProps.containsKey(inputPartNames[i]) && dest != null) { + String name = (String) (inJmsProps.get(inputPartNames[i])); if (!timeoutProperty(dest, name, obj)) { dest.setProperty(name, obj); } @@ -794,7 +892,7 @@ Trc.event(this, "Returned from operation, response ", response); // setJMSOutPropsInContext( dest ); TODO doesn't work yet - if (!isAsyncOperation() && returnType != null) { + if (!isAsyncOperation() && outputPartNames.length > 0) { Map callParams = call.getOutputParams(); if (callParams != null) { HashMap outParams = new HashMap(); @@ -815,12 +913,220 @@ return respOK; } + public boolean invokeRequestResponseOperationDocument( + WSIFMessage inMsg, + WSIFMessage outMsg, + WSIFMessage faultMsg) + throws WSIFException { + Trc.entry(this, inMsg, outMsg, faultMsg); + boolean workedOK = false; + + Call call = portInstance.getCall(); + Service service = new Service(); + try { + call = (Call) service.createCall(); + } catch (ServiceException ex) { + throw new WSIFException("ex creating call: " + ex.getLocalizedMessage(), ex); + } + + call.setSOAPActionURI(getSoapActionURI()); + call.setTargetEndpointAddress(portInstance.getEndPoint()); + + Input inputMsg = operation.getInput(); + if (inputMsg != null) { + List parts = inputMsg.getMessage().getOrderedParts(null); + if (WSIFUtils.isWrappedDocLiteral(parts, operation.getName())) { + style = "wrapped"; + } + } + + if (isMessaging(inMsg)) { + style = "message"; + } + + if (inputPartNames == null) { + prepare(call); + } + + Transport axistransport = getTransport(); + WSIFJMSDestination dest = null; + if (axistransport != null) { + call.setTransport(axistransport); + if (axistransport instanceof WSIFJmsTransport) { + WSIFJmsTransport jmst = (WSIFJmsTransport) axistransport; + dest = jmst.getDestination(); + dest.setAsyncMode(isAsyncOperation()); + jmst.setSyncTimeout(null); // reset timeouts to defaults + jmst.setAsyncTimeout(null); + } + } + + if ("message".equals(style)) { + workedOK = doAXISMessaging(call, inMsg, outMsg, faultMsg); + } else { + workedOK = doAXISDocStyle(call, inMsg, outMsg, faultMsg); + } + + Trc.exit(workedOK); + return workedOK; + } + + private boolean isMessaging(WSIFMessage msg) { + boolean allDomElements = true; + + //TODO this should ignore any MIME parts + if (msg != null) { + for (Iterator i = msg.getParts(); i.hasNext() && allDomElements;) { + if (!(i.next() instanceof Element)) { + allDomElements = false; + } + } + } + return allDomElements; + } + private boolean doAXISDocStyle( + Call call, + WSIFMessage inMsg, + WSIFMessage outMsg, + WSIFMessage faultMsg) + throws WSIFException { + + boolean respOK = false; + + // setup the call object + call.setOperationName(new QName(getInputNamespace(), operation.getName())); + call.setEncodingStyle(null); + call.setScopedProperty(Call.SEND_TYPE_ATTR, Boolean.FALSE); + call.setScopedProperty(AxisEngine.PROP_DOMULTIREFS, Boolean.FALSE); + call.setOperationStyle(style); + + // setup the input values + for (int i = 0; i < inputPartNames.length; i++) { + call.addParameter( + inputPartQNs[i], + inputPartTypeQNs[i], + inputPartTypes[i], + javax.xml.rpc.ParameterMode.IN); + } + Object[] inputValues = getInputMessageValues(inMsg); + + // setup the return part + call.setReturnQName(outputPartQNs[returnPartIndex]); + call.setReturnType( + outputPartTypeQNs[returnPartIndex], + outputPartTypes[returnPartIndex]); + + // invoke the AXIS call + Trc.event(this, "Invoking AXIS call", call, inputValues); + Object response; + try { + response = call.invoke(inputValues); + } catch (RemoteException ex) { + ex.printStackTrace(); + throw new WSIFException( + "exception on AXIS invoke: " + ex.getLocalizedMessage(), + ex); + } + Trc.event(this, "Returned from AXIS invoke, response: ", response); + + // process the AXIS response + if (!isAsyncOperation() && outputPartTypes[returnPartIndex] != null) { + Map callParams = call.getOutputParams(); + if (callParams != null) { + HashMap outParams = new HashMap(); + for (Iterator i = callParams.keySet().iterator(); + i.hasNext(); + ) { + QName qn = (QName) i.next(); + outParams.put(qn.getLocalPart(), callParams.get(qn)); + } + setResponseMsgParams(outParams); + } + respOK = buildResponseMessages(response, outMsg, faultMsg); + } + + return respOK; + } + + private boolean doAXISMessaging( + Call call, + WSIFMessage inMsg, + WSIFMessage outMsg, + WSIFMessage faultMsg) + throws WSIFException { + + boolean workedOK = false; + + Object[] inputValues = getInputMessageValues(inMsg); + SOAPBodyElement[] axisInputs = + new SOAPBodyElement[inputValues.length]; + for (int i = 0; i < inputValues.length; i++) { + if ( inputValues[i] instanceof Element) { + axisInputs[i] = new SOAPBodyElement((Element)inputValues[i]); + } else { + throw new WSIFException("unexpected input type: " + inputValues[i]); + } + } + + call.setOperationStyle("message"); + + Trc.event(this, "Invoking AXIS call", call, axisInputs); + Object axisResponse; + try { + axisResponse = call.invoke(axisInputs); + } catch (RemoteException ex) { + throw new WSIFException( + "exception on AXIS invoke: " + ex.getLocalizedMessage(), + ex); + } + Trc.event(this, "Returned from AXIS invoke, response: ", axisResponse); + + setOutputMessageValues(axisResponse, outMsg); + + workedOK = true; + return workedOK; + } + + /** + * Prepares this operation. + * The intention of this is to setup everything that can be + * reused by the operation. + */ private void prepare(Call call) throws WSIFException { Trc.entry(this,call); - // This registerTypeMapping code is duplicated in deserialiseResponseObject - TypeMappingRegistry registry = - call.getMessageContext().getTypeMappingRegistry(); + // register any WSIFDynamicTypeMappings + if ( "rpc".equals( style ) ) { + //TODO: fails for "document" as the element types are mapped + registerTypeMappings(call); + } + + // create the arrays for the input parts + List inputParts = getInputParts(); + this.inputPartNames = getPartNamesArray(inputParts); + this.inputPartQNs = getPartQNamesArray(inputParts); + this.inputPartTypeQNs = getPartTypeQNamesArray(inputParts); + this.inputPartTypes = getPartTypesArray(inputParts, call); + registerMIMETypes(inputPartNames, inputPartTypes, inputPartTypeQNs, call); + + // create the arrays for the output parts + List outputParts = getOutputParts(); + this.outputPartNames = getPartNamesArray(outputParts); + this.outputPartQNs = getPartQNamesArray(outputParts); + this.outputPartTypeQNs = getPartTypeQNamesArray(outputParts); + this.outputPartTypes = getPartTypesArray(outputParts, call); + registerMIMETypes(outputPartNames, outputPartTypes, outputPartTypeQNs, call); + + // the index in the output part arrays of the return part + this.returnPartIndex = getReturnPartIndex(); + + Trc.exit(); + } + + /** + * Register all the type mappings with the AXIS Call object + */ + private void registerTypeMappings(Call call) throws WSIFException { Class objClass; String namespaceURI, localPart; WSIFDynamicTypeMapping wsifdynamictypemapping; @@ -841,164 +1147,293 @@ localPart = wsifdynamictypemapping.getXmlType().getLocalPart(); QName qn = new QName(namespaceURI, localPart); - 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); - } + 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); + } } } + } - Input input = operation.getInput(); - if (input != null) { - Object obj; - if (soapPartNames != null) { - obj = new Vector(); - Part part1; - for (Iterator iterator1 = soapPartNames.iterator(); - iterator1.hasNext(); - ((List) (obj)).add(part1)) { - String s = (String) iterator1.next(); - part1 = input.getMessage().getPart(s); - if (part1 == null) + /** + * Gets an array of all the input WSIFMessage values + */ + private Object[] getInputMessageValues(WSIFMessage inMsg) + throws WSIFException { + + Object[] axisInputs = new Object[inputPartNames.length]; + for (int i = 0; i < inputPartNames.length; i++) { + try { + Object o = inMsg.getObjectPart(inputPartNames[i]); + if ((inputPartTypes[i].isAssignableFrom(o.getClass()))) { + axisInputs[i] = o; + } else { + throw new WSIFException( + "expected type " + + inputPartTypes[i] + + " for input part " + + inputPartNames[i] + + ", but type is: " + + o.getClass()); + } + } catch (WSIFException ex) { + throw new WSIFException( + "part " + + inputPartNames[i] + + ", not found in input message"); + } + } + return axisInputs; + } + + //TODO why can't this use buildResponseMessages + private void setOutputMessageValues(Object axisResponse, WSIFMessage outMsg) + throws WSIFException { + if (!(axisResponse instanceof Vector)) { + throw new WSIFException( + "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) { + try { + SOAPBodyElement sbe = (SOAPBodyElement) v.elementAt(i); + Element respEl = sbe.getAsDOM(); + String partName = + (j < outputPartNames.length) + ? outputPartNames[j++] + : sbe.getName(); + outMsg.setObjectPart(partName, respEl); + } catch (Exception ex) { + throw new WSIFException( + "exception processing response: " + + ex.getLocalizedMessage(), + ex); + } + } else { + throw new WSIFException( + "expecting response type org.w3c.dom.Element, found: " + + v.elementAt(i)); + } + } + } + + /** + * Gets the parts on the WSDL input message. + * TODO shouldn't there be in + out soapPartNames? + */ + private List getInputParts() throws WSIFException { + List parts = new ArrayList(); + Input inputMsg = operation.getInput(); + if (inputMsg != null) { + if (soapPartNames == null) { + parts = inputMsg.getMessage().getOrderedParts(null); + } else { + for (Iterator i = soapPartNames.iterator(); i.hasNext();) { + String partName = (String) i.next(); + Part p = inputMsg.getMessage().getPart(partName); + if (p == null) { throw new WSIFException( "no input part named " - + s + + partName + " for binding operation " + getName()); + } + parts.add(p); } - - } else { - obj = input.getMessage().getOrderedParts(null); } + } + unWrapIfWrappedDocLit(parts, operation.getName()); + return parts; + } - 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++) { - Part part2 = (Part) ((List) (obj)).get(j); - names[j] = part2.getName(); - QName qname1 = part2.getTypeName(); - if (qname1 == null) - throw new WSIFException( - "part " + names[j] + " must have type name declared"); + /** + * Gets the parts on the WSDL output message. + * TODO shouldn't there be in + out soapPartNames? + */ + private List getOutputParts() throws WSIFException { + List parts; + Output outputMsg = operation.getOutput(); + if (outputMsg == null) { + parts = new ArrayList(); + } else { + parts = outputMsg.getMessage().getOrderedParts(null); + } + unWrapIfWrappedDocLit(parts, operation.getName() + "Response"); + return parts; + } - if (tm2 != null) - types[j] = tm2.getClassForQName(qname1); + /** + * Unwraps the top level element if this a wrapped message. + */ + private void unWrapIfWrappedDocLit(List parts, String operationName) + throws WSIFException { + if (!"message".equals(style)) { + Part p = WSIFUtils.getWrappedDocLiteralPart(parts, operationName); + if (p != null) { + List unWrappedParts = WSIFUtils.unWrapPart(p, definition); + parts.remove(p); + parts.addAll(unWrappedParts); + } + } + } - // Automatically register mime types as DataHandler (unless - // the user has already typemapped them explicitly). - if (types[j] == null - && mimePartNames != null - && mimePartNames.contains(names[j])) { - types[j] = DataHandler.class; - call.registerTypeMapping( - DataHandler.class, - qname1, - JAFDataHandlerSerializerFactory.class, - JAFDataHandlerDeserializerFactory.class); - } - } + /** + * Returns a String array of the name of each part + */ + private String[] getPartNamesArray(List parts) { + String[] names = new String[parts.size()]; + for (int i = 0; i < parts.size(); i++) { + Part p = (Part) parts.get(i); + names[i] = p.getName(); + } + return names; + } - } else { - names = new String[0]; - types = new Class[0]; + /** + * Returns a QName array of the QName of each part + */ + private QName[] getPartQNamesArray(List parts) { + QName[] qnames = new QName[parts.size()]; + String namespace = getInputNamespace(); + for (int i = 0; i < parts.size(); i++) { + Part p = (Part) parts.get(i); + qnames[i] = new QName(namespace, p.getName()); } - - Output output = operation.getOutput(); - if (output != null) { - Part part = null; - if (returnName != null) { - part = output.getMessage().getPart(returnName); - if (part == null) - throw new WSIFException( - "no output part named " - + returnName - + " for bining operation " - + getName()); + return qnames; + } + + /** + * Returns a QName array of the type/element of each part + */ + private QName[] getPartTypeQNamesArray(List parts) { + QName[] qnames = new QName[parts.size()]; + for (int i = 0; i < parts.size(); i++) { + Part p = (Part) parts.get(i); + qnames[i] = p.getTypeName(); + if (qnames[i]==null) { + qnames[i] = p.getElementName(); + } + } + return qnames; + } + + /** + * Returns a Class array of the class of each part + */ + private Class[] getPartTypesArray(List parts, Call call) + throws WSIFException { + + TypeMappingRegistry registry = + call.getMessageContext().getTypeMappingRegistry(); + Object o = + registry.getTypeMapping( + "http://schemas.xmlsoap.org/soap/encoding/"); + if (!(o instanceof TypeMapping)) { + throw new WSIFException("expecting a TypeMapping but found: " + o); + } + TypeMapping tm = (TypeMapping) o; + + Class[] types = new Class[parts.size()]; + for (int i = 0; i < parts.size(); i++) { + Part p = (Part) parts.get(i); + QName partQN = p.getTypeName(); + if (partQN == null) { + partQN = p.getElementName(); + } + if (partQN == null) { + throw new WSIFException( + "part " + + p + + " must have type name or element declared"); + } + if ("message".equals(style)) { + types[i] = Element.class; } else { - List list = output.getMessage().getOrderedParts(null); - if (list.size() > 0) { - part = (Part) list.get(0); - returnName = part.getName(); - } + types[i] = tm.getClassForQName(partQN); } - - 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); - } + } + return types; + } - // Automatically register mime types as DataHandler (unless - // the user has already typemapped them explicitly). - if (returnType == null - && mimePartNames != 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) { - wsdlOutParams = new ArrayList(); - for (int i = 1; i < list.size(); i++) { - part = (Part) list.get(i); - wsdlOutParams.add(part.getName()); + /** + * Finds the index of the return part in the outputPartxxx arrays. + * The return part is either the part set by the setReturnName + * method, or the first part in the response method. + */ + private int getReturnPartIndex() { + int returnIndex = 0; + if (returnName != null) { + for (int i = 0; i < outputPartNames.length; i++) { + if (returnName.equals(outputPartNames[i])) { + returnIndex = i; + break; } - setWSDLOutParams(wsdlOutParams); } + } else { + returnIndex = 0; } - Trc.exit(); + return returnIndex; + } + + /** + * Automatically register mime types as DataHandler. + * (unless the user has already typemapped them explicitly) + */ + private void registerMIMETypes( + String[] partNames, + Class[] partTypes, + QName[] partTypeQNs, + Call call) { + //TODO shouldn't there be in + out mimePartNames + if (mimePartNames != null) { + for (int i = 0; i < partNames.length; i++) { + if (partTypes[i] == null // no user explicit mapping + && mimePartNames.contains(partNames[i])) { + partTypes[i] = DataHandler.class; + call.registerTypeMapping( + DataHandler.class, + partTypeQNs[i], + JAFDataHandlerSerializerFactory.class, + JAFDataHandlerDeserializerFactory.class); + } + } + } } /** @@ -1020,17 +1455,6 @@ return responseHandler; } - private ArrayList getWSDLOutParams() { - if (wsdlOutParams == null) { - wsdlOutParams = new ArrayList(); - } - return wsdlOutParams; - } - - private void setWSDLOutParams(ArrayList al) { - wsdlOutParams = al; - } - public void setDefinition(Definition definition1) { Trc.entry(this, definition1); definition = definition1; @@ -1126,52 +1550,6 @@ } /** - * Creates a new input WSIFMessage. This overrides the - * WSIFDefaultOperation method to enable the use of - * compiled WSIFMessages by using a WSIFMessageFactory - * to create the message. - * - * @param name the name of the message - * @return a WSIFMessage instance - * @see WSIFOperation#createInputMessage(String) - */ - // defect 131672 and disable compiled msg support for now - // public WSIFMessage createInputMessage(String name) { - // Tr.entry(this, name); - // Definition d = getDefinition(); - // String ns = (d == null) ? "" : d.getTargetNamespace(); - // WSIFMessageFactory mf = WSIFServiceImpl.getMessageFactory(); - // WSIFMessage msg = mf.createMessage(ns, name + "Message"); - // if (msg != null) - // msg.setName(name); - // Tr.exit(msg); - // return msg; - // } - - /** - * Creates a new output WSIFMessage. This overrides the - * WSIFDefaultOperation method to enable the use of - * compiled WSIFMessages by using a WSIFMessageFactory - * to create the message. - * - * @param name the name of the message - * @return a WSIFMessage instance - * @see WSIFOperation#createInputMessage(String) - */ - // defect 131672 and disable compiled msg support for now - // public WSIFMessage createOutputMessage(String name) { - // Tr.entry(this, name); - // Definition d = getDefinition(); - // String ns = (d == null) ? "" : d.getTargetNamespace(); - // WSIFMessageFactory mf = WSIFServiceImpl.getMessageFactory(); - // WSIFMessage msg = mf.createMessage(ns, name + "Message"); - // if (msg != null) - // msg.setName(name); - // Tr.exit(msg); - // return msg; - // } - - /** * This sets up the output JMS property values in the context */ private void setJMSOutPropsInContext(WSIFJMSDestination dest) @@ -1350,6 +1728,93 @@ return false; } + // package visable as it's used by WSIFJmsTransport + void setAsyncRequestID(WSIFCorrelationId asyncRequestID) { + Trc.entry(this, asyncRequestID); + this.asyncRequestID = asyncRequestID; + Trc.exit(); + } + + /** + * Sets the style. + * @param style The style to set + */ + public void setStyle(String style) { + this.style = style; + } + + /** + * Sets the inputPartNames. + * @param inputPartNames The inputPartNames to set + */ + private void setInputPartNames(String[] inputPartNames) { + this.inputPartNames = inputPartNames; + } + + /** + * Sets the inputPartQNs. + * @param inputPartQNs The inputPartQNs to set + */ + public void setInputPartQNs(QName[] inputPartQNs) { + this.inputPartQNs = inputPartQNs; + } + + /** + * Sets the inputPartTypeQNs. + * @param inputPartTypeQNs The inputPartTypeQNs to set + */ + private void setInputPartTypeQNs(QName[] inputPartTypeQNs) { + this.inputPartTypeQNs = inputPartTypeQNs; + } + + /** + * Sets the inputPartTypes. + * @param inputPartTypes The inputPartTypes to set + */ + private void setInputPartTypes(Class[] inputPartTypes) { + this.inputPartTypes = inputPartTypes; + } + + /** + * Sets the outputPartNames. + * @param outputPartNames The outputPartNames to set + */ + private void setOutputPartNames(String[] outputPartNames) { + this.outputPartNames = outputPartNames; + } + + /** + * Sets the outputPartQNs. + * @param outputPartQNs The outputPartQNs to set + */ + private void setOutputPartQNs(QName[] outputPartQNs) { + this.outputPartQNs = outputPartQNs; + } + + /** + * Sets the outputPartTypeQNs. + * @param outputPartTypeQNs The outputPartTypeQNs to set + */ + private void setOutputPartTypeQNs(QName[] outputPartTypeQNs) { + this.outputPartTypeQNs = outputPartTypeQNs; + } + + /** + * Sets the outputPartTypes. + * @param outputPartTypes The outputPartTypes to set + */ + private void setOutputPartTypes(Class[] outputPartTypes) { + this.outputPartTypes = outputPartTypes; + } + + /** + * Sets the returnPartIndex. + * @param returnPartIndex The returnPartIndex to set + */ + private void setReturnPartIndex(int returnPartIndex) { + this.returnPartIndex = returnPartIndex; + } + public String deep() { String buff = ""; try { @@ -1360,8 +1825,6 @@ buff += " definition:" + Trc.brief(definition); buff += " soapPartNames:" + soapPartNames; buff += " mimePartNames:" + mimePartNames; - buff += " names:" + names; - buff += " types:" + types; buff += " inputEncodingStyle:" + inputEncodingStyle; buff += " inputNamespace:" + inputNamespace; buff += " actionUri:" + actionUri; @@ -1369,12 +1832,19 @@ buff += " outJmsProps:" + outJmsProps; buff += " inJmsPropVals:" + inJmsPropVals; buff += " context:" + context; - buff += " returnType:" + returnType; buff += " asyncOperation:" + asyncOperation; buff += " asyncRequestID:" + asyncRequestID; buff += " responseHandler:" + responseHandler; buff += " returnName:" + returnName; - buff += " wsdlOutParams:" + wsdlOutParams; + buff += " inputPartNames:" + inputPartNames; + buff += " inputPartQNs:" + inputPartQNs; + buff += " inputPartTypes:" + inputPartTypes; + buff += " inputPartTypeQN:" + inputPartTypeQNs; + buff += " outputPartNames:" + outputPartNames; + buff += " outputPartQNs:" + outputPartQNs; + buff += " outputPartTypes:" + outputPartTypes; + buff += " outputPartTypeQN:" + outputPartTypeQNs; + buff += " returnPartIndex:" + returnPartIndex; buff += " outParams:" + outParams; buff += " outputEncodingStyle:" + outputEncodingStyle; buff += " typeMap:" + typeMap;