<commit_before>/*
// $Id$
// This software is subject to the terms of the Common Public License
// Agreement, available at the following URL:
// http://www.opensource.org/licenses/cpl.html.
// Copyright (C) 2005-2005 <NAME>
// All Rights Reserved.
// You must accept the terms of that agreement to use this software.
*/
package mondrian.xmla.impl;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.util.Map;
import java.util.List;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import mondrian.xmla.SaxWriter;
import mondrian.xmla.XmlaRequest;
import mondrian.xmla.XmlaResponse;
import mondrian.xmla.XmlaServlet;
import mondrian.xmla.XmlaUtil;
import mondrian.olap.Util;
import mondrian.xmla.XmlaRequestCallback;
import mondrian.xmla.XmlaException;
 
import org.apache.log4j.Logger;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Element;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

/**
 * Default implementation of XML/A servlet.
 *
 * @author <NAME>
 */
public class DefaultXmlaServlet extends XmlaServlet {

    private static final Logger LOGGER = Logger.getLogger(DefaultXmlaServlet.class);
    protected static final String nl = Util.nl;

    private DocumentBuilderFactory domFactory = null;

    public void init(ServletConfig servletConfig) throws ServletException {
        super.init(servletConfig);
        domFactory = getDocumentBuilderFactory();
    }

    protected DocumentBuilderFactory getDocumentBuilderFactory() {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setIgnoringComments(true);
        factory.setIgnoringElementContentWhitespace(true);
        factory.setNamespaceAware(true);
        return factory;
    }

    protected void unmarshallSoapMessage(
            HttpServletRequest request,
            Element[] requestSoapParts) 
            throws XmlaException {

        try {
            InputStream inputStream = null;
            try {
                inputStream = request.getInputStream();
            } catch (IllegalStateException ex) {
                throw new XmlaException(
                    SERVER_FAULT_FC,
                    USM_REQUEST_STATE_CODE, 
                    USM_REQUEST_STATE_FAULT_FS,
                    ex);
            } catch (IOException ex) {
                // This is either Client or Server
                throw new XmlaException(
                    SERVER_FAULT_FC,
                    USM_REQUEST_INPUT_CODE,
                    USM_REQUEST_INPUT_FAULT_FS,
                    ex);
            }

            DocumentBuilder domBuilder = null;
            try {
                domBuilder = domFactory.newDocumentBuilder();
            } catch (ParserConfigurationException ex) {
                throw new XmlaException(
                    SERVER_FAULT_FC,
                    USM_DOM_FACTORY_CODE,
                    USM_DOM_FACTORY_FAULT_FS,
                    ex);
            }

            Document soapDoc = null;
            try {
                soapDoc = domBuilder.parse(new InputSource(inputStream));
            } catch (IOException ex) {
                // This is either Client or Server
                throw new XmlaException(
                    SERVER_FAULT_FC,
                    USM_DOM_PARSE_IO_CODE,
                    USM_DOM_PARSE_IO_FAULT_FS,
                    ex);
            } catch (SAXException ex) {
                // Assume client passed bad xml
                throw new XmlaException(
                    CLIENT_FAULT_FC,
                    USM_DOM_PARSE_CODE,
                    USM_DOM_PARSE_FAULT_FS,
                    ex);
            }

            /* Check SOAP message */
            Element envElem = soapDoc.getDocumentElement();

            if (LOGGER.isDebugEnabled()) {
                StringBuffer buf = new StringBuffer(100);
                buf.append("XML/A request content").append(nl);
                buf.append(XmlaUtil.element2Text(envElem));
                LOGGER.debug(buf.toString());
            }

            if ("Envelope".equals(envElem.getLocalName())) {
                if (!(NS_SOAP_ENV_1_1.equals(envElem.getNamespaceURI()))) {
                    String msg = "Invalid SOAP message: " +
                        "Envelope element not in SOAP namespace";
                    throw new XmlaException(
                        CLIENT_FAULT_FC,
                        USM_DOM_PARSE_CODE,
                        USM_DOM_PARSE_FAULT_FS,
                        new SAXException(msg));
                }
            } else {
                String msg = "Invalid SOAP message: " +
                        "Top element not Envelope";
                throw new XmlaException(
                    CLIENT_FAULT_FC,
                    USM_DOM_PARSE_CODE,
                    USM_DOM_PARSE_FAULT_FS,
                    new SAXException(msg));
            }

            Element[] childs = 
                XmlaUtil.filterChildElements(envElem, NS_SOAP_ENV_1_1, "Header");
            if (childs.length > 1) {
                String msg = "Invalid SOAP message: " +
                        "More than one Header elements";
                throw new XmlaException(
                    CLIENT_FAULT_FC,
                    USM_DOM_PARSE_CODE,
                    USM_DOM_PARSE_FAULT_FS,
                    new SAXException(msg));
            }
            requestSoapParts[0] = childs.length == 1 ? childs[0] : null;

            childs = XmlaUtil.filterChildElements(envElem, NS_SOAP_ENV_1_1, "Body");
            if (childs.length != 1) {
                String msg = "Invalid SOAP message: " +
                        "Does not have one Body element";
                throw new XmlaException(
                    CLIENT_FAULT_FC,
                    USM_DOM_PARSE_CODE,
                    USM_DOM_PARSE_FAULT_FS,
                    new SAXException(msg));
            }
            requestSoapParts[1] = childs[0];

            if (LOGGER.isDebugEnabled()) {
                StringBuffer buf = new StringBuffer();
                buf.append("XML/A request content").append(nl);
                buf.append(XmlaUtil.element2Text(envElem));
                LOGGER.debug(buf.toString());
            }
        } catch (XmlaException xex) {
            throw xex;
        } catch (Exception ex) {
            throw new XmlaException(
                SERVER_FAULT_FC,
                USM_UNKNOWN_CODE,
                USM_UNKNOWN_FAULT_FS,
                ex);
        }
    }

    /** 
     * See if there is a "mustUnderstand" header element.
     * If there is a BeginSession element, then generate a session id and
     * add to context Map.
     * <p>
     * Excel 2000 and Excel XP generate both a BeginSession, Session and
     * EndSession mustUnderstand==1<commit_msg>MONDRIAN        Remove redundant debug comment.<commit_after>/*
// $Id$
// This software is subject to the terms of the Common Public License
// Agreement, available at the following URL:
// http://www.opensource.org/licenses/cpl.html.
// Copyright (C) 2005-2005 <NAME>
// All Rights Reserved.
// You must accept the terms of that agreement to use this software.
*/
package mondrian.xmla.impl;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.util.Map;
import java.util.List;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import mondrian.xmla.SaxWriter;
import mondrian.xmla.XmlaRequest;
import mondrian.xmla.XmlaResponse;
import mondrian.xmla.XmlaServlet;
import mondrian.xmla.XmlaUtil;
import mondrian.olap.Util;
import mondrian.xmla.XmlaRequestCallback;
import mondrian.xmla.XmlaException;
 
import org.apache.log4j.Logger;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Element;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

/**
 * Default implementation of XML/A servlet.
 *
 * @author <NAME>
 */
public class DefaultXmlaServlet extends XmlaServlet {

    private static final Logger LOGGER = Logger.getLogger(DefaultXmlaServlet.class);
    protected static final String nl = Util.nl;

    private DocumentBuilderFactory domFactory = null;

    public void init(ServletConfig servletConfig) throws ServletException {
        super.init(servletConfig);
        domFactory = getDocumentBuilderFactory();
    }

    protected DocumentBuilderFactory getDocumentBuilderFactory() {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setIgnoringComments(true);
        factory.setIgnoringElementContentWhitespace(true);
        factory.setNamespaceAware(true);
        return factory;
    }

    protected void unmarshallSoapMessage(
            HttpServletRequest request,
            Element[] requestSoapParts) 
            throws XmlaException {

        try {
            InputStream inputStream = null;
            try {
                inputStream = request.getInputStream();
            } catch (IllegalStateException ex) {
                throw new XmlaException(
                    SERVER_FAULT_FC,
                    USM_REQUEST_STATE_CODE, 
                    USM_REQUEST_STATE_FAULT_FS,
                    ex);
            } catch (IOException ex) {
                // This is either Client or Server
                throw new XmlaException(
                    SERVER_FAULT_FC,
                    USM_REQUEST_INPUT_CODE,
                    USM_REQUEST_INPUT_FAULT_FS,
                    ex);
            }

            DocumentBuilder domBuilder = null;
            try {
                domBuilder = domFactory.newDocumentBuilder();
            } catch (ParserConfigurationException ex) {
                throw new XmlaException(
                    SERVER_FAULT_FC,
                    USM_DOM_FACTORY_CODE,
                    USM_DOM_FACTORY_FAULT_FS,
                    ex);
            }

            Document soapDoc = null;
            try {
                soapDoc = domBuilder.parse(new InputSource(inputStream));
            } catch (IOException ex) {
                // This is either Client or Server
                throw new XmlaException(
                    SERVER_FAULT_FC,
                    USM_DOM_PARSE_IO_CODE,
                    USM_DOM_PARSE_IO_FAULT_FS,
                    ex);
            } catch (SAXException ex) {
                // Assume client passed bad xml
                throw new XmlaException(
                    CLIENT_FAULT_FC,
                    USM_DOM_PARSE_CODE,
                    USM_DOM_PARSE_FAULT_FS,
                    ex);
            }

            /* Check SOAP message */
            Element envElem = soapDoc.getDocumentElement();

            if (LOGGER.isDebugEnabled()) {
                StringBuffer buf = new StringBuffer(100);
                buf.append("XML/A request content").append(nl);
                buf.append(XmlaUtil.element2Text(envElem));
                LOGGER.debug(buf.toString());
            }

            if ("Envelope".equals(envElem.getLocalName())) {
                if (!(NS_SOAP_ENV_1_1.equals(envElem.getNamespaceURI()))) {
                    String msg = "Invalid SOAP message: " +
                        "Envelope element not in SOAP namespace";
                    throw new XmlaException(
                        CLIENT_FAULT_FC,
                        USM_DOM_PARSE_CODE,
                        USM_DOM_PARSE_FAULT_FS,
                        new SAXException(msg));
                }
            } else {
                String msg = "Invalid SOAP message: " +
                        "Top element not Envelope";
                throw new XmlaException(
                    CLIENT_FAULT_FC,
                    USM_DOM_PARSE_CODE,
                    USM_DOM_PARSE_FAULT_FS,
                    new SAXException(msg));
            }

            Element[] childs = 
                XmlaUtil.filterChildElements(envElem, NS_SOAP_ENV_1_1, "Header");
            if (childs.length > 1) {
                String msg = "Invalid SOAP message: " +
                        "More than one Header elements";
                throw new XmlaException(
                    CLIENT_FAULT_FC,
                    USM_DOM_PARSE_CODE,
                    USM_DOM_PARSE_FAULT_FS,
                    new SAXException(msg));
            }
            requestSoapParts[0] = childs.length == 1 ? childs[0] : null;

            childs = XmlaUtil.filterChildElements(envElem, NS_SOAP_ENV_1_1, "Body");
            if (childs.length != 1) {
                String msg = "Invalid SOAP message: " +
                        "Does not have one Body element";
                throw new XmlaException(
                    CLIENT_FAULT_FC,
                    USM_DOM_PARSE_CODE,
                    USM_DOM_PARSE_FAULT_FS,
                    new SAXException(msg));
            }
            requestSoapParts[1] = childs[0];

        } catch (XmlaException xex) {
            throw xex;
        } catch (Exception ex) {
            throw new XmlaException(
                SERVER_FAULT_FC,
                USM_UNKNOWN_CODE,
                USM_UNKNOWN_FAULT_FS,
                ex);
        }
    }

    /** 
     * See if there is a "mustUnderstand" header element.
     * If there is a BeginSession element, then generate a session id and
     * add to context Map.
     * <p>
     * Excel 2000 and Excel XP generate both a BeginSession, Session and
     * EndSession mustUnderstand==1
{'fraction_non_alphanumeric': 0.07559248161263961, 'fraction_numerical': 0.004971397439389812, 'mean_word_length': 1.7598195827851908, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 28}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '524853', 'n_tokens_mistral': 4048, 'n_tokens_neox': 3807, 'n_words': 866}