bb.io
Class StreamDrainerForwarding

java.lang.Object
  extended by bb.io.StreamDrainerForwarding
All Implemented Interfaces:
StreamDrainer, Runnable
Direct Known Subclasses:
StreamDrainerForwarding.UnitTest.Crashes

public class StreamDrainerForwarding
extends Object
implements StreamDrainer

StreamDrainer implementation that immediately forwards all bytes read from its InputStream to another OutputStream.

This class is multithread safe: almost every method is synchronized. The sole exception is run, which internally synchronizes those code blocks which involve mutable state using the same lock as the other methods (i.e. the instance itself).

Author:
Brent Boyer

Nested Class Summary
static class StreamDrainerForwarding.UnitTest
          See the Overview page of the project's javadocs for a general description of this unit test class.
 
Field Summary
private static int bufferSize
           
private static byte[] bytesEmpty
           
private  InputStream in
           
private  OutputStream out
           
private  boolean runCalled
           
private  Throwable throwable
           
 
Constructor Summary
StreamDrainerForwarding(InputStream in, OutputStream out)
          Constructor that assigns out with the corresponding parameter, and calls init with the in parameter.
StreamDrainerForwarding(OutputStream out)
          Constructor that simply assigns out with the correspondingparameter.
 
Method Summary
 byte[] getBytes()
          Because this class never stores the bytes drained by run, this method always returns an empty byte[].
 Throwable getThrowable()
          Returns any Throwable caught by run while it was draining that it could not handle.
 void init(InputStream in)
          Assigns the InputStream that this instance must drain.
protected  void onBytesRead(byte[] buffer, int numberRead)
          Hook method for the event that bytes were read from in by run.
 void run()
          Drains the InputStream supplied to init.
private  void setThrowable(Throwable throwable)
           
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

bufferSize

private static final int bufferSize
See Also:
Constant Field Values

bytesEmpty

private static final byte[] bytesEmpty

out

private final OutputStream out

in

private InputStream in

runCalled

private boolean runCalled

throwable

private Throwable throwable
Constructor Detail

StreamDrainerForwarding

public StreamDrainerForwarding(OutputStream out)
                        throws IllegalArgumentException
Constructor that simply assigns out with the correspondingparameter. A subsequent call to init must be made before run can be executed.

Throws:
IllegalArgumentException

StreamDrainerForwarding

public StreamDrainerForwarding(InputStream in,
                               OutputStream out)
                        throws IllegalArgumentException
Constructor that assigns out with the corresponding parameter, and calls init with the in parameter. This is a convenience, because it relieves the user of having to make an additional call to init.

Throws:
IllegalArgumentException - if out is null; in is null
Method Detail

init

public void init(InputStream in)
          throws IllegalArgumentException,
                 IllegalStateException
Description copied from interface: StreamDrainer
Assigns the InputStream that this instance must drain.

Note that some implementations may have a constructor which takes an InputStream arg. In these cases, that constructor must call this method and the user should not subsequently call it again.

Specified by:
init in interface StreamDrainer
Throws:
IllegalArgumentException - if in is null
IllegalStateException - if called more than once

run

public void run()
         throws IllegalStateException
Drains the InputStream supplied to init. The fate of the drained bytes is implementation dependent (see getBytes).

Other than the IllegalStateException described below, this method guarantees to never throw any Throwable once draining has started. Instead, if a Throwable is thrown that cannot be internally handled, this method guarantees to store it for future retrieval by getThrowable before aborting execution.

Note: when finished draining, will flush (but not close) out.

Specified by:
run in interface StreamDrainer
Specified by:
run in interface Runnable
Throws:
IllegalStateException - if init has not been called yet; this method is called more than once

onBytesRead

protected void onBytesRead(byte[] buffer,
                           int numberRead)
Hook method for the event that bytes were read from in by run. When this method is called, run will have already written those bytes to out. The implementation here does nothing, because writing to out is all that this class does. Subclasses, however, may wish to do additional processing. For example, if the subclass is monitoring some error stream like System.err, then it may wish to do additional error notification.


getBytes

public byte[] getBytes()
                throws IllegalStateException
Because this class never stores the bytes drained by run, this method always returns an empty byte[].

Specified by:
getBytes in interface StreamDrainer
Returns:
a zero-length byte[]
Throws:
IllegalStateException - if run has never been called

getThrowable

public Throwable getThrowable()
                       throws IllegalStateException
Description copied from interface: StreamDrainer
Returns any Throwable caught by run while it was draining that it could not handle.

Specified by:
getThrowable in interface StreamDrainer
Returns:
the Throwable which aborted the draining; is null if no such Throwable occurred
Throws:
IllegalStateException - if run has never been called

setThrowable

private void setThrowable(Throwable throwable)