com.gc.iotools.stream.is.inspection
Class DiagnosticInputStream<T extends InputStream>

java.lang.Object
  extended by java.io.InputStream
      extended by java.io.FilterInputStream
          extended by com.gc.iotools.stream.is.inspection.DiagnosticInputStream<T>
All Implemented Interfaces:
Closeable

public class DiagnosticInputStream<T extends InputStream>
extends FilterInputStream

Detects and log useful debug informations about the stream passed in the constructor, and detects wrong usage patterns.

It normally acts as a FilterInputStream simply forwarding all the calls to the InputStream passed in the constructor, but also keeping track of the usage of the methods.

Errors are both logged at WARN level and available through the standard class interface. Future version will allow the customization of this behavior disable the logging.

It is designed to detect also errors that happens during object finalization, but to detect these errors in tests you must be very careful on your test design (see example). Errors in finalizers are available trough the getFinalizationErrors() method.

It's an useful tool in unit tests to detect wrong handling of the streams, but it can be used in main applications too since it adds a very little overhead in standard situations.

Sample Usage (in Junit 4):

 @org.junit.Test
 public void testWarnDoubleClose() throws Exception {
  InputStream myTestData = ....
  DiagnosticInputStream<InputStream> diagIs = new DiagnosticInputStream<InputStream>(
                        myTestData);
  //The class and the method under test
  MyClassUnderTest.myMethodUnderTest(diagIs);
  final String[] instanceWarnings = diagIs.getInstanceWarnings();
  assertTrue("No problems" + diagIs.getStatusMessage(), 
                        instanceWarnings.length == 0);
 }
 

If your code free resources in finalize() methods, or the libraries you use do so you must use a more complex testing strategy because the references to to the active DiagnosticInputStream instance in your Junit prevents the class from being garbage collected. See the wiki for details and getFinalizationErrors().

Since:
1.2.6
Author:
dvd.msnt

Field Summary
 
Fields inherited from class java.io.FilterInputStream
in
 
Constructor Summary
DiagnosticInputStream(T in)
           
DiagnosticInputStream(T inputStream, int logDepth)
           
 
Method Summary
 int available()
           
 void clearInstanceWarnings()
           
 void close()
           
 void finalize()
           
 int getCloseCount()
           
static String[] getFinalizationErrors()
           
 String[] getInstanceWarnings()
           
 String getStatusMessage()
           Returns a string representation of the usage errors of the stream until now.
 T getWrappedInputStream()
           Returns the wrapped (original) InputStream passed in the constructor.
 boolean isMethodCalledAfterClose()
           
 void mark(int readlimit)
           
 boolean markSupported()
           
 int read()
           
 int read(byte[] b)
           
 int read(byte[] b, int off, int len)
           
 void reset()
           
static void resetFinalizationErrors()
           
static void setDefaultLogDepth(int defaultFrameDepth)
           
 long skip(long n)
           
 
Methods inherited from class java.lang.Object
clone, equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

DiagnosticInputStream

public DiagnosticInputStream(T in)
Parameters:
in - the source InputStream.

DiagnosticInputStream

public DiagnosticInputStream(T inputStream,
                             int logDepth)
Parameters:
inputStream - the source InputStream
logDepth - Number of stack frames to log. It overrides the default static value.
Method Detail

getFinalizationErrors

public static String[] getFinalizationErrors()

resetFinalizationErrors

public static void resetFinalizationErrors()

setDefaultLogDepth

public static void setDefaultLogDepth(int defaultFrameDepth)

available

public int available()
              throws IOException
Overrides:
available in class FilterInputStream
Throws:
IOException

clearInstanceWarnings

public void clearInstanceWarnings()

close

public void close()
           throws IOException
Specified by:
close in interface Closeable
Overrides:
close in class FilterInputStream
Throws:
IOException

finalize

public void finalize()
              throws Throwable
Overrides:
finalize in class Object
Throws:
Throwable

getCloseCount

public int getCloseCount()

getInstanceWarnings

public String[] getInstanceWarnings()

getWrappedInputStream

public T getWrappedInputStream()

Returns the wrapped (original) InputStream passed in the constructor. Any calls made to the returned stream will not be tracked by DiagnosticInputStream, so this method should be used with care, and close() and read() methods should'nt be called on the returned InputStream. Instead these methods should be called on DiagnosticInputStream that simply forwards them to the underlying stream.

Returns:
The original InputStream passed in the constructor

getStatusMessage

public String getStatusMessage()

Returns a string representation of the usage errors of the stream until now. Null if no error happened yet.

Returns:
String message that represents the errors, null if no error.

isMethodCalledAfterClose

public boolean isMethodCalledAfterClose()

mark

public void mark(int readlimit)
Overrides:
mark in class FilterInputStream

markSupported

public boolean markSupported()
Overrides:
markSupported in class FilterInputStream

read

public int read()
         throws IOException
Overrides:
read in class FilterInputStream
Throws:
IOException

read

public int read(byte[] b)
         throws IOException
Overrides:
read in class FilterInputStream
Throws:
IOException

read

public int read(byte[] b,
                int off,
                int len)
         throws IOException
Overrides:
read in class FilterInputStream
Throws:
IOException

reset

public void reset()
           throws IOException
Overrides:
reset in class FilterInputStream
Throws:
IOException

skip

public long skip(long n)
          throws IOException
Overrides:
skip in class FilterInputStream
Throws:
IOException


Copyright © 2008-2009. All Rights Reserved.