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}