package edu.pdx.cs410J.net;
import java.io.*;
import java.util.*;
import java.net.*;
/**
* A <code>ChatListener</code> runs in the background and listens for
* messages on a socket on localhost.
*/
public class ChatListener implements Runnable {
private static PrintStream err = System.err;
private List incoming; // Incoming messages
private BufferedInputStream bis; // Read messages from here
/**
* Creates a new <code>ChatListener</code>
*/
public ChatListener() {
this.incoming = new ArrayList();
}
/**
* Sets the socket on which this <code>ChatListener</code> listens
*/
public void setSocket(Socket socket) {
// System.out.println("Making input stream");
try {
// Make streams for reading and writing
// System.out.println("InputStream");
this.bis = new BufferedInputStream(socket.getInputStream());
} catch (IOException ex) {
err.println("** IOException: " + ex);
System.exit(1);
}
}
/**
* Sit in a loop and wait for messages to come in. Unfortunately,
* calling the constructor of <code>ObjectInputStream</code>
* blocks. So, we have to encode a "STOP" command in the final
* message. Awful.
*/
public void run() {
// System.out.println("ChatListener starting");
// Do stuff...
while (true) {
// System.out.println("Waiting to receive");
try {
// Is there a message to receive?
ObjectInputStream in = new ObjectInputStream(bis);
ChatMessage m = (ChatMessage) in.readObject();
if(m != null) {
synchronized(this.incoming) {
// System.out.println("Receiving: " + m);
this.incoming.add(m);
}
// System.out.println("Is " + m + " last? " +
// (m.isLastMessage() ? "yes" : "no"));
if (m.isLastMessage()) {
break;
}
}
} catch (ClassNotFoundException ex) {
err.println("** Could not find class: " + ex);
System.exit(1);
} catch (IOException ex) {
err.println("** IOException: " + ex);
System.exit(1);
}
}
// System.out.println("ChatListener stopping");
}
/**
* Returns all incoming messages. This method will be called by a
* thread other than the one running run().
*/
public List getMessages() {
List messages = new ArrayList();
synchronized(this.incoming) {
// Why can't we just return this.incoming?
messages.addAll(this.incoming);
this.incoming.clear();
}
return messages;
}
}