providerdispatcher.java

来自「开源的axis2框架的源码。用于开发WEBSERVER」· Java 代码 · 共 425 行 · 第 1/2 页

JAVA
425
字号
/*
 * 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.dispatcher;

import org.apache.axis2.jaxws.ExceptionFactory;
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.i18n.Messages;
import org.apache.axis2.jaxws.marshaller.impl.alt.MethodMarshallerUtils;
import org.apache.axis2.jaxws.message.Block;
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.factory.BlockFactory;
import org.apache.axis2.jaxws.message.factory.MessageFactory;
import org.apache.axis2.jaxws.message.factory.SOAPEnvelopeBlockFactory;
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.utility.ClassUtils;
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.transform.Source;
import javax.xml.ws.Provider;
import javax.xml.ws.Service;
import javax.xml.ws.soap.SOAPBinding;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.security.PrivilegedExceptionAction;

/**
 * The ProviderDispatcher is used to invoke instances of a target endpoint that implement the {@link
 * javax.xml.ws.Provider} interface.
 * <p/>
 * The Provider<T> is a generic class, with certain restrictions on the parameterized type T.  This
 * implementation supports the following types:
 * <p/>
 * java.lang.String javax.activation.DataSource javax.xml.soap.SOAPMessage
 * javax.xml.transform.Source
 */
public class ProviderDispatcher extends JavaDispatcher {

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

    private BlockFactory blockFactory = null;
    private Class providerType = null;
    private Provider providerInstance = null;
    private Service.Mode providerServiceMode = null;
    private Message message = null;
    private Protocol messageProtocol;


    /**
     * Constructor
     *
     * @param _class
     * @param serviceInstance
     */
    public ProviderDispatcher(Class _class, Object serviceInstance) {
        super(_class, serviceInstance);
    }

    /* (non-Javadoc)
    * @see org.apache.axis2.jaxws.server.EndpointDispatcher#execute()
    */
    public MessageContext invoke(final MessageContext mc) throws Exception {
        if (log.isDebugEnabled()) {
            log.debug("Preparing to invoke javax.xml.ws.Provider based endpoint");
        }

        providerInstance = getProviderInstance();

        // 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();

        // 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();
        if (message != null) {
            
            // 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)) {
                    message.setMTOMEnabled(true);
                }
            }

            // Save off the protocol info so we can use it when creating the response message.
            messageProtocol = message.getProtocol();
            // Determine what type blocks we want to create (String, Source, etc) based on Provider Type
            BlockFactory factory = createBlockFactory(providerType);


            providerServiceMode = endpointDesc.getServiceMode();

            if (providerServiceMode != null && providerServiceMode == Service.Mode.MESSAGE) {
                if (providerType.equals(SOAPMessage.class)) {
                    // We can get the SOAPMessage directly from the message itself
                    if (log.isDebugEnabled()) {
                        log.debug("Provider Type is SOAPMessage.");
                        log.debug("Number Message attachments=" + message.getAttachmentIDs().size());
                    }
                }

                requestParamValue = message.getValue(null, factory);
                if (requestParamValue == null) {
                    if (log.isDebugEnabled()) {
                        log.debug(
                                "There are no elements to unmarshal.  ProviderDispatch will pass a null as input");
                    }
                }
            } else {
                // 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);
                } else {
                    if (log.isDebugEnabled()) {
                        log.debug(
                                "No body blocks in SOAPMessage, Calling provider method with null input parameters");
                    }
                    requestParamValue = null;
                }
            }
        }

        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;
        try {
            responseParamValue = (Object)org.apache.axis2.java.security.AccessController
                    .doPrivileged(new PrivilegedExceptionAction() {
                        public Object run() throws Exception {
                            return invokeProvider(mc, providerInstance, input);
                        }
                    });
        } 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());
            }
        }

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

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?