Package org.apache.axis2.soap.impl.llom.builder

Source Code of org.apache.axis2.soap.impl.llom.builder.StAXSOAPModelBuilder

/*
* Copyright 2004,2005 The Apache Software Foundation.
*
* Licensed 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.soap.impl.llom.builder;

import org.apache.axis2.om.OMAbstractFactory;
import org.apache.axis2.om.OMDocument;
import org.apache.axis2.om.OMElement;
import org.apache.axis2.om.OMException;
import org.apache.axis2.om.OMNamespace;
import org.apache.axis2.om.OMNode;
import org.apache.axis2.om.impl.OMNodeEx;
import org.apache.axis2.om.impl.llom.builder.StAXOMBuilder;
import org.apache.axis2.soap.SOAP11Constants;
import org.apache.axis2.soap.SOAP12Constants;
import org.apache.axis2.soap.SOAPBody;
import org.apache.axis2.soap.SOAPConstants;
import org.apache.axis2.soap.SOAPEnvelope;
import org.apache.axis2.soap.SOAPFactory;
import org.apache.axis2.soap.SOAPHeader;
import org.apache.axis2.soap.SOAPMessage;
import org.apache.axis2.soap.SOAPProcessingException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.xml.stream.XMLStreamReader;

/**
* Class StAXSOAPModelBuilder
*/
public class StAXSOAPModelBuilder extends StAXOMBuilder {

    SOAPMessage soapMessage;
    /**
     * Field envelope
     */
    private SOAPEnvelope envelope;
    private OMNamespace envelopeNamespace;


    private SOAPFactory soapFactory;

    /**
     * Field headerPresent
     */
    private boolean headerPresent = false;

    /**
     * Field bodyPresent
     */
    private boolean bodyPresent = false;

    /**
     * Field log
     */
    private Log log = LogFactory.getLog(getClass());

    /**
     * element level 1 = envelope level element level 2 = Header or Body level
     * element level 3 = HeaderElement or BodyElement level
     */
    protected int elementLevel = 0;

    private boolean processingFault = false;


    //added
    /* This is used to indicate whether detail element is processing in soap 1.2 builderhelper
    */
    private boolean processingDetailElements = false;

    private SOAPBuilderHelper builderHelper;
    private String senderfaultCode;
    private String receiverfaultCode;
    private boolean processingMandatoryFaultElements;
   
    // We need to have soap factory, temporary, until we find out the correct SOAP version. If user has not provided
    // a SOAP factory, internally we are creating a default one. This flag will be set if we create one internally, to
    // warn that this should be replaced later.
    private boolean isTempSOAPFactory = true;

    /**
     * Constructor StAXSOAPModelBuilder
     * soapVersion parameter is to give the soap version from the transport. For example, in HTTP case
     * you can identify the version of the soap message u have recd by looking at the HTTP headers.
     * It is used to check whether the actual soap message contained is of that version.
     * If one is creates the builder from the transport, then can just pass null for version.
     *
     * @param parser
     * @param soapVersion   parameter is to give the soap version for the transport. 
     */
    public StAXSOAPModelBuilder(XMLStreamReader parser, String soapVersion) {
        super(parser);
        soapFactory = OMAbstractFactory.getDefaultSOAPFactory();
        isTempSOAPFactory = true;
        soapMessage = soapFactory.createSOAPMessage(this);
        this.document = soapMessage;
        if(parser.getCharacterEncodingScheme() != null) {
            document.setCharsetEncoding(parser.getCharacterEncodingScheme());
        }
        identifySOAPVersion(soapVersion);
        parseHeaders();
    }

    /**
     * @param parser
     * @param factory
     * @param soapVersion parameter is to give the soap version from the transport. For example, in
     *                    HTTP case you can identify the version of the soap message u have recd by looking at
     *                    the HTTP headers. It is used to check whether the actual soap message
     *                    contained is of that version.If one is creates the builder from the transport,
     *                    then can just pass null for version.
     */
    public StAXSOAPModelBuilder(XMLStreamReader parser, SOAPFactory factory, String soapVersion) {
        super(factory, parser);
        soapFactory = factory;
        isTempSOAPFactory = false;
        soapMessage = soapFactory.createSOAPMessage(this);
        this.document = soapMessage;
        identifySOAPVersion(soapVersion);
        parseHeaders();
    }

    private void identifySOAPVersion(String soapVersionURIFromTransport) {

        SOAPEnvelope soapEnvelope = getSOAPEnvelope();
        if (soapEnvelope == null) {
            throw new SOAPProcessingException("SOAP Message does not contain an Envelope",
                    SOAPConstants.FAULT_CODE_VERSION_MISMATCH);
        }

        envelopeNamespace = soapEnvelope.getNamespace();
        String namespaceName = envelopeNamespace.getName();
        if ((soapVersionURIFromTransport != null) && !(soapVersionURIFromTransport.equals(namespaceName))) {
            throw new SOAPProcessingException("Transport level information does not match with SOAP" +
                    " Message namespace URI", SOAPConstants.FAULT_CODE_VERSION_MISMATCH);

        }
        if(isTempSOAPFactory) {
          if (SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI.equals(namespaceName)) {
              soapFactory = OMAbstractFactory.getSOAP12Factory();
              log.info("Starting to process SOAP 1.2 message");
          } else if (SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI.equals(namespaceName)) {
              soapFactory = OMAbstractFactory.getSOAP11Factory();
              log.info("Starting to process SOAP 1.1 message");
 
          } else {
              throw new SOAPProcessingException("Only SOAP 1.1 or SOAP 1.2 messages are supported in the" +
                      " system", SOAPConstants.FAULT_CODE_VERSION_MISMATCH);
          }
        }
    }

    private void parseHeaders() {
        // by the time execution comes here the nullity of SOAPEnvelope has been cheched in the
        // identifySOAPVersion() method. So not checking getSOAPEnvelope() == null here
        SOAPHeader soapHeader = getSOAPEnvelope().getHeader();

        if (soapHeader != null) {
            while (!soapHeader.isComplete()) {
                next();
            }
        } else {
            log.info("No SOAPHeaders present !!");
        }
    }


    /**
     * Method getSOAPEnvelope.
     *
     * @return Returns SOAPEnvelope.
     * @throws OMException
     */
    public SOAPEnvelope getSOAPEnvelope() throws OMException {
        while ((envelope == null) && !done) {
            next();
        }
        return envelope;
    }

    /**
     * Method createOMElement.
     *
     * @return Returns OMNode.
     * @throws OMException
     */
    protected OMNode createOMElement() throws OMException {
        elementLevel++;
        OMElement node;
        String elementName = parser.getLocalName();
        if (lastNode == null) {
            node = constructNode(null, elementName, true);
            setSOAPEnvelope(node);
        } else if (lastNode.isComplete()) {
            node =
                    constructNode((OMElement) lastNode.getParent(),
                            elementName,
                            false);
            ((OMNodeEx) lastNode).setNextOMSibling(node);
            ((OMNodeEx) node).setPreviousOMSibling(lastNode);
        } else {
            OMElement e = (OMElement) lastNode;
            node = constructNode((OMElement) lastNode, elementName, false);
            e.setFirstChild(node);
        }


        log.debug("Build the OMElelment " + node.getLocalName() +
                "By the StaxSOAPModelBuilder");
        return node;
    }

    protected void setSOAPEnvelope(OMElement node) {
        soapMessage.setSOAPEnvelope((SOAPEnvelope) node);
        soapMessage.setXMLVersion(parser.getVersion());
        soapMessage.setCharsetEncoding(parser.getCharacterEncodingScheme());
    }

    /**
     * Method constructNode
     *
     * @param parent
     * @param elementName
     * @param isEnvelope
     */
    protected OMElement constructNode(OMElement parent, String elementName,
                                      boolean isEnvelope) {
        OMElement element = null;
        if (parent == null) {
            if (!elementName.equalsIgnoreCase(SOAPConstants.SOAPENVELOPE_LOCAL_NAME)) {
                throw new SOAPProcessingException("First Element must contain the local name, "
                        + SOAPConstants.SOAPENVELOPE_LOCAL_NAME, SOAPConstants.FAULT_CODE_VERSION_MISMATCH);
            }
            envelope = soapFactory.createSOAPEnvelope(this);
            element = envelope;
            processNamespaceData(element, true);
            // fill in the attributes
            processAttributes(element);

        } else if (elementLevel == 2) {

            // this is either a header or a body
            if (elementName.equals(SOAPConstants.HEADER_LOCAL_NAME)) {
                if (headerPresent) {
                    throw new SOAPProcessingException("Multiple headers encountered!", getSenderFaultCode());
                }
                if (bodyPresent) {
                    throw new SOAPProcessingException("Header Body wrong order!", getSenderFaultCode());
                }
                headerPresent = true;
                element =
                        soapFactory.createSOAPHeader((SOAPEnvelope) parent,
                                this);

                processNamespaceData(element, true);
                processAttributes(element);

            } else if (elementName.equals(SOAPConstants.BODY_LOCAL_NAME)) {
                if (bodyPresent) {
                    throw new SOAPProcessingException("Multiple body elements encountered", getSenderFaultCode());
                }
                bodyPresent = true;
                element =
                        soapFactory.createSOAPBody((SOAPEnvelope) parent,
                                this);

                processNamespaceData(element, true);
                processAttributes(element);

            } else {
                throw new SOAPProcessingException(elementName
                        +
                        " is not supported here. Envelope can not have elements other than Header and Body.", getSenderFaultCode());
            }
        } else if ((elementLevel == 3)
                &&
                parent.getLocalName().equalsIgnoreCase(SOAPConstants.HEADER_LOCAL_NAME)) {

            // this is a headerblock
            try {
                element =
                        soapFactory.createSOAPHeaderBlock(elementName, null,
                                (SOAPHeader) parent, this);
            } catch (SOAPProcessingException e) {
                throw new SOAPProcessingException("Can not create SOAPHeader block", getReceiverFaultCode(), e);
            }
            processNamespaceData(element, false);
            processAttributes(element);

        } else if ((elementLevel == 3) &&
                parent.getLocalName().equalsIgnoreCase(SOAPConstants.BODY_LOCAL_NAME) &&
                elementName.equalsIgnoreCase(SOAPConstants.BODY_FAULT_LOCAL_NAME)) {

            // this is a headerblock
            element = soapFactory.createSOAPFault((SOAPBody) parent, this);
            processNamespaceData(element, false);
            processAttributes(element);


            processingFault = true;
            processingMandatoryFaultElements = true;
            if (SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI.equals(envelopeNamespace.getName())) {
                builderHelper = new SOAP12BuilderHelper(this);
            } else if (SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI.equals(envelopeNamespace.getName())) {
                builderHelper = new SOAP11BuilderHelper(this);
            }

        } else if (elementLevel > 3 && processingFault) {
            element = builderHelper.handleEvent(parser, parent, elementLevel);
        } else {

            // this is neither of above. Just create an element
            element = soapFactory.createOMElement(elementName, null,
                    parent, this);
            processNamespaceData(element, false);
            processAttributes(element);

        }
        return element;
    }

    private String getSenderFaultCode() {
        if (senderfaultCode == null) {
            senderfaultCode = SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI.equals(envelopeNamespace.getName()) ? SOAP12Constants.FAULT_CODE_SENDER : SOAP11Constants.FAULT_CODE_SENDER;
        }
        return senderfaultCode;
    }

    private String getReceiverFaultCode() {
        if (receiverfaultCode == null) {
            receiverfaultCode = SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI.equals(envelopeNamespace.getName()) ? SOAP12Constants.FAULT_CODE_RECEIVER : SOAP11Constants.FAULT_CODE_RECEIVER;
        }
        return receiverfaultCode;
    }

    public void endElement() {
        if (lastNode.isComplete()) {
            OMElement parent = (OMElement) lastNode.getParent();
            ((OMNodeEx) parent).setComplete(true);
            lastNode = parent;
        } else {
            OMNode e = lastNode;
            ((OMNodeEx) e).setComplete(true);
        }
        elementLevel--;
    }

    /**
     * Method createDTD.
     * Overriding the default behaviour as a SOAPMessage should not have a DTD.
     */
    protected OMNode createDTD() throws OMException {
        throw new OMException("SOAP message MUST NOT contain a Document Type Declaration(DTD)");
    }

    /**
     * Method createPI.
     * Overriding the default behaviour as a SOAP Message should not have a PI.
     */
    protected OMNode createPI() throws OMException {
        throw new OMException("SOAP message MUST NOT contain Processing Instructions(PI)");
    }

    /**
     * Method getDocumentElement.
     *
     * @return Returns OMElement.
     */
    public OMElement getDocumentElement() {
        return getSOAPEnvelope();
    }

    /**
     * Method processNamespaceData.
     *
     * @param node
     * @param isSOAPElement
     */
    protected void processNamespaceData(OMElement node, boolean isSOAPElement) {

        super.processNamespaceData(node, isSOAPElement);

        if (isSOAPElement) {
            if (node.getNamespace() != null &&
                    !node.getNamespace().getName().equals(SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI) &&
                    !node.getNamespace().getName().equals(SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI)) {
                throw new SOAPProcessingException("invalid SOAP namespace URI. " +
                        "Only " + SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI +
                        " and " + SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI +
                        " are supported.", SOAP12Constants.FAULT_CODE_SENDER);
            }
        }

    }

/*these three methods to set and check detail element processing or mandatory fault element are present
*/

    public OMNamespace getEnvelopeNamespace() {
        return envelopeNamespace;
    }

    public void setBooleanProcessingMandatoryFaultElements(boolean value) {
        this.processingMandatoryFaultElements = value;
    }

    public boolean isProcessingDetailElements() {
        return processingDetailElements;
    }

    public void setProcessingDetailElements(boolean value) {
        processingDetailElements = value;
    }

    public SOAPMessage getSoapMessage() {
        return soapMessage;
    }

    public OMDocument getDocument() {
        return (OMDocument) this.soapMessage;
    }

  /**
   * @return Returns the soapFactory.
   */
  protected SOAPFactory getSoapFactory() {
    return soapFactory;
  }

}
TOP

Related Classes of org.apache.axis2.soap.impl.llom.builder.StAXSOAPModelBuilder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.