You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by mr...@apache.org on 2008/06/28 09:25:06 UTC

svn commit: r672473 - in /struts/struts2/trunk/core/src: main/java/org/apache/struts2/dispatcher/ main/java/org/apache/struts2/dispatcher/filter/ test/java/org/apache/struts2/dispatcher/filter/ test/resources/ test/resources/org/apache/struts2/dispatch...

Author: mrdon
Date: Sat Jun 28 00:25:05 2008
New Revision: 672473

URL: http://svn.apache.org/viewvc?rev=672473&view=rev
Log:
Adding new filter tests, deprecating old filter
WW-2193

Added:
    struts/struts2/trunk/core/src/test/java/org/apache/struts2/dispatcher/filter/
    struts/struts2/trunk/core/src/test/java/org/apache/struts2/dispatcher/filter/StrutsPrepareAndExecuteFilterIntegrationTest.java
    struts/struts2/trunk/core/src/test/java/org/apache/struts2/dispatcher/filter/TwoFilterIntegrationTest.java
    struts/struts2/trunk/core/src/test/resources/org/apache/struts2/dispatcher/filter/
    struts/struts2/trunk/core/src/test/resources/org/apache/struts2/dispatcher/filter/struts-no-op.xml
Removed:
    struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/filter/CleanupOperations.java
Modified:
    struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/ActionContextCleanUp.java
    struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/Dispatcher.java
    struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/FilterDispatcher.java
    struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/FilterDispatcherCompatWeblogic61.java
    struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/filter/InitOperations.java
    struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/filter/PrepareOperations.java
    struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/filter/StrutsExecuteFilter.java
    struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/filter/StrutsPrepareAndExecuteFilter.java
    struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/filter/StrutsPrepareFilter.java
    struts/struts2/trunk/core/src/test/resources/struts.xml

Modified: struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/ActionContextCleanUp.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/ActionContextCleanUp.java?rev=672473&r1=672472&r2=672473&view=diff
==============================================================================
--- struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/ActionContextCleanUp.java (original)
+++ struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/ActionContextCleanUp.java Sat Jun 28 00:25:05 2008
@@ -59,8 +59,13 @@
  * <!-- SNIPPET END: description -->
  *
  *
+ * @deprecated Since Struts 2.1.3, use {@link org.apache.struts2.dispatcher.filter.StrutsPrepareFilter} and
+ * {@link org.apache.struts2.dispatcher.filter.StrutsExecuteFilter} to use other Servlet filters that need access to
+ * the ActionContext
  * @see FilterDispatcher
  * @see Dispatcher
+ * @see org.apache.struts2.dispatcher.filter.StrutsPrepareFilter
+ * @see org.apache.struts2.dispatcher.filter.StrutsExecuteFilter
  *
  * @version $Date$ $Id$
  */

Modified: struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/Dispatcher.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/Dispatcher.java?rev=672473&r1=672472&r2=672473&view=diff
==============================================================================
--- struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/Dispatcher.java (original)
+++ struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/Dispatcher.java Sat Jun 28 00:25:05 2008
@@ -418,6 +418,12 @@
 
         // If there was a previous value stack, then create a new copy and pass it in to be used by the new Action
         ValueStack stack = (ValueStack) request.getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);
+        if (stack == null) {
+            ActionContext ctx = ActionContext.getContext();
+            if (ctx != null) {
+                stack = ctx.getValueStack();
+            }
+        }
         if (stack != null) {
             extraContext.put(ActionContext.VALUE_STACK, valueStackFactory.createValueStack(stack));
         }

Modified: struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/FilterDispatcher.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/FilterDispatcher.java?rev=672473&r1=672472&r2=672473&view=diff
==============================================================================
--- struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/FilterDispatcher.java (original)
+++ struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/FilterDispatcher.java Sat Jun 28 00:25:05 2008
@@ -146,8 +146,15 @@
  * the subclass.
  *
  * @version $Date$ $Id$
+ * @deprecated Since Struts 2.1.3, use {@link org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter} instead or
+ * {@link org.apache.struts2.dispatcher.filter.StrutsPrepareFilter} and {@link org.apache.struts2.dispatcher.filter.StrutsExecuteFilter}
+ * if needing using the {@link ActionContextCleanUp} filter in addition to this one
+ *
  * @see ActionMapper
  * @see ActionContextCleanUp
+ * @see org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter
+ * @see org.apache.struts2.dispatcher.filter.StrutsPrepareFilter
+ * @see org.apache.struts2.dispatcher.filter.StrutsExecuteFilter
  */
 public class FilterDispatcher implements StrutsStatics, Filter {
 

Modified: struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/FilterDispatcherCompatWeblogic61.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/FilterDispatcherCompatWeblogic61.java?rev=672473&r1=672472&r2=672473&view=diff
==============================================================================
--- struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/FilterDispatcherCompatWeblogic61.java (original)
+++ struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/FilterDispatcherCompatWeblogic61.java Sat Jun 28 00:25:05 2008
@@ -47,6 +47,8 @@
  * must "swallow" the exception.  This it does by logging the
  * exception as an error.
  *
+ * @deprecated Since Struts 2.1.3 as it probably isn't used anymore
+ *
  */
 public class FilterDispatcherCompatWeblogic61 extends FilterDispatcher {
 

Modified: struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/filter/InitOperations.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/filter/InitOperations.java?rev=672473&r1=672472&r2=672473&view=diff
==============================================================================
--- struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/filter/InitOperations.java (original)
+++ struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/filter/InitOperations.java Sat Jun 28 00:25:05 2008
@@ -21,6 +21,7 @@
 package org.apache.struts2.dispatcher.filter;
 
 import com.opensymphony.xwork2.util.logging.LoggerFactory;
+import com.opensymphony.xwork2.ActionContext;
 import org.apache.struts2.dispatcher.Dispatcher;
 import org.apache.struts2.dispatcher.StaticContentLoader;
 import org.apache.struts2.util.ClassLoaderUtils;
@@ -103,4 +104,8 @@
         }
         return new Dispatcher(filterConfig.getServletContext(), params);
     }
+
+    public void cleanup() {
+        ActionContext.setContext(null);
+    }
 }

Modified: struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/filter/PrepareOperations.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/filter/PrepareOperations.java?rev=672473&r1=672472&r2=672473&view=diff
==============================================================================
--- struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/filter/PrepareOperations.java (original)
+++ struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/filter/PrepareOperations.java Sat Jun 28 00:25:05 2008
@@ -23,8 +23,8 @@
 import org.apache.struts2.dispatcher.Dispatcher;
 import org.apache.struts2.dispatcher.mapper.ActionMapping;
 import org.apache.struts2.dispatcher.mapper.ActionMapper;
+import org.apache.struts2.StrutsException;
 
-import javax.servlet.ServletConfig;
 import javax.servlet.ServletException;
 import javax.servlet.ServletContext;
 import javax.servlet.http.HttpServletRequest;
@@ -33,8 +33,11 @@
 import com.opensymphony.xwork2.ActionContext;
 import com.opensymphony.xwork2.util.ValueStack;
 import com.opensymphony.xwork2.util.ValueStackFactory;
+import com.opensymphony.xwork2.util.logging.Logger;
+import com.opensymphony.xwork2.util.logging.LoggerFactory;
 
 import java.io.IOException;
+import java.util.HashMap;
 
 /**
  * Contains preparation operations for a request before execution
@@ -44,6 +47,8 @@
     private ServletContext servletContext;
     private Dispatcher dispatcher;
     private static final String STRUTS_ACTION_MAPPING_KEY = "struts.actionMapping";
+    public static final String CLEANUP_RECURSION_COUNTER = "__cleanup_recursion_counter";
+    private Logger log = LoggerFactory.getLogger(PrepareOperations.class);
 
     public PrepareOperations(ServletContext servletContext, Dispatcher dispatcher) {
         this.dispatcher = dispatcher;
@@ -53,14 +58,49 @@
     /**
      * Creates the action context and initializes the thread local
      */
-    public ActionContext createActionContext() {
-        ValueStack stack = dispatcher.getContainer().getInstance(ValueStackFactory.class).createValueStack();
-        ActionContext ctx = new ActionContext(stack.getContext());
+    public ActionContext createActionContext(HttpServletRequest request) {
+        ActionContext ctx;
+        Integer counter = 1;
+        Integer oldCounter = (Integer) request.getAttribute(CLEANUP_RECURSION_COUNTER);
+        if (oldCounter != null) {
+            counter = oldCounter + 1;
+        }
+        
+        ActionContext oldContext = ActionContext.getContext();
+        if (oldContext != null) {
+            // detected existing context, so we are probably in a forward
+            ctx = new ActionContext(new HashMap<String, Object>(oldContext.getContextMap()));
+        } else {
+            ValueStack stack = dispatcher.getContainer().getInstance(ValueStackFactory.class).createValueStack();
+            ctx = new ActionContext(stack.getContext());
+        }
+        request.setAttribute(CLEANUP_RECURSION_COUNTER, counter);
         ActionContext.setContext(ctx);
         return ctx;
     }
 
     /**
+     * Cleans up a request of thread locals
+     */
+    public void cleanupRequest(HttpServletRequest request) {
+        Integer counterVal = (Integer) request.getAttribute(CLEANUP_RECURSION_COUNTER);
+        if (counterVal != null) {
+            counterVal -= 1;
+            request.setAttribute(CLEANUP_RECURSION_COUNTER, counterVal);
+            if (counterVal > 0 ) {
+                if (log.isDebugEnabled()) {
+                    log.debug("skipping cleanup counter="+counterVal);
+                }
+                return;
+            }
+        }
+
+        // always clean up the thread request, even if an action hasn't been executed
+        ActionContext.setContext(null);
+        Dispatcher.setInstance(null);
+    }
+
+    /**
      * Assigns the dispatcher to the dispatcher thread local
      */
     public void assignDispatcherToThread() {
@@ -113,5 +153,18 @@
         return mapping;
     }
 
-
+    /**
+     * Cleans up the dispatcher instance
+     */
+    public void cleanupDispatcher() {
+        if (dispatcher == null) {
+            throw new StrutsException("something is seriously wrong, Dispatcher is not initialized (null) ");
+        } else {
+            try {
+                dispatcher.cleanup();
+            } finally {
+                ActionContext.setContext(null);
+            }
+        }
+    }
 }

Modified: struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/filter/StrutsExecuteFilter.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/filter/StrutsExecuteFilter.java?rev=672473&r1=672472&r2=672473&view=diff
==============================================================================
--- struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/filter/StrutsExecuteFilter.java (original)
+++ struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/filter/StrutsExecuteFilter.java Sat Jun 28 00:25:05 2008
@@ -35,7 +35,6 @@
  */
 public class StrutsExecuteFilter implements StrutsStatics, Filter {
     private PrepareOperations prepare;
-    private CleanupOperations cleanup;
     private ExecuteOperations execute;
 
     private FilterConfig filterConfig;
@@ -47,16 +46,11 @@
     protected synchronized void lazyInit() {
         if (execute == null) {
             InitOperations init = new InitOperations();
-            try {
-                Dispatcher dispatcher = init.findDispatcherOnThread();
-                init.initStaticContentLoader(filterConfig, dispatcher);
-
-                prepare = new PrepareOperations(filterConfig.getServletContext(), dispatcher);
-                cleanup = new CleanupOperations(dispatcher);
-                execute = new ExecuteOperations(filterConfig.getServletContext(), dispatcher);
-            } finally {
-                cleanup.cleanupInit();
-            }
+            Dispatcher dispatcher = init.findDispatcherOnThread();
+            init.initStaticContentLoader(filterConfig, dispatcher);
+
+            prepare = new PrepareOperations(filterConfig.getServletContext(), dispatcher);
+            execute = new ExecuteOperations(filterConfig.getServletContext(), dispatcher);
         }
 
     }
@@ -83,7 +77,6 @@
     public void destroy() {
         prepare = null;
         execute = null;
-        cleanup = null;
         filterConfig = null;
     }
 }
\ No newline at end of file

Modified: struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/filter/StrutsPrepareAndExecuteFilter.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/filter/StrutsPrepareAndExecuteFilter.java?rev=672473&r1=672472&r2=672473&view=diff
==============================================================================
--- struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/filter/StrutsPrepareAndExecuteFilter.java (original)
+++ struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/filter/StrutsPrepareAndExecuteFilter.java Sat Jun 28 00:25:05 2008
@@ -35,7 +35,6 @@
  */
 public class StrutsPrepareAndExecuteFilter implements StrutsStatics, Filter {
     private PrepareOperations prepare;
-    private CleanupOperations cleanup;
     private ExecuteOperations execute;
 
     public void init(FilterConfig filterConfig) throws ServletException {
@@ -46,12 +45,9 @@
             init.initStaticContentLoader(filterConfig, dispatcher);
 
             prepare = new PrepareOperations(filterConfig.getServletContext(), dispatcher);
-            cleanup = new CleanupOperations(dispatcher);
             execute = new ExecuteOperations(filterConfig.getServletContext(), dispatcher);
         } finally {
-            if (cleanup != null) {
-                cleanup.cleanupInit();
-            }
+            init.cleanup();
         }
 
     }
@@ -62,7 +58,7 @@
         HttpServletResponse response = (HttpServletResponse) res;
 
         try {
-            prepare.createActionContext();
+            prepare.createActionContext(request);
             prepare.assignDispatcherToThread();
             prepare.setEncodingAndLocale(request, response);
             request = prepare.wrapRequest(request);
@@ -76,11 +72,11 @@
                 execute.executeAction(request, response, mapping);
             }
         } finally {
-            cleanup.cleanupRequest();
+            prepare.cleanupRequest(request);
         }
     }
 
     public void destroy() {
-        cleanup.cleanupDispatcher();
+        prepare.cleanupDispatcher();
     }
 }

Modified: struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/filter/StrutsPrepareFilter.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/filter/StrutsPrepareFilter.java?rev=672473&r1=672472&r2=672473&view=diff
==============================================================================
--- struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/filter/StrutsPrepareFilter.java (original)
+++ struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/filter/StrutsPrepareFilter.java Sat Jun 28 00:25:05 2008
@@ -33,7 +33,6 @@
  */
 public class StrutsPrepareFilter implements StrutsStatics, Filter {
     private PrepareOperations prepare;
-    private CleanupOperations cleanup;
 
     public void init(FilterConfig filterConfig) throws ServletException {
         InitOperations init = new InitOperations();
@@ -42,11 +41,8 @@
             Dispatcher dispatcher = init.initDispatcher(filterConfig);
 
             prepare = new PrepareOperations(filterConfig.getServletContext(), dispatcher);
-            cleanup = new CleanupOperations(dispatcher);
         } finally {
-            if (cleanup != null) {
-                cleanup.cleanupInit();
-            }
+            init.cleanup();
         }
 
     }
@@ -57,7 +53,7 @@
         HttpServletResponse response = (HttpServletResponse) res;
 
         try {
-            prepare.createActionContext();
+            prepare.createActionContext(request);
             prepare.assignDispatcherToThread();
             prepare.setEncodingAndLocale(request, response);
             request = prepare.wrapRequest(request);
@@ -65,11 +61,11 @@
 
             chain.doFilter(request, response);
         } finally {
-            cleanup.cleanupRequest();
+            prepare.cleanupRequest(request);
         }
     }
 
     public void destroy() {
-        cleanup.cleanupDispatcher();
+        prepare.cleanupDispatcher();
     }
 }
\ No newline at end of file

Added: struts/struts2/trunk/core/src/test/java/org/apache/struts2/dispatcher/filter/StrutsPrepareAndExecuteFilterIntegrationTest.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/test/java/org/apache/struts2/dispatcher/filter/StrutsPrepareAndExecuteFilterIntegrationTest.java?rev=672473&view=auto
==============================================================================
--- struts/struts2/trunk/core/src/test/java/org/apache/struts2/dispatcher/filter/StrutsPrepareAndExecuteFilterIntegrationTest.java (added)
+++ struts/struts2/trunk/core/src/test/java/org/apache/struts2/dispatcher/filter/StrutsPrepareAndExecuteFilterIntegrationTest.java Sat Jun 28 00:25:05 2008
@@ -0,0 +1,128 @@
+/*
+ * $Id: DefaultActionSupport.java 651946 2008-04-27 13:41:38Z apetrelli $
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.struts2.dispatcher.filter;
+
+import com.opensymphony.xwork2.ActionContext;
+import junit.framework.TestCase;
+import org.apache.struts2.dispatcher.Dispatcher;
+import org.springframework.mock.web.MockFilterChain;
+import org.springframework.mock.web.MockFilterConfig;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.mock.web.MockHttpServletResponse;
+
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import java.io.IOException;
+
+/**
+ * Integration tests for the filter
+ */
+public class StrutsPrepareAndExecuteFilterIntegrationTest extends TestCase {
+
+    public void test404() throws ServletException, IOException {
+        MockHttpServletRequest request = new MockHttpServletRequest();
+        MockHttpServletResponse response = new MockHttpServletResponse();
+        MockFilterConfig filterConfig = new MockFilterConfig();
+        MockFilterChain filterChain = new MockFilterChain() {
+            @Override
+            public void doFilter(ServletRequest req, ServletResponse res) {
+                fail("Shouldn't get here");
+            }
+        };
+
+        request.setRequestURI("/foo.action");
+        StrutsPrepareAndExecuteFilter filter = new StrutsPrepareAndExecuteFilter();
+        filter.init(filterConfig);
+        filter.doFilter(request, response, filterChain);
+        assertEquals(404, response.getStatus());
+        assertNull(ActionContext.getContext());
+        assertNull(Dispatcher.getInstance());
+    }
+
+    public void test200() throws ServletException, IOException {
+        MockHttpServletRequest request = new MockHttpServletRequest();
+        MockHttpServletResponse response = new MockHttpServletResponse();
+        MockFilterConfig filterConfig = new MockFilterConfig();
+        MockFilterChain filterChain = new MockFilterChain() {
+            @Override
+            public void doFilter(ServletRequest req, ServletResponse res) {
+                fail("Shouldn't get here");
+            }
+        };
+
+        request.setRequestURI("/hello.action");
+        StrutsPrepareAndExecuteFilter filter = new StrutsPrepareAndExecuteFilter();
+        filter.init(filterConfig);
+        filter.doFilter(request, response, filterChain);
+        assertEquals(200, response.getStatus());
+        assertNull(ActionContext.getContext());
+        assertNull(Dispatcher.getInstance());
+    }
+
+    public void testStaticFallthrough() throws ServletException, IOException {
+        MockHttpServletRequest request = new MockHttpServletRequest();
+        MockHttpServletResponse response = new MockHttpServletResponse();
+        MockFilterConfig filterConfig = new MockFilterConfig();
+        MockFilterChain filterChain = new MockFilterChain() {
+            @Override
+            public void doFilter(ServletRequest req, ServletResponse res) {
+                assertNotNull(ActionContext.getContext());
+                assertNotNull(Dispatcher.getInstance());
+                try {
+                    res.getWriter().write("found");
+                } catch (IOException e) {
+                    fail(e.getMessage());
+                }
+            }
+        };
+
+        request.setRequestURI("/foo.txt");
+        StrutsPrepareAndExecuteFilter filter = new StrutsPrepareAndExecuteFilter();
+        filter.init(filterConfig);
+        filter.doFilter(request, response, filterChain);
+        assertEquals(200, response.getStatus());
+        assertEquals("found", response.getContentAsString());
+        assertNull(ActionContext.getContext());
+        assertNull(Dispatcher.getInstance());
+    }
+
+    public void testStaticExecute() throws ServletException, IOException {
+        MockHttpServletRequest request = new MockHttpServletRequest();
+        MockHttpServletResponse response = new MockHttpServletResponse();
+        MockFilterConfig filterConfig = new MockFilterConfig();
+        MockFilterChain filterChain = new MockFilterChain() {
+            @Override
+            public void doFilter(ServletRequest req, ServletResponse res) {
+                fail("Should never get here");
+            }
+        };
+
+        request.setRequestURI("/struts/utils.js");
+        StrutsPrepareAndExecuteFilter filter = new StrutsPrepareAndExecuteFilter();
+        filter.init(filterConfig);
+        filter.doFilter(request, response, filterChain);
+        assertEquals(200, response.getStatus());
+        assertTrue(response.getContentAsString().contains("StrutsUtils"));
+        assertNull(ActionContext.getContext());
+        assertNull(Dispatcher.getInstance());
+    }
+}

Added: struts/struts2/trunk/core/src/test/java/org/apache/struts2/dispatcher/filter/TwoFilterIntegrationTest.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/test/java/org/apache/struts2/dispatcher/filter/TwoFilterIntegrationTest.java?rev=672473&view=auto
==============================================================================
--- struts/struts2/trunk/core/src/test/java/org/apache/struts2/dispatcher/filter/TwoFilterIntegrationTest.java (added)
+++ struts/struts2/trunk/core/src/test/java/org/apache/struts2/dispatcher/filter/TwoFilterIntegrationTest.java Sat Jun 28 00:25:05 2008
@@ -0,0 +1,150 @@
+/*
+ * $Id: DefaultActionSupport.java 651946 2008-04-27 13:41:38Z apetrelli $
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.struts2.dispatcher.filter;
+
+import com.opensymphony.xwork2.ActionContext;
+import com.opensymphony.xwork2.util.ValueStack;
+import com.opensymphony.xwork2.util.ValueStackFactory;
+import junit.framework.TestCase;
+import org.apache.struts2.dispatcher.Dispatcher;
+import org.springframework.mock.web.*;
+
+import javax.servlet.*;
+import java.io.IOException;
+import java.util.LinkedList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Collections;
+
+/**
+ * Integration tests for the filter
+ */
+public class TwoFilterIntegrationTest extends TestCase {
+    StrutsExecuteFilter filterExecute;
+    StrutsPrepareFilter filterPrepare;
+    Filter failFilter;
+    private Filter stringFilter;
+
+    public void setUp() {
+        filterPrepare = new StrutsPrepareFilter();
+        filterExecute = new StrutsExecuteFilter();
+        failFilter = new Filter() {
+            public void init(FilterConfig filterConfig) throws ServletException {}
+            public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
+                fail("Should never get here");
+            }
+            public void destroy() {}
+        };
+        stringFilter = new Filter() {
+            public void init(FilterConfig filterConfig) throws ServletException {}
+            public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
+                response.getWriter().write("content");
+                assertNotNull(ActionContext.getContext());
+                assertNotNull(Dispatcher.getInstance());
+            }
+            public void destroy() {}
+        };
+    }
+
+    public void test404() throws ServletException, IOException {
+        MockHttpServletResponse response = run("/foo.action", filterPrepare, filterExecute, failFilter);
+        assertEquals(404, response.getStatus());
+    }
+
+    public void test200() throws ServletException, IOException {
+        MockHttpServletResponse response = run("/hello.action", filterPrepare, filterExecute, failFilter);
+        assertEquals(200, response.getStatus());
+    }
+
+    public void testStaticFallthrough() throws ServletException, IOException {
+        MockHttpServletResponse response = run("/foo.txt", filterPrepare, filterExecute, stringFilter);
+        assertEquals(200, response.getStatus());
+        assertEquals("content", response.getContentAsString());
+
+    }
+
+    public void testStaticExecute() throws ServletException, IOException {
+        MockHttpServletResponse response = run("/struts/utils.js", filterPrepare, filterExecute, failFilter);
+        assertEquals(200, response.getStatus());
+        assertTrue(response.getContentAsString().contains("StrutsUtils"));
+    }
+
+    public void testFilterInMiddle() throws ServletException, IOException {
+        Filter middle = new Filter() {
+            public void init(FilterConfig filterConfig) throws ServletException {}
+            public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
+                assertNotNull(ActionContext.getContext());
+                assertNotNull(Dispatcher.getInstance());
+                assertNull(ActionContext.getContext().getActionInvocation());
+                chain.doFilter(request, response);
+                assertEquals("hello", ActionContext.getContext().getActionInvocation().getProxy().getActionName());
+            }
+            public void destroy() {}
+        };
+        MockHttpServletResponse response = run("/hello.action", filterPrepare, middle, filterExecute, failFilter);
+        assertEquals(200, response.getStatus());
+    }
+
+    private MockHttpServletResponse run(String uri, final Filter... filters) throws ServletException, IOException {
+        return run(uri, null, filters);
+    }
+    private MockHttpServletResponse run(String uri, ActionContext existingContext, final Filter... filters) throws ServletException, IOException {
+        final LinkedList<Filter> filterList = new LinkedList<Filter>(Arrays.asList(filters));
+        MockHttpServletRequest request = new MockHttpServletRequest();
+        MockHttpServletResponse response = new MockHttpServletResponse();
+        MockFilterConfig filterConfig = new MockFilterConfig();
+        MockFilterChain filterChain = new MockFilterChain() {
+            @Override
+            public void doFilter(ServletRequest req, ServletResponse res) {
+                Filter next = (filterList.size() > 0 ? filterList.removeFirst() : null);
+                if (next != null) {
+                    try {
+                        next.doFilter(req, res, this);
+                    } catch (IOException e) {
+                        throw new RuntimeException(e);
+                    } catch (ServletException e) {
+                        throw new RuntimeException(e);
+                    }
+                }
+            }
+        };
+
+        if (existingContext != null) {
+            request.setAttribute(PrepareOperations.CLEANUP_RECURSION_COUNTER, 1);
+        }
+        request.setRequestURI(uri);
+        for (Filter filter : filters) {
+            filter.init(filterConfig);
+        }
+
+        ActionContext.setContext(existingContext);
+        filterList.removeFirst().doFilter(request, response, filterChain);
+        if (existingContext == null) {
+            assertNull(ActionContext.getContext());
+            assertNull(Dispatcher.getInstance());
+        } else {
+            assertEquals(Integer.valueOf(1), request.getAttribute(PrepareOperations.CLEANUP_RECURSION_COUNTER));
+        }
+        return response;
+    }
+
+
+}
\ No newline at end of file

Added: struts/struts2/trunk/core/src/test/resources/org/apache/struts2/dispatcher/filter/struts-no-op.xml
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/test/resources/org/apache/struts2/dispatcher/filter/struts-no-op.xml?rev=672473&view=auto
==============================================================================
--- struts/struts2/trunk/core/src/test/resources/org/apache/struts2/dispatcher/filter/struts-no-op.xml (added)
+++ struts/struts2/trunk/core/src/test/resources/org/apache/struts2/dispatcher/filter/struts-no-op.xml Sat Jun 28 00:25:05 2008
@@ -0,0 +1,26 @@
+<!--
+/*
+ * $Id: struts.xml 590812 2007-10-31 20:32:54Z apetrelli $
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+-->
+<!DOCTYPE struts PUBLIC
+          "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
+          "http://struts.apache.org/dtds/struts-2.0.dtd">
+<struts /> 
\ No newline at end of file

Modified: struts/struts2/trunk/core/src/test/resources/struts.xml
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/test/resources/struts.xml?rev=672473&r1=672472&r2=672473&view=diff
==============================================================================
--- struts/struts2/trunk/core/src/test/resources/struts.xml (original)
+++ struts/struts2/trunk/core/src/test/resources/struts.xml Sat Jun 28 00:25:05 2008
@@ -24,7 +24,6 @@
           "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
           "http://struts.apache.org/dtds/struts-2.0.dtd">
 <struts>
-	<include file="struts-default.xml" />
     <package name="default" extends="struts-default">
         <action name="hello" class="com.opensymphony.xwork2.ActionSupport">
             <result name="success">hello.jsp</result>