package de.netseeker.ejoe.io;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.channels.ClosedChannelException;
import de.netseeker.ejoe.EJConstants;
/**
* Simple input stream wrapper which overwrites #close to prevent some and is used when output streams are handed over
* to serialize adapters to prevent some encoders, eg. Suns XmlEncoder, to close our socket output streams
* automatically.
*
* @author netseeker
* @since 0.3.5
*/
public class UncloseableOutputStream extends FilterOutputStream
{
private boolean _customEOF;
private boolean _isClosed = false;
private int _written = 0;
private int _lastFlush = 0;
/**
* @param out
*/
public UncloseableOutputStream(OutputStream out)
{
this( out, false );
}
/**
* @param out
* @param customEOF
*/
public UncloseableOutputStream(OutputStream out, boolean customEOF)
{
super( out );
_customEOF = customEOF;
}
/*
* (non-Javadoc)
*
* @see java.io.FilterOutputStream#write(byte[], int, int)
*/
public void write( byte[] b, int off, int len ) throws IOException
{
if ( _customEOF && len > 0 && b[off + len - 1] == -1 )
{
len -= 1;
}
super.write( b, off, len );
_written += len;
}
/*
* (non-Javadoc)
*
* @see java.io.FilterOutputStream#write(byte[])
*/
public void write( byte[] b ) throws IOException
{
write( b, 0, b.length );
}
/*
* (non-Javadoc)
*
* @see java.io.FilterOutputStream#write(int)
*/
public void write( int b ) throws IOException
{
super.write( b );
_written++;
}
/*
* (non-Javadoc)
*
* @see java.io.FilterOutputStream#flush()
*/
public void flush() throws IOException
{
try
{
if ( _written > _lastFlush ) super.flush();
}
catch ( IOException e )
{
throw new ClosedChannelException();
}
finally
{
_lastFlush = _written;
}
}
/*
* (non-Javadoc)
*
* @see java.io.FilterOutputStream#close()
*/
public void close() throws IOException
{
if ( !_isClosed )
{
try
{
if ( _written > 0 )
{
if ( _customEOF )
{
super.write( EJConstants.EJOE_EOF );
}
flush();
}
}
catch ( IOException e )
{
throw new ClosedChannelException();
}
finally
{
_isClosed = true;
_written = 0;
}
}
}
}