xmlpartbase.java

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

JAVA
679
字号
/*
 * 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.message.impl;

import org.apache.axiom.om.OMElement;
import org.apache.axiom.soap.SOAP11Constants;
import org.apache.axiom.soap.SOAP12Constants;
import org.apache.axis2.jaxws.ExceptionFactory;
import org.apache.axis2.jaxws.i18n.Messages;
import org.apache.axis2.jaxws.message.Block;
import org.apache.axis2.jaxws.message.Message;
import org.apache.axis2.jaxws.message.Protocol;
import org.apache.axis2.jaxws.message.XMLFault;
import org.apache.axis2.jaxws.message.XMLPart;
import org.apache.axis2.jaxws.message.factory.BlockFactory;
import org.apache.axis2.jaxws.message.util.XMLFaultUtils;
import org.apache.axis2.jaxws.utility.JavaUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.jws.soap.SOAPBinding.Style;
import javax.xml.namespace.QName;
import javax.xml.soap.Name;
import javax.xml.soap.Node;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;
import javax.xml.ws.WebServiceException;
import java.util.Iterator;

/**
 * XMLPartBase class for an XMLPart An XMLPart is an abstraction of the xml portion of the message.
 * The actual representation can be in one of three different forms: * An OM tree * A SAAJ
 * SOAPEnvelope * An XMLSpine (an optimized representation of the message) The representation is
 * stored in the private variable (content)
 * <p/>
 * The representation changes as the Message flows through the JAX-WS framework.  For example, here
 * is a typical flow on the inbound case: a) Message is built from OM
 * (representation: OM) b) Message flows into SOAP Handler chain              (representation:
 * OM->SOAPEnvelope) c) Message flows out of the SOAP Handler chain d) Message flows into the
 * logical dispatch processing (representation: SOAPEnvelope->XMLSpine)
 * <p/>
 * The key to performance is the implementation of the transformations between OM, SAAJ SOAPEnvelope
 * and XMLSpine.   This base class defines all of the methods that are required on an XMLPart, the
 * actual transformations are provided by the derived class.  This division of work allows the
 * derived class to concentrate on the optimization of the transformations.  For example, the
 * derived class may implement XMLSpine -> OM using OMObjectWrapperElement constructs...thus avoid
 * expensive parsing.
 * <p/>
 * Here are the methods that the derived XMLPart should implement. OMElement
 * _convertSE2OM(SOAPEnvelope se) OMElement _convertSpine2OM(XMLSpine spine) SOAPEnvelope
 * _convertOM2SE(OMElement om) SOAPEnvelope _convertSpine2SE(XMLSpine spine) XMLSpine
 * _convertOM2Spine(OMElement om) XMLSpine _convertSE2Spine(SOAPEnvelope se) XMLSpine
 * _createSpine(Protocol protocol)
 * <p/>
 * NOTE: For XML/HTTP (REST), a SOAP 1.1. Envelope is built and the rest payload is placed in the
 * body.  This purposely mimics the Axis2 implementation.
 *
 * @see org.apache.axis2.jaxws.message.XMLPart
 * @see XMLPartImpl
 */
public abstract class XMLPartBase implements XMLPart {

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

    Protocol protocol = Protocol.unknown;  // Protocol defaults to unknown
    Style style = Style.DOCUMENT;          // Style defaults to document
    int indirection = 0;                   // Default indirection for Document

    // The actual xml representation is always one of the following
    //   OM if the content is an OM tree
    //   SOAPENVELOPE if the content is a SOAPEnvelope
    //   SPINE if the content is a OM "spine" + Blocks
    Object content = null;
    int contentType = UNKNOWN;

    static final int UNKNOWN = 0;
    static final int OM = 1;
    static final int SOAPENVELOPE = 2;
    static final int SPINE = 3;

    boolean consumed = false;

    Message parent;


    /**
     * XMLPart should be constructed via the XMLPartFactory. This constructor constructs an empty
     * XMLPart with the specified protocol
     *
     * @param protocol
     * @throws WebServiceException
     */
    XMLPartBase(Protocol protocol) throws WebServiceException {
        super();
        if (protocol.equals(Protocol.unknown)) {
            throw ExceptionFactory
                    .makeWebServiceException(Messages.getMessage("ProtocolIsNotKnown"));
        }
        content = _createSpine(protocol, getStyle(), getIndirection(), null);
        this.protocol = ((XMLSpine)content).getProtocol();
        contentType = SPINE;
    }

    /**
     * XMLPart should be constructed via the XMLPartFactory. This constructor creates an XMLPart from
     * the specified root.
     *
     * @param root
     * @param protocol (if null, the soap protocol is inferred from the namespace)
     * @throws WebServiceException
     */
    XMLPartBase(OMElement root, Protocol protocol) throws WebServiceException {
        content = root;
        contentType = OM;
        QName qName = root.getQName();
        if (protocol == null) {
            if (qName.getNamespaceURI().equals(SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI)) {
                this.protocol = Protocol.soap11;
            } else
            if (qName.getNamespaceURI().equals(SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI)) {
                this.protocol = Protocol.soap12;
            }
        } else if (protocol == Protocol.rest) {
            this.protocol = Protocol.rest;
            // Axis2 stores XML/HTTP messages inside a soap11 envelope.  We will mimic this behavior
            if (qName.getNamespaceURI().equals(SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI)) {
                // Okay
            } else
            if (qName.getNamespaceURI().equals(SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI)) {
                throw ExceptionFactory.makeWebServiceException("UNEXPECTED");  // TODO NLS
            } else {
                content = _createSpine(Protocol.rest, Style.DOCUMENT, 0, root);
                contentType = SPINE;
            }
        } else {
            this.protocol = protocol;
        }
    }

    /**
     * XMLPart should be constructed via the XMLPartFactory. This constructor creates an XMLPart from
     * the specified root.
     *
     * @param root
     * @throws WebServiceException
     */
    XMLPartBase(SOAPEnvelope root) throws WebServiceException {
        content = root;
        contentType = SOAPENVELOPE;
        String ns = root.getNamespaceURI();
        if (ns.equals(SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI)) {
            protocol = Protocol.soap11;
        } else if (ns.equals(SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI)) {
            protocol = Protocol.soap12;
        } else {
            throw ExceptionFactory
                    .makeWebServiceException(Messages.getMessage("RESTIsNotSupported"));
        }
    }

    private void setContent(Object content, int contentType) {
        this.content = content;
        this.contentType = contentType;
    }

    private OMElement getContentAsOMElement() throws WebServiceException {

        OMElement om = null;
        switch (contentType) {
            case (OM):
                om = (OMElement)content;
                break;
            case (SPINE):
                om = _convertSpine2OM((XMLSpine)content);
                break;
            case (SOAPENVELOPE):
                om = _convertSE2OM((SOAPEnvelope)content);
                break;
            default:
                throw ExceptionFactory
                        .makeWebServiceException(Messages.getMessage("XMLPartImplErr2"));
        }
        setContent(om, OM);
        return om;
    }

    private SOAPEnvelope getContentAsSOAPEnvelope() throws WebServiceException {
        SOAPEnvelope se = null;
        switch (contentType) {
            case (SOAPENVELOPE):
                se = (SOAPEnvelope)content;
                break;
            case (SPINE):
                se = _convertSpine2SE((XMLSpine)content);
                break;
            case (OM):
                se = _convertOM2SE((OMElement)content);
                break;
            default:
                throw ExceptionFactory
                        .makeWebServiceException(Messages.getMessage("XMLPartImplErr2"));
        }
        setContent(se, SOAPENVELOPE);
        return se;
    }

    private XMLSpine getContentAsXMLSpine() throws WebServiceException {
        XMLSpine spine = null;
        switch (contentType) {
            case (SPINE):
                spine = (XMLSpine)content;
                break;
            case (SOAPENVELOPE):
                spine = _convertSE2Spine((SOAPEnvelope)content);
                break;
            case (OM):
                spine = _convertOM2Spine((OMElement)content);
                break;
            default:
                throw ExceptionFactory
                        .makeWebServiceException(Messages.getMessage("XMLPartImplErr2"));
        }
        spine.setParent(getParent());
        setContent(spine, SPINE);
        return spine;
    }

    /* (non-Javadoc)
      * @see org.apache.axis2.jaxws.message.XMLPart#getAsOMElement()
      */
    public OMElement getAsOMElement() throws WebServiceException {
        return getContentAsOMElement();
    }

    /* (non-Javadoc)
      * @see org.apache.axis2.jaxws.message.XMLPart#getAsSOAPEnvelope()
      */
    public SOAPEnvelope getAsSOAPEnvelope() throws WebServiceException {
        return getContentAsSOAPEnvelope();
    }

    /* (non-Javadoc)
      * @see org.apache.axis2.jaxws.message.XMLPart#getProtocol()
      */
    public Protocol getProtocol() {
        return protocol;
    }

    /* (non-Javadoc)
      * @see org.apache.axis2.jaxws.message.XMLPart#getStyle()
      */
    public Style getStyle() {
        return style;
    }

    /* (non-Javadoc)
    * @see org.apache.axis2.jaxws.message.XMLPart#getIndirection()
    */
    public int getIndirection() {
        return indirection;
    }


    /* (non-Javadoc)
    * @see org.apache.axis2.jaxws.message.XMLPart#setStyle(javax.jws.soap.SOAPBinding.Style)
    */
    public void setStyle(Style style) throws WebServiceException {
        if (this.style != style) {
            if (contentType == SPINE) {
                // Must switch to something other than XMLSpine
                getContentAsOMElement();
            }
        }
        this.style = style;
        if (style == Style.RPC) {
            setIndirection(1);
        } else {
            setIndirection(0);
        }
    }

    public void setIndirection(int indirection) {
        if (this.indirection != indirection) {
            if (contentType == SPINE) {
                // Must switch to something other than XMLSpine
                getContentAsOMElement();
            }
        }
        this.indirection = indirection;
    }

    public QName getOperationElement() throws WebServiceException {
        try {
            if (style != Style.RPC) {
                return null;
            }
            switch (contentType) {
                case OM:
                    return ((org.apache.axiom.soap.SOAPEnvelope)content).getBody().
                            getFirstElement().getQName();
                case SPINE:
                    return ((XMLSpine)content).getOperationElement();
                case SOAPENVELOPE:
                    Iterator it = ((SOAPEnvelope)content).getBody().getChildElements();
                    while (it.hasNext()) {
                        Node node = (Node)it.next();
                        if (node instanceof SOAPElement) {
                            Name name = ((SOAPElement)node).getElementName();
                            return new QName(name.getURI(), name.getLocalName(), name.getPrefix());
                        }
                    }
            }
            return null;
        } catch (SOAPException se) {
            throw ExceptionFactory.makeWebServiceException(se);
        }
    }

    public void setOperationElement(QName operationQName) throws WebServiceException {
        if (indirection == 1) {

⌨️ 快捷键说明

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