// //
 * $Id$
 *
 * Copyright 1998 Integrated Computer Solutions, Inc. All Rights Reserved
 *
 * This source code is protected by copyright law and international treaties.
 * Unauthorized reproduction or distribution of this source code module or any
 * portion of it, may result in severe civil and criminal penalties, and will
 * be prosecuted to the maximum extent possible under law.
 */

import com.ics.lib.*;
import com.ics.util.*;
import java.io.PrintWriter;
import java.io.*;
import java.net.*;
import java.util.Hashtable;
import java.util.Vector;

import com.ibm.xml.parser.*;
import org.w3c.dom.*;

/**
 * The Request class is the meat of the thing
 */

public class Request extends HTTPRequestI
{
	/** The parsed request as an XML DOM document */
	public TXDocument	contents;

	/** The reader to get stuff from the socket */
	HTTPInputStream socketReader = null;

	/** The XML parser instance reading the request */
	Parser  xmlparser = null;

	/** Source stream into xml parser */
	Source	xmlsource = null;
	 
	/** The socket which we are connected to */
	Socket	socket;

	/** Create a Request
	 * @param _server	what PUPserver I belong to
	 * @param _pool		what RequestPool I belong to
	 * @param _socket	my connection to the ultimate client
	 */
	Request(Socket _socket)
	{
		super(_socket);
		socket = _socket;
	}

	/** 
	 * Read a request from the client input stream
	 */
	public boolean readRequestFromSocket()
		throws IOException
	{
		socketReader = new HTTPInputStream(socket.getInputStream());

		// This routine reads the HTTP header up through the
		// blank line and load various members of the superclass
		// HTTPRequestI.
		HTTPUtil.readHTTPRequest(this, socketReader);
		return true;
	}

	/** Fullfill a request */
	void process()
	{
		try {
			readRequestFromSocket();

			// Execute operation from the message 

			if(readXMLdoc() < 0) {
				errorCode = 666;
				return -1;
			}

			// Print the DOM tree for debugging
			DOMHelpers.dumpDoc(contents);

		} catch(IOException ioe) {
			LogManager.danger(Constants.REQUEST, ioe);
			try {
				if(socket != null) socket.close();
			} catch(IOException ioe2) {
			}
		} finally {
			socket = null;
		}
	}


	/** Load up a configuration file containing parameters
	 */
	public int readXMLdoc()
	{
		//*** The confTree is the root of the DOM Tree. It is of type
		//*** Document which implements the DOM Document interface.
		xmlparser = new Parser(null,
				new RequestErrorListener(), 
				new RequestStreamProducer());
		xmlparser.setKeepComment(false);
		// I do not use a DTD, this prevents DTD checks
		xmlparser.setElementFactory(new TXDocument() {
			public boolean isCheckValidity() {
				return false;
			}
		});
		xmlparser.setTagHandler(new PUPTagHandler());   // PUPTagHandler
		// System.out.println("Start xml parse");
		contents = xmlparser.readStream(socketReader);
		xmlparser = null;	// discard, it cannot be reused

		return 0;
	}



    class RequestErrorListener implements ErrorListener
    {
	public int error(String fileName, int lineNo, int charOffset, 
                       Object key, String msg) {

		StringBuffer x = new StringBuffer("Parse error at line:");
		x.append(lineNo);
		x.append(", col:");
		x.append(charOffset);
		x.append(" = ");
		x.append(msg);

		LogManager.warning(Constants.REQUEST, x.toString());

		return 0;
	}
    }

	/** The RequestStreamProducer is an artifact needed by the XML
	 * parser.
	 */
    class RequestStreamProducer implements StreamProducer
    {
	/** This is never called by the XML4J package */
	public Source getInputStream(String name, String pID, String sysID)
	{
		System.out.println("RSP.getInputStream called");
		xmlsource = new Source(socketReader);
		return xmlsource;
	}
	/** Yet, this is called.  Sounds like a bug to me */
	public void closeInputStream(Source s)
	{
		// System.out.println("RSP.closeInputSteam called");
	}
	public void loadCatalog(Reader r)
	{
		// System.out.println("RSP.loadCatalog called");
	}
    }

// 
//

// 
    class PUPTagHandler implements TagHandler
    {
	public void handleStartTag(TXElement tag, boolean isEmpty) { 
	//	System.out.println("I got the " + tag.getTagName() + " start");
	}
// 
	public void handleEndTag(TXElement tag, boolean isEmpty) { 
	//	System.out.println("I got the " + tag.getTagName() + " end");
		if("BODY".equals(tag.getTagName())) {
			System.out.println("Body text="+tag.getText());
		}
		if("PUP".equals(tag.getTagName())) {
			// System.out.println("Got FINAL PUP TAG - DONE");
			
			/** Both of these sound like they should work,
			 * from reading the docs, but they don't seem to
			 * do it.   The HTTPInputStream.signalEOF call
			 * simulates an EOF on the next read, so that the
			 * parser returns.
			 */
			// xmlparser.closeInputStream(xmlsource);
			// xmlparser.stop();

			socketReader.signalEOF();
		}
	}
    }
}
//