/*
 * HelloIO.java
 * Copyright Terran Lane, 2004.
 *
 * $Id: HelloIO.java,v 1.1 2004/01/21 18:54:25 terran Exp $
 */

import java.io.PrintWriter;
import java.io.BufferedWriter;
import java.io.Writer;
import java.io.Serializable;
import java.io.OutputStreamWriter;

/**
 * This class does the majority of the work of the "refactored" "Hello
 * world" program.  It supports output to arbitrary {@link
 * java.io.Writer}'s, serialization, and synchronized multithreaded
 * operation.
 *
 * @author <a href="mailto:terran@illuminatus.cs.unm.edu">Terran
 * Lane</a>
 * @version 1.0
 */
public class HelloIO implements Runnable, Serializable {
  /**
   * Creates a new <code>HelloIO</code> instance, initialized with a
   * message string and {@link java.io.Writer} output destination.
   *
   * @param str Message string to print.
   * @param w {@link java.io.Writer} output destination.
   */
  public HelloIO(String str, Writer w) {
    _msg=str;
    _dest=w;
  }

  /**
   * A convenience constructor to initialize output to standard output.
   *
   * @param str Message string to print.
   */
  public HelloIO(String str) {
    this(str,new OutputStreamWriter(System.out));
  }

  /**
   * Method run by a new {@link Thread} instance when invoking this
   * class.  This method actually arranges for the message to be
   * printed to the previously specified output stream, then
   * terminates.
   */
  public void run() {
    PrintWriter w=new PrintWriter(new BufferedWriter(_dest));
    _displayMsg(w);
  }

  /* ******************** end of public interface ******************** */

  /**
   * This method is actually responsible for message display.  It is
   * separated out from {@link run()} so that it can be
   * <code>synchronized</code> to prevent race conditions when writing
   * to the output destination.
   *
   * @param w The output destination, cast into a {@link
   * java.io.PrintWriter} to support line-oriented output.
   */
  private synchronized void _displayMsg(PrintWriter w) {
    w.println(_msg);
    w.flush();
  }

  private String _msg;
  private Writer _dest;
}
