This is an automated email from the ASF dual-hosted git repository. lukaszlenart pushed a commit to branch feat/ognl-3.5-upgrade in repository https://gitbox.apache.org/repos/asf/struts.git
commit fbb904e9c656cc71beaca17e04d8d325f5ef30ed Author: Lukasz Lenart <[email protected]> AuthorDate: Mon Apr 6 18:41:27 2026 +0200 WW-5326 refactor(ognl): replace Ognl.createDefaultContext with direct StrutsContext construction Co-Authored-By: Claude Opus 4.6 <[email protected]> --- .../struts2/ognl/OgnlReflectionContextFactory.java | 1 + .../java/org/apache/struts2/ognl/OgnlUtil.java | 59 ++++++++++++---------- .../org/apache/struts2/ognl/OgnlValueStack.java | 16 +++--- .../apache/struts2/ognl/OgnlValueStackFactory.java | 3 ++ .../ognl/accessor/ObjectProxyPropertyAccessor.java | 8 +-- 5 files changed, 45 insertions(+), 42 deletions(-) diff --git a/core/src/main/java/org/apache/struts2/ognl/OgnlReflectionContextFactory.java b/core/src/main/java/org/apache/struts2/ognl/OgnlReflectionContextFactory.java index 62dab60a3..ed79b2fbf 100644 --- a/core/src/main/java/org/apache/struts2/ognl/OgnlReflectionContextFactory.java +++ b/core/src/main/java/org/apache/struts2/ognl/OgnlReflectionContextFactory.java @@ -29,6 +29,7 @@ import ognl.Ognl; public class OgnlReflectionContextFactory implements ReflectionContextFactory { @Override + @SuppressWarnings({"rawtypes", "unchecked"}) public OgnlContext createDefaultContext(Object root) { return Ognl.createDefaultContext(root); } 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 f9e484202..cec398f0b 100644 --- a/core/src/main/java/org/apache/struts2/ognl/OgnlUtil.java +++ b/core/src/main/java/org/apache/struts2/ognl/OgnlUtil.java @@ -61,7 +61,7 @@ public class OgnlUtil { private final OgnlCache<String, Object> expressionCache; private final OgnlCache<Class<?>, BeanInfo> beanInfoCache; - private TypeConverter defaultConverter; + private TypeConverter<StrutsContext> defaultConverter; private final OgnlGuard ognlGuard; private boolean devMode; @@ -211,14 +211,14 @@ public class OgnlUtil { * @return an OgnlContext instance * @since 7.2.0 */ - private OgnlContext ensureOgnlContext(Map<String, Object> context) { - if (context instanceof OgnlContext ognlContext) { - return ognlContext; + private StrutsContext ensureOgnlContext(Map<String, Object> context) { + if (context instanceof StrutsContext strutsContext) { + return strutsContext; } - // Create a new OgnlContext and copy the Map contents - OgnlContext ognlContext = createDefaultContext(null); - ognlContext.putAll(context); - return ognlContext; + // Create a new StrutsContext and copy the Map contents + StrutsContext strutsContext = createDefaultContext(null); + strutsContext.putAll(context); + return strutsContext; } /** @@ -247,9 +247,9 @@ public class OgnlUtil { return; } - OgnlContext ognlContext = ensureOgnlContext(context); + StrutsContext strutsContext = ensureOgnlContext(context); try { - withRoot(ognlContext, o, () -> { + withRoot(strutsContext, o, () -> { for (Map.Entry<String, ?> entry : props.entrySet()) { String expression = entry.getKey(); internalSetProperty(expression, entry.getValue(), o, context, throwPropertyExceptions); @@ -309,9 +309,9 @@ public class OgnlUtil { * problems setting the property */ public void setProperty(String name, Object value, Object o, Map<String, Object> context, boolean throwPropertyExceptions) { - OgnlContext ognlContext = ensureOgnlContext(context); + StrutsContext strutsContext = ensureOgnlContext(context); try { - withRoot(ognlContext, o, () -> internalSetProperty(name, value, o, context, throwPropertyExceptions)); + withRoot(strutsContext, o, () -> internalSetProperty(name, value, o, context, throwPropertyExceptions)); } catch (OgnlException e) { // Should never happen as internalSetProperty catches OgnlException throw new IllegalStateException("Unexpected OgnlException in setProperty", e); @@ -424,7 +424,7 @@ public class OgnlUtil { for (TreeValidator validator : treeValidators) { validator.validate(tree, checkContext); } - OgnlContext ognlContext = (OgnlContext) context; + StrutsContext ognlContext = (StrutsContext) context; withRoot(ognlContext, root, () -> Ognl.setValue(tree, ognlContext, root, value)); } @@ -434,7 +434,7 @@ public class OgnlUtil { for (TreeValidator validator : treeValidators) { validator.validate(tree, checkContext); } - OgnlContext ognlContext = (OgnlContext) context; + StrutsContext ognlContext = (StrutsContext) context; return withRoot(ognlContext, root, () -> (T) Ognl.getValue(tree, ognlContext, root, resultType)); } @@ -548,8 +548,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; @@ -654,7 +654,7 @@ 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 sourceMap = createDefaultContext(source); PropertyDescriptor[] propertyDescriptors = getPropertyDescriptors(source); for (PropertyDescriptor propertyDescriptor : propertyDescriptors) { final String propertyName = propertyDescriptor.getDisplayName(); @@ -724,18 +724,21 @@ public class OgnlUtil { } } - protected OgnlContext createDefaultContext(Object root) { + protected StrutsContext createDefaultContext(Object root) { return createDefaultContext(root, null); } - protected OgnlContext createDefaultContext(Object root, ClassResolver resolver) { + protected StrutsContext createDefaultContext(Object root, ClassResolver<StrutsContext> 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); + StrutsContext context = new StrutsContext( + container.getInstance(SecurityMemberAccess.class), resolver, defaultConverter); + context.withRoot(root); + return context; } @FunctionalInterface @@ -762,13 +765,13 @@ public class OgnlUtil { * @param action the action to execute * @throws OgnlException if the action throws an OgnlException */ - private void withRoot(OgnlContext context, Object root, OgnlAction action) throws OgnlException { - Object oldRoot = Ognl.getRoot(context); + private void withRoot(StrutsContext context, Object root, OgnlAction action) throws OgnlException { + Object oldRoot = context.getRoot(); try { - Ognl.setRoot(context, root); + context.withRoot(root); action.run(); } finally { - Ognl.setRoot(context, oldRoot); + context.withRoot(oldRoot); } } @@ -783,13 +786,13 @@ public class OgnlUtil { * @return the result of the supplier * @throws OgnlException if the supplier throws an OgnlException */ - private <T> T withRoot(OgnlContext context, Object root, OgnlSupplier<T> supplier) throws OgnlException { - Object oldRoot = Ognl.getRoot(context); + private <T> T withRoot(StrutsContext context, Object root, OgnlSupplier<T> supplier) throws OgnlException { + Object oldRoot = context.getRoot(); try { - Ognl.setRoot(context, root); + context.withRoot(root); return supplier.get(); } finally { - Ognl.setRoot(context, oldRoot); + context.withRoot(oldRoot); } } } 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 2376a418f..fc8a9d33f 100644 --- a/core/src/main/java/org/apache/struts2/ognl/OgnlValueStack.java +++ b/core/src/main/java/org/apache/struts2/ognl/OgnlValueStack.java @@ -31,8 +31,6 @@ import org.apache.struts2.util.ValueStack; import org.apache.struts2.util.reflection.ReflectionContextState; import ognl.MethodFailedException; import ognl.NoSuchPropertyException; -import ognl.Ognl; -import ognl.OgnlContext; import ognl.OgnlException; import org.apache.commons.lang3.BooleanUtils; import org.apache.logging.log4j.LogManager; @@ -68,7 +66,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,12 +119,12 @@ public class OgnlValueStack implements Serializable, ValueStack, ClearableValueS protected void setRoot(XWorkConverter xworkConverter, RootAccessor accessor, CompoundRoot compoundRoot, SecurityMemberAccess securityMemberAccess) { this.root = compoundRoot; this.securityMemberAccess = securityMemberAccess; - OgnlContext ognlContext = Ognl.createDefaultContext(this.root, securityMemberAccess, accessor, new OgnlTypeConverterWrapper(xworkConverter)); - this.context = ognlContext; + this.context = new StrutsContext(securityMemberAccess, accessor, new OgnlTypeConverterWrapper(xworkConverter)); + this.context.withRoot(this.root); this.converter = xworkConverter; context.put(VALUE_STACK, this); - ognlContext.setTraceEvaluations(false); - ognlContext.setKeepLastEvaluation(false); + context.setTraceEvaluations(false); + context.setKeepLastEvaluation(false); } @Inject(StrutsConstants.STRUTS_DEVMODE) @@ -508,9 +506,7 @@ public class OgnlValueStack implements Serializable, ValueStack, ClearableValueS @Override public void clearContextValues() { - //this is an OGNL ValueStack so the context will be an OgnlContext - //it would be better to make context of type OgnlContext - ((OgnlContext) context).getValues().clear(); + context.getValues().clear(); } @Override diff --git a/core/src/main/java/org/apache/struts2/ognl/OgnlValueStackFactory.java b/core/src/main/java/org/apache/struts2/ognl/OgnlValueStackFactory.java index ac60de0dc..eb9f39749 100644 --- a/core/src/main/java/org/apache/struts2/ognl/OgnlValueStackFactory.java +++ b/core/src/main/java/org/apache/struts2/ognl/OgnlValueStackFactory.java @@ -54,6 +54,7 @@ public class OgnlValueStackFactory implements ValueStackFactory { } @Inject + @SuppressWarnings({"rawtypes", "unchecked"}) protected void setCompoundRootAccessor(RootAccessor compoundRootAccessor) { this.compoundRootAccessor = compoundRootAccessor; OgnlRuntime.setPropertyAccessor(CompoundRoot.class, compoundRootAccessor); @@ -110,6 +111,7 @@ public class OgnlValueStackFactory implements ValueStackFactory { * {@link #setMethodAccessor} and can be configured using the extension point * {@link StrutsConstants#STRUTS_METHOD_ACCESSOR}. */ + @SuppressWarnings({"rawtypes", "unchecked"}) protected void registerAdditionalMethodAccessors() { Set<String> names = container.getInstanceNames(MethodAccessor.class); for (String name : names) { @@ -145,6 +147,7 @@ public class OgnlValueStackFactory implements ValueStackFactory { } } + @SuppressWarnings({"rawtypes", "unchecked"}) protected void registerPropertyAccessors() throws ClassNotFoundException { Set<String> names = container.getInstanceNames(PropertyAccessor.class); for (String name : names) { 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 4f0230426..3120588a6 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 @@ -52,22 +52,22 @@ public class ObjectProxyPropertyAccessor implements PropertyAccessor<StrutsConte } @Override - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "rawtypes"}) public Object getProperty(StrutsContext context, Object target, Object name) throws OgnlException { ObjectProxy proxy = (ObjectProxy) target; setupContext(context, proxy); - return OgnlRuntime.getPropertyAccessor(proxy.getValue().getClass()).getProperty(context, target, name); + return ((PropertyAccessor) OgnlRuntime.getPropertyAccessor(proxy.getValue().getClass())).getProperty(context, target, name); } @Override - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "rawtypes"}) public void setProperty(StrutsContext context, Object target, Object name, Object value) throws OgnlException { ObjectProxy proxy = (ObjectProxy) target; setupContext(context, proxy); - OgnlRuntime.getPropertyAccessor(proxy.getValue().getClass()).setProperty(context, target, name, value); + ((PropertyAccessor) OgnlRuntime.getPropertyAccessor(proxy.getValue().getClass())).setProperty(context, target, name, value); } /**
