servicedescriptionimpl.java

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

JAVA
1,278
字号
/*
 * 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 static org.apache.axis2.jaxws.description.builder.MDQConstants.RETURN_TYPE_FUTURE;
import static org.apache.axis2.jaxws.description.builder.MDQConstants.RETURN_TYPE_RESPONSE;

import org.apache.axis2.client.ServiceClient;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.description.AxisService;
import org.apache.axis2.jaxws.ClientConfigurationFactory;
import org.apache.axis2.jaxws.ExceptionFactory;
import org.apache.axis2.jaxws.description.DescriptionFactory;
import org.apache.axis2.jaxws.description.EndpointDescription;
import org.apache.axis2.jaxws.description.EndpointInterfaceDescription;
import org.apache.axis2.jaxws.description.ServiceDescription;
import org.apache.axis2.jaxws.description.ServiceDescriptionJava;
import org.apache.axis2.jaxws.description.ServiceDescriptionWSDL;
import org.apache.axis2.jaxws.description.ServiceRuntimeDescription;
import org.apache.axis2.jaxws.description.builder.DescriptionBuilderComposite;
import org.apache.axis2.jaxws.description.builder.MDQConstants;
import org.apache.axis2.jaxws.description.builder.MethodDescriptionComposite;
import org.apache.axis2.jaxws.description.builder.ParameterDescriptionComposite;
import org.apache.axis2.jaxws.description.xml.handler.HandlerChainsType;
import org.apache.axis2.jaxws.i18n.Messages;
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;

import javax.jws.HandlerChain;
import javax.wsdl.Definition;
import javax.wsdl.Port;
import javax.wsdl.PortType;
import javax.wsdl.Service;
import javax.wsdl.WSDLException;
import javax.wsdl.extensions.ExtensibilityElement;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.Unmarshaller;
import javax.xml.namespace.QName;
import javax.xml.ws.soap.SOAPBinding;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.ConnectException;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;


/** @see ../ServiceDescription */
class ServiceDescriptionImpl
        implements ServiceDescription, ServiceDescriptionWSDL, ServiceDescriptionJava {
    private ClientConfigurationFactory clientConfigFactory;
    private ConfigurationContext configContext;

    private URL wsdlURL;
    private QName serviceQName;

    // Only ONE of the following will be set in a ServiceDescription, depending on whether this Description
    // was created from a service-requester or service-provider flow. 
    private Class serviceClass;         // A service-requester generated service or generic service class

    // TODO: Possibly remove Definition and delegate to the Defn on the AxisSerivce set as a paramater by WSDLtoAxisServicBuilder?
    private WSDLWrapper wsdlWrapper;
    private WSDLWrapper generatedWsdlWrapper;
    
    //ANNOTATION: @HandlerChain
    private HandlerChain handlerChainAnnotation;
    private HandlerChainsType handlerChainsType;

    private Map<QName, EndpointDescription> endpointDescriptions =
            new HashMap<QName, EndpointDescription>();

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

    private HashMap<String, DescriptionBuilderComposite> dbcMap = null;

    private DescriptionBuilderComposite composite = null;
    private boolean isServerSide = false;

//  RUNTIME INFORMATION
    Map<String, ServiceRuntimeDescription> runtimeDescMap =
            Collections.synchronizedMap(new HashMap<String, ServiceRuntimeDescription>());


    /**
     * This is (currently) the client-side-only constructor Construct a service description hierachy
     * based on WSDL (may be null), the Service class, and a service QName.
     *
     * @param wsdlURL      The WSDL file (this may be null).
     * @param serviceQName The name of the service in the WSDL.  This can not be null since a
     *                     javax.xml.ws.Service can not be created with a null service QName.
     * @param serviceClass The JAX-WS service class.  This could be an instance of
     *                     javax.xml.ws.Service or a generated service subclass thereof.  This will
     *                     not be null.
     */
    ServiceDescriptionImpl(URL wsdlURL, QName serviceQName, Class serviceClass) {
        if (serviceQName == null) {
            throw ExceptionFactory.makeWebServiceException(Messages.getMessage("serviceDescErr0"));
        }
        if (serviceClass == null) {
            throw ExceptionFactory
                    .makeWebServiceException(Messages.getMessage("serviceDescErr1", "null"));
        }
        if (!javax.xml.ws.Service.class.isAssignableFrom(serviceClass)) {
            throw ExceptionFactory.makeWebServiceException(
                    Messages.getMessage("serviceDescErr1", serviceClass.getName()));
        }

        // TODO: On the client side, we should not support partial WSDL; i.e. if the WSDL is specified it must be
        //       complete and must contain the ServiceQName.  This is how the Sun RI behaves on the client.
        //       When this is fixed, the check in ServiceDelegate(URL, QName, Class) should be removed
        this.wsdlURL = wsdlURL;
        // TODO: The serviceQName needs to be verified between the argument/WSDL/Annotation
        this.serviceQName = serviceQName;
        this.serviceClass = serviceClass;

        setupWsdlDefinition();
    }

    /**
     * This is (currently) the service-provider-side-only constructor. Create a service Description
     * based on a service implementation class
     *
     * @param serviceImplClass
     */
    ServiceDescriptionImpl(Class serviceImplClass, AxisService axisService) {
        isServerSide = true;
        // Create the EndpointDescription hierachy from the service impl annotations; Since the PortQName is null, 
        // it will be set to the annotation value.
        EndpointDescriptionImpl endpointDescription =
                new EndpointDescriptionImpl(serviceImplClass, null, axisService, this);
        addEndpointDescription(endpointDescription);

        // TODO: The ServiceQName instance variable should be set based on annotation or default
    }

    /**
     * This is (currently) the service-provider-side-only constructor. Create a service Description
     * based on a service implementation class
     *
     * @param serviceImplClass
     */
    ServiceDescriptionImpl(
            HashMap<String, DescriptionBuilderComposite> dbcMap,
            DescriptionBuilderComposite composite) {
        this.composite = composite;

        String serviceImplName = this.composite.getClassName();

        this.dbcMap = dbcMap;
        //TODO: How to we get this when called from server side, create here for now
        //REVIEW: The value being set here is used later in validation checking to
        //        validation that should occur separately on server and client. If
        //        at some point this constructor is ever called by the client side,
        //        then we'll have to get smarter about how we determine server/client
        //        validation
        this.isServerSide = true;

        //capture the WSDL, if there is any...to be used for later processing
        setupWsdlDefinition();

        // Do a first pass validation for this DescriptionBuilderComposite.
        // This is not intended to be a full integrity check, but rather a fail-fast mechanism
        // TODO: Refactor this to a seperate validator class?
        validateDBCLIntegrity();

        // The ServiceQName instance variable is set based on annotation or default
        // It will be set by the EndpointDescriptionImpl since it is the one that knows
        // how to process the annotations and the defaults.
        //TODO: When we get this, need to consider verifying service name between WSDL
        //      and annotations, so

        // Create the EndpointDescription hierachy from the service impl annotations; Since the PortQName is null, 
        // it will be set to the annotation value.
        //EndpointDescription endpointDescription = new EndpointDescription(null, this, serviceImplName);
        EndpointDescriptionImpl endpointDescription =
                new EndpointDescriptionImpl(this, serviceImplName);
        addEndpointDescription(endpointDescription);
    }

    /*=======================================================================*/
    /*=======================================================================*/
    // START of public accessor methods

    /**
     * Update or create an EndpointDescription. Updates to existing EndpointDescriptons will be
     * based on the SEI class and its annotations.  Both declared ports and dynamic ports can be
     * updated.  A declared port is one that is defined (e.g. in WSDL or via annotations); a dyamic
     * port is one that is not defined (e.g. not via WSDL or annotations) and has been added via
     * Serivce.addPort.
     * <p/>
     * Notes on how an EndpointDescription can be updated or created: 1) Service.createDispatch can
     * create a Dispatch client for either a declared or dynamic port 2) Note that creating a
     * Dispatch does not associate an SEI with an endpoint 3) Service.getPort will associate an SEI
     * with a port 4) A getPort on an endpoint which was originally created for a Distpatch will
     * update that EndpointDescription with the SEI provided on the getPort 5) Service.getPort can
     * not be called on a dynamic port (per the JAX-WS spec) 6) Service.addPort can not be called
     * for a declared port
     *
     * @param sei        This will be non-null if the update is of type GET_PORT; it will be null if
     *                   the update is ADD_PORT or CREATE_DISPATCH
     * @param portQName
     * @param updateType Indicates what is causing the update GET_PORT is an attempt to get a
     *                   declared SEI-based port ADD_PORT is an attempt to add a previously
     *                   non-existent dynamic port CREATE_DISPATCH is an attempt to create a
     *                   Dispatch-based client to either a declared port or a pre-existing dynamic
     *                   port.
     */

    EndpointDescription updateEndpointDescription(Class sei, QName portQName,
                                                  DescriptionFactory.UpdateType updateType) {

        EndpointDescriptionImpl endpointDescription = getEndpointDescriptionImpl(portQName);
        boolean isPortDeclared = isPortDeclared(portQName);

        switch (updateType) {

            case ADD_PORT:
                // Port must NOT be declared (e.g. can not already exist in WSDL)
                // If an EndpointDesc doesn't exist; create it as long as it doesn't exist in the WSDL
                // TODO: This test can be simplified once isPortDeclared(QName) understands annotations and WSDL as ways to declare a port.
                if (DescriptionUtils.isEmpty(portQName)) {
                    throw ExceptionFactory
                            .makeWebServiceException(Messages.getMessage("addPortErr2"));
                }
                if (getWSDLWrapper() != null && isPortDeclared) {
                    // TODO: RAS & NLS
                    throw ExceptionFactory.makeWebServiceException(
                            Messages.getMessage("addPortDup", portQName.toString()));
                } else if (endpointDescription == null) {

⌨️ 快捷键说明

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