/******************************************************************************* * Copyright © 2010, 2013 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation * *******************************************************************************/ package org.eclipse.edt.javart.util.gzip; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.zip.GZIPOutputStream; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; import org.eclipse.edt.javart.resources.Trace; public class CompressionServletOutputStream extends ServletOutputStream { protected int compressionThreshold = 0; protected byte[] buffer = null; protected int bufferCount = 0; protected GZIPOutputStream gzipstream = null; protected boolean closed = false; protected int length = -1; protected HttpServletResponse response = null; protected ServletOutputStream output = null; private ByteArrayOutputStream byteStream = null; protected int beforeCompress; protected int afterCompress; protected Trace tracer; protected static final String CLOSED_STREAM_MSG = "This output stream has already been closed"; protected static final String CANNOT_WRITE_MSG = "Cannot write to a closed output stream"; public CompressionServletOutputStream(HttpServletResponse response, Trace tracer) throws IOException { super(); closed = false; this.response = response; this.output = response.getOutputStream(); this.tracer = tracer; } protected void setBuffer(int threshold) { compressionThreshold = threshold; buffer = new byte[compressionThreshold]; } public void close() throws IOException { if (closed) throw new IOException( CLOSED_STREAM_MSG ); if (gzipstream != null) { flushToGZip(); gzipstream.close(); gzipstream = null; if ( tracer.traceIsOn() ) { afterCompress += byteStream.size(); byteStream.writeTo( output ); byteStream.close(); tracer.put( "Befor Compress: " + beforeCompress + " After Compress: " + afterCompress ); } } else { if (bufferCount > 0) { output.write(buffer, 0, bufferCount); bufferCount = 0; } } output.close(); closed = true; } public void flush() throws IOException { if (closed) { throw new IOException(""); } if (gzipstream != null) { gzipstream.flush(); } } public void flushToGZip() throws IOException { if (bufferCount > 0) { writeToGZip(buffer, 0, bufferCount); bufferCount = 0; } } public void write(int b) throws IOException { if (closed) throw new IOException( CLOSED_STREAM_MSG ); if (bufferCount >= buffer.length) { flushToGZip(); } buffer[bufferCount++] = (byte) b; } public void write(byte b[]) throws IOException { write(b, 0, b.length); } public void write(byte b[], int off, int len) throws IOException { if (closed) throw new IOException( CANNOT_WRITE_MSG ); if (len == 0) return; if (len <= (buffer.length - bufferCount)) { System.arraycopy(b, off, buffer, bufferCount, len); bufferCount += len; return; } flushToGZip(); if (len <= (buffer.length - bufferCount)) { System.arraycopy(b, off, buffer, bufferCount, len); bufferCount += len; return; } writeToGZip(b, off, len); } public void writeToGZip(byte b[], int off, int len) throws IOException { if (gzipstream == null) { response.addHeader("Content-Encoding", "gzip"); if ( tracer.traceIsOn() ) { byteStream = new ByteArrayOutputStream(); gzipstream = new GZIPOutputStream(byteStream); } else { gzipstream = new GZIPOutputStream(output); } } gzipstream.write(b, off, len); if ( tracer.traceIsOn() ) { beforeCompress += len; } } }