/* 
 * E-XML Library:  For XML, XML-RPC, HTTP, and related.
 * Copyright (C) 2002-2008  Elias Ross
 * 
 * genman@noderunner.net
 * http://noderunner.net/~genman
 * 
 * 1025 NE 73RD ST
 * SEATTLE WA 98115
 * USA
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * $Id$
 */

package net.noderunner.http.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;

import javax.servlet.http.HttpServlet;

import net.noderunner.http.MessageHeader;
import net.noderunner.http.ServerRequest;
import net.noderunner.http.ServerResponse;
import net.noderunner.http.ThreadedHttpServer;

/**
 * Extends the threaded HTTP server by sending requests to a single servlet.
 * 
 * Currently does not support streamed requests or responses, though this
 * feature may likely be supported in the future.
 * 
 * @author Elias Ross
 */
public class ServletServer extends ThreadedHttpServer {
	
	private HttpServlet servlet;

	/**
	 * Constructs a new ServletServer.
	 * 
	 * @param servlet pre-initialized HTTP servlet to use
	 * @throws IOException
	 */
	public ServletServer(HttpServlet servlet) throws IOException {
		super();
		this.servlet = servlet;
	}

	/**
	 * Constructs a new ServletServer.
	 * 
	 * @param servlet pre-initialized HTTP servlet to use
	 * @param ss server socket
	 */
	public ServletServer(HttpServlet servlet, ServerSocket ss) {
		super(ss);
		this.servlet = servlet;
	}
	
	/**
	 * Constructs a new ServletServer for this local port.
	 * 
	 * @param servlet pre-initialized HTTP servlet to use
	 * @param port TCP/IP port number
	 */
	public ServletServer(HttpServlet servlet, int port) throws IOException {
		this(servlet, new ServerSocket(port));
	}

	@Override
	protected void handleRequest(Request r) throws IOException {
		ServerRequest request = r.getServer().readRequest();
		HttpServletRequestImpl sreq = new HttpServletRequestImpl(request);
		HttpServletResponseImpl sres = new HttpServletResponseImpl();
		sres.setHeader(MessageHeader.FN_SERVER, "ServletServer_" + servlet.getClass().getSimpleName());
		if (ss != null) {
    		sreq.serverSocket(ss);
		}
		sreq.remoteAddress(r.getRemoteAddress());
		
		try {
			servlet.service(sreq, sres);
		} catch (Exception e) {
			PrintWriter pw = sres.getWriter();
			pw.println("Failure to process request:");
			e.printStackTrace(pw);
			pw.flush();
			sres.setStatus(500, sres.toString());
			exception(e);
		}
		
		ServerResponse response = sres.createServerResponse();
		r.getServer().writeResponse(response);
	}

}
