Package org.apache.axis2.transport

Source Code of org.apache.axis2.transport.TransportUtils

/*
* 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.transport;

import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMException;
import org.apache.axiom.om.OMOutputFormat;
import org.apache.axiom.om.impl.builder.StAXBuilder;
import org.apache.axiom.soap.SOAP11Constants;
import org.apache.axiom.soap.SOAP12Constants;
import org.apache.axiom.soap.SOAPEnvelope;
import org.apache.axiom.soap.SOAPFactory;
import org.apache.axiom.soap.impl.llom.soap11.SOAP11Factory;
import org.apache.axis2.AxisFault;
import org.apache.axis2.Constants;
import org.apache.axis2.builder.Builder;
import org.apache.axis2.builder.BuilderUtil;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.description.Parameter;
import org.apache.axis2.i18n.Messages;
import org.apache.axis2.transport.http.ApplicationXMLFormatter;
import org.apache.axis2.transport.http.HTTPConstants;
import org.apache.axis2.transport.http.SOAPMessageFormatter;
import org.apache.axis2.util.JavaUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.stream.XMLStreamException;
import java.io.InputStream;
import java.io.OutputStream;

public class TransportUtils {

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

    public static SOAPEnvelope createSOAPMessage(MessageContext msgContext) throws AxisFault {
        try {
            InputStream inStream = (InputStream) msgContext
                    .getProperty(MessageContext.TRANSPORT_IN);
            msgContext.setProperty(MessageContext.TRANSPORT_IN, null);

            // this inputstram is set by the TransportSender represents a two
            // way transport or a Transport Recevier
            if (inStream == null) {
                throw new AxisFault(Messages.getMessage("inputstreamNull"));
            }

            String contentType = (String) msgContext
                    .getProperty(Constants.Configuration.CONTENT_TYPE);

            // get the type of char encoding
            String charSetEnc = (String) msgContext
                    .getProperty(Constants.Configuration.CHARACTER_SET_ENCODING);
            if (charSetEnc == null && contentType != null) {
                charSetEnc = BuilderUtil.getCharSetEncoding(contentType);
            } else if (charSetEnc == null) {
                charSetEnc = MessageContext.DEFAULT_CHAR_SET_ENCODING;
            }
            msgContext.setProperty(Constants.Configuration.CHARACTER_SET_ENCODING, charSetEnc);

            return createSOAPMessage(msgContext, inStream, contentType);
        } catch (AxisFault e) {
            throw e;
        } catch (OMException e) {
            throw new AxisFault(e);
        } catch (XMLStreamException e) {
            throw new AxisFault(e);
        } catch (FactoryConfigurationError e) {
            throw new AxisFault(e);
        }
    }

    /**
     * Objective of this method is to capture the SOAPEnvelope creation logic
     * and make it a common for all the transports and to in/out flows.
     *
     * @param msgContext
     * @param inStream
     * @param contentType
     * @return the SOAPEnvelope
     * @throws AxisFault
     * @throws OMException
     * @throws XMLStreamException
     * @throws FactoryConfigurationError
     */
    public static SOAPEnvelope createSOAPMessage(MessageContext msgContext, InputStream inStream,
                                                 String contentType)
            throws AxisFault, OMException, XMLStreamException,
            FactoryConfigurationError {
        OMElement documentElement = null;
        String charsetEncoding = null;
        if (contentType != null) {
            String type;
            int index = contentType.indexOf(';');
            if (index > 0) {
                type = contentType.substring(0, index);
            } else {
                type = contentType;
            }
            // Some services send REST responces as text/xml. We should convert it to
            // application/xml if its a REST response, if not it will try to use the SOAPMessageBuilder.        
            if (HTTPConstants.MEDIA_TYPE_TEXT_XML.equals(type)) {
                if (msgContext.isServerSide()) {
                    if (msgContext.getSoapAction() == null) {
                        type = HTTPConstants.MEDIA_TYPE_APPLICATION_XML;
                    }
                } else if (msgContext.isDoingREST() && !JavaUtils.isTrueExplicitly(
                        msgContext.getProperty(Constants.Configuration.SOAP_RESPONSE_MEP))) {
                    type = HTTPConstants.MEDIA_TYPE_APPLICATION_XML;
                }
            }
            Builder builder = BuilderUtil.getBuilderFromSelector(type, msgContext);
            if (builder != null) {
                documentElement = builder.processDocument(inStream, contentType, msgContext);
            }
        }
        if (documentElement == null) {
            if (msgContext.isDoingREST()) {
                StAXBuilder builder = BuilderUtil.getPOXBuilder(inStream, charsetEncoding);
                documentElement = builder.getDocumentElement();
            } else {
                // FIXME making soap defualt for the moment..might effect the
                // performance
                String charSetEnc = (String) msgContext
                        .getProperty(Constants.Configuration.CHARACTER_SET_ENCODING);
                StAXBuilder builder = BuilderUtil.getSOAPBuilder(inStream, charSetEnc);
                documentElement = builder.getDocumentElement();
                charsetEncoding = builder.getDocument().getCharsetEncoding();
            }
        }

        SOAPEnvelope envelope;
        // Check whether we have received a SOAPEnvelope or not
        if (documentElement instanceof SOAPEnvelope) {
            envelope = (SOAPEnvelope) documentElement;
        } else {
            // If it is not a SOAPEnvelope we wrap that with a fake
            // SOAPEnvelope.
            SOAPFactory soapFactory = new SOAP11Factory();
            envelope = soapFactory.getDefaultEnvelope();
            envelope.getBody().addChild(documentElement);
        }
        return envelope;
    }

    /**
     * Extracts and returns the character set encoding from the
     * Content-type header
     * Example:
     * Content-Type: text/xml; charset=utf-8
     *
     * @param contentType
     */
    public static String getCharSetEncoding(String contentType) {
        int index = contentType.indexOf(HTTPConstants.CHAR_SET_ENCODING);

        if (index == -1) {    // Charset encoding not found in the content-type header
            // Using the default UTF-8
            return MessageContext.DEFAULT_CHAR_SET_ENCODING;
        }

        // If there are spaces around the '=' sign
        int indexOfEq = contentType.indexOf("=", index);

        // There can be situations where "charset" is not the last parameter of the Content-Type header
        int indexOfSemiColon = contentType.indexOf(";", indexOfEq);
        String value;

        if (indexOfSemiColon > 0) {
            value = (contentType.substring(indexOfEq + 1, indexOfSemiColon));
        } else {
            value = (contentType.substring(indexOfEq + 1, contentType.length())).trim();
        }

        // There might be "" around the value - if so remove them
        if (value.indexOf('\"') != -1) {
            value = value.replaceAll("\"", "");
        }

        return value.trim();
    }

    public static void writeMessage(MessageContext msgContext, OutputStream out) throws AxisFault {
        SOAPEnvelope envelope = msgContext.getEnvelope();
        OMElement outputMessage = envelope;

        if ((envelope != null) && msgContext.isDoingREST()) {
            outputMessage = envelope.getBody().getFirstElement();
        }

        if (outputMessage != null) {
            try {
                OMOutputFormat format = new OMOutputFormat();

                // Pick the char set encoding from the msgContext
                String charSetEnc =
                        (String) msgContext
                                .getProperty(Constants.Configuration.CHARACTER_SET_ENCODING);

                format.setDoOptimize(false);
                format.setDoingSWA(false);
                format.setCharSetEncoding(charSetEnc);
                outputMessage.serializeAndConsume(out, format);
                out.flush();
            } catch (Exception e) {
                throw new AxisFault(e);
            }
        } else {
            throw new AxisFault(Messages.getMessage("outMessageNull"));
        }
    }

    /**
     * Initial work for a builder selector which selects the builder for a given message format based on the the content type of the recieved message.
     * content-type to builder mapping can be specified through the Axis2.xml.
     *
     * @param msgContext
     * @return the builder registered against the given content-type
     * @throws AxisFault
     */
    public static MessageFormatter getMessageFormatter(MessageContext msgContext)
            throws AxisFault {
        MessageFormatter messageFormatter = null;
        String messageFormatString = getMessageFormatterProperty(msgContext);
        if (messageFormatString != null) {
            messageFormatter = msgContext.getConfigurationContext()
                    .getAxisConfiguration().getMessageFormatter(messageFormatString);

        }
        if (messageFormatter == null) {

            // If we are doing rest better default to Application/xml formatter
            if (msgContext.isDoingREST()) {
                messageFormatter = new ApplicationXMLFormatter();
            } else {
                // Lets default to SOAP formatter
                //TODO need to improve this to use the stateless nature
                messageFormatter = new SOAPMessageFormatter();
            }
        }
        return messageFormatter;
    }


    /**
     * @param contentType          The contentType of the incoming message.  It may be null
     * @param defaultSOAPNamespace Usually set the version that is expected.  This a fallback if the contentType is unavailable or
     *                             does not match our expectations
     * @return null or the soap namespace.  A null indicates that the message will be interpretted as a non-SOAP (i.e. REST) message
     */
    private static String getSOAPNamespaceFromContentType(String contentType,
                                                          String defaultSOAPNamespace) {

        String returnNS = defaultSOAPNamespace;
        // Discriminate using the content Type
        if (contentType != null) {

            /*
            * SOAP11 content-type is "text/xml"
            * SOAP12 content-type is "application/soap+xml"
            *
            * What about other content-types?
            *
            * TODO: I'm not fully convinced this method is complete, given the media types
            * listed in HTTPConstants.  Should we assume all application/* is SOAP12?
            * Should we assume all text/* is SOAP11?
            *
            * So, we'll follow this pattern:
            * 1)  find the content-type main setting
            * 2)  if (1) not understood, find the "type=" param
            * Thilina: I merged (1) & (2)
            */

            if (JavaUtils.indexOfIgnoreCase(contentType, SOAP12Constants.SOAP_12_CONTENT_TYPE) > -1)
            {
                returnNS = SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI;
            }
            // search for "type=text/xml"
            else
            if (JavaUtils.indexOfIgnoreCase(contentType, SOAP11Constants.SOAP_11_CONTENT_TYPE) > -1)
            {
                returnNS = SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI;
            }
        }

        if (returnNS == null) {
            if (log.isDebugEnabled()) {
                log.debug("No content-type or \"type=\" parameter was found in the content-type " +
                        "header and no default was specified, thus defaulting to SOAP 1.1.");
            }
            returnNS = SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI;
        }

        if (log.isDebugEnabled()) {
            log.debug("content-type: " + contentType);
            log.debug("defaultSOAPNamespace: " + defaultSOAPNamespace);
            log.debug("Returned namespace: " + returnNS);
        }
        return returnNS;

    }

    public static void processContentTypeForAction(String contentType, MessageContext msgContext) {
        //Check for action header and set it in as soapAction in MessageContext
        int index = contentType.indexOf("action");
        if (index > -1) {
            String transientString = contentType.substring(index, contentType.length());
            int equal = transientString.indexOf("=");
            int firstSemiColon = transientString.indexOf(";");
            String soapAction; // This will contain "" in the string
            if (firstSemiColon > -1) {
                soapAction = transientString.substring(equal + 1, firstSemiColon);
            } else {
                soapAction = transientString.substring(equal + 1, transientString.length());
            }
            if ((soapAction != null) && soapAction.startsWith("\"")
                    && soapAction.endsWith("\"")) {
                soapAction = soapAction
                        .substring(1, soapAction.length() - 1);
            }
            msgContext.setSoapAction(soapAction);
        }
    }


    private static String getMessageFormatterProperty(MessageContext msgContext) {
        String messageFormatterProperty = null;
        Object property = msgContext
                .getProperty(Constants.Configuration.MESSAGE_TYPE);
        if (property != null) {
            messageFormatterProperty = (String) property;
        }
        if (messageFormatterProperty == null) {
            Parameter parameter = msgContext
                    .getParameter(Constants.Configuration.MESSAGE_TYPE);
            if (parameter != null) {
                messageFormatterProperty = (String) parameter.getValue();
            }
        }
        return messageFormatterProperty;
    }
}
TOP

Related Classes of org.apache.axis2.transport.TransportUtils

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.