package ro.isdc.wro.http.support;

import java.io.IOException;
import java.util.List;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ro.isdc.wro.WroRuntimeException;
import ro.isdc.wro.config.Context;
import ro.isdc.wro.http.WroFilter;
import ro.isdc.wro.model.resource.processor.ResourcePreProcessor;

/**
 * Allows configuration of a list of processors to be applied on the    
 * 
 * @author Alex Objelean
 * @since 1.4.5
 * @created 17 Mar 2012
 */
public abstract class AbstractProcessorFilter
    implements Filter {
  private static final Logger LOG = LoggerFactory.getLogger(WroFilter.class);
  private FilterConfig filterConfig;
  /**
   * {@inheritDoc}
   */
  public final void init(final FilterConfig config)
    throws ServletException {
    this.filterConfig = config;
  }
  
  /**
   * {@inheritDoc}
   */
  public void doFilter(final ServletRequest req, final ServletResponse res, final FilterChain chain)
      throws IOException, ServletException {
    final HttpServletRequest request = (HttpServletRequest) req;
    final HttpServletResponse response = (HttpServletResponse) res;
    try {
      // add request, response & servletContext to thread local
      Context.set(Context.webContext(request, response, filterConfig));
      chain.doFilter(req, res);
    } catch (final RuntimeException e) {
      onRuntimeException(e, response, chain);
    } finally {
      Context.unset();
    }
  }
  
  /**
   * Invoked when a {@link RuntimeException} is thrown. Allows custom exception handling. The default implementation
   * redirects to 404 for a specific {@link WroRuntimeException} exception when in DEPLOYMENT mode.
   *
   * @param e {@link RuntimeException} thrown during request processing.
   */
  protected void onRuntimeException(final RuntimeException e, final HttpServletResponse response,
    final FilterChain chain) {
    LOG.debug("RuntimeException occured", e);
    try {
      LOG.debug("Cannot process. Proceeding with chain execution.");
      chain.doFilter(Context.get().getRequest(), response);
    } catch (final Exception ex) {
      // should never happen
      LOG.error("Error while chaining the request: " + HttpServletResponse.SC_NOT_FOUND);
    }
  }

  /**
   * @return a list of processors to apply for this filter.
   */
  protected abstract List<ResourcePreProcessor> processorsList();
}

@@ -48,32 +48,60 @@
 io.IOException;%0A
+import java.io.PrintWriter;%0A
 import java.util
@@ -107,16 +107,16 @@
 l.List;%0A
-
 %0Aimport 
@@ -237,32 +237,74 @@
 rvletException;%0A
+import javax.servlet.ServletOutputStream;%0A
 import javax.ser
@@ -400,32 +400,32 @@
 ServletRequest;%0A
-
 import javax.ser
@@ -454,16 +454,70 @@
 esponse;
+%0Aimport javax.servlet.http.HttpServletResponseWrapper;
 %0A%0Aimport
@@ -2420,16 +2420,409 @@
 ion.%22);%0A
+      HttpServletResponse wrappedResponse = new HttpServletResponseWrapper(response) %7B%0A        /**%0A         * PrintWrapper of wrapped response.%0A         */%0A//        private PrintWriter pw = new PrintWriter(os);%0A//%0A//        /**%0A//         * Servlet output stream of wrapped response.%0A//         */%0A//        private ServletOutputStream sos = new DelegatingServletOutputStream(os);%0A%0A%0A      %7D;%0A
       ch
@@ -2862,17 +2862,24 @@
 uest(), 
-r
+wrappedR
 esponse)

wrap the response