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>
Type Parameters:
T - Type of the wrapped (contained) InputStream.
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
Version:
$Id: DiagnosticInputStream.java 463 2011-01-21 23:54:17Z dvd.smnt@gmail.com $
Author:
dvd.msnt

Field Summary
 
Fields inherited from class java.io.FilterInputStream
in
 
Constructor Summary
DiagnosticInputStream(T in)
           Constructor for DiagnosticInputStream.
DiagnosticInputStream(T inputStream, int logDepth)
           Constructor for DiagnosticInputStream.
 
Method Summary
 int available()
          
 void clearInstanceWarnings()
           clearInstanceWarnings
 void close()
          
 void finalize()
          
 int getCloseCount()
          Returns the number of times that close was called on this stream.
 byte[] getContent()
           Return the current captured bytes, if capture was enabled.
static String[] getFinalizationErrors()
           Returns an array of descriptions of finalization errors.
 String[] getInstanceWarnings()
           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()
           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()
           resetFinalizationErrors
static void setDefaultLogDepth(int defaultFrameDepth)
           Setter for the field defaultLogDepth.
 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)

Constructor for DiagnosticInputStream.

Parameters:
in - the source InputStream.

DiagnosticInputStream

public DiagnosticInputStream(T inputStream,
                             int logDepth)

Constructor for DiagnosticInputStream.

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()

Returns an array of descriptions of finalization errors. For instance when the stream is finalized but it was not closed.

Returns:
Description of finalization erros as an array of String objects.

resetFinalizationErrors

public static void resetFinalizationErrors()

resetFinalizationErrors


setDefaultLogDepth

public static void setDefaultLogDepth(int defaultFrameDepth)

Setter for the field defaultLogDepth.

Parameters:
defaultFrameDepth - a int.

available

public int available()
              throws IOException

Overrides:
available in class FilterInputStream
Throws:
IOException

clearInstanceWarnings

public void clearInstanceWarnings()

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()
Returns the number of times that close was called on this stream.

Returns:
number of times that close was called on this stream.

getContent

public byte[] getContent()

Return the current captured bytes, if capture was enabled.

The capture buffer might be truncated if maxCapture is set.

Returns:
the current captured bytes.
Since:
1.2.9

getInstanceWarnings

public String[] getInstanceWarnings()

getInstanceWarnings

Returns:
an array of String objects.

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.

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

isMethodCalledAfterClose

public boolean isMethodCalledAfterClose()

isMethodCalledAfterClose

Returns:
a boolean.

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-2011. All Rights Reserved.