001package edu.pdx.cs410J.net;
002
003import java.io.*;
004import java.util.*;
005import java.net.*;
006
007/**
008 * A <code>ChatSpeaker</code> runs in the background and sends
009 * <code>ChatMessage</code>s over a <code>Socket</code>.
010 */
011public class ChatSpeaker implements Runnable {
012  private static PrintStream err = System.err;
013
014  private List outgoing;  // Outgoing messages
015  private BufferedOutputStream bos;  // Send messages here
016
017  /**
018   * Creates a new <code>ChatSpeaker</code>
019   */
020  public ChatSpeaker() {
021    this.outgoing = new ArrayList();
022  }
023
024  /**
025   * Sets the socket to which this <code>ChatSpeaker</code> sends
026   * messages.
027   */
028  public void setSocket(Socket socket) {
029//      System.out.println("Making output stream");
030
031    try {
032      // Make streams for reading and writing
033//        System.out.println("OutputStream");
034
035      this.bos = new BufferedOutputStream(socket.getOutputStream());
036
037    } catch (IOException ex) {
038      err.println("** IOException: " + ex);
039      System.exit(1);
040    }
041  }
042
043  /** 
044   * A <code>ChatSpeaker</code> uses wait/notify on its
045   * <code>incoming</code> list to know when to send a message.  For
046   * the sake of symmetry, we interrupt it to tell it to stop.
047   */
048  public void run() {
049//      System.out.println("ChatSpeaker starting");
050
051    while (true) {
052      try {
053        // Is there a message to send?
054        synchronized(this.outgoing) {
055          if (!this.outgoing.isEmpty()) {
056            ChatMessage m = (ChatMessage) this.outgoing.remove(0);
057            
058//          System.out.println("Sending: " + m);
059            
060            ObjectOutputStream out = new ObjectOutputStream(bos);
061            out.writeObject(m);
062            out.flush();
063
064            if (m.isLastMessage()) {
065              // Send the last message and then go home
066              break;
067            }
068
069          }
070
071          // Wait for a message
072          this.outgoing.wait();
073        }
074
075      } catch (IOException ex) {
076        err.println("** IOException: " + ex);
077        System.exit(1);
078        break;
079        
080      } catch (InterruptedException ex) {
081//      System.out.println("Done sending messages");
082        break;
083      }
084    }
085
086//      System.out.println("ChatSpeaker stopping");
087  }
088
089  /**
090   * Queues a message to be sent.  This method will be called by a
091   * thread other than the one running run().
092   */
093  public void sendMessage(ChatMessage message) {
094    synchronized(this.outgoing) {
095//        System.out.println("Adding message: " + message);
096      this.outgoing.add(message);
097      this.outgoing.notify();
098    }
099  }
100}