addressinginhandler.java

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

JAVA
426
字号
/*
 * 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.handlers.addressing;

import org.apache.axiom.om.OMAttribute;
import org.apache.axiom.soap.SOAP12Constants;
import org.apache.axiom.soap.SOAPHeader;
import org.apache.axiom.soap.SOAPHeaderBlock;
import org.apache.axis2.AxisFault;
import org.apache.axis2.addressing.AddressingConstants;
import org.apache.axis2.addressing.AddressingFaultsHelper;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.addressing.EndpointReferenceHelper;
import org.apache.axis2.addressing.RelatesTo;
import org.apache.axis2.client.Options;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.handlers.AbstractHandler;
import org.apache.axis2.util.LoggingControl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

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

public abstract class AddressingInHandler extends AbstractHandler implements AddressingConstants {

    protected String addressingNamespace = Final.WSA_NAMESPACE;  // defaulting to final version
    protected String addressingVersion = null;
    private static final Log log = LogFactory.getLog(AddressingInHandler.class);


    public InvocationResponse invoke(MessageContext msgContext) throws AxisFault {
        // if another handler has already processed the addressing headers, do not do anything here.
        if (msgContext.isPropertyTrue(IS_ADDR_INFO_ALREADY_PROCESSED)) {
            if (LoggingControl.debugLoggingAllowed && log.isDebugEnabled()) {
                log.debug(
                        "Another handler has processed the addressing headers. Nothing to do here.");
            }
            return InvocationResponse.CONTINUE;
        }

        // check whether someone has explicitly set which addressing handler should run.
        String namespace = (String)msgContext.getProperty(WS_ADDRESSING_VERSION);
        if (namespace == null) {
            namespace = addressingNamespace;
        } else if (!namespace.equals(addressingNamespace)) {
            if (LoggingControl.debugLoggingAllowed && log.isDebugEnabled()) {
                log.debug("This addressing handler does not match the specified namespace, " +
                        namespace);
            }

            return InvocationResponse.CONTINUE;
        }

        SOAPHeader header = msgContext.getEnvelope().getHeader();

        // if there are not headers put a flag to disable addressing temporary
        if (header == null) {
            msgContext.setProperty(DISABLE_ADDRESSING_FOR_OUT_MESSAGES, Boolean.TRUE);
            return InvocationResponse.CONTINUE;
        }

        if (LoggingControl.debugLoggingAllowed && log.isDebugEnabled()) {
            log.debug("Starting " + addressingVersion + " IN handler ...");
        }


        ArrayList addressingHeaders;
        addressingHeaders = header.getHeaderBlocksWithNSURI(namespace);
        if (addressingHeaders != null && addressingHeaders.size() > 0) {
            msgContext.setProperty(WS_ADDRESSING_VERSION, namespace);
            msgContext.setProperty(DISABLE_ADDRESSING_FOR_OUT_MESSAGES, Boolean.FALSE);

            if (LoggingControl.debugLoggingAllowed && log.isDebugEnabled()) {
                log.debug(addressingVersion +
                        " Headers present in the SOAP message. Starting to process ...");
            }

            extractAddressingInformation(header, msgContext, addressingHeaders, namespace);
            msgContext.setProperty(IS_ADDR_INFO_ALREADY_PROCESSED, Boolean.TRUE);
        } else {
            msgContext.setProperty(DISABLE_ADDRESSING_FOR_OUT_MESSAGES, Boolean.TRUE);
            if (LoggingControl.debugLoggingAllowed && log.isDebugEnabled()) {
                log.debug("No Headers present corresponding to " + addressingVersion);
            }
        }

        return InvocationResponse.CONTINUE;
    }

    protected Options extractAddressingInformation(SOAPHeader header, MessageContext messageContext,
                                                   ArrayList addressingHeaders, String namespace)
            throws AxisFault {

        Options messageContextOptions = messageContext.getOptions();

        ArrayList checkedHeaderNames = new ArrayList(7); // Up to 7 header names to be recorded
        ArrayList duplicateHeaderNames =
                new ArrayList(1); // Normally will not be used for more than 1 header

        // Per the SOAP Binding spec "headers with an incorrect cardinality MUST NOT be used" So
        // these variables are used to keep track of invalid cardinality headers so they are not
        // deserialised.
        boolean ignoreTo = false, ignoreFrom = false, ignoreReplyTo = false, ignoreFaultTo =
                false, ignoreMessageID = false, ignoreAction = false;

        // First pass just check for duplicates
        Iterator addressingHeadersIt = addressingHeaders.iterator();
        while (addressingHeadersIt.hasNext()) {
            SOAPHeaderBlock soapHeaderBlock = (SOAPHeaderBlock)addressingHeadersIt.next();
            // TODO - Don't do role processing here!
            if (!SOAP12Constants.SOAP_ROLE_NONE.equals(soapHeaderBlock.getRole())) {
                if (WSA_ACTION.equals(soapHeaderBlock.getLocalName())) {
                    ignoreAction = checkDuplicateHeaders(WSA_ACTION, checkedHeaderNames,
                                                         duplicateHeaderNames);
                } else if (WSA_TO.equals(soapHeaderBlock.getLocalName())) {
                    ignoreTo =
                            checkDuplicateHeaders(WSA_TO, checkedHeaderNames, duplicateHeaderNames);
                } else if (WSA_MESSAGE_ID.equals(soapHeaderBlock.getLocalName())) {
                    ignoreMessageID = checkDuplicateHeaders(WSA_MESSAGE_ID, checkedHeaderNames,
                                                            duplicateHeaderNames);
                } else if (WSA_REPLY_TO.equals(soapHeaderBlock.getLocalName())) {
                    ignoreReplyTo = checkDuplicateHeaders(WSA_REPLY_TO, checkedHeaderNames,
                                                          duplicateHeaderNames);
                } else if (WSA_FAULT_TO.equals(soapHeaderBlock.getLocalName())) {
                    ignoreFaultTo = checkDuplicateHeaders(WSA_FAULT_TO, checkedHeaderNames,
                                                          duplicateHeaderNames);
                } else if (WSA_FROM.equals(soapHeaderBlock.getLocalName())) {
                    ignoreFrom = checkDuplicateHeaders(WSA_FROM, checkedHeaderNames,
                                                       duplicateHeaderNames);
                }
            }
        }

        // Now extract information
        Iterator addressingHeadersIt2 = addressingHeaders.iterator();
        while (addressingHeadersIt2.hasNext()) {
            SOAPHeaderBlock soapHeaderBlock = (SOAPHeaderBlock)addressingHeadersIt2.next();
            if (!SOAP12Constants.SOAP_ROLE_NONE.equals(soapHeaderBlock.getRole())) {
                if (WSA_ACTION.equals(soapHeaderBlock.getLocalName()) && !ignoreAction) {
                    extractActionInformation(soapHeaderBlock, messageContext);
                } else if (WSA_TO.equals(soapHeaderBlock.getLocalName()) && !ignoreTo) {
                    extractToEPRInformation(soapHeaderBlock, messageContextOptions, header,
                                            namespace);
                } else
                if (WSA_MESSAGE_ID.equals(soapHeaderBlock.getLocalName()) && !ignoreMessageID) {
                    extractMessageIDInformation(soapHeaderBlock, messageContext);
                } else if (WSA_REPLY_TO.equals(soapHeaderBlock.getLocalName()) && !ignoreReplyTo) {
                    extractReplyToEPRInformation(soapHeaderBlock, namespace, messageContext);
                } else if (WSA_FAULT_TO.equals(soapHeaderBlock.getLocalName()) && !ignoreFaultTo) {
                    extractFaultToEPRInformation(soapHeaderBlock, namespace, messageContext);
                } else if (WSA_RELATES_TO.equals(soapHeaderBlock.getLocalName())) {
                    extractRelatesToInformation(soapHeaderBlock, messageContextOptions);
                } else if (WSA_FROM.equals(soapHeaderBlock.getLocalName()) && !ignoreFrom) {
                    extractFromEPRInformation(soapHeaderBlock, namespace, messageContext);
                }
            }
        }

        // Now that all the valid wsa headers have been read, throw an exception if there was an invalid cardinality
        // This means that if for example there are multiple MessageIDs and a FaultTo, the FaultTo will be respected.
        if (!duplicateHeaderNames.isEmpty()) {
            // Simply choose the first problem header we came across as we can only fault for one of them.
            AddressingFaultsHelper.triggerInvalidCardinalityFault(messageContext,
                                                                  (String)duplicateHeaderNames
                                                                          .get(0));
        }

        // check for the presence of madatory addressing headers
        checkForMandatoryHeaders(checkedHeaderNames, messageContext);

        // provide default values for headers that have not been found.
        setDefaults(checkedHeaderNames, messageContext);

        return messageContextOptions;
    }

    protected abstract void checkForMandatoryHeaders(ArrayList alreadyFoundAddrHeader,
                                                     MessageContext messageContext)
            throws AxisFault;

    protected abstract void setDefaults(ArrayList alreadyFoundAddrHeader,
                                        MessageContext messageContext) throws AxisFault;

    private boolean checkDuplicateHeaders(String addressingHeaderName, ArrayList checkedHeaderNames,
                                          ArrayList duplicateHeaderNames) {//throws AxisFault {
        // If the header name has been seen before then we should return true and add it to the list
        // of duplicate header names. Otherwise it is the first time we've seen the header so add it
        // to the checked liat and return false.
        boolean shouldIgnore = checkedHeaderNames.contains(addressingHeaderName);
        if (shouldIgnore) {
            duplicateHeaderNames.add(addressingHeaderName);
        } else {
            checkedHeaderNames.add(addressingHeaderName);
        }

⌨️ 快捷键说明

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