axisoperation.java

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

JAVA
590
字号
/*
 * 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.description;

import org.apache.axiom.om.util.UUIDGenerator;
import org.apache.axis2.AxisFault;
import org.apache.axis2.client.OperationClient;
import org.apache.axis2.client.Options;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.context.OperationContext;
import org.apache.axis2.context.ServiceContext;
import org.apache.axis2.engine.AxisConfiguration;
import org.apache.axis2.engine.AxisError;
import org.apache.axis2.engine.MessageReceiver;
import org.apache.axis2.i18n.Messages;
import org.apache.axis2.modules.Module;
import org.apache.axis2.phaseresolver.PhaseResolver;
import org.apache.axis2.wsdl.WSDLConstants;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.xml.namespace.QName;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;

public abstract class AxisOperation extends AxisDescription
        implements WSDLConstants {

    public static final String STYLE_RPC = "rpc";
    public static final String STYLE_MSG = "msg";
    public static final String STYLE_DOC = "doc";

    private static final Log log = LogFactory.getLog(AxisOperation.class);
    /**
     * message exchange pattern
     */
    private int mep = WSDLConstants.MEP_CONSTANT_INVALID;

    // to hide control operation , operation which added by RM like module
    private boolean controlOperation = false;
    private String style = STYLE_DOC;

    // to store mepURL
    private String mepURI;

    private MessageReceiver messageReceiver;

    private HashMap moduleConfigmap;

    // To store deploy-time module refs
    private ArrayList modulerefs;

    private ArrayList faultMessages;

    private QName name;

    private ArrayList wsamappingList;
    private String outputAction;
    private HashMap faultActions = new HashMap();

    private String soapAction;


    /**
     * constructor
     */
    public AxisOperation() {
        mepURI = WSDL2Constants.MEP_URI_IN_OUT;
        modulerefs = new ArrayList();
        moduleConfigmap = new HashMap();
        faultMessages = new ArrayList();
        //setup a temporary name
        QName tmpName = new QName(this.getClass().getName() + "_" + UUIDGenerator.getUUID());
        this.setName(tmpName);
    }

    public AxisOperation(QName name) {
        this();
        this.setName(name);
    }

    public abstract void addMessage(AxisMessage message, String label);

    /**
     * Adds a message context into an operation context. Depending on MEPs, this
     * method has to be overridden.
     * Depending on the MEP operation description know how to fill the message context map
     * in operationContext.
     * As an example, if the MEP is IN-OUT then depending on messagable operation description
     * should know how to keep them in correct locations.
     *
     * @param msgContext <code>MessageContext</code>
     * @param opContext  <code>OperationContext</code>
     * @throws AxisFault <code>AxisFault</code>
     */
    public abstract void addMessageContext(MessageContext msgContext, OperationContext opContext)
            throws AxisFault;

    public abstract void addFaultMessageContext(MessageContext msgContext,
                                                OperationContext opContext)
            throws AxisFault;

    public void addModule(String moduleName) {
        modulerefs.add(moduleName);
    }

    /**
     * Adds module configuration, if there is moduleConfig tag in operation.
     *
     * @param moduleConfiguration
     */
    public void addModuleConfig(ModuleConfiguration moduleConfiguration) {
        moduleConfigmap.put(moduleConfiguration.getModuleName(), moduleConfiguration);
    }

    /**
     * This is called when a module is engaged on this operation.  Handle operation-specific
     * tasks.
     *
     * @param axisModule AxisModule
     * @param engager
     * @throws AxisFault
     */
    public final void onEngage(AxisModule axisModule, AxisDescription engager) throws AxisFault {
        // Am I the source of this engagement?
        boolean selfEngaged = (engager == this);

        // If I'm not, the operations will already have been added by someone above, so don't
        // do it again.
        if (selfEngaged) {
            AxisService service = getAxisService();
            if (service != null) {
                service.addModuleOperations(axisModule);
            }
        }
        AxisConfiguration axisConfig = getAxisConfiguration();
        PhaseResolver phaseResolver = new PhaseResolver(axisConfig);
        phaseResolver.engageModuleToOperation(this, axisModule);
    }

    protected void onDisengage(AxisModule module) {
        AxisService service = getAxisService();
        if (service == null) return;

        AxisConfiguration axisConfiguration = service.getAxisConfiguration();
        PhaseResolver phaseResolver = new PhaseResolver(axisConfiguration);
        if (!service.isEngaged(module.getName()) &&
                (axisConfiguration != null && !axisConfiguration.isEngaged(module.getName()))) {
            phaseResolver.disengageModuleFromGlobalChains(module);
        }
        phaseResolver.disengageModuleFromOperationChain(module, this);

        //removing operations added at the time of module engagemnt
        HashMap moduleOperations = module.getOperations();
        if (moduleOperations != null) {
            Iterator moduleOperations_itr = moduleOperations.values().iterator();
            while (moduleOperations_itr.hasNext()) {
                AxisOperation operation = (AxisOperation) moduleOperations_itr.next();
                service.removeOperation(operation.getName());
            }
        }
    }

    /**
     * To remove module from engage  module list
     *
     * @param module module to remove
     * @deprecated please use disengageModule(), this method will disappear after 1.3
     */
    public void removeFromEngagedModuleList(AxisModule module) {
        try {
            disengageModule(module);
        } catch (AxisFault axisFault) {
            // Can't do much here...
            log.error(axisFault.getMessage(), axisFault);
        }
    }

    /**
     * Gets a copy from module operation.
     *
     * @param axisOperation
     * @return Returns AxisOperation.
     * @throws AxisFault
     */
    private AxisOperation copyOperation(AxisOperation axisOperation) throws AxisFault {
        AxisOperation operation =
                AxisOperationFactory
                        .getOperationDescription(axisOperation.getMessageExchangePattern());

        operation.setMessageReceiver(axisOperation.getMessageReceiver());
        operation.setName(axisOperation.getName());

        Iterator parameters = axisOperation.getParameters().iterator();

        while (parameters.hasNext()) {
            Parameter parameter = (Parameter) parameters.next();

            operation.addParameter(parameter);
        }

        operation.setWsamappingList(axisOperation.getWSAMappingList());
        operation.setOutputAction(axisOperation.getOutputAction());
        String[] faultActionNames = axisOperation.getFaultActionNames();
        for (int i = 0; i < faultActionNames.length; i++) {
            operation.addFaultAction(faultActionNames[i],
                                     axisOperation.getFaultAction(faultActionNames[i]));
        }
        operation.setRemainingPhasesInFlow(axisOperation.getRemainingPhasesInFlow());
        operation.setPhasesInFaultFlow(axisOperation.getPhasesInFaultFlow());
        operation.setPhasesOutFaultFlow(axisOperation.getPhasesOutFaultFlow());
        operation.setPhasesOutFlow(axisOperation.getPhasesOutFlow());

        return operation;
    }


    /**
     * Returns as existing OperationContext related to this message if one exists.
     *
     * @param msgContext
     * @return Returns OperationContext.
     * @throws AxisFault
     */
    public OperationContext findForExistingOperationContext(MessageContext msgContext)
            throws AxisFault {
        OperationContext operationContext;

        if ((operationContext = msgContext.getOperationContext()) != null) {
            return operationContext;
        }

        // If this message is not related to another one, or it is but not one emitted
        // from the same operation, don't further look for an operation context or fault.
        if (null != msgContext.getRelatesTo()) {
            // So this message may be part of an ongoing MEP
            ConfigurationContext configContext = msgContext.getConfigurationContext();

            operationContext =
                    configContext.getOperationContext(msgContext.getRelatesTo().getValue());

            if (null == operationContext && log.isDebugEnabled()) {
                log.debug(msgContext.getLogIDString() +
                        " Cannot correlate inbound message RelatesTo value [" +
                        msgContext.getRelatesTo() + "] to in-progree MEP");
            }
        }

        return operationContext;
    }

    /**
     * Finds a MEPContext for an incoming message. An incoming message can be
     * of two states.
     * <p/>
     * 1)This is a new incoming message of a given MEP. 2)This message is a
     * part of an MEP which has already begun.
     * <p/>
     * The method is special cased for the two MEPs
     * <p/>
     * #IN_ONLY #IN_OUT
     * <p/>
     * for two reasons. First reason is the wide usage and the second being that
     * the need for the MEPContext to be saved for further incoming messages.
     * <p/>
     * In the event that MEP of this operation is different from the two MEPs
     * defaulted above the decision of creating a new or this message relates
     * to a MEP which already in business is decided by looking at the WSA
     * Relates TO of the incoming message.
     *
     * @param msgContext
     */
    public OperationContext findOperationContext(MessageContext msgContext,
                                                 ServiceContext serviceContext)
            throws AxisFault {

⌨️ 快捷键说明

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