antelder 2003/01/17 08:29:08 Modified: java/src/org/apache/wsif/providers/soap/apacheaxis WSIFPort_ApacheAxis.java WSIFOperation_ApacheAxis.java Log: Fix bugzilla 16196 - reinstate the axis WSIFPort caching of WSIFOperations that it creates, and that the axis WSIFOperation to correctly construct, prepare and copy relevant fields. The intention is that constructing an AXIS WSIFOperation doesn't do mcuh work, on the 1st invole the prepare method runs parsing and validating the WSDL and setting up the various instance variables that can be shared btw operation instances, and the copy method copys these field to th enew copied operation, so it doesn't need to then run prepare again. Revision Changes Path 1.23 +6 -5 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.22 retrieving revision 1.23 diff -u -r1.22 -r1.23 --- WSIFPort_ApacheAxis.java 31 Dec 2002 14:25:27 -0000 1.22 +++ WSIFPort_ApacheAxis.java 17 Jan 2003 16:29:07 -0000 1.23 @@ -288,9 +288,8 @@ + ":" + outputName); } - WSIFOperation wo = op.copy(); - Trc.exit(wo); - return wo; + Trc.exit(op); + return op; } /** @@ -408,6 +407,7 @@ getKey(opName, inputName, outputName)); } + WSIFOperation_ApacheAxis wsifOperation; if (cachedOp == null) { BindingOperation bop = WSIFUtils.getBindingOperation( @@ -425,9 +425,10 @@ cachedWSIFOperations.put( getKey(opName, inputName, outputName), cachedOp); + wsifOperation = cachedOp; + } else { + wsifOperation = cachedOp.copy(); } - - WSIFOperation_ApacheAxis wsifOperation = cachedOp.copy(); Trc.exit(wsifOperation); return wsifOperation; 1.63 +256 -251 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.62 retrieving revision 1.63 diff -u -r1.62 -r1.63 --- WSIFOperation_ApacheAxis.java 16 Jan 2003 17:30:46 -0000 1.62 +++ WSIFOperation_ApacheAxis.java 17 Jan 2003 16:29:07 -0000 1.63 @@ -152,7 +152,6 @@ transient protected BindingOperation bindingOperation; transient protected SOAPOperation soapOperation; - transient protected List inputParts; transient protected List inputSOAPParts; transient protected List inputUnwrappedSOAPParts; transient protected List inputMIMEParts; @@ -191,6 +190,11 @@ throws WSIFException { Trc.entry(this, wsifPort, portTypeOperation, typeMap); + /* Note: if you change anything here make sure you consider + * the impact to the constructor, copy and prepare methods + * and to if any instance variables are transient + */ + this.wsifPort = wsifPort; this.portTypeOperation = portTypeOperation; this.typeMap = typeMap; @@ -200,34 +204,45 @@ this.inputEncodingStyle = WSIFAXISConstants.DEFAULT_SOAP_ENCODING_URI; this.outputEncodingStyle = WSIFAXISConstants.DEFAULT_SOAP_ENCODING_URI; - this.inputSOAPParts = new ArrayList(); - this.inputMIMEParts = new ArrayList(); - this.outputSOAPParts = new ArrayList(); - this.outputMIMEParts = new ArrayList(); - - // the parseXxx methods validate the WSDL and setup inputXxx and outputXxx - // arrays of WSDL Part objects for the SOAP, MIME, and Header parts. - parseSoapOperation(); - parseBindingInput(); - parseBindingOutput(); - unwrapSOAPParts(); - - if (Trc.ON) + if (Trc.ON) { Trc.exit(deep()); + } } /** * 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? + * The intention here is to copy anything that the prepare method + * has done so that WSIFOperation instances can be cached by the + * WSIFPort and safely reused with minimum overhead. + * @deprecated why was this ever made public??? It should only + * ever be used by the WSIFPort!!! */ public WSIFOperation_ApacheAxis copy() throws WSIFException { Trc.entry(this); + /* Note: if you change anything here make sure you consider + * the impact to the constructor, copy and prepare methods + * and to if any instance variables are transient + */ + WSIFOperation_ApacheAxis op = new WSIFOperation_ApacheAxis(wsifPort, portTypeOperation, typeMap); + op.inputSOAPParts = inputSOAPParts; + op.inputUnwrappedSOAPParts = inputUnwrappedSOAPParts; + op.inputMIMEParts = inputMIMEParts; + op.inputSOAPHeader = inputSOAPHeader; + op.inputSOAPHeaderFault = inputSOAPHeaderFault; + + op.outputSOAPParts = outputSOAPParts; + op.outputUnwrappedSOAPParts = outputUnwrappedSOAPParts; + op.outputMIMEParts = outputMIMEParts; + op.outputSOAPHeader = outputSOAPHeader; + op.outputSOAPHeaderFault = outputSOAPHeaderFault; + + op.soapOperation = soapOperation; + op.setSoapActionURI(getSoapActionURI()); op.setInputNamespace(getInputNamespace()); op.setInputEncodingStyle(getInputEncodingStyle()); @@ -237,7 +252,7 @@ op.setInputJmsProperties(getInputJmsProperties()); op.setOutputJmsProperties(getOutputJmsProperties()); op.setInputJmsPropertyValues(getInputJmsPropertyValues()); - op.setStyle(getStyle()); + op.setOperationStyle(getOperationStyle()); if (Trc.ON) Trc.exit(op.deep()); @@ -848,6 +863,9 @@ return d; } + /** + * @deprecated use getWSIFPort + */ public WSIFPort_ApacheAxis getDynamicWSIFPort() { Trc.entry(this); Trc.exit(wsifPort); @@ -940,14 +958,6 @@ return responseMessageParameters; } - /** - * Returns the style. - * @return String - */ - public String getStyle() { - return operationStyle; - } - public WSIFPort getWSIFPort() { Trc.entry(this); Trc.exit(wsifPort); @@ -966,11 +976,16 @@ return asyncOperation; } - public void executeInputOnlyOperation(WSIFMessage wsifmessage) + public void executeInputOnlyOperation(WSIFMessage inMsg) throws WSIFException { - Trc.entry(this, wsifmessage); + Trc.entry(this, inMsg); + + if (inMsg == null) { + throw new IllegalArgumentException("input message is null"); + } + setAsyncOperation(false); - invokeRequestResponseOperation(wsifmessage, null, null); + invokeRequestResponseOperation(inMsg, null, null); Trc.exit(); return; } @@ -982,16 +997,22 @@ throws WSIFException { Trc.entry(this, inMsg, outMsg, faultMsg); + + if (inMsg == null) { + throw new IllegalArgumentException("input message is null"); + } + if (outMsg == null) { + throw new IllegalArgumentException("output message is null"); + } + if (faultMsg == null) { + throw new IllegalArgumentException("fault message is null"); + } + close(); setAsyncOperation(false); - boolean succ; - if (WSIFAXISConstants.STYLE_RPC.equals(operationStyle)) { - succ = invokeRequestResponseOperation(inMsg, outMsg, faultMsg); - } else { - succ = - invokeRequestResponseOperationDocument(inMsg, outMsg, faultMsg); - } + boolean succ = + invokeRequestResponseOperation(inMsg, outMsg, faultMsg); Trc.exit(succ); return succ; @@ -1006,10 +1027,15 @@ * @exception WSIFException if something goes wrong. * @see WSIFOperation#executeRequestResponseAsync(WSIFMessage) */ - public WSIFCorrelationId executeRequestResponseAsync(WSIFMessage input) + public WSIFCorrelationId executeRequestResponseAsync(WSIFMessage inMsg) throws WSIFException { - Trc.entry(this, input); - WSIFCorrelationId id = executeRequestResponseAsync(input, null); + Trc.entry(this, inMsg); + + if (inMsg == null) { + throw new IllegalArgumentException("input message is null"); + } + + WSIFCorrelationId id = executeRequestResponseAsync(inMsg, null); Trc.exit(id); return id; @@ -1027,13 +1053,16 @@ * @see WSIFOperation#executeRequestResponseAsync(WSIFMessage,WSIFResponseHandler) */ public WSIFCorrelationId executeRequestResponseAsync( - WSIFMessage input, + WSIFMessage inMsg, WSIFResponseHandler handler) throws WSIFException { + Trc.entry(this, inMsg, handler); - Trc.entry(this, input, handler); + if (inMsg == null) { + throw new IllegalArgumentException("input message is null"); + } close(); - + if (!wsifPort.supportsAsync()) { throw new WSIFException("asynchronous operations not available"); } @@ -1044,7 +1073,7 @@ transport.setWsifOperation(this); transport.setAsyncOperation("true"); - invokeRequestResponseOperation(input, null, null); + invokeRequestResponseOperation(inMsg, null, null); transport.setAsyncOperation("false"); WSIFCorrelationId id = getAsyncRequestID(); @@ -1305,34 +1334,65 @@ MIMEHelper.setMIMEMessagePart(msg, name, value, type); Trc.exit(); - } + } /** - * This does the AXIS Call invoke for RPC style operations - * @deprecated why was this ever public??? + * 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. + * (for now? probably the wrong thing to be doing) */ + private QName getPartType(Part p) { + QName type = p.getTypeName(); + if (type == null) { + type = p.getElementName(); + } + return type; + } + public boolean invokeRequestResponseOperation( WSIFMessage inMsg, WSIFMessage outMsg, WSIFMessage faultMsg) throws WSIFException { Trc.entry(this, inMsg, outMsg, faultMsg); + boolean workedOK = false; Call call = wsifPort.getCall(); - + // Make sure we're making a fresh start. call.removeAllParameters(); call.clearHeaders(); -// if (inputSOAPParts == null) { - prepare(call); +// //TODO need to sort out the namespace +// QName bindingQN = wsifPort.getBindingName(); +// if (bindingQN != null) { +// setInputNamespace(bindingQN.getNamespaceURI()); // } - + + call.setTargetEndpointAddress(wsifPort.getEndPoint()); + + if (!WSIFAXISConstants.STYLE_RPC.equals(operationStyle)) { + call.setEncodingStyle(null); + inputEncodingStyle = ""; + outputEncodingStyle = ""; + } + + if (inputSOAPParts == null) { + prepare(call); + } call.setSOAPActionURI(getSoapActionURI()); - call.setOperationName( - new QName(getInputNamespace(), portTypeOperation.getName())); + + if (WSIFAXISConstants.STYLE_DOCUMENT.equals(operationStyle) + && isInputMessageUnWrapped(inMsg)) { + operationStyle = WSIFAXISConstants.AXIS_STYLE_WRAPPED; + } + + // TODO: what about wrapped messaging? Not supported yet + if (isMessaging(inMsg)) { + operationStyle = WSIFAXISConstants.AXIS_STYLE_MESSAGE; + } + Transport axistransport = getTransport(); - WSIFJMSDestination dest = null; if (axistransport != null) { call.setTransport(axistransport); @@ -1345,11 +1405,98 @@ } } - if (inJmsPropVals != null && !inJmsPropVals.isEmpty()) { + if (dest != null + && inJmsPropVals != null + && !inJmsPropVals.isEmpty()) { checkForTimeoutProperties(inJmsPropVals, dest); dest.setProperties(inJmsPropVals); } - + + //TODO: jms:property parts + + setDestinationContext(dest); + setCallContext(call); + + if (WSIFAXISConstants.AXIS_STYLE_MESSAGE.equals(operationStyle)) { + workedOK = invokeAXISMessaging(call, inMsg, outMsg, faultMsg); + } else if (WSIFAXISConstants.STYLE_RPC.equals(operationStyle)) { + workedOK = invokeAXISRPCStyle(call, inMsg, outMsg, faultMsg, dest); + } else { + workedOK = invokeAXISDocStyle(call, inMsg, outMsg, faultMsg); + } + + Trc.exit(workedOK); + return workedOK; + } + + /** + * This attempts to determine if the WSIF input message parts are + * for a wrapped or unwrapped style operation. Tricky to tell for + * sure so this just checks parts with the correct names exist in + * the message. + * @return true if the input message has a multiple parts matching + * the unwrapped SOAP parts, otherwise false + */ + private boolean isInputMessageUnWrapped(WSIFMessage msg) { + boolean unWrapped = (inputUnwrappedSOAPParts != null); + if (unWrapped) { + for (Iterator i=inputUnwrappedSOAPParts.iterator(); i.hasNext() && unWrapped; ) { + Part p = (Part) i.next(); + try { + msg.getObjectPart(p.getName()); + } catch (WSIFException e) { + unWrapped = false; + } + } + } + return unWrapped; + } + + /** + * This attempts to determine if the WSIF input message parts are + * for a 'message' style document operation. + * Note: messaging cannot use unwrapped parts + * @return true if all the WSIF input message part types for the + * soap parts have a type of DOM Element, otherwise false + */ + private boolean isMessaging(WSIFMessage msg) { + boolean allDOMElements = true; + boolean anyDOMElements = false; + + if (msg != null) { + for (Iterator i = inputSOAPParts.iterator(); i.hasNext(); ) { + Part p = (Part) i.next(); + try { + Object o = msg.getObjectPart(p.getName()); + if (o instanceof Element) { + anyDOMElements = true; + } else { + allDOMElements = false; + } + } catch (WSIFException e) { + Trc.ignoredException(e); + } + } + } + return anyDOMElements && allDOMElements; + } + + + /** + * This does the AXIS Call invoke for document style operations + * when the WSIF input message parts are NOT DOM elements + */ + private boolean invokeAXISRPCStyle( + Call call, + WSIFMessage inMsg, + WSIFMessage outMsg, + WSIFMessage faultMsg, + WSIFJMSDestination dest) + throws WSIFException { + + call.setOperationName( + new QName(getInputNamespace(), portTypeOperation.getName())); + setCallParameterNames(call); setDestinationContext(dest); setCallContext(call); @@ -1400,10 +1547,9 @@ buildResponseMessages(response, outMsg, faultMsg); } - Trc.exit(respOK); return respOK; } - + /** * This tells AXIS the name and type of the input, return, and output parameters. */ @@ -1486,148 +1632,6 @@ } /** - * 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. - * (for now? probably the wrong thing to be doing) - */ - private QName getPartType(Part p) { - QName type = p.getTypeName(); - if (type == null) { - type = p.getElementName(); - } - return type; - } - - public boolean invokeRequestResponseOperationDocument( - WSIFMessage inMsg, - WSIFMessage outMsg, - WSIFMessage faultMsg) - throws WSIFException { - Trc.entry(this, inMsg, outMsg, faultMsg); - boolean workedOK = false; - - Call call = wsifPort.getCall(); - - // Make sure we're making a fresh start. - call.removeAllParameters(); - call.clearHeaders(); - - //TODO need to sort out the namespace - QName bindingQN = wsifPort.getBindingName(); - if (bindingQN != null) { - setInputNamespace(bindingQN.getNamespaceURI()); - } - - call.setSOAPActionURI(getSoapActionURI()); - call.setTargetEndpointAddress(wsifPort.getEndPoint()); - call.setEncodingStyle(null); - inputEncodingStyle = ""; - outputEncodingStyle = ""; - -// if (inputSOAPParts == null) { - prepare(call); -// } - - // confusingly AXIS style="wrapped" is when there are multiple - // input parts, 1 for each unwrapped element, and style="document" - // is for all other document style operations - if (isInputMessageUnWrapped(inMsg)) { - operationStyle = WSIFAXISConstants.AXIS_STYLE_WRAPPED; - } - - // TODO: what about wrapped messaging? Not supported yet - if (isMessaging(inMsg)) { - operationStyle = WSIFAXISConstants.AXIS_STYLE_MESSAGE; - } - - 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 (dest != null - && inJmsPropVals != null - && !inJmsPropVals.isEmpty()) { - checkForTimeoutProperties(inJmsPropVals, dest); - dest.setProperties(inJmsPropVals); - } - - //TODO: jms:property parts - - setDestinationContext(dest); - setCallContext(call); - - if (WSIFAXISConstants.AXIS_STYLE_MESSAGE.equals(operationStyle)) { - workedOK = invokeAXISMessaging(call, inMsg, outMsg, faultMsg); - } else { - workedOK = invokeAXISDocStyle(call, inMsg, outMsg, faultMsg); - } - - Trc.exit(workedOK); - return workedOK; - } - - /** - * This attempts to determine if the WSIF input message parts are - * for a wrapped or unwrapped style operation. Tricky to tell for - * sure so this just checks parts with the correct names exist in - * the message. - * @return true if the input message has a multiple parts matching - * the unwrapped SOAP parts, otherwise false - */ - private boolean isInputMessageUnWrapped(WSIFMessage msg) { - boolean unWrapped = (inputUnwrappedSOAPParts != null); - if (unWrapped) { - for (Iterator i=inputUnwrappedSOAPParts.iterator(); i.hasNext() && unWrapped; ) { - Part p = (Part) i.next(); - try { - msg.getObjectPart(p.getName()); - } catch (WSIFException e) { - unWrapped = false; - } - } - } - return unWrapped; - } - - /** - * This attempts to determine if the WSIF input message parts are - * for a 'message' style document operation. - * Note: messaging cannot use unwrapped parts - * @return true if all the WSIF input message part types for the - * soap parts have a type of DOM Element, otherwise false - */ - private boolean isMessaging(WSIFMessage msg) { - boolean allDOMElements = true; - boolean anyDOMElements = false; - - if (msg != null) { - for (Iterator i = inputSOAPParts.iterator(); i.hasNext(); ) { - Part p = (Part) i.next(); - try { - Object o = msg.getObjectPart(p.getName()); - if (o instanceof Element) { - anyDOMElements = true; - } else { - allDOMElements = false; - } - } catch (WSIFException e) { - Trc.ignoredException(e); - } - } - } - return anyDOMElements && allDOMElements; - } - - /** * This does the AXIS Call invoke for document style operations * when the WSIF input message parts are NOT DOM elements */ @@ -1709,7 +1713,7 @@ List attachments = addAttachments(inMsg, call); - Object[] inputValues = getInputMessageValues2(inMsg, null); + Object[] inputValues = getInputMessageValues(inMsg, null); ArrayList soapBodies = new ArrayList(); for (int i = 0; i < inputValues.length; i++) { if (inputValues[i] instanceof Element) { @@ -1726,7 +1730,6 @@ } } - Object[] axisInputs = soapBodies.toArray(); Trc.event(this, "Invoking AXIS call", call, axisInputs); @@ -1808,13 +1811,32 @@ /** * Prepares this operation. - * The intention of this is to setup everything that can be - * reused by the operation. - * TODO: not much left here, merge with the parseXxx methods? + * The intention of this is to setup everything that can be reused + * by the WSIFOperation. Clients must not reuse a WSIFOperation + * but a WSIFPort may cache WSIFOperation instances and use the + * WSIFOperation copy method to return copies to clients */ private void prepare(Call call) throws WSIFException { Trc.entry(this, call); + /* Note: if you change anything here make sure you consider + * the impact to the constructor, copy and prepare methods + * and to if any instance variables are transient + */ + + /* Create the ArrayList identify each part and populate + * by calling the appropriate parseXxxx method. + */ + this.inputSOAPParts = new ArrayList(); + this.inputMIMEParts = new ArrayList(); + this.outputSOAPParts = new ArrayList(); + this.outputMIMEParts = new ArrayList(); + + parseSoapOperation(); + parseBindingInput(); + parseBindingOutput(); + unwrapSOAPParts(); + // register any jms:address propertyValues addInputJmsPropertyValues(wsifPort.getJmsAddressPropVals()); @@ -1839,7 +1861,9 @@ outputMIMEParts, call); - Trc.exit(); + if (Trc.ON) { + Trc.exit(deep()); + } } /** @@ -2065,56 +2089,22 @@ } } - for (int i = 0; i < inputMIMEParts.size(); i++) { - Part p = (Part) inputMIMEParts.get(i); - String partName = p.getName(); - try { - axisInputs.add(inMsg.getObjectPart(partName)); - } catch (WSIFException e) { - Trc.ignoredException(e); - axisInputs.add(null); // missing part values default to null - } - } - return axisInputs.toArray(); - } - /** - * 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); + /* MIME parts are done seperatley for messaging + * using addAttachmentPart (see invokeAXISMessaging) + */ + if (!WSIFAXISConstants.AXIS_STYLE_MESSAGE.equals(operationStyle)) { + for (int i = 0; i < inputMIMEParts.size(); i++) { + Part p = (Part) inputMIMEParts.get(i); + String partName = p.getName(); + try { + axisInputs.add(inMsg.getObjectPart(partName)); + } catch (WSIFException e) { + Trc.ignoredException(e); + axisInputs.add(null); // missing part values default to null } - } else { - axisInputs.add(value); } - - } + } return axisInputs.toArray(); } @@ -2554,6 +2544,21 @@ Trc.entry(this, asyncRequestID); this.asyncRequestID = asyncRequestID; Trc.exit(); + } + + /** + * @deprecated use getOperationStyle + */ + public String getStyle() { + return operationStyle; + } + + /** + * Returns the operation style. + * @return String + */ + public String getOperationStyle() { + return operationStyle; } /**