You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by tm...@apache.org on 2006/11/05 08:47:20 UTC
svn commit: r471375 - in /struts/struts2/trunk/core/src:
main/java/org/apache/struts2/dispatcher/
test/java/org/apache/struts2/dispatcher/
Author: tmjee
Date: Sat Nov 4 23:47:19 2006
New Revision: 471375
URL: http://svn.apache.org/viewvc?view=rev&rev=471375
Log:
WW-1489
- Refactor ActionContextCleanUp and DispatcherFilter to have common logics in an abstract super class
Added:
struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/AbstractFilter.java
struts/struts2/trunk/core/src/test/java/org/apache/struts2/dispatcher/ActionContextCleanUpTest.java
struts/struts2/trunk/core/src/test/java/org/apache/struts2/dispatcher/FilterTest.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/FilterDispatcher.java
struts/struts2/trunk/core/src/test/java/org/apache/struts2/dispatcher/FilterDispatcherTest.java
Added: struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/AbstractFilter.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/AbstractFilter.java?view=auto&rev=471375
==============================================================================
--- struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/AbstractFilter.java (added)
+++ struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/AbstractFilter.java Sat Nov 4 23:47:19 2006
@@ -0,0 +1,191 @@
+/*
+ * $Id: ActionContextCleanUp.java 454720 2006-10-10 12:31:52Z tmjee $
+ *
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed 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;
+
+import java.io.IOException;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * An abstract for superclass for Struts2 filter, encapsulating common logics and
+ * helper methods usefull to subclass, to avoid duplication.
+ *
+ * Common logics encapsulated:-
+ * <ul>
+ * <li>
+ * Dispatcher instance creation through <code>createDispatcher</code> method that acts
+ * as a hook subclass could override. By default it creates an instance of Dispatcher.
+ * </li>
+ * <li>
+ * <code>postInit(FilterConfig)</code> is a hook subclass may use to add post initialization
+ * logics in <code>{@link javax.servlet.Filter#init(FilterConfig)}</code>. It is called before
+ * {@link javax.servlet.Filter#init(FilterConfig)} method ends.
+ * </li>
+ * <li>
+ * A default <code>{@link javax.servlet.Filter#destroy()}</code> that clean up Dispatcher by
+ * calling <code>dispatcher.cleanup()</code>
+ * </li>
+ * <li>
+ * <code>prepareDispatcherAndWrapRequest(HttpServletRequest, HttpServletResponse)</code> helper method
+ * that basically called <code>dispatcher.prepare()</code>, wrap the HttpServletRequest and return the
+ * wrapped version.
+ * </li>
+ * <li>
+ * Various other common helper methods like
+ * <ul>
+ * <li>getFilterConfig</li>
+ * <li>getServletContext</li>
+ * </ul>
+ * </li>
+ * </ul>
+ *
+ *
+ * @see Dispatcher
+ * @see FilterDispatcher
+ * @see ActionContextCleanUp
+ *
+ * @version $Date$ $Id$
+ */
+public abstract class AbstractFilter implements Filter {
+
+ private static final Log LOG = LogFactory.getLog(AbstractFilter.class);
+
+ /** Internal copy of dispatcher, created when Filter instance gets initialized. */
+ private Dispatcher _dispatcher;
+
+ protected FilterConfig filterConfig;
+
+ /** Dispatcher instance to be used by subclass. */
+ protected Dispatcher dispatcher;
+
+
+ /**
+ * Initializes the filter
+ *
+ * @param filterConfig The filter configuration
+ */
+ public void init(FilterConfig filterConfig) throws ServletException {
+ this.filterConfig = filterConfig;
+ _dispatcher = createDispatcher();
+ postInit(filterConfig);
+ }
+
+ /**
+ * Cleans up the dispatcher
+ *
+ * @see javax.servlet.Filter#destroy()
+ */
+ public void destroy() {
+ if (_dispatcher == null) {
+ LOG.warn("something is seriously wrong, Dispatcher is not initialized (null) ");
+ } else {
+ _dispatcher.cleanup();
+ }
+ }
+
+ /**
+ * Hook for subclass todo custom initialization, called after
+ * <code>javax.servlet.Filter.init(FilterConfig)</code>.
+ *
+ * @param filterConfig
+ * @throws ServletException
+ */
+ protected abstract void postInit(FilterConfig filterConfig) throws ServletException;
+
+ /**
+ * Create a {@link Dispatcher}, this serves as a hook for subclass to overried
+ * such that a custom {@link Dispatcher} could be created.
+ *
+ * @return Dispatcher
+ */
+ protected Dispatcher createDispatcher() {
+ return new Dispatcher(filterConfig.getServletContext());
+ }
+
+ /**
+ * Servlet 2.3 specifies that the servlet context can be retrieved from the session. Unfortunately, some versions of
+ * WebLogic can only retrieve the servlet context from the filter config. Hence, this method enables subclasses to
+ * retrieve the servlet context from other sources.
+ *
+ * @param session the HTTP session where, in Servlet 2.3, the servlet context can be retrieved
+ * @return the servlet context.
+ */
+ protected ServletContext getServletContext() {
+ return filterConfig.getServletContext();
+ }
+
+ /**
+ * Gets this filter's configuration
+ *
+ * @return The filter config
+ */
+ protected FilterConfig getFilterConfig() {
+ return filterConfig;
+ }
+
+ /**
+ * Helper method that prepare <code>Dispatcher</code>
+ * (by calling <code>Dispatcher.prepare(HttpServletRequest, HttpServletResponse)</code>)
+ * following by wrapping and returning the wrapping <code>HttpServletRequest</code> [ through
+ * <code>dispatcher.wrapRequest(HttpServletRequest, ServletContext)</code> ]
+ *
+ * @param request
+ * @param response
+ * @return HttpServletRequest
+ * @throws ServletException
+ */
+ protected HttpServletRequest prepareDispatcherAndWrapRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException {
+
+ Dispatcher du = Dispatcher.getInstance();
+
+ // Prepare and wrap the request if the cleanup filter hasn't already, cleanup filter should be
+ // configured first before struts2 dispatcher filter, hence when its cleanup filter's turn,
+ // static instance of Dispatcher should be null.
+ if (du == null) {
+ dispatcher = _dispatcher;
+
+ Dispatcher.setInstance(dispatcher);
+
+ // prepare the request no matter what - this ensures that the proper character encoding
+ // is used before invoking the mapper (see WW-9127)
+ dispatcher.prepare(request, response);
+
+ try {
+ // Wrap request first, just in case it is multipart/form-data
+ // parameters might not be accessible through before encoding (ww-1278)
+ request = dispatcher.wrapRequest(request, getServletContext());
+ } catch (IOException e) {
+ String message = "Could not wrap servlet request with MultipartRequestWrapper!";
+ LOG.error(message, e);
+ throw new ServletException(message, e);
+ }
+ }
+ else {
+ dispatcher = du;
+ }
+ return request;
+ }
+}
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?view=diff&rev=471375&r1=471374&r2=471375
==============================================================================
--- 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 Nov 4 23:47:19 2006
@@ -19,10 +19,8 @@
import java.io.IOException;
-import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
-import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
@@ -56,29 +54,28 @@
* </ul>
* <!-- SNIPPET END: description -->
*
- * @version $Date$ $Id$
*
* @see FilterDispatcher
+ * @see AbstractFilter
+ * @see Dispatcher
+ *
+ * @version $Date$ $Id$
*/
-public class ActionContextCleanUp implements Filter {
+public class ActionContextCleanUp extends AbstractFilter {
private static final Log LOG = LogFactory.getLog(ActionContextCleanUp.class);
private static final String COUNTER = "__cleanup_recursion_counter";
protected FilterConfig filterConfig;
- protected Dispatcher dispatcher;
+
/**
- * Initializes the filter
- *
- * @param filterConfig The filter configuration
+ * Empty implementation.
*/
- public void init(FilterConfig filterConfig) throws ServletException {
- this.filterConfig = filterConfig;
- dispatcher = new Dispatcher(filterConfig.getServletContext());
+ protected void postInit(FilterConfig filterConfig) throws ServletException {
+ // does nothing.
}
-
/**
* @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
@@ -92,19 +89,7 @@
try {
UtilTimerStack.push(timerKey);
- // prepare the request no matter what - this ensures that the proper character encoding
- // is used before invoking the mapper (see WW-9127)
- Dispatcher.setInstance(dispatcher);
- dispatcher.prepare(request, response);
-
- ServletContext servletContext = filterConfig.getServletContext();
- try {
- request = dispatcher.wrapRequest(request, servletContext);
- } catch (IOException e) {
- String message = "Could not wrap servlet request with MultipartRequestWrapper!";
- LOG.error(message, e);
- throw new ServletException(message, e);
- }
+ request = prepareDispatcherAndWrapRequest(request, response);
try {
Integer count = (Integer)request.getAttribute(COUNTER);
@@ -115,6 +100,11 @@
count = new Integer(count.intValue()+1);
}
request.setAttribute(COUNTER, count);
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("filtering counter="+count);
+ }
+
chain.doFilter(request, response);
} finally {
int counterVal = ((Integer)request.getAttribute(COUNTER)).intValue();
@@ -135,21 +125,20 @@
*/
protected static void cleanUp(ServletRequest req) {
// should we clean up yet?
- if (req.getAttribute(COUNTER) != null &&
- ((Integer)req.getAttribute(COUNTER)).intValue() > 0 ) {
- return;
- }
+ Integer count = (Integer) req.getAttribute(COUNTER);
+ if (count != null && count > 0 ) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("skipping cleanup counter="+count);
+ }
+ return;
+ }
// always dontClean up the thread request, even if an action hasn't been executed
ActionContext.setContext(null);
-
Dispatcher.setInstance(null);
- }
-
-
- /* (non-Javadoc)
- * @see javax.servlet.Filter#destroy()
- */
- public void destroy() {
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("clean up ");
+ }
}
}
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?view=diff&rev=471375&r1=471374&r2=471375
==============================================================================
--- 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 Nov 4 23:47:19 2006
@@ -28,7 +28,6 @@
import java.util.StringTokenizer;
import java.util.TimeZone;
-import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
@@ -37,7 +36,6 @@
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpSession;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -118,49 +116,30 @@
*
* @version $Date$ $Id$
*/
-public class FilterDispatcher implements Filter, StrutsStatics {
+public class FilterDispatcher extends AbstractFilter implements StrutsStatics {
+
private static final Log LOG = LogFactory.getLog(FilterDispatcher.class);
- private FilterConfig filterConfig;
private String[] pathPrefixes;
- private Dispatcher dispatcher;
private SimpleDateFormat df = new SimpleDateFormat("E, d MMM yyyy HH:mm:ss");
private final Calendar lastModifiedCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
private final String lastModified = df.format(lastModifiedCal.getTime());
- /**
- * Gets this filter's configuration
- *
- * @return The filter config
- */
- protected FilterConfig getFilterConfig() {
- return filterConfig;
- }
-
- /**
- * Cleans up the dispatcher
- */
- public void destroy() {
- if (dispatcher == null) {
- LOG.warn("something is seriously wrong, DispatcherUtil is not initialized (null) ");
- } else {
- dispatcher.cleanup();
- }
- }
-
+
/**
- * Initializes the dispatcher and filter
+ * Look for "packages" defined through filter-config's parameters.
+ *
+ * @param FilterConfig
+ * @throws ServletException
*/
- public void init(FilterConfig filterConfig) throws ServletException {
- this.filterConfig = filterConfig;
- String param = filterConfig.getInitParameter("packages");
+ protected void postInit(FilterConfig filterConfig) throws ServletException {
+ String param = filterConfig.getInitParameter("packages");
String packages = "org.apache.struts2.static template org.apache.struts2.interceptor.debugging";
if (param != null) {
packages = param + " " + packages;
}
this.pathPrefixes = parse(packages);
- dispatcher = createDispatcher();
}
/**
@@ -188,45 +167,29 @@
}
- /* (non-Javadoc)
+ /**
* @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
*/
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
- ServletContext servletContext = filterConfig.getServletContext();
+ ServletContext servletContext = getServletContext();
String timerKey = "FilterDispatcher_doFilter: ";
try {
UtilTimerStack.push(timerKey);
- Dispatcher du = Dispatcher.getInstance();
- // Prepare and wrap the request if the cleanup filter hasn't already
- if (du == null) {
- du = dispatcher;
- // prepare the request no matter what - this ensures that the proper character encoding
- // is used before invoking the mapper (see WW-9127)
- du.prepare(request, response);
-
- try {
- // Wrap request first, just in case it is multipart/form-data
- // parameters might not be accessible through before encoding (ww-1278)
- request = du.wrapRequest(request, servletContext);
- } catch (IOException e) {
- String message = "Could not wrap servlet request with MultipartRequestWrapper!";
- LOG.error(message, e);
- throw new ServletException(message, e);
- }
- Dispatcher.setInstance(du);
- }
+ request = prepareDispatcherAndWrapRequest(request, response);
+
ActionMapper mapper = null;
ActionMapping mapping = null;
try {
mapper = ActionMapperFactory.getMapper();
- mapping = mapper.getMapping(request, du.getConfigurationManager());
+ mapping = mapper.getMapping(request, dispatcher.getConfigurationManager());
} catch (Exception ex) {
- du.sendError(request, response, servletContext, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, ex);
+ LOG.error("error getting ActionMapping", ex);
+ dispatcher.sendError(request, response, servletContext, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, ex);
ActionContextCleanUp.cleanUp(req);
return;
}
@@ -264,18 +227,6 @@
}
/**
- * Servlet 2.3 specifies that the servlet context can be retrieved from the session. Unfortunately, some versions of
- * WebLogic can only retrieve the servlet context from the filter config. Hence, this method enables subclasses to
- * retrieve the servlet context from other sources.
- *
- * @param session the HTTP session where, in Servlet 2.3, the servlet context can be retrieved
- * @return the servlet context.
- */
- protected ServletContext getServletContext(HttpSession session) {
- return filterConfig.getServletContext();
- }
-
- /**
* Finds a static resource
*
* @param name The resource name
@@ -385,15 +336,5 @@
resourcePath = URLDecoder.decode(resourcePath, enc);
return ClassLoaderUtil.getResourceAsStream(resourcePath, getClass());
- }
-
- /**
- * Create a {@link Dispatcher}, this serves as a hook for subclass to overried
- * such that a custom {@link Dispatcher} could be created.
- *
- * @return Dispatcher
- */
- protected Dispatcher createDispatcher() {
- return new Dispatcher(filterConfig.getServletContext());
}
}
Added: struts/struts2/trunk/core/src/test/java/org/apache/struts2/dispatcher/ActionContextCleanUpTest.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/test/java/org/apache/struts2/dispatcher/ActionContextCleanUpTest.java?view=auto&rev=471375
==============================================================================
--- struts/struts2/trunk/core/src/test/java/org/apache/struts2/dispatcher/ActionContextCleanUpTest.java (added)
+++ struts/struts2/trunk/core/src/test/java/org/apache/struts2/dispatcher/ActionContextCleanUpTest.java Sat Nov 4 23:47:19 2006
@@ -0,0 +1,205 @@
+/*
+ * $Id: FilterDispatcherTest.java 449367 2006-09-24 06:49:04Z mrdon $
+ *
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed 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;
+
+import java.io.IOException;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.struts2.dispatcher.mapper.ActionMapping;
+import org.springframework.mock.web.MockFilterConfig;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.mock.web.MockHttpServletResponse;
+import org.springframework.mock.web.MockServletContext;
+
+import com.mockobjects.servlet.MockFilterChain;
+
+import junit.framework.TestCase;
+
+/**
+ * @version $Date$ $Id$
+ */
+public class ActionContextCleanUpTest extends TestCase {
+
+
+ protected MockFilterConfig filterConfig;
+ protected MockHttpServletRequest request;
+ protected MockHttpServletResponse response;
+ protected MockFilterChain filterChain;
+ protected MockFilterChain filterChain2;
+ protected MockServletContext servletContext;
+
+ protected Counter counter;
+ protected Map<String, Integer> _tmpStore;
+ protected InnerDispatcher _dispatcher;
+ protected InnerDispatcher _dispatcher2;
+ protected ActionContextCleanUp cleanUp;
+ protected ActionContextCleanUp cleanUp2;
+
+
+ @Override
+ protected void tearDown() throws Exception {
+ filterConfig = null;
+ request = null;
+ response = null;
+ filterChain = null;
+ filterChain2 = null;
+ servletContext = null;
+ counter = null;
+ _tmpStore = null;
+ _dispatcher = null;
+ _dispatcher2 = null;
+ cleanUp = null;
+ cleanUp2 = null;
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ Dispatcher.setInstance(null);
+
+ counter = new Counter();
+ _tmpStore = new LinkedHashMap<String, Integer>();
+
+ filterConfig = new MockFilterConfig();
+ request = new MockHttpServletRequest();
+ response = new MockHttpServletResponse();
+ servletContext = new MockServletContext();
+ _dispatcher = new InnerDispatcher(servletContext) {
+ @Override
+ public String toString() {
+ return "dispatcher";
+ }
+ };
+ _dispatcher2 = new InnerDispatcher(servletContext){
+ @Override
+ public String toString() {
+ return "dispatcher2";
+ }
+ };
+
+
+ filterChain = new MockFilterChain() {
+ @Override
+ public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
+ _tmpStore.put("counter"+(counter.count++), (Integer) request.getAttribute("__cleanup_recursion_counter"));
+ }
+ };
+
+ cleanUp = new ActionContextCleanUp() {
+ @Override
+ protected Dispatcher createDispatcher() {
+ return _dispatcher;
+ }
+ };
+
+ cleanUp2 = new ActionContextCleanUp() {
+ @Override
+ protected Dispatcher createDispatcher() {
+ return _dispatcher2;
+ }
+ };
+
+ filterChain2 = new MockFilterChain() {
+ @Override
+ public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
+ _tmpStore.put("counter"+(counter.count++), (Integer) request.getAttribute("__cleanup_recursion_counter"));
+ cleanUp2.doFilter(request, response, filterChain);
+ }
+ };
+ }
+
+
+ public void testSingle() throws Exception {
+ assertFalse(_dispatcher.prepare);
+ assertFalse(_dispatcher.wrapRequest);
+ assertNull(request.getAttribute("__cleanup_recursion_counter"));
+
+ cleanUp.init(filterConfig);
+ cleanUp.doFilter(request, response, filterChain);
+ cleanUp.destroy();
+
+ assertEquals(_tmpStore.size(), 1);
+ assertEquals(_tmpStore.get("counter0"), new Integer(1));
+
+ assertTrue(_dispatcher.prepare);
+ assertTrue(_dispatcher.wrapRequest);
+ assertEquals(request.getAttribute("__cleanup_recursion_counter"), new Integer("0"));
+ }
+
+ public void testMultiple() throws Exception {
+ assertFalse(_dispatcher.prepare);
+ assertFalse(_dispatcher.wrapRequest);
+ assertFalse(_dispatcher2.prepare);
+ assertFalse(_dispatcher2.wrapRequest);
+ assertNull(request.getAttribute("__cleanup_recursion_counter"));
+
+ cleanUp.init(filterConfig);
+ cleanUp2.init(filterConfig);
+ cleanUp.doFilter(request, response, filterChain2);
+ cleanUp2.destroy();
+ cleanUp.destroy();
+
+ assertEquals(_tmpStore.size(), 2);
+ assertEquals(_tmpStore.get("counter0"), new Integer(1));
+ assertEquals(_tmpStore.get("counter1"), new Integer(2));
+
+ assertFalse(_dispatcher2.prepare);
+ assertFalse(_dispatcher2.wrapRequest);
+ assertTrue(_dispatcher.prepare);
+ assertTrue(_dispatcher.wrapRequest);
+ assertEquals(request.getAttribute("__cleanup_recursion_counter"), new Integer("0"));
+ }
+
+
+ class InnerDispatcher extends Dispatcher {
+ public boolean prepare = false;
+ public boolean wrapRequest = false;
+ public boolean service = false;
+
+ public InnerDispatcher(ServletContext servletContext) {
+ super(servletContext);
+ }
+
+ @Override
+ public void prepare(HttpServletRequest request, HttpServletResponse response) {
+ prepare = true;
+ }
+
+ @Override
+ public HttpServletRequest wrapRequest(HttpServletRequest request, ServletContext servletContext) throws IOException {
+ wrapRequest = true;
+ return request;
+ }
+
+ @Override
+ public void serviceAction(HttpServletRequest request, HttpServletResponse response, ServletContext context, ActionMapping mapping) throws ServletException {
+ service = true;
+ }
+ }
+
+ class Counter {
+ public int count=0;
+ }
+}
Modified: struts/struts2/trunk/core/src/test/java/org/apache/struts2/dispatcher/FilterDispatcherTest.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/test/java/org/apache/struts2/dispatcher/FilterDispatcherTest.java?view=diff&rev=471375&r1=471374&r2=471375
==============================================================================
--- struts/struts2/trunk/core/src/test/java/org/apache/struts2/dispatcher/FilterDispatcherTest.java (original)
+++ struts/struts2/trunk/core/src/test/java/org/apache/struts2/dispatcher/FilterDispatcherTest.java Sat Nov 4 23:47:19 2006
@@ -47,11 +47,13 @@
/**
* FilterDispatcher TestCase.
*
+ * @version $Date$ $Id$
*/
public class FilterDispatcherTest extends StrutsTestCase {
public void testParsePackages() throws Exception {
+
FilterDispatcher filterDispatcher = new FilterDispatcher();
String[] result1 = filterDispatcher.parse("foo.bar.package1 foo.bar.package2 foo.bar.package3");
String[] result2 = filterDispatcher.parse("foo.bar.package1\tfoo.bar.package2\tfoo.bar.package3");
@@ -136,12 +138,12 @@
MockHttpServletRequest req = new MockHttpServletRequest(servletContext);
MockHttpServletResponse res = new MockHttpServletResponse();
MockFilterChain chain = new MockFilterChain();
- final NoOpDispatcher dispatcher = new NoOpDispatcher(servletContext);
+ final NoOpDispatcher _dispatcher = new NoOpDispatcher(servletContext);
Dispatcher.setInstance(null);
ConfigurationManager confManager = new ConfigurationManager();
confManager.setConfiguration(new DefaultConfiguration());
- dispatcher.setConfigurationManager(confManager);
+ _dispatcher.setConfigurationManager(confManager);
ObjectFactory.setObjectFactory(new InnerObjectFactory());
@@ -152,13 +154,13 @@
FilterDispatcher filter = new FilterDispatcher() {
protected Dispatcher createDispatcher() {
- return dispatcher;
+ return _dispatcher;
}
};
filter.init(filterConfig);
filter.doFilter(req, res, chain);
- assertFalse(dispatcher.serviceRequest);
+ assertFalse(_dispatcher.serviceRequest);
}
finally {
Settings.reset();
@@ -172,12 +174,12 @@
MockHttpServletRequest req = new MockHttpServletRequest(servletContext);
MockHttpServletResponse res = new MockHttpServletResponse();
MockFilterChain chain = new MockFilterChain();
- final InnerDispatcher dispatcher = new InnerDispatcher(servletContext);
+ final InnerDispatcher _dispatcher = new InnerDispatcher(servletContext);
Dispatcher.setInstance(null);
ConfigurationManager confManager = new ConfigurationManager();
confManager.setConfiguration(new DefaultConfiguration());
- dispatcher.setConfigurationManager(confManager);
+ _dispatcher.setConfigurationManager(confManager);
ObjectFactory.setObjectFactory(new InnerObjectFactory());
@@ -189,14 +191,14 @@
FilterDispatcher filter = new FilterDispatcher() {
protected Dispatcher createDispatcher() {
- return dispatcher;
+ return _dispatcher;
}
};
filter.init(filterConfig);
filter.doFilter(req, res, chain);
- assertTrue(dispatcher.wrappedRequest);
- assertTrue(dispatcher.serviceRequest);
+ assertTrue(_dispatcher.wrappedRequest);
+ assertTrue(_dispatcher.serviceRequest);
}
finally {
Settings.reset();
Added: struts/struts2/trunk/core/src/test/java/org/apache/struts2/dispatcher/FilterTest.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/test/java/org/apache/struts2/dispatcher/FilterTest.java?view=auto&rev=471375
==============================================================================
--- struts/struts2/trunk/core/src/test/java/org/apache/struts2/dispatcher/FilterTest.java (added)
+++ struts/struts2/trunk/core/src/test/java/org/apache/struts2/dispatcher/FilterTest.java Sat Nov 4 23:47:19 2006
@@ -0,0 +1,344 @@
+/*
+ * $Id: FilterDispatcherTest.java 449367 2006-09-24 06:49:04Z mrdon $
+ *
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed 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;
+
+import java.io.IOException;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import junit.framework.TestCase;
+
+import org.apache.struts2.StrutsConstants;
+import org.apache.struts2.config.Settings;
+import org.apache.struts2.dispatcher.mapper.ActionMapper;
+import org.apache.struts2.dispatcher.mapper.ActionMapping;
+import org.springframework.mock.web.MockFilterConfig;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.mock.web.MockHttpServletResponse;
+import org.springframework.mock.web.MockServletContext;
+
+import com.mockobjects.servlet.MockFilterChain;
+import com.opensymphony.xwork2.ObjectFactory;
+import com.opensymphony.xwork2.config.ConfigurationManager;
+
+
+/**
+ *
+ * @version $Date$ $Id$
+ */
+public class FilterTest extends TestCase {
+
+ protected MockFilterConfig filterConfig;
+ protected MockHttpServletRequest request;
+ protected MockHttpServletResponse response;
+ protected MockFilterChain filterChain;
+ protected MockFilterChain filterChain2;
+ protected MockServletContext servletContext;
+
+ protected InnerDispatcher _dispatcher1;
+ protected InnerDispatcher _dispatcher2;
+ protected ActionContextCleanUp cleanUp;
+ protected FilterDispatcher filterDispatcher;
+
+ protected int cleanUpFilterCreateDispatcherCount = 0; // number of times clean up filter create a dispatcher
+ protected int filterDispatcherCreateDispatcherCount = 0; // number of times FilterDispatcher create a dispatcher
+
+
+ @Override
+ protected void tearDown() throws Exception {
+ filterConfig = null;
+ request = null;
+ response = null;
+ filterChain = null;
+ filterChain2 = null;
+ servletContext = null;
+ _dispatcher1 = null;
+ _dispatcher2 = null;
+ cleanUp = null;
+ filterDispatcher = null;
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ Dispatcher.setInstance(null);
+
+ filterConfig = new MockFilterConfig();
+ request = new MockHttpServletRequest();
+ response = new MockHttpServletResponse();
+ servletContext = new MockServletContext();
+
+ _dispatcher1 = new InnerDispatcher(servletContext){
+ @Override
+ public String toString() {
+ return "dispatcher1";
+ }
+ };
+ _dispatcher2 = new InnerDispatcher(servletContext){
+ @Override
+ public String toString() {
+ return "dispatcher2";
+ }
+ };
+ filterChain = new MockFilterChain() {
+ @Override
+ public void doFilter(ServletRequest req, ServletResponse res) throws IOException, ServletException {
+ filterDispatcher.doFilter(req, res, filterChain2);
+ }
+ };
+ filterChain2 = new MockFilterChain() {
+ @Override
+ public void doFilter(ServletRequest req, ServletResponse res) throws IOException, ServletException {
+ }
+ };
+
+
+ cleanUp = new ActionContextCleanUp() {
+ @Override
+ protected Dispatcher createDispatcher() {
+ cleanUpFilterCreateDispatcherCount++;
+ return _dispatcher1;
+ }
+
+ @Override
+ public String toString() {
+ return "cleanUp";
+ }
+ };
+
+ filterDispatcher = new FilterDispatcher() {
+ @Override
+ protected Dispatcher createDispatcher() {
+ filterDispatcherCreateDispatcherCount++;
+ return _dispatcher2;
+ }
+
+ @Override
+ public String toString() {
+ return "filterDispatcher";
+ }
+ };
+ }
+
+
+ public void testUsingFilterDispatcherOnly() throws Exception {
+ ObjectFactory oldObjecFactory = ObjectFactory.getObjectFactory();
+ try {
+ ObjectFactory.setObjectFactory(new InnerObjectFactory());
+ Settings.set(StrutsConstants.STRUTS_MAPPER_CLASS, "org.apache.struts2.dispatcher.FilterTest$InnerMapper");
+
+ assertEquals(cleanUpFilterCreateDispatcherCount, 0);
+ assertEquals(filterDispatcherCreateDispatcherCount, 0);
+ assertFalse(_dispatcher1.prepare);
+ assertFalse(_dispatcher1.wrapRequest);
+ assertFalse(_dispatcher1.service);
+ assertFalse(_dispatcher2.prepare);
+ assertFalse(_dispatcher2.wrapRequest);
+ assertFalse(_dispatcher2.service);
+
+ filterDispatcher.init(filterConfig);
+ filterDispatcher.doFilter(request, response, filterChain2);
+ filterDispatcher.destroy();
+
+ // we are using FilterDispatcher only, so cleanUp filter's Dispatcher should not be created.
+ assertEquals(cleanUpFilterCreateDispatcherCount, 0);
+ assertEquals(filterDispatcherCreateDispatcherCount, 1);
+ assertFalse(_dispatcher1.prepare);
+ assertFalse(_dispatcher1.wrapRequest);
+ assertFalse(_dispatcher1.service);
+ assertTrue(_dispatcher2.prepare);
+ assertTrue(_dispatcher2.wrapRequest);
+ assertTrue(_dispatcher2.service);
+ assertTrue(Dispatcher.getInstance() == null);
+ }
+ finally {
+ ObjectFactory.setObjectFactory(oldObjecFactory);
+ }
+ }
+
+ public void testUsingFilterDispatcherOnly_Multiple() throws Exception {
+ ObjectFactory oldObjecFactory = ObjectFactory.getObjectFactory();
+ try {
+ ObjectFactory.setObjectFactory(new InnerObjectFactory());
+ Settings.set(StrutsConstants.STRUTS_MAPPER_CLASS, "org.apache.struts2.dispatcher.FilterTest$InnerMapper");
+
+ assertEquals(cleanUpFilterCreateDispatcherCount, 0);
+ assertEquals(filterDispatcherCreateDispatcherCount, 0);
+ assertFalse(_dispatcher1.prepare);
+ assertFalse(_dispatcher1.wrapRequest);
+ assertFalse(_dispatcher1.service);
+ assertFalse(_dispatcher2.prepare);
+ assertFalse(_dispatcher2.wrapRequest);
+ assertFalse(_dispatcher2.service);
+
+ filterDispatcher.init(filterConfig);
+ filterDispatcher.doFilter(request, response, filterChain2);
+ filterDispatcher.doFilter(request, response, filterChain2);
+ filterDispatcher.destroy();
+
+ assertEquals(cleanUpFilterCreateDispatcherCount, 0);
+ // We should create dispatcher once, although filter.doFilter(...) is called many times.
+ assertEquals(filterDispatcherCreateDispatcherCount, 1);
+ assertFalse(_dispatcher1.prepare);
+ assertFalse(_dispatcher1.wrapRequest);
+ assertFalse(_dispatcher1.service);
+ assertTrue(_dispatcher2.prepare);
+ assertTrue(_dispatcher2.wrapRequest);
+ assertTrue(_dispatcher2.service);
+ assertTrue(Dispatcher.getInstance() == null);
+ }
+ finally {
+ ObjectFactory.setObjectFactory(oldObjecFactory);
+ }
+ }
+
+ public void testUsingCleanUpAndFilterDispatcher() throws Exception {
+ ObjectFactory oldObjecFactory = ObjectFactory.getObjectFactory();
+ try {
+ ObjectFactory.setObjectFactory(new InnerObjectFactory());
+ Settings.set(StrutsConstants.STRUTS_MAPPER_CLASS, "org.apache.struts2.dispatcher.FilterTest$InnerMapper");
+
+ assertEquals(cleanUpFilterCreateDispatcherCount, 0);
+ assertEquals(filterDispatcherCreateDispatcherCount, 0);
+ assertFalse(_dispatcher1.prepare);
+ assertFalse(_dispatcher1.wrapRequest);
+ assertFalse(_dispatcher1.service);
+ assertFalse(_dispatcher2.prepare);
+ assertFalse(_dispatcher2.wrapRequest);
+ assertFalse(_dispatcher2.service);
+
+ cleanUp.init(filterConfig);
+ filterDispatcher.init(filterConfig);
+ cleanUp.doFilter(request, response, filterChain);
+ filterDispatcher.destroy();
+ cleanUp.destroy();
+
+ assertEquals(cleanUpFilterCreateDispatcherCount, 1);
+ assertEquals(filterDispatcherCreateDispatcherCount, 1);
+ assertTrue(_dispatcher1.prepare);
+ assertTrue(_dispatcher1.wrapRequest);
+ assertTrue(_dispatcher1.service);
+ assertFalse(_dispatcher2.prepare);
+ assertFalse(_dispatcher2.wrapRequest);
+ assertFalse(_dispatcher2.service);
+ assertTrue(Dispatcher.getInstance() == null);
+ }
+ finally {
+ ObjectFactory.setObjectFactory(oldObjecFactory);
+ }
+ }
+
+
+ public void testUsingCleanUpAndFilterDispatcher_Multiple() throws Exception {
+ ObjectFactory oldObjecFactory = ObjectFactory.getObjectFactory();
+ try {
+ ObjectFactory.setObjectFactory(new InnerObjectFactory());
+ Settings.set(StrutsConstants.STRUTS_MAPPER_CLASS, "org.apache.struts2.dispatcher.FilterTest$InnerMapper");
+
+ assertEquals(cleanUpFilterCreateDispatcherCount, 0);
+ assertEquals(filterDispatcherCreateDispatcherCount, 0);
+ assertFalse(_dispatcher1.prepare);
+ assertFalse(_dispatcher1.wrapRequest);
+ assertFalse(_dispatcher1.service);
+ assertFalse(_dispatcher2.prepare);
+ assertFalse(_dispatcher2.wrapRequest);
+ assertFalse(_dispatcher2.service);
+
+ cleanUp.init(filterConfig);
+ filterDispatcher.init(filterConfig);
+ cleanUp.doFilter(request, response, filterChain);
+ cleanUp.doFilter(request, response, filterChain);
+ filterDispatcher.destroy();
+ cleanUp.destroy();
+
+ assertEquals(cleanUpFilterCreateDispatcherCount, 1);
+ assertEquals(filterDispatcherCreateDispatcherCount, 1);
+ assertTrue(_dispatcher1.prepare);
+ assertTrue(_dispatcher1.wrapRequest);
+ assertTrue(_dispatcher1.service);
+ assertFalse(_dispatcher2.prepare);
+ assertFalse(_dispatcher2.wrapRequest);
+ assertFalse(_dispatcher2.service);
+ assertTrue(Dispatcher.getInstance() == null);
+ }
+ finally {
+ ObjectFactory.setObjectFactory(oldObjecFactory);
+ }
+ }
+
+
+ class InnerDispatcher extends Dispatcher {
+ public boolean prepare = false;
+ public boolean wrapRequest = false;
+ public boolean service = false;
+
+ public InnerDispatcher(ServletContext servletContext) {
+ super(servletContext);
+ }
+
+ @Override
+ public void prepare(HttpServletRequest request, HttpServletResponse response) {
+ prepare = true;
+ }
+
+ @Override
+ public HttpServletRequest wrapRequest(HttpServletRequest request, ServletContext servletContext) throws IOException {
+ wrapRequest = true;
+ return request;
+ }
+
+ @Override
+ public void serviceAction(HttpServletRequest request, HttpServletResponse response, ServletContext context, ActionMapping mapping) throws ServletException {
+ service = true;
+ }
+ }
+
+ class NullInnerMapper implements ActionMapper {
+ public ActionMapping getMapping(HttpServletRequest request, ConfigurationManager configManager) {
+ return null;
+ }
+
+ public String getUriFromActionMapping(ActionMapping mapping) {
+ return null;
+ }
+ }
+
+ public static class InnerMapper implements ActionMapper {
+
+ public InnerMapper() {}
+
+ public ActionMapping getMapping(HttpServletRequest request, ConfigurationManager configManager) {
+ return new ActionMapping();
+ }
+
+ public String getUriFromActionMapping(ActionMapping mapping) {
+ return "";
+ }
+ }
+
+ class InnerObjectFactory extends ObjectFactory {
+ public InnerObjectFactory() {
+ super();
+ }
+ }
+}
+