Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,9 @@
*/
package org.apache.struts2.ognl;

import ognl.OgnlContext;
import org.apache.struts2.conversion.NullHandler;

public class OgnlNullHandlerWrapper implements ognl.NullHandler {
public class OgnlNullHandlerWrapper implements ognl.NullHandler<StrutsContext> {

private final NullHandler wrapped;

Expand All @@ -30,13 +29,13 @@ public OgnlNullHandlerWrapper(NullHandler target) {
}

@Override
public Object nullMethodResult(OgnlContext context, Object target,
public Object nullMethodResult(StrutsContext context, Object target,
String methodName, Object[] args) {
return wrapped.nullMethodResult(context, target, methodName, args);
}

@Override
public Object nullPropertyValue(OgnlContext context, Object target, Object property) {
public Object nullPropertyValue(StrutsContext context, Object target, Object property) {
return wrapped.nullPropertyValue(context, target, property);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
public class OgnlReflectionContextFactory implements ReflectionContextFactory {

@Override
@SuppressWarnings({"rawtypes", "unchecked"})
public OgnlContext createDefaultContext(Object root) {
return Ognl.createDefaultContext(root);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,14 @@
*/
package org.apache.struts2.ognl;

import ognl.OgnlContext;
import org.apache.struts2.conversion.TypeConverter;

import java.lang.reflect.Member;

/**
* Wraps an XWork type conversion class for as an OGNL TypeConverter
*/
public class OgnlTypeConverterWrapper implements ognl.TypeConverter {
public class OgnlTypeConverterWrapper implements ognl.TypeConverter<StrutsContext> {

private final TypeConverter typeConverter;

Expand All @@ -38,7 +37,7 @@ public OgnlTypeConverterWrapper(TypeConverter converter) {
}

@Override
public Object convertValue(OgnlContext context, Object target, Member member, String propertyName, Object value, Class<?> toType) {
public Object convertValue(StrutsContext context, Object target, Member member, String propertyName, Object value, Class<?> toType) {
return typeConverter.convertValue(context, target, member, propertyName, value, toType);
}

Expand Down
59 changes: 31 additions & 28 deletions core/src/main/java/org/apache/struts2/ognl/OgnlUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -211,14 +211,14 @@ public int beanInfoCacheSize() {
* @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;
}

/**
Expand Down Expand Up @@ -247,9 +247,9 @@ public void setProperties(Map<String, ?> props, Object o, Map<String, Object> co
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);
Expand Down Expand Up @@ -309,9 +309,9 @@ public void setProperty(String name, Object value, Object o, Map<String, Object>
* 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);
Expand Down Expand Up @@ -424,7 +424,7 @@ private void ognlSet(String expr, Map<String, Object> context, Object root, Obje
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));
}

Expand All @@ -434,7 +434,7 @@ private <T> T ognlGet(String expr, Map<String, Object> context, Object root, Cla
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));
}

Expand Down Expand Up @@ -548,8 +548,8 @@ public void copy(final Object from,
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;
Expand Down Expand Up @@ -654,7 +654,7 @@ public PropertyDescriptor[] getPropertyDescriptors(Class<?> clazz) throws Intros
*/
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();
Expand Down Expand Up @@ -724,18 +724,21 @@ void internalSetProperty(String name, Object value, Object o, Map<String, Object
}
}

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
Expand All @@ -762,13 +765,13 @@ private interface OgnlSupplier<T> {
* @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);
}
}

Expand All @@ -783,13 +786,13 @@ private void withRoot(OgnlContext context, Object root, OgnlAction action) throw
* @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);
}
}
}
16 changes: 6 additions & 10 deletions core/src/main/java/org/apache/struts2/ognl/OgnlValueStack.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@
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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -121,12 +119,12 @@ protected void setOgnlUtil(OgnlUtil ognlUtil) {
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)
Expand Down Expand Up @@ -508,9 +506,7 @@ private Object readResolve() {

@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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ protected void setXWorkConverter(XWorkConverter converter) {
}

@Inject
@SuppressWarnings({"rawtypes", "unchecked"})
protected void setCompoundRootAccessor(RootAccessor compoundRootAccessor) {
this.compoundRootAccessor = compoundRootAccessor;
OgnlRuntime.setPropertyAccessor(CompoundRoot.class, compoundRootAccessor);
Expand Down Expand Up @@ -110,6 +111,7 @@ protected void setContainer(Container container) throws ClassNotFoundException {
* {@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) {
Expand Down Expand Up @@ -145,6 +147,7 @@ protected void registerNullHandlers() throws ClassNotFoundException {
}
}

@SuppressWarnings({"rawtypes", "unchecked"})
protected void registerPropertyAccessors() throws ClassNotFoundException {
Set<String> names = container.getInstanceNames(PropertyAccessor.class);
for (String name : names) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
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;
Expand Down Expand Up @@ -54,7 +53,7 @@
* Allows access decisions to be made on the basis of whether a member is static or not.
* Also blocks or allows access to properties.
*/
public class SecurityMemberAccess implements MemberAccess {
public class SecurityMemberAccess implements MemberAccess<StrutsContext> {

private static final Logger LOG = LogManager.getLogger(SecurityMemberAccess.class);

Expand Down Expand Up @@ -115,7 +114,7 @@ public void setProxyService(ProxyService proxyService) {
}

@Override
public Object setup(OgnlContext context, Object target, Member member, String propertyName) {
public Object setup(StrutsContext context, Object target, Member member, String propertyName) {
Object result = null;

if (isAccessible(context, target, member, propertyName)) {
Expand All @@ -130,7 +129,7 @@ public Object setup(OgnlContext context, Object target, Member member, String pr
}

@Override
public void restore(OgnlContext context, Object target, Member member, String propertyName, Object state) {
public void restore(StrutsContext context, Object target, Member member, String propertyName, Object state) {
if (state == null) {
return;
}
Expand All @@ -145,7 +144,7 @@ public void restore(OgnlContext context, Object target, Member member, String pr
}

@Override
public boolean isAccessible(OgnlContext context, Object target, Member member, String propertyName) {
public boolean isAccessible(StrutsContext context, Object target, Member member, String propertyName) {
LOG.debug("Checking access for [target: {}, member: {}, property: {}]", target, member, propertyName);

if (member == null) {
Expand Down
53 changes: 53 additions & 0 deletions core/src/main/java/org/apache/struts2/ognl/StrutsContext.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.struts2.ognl;

import ognl.ClassResolver;
import ognl.MemberAccess;
import ognl.OgnlContext;
import ognl.TypeConverter;

/**
* Struts-specific OGNL evaluation context. Extends {@link OgnlContext} with the
* self-bounded generic parameter to enable type-safe access in all OGNL interface
* implementations ({@link MemberAccess}, {@link ognl.PropertyAccessor}, etc.).
*
* <p>Phase 1: minimal subclass delegating to super constructors.
* Future phases will promote stringly-typed map entries (e.g. {@code DENY_METHOD_EXECUTION},
* {@code CREATE_NULL_OBJECTS}) to proper typed fields.</p>
*
* @since 7.2.0
*/
public class StrutsContext extends OgnlContext<StrutsContext> {

public StrutsContext(MemberAccess<StrutsContext> memberAccess) {
super(memberAccess);
}

public StrutsContext(MemberAccess<StrutsContext> memberAccess,
ClassResolver<StrutsContext> classResolver) {
super(memberAccess, classResolver);
}

public StrutsContext(MemberAccess<StrutsContext> memberAccess,
ClassResolver<StrutsContext> classResolver,
TypeConverter<StrutsContext> typeConverter) {
super(memberAccess, classResolver, typeConverter);
}
}
Loading
Loading