serviceclient.java

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

JAVA
832
字号
/*
 * 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.client;

import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.soap.SOAP12Constants;
import org.apache.axiom.soap.SOAPEnvelope;
import org.apache.axiom.soap.SOAPFactory;
import org.apache.axiom.soap.SOAPHeader;
import org.apache.axiom.soap.SOAPHeaderBlock;
import org.apache.axis2.AxisFault;
import org.apache.axis2.util.Counter;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.async.Callback;
import org.apache.axis2.client.async.AxisCallback;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.context.ConfigurationContextFactory;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.context.OperationContext;
import org.apache.axis2.context.ServiceContext;
import org.apache.axis2.context.ServiceGroupContext;
import org.apache.axis2.description.AxisModule;
import org.apache.axis2.description.AxisOperation;
import org.apache.axis2.description.AxisService;
import org.apache.axis2.description.AxisServiceGroup;
import org.apache.axis2.description.OutInAxisOperation;
import org.apache.axis2.description.OutOnlyAxisOperation;
import org.apache.axis2.description.RobustOutOnlyAxisOperation;
import org.apache.axis2.engine.AxisConfiguration;
import org.apache.axis2.engine.ListenerManager;
import org.apache.axis2.i18n.Messages;
import org.apache.axis2.wsdl.WSDLConstants;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.logging.Log;


import javax.wsdl.Definition;
import javax.xml.namespace.QName;
import java.net.URL;
import java.util.ArrayList;

/**
 * Client access to a service. Each instance of this class is associated with a
 * particular {@link org.apache.axis2.description.AxisService}, and the methods
 * support operations using that service. {@link Options} instances are used to
 * configure various aspects of the service access.
 */
public class ServiceClient {
    protected static final Log log = LogFactory.getLog(ServiceClient.class);
    
    /**
     * Base name used for a service created without an existing configuration.
     */
    public static final String ANON_SERVICE = "anonService";

    /** Counter used to generate the anonymous service name. */
    private static Counter anonServiceCounter = new Counter();


    /**
     * Operation name used for an anonymous out-only operation (meaning we send
     * a message with no response allowed from the service, equivalent to a WSDL
     * In-Only operation).
     */
    public static final QName ANON_OUT_ONLY_OP = new QName(
            "anonOutonlyOp");

    /**
     * Operation name used for an anonymous robust-out-only operation
     * (meaning we send a message, with the only possible response a fault,
     * equivalent to a WSDL Robust-In-Only operation).
     */
    public static final QName ANON_ROBUST_OUT_ONLY_OP = new QName(
            "anonRobustOp");

    /**
     * Operation name used for an anonymous in-out operation (meaning we sent a
     * message and receive a response, equivalent to a WSDL In-Out operation).
     */
    public static final QName ANON_OUT_IN_OP = new QName("anonOutInOp");

    // the meta-data of the service that this client access
    private AxisService axisService;

    // the configuration in which my meta-data lives
    private AxisConfiguration axisConfig;

    // the configuration context in which I live
    private ConfigurationContext configContext;

    // service context for this specific service instance
    private ServiceContext serviceContext;

    // client options for this service interaction
    private Options options = new Options();

    // options that must override those of the child operation client also
    private Options overrideOptions;

    // list of headers to be sent with the simple APIs
    private ArrayList headers;

    //whether we create configctx or not
    private boolean createConfigCtx;

    /**
     * Create a service client configured to work with a specific AxisService.
     * If this service is already in the world that's handed in (in the form of
     * a ConfigurationContext) then I will happily work in it. If not I will
     * create a small little virtual world and live there.
     *
     * @param configContext The configuration context under which this service lives (may
     *                      be null, in which case a new local one will be created)
     * @param axisService   The service for which this is the client (may be
     *                      <code>null</code>, in which case an anonymous service will be created)
     * @throws AxisFault if something goes wrong while creating a config context (if
     *                   needed)
     */
    public ServiceClient(ConfigurationContext configContext,
                         AxisService axisService) throws AxisFault {
        configureServiceClient(configContext, axisService);
    }

    private void configureServiceClient(ConfigurationContext configContext, AxisService axisService)
            throws AxisFault {
        if (configContext == null) {
            if (ListenerManager.defaultConfigurationContext == null) {
                configContext = ConfigurationContextFactory.
                        createConfigurationContextFromFileSystem(null, null);
                createConfigCtx = true;
            } else {
                configContext = ListenerManager.defaultConfigurationContext;
            }
        }
        this.configContext = configContext;

        // Initialize transports
        ListenerManager transportManager = configContext.getListenerManager();
        if (transportManager == null) {
            transportManager = new ListenerManager();
            transportManager.init(this.configContext);
        }

        // save the axisConfig and service
        axisConfig = configContext.getAxisConfiguration();
        if (axisService == null) {
            axisService = createAnonymousService();
        }
        this.axisService = axisService;
        if (axisConfig.getService(axisService.getName()) == null) {
            axisService.setClientSide(true);
            axisConfig.addService(axisService);
        } else {
            throw new AxisFault(Messages.getMessage(
                    "twoservicecannothavesamename",
                    axisService.getName()));
        }
        AxisServiceGroup axisServiceGroup = axisService.getAxisServiceGroup();
        ServiceGroupContext sgc = configContext.createServiceGroupContext(axisServiceGroup);
        serviceContext = sgc.getServiceContext(axisService);
    }


    /**
     * This is WSDL4J based constructor to configure the Service Client/
     * TODO: make this policy aware
     *
     * @param configContext active ConfigurationContext
     * @param wsdl4jDefinition the WSDL we're going to be using to configure ourselves
     * @param wsdlServiceName QName of the WSDL service we'd like to access
     * @param portName name of the WSDL port we'd like to access
     * @throws AxisFault in case of error
     */

    public ServiceClient(ConfigurationContext configContext, Definition wsdl4jDefinition,
                         QName wsdlServiceName, String portName) throws AxisFault {
        configureServiceClient(configContext, AxisService.createClientSideAxisService(
                wsdl4jDefinition, wsdlServiceName, portName, options));
    }

    /**
     * Create a service client for WSDL service identified by the QName of the
     * wsdl:service element in a WSDL document.
     *
     * @param configContext   The configuration context under which this service lives (may
     *                        be <code>null</code>, in which case a new local one will be created) *
     * @param wsdlURL         The URL of the WSDL document to read
     * @param wsdlServiceName The QName of the WSDL service in the WSDL document to create a
     *                        client for
     * @param portName        The name of the WSDL 1.1 port to create a client for. May be
     *                        null (if WSDL 2.0 is used or if only one port is there). .
     * @throws AxisFault if something goes wrong while creating a config context (if
     *                   needed)
     */
    public ServiceClient(ConfigurationContext configContext, URL wsdlURL,
                         QName wsdlServiceName, String portName) throws AxisFault {
        configureServiceClient(configContext, AxisService.createClientSideAxisService(wsdlURL,
                                                                                      wsdlServiceName,
                                                                                      portName,
                                                                                      options));
    }

    /**
     * Create a service client by assuming an anonymous service and any other
     * necessary information.
     *
     * @throws AxisFault in case of error
     */
    public ServiceClient() throws AxisFault {
        this(null, null);
    }

    /**
     * Create an anonymous axisService with one (anonymous) operation for each
     * MEP that we support dealing with anonymously using the convenience APIs.
     *
     * @return the minted anonymous service
     */
    private AxisService createAnonymousService() {
        // now add anonymous operations to the axis2 service for use with the
        // shortcut client API. NOTE: We only add the ones we know we'll use
        // later in the convenience API; if you use
        // this constructor then you can't expect any magic!
        AxisService axisService =
                new AxisService(ANON_SERVICE + anonServiceCounter.incrementAndGet());
        RobustOutOnlyAxisOperation robustoutoonlyOperation = new RobustOutOnlyAxisOperation(
                ANON_ROBUST_OUT_ONLY_OP);
        axisService.addOperation(robustoutoonlyOperation);

        OutOnlyAxisOperation outOnlyOperation = new OutOnlyAxisOperation(
                ANON_OUT_ONLY_OP);
        axisService.addOperation(outOnlyOperation);

        OutInAxisOperation outInOperation = new OutInAxisOperation(
                ANON_OUT_IN_OP);
        axisService.addOperation(outInOperation);
        return axisService;
    }

    /**
     * Returns the AxisConfiguration associated with the client.    
     */
    public AxisConfiguration getAxisConfiguration() {
        return axisConfig;
    }
    
    /**
     * Return the AxisService this is a client for. This is primarily useful
     * when the AxisService is created anonymously or from WSDL as otherwise the
     * user had the AxisService to start with.
     *
     * @return the axisService
     */
    public AxisService getAxisService() {
        return axisService;
    }

    /**
     * Set the basic client configuration related to this service interaction.
     *

⌨️ 快捷键说明

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