endpointdescriptionimpl.java

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

JAVA
1,359
字号
/*
 * 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.description.impl;

import java.io.InputStream;
import java.security.PrivilegedAction;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeSet;

import javax.jws.HandlerChain;
import javax.jws.WebService;
import javax.wsdl.Binding;
import javax.wsdl.Definition;
import javax.wsdl.Port;
import javax.wsdl.extensions.ExtensibilityElement;
import javax.wsdl.extensions.http.HTTPBinding;
import javax.wsdl.extensions.soap.SOAPAddress;
import javax.wsdl.extensions.soap12.SOAP12Address;
import javax.wsdl.extensions.soap12.SOAP12Binding;
import javax.xml.namespace.QName;
import javax.xml.ws.BindingType;
import javax.xml.ws.Service;
import javax.xml.ws.ServiceMode;
import javax.xml.ws.WebServiceProvider;
import javax.xml.ws.handler.PortInfo;
import javax.xml.ws.soap.SOAPBinding;

import org.apache.axis2.AxisFault;
import org.apache.axis2.client.ServiceClient;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.deployment.DeploymentException;
import org.apache.axis2.description.AxisService;
import org.apache.axis2.description.OutInAxisOperation;
import org.apache.axis2.description.OutOnlyAxisOperation;
import org.apache.axis2.description.Parameter;
import org.apache.axis2.description.WSDL11ToAllAxisServicesBuilder;
import org.apache.axis2.description.WSDL11ToAxisServiceBuilder;
import org.apache.axis2.engine.AxisConfiguration;
import org.apache.axis2.java.security.AccessController;
import org.apache.axis2.jaxws.ExceptionFactory;
import org.apache.axis2.jaxws.description.EndpointDescription;
import org.apache.axis2.jaxws.description.EndpointDescriptionJava;
import org.apache.axis2.jaxws.description.EndpointDescriptionWSDL;
import org.apache.axis2.jaxws.description.EndpointInterfaceDescription;
import org.apache.axis2.jaxws.description.ServiceDescription;
import org.apache.axis2.jaxws.description.ServiceDescriptionWSDL;
import org.apache.axis2.jaxws.description.builder.DescriptionBuilderComposite;
import org.apache.axis2.jaxws.description.builder.MDQConstants;
import org.apache.axis2.jaxws.description.builder.WsdlComposite;
import org.apache.axis2.jaxws.description.xml.handler.HandlerChainsType;
import org.apache.axis2.jaxws.i18n.Messages;
import org.apache.axis2.jaxws.util.ClassLoaderUtils;
import org.apache.axis2.jaxws.util.WSDL4JWrapper;
import org.apache.axis2.jaxws.util.WSDLWrapper;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/** @see ../EndpointDescription */
/*
 * TODO: EndpointDescription should be created via AxisService objects and not directly from WSDL
 * IMPORTANT NOTE: Axis2 currently only supports 1 service and 1 port under that service.  When that is
 * fixed, that will probably have an impact on this class.  In particular, I think this should be created 
 * somehow from an AxisService/AxisPort combination, and not directly from the WSDL.
 */
class EndpointDescriptionImpl
        implements EndpointDescription, EndpointDescriptionJava, EndpointDescriptionWSDL {

    private ServiceDescriptionImpl parentServiceDescription;
    private AxisService axisService;

    private QName portQName;
    private QName serviceQName;

    // Corresponds to a port that was added dynamically via addPort and is not declared (either in WSDL or annotations)
    private boolean isDynamicPort;

    // If the WSDL is fully specified, we could build the AxisService from the WSDL
    private boolean isAxisServiceBuiltFromWSDL;

    private String serviceImplName;    //class name of the service impl or SEI

    // Note that an EndpointInterfaceDescription will ONLY be set for an Endpoint-based implementation;
    // it will NOT be set for a Provider-based implementation
    private EndpointInterfaceDescription endpointInterfaceDescription;

    // This can be an SEI (on the client or server) or a Service implentation (server only)
    // Note that for clients that are Dispatch, this will be null.  Also note that a client that was initially
    // dispatch (sei = null) could later do a getPort(sei), at which time the original EndpointDescription will be
    // updated with the SEI information.
    private Class implOrSEIClass;

    //On Client side, there should be One ServiceClient instance per AxisSerivce
    private ServiceClient serviceClient = null;

    //This is the base WebService or WebServiceProvider that we are processing
    DescriptionBuilderComposite composite = null;

    // Set of packages that are needed to marshal/unmashal data (used to set JAXBContext)
    TreeSet<String> packages = null;

    // The JAX-WS Handler port information corresponding to this endpoint
    private PortInfo portInfo;

    private String clientBindingID;
    // The effective endpoint address.  It could be set by the client or come from the WSDL SOAP address
    private String endpointAddress;
    // The endpoint address from the WSDL soap:address extensibility element if present.
    private String wsdlSOAPAddress;

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

    // ===========================================
    // ANNOTATION related information
    // ===========================================

    // ANNOTATION: @WebService and @WebServiceProvider
    // Only one of these two annotations will be set; they are mutually exclusive
    private WebService webServiceAnnotation;
    private WebServiceProvider webServiceProviderAnnotation;

    //ANNOTATION: @HandlerChain
    private HandlerChain handlerChainAnnotation;
    private HandlerChainsType handlerChainsType;

    // Information common to both WebService and WebServiceProvider annotations
    private String annotation_WsdlLocation;
    private String annotation_ServiceName;
    private String annotation_PortName;
    private String annotation_TargetNamespace;

    // Information only set on WebService annotation
    // ANNOTATION: @WebService
    private String webService_EndpointInterface;
    private String webService_Name;

    // ANNOTATION: @ServiceMode
    // Note this is only valid on a Provider-based endpoint
    private ServiceMode serviceModeAnnotation;
    private Service.Mode serviceModeValue;
    // Default ServiceMode.value per JAXWS Spec 7.1 "javax.xml.ServiceMode" pg 79
    public static final javax.xml.ws.Service.Mode ServiceMode_DEFAULT =
            javax.xml.ws.Service.Mode.PAYLOAD;

    // ANNOTATION: @BindingType
    private BindingType bindingTypeAnnotation;
    private String bindingTypeValue;
    // Default BindingType.value per JAXWS Spec Sec 7.8 "javax.xml.ws.BindingType" pg 83 
    // and Sec 1.4 "SOAP Transport and Transfer Bindings" pg 119
    public static final String BindingType_DEFAULT =
            javax.xml.ws.soap.SOAPBinding.SOAP11HTTP_BINDING;

    /**
     * Create an EndpointDescription based on the WSDL port.  Note that per the JAX-WS Spec (Final
     * Release, 4/19/2006 Section 4.2.3 Proxies, page 55)the "namespace component of the port is the
     * target namespace of the WSDL definition document". Note this is currently only used on the
     * client-side (this may change).
     *
     * @param theClass The SEI or Impl class.  This will be NULL for Dispatch clients since they
     *                 don't use an SEI
     */
    EndpointDescriptionImpl(Class theClass, QName portName, ServiceDescriptionImpl parent) {
        this(theClass, portName, false, parent);
    }

    EndpointDescriptionImpl(Class theClass, QName portName, boolean dynamicPort,
                            ServiceDescriptionImpl parent) {
        // TODO: This and the other constructor will (eventually) take the same args, so the logic needs to be combined
        // TODO: If there is WSDL, could compare the namespace of the defn against the portQName.namespace
        this.parentServiceDescription = parent;
        this.implOrSEIClass = theClass;
        // REVIEW: setting these should probably be done in the getters!  It needs to be done before we try to select a 
        //         port to use if one wasn't specified because we'll try to get to the annotations to get the PortType
        if (this.implOrSEIClass != null) {
            webServiceAnnotation = (WebService)implOrSEIClass.getAnnotation(WebService.class);
            webServiceProviderAnnotation =
                    (WebServiceProvider)implOrSEIClass.getAnnotation(WebServiceProvider.class);
        }
        this.isDynamicPort = dynamicPort;
        if (DescriptionUtils.isEmpty(portName)) {
            // If the port name is null, then per JAX-WS 2.0 spec p. 55, the runtime is responsible for selecting the port.
            this.portQName = selectPortToUse();
        } else {
            this.portQName = portName;
        }
        // At this point, there must be a port QName set, either as passed in, or determined from the WSDL and/or annotations.
        // If not, that is an error.
        if (this.portQName == null) {
            if (log.isDebugEnabled()) {
                log.debug("PortQName was null and could not be determined by runtime.  Class: " +
                        theClass + "; ServiceDescription: " + parent);
            }
            throw ExceptionFactory.makeWebServiceException(
                    "EndpointDescription: portQName could not be determined for class " + theClass);
        }

        // TODO: Refactor this with the consideration of no WSDL/Generic Service/Annotated SEI
        setupAxisService();
        addToAxisService();

        buildDescriptionHierachy();
        addAnonymousAxisOperations();

        // This will set the serviceClient field after adding the AxisService to the AxisConfig
        getServiceClient();
        // Give the configuration builder a chance to finalize configuration for this service
        try {
            getServiceDescriptionImpl().getClientConfigurationFactory()
                    .completeAxis2Configuration(axisService);
        } catch (DeploymentException e) {
            // TODO RAS & NLS
            if (log.isDebugEnabled()) {
                log.debug(
                        "Caught DeploymentException attempting to complete configuration on AxisService: "
                                + axisService + " for ServiceDesription: " + parent, e);
            }
            throw ExceptionFactory.makeWebServiceException(
                    "Unable to complete configuration due to exception " + e, e);
        } catch (Exception e) {
            // TODO RAS & NLS
            if (log.isDebugEnabled()) {
                log.debug("Caught Exception attempting to complete configuration on AxisService: "
                        + axisService + " for ServiceDesription: " + parent, e);
            }
            throw ExceptionFactory.makeWebServiceException(
                    "Unable to complete configuration due to exception " + e, e);
        }
    }

    /**
     * Create an EndpointDescription based on the DescriptionBuilderComposite. Note that per the
     * JAX-WS Spec (Final Release, 4/19/2006 Section 4.2.3 Proxies, page 55)the "namespace component
     * of the port is the target namespace of the WSDL definition document".
     *
     * @param theClass The SEI or Impl class.  This will be NULL for Dispatch clients since they
     *                 don't use an SEI
     */
    EndpointDescriptionImpl(ServiceDescriptionImpl parent, String serviceImplName) {

        // TODO: This and the other constructor will (eventually) take the same args, so the logic needs to be combined
        // TODO: If there is WSDL, could compare the namespace of the defn against the portQName.namespace
        this.parentServiceDescription = parent;
        this.serviceImplName = serviceImplName;
        this.implOrSEIClass = null;

        composite = getServiceDescriptionImpl().getDescriptionBuilderComposite();
        if (composite == null) {
            throw ExceptionFactory.makeWebServiceException(
                    "EndpointDescription.EndpointDescription: parents DBC is null");
        }

        //Set the base level of annotation that we are processing...currently
        // a 'WebService' or a 'WebServiceProvider'
        if (composite.getWebServiceAnnot() != null)
            webServiceAnnotation = composite.getWebServiceAnnot();

⌨️ 快捷键说明

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