package com.sissi.pipeline.out; import io.netty.buffer.ByteBuf; import io.netty.buffer.PooledByteBufAllocator; import io.netty.util.ReferenceCountUtil; import java.io.BufferedOutputStream; import java.io.IOException; import java.io.OutputStream; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.sissi.commons.Trace; import com.sissi.commons.apache.IOUtil; import com.sissi.context.JIDContext; import com.sissi.io.write.Writer; import com.sissi.pipeline.Output; import com.sissi.pipeline.OutputBuilder; import com.sissi.pipeline.Transfer; import com.sissi.pipeline.TransferBuffer; import com.sissi.protocol.Element; /** * @author kim 2013年12月1日 */ public class NetworkOutputBuilder implements OutputBuilder { private final Log log = LogFactory.getLog(this.getClass()); private final Writer writer; public NetworkOutputBuilder(Writer writer) { super(); this.writer = writer; } @Override public Output build(Transfer transfer) { return new NetworkOutut(transfer); } private class NetworkOutut implements Output { private final Transfer transfer; public NetworkOutut(Transfer transfer) { super(); this.transfer = transfer; } @Override public boolean output(JIDContext context, Element element) { ByteBufOutputTransferBuffer output = new ByteBufOutputTransferBuffer(); BufferedOutputStream buf = new BufferedOutputStream(output); try { NetworkOutputBuilder.this.writer.write(context, buf, element).flush(); this.transfer.transfer(output); } catch (Exception e) { NetworkOutputBuilder.this.log.error(e.toString()); Trace.trace(NetworkOutputBuilder.this.log, e); } finally { IOUtil.closeQuietly(buf); IOUtil.closeQuietly(output); } return false; } public Output close() { this.transfer.close(); return this; } private class ByteBufOutputTransferBuffer extends OutputStream implements TransferBuffer { private final ByteBuf buffer; public ByteBufOutputTransferBuffer() { super(); this.buffer = PooledByteBufAllocator.DEFAULT.buffer(); } @Override public void write(int b) throws IOException { this.buffer.writeByte(b); } public ByteBuf getBuffer() { return this.buffer; } @Override public TransferBuffer release() { if (this.buffer.refCnt() > 0) { ReferenceCountUtil.release(this.buffer); } return this; } } } }