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

lukaszlenart pushed a commit to branch feature/WW-5326-ognl
in repository https://gitbox.apache.org/repos/asf/struts.git

commit 9c0ba314477d222c9f67eb880e36ec508ba5eb74
Author: Lukasz Lenart <lukaszlen...@apache.org>
AuthorDate: Sun Mar 30 08:49:18 2025 +0200

    WW-5326 Uses StrutsContext instead of raw Map as OgnlContext
---
 .../org/apache/struts2/conversion/NullHandler.java |   6 +-
 .../conversion/impl/InstantiatingNullHandler.java  |   7 +-
 .../org/apache/struts2/factory/ResultFactory.java  |   3 +-
 .../struts2/factory/StrutsResultFactory.java       |   7 +-
 .../struts2/ognl/OgnlNullHandlerWrapper.java       |   7 +-
 .../struts2/ognl/OgnlReflectionProvider.java       |  30 +++----
 .../struts2/ognl/OgnlTypeConverterWrapper.java     |   3 +-
 .../java/org/apache/struts2/ognl/OgnlUtil.java     | 100 +++++++++------------
 .../org/apache/struts2/ognl/OgnlValueStack.java    |  14 +--
 .../apache/struts2/ognl/SecurityMemberAccess.java  |   7 +-
 .../ognl/accessor/CompoundRootAccessor.java        |  43 ++++-----
 .../accessor/HttpParametersPropertyAccessor.java   |   7 +-
 .../struts2/ognl/accessor/ObjectAccessor.java      |  12 +--
 .../ognl/accessor/ObjectProxyPropertyAccessor.java |   6 +-
 .../ognl/accessor/ParameterPropertyAccessor.java   |   5 +-
 .../accessor/XWorkCollectionPropertyAccessor.java  |  14 +--
 .../ognl/accessor/XWorkEnumerationAccessor.java    |   3 +-
 .../accessor/XWorkIteratorPropertyAccessor.java    |   4 +-
 .../ognl/accessor/XWorkMapPropertyAccessor.java    |   9 +-
 .../struts2/ognl/accessor/XWorkMethodAccessor.java |  94 ++++++++++---------
 .../ognl/accessor/XWorkObjectPropertyAccessor.java |   4 +-
 .../java/org/apache/struts2/util/ValueStack.java   |   3 +-
 .../util/reflection/ReflectionProvider.java        |  19 ++--
 23 files changed, 194 insertions(+), 213 deletions(-)

diff --git a/core/src/main/java/org/apache/struts2/conversion/NullHandler.java 
b/core/src/main/java/org/apache/struts2/conversion/NullHandler.java
index 2eb2ed06f..3db4afefd 100644
--- a/core/src/main/java/org/apache/struts2/conversion/NullHandler.java
+++ b/core/src/main/java/org/apache/struts2/conversion/NullHandler.java
@@ -18,6 +18,8 @@
  */
 package org.apache.struts2.conversion;
 
+import org.apache.struts2.ognl.StrutsContext;
+
 import java.util.Map;
 
 /**
@@ -41,7 +43,7 @@ public interface NullHandler
      *
      *  @return object
      */
-    Object nullMethodResult(Map<String, Object> context, Object target, String 
methodName, Object[] args);
+    Object nullMethodResult(StrutsContext context, Object target, String 
methodName, Object[] args);
 
     /**
      *   Property in target evaluated to null.  Property can be a constant
@@ -53,5 +55,5 @@ public interface NullHandler
      *
      *  @return object
      */
-    Object nullPropertyValue(Map<String, Object> context, Object target, 
Object property);
+    Object nullPropertyValue(StrutsContext context, Object target, Object 
property);
 }
\ No newline at end of file
diff --git 
a/core/src/main/java/org/apache/struts2/conversion/impl/InstantiatingNullHandler.java
 
b/core/src/main/java/org/apache/struts2/conversion/impl/InstantiatingNullHandler.java
index 52ebdd836..e00c5f55f 100644
--- 
a/core/src/main/java/org/apache/struts2/conversion/impl/InstantiatingNullHandler.java
+++ 
b/core/src/main/java/org/apache/struts2/conversion/impl/InstantiatingNullHandler.java
@@ -22,6 +22,7 @@ import org.apache.struts2.ObjectFactory;
 import org.apache.struts2.conversion.NullHandler;
 import org.apache.struts2.conversion.ObjectTypeDeterminer;
 import org.apache.struts2.inject.Inject;
+import org.apache.struts2.ognl.StrutsContext;
 import org.apache.struts2.util.reflection.ReflectionContextState;
 import org.apache.struts2.util.reflection.ReflectionProvider;
 import org.apache.logging.log4j.LogManager;
@@ -97,12 +98,14 @@ public class InstantiatingNullHandler implements 
NullHandler {
         this.objectFactory = fac;
     }
 
-    public Object nullMethodResult(Map<String, Object> context, Object target, 
String methodName, Object[] args) {
+    @Override
+    public Object nullMethodResult(StrutsContext context, Object target, 
String methodName, Object[] args) {
         LOG.debug("Entering nullMethodResult");
         return null;
     }
 
-    public Object nullPropertyValue(Map<String, Object> context, Object 
target, Object property) {
+    @Override
+    public Object nullPropertyValue(StrutsContext context, Object target, 
Object property) {
         LOG.debug("Entering nullPropertyValue [target={}, property={}]", 
target, property);
         boolean c = ReflectionContextState.isCreatingNullObjects(context);
 
diff --git a/core/src/main/java/org/apache/struts2/factory/ResultFactory.java 
b/core/src/main/java/org/apache/struts2/factory/ResultFactory.java
index 88331feba..866ded1e7 100644
--- a/core/src/main/java/org/apache/struts2/factory/ResultFactory.java
+++ b/core/src/main/java/org/apache/struts2/factory/ResultFactory.java
@@ -19,6 +19,7 @@
 package org.apache.struts2.factory;
 
 import org.apache.struts2.config.entities.ResultConfig;
+import org.apache.struts2.ognl.StrutsContext;
 import org.apache.struts2.result.Result;
 
 import java.util.Map;
@@ -28,6 +29,6 @@ import java.util.Map;
  */
 public interface ResultFactory {
 
-    Result buildResult(ResultConfig resultConfig, Map<String, Object> 
extraContext) throws Exception;
+    Result buildResult(ResultConfig resultConfig, StrutsContext extraContext) 
throws Exception;
 
 }
diff --git 
a/core/src/main/java/org/apache/struts2/factory/StrutsResultFactory.java 
b/core/src/main/java/org/apache/struts2/factory/StrutsResultFactory.java
index 53f0e32d9..1620b7513 100644
--- a/core/src/main/java/org/apache/struts2/factory/StrutsResultFactory.java
+++ b/core/src/main/java/org/apache/struts2/factory/StrutsResultFactory.java
@@ -22,6 +22,7 @@ import org.apache.struts2.ObjectFactory;
 import org.apache.struts2.config.ConfigurationException;
 import org.apache.struts2.config.entities.ResultConfig;
 import org.apache.struts2.inject.Inject;
+import org.apache.struts2.ognl.StrutsContext;
 import org.apache.struts2.result.ParamNameAwareResult;
 import org.apache.struts2.result.Result;
 import org.apache.struts2.util.reflection.ReflectionException;
@@ -49,7 +50,7 @@ public class StrutsResultFactory implements ResultFactory {
     }
 
     @Override
-    public Result buildResult(ResultConfig resultConfig, Map<String, Object> 
extraContext) throws Exception {
+    public Result buildResult(ResultConfig resultConfig, StrutsContext 
extraContext) throws Exception {
         String resultClassName = resultConfig.getClassName();
 
         if (resultClassName == null) {
@@ -68,7 +69,7 @@ public class StrutsResultFactory implements ResultFactory {
         return result;
     }
 
-    protected void setParameters(Map<String, Object> extraContext, Result 
result, Map<String, String> params) {
+    protected void setParameters(StrutsContext extraContext, Result result, 
Map<String, String> params) {
         for (Map.Entry<String, String> paramEntry : params.entrySet()) {
             try {
                 String name = paramEntry.getKey();
@@ -82,7 +83,7 @@ public class StrutsResultFactory implements ResultFactory {
         }
     }
 
-    protected void setParameter(Result result, String name, String value, 
Map<String, Object> extraContext) {
+    protected void setParameter(Result result, String name, String value, 
StrutsContext extraContext) {
         if (!(result instanceof ParamNameAwareResult paramNameAwareResult) || 
paramNameAwareResult.acceptableParameterName(name, value)) {
             reflectionProvider.setProperty(name, value, result, extraContext, 
true);
         }
diff --git 
a/core/src/main/java/org/apache/struts2/ognl/OgnlNullHandlerWrapper.java 
b/core/src/main/java/org/apache/struts2/ognl/OgnlNullHandlerWrapper.java
index aac6a478a..743d4ea38 100644
--- a/core/src/main/java/org/apache/struts2/ognl/OgnlNullHandlerWrapper.java
+++ b/core/src/main/java/org/apache/struts2/ognl/OgnlNullHandlerWrapper.java
@@ -18,6 +18,7 @@
  */
 package org.apache.struts2.ognl;
 
+import ognl.OgnlContext;
 import org.apache.struts2.conversion.NullHandler;
 
 import java.util.Map;
@@ -31,13 +32,13 @@ public class OgnlNullHandlerWrapper implements 
ognl.NullHandler {
     }
 
     @Override
-    public Object nullMethodResult(Map context, Object target,
-            String methodName, Object[] args) {
+    public Object nullMethodResult(OgnlContext context, Object target,
+                                   String methodName, Object[] args) {
         return wrapped.nullMethodResult(context, target, methodName, args);
     }
 
     @Override
-    public Object nullPropertyValue(Map context, Object target, Object 
property) {
+    public Object nullPropertyValue(OgnlContext context, Object target, Object 
property) {
         return wrapped.nullPropertyValue(context, target, property);
     }
 
diff --git 
a/core/src/main/java/org/apache/struts2/ognl/OgnlReflectionProvider.java 
b/core/src/main/java/org/apache/struts2/ognl/OgnlReflectionProvider.java
index 9df38d9ae..04e6c003c 100644
--- a/core/src/main/java/org/apache/struts2/ognl/OgnlReflectionProvider.java
+++ b/core/src/main/java/org/apache/struts2/ognl/OgnlReflectionProvider.java
@@ -48,30 +48,22 @@ public class OgnlReflectionProvider implements 
ReflectionProvider {
     @Override
     public Method getGetMethod(Class targetClass, String propertyName)
             throws IntrospectionException, ReflectionException {
-        try {
-            return OgnlRuntime.getGetMethod(null, targetClass, propertyName);
-        } catch (OgnlException e) {
-            throw new ReflectionException(e);
-        }
+        return OgnlRuntime.getGetMethod(targetClass, propertyName);
     }
 
     @Override
     public Method getSetMethod(Class targetClass, String propertyName)
             throws IntrospectionException, ReflectionException {
-        try {
-            return OgnlRuntime.getSetMethod(null, targetClass, propertyName);
-        } catch (OgnlException e) {
-            throw new ReflectionException(e);
-        }
+        return OgnlRuntime.getSetMethod(null, targetClass, propertyName);
     }
 
     @Override
-    public void setProperties(Map<String, ?> props, Object o, Map<String, 
Object> context) {
+    public void setProperties(Map<String, ?> props, Object o, StrutsContext 
context) {
         ognlUtil.setProperties(props, o, context);
     }
 
     @Override
-    public void setProperties(Map<String, ?> props, Object o, Map<String, 
Object> context, boolean throwPropertyExceptions) throws ReflectionException{
+    public void setProperties(Map<String, ?> props, Object o, StrutsContext 
context, boolean throwPropertyExceptions) throws ReflectionException{
         ognlUtil.setProperties(props, o, context, throwPropertyExceptions);
     }
 
@@ -92,19 +84,19 @@ public class OgnlReflectionProvider implements 
ReflectionProvider {
     }
 
     @Override
-    public void copy(Object from, Object to, Map<String, Object> context,
+    public void copy(Object from, Object to, StrutsContext context,
             Collection<String> exclusions, Collection<String> inclusions) {
         copy(from, to, context, exclusions, inclusions, null);
     }
 
     @Override
-    public void copy(Object from, Object to, Map<String, Object> context,
+    public void copy(Object from, Object to, StrutsContext context,
                      Collection<String> exclusions, Collection<String> 
inclusions, Class<?> editable) {
         ognlUtil.copy(from, to, context, exclusions, inclusions, editable);
     }
 
     @Override
-    public Object getRealTarget(String property, Map<String, Object> context, 
Object root)
+    public Object getRealTarget(String property, StrutsContext context, Object 
root)
             throws ReflectionException {
         try {
             return ognlUtil.getRealTarget(property, context, root);
@@ -114,12 +106,12 @@ public class OgnlReflectionProvider implements 
ReflectionProvider {
     }
 
     @Override
-    public void setProperty(String name, Object value, Object o, Map<String, 
Object> context) {
+    public void setProperty(String name, Object value, Object o, StrutsContext 
context) {
         ognlUtil.setProperty(name, value, o, context);
     }
 
     @Override
-    public void setProperty(String name, Object value, Object o, Map<String, 
Object> context, boolean throwPropertyExceptions) {
+    public void setProperty(String name, Object value, Object o, StrutsContext 
context, boolean throwPropertyExceptions) {
         ognlUtil.setProperty(name, value, o, context, throwPropertyExceptions);
     }
 
@@ -134,7 +126,7 @@ public class OgnlReflectionProvider implements 
ReflectionProvider {
     }
 
     @Override
-    public Object getValue(String expression, Map<String, Object> context, 
Object root)
+    public Object getValue(String expression, StrutsContext context, Object 
root)
             throws ReflectionException {
         try {
             return ognlUtil.getValue(expression, context, root);
@@ -144,7 +136,7 @@ public class OgnlReflectionProvider implements 
ReflectionProvider {
     }
 
     @Override
-    public void setValue(String expression, Map<String, Object> context, 
Object root,
+    public void setValue(String expression, StrutsContext context, Object root,
             Object value) throws ReflectionException {
         try {
             ognlUtil.setValue(expression, context, root, value);
diff --git 
a/core/src/main/java/org/apache/struts2/ognl/OgnlTypeConverterWrapper.java 
b/core/src/main/java/org/apache/struts2/ognl/OgnlTypeConverterWrapper.java
index 100fc61b9..caf71700d 100644
--- a/core/src/main/java/org/apache/struts2/ognl/OgnlTypeConverterWrapper.java
+++ b/core/src/main/java/org/apache/struts2/ognl/OgnlTypeConverterWrapper.java
@@ -18,6 +18,7 @@
  */
 package org.apache.struts2.ognl;
 
+import ognl.OgnlContext;
 import org.apache.struts2.conversion.TypeConverter;
 
 import java.lang.reflect.Member;
@@ -38,7 +39,7 @@ public class OgnlTypeConverterWrapper implements 
ognl.TypeConverter {
     }
 
     @Override
-    public Object convertValue(Map context, Object target, Member member, 
String propertyName, Object value, Class toType) {
+    public Object convertValue(OgnlContext context, Object target, Member 
member, String propertyName, Object value, Class toType) {
         return typeConverter.convertValue(context, target, member, 
propertyName, value, toType);
     }
 
diff --git a/core/src/main/java/org/apache/struts2/ognl/OgnlUtil.java 
b/core/src/main/java/org/apache/struts2/ognl/OgnlUtil.java
index 4d51ff294..6fbd3f79a 100644
--- a/core/src/main/java/org/apache/struts2/ognl/OgnlUtil.java
+++ b/core/src/main/java/org/apache/struts2/ognl/OgnlUtil.java
@@ -213,7 +213,7 @@ public class OgnlUtil {
      * @param o       the object
      * @param context the action context
      */
-    public void setProperties(Map<String, ?> props, Object o, Map<String, 
Object> context) {
+    public void setProperties(Map<String, ?> props, Object o, StrutsContext 
context) {
         setProperties(props, o, context, false);
     }
 
@@ -226,7 +226,7 @@ public class OgnlUtil {
      * @param throwPropertyExceptions boolean which tells whether it should 
throw exceptions for
      *                                problems setting the properties
      */
-    public void setProperties(Map<String, ?> props, Object o, Map<String, 
Object> context, boolean throwPropertyExceptions) throws ReflectionException{
+    public void setProperties(Map<String, ?> props, Object o, StrutsContext 
context, boolean throwPropertyExceptions) throws ReflectionException{
         if (props == null) {
             return;
         }
@@ -262,7 +262,7 @@ public class OgnlUtil {
      *                                problems setting the properties
      */
     public void setProperties(Map<String, ?> properties, Object o, boolean 
throwPropertyExceptions) {
-        Map<String, Object> context = createDefaultContext(o);
+        StrutsContext context = createDefaultContext(o);
         setProperties(properties, o, context, throwPropertyExceptions);
     }
 
@@ -275,7 +275,7 @@ public class OgnlUtil {
      * @param o       the object upon which to set the property
      * @param context the context which may include the TypeConverter
      */
-    public void setProperty(String name, Object value, Object o, Map<String, 
Object> context) {
+    public void setProperty(String name, Object value, Object o, StrutsContext 
context) {
         setProperty(name, value, o, context, false);
     }
 
@@ -289,7 +289,7 @@ public class OgnlUtil {
      * @param throwPropertyExceptions boolean which tells whether it should 
throw exceptions for
      *                                problems setting the property
      */
-    public void setProperty(String name, Object value, Object o, Map<String, 
Object> context, boolean throwPropertyExceptions) {
+    public void setProperty(String name, Object value, Object o, StrutsContext 
context, boolean throwPropertyExceptions) {
 
         Object oldRoot = Ognl.getRoot(context);
         Ognl.setRoot(context, o);
@@ -310,7 +310,7 @@ public class OgnlUtil {
      * @return the real target or null if no object can be found with the 
specified property
      * @throws OgnlException in case of ognl errors
      */
-    public Object getRealTarget(String property, Map<String, Object> context, 
Object root) throws OgnlException {
+    public Object getRealTarget(String property, StrutsContext context, Object 
root) throws OgnlException {
         //special keyword, they must be cutting the stack
         if ("top".equals(property)) {
             return root;
@@ -322,9 +322,9 @@ public class OgnlUtil {
 
             try {
                 for (Object target : cr) {
-                    if (OgnlRuntime.hasSetProperty((OgnlContext) context, 
target, property)
-                            || OgnlRuntime.hasGetProperty((OgnlContext) 
context, target, property)
-                            || 
OgnlRuntime.getIndexedPropertyType((OgnlContext) context, target.getClass(), 
property) != OgnlRuntime.INDEXED_PROPERTY_NONE
+                    if (OgnlRuntime.hasSetProperty(context, target, property)
+                            || OgnlRuntime.hasGetProperty(context, target, 
property)
+                            || 
OgnlRuntime.getIndexedPropertyType(target.getClass(), property) != 
OgnlRuntime.INDEXED_PROPERTY_NONE
                             ) {
                         return target;
                     }
@@ -349,58 +349,40 @@ public class OgnlUtil {
      *
      * @throws OgnlException in case of ognl errors
      */
-    public void setValue(final String name, final Map<String, Object> context, 
final Object root, final Object value) throws OgnlException {
+    public void setValue(final String name, final StrutsContext context, final 
Object root, final Object value) throws OgnlException {
         ognlSet(name, context, root, value, context, 
this::checkEvalExpression, this::checkArithmeticExpression);
     }
 
-    private boolean isEvalExpression(Object tree, Map<String, Object> context) 
throws OgnlException {
-        if (tree instanceof SimpleNode) {
-            SimpleNode node = (SimpleNode) tree;
-            OgnlContext ognlContext = null;
-
-            if (context instanceof OgnlContext) {
-                ognlContext = (OgnlContext) context;
-            }
-            return node.isEvalChain(ognlContext) || 
node.isSequence(ognlContext);
+    private boolean isEvalExpression(Object tree, StrutsContext context) 
throws OgnlException {
+        if (tree instanceof SimpleNode node) {
+            return node.isEvalChain(context) || node.isSequence(context);
         }
         return false;
     }
 
-    private boolean isArithmeticExpression(Object tree, Map<String, Object> 
context) throws OgnlException {
-        if (tree instanceof SimpleNode) {
-            SimpleNode node = (SimpleNode) tree;
-            OgnlContext ognlContext = null;
-
-            if (context instanceof OgnlContext) {
-                ognlContext = (OgnlContext) context;
-            }
-            return node.isOperation(ognlContext);
+    private boolean isArithmeticExpression(Object tree, StrutsContext context) 
throws OgnlException {
+        if (tree instanceof SimpleNode node) {
+            return node.isOperation(context);
         }
         return false;
     }
 
-    private boolean isSimpleMethod(Object tree, Map<String, Object> context) 
throws OgnlException {
-        if (tree instanceof SimpleNode) {
-            SimpleNode node = (SimpleNode) tree;
-            OgnlContext ognlContext = null;
-
-            if (context instanceof OgnlContext) {
-                ognlContext = (OgnlContext) context;
-            }
-            return node.isSimpleMethod(ognlContext) && 
!node.isChain(ognlContext);
+    private boolean isSimpleMethod(Object tree, StrutsContext context) throws 
OgnlException {
+        if (tree instanceof SimpleNode node) {
+            return node.isSimpleMethod(context) && !node.isChain(context);
         }
         return false;
     }
 
-    public Object getValue(final String name, final Map<String, Object> 
context, final Object root) throws OgnlException {
+    public Object getValue(final String name, final StrutsContext context, 
final Object root) throws OgnlException {
         return getValue(name, context, root, null);
     }
 
-    public Object callMethod(final String name, final Map<String, Object> 
context, final Object root) throws OgnlException {
+    public Object callMethod(final String name, final StrutsContext context, 
final Object root) throws OgnlException {
         return ognlGet(name, context, root, null, context, 
this::checkSimpleMethod);
     }
 
-    public Object getValue(final String name, final Map<String, Object> 
context, final Object root, final Class<?> resultType) throws OgnlException {
+    public Object getValue(final String name, final StrutsContext context, 
final Object root, final Class<?> resultType) throws OgnlException {
         return ognlGet(name, context, root, resultType, context, 
this::checkEnableEvalExpression);
     }
 
@@ -408,7 +390,7 @@ public class OgnlUtil {
         return compile(expression, null);
     }
 
-    private void ognlSet(String expr, Map<String, Object> context, Object 
root, Object value, Map<String, Object> checkContext, TreeValidator... 
treeValidators) throws OgnlException {
+    private void ognlSet(String expr, StrutsContext context, Object root, 
Object value, StrutsContext checkContext, TreeValidator... treeValidators) 
throws OgnlException {
         Object tree = toTree(expr);
         for (TreeValidator validator : treeValidators) {
             validator.validate(tree, checkContext);
@@ -416,7 +398,7 @@ public class OgnlUtil {
         Ognl.setValue(tree, context, root, value);
     }
 
-    private <T> T ognlGet(String expr, Map<String, Object> context, Object 
root, Class<T> resultType, Map<String, Object> checkContext, TreeValidator... 
treeValidators) throws OgnlException {
+    private <T> T ognlGet(String expr, StrutsContext context, Object root, 
Class<T> resultType, StrutsContext checkContext, TreeValidator... 
treeValidators) throws OgnlException {
         Object tree = toTree(expr);
         for (TreeValidator validator : treeValidators) {
             validator.validate(tree, checkContext);
@@ -462,31 +444,31 @@ public class OgnlUtil {
         throw e;
     }
 
-    public Object compile(String expression, Map<String, Object> context) 
throws OgnlException {
+    public Object compile(String expression, StrutsContext context) throws 
OgnlException {
         Object tree = toTree(expression);
         checkEnableEvalExpression(tree, context);
         return tree;
     }
 
-    private void checkEnableEvalExpression(Object tree, Map<String, Object> 
context) throws OgnlException {
+    private void checkEnableEvalExpression(Object tree, StrutsContext context) 
throws OgnlException {
         if (!enableEvalExpression && isEvalExpression(tree, context)) {
             throw new OgnlException("Eval expressions/chained expressions have 
been disabled!");
         }
     }
 
-    private void checkSimpleMethod(Object tree, Map<String, Object> context) 
throws OgnlException {
+    private void checkSimpleMethod(Object tree, StrutsContext context) throws 
OgnlException {
         if (!isSimpleMethod(tree, context)) {
             throw new OgnlException("It isn't a simple method which can be 
called!");
         }
     }
 
-    private void checkEvalExpression(Object tree, Map<String, Object> context) 
throws OgnlException {
+    private void checkEvalExpression(Object tree, StrutsContext context) 
throws OgnlException {
         if (isEvalExpression(tree, context)) {
             throw new OgnlException("Eval expression/chained expressions 
cannot be used as parameter name");
         }
     }
 
-    private void checkArithmeticExpression(Object tree, Map<String, Object> 
context) throws OgnlException {
+    private void checkArithmeticExpression(Object tree, StrutsContext context) 
throws OgnlException {
         if (isArithmeticExpression(tree, context)) {
             throw new OgnlException("Arithmetic expressions cannot be used as 
parameter name");
         }
@@ -504,7 +486,7 @@ public class OgnlUtil {
      * @param inclusions collection of method names to included copying  (can 
be null)
      *                   note if exclusions AND inclusions are supplied and 
not null nothing will get copied.
      */
-    public void copy(final Object from, final Object to, final Map<String, 
Object> context, Collection<String> exclusions, Collection<String> inclusions) {
+    public void copy(final Object from, final Object to, final StrutsContext 
context, Collection<String> exclusions, Collection<String> inclusions) {
         copy(from, to, context, exclusions, inclusions, null);
     }
 
@@ -524,7 +506,7 @@ public class OgnlUtil {
      */
     public void copy(final Object from,
                      final Object to,
-                     final Map<String, Object> context,
+                     final StrutsContext context,
                      Collection<String> exclusions,
                      Collection<String> inclusions,
                      Class<?> editable) {
@@ -534,8 +516,8 @@ public class OgnlUtil {
             return;
         }
 
-        final Map<String, Object> contextFrom = createDefaultContext(from);
-        final Map<String, Object> contextTo = createDefaultContext(to);
+        final StrutsContext contextFrom = createDefaultContext(from);
+        final StrutsContext contextTo = createDefaultContext(to);
 
         PropertyDescriptor[] fromPds;
         PropertyDescriptor[] toPds;
@@ -597,7 +579,7 @@ public class OgnlUtil {
      * @param to      the target object
      * @param context the action context we're running under
      */
-    public void copy(Object from, Object to, Map<String, Object> context) {
+    public void copy(Object from, Object to, StrutsContext context) {
         copy(from, to, context, null, null);
     }
 
@@ -640,13 +622,13 @@ public class OgnlUtil {
      */
     public Map<String, Object> getBeanMap(final Object source) throws 
IntrospectionException, OgnlException {
         Map<String, Object> beanMap = new HashMap<>();
-        final Map<String, Object> sourceMap = createDefaultContext(source);
+        final StrutsContext sourceContext = createDefaultContext(source);
         PropertyDescriptor[] propertyDescriptors = 
getPropertyDescriptors(source);
         for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
             final String propertyName = propertyDescriptor.getDisplayName();
             Method readMethod = propertyDescriptor.getReadMethod();
             if (readMethod != null) {
-                final Object value = ognlGet(propertyName, sourceMap, source, 
null, null, this::checkEnableEvalExpression);
+                final Object value = ognlGet(propertyName, sourceContext, 
source, null, null, this::checkEnableEvalExpression);
                 beanMap.put(propertyName, value);
             } else {
                 beanMap.put(propertyName, "There is no read method for " + 
propertyName);
@@ -691,7 +673,7 @@ public class OgnlUtil {
         }
     }
 
-    void internalSetProperty(String name, Object value, Object o, Map<String, 
Object> context, boolean throwPropertyExceptions) throws ReflectionException{
+    void internalSetProperty(String name, Object value, Object o, 
StrutsContext context, boolean throwPropertyExceptions) throws 
ReflectionException{
         try {
             setValue(name, context, o, value);
         } catch (OgnlException e) {
@@ -710,22 +692,22 @@ public class OgnlUtil {
         }
     }
 
-    protected Map<String, Object> createDefaultContext(Object root) {
+    protected StrutsContext createDefaultContext(Object root) {
         return createDefaultContext(root, null);
     }
 
-    protected Map<String, Object> createDefaultContext(Object root, 
ClassResolver resolver) {
+    protected StrutsContext createDefaultContext(Object root, ClassResolver 
resolver) {
         if (resolver == null) {
             resolver = container.getInstance(RootAccessor.class);
             if (resolver == null) {
                 throw new IllegalStateException("Cannot find ClassResolver");
             }
         }
-        return Ognl.createDefaultContext(root, 
container.getInstance(SecurityMemberAccess.class), resolver, defaultConverter);
+        return StrutsContext.wrap(Ognl.createDefaultContext(root, 
container.getInstance(SecurityMemberAccess.class), resolver, defaultConverter));
     }
 
     @FunctionalInterface
     private interface TreeValidator {
-        void validate(Object tree, Map<String, Object> context) throws 
OgnlException;
+        void validate(Object tree, StrutsContext context) throws OgnlException;
     }
 }
diff --git a/core/src/main/java/org/apache/struts2/ognl/OgnlValueStack.java 
b/core/src/main/java/org/apache/struts2/ognl/OgnlValueStack.java
index 26a76f7f5..2ea3a4bf7 100644
--- a/core/src/main/java/org/apache/struts2/ognl/OgnlValueStack.java
+++ b/core/src/main/java/org/apache/struts2/ognl/OgnlValueStack.java
@@ -68,7 +68,7 @@ public class OgnlValueStack implements Serializable, 
ValueStack, ClearableValueS
     private static final String MAP_IDENTIFIER_KEY = 
"org.apache.struts2.util.OgnlValueStack.MAP_IDENTIFIER_KEY";
 
     protected CompoundRoot root;
-    protected transient Map<String, Object> context;
+    protected transient StrutsContext context;
     protected Class defaultType;
     protected Map<Object, Object> overrides;
     protected transient OgnlUtil ognlUtil;
@@ -121,11 +121,11 @@ public class OgnlValueStack implements Serializable, 
ValueStack, ClearableValueS
     protected void setRoot(XWorkConverter xworkConverter, RootAccessor 
accessor, CompoundRoot compoundRoot, SecurityMemberAccess securityMemberAccess) 
{
         this.root = compoundRoot;
         this.securityMemberAccess = securityMemberAccess;
-        this.context = Ognl.createDefaultContext(this.root, 
securityMemberAccess, accessor, new OgnlTypeConverterWrapper(xworkConverter));
+        this.context = StrutsContext.wrap(Ognl.createDefaultContext(this.root, 
securityMemberAccess, accessor, new OgnlTypeConverterWrapper(xworkConverter)));
         this.converter = xworkConverter;
         context.put(VALUE_STACK, this);
-        ((OgnlContext) context).setTraceEvaluations(false);
-        ((OgnlContext) context).setKeepLastEvaluation(false);
+        context.setTraceEvaluations(false);
+        context.setKeepLastEvaluation(false);
     }
 
     @Inject(StrutsConstants.STRUTS_DEVMODE)
@@ -147,7 +147,7 @@ public class OgnlValueStack implements Serializable, 
ValueStack, ClearableValueS
      * @see org.apache.struts2.util.ValueStack#getContext()
      */
     @Override
-    public Map<String, Object> getContext() {
+    public StrutsContext getContext() {
         return context;
     }
 
@@ -212,7 +212,7 @@ public class OgnlValueStack implements Serializable, 
ValueStack, ClearableValueS
      */
     @Override
     public void setValue(String expr, Object value, boolean 
throwExceptionOnFailure) {
-        Map<String, Object> context = getContext();
+        StrutsContext context = getContext();
         try {
             trySetValue(expr, value, throwExceptionOnFailure, context);
         } catch (OgnlException e) {
@@ -224,7 +224,7 @@ public class OgnlValueStack implements Serializable, 
ValueStack, ClearableValueS
         }
     }
 
-    private void trySetValue(String expr, Object value, boolean 
throwExceptionOnFailure, Map<String, Object> context) throws OgnlException {
+    private void trySetValue(String expr, Object value, boolean 
throwExceptionOnFailure, StrutsContext context) throws OgnlException {
         context.put(XWorkConverter.CONVERSION_PROPERTY_FULLNAME, expr);
         context.put(REPORT_ERRORS_ON_NO_PROP, throwExceptionOnFailure || 
logMissingProperties ? Boolean.TRUE : Boolean.FALSE);
         ognlUtil.setValue(expr, context, root, value);
diff --git 
a/core/src/main/java/org/apache/struts2/ognl/SecurityMemberAccess.java 
b/core/src/main/java/org/apache/struts2/ognl/SecurityMemberAccess.java
index 928dda78d..ed7588847 100644
--- a/core/src/main/java/org/apache/struts2/ognl/SecurityMemberAccess.java
+++ b/core/src/main/java/org/apache/struts2/ognl/SecurityMemberAccess.java
@@ -19,6 +19,7 @@
 package org.apache.struts2.ognl;
 
 import ognl.MemberAccess;
+import ognl.OgnlContext;
 import org.apache.commons.lang3.BooleanUtils;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
@@ -108,7 +109,7 @@ public class SecurityMemberAccess implements MemberAccess {
     }
 
     @Override
-    public Object setup(Map context, Object target, Member member, String 
propertyName) {
+    public Object setup(OgnlContext context, Object target, Member member, 
String propertyName) {
         Object result = null;
 
         if (isAccessible(context, target, member, propertyName)) {
@@ -123,7 +124,7 @@ public class SecurityMemberAccess implements MemberAccess {
     }
 
     @Override
-    public void restore(Map context, Object target, Member member, String 
propertyName, Object state) {
+    public void restore(OgnlContext context, Object target, Member member, 
String propertyName, Object state) {
         if (state == null) {
             return;
         }
@@ -138,7 +139,7 @@ public class SecurityMemberAccess implements MemberAccess {
     }
 
     @Override
-    public boolean isAccessible(Map context, Object target, Member member, 
String propertyName) {
+    public boolean isAccessible(OgnlContext context, Object target, Member 
member, String propertyName) {
         LOG.debug("Checking access for [target: {}, member: {}, property: 
{}]", target, member, propertyName);
 
         if (member == null) {
diff --git 
a/core/src/main/java/org/apache/struts2/ognl/accessor/CompoundRootAccessor.java 
b/core/src/main/java/org/apache/struts2/ognl/accessor/CompoundRootAccessor.java
index b40ff0219..4909efa0a 100644
--- 
a/core/src/main/java/org/apache/struts2/ognl/accessor/CompoundRootAccessor.java
+++ 
b/core/src/main/java/org/apache/struts2/ognl/accessor/CompoundRootAccessor.java
@@ -94,9 +94,8 @@ public class CompoundRootAccessor implements RootAccessor {
     }
 
     @Override
-    public void setProperty(Map context, Object target, Object name, Object 
value) throws OgnlException {
+    public void setProperty(OgnlContext context, Object target, Object name, 
Object value) throws OgnlException {
         CompoundRoot root = (CompoundRoot) target;
-        OgnlContext ognlContext = (OgnlContext) context;
 
         for (Object o : root) {
             if (o == null) {
@@ -104,8 +103,8 @@ public class CompoundRootAccessor implements RootAccessor {
             }
 
             try {
-                if (OgnlRuntime.hasSetProperty(ognlContext, o, name)) {
-                    OgnlRuntime.setProperty(ognlContext, o, name, value);
+                if (OgnlRuntime.hasSetProperty(context, o, name)) {
+                    OgnlRuntime.setProperty(context, o, name, value);
 
                     return;
                 } else if (o instanceof Map) {
@@ -143,9 +142,8 @@ public class CompoundRootAccessor implements RootAccessor {
     }
 
     @Override
-    public Object getProperty(Map context, Object target, Object name) throws 
OgnlException {
+    public Object getProperty(OgnlContext context, Object target, Object name) 
throws OgnlException {
         CompoundRoot root = (CompoundRoot) target;
-        OgnlContext ognlContext = (OgnlContext) context;
 
         if (name instanceof Integer index) {
             return root.cutStack(index);
@@ -164,8 +162,8 @@ public class CompoundRootAccessor implements RootAccessor {
                 }
 
                 try {
-                    if ((OgnlRuntime.hasGetProperty(ognlContext, o, name)) || 
((o instanceof Map) && ((Map) o).containsKey(name))) {
-                        return OgnlRuntime.getProperty(ognlContext, o, name);
+                    if ((OgnlRuntime.hasGetProperty(context, o, name)) || ((o 
instanceof Map) && ((Map) o).containsKey(name))) {
+                        return OgnlRuntime.getProperty(context, o, name);
                     }
                 } catch (OgnlException e) {
                     if (e.getReason() != null) {
@@ -188,7 +186,7 @@ public class CompoundRootAccessor implements RootAccessor {
     }
 
     @Override
-    public Object callMethod(Map context, Object target, String name, Object[] 
objects) throws MethodFailedException {
+    public Object callMethod(OgnlContext context, Object target, String name, 
Object[] objects) throws MethodFailedException {
         CompoundRoot root = (CompoundRoot) target;
 
         if ("describe".equals(name)) {
@@ -204,19 +202,18 @@ public class CompoundRootAccessor implements RootAccessor 
{
                 return v.toString();
             }
 
-            try {
-                Map<String, PropertyDescriptor> descriptors = 
OgnlRuntime.getPropertyDescriptors(v.getClass());
+            Map<String, PropertyDescriptor> descriptors = 
OgnlRuntime.getPropertyDescriptors(v.getClass());
 
-                int maxSize = 0;
-                for (String pdName : descriptors.keySet()) {
+            int maxSize = 0;
+            for (String pdName : descriptors.keySet()) {
                     if (pdName.length() > maxSize) {
                         maxSize = pdName.length();
                     }
                 }
 
-                SortedSet<String> set = new TreeSet<>();
+            SortedSet<String> set = new TreeSet<>();
 
-                for (PropertyDescriptor pd : descriptors.values()) {
+            for (PropertyDescriptor pd : descriptors.values()) {
                     StringBuilder sb = new StringBuilder();
                     sb.append(pd.getName()).append(": ");
 
@@ -228,15 +225,11 @@ public class CompoundRootAccessor implements RootAccessor 
{
                     set.add(sb.toString());
                 }
 
-                StringBuilder sb = new StringBuilder();
-                for (String aSet : set) {
+            StringBuilder sb = new StringBuilder();
+            for (String aSet : set) {
                     sb.append(aSet).append("\n");
                 }
-                return sb.toString();
-            } catch (IntrospectionException | OgnlException e) {
-                LOG.debug("Got exception in callMethod", e);
-            }
-            return null;
+            return sb.toString();
         }
 
         Throwable reason = null;
@@ -281,16 +274,16 @@ public class CompoundRootAccessor implements RootAccessor 
{
     }
 
     @Override
-    public Object callStaticMethod(Map transientVars, Class aClass, String s, 
Object[] objects) throws MethodFailedException {
+    public Object callStaticMethod(OgnlContext transientVars, Class aClass, 
String s, Object[] objects) throws MethodFailedException {
         return null;
     }
 
     @Override
-    public Class classForName(String className, Map context) throws 
ClassNotFoundException {
+    public Class classForName(String className, OgnlContext context) throws 
ClassNotFoundException {
         Object root = Ognl.getRoot(context);
 
         if (disallowCustomOgnlMap) {
-            String nodeClassName = ((OgnlContext) 
context).getCurrentNode().getClass().getName();
+            String nodeClassName = 
context.getCurrentNode().getClass().getName();
             if ("ognl.ASTMap".equals(nodeClassName) && 
!ALLOWED_MAP_CLASSES.contains(className)) {
                 LOG.error("Constructing OGNL ASTMap's from custom classes is 
forbidden. Attempted class: {}", className);
                 return null;
diff --git 
a/core/src/main/java/org/apache/struts2/ognl/accessor/HttpParametersPropertyAccessor.java
 
b/core/src/main/java/org/apache/struts2/ognl/accessor/HttpParametersPropertyAccessor.java
index 6f1216b8c..53191030c 100644
--- 
a/core/src/main/java/org/apache/struts2/ognl/accessor/HttpParametersPropertyAccessor.java
+++ 
b/core/src/main/java/org/apache/struts2/ognl/accessor/HttpParametersPropertyAccessor.java
@@ -19,21 +19,20 @@
 package org.apache.struts2.ognl.accessor;
 
 import ognl.ObjectPropertyAccessor;
+import ognl.OgnlContext;
 import ognl.OgnlException;
 import org.apache.struts2.dispatcher.HttpParameters;
 
-import java.util.Map;
-
 public class HttpParametersPropertyAccessor extends ObjectPropertyAccessor {
 
     @Override
-    public Object getProperty(Map context, Object target, Object oname) throws 
OgnlException {
+    public Object getProperty(OgnlContext context, Object target, Object 
oname) throws OgnlException {
         HttpParameters parameters = (HttpParameters) target;
         return parameters.get(String.valueOf(oname)).getObject();
     }
 
     @Override
-    public void setProperty(Map context, Object target, Object oname, Object 
value) throws OgnlException {
+    public void setProperty(OgnlContext context, Object target, Object oname, 
Object value) throws OgnlException {
         throw new OgnlException("Access to " + target.getClass().getName() + " 
is read-only!");
     }
 }
\ No newline at end of file
diff --git 
a/core/src/main/java/org/apache/struts2/ognl/accessor/ObjectAccessor.java 
b/core/src/main/java/org/apache/struts2/ognl/accessor/ObjectAccessor.java
index a8cabd7e1..ac80676e9 100644
--- a/core/src/main/java/org/apache/struts2/ognl/accessor/ObjectAccessor.java
+++ b/core/src/main/java/org/apache/struts2/ognl/accessor/ObjectAccessor.java
@@ -18,16 +18,16 @@
  */
 package org.apache.struts2.ognl.accessor;
 
-import org.apache.struts2.conversion.impl.XWorkConverter;
-import org.apache.struts2.util.reflection.ReflectionContextState;
 import ognl.ObjectPropertyAccessor;
+import ognl.OgnlContext;
 import ognl.OgnlException;
-
-import java.util.Map;
+import org.apache.struts2.conversion.impl.XWorkConverter;
+import org.apache.struts2.util.reflection.ReflectionContextState;
 
 public class ObjectAccessor extends ObjectPropertyAccessor {
+
     @Override
-    public Object getProperty(Map map, Object o, Object o1) throws 
OgnlException {
+    public Object getProperty(OgnlContext map, Object o, Object o1) throws 
OgnlException {
         Object obj = super.getProperty(map, o, o1);
 
         map.put(XWorkConverter.LAST_BEAN_CLASS_ACCESSED, o.getClass());
@@ -37,7 +37,7 @@ public class ObjectAccessor extends ObjectPropertyAccessor {
     }
 
     @Override
-    public void setProperty(Map map, Object o, Object o1, Object o2) throws 
OgnlException {
+    public void setProperty(OgnlContext map, Object o, Object o1, Object o2) 
throws OgnlException {
         super.setProperty(map, o, o1, o2);
     }
 }
\ No newline at end of file
diff --git 
a/core/src/main/java/org/apache/struts2/ognl/accessor/ObjectProxyPropertyAccessor.java
 
b/core/src/main/java/org/apache/struts2/ognl/accessor/ObjectProxyPropertyAccessor.java
index e57c55a84..4fcdfdb57 100644
--- 
a/core/src/main/java/org/apache/struts2/ognl/accessor/ObjectProxyPropertyAccessor.java
+++ 
b/core/src/main/java/org/apache/struts2/ognl/accessor/ObjectProxyPropertyAccessor.java
@@ -54,7 +54,7 @@ public class ObjectProxyPropertyAccessor implements 
PropertyAccessor {
     }
 
     @Override
-    public Object getProperty(Map context, Object target, Object name) throws 
OgnlException {
+    public Object getProperty(OgnlContext context, Object target, Object name) 
throws OgnlException {
         ObjectProxy proxy = (ObjectProxy) target;
         setupContext(context, proxy);
 
@@ -63,7 +63,7 @@ public class ObjectProxyPropertyAccessor implements 
PropertyAccessor {
     }
 
     @Override
-    public void setProperty(Map context, Object target, Object name, Object 
value) throws OgnlException {
+    public void setProperty(OgnlContext context, Object target, Object name, 
Object value) throws OgnlException {
         ObjectProxy proxy = (ObjectProxy) target;
         setupContext(context, proxy);
 
@@ -77,7 +77,7 @@ public class ObjectProxyPropertyAccessor implements 
PropertyAccessor {
      * @param context
      * @param proxy
      */
-    private void setupContext(Map context, ObjectProxy proxy) {
+    private void setupContext(OgnlContext context, ObjectProxy proxy) {
         ReflectionContextState.setLastBeanClassAccessed(context, 
proxy.getLastClassAccessed());
         ReflectionContextState.setLastBeanPropertyAccessed(context, 
proxy.getLastPropertyAccessed());
     }
diff --git 
a/core/src/main/java/org/apache/struts2/ognl/accessor/ParameterPropertyAccessor.java
 
b/core/src/main/java/org/apache/struts2/ognl/accessor/ParameterPropertyAccessor.java
index f7e4fb102..bd58d2924 100644
--- 
a/core/src/main/java/org/apache/struts2/ognl/accessor/ParameterPropertyAccessor.java
+++ 
b/core/src/main/java/org/apache/struts2/ognl/accessor/ParameterPropertyAccessor.java
@@ -19,6 +19,7 @@
 package org.apache.struts2.ognl.accessor;
 
 import ognl.ObjectPropertyAccessor;
+import ognl.OgnlContext;
 import ognl.OgnlException;
 import org.apache.struts2.dispatcher.Parameter;
 
@@ -27,7 +28,7 @@ import java.util.Map;
 public class ParameterPropertyAccessor extends ObjectPropertyAccessor {
 
     @Override
-    public Object getProperty(Map context, Object target, Object oname) throws 
OgnlException {
+    public Object getProperty(OgnlContext context, Object target, Object 
oname) throws OgnlException {
         if (target instanceof Parameter) {
             if ("value".equalsIgnoreCase(String.valueOf(oname))) {
                 throw new OgnlException("Access to " + oname + " is not 
allowed! Call parameter name directly!");
@@ -38,7 +39,7 @@ public class ParameterPropertyAccessor extends 
ObjectPropertyAccessor {
     }
 
     @Override
-    public void setProperty(Map context, Object target, Object oname, Object 
value) throws OgnlException {
+    public void setProperty(OgnlContext context, Object target, Object oname, 
Object value) throws OgnlException {
         if (target instanceof Parameter) {
             throw new OgnlException("Access to " + target.getClass().getName() 
+ " is read-only!");
         } else {
diff --git 
a/core/src/main/java/org/apache/struts2/ognl/accessor/XWorkCollectionPropertyAccessor.java
 
b/core/src/main/java/org/apache/struts2/ognl/accessor/XWorkCollectionPropertyAccessor.java
index d416785a5..d051f29b1 100644
--- 
a/core/src/main/java/org/apache/struts2/ognl/accessor/XWorkCollectionPropertyAccessor.java
+++ 
b/core/src/main/java/org/apache/struts2/ognl/accessor/XWorkCollectionPropertyAccessor.java
@@ -18,11 +18,13 @@
  */
 package org.apache.struts2.ognl.accessor;
 
+import ognl.OgnlContext;
 import org.apache.struts2.ObjectFactory;
 import org.apache.struts2.conversion.ObjectTypeDeterminer;
 import org.apache.struts2.conversion.impl.XWorkConverter;
 import org.apache.struts2.inject.Inject;
 import org.apache.struts2.ognl.OgnlUtil;
+import org.apache.struts2.ognl.StrutsContext;
 import org.apache.struts2.util.reflection.ReflectionContextState;
 import ognl.ObjectPropertyAccessor;
 import ognl.OgnlException;
@@ -83,10 +85,10 @@ public class XWorkCollectionPropertyAccessor extends 
SetPropertyAccessor {
      * a Map returning a JavaBean with the value of id property matching
      * the input.
      *
-     * @see ognl.PropertyAccessor#getProperty(java.util.Map, Object, Object)
+     * @see ognl.PropertyAccessor#getProperty(OgnlContext, Object, Object)
      */
     @Override
-    public Object getProperty(Map context, Object target, Object key) throws 
OgnlException {
+    public Object getProperty(OgnlContext context, Object target, Object key) 
throws OgnlException {
         LOG.trace("Entering getProperty()");
 
         //check if it is a generic type property.
@@ -185,7 +187,7 @@ public class XWorkCollectionPropertyAccessor extends 
SetPropertyAccessor {
       * Gets an indexed Map by a given key property with the key being
       * the value of the property and the value being the
       */
-    private Map getSetMap(Map context, Collection collection, String property) 
throws OgnlException {
+    private Map getSetMap(OgnlContext context, Collection collection, String 
property) throws OgnlException {
         LOG.trace("getting set Map");
 
         String path = ReflectionContextState.getCurrentPropertyPath(context);
@@ -210,7 +212,7 @@ public class XWorkCollectionPropertyAccessor extends 
SetPropertyAccessor {
     /*
       * gets a bean with the given
       */
-    public Object getPropertyThroughIteration(Map context, Collection 
collection, String property, Object key)
+    public Object getPropertyThroughIteration(OgnlContext context, Collection 
collection, String property, Object key)
             throws OgnlException {
         //TODO
         for (Object currTest : collection) {
@@ -223,7 +225,7 @@ public class XWorkCollectionPropertyAccessor extends 
SetPropertyAccessor {
     }
 
     @Override
-    public void setProperty(Map context, Object target, Object name, Object 
value) throws OgnlException {
+    public void setProperty(OgnlContext context, Object target, Object name, 
Object value) throws OgnlException {
         Class lastClass = (Class) 
context.get(XWorkConverter.LAST_BEAN_CLASS_ACCESSED);
         String lastProperty = (String) 
context.get(XWorkConverter.LAST_BEAN_PROPERTY_ACCESSED);
         Class convertToClass = objectTypeDeterminer.getElementClass(lastClass, 
lastProperty, name);
@@ -238,7 +240,7 @@ public class XWorkCollectionPropertyAccessor extends 
SetPropertyAccessor {
             for (Object v : values) {
                 try {
                     Object o = objectFactory.buildBean(convertToClass, 
context);
-                    ognlUtil.setValue((String) name, context, o, v);
+                    ognlUtil.setValue((String) name, (StrutsContext) context, 
o, v);
                     c.add(o);
                 } catch (Exception e) {
                     throw new OgnlException("Error converting given String 
values for Collection.", e);
diff --git 
a/core/src/main/java/org/apache/struts2/ognl/accessor/XWorkEnumerationAccessor.java
 
b/core/src/main/java/org/apache/struts2/ognl/accessor/XWorkEnumerationAccessor.java
index cad0c7cd8..933f9f989 100644
--- 
a/core/src/main/java/org/apache/struts2/ognl/accessor/XWorkEnumerationAccessor.java
+++ 
b/core/src/main/java/org/apache/struts2/ognl/accessor/XWorkEnumerationAccessor.java
@@ -20,6 +20,7 @@ package org.apache.struts2.ognl.accessor;
 
 import ognl.EnumerationPropertyAccessor;
 import ognl.ObjectPropertyAccessor;
+import ognl.OgnlContext;
 import ognl.OgnlException;
 
 import java.util.Map;
@@ -33,7 +34,7 @@ public class XWorkEnumerationAccessor extends 
EnumerationPropertyAccessor {
     private final ObjectPropertyAccessor opa = new ObjectPropertyAccessor();
 
     @Override
-    public void setProperty(Map context, Object target, Object name, Object 
value) throws OgnlException {
+    public void setProperty(OgnlContext context, Object target, Object name, 
Object value) throws OgnlException {
         opa.setProperty(context, target, name, value);
     }
 }
diff --git 
a/core/src/main/java/org/apache/struts2/ognl/accessor/XWorkIteratorPropertyAccessor.java
 
b/core/src/main/java/org/apache/struts2/ognl/accessor/XWorkIteratorPropertyAccessor.java
index acd7c52d2..476423721 100644
--- 
a/core/src/main/java/org/apache/struts2/ognl/accessor/XWorkIteratorPropertyAccessor.java
+++ 
b/core/src/main/java/org/apache/struts2/ognl/accessor/XWorkIteratorPropertyAccessor.java
@@ -20,11 +20,11 @@ package org.apache.struts2.ognl.accessor;
 
 import ognl.IteratorPropertyAccessor;
 import ognl.ObjectPropertyAccessor;
+import ognl.OgnlContext;
 import ognl.OgnlException;
 
 import java.util.Map;
 
-
 /**
  * @author plightbo
  */
@@ -33,7 +33,7 @@ public class XWorkIteratorPropertyAccessor extends 
IteratorPropertyAccessor {
     private final ObjectPropertyAccessor opa = new ObjectPropertyAccessor();
 
     @Override
-    public void setProperty(Map context, Object target, Object name, Object 
value) throws OgnlException {
+    public void setProperty(OgnlContext context, Object target, Object name, 
Object value) throws OgnlException {
         opa.setProperty(context, target, name, value);
     }
 }
diff --git 
a/core/src/main/java/org/apache/struts2/ognl/accessor/XWorkMapPropertyAccessor.java
 
b/core/src/main/java/org/apache/struts2/ognl/accessor/XWorkMapPropertyAccessor.java
index 6c1cf0419..fea11bae2 100644
--- 
a/core/src/main/java/org/apache/struts2/ognl/accessor/XWorkMapPropertyAccessor.java
+++ 
b/core/src/main/java/org/apache/struts2/ognl/accessor/XWorkMapPropertyAccessor.java
@@ -18,6 +18,7 @@
  */
 package org.apache.struts2.ognl.accessor;
 
+import ognl.OgnlContext;
 import org.apache.struts2.ObjectFactory;
 import org.apache.struts2.conversion.ObjectTypeDeterminer;
 import org.apache.struts2.conversion.impl.XWorkConverter;
@@ -62,7 +63,7 @@ public class XWorkMapPropertyAccessor extends 
MapPropertyAccessor {
     }
 
     @Override
-    public Object getProperty(Map context, Object target, Object name) throws 
OgnlException {
+    public Object getProperty(OgnlContext context, Object target, Object name) 
throws OgnlException {
         LOG.trace("Entering getProperty ({},{},{})", context, target, name);
 
         ReflectionContextState.updateCurrentPropertyPath(context, name);
@@ -122,7 +123,7 @@ public class XWorkMapPropertyAccessor extends 
MapPropertyAccessor {
     }
 
     @Override
-    public void setProperty(Map context, Object target, Object name, Object 
value) throws OgnlException {
+    public void setProperty(OgnlContext context, Object target, Object name, 
Object value) throws OgnlException {
         LOG.trace("Entering setProperty({},{},{},{})", context, target, name, 
value);
 
         Object key = getKey(context, name);
@@ -130,7 +131,7 @@ public class XWorkMapPropertyAccessor extends 
MapPropertyAccessor {
         map.put(key, getValue(context, value));
      }
 
-    private Object getValue(Map context, Object value) {
+    private Object getValue(OgnlContext context, Object value) {
          Class lastClass = (Class) 
context.get(XWorkConverter.LAST_BEAN_CLASS_ACCESSED);
          String lastProperty = (String) 
context.get(XWorkConverter.LAST_BEAN_PROPERTY_ACCESSED);
          if (lastClass == null || lastProperty == null) {
@@ -143,7 +144,7 @@ public class XWorkMapPropertyAccessor extends 
MapPropertyAccessor {
          return xworkConverter.convertValue(context, value, elementClass);
     }
 
-    private Object getKey(Map context, Object name) {
+    private Object getKey(OgnlContext context, Object name) {
         Class lastClass = (Class) 
context.get(XWorkConverter.LAST_BEAN_CLASS_ACCESSED);
         String lastProperty = (String) 
context.get(XWorkConverter.LAST_BEAN_PROPERTY_ACCESSED);
         if (lastClass == null || lastProperty == null) {
diff --git 
a/core/src/main/java/org/apache/struts2/ognl/accessor/XWorkMethodAccessor.java 
b/core/src/main/java/org/apache/struts2/ognl/accessor/XWorkMethodAccessor.java
index 70730c4ca..aaae904b6 100644
--- 
a/core/src/main/java/org/apache/struts2/ognl/accessor/XWorkMethodAccessor.java
+++ 
b/core/src/main/java/org/apache/struts2/ognl/accessor/XWorkMethodAccessor.java
@@ -18,7 +18,6 @@
  */
 package org.apache.struts2.ognl.accessor;
 
-import org.apache.struts2.util.reflection.ReflectionContextState;
 import ognl.MethodFailedException;
 import ognl.ObjectMethodAccessor;
 import ognl.OgnlContext;
@@ -26,11 +25,11 @@ import ognl.OgnlRuntime;
 import ognl.PropertyAccessor;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
+import org.apache.struts2.util.reflection.ReflectionContextState;
 
 import java.beans.PropertyDescriptor;
 import java.util.Arrays;
 import java.util.Collection;
-import java.util.Map;
 
 /**
  * Allows methods to be executed under normal cirumstances, except when {@link 
ReflectionContextState#DENY_METHOD_EXECUTION}
@@ -41,40 +40,39 @@ import java.util.Map;
  */
 public class XWorkMethodAccessor extends ObjectMethodAccessor {
 
-       private static final Logger LOG = 
LogManager.getLogger(XWorkMethodAccessor.class);
+    private static final Logger LOG = 
LogManager.getLogger(XWorkMethodAccessor.class);
 
     @Override
-    public Object callMethod(Map context, Object object, String string, 
Object[] objects) throws MethodFailedException {
+    public Object callMethod(OgnlContext context, Object object, String 
string, Object[] objects) throws MethodFailedException {
 
         //Collection property accessing
         //this if statement ensures that ognl
         //statements of the form someBean.mySet('keyPropVal')
         //return the set element with value of the keyProp given
 
-        if (objects.length == 1 && context instanceof OgnlContext) {
+        if (objects.length == 1 && context != null) {
             try {
-              OgnlContext ogContext=(OgnlContext)context;
-              if (OgnlRuntime.hasSetProperty(ogContext, object, string))  {
-                       PropertyDescriptor 
descriptor=OgnlRuntime.getPropertyDescriptor(object.getClass(), string);
-                       Class propertyType=descriptor.getPropertyType();
-                       if ((Collection.class).isAssignableFrom(propertyType)) {
-                           //go directly through OgnlRuntime here
-                           //so that property strings are not cleared
-                           //i.e. OgnlUtil should be used initially, 
OgnlRuntime
-                           //thereafter
+                if (OgnlRuntime.hasSetProperty(context, object, string)) {
+                    PropertyDescriptor descriptor = 
OgnlRuntime.getPropertyDescriptor(object.getClass(), string);
+                    Class<?> propertyType = descriptor.getPropertyType();
+                    if ((Collection.class).isAssignableFrom(propertyType)) {
+                        //go directly through OgnlRuntime here
+                        //so that property strings are not cleared
+                        //i.e. OgnlUtil should be used initially, OgnlRuntime
+                        //thereafter
 
-                           Object propVal=OgnlRuntime.getProperty(ogContext, 
object, string);
-                           //use the Collection property accessor instead of 
the individual property accessor, because
-                           //in the case of Lists otherwise the index property 
could be used
-                           PropertyAccessor 
accessor=OgnlRuntime.getPropertyAccessor(Collection.class);
-                           
ReflectionContextState.setGettingByKeyProperty(ogContext,true);
-                           return 
accessor.getProperty(ogContext,propVal,objects[0]);
-                       }
-              }
-            }  catch (Exception oe) {
+                        Object propVal = OgnlRuntime.getProperty(context, 
object, string);
+                        //use the Collection property accessor instead of the 
individual property accessor, because
+                        //in the case of Lists otherwise the index property 
could be used
+                        PropertyAccessor accessor = 
OgnlRuntime.getPropertyAccessor(Collection.class);
+                        
ReflectionContextState.setGettingByKeyProperty(context, true);
+                        return accessor.getProperty(context, propVal, 
objects[0]);
+                    }
+                }
+            } catch (Exception oe) {
                 //this exception should theoretically never happen
                 //log it
-               LOG.error("An unexpected exception occurred", oe);
+                LOG.error("An unexpected exception occurred", oe);
             }
 
         }
@@ -96,23 +94,22 @@ public class XWorkMethodAccessor extends 
ObjectMethodAccessor {
         }
     }
 
-    private Object callMethodWithDebugInfo(Map context, Object object, String 
methodName, Object[] objects) throws MethodFailedException {
+    private Object callMethodWithDebugInfo(OgnlContext context, Object object, 
String methodName, Object[] objects) throws MethodFailedException {
         try {
             return super.callMethod(context, object, methodName, objects);
-               }
-               catch(MethodFailedException e) {
-                       if (LOG.isDebugEnabled()) {
-                               if (!(e.getReason() instanceof 
NoSuchMethodException)) {
-                                       // the method exists on the target 
object, but something went wrong
+        } catch (MethodFailedException e) {
+            if (LOG.isDebugEnabled()) {
+                if (!(e.getReason() instanceof NoSuchMethodException)) {
+                    // the method exists on the target object, but something 
went wrong
                     LOG.debug("Error calling method through OGNL: object: [{}] 
method: [{}] args: [{}] - {}", object.toString(), methodName, 
Arrays.toString(objects), e.getReason());
                 }
             }
-                       throw e;
-               }
-       }
+            throw e;
+        }
+    }
 
     @Override
-    public Object callStaticMethod(Map context, Class aClass, String string, 
Object[] objects) throws MethodFailedException {
+    public Object callStaticMethod(OgnlContext context, Class aClass, String 
string, Object[] objects) throws MethodFailedException {
         boolean e = ReflectionContextState.isDenyMethodExecution(context);
 
         if (!e) {
@@ -122,19 +119,18 @@ public class XWorkMethodAccessor extends 
ObjectMethodAccessor {
         }
     }
 
-       private Object callStaticMethodWithDebugInfo(Map context, Class aClass, 
String methodName,
-                       Object[] objects) throws MethodFailedException {
-               try {
-                       return super.callStaticMethod(context, aClass, 
methodName, objects);
-               }
-               catch(MethodFailedException e) {
-                       if (LOG.isDebugEnabled()) {
-                               if (!(e.getReason() instanceof 
NoSuchMethodException)) {
-                                       // the method exists on the target 
class, but something went wrong
-                                       LOG.debug("Error calling method through 
OGNL, class: [{}] method: [{}] args: [{}] - {}", aClass.getName(), methodName, 
Arrays.toString(objects), e.getReason());
-                               }
-                       }
-                       throw e;
-               }
-       }
+    private Object callStaticMethodWithDebugInfo(OgnlContext context, Class<?> 
aClass, String methodName,
+                                                 Object[] objects) throws 
MethodFailedException {
+        try {
+            return super.callStaticMethod(context, aClass, methodName, 
objects);
+        } catch (MethodFailedException e) {
+            if (LOG.isDebugEnabled()) {
+                if (!(e.getReason() instanceof NoSuchMethodException)) {
+                    // the method exists on the target class, but something 
went wrong
+                    LOG.debug("Error calling method through OGNL, class: [{}] 
method: [{}] args: [{}] - {}", aClass.getName(), methodName, 
Arrays.toString(objects), e.getReason());
+                }
+            }
+            throw e;
+        }
+    }
 }
diff --git 
a/core/src/main/java/org/apache/struts2/ognl/accessor/XWorkObjectPropertyAccessor.java
 
b/core/src/main/java/org/apache/struts2/ognl/accessor/XWorkObjectPropertyAccessor.java
index 0d364bf54..f877ad68a 100644
--- 
a/core/src/main/java/org/apache/struts2/ognl/accessor/XWorkObjectPropertyAccessor.java
+++ 
b/core/src/main/java/org/apache/struts2/ognl/accessor/XWorkObjectPropertyAccessor.java
@@ -18,6 +18,7 @@
  */
 package org.apache.struts2.ognl.accessor;
 
+import ognl.OgnlContext;
 import org.apache.struts2.conversion.impl.XWorkConverter;
 import org.apache.struts2.util.reflection.ReflectionContextState;
 import ognl.ObjectPropertyAccessor;
@@ -28,9 +29,10 @@ import java.util.Map;
 /**
  * @author Gabe
  */
+@Deprecated(since = "7.1.0", forRemoval = true)
 public class XWorkObjectPropertyAccessor extends ObjectPropertyAccessor {
     @Override
-    public Object getProperty(Map context, Object target, Object oname) throws 
OgnlException {
+    public Object getProperty(OgnlContext context, Object target, Object 
oname) throws OgnlException {
         //set the last set objects in the context
         //so if the next objects accessed are
         //Maps or Collections they can use the information
diff --git a/core/src/main/java/org/apache/struts2/util/ValueStack.java 
b/core/src/main/java/org/apache/struts2/util/ValueStack.java
index eac299833..cb4a4a77c 100644
--- a/core/src/main/java/org/apache/struts2/util/ValueStack.java
+++ b/core/src/main/java/org/apache/struts2/util/ValueStack.java
@@ -19,6 +19,7 @@
 package org.apache.struts2.util;
 
 import org.apache.struts2.ActionContext;
+import org.apache.struts2.ognl.StrutsContext;
 
 import java.util.Map;
 
@@ -39,7 +40,7 @@ public interface ValueStack {
      *
      * @return  the context.
      */
-    Map<String, Object> getContext();
+    StrutsContext getContext();
 
     ActionContext getActionContext();
 
diff --git 
a/core/src/main/java/org/apache/struts2/util/reflection/ReflectionProvider.java 
b/core/src/main/java/org/apache/struts2/util/reflection/ReflectionProvider.java
index 7ffc19a71..f77a463e7 100644
--- 
a/core/src/main/java/org/apache/struts2/util/reflection/ReflectionProvider.java
+++ 
b/core/src/main/java/org/apache/struts2/util/reflection/ReflectionProvider.java
@@ -19,6 +19,7 @@
 package org.apache.struts2.util.reflection;
 
 import org.apache.struts2.conversion.impl.XWorkConverter;
+import org.apache.struts2.ognl.StrutsContext;
 
 import java.beans.IntrospectionException;
 import java.beans.PropertyDescriptor;
@@ -43,7 +44,7 @@ public interface ReflectionProvider {
      * @param o       the object
      * @param context the action context
      */
-    void setProperties(Map<String, ?> props, Object o, Map<String, Object> 
context);
+    void setProperties(Map<String, ?> props, Object o, StrutsContext context);
 
     /**
      * Sets the object's properties using the default type converter.
@@ -54,7 +55,7 @@ public interface ReflectionProvider {
      * @param throwPropertyExceptions boolean which tells whether it should 
throw exceptions for
      *                                problems setting the properties
      */
-    void setProperties(Map<String, ?> props, Object o, Map<String, Object> 
context, boolean throwPropertyExceptions) throws ReflectionException;
+    void setProperties(Map<String, ?> props, Object o, StrutsContext context, 
boolean throwPropertyExceptions) throws ReflectionException;
 
     /**
      * Sets the properties on the object using the default context, defaulting 
to not throwing
@@ -91,7 +92,7 @@ public interface ReflectionProvider {
      * @param inclusions collection of method names to included copying  (can 
be null)
      *                   note if exclusions AND inclusions are supplied and 
not null nothing will get copied.
      */
-    void copy(Object from, Object to, Map<String, Object> context, 
Collection<String> exclusions, Collection<String> inclusions);
+    void copy(Object from, Object to, StrutsContext context, 
Collection<String> exclusions, Collection<String> inclusions);
 
     /**
      * Copies the properties in the object "from" and sets them in the object 
"to"
@@ -107,7 +108,7 @@ public interface ReflectionProvider {
      *                   note if exclusions AND inclusions are supplied and 
not null nothing will get copied.
      * @param editable the class (or interface) to restrict property setting to
      */
-    void copy(Object from, Object to, Map<String, Object> context, 
Collection<String> exclusions, Collection<String> inclusions, Class<?> 
editable);
+    void copy(Object from, Object to, StrutsContext context, 
Collection<String> exclusions, Collection<String> inclusions, Class<?> 
editable);
 
     /**
      * Looks for the real target with the specified property given a root 
Object which may be a
@@ -119,7 +120,7 @@ public interface ReflectionProvider {
      * @return the real target or null if no object can be found with the 
specified property
      * @throws ReflectionException in case of reflection problems
      */
-    Object getRealTarget(String property, Map<String, Object> context, Object 
root) throws ReflectionException;
+    Object getRealTarget(String property, StrutsContext context, Object root) 
throws ReflectionException;
 
     /**
      * Sets the named property to the supplied value on the Object,
@@ -131,7 +132,7 @@ public interface ReflectionProvider {
      * @param throwPropertyExceptions boolean which tells whether it should 
throw exceptions for
      *                                problems setting the properties
      */
-    void setProperty(String name, Object value, Object o, Map<String, Object> 
context, boolean throwPropertyExceptions);
+    void setProperty(String name, Object value, Object o, StrutsContext 
context, boolean throwPropertyExceptions);
 
     /**
      * Sets the named property to the supplied value on the Object, defaults 
to not throwing
@@ -142,7 +143,7 @@ public interface ReflectionProvider {
      * @param o       the object upon which to set the property
      * @param context the context which may include the TypeConverter
      */
-    void setProperty(String name, Object value, Object o, Map<String, Object> 
context);
+    void setProperty(String name, Object value, Object o, StrutsContext 
context);
 
     /**
      * Creates a Map with read properties for the given source object.
@@ -166,7 +167,7 @@ public interface ReflectionProvider {
      * @param root the root object for the OGNL expression
      * @return the result of evaluating the expression
      */
-    Object getValue( String expression, Map<String, Object> context, Object 
root ) throws ReflectionException;
+    Object getValue( String expression, StrutsContext context, Object root ) 
throws ReflectionException;
 
     /**
      * Evaluates the given OGNL expression to insert a value into the object 
graph
@@ -177,7 +178,7 @@ public interface ReflectionProvider {
      * @param context the naming context for the evaluation
      * @param value the value to insert into the object graph
      */
-    void setValue( String expression, Map<String, Object> context, Object 
root, Object value ) throws ReflectionException;
+    void setValue( String expression, StrutsContext context, Object root, 
Object value ) throws ReflectionException;
 
     /**
      * Get's the java beans property descriptors for the given source.

Reply via email to