package com.clientsoft.webpack.util;

import java.io.IOException;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;


import javax.xml.parsers.*;

import javax.servlet.ServletException;
import javax.servlet.ServletConfig;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.w3c.dom.Node;
import org.w3c.dom.Element;
import org.w3c.dom.Document;

import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

import com.clientsoft.webpack.util.CSUtils;

import org.apache.xml.serialize.Method;
import org.apache.xml.serialize.SerializerFactory;
import org.apache.xml.serialize.XMLSerializer;
import org.apache.xml.serialize.OutputFormat;
import org.apache.xml.serialize.DOMSerializer;

public class TestServlet extends HttpServlet {

    final DocumentBuilderFactory parserFactory = DocumentBuilderFactory.newInstance();
    final SerializerFactory print_factory = SerializerFactory.getSerializerFactory(Method.XML);

    public void init(ServletConfig config) throws ServletException {
        try {
            parserFactory.setValidating(false);
        } catch(Exception e) {
            throw new ServletException( e.getMessage() ); // this is to cover up the JAXP Exception
        }
    }

    public void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
        try {
            String ct = req.getContentType();
            if(!ct.equals("text/xml")) {
                res.sendError(HttpServletResponse.SC_BAD_REQUEST);
                return;
            }

            Document in_doc = getParser().parse(req.getInputStream());
            Node echo_back = in_doc.getDocumentElement().getElementsByTagName("echo").item(0);

            Document out_doc = getParser().newDocument();
            Element newElement = out_doc.createElement("response");
            out_doc.appendChild(newElement);
            out_doc.importNode(echo_back, true);

            res.setContentType("text/xml;charset=UTF-8");
            ByteArrayOutputStream bout = getByteArrayStream(out_doc);
            res.setContentLength(bout.size());
            OutputStream out = res.getOutputStream();
            bout.writeTo(out);
            out.flush();
        } catch(ServletException e) {
            throw e;
        } catch(IOException e) {
            throw e;
        } catch(Exception e) {
            throw new ServletException(e.getMessage());
        }
    }

    final DocumentBuilder getParser() throws Exception {
        DocumentBuilder parser = null;
        parser = parserFactory.newDocumentBuilder();
        return parser;
    }

    /** Method added for convience to count content length for responce.
     * @param doc XML docuemnt to buffer
     * @throws IOException thrown if stream is closed
     * @return the serialized document as ByteArrayStream
     */
    final ByteArrayOutputStream getByteArrayStream(Document doc) throws Exception {
        ByteArrayOutputStream retval = new ByteArrayOutputStream();
         OutputFormat _format = new OutputFormat();
        _format.setPreserveSpace(true); // bug fix (\r\n are converted to HEX20 with out fix)
        _format.setIndenting(true); //pretty print
        DOMSerializer xmlWriter = print_factory.makeSerializer(retval, _format).asDOMSerializer();
        xmlWriter.serialize(doc);
       return retval;
    }
}