This is an automated email from the ASF dual-hosted git repository.

lukaszlenart pushed a commit to branch action-context-boost
in repository https://gitbox.apache.org/repos/asf/struts.git

commit 6721c9c98ae2eaf926f20901998990c4add798f2
Author: Lukasz Lenart <lukaszlen...@apache.org>
AuthorDate: Sat Mar 21 10:05:48 2020 +0100

    WW-4789 WW-3788 ActionContext refactoring
---
 .../com/opensymphony/xwork2/ActionContext.java     |  46 +++++-
 .../opensymphony/xwork2/ognl/OgnlValueStack.java   |   5 +
 .../interceptor/ActionAutowiringInterceptor.java   |   5 +-
 .../com/opensymphony/xwork2/util/ValueStack.java   |  44 +++---
 .../org/apache/struts2/ServletActionContext.java   |  38 +++--
 .../java/org/apache/struts2/StrutsStatics.java     |  38 +++--
 .../apache/struts2/components/ActionComponent.java |   8 +-
 .../struts2/components/ServletUrlRenderer.java     |   2 +-
 .../template/FreemarkerTemplateEngine.java         |   8 +-
 .../org/apache/struts2/dispatcher/Dispatcher.java  | 155 ++++++++++++---------
 .../apache/struts2/dispatcher/InitOperations.java  |   4 +-
 .../dispatcher/listener/StrutsListener.java        |   1 -
 .../dispatcher/mapper/DefaultActionMapper.java     |   2 +-
 .../ActionMappingParametersInterceptor.java        |   2 +-
 .../interceptor/CookieProviderInterceptor.java     |   2 +-
 .../interceptor/CreateSessionInterceptor.java      |   9 +-
 .../struts2/interceptor/FileUploadInterceptor.java |   2 +-
 .../interceptor/MessageStoreInterceptor.java       |   2 +-
 .../interceptor/ServletConfigInterceptor.java      |  16 +--
 .../interceptor/TokenSessionStoreInterceptor.java  |   6 +-
 .../debugging/DebuggingInterceptor.java            |   6 +-
 .../main/java/org/apache/struts2/util/URLBean.java |   3 +-
 .../struts2/views/freemarker/FreemarkerResult.java |   2 +-
 .../com/opensymphony/xwork2/StubValueStack.java    |   5 +
 .../apache/struts2/ServletActionContextTest.java   |  10 +-
 .../interceptor/CreateSessionInterceptorTest.java  |  13 +-
 .../struts2/interceptor/I18nInterceptorTest.java   |   2 +-
 .../main/java/org/apache/struts2/JSPLoader.java    |   6 +-
 .../sitemesh/FreemarkerDecoratorServlet.java       |   2 +-
 .../struts2/sitemesh/VelocityDecoratorServlet.java |   2 +-
 30 files changed, 270 insertions(+), 176 deletions(-)

diff --git a/core/src/main/java/com/opensymphony/xwork2/ActionContext.java 
b/core/src/main/java/com/opensymphony/xwork2/ActionContext.java
index 757dffd..595c7c6 100644
--- a/core/src/main/java/com/opensymphony/xwork2/ActionContext.java
+++ b/core/src/main/java/com/opensymphony/xwork2/ActionContext.java
@@ -22,8 +22,14 @@ import 
com.opensymphony.xwork2.conversion.impl.ConversionData;
 import com.opensymphony.xwork2.inject.Container;
 import com.opensymphony.xwork2.util.ValueStack;
 import org.apache.struts2.StrutsException;
+import org.apache.struts2.StrutsStatics;
 import org.apache.struts2.dispatcher.HttpParameters;
+import org.apache.struts2.dispatcher.mapper.ActionMapping;
 
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.jsp.PageContext;
 import java.io.Serializable;
 import java.util.HashMap;
 import java.util.Locale;
@@ -106,12 +112,18 @@ public class ActionContext implements Serializable {
      * Creates a new ActionContext initialized with another context.
      *
      * @param context a context map.
+     *
+     * @deprecated Please use {@link #of(Map)} builder method
      */
+    @Deprecated
     public ActionContext(Map<String, Object> context) {
         this.context = context;
     }
 
-
+    public static ActionContext of(Map<String, Object> context) {
+        ActionContext.setContext(new ActionContext(context));
+        return ActionContext.getContext();
+    }
     /**
      * Sets the action invocation (the execution state).
      *
@@ -347,4 +359,36 @@ public class ActionContext implements Serializable {
     public void put(String key, Object value) {
         context.put(key, value);
     }
+
+    public ServletContext getServletContext() {
+        return (ServletContext) get(StrutsStatics.SERVLET_CONTEXT);
+    }
+
+    public HttpServletRequest getServletRequest() {
+        return (HttpServletRequest) get(StrutsStatics.HTTP_REQUEST);
+    }
+
+    public HttpServletResponse getServletResponse() {
+        return (HttpServletResponse) get(StrutsStatics.HTTP_RESPONSE);
+    }
+
+    public void setServletContext(ServletContext servletContext) {
+        put(StrutsStatics.SERVLET_CONTEXT, servletContext);
+    }
+
+    public ActionMapping getActionMapping() {
+        return (ActionMapping) get(StrutsStatics.ACTION_MAPPING);
+    }
+
+    public PageContext getPageContext() {
+        return (PageContext) get(StrutsStatics.PAGE_CONTEXT);
+    }
+
+    public void setServletRequest(HttpServletRequest request) {
+        put(StrutsStatics.HTTP_REQUEST, request);
+    }
+
+    public void setServletResponse(HttpServletResponse response) {
+        put(StrutsStatics.HTTP_RESPONSE, response);
+    }
 }
diff --git 
a/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlValueStack.java 
b/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlValueStack.java
index 5aec937..1568a54 100644
--- a/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlValueStack.java
+++ b/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlValueStack.java
@@ -117,6 +117,11 @@ public class OgnlValueStack implements Serializable, 
ValueStack, ClearableValueS
         return context;
     }
 
+    @Override
+    public ActionContext getActionContext() {
+        return new ActionContext(context);
+    }
+
     /**
      * @see 
com.opensymphony.xwork2.util.ValueStack#setDefaultType(java.lang.Class)
      */
diff --git 
a/core/src/main/java/com/opensymphony/xwork2/spring/interceptor/ActionAutowiringInterceptor.java
 
b/core/src/main/java/com/opensymphony/xwork2/spring/interceptor/ActionAutowiringInterceptor.java
index 72f8438..bf87805 100644
--- 
a/core/src/main/java/com/opensymphony/xwork2/spring/interceptor/ActionAutowiringInterceptor.java
+++ 
b/core/src/main/java/com/opensymphony/xwork2/spring/interceptor/ActionAutowiringInterceptor.java
@@ -64,9 +64,8 @@ import org.springframework.web.context.WebApplicationContext;
  * @author Eric Hauser
  */
 public class ActionAutowiringInterceptor extends AbstractInterceptor 
implements ApplicationContextAware {
-    private static final Logger LOG = 
LogManager.getLogger(ActionAutowiringInterceptor.class);
 
-    public static final String APPLICATION_CONTEXT = 
"com.opensymphony.xwork2.spring.interceptor.ActionAutowiringInterceptor.applicationContext";
+    private static final Logger LOG = 
LogManager.getLogger(ActionAutowiringInterceptor.class);
 
     private boolean initialized = false;
     private ApplicationContext context;
@@ -121,8 +120,6 @@ public class ActionAutowiringInterceptor extends 
AbstractInterceptor implements
         if (factory != null) {
             Object bean = invocation.getAction();
             factory.autoWireBean(bean);
-    
-            ActionContext.getContext().put(APPLICATION_CONTEXT, context);
         }
         return invocation.invoke();
     }
diff --git a/core/src/main/java/com/opensymphony/xwork2/util/ValueStack.java 
b/core/src/main/java/com/opensymphony/xwork2/util/ValueStack.java
index c14b01b..4d02b23 100644
--- a/core/src/main/java/com/opensymphony/xwork2/util/ValueStack.java
+++ b/core/src/main/java/com/opensymphony/xwork2/util/ValueStack.java
@@ -18,6 +18,8 @@
  */
 package com.opensymphony.xwork2.util;
 
+import com.opensymphony.xwork2.ActionContext;
+
 import java.util.Map;
 
 /**
@@ -28,23 +30,25 @@ import java.util.Map;
  */
 public interface ValueStack {
 
-    public static final String VALUE_STACK = 
"com.opensymphony.xwork2.util.ValueStack.ValueStack";
+    String VALUE_STACK = "com.opensymphony.xwork2.util.ValueStack.ValueStack";
 
-    public static final String REPORT_ERRORS_ON_NO_PROP = 
"com.opensymphony.xwork2.util.ValueStack.ReportErrorsOnNoProp";
+    String REPORT_ERRORS_ON_NO_PROP = 
"com.opensymphony.xwork2.util.ValueStack.ReportErrorsOnNoProp";
 
     /**
      * Gets the context for this value stack. The context holds all the 
information in the value stack and it's surroundings.
      *
      * @return  the context.
      */
-    public abstract Map<String, Object> getContext();
+    Map<String, Object> getContext();
+
+    ActionContext getActionContext();
 
     /**
      * Sets the default type to convert to if no type is provided when getting 
a value.
      *
      * @param defaultType the new default type
      */
-    public abstract void setDefaultType(Class defaultType);
+    void setDefaultType(Class defaultType);
 
     /**
      * Set a override map containing <code> key -&gt; values </code> that 
takes precedent when doing find operations on the ValueStack.
@@ -54,21 +58,21 @@ public interface ValueStack {
      *
      * @param overrides  overrides map.
      */
-    public abstract void setExprOverrides(Map<Object, Object> overrides);
+    void setExprOverrides(Map<Object, Object> overrides);
 
     /**
      * Gets the override map if anyone exists.
      *
      * @return the override map, <tt>null</tt> if not set.
      */
-    public abstract Map<Object, Object> getExprOverrides();
+    Map<Object, Object> getExprOverrides();
 
     /**
      * Get the CompoundRoot which holds the objects pushed onto the stack
      *
      * @return the root
      */
-    public abstract CompoundRoot getRoot();
+    CompoundRoot getRoot();
 
     /**
      * Attempts to set a property on a bean in the stack with the given 
expression using the default search order.
@@ -76,7 +80,7 @@ public interface ValueStack {
      * @param expr  the expression defining the path to the property to be set.
      * @param value the value to be set into the named property
      */
-    public abstract void setValue(String expr, Object value);
+    void setValue(String expr, Object value);
 
     /**
      * Attempts to set a property on a bean in the stack with the given 
expression using the default search order.
@@ -94,10 +98,10 @@ public interface ValueStack {
      * @param throwExceptionOnFailure a flag to tell whether an exception 
should be thrown if there is no property with
      *                                the given name.
      */
-    public abstract void setValue(String expr, Object value, boolean 
throwExceptionOnFailure);
+    void setValue(String expr, Object value, boolean throwExceptionOnFailure);
 
-    public abstract String findString(String expr);
-    public abstract String findString(String expr, boolean 
throwExceptionOnFailure);
+    String findString(String expr);
+    String findString(String expr, boolean throwExceptionOnFailure);
 
     /**
      * Find a value by evaluating the given expression against the stack in 
the default search order.
@@ -105,9 +109,9 @@ public interface ValueStack {
      * @param expr the expression giving the path of properties to navigate to 
find the property value to return
      * @return the result of evaluating the expression
      */
-    public abstract Object findValue(String expr);
+    Object findValue(String expr);
 
-    public abstract Object findValue(String expr, boolean 
throwExceptionOnFailure);
+    Object findValue(String expr, boolean throwExceptionOnFailure);
 
     /**
      * Find a value by evaluating the given expression against the stack in 
the default search order.
@@ -116,8 +120,8 @@ public interface ValueStack {
      * @param asType the type to convert the return value to
      * @return the result of evaluating the expression
      */
-    public abstract Object findValue(String expr, Class asType);
-    public abstract Object findValue(String expr, Class asType,  boolean 
throwExceptionOnFailure);
+    Object findValue(String expr, Class asType);
+    Object findValue(String expr, Class asType, boolean 
throwExceptionOnFailure);
 
     /**
      * Get the object on the top of the stack <b>without</b> changing the 
stack.
@@ -125,7 +129,7 @@ public interface ValueStack {
      * @return the object on the top.
      * @see CompoundRoot#peek()
      */
-    public abstract Object peek();
+    Object peek();
 
     /**
      * Get the object on the top of the stack and <b>remove</b> it from the 
stack.
@@ -133,7 +137,7 @@ public interface ValueStack {
      * @return the object on the top of the stack
      * @see CompoundRoot#pop()
      */
-    public abstract Object pop();
+    Object pop();
 
     /**
      * Put this object onto the top of the stack
@@ -141,7 +145,7 @@ public interface ValueStack {
      * @param o the object to be pushed onto the stack
      * @see CompoundRoot#push(Object)
      */
-    public abstract void push(Object o);
+    void push(Object o);
 
     /**
      * Sets an object on the stack with the given key
@@ -150,13 +154,13 @@ public interface ValueStack {
      * @param key  the key
      * @param o    the object
      */
-    public abstract void set(String key, Object o);
+    void set(String key, Object o);
 
     /**
      * Get the number of objects in the stack
      *
      * @return the number of objects in the stack
      */
-    public abstract int size();
+    int size();
 
 }
\ No newline at end of file
diff --git a/core/src/main/java/org/apache/struts2/ServletActionContext.java 
b/core/src/main/java/org/apache/struts2/ServletActionContext.java
index 4af8d53..6942dbd 100644
--- a/core/src/main/java/org/apache/struts2/ServletActionContext.java
+++ b/core/src/main/java/org/apache/struts2/ServletActionContext.java
@@ -26,23 +26,18 @@ import javax.servlet.ServletContext;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.jsp.PageContext;
-import java.util.Map;
 
 /**
  * Web-specific context information for actions. This class subclasses 
<tt>ActionContext</tt> which
  * provides access to things like the action name, value stack, etc. This 
class adds access to
  * web objects like servlet parameters, request attributes and things like the 
HTTP session.
  */
-public class ServletActionContext extends ActionContext implements 
StrutsStatics {
-
-    private static final long serialVersionUID = -666854718275106687L;
+public class ServletActionContext implements StrutsStatics {
 
     public static final String STRUTS_VALUESTACK_KEY = "struts.valueStack";
-    public static final String ACTION_MAPPING = "struts.actionMapping";
 
     @SuppressWarnings("unused")
-    private ServletActionContext(Map context) {
-        super(context);
+    private ServletActionContext() {
     }
 
     /**
@@ -61,6 +56,19 @@ public class ServletActionContext extends ActionContext 
implements StrutsStatics
     }
 
     /**
+     * Do not use this method, use {@link #getActionContext()}
+     * @return action context
+     * @deprecated Use {@link #getActionContext()} instead
+     */
+    @Deprecated
+    public static ActionContext getContext() {
+        return ActionContext.getContext();
+    }
+
+    public static ActionContext getActionContext() {
+        return ActionContext.getContext();
+    }
+    /**
      * Gets the current value stack for this request
      *
      * @param req The request
@@ -76,7 +84,7 @@ public class ServletActionContext extends ActionContext 
implements StrutsStatics
      * @return The action mapping
      */
     public static ActionMapping getActionMapping() {
-        return (ActionMapping) ActionContext.getContext().get(ACTION_MAPPING);
+        return ActionContext.getContext().getActionMapping();
     }
 
     /**
@@ -85,7 +93,7 @@ public class ServletActionContext extends ActionContext 
implements StrutsStatics
      * @return the HTTP page context.
      */
     public static PageContext getPageContext() {
-        return (PageContext) ActionContext.getContext().get(PAGE_CONTEXT);
+        return ActionContext.getContext().getPageContext();
     }
 
     /**
@@ -94,7 +102,7 @@ public class ServletActionContext extends ActionContext 
implements StrutsStatics
      * @param request the HTTP servlet request object.
      */
     public static void setRequest(HttpServletRequest request) {
-        ActionContext.getContext().put(HTTP_REQUEST, request);
+        ActionContext.getContext().setServletRequest(request);
     }
 
     /**
@@ -103,7 +111,7 @@ public class ServletActionContext extends ActionContext 
implements StrutsStatics
      * @return the HTTP servlet request object.
      */
     public static HttpServletRequest getRequest() {
-        return (HttpServletRequest) 
ActionContext.getContext().get(HTTP_REQUEST);
+        return ActionContext.getContext().getServletRequest();
     }
 
     /**
@@ -112,7 +120,7 @@ public class ServletActionContext extends ActionContext 
implements StrutsStatics
      * @param response the HTTP servlet response object.
      */
     public static void setResponse(HttpServletResponse response) {
-        ActionContext.getContext().put(HTTP_RESPONSE, response);
+        ActionContext.getContext().setServletResponse(response);
     }
 
     /**
@@ -121,7 +129,7 @@ public class ServletActionContext extends ActionContext 
implements StrutsStatics
      * @return the HTTP servlet response object.
      */
     public static HttpServletResponse getResponse() {
-        return (HttpServletResponse) 
ActionContext.getContext().get(HTTP_RESPONSE);
+        return ActionContext.getContext().getServletResponse();
     }
 
     /**
@@ -130,7 +138,7 @@ public class ServletActionContext extends ActionContext 
implements StrutsStatics
      * @return the servlet context.
      */
     public static ServletContext getServletContext() {
-        return (ServletContext) 
ActionContext.getContext().get(SERVLET_CONTEXT);
+        return ActionContext.getContext().getServletContext();
     }
 
     /**
@@ -139,6 +147,6 @@ public class ServletActionContext extends ActionContext 
implements StrutsStatics
      * @param servletContext The servlet context to use
      */
     public static void setServletContext(ServletContext servletContext) {
-        ActionContext.getContext().put(SERVLET_CONTEXT, servletContext);
+        ActionContext.getContext().setServletContext(servletContext);
     }
 }
diff --git a/core/src/main/java/org/apache/struts2/StrutsStatics.java 
b/core/src/main/java/org/apache/struts2/StrutsStatics.java
index c4e2c1c..e0adccc 100644
--- a/core/src/main/java/org/apache/struts2/StrutsStatics.java
+++ b/core/src/main/java/org/apache/struts2/StrutsStatics.java
@@ -18,22 +18,12 @@
  */
 package org.apache.struts2;
 
+import javax.servlet.ServletContext;
+
 /**
  * <p>
- * Constants used by Struts. The constants can be used to get or set objects
- * out of the action context or other collections.
- * </p>
- *
- * <p>
- * Example:
- *
- * <code>ActionContext.getContext().put(HTTP_REQUEST, request);</code>
- *
- * or
- *
- * <code>
- * ActionContext context = ActionContext.getContext();<br>
- * HttpServletRequest request = 
(HttpServletRequest)context.get(HTTP_REQUEST);</code>
+ * Constants used internally by Struts. Do not use these constants directly,
+ * instead use exposed helpers eg.: {@link 
org.apache.struts2.dispatcher.Dispatcher#getInstance(ServletContext)}
  * </p>
  */
 public interface StrutsStatics {
@@ -41,34 +31,38 @@ public interface StrutsStatics {
     /**
      * Constant for the HTTP request object.
      */
-    public static final String HTTP_REQUEST = 
"com.opensymphony.xwork2.dispatcher.HttpServletRequest";
+    String HTTP_REQUEST = 
"com.opensymphony.xwork2.dispatcher.HttpServletRequest";
 
     /**
      * Constant for the HTTP response object.
      */
-    public static final String HTTP_RESPONSE = 
"com.opensymphony.xwork2.dispatcher.HttpServletResponse";
+    String HTTP_RESPONSE = 
"com.opensymphony.xwork2.dispatcher.HttpServletResponse";
 
     /**
      * Constant for an HTTP {@link javax.servlet.RequestDispatcher request 
dispatcher}.
      */
-    public static final String SERVLET_DISPATCHER = 
"com.opensymphony.xwork2.dispatcher.ServletDispatcher";
+    String SERVLET_DISPATCHER = 
"com.opensymphony.xwork2.dispatcher.ServletDispatcher";
 
     /**
      * Constant for the {@link javax.servlet.ServletContext servlet context} 
object.
      */
-    public static final String SERVLET_CONTEXT = 
"com.opensymphony.xwork2.dispatcher.ServletContext";
+    String SERVLET_CONTEXT = 
"com.opensymphony.xwork2.dispatcher.ServletContext";
 
     /**
      * Constant for the JSP {@link javax.servlet.jsp.PageContext page context}.
      */
-    public static final String PAGE_CONTEXT = 
"com.opensymphony.xwork2.dispatcher.PageContext";
+    String PAGE_CONTEXT = "com.opensymphony.xwork2.dispatcher.PageContext";
 
-    /** Constant for the PortletContext object */
-    public static final String STRUTS_PORTLET_CONTEXT = 
"struts.portlet.context";
+    /**
+     * Constant for the PortletContext object
+     */
+    String STRUTS_PORTLET_CONTEXT = "struts.portlet.context";
 
     /**
      * Set as an attribute in the request to let other parts of the framework 
know that the invocation is happening inside an
      * action tag
      */
-    public static final String STRUTS_ACTION_TAG_INVOCATION= 
"struts.actiontag.invocation";
+    String STRUTS_ACTION_TAG_INVOCATION = "struts.actiontag.invocation";
+
+    String ACTION_MAPPING = "struts.actionMapping";
 }
diff --git 
a/core/src/main/java/org/apache/struts2/components/ActionComponent.java 
b/core/src/main/java/org/apache/struts2/components/ActionComponent.java
index 901556f..8c32d43 100644
--- a/core/src/main/java/org/apache/struts2/components/ActionComponent.java
+++ b/core/src/main/java/org/apache/struts2/components/ActionComponent.java
@@ -178,10 +178,10 @@ public class ActionComponent extends ContextBean {
     protected Map createExtraContext() {
         HttpParameters newParams = createParametersForContext();
 
-        ActionContext ctx = new ActionContext(stack.getContext());
-        PageContext pageContext = (PageContext) 
ctx.get(ServletActionContext.PAGE_CONTEXT);
-        Map session = ctx.getSession();
-        Map application = ctx.getApplication();
+        ActionContext ctx = stack.getActionContext();
+        PageContext pageContext = ctx.getPageContext();
+        Map<String, Object> session = ctx.getSession();
+        Map<String, Object> application = ctx.getApplication();
 
         Dispatcher du = Dispatcher.getInstance();
         Map<String, Object> extraContext = du.createContextMap(new 
RequestMap(req),
diff --git 
a/core/src/main/java/org/apache/struts2/components/ServletUrlRenderer.java 
b/core/src/main/java/org/apache/struts2/components/ServletUrlRenderer.java
index b41b4d6..550fa35 100644
--- a/core/src/main/java/org/apache/struts2/components/ServletUrlRenderer.java
+++ b/core/src/main/java/org/apache/struts2/components/ServletUrlRenderer.java
@@ -74,7 +74,7 @@ public class ServletUrlRenderer implements UrlRenderer {
         }
 
         String result;
-        ActionInvocation ai = (ActionInvocation) 
ActionContext.getContext().get(ActionContext.ACTION_INVOCATION);
+        ActionInvocation ai = ActionContext.getContext().getActionInvocation();
         if (urlComponent.getValue() == null && urlComponent.getAction() != 
null) {
             result = urlComponent.determineActionURL(urlComponent.getAction(), 
urlComponent.getNamespace(), urlComponent.getMethod(), 
urlComponent.getHttpServletRequest(), urlComponent.getHttpServletResponse(), 
urlComponent.getParameters(), scheme, urlComponent.isIncludeContext(), 
urlComponent.isEncode(), urlComponent.isForceAddSchemeHostAndPort(), 
urlComponent.isEscapeAmp());
         } else if (urlComponent.getValue() == null && urlComponent.getAction() 
== null && ai != null) {
diff --git 
a/core/src/main/java/org/apache/struts2/components/template/FreemarkerTemplateEngine.java
 
b/core/src/main/java/org/apache/struts2/components/template/FreemarkerTemplateEngine.java
index a272697..7cec84a 100644
--- 
a/core/src/main/java/org/apache/struts2/components/template/FreemarkerTemplateEngine.java
+++ 
b/core/src/main/java/org/apache/struts2/components/template/FreemarkerTemplateEngine.java
@@ -68,10 +68,10 @@ public class FreemarkerTemplateEngine extends 
BaseTemplateEngine {
     public void renderTemplate(TemplateRenderingContext templateContext) 
throws Exception {
        // get the various items required from the stack
         ValueStack stack = templateContext.getStack();
-        Map context = stack.getContext();
-        ServletContext servletContext = (ServletContext) 
context.get(ServletActionContext.SERVLET_CONTEXT);
-        HttpServletRequest req = (HttpServletRequest) 
context.get(ServletActionContext.HTTP_REQUEST);
-        HttpServletResponse res = (HttpServletResponse) 
context.get(ServletActionContext.HTTP_RESPONSE);
+        ActionContext context = stack.getActionContext();
+        ServletContext servletContext = context.getServletContext();
+        HttpServletRequest req = context.getServletRequest();
+        HttpServletResponse res = context.getServletResponse();
 
         // prepare freemarker
         Configuration config = 
freemarkerManager.getConfiguration(servletContext);
diff --git a/core/src/main/java/org/apache/struts2/dispatcher/Dispatcher.java 
b/core/src/main/java/org/apache/struts2/dispatcher/Dispatcher.java
index 27d025b..8bf67cf 100644
--- a/core/src/main/java/org/apache/struts2/dispatcher/Dispatcher.java
+++ b/core/src/main/java/org/apache/struts2/dispatcher/Dispatcher.java
@@ -18,8 +18,22 @@
  */
 package org.apache.struts2.dispatcher;
 
-import com.opensymphony.xwork2.*;
-import com.opensymphony.xwork2.config.*;
+import com.opensymphony.xwork2.ActionContext;
+import com.opensymphony.xwork2.ActionInvocation;
+import com.opensymphony.xwork2.ActionProxy;
+import com.opensymphony.xwork2.ActionProxyFactory;
+import com.opensymphony.xwork2.FileManager;
+import com.opensymphony.xwork2.FileManagerFactory;
+import com.opensymphony.xwork2.LocaleProviderFactory;
+import com.opensymphony.xwork2.ObjectFactory;
+import com.opensymphony.xwork2.Result;
+import com.opensymphony.xwork2.config.Configuration;
+import com.opensymphony.xwork2.config.ConfigurationException;
+import com.opensymphony.xwork2.config.ConfigurationManager;
+import com.opensymphony.xwork2.config.ConfigurationProvider;
+import com.opensymphony.xwork2.config.FileManagerFactoryProvider;
+import com.opensymphony.xwork2.config.FileManagerProvider;
+import com.opensymphony.xwork2.config.ServletContextAwareConfigurationProvider;
 import com.opensymphony.xwork2.config.entities.InterceptorMapping;
 import com.opensymphony.xwork2.config.entities.InterceptorStackConfig;
 import com.opensymphony.xwork2.config.entities.PackageConfig;
@@ -34,8 +48,8 @@ import com.opensymphony.xwork2.util.ValueStackFactory;
 import com.opensymphony.xwork2.util.location.LocatableProperties;
 import com.opensymphony.xwork2.util.location.Location;
 import com.opensymphony.xwork2.util.location.LocationUtils;
-import org.apache.commons.lang3.LocaleUtils;
 import org.apache.commons.lang3.BooleanUtils;
+import org.apache.commons.lang3.LocaleUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
@@ -44,15 +58,16 @@ import org.apache.struts2.ServletActionContext;
 import org.apache.struts2.StrutsConstants;
 import org.apache.struts2.StrutsException;
 import org.apache.struts2.StrutsStatics;
-import org.apache.struts2.config.StrutsBeanSelectionProvider;
 import org.apache.struts2.config.DefaultPropertiesProvider;
 import org.apache.struts2.config.PropertiesConfigurationProvider;
+import org.apache.struts2.config.StrutsBeanSelectionProvider;
 import org.apache.struts2.config.StrutsJavaConfiguration;
 import org.apache.struts2.config.StrutsJavaConfigurationProvider;
 import org.apache.struts2.config.StrutsXmlConfigurationProvider;
 import org.apache.struts2.dispatcher.mapper.ActionMapping;
 import org.apache.struts2.dispatcher.multipart.MultiPartRequest;
 import org.apache.struts2.dispatcher.multipart.MultiPartRequestWrapper;
+import org.apache.struts2.dispatcher.servlet.StrutsServlet;
 import org.apache.struts2.util.AttributeMap;
 import org.apache.struts2.util.ObjectFactoryDestroyable;
 import org.apache.struts2.util.fs.JBossFileManager;
@@ -63,7 +78,13 @@ import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.io.File;
 import java.io.IOException;
-import java.util.*;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.regex.Pattern;
 
@@ -220,15 +241,20 @@ public class Dispatcher {
      * Create the Dispatcher instance for a given ServletContext and set of 
initialization parameters.
      *
      * @param servletContext Our servlet context
-     * @param initParams The set of initialization parameters
+     * @param initParams     The set of initialization parameters
      */
     public Dispatcher(ServletContext servletContext, Map<String, String> 
initParams) {
         this.servletContext = servletContext;
         this.initParams = initParams;
     }
 
+    public static Dispatcher getInstance(ServletContext servletContext) {
+        return (Dispatcher) 
servletContext.getAttribute(StrutsStatics.SERVLET_DISPATCHER);
+    }
+
     /**
      * Modify state of StrutsConstants.STRUTS_DEVMODE setting.
+     *
      * @param mode New setting
      */
     @Inject(StrutsConstants.STRUTS_DEVMODE)
@@ -242,24 +268,27 @@ public class Dispatcher {
 
     /**
      * Modify state of 
StrutsConstants.DISABLE_REQUEST_ATTRIBUTE_VALUE_STACK_LOOKUP setting.
+     *
      * @param disableRequestAttributeValueStackLookup New setting
      */
-    
@Inject(value=StrutsConstants.STRUTS_DISABLE_REQUEST_ATTRIBUTE_VALUE_STACK_LOOKUP,
 required=false)
+    @Inject(value = 
StrutsConstants.STRUTS_DISABLE_REQUEST_ATTRIBUTE_VALUE_STACK_LOOKUP, required = 
false)
     public void setDisableRequestAttributeValueStackLookup(String 
disableRequestAttributeValueStackLookup) {
         this.disableRequestAttributeValueStackLookup = 
BooleanUtils.toBoolean(disableRequestAttributeValueStackLookup);
     }
 
     /**
      * Modify state of StrutsConstants.STRUTS_LOCALE setting.
+     *
      * @param val New setting
      */
-    @Inject(value=StrutsConstants.STRUTS_LOCALE, required=false)
+    @Inject(value = StrutsConstants.STRUTS_LOCALE, required = false)
     public void setDefaultLocale(String val) {
         defaultLocale = val;
     }
 
     /**
      * Modify state of StrutsConstants.STRUTS_I18N_ENCODING setting.
+     *
      * @param val New setting
      */
     @Inject(StrutsConstants.STRUTS_I18N_ENCODING)
@@ -269,6 +298,7 @@ public class Dispatcher {
 
     /**
      * Modify state of StrutsConstants.STRUTS_MULTIPART_SAVEDIR setting.
+     *
      * @param val New setting
      */
     @Inject(StrutsConstants.STRUTS_MULTIPART_SAVEDIR)
@@ -314,17 +344,15 @@ public class Dispatcher {
      * Releases all instances bound to this dispatcher instance.
      */
     public void cleanup() {
-
-       // clean up ObjectFactory
+        // clean up ObjectFactory
         ObjectFactory objectFactory = 
getContainer().getInstance(ObjectFactory.class);
         if (objectFactory == null) {
-               LOG.warn("Object Factory is null, something is seriously wrong, 
no clean up will be performed");
+            LOG.warn("Object Factory is null, something is seriously wrong, no 
clean up will be performed");
         }
         if (objectFactory instanceof ObjectFactoryDestroyable) {
             try {
-                ((ObjectFactoryDestroyable)objectFactory).destroy();
-            }
-            catch(Exception e) {
+                ((ObjectFactoryDestroyable) objectFactory).destroy();
+            } catch (Exception e) {
                 // catch any exception that may occurred during destroy() and 
log it
                 LOG.error("Exception occurred while destroying ObjectFactory 
[{}]", objectFactory.toString(), e);
             }
@@ -332,6 +360,7 @@ public class Dispatcher {
 
         // clean up Dispatcher itself for this thread
         instance.set(null);
+        servletContext.setAttribute(StrutsStatics.SERVLET_DISPATCHER, null);
 
         // clean up DispatcherListeners
         if (!dispatcherListeners.isEmpty()) {
@@ -347,13 +376,13 @@ public class Dispatcher {
             for (Object config : 
packageConfig.getAllInterceptorConfigs().values()) {
                 if (config instanceof InterceptorStackConfig) {
                     for (InterceptorMapping interceptorMapping : 
((InterceptorStackConfig) config).getInterceptors()) {
-                           
interceptors.add(interceptorMapping.getInterceptor());
+                        interceptors.add(interceptorMapping.getInterceptor());
                     }
                 }
             }
         }
         for (Interceptor interceptor : interceptors) {
-               interceptor.destroy();
+            interceptor.destroy();
         }
 
         // Clear container holder when application is unloaded / server 
shutdown
@@ -363,8 +392,8 @@ public class Dispatcher {
         ActionContext.setContext(null);
 
         // clean up configuration
-       configurationManager.destroyConfiguration();
-       configurationManager = null;
+        configurationManager.destroyConfiguration();
+        configurationManager = null;
     }
 
     private void init_FileManager() throws ClassNotFoundException {
@@ -388,7 +417,7 @@ public class Dispatcher {
     private void init_DefaultProperties() {
         configurationManager.addContainerProvider(new 
DefaultPropertiesProvider());
     }
-    
+
     private void init_LegacyStrutsProperties() {
         configurationManager.addContainerProvider(new 
PropertiesConfigurationProvider());
     }
@@ -443,17 +472,17 @@ public class Dispatcher {
             for (String cname : classes) {
                 try {
                     Class cls = ClassLoaderUtil.loadClass(cname, 
this.getClass());
-                    ConfigurationProvider prov = 
(ConfigurationProvider)cls.newInstance();
+                    ConfigurationProvider prov = (ConfigurationProvider) 
cls.newInstance();
                     if (prov instanceof 
ServletContextAwareConfigurationProvider) {
-                        
((ServletContextAwareConfigurationProvider)prov).initWithContext(servletContext);
+                        ((ServletContextAwareConfigurationProvider) 
prov).initWithContext(servletContext);
                     }
                     configurationManager.addContainerProvider(prov);
                 } catch (InstantiationException e) {
-                    throw new ConfigurationException("Unable to instantiate 
provider: "+cname, e);
+                    throw new ConfigurationException("Unable to instantiate 
provider: " + cname, e);
                 } catch (IllegalAccessException e) {
-                    throw new ConfigurationException("Unable to access 
provider: "+cname, e);
+                    throw new ConfigurationException("Unable to access 
provider: " + cname, e);
                 } catch (ClassNotFoundException e) {
-                    throw new ConfigurationException("Unable to locate 
provider class: "+cname, e);
+                    throw new ConfigurationException("Unable to locate 
provider class: " + cname, e);
                 }
             }
         }
@@ -495,7 +524,7 @@ public class Dispatcher {
             paramsWorkaroundEnabled = true;
         } else {
             paramsWorkaroundEnabled = 
"true".equals(container.getInstance(String.class,
-                    StrutsConstants.STRUTS_DISPATCHER_PARAMETERSWORKAROUND));
+                StrutsConstants.STRUTS_DISPATCHER_PARAMETERSWORKAROUND));
         }
     }
 
@@ -504,10 +533,9 @@ public class Dispatcher {
      * and update optional settings, including whether to reload 
configurations and resource files.
      */
     public void init() {
-
-       if (configurationManager == null) {
-               configurationManager = 
createConfigurationManager(Container.DEFAULT_NAME);
-       }
+        if (configurationManager == null) {
+            configurationManager = 
createConfigurationManager(Container.DEFAULT_NAME);
+        }
 
         try {
             init_FileManager();
@@ -516,8 +544,8 @@ public class Dispatcher {
             init_JavaConfigurations();
             init_LegacyStrutsProperties(); // [3]
             init_CustomConfigurationProviders(); // [5]
-            init_FilterInitParameters() ; // [6]
-            init_AliasStandardObjects() ; // [7]
+            init_FilterInitParameters(); // [6]
+            init_AliasStandardObjects(); // [7]
 
             Container container = init_PreloadConfiguration();
             container.inject(this);
@@ -530,6 +558,9 @@ public class Dispatcher {
             }
             errorHandler.init(servletContext);
 
+            if (servletContext.getAttribute(StrutsStatics.SERVLET_DISPATCHER) 
== null) {
+                servletContext.setAttribute(StrutsStatics.SERVLET_DISPATCHER, 
this);
+            }
         } catch (Exception ex) {
             LOG.error("Dispatcher initialization failed", ex);
             throw new StrutsException(ex);
@@ -559,11 +590,10 @@ public class Dispatcher {
      * @param mapping  the action mapping object
      * @throws ServletException when an unknown error occurs (not a 404, but 
typically something that
      *                          would end up as a 5xx by the servlet container)
-     *
      * @since 2.3.17
      */
     public void serviceAction(HttpServletRequest request, HttpServletResponse 
response, ActionMapping mapping)
-            throws ServletException {
+        throws ServletException {
 
         Map<String, Object> extraContext = createContextMap(request, response, 
mapping);
 
@@ -591,7 +621,7 @@ public class Dispatcher {
             ActionInvocation invocation = 
ActionContext.getContext().getActionInvocation();
             if (invocation == null || invocation.isExecuted()) {
                 proxy = 
getContainer().getInstance(ActionProxyFactory.class).createActionProxy(namespace,
 name, method,
-                        extraContext, true, false);
+                    extraContext, true, false);
             } else {
                 proxy = invocation.getProxy();
             }
@@ -629,7 +659,7 @@ public class Dispatcher {
      * Performs logging of missing action/result configuration exception
      *
      * @param request current {@link HttpServletRequest}
-     * @param e {@link ConfigurationException} that occurred
+     * @param e       {@link ConfigurationException} that occurred
      */
     protected void logConfigurationException(HttpServletRequest request, 
ConfigurationException e) {
         // WW-2874 Only log error if in devMode
@@ -647,15 +677,14 @@ public class Dispatcher {
     /**
      * Create a context map containing all the wrapped request objects
      *
-     * @param request The servlet request
+     * @param request  The servlet request
      * @param response The servlet response
-     * @param mapping The action mapping
+     * @param mapping  The action mapping
      * @return A map of context objects
-     *
      * @since 2.3.17
      */
-    public Map<String,Object> createContextMap(HttpServletRequest request, 
HttpServletResponse response,
-            ActionMapping mapping) {
+    public Map<String, Object> createContextMap(HttpServletRequest request, 
HttpServletResponse response,
+                                                ActionMapping mapping) {
 
         // request map wrapping the http request objects
         Map requestMap = new RequestMap(request);
@@ -669,7 +698,7 @@ public class Dispatcher {
         // application map wrapping the ServletContext
         Map application = new ApplicationMap(servletContext);
 
-        Map<String,Object> extraContext = createContextMap(requestMap, params, 
session, application, request, response);
+        Map<String, Object> extraContext = createContextMap(requestMap, 
params, session, application, request, response);
 
         if (mapping != null) {
             extraContext.put(ServletActionContext.ACTION_MAPPING, mapping);
@@ -688,15 +717,14 @@ public class Dispatcher {
      * @param request        the HttpServletRequest object.
      * @param response       the HttpServletResponse object.
      * @return a HashMap representing the <tt>Action</tt> context.
-     *
      * @since 2.3.17
      */
-    public HashMap<String,Object> createContextMap(Map requestMap,
-                                    HttpParameters parameters,
-                                    Map sessionMap,
-                                    Map applicationMap,
-                                    HttpServletRequest request,
-                                    HttpServletResponse response) {
+    public HashMap<String, Object> createContextMap(Map requestMap,
+                                                    HttpParameters parameters,
+                                                    Map sessionMap,
+                                                    Map applicationMap,
+                                                    HttpServletRequest request,
+                                                    HttpServletResponse 
response) {
         HashMap<String, Object> extraContext = new HashMap<>();
         extraContext.put(ActionContext.PARAMETERS, parameters);
         extraContext.put(ActionContext.SESSION, sessionMap);
@@ -727,7 +755,7 @@ public class Dispatcher {
                 locale = LocaleUtils.toLocale(defaultLocale);
             } catch (IllegalArgumentException e) {
                 LOG.warn(new ParameterizedMessage("Cannot convert 
'struts.locale' = [{}] to proper locale, defaulting to request locale [{}]",
-                                defaultLocale, request.getLocale()), e);
+                    defaultLocale, request.getLocale()), e);
                 locale = request.getLocale();
             }
         } else {
@@ -746,7 +774,7 @@ public class Dispatcher {
 
         if (saveDir.equals("")) {
             File tempdir = (File) 
servletContext.getAttribute("javax.servlet.context.tempdir");
-               LOG.info("Unable to find 'struts.multipart.saveDir' property 
setting. Defaulting to javax.servlet.context.tempdir");
+            LOG.info("Unable to find 'struts.multipart.saveDir' property 
setting. Defaulting to javax.servlet.context.tempdir");
 
             if (tempdir != null) {
                 saveDir = tempdir.toString();
@@ -780,7 +808,7 @@ public class Dispatcher {
     /**
      * Prepare a request, including setting the encoding and locale.
      *
-     * @param request The request
+     * @param request  The request
      * @param response The response
      */
     public void prepare(HttpServletRequest request, HttpServletResponse 
response) {
@@ -834,9 +862,8 @@ public class Dispatcher {
      *
      * @param request the HttpServletRequest object.
      * @return a wrapped request or original request.
-     * @see org.apache.struts2.dispatcher.multipart.MultiPartRequestWrapper
      * @throws java.io.IOException on any error.
-     *
+     * @see org.apache.struts2.dispatcher.multipart.MultiPartRequestWrapper
      * @since 2.3.17
      */
     public HttpServletRequest wrapRequest(HttpServletRequest request) throws 
IOException {
@@ -850,11 +877,11 @@ public class Dispatcher {
             LocaleProviderFactory localeProviderFactory = 
getContainer().getInstance(LocaleProviderFactory.class);
 
             request = new MultiPartRequestWrapper(
-                    multiPartRequest,
-                    request,
-                    getSaveDir(),
-                    localeProviderFactory.createLocaleProvider(),
-                    disableRequestAttributeValueStackLookup
+                multiPartRequest,
+                request,
+                getSaveDir(),
+                localeProviderFactory.createLocaleProvider(),
+                disableRequestAttributeValueStackLookup
             );
         } else {
             request = new StrutsRequestWrapper(request, 
disableRequestAttributeValueStackLookup);
@@ -865,10 +892,9 @@ public class Dispatcher {
 
     /**
      * Checks if support to parse multipart requests is enabled
-     * 
+     *
      * @param request current servlet request
      * @return false if disabled
-     *
      * @since 2.5.11
      */
     protected boolean isMultipartSupportEnabled(HttpServletRequest request) {
@@ -880,7 +906,6 @@ public class Dispatcher {
      *
      * @param request current servlet request
      * @return true if it is a multipart request
-     *
      * @since 2.5.11
      */
     protected boolean isMultipartRequest(HttpServletRequest request) {
@@ -888,8 +913,8 @@ public class Dispatcher {
         String contentType = request.getContentType();
 
         return REQUEST_POST_METHOD.equalsIgnoreCase(httpMethod) &&
-                contentType != null &&
-                
multipartValidationPattern.matcher(contentType.toLowerCase(Locale.ENGLISH)).matches();
+            contentType != null &&
+            
multipartValidationPattern.matcher(contentType.toLowerCase(Locale.ENGLISH)).matches();
     }
 
     /**
@@ -907,7 +932,7 @@ public class Dispatcher {
                 mpr = getContainer().getInstance(MultiPartRequest.class, 
multiName);
             }
         }
-        if (mpr == null ) {
+        if (mpr == null) {
             mpr = getContainer().getInstance(MultiPartRequest.class);
         }
         return mpr;
@@ -935,7 +960,6 @@ public class Dispatcher {
      * @param response the HttpServletResponse object.
      * @param code     the HttpServletResponse error code (see {@link 
javax.servlet.http.HttpServletResponse} for possible error codes).
      * @param e        the Exception that is reported.
-     *
      * @since 2.3.17
      */
     public void sendError(HttpServletRequest request, HttpServletResponse 
response, int code, Exception e) {
@@ -976,6 +1000,7 @@ public class Dispatcher {
 
     /**
      * Expose the dependency injection container.
+     *
      * @return Our dependency injection container
      */
     public Container getContainer() {
diff --git 
a/core/src/main/java/org/apache/struts2/dispatcher/InitOperations.java 
b/core/src/main/java/org/apache/struts2/dispatcher/InitOperations.java
index 55f6481..ed47533 100644
--- a/core/src/main/java/org/apache/struts2/dispatcher/InitOperations.java
+++ b/core/src/main/java/org/apache/struts2/dispatcher/InitOperations.java
@@ -81,8 +81,8 @@ public class InitOperations {
      */
     protected Dispatcher createDispatcher(HostConfig filterConfig) {
         Map<String, String> params = new HashMap<>();
-        for ( Iterator e = filterConfig.getInitParameterNames(); e.hasNext(); 
) {
-            String name = (String) e.next();
+        for ( Iterator<String> parameterNames = 
filterConfig.getInitParameterNames(); parameterNames.hasNext(); ) {
+            String name = parameterNames.next();
             String value = filterConfig.getInitParameter(name);
             params.put(name, value);
         }
diff --git 
a/core/src/main/java/org/apache/struts2/dispatcher/listener/StrutsListener.java 
b/core/src/main/java/org/apache/struts2/dispatcher/listener/StrutsListener.java
index bf83984..5bdeee1 100644
--- 
a/core/src/main/java/org/apache/struts2/dispatcher/listener/StrutsListener.java
+++ 
b/core/src/main/java/org/apache/struts2/dispatcher/listener/StrutsListener.java
@@ -44,7 +44,6 @@ public class StrutsListener implements ServletContextListener 
{
             init.initStaticContentLoader(config, dispatcher);
 
             prepare = new PrepareOperations(dispatcher);
-            
sce.getServletContext().setAttribute(StrutsStatics.SERVLET_DISPATCHER, 
dispatcher);
         } finally {
             if (dispatcher != null) {
                 dispatcher.cleanUpAfterInit();
diff --git 
a/core/src/main/java/org/apache/struts2/dispatcher/mapper/DefaultActionMapper.java
 
b/core/src/main/java/org/apache/struts2/dispatcher/mapper/DefaultActionMapper.java
index 06c31d4..a9679a3 100644
--- 
a/core/src/main/java/org/apache/struts2/dispatcher/mapper/DefaultActionMapper.java
+++ 
b/core/src/main/java/org/apache/struts2/dispatcher/mapper/DefaultActionMapper.java
@@ -564,7 +564,7 @@ public class DefaultActionMapper implements ActionMapper {
             // Look for the current extension, if available
             ActionContext context = ActionContext.getContext();
             if (context != null) {
-                ActionMapping orig = (ActionMapping) 
context.get(ServletActionContext.ACTION_MAPPING);
+                ActionMapping orig = context.getActionMapping();
                 if (orig != null) {
                     extension = orig.getExtension();
                 }
diff --git 
a/core/src/main/java/org/apache/struts2/interceptor/ActionMappingParametersInterceptor.java
 
b/core/src/main/java/org/apache/struts2/interceptor/ActionMappingParametersInterceptor.java
index 2b04795..79cd0cc 100644
--- 
a/core/src/main/java/org/apache/struts2/interceptor/ActionMappingParametersInterceptor.java
+++ 
b/core/src/main/java/org/apache/struts2/interceptor/ActionMappingParametersInterceptor.java
@@ -81,7 +81,7 @@ public class ActionMappingParametersInterceptor extends 
ParametersInterceptor {
      */
     @Override
     protected HttpParameters retrieveParameters(ActionContext ac) {
-        ActionMapping mapping = (ActionMapping) 
ac.get(ServletActionContext.ACTION_MAPPING);
+        ActionMapping mapping = ac.getActionMapping();
         if (mapping != null) {
             return 
HttpParameters.create(mapping.getParams()).buildNoNestedWrapping();
         } else {
diff --git 
a/core/src/main/java/org/apache/struts2/interceptor/CookieProviderInterceptor.java
 
b/core/src/main/java/org/apache/struts2/interceptor/CookieProviderInterceptor.java
index 4e415e2..e04c3fa 100644
--- 
a/core/src/main/java/org/apache/struts2/interceptor/CookieProviderInterceptor.java
+++ 
b/core/src/main/java/org/apache/struts2/interceptor/CookieProviderInterceptor.java
@@ -96,7 +96,7 @@ public class CookieProviderInterceptor extends 
AbstractInterceptor implements Pr
             LOG.trace("beforeResult start");
             ActionContext ac = invocation.getInvocationContext();
             if (invocation.getAction() instanceof CookieProvider) {
-                HttpServletResponse response = (HttpServletResponse) 
ac.get(StrutsStatics.HTTP_RESPONSE);
+                HttpServletResponse response = ac.getServletResponse();
                 addCookiesToResponse((CookieProvider) invocation.getAction(), 
response);
             }
             LOG.trace("beforeResult end");
diff --git 
a/core/src/main/java/org/apache/struts2/interceptor/CreateSessionInterceptor.java
 
b/core/src/main/java/org/apache/struts2/interceptor/CreateSessionInterceptor.java
index 32aea1e..9091220 100644
--- 
a/core/src/main/java/org/apache/struts2/interceptor/CreateSessionInterceptor.java
+++ 
b/core/src/main/java/org/apache/struts2/interceptor/CreateSessionInterceptor.java
@@ -18,6 +18,7 @@
  */
 package org.apache.struts2.interceptor;
 
+import com.opensymphony.xwork2.ActionContext;
 import com.opensymphony.xwork2.ActionInvocation;
 import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
 import org.apache.logging.log4j.LogManager;
@@ -25,6 +26,7 @@ import org.apache.logging.log4j.Logger;
 import org.apache.struts2.ServletActionContext;
 import org.apache.struts2.dispatcher.SessionMap;
 
+import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpSession;
 
 /**
@@ -86,11 +88,12 @@ public class CreateSessionInterceptor extends 
AbstractInterceptor {
      * @see 
com.opensymphony.xwork2.interceptor.Interceptor#intercept(com.opensymphony.xwork2.ActionInvocation)
      */
     public String intercept(ActionInvocation invocation) throws Exception {
-        HttpSession httpSession = 
ServletActionContext.getRequest().getSession(false);
+        HttpServletRequest servletRequest = 
invocation.getInvocationContext().getServletRequest();
+        HttpSession httpSession = servletRequest.getSession(false);
         if (httpSession == null) {
             LOG.debug("Creating new HttpSession and new SessionMap in 
ServletActionContext");
-            ServletActionContext.getRequest().getSession(true);
-            ServletActionContext.getContext().setSession(new 
SessionMap<String, Object>(ServletActionContext.getRequest()));
+            servletRequest.getSession(true);
+            invocation.getInvocationContext().setSession(new 
SessionMap<>(servletRequest));
         }
         return invocation.invoke();
     }
diff --git 
a/core/src/main/java/org/apache/struts2/interceptor/FileUploadInterceptor.java 
b/core/src/main/java/org/apache/struts2/interceptor/FileUploadInterceptor.java
index b6a0fa9..e0619e2 100644
--- 
a/core/src/main/java/org/apache/struts2/interceptor/FileUploadInterceptor.java
+++ 
b/core/src/main/java/org/apache/struts2/interceptor/FileUploadInterceptor.java
@@ -232,7 +232,7 @@ public class FileUploadInterceptor extends 
AbstractInterceptor {
     public String intercept(ActionInvocation invocation) throws Exception {
         ActionContext ac = invocation.getInvocationContext();
 
-        HttpServletRequest request = (HttpServletRequest) 
ac.get(ServletActionContext.HTTP_REQUEST);
+        HttpServletRequest request = ac.getServletRequest();
 
         if (!(request instanceof MultiPartRequestWrapper)) {
             if (LOG.isDebugEnabled()) {
diff --git 
a/core/src/main/java/org/apache/struts2/interceptor/MessageStoreInterceptor.java
 
b/core/src/main/java/org/apache/struts2/interceptor/MessageStoreInterceptor.java
index 5d72945..1596be5 100644
--- 
a/core/src/main/java/org/apache/struts2/interceptor/MessageStoreInterceptor.java
+++ 
b/core/src/main/java/org/apache/struts2/interceptor/MessageStoreInterceptor.java
@@ -233,7 +233,7 @@ public class MessageStoreInterceptor extends 
AbstractInterceptor {
             Object action = invocation.getAction();
             if (action instanceof ValidationAware) {
                 // retrieve error / message from session
-                Map session = (Map) 
invocation.getInvocationContext().get(ActionContext.SESSION);
+                Map<String, Object> session = 
invocation.getInvocationContext().getSession();
 
                 if (session == null) {
                     LOG.debug("Session is not open, no errors / messages could 
be retrieve for action [{}]", action);
diff --git 
a/core/src/main/java/org/apache/struts2/interceptor/ServletConfigInterceptor.java
 
b/core/src/main/java/org/apache/struts2/interceptor/ServletConfigInterceptor.java
index 9707896..0ef0f37 100644
--- 
a/core/src/main/java/org/apache/struts2/interceptor/ServletConfigInterceptor.java
+++ 
b/core/src/main/java/org/apache/struts2/interceptor/ServletConfigInterceptor.java
@@ -125,22 +125,22 @@ public class ServletConfigInterceptor extends 
AbstractInterceptor implements Str
         final ActionContext context = invocation.getInvocationContext();
 
         if (action instanceof ServletRequestAware) {
-            HttpServletRequest request = (HttpServletRequest) 
context.get(HTTP_REQUEST);
+            HttpServletRequest request = context.getServletRequest();
             ((ServletRequestAware) action).setServletRequest(request);
         }
 
         if (action instanceof org.apache.struts2.action.ServletRequestAware) {
-            HttpServletRequest request = (HttpServletRequest) 
context.get(HTTP_REQUEST);
+            HttpServletRequest request = context.getServletRequest();
             ((org.apache.struts2.action.ServletRequestAware) 
action).withServletRequest(request);
         }
 
         if (action instanceof ServletResponseAware) {
-            HttpServletResponse response = (HttpServletResponse) 
context.get(HTTP_RESPONSE);
+            HttpServletResponse response = context.getServletResponse();
             ((ServletResponseAware) action).setServletResponse(response);
         }
 
         if (action instanceof org.apache.struts2.action.ServletResponseAware) {
-            HttpServletResponse response = (HttpServletResponse) 
context.get(HTTP_RESPONSE);
+            HttpServletResponse response = context.getServletResponse();
             ((org.apache.struts2.action.ServletResponseAware) 
action).withServletResponse(response);
         }
 
@@ -177,7 +177,7 @@ public class ServletConfigInterceptor extends 
AbstractInterceptor implements Str
         }
 
         if (action instanceof PrincipalAware) {
-            HttpServletRequest request = (HttpServletRequest) 
context.get(HTTP_REQUEST);
+            HttpServletRequest request = context.getServletRequest();
             if(request != null) {
                 // We are in servtlet environment, so principal information 
resides in HttpServletRequest
                 ((PrincipalAware) action).setPrincipalProxy(new 
ServletPrincipalProxy(request));
@@ -185,7 +185,7 @@ public class ServletConfigInterceptor extends 
AbstractInterceptor implements Str
         }
 
         if (action instanceof org.apache.struts2.action.PrincipalAware) {
-            HttpServletRequest request = (HttpServletRequest) 
context.get(HTTP_REQUEST);
+            HttpServletRequest request = context.getServletRequest();
             if(request != null) {
                 // We are in servlet environment, so principal information 
resides in HttpServletRequest
                 ((org.apache.struts2.action.PrincipalAware) 
action).withPrincipalProxy(new ServletPrincipalProxy(request));
@@ -193,12 +193,12 @@ public class ServletConfigInterceptor extends 
AbstractInterceptor implements Str
         }
 
         if (action instanceof ServletContextAware) {
-            ServletContext servletContext = (ServletContext) 
context.get(SERVLET_CONTEXT);
+            ServletContext servletContext = context.getServletContext();
             ((ServletContextAware) action).setServletContext(servletContext);
         }
 
         if (action instanceof org.apache.struts2.action.ServletContextAware) {
-            ServletContext servletContext = (ServletContext) 
context.get(SERVLET_CONTEXT);
+            ServletContext servletContext = context.getServletContext();
             ((org.apache.struts2.action.ServletContextAware) 
action).withServletContext(servletContext);
         }
 
diff --git 
a/core/src/main/java/org/apache/struts2/interceptor/TokenSessionStoreInterceptor.java
 
b/core/src/main/java/org/apache/struts2/interceptor/TokenSessionStoreInterceptor.java
index 863e804..05e491e 100644
--- 
a/core/src/main/java/org/apache/struts2/interceptor/TokenSessionStoreInterceptor.java
+++ 
b/core/src/main/java/org/apache/struts2/interceptor/TokenSessionStoreInterceptor.java
@@ -130,8 +130,8 @@ public class TokenSessionStoreInterceptor extends 
TokenInterceptor {
     protected String handleInvalidToken(ActionInvocation invocation) throws 
Exception {
         ActionContext ac = invocation.getInvocationContext();
 
-        HttpServletRequest request = (HttpServletRequest) 
ac.get(ServletActionContext.HTTP_REQUEST);
-        HttpServletResponse response = (HttpServletResponse) 
ac.get(ServletActionContext.HTTP_RESPONSE);
+        HttpServletRequest request = ac.getServletRequest();
+        HttpServletResponse response = ac.getServletResponse();
         String tokenName = TokenHelper.getTokenName();
         String token = TokenHelper.getToken(tokenName);
 
@@ -169,7 +169,7 @@ public class TokenSessionStoreInterceptor extends 
TokenInterceptor {
 
     /**
      * Handles processing of valid tokens.  Stores the current invocation for
-     * later use by {@link handleInvalidToken}.
+     * later use by {@see #handleValidToken(ActionInvocation)}.
      * See {@link 
org.apache.struts2.util.InvocationSessionStore#storeInvocation(String key, 
String token, ActionInvocation invocation)} for details.
      * 
      * @param invocation
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 10fdcf4..1cff710 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
@@ -192,7 +192,7 @@ public class DebuggingInterceptor extends 
AbstractInterceptor {
                 ValueStack stack = (ValueStack) 
ctx.getSession().get(SESSION_KEY);
                 if (stack == null) {
                     //allows it to be embedded on another page
-                    stack = (ValueStack) ctx.get(ActionContext.VALUE_STACK);
+                    stack = ctx.getValueStack();
                     ctx.getSession().put(SESSION_KEY, stack);
                 }
                 String cmd = getParameter(EXPRESSION_PARAM);
@@ -218,7 +218,7 @@ public class DebuggingInterceptor extends 
AbstractInterceptor {
                                 rootObjectExpression = "action";
                             }
                             String decorate = getParameter(DECORATE_PARAM);
-                            ValueStack stack = (ValueStack) 
ctx.get(ActionContext.VALUE_STACK);
+                            ValueStack stack = ctx.getValueStack();
                             Object rootObject = 
stack.findValue(rootObjectExpression);
 
                             try (StringWriter writer = new StringWriter()) {
@@ -258,7 +258,7 @@ public class DebuggingInterceptor extends 
AbstractInterceptor {
             } finally {
                 if (devMode && consoleEnabled) {
                     final ActionContext ctx = ActionContext.getContext();
-                    ctx.getSession().put(SESSION_KEY, 
ctx.get(ActionContext.VALUE_STACK));
+                    ctx.getSession().put(SESSION_KEY, ctx.getValueStack());
                 }
             }
         } else {
diff --git a/core/src/main/java/org/apache/struts2/util/URLBean.java 
b/core/src/main/java/org/apache/struts2/util/URLBean.java
index c5cf6fb..5e09718 100644
--- a/core/src/main/java/org/apache/struts2/util/URLBean.java
+++ b/core/src/main/java/org/apache/struts2/util/URLBean.java
@@ -18,6 +18,7 @@
  */
 package org.apache.struts2.util;
 
+import com.opensymphony.xwork2.ActionContext;
 import org.apache.struts2.ServletActionContext;
 import org.apache.struts2.views.util.DefaultUrlHelper;
 import org.apache.struts2.views.util.UrlHelper;
@@ -48,7 +49,7 @@ public class URLBean {
 
     public void setRequest(HttpServletRequest request) {
         this.request = request;
-        urlHelper = 
ServletActionContext.getContext().getInstance(DefaultUrlHelper.class);
+        urlHelper = 
ActionContext.getContext().getInstance(DefaultUrlHelper.class);
     }
 
     public void setResponse(HttpServletResponse response) {
diff --git 
a/core/src/main/java/org/apache/struts2/views/freemarker/FreemarkerResult.java 
b/core/src/main/java/org/apache/struts2/views/freemarker/FreemarkerResult.java
index 5bdb2e9..5f57297 100644
--- 
a/core/src/main/java/org/apache/struts2/views/freemarker/FreemarkerResult.java
+++ 
b/core/src/main/java/org/apache/struts2/views/freemarker/FreemarkerResult.java
@@ -275,7 +275,7 @@ public class FreemarkerResult extends StrutsResultSupport {
         ServletContext servletContext = 
ServletActionContext.getServletContext();
         HttpServletRequest request = ServletActionContext.getRequest();
         HttpServletResponse response = ServletActionContext.getResponse();
-        ValueStack stack = ServletActionContext.getContext().getValueStack();
+        ValueStack stack = ActionContext.getContext().getValueStack();
 
         Object action = null;
         if(invocation!= null ) action = invocation.getAction(); //Added for 
NullPointException
diff --git a/core/src/test/java/com/opensymphony/xwork2/StubValueStack.java 
b/core/src/test/java/com/opensymphony/xwork2/StubValueStack.java
index ea475f0..f5d4665 100644
--- a/core/src/test/java/com/opensymphony/xwork2/StubValueStack.java
+++ b/core/src/test/java/com/opensymphony/xwork2/StubValueStack.java
@@ -35,6 +35,11 @@ public class StubValueStack implements ValueStack {
         return ctx;
     }
 
+    @Override
+    public ActionContext getActionContext() {
+        return new ActionContext(ctx);
+    }
+
     public void setDefaultType(Class defaultType) {
     }
 
diff --git 
a/core/src/test/java/org/apache/struts2/ServletActionContextTest.java 
b/core/src/test/java/org/apache/struts2/ServletActionContextTest.java
index bd748c6..3e92e85 100644
--- a/core/src/test/java/org/apache/struts2/ServletActionContextTest.java
+++ b/core/src/test/java/org/apache/struts2/ServletActionContextTest.java
@@ -37,15 +37,14 @@ import java.util.Map;
  */
 public class ServletActionContextTest extends TestCase implements 
StrutsStatics {
 
-    ActionContext actionContext;
-    ServletActionContext servletActionContext;
+    private ActionContext actionContext;
     private HttpServletRequest request;
     private HttpServletResponse response;
     private MockServletContext servletContext;
 
 
     public void setUp() {
-        Map extraContext = new HashMap();
+        Map<String, Object> extraContext = new HashMap<>();
 
         request = new MockHttpServletRequest();
         response = new MockHttpServletResponse();
@@ -55,8 +54,7 @@ public class ServletActionContextTest extends TestCase 
implements StrutsStatics
         extraContext.put(HTTP_RESPONSE, response);
         extraContext.put(SERVLET_CONTEXT, servletContext);
 
-        actionContext = new ActionContext(extraContext);
-        ServletActionContext.setContext(actionContext);
+        actionContext = ActionContext.of(extraContext);
     }
 
     public void testContextParams() {
@@ -66,7 +64,7 @@ public class ServletActionContextTest extends TestCase 
implements StrutsStatics
     }
 
     public void testGetContext() {
-        ActionContext threadContext = ServletActionContext.getContext();
+        ActionContext threadContext = ServletActionContext.getActionContext();
         assertEquals(actionContext, threadContext);
     }
 }
diff --git 
a/core/src/test/java/org/apache/struts2/interceptor/CreateSessionInterceptorTest.java
 
b/core/src/test/java/org/apache/struts2/interceptor/CreateSessionInterceptorTest.java
index 0ea33f8..3a887c2 100644
--- 
a/core/src/test/java/org/apache/struts2/interceptor/CreateSessionInterceptorTest.java
+++ 
b/core/src/test/java/org/apache/struts2/interceptor/CreateSessionInterceptorTest.java
@@ -18,6 +18,7 @@
  */
 package org.apache.struts2.interceptor;
 
+import com.opensymphony.xwork2.ActionContext;
 import com.opensymphony.xwork2.mock.MockActionInvocation;
 import org.apache.struts2.ServletActionContext;
 import org.apache.struts2.StrutsInternalTestCase;
@@ -33,6 +34,15 @@ import javax.servlet.http.HttpServletRequest;
  */
 public class CreateSessionInterceptorTest extends StrutsInternalTestCase {
 
+    private MockActionInvocation invocation;
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        invocation = new MockActionInvocation();
+        invocation.setInvocationContext(ActionContext.getContext());
+    }
+
     public void testCreateSession() throws Exception {
         Mock httpServletRequestMock = new Mock(HttpServletRequest.class);
         httpServletRequestMock.expects(new 
InvokeOnceMatcher()).method("getSession").with(new IsEqual(Boolean.FALSE));
@@ -43,7 +53,8 @@ public class CreateSessionInterceptorTest extends 
StrutsInternalTestCase {
         ServletActionContext.setRequest(request);
 
         CreateSessionInterceptor interceptor = new CreateSessionInterceptor();
-        interceptor.intercept(new MockActionInvocation());
+
+        interceptor.intercept(invocation);
 
         httpServletRequestMock.verify();
     }
diff --git 
a/core/src/test/java/org/apache/struts2/interceptor/I18nInterceptorTest.java 
b/core/src/test/java/org/apache/struts2/interceptor/I18nInterceptorTest.java
index da5607f..7cd0fcb 100644
--- a/core/src/test/java/org/apache/struts2/interceptor/I18nInterceptorTest.java
+++ b/core/src/test/java/org/apache/struts2/interceptor/I18nInterceptorTest.java
@@ -261,8 +261,8 @@ public class I18nInterceptorTest extends TestCase {
         ctx.put(ActionContext.SESSION, session);
 
         ac = new ActionContext(ctx);
+        ActionContext.setContext(ac);
 
-        ServletActionContext.setContext(ac);
         request = new MockHttpServletRequest();
         request.setSession(new MockHttpSession());
         ServletActionContext.setRequest(request);
diff --git 
a/plugins/embeddedjsp/src/main/java/org/apache/struts2/JSPLoader.java 
b/plugins/embeddedjsp/src/main/java/org/apache/struts2/JSPLoader.java
index 713fcb8..57c19fb 100644
--- a/plugins/embeddedjsp/src/main/java/org/apache/struts2/JSPLoader.java
+++ b/plugins/embeddedjsp/src/main/java/org/apache/struts2/JSPLoader.java
@@ -182,11 +182,11 @@ public class JSPLoader {
         List<URL> urls = urlSet.getUrls();
 
         if (urls != null && urls.size() > 0) {
-            final FileManagerFactory fileManagerFactoryGetInstance = 
ServletActionContext.getContext().getInstance(FileManagerFactory.class);
-            final FileManagerFactory contextFileManagerFactory = 
(fileManagerFactoryGetInstance != null ? fileManagerFactoryGetInstance : 
(FileManagerFactory) 
ServletActionContext.getContext().get(StrutsConstants.STRUTS_FILE_MANAGER_FACTORY));
 
+            final FileManagerFactory fileManagerFactoryGetInstance = 
ServletActionContext.getActionContext().getInstance(FileManagerFactory.class);
+            final FileManagerFactory contextFileManagerFactory = 
(fileManagerFactoryGetInstance != null ? fileManagerFactoryGetInstance : 
(FileManagerFactory) 
ServletActionContext.getActionContext().get(StrutsConstants.STRUTS_FILE_MANAGER_FACTORY));
             final FileManagerFactory fileManagerFactory = 
(contextFileManagerFactory != null ? contextFileManagerFactory : new 
DefaultFileManagerFactory());
             final FileManager fileManagerGetInstance = 
fileManagerFactory.getFileManager();
-            final FileManager contextFileManager = (fileManagerGetInstance != 
null ? fileManagerGetInstance : (FileManager) 
ServletActionContext.getContext().get(StrutsConstants.STRUTS_FILE_MANAGER));
+            final FileManager contextFileManager = (fileManagerGetInstance != 
null ? fileManagerGetInstance : (FileManager) 
ServletActionContext.getActionContext().get(StrutsConstants.STRUTS_FILE_MANAGER));
             final FileManager fileManager = (contextFileManager != null ? 
contextFileManager : new DefaultFileManager());
             for (URL url : urls) {
                 URL normalizedUrl = fileManager.normalizeToFileProtocol(url);
diff --git 
a/plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/FreemarkerDecoratorServlet.java
 
b/plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/FreemarkerDecoratorServlet.java
index e3760cf..85ef896 100644
--- 
a/plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/FreemarkerDecoratorServlet.java
+++ 
b/plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/FreemarkerDecoratorServlet.java
@@ -66,7 +66,7 @@ public class FreemarkerDecoratorServlet extends 
freemarker.ext.servlet.Freemarke
 
     public void init() throws ServletException {
         try {
-            Dispatcher dispatcher = (Dispatcher) 
getServletContext().getAttribute(StrutsStatics.SERVLET_DISPATCHER);
+            Dispatcher dispatcher = 
Dispatcher.getInstance(getServletContext());
             if (dispatcher == null) {
                 throw new IllegalStateException("Unable to find the Dispatcher 
in the Servlet Context. Is '" + StrutsListener.class.getName() + "' missing in 
web.xml?");
             }
diff --git 
a/plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/VelocityDecoratorServlet.java
 
b/plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/VelocityDecoratorServlet.java
index 7fd2265..4859c4f 100644
--- 
a/plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/VelocityDecoratorServlet.java
+++ 
b/plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/VelocityDecoratorServlet.java
@@ -74,7 +74,7 @@ public class VelocityDecoratorServlet extends 
VelocityViewServlet {
      */
     public void init(ServletConfig config) throws ServletException {
         super.init(config);
-        Dispatcher dispatcher = (Dispatcher) 
getServletContext().getAttribute(StrutsStatics.SERVLET_DISPATCHER);
+        Dispatcher dispatcher = Dispatcher.getInstance(getServletContext());
         if (dispatcher == null) {
             throw new IllegalStateException("Unable to find the Dispatcher in 
the Servlet Context. Is '" + StrutsListener.class.getName() + "' missing in 
web.xml?");
         }

Reply via email to