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 <[email protected]> Authored: Tue Jun 23 16:09:34 2015 +0200 Committer: Lukasz Lenart <[email protected]> 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; }
