org.apache.axis2.jaxws.server.EndpointController.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.axis2.jaxws.server.EndpointController.java

Source

/*
 * 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.axiom.om.util.StAXUtils;
import org.apache.axiom.soap.SOAPEnvelope;
import org.apache.axis2.AxisFault;
import org.apache.axis2.description.AxisOperation;
import org.apache.axis2.description.AxisService;
import org.apache.axis2.description.Parameter;
import org.apache.axis2.description.WSDL2Constants;
import org.apache.axis2.java.security.AccessController;
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.handler.HandlerChainProcessor;
import org.apache.axis2.jaxws.handler.HandlerInvocationContext;
import org.apache.axis2.jaxws.handler.HandlerInvoker;
import org.apache.axis2.jaxws.handler.HandlerInvokerUtils;
import org.apache.axis2.jaxws.handler.HandlerResolverImpl;
import org.apache.axis2.jaxws.handler.HandlerUtils;
import org.apache.axis2.jaxws.handler.factory.HandlerInvokerFactory;
import org.apache.axis2.jaxws.handler.lifecycle.factory.HandlerLifecycleManager;
import org.apache.axis2.jaxws.handler.lifecycle.factory.HandlerLifecycleManagerFactory;
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.factory.MessageFactory;
import org.apache.axis2.jaxws.registry.FactoryRegistry;
import org.apache.axis2.jaxws.server.dispatcher.EndpointDispatcher;
import org.apache.axis2.jaxws.server.dispatcher.ProviderDispatcher;
import org.apache.axis2.jaxws.server.dispatcher.factory.EndpointDispatcherFactory;
import org.apache.axis2.jaxws.server.endpoint.Utils;
import org.apache.axis2.jaxws.spi.Constants;
import org.apache.axis2.wsdl.WSDLConstants.WSDL20_2004_Constants;
import org.apache.axis2.wsdl.WSDLConstants.WSDL20_2006Constants;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamReader;
import javax.xml.ws.WebServiceException;
import javax.xml.ws.handler.Handler;
import javax.xml.ws.handler.PortInfo;

import java.io.StringReader;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

/**
 * The EndpointController is the server side equivalent to the InvocationController on the client
 * side.  It is an abstraction of the server side endpoint invocation that encapsulates all of the
 * Axis2 semantics.
 * <p/>
 * Like the InvocationController, this class is responsible for invoking the JAX-WS application
 * handler chain along with taking all of the provided information and setting up what's needed to
 * perform the actual invocation of the endpoint.
 */
public class EndpointController {

    private static final Log log = LogFactory.getLog(EndpointController.class);

    /**
     * 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 EndpointInvocationContext invoke(EndpointInvocationContext eic) throws AxisFault, WebServiceException {
        if (log.isDebugEnabled()) {
            log.debug("Invocation pattern: synchronous");
        }

        MessageContext request = eic.getRequestMessageContext();
        boolean good = true;
        try {
            good = handleRequest(eic);

            if (!good) {
                return eic;
            }
            MessageContext response = null;
            EndpointDispatcher dispatcher = eic.getDispatcher();
            if (request != null && dispatcher != null) {
                response = dispatcher.invoke(request);
                // Note that response may be null in the case of a Provider returning null
                eic.setResponseMessageContext(response);
            } else {
                throw ExceptionFactory.makeWebServiceException(Messages.getMessage("invokeErr"));
            }
        } catch (AxisFault af) {
            throw af;
        } catch (Exception e) {
            Throwable toBeThrown = InvocationHelper.determineMappedException(e, eic);
            if (toBeThrown == null) {
                toBeThrown = e;
            }
            throw ExceptionFactory.makeWebServiceException(toBeThrown);
        } finally {
            if (good) {
                // Passed pivot point
                request.getMessage().setPostPivot();
                handleResponse(eic);
            } else {
                destroyHandlers(eic, request);
            }
            // Release WebServiceContextResources if available
            ContextUtils.releaseWebServiceContextResources(request);
        }

        return eic;
    }

    public void invokeAsync(EndpointInvocationContext eic) {
        if (log.isDebugEnabled()) {
            log.debug("Invocation pattern: asynchronous");
        }

        MessageContext request = eic.getRequestMessageContext();
        try {
            boolean good = handleRequest(eic);

            if (!good) {
                return;
            }
            EndpointDispatcher dispatcher = eic.getDispatcher();
            if (request != null && dispatcher != null) {
                dispatcher.invokeAsync(request, eic.getCallback());
            } else {
                throw ExceptionFactory.makeWebServiceException(Messages.getMessage("invokeErr"));
            }
        } catch (Exception e) {
            Throwable toBeThrown = InvocationHelper.determineMappedException(e, eic);
            if (toBeThrown == null) {
                toBeThrown = e;
            }
            throw ExceptionFactory.makeWebServiceException(toBeThrown);
        } 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");
        }

        MessageContext request = eic.getRequestMessageContext();
        try {
            boolean good = handleRequest(eic);

            if (!good) {
                return;
            }
            EndpointDispatcher dispatcher = eic.getDispatcher();
            if (request != null && dispatcher != null) {
                dispatcher.invokeOneWay(request);
            } else {
                throw ExceptionFactory.makeWebServiceException(Messages.getMessage("invokeErr"));
            }
        } catch (Exception e) {
            Throwable toBeThrown = InvocationHelper.determineMappedException(e, eic);
            if (toBeThrown == null) {
                toBeThrown = e;
            }
            throw ExceptionFactory.makeWebServiceException(toBeThrown);
        } finally {
            // Passed pivot point
            request.getMessage().setPostPivot();
        }

        return;
    }

    protected boolean handleRequest(EndpointInvocationContext eic) throws AxisFault, WebServiceException {

        MessageContext responseMsgContext = null;

        try {
            requestReceived(eic);

            MessageContext request = eic.getRequestMessageContext();

            Class serviceEndpoint = getServiceImplementation(request);
            EndpointDescription endpointDesc = getEndpointDescription(request);
            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...
            List<String> handlerRoles = null;
            if (eic.getHandlers() == null) {
                if (log.isDebugEnabled()) {
                    log.debug("No handlers found on the InvocationContext, initializing handler list.");
                }
                HandlerResolverImpl hri = new HandlerResolverImpl(endpointDesc.getServiceDescription());
                PortInfo portInfo = endpointDesc.getPortInfo();
                eic.setHandlers(hri.getHandlerChain(portInfo));
                handlerRoles = hri.getRoles(portInfo);
            }

            //  Get the service instance.  This will run the @PostConstruct code.
            ServiceInstanceFactory instanceFactory = (ServiceInstanceFactory) FactoryRegistry
                    .getFactory(ServiceInstanceFactory.class);
            Object serviceInstance = instanceFactory.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(request);

            boolean success = true;

            // Perform inbound header/handler processing only if there is are headers OR handlers
            if ((request.getAxisMessageContext() != null
                    && request.getAxisMessageContext().getEnvelope().getHeader() != null)
                    || (eic.getHandlers() != null && !eic.getHandlers().isEmpty())) {
                success = inboundHeaderAndHandlerProcessing(request, eic, handlerRoles);
            }

            if (success) {
                if (log.isDebugEnabled()) {
                    log.debug("JAX-WS inbound handler chain invocation complete.");
                }
                // Set the dispatcher.
                EndpointDispatcher dispatcher = getEndpointDispatcher(request, serviceEndpoint, serviceInstance);
                Boolean ignoreSOAPVersion = false;
                if (log.isDebugEnabled()) {
                    log.debug("Checking for ProviderDispatcher instance");
                }
                if (dispatcher instanceof ProviderDispatcher) {
                    if (log.isDebugEnabled()) {
                        log.debug("ProviderDispatcher instance Found");
                    }
                    String bindingType = endpointDesc.getBindingType();
                    if (bindingType.equals(org.apache.axis2.jaxws.Constants.SOAP_HTTP_BINDING)) {
                        ignoreSOAPVersion = true;
                    }
                    if (log.isDebugEnabled()) {
                        log.debug("ignoreSOAPVersion Value =" + ignoreSOAPVersion.booleanValue());
                    }
                }
                //Need to make sure the protocol (envelope ns)  of the request matches the binding
                // expected by the service description
                if (!ignoreSOAPVersion && !Utils.bindingTypesMatch(request, endpointDesc)) {
                    Protocol protocol = request.getMessage().getProtocol();
                    MessageContext faultContext = Utils.createVersionMismatchMessage(request, protocol);
                    eic.setResponseMessageContext(faultContext);
                    return false;
                }

                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.");
                }
                responseMsgContext = 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(request.getMessage());
                eic.setResponseMessageContext(responseMsgContext);
                responseReady(eic);
                return false;
            }
        } catch (AxisFault af) {
            throw af;
        } 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);
        }
    }

    /**
     * Perform inbound Handler and Header processing
     * This includes the must understand checking and
     * invoking the inbound handler chain
     * @param request
     * @param eic
     * @param handlerRoles
     * @return
     * @throws AxisFault
     */
    private boolean inboundHeaderAndHandlerProcessing(MessageContext request, EndpointInvocationContext eic,
            List<String> handlerRoles) throws AxisFault {
        //Lets Initialize the understood QName here, add only the headers that the handler 
        //injects when we invoke the getHeader().
        //Since we are adding the handlers to description layer here we will register all the
        //headers set by SOAPHandler->getHeader().
        List<QName> understood = HandlerUtils.registerSOAPHandlerHeaders(request.getAxisMessageContext(),
                eic.getHandlers());

        //As per section 10.2.1 of JAXWS Specification, perform a mustUnderstand processing before
        //invoking inbound handlers.
        HandlerUtils.checkMustUnderstand(request.getAxisMessageContext(), understood, handlerRoles);

        // 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
        HandlerInvocationContext hiContext = buildHandlerInvocationContext(request, eic.getHandlers(),
                HandlerChainProcessor.MEP.REQUEST, isOneWay(request.getAxisMessageContext()));
        HandlerInvokerFactory hiFactory = (HandlerInvokerFactory) FactoryRegistry
                .getFactory(HandlerInvokerFactory.class);
        HandlerInvoker handlerInvoker = hiFactory.createHandlerInvoker(request);
        boolean success = handlerInvoker.invokeInboundHandlers(hiContext);

        return success;

    }

    protected boolean handleResponse(EndpointInvocationContext eic) {
        MessageContext request = eic.getRequestMessageContext();
        MessageContext response = eic.getResponseMessageContext();

        try {
            if (response != null) {
                //Before running inbound handlers lets make sure that the request and response have no protocol mismatch.
                EndpointDescription endpointDesc = request.getEndpointDescription();
                String bindingType = endpointDesc.getBindingType();
                if (bindingType.equals(org.apache.axis2.jaxws.Constants.SOAP_HTTP_BINDING)) {
                    if (log.isDebugEnabled()) {
                        log.debug("Check for protocol mismatch");
                    }
                    MessageContext faultContext = isProtocolMismatch(request, response);
                    if (faultContext != null) {
                        if (log.isDebugEnabled()) {
                            log.debug("There is a protocol mismatch, generating fault message");
                        }
                        eic.setResponseMessageContext(faultContext);
                        return false;
                    }
                    if (log.isDebugEnabled()) {
                        log.debug("There is no protocol mismatch");
                    }
                }
                // 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(request.getAxisMessageContext())) {
                    response.setMEPContext(request.getMEPContext());

                    HandlerInvocationContext hiContext = buildHandlerInvocationContext(request, eic.getHandlers(),
                            HandlerChainProcessor.MEP.RESPONSE, false);
                    HandlerInvokerFactory hiFactory = (HandlerInvokerFactory) FactoryRegistry
                            .getFactory(HandlerInvokerFactory.class);
                    HandlerInvoker handlerInvoker = hiFactory.createHandlerInvoker(response);
                    handlerInvoker.invokeOutboundHandlers(hiContext);

                }
            } else { // reponse is null.  
                if (MessageContextUtils.getJaxwsProviderInterpretNullOneway(request)) {
                    // Provider must have returned null, and property is set.
                    // so now we only need to call closure
                    HandlerInvokerUtils.invokeInboundHandlersForClosure(request.getMEPContext(), eic.getHandlers(),
                            HandlerChainProcessor.MEP.RESPONSE);
                }
            }
        } catch (Exception e) {
            // TODO for now, throw it.  We probably should try to make an XMLFault object and set it on the message
            Throwable toBeThrown = InvocationHelper.determineMappedException(e, eic);
            if (toBeThrown == null) {
                toBeThrown = e;
            }
            throw ExceptionFactory.makeWebServiceException(toBeThrown);
        } finally {
            // at this point, we are done with handler instances on the server; call @PreDestroy on all of them
            destroyHandlers(eic, request);
            responseReady(eic);
            restoreRequestMessage(request);
        }

        eic.setResponseMessageContext(response);
        return true;
    }

    private void destroyHandlers(EndpointInvocationContext eic, MessageContext request) {
        HandlerLifecycleManager hlm = createHandlerlifecycleManager();
        List<Handler> list = eic.getHandlers();
        if (list != null) {
            for (Iterator it = list.iterator(); it.hasNext();) {
                try {
                    Handler handler = (Handler) it.next();
                    hlm.destroyHandlerInstance(request, handler);
                } catch (Exception e) {
                    // TODO: can we ignore this?
                    throw ExceptionFactory.makeWebServiceException(e);
                }
            }
        }
    }

    /*
     * 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;
    }

    /*
      * Get the appropriate EndpointDispatcher for a given service endpoint.
      */
    protected EndpointDispatcher getEndpointDispatcher(Class serviceImplClass, Object serviceInstance)
            throws Exception {
        return getEndpointDispatcher(null, serviceImplClass, serviceInstance);
    }

    protected EndpointDispatcher getEndpointDispatcher(MessageContext mc, Class serviceImplClass,
            Object serviceInstance) throws Exception {
        EndpointDispatcherFactory factory = (EndpointDispatcherFactory) FactoryRegistry
                .getFactory(EndpointDispatcherFactory.class);
        return factory.createEndpointDispatcher(mc, 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
      */
    private Class loadServiceImplClass(String className, ClassLoader cl) {
        if (log.isDebugEnabled()) {
            log.debug("Attempting to load service impl class: " + className);
        }

        try {
            //TODO: What should be done if the supplied ClassLoader is null?
            Class _class = forName(className, true, cl);
            return _class;
            //Catch Throwable as ClassLoader can throw an NoClassDefFoundError that
            //does not extend Exception, so lets catch everything that extends Throwable
            //rather than just Exception.
        } catch (Throwable cnf) {
            throw ExceptionFactory.makeWebServiceException(Messages.getMessage("EndpointControllerErr4", className),
                    cnf);
        }
    }

    /**
     * Return the class for this name
     *
     * @return Class
     */
    private static Class forName(final String className, final boolean initialize, final ClassLoader classloader)
            throws ClassNotFoundException {
        // NOTE: This method must remain private because it uses AccessController
        Class cl = null;
        try {
            cl = (Class) AccessController.doPrivileged(new PrivilegedExceptionAction() {
                public Object run() throws ClassNotFoundException {
                    return Class.forName(className, initialize, classloader);
                }
            });
        } catch (PrivilegedActionException e) {
            if (log.isDebugEnabled()) {
                log.debug("PrivilegedActionException thrown from AccessController: " + e);
                log.debug("Real Cause is " + e.getException().getCause());
            }
            throw (ClassNotFoundException) e.getException();
        }

        return cl;
    }

    /*
    * Gets the EndpointDescription associated with the request that is currently
    * being processed.
    */
    private EndpointDescription getEndpointDescription(MessageContext mc) {
        AxisService axisSvc = mc.getAxisMessageContext().getAxisService();
        Parameter param = axisSvc.getParameter(EndpointDescription.AXIS_SERVICE_PARAMETER);

        if (param == null) {
            // If we've made it here, its very likely that although the AxisService was deployed, the 
            // associated ServiceDescription was not created successfully
            throw ExceptionFactory.makeWebServiceException(Messages.getMessage("endpointDescErr1"));
        }

        EndpointDescription ed = (EndpointDescription) param.getValue();
        return ed;
    }

    /**
     * Save the request message if indicated by the SAVE_REQUEST_MSG property
     *
     * @param requestMsgContext
     */
    private void saveRequestMessage(MessageContext requestMsgContext) {

        // TODO: TESTING...FORCE SAVING THE REQUEST MESSAGE
        // requestMsgContext.getAxisMessageContext().setProperty(Constants.SAVE_REQUEST_MSG, Boolean.TRUE);
        // END TESTING

        Boolean value = (Boolean) requestMsgContext.getAxisMessageContext().getProperty(Constants.SAVE_REQUEST_MSG);
        if (value != null && value.booleanValue()) {
            // REVIEW: This does not properly account for attachments.
            Message m = requestMsgContext.getMessage();
            String savedMsg = m.getAsOMElement().toString();
            requestMsgContext.getAxisMessageContext().setProperty(Constants.SAVED_REQUEST_MSG_TEXT, savedMsg);
        }
    }

    /**
     * Restore the request message from the saved message text
     *
     * @param requestMsgContext
     */
    private void restoreRequestMessage(MessageContext requestMsgContext) {

        Boolean value = (Boolean) requestMsgContext.getAxisMessageContext().getProperty(Constants.SAVE_REQUEST_MSG);
        if (value != null && value.booleanValue()) {
            // REVIEW: This does not properly account for attachments.
            String savedMsg = (String) requestMsgContext.getAxisMessageContext()
                    .getProperty(Constants.SAVED_REQUEST_MSG_TEXT);
            if (savedMsg != null && savedMsg.length() > 0) {
                try {
                    StringReader sr = new StringReader(savedMsg);
                    XMLStreamReader xmlreader = StAXUtils.createXMLStreamReader(sr);
                    MessageFactory mf = (MessageFactory) FactoryRegistry.getFactory(MessageFactory.class);
                    Protocol protocol = requestMsgContext.getAxisMessageContext().isDoingREST() ? Protocol.rest
                            : null;
                    Message msg = mf.createFrom(xmlreader, protocol);
                    requestMsgContext.setMessage(msg);
                } catch (Throwable e) {
                    throw ExceptionFactory.makeWebServiceException(e);
                }
            }
        }

        // TESTING....SIMULATE A PERSIST OF THE REQUEST MESSAGE
        // String text = requestMsgContext.getMessage().getAsOMElement().toString();
        // System.out.println("Persist Message" + text);
        // END TESTING
    }

    /*
    * Determine if this is a one-way invocation or not.
    */
    public static boolean isOneWay(org.apache.axis2.context.MessageContext mc) {
        if (mc != null) {
            AxisOperation op = mc.getAxisOperation();
            String mep = op.getMessageExchangePattern();

            if (mep.equals(WSDL20_2004_Constants.MEP_URI_ROBUST_IN_ONLY)
                    || mep.equals(WSDL20_2004_Constants.MEP_URI_IN_ONLY)
                    || mep.equals(WSDL20_2006Constants.MEP_URI_ROBUST_IN_ONLY)
                    || mep.equals(WSDL20_2006Constants.MEP_URI_IN_ONLY)
                    || mep.equals(WSDL2Constants.MEP_URI_ROBUST_IN_ONLY)
                    || mep.equals(WSDL2Constants.MEP_URI_IN_ONLY)) {
                return true;
            }
        }
        return false;
    }

    /**
     * Builds the HandlerInvocationContext that will be used when invoking 
     * inbound/outbound handler chains.
     */
    static HandlerInvocationContext buildHandlerInvocationContext(MessageContext request, List<Handler> handlers,
            HandlerChainProcessor.MEP mep, boolean isOneWay) {
        HandlerInvocationContext hiContext = new HandlerInvocationContext();
        hiContext.setMessageContext(request);
        hiContext.setMEP(mep);
        hiContext.setHandlers(handlers);
        hiContext.setOneWay(isOneWay);
        return hiContext;
    }

    /**
     * This method will retrieve all the InvocationListenerFactory instances and
     * call the 'createInvocationListener' instance on each. If a non-null listener
     * is returned, the 'requestReceived' method will be called on the instance,
     * and it will be added to the EndpointInvocationContext.
     */
    protected void requestReceived(EndpointInvocationContext eic) {
        Collection<InvocationListenerFactory> factoryList = eic.getInvocationListenerFactories();
        if (factoryList != null) {
            InvocationListenerBean bean = new InvocationListenerBean(eic, InvocationListenerBean.State.REQUEST);
            Iterator<InvocationListenerFactory> factoryIter = factoryList.iterator();
            while (factoryIter.hasNext()) {
                InvocationListenerFactory factory = factoryIter.next();
                InvocationListener listener = factory.createInvocationListener(eic.getRequestMessageContext());
                if (listener != null) {
                    try {
                        listener.notify(bean);
                    } catch (Exception e) {
                        throw ExceptionFactory.makeWebServiceException(e);
                    } finally {
                        // add this instance so it can be called on the response also
                        eic.addInvocationListener(listener);
                    }
                }
            }
            MessageContext request = eic.getRequestMessageContext();
            request.setProperty(org.apache.axis2.jaxws.spi.Constants.INVOCATION_LISTENER_LIST,
                    eic.getInvocationListeners());
        }
    }

    /** 
     * This will call the InvocationListener instances that were called during
     * the request processing for this message.
     */
    protected void responseReady(EndpointInvocationContext eic) {
        List<InvocationListener> listenerList = eic.getInvocationListeners();
        if (listenerList != null) {
            InvocationListenerBean bean = new InvocationListenerBean(eic, InvocationListenerBean.State.RESPONSE);
            for (InvocationListener listener : listenerList) {
                try {
                    listener.notify(bean);
                } catch (Exception e) {
                    throw ExceptionFactory.makeWebServiceException(e);
                }
            }
        }
    }

    /**
     * we need a HandlerLifecycleManager so we can call the @PreDestroy when we are done with the server-side handler instances
     */
    private HandlerLifecycleManager createHandlerlifecycleManager() {
        HandlerLifecycleManagerFactory elmf = (HandlerLifecycleManagerFactory) FactoryRegistry
                .getFactory(HandlerLifecycleManagerFactory.class);
        return elmf.createHandlerLifecycleManager();
    }

    private MessageContext isProtocolMismatch(MessageContext request, MessageContext response) {
        Protocol requestProtocol = request.getMessage().getProtocol();
        Protocol responseProtocol = response.getMessage().getProtocol();
        boolean protocolMismatch = false;
        String msg = null;
        if (requestProtocol.equals(Protocol.soap11)) {
            if (!responseProtocol.equals(Protocol.soap11)) {
                protocolMismatch = true;
                msg = "Request SOAP message protocol is version 1.1, but Response SOAP message is configured for SOAP 1.2.  This is not supported.";
            }
        } else if (requestProtocol.equals(Protocol.soap12)) {
            if (!responseProtocol.equals(Protocol.soap12)) {
                protocolMismatch = true;
                msg = "Request SOAP message protocol is version 1.2, but Response SOAP message is configured for SOAP 1.1.  This is not supported.";
            }
        }
        MessageContext msgContext = null;
        if (protocolMismatch) {
            msgContext = Utils.createFaultMessage(response, msg);
        }
        return msgContext;
    }

}