001package edu.pdx.cs410J.net;
002
003import java.io.*;
004import java.util.*;
005import java.net.*;
006
007/**
008 * A <code>ChatListener</code> runs in the background and listens for
009 * messages on a socket on localhost.
010 */
011public class ChatListener implements Runnable {
012  private static PrintStream err = System.err;
013
014  private List incoming;  // Incoming messages
015  private BufferedInputStream bis;  // Read messages from here
016
017  /**
018   * Creates a new <code>ChatListener</code>
019   */
020  public ChatListener() {
021    this.incoming = new ArrayList();
022  }
023
024  /**
025   * Sets the socket on which this <code>ChatListener</code> listens
026   */
027  public void setSocket(Socket socket) {
028//      System.out.println("Making input stream");
029
030    try {
031      // Make streams for reading and writing
032//        System.out.println("InputStream");
033      this.bis = new BufferedInputStream(socket.getInputStream());
034
035    } catch (IOException ex) {
036      err.println("** IOException: " + ex);
037      System.exit(1);
038    }
039  }
040
041  /** 
042   * Sit in a loop and wait for messages to come in.  Unfortunately,
043   * calling the constructor of <code>ObjectInputStream</code>
044   * blocks.  So, we have to encode a "STOP" command in the final
045   * message.  Awful.
046   */
047  public void run() {
048//      System.out.println("ChatListener starting");
049
050    // Do stuff...
051    while (true) {
052//        System.out.println("Waiting to receive");
053      
054      try {
055        // Is there a message to receive?
056        ObjectInputStream in = new ObjectInputStream(bis);
057        ChatMessage m = (ChatMessage) in.readObject();
058        if(m != null) {
059          synchronized(this.incoming) {
060//          System.out.println("Receiving: " + m);
061            this.incoming.add(m);
062          }
063
064//        System.out.println("Is " + m + " last? " +
065//                           (m.isLastMessage() ? "yes" : "no"));
066
067          if (m.isLastMessage()) {
068            break;
069          }
070        }
071          
072      } catch (ClassNotFoundException ex) {
073        err.println("** Could not find class: " + ex);
074        System.exit(1);
075          
076      } catch (IOException ex) {
077        err.println("** IOException: " + ex);
078        System.exit(1);
079      }
080    }
081
082//      System.out.println("ChatListener stopping");
083  }
084
085  /**
086   * Returns all incoming messages.  This method will be called by a
087   * thread other than the one running run().
088   */
089  public List getMessages() {
090    List messages = new ArrayList();
091    synchronized(this.incoming) {
092      // Why can't we just return this.incoming?
093
094      messages.addAll(this.incoming);
095      this.incoming.clear();
096    }
097
098    return messages;
099  }
100}