You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by lu...@apache.org on 2015/06/23 16:09:52 UTC

struts git commit: WW-4518 Drops FilterDispatcher

Repository: struts
Updated Branches:
  refs/heads/master e133b9efc -> 8de090fda


WW-4518 Drops FilterDispatcher


Project: http://git-wip-us.apache.org/repos/asf/struts/repo
Commit: http://git-wip-us.apache.org/repos/asf/struts/commit/8de090fd
Tree: http://git-wip-us.apache.org/repos/asf/struts/tree/8de090fd
Diff: http://git-wip-us.apache.org/repos/asf/struts/diff/8de090fd

Branch: refs/heads/master
Commit: 8de090fda29abda6695683995f2fa594f536fca2
Parents: e133b9e
Author: Lukasz Lenart <lu...@apache.org>
Authored: Tue Jun 23 16:09:34 2015 +0200
Committer: Lukasz Lenart <lu...@apache.org>
Committed: Tue Jun 23 16:09:34 2015 +0200

----------------------------------------------------------------------
 apps/portlet/src/main/etc/exo/web.xml           |   2 +-
 apps/portlet/src/main/etc/gridsphere/web.xml    |   2 +-
 apps/portlet/src/main/etc/liferay3.6.1/web.xml  |   2 +-
 .../struts2/config/ServletContextSingleton.java |  92 ----
 .../dispatcher/ActionContextCleanUp.java        | 152 ------
 .../DefaultDispatcherErrorHandler.java          |   4 +-
 .../struts2/dispatcher/FilterDispatcher.java    | 460 -------------------
 .../FilterDispatcherCompatWeblogic61.java       | 108 -----
 .../dispatcher/ng/PrepareOperations.java        |  26 ++
 .../debugging/DebuggingInterceptor.java         |   4 +-
 .../struts2/util/ObjectFactoryDestroyable.java  |   1 -
 .../dispatcher/ActionContextCleanUpTest.java    | 186 --------
 .../struts2/dispatcher/DispatcherTest.java      |  12 +-
 .../dispatcher/FilterDispatcherTest.java        | 203 --------
 .../apache/struts2/dispatcher/FilterTest.java   | 363 ---------------
 .../apache/struts2/json/JSONInterceptor.java    |   4 +-
 16 files changed, 46 insertions(+), 1575 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/struts/blob/8de090fd/apps/portlet/src/main/etc/exo/web.xml
----------------------------------------------------------------------
diff --git a/apps/portlet/src/main/etc/exo/web.xml b/apps/portlet/src/main/etc/exo/web.xml
index 675c913..b56d9fa 100644
--- a/apps/portlet/src/main/etc/exo/web.xml
+++ b/apps/portlet/src/main/etc/exo/web.xml
@@ -10,7 +10,7 @@
 	<filter>
 		<filter-name>action2</filter-name>
 		<filter-class>
-			org.apache.struts2.dispatcher.FilterDispatcher
+			org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
 		</filter-class>
 	</filter>
 

http://git-wip-us.apache.org/repos/asf/struts/blob/8de090fd/apps/portlet/src/main/etc/gridsphere/web.xml
----------------------------------------------------------------------
diff --git a/apps/portlet/src/main/etc/gridsphere/web.xml b/apps/portlet/src/main/etc/gridsphere/web.xml
index e453c96..f7fee3a 100644
--- a/apps/portlet/src/main/etc/gridsphere/web.xml
+++ b/apps/portlet/src/main/etc/gridsphere/web.xml
@@ -10,7 +10,7 @@
 	<filter>
 		<filter-name>action2</filter-name>
 		<filter-class>
-			org.apache.struts2.dispatcher.FilterDispatcher
+			org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
 		</filter-class>
 	</filter>
 

http://git-wip-us.apache.org/repos/asf/struts/blob/8de090fd/apps/portlet/src/main/etc/liferay3.6.1/web.xml
----------------------------------------------------------------------
diff --git a/apps/portlet/src/main/etc/liferay3.6.1/web.xml b/apps/portlet/src/main/etc/liferay3.6.1/web.xml
index b5fedfb..bffebfb 100644
--- a/apps/portlet/src/main/etc/liferay3.6.1/web.xml
+++ b/apps/portlet/src/main/etc/liferay3.6.1/web.xml
@@ -13,7 +13,7 @@
 	<filter>
 		<filter-name>action2</filter-name>
 		<filter-class>
-			org.apache.struts2.dispatcher.FilterDispatcher
+			org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
 		</filter-class>
 	</filter>
 

http://git-wip-us.apache.org/repos/asf/struts/blob/8de090fd/core/src/main/java/org/apache/struts2/config/ServletContextSingleton.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/struts2/config/ServletContextSingleton.java b/core/src/main/java/org/apache/struts2/config/ServletContextSingleton.java
deleted file mode 100644
index 5c59410..0000000
--- a/core/src/main/java/org/apache/struts2/config/ServletContextSingleton.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * $Id$
- *
- * 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.config;
-
-import javax.servlet.ServletContext;
-
-/**
- * This singleton holds an instance of the web servlet context.
- * <p/>
- * This is needed for running Struts on Weblogic Server 6.1
- * because there is no provision to retrieve the servlet context
- * from the web session object.
- * <p/>
- * This class is created to bet that this singleton can be set by
- * {@link org.apache.struts2.dispatcher.FilterDispatcherCompatWeblogic61}
- * before the servlet context is needed by
- * {@link org.apache.struts2.lifecycle.SessionLifecycleListener}
- * which will use this object to get it.
- *
- */
-public class ServletContextSingleton {
-    /**
-     * The web servlet context.  Holding this is the
-     * purpose of this singleton.
-     */
-    private ServletContext servletContext;
-
-    /**
-     * The sole instance of this class.
-     */
-    private static ServletContextSingleton singleton;
-
-    /**
-     * Constructor which cannot be called
-     * publicly.
-     */
-    private ServletContextSingleton() {
-    }
-
-    /**
-     * Answers the singleton.
-     * <p/>
-     * At some point, the caller must populate the web servlet
-     * context.
-     *
-     * @return Answers the singleton instance of this class
-     */
-    public static ServletContextSingleton getInstance() {
-        if (singleton == null) {
-            singleton = new ServletContextSingleton();
-        }
-        return singleton;
-    }
-
-    /**
-     * Gets the servlet context
-     *
-     * @return The web servlet context
-     */
-    public ServletContext getServletContext() {
-        return servletContext;
-    }
-
-    /**
-     * Sets the servlet context
-     *
-     * @param context The web servlet context
-     */
-    public void setServletContext(ServletContext context) {
-        servletContext = context;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/struts/blob/8de090fd/core/src/main/java/org/apache/struts2/dispatcher/ActionContextCleanUp.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/struts2/dispatcher/ActionContextCleanUp.java b/core/src/main/java/org/apache/struts2/dispatcher/ActionContextCleanUp.java
deleted file mode 100644
index b0dd299..0000000
--- a/core/src/main/java/org/apache/struts2/dispatcher/ActionContextCleanUp.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * $Id$
- *
- * 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;
-
-import com.opensymphony.xwork2.ActionContext;
-import com.opensymphony.xwork2.util.profiling.UtilTimerStack;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-
-import javax.servlet.*;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-
-/**
- * <!-- SNIPPET START: description -->
- * Special filter designed to work with the {@link FilterDispatcher} and allow
- * for easier integration with SiteMesh. Normally, ordering your filters to have
- * SiteMesh go first, and then {@link FilterDispatcher} go second is perfectly fine.
- * However, sometimes you may wish to access Struts features, including the
- * value stack, from within your SiteMesh decorators. Because {@link FilterDispatcher}
- * cleans up the {@link ActionContext}, your decorator won't have access to the
- * data you want.
- * <p/>
- * <p/>
- * By adding this filter, the {@link FilterDispatcher} will know to not clean up and
- * instead defer cleanup to this filter. The ordering of the filters should then be:
- * <p/>
- * <ul>
- * <li>this filter</li>
- * <li>SiteMesh filter</li>
- * <li>{@link FilterDispatcher}</li>
- * </ul>
- * <!-- SNIPPET END: description -->
- *
- *
- * @deprecated Since Struts 2.1.3, use {@link org.apache.struts2.dispatcher.ng.filter.StrutsPrepareFilter} and
- * {@link org.apache.struts2.dispatcher.ng.filter.StrutsExecuteFilter} to use other Servlet filters that need access to
- * the ActionContext
- * @see FilterDispatcher
- * @see Dispatcher
- * @see org.apache.struts2.dispatcher.ng.filter.StrutsPrepareFilter
- * @see org.apache.struts2.dispatcher.ng.filter.StrutsExecuteFilter
- *
- * @version $Date$ $Id$
- */
-public class ActionContextCleanUp implements Filter {
-
-    private static final Logger LOG = LogManager.getLogger(ActionContextCleanUp.class);
-
-    private static final String COUNTER = "__cleanup_recursion_counter";
-
-    /**
-     * @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 {
-
-        showDeprecatedWarning();
-
-        HttpServletRequest request = (HttpServletRequest) req;
-        HttpServletResponse response = (HttpServletResponse) res;
-
-        String timerKey = "ActionContextCleanUp_doFilter: ";
-        try {
-            UtilTimerStack.push(timerKey);
-
-            try {
-                Integer count = (Integer)request.getAttribute(COUNTER);
-                if (count == null) {
-                    count = 1;
-                }
-                else {
-                    count = count.intValue() + 1;
-                }
-                request.setAttribute(COUNTER, count);
-
-                //LOG.debug("filtering counter="+count);
-
-                chain.doFilter(request, response);
-            } finally {
-                int counterVal = ((Integer) request.getAttribute(COUNTER));
-                counterVal -= 1;
-                request.setAttribute(COUNTER, counterVal);
-                cleanUp(request);
-            }
-        }
-        finally {
-            UtilTimerStack.pop(timerKey);
-        }
-    }
-
-    /**
-     * Clean up the request of threadlocals if this is the last execution
-     *
-     * @param req The servlet request
-     */
-    protected static void cleanUp(ServletRequest req) {
-        // should we clean up yet?
-        Integer count = (Integer) req.getAttribute(COUNTER);
-        if (count != null && count > 0 ) {
-            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);
-    }
-
-    public void destroy() {
-    }
-
-    public void init(FilterConfig arg0) throws ServletException {
-    }
-
-    private void showDeprecatedWarning() {
-        String msg =
-                "\n\n" +
-                "***************************************************************************\n" +
-                "*                                 WARNING!!!                              *\n" +
-                "*                                                                         *\n" +
-                "* >>> ActionContextCleanUp <<< is deprecated! Please use the new filters! *\n" +
-                "*                                                                         *\n" +
-                "*             This can be a source of unpredictable problems!             *\n" +
-                "*                                                                         *\n" +
-                "*                Please refer to the docs for more details!               *\n" +
-                        "*              http://struts.apache.org/docs/webxml.html                  *\n" +
-                "*                                                                         *\n" +
-                "***************************************************************************\n\n";
-        System.out.println(msg);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/struts/blob/8de090fd/core/src/main/java/org/apache/struts2/dispatcher/DefaultDispatcherErrorHandler.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/struts2/dispatcher/DefaultDispatcherErrorHandler.java b/core/src/main/java/org/apache/struts2/dispatcher/DefaultDispatcherErrorHandler.java
index d64b800..13523ce 100644
--- a/core/src/main/java/org/apache/struts2/dispatcher/DefaultDispatcherErrorHandler.java
+++ b/core/src/main/java/org/apache/struts2/dispatcher/DefaultDispatcherErrorHandler.java
@@ -9,6 +9,8 @@ import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 import org.apache.struts2.StrutsConstants;
 import org.apache.struts2.StrutsException;
+import org.apache.struts2.dispatcher.ng.ExecuteOperations;
+import org.apache.struts2.dispatcher.ng.PrepareOperations;
 import org.apache.struts2.views.freemarker.FreemarkerManager;
 
 import javax.servlet.ServletContext;
@@ -53,7 +55,7 @@ public class DefaultDispatcherErrorHandler implements DispatcherErrorHandler {
     }
 
     public void handleError(HttpServletRequest request, HttpServletResponse response, int code, Exception e) {
-        Boolean devModeOverride = FilterDispatcher.getDevModeOverride();
+        Boolean devModeOverride = PrepareOperations.getDevModeOverride();
         if (devModeOverride != null ? devModeOverride : devMode) {
             handleErrorInDevMode(response, code, e);
         } else {

http://git-wip-us.apache.org/repos/asf/struts/blob/8de090fd/core/src/main/java/org/apache/struts2/dispatcher/FilterDispatcher.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/struts2/dispatcher/FilterDispatcher.java b/core/src/main/java/org/apache/struts2/dispatcher/FilterDispatcher.java
deleted file mode 100644
index eab9acb..0000000
--- a/core/src/main/java/org/apache/struts2/dispatcher/FilterDispatcher.java
+++ /dev/null
@@ -1,460 +0,0 @@
-/*
- * $Id$
- *
- * 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;
-
-import com.opensymphony.xwork2.ActionContext;
-import com.opensymphony.xwork2.config.Configuration;
-import com.opensymphony.xwork2.config.ConfigurationProvider;
-import com.opensymphony.xwork2.inject.Inject;
-import com.opensymphony.xwork2.util.ClassLoaderUtil;
-import com.opensymphony.xwork2.util.ValueStack;
-import com.opensymphony.xwork2.util.ValueStackFactory;
-import com.opensymphony.xwork2.util.logging.LoggerFactory;
-import com.opensymphony.xwork2.util.profiling.UtilTimerStack;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.apache.struts2.RequestUtils;
-import org.apache.struts2.StrutsStatics;
-import org.apache.struts2.dispatcher.mapper.ActionMapper;
-import org.apache.struts2.dispatcher.mapper.ActionMapping;
-import org.apache.struts2.dispatcher.ng.filter.FilterHostConfig;
-
-import javax.servlet.*;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Master filter for Struts that handles four distinct
- * responsibilities:
- * <p/>
- * <ul>
- * <p/>
- * <li>Executing actions</li>
- * <p/>
- * <li>Cleaning up the {@link ActionContext} (see note)</li>
- * <p/>
- * <li>Serving static content</li>
- * <p/>
- * <li>Kicking off XWork's interceptor chain for the request lifecycle</li>
- * <p/>
- * </ul>
- * <p/>
- * <p/> <b>IMPORTANT</b>: this filter must be mapped to all requests. Unless you know exactly what you are doing, always
- * map to this URL pattern: /*
- * <p/>
- * <p/> <b>Executing actions</b>
- * <p/>
- * <p/> This filter executes actions by consulting the {@link ActionMapper} and determining if the requested URL should
- * invoke an action. If the mapper indicates it should, <b>the rest of the filter chain is stopped</b> and the action is
- * invoked. This is important, as it means that filters like the SiteMesh filter must be placed <b>before</b> this
- * filter or they will not be able to decorate the output of actions.
- * <p/>
- * <p/> <b>Cleaning up the {@link ActionContext}</b>
- * <p/>
- * <p/> This filter will also automatically clean up the {@link ActionContext} for you, ensuring that no memory leaks
- * take place. However, this can sometimes cause problems integrating with other products like SiteMesh. See {@link
- * ActionContextCleanUp} for more information on how to deal with this.
- * <p/>
- * <p/> <b>Serving static content</b>
- * <p/>
- * <p/> This filter also serves common static content needed when using various parts of Struts, such as JavaScript
- * files, CSS files, etc. It works by looking for requests to /struts/*, and then mapping the value after "/struts/"
- * to common packages in Struts and, optionally, in your class path. By default, the following packages are
- * automatically searched:
- * <p/>
- * <ul>
- * <p/>
- * <li>org.apache.struts2.static</li>
- * <p/>
- * <li>template</li>
- * <p/>
- * </ul>
- * <p/>
- * <p/> This means that you can simply request /struts/xhtml/styles.css and the XHTML UI theme's default stylesheet
- * will be returned. Likewise, many of the AJAX UI components require various JavaScript files, which are found in the
- * org.apache.struts2.static package. If you wish to add additional packages to be searched, you can add a comma
- * separated (space, tab and new line will do as well) list in the filter init parameter named "packages". <b>Be
- * careful</b>, however, to expose any packages that may have sensitive information, such as properties file with
- * database access credentials.
- * <p/>
- * <p/>
- * <p/>
- * <p>
- * <p/>
- * This filter supports the following init-params:
- * <!-- START SNIPPET: params -->
- * <p/>
- * <ul>
- * <p/>
- * <li><b>config</b> - a comma-delimited list of XML configuration files to load.</li>
- * <p/>
- * <li><b>actionPackages</b> - a comma-delimited list of Java packages to scan for Actions.</li>
- * <p/>
- * <li><b>configProviders</b> - a comma-delimited list of Java classes that implement the
- * {@link ConfigurationProvider} interface that should be used for building the {@link Configuration}.</li>
- * <p/>
- * <li><b>loggerFactory</b> - The class name of the {@link LoggerFactory} implementation.</li>
- * <p/>
- * <li><b>*</b> - any other parameters are treated as framework constants.</li>
- * <p/>
- * </ul>
- * <p/>
- * <!-- END SNIPPET: params -->
- * <p/>
- * </p>
- * <p/>
- * To use a custom {@link Dispatcher}, the <code>createDispatcher()</code> method could be overriden by
- * the subclass.
- *
- * @version $Date$ $Id$
- * @deprecated Since Struts 2.1.3, use {@link org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter} instead or
- * {@link org.apache.struts2.dispatcher.ng.filter.StrutsPrepareFilter} and {@link org.apache.struts2.dispatcher.ng.filter.StrutsExecuteFilter}
- * if needing using the {@link ActionContextCleanUp} filter in addition to this one
- *
- * @see ActionMapper
- * @see ActionContextCleanUp
- * @see org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
- * @see org.apache.struts2.dispatcher.ng.filter.StrutsPrepareFilter
- * @see org.apache.struts2.dispatcher.ng.filter.StrutsExecuteFilter
- */
-public class FilterDispatcher implements StrutsStatics, Filter {
-
-    /**
-     * Provide a logging instance.
-     */
-    private Logger log;
-
-    /**
-     * Provide ActionMapper instance, set by injection.
-     */
-    private ActionMapper actionMapper;
-
-    /**
-     * Provide FilterConfig instance, set on init.
-     */
-    private FilterConfig filterConfig;
-
-    /**
-     * Expose Dispatcher instance to subclass.
-     */
-    protected Dispatcher dispatcher;
-
-    /**
-     * Loads static resources, set by injection.
-     */
-    protected StaticContentLoader staticResourceLoader;
-
-    /**
-     * Maintains per-request override of devMode configuration.
-     */
-    private static ThreadLocal<Boolean> devModeOverride = new InheritableThreadLocal<>();
-
-    /**
-     * Initializes the filter by creating a default dispatcher
-     * and setting the default packages for static resources.
-     *
-     * @param filterConfig The filter configuration
-     */
-    public void init(FilterConfig filterConfig) throws ServletException {
-        try {
-            this.filterConfig = filterConfig;
-
-            initLogging();
-
-            dispatcher = createDispatcher(filterConfig);
-            dispatcher.init();
-            dispatcher.getContainer().inject(this);
-
-            staticResourceLoader.setHostConfig(new FilterHostConfig(filterConfig));
-        } finally {
-            ActionContext.setContext(null);
-        }
-    }
-
-    /**
-     * @deprecated since 2.5
-     */
-    @Deprecated
-    private void initLogging() {
-        String factoryName = filterConfig.getInitParameter("loggerFactory");
-        if (factoryName != null) {
-            try {
-                Class cls = ClassLoaderUtil.loadClass(factoryName, this.getClass());
-                LoggerFactory fac = (LoggerFactory) cls.newInstance();
-                LoggerFactory.setLoggerFactory(fac);
-            } catch (InstantiationException e) {
-                System.err.println("Unable to instantiate logger factory: " + factoryName + ", using default");
-                e.printStackTrace();
-            } catch (IllegalAccessException e) {
-                System.err.println("Unable to access logger factory: " + factoryName + ", using default");
-                e.printStackTrace();
-            } catch (ClassNotFoundException e) {
-                System.err.println("Unable to locate logger factory class: " + factoryName + ", using default");
-                e.printStackTrace();
-            }
-        }
-
-        log = LogManager.getLogger(FilterDispatcher.class);
-
-    }
-
-    /**
-     * Calls dispatcher.cleanup,
-     * which in turn releases local threads and destroys any DispatchListeners.
-     *
-     * @see javax.servlet.Filter#destroy()
-     */
-    public void destroy() {
-        if (dispatcher == null) {
-            log.warn("something is seriously wrong, Dispatcher is not initialized (null)");
-        } else {
-            try {
-                dispatcher.cleanup();
-            } finally {
-                ActionContext.setContext(null);
-            }
-        }
-    }
-
-    /**
-     * Set an override of the static devMode value.  Do not set this via a
-     * request parameter or any other unprotected method.  Using a signed
-     * cookie is one safe way to turn it on per request.
-     * 
-     * @param devMode   the override value
-     */
-    public static void overrideDevMode(boolean devMode) {
-        devModeOverride.set(devMode);
-    }
-
-    /**
-     * @return Boolean override value, or null if no override
-     */
-    public static Boolean getDevModeOverride()
-    {
-        return devModeOverride.get();
-    }
-
-    /**
-     * Create a default {@link Dispatcher} that subclasses can override
-     * with a custom Dispatcher, if needed.
-     *
-     * @param filterConfig Our FilterConfig
-     * @return Initialized Dispatcher
-     */
-    protected Dispatcher createDispatcher(FilterConfig filterConfig) {
-        Map<String, String> params = new HashMap<>();
-        for (Enumeration e = filterConfig.getInitParameterNames(); e.hasMoreElements();) {
-            String name = (String) e.nextElement();
-            String value = filterConfig.getInitParameter(name);
-            params.put(name, value);
-        }
-        return createDispatcher(filterConfig.getServletContext(), params);
-    }
-
-    /**
-     * Create a default {@link Dispatcher} that subclasses can override
-     * with a custom Dispatcher, if needed.  Called by
-     * createDispatcher(FilterConfig).
-     *
-     * @param ctx ServletContext
-     * @param params parameters from FilterConfig
-     * @return Initialized Dispatcher
-     */
-    protected Dispatcher createDispatcher(ServletContext ctx, Map<String, String> params) {
-        return new Dispatcher(ctx, params);
-    }
-
-    /**
-     * Modify state of StrutsConstants.STRUTS_STATIC_CONTENT_LOADER setting.
-     * @param staticResourceLoader val New setting
-     */
-    @Inject
-    public void setStaticResourceLoader(StaticContentLoader staticResourceLoader) {
-        this.staticResourceLoader = staticResourceLoader;
-    }
-
-    /**
-     * Modify ActionMapper instance.
-     * @param mapper New instance
-     */
-    @Inject
-    public void setActionMapper(ActionMapper mapper) {
-        actionMapper = mapper;
-    }
-
-    /**
-     * Provide a workaround for some versions of WebLogic.
-     * <p/>
-     * 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.
-     *
-     * @return the servlet context.
-     */
-    protected ServletContext getServletContext() {
-        return filterConfig.getServletContext();
-    }
-
-    /**
-     * Expose the FilterConfig instance.
-     *
-     * @return Our FilterConfit instance
-     */
-    protected FilterConfig getFilterConfig() {
-        return filterConfig;
-    }
-
-    /**
-     * Wrap and return the given request, if needed, so as to to transparently
-     * handle multipart data as a wrapped class around the given request.
-     *
-     * @param request  Our ServletRequest object
-     * @param response Our ServerResponse object
-     * @return Wrapped HttpServletRequest object
-     * @throws ServletException on any error
-     */
-    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.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);
-        } else {
-            dispatcher = du;
-        }
-
-        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);
-        } catch (IOException e) {
-            String message = "Could not wrap servlet request with MultipartRequestWrapper!";
-            log.error(message, e);
-            throw new ServletException(message, e);
-        }
-
-        return request;
-    }
-
-    /**
-     * Process an action or handle a request a static resource.
-     * <p/>
-     * The filter tries to match the request to an action mapping.
-     * If mapping is found, the action processes is delegated to the dispatcher's serviceAction method.
-     * If action processing fails, doFilter will try to create an error page via the dispatcher.
-     * <p/>
-     * Otherwise, if the request is for a static resource,
-     * the resource is copied directly to the response, with the appropriate caching headers set.
-     * <p/>
-     * If the request does not match an action mapping, or a static resource page,
-     * then it passes through.
-     *
-     * @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 {
-
-        showDeprecatedWarning();
-
-        HttpServletRequest request = (HttpServletRequest) req;
-        HttpServletResponse response = (HttpServletResponse) res;
-        ServletContext servletContext = getServletContext();
-
-        String timerKey = "FilterDispatcher_doFilter: ";
-        try {
-
-            // FIXME: this should be refactored better to not duplicate work with the action invocation
-            ValueStack stack = dispatcher.getContainer().getInstance(ValueStackFactory.class).createValueStack();
-            ActionContext ctx = new ActionContext(stack.getContext());
-            ActionContext.setContext(ctx);
-
-            UtilTimerStack.push(timerKey);
-            request = prepareDispatcherAndWrapRequest(request, response);
-            ActionMapping mapping;
-            try {
-                mapping = actionMapper.getMapping(request, dispatcher.getConfigurationManager());
-            } catch (Exception ex) {
-                log.error("error getting ActionMapping", ex);
-                dispatcher.sendError(request, response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, ex);
-                return;
-            }
-
-            if (mapping == null) {
-                // there is no action in this request, should we look for a static resource?
-                String resourcePath = RequestUtils.getServletPath(request);
-
-                if ("".equals(resourcePath) && null != request.getPathInfo()) {
-                    resourcePath = request.getPathInfo();
-                }
-
-                if (staticResourceLoader.canHandle(resourcePath)) {
-                    staticResourceLoader.findStaticResource(resourcePath, request, response);
-                } else {
-                    // this is a normal request, let it pass through
-                    chain.doFilter(request, response);
-                }
-                // The framework did its job here
-                return;
-            }
-
-            dispatcher.serviceAction(request, response, mapping);
-
-        } finally {
-            dispatcher.cleanUpRequest(request);
-            try {
-                ActionContextCleanUp.cleanUp(req);
-            } finally {
-                UtilTimerStack.pop(timerKey);
-            }
-            devModeOverride.remove();
-        }
-    }
-
-    private void showDeprecatedWarning() {
-        String msg =
-                "\n\n" +
-                "***********************************************************************\n" +
-                "*                               WARNING!!!                            *\n" +
-                "*                                                                     *\n" +
-                "* >>> FilterDispatcher <<< is deprecated! Please use the new filters! *\n" +
-                "*                                                                     *\n" +
-                "*           This can be a source of unpredictable problems!           *\n" +
-                "*                                                                     *\n" +
-                "*              Please refer to the docs for more details!             *\n" +
-                        "*            http://struts.apache.org/docs/webxml.html                *\n" +
-                "*                                                                     *\n" +
-                "***********************************************************************\n\n";
-        System.out.println(msg);
-    }
-}

http://git-wip-us.apache.org/repos/asf/struts/blob/8de090fd/core/src/main/java/org/apache/struts2/dispatcher/FilterDispatcherCompatWeblogic61.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/struts2/dispatcher/FilterDispatcherCompatWeblogic61.java b/core/src/main/java/org/apache/struts2/dispatcher/FilterDispatcherCompatWeblogic61.java
deleted file mode 100644
index 6598d71..0000000
--- a/core/src/main/java/org/apache/struts2/dispatcher/FilterDispatcherCompatWeblogic61.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * $Id$
- *
- * 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;
-
-import javax.servlet.Filter;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletContext;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpSession;
-
-import org.apache.struts2.config.ServletContextSingleton;
-
-import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.LogManager;
-
-
-/**
- * When running Weblogic Server 6.1, this class should be
- * specified in web.xml instead of {@link FilterDispatcher}.
- * <p/>
- * This class properly handles the weblogic.jar handling
- * of servlet filters.  There is one serious incompatibility, and
- * that is that while {@link FilterDispatcher#init(FilterConfig)}
- * throws a {@link ServletException}, this class's method
- * {@link #setFilterConfig(FilterConfig)} does not throw
- * the exception.  Since {@link #setFilterConfig(FilterConfig)}
- * invokes {@link FilterDispatcher#init(FilterConfig)}, the setter
- * 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 {
-
-    private static Logger LOG = LogManager.getLogger(FilterDispatcherCompatWeblogic61.class);
-
-    /**
-     * dummy setter for {@link #filterConfig}; this method
-     * sets up the {@link org.apache.struts2.config.ServletContextSingleton} with
-     * the servlet context from the filter configuration.
-     * <p/>
-     * This is needed by Weblogic Server 6.1 because it
-     * uses a slightly obsolete Servlet 2.3-minus spec
-     * whose {@link Filter} interface requires this method.
-     * <p/>
-     *
-     * @param filterConfig the filter configuration.
-     */
-    public void setFilterConfig(FilterConfig filterConfig) {
-        try {
-            init(filterConfig);
-        } catch (ServletException se) {
-            LOG.error("Couldn't set the filter configuration in this filter", se);
-        }
-
-        ServletContextSingleton singleton = ServletContextSingleton.getInstance();
-        singleton.setServletContext(filterConfig.getServletContext());
-    }
-
-    /**
-     * answers the servlet context.
-     * <p/>
-     * Servlet 2.3 specifies that this can be retrieved from
-     * the session.  Unfortunately, weblogic.jar can only retrieve
-     * the servlet context from the filter config.  Hence, this
-     * returns the servlet context from the singleton that was
-     * setup by {@link #setFilterConfig(FilterConfig)}.
-     *
-     * @param session the HTTP session.  Not used
-     * @return the servlet context.
-     */
-    protected ServletContext getServletContext(HttpSession session) {
-        ServletContextSingleton singleton =
-                ServletContextSingleton.getInstance();
-        return singleton.getServletContext();
-    }
-
-    /**
-     * This method is required by Weblogic 6.1 SP4 because
-     * they defined this as a required method just before
-     * the Servlet 2.3 specification was finalized.
-     *
-     * @return the filter's filter configuration
-     */
-    public FilterConfig getFilterConfig() {
-        return super.getFilterConfig();
-    }
-}

http://git-wip-us.apache.org/repos/asf/struts/blob/8de090fd/core/src/main/java/org/apache/struts2/dispatcher/ng/PrepareOperations.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/struts2/dispatcher/ng/PrepareOperations.java b/core/src/main/java/org/apache/struts2/dispatcher/ng/PrepareOperations.java
index 2861916..a8cf930 100644
--- a/core/src/main/java/org/apache/struts2/dispatcher/ng/PrepareOperations.java
+++ b/core/src/main/java/org/apache/struts2/dispatcher/ng/PrepareOperations.java
@@ -47,6 +47,12 @@ public class PrepareOperations {
 
     private static final Logger LOG = LogManager.getLogger(PrepareOperations.class);
 
+    /**
+     * Maintains per-request override of devMode configuration.
+     */
+    private static ThreadLocal<Boolean> devModeOverride = new InheritableThreadLocal<>();
+
+
     private Dispatcher dispatcher;
     private static final String STRUTS_ACTION_MAPPING_KEY = "struts.actionMapping";
     public static final String CLEANUP_RECURSION_COUNTER = "__cleanup_recursion_counter";
@@ -99,6 +105,7 @@ public class PrepareOperations {
         } finally {
             ActionContext.setContext(null);
             Dispatcher.setInstance(null);
+            devModeOverride.remove();
         }
     }
 
@@ -200,4 +207,23 @@ public class PrepareOperations {
         return false;
     }
 
+    /**
+     * Set an override of the static devMode value.  Do not set this via a
+     * request parameter or any other unprotected method.  Using a signed
+     * cookie is one safe way to turn it on per request.
+     *
+     * @param devMode   the override value
+     */
+    public static void overrideDevMode(boolean devMode) {
+        devModeOverride.set(devMode);
+    }
+
+    /**
+     * @return Boolean override value, or null if no override
+     */
+    public static Boolean getDevModeOverride()
+    {
+        return devModeOverride.get();
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/struts/blob/8de090fd/core/src/main/java/org/apache/struts2/interceptor/debugging/DebuggingInterceptor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/struts2/interceptor/debugging/DebuggingInterceptor.java b/core/src/main/java/org/apache/struts2/interceptor/debugging/DebuggingInterceptor.java
index 5a88577..43752ce 100644
--- a/core/src/main/java/org/apache/struts2/interceptor/debugging/DebuggingInterceptor.java
+++ b/core/src/main/java/org/apache/struts2/interceptor/debugging/DebuggingInterceptor.java
@@ -32,7 +32,7 @@ import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 import org.apache.struts2.ServletActionContext;
 import org.apache.struts2.StrutsConstants;
-import org.apache.struts2.dispatcher.FilterDispatcher;
+import org.apache.struts2.dispatcher.ng.PrepareOperations;
 import org.apache.struts2.views.freemarker.FreemarkerManager;
 import org.apache.struts2.views.freemarker.FreemarkerResult;
 
@@ -137,7 +137,7 @@ public class DebuggingInterceptor extends AbstractInterceptor {
     public String intercept(ActionInvocation inv) throws Exception {
         boolean actionOnly = false;
         boolean cont = true;
-        Boolean devModeOverride = FilterDispatcher.getDevModeOverride();
+        Boolean devModeOverride = PrepareOperations.getDevModeOverride();
         boolean devMode = devModeOverride != null ? devModeOverride : this.devMode;
         if (devMode) {
             final ActionContext ctx = ActionContext.getContext();

http://git-wip-us.apache.org/repos/asf/struts/blob/8de090fd/core/src/main/java/org/apache/struts2/util/ObjectFactoryDestroyable.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/struts2/util/ObjectFactoryDestroyable.java b/core/src/main/java/org/apache/struts2/util/ObjectFactoryDestroyable.java
index 55a9ad1..603ba60 100644
--- a/core/src/main/java/org/apache/struts2/util/ObjectFactoryDestroyable.java
+++ b/core/src/main/java/org/apache/struts2/util/ObjectFactoryDestroyable.java
@@ -26,7 +26,6 @@ package org.apache.struts2.util;
  * if it requires shutdown hook whenever an ObjectFactory is to be
  * destroyed.
  *
- * @see org.apache.struts2.dispatcher.FilterDispatcher
  * @see org.apache.struts2.dispatcher.Dispatcher
  */
 public interface ObjectFactoryDestroyable {

http://git-wip-us.apache.org/repos/asf/struts/blob/8de090fd/core/src/test/java/org/apache/struts2/dispatcher/ActionContextCleanUpTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/struts2/dispatcher/ActionContextCleanUpTest.java b/core/src/test/java/org/apache/struts2/dispatcher/ActionContextCleanUpTest.java
deleted file mode 100644
index f4993c5..0000000
--- a/core/src/test/java/org/apache/struts2/dispatcher/ActionContextCleanUpTest.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * $Id$
- *
- * 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;
-
-import java.io.IOException;
-import java.util.HashMap;
-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();
-        cleanUp2 = new ActionContextCleanUp();
-        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 {
-        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));
-
-        assertEquals(request.getAttribute("__cleanup_recursion_counter"), new Integer("0"));
-    }
-
-    public void testMultiple() throws Exception {
-        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));
-
-        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, new HashMap<String,String>());
-        }
-
-        @Override
-        public void prepare(HttpServletRequest request, HttpServletResponse response) {
-            prepare = true;
-        }
-
-        @Override
-        public HttpServletRequest wrapRequest(HttpServletRequest request) throws IOException {
-            wrapRequest = true;
-            return request;
-        }
-
-        @Override
-        public void serviceAction(HttpServletRequest request, HttpServletResponse response, ActionMapping mapping) throws ServletException {
-            service = true;
-        }
-    }
-
-    class Counter {
-        public int count=0;
-    }
-}

http://git-wip-us.apache.org/repos/asf/struts/blob/8de090fd/core/src/test/java/org/apache/struts2/dispatcher/DispatcherTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/struts2/dispatcher/DispatcherTest.java b/core/src/test/java/org/apache/struts2/dispatcher/DispatcherTest.java
index 5b5dd7e..edcf987 100644
--- a/core/src/test/java/org/apache/struts2/dispatcher/DispatcherTest.java
+++ b/core/src/test/java/org/apache/struts2/dispatcher/DispatcherTest.java
@@ -35,13 +35,12 @@ import com.opensymphony.xwork2.interceptor.Interceptor;
 import com.opensymphony.xwork2.util.LocalizedTextUtil;
 import org.apache.struts2.StrutsConstants;
 import org.apache.struts2.StrutsInternalTestCase;
-import org.apache.struts2.dispatcher.FilterDispatcherTest.InnerDestroyableObjectFactory;
 import org.apache.struts2.dispatcher.multipart.MultiPartRequestWrapper;
+import org.apache.struts2.util.ObjectFactoryDestroyable;
 import org.springframework.mock.web.MockHttpServletRequest;
 import org.springframework.mock.web.MockHttpServletResponse;
 import org.springframework.mock.web.MockServletContext;
 
-import javax.servlet.ServletContext;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.util.Collections;
@@ -273,4 +272,13 @@ public class DispatcherTest extends StrutsInternalTestCase {
     	public boolean isInitialized = false;
     	public boolean isDestroyed = false;
     }
+
+    public static class InnerDestroyableObjectFactory extends ObjectFactory implements ObjectFactoryDestroyable {
+        public boolean destroyed = false;
+
+        public void destroy() {
+            destroyed = true;
+        }
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/struts/blob/8de090fd/core/src/test/java/org/apache/struts2/dispatcher/FilterDispatcherTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/struts2/dispatcher/FilterDispatcherTest.java b/core/src/test/java/org/apache/struts2/dispatcher/FilterDispatcherTest.java
deleted file mode 100644
index f65dc3e..0000000
--- a/core/src/test/java/org/apache/struts2/dispatcher/FilterDispatcherTest.java
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * $Id$
- *
- * 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;
-
-import com.mockobjects.servlet.MockFilterChain;
-import com.opensymphony.xwork2.ObjectFactory;
-import com.opensymphony.xwork2.config.ConfigurationManager;
-import com.opensymphony.xwork2.config.impl.DefaultConfiguration;
-import org.apache.struts2.StrutsInternalTestCase;
-import org.apache.struts2.dispatcher.mapper.ActionMapper;
-import org.apache.struts2.dispatcher.mapper.ActionMapping;
-import org.apache.struts2.util.ObjectFactoryDestroyable;
-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 javax.servlet.FilterConfig;
-import javax.servlet.ServletContext;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.util.Collections;
-import java.util.HashMap;
-
-/**
- * FilterDispatcher TestCase.
- *
- * @version $Date$ $Id$
- */
-public class FilterDispatcherTest extends StrutsInternalTestCase {
-
-    public void testIfActionMapperIsNullDontServiceAction() throws Exception {
-        MockServletContext servletContext = new MockServletContext();
-        MockFilterConfig filterConfig = new MockFilterConfig(servletContext);
-        MockHttpServletRequest req = new MockHttpServletRequest(servletContext);
-        MockHttpServletResponse res = new MockHttpServletResponse();
-        MockFilterChain chain = new MockFilterChain();
-        ConfigurationManager confManager = new ConfigurationManager();
-        confManager.setConfiguration(new DefaultConfiguration());
-
-        final NoOpDispatcher _dispatcher = new NoOpDispatcher(servletContext, confManager);
-        Dispatcher.setInstance(_dispatcher);
-
-        
-
-
-        FilterDispatcher filter = new FilterDispatcher() {
-            protected Dispatcher createDispatcher() {
-                return _dispatcher;
-            }
-        };
-        filter.init(filterConfig);
-        filter.setActionMapper(null);
-        filter.doFilter(req, res, chain);
-
-        assertFalse(_dispatcher.serviceRequest);
-    }
-    
-    public void testCharacterEncodingSetBeforeRequestWrappingAndActionService() throws Exception {
-        MockServletContext servletContext = new MockServletContext();
-        MockFilterConfig filterConfig = new MockFilterConfig(servletContext);
-        MockHttpServletRequest req = new MockHttpServletRequest(servletContext);
-        MockHttpServletResponse res = new MockHttpServletResponse();
-        MockFilterChain chain = new MockFilterChain();
-        final InnerDispatcher _dispatcher = new InnerDispatcher(servletContext);
-        Dispatcher.setInstance(null);
-
-        _dispatcher.setDefaultEncoding("UTF-16_DUMMY");
-
-        FilterDispatcher filter = new FilterDispatcher() {
-            protected Dispatcher createDispatcher(FilterConfig filterConfig) {
-                return _dispatcher;
-            }
-        };
-        filter.init(filterConfig);
-        // set ActionMapper after init() as all dependencies will be injected in init()
-        filter.setActionMapper(new InnerActionMapper());
-        _dispatcher.setDefaultEncoding("UTF-16_DUMMY");
-        filter.doFilter(req, res, chain);
-
-        assertTrue(_dispatcher.wrappedRequest);
-        assertTrue(_dispatcher.serviceRequest);
-    }
-
-    // === inner class ========
-    public static class InnerObjectFactory extends ObjectFactory {
-
-    }
-
-    public static class NoOpDispatcher extends Dispatcher {
-        protected boolean wrappedRequest = false;
-        protected boolean serviceRequest = false;
-
-        public NoOpDispatcher(ServletContext servletContext, ConfigurationManager cm) {
-            super(servletContext, new HashMap());
-            this.configurationManager = cm;
-        }
-
-        @Override
-        public HttpServletRequest wrapRequest(HttpServletRequest request) throws IOException {
-            wrappedRequest = true;
-            return request;
-        }
-
-        public void serviceAction(HttpServletRequest request, HttpServletResponse response, ActionMapping mapping) throws ServletException {
-            serviceRequest = true;
-        }
-
-        @Override
-        public void sendError(HttpServletRequest request, HttpServletResponse response, int code, Exception e) {
-            // NO-OP
-        }
-    }
-
-    public static class InnerDispatcher extends Dispatcher {
-
-        protected boolean wrappedRequest = false;
-        protected boolean serviceRequest = false;
-
-        public InnerDispatcher(ServletContext servletContext) {
-            super(servletContext, new HashMap());
-        }
-
-        @Override
-        public HttpServletRequest wrapRequest(HttpServletRequest request) throws IOException {
-            wrappedRequest = true;
-            // if we set the chracter encoding AFTER we do wrap request, we will get
-            // a failing test
-            assertNotNull(request.getCharacterEncoding());
-            assertEquals("UTF-16_DUMMY", request.getCharacterEncoding());
-
-            return request;
-        }
-
-        public void serviceAction(HttpServletRequest request, HttpServletResponse response, ActionMapping mapping) throws ServletException {
-            serviceRequest = true;
-            // if we set the chracter encoding AFTER we do wrap request, we will get
-            // a failing test
-            assertNotNull(request.getCharacterEncoding());
-            assertEquals("UTF-16_DUMMY", request.getCharacterEncoding());
-        }
-    }
-
-    public static class InnerActionMapper implements ActionMapper {
-
-        public ActionMapping getMapping(HttpServletRequest request, ConfigurationManager config) {
-            return new ActionMapping("action", "/", null, Collections.<String, Object>emptyMap());
-        }
-
-        public ActionMapping getMappingFromActionName(String actionName) {
-            return null;  //To change body of implemented methods use File | Settings | File Templates.
-        }
-
-        public String getUriFromActionMapping(ActionMapping mapping) {
-            return null;
-        }
-    }
-
-    public static class NullActionMapper implements ActionMapper {
-        public ActionMapping getMapping(HttpServletRequest request, ConfigurationManager config) {
-            return null;
-        }
-
-        public ActionMapping getMappingFromActionName(String actionName) {
-            return null;  //To change body of implemented methods use File | Settings | File Templates.
-        }
-
-        public String getUriFromActionMapping(ActionMapping mapping) {
-            return null;
-        }
-    }
-
-
-    public static class InnerDestroyableObjectFactory extends ObjectFactory implements ObjectFactoryDestroyable {
-        public boolean destroyed = false;
-
-        public void destroy() {
-            destroyed = true;
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/struts/blob/8de090fd/core/src/test/java/org/apache/struts2/dispatcher/FilterTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/struts2/dispatcher/FilterTest.java b/core/src/test/java/org/apache/struts2/dispatcher/FilterTest.java
deleted file mode 100644
index 5d1647d..0000000
--- a/core/src/test/java/org/apache/struts2/dispatcher/FilterTest.java
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
- * $Id$
- *
- * 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;
-
-import java.io.IOException;
-import java.util.HashMap;
-
-import javax.servlet.FilterConfig;
-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.StrutsInternalTestCase;
-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;
-import com.opensymphony.xwork2.inject.Container;
-
-
-/**
- *
- * @version $Date$ $Id$
- */
-public class FilterTest extends StrutsInternalTestCase {
-
-    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 {
-        super.tearDown();
-        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 {
-        super.setUp();
-        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();
-
-        filterDispatcher = new FilterDispatcher() {
-            @Override
-            protected Dispatcher createDispatcher(FilterConfig filterConfig) {
-                filterDispatcherCreateDispatcherCount++;
-                return _dispatcher2;
-            }
-            
-            @Override
-            public String toString() {
-                return "filterDispatcher";
-            }
-        };
-    }
-
-    public void testUsingFilterDispatcherOnly() throws Exception {
-        assertEquals(cleanUpFilterCreateDispatcherCount, 0);
-        assertEquals(filterDispatcherCreateDispatcherCount, 0);
-        assertFalse(_dispatcher1.init);
-        assertFalse(_dispatcher1.prepare);
-        assertFalse(_dispatcher1.wrapRequest);
-        assertFalse(_dispatcher1.service);
-        assertFalse(_dispatcher2.init);
-        assertFalse(_dispatcher2.prepare);
-        assertFalse(_dispatcher2.wrapRequest);
-        assertFalse(_dispatcher2.service);
-
-        filterDispatcher.init(filterConfig);
-        filterDispatcher.setActionMapper(new FilterTest.InnerMapper());
-        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.init);
-        assertFalse(_dispatcher1.prepare);
-        assertFalse(_dispatcher1.wrapRequest);
-        assertFalse(_dispatcher1.service);
-        assertTrue(_dispatcher2.init);
-        assertTrue(_dispatcher2.prepare);
-        assertTrue(_dispatcher2.wrapRequest);
-        assertTrue(_dispatcher2.service);
-        assertTrue(Dispatcher.getInstance() == null);
-    }
-
-
-    public void testUsingFilterDispatcherOnly_Multiple() throws Exception {
-        
-        filterDispatcher.setActionMapper(new FilterTest.InnerMapper());
-
-        assertEquals(cleanUpFilterCreateDispatcherCount, 0);
-        assertEquals(filterDispatcherCreateDispatcherCount, 0);
-        assertFalse(_dispatcher1.prepare);
-        assertFalse(_dispatcher1.wrapRequest);
-        assertFalse(_dispatcher1.service);
-        assertFalse(_dispatcher1.cleanUp);
-        assertFalse(_dispatcher2.prepare);
-        assertFalse(_dispatcher2.wrapRequest);
-        assertFalse(_dispatcher2.service);
-        assertFalse(_dispatcher2.cleanUp);
-
-        filterDispatcher.init(filterConfig);
-        filterDispatcher.setActionMapper(new FilterTest.InnerMapper());
-        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);
-        assertFalse(_dispatcher1.cleanUp);
-        assertTrue(_dispatcher2.prepare);
-        assertTrue(_dispatcher2.wrapRequest);
-        assertTrue(_dispatcher2.service);
-        assertTrue(_dispatcher2.cleanUp);
-        assertTrue(Dispatcher.getInstance() == null);
-        
-    }
-
-    
-
-    /*public void testUsingCleanUpAndFilterDispatcher() throws Exception {
-        ObjectFactory oldObjecFactory = ObjectFactory.getObjectFactory();
-        try {
-            ObjectFactory.setObjectFactory(new InnerObjectFactory());
-            filterDispatcher.setActionMapper(new 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(1, cleanUpFilterCreateDispatcherCount);
-            assertEquals(1, filterDispatcherCreateDispatcherCount);
-            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());
-            filterDispatcher.setActionMapper(new 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 init = false;
-        public boolean prepare = false;
-        public boolean wrapRequest = false;
-        public boolean service = false;
-        public boolean cleanUp = false;
-
-        public InnerDispatcher(ServletContext servletContext) {
-            super(servletContext, new HashMap<String, String>());
-        }
-        
-        @Override
-        public void init() {
-        	init= true;
-        }
-        
-        @Override 
-        public Container getContainer() {
-            return container;
-        }
-
-        @Override
-        public void prepare(HttpServletRequest request, HttpServletResponse response) {
-            prepare = true;
-        }
-
-        @Override
-        public HttpServletRequest wrapRequest(HttpServletRequest request) throws IOException {
-            wrapRequest = true;
-            return request;
-        }
-
-        @Override
-        public void serviceAction(HttpServletRequest request, HttpServletResponse response, ActionMapping mapping) throws ServletException {
-            service = true;
-        }
-
-        @Override
-        public void cleanup() {
-        	cleanUp = true;
-        }
-    }
-
-    class NullInnerMapper implements ActionMapper {
-        public ActionMapping getMapping(HttpServletRequest request, ConfigurationManager configManager) {
-            return null;
-        }
-
-        public ActionMapping getMappingFromActionName(String actionName) {
-            return null;  //To change body of implemented methods use File | Settings | File Templates.
-        }
-
-        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 ActionMapping getMappingFromActionName(String actionName) {
-            return null;  //To change body of implemented methods use File | Settings | File Templates.
-        }
-
-        public String getUriFromActionMapping(ActionMapping mapping) {
-            return "";
-        }
-    }
-
-    class InnerObjectFactory extends ObjectFactory {
-        public InnerObjectFactory() {
-            super();
-        }
-    }
-}
-

http://git-wip-us.apache.org/repos/asf/struts/blob/8de090fd/plugins/json/src/main/java/org/apache/struts2/json/JSONInterceptor.java
----------------------------------------------------------------------
diff --git a/plugins/json/src/main/java/org/apache/struts2/json/JSONInterceptor.java b/plugins/json/src/main/java/org/apache/struts2/json/JSONInterceptor.java
index 895245a..f81609f 100644
--- a/plugins/json/src/main/java/org/apache/struts2/json/JSONInterceptor.java
+++ b/plugins/json/src/main/java/org/apache/struts2/json/JSONInterceptor.java
@@ -31,7 +31,7 @@ import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 import org.apache.struts2.ServletActionContext;
 import org.apache.struts2.StrutsConstants;
-import org.apache.struts2.dispatcher.FilterDispatcher;
+import org.apache.struts2.dispatcher.ng.PrepareOperations;
 import org.apache.struts2.json.annotations.SMDMethod;
 import org.apache.struts2.json.rpc.RPCError;
 import org.apache.struts2.json.rpc.RPCErrorCode;
@@ -382,7 +382,7 @@ public class JSONInterceptor extends AbstractInterceptor {
      * @return true if debugging is turned on
      */
     public boolean getDebug() {
-        Boolean devModeOverride = FilterDispatcher.getDevModeOverride();
+        Boolean devModeOverride = PrepareOperations.getDevModeOverride();
         return devModeOverride != null ? devModeOverride : this.debug;
     }