biz.paluch.logging.gelf.intern.OutputAccessor Maven / Gradle / Ivy
package biz.paluch.logging.gelf.intern;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.ByteBuffer;
/**
* @author Mark Paluch
*/
abstract class OutputAccessor {
public abstract void write(int b);
public abstract void write(byte[] b);
public abstract void write(byte[] b, int off, int len);
/**
* Create an {@link OutputAccessor} for the given {@link OutputStream}.
*
* @param outputStream
* @return
*/
public static OutputAccessor from(OutputStream outputStream) {
return new OutputStreamAccessor(outputStream);
}
/**
* Create an {@link OutputAccessor} for the given {@link ByteBuffer}. Instances are pooled within the thread scope.
*
* @param byteBuffer
* @return
*/
public static OutputAccessor from(ByteBuffer byteBuffer) {
ByteBufferOutputAccessor accessor = new ByteBufferOutputAccessor();
accessor.byteBuffer = byteBuffer;
return accessor;
}
/**
* Create an {@link OutputAccessor} for the given {@link ByteBuffer}. Instances are pooled within the thread scope.
*
* @param poolHolder
* @param byteBuffer
* @return
*/
public static OutputAccessor from(OutputAccessorPoolHolder poolHolder, ByteBuffer byteBuffer) {
ByteBufferOutputAccessor accessor = poolHolder.getByteBufferOutputAccessor();
accessor.byteBuffer = byteBuffer;
return accessor;
}
/**
* Retrieve a pooled {@link OutputStream}.
*
* @param poolHolder
* @return
*/
public static OutputStream pooledStream(OutputAccessorPoolHolder poolHolder) {
return poolHolder.getByteBufferOutputStream();
}
/**
* Retrieved a pooled an {@link OutputStream} for the given {@link ByteBuffer}. Instances are pooled within the thread
* scope.
*
* @param poolHolder
* @param byteBuffer
* @return
*/
public static OutputStream asStream(OutputAccessorPoolHolder poolHolder, ByteBuffer byteBuffer) {
ByteBufferOutputStream accessor = poolHolder.getByteBufferOutputStream();
accessor.byteBuffer = byteBuffer;
return accessor;
}
static class ByteBufferOutputAccessor extends OutputAccessor {
private ByteBuffer byteBuffer;
@Override
public void write(byte[] b, int off, int len) {
byteBuffer.put(b, off, len);
}
@Override
public void write(byte[] b) {
byteBuffer.put(b);
}
@Override
public void write(int b) {
byteBuffer.put((byte) b);
}
}
static class ByteBufferOutputStream extends OutputStream {
private ByteBuffer byteBuffer;
public ByteBufferOutputStream(ByteBuffer byteBuffer) {
this.byteBuffer = byteBuffer;
}
@Override
public void write(byte[] b, int off, int len) {
byteBuffer.put(b, off, len);
}
@Override
public void write(byte[] b) {
byteBuffer.put(b);
}
@Override
public void write(int b) {
byteBuffer.put((byte) b);
}
}
static class OutputStreamAccessor extends OutputAccessor {
private final OutputStream delegate;
public OutputStreamAccessor(OutputStream delegate) {
this.delegate = delegate;
}
@Override
public void write(byte[] b, int off, int len) {
try {
delegate.write(b, off, len);
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
@Override
public void write(byte[] b) {
try {
delegate.write(b);
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
@Override
public void write(int b) {
try {
delegate.write(b);
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
}
/**
* Holder for {@link ThreadLocal} pools.
*/
static class OutputAccessorPoolHolder {
private final ThreadLocal accessorPool = new ThreadLocal() {
@Override
protected ByteBufferOutputAccessor initialValue() {
return new ByteBufferOutputAccessor();
}
};
private final ThreadLocal streamPool = new ThreadLocal() {
@Override
protected ByteBufferOutputStream initialValue() {
return new ByteBufferOutputStream(null);
}
};
/**
* @return a pooled {@link ByteBufferOutputAccessor} instance.
*/
public ByteBufferOutputAccessor getByteBufferOutputAccessor() {
return accessorPool.get();
}
/**
* @return a pooled {@link ByteBufferOutputStream} instance.
*/
public ByteBufferOutputStream getByteBufferOutputStream() {
return streamPool.get();
}
}
}