import javax.servlet.FilterChain;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.util.zip.GZIPOutputStream;
import java.util.StringTokenizer;
   
   
public class GZIPFilter extends GenericFilter
 {
   
    public GZIPFilter() {}
   
    private boolean _findGZIP(String ae) {
       if(ae == null)
          return false;
       StringTokenizer sTok = new StringTokenizer(ae, ", ");
       String gzip = "gzip";
       String sub;
       while(sTok.hasMoreTokens()) {
          sub = sTok.nextToken();
          if(gzip.equalsIgnoreCase(sub))
             return true;
       }
       return false;
    }
   
    public void doFilter(final ServletRequest request, final ServletResponse response, FilterChain chain) throws java.io.IOException, javax.servlet.ServletException
    {
        GenericResponseWrapper wrapper = new GenericResponseWrapper((HttpServletResponse) response);
        chain.doFilter(request, wrapper);
        if(response.isCommitted())
           return;
         OutputStream out = response.getOutputStream();
         HttpServletRequest req = (HttpServletRequest)request;
         String acceptEncoding = req.getHeader("Accept-Encoding");
         if (_findGZIP(acceptEncoding)
             && notCached(wrapper) 
             && notInclude(request))
         {
             ByteArrayOutputStream compressed = new ByteArrayOutputStream();
             GZIPOutputStream gzout = new GZIPOutputStream(compressed);
             gzout.write(wrapper.getData());
             gzout.close();
             HttpServletResponse httpResponse = (HttpServletResponse) response;
             httpResponse.setHeader("Content-Encoding", "gzip");
             out.write(compressed.toByteArray());
             response.setContentLength(compressed.size());
         }
         else
         {
             out.write(wrapper.getData());
         }
    }
   
    protected boolean notInclude(ServletRequest request)
    {
        String uri = (String) request.getAttribute("javax.servlet.include.request_uri");
        if (uri == null)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
   
    protected boolean notCached(GenericResponseWrapper wrapper)
    {
        if (wrapper.getData().length > 0)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
}
