PIRL.Conductor

## Class Stream_Logger

- java.lang.Object
- - java.lang.Thread
  - - PIRL.Conductor.Stream_Logger

All Implemented Interfaces:
  Runnable

    public class Stream_Logger
    extends Thread

A Stream_Logger is a Thread that is used to forward the lines read from an InputStream to one or more Writers.

Once started a Stream_Logger reads a line of input from its InputStream and then writes the line to each Writer in its list. Writers may be added or removed from the list at any time, before or after the start of the Stream_Logger. If no Writer has been bound to the Stream_Logger the input stream is still read and buffered.

Lines read are stored in a buffer up to an amount that may be changed at any time.

A Stream_Logger stops when an end of file or IOException has been encountered on its InputStream. However, it may be notified to end before reading the next line. It may also be notified to close if no input has arrived, but continue to the normal end of file (or IOException) if data has already arrived.

See Also:
  `Thread`

### Nested Class Summary

### Nested classes/interfaces inherited from class java.lang.Thread

`Thread.State, Thread.UncaughtExceptionHandler`

### Field Summary

Fields
`static int` `DEFAULT_BUFFER_SIZE` The default `buffer size`.
`static int` `DEFAULT_POLLING_INTERVAL` The default `polling interval`.
`static String` `ID` Class identification name with source code version and date.
`static int` `MINIMUM_BUFFER_SIZE` The minimum `buffer size`.

### Fields inherited from class java.lang.Thread

`MAX_PRIORITY, MIN_PRIORITY, NORM_PRIORITY`

### Constructor Summary

Constructors
Constructor and Description
`Stream_Logger(String stream_name, InputStream input_stream)` Constructs a Stream_Logger for an InputStream without an initial log Writer.
`Stream_Logger(String stream_name, InputStream input_stream, Writer writer)` Constructs a Stream_Logger connecting an InputStream with a log Writer.

### Method Summary

Methods
`boolean` `Add(Writer writer)` Adds a Writer to the list of writers where read lines will sent.
`int` `Buffer_Size()` Gets the maximum size of the last-lines-read buffer.
`Stream_Logger` `Buffer_Size(int size)` Sets the maximum size of the last-lines-read buffer.
`StringBuffer` `Buffer()` Gets the last-lines-read buffer.
`void` `Clear_Buffer()` Clears the last-lines-read buffer.
`void` `Close()` Effectively closes the input stream.
`void` `End()` Ends the Stream_Logger.
`long` `Polling_Interval()` Gets the polling interval to check for the initial arrival of data.
`Stream_Logger` `Polling_Interval(long interval)` Sets the polling interval to check for the arrival of data.
`boolean` `Remove(Writer writer)` Removes a Writer from the Vector of log Writers.
`void` `run()` Runs the Stream_Logger.

### Methods inherited from class java.lang.Thread

`activeCount, checkAccess, clone, countStackFrames, currentThread, destroy, dumpStack, enumerate, getAllStackTraces, getContextClassLoader, getDefaultUncaughtExceptionHandler, getId, getName, getPriority, getStackTrace, getState, getThreadGroup, getUncaughtExceptionHandler, holdsLock, interrupt, interrupted, isAlive, isDaemon, isInterrupted, join, join, join, resume, setContextClassLoader, setDaemon, setDefaultUncaughtExceptionHandler, setName, setPriority, setUncaughtExceptionHandler, sleep, sleep, start, stop, stop, suspend, toString, yield`

### Methods inherited from class java.lang.Object

`equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait`

### Field Detail

#### ID

    public static final String ID

Class identification name with source code version and date.

See Also:
  Constant Field Values

#### DEFAULT_POLLING_INTERVAL

    public static final int DEFAULT_POLLING_INTERVAL

The default `polling interval`.

See Also:
  Constant Field Values

#### MINIMUM_BUFFER_SIZE

    public static final int MINIMUM_BUFFER_SIZE

The minimum `buffer size`.

#### DEFAULT_BUFFER_SIZE

    public static final int DEFAULT_BUFFER_SIZE

The default `buffer size`.

### Constructor Detail

#### Stream_Logger

    public Stream_Logger(String stream_name,
                 InputStream input_stream,
                 Writer writer)

Constructs a Stream_Logger connecting an InputStream with a log Writer.

The InputStream is wrapped in an InputStreamReader and a BufferedReader. The Writer, if not null, is the first entry in the Vector of log Writers.

Note: This Thread is marked as a `daemon` so it does not need to finish before the user application can exit.

Parameters:
  `stream_name` - The name of the stream to prefix to each line logged along with a ": " separator. If null no line prefix is added.
  `input_stream` - The InputStream to be read.
  `writer` - A Writer to use for logging lines. If null, the Stream_Logger will not have any initial Writer.
Throws:
  `IllegalArgumentException` - If the input_stream is null.

#### Stream_Logger

    public Stream_Logger(String stream_name,
                 InputStream input_stream)

Constructs a Stream_Logger for an InputStream without an initial log Writer.

Parameters:
  `stream_name` - The name of the stream to prepend to each line logged. This may be null.
  `input_stream` - The InputStream to be read.
Throws:
  `IllegalArgumentException` - If the input_stream is null.
See Also:
  `Stream_Logger(String, InputStream, Writer)`

### Method Detail

#### Add

    public boolean Add(Writer writer)

Adds a Writer to the list of writers where read lines will sent.

If the Writer is already in the list it is not added.

Parameters:
  `writer` - The Writer to add.
Returns:
  true if the Writer was added to the list; false if it was already in the list or is null.
See Also:
  `Remove(Writer)`

#### Remove

    public boolean Remove(Writer writer)

Removes a Writer from the Vector of log Writers.

Parameters:
  `writer` - The Writer to remove.
Returns:
  true if the Writer was removed to the list; false if it was not in the list or is null.
See Also:
  `Add(Writer)`

#### Buffer

    public StringBuffer Buffer()

Gets the last-lines-read buffer.

If the Stream_Logger is `running` the contents of the buffer will change if a new line arrives. Obviously, the buffer returned should not be modified while the Stream_Logger is running. N.B.: Synchronize on the buffer if necessary, though this will block reading of further lines until the lock is released.

Returns:
  A StringBuffer containing the last lines read from the InputStream.

#### Buffer_Size

    public Stream_Logger Buffer_Size(int size)

Sets the maximum size of the last-lines-read buffer.

Note: The buffer size is never allowed to be less than the `MINIMUM_BUFFER_SIZE`.

Warning: Do not call this method while sychronized on the buffer as this will result in a deadlock.

Parameters:
  `size` - The maximum number of characters allowed in the buffer. If the buffer is currently larger than this amount whole lines will be removed from the front of the buffer to bring the content amount below the size.
Returns:
  This Stream_Logger.

#### Buffer_Size

    public int Buffer_Size()

Gets the maximum size of the last-lines-read buffer.

Returns:
  The maximum number of characters allowed in the buffer.
See Also:
  `Buffer_Size(int)`

#### Clear_Buffer

    public void Clear_Buffer()

Clears the last-lines-read buffer.

Warning: Do not call this method while sychronized on the buffer as this will result in a deadlock.

#### Polling_Interval

    public Stream_Logger Polling_Interval(long interval)

Sets the polling interval to check for the arrival of data.

The polling interval is only used while waiting for data to arrive on the input stream. After that point blocking reads are used.

A short polling interval has the disadvantage of consuming more CPU cycles while waiting for data to arrive. This can have an adverse affect on system performance, especially if no data arrives for a long time.

A long polling interval has the disadvantage of introducing a delay up to the interval time between when data first arrives and input actually begins. This is generally not a problem if the delay is not so long as to interfere with data delivery downstream or cause data loss due to buffer overflow upstream.

Parameters:
  `interval` - The amount of time to wait, in milliseconds, between tests to see if data has arrived. The minimum time is one millisecond. This initial default is `DEFAULT_POLLING_INTERVAL` milliseconds.
Returns:
  This Stream_Logger.
See Also:
  `Close()`

#### Polling_Interval

    public long Polling_Interval()

Gets the polling interval to check for the initial arrival of data.

Returns:
  The polling interval in milliseconds.
See Also:
  `Polling_Interval(long)`

#### run

    public void run()

Runs the Stream_Logger.

Each line of input `read` from the InputStream is written to each Writer in the Vector of Writers. Each line written is prepended with the stream name followed by ": ", unless no stream name was provided. The system's line ending sequence, from the "line.separator" property, is appended to each line written.

Each line read is also appended to the last-lines-read buffer. Only entire lines are buffered; lines that are too big to fit in the buffer are dropped. Lines, and only entire lines, are removed from the front of the buffer as needed to make room for new lines to be added at the end.

Logging continues until an end-of-file or IOException is encountered on the InputStream, or the logger is told to ``End``.

N.B.: If a Writer throws an IOException it is removed from the list of Writers.

Specified by:
  `run` in interface `Runnable`
Overrides:
  `run` in class `Thread`

#### End

    public void End()

Ends the Stream_Logger.

Logging ends before the next line is read, but after the current line has finished logging.

N.B.: Logging stops even if there may be more input available from the InputStream after the current line.

#### Close

    public void Close()

Effectively closes the input stream.

The input stream is initially polled for a ready condition (characters are available) before begining to read lines. This prevents the Stream_Logger from becoming blocked on input which will never arrive, thus allowing it to be externally halted. However, it may not be known if input has arrived or not.

If input has not arrived then the Stream_Logger is to stop polling and ``End``. If input has arrived then the Stream_Logger is to continue reading until EOF or an IOException occurs.