You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by ro...@apache.org on 2007/09/13 22:19:39 UTC

svn commit: r575435 [1/2] - in /webservices/axis2/trunk/java/modules/jaxws: src/org/apache/axis2/jaxws/core/ src/org/apache/axis2/jaxws/registry/ src/org/apache/axis2/jaxws/server/ src/org/apache/axis2/jaxws/server/dispatcher/ src/org/apache/axis2/jaxw...

Author: rott
Date: Thu Sep 13 13:19:37 2007
New Revision: 575435

URL: http://svn.apache.org/viewvc?rev=575435&view=rev
Log:
Jira AXIS2-3202:  Server sends close connection causes client to halt.  Solution is to switch threads on client dispatch.

Added:
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointCallback.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointInvocationContext.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointInvocationContextImpl.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/factory/EndpointDispatcherFactoryImpl.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/endpoint/Utils.java
Modified:
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/core/InvocationContextFactory.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/registry/FactoryRegistry.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointController.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/JAXWSMessageReceiver.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/EndpointDispatcher.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/JavaBeanDispatcher.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/JavaDispatcher.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/ProviderDispatcher.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/factory/EndpointDispatcherFactory.java
    webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/dispatch/SOAP12Dispatch.java

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/core/InvocationContextFactory.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/core/InvocationContextFactory.java?rev=575435&r1=575434&r2=575435&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/core/InvocationContextFactory.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/core/InvocationContextFactory.java Thu Sep 13 13:19:37 2007
@@ -18,6 +18,9 @@
  */
 package org.apache.axis2.jaxws.core;
 
+import org.apache.axis2.jaxws.server.EndpointInvocationContext;
+import org.apache.axis2.jaxws.server.EndpointInvocationContextImpl;
+
 import javax.xml.ws.Binding;
 
 /** The InvocationContextFactory is used to create instances of an InvocationContext. */
@@ -31,5 +34,15 @@
         }
 
         return ic;
+    }
+    
+    public static EndpointInvocationContext createEndpointInvocationContext(Binding binding) {
+        EndpointInvocationContext eic = new EndpointInvocationContextImpl();
+        
+        if (binding != null) {
+            eic.setHandlers(binding.getHandlerChain());
+        }
+        
+        return eic;
     }
 }

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/registry/FactoryRegistry.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/registry/FactoryRegistry.java?rev=575435&r1=575434&r2=575435&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/registry/FactoryRegistry.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/registry/FactoryRegistry.java Thu Sep 13 13:19:37 2007
@@ -38,6 +38,7 @@
 import org.apache.axis2.jaxws.message.impl.XMLPartFactoryImpl;
 import org.apache.axis2.jaxws.message.util.impl.SAAJConverterFactoryImpl;
 import org.apache.axis2.jaxws.server.dispatcher.factory.EndpointDispatcherFactory;
+import org.apache.axis2.jaxws.server.dispatcher.factory.EndpointDispatcherFactoryImpl;
 import org.apache.axis2.jaxws.server.endpoint.lifecycle.factory.EndpointLifecycleManagerFactory;
 import org.apache.axis2.jaxws.utility.ExecutorFactory;
 import org.apache.axis2.jaxws.utility.JAXWSExecutorFactory;
@@ -53,6 +54,7 @@
     static {
         table = new Hashtable<Class, Object>();
         table.put(XMLStringBlockFactory.class, new XMLStringBlockFactoryImpl());
+        table.put(EndpointDispatcherFactory.class, new EndpointDispatcherFactoryImpl());
         table.put(JAXBBlockFactory.class, new JAXBBlockFactoryImpl());
         table.put(OMBlockFactory.class, new OMBlockFactoryImpl());
         table.put(SourceBlockFactory.class, new SourceBlockFactoryImpl());
@@ -63,7 +65,6 @@
         table.put(EndpointLifecycleManagerFactory.class, new EndpointLifecycleManagerFactory());
         table.put(HandlerLifecycleManagerFactory.class, new HandlerLifecycleManagerFactory());
         table.put(ClassFinderFactory.class, new ClassFinderFactory());
-        table.put(EndpointDispatcherFactory.class, new EndpointDispatcherFactory());
         table.put(ExecutorFactory.class, new JAXWSExecutorFactory());
     }
 

Added: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointCallback.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointCallback.java?rev=575435&view=auto
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointCallback.java (added)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointCallback.java Thu Sep 13 13:19:37 2007
@@ -0,0 +1,102 @@
+/*
+ * 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.server;
+
+import org.apache.axis2.context.OperationContext;
+import org.apache.axis2.engine.AxisEngine;
+import org.apache.axis2.jaxws.core.MessageContext;
+import org.apache.axis2.jaxws.message.util.MessageUtils;
+import org.apache.axis2.jaxws.util.Constants;
+import org.apache.axis2.util.ThreadContextMigratorUtil;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+public class EndpointCallback {
+    
+    private static final Log log = LogFactory.getLog(EndpointCallback.class);
+    
+    public void handleResponse(EndpointInvocationContext eic) {
+        MessageContext responseMsgCtx = eic.getResponseMessageContext();
+        org.apache.axis2.context.MessageContext axisResponseMsgCtx =
+                responseMsgCtx.getAxisMessageContext();
+
+        try {
+            MessageUtils.putMessageOnMessageContext(responseMsgCtx.getMessage(),
+                                                    axisResponseMsgCtx);
+
+            OperationContext opCtx = axisResponseMsgCtx.getOperationContext();
+            opCtx.addMessageContext(axisResponseMsgCtx);
+            
+            // This assumes that we are on the ultimate execution thread
+            ThreadContextMigratorUtil.performMigrationToContext(Constants.THREAD_CONTEXT_MIGRATOR_LIST_ID,
+                                                                axisResponseMsgCtx);
+    
+            //Create the AxisEngine for the reponse and send it.
+            AxisEngine engine =
+                    new AxisEngine(axisResponseMsgCtx.getConfigurationContext());
+            if (log.isDebugEnabled()) {
+                log.debug("Sending async response.");
+            }
+            engine.send(axisResponseMsgCtx);
+            
+            //This assumes that we are on the ultimate execution thread
+            ThreadContextMigratorUtil.performContextCleanup(Constants.THREAD_CONTEXT_MIGRATOR_LIST_ID,
+                                                            axisResponseMsgCtx);
+        } catch (Throwable t) {
+            if (log.isDebugEnabled()) {
+                log.debug("An error occurred while attempting to send the async response.");
+                t.printStackTrace();
+            }
+            
+            ThreadContextMigratorUtil.performThreadCleanup(Constants.THREAD_CONTEXT_MIGRATOR_LIST_ID,
+                eic.getRequestMessageContext().getAxisMessageContext());
+            
+            // FIXME (NLG): This is probably not right
+            handleFaultResponse(eic);
+        } 
+    }
+    
+    public void handleFaultResponse(EndpointInvocationContext eic) {
+        MessageContext responseMsgCtx = eic.getResponseMessageContext();
+        org.apache.axis2.context.MessageContext axisResponseMsgCtx =
+                responseMsgCtx.getAxisMessageContext();
+        
+        try {
+            MessageUtils.putMessageOnMessageContext(responseMsgCtx.getMessage(),
+                axisResponseMsgCtx);
+
+            OperationContext opCtx = axisResponseMsgCtx.getOperationContext();
+            opCtx.addMessageContext(axisResponseMsgCtx);
+            
+            ThreadContextMigratorUtil.performThreadCleanup(Constants.THREAD_CONTEXT_MIGRATOR_LIST_ID,
+                eic.getRequestMessageContext().getAxisMessageContext());
+            
+            //Create the AxisEngine for the reponse and send it.
+            AxisEngine engine =
+                new AxisEngine(axisResponseMsgCtx.getConfigurationContext());
+            engine.sendFault(axisResponseMsgCtx);
+            
+        } catch (Throwable t) {
+            // TODO Auto-generated catch block
+            t.printStackTrace();
+        }
+    }
+    
+}

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointController.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointController.java?rev=575435&r1=575434&r2=575435&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointController.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointController.java Thu Sep 13 13:19:37 2007
@@ -25,8 +25,6 @@
 import org.apache.axis2.description.WSDL2Constants;
 import org.apache.axis2.java.security.AccessController;
 import org.apache.axis2.jaxws.ExceptionFactory;
-import org.apache.axis2.jaxws.binding.SOAPBinding;
-import org.apache.axis2.jaxws.core.InvocationContext;
 import org.apache.axis2.jaxws.core.MessageContext;
 import org.apache.axis2.jaxws.core.util.MessageContextUtils;
 import org.apache.axis2.jaxws.description.DescriptionFactory;
@@ -35,17 +33,14 @@
 import org.apache.axis2.jaxws.handler.HandlerChainProcessor;
 import org.apache.axis2.jaxws.handler.HandlerInvokerUtils;
 import org.apache.axis2.jaxws.handler.HandlerResolverImpl;
-import org.apache.axis2.jaxws.handler.MEPContext;
 import org.apache.axis2.jaxws.i18n.Messages;
 import org.apache.axis2.jaxws.message.Message;
 import org.apache.axis2.jaxws.message.Protocol;
-import org.apache.axis2.jaxws.message.XMLFault;
-import org.apache.axis2.jaxws.message.XMLFaultCode;
-import org.apache.axis2.jaxws.message.XMLFaultReason;
 import org.apache.axis2.jaxws.message.factory.MessageFactory;
 import org.apache.axis2.jaxws.registry.FactoryRegistry;
 import org.apache.axis2.jaxws.server.dispatcher.EndpointDispatcher;
 import org.apache.axis2.jaxws.server.dispatcher.factory.EndpointDispatcherFactory;
+import org.apache.axis2.jaxws.server.endpoint.Utils;
 import org.apache.axis2.jaxws.server.endpoint.lifecycle.EndpointLifecycleManager;
 import org.apache.axis2.jaxws.server.endpoint.lifecycle.factory.EndpointLifecycleManagerFactory;
 import org.apache.axis2.jaxws.spi.Constants;
@@ -54,13 +49,10 @@
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
-import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamReader;
-import javax.xml.ws.http.HTTPBinding;
 import java.io.StringReader;
 import java.security.PrivilegedActionException;
 import java.security.PrivilegedExceptionAction;
-import java.util.Collection;
 
 /**
  * The EndpointController is the server side equivalent to the InvocationController on the client
@@ -75,73 +67,140 @@
 
     private static final Log log = LogFactory.getLog(EndpointController.class);
 
-    private static final String PARAM_SERVICE_CLASS = "ServiceClass";
-
-    public EndpointController() {
-        //do nothing
-    }
 
     /**
      * This method is used to start the JAX-WS invocation of a target endpoint. It takes an
      * InvocationContext, which must have a MessageContext specied for the request.  Once the
      * invocation is complete, the information will be stored
+     * 
+     * @param eic
+     * @return
      */
-    public InvocationContext invoke(InvocationContext ic) {
-        MessageContext requestMsgCtx = ic.getRequestMessageContext();
+    public EndpointInvocationContext invoke(EndpointInvocationContext eic) {
+        if (log.isDebugEnabled()) {
+            log.debug("Invocation pattern: synchronous");
+        }
 
-        String implClassName = getServiceImplClassName(requestMsgCtx);
+        boolean good = handleRequest(eic);
 
-        Class implClass = loadServiceImplClass(implClassName,
-                                               requestMsgCtx.getClassLoader());
+        if (!good) {
+            return eic;
+        }
+        
+        MessageContext request = eic.getRequestMessageContext();
+        MessageContext response = null;
+        try {
+            EndpointDispatcher dispatcher = eic.getDispatcher();
+            if (request != null && dispatcher != null) {
+                response = dispatcher.invoke(request);    
+                eic.setResponseMessageContext(response);
+            }
+            else {
+                throw ExceptionFactory.makeWebServiceException("No dispatcher found.");
+            }
+        } catch (Exception e) {
+            throw ExceptionFactory.makeWebServiceException(e);
+        } finally {
+            // Passed pivot point
+            request.getMessage().setPostPivot();
+        }
+        
+        handleResponse(eic);            
+        
+        return eic;
+    }
+    
+    public void invokeAsync(EndpointInvocationContext eic) {
+        if (log.isDebugEnabled()) {
+            log.debug("Invocation pattern: asynchronous");
+        }
+        
+        boolean good = handleRequest(eic);
 
-        EndpointDescription endpointDesc = getEndpointDescription(requestMsgCtx, implClass);
-        requestMsgCtx.setEndpointDescription(endpointDesc);
-
-        /*
-         * 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.
-         * 
-         * Since we're on the server, and there apparently is no Binding object
-         * anywhere to be found...
-         */
-        if (ic.getHandlers() == null) {
-            ic.setHandlers(new HandlerResolverImpl(endpointDesc.getServiceDescription()).getHandlerChain(endpointDesc.getPortInfo()));
-        }
-
-        if (!bindingTypesMatch(requestMsgCtx, endpointDesc.getServiceDescription())) {
-            Protocol protocol = requestMsgCtx.getMessage().getProtocol();
-            // only if protocol is soap12 and MISmatches the endpoint do we halt processing
-            if (protocol.equals(Protocol.soap12)) {
-                ic.setResponseMessageContext(createMismatchFaultMsgCtx(requestMsgCtx,
-                                                                       "Incoming SOAP message protocol is version 1.2, but endpoint is configured for SOAP 1.1"));
-                return ic;
-            } else if (protocol.equals(Protocol.soap11)) {
-                // SOAP 1.1 message and SOAP 1.2 binding
-
-                // The canSupport flag indicates that we can support this scenario.
-                // Possible Examples of canSupport:  JAXB impl binding, JAXB Provider
-                // Possible Example of !canSupport: Application handler usage, non-JAXB Provider
-                // Initially I vote to hard code this as false.
-                boolean canSupport = false;
-                if (canSupport) {
-                    // TODO: Okay, but we need to scrub the Message create code to make sure that the response message
-                    // is always built from the receiver protocol...not the binding protocol
-                } else {
-                    ic.setResponseMessageContext(createMismatchFaultMsgCtx(requestMsgCtx,
-                                                                           "Incoming SOAP message protocol is version 1.1, but endpoint is configured for SOAP 1.2.  This is not supported."));
-                    return ic;
-                }
-            } else {
-                ic.setResponseMessageContext(createMismatchFaultMsgCtx(requestMsgCtx,
-                                                                       "Incoming message protocol does not match endpoint protocol."));
-                return ic;
+        if (!good) {
+            return;
+        }
+        
+        MessageContext request = eic.getRequestMessageContext();
+        try {
+            EndpointDispatcher dispatcher = eic.getDispatcher();
+            if (request != null && dispatcher != null) {
+                dispatcher.invokeAsync(request, eic.getCallback());    
+            }
+            else {
+                throw ExceptionFactory.makeWebServiceException("No dispatcher found.");
+            }
+        } catch (Exception e) {
+            throw ExceptionFactory.makeWebServiceException(e);
+        } finally {
+            // FIXME (NLG): Probably need to revisit this location.  Should it be moved down?
+            // Passed pivot point
+            request.getMessage().setPostPivot();
+        }
+        
+        return;
+    }
+    
+    public void invokeOneWay(EndpointInvocationContext eic) {
+        if (log.isDebugEnabled()) {
+            log.debug("Invocation pattern: one-way");
+        }
+    
+        boolean good = handleRequest(eic);
+
+        if (!good) {
+            return;
+        }
+        
+        MessageContext request = eic.getRequestMessageContext();
+        try {
+            EndpointDispatcher dispatcher = eic.getDispatcher();
+            if (request != null && dispatcher != null) {
+                dispatcher.invokeOneWay(request);    
             }
+            else {
+                throw ExceptionFactory.makeWebServiceException("No dispatcher found.");
+            }
+        } catch (Exception e) {
+            throw ExceptionFactory.makeWebServiceException(e);
+        } finally {
+            // Passed pivot point
+            request.getMessage().setPostPivot();
+        }
+        
+        return;
+    }
+    
+    protected boolean handleRequest(EndpointInvocationContext eic) {
+        MessageContext request = eic.getRequestMessageContext();
+        
+        Class serviceEndpoint = getServiceImplementation(request);
+        EndpointDescription endpointDesc = getEndpointDescription(request, serviceEndpoint);
+        request.setEndpointDescription(endpointDesc);
+        
+        //  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.
+        //  
+        //  Since we're on the server, and there apparently is no Binding object
+        //  anywhere to be found...
+        if (eic.getHandlers() == null) {
+            if (log.isDebugEnabled()) {
+                log.debug("No handlers found on the InvocationContext, initializing handler list.");
+            }
+            eic.setHandlers(new HandlerResolverImpl(endpointDesc.getServiceDescription()).getHandlerChain(endpointDesc.getPortInfo()));
+        }
+
+        if (!Utils.bindingTypesMatch(request, endpointDesc.getServiceDescription())) {
+            Protocol protocol = request.getMessage().getProtocol();
+            MessageContext faultContext = Utils.createVersionMismatchMessage(request, protocol);
+            eic.setResponseMessageContext(faultContext);
+            return false;
         }
 
         MessageContext responseMsgContext = null;
@@ -149,62 +208,83 @@
         try {
             // Get the service instance.  This will run the @PostConstruct code.
             EndpointLifecycleManager elm = createEndpointlifecycleManager();
-            Object serviceInstance = elm.createServiceInstance(requestMsgCtx, implClass);
+            Object serviceInstance = elm.createServiceInstance(request, serviceEndpoint);
 
             // The application handlers and dispatcher invoke will 
             // modify/destroy parts of the message.  Make sure to save
             // the request message if appropriate.
-            saveRequestMessage(requestMsgCtx);
-
+            saveRequestMessage(request);
+            
             // Invoke inbound application handlers.  It's safe to use the first object on the iterator because there is
             // always exactly one EndpointDescription on a server invoke
             boolean success =
-                    HandlerInvokerUtils.invokeInboundHandlers(requestMsgCtx.getMEPContext(),
-                                                              ic.getHandlers(),
+                    HandlerInvokerUtils.invokeInboundHandlers(request.getMEPContext(),
+                                                              eic.getHandlers(),
                                                               HandlerChainProcessor.MEP.REQUEST,
-                                                              isOneWay(requestMsgCtx.getAxisMessageContext()));
+                                                              isOneWay(request.getAxisMessageContext()));
 
             if (success) {
-
-                // Dispatch to the
-                EndpointDispatcher dispatcher = getEndpointDispatcher(implClass, serviceInstance);
-                try {
-                    responseMsgContext = dispatcher.invoke(requestMsgCtx);
-                } finally {
-                    // Passed pivot point
-                    requestMsgCtx.getMessage().setPostPivot();
+                if (log.isDebugEnabled()) {
+                    log.debug("JAX-WS inbound handler chain invocation complete.");
                 }
-
-                // Invoke the outbound response handlers.
-                // If the message is one way, we should not invoke the response handlers.  There is no response
-                // MessageContext since a one way invocation is considered to have a "void" return.
-                if (!isOneWay(requestMsgCtx.getAxisMessageContext())) {
-                    responseMsgContext.setMEPContext(requestMsgCtx.getMEPContext());
-                    
-                    HandlerInvokerUtils.invokeOutboundHandlers(responseMsgContext.getMEPContext(),
-                                                               ic.getHandlers(),
-                                                               HandlerChainProcessor.MEP.RESPONSE,
-                                                               false);
+                // Set the dispatcher.
+                EndpointDispatcher dispatcher = getEndpointDispatcher(serviceEndpoint, serviceInstance);
+                eic.setEndpointDispatcher(dispatcher);
+                return true;
+            } else { // the inbound handler chain must have had a problem, and we've reversed directions
+                if (log.isDebugEnabled()) {
+                    log.debug("JAX-WS inbound handler chain invocation completed with errors.");
                 }
-            } else
-            { // the inbound handler chain must have had a problem, and we've reversed directions
                 responseMsgContext =
-                        MessageContextUtils.createResponseMessageContext(requestMsgCtx);
+                        MessageContextUtils.createResponseMessageContext(request);
                 // since we've reversed directions, the message has "become a response message" (section 9.3.2.1, footnote superscript 2)
-                responseMsgContext.setMessage(requestMsgCtx.getMessage());
+                responseMsgContext.setMessage(request.getMessage());
+                eic.setResponseMessageContext(responseMsgContext);
+                return false;
             }
-
         } catch (Exception e) {
             // TODO for now, throw it.  We probably should try to make an XMLFault object and set it on the message
             throw ExceptionFactory.makeWebServiceException(e);
+        } 
+    }
+    
+    protected boolean handleResponse(EndpointInvocationContext eic) {
+        MessageContext request = eic.getRequestMessageContext();
+        MessageContext response = eic.getResponseMessageContext();
+        
+        try {
+            if (response != null) {
+               // Invoke the outbound response handlers.
+               // If the message is one way, we should not invoke the response handlers.  There is no response
+               // MessageContext since a one way invocation is considered to have a "void" return.
+               
+               if (!isOneWay(eic.getRequestMessageContext().getAxisMessageContext())) {
+                    response.setMEPContext(request.getMEPContext());
+                    
+                    HandlerInvokerUtils.invokeOutboundHandlers(response.getMEPContext(),
+                                                               eic.getHandlers(),
+                                                               HandlerChainProcessor.MEP.RESPONSE,
+                                                               false);
+               }
+           } 
+        } catch (Exception e) {
+            // TODO for now, throw it.  We probably should try to make an XMLFault object and set it on the message
+            throw ExceptionFactory.makeWebServiceException(e);  
         } finally {
-            restoreRequestMessage(requestMsgCtx);
+            restoreRequestMessage(request);
         }
-
-		// The response MessageContext should be set on the InvocationContext
-		ic.setResponseMessageContext(responseMsgContext);
-
-        return ic;
+        
+        eic.setResponseMessageContext(response);
+        return true;
+    }
+    
+    /*
+     * Returns the Class object for the implementation of the web service.
+     */
+    private Class getServiceImplementation(MessageContext mc) {
+        String implClassName = getServiceImplClassName(mc);
+        Class implClass = loadServiceImplClass(implClassName, mc.getClassLoader());
+        return implClass;
     }
 
     /*
@@ -217,6 +297,23 @@
         return factory.createEndpointDispatcher(serviceImplClass, serviceInstance);       
     }
 
+    private String getServiceImplClassName(MessageContext mc) {
+        // The PARAM_SERVICE_CLASS property that is set on the AxisService
+        // will tell us what the service implementation class is.
+        org.apache.axis2.context.MessageContext axisMsgContext = mc.getAxisMessageContext();
+        AxisService as = axisMsgContext.getAxisService();
+        Parameter param = as.getParameter(org.apache.axis2.Constants.SERVICE_CLASS);
+
+        // If there was no implementation class, we should not go any further
+        if (param == null) {
+            throw ExceptionFactory.makeWebServiceException(Messages.getMessage(
+                    "EndpointControllerErr2"));
+        }
+
+        String className = ((String)param.getValue()).trim();
+        return className;
+    }
+    
     /*
       * Tries to load the implementation class that was specified for the
       * target endpoint
@@ -266,23 +363,6 @@
         return cl;
     }
 
-    private String getServiceImplClassName(MessageContext mc) {
-        // The PARAM_SERVICE_CLASS property that is set on the AxisService
-        // will tell us what the service implementation class is.
-        org.apache.axis2.context.MessageContext axisMsgContext = mc.getAxisMessageContext();
-        AxisService as = axisMsgContext.getAxisService();
-        Parameter param = as.getParameter(PARAM_SERVICE_CLASS);
-
-        // If there was no implementation class, we should not go any further
-        if (param == null) {
-            throw ExceptionFactory.makeWebServiceException(Messages.getMessage(
-                    "EndpointControllerErr2"));
-        }
-
-        String className = ((String)param.getValue()).trim();
-        return className;
-    }
-
     /*
     * Gets the ServiceDescription associated with the request that is currently
     * being processed.
@@ -318,49 +398,6 @@
         EndpointLifecycleManagerFactory elmf = (EndpointLifecycleManagerFactory)FactoryRegistry
                 .getFactory(EndpointLifecycleManagerFactory.class);
         return elmf.createEndpointLifecycleManager();
-    }
-
-
-    private boolean bindingTypesMatch(MessageContext requestMsgCtx,
-                                      ServiceDescription serviceDesc) {
-        // compare soap versions and respond appropriately under SOAP 1.2 Appendix 'A'
-        Collection<EndpointDescription> eds = serviceDesc.getEndpointDescriptions_AsCollection();
-        // dispatch endpoints do not have SEIs, so watch out for null or empty array
-        if ((eds != null) && (eds.size() > 0)) {
-            EndpointDescription ed = eds.iterator().next();
-            Protocol protocol = requestMsgCtx.getMessage().getProtocol();
-            String endpointBindingType = ed.getBindingType();
-            if (protocol.equals(Protocol.soap11)) {
-                return (SOAPBinding.SOAP11HTTP_BINDING.equalsIgnoreCase(endpointBindingType)) ||
-                        (SOAPBinding.SOAP11HTTP_MTOM_BINDING.equalsIgnoreCase(endpointBindingType));
-            } else if (protocol.equals(Protocol.soap12)) {
-                return (SOAPBinding.SOAP12HTTP_BINDING.equalsIgnoreCase(endpointBindingType)) ||
-                        (SOAPBinding.SOAP12HTTP_MTOM_BINDING.equalsIgnoreCase(endpointBindingType));
-            } else if (protocol.equals(Protocol.rest)) {
-                return HTTPBinding.HTTP_BINDING.equalsIgnoreCase(endpointBindingType);
-            }
-        }
-        // safe to assume?
-        return true;
-    }
-
-    private MessageContext createMismatchFaultMsgCtx(MessageContext requestMsgCtx,
-                                                     String errorMsg) {
-        try {
-            XMLFault xmlfault =
-                    new XMLFault(XMLFaultCode.VERSIONMISMATCH, new XMLFaultReason(errorMsg));
-            Message msg = ((MessageFactory)FactoryRegistry.getFactory(MessageFactory.class))
-                    .create(Protocol.soap11);  // always soap11 according to the spec
-            msg.setXMLFault(xmlfault);
-            MessageContext responseMsgCtx =
-                    MessageContextUtils.createFaultMessageContext(requestMsgCtx);
-            responseMsgCtx.setMessage(msg);
-            return responseMsgCtx;
-        } catch (XMLStreamException e) {
-            // Need to fix this !   At least provide logging
-            // TODO for now, throw it.  We probably should try to make an XMLFault object and set it on the message
-            throw ExceptionFactory.makeWebServiceException(e);
-        }
     }
 
     /**

Added: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointInvocationContext.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointInvocationContext.java?rev=575435&view=auto
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointInvocationContext.java (added)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointInvocationContext.java Thu Sep 13 13:19:37 2007
@@ -0,0 +1,75 @@
+/*
+ * 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.server;
+
+import org.apache.axis2.jaxws.core.InvocationContext;
+import org.apache.axis2.jaxws.server.dispatcher.EndpointDispatcher;
+
+/**
+ * The EndpointInvocationContext is an extension of the base InvocationContext
+ * that provides extensions specific to the environment of the service
+ * endpoint.  
+ */
+public interface EndpointInvocationContext extends InvocationContext {
+
+    /**
+     * Returns the callback object to be used for asynchronous 
+     * endpoint invocations.
+     * 
+     * @return EndpointCallback - the EndpointCallback instance.
+     */
+    public EndpointCallback getCallback();
+    
+    /**
+     * Sets the callback object to be used for asynchronous 
+     * endpoint invocations.
+     * 
+     * @param cb - the EndpointCallback instance to be used.
+     */
+    public void setCallback(EndpointCallback cb);
+    
+    /**
+     * 
+     * @return
+     */
+    public EndpointDispatcher getDispatcher();
+    
+    /**
+     * 
+     * @param ed
+     */
+    public void setEndpointDispatcher(EndpointDispatcher ed);
+    
+    /**
+     * Returns a boolean value indicating whether or not the invocation
+     * pattern for the request is one way or not.
+     * 
+     * @return
+     */
+    public boolean isOneWay(); 
+    
+    /**
+     * Sets the value for marking the request as a one way invocation.
+     * 
+     * @param value
+     */
+    public void setIsOneWay(boolean value);
+
+}

Added: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointInvocationContextImpl.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointInvocationContextImpl.java?rev=575435&view=auto
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointInvocationContextImpl.java (added)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointInvocationContextImpl.java Thu Sep 13 13:19:37 2007
@@ -0,0 +1,86 @@
+/*
+ * 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.server;
+
+import org.apache.axis2.jaxws.core.InvocationContextImpl;
+import org.apache.axis2.jaxws.server.dispatcher.EndpointDispatcher;
+
+public class EndpointInvocationContextImpl extends InvocationContextImpl
+    implements EndpointInvocationContext {
+
+    private EndpointCallback callback;
+    private EndpointDispatcher dispatcher;
+    private Boolean oneWay;
+    
+    /*
+     * (non-Javadoc)
+     * @see org.apache.axis2.jaxws.server.EndpointInvocationContext#getCallback()
+     */
+    public EndpointCallback getCallback() {
+        return callback;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see org.apache.axis2.jaxws.server.EndpointInvocationContext#getDispatcher()
+     */
+    public EndpointDispatcher getDispatcher() {
+        return dispatcher;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see org.apache.axis2.jaxws.server.EndpointInvocationContext#setCallback(org.apache.axis2.jaxws.server.EndpointCallback)
+     */
+    public void setCallback(EndpointCallback cb) {
+        callback = cb;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see org.apache.axis2.jaxws.server.EndpointInvocationContext#setEndpointDispatcher(org.apache.axis2.jaxws.server.dispatcher.EndpointDispatcher)
+     */
+    public void setEndpointDispatcher(EndpointDispatcher ed) {
+        dispatcher = ed;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see org.apache.axis2.jaxws.server.EndpointInvocationContext#isOneWay()
+     */
+    public boolean isOneWay() {
+        if (oneWay != null) {
+            return oneWay.booleanValue();    
+        }
+        else {
+            // TODO: We can add some code to derive it here 
+            // should we see fit.
+            return false;
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see org.apache.axis2.jaxws.server.EndpointInvocationContext#setIsOneWay(boolean)
+     */
+    public void setIsOneWay(boolean value) {
+        oneWay = value;
+    }
+
+}

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/JAXWSMessageReceiver.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/JAXWSMessageReceiver.java?rev=575435&r1=575434&r2=575435&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/JAXWSMessageReceiver.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/JAXWSMessageReceiver.java Thu Sep 13 13:19:37 2007
@@ -20,6 +20,7 @@
 package org.apache.axis2.jaxws.server;
 
 import org.apache.axis2.AxisFault;
+import org.apache.axis2.addressing.AddressingConstants;
 import org.apache.axis2.context.OperationContext;
 import org.apache.axis2.description.AxisOperation;
 import org.apache.axis2.description.AxisService;
@@ -27,9 +28,7 @@
 import org.apache.axis2.engine.AxisEngine;
 import org.apache.axis2.engine.MessageReceiver;
 import org.apache.axis2.jaxws.ExceptionFactory;
-import org.apache.axis2.jaxws.core.InvocationContext;
 import org.apache.axis2.jaxws.core.InvocationContextFactory;
-import org.apache.axis2.jaxws.core.InvocationContextImpl;
 import org.apache.axis2.jaxws.core.MessageContext;
 import org.apache.axis2.jaxws.handler.AttachmentsAdapter;
 import org.apache.axis2.jaxws.handler.MEPContext;
@@ -37,6 +36,7 @@
 import org.apache.axis2.jaxws.i18n.Messages;
 import org.apache.axis2.jaxws.message.util.MessageUtils;
 import org.apache.axis2.jaxws.util.Constants;
+import org.apache.axis2.util.JavaUtils;
 import org.apache.axis2.util.ThreadContextMigratorUtil;
 import org.apache.axis2.wsdl.WSDLConstants.WSDL20_2004_Constants;
 import org.apache.axis2.wsdl.WSDLConstants.WSDL20_2006Constants;
@@ -98,27 +98,49 @@
 
             MessageContext requestMsgCtx = new MessageContext(axisRequestMsgCtx);
             requestMsgCtx.setMEPContext(new MEPContext(requestMsgCtx));
+            
             // The adapters need to be installed on the new request Message Context
             AttachmentsAdapter.install(requestMsgCtx);
             TransportHeadersAdapter.install(requestMsgCtx);
             
             Binding binding = (Binding)axisRequestMsgCtx.getProperty(PARAM_BINDING);
-            InvocationContext ic = InvocationContextFactory.createInvocationContext(binding);
-            ic.setRequestMessageContext(requestMsgCtx);
+            EndpointInvocationContext eic = InvocationContextFactory.createEndpointInvocationContext(binding);
+            eic.setRequestMessageContext(requestMsgCtx);
 
             //TODO:Once we the JAX-WS MessageContext one of the next things that
             //needs to be done here is setting up all of the javax.xml.ws.* 
             //properties for the MessageContext.
 
-            ic = endpointCtlr.invoke(ic);
-            MessageContext responseMsgCtx = ic.getResponseMessageContext();
+            if (isMepInOnly(mep)) {
+                if (log.isDebugEnabled()) {
+                    log.debug("Detected a one way invocation.");
+                }
+                eic.setIsOneWay(true);
+                endpointCtlr.invokeOneWay(eic);
+            } else if (JavaUtils.isTrueExplicitly(axisRequestMsgCtx.getProperty(
+                AddressingConstants.IS_ADDR_INFO_ALREADY_PROCESSED))
+                && (axisRequestMsgCtx.getReplyTo() != null
+                && !axisRequestMsgCtx.getReplyTo().hasAnonymousAddress())) {
+                
+                if (log.isDebugEnabled()) {
+                    log.debug("Detected an async invocation.");
+                }
+                
+                EndpointCallback ecb = new EndpointCallback();
+                eic.setCallback(ecb);
+                
+                endpointCtlr.invokeAsync(eic);
+            } else {
+                if (log.isDebugEnabled()) {
+                    log.debug("Detected a sync invocation.");
+                }
+                eic = endpointCtlr.invoke(eic);
 
-            //If there is a fault it could be Robust In-Only
-            if (!isMepInOnly(mep) || hasFault(responseMsgCtx)) {
-                // If this is a two-way exchange, there should already be a
+                // If this is a two-way exchange, there should already be a 
                 // JAX-WS MessageContext for the response.  We need to pull 
                 // the Message data out of there and set it on the Axis2 
                 // MessageContext.
+                MessageContext responseMsgCtx = eic.getResponseMessageContext();
                 org.apache.axis2.context.MessageContext axisResponseMsgCtx =
                         responseMsgCtx.getAxisMessageContext();
 
@@ -159,6 +181,11 @@
             ThreadContextMigratorUtil.performThreadCleanup(
                     Constants.THREAD_CONTEXT_MIGRATOR_LIST_ID, axisRequestMsgCtx);
 
+            //e.printStackTrace();
+
+            // TODO.  This is throwing a client exception ?
+            // TODO Why are we preserving the stack information  ?  
+            
             // Make a webservice exception (which will strip out a unnecessary stuff)
             WebServiceException wse = ExceptionFactory.makeWebServiceException(e);
 
@@ -176,12 +203,6 @@
         }
     }
 
-    private boolean hasFault(MessageContext responseMsgCtx) {
-        if (responseMsgCtx == null || responseMsgCtx.getMessage() == null) {
-            return false;
-        }
-        return responseMsgCtx.getMessage().isFault();
-    }
 
     private boolean isMepInOnly(String mep) {
         boolean inOnly = mep.equals(WSDL20_2004_Constants.MEP_URI_ROBUST_IN_ONLY) ||

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/EndpointDispatcher.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/EndpointDispatcher.java?rev=575435&r1=575434&r2=575435&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/EndpointDispatcher.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/EndpointDispatcher.java Thu Sep 13 13:19:37 2007
@@ -20,6 +20,7 @@
 package org.apache.axis2.jaxws.server.dispatcher;
 
 import org.apache.axis2.jaxws.core.MessageContext;
+import org.apache.axis2.jaxws.server.EndpointCallback;
 
 /**
  * The EndpointDispatcher is an abstraction for the object that will be doing the invocation of an
@@ -33,7 +34,10 @@
      * @param mc
      * @return
      */
-    public MessageContext invoke(MessageContext mc)
-            throws Exception;
+    public MessageContext invoke(MessageContext request) throws Exception;
+    
+    public void invokeOneWay(MessageContext request);
+    
+    public void invokeAsync(MessageContext request, EndpointCallback callback);
 
 }

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/JavaBeanDispatcher.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/JavaBeanDispatcher.java?rev=575435&r1=575434&r2=575435&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/JavaBeanDispatcher.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/JavaBeanDispatcher.java Thu Sep 13 13:19:37 2007
@@ -18,24 +18,31 @@
  */
 package org.apache.axis2.jaxws.server.dispatcher;
 
+
 import org.apache.axis2.jaxws.ExceptionFactory;
 import org.apache.axis2.jaxws.context.utils.ContextUtils;
 import org.apache.axis2.jaxws.core.MessageContext;
 import org.apache.axis2.jaxws.core.util.MessageContextUtils;
 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.MethodMarshaller;
 import org.apache.axis2.jaxws.marshaller.factory.MethodMarshallerFactory;
 import org.apache.axis2.jaxws.message.Message;
 import org.apache.axis2.jaxws.message.Protocol;
+import org.apache.axis2.jaxws.registry.FactoryRegistry;
+import org.apache.axis2.jaxws.server.EndpointCallback;
+import org.apache.axis2.jaxws.server.EndpointInvocationContext;
+import org.apache.axis2.jaxws.server.endpoint.Utils;
+import org.apache.axis2.jaxws.utility.ExecutorFactory;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
 import javax.xml.ws.soap.SOAPBinding;
 import org.apache.axis2.AxisFault;
 import java.lang.reflect.Method;
+import java.util.concurrent.Executor;
+import java.util.concurrent.FutureTask;
 
 /**
  * The JavaBeanDispatcher is used to manage creating an instance of a JAX-WS service implementation
@@ -57,20 +64,16 @@
     */
     public MessageContext invoke(MessageContext mc) throws Exception {
         if (log.isDebugEnabled()) {
-            log.debug("Preparing to invoke service endpoint implementation " +
-                    "class: " + serviceImplClass.getName());
+            log.debug("Invoking service endpoint: " + serviceImplClass.getName());
+            log.debug("Invocation pattern: two way, sync");
         }
 
         initialize(mc);
-        OperationDescription operationDesc =
-                getOperationDescription(mc); //mc.getOperationDescription();
-        //Set SOAP Operation Related properties in SOAPMessageContext.
-        ContextUtils.addWSDLProperties(mc);
-        Protocol requestProtocol = mc.getMessage().getProtocol();
-        MethodMarshaller methodMarshaller =
-                getMethodMarshaller(mc.getMessage().getProtocol(), mc.getOperationDescription());
-        Object[] methodInputParams =
-                methodMarshaller.demarshalRequest(mc.getMessage(), mc.getOperationDescription());
+        
+        OperationDescription operationDesc = Utils.getOperationDescription(mc);
+        
+        Object[] methodInputParams = createRequestParameters(mc);
+        
         Method target = getJavaMethod(mc, serviceImplClass);
         if (log.isDebugEnabled()) {
             // At this point, the OpDesc includes everything we know, including the actual method
@@ -79,81 +82,96 @@
                     operationDesc.toString());
         }
 
-        //At this point, we have the method that is going to be invoked and
-        //the parameter data to invoke it with, so we use the instance and 
-        //do the invoke.
-        //Passing method input params to grab holder values, if any.
+        // We have the method that is going to be invoked and the parameter data to invoke it 
+        // with, so just invoke the operation.
         boolean faultThrown = false;
         Throwable fault = null;
-        Object response = null;
+        Object output = null;
         try {
-            response = invokeService(mc, target, serviceInstance, methodInputParams);
-        } catch (Exception e) {
+            output = invokeTargetOperation(target, methodInputParams);
+        } 
+        catch (Throwable e) {
             faultThrown = true;
             fault = e;
-            if (log.isDebugEnabled()) {
-                log.debug("Exception invoking a method of " +
-                        serviceImplClass.toString() + " of instance " +
-                        serviceInstance.toString());
-                log.debug("Exception type thrown: " + e.getClass().getName());
-                log.debug("Method = " + target.toGenericString());
-                for (int i = 0; i < methodInputParams.length; i++) {
-                    String value = (methodInputParams[i] == null) ? "null" :
-                            methodInputParams[i].getClass().toString();
-                    log.debug(" Argument[" + i + "] is " + value);
-                }
-            }
         }
 
-        Message message = null;
+        MessageContext response = null;
         if (operationDesc.isOneWay()) {
             // If the operation is one-way, then we can just return null because
             // we cannot create a MessageContext for one-way responses.
             return null;
         } else if (faultThrown) {
-            message = methodMarshaller.marshalFaultResponse(fault, mc.getOperationDescription(),
-                                                            requestProtocol); // Send the response using the same protocol as the request
-        } else if (target.getReturnType().getName().equals("void")) {
-            message = methodMarshaller
-                    .marshalResponse(null, methodInputParams, mc.getOperationDescription(),
-                                     requestProtocol); // Send the response using the same protocol as the request
+            response = createFaultResponse(mc, mc.getMessage().getProtocol(), fault);
         } else {
-            message = methodMarshaller
-                    .marshalResponse(response, methodInputParams, mc.getOperationDescription(),
-                                     requestProtocol); // Send the response using the same protocol as the request
+            response = createResponse(mc, mc.getMessage().getProtocol(), methodInputParams, output);
         }
+                
+        return response;
+    }
 
-        MessageContext responseMsgCtx = null;
-        if (faultThrown) {
-            responseMsgCtx = MessageContextUtils.createFaultMessageContext(mc);
-            responseMsgCtx.setMessage(message);
-
-            AxisFault axisFault = new AxisFault("An error was detected during JAXWS processing",
-                                              responseMsgCtx.getAxisMessageContext(),
-                                              fault);
-            
-            responseMsgCtx.setCausedByException(axisFault);
-
+    public void invokeOneWay(MessageContext request) {
+        if (log.isDebugEnabled()) {
+            log.debug("Invoking service endpoint: " + serviceImplClass.getName());
+            log.debug("Invocation pattern: one way");
+        }
 
-        } else {
-            responseMsgCtx = MessageContextUtils.createResponseMessageContext(mc);
-            responseMsgCtx.setMessage(message);
+        initialize(request);
+        
+        OperationDescription operationDesc = Utils.getOperationDescription(request);
+        
+        Object[] methodInputParams = createRequestParameters(request);
+        
+        Method target = getJavaMethod(request, serviceImplClass);
+        if (log.isDebugEnabled()) {
+            // At this point, the OpDesc includes everything we know, including the actual method
+            // on the service impl we will delegate to; it was set by getJavaMethod(...) above.
+            log.debug("JavaBeanDispatcher about to invoke using OperationDesc: "
+                    + operationDesc.toString());
         }
 
-        //Enable MTOM if necessary
-        EndpointInterfaceDescription epInterfaceDesc =
-                operationDesc.getEndpointInterfaceDescription();
-        EndpointDescription epDesc = epInterfaceDesc.getEndpointDescription();
+        ExecutorFactory ef = (ExecutorFactory) FactoryRegistry.getFactory(ExecutorFactory.class);
+        Executor executor = ef.getExecutorInstance();
+        
+        EndpointInvocationContext eic = (EndpointInvocationContext) request.getInvocationContext();
+        ClassLoader cl = Thread.currentThread().getContextClassLoader();
+        
+        AsyncInvocationWorker worker = new AsyncInvocationWorker(target, methodInputParams, cl, eic);
+        FutureTask task = new FutureTask<AsyncInvocationWorker>(worker);
+        executor.execute(task);
+        
+        return;
+    }
 
-        String bindingType = epDesc.getBindingType();
-        if (bindingType != null) {
-            if (bindingType.equals(SOAPBinding.SOAP11HTTP_MTOM_BINDING) ||
-                    bindingType.equals(SOAPBinding.SOAP12HTTP_MTOM_BINDING)) {
-                message.setMTOMEnabled(true);
-            }
+    public void invokeAsync(MessageContext request, EndpointCallback callback) {
+        if (log.isDebugEnabled()) {
+            log.debug("Invoking service endpoint: " + serviceImplClass.getName());
+            log.debug("Invocation pattern: two way, async");
         }
 
-        return responseMsgCtx;
+        initialize(request);
+        
+        OperationDescription operationDesc = Utils.getOperationDescription(request);
+        
+        Object[] methodInputParams = createRequestParameters(request);
+        
+        Method target = getJavaMethod(request, serviceImplClass);
+        if (log.isDebugEnabled()) {
+            // At this point, the OpDesc includes everything we know, including the actual method
+            // on the service impl we will delegate to; it was set by getJavaMethod(...) above.
+            log.debug("JavaBeanDispatcher about to invoke using OperationDesc: "
+                    + operationDesc.toString());
+        }
+        ExecutorFactory ef = (ExecutorFactory) FactoryRegistry.getFactory(ExecutorFactory.class);
+        Executor executor = ef.getExecutorInstance();
+        
+        EndpointInvocationContext eic = (EndpointInvocationContext) request.getInvocationContext();
+        ClassLoader cl = Thread.currentThread().getContextClassLoader();
+        
+        AsyncInvocationWorker worker = new AsyncInvocationWorker(target, methodInputParams, cl, eic);
+        FutureTask task = new FutureTask<AsyncInvocationWorker>(worker);
+        executor.execute(task);
+        
+        return;
     }
 
     protected Object invokeService(MessageContext ctx,
@@ -165,8 +183,8 @@
     
     private void initialize(MessageContext mc) {
         mc.setOperationName(mc.getAxisMessageContext().getAxisOperation().getName());
+        mc.setOperationDescription(Utils.getOperationDescription(mc));
         endpointDesc = mc.getEndpointDescription();
-        mc.setOperationDescription(getOperationDescription(mc));
         String bindingType = endpointDesc.getBindingType();
         if (bindingType != null) {
             if (bindingType.equals(SOAPBinding.SOAP11HTTP_MTOM_BINDING)
@@ -174,41 +192,9 @@
                 mc.getMessage().setMTOMEnabled(true);
             }
         }
-    }
-
-    /*
-     * Gets the OperationDescription associated with the request that is currently
-     * being processed.
-     * 
-     *  Note that this is not done in the EndpointController since operations are only relevant
-     *  to Endpoint-based implementation (i.e. not to Proxy-based ones)s
-     */
-    private OperationDescription getOperationDescription(MessageContext mc) {
-        EndpointDescription ed = mc.getEndpointDescription();
-        EndpointInterfaceDescription eid = ed.getEndpointInterfaceDescription();
-
-        OperationDescription[] ops = eid.getDispatchableOperation(mc.getOperationName());
-        // TODO: Implement signature matching.  Currently only matching on the wsdl:OperationName is supported.
-        //       That means that overloading of wsdl operations is not supported (although that's not supported in 
-        //       WSDL 1.1 anyway).
-        if (ops == null || ops.length == 0) {
-            // TODO: RAS & NLS
-            throw ExceptionFactory.makeWebServiceException(
-                    "No operation found.  WSDL Operation name: " + mc.getOperationName());
-        }
-        if (ops.length > 1) {
-            // TODO: RAS & NLS
-            throw ExceptionFactory.makeWebServiceException(
-                    "More than one operation found. Overloaded WSDL operations are not supported.  WSDL Operation name: " +
-                            mc.getOperationName());
-        }
-        OperationDescription op = ops[0];
-        if (log.isDebugEnabled()) {
-            log.debug("wsdl operation: " + op.getName());
-            log.debug("   java method: " + op.getJavaMethodName());
-        }
-
-        return op;
+        
+        //Set SOAP Operation Related properties in SOAPMessageContext.
+        ContextUtils.addWSDLProperties(mc);
     }
 
     private MethodMarshaller getMethodMarshaller(Protocol protocol,
@@ -222,7 +208,7 @@
         return MethodMarshallerFactory.getMarshaller(operationDesc, false);
     }
 
-    private Method getJavaMethod(MessageContext mc, Class serviceImplClass) {
+    protected Method getJavaMethod(MessageContext mc, Class serviceImplClass) {
 
         OperationDescription opDesc = mc.getOperationDescription();
         if (opDesc == null) {
@@ -238,28 +224,87 @@
 
         return returnMethod;
     }
-    /*
-    protected boolean isDocLitBare(EndpointDescription endpointDesc, OperationDescription operationDesc){
-		javax.jws.soap.SOAPBinding.ParameterStyle methodParamStyle = operationDesc.getSoapBindingParameterStyle();
-		if(methodParamStyle!=null){
-			return methodParamStyle == javax.jws.soap.SOAPBinding.ParameterStyle.BARE;
-		}
-		else{
-			javax.jws.soap.SOAPBinding.ParameterStyle SEIParamStyle = endpointDesc.getEndpointInterfaceDescription().getSoapBindingParameterStyle();
-			return SEIParamStyle == javax.jws.soap.SOAPBinding.ParameterStyle.BARE;
-		}
-	}
-	
-	protected boolean isDocLitWrapped(EndpointDescription endpointDesc, OperationDescription operationDesc){
-		javax.jws.soap.SOAPBinding.ParameterStyle methodParamStyle = operationDesc.getSoapBindingParameterStyle();
-		if(methodParamStyle!=null){
-			return methodParamStyle == javax.jws.soap.SOAPBinding.ParameterStyle.WRAPPED;
-		}
-		else{
-		javax.jws.soap.SOAPBinding.ParameterStyle SEIParamStyle = endpointDesc.getEndpointInterfaceDescription().getSoapBindingParameterStyle();
-		return SEIParamStyle == javax.jws.soap.SOAPBinding.ParameterStyle.WRAPPED;
-		}
-	}
-    */
+    
+    private Object[] createRequestParameters(MessageContext request) {
+        // Get the appropriate MethodMarshaller for the WSDL type.  This will reflect
+        // the "style" and "use" of the WSDL.
+        Protocol requestProtocol = request.getMessage().getProtocol();
+        MethodMarshaller methodMarshaller =
+                getMethodMarshaller(requestProtocol, request.getOperationDescription());
+        
+        // The MethodMarshaller will return the input parameters that are needed to 
+        // invoke the target method.
+        Object[] methodInputParams =
+                methodMarshaller.demarshalRequest(request.getMessage(), request.getOperationDescription());
+        
+        if (log.isDebugEnabled()) {
+            log.debug("Unmarshalled parameters for request");
+            if (methodInputParams != null) {
+                log.debug(methodInputParams.length + " parameters were found.");    
+            }
+        }
+        
+        return methodInputParams;
+    }
+    
+    public MessageContext createResponse(MessageContext request, Object[] input, Object output) {
+        return createResponse(request, request.getMessage().getProtocol(), input, output);
+    }
+    
+    public MessageContext createResponse(MessageContext request, Protocol p, Object[] params, Object output) {
+        OperationDescription operationDesc = request.getOperationDescription();
+        Method method = operationDesc.getMethodFromServiceImpl(serviceImplClass);
+        
+        // Create the appropriate response message, using the protocol from the
+        // request message.
+        MethodMarshaller marshaller = getMethodMarshaller(p, request.getOperationDescription());
+        Message m = null;
+        if (method.getReturnType().getName().equals("void")) {
+            m = marshaller.marshalResponse(null, params, operationDesc, p); 
+        } else {
+            m = marshaller.marshalResponse(output, params, operationDesc, p);
+        }
+        
+        // We'll need a MessageContext configured based on the response.
+        MessageContext response = MessageContextUtils.createResponseMessageContext(request);
+        response.setMessage(m);
+        
+        // Enable MTOM for the response if necessary.
+        EndpointDescription epDesc = request.getEndpointDescription();
 
+        String bindingType = epDesc.getBindingType();
+        if (bindingType != null) {
+            if (bindingType.equals(SOAPBinding.SOAP11HTTP_MTOM_BINDING) || 
+                bindingType.equals(SOAPBinding.SOAP12HTTP_MTOM_BINDING)) {
+                if (log.isDebugEnabled()) {
+                    log.debug("MTOM enabled for the response message.");
+                }
+                m.setMTOMEnabled(true);
+            }
+        }
+        
+        return response;
+    }
+    
+    public MessageContext createFaultResponse(MessageContext request, Throwable t) {
+        return createFaultResponse(request, request.getMessage().getProtocol(), t);
+    }
+    
+    public MessageContext createFaultResponse(MessageContext request, Protocol p, Throwable t) {
+        MethodMarshaller marshaller = getMethodMarshaller(p, request.getOperationDescription());
+        
+        Message m = marshaller.marshalFaultResponse(t, request.getOperationDescription(), p);
+        
+        MessageContext response = MessageContextUtils.createFaultMessageContext(request);
+        response.setMessage(m);
+
+        AxisFault axisFault = new AxisFault("The endpoint returned a fault when invoking the target operation.",
+                                            response.getAxisMessageContext(),
+                                            t);
+        
+        response.setCausedByException(axisFault);
+        
+        return response;
+    }
+    
 }

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/JavaDispatcher.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/JavaDispatcher.java?rev=575435&r1=575434&r2=575435&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/JavaDispatcher.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/JavaDispatcher.java Thu Sep 13 13:19:37 2007
@@ -19,12 +19,15 @@
 
 package org.apache.axis2.jaxws.server.dispatcher;
 
-import org.apache.axis2.jaxws.ExceptionFactory;
 import org.apache.axis2.jaxws.core.MessageContext;
-import org.apache.axis2.jaxws.i18n.Messages;
+import org.apache.axis2.jaxws.server.EndpointCallback;
+import org.apache.axis2.jaxws.server.EndpointInvocationContext;
+import org.apache.axis2.jaxws.utility.ClassUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
+import java.lang.reflect.Method;
+import java.util.concurrent.Callable;
 /**
  * JavaDispatcher is an abstract class that can be extended to implement an EndpointDispatcher to a
  * Java object.
@@ -41,35 +44,136 @@
         this.serviceInstance = serviceInstance;
     }
 
-    public abstract MessageContext invoke(MessageContext mc)
-            throws Exception;
-
+    public abstract MessageContext invoke(MessageContext request) throws Exception;
+    
+    public abstract void invokeOneWay(MessageContext request);
+    
+    public abstract void invokeAsync(MessageContext request, EndpointCallback callback);
+
+    protected abstract MessageContext createResponse(MessageContext request, Object[] input, Object output);
+    
+    protected abstract MessageContext createFaultResponse(MessageContext request, Throwable fault);
+    
+    
     public Class getServiceImplementationClass() {
         return serviceImplClass;
     }
-
-    protected Object createServiceInstance() {
-        if (log.isDebugEnabled()) {
-            log.debug("Creating new instance of service endpoint");
+    
+    protected Object invokeTargetOperation(Method method, Object[] params) throws Exception {
+        Object output = null;
+        try {
+            output = method.invoke(serviceInstance, params);
+        } catch (Exception t) {
+            if (log.isDebugEnabled()) {
+                log.debug("Exception invoking a method of " + serviceImplClass.toString()
+                        + " of instance " + serviceInstance.toString());
+                log.debug("Exception type thrown: " + t.getClass().getName());
+                log.debug("Method = " + method.toGenericString());
+                for (int i = 0; i < params.length; i++) {
+                    String value =
+                            (params[i] == null) ? "null"
+                                    : params[i].getClass().toString();
+                    log.debug(" Argument[" + i + "] is " + value);
+                }
+            }
+            
+            throw t;
         }
-
-        if (serviceImplClass == null) {
-            throw ExceptionFactory.makeWebServiceException(Messages.getMessage(
-                    "JavaDispErr1"));
+        
+        return output;
+    }
+    
+    
+    protected class AsyncInvocationWorker implements Callable {
+        
+        private Method method;
+        private Object[] params;
+        private ClassLoader classLoader;
+        private EndpointInvocationContext eic;
+        
+        public AsyncInvocationWorker(Method m, Object[] p, ClassLoader cl, EndpointInvocationContext ctx) {
+            method = m;
+            params = p;
+            classLoader = cl;
+            eic = ctx;
         }
-
-        Object instance = null;
-        try {
-            instance = serviceImplClass.newInstance();
-        } catch (IllegalAccessException e) {
-            throw ExceptionFactory.makeWebServiceException(Messages.getMessage(
-                    "JavaDispErr2", serviceImplClass.getName()));
-        } catch (InstantiationException e) {
-            throw ExceptionFactory.makeWebServiceException(Messages.getMessage(
-                    "JavaDispErr2", serviceImplClass.getName()));
+        
+        public Object call() throws Exception {
+            if (log.isDebugEnabled()) {
+                log.debug("Invoking target endpoint via the async worker.");
+            }
+            
+            // Set the proper class loader so that we can properly marshall the
+            // outbound response.
+            ClassLoader currentLoader = Thread.currentThread().getContextClassLoader();
+            if (classLoader != null) {
+                Thread.currentThread().setContextClassLoader(classLoader);
+                if (log.isDebugEnabled()) {
+                    log.debug("Context ClassLoader set to:" + classLoader);
+                }
+            }
+            
+            // We have the method that is going to be invoked and the parameter data to invoke it 
+            // with, so just invoke the operation.
+            Object output = null;
+            boolean faultThrown = false;
+            Throwable fault = null;
+            try {
+                output = invokeTargetOperation(method, params);
+            } 
+            catch (Exception e) {
+                fault = ClassUtils.getRootCause(e);
+                faultThrown = true;
+            }
+            
+            // If this is a one way invocation, we are done and just need to return.
+            if (eic.isOneWay()) {
+                if (log.isDebugEnabled()) {
+                    log.debug("Invocation pattern was one way, work complete.");
+                    return null;
+                }
+            }
+            
+            // Create the response MessageContext
+            MessageContext request = eic.getRequestMessageContext();
+            MessageContext response = null;
+            if (faultThrown) {
+                // If a fault was thrown, we need to create a slightly different
+                // MessageContext, than in the response path.
+                response = createFaultResponse(request, fault);
+            } else {
+                if (log.isDebugEnabled()) {
+                    log.debug("Async invocation of the endpoint was successful.  Creating response message.");
+                }
+                response = createResponse(request, params, output);
+            }
+
+            EndpointInvocationContext eic = null;
+            if (request.getInvocationContext() != null) {
+                eic = (EndpointInvocationContext) request.getInvocationContext();
+                eic.setResponseMessageContext(response);                
+            }
+            
+            EndpointCallback callback = eic.getCallback();
+            boolean handleFault = response.getMessage().isFault();
+            if (!handleFault) {
+                if (log.isDebugEnabled()) {
+                    log.debug("No fault detected in response message, sending back application response.");
+                }
+                callback.handleResponse(eic);
+            }
+            else {
+                if (log.isDebugEnabled()) {
+                    log.debug("A fault was detected.  Sending back a fault response.");
+                }
+                callback.handleFaultResponse(eic);
+            }
+            
+            // Set the thread's ClassLoader back to what it originally was.
+            Thread.currentThread().setContextClassLoader(currentLoader);
+            
+            return null;
         }
-
-        return instance;
     }
 
 }

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/ProviderDispatcher.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/ProviderDispatcher.java?rev=575435&r1=575434&r2=575435&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/ProviderDispatcher.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/ProviderDispatcher.java Thu Sep 13 13:19:37 2007
@@ -34,21 +34,28 @@
 import org.apache.axis2.jaxws.message.factory.SourceBlockFactory;
 import org.apache.axis2.jaxws.message.factory.XMLStringBlockFactory;
 import org.apache.axis2.jaxws.registry.FactoryRegistry;
-import org.apache.axis2.jaxws.server.EndpointController;
+import org.apache.axis2.jaxws.server.EndpointCallback;
+import org.apache.axis2.jaxws.server.EndpointInvocationContext;
 import org.apache.axis2.jaxws.utility.ClassUtils;
+import org.apache.axis2.jaxws.utility.ExecutorFactory;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
 import javax.activation.DataSource;
 import javax.xml.bind.JAXBContext;
 import javax.xml.soap.SOAPMessage;
+import javax.xml.stream.XMLStreamException;
 import javax.xml.transform.Source;
 import javax.xml.ws.Provider;
 import javax.xml.ws.Service;
+import javax.xml.ws.WebServiceException;
 import javax.xml.ws.soap.SOAPBinding;
+
+import java.lang.reflect.Method;
 import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
-import java.security.PrivilegedExceptionAction;
+import java.util.concurrent.Executor;
+import java.util.concurrent.FutureTask;
 
 /**
  * The ProviderDispatcher is used to invoke instances of a target endpoint that implement the {@link
@@ -71,6 +78,7 @@
     private Message message = null;
     private Protocol messageProtocol;
 
+    private EndpointDescription endpointDesc;
 
     /**
      * Constructor
@@ -85,24 +93,141 @@
     /* (non-Javadoc)
     * @see org.apache.axis2.jaxws.server.EndpointDispatcher#execute()
     */
-    public MessageContext invoke(final MessageContext mc) throws Exception {
+    public MessageContext invoke(MessageContext request) throws Exception {
         if (log.isDebugEnabled()) {
             log.debug("Preparing to invoke javax.xml.ws.Provider based endpoint");
+            log.debug("Invocation pattern: two way, sync");
         }
 
         providerInstance = getProviderInstance();
 
+        Object param = createRequestParameters(request);
+
+        if (log.isDebugEnabled()) {
+            final Object input = providerType.cast(param);
+            log.debug("Invoking Provider<" + providerType.getName() + ">");
+            if (input != null) {
+                log.debug("Parameter type: " + input.getClass().getName());
+            }
+            else {
+                log.debug("Parameter is NULL");
+            }
+        }
+
+        // Invoke the actual Provider.invoke() method
+        boolean faultThrown = false;
+        Throwable fault = null;
+        Object[] input = new Object[] {param};
+        Object responseParamValue = null;
+        try {
+            responseParamValue = invokeTargetOperation(getJavaMethod(), input);
+        } catch (Throwable e) {
+            fault = ClassUtils.getRootCause(e);
+            faultThrown = true;
+        }
+
+        // TODO (NLG): Need to find a better way to sync this across both Dispatchers.
+        endpointDesc = request.getEndpointDescription();
+        
+        // Create the response MessageContext
+        MessageContext responseMsgCtx = null;
+        if (faultThrown) {
+            // If a fault was thrown, we need to create a slightly different
+            // MessageContext, than in the response path.
+            responseMsgCtx = createFaultResponse(request, fault);
+        } else {
+            responseMsgCtx = createResponse(request, input, responseParamValue);
+        }
+
+        return responseMsgCtx;
+    }
+    
+    public void invokeOneWay(MessageContext request) {
+        if (log.isDebugEnabled()) {
+            log.debug("Preparing to invoke javax.xml.ws.Provider based endpoint");
+            log.debug("Invocation pattern: one way");
+        }
+        
+        providerInstance = getProviderInstance();
+
+        Object param = createRequestParameters(request);
+
+        if (log.isDebugEnabled()) {
+            final Object input = providerType.cast(param);
+            log.debug("Invoking Provider<" + providerType.getName() + ">");
+            if (input != null) {
+                log.debug("Parameter type: " + input.getClass().getName());
+            }
+            else {
+                log.debug("Parameter is NULL");
+            }
+        }
+
+        ExecutorFactory ef = (ExecutorFactory) FactoryRegistry.getFactory(ExecutorFactory.class);
+        Executor executor = ef.getExecutorInstance();
+        
+        Method m = getJavaMethod();
+        Object[] params = new Object[] {param};
+        
+        EndpointInvocationContext eic = (EndpointInvocationContext) request.getInvocationContext();
+        ClassLoader cl = Thread.currentThread().getContextClassLoader();
+        
+        AsyncInvocationWorker worker = new AsyncInvocationWorker(m, params, cl, eic);
+        FutureTask task = new FutureTask<AsyncInvocationWorker>(worker);
+        executor.execute(task);
+        
+        return;
+    }
+    
+    public void invokeAsync(MessageContext request, EndpointCallback callback) {
+        if (log.isDebugEnabled()) {
+            log.debug("Preparing to invoke javax.xml.ws.Provider based endpoint");
+            log.debug("Invocation pattern: two way, async");
+        }
+        
+        providerInstance = getProviderInstance();
+
+        Object param = createRequestParameters(request);
+
+        if (log.isDebugEnabled()) {
+            final Object input = providerType.cast(param);
+            log.debug("Invoking Provider<" + providerType.getName() + ">");
+            if (input != null) {
+                log.debug("Parameter type: " + input.getClass().getName());
+            }
+            else {
+                log.debug("Parameter is NULL");
+            }
+        }
+
+        ExecutorFactory ef = (ExecutorFactory) FactoryRegistry.getFactory(ExecutorFactory.class);
+        Executor executor = ef.getExecutorInstance();
+        
+        Method m = getJavaMethod();
+        Object[] params = new Object[] {param};
+        
+        EndpointInvocationContext eic = (EndpointInvocationContext) request.getInvocationContext();
+        ClassLoader cl = Thread.currentThread().getContextClassLoader();
+        
+        AsyncInvocationWorker worker = new AsyncInvocationWorker(m, params, cl, eic);
+        FutureTask task = new FutureTask<AsyncInvocationWorker>(worker);
+        executor.execute(task);
+        
+        return;
+    }
+    
+    public Object createRequestParameters(MessageContext request) {
         // First we need to know what kind of Provider instance we're going
         // to be invoking against
         providerType = getProviderType();
 
         // REVIEW: This assumes there is only one endpoint description on the service.  Is that always the case?
-        EndpointDescription endpointDesc = mc.getEndpointDescription();
+        EndpointDescription endpointDesc = request.getEndpointDescription();
 
         // Now that we know what kind of Provider we have, we can create the 
         // right type of Block for the request parameter data
         Object requestParamValue = null;
-        Message message = mc.getMessage();
+        Message message = request.getMessage();
         if (message != null) {
             
             // Enable MTOM if indicated by the binding
@@ -142,7 +267,13 @@
                 // If it is not MESSAGE, then it is PAYLOAD (which is the default); only work with the body 
                 Block block = message.getBodyBlock(null, factory);
                 if (block != null) {
-                    requestParamValue = block.getBusinessObject(true);
+                    try {
+                        requestParamValue = block.getBusinessObject(true);
+                    } catch (WebServiceException e) {
+                        throw ExceptionFactory.makeWebServiceException(e);
+                    } catch (XMLStreamException e) {
+                        throw ExceptionFactory.makeWebServiceException(e);
+                    }
                 } else {
                     if (log.isDebugEnabled()) {
                         log.debug(
@@ -152,81 +283,47 @@
                 }
             }
         }
-
-        if (log.isDebugEnabled())
-            log.debug(
-                    "Provider Type = " + providerType + "; parameter type = " + requestParamValue);
-
-        final Object input = providerType.cast(requestParamValue);
-        if (input != null && log.isDebugEnabled()) {
-            log.debug("Invoking Provider<" + providerType.getName() + "> with " +
-                    "parameter of type " + input.getClass().getName());
-        }
-        if (input == null && log.isDebugEnabled()) {
-            log.debug("Invoking Provider<" + providerType.getName() + "> with " +
-                    "NULL input parameter");
-        }
-
-        // Invoke the actual Provider.invoke() method
-        boolean faultThrown = false;
-        XMLFault fault = null;
-        Object responseParamValue = null;
-        Throwable t = null;
+        
+        
+        return requestParamValue;
+    }
+    
+    public MessageContext createResponse(MessageContext request, Object[] input, Object output) {
+        Message m;
         try {
-            responseParamValue = (Object)org.apache.axis2.java.security.AccessController
-                    .doPrivileged(new PrivilegedExceptionAction() {
-                        public Object run() throws Exception {
-                            return invokeProvider(mc, providerInstance, input);
-                        }
-                    });
+            m = createMessageFromValue(output);
         } catch (Exception e) {
-            t = ClassUtils.getRootCause(e);
-            faultThrown = true;
-            fault = MethodMarshallerUtils.createXMLFaultFromSystemException(t);
-
-            if (log.isDebugEnabled()) {
-                log.debug("Marshal Throwable =" + e.getClass().getName());
-                log.debug("  rootCause =" + t.getClass().getName());
-                log.debug("  exception=" + t.toString());
-            }
+            throw ExceptionFactory.makeWebServiceException(e);
         }
 
-        // Create the response MessageContext
-        MessageContext responseMsgCtx = null;
-        if (!EndpointController.isOneWay(mc.getAxisMessageContext())) {
-            if (faultThrown) {
-                // If a fault was thrown, we need to create a slightly different
-                // MessageContext, than in the response path.
-                Message responseMsg = createMessageFromValue(fault);
-                responseMsgCtx = MessageContextUtils.createFaultMessageContext(mc);
-                responseMsgCtx.setMessage(responseMsg);
-            } else {
-                Message responseMsg = createMessageFromValue(responseParamValue);
-
-                // Enable MTOM if indicated by the binding
-                String bindingType = endpointDesc.getBindingType();
-                if (bindingType != null) {
-                    if (bindingType.equals(SOAPBinding.SOAP11HTTP_MTOM_BINDING) ||
-                            bindingType.equals(SOAPBinding.SOAP12HTTP_MTOM_BINDING)) {
-                        responseMsg.setMTOMEnabled(true);
-                    }
-                }
-
-                responseMsgCtx = MessageContextUtils.createResponseMessageContext(mc);
-                responseMsgCtx.setMessage(responseMsg);
+        // Enable MTOM if indicated by the binding
+        String bindingType = endpointDesc.getBindingType();
+        if (bindingType != null) {
+            if (bindingType.equals(SOAPBinding.SOAP11HTTP_MTOM_BINDING)
+                    || bindingType.equals(SOAPBinding.SOAP12HTTP_MTOM_BINDING)) {
+                m.setMTOMEnabled(true);
             }
-        } else {
-            // If we have a one-way operation, then we cannot create a MessageContext for the response.
-            return null;
         }
 
-        return responseMsgCtx;
+        MessageContext response = MessageContextUtils.createResponseMessageContext(request);
+        response.setMessage(m);
+        
+        return response;
     }
-
-    protected Object invokeProvider(MessageContext ctx,
-                                    Provider provider,
-                                    Object input) throws Exception {
-        return provider.invoke(input);
+    
+    public MessageContext createFaultResponse(MessageContext request, Throwable fault) {
+        Message m;
+        try {
+            XMLFault xmlFault = MethodMarshallerUtils.createXMLFaultFromSystemException(fault);
+            m = createMessageFromValue(xmlFault);
+        } catch (Exception e) {
+            throw ExceptionFactory.makeWebServiceException(e);
+        }
+        
+        MessageContext response = MessageContextUtils.createFaultMessageContext(request);
+        response.setMessage(m);
+        
+        return response;
     }
     
     /**
@@ -311,12 +408,12 @@
     /*
       * Determine the Provider type for this instance
       */
-    private Provider getProviderInstance() throws Exception {
+    private Provider getProviderInstance() {
         Class<?> clazz = getProviderType();
 
         if (!isValidProviderType(clazz)) {
-            //TODO This will change once deployment code it in place
-            throw new Exception(Messages.getMessage("InvalidProvider", clazz.getName()));
+            // TODO This will change once deployment code it in place
+            throw ExceptionFactory.makeWebServiceException(Messages.getMessage("InvalidProvider", clazz.getName()));
         }
 
         Provider provider = null;
@@ -340,9 +437,9 @@
     }
 
     /*
-    * Get the provider type from a given implemention class instance
-    */
-    private Class<?> getProviderType() throws Exception {
+     * Get the provider type from a given implemention class instance
+     */
+    private Class<?> getProviderType() {
 
         Class providerType = null;
 
@@ -360,19 +457,11 @@
             if (interfaceName == javax.xml.ws.Provider.class) {
                 if (paramType.getActualTypeArguments().length > 1) {
                     //TODO NLS
-                    throw new Exception(
-                            "Provider cannot have more than one Generic Types defined as Per JAX-WS Specification");
+                    throw ExceptionFactory.makeWebServiceException("Provider cannot have more than one Generic Types defined as Per JAX-WS Specification");
                 }
                 providerType = (Class)paramType.getActualTypeArguments()[0];
-                break;
             }
         }
-        if(providerType == null) {
-            throw new Exception("Provider based SEI Class has to implement javax.xml.ws." +
-                        "Provider as javax.xml.ws.Provider<String>, javax.xml.ws." +
-                        "Provider<SOAPMessage>, javax.xml.ws.Provider<Source> or " +
-                        "javax.xml.ws.Provider<JAXBContext>");
-        }
         return providerType;
     }
 
@@ -427,4 +516,17 @@
         return blockFactory;
     }
     
+    protected Method getJavaMethod() {
+        Method m = null;
+        try {
+            m = providerInstance.getClass().getMethod("invoke", new Class[] {getProviderType()});
+        } catch (SecurityException e) {
+            throw ExceptionFactory.makeWebServiceException(e);
+        } catch (NoSuchMethodException e) {
+            throw ExceptionFactory.makeWebServiceException(e);
+        }
+        
+        return m;
+    }
+
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: axis-cvs-unsubscribe@ws.apache.org
For additional commands, e-mail: axis-cvs-help@ws.apache.org