You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by xu...@apache.org on 2011/05/30 17:20:22 UTC

svn commit: r1129214 - in /geronimo/bundles/trunk/axis2: pom.xml src/main/java/org/apache/axis2/jaxws/client/dispatch/ src/main/java/org/apache/axis2/jaxws/client/dispatch/BaseDispatch.java

Author: xuhaihong
Date: Mon May 30 15:20:22 2011
New Revision: 1129214

URL: http://svn.apache.org/viewvc?rev=1129214&view=rev
Log:
Try the temp fix for connection leak while using Dispatch.invokeOneWay

Added:
    geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/client/dispatch/
    geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/client/dispatch/BaseDispatch.java   (with props)
Modified:
    geronimo/bundles/trunk/axis2/pom.xml

Modified: geronimo/bundles/trunk/axis2/pom.xml
URL: http://svn.apache.org/viewvc/geronimo/bundles/trunk/axis2/pom.xml?rev=1129214&r1=1129213&r2=1129214&view=diff
==============================================================================
--- geronimo/bundles/trunk/axis2/pom.xml (original)
+++ geronimo/bundles/trunk/axis2/pom.xml Mon May 30 15:20:22 2011
@@ -311,7 +311,8 @@
                            org/apache/axis2/jaxws/description/impl/EndpointDescriptionImpl$6.class=target/classes/org/apache/axis2/jaxws/description/impl/EndpointDescriptionImpl$6.class,
                            org/apache/axis2/transport/http/AbstractHTTPSender.class=target/classes/org/apache/axis2/transport/http/AbstractHTTPSender.class,
                            org/apache/axis2/client/OperationClient.class=target/classes/org/apache/axis2/client/OperationClient.class,
-                           org/apache/axis2/jaxws/description/impl/PostRI216MethodRetrieverImpl.class=target/classes/org/apache/axis2/jaxws/description/impl/PostRI216MethodRetrieverImpl.class
+                           org/apache/axis2/jaxws/description/impl/PostRI216MethodRetrieverImpl.class=target/classes/org/apache/axis2/jaxws/description/impl/PostRI216MethodRetrieverImpl.class,
+                           org/apache/axis2/jaxws/client/dispatch/BaseDispatch.class=target/classes/org/apache/axis2/jaxws/client/dispatch/BaseDispatch.class
                         </Include-Resource>
                         <SPI-Provider>true</SPI-Provider>
                     </instructions>

Added: geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/client/dispatch/BaseDispatch.java
URL: http://svn.apache.org/viewvc/geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/client/dispatch/BaseDispatch.java?rev=1129214&view=auto
==============================================================================
--- geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/client/dispatch/BaseDispatch.java (added)
+++ geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/client/dispatch/BaseDispatch.java Mon May 30 15:20:22 2011
@@ -0,0 +1,998 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.axis2.jaxws.client.dispatch;
+
+import org.apache.axis2.addressing.EndpointReference;
+import org.apache.axis2.client.ServiceClient;
+import org.apache.axis2.description.AxisOperation;
+import org.apache.axis2.description.AxisService;
+import org.apache.axis2.description.Parameter;
+import org.apache.axis2.engine.AxisConfiguration;
+import org.apache.axis2.jaxws.BindingProvider;
+import org.apache.axis2.jaxws.ExceptionFactory;
+import org.apache.axis2.jaxws.client.async.AsyncResponse;
+import org.apache.axis2.jaxws.core.InvocationContext;
+import org.apache.axis2.jaxws.core.InvocationContextFactory;
+import org.apache.axis2.jaxws.core.MessageContext;
+import org.apache.axis2.jaxws.core.controller.InvocationController;
+import org.apache.axis2.jaxws.core.controller.InvocationControllerFactory;
+import org.apache.axis2.jaxws.description.EndpointDescription;
+import org.apache.axis2.jaxws.description.EndpointInterfaceDescription;
+import org.apache.axis2.jaxws.description.OperationDescription;
+import org.apache.axis2.jaxws.i18n.Messages;
+import org.apache.axis2.jaxws.marshaller.impl.alt.MethodMarshallerUtils;
+import org.apache.axis2.jaxws.message.Message;
+import org.apache.axis2.jaxws.registry.FactoryRegistry;
+import org.apache.axis2.jaxws.spi.Binding;
+import org.apache.axis2.jaxws.spi.Constants;
+import org.apache.axis2.jaxws.spi.ServiceDelegate;
+import org.apache.axis2.jaxws.spi.migrator.ApplicationContextMigratorUtil;
+import org.apache.axis2.transport.http.HTTPConstants;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Node;
+
+import javax.xml.namespace.QName;
+import javax.xml.soap.SOAPBody;
+import javax.xml.soap.SOAPException;
+import javax.xml.soap.SOAPMessage;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.ws.AsyncHandler;
+import javax.xml.ws.ProtocolException;
+import javax.xml.ws.Response;
+import javax.xml.ws.Service.Mode;
+import javax.xml.ws.WebServiceException;
+import javax.xml.ws.WebServiceFeature;
+import javax.xml.ws.http.HTTPBinding;
+import javax.xml.ws.soap.SOAPBinding;
+
+import java.io.IOException;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Future;
+
+public abstract class BaseDispatch<T> extends BindingProvider
+        implements javax.xml.ws.Dispatch {
+
+    private static Log log = LogFactory.getLog(BaseDispatch.class);
+
+    protected InvocationController ic;
+
+    protected ServiceClient serviceClient;
+
+    protected Mode mode;
+
+    protected BaseDispatch(ServiceDelegate svcDelgate,
+                           EndpointDescription epDesc,
+                           EndpointReference epr,
+                           String addressingNamespace,
+                           WebServiceFeature... features) {
+        super(svcDelgate, epDesc, epr, addressingNamespace, features);
+
+        InvocationControllerFactory icf = (InvocationControllerFactory) FactoryRegistry.getFactory(InvocationControllerFactory.class);
+        ic = icf.getInvocationController();
+        
+        if (ic == null) {
+            throw new WebServiceException(Messages.getMessage("missingInvocationController"));
+        }
+    }
+
+    /**
+     * Take the input object and turn it into an OMElement so that it can be sent.
+     *
+     * @param value
+     * @return
+     */
+    protected abstract Message createMessageFromValue(Object value);
+
+    /**
+     * Given a message, return the business object based on the requestor's required format (PAYLOAD
+     * vs. MESSAGE) and datatype.
+     *
+     * @param message
+     * @return
+     */
+    protected abstract Object getValueFromMessage(Message message);
+
+    /**
+     * Creates an instance of the AsyncListener that is to be used for waiting for async responses.
+     *
+     * @return a configured AsyncListener instance
+     */
+    protected abstract AsyncResponse createAsyncResponseListener();
+
+    
+    /**
+     * Note to developer: When making a change or fix to this method, please consider
+     * all 5 Proxy/Dispatch "invoke" methods now available in JAX-WS. For Dispatch, 
+     * these are:
+     * 1) Synchronous invoke()
+     * 2) invokeOneWay()
+     * 3) invokeAsynch (Future)
+     * 4) invokeAsynch (Callback)
+     * 
+     * For Proxy:
+     * 5) invokeSEIMethod() 
+     *
+     */
+    public Object invoke(Object obj) throws WebServiceException {
+
+        // Catch all exceptions and rethrow an appropriate WebService Exception
+        try {
+            if (log.isDebugEnabled()) {
+                log.debug("Entered synchronous invocation: BaseDispatch.invoke()");
+            }
+
+            // Create the InvocationContext instance for this request/response flow.
+            InvocationContext invocationContext =
+                    InvocationContextFactory.createInvocationContext(null);
+            invocationContext.setServiceClient(serviceClient);
+
+            // Create the MessageContext to hold the actual request message and its
+            // associated properties
+            MessageContext requestMsgCtx = new MessageContext();
+            requestMsgCtx.getAxisMessageContext().setProperty(BINDING_PROVIDER, this);
+            requestMsgCtx.setEndpointDescription(getEndpointDescription());
+            invocationContext.setRequestMessageContext(requestMsgCtx);
+            
+            /*
+             * TODO: review: make sure the handlers are set on the InvocationContext
+             * This implementation of the JAXWS runtime does not use Endpoint, which
+             * would normally be the place to initialize and store the handler list.
+             * In lieu of that, we will have to intialize and store them on the 
+             * InvocationContext.  also see the InvocationContextFactory.  On the client
+             * side, the binding is not yet set when we call into that factory, so the
+             * handler list doesn't get set on the InvocationContext object there.  Thus
+             * we gotta do it here.
+             */
+
+            // be sure to use whatever handlerresolver is registered on the Service
+            Binding binding = (Binding) getBinding();
+            invocationContext.setHandlers(binding.getHandlerChain());
+
+            initMessageContext(obj, requestMsgCtx);
+
+            // call common init method for all invoke* paths
+            preInvokeInit(invocationContext);
+                        
+            // Migrate the properties from the client request context bag to
+            // the request MessageContext.
+            ApplicationContextMigratorUtil.performMigrationToMessageContext(
+                    Constants.APPLICATION_CONTEXT_MIGRATOR_LIST_ID,
+                    getRequestContext(), requestMsgCtx);
+
+            // Perform the WebServiceFeature configuration requested by the user.
+            binding.configure(requestMsgCtx, this);
+
+            // Initializing the message context above will put the outbound message onto the messageContext
+            // Determine the operation if possible from the outbound message.  If it can not be determined
+            // it will be set to null.  In this case, an anonymous operation will be used.  Note that determining
+            // the operation will mean deserializing the message.  That means that any WebServiceFeatures must have
+            // been configured first so that any relevant configurations (such as MTOM) have been initialized prior to 
+            // the message being deserialized.  This is particularly true for Dispatch<JAXB Element>.
+            requestMsgCtx.setOperationDescription(getOperationDescriptionForDispatch(requestMsgCtx));
+
+            // Send the request using the InvocationController
+            ic.invoke(invocationContext);
+
+            MessageContext responseMsgCtx = invocationContext.getResponseMessageContext();
+            responseMsgCtx.setEndpointDescription(requestMsgCtx.getEndpointDescription());
+
+            // Migrate the properties from the response MessageContext back
+            // to the client response context bag.
+            ApplicationContextMigratorUtil.performMigrationFromMessageContext(
+                    Constants.APPLICATION_CONTEXT_MIGRATOR_LIST_ID,
+                    getResponseContext(), responseMsgCtx);
+            
+            if (hasFaultResponse(responseMsgCtx)) {
+                WebServiceException wse = BaseDispatch.getFaultResponse(responseMsgCtx);
+                throw wse;
+            }
+
+            // Get the return object
+            Object returnObj = null;
+            try {
+                Message responseMsg = responseMsgCtx.getMessage();
+                returnObj = getValueFromMessage(responseMsg);
+            }
+            finally {
+                // Free the incoming input stream
+                try {
+                    responseMsgCtx.freeInputStream();
+                }
+                catch (Throwable t) {
+                    throw ExceptionFactory.makeWebServiceException(t);
+                }
+            }
+           
+            //Check to see if we need to maintain session state
+            checkMaintainSessionState(requestMsgCtx, invocationContext);
+
+            if (log.isDebugEnabled()) {
+                log.debug("Synchronous invocation completed: BaseDispatch.invoke()");
+            }
+
+            return returnObj;
+        } catch (WebServiceException e) {
+            if (log.isDebugEnabled()) {
+                log.debug("BaseDispatch.invoke(): Synchronous invocation failed, " 
+                        + "caught a WebServiceException: ", e);
+            }
+            throw e;
+        } catch (Exception e) {
+            // All exceptions are caught and rethrown as a WebServiceException
+            if (log.isDebugEnabled()) {
+                log.debug("BaseDispatch.invoke(): Synchronous invocation failed, caught an Exception, " + 
+                        "wrapping into a WebServiceException. Exception caught: ", e);
+            }  
+            throw ExceptionFactory.makeWebServiceException(e);
+        }
+    }
+
+    /**
+     * Given a JAXWS Message Context which contains an outbound service-requester Message for a Dispatch client, 
+     * determine the OperationDescription for the operation contained in that Dispatch message.
+     * 
+     * Note that operation resolution can be disabled by a property setting.
+     * @see org.apache.axis2.jaxws.Constants.DISPATCH_CLIENT_OUTBOUND_RESOLUTION
+     * 
+     * @param requestMessageCtx JAXWS Message Context containing the outbound Dispatch message
+     * @return the OperationDescription corresponding to the operation contained in the Dispatch message, or null 
+     * if it can not be determined or if dispatch operation resolution is disabled via a property.
+     */
+    private OperationDescription getOperationDescriptionForDispatch(MessageContext requestMessageCtx) {
+        OperationDescription operationDesc = null;
+        if (dispatchOperationResolutionEnabled()) {
+            EndpointInterfaceDescription endpointInterfaceDesc = getEndpointDescription().getEndpointInterfaceDescription();
+            // The SEI interface could be null (for example if there was no SEI and all the ports were dynamically added).
+            // If there is an SEI, then try to determine the operation for the outbound dispatch message.
+            if (endpointInterfaceDesc != null) {
+                QName bodyElementQName = getBodyElementQNameFromDispatchMessage(requestMessageCtx);
+                operationDesc = determineOperationDescFromBodyElementQName(endpointInterfaceDesc, bodyElementQName);
+            }
+        }
+        return operationDesc;
+    }
+    
+    /**
+     * Returns the OperationDescription corresponding to the bodyElementQName passed in.  What that body element corresponds to
+     * depends on the type of the message:
+     * - For Doc/Lit/Wrapped, the body element is the operation name
+     * - For Doc/Lit/Bare, the body element is the element name contained in the wsdl:message wsdl:part
+     * - For RPC, the body element is effectively the operation name.
+     * 
+     * @param endpointInterfaceDesc The interface (i.e. SEI) on which to search for the operation
+     * @param bodyElementQName the QName of the first body element for which to find the operation
+     * 
+     * @return The OperationDescription corresponding to the body element QName or null if one can not be found.
+     */
+    private OperationDescription determineOperationDescFromBodyElementQName(EndpointInterfaceDescription endpointInterfaceDesc,
+                                                                            QName bodyElementQName) {
+        OperationDescription operationDesc = null;
+        
+        // If there's no bodyElementQName for us to work with, there's nothing more we can do.
+        if (bodyElementQName != null) {
+            // This logic mimics the code in SOAPMessageBodyBasedOperationDispatcher.findOperation.  We will look for
+            // the AxisOperation corresponding to the body element name.  Note that we are searching for the AxisOperation instead
+            // of searching through the OperationDescriptions so that we can use the getOperationByMessageElementQName
+            // for the Doc/Lit/Bare case.  Once we have the AxisOperation, we'll use that to find the Operation Description.
+            AxisService axisService = endpointInterfaceDesc.getEndpointDescription().getAxisService();
+            AxisOperation axisOperation = null;
+    
+            // Doc/Lit/Wrapped and RPC, the operation name is the first body element qname
+            axisOperation = axisService.getOperation(new QName(bodyElementQName.getLocalPart()));
+            
+            if (axisOperation == null) {
+                // Doc/Lit/Bare, the first body element qname is the element name contained in the wsdl:message part
+                axisOperation = axisService.getOperationByMessageElementQName(bodyElementQName);
+            }
+            
+            if (axisOperation == null) {
+                // Not sure why we wouldn't have found the operation above using just the localPart rather than the full QName used here,
+                // but this is what SOAPMessageBodyBasedOperationDispatcher.findOperation does.
+                axisOperation = axisService.getOperation(bodyElementQName);
+            }
+    
+            // If we found an axis operation, then find the operation description that corresponds to it
+            if (axisOperation != null) {
+                OperationDescription allOpDescs[] = endpointInterfaceDesc.getDispatchableOperations();
+                for (OperationDescription checkOpDesc : allOpDescs ) {
+                    AxisOperation checkAxisOperation = checkOpDesc.getAxisOperation();
+                    if (checkAxisOperation == axisOperation) {
+                        operationDesc = checkOpDesc;
+                        break;
+                    }
+                }
+            }
+        }
+        return operationDesc;
+    }
+
+    /**
+     * Answer if operation resolution on outbound messages for dispatch clients should be done.  The default value 
+     * is TRUE, enabling operation resolution.  Resolution can be disabled via a property on the AxisConfiguration
+     * or on the RequestContext.  
+     * 
+     * Operation resolution is also disabled if a non-null value is specified on the request context for the Action
+     * 
+     * @see org.apache.axis2.jaxws.Constants.DISPATCH_CLIENT_OUTBOUND_RESOLUTION
+     * @see javax.xml.ws.BindingProvider.SOAPACTION_USE_PROPERTY
+     * @see javax.xml.ws.BindingProvider.SOAPACTION_URI_PROPERTY
+     * 
+     * @return true if operation resolution should be performed on outbound 
+     */
+    private boolean dispatchOperationResolutionEnabled() {
+        boolean resolutionEnabled = true;
+        
+        // See if any properties disabled operation resolution 
+        // Check for System property setting
+        String flagValue = getProperty(org.apache.axis2.jaxws.Constants.DISPATCH_CLIENT_OUTBOUND_RESOLUTION);
+
+        // If no System property was set, see if one was set on this request context.
+        if (flagValue == null) {
+            flagValue =  (String) getRequestContext().get(org.apache.axis2.jaxws.Constants.DISPATCH_CLIENT_OUTBOUND_RESOLUTION);
+        }
+        
+        // If any property was set, check the value.
+        if (flagValue != null) {
+            if ("false".equalsIgnoreCase(flagValue)) {
+                resolutionEnabled = false;
+            } else if ("true".equalsIgnoreCase(flagValue)) {
+                resolutionEnabled = true;
+            }
+        }
+
+        // If a property didn't disable resolution, then see if a URI value was specified.
+        // If so, we'll use that later and there's no need to do operation resolution.         
+        if (resolutionEnabled) {
+            Boolean useSoapAction = (Boolean) getRequestContext().get(SOAPACTION_USE_PROPERTY);
+            if (useSoapAction != null && useSoapAction.booleanValue()) {
+                String soapAction = (String) getRequestContext().get(SOAPACTION_URI_PROPERTY);
+                if (soapAction != null) {
+                    resolutionEnabled = false;
+                }
+            }
+        }
+        return resolutionEnabled;
+    }
+
+    /**
+     * Retrieve the specified property from the AxisConfiguration.
+     * 
+     * @param key The property to retrieve from the AxisConfiguration
+     * @return the value associated with the property or null if the property did not exist on the configuration.
+     */
+    private String getProperty(String key) {
+        String propertyValue = null;
+        AxisConfiguration axisConfig = serviceDelegate.getServiceDescription().getAxisConfigContext().getAxisConfiguration();
+        Parameter parameter = axisConfig.getParameter(key);
+        if (parameter != null) {
+            propertyValue = (String) parameter.getValue();
+        }
+        return propertyValue;
+    }
+
+
+    /**
+     * Given a JAXWS Message Context which contains an outbound service-requester Message for a Dispatch client,
+     * determine the QName of the first body element contained in that message.
+     * 
+     * @param requestMessageCtx requestMessageCtx JAXWS Message Context containing the outbound Dispatch message
+     * @return the QName of the first body element contained in the outbound Dispatch message, or null if it 
+     * can not be determined.
+     */
+    QName getBodyElementQNameFromDispatchMessage(MessageContext requestMessageCtx) {
+        QName bodyElementQName = null;
+        Message dispatchMessage = requestMessageCtx.getMessage();
+        SOAPMessage soapMessage = dispatchMessage.getAsSOAPMessage();
+        try {
+            SOAPBody soapBody = soapMessage.getSOAPBody();
+            Node firstElement = soapBody.getFirstChild();
+            // A Doc/Lit/Bare message may not have a firsElement.  The soap:Body element may be empty if there 
+            // are no arguments to the operation.
+            if (firstElement != null) {
+                String ns = firstElement.getNamespaceURI();
+                String lp= firstElement.getLocalName();
+                // A Doc/Lit/Bare message may not have a localPart on the element.  That can happen if the first element
+                // is the argument value and there is no wrapper element surrounding it.
+                if (lp != null) {
+                    bodyElementQName = new QName(ns, lp);
+                }
+            }
+        } catch (SOAPException e) {
+            if (log.isDebugEnabled()) {
+                log.debug("Unabled to get the first body element from the outbound dispatch message", e);
+            }
+        }
+        return bodyElementQName;
+    }
+
+    protected void initMessageContext(Object obj, MessageContext requestMsgCtx) {
+        Message requestMsg = createRequestMessage(obj);
+        setupMessageProperties(requestMsg);
+        requestMsgCtx.setMessage(requestMsg);
+        // handle HTTP_REQUEST_METHOD property
+        String method = (String)requestContext.get(javax.xml.ws.handler.MessageContext.HTTP_REQUEST_METHOD);
+        if (method != null) {
+            requestMsgCtx.setProperty(org.apache.axis2.Constants.Configuration.HTTP_METHOD, method);
+        }
+    }
+
+    /**
+     * Note to developer: When making a change or fix to this method, please consider
+     * all 5 Proxy/Dispatch "invoke" methods now available in JAX-WS. For Dispatch, 
+     * these are:
+     * 1) Synchronous invoke()
+     * 2) invokeOneWay()
+     * 3) invokeAsynch (Future)
+     * 4) invokeAsynch (Callback)
+     * 
+     * For Proxy:
+     * 5) invokeSEIMethod() 
+     *
+     */
+    public void invokeOneWay(Object obj) throws WebServiceException {
+
+        // All exceptions are caught and rethrown as a WebServiceException
+        MessageContext requestMsgCtx = null;
+        try {
+            if (log.isDebugEnabled()) {
+                log.debug("Entered one-way invocation: BaseDispatch.invokeOneWay()");
+            }
+
+            // Create the InvocationContext instance for this request/response flow.
+            InvocationContext invocationContext =
+                    InvocationContextFactory.createInvocationContext(null);
+            invocationContext.setServiceClient(serviceClient);
+
+            // Create the MessageContext to hold the actual request message and its
+            // associated properties
+            requestMsgCtx = new MessageContext();
+            requestMsgCtx.getAxisMessageContext().setProperty(BINDING_PROVIDER, this);
+            requestMsgCtx.setEndpointDescription(getEndpointDescription());
+            invocationContext.setRequestMessageContext(requestMsgCtx);
+            
+            /*
+             * TODO: review: make sure the handlers are set on the InvocationContext
+             * This implementation of the JAXWS runtime does not use Endpoint, which
+             * would normally be the place to initialize and store the handler list.
+             * In lieu of that, we will have to intialize and store them on the 
+             * InvocationContext.  also see the InvocationContextFactory.  On the client
+             * side, the binding is not yet set when we call into that factory, so the
+             * handler list doesn't get set on the InvocationContext object there.  Thus
+             * we gotta do it here.
+             */
+
+            // be sure to use whatever handlerresolver is registered on the Service
+            Binding binding = (Binding) getBinding();
+            invocationContext.setHandlers(binding.getHandlerChain());
+
+            initMessageContext(obj, requestMsgCtx);
+
+            /*
+             * if SESSION_MAINTAIN_PROPERTY is true, and the client app has explicitly set a HEADER_COOKIE on the request context, assume the client
+             * app is expecting the HEADER_COOKIE to be the session id.  If we were establishing a new session, no cookie would be sent, and the 
+             * server would reply with a "Set-Cookie" header, which is copied as a "Cookie"-keyed property to the service context during response.
+             * In this case, if we succeed in using an existing server session, no "Set-Cookie" header will be returned, and therefore no
+             * "Cookie"-keyed property would be set on the service context.  So, let's copy our request context HEADER_COOKIE key to the service
+             * context now to prevent the "no cookie" exception in BindingProvider.setupSessionContext.  It is possible the server does not support
+             * sessions, in which case no error occurs, but the client app would assume it is participating in a session.
+             */
+            if ((requestContext.containsKey(BindingProvider.SESSION_MAINTAIN_PROPERTY)) && ((Boolean)requestContext.get(BindingProvider.SESSION_MAINTAIN_PROPERTY))) {
+                if ((requestContext.containsKey(HTTPConstants.HEADER_COOKIE)) && (requestContext.get(HTTPConstants.HEADER_COOKIE) != null)) {
+                    if (invocationContext.getServiceClient().getServiceContext().getProperty(HTTPConstants.HEADER_COOKIE) == null) {
+                        invocationContext.getServiceClient().getServiceContext().setProperty(HTTPConstants.HEADER_COOKIE, requestContext.get(HTTPConstants.HEADER_COOKIE));
+                        if (log.isDebugEnabled()) {
+                            log.debug("Client-app defined Cookie property (assume to be session cookie) on request context copied to service context." +
+                                "  Caution:  server may or may not support sessions, but client app will not be informed when not supported.");
+                        }
+                    }
+                }
+            }
+
+            // call common init method for all invoke* paths
+            preInvokeInit(invocationContext);
+            
+            // Migrate the properties from the client request context bag to
+            // the request MessageContext.
+            ApplicationContextMigratorUtil.performMigrationToMessageContext(
+                    Constants.APPLICATION_CONTEXT_MIGRATOR_LIST_ID,
+                    getRequestContext(), requestMsgCtx);
+
+            // Perform the WebServiceFeature configuration requested by the user.
+            binding.configure(requestMsgCtx, this);
+
+            // Initializing the message context above will put the outbound message onto the messageContext
+            // Determine the operation if possible from the outbound message.  If it can not be determined
+            // it will be set to null.  In this case, an anonymous operation will be used.  Note that determining
+            // the operation will mean deserializing the message.  That means that any WebServiceFeatures must have
+            // been configured first so that any relevant configurations (such as MTOM) have been initialized prior to 
+            // the message being deserialized.  This is particularly true for Dispatch<JAXB Element>.
+            requestMsgCtx.setOperationDescription(getOperationDescriptionForDispatch(requestMsgCtx));
+
+            // Send the request using the InvocationController
+            ic.invokeOneWay(invocationContext);
+
+            //Check to see if we need to maintain session state
+            checkMaintainSessionState(requestMsgCtx, invocationContext);
+
+            if (log.isDebugEnabled()) {
+                log.debug("One-way invocation completed: BaseDispatch.invokeOneWay()");
+            }
+
+            return;
+        } catch (WebServiceException e) {
+            if (log.isDebugEnabled()) {
+                log.debug("BaseDispatch.invokeOneWay(): One-way invocation failed, " + 
+                        "caught a WebServiceException: ", e);
+            }
+            throw e;
+        } catch (Exception e) {
+            // All exceptions are caught and rethrown as a WebServiceException
+            if (log.isDebugEnabled()) {
+                log.debug("BaseDispatch.invokeOneWay(): One-way invocation failed, " + 
+                        "caught an Exception, wrapping into a WebServicesException. " + 
+                        " Exception caught: ", e);
+            }
+            throw ExceptionFactory.makeWebServiceException(e);
+        } finally {
+            try {
+                if (requestMsgCtx != null && requestMsgCtx.getAxisMessageContext() != null) {
+                    org.apache.axis2.context.MessageContext axisMsgCtx = requestMsgCtx.getAxisMessageContext();
+                    if (axisMsgCtx.getTransportOut() != null && axisMsgCtx.getTransportOut().getSender() != null) {
+                        axisMsgCtx.getTransportOut().getSender().cleanup(axisMsgCtx);
+                    }
+                }
+            } catch (Exception ignore) {
+            }
+        }
+    }
+
+    /**
+     * Note to developer: When making a change or fix to this method, please consider
+     * all 5 Proxy/Dispatch "invoke" methods now available in JAX-WS. For Dispatch, 
+     * these are:
+     * 1) Synchronous invoke()
+     * 2) invokeOneWay()
+     * 3) invokeAsynch (Future)
+     * 4) invokeAsynch (Callback)
+     * 
+     * For Proxy:
+     * 5) invokeSEIMethod() 
+     *
+     */
+    public Future<?> invokeAsync(Object obj, AsyncHandler asynchandler) throws WebServiceException {
+
+        // All exceptions are caught and rethrown as a WebServiceException
+        try {
+            if (log.isDebugEnabled()) {
+                log.debug("Entered asynchronous (callback) invocation: BaseDispatch.invokeAsync()");
+            }
+
+            // Create the InvocationContext instance for this request/response flow.
+            InvocationContext invocationContext =
+                    InvocationContextFactory.createInvocationContext(null);
+            invocationContext.setServiceClient(serviceClient);
+
+            // Create the MessageContext to hold the actual request message and its
+            // associated properties
+            MessageContext requestMsgCtx = new MessageContext();
+            requestMsgCtx.getAxisMessageContext().setProperty(BINDING_PROVIDER, this);
+            requestMsgCtx.setEndpointDescription(getEndpointDescription());
+            invocationContext.setRequestMessageContext(requestMsgCtx);
+            
+            /*
+             * TODO: review: make sure the handlers are set on the InvocationContext
+             * This implementation of the JAXWS runtime does not use Endpoint, which
+             * would normally be the place to initialize and store the handler list.
+             * In lieu of that, we will have to intialize and store them on the 
+             * InvocationContext.  also see the InvocationContextFactory.  On the client
+             * side, the binding is not yet set when we call into that factory, so the
+             * handler list doesn't get set on the InvocationContext object there.  Thus
+             * we gotta do it here.
+             */
+
+            // be sure to use whatever handlerresolver is registered on the Service
+            Binding binding = (Binding) getBinding();
+            invocationContext.setHandlers(binding.getHandlerChain());
+
+            initMessageContext(obj, requestMsgCtx);
+            /*
+             * if SESSION_MAINTAIN_PROPERTY is true, and the client app has explicitly set a HEADER_COOKIE on the request context, assume the client
+             * app is expecting the HEADER_COOKIE to be the session id.  If we were establishing a new session, no cookie would be sent, and the 
+             * server would reply with a "Set-Cookie" header, which is copied as a "Cookie"-keyed property to the service context during response.
+             * In this case, if we succeed in using an existing server session, no "Set-Cookie" header will be returned, and therefore no
+             * "Cookie"-keyed property would be set on the service context.  So, let's copy our request context HEADER_COOKIE key to the service
+             * context now to prevent the "no cookie" exception in BindingProvider.setupSessionContext.  It is possible the server does not support
+             * sessions, in which case no error occurs, but the client app would assume it is participating in a session.
+             */
+            if ((requestContext.containsKey(BindingProvider.SESSION_MAINTAIN_PROPERTY)) && ((Boolean)requestContext.get(BindingProvider.SESSION_MAINTAIN_PROPERTY))) {
+                if ((requestContext.containsKey(HTTPConstants.HEADER_COOKIE)) && (requestContext.get(HTTPConstants.HEADER_COOKIE) != null)) {
+                    if (invocationContext.getServiceClient().getServiceContext().getProperty(HTTPConstants.HEADER_COOKIE) == null) {
+                        invocationContext.getServiceClient().getServiceContext().setProperty(HTTPConstants.HEADER_COOKIE, requestContext.get(HTTPConstants.HEADER_COOKIE));
+                        if (log.isDebugEnabled()) {
+                            log.debug("Client-app defined Cookie property (assume to be session cookie) on request context copied to service context." +
+                                "  Caution:  server may or may not support sessions, but client app will not be informed when not supported.");
+                        }
+                    }
+                }
+            }
+
+            // call common init method for all invoke* paths
+            preInvokeInit(invocationContext);
+            
+            // Migrate the properties from the client request context bag to
+            // the request MessageContext.
+            ApplicationContextMigratorUtil.performMigrationToMessageContext(
+                    Constants.APPLICATION_CONTEXT_MIGRATOR_LIST_ID,
+                    getRequestContext(), requestMsgCtx);
+
+            // Perform the WebServiceFeature configuration requested by the user.
+            binding.configure(requestMsgCtx, this);
+
+            // Initializing the message context above will put the outbound message onto the messageContext
+            // Determine the operation if possible from the outbound message.  If it can not be determined
+            // it will be set to null.  In this case, an anonymous operation will be used.  Note that determining
+            // the operation will mean deserializing the message.  That means that any WebServiceFeatures must have
+            // been configured first so that any relevant configurations (such as MTOM) have been initialized prior to 
+            // the message being deserialized.  This is particularly true for Dispatch<JAXB Element>.
+            requestMsgCtx.setOperationDescription(getOperationDescriptionForDispatch(requestMsgCtx));
+
+            // Setup the Executor that will be used to drive async responses back to 
+            // the client.
+            // FIXME: We shouldn't be getting this from the ServiceDelegate, rather each 
+            // Dispatch object should have it's own.
+            Executor e = serviceDelegate.getExecutor();
+            invocationContext.setExecutor(e);
+
+            // Create the AsyncListener that is to be used by the InvocationController.
+            AsyncResponse listener = createAsyncResponseListener();
+            invocationContext.setAsyncResponseListener(listener);
+
+            // Send the request using the InvocationController
+            Future<?> asyncResponse = ic.invokeAsync(invocationContext, asynchandler);
+
+            //Check to see if we need to maintain session state
+            checkMaintainSessionState(requestMsgCtx, invocationContext);
+
+            if (log.isDebugEnabled()) {
+                log.debug("Asynchronous (callback) invocation sent: BaseDispatch.invokeAsync()");
+            }
+
+            return asyncResponse;
+        } catch (WebServiceException e) {
+            if (log.isDebugEnabled()) {
+                log.debug("BaseDispatch.invokeAsync() [Callback]: Asynchronous invocation failed, " +
+                    "caught a WebServiceException: ", e);
+            }
+            throw e;
+        } catch (Exception e) {
+            if (log.isDebugEnabled()) {
+                log.debug("BaseDispatch.invokeAsync() [Callback]: Asynchronous invocation failed, " +
+                    "caught an Exception, wrapping into a WebServiceException. Exception caught: ", e);
+            }
+            // All exceptions are caught and rethrown as a WebServiceException
+            throw ExceptionFactory.makeWebServiceException(e);
+        }
+    }
+
+    /**
+     * Note to developer: When making a change or fix to this method, please consider
+     * all 5 Proxy/Dispatch "invoke" methods now available in JAX-WS. For Dispatch, 
+     * these are:
+     * 1) Synchronous invoke()
+     * 2) invokeOneWay()
+     * 3) invokeAsynch (Future)
+     * 4) invokeAsynch (Callback)
+     * 
+     * For Proxy:
+     * 5) invokeSEIMethod() 
+     *
+     */
+    public Response invokeAsync(Object obj) throws WebServiceException {
+
+        // All exceptions are caught and rethrown as a WebServiceException
+        try {
+            if (log.isDebugEnabled()) {
+                log.debug("Entered asynchronous (polling) invocation: BaseDispatch.invokeAsync()");
+            }
+
+            // Create the InvocationContext instance for this request/response flow.
+            InvocationContext invocationContext =
+                    InvocationContextFactory.createInvocationContext(null);
+            invocationContext.setServiceClient(serviceClient);
+
+            // Create the MessageContext to hold the actual request message and its
+            // associated properties
+            MessageContext requestMsgCtx = new MessageContext();
+            requestMsgCtx.getAxisMessageContext().setProperty(BINDING_PROVIDER, this);
+            requestMsgCtx.setEndpointDescription(getEndpointDescription());
+            invocationContext.setRequestMessageContext(requestMsgCtx);
+            
+            /*
+             * TODO: review: make sure the handlers are set on the InvocationContext
+             * This implementation of the JAXWS runtime does not use Endpoint, which
+             * would normally be the place to initialize and store the handler list.
+             * In lieu of that, we will have to intialize and store them on the 
+             * InvocationContext.  also see the InvocationContextFactory.  On the client
+             * side, the binding is not yet set when we call into that factory, so the
+             * handler list doesn't get set on the InvocationContext object there.  Thus
+             * we gotta do it here.
+             */
+
+            // be sure to use whatever handlerresolver is registered on the Service
+            Binding binding = (Binding) getBinding();
+            invocationContext.setHandlers(binding.getHandlerChain());
+
+            initMessageContext(obj, requestMsgCtx);
+
+            /*
+             * if SESSION_MAINTAIN_PROPERTY is true, and the client app has explicitly set a HEADER_COOKIE on the request context, assume the client
+             * app is expecting the HEADER_COOKIE to be the session id.  If we were establishing a new session, no cookie would be sent, and the 
+             * server would reply with a "Set-Cookie" header, which is copied as a "Cookie"-keyed property to the service context during response.
+             * In this case, if we succeed in using an existing server session, no "Set-Cookie" header will be returned, and therefore no
+             * "Cookie"-keyed property would be set on the service context.  So, let's copy our request context HEADER_COOKIE key to the service
+             * context now to prevent the "no cookie" exception in BindingProvider.setupSessionContext.  It is possible the server does not support
+             * sessions, in which case no error occurs, but the client app would assume it is participating in a session.
+             */
+            if ((requestContext.containsKey(BindingProvider.SESSION_MAINTAIN_PROPERTY)) && ((Boolean)requestContext.get(BindingProvider.SESSION_MAINTAIN_PROPERTY))) {
+                if ((requestContext.containsKey(HTTPConstants.HEADER_COOKIE)) && (requestContext.get(HTTPConstants.HEADER_COOKIE) != null)) {
+                    if (invocationContext.getServiceClient().getServiceContext().getProperty(HTTPConstants.HEADER_COOKIE) == null) {
+                        invocationContext.getServiceClient().getServiceContext().setProperty(HTTPConstants.HEADER_COOKIE, requestContext.get(HTTPConstants.HEADER_COOKIE));
+                        if (log.isDebugEnabled()) {
+                            log.debug("Client-app defined Cookie property (assume to be session cookie) on request context copied to service context." +
+                                "  Caution:  server may or may not support sessions, but client app will not be informed when not supported.");
+                        }
+                    }
+                }
+            }
+
+            // call common init method for all invoke* paths
+            preInvokeInit(invocationContext);
+            
+            // Migrate the properties from the client request context bag to
+            // the request MessageContext.
+            ApplicationContextMigratorUtil.performMigrationToMessageContext(
+                    Constants.APPLICATION_CONTEXT_MIGRATOR_LIST_ID,
+                    getRequestContext(), requestMsgCtx);
+
+            // Perform the WebServiceFeature configuration requested by the user.
+            binding.configure(requestMsgCtx, this);
+
+            // Initializing the message context above will put the outbound message onto the messageContext
+            // Determine the operation if possible from the outbound message.  If it can not be determined
+            // it will be set to null.  In this case, an anonymous operation will be used.  Note that determining
+            // the operation will mean deserializing the message.  That means that any WebServiceFeatures must have
+            // been configured first so that any relevant configurations (such as MTOM) have been initialized prior to 
+            // the message being deserialized.  This is particularly true for Dispatch<JAXB Element>.
+            requestMsgCtx.setOperationDescription(getOperationDescriptionForDispatch(requestMsgCtx));
+            
+
+            // Setup the Executor that will be used to drive async responses back to 
+            // the client.
+            // FIXME: We shouldn't be getting this from the ServiceDelegate, rather each 
+            // Dispatch object should have it's own.
+            Executor e = serviceDelegate.getExecutor();
+            invocationContext.setExecutor(e);
+
+            // Create the AsyncListener that is to be used by the InvocationController.
+            AsyncResponse listener = createAsyncResponseListener();
+            invocationContext.setAsyncResponseListener(listener);
+
+            // Send the request using the InvocationController
+            Response asyncResponse = ic.invokeAsync(invocationContext);
+
+            //Check to see if we need to maintain session state
+            checkMaintainSessionState(requestMsgCtx, invocationContext);
+
+            if (log.isDebugEnabled()) {
+                log.debug("Asynchronous (polling) invocation sent: BaseDispatch.invokeAsync()");
+            }
+
+            return asyncResponse;
+        } catch (WebServiceException e) {
+            if (log.isDebugEnabled()) {
+                log.debug("BaseDispatch.invokeAsync() [Polling]: Asynchronous invocation failed, " +
+                    "caught a WebServiceException: ", e);
+            }
+            throw e;
+        } catch (Exception e) {
+            if (log.isDebugEnabled()) {
+                log.debug("BaseDispatch.invokeAsync() [Polling]: Asynchronous invocation failed, " +
+                    "caught an Exception, wrapping into a WebServiceException. Exception caught: ",e);
+            }
+            // All exceptions are caught and rethrown as a WebServiceException
+            throw ExceptionFactory.makeWebServiceException(e);
+        }
+    }
+
+    public void setServiceClient(ServiceClient sc) {
+        serviceClient = sc;
+    }
+
+    public Mode getMode() {
+        return mode;
+    }
+
+    public void setMode(Mode m) {
+        mode = m;
+    }
+
+    /**
+     * Returns the fault that is contained within the MessageContext for an invocation. If no fault
+     * exists, null will be returned.
+     *
+     * @param msgCtx
+     * @return
+     */
+    public static WebServiceException getFaultResponse(MessageContext msgCtx) {
+        try {
+            Message msg = msgCtx.getMessage();
+            if (msg != null && msg.isFault()) {
+                //XMLFault fault = msg.getXMLFault();
+                // 4.3.2 conformance bullet 1 requires a ProtocolException here
+                ProtocolException pe =
+                    MethodMarshallerUtils.createSystemException(msg.getXMLFault(), msg);
+                if (msgCtx.getLocalException() != null) {
+                    // If a local exception occured, set it as the initial cause of the 
+                    // exception that will be returned
+                    ExceptionFactory.setInitialCause(pe, msgCtx.getLocalException());
+                }
+                return pe;
+            } else if (msgCtx.getLocalException() != null) {
+                // use the factory, it'll throw the right thing:
+                return ExceptionFactory.makeWebServiceException(msgCtx.getLocalException());
+            }
+        } finally {
+            // Free the incoming input stream
+            try {
+                msgCtx.freeInputStream();
+            } catch (IOException ioe) {
+                return ExceptionFactory.makeWebServiceException(ioe);
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Returns a boolean indicating whether or not the MessageContext contained a fault.
+     *
+     * @param msgCtx
+     * @return
+     */
+    public boolean hasFaultResponse(MessageContext msgCtx) {
+    	if(!msgCtx.getAxisMessageContext().getOptions().isExceptionToBeThrownOnSOAPFault()){
+        	if(log.isDebugEnabled()){
+        		log.debug("msgCtx.Options.isExceptionToBeThrownOnSOAPFault set to false; Exception will not be thrown on fault");
+        	}
+    		return false;
+    	}
+        if (msgCtx.getMessage() != null && msgCtx.getMessage().isFault())
+            return true;
+        else if (msgCtx.getLocalException() != null)
+            return true;
+        else
+            return false;
+    }
+
+    /*
+     * Configure any properties that will be needed on the Message
+     */
+    private void setupMessageProperties(Message msg) {
+        // If the user has enabled MTOM on the SOAPBinding, we need
+        // to make sure that gets pushed to the Message object.
+        Binding binding = (Binding) getBinding();
+        if (binding != null && binding instanceof SOAPBinding) {
+            SOAPBinding soapBinding = (SOAPBinding)binding;
+            if (soapBinding.isMTOMEnabled())
+                msg.setMTOMEnabled(true);
+        }
+    }
+
+    /*
+    * Checks to see if the parameter for the invocation is valid
+    * given the scenario that the client is operating in.  There are
+    * some cases when nulls are allowed and others where it is
+    * an error.
+    */
+    private boolean isValidInvocationParam(Object object) {
+        String bindingId = endpointDesc.getClientBindingID();
+
+        // If no bindingId was found, use the default.
+        if (bindingId == null) {
+            bindingId = SOAPBinding.SOAP11HTTP_BINDING;
+        }
+
+        // If it's not an HTTP_BINDING, then we can allow for null params,  
+        // but only in PAYLOAD mode per JAX-WS Section 4.3.2.
+        if (!bindingId.equals(HTTPBinding.HTTP_BINDING)) {
+            if (mode.equals(Mode.MESSAGE) && object == null) {
+                throw ExceptionFactory.makeWebServiceException(Messages.getMessage("dispatchNullParamMessageMode"));
+            }
+        } else {
+            // In all cases (PAYLOAD and MESSAGE) we must throw a WebServiceException
+            // if the parameter is null and request method is POST or PUT.
+            if (object == null && isPOSTorPUTRequest()) {
+                throw ExceptionFactory.makeWebServiceException(Messages.getMessage("dispatchNullParamHttpBinding"));
+            }
+        }
+
+        if (object instanceof DOMSource) {
+            DOMSource ds = (DOMSource)object;
+            if (ds.getNode() == null && ds.getSystemId() == null) {
+                throw ExceptionFactory.makeWebServiceException(Messages.getMessage("dispatchBadDOMSource"));
+            }
+        }
+
+        // If we've gotten this far, then all is good.
+        return true;
+    }
+    
+    private boolean isPOSTorPUTRequest() {
+        String method = (String)this.requestContext.get(javax.xml.ws.handler.MessageContext.HTTP_REQUEST_METHOD);
+        // if HTTP_REQUEST_METHOD is not specified, assume it is a POST method
+        return (method == null || 
+                HTTPConstants.HEADER_POST.equalsIgnoreCase(method) || 
+                HTTPConstants.HEADER_PUT.equalsIgnoreCase(method));
+    }
+    
+    private Message createRequestMessage(Object obj) throws WebServiceException {
+        
+        // Check to see if the object is a valid invocation parameter.  
+        // Then create the message from the object.
+        // If an exception occurs, it is local to the client and therefore is a
+        // WebServiceException (and not ProtocolExceptions).
+        // This code complies with JAX-WS 2.0 sections 4.3.2, 4.3.3 and 4.3.4.
+        if (!isValidInvocationParam(obj)) {
+            throw ExceptionFactory.makeWebServiceException(Messages.getMessage("dispatchInvalidParam"));
+        } 
+        Message requestMsg = null;
+        try {
+             requestMsg = createMessageFromValue(obj);
+        } catch (Throwable t) {
+            // The webservice exception wraps the thrown exception.
+            throw ExceptionFactory.makeWebServiceException(t);
+        }
+        return requestMsg;
+    }
+    
+    private void preInvokeInit(InvocationContext requestIC) {
+        /*
+         * if SESSION_MAINTAIN_PROPERTY is true, and the client app has explicitly set a HEADER_COOKIE on the request context, assume the client
+         * app is expecting the HEADER_COOKIE to be the session id.  If we were establishing a new session, no cookie would be sent, and the 
+         * server would reply with a "Set-Cookie" header, which is copied as a "Cookie"-keyed property to the service context during response.
+         * In this case, if we succeed in using an existing server session, no "Set-Cookie" header will be returned, and therefore no
+         * "Cookie"-keyed property would be set on the service context.  So, let's copy our request context HEADER_COOKIE key to the service
+         * context now to prevent the "no cookie" exception in BindingProvider.setupSessionContext.  It is possible the server does not support
+         * sessions, in which case no error occurs, but the client app would assume it is participating in a session.
+         */
+        if ((requestContext.containsKey(BindingProvider.SESSION_MAINTAIN_PROPERTY)) && ((Boolean)requestContext.get(BindingProvider.SESSION_MAINTAIN_PROPERTY))) {
+            if ((requestContext.containsKey(HTTPConstants.HEADER_COOKIE)) && (requestContext.get(HTTPConstants.HEADER_COOKIE) != null)) {
+                if (requestIC.getServiceClient().getServiceContext().getProperty(HTTPConstants.HEADER_COOKIE) == null) {
+                    requestIC.getServiceClient().getServiceContext().setProperty(HTTPConstants.HEADER_COOKIE, requestContext.get(HTTPConstants.HEADER_COOKIE));
+                    if (log.isDebugEnabled()) {
+                        log.debug("Client-app defined Cookie property (assume to be session cookie) on request context copied to service context." +
+                                "  Caution:  server may or may not support sessions, but client app will not be informed when not supported.");
+                    }
+                }
+            }
+        }
+    }
+}

Propchange: geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/client/dispatch/BaseDispatch.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/client/dispatch/BaseDispatch.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/client/dispatch/BaseDispatch.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain