package com.nec.webotx.webservice.sample;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.StringTokenizer;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.MimeHeader;
import javax.xml.soap.MimeHeaders;
import javax.xml.soap.SOAPConnection;
import javax.xml.soap.SOAPConnectionFactory;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;

public abstract class SAAJServlet extends HttpServlet {

	protected SOAPConnection conn = null;
	protected MessageFactory msgFactory = null;

	public void init(ServletConfig servletConfig) throws ServletException {
		super.init(servletConfig);
		try {
			msgFactory = MessageFactory.newInstance();
			SOAPConnectionFactory connFactory =
				SOAPConnectionFactory.newInstance();
			conn = connFactory.createConnection();
		} catch (SOAPException ex) {
			throw new ServletException(
				"Unable to create message factory" + ex.getMessage());
		}
	}

	public void setMessageFactory(MessageFactory msgFactory) {
		this.msgFactory = msgFactory;
	}

	protected static MimeHeaders getHeaders(HttpServletRequest req) {
		Enumeration enum = req.getHeaderNames();
		MimeHeaders headers = new MimeHeaders();

		while (enum.hasMoreElements()) {
			String headerName = (String) enum.nextElement();
			String headerValue = req.getHeader(headerName);

			StringTokenizer values = new StringTokenizer(headerValue, ",");

			while (values.hasMoreTokens()) {
				headers.addHeader(headerName, values.nextToken().trim());
			}
		}

		return headers;
	}

	protected static void putHeaders(
		MimeHeaders headers,
		HttpServletResponse res) {
		Iterator it = headers.getAllHeaders();

		while (it.hasNext()) {
			MimeHeader header = (MimeHeader) it.next();

			String[] values = headers.getHeader(header.getName());

			if (values.length == 1) {
				res.setHeader(header.getName(), header.getValue());
			} else {
				StringBuffer concat = new StringBuffer();
				int i = 0;

				while (i < values.length) {
					if (i != 0) {
						concat.append(',');
					}
					concat.append(values[i++]);
				}
				res.setHeader(header.getName(), concat.toString());
			}
		}
	}

	public void doPost(HttpServletRequest req, HttpServletResponse resp)
		throws ServletException, IOException {
		try {
			MimeHeaders headers = getHeaders(req);

			InputStream is = req.getInputStream();

			SOAPMessage msg = msgFactory.createMessage(headers, is);

			SOAPMessage reply = null;

			reply = onMessage(msg);

			if (reply != null) {

				if (reply.saveRequired()) {
					reply.saveChanges();
				}

				resp.setStatus(HttpServletResponse.SC_OK);

				putHeaders(reply.getMimeHeaders(), resp);

				OutputStream os = resp.getOutputStream();

				reply.writeTo(os);

				os.flush();

			} else {
				resp.setStatus(HttpServletResponse.SC_NO_CONTENT);
			}
		} catch (Exception ex) {
			throw new ServletException("SAAJ POST failed " + ex.getMessage());
		}
	}

	public abstract SOAPMessage onMessage(SOAPMessage message)
		throws Exception;
}
