import java.io.*;
import java.net.*;

import org.w3c.dom.Document;
import org.xml.sax.SAXException;

/**
 * A thread to manage a single connection.  This thread asynchronously
 * notifies the DOMProcessor when an incoming message is received.  The send
 * method can be called to initiate an outgoing message.
 */

public class XMLSocketThread extends Thread {
    Socket s;
    DOMProcessor proc;

    private InputStream in;
    private OutputStream out;

    public XMLSocketThread(Socket s) {
	this.s = s;
    }

    public void setDOMProcessor(DOMProcessor proc) {
	this.proc = proc;
    }

    public void run() {
	try {
	    in = s.getInputStream();
	    out = s.getOutputStream();
	    while (!s.isClosed()) {
		Document d = null;
		/* doesn't seem to work with SSL sockets...
		 * this isn't necessary anyway
		while (!s.isClosed() && in.available() == 0) {
		    // Java isn't very good about providing facilities
		    // to wait on sockets, so we'll just poll
		    Thread.sleep(100);
		}
		*/
		if (s.isClosed()) break;
		d = recv();
		proc.process(d);
	    }
	} catch (Exception ex) {
	    ex.printStackTrace();
	}
	System.out.println("shutting down " + s);
    }

    /**
     * send an XML message to the other end of the connection
     */
    public void send(Document d) throws IOException {
	WrappedOutputStream o = new WrappedOutputStream(out);
	try {
	    XML.format(o, d);
	} finally {
	    o.close();
	}
    }

    /**
     * receive an XML message from the other end of the connection
     */
    private synchronized Document recv() throws IOException, SAXException  {
	WrappedInputStream i = new WrappedInputStream(in);
	try {
	    Document d = XML.parse(i);
	    return d;
	} finally {
	    i.close();
	}
    }
}

