diff --git a/core/src/main/java/com/opensymphony/xwork2/ActionContext.java b/core/src/main/java/com/opensymphony/xwork2/ActionContext.java index 34198d1fa..f5a020c0e 100644 --- a/core/src/main/java/com/opensymphony/xwork2/ActionContext.java +++ b/core/src/main/java/com/opensymphony/xwork2/ActionContext.java @@ -83,11 +83,6 @@ public class ActionContext implements Serializable { */ public static final String LOCALE = "com.opensymphony.xwork2.ActionContext.locale"; - /** - * Constant for the action's type converter. - */ - public static final String TYPE_CONVERTER = "com.opensymphony.xwork2.ActionContext.typeConverter"; - /** * Constant for the action's {@link com.opensymphony.xwork2.ActionInvocation invocation} context. */ @@ -170,22 +165,13 @@ public class ActionContext implements Serializable { return actionContext.get(); } - /** - * Sets the action's context map. - * - * @param contextMap the context map. - */ - public void setContextMap(Map contextMap) { - getContext().context = contextMap; - } - /** * Gets the context map. * * @return the context map. */ public Map getContextMap() { - return context; + return getContext().context; } /** diff --git a/core/src/main/java/com/opensymphony/xwork2/conversion/TypeConverter.java b/core/src/main/java/com/opensymphony/xwork2/conversion/TypeConverter.java index 19b262678..0bbad6c6a 100644 --- a/core/src/main/java/com/opensymphony/xwork2/conversion/TypeConverter.java +++ b/core/src/main/java/com/opensymphony/xwork2/conversion/TypeConverter.java @@ -23,30 +23,32 @@ import java.util.Map; /** * Interface for accessing the type conversion facilities within a context. - * + * * This interface was copied from OGNL's TypeConverter - * + * * @author Luke Blanshard (blanshlu@netscape.net) * @author Drew Davidson (drew@ognl.org) */ -public interface TypeConverter -{ +public interface TypeConverter { /** - * Converts the given value to a given type. The OGNL context, target, member and - * name of property being set are given. This method should be able to handle - * conversion in general without any context, target, member or property name specified. - * @param context context under which the conversion is being done - * @param target target object in which the property is being set - * @param member member (Constructor, Method or Field) being set - * @param propertyName property name being set - * @param value value to be converted - * @param toType type to which value is converted - * @return Converted value of type toType or TypeConverter.NoConversionPossible to indicate that the - conversion was not possible. + * Converts the given value to a given type. The OGNL context, target, member and + * name of property being set are given. This method should be able to handle + * conversion in general without any context, target, member or property name specified. + * + * @param context context under which the conversion is being done + * @param target target object in which the property is being set + * @param member member (Constructor, Method or Field) being set + * @param propertyName property name being set + * @param value value to be converted + * @param toType type to which value is converted + * @return Converted value of type toType or TypeConverter.NoConversionPossible to indicate that the + * conversion was not possible. */ - public Object convertValue(Map context, Object target, Member member, String propertyName, Object value, Class toType); - - public static final Object NO_CONVERSION_POSSIBLE = "ognl.NoConversionPossible"; - - public static final String TYPE_CONVERTER_CONTEXT_KEY = "_typeConverter"; -} \ No newline at end of file + Object convertValue(Map context, Object target, Member member, String propertyName, Object value, Class toType); + + Object NO_CONVERSION_POSSIBLE = "ognl.NoConversionPossible"; + + @Deprecated + String TYPE_CONVERTER_CONTEXT_KEY = "_typeConverter"; + +} diff --git a/core/src/main/java/com/opensymphony/xwork2/conversion/impl/DefaultTypeConverter.java b/core/src/main/java/com/opensymphony/xwork2/conversion/impl/DefaultTypeConverter.java index 15ecbcf7b..e8fdb2c00 100644 --- a/core/src/main/java/com/opensymphony/xwork2/conversion/impl/DefaultTypeConverter.java +++ b/core/src/main/java/com/opensymphony/xwork2/conversion/impl/DefaultTypeConverter.java @@ -19,12 +19,12 @@ package com.opensymphony.xwork2.conversion.impl; import com.opensymphony.xwork2.ActionContext; -import com.opensymphony.xwork2.LocaleProvider; import com.opensymphony.xwork2.LocaleProviderFactory; import com.opensymphony.xwork2.conversion.TypeConverter; import com.opensymphony.xwork2.inject.Container; import com.opensymphony.xwork2.inject.Inject; import com.opensymphony.xwork2.ognl.XWorkTypeConverterWrapper; +import ognl.OgnlContext; import java.lang.reflect.Array; import java.lang.reflect.Member; @@ -81,17 +81,22 @@ public abstract class DefaultTypeConverter implements TypeConverter { return convertValue(context, value, toType); } - public TypeConverter getTypeConverter( Map context ) - { - Object obj = context.get(TypeConverter.TYPE_CONVERTER_CONTEXT_KEY); - if (obj instanceof TypeConverter) { - return (TypeConverter) obj; - - // for backwards-compatibility - } else if (obj instanceof ognl.TypeConverter) { - return new XWorkTypeConverterWrapper((ognl.TypeConverter) obj); + public TypeConverter getTypeConverter( Map context ) { + ognl.TypeConverter converter = null; + + if (context instanceof OgnlContext) { + converter = ((OgnlContext) context).getTypeConverter(); } - return null; + + if (converter != null) { + if (converter instanceof TypeConverter) { + return (TypeConverter) converter; + } else { + return new XWorkTypeConverterWrapper(converter); + } + } + + return null; } /** diff --git a/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlUtil.java b/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlUtil.java index 0f2d78e5f..0982936dc 100644 --- a/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlUtil.java +++ b/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlUtil.java @@ -184,8 +184,6 @@ public class OgnlUtil { return; } - Ognl.setTypeConverter(context, getTypeConverterFromContext(context)); - Object oldRoot = Ognl.getRoot(context); Ognl.setRoot(context, o); @@ -245,7 +243,6 @@ public class OgnlUtil { * problems setting the property */ public void setProperty(String name, Object value, Object o, Map context, boolean throwPropertyExceptions) { - Ognl.setTypeConverter(context, getTypeConverterFromContext(context)); Object oldRoot = Ognl.getRoot(context); Ognl.setRoot(context, o); @@ -487,11 +484,8 @@ public class OgnlUtil { return; } - TypeConverter converter = getTypeConverterFromContext(context); final Map contextFrom = createDefaultContext(from, null); - Ognl.setTypeConverter(contextFrom, converter); final Map contextTo = createDefaultContext(to, null); - Ognl.setTypeConverter(contextTo, converter); PropertyDescriptor[] fromPds; PropertyDescriptor[] toPds; @@ -667,18 +661,6 @@ public class OgnlUtil { } } - TypeConverter getTypeConverterFromContext(Map context) { - /*ValueStack stack = (ValueStack) context.get(ActionContext.VALUE_STACK); - Container cont = (Container)stack.getContext().get(ActionContext.CONTAINER); - if (cont != null) { - return new OgnlTypeConverterWrapper(cont.getInstance(XWorkConverter.class)); - } else { - throw new IllegalArgumentException("Cannot find type converter in context map"); - } - */ - return defaultConverter; - } - protected Map createDefaultContext(Object root) { return createDefaultContext(root, null); } @@ -695,7 +677,7 @@ public class OgnlUtil { memberAccess.setExcludedPackageNames(excludedPackageNames); memberAccess.setDisallowProxyMemberAccess(disallowProxyMemberAccess); - return Ognl.createDefaultContext(root, resolver, defaultConverter, memberAccess); + return Ognl.createDefaultContext(root, memberAccess, resolver, defaultConverter); } private interface OgnlTask { diff --git a/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlValueStack.java b/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlValueStack.java index ab580691b..07464e04d 100644 --- a/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlValueStack.java +++ b/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlValueStack.java @@ -94,9 +94,8 @@ public class OgnlValueStack implements Serializable, ValueStack, ClearableValueS boolean allowStaticMethodAccess) { this.root = compoundRoot; this.securityMemberAccess = new SecurityMemberAccess(allowStaticMethodAccess); - this.context = Ognl.createDefaultContext(this.root, accessor, new OgnlTypeConverterWrapper(xworkConverter), securityMemberAccess); + this.context = Ognl.createDefaultContext(this.root, securityMemberAccess, accessor, new OgnlTypeConverterWrapper(xworkConverter)); context.put(VALUE_STACK, this); - Ognl.setClassResolver(context, accessor); ((OgnlContext) context).setTraceEvaluations(false); ((OgnlContext) context).setKeepLastEvaluation(false); } diff --git a/core/src/main/java/com/opensymphony/xwork2/ognl/SecurityMemberAccess.java b/core/src/main/java/com/opensymphony/xwork2/ognl/SecurityMemberAccess.java index 905ef775c..05db70fc9 100644 --- a/core/src/main/java/com/opensymphony/xwork2/ognl/SecurityMemberAccess.java +++ b/core/src/main/java/com/opensymphony/xwork2/ognl/SecurityMemberAccess.java @@ -19,11 +19,13 @@ package com.opensymphony.xwork2.ognl; import com.opensymphony.xwork2.util.ProxyUtil; -import ognl.DefaultMemberAccess; +import ognl.MemberAccess; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import java.lang.reflect.*; +import java.lang.reflect.AccessibleObject; +import java.lang.reflect.Member; +import java.lang.reflect.Modifier; import java.util.Collections; import java.util.Map; import java.util.Set; @@ -34,7 +36,7 @@ import java.util.regex.Pattern; * 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 extends DefaultMemberAccess { +public class SecurityMemberAccess implements MemberAccess { private static final Logger LOG = LogManager.getLogger(SecurityMemberAccess.class); @@ -47,7 +49,6 @@ public class SecurityMemberAccess extends DefaultMemberAccess { private boolean disallowProxyMemberAccess; public SecurityMemberAccess(boolean method) { - super(false); allowStaticMethodAccess = method; } @@ -55,6 +56,28 @@ public class SecurityMemberAccess extends DefaultMemberAccess { return allowStaticMethodAccess; } + @Override + public Object setup(Map context, Object target, Member member, String propertyName) { + Object result = null; + + if (isAccessible(context, target, member, propertyName)) { + AccessibleObject accessible = (AccessibleObject) member; + + if (!accessible.isAccessible()) { + result = Boolean.FALSE; + accessible.setAccessible(true); + } + } + return result; + } + + @Override + public void restore(Map context, Object target, Member member, String propertyName, Object state) { + if (state != null) { + ((AccessibleObject) member).setAccessible((Boolean) state); + } + } + @Override public boolean isAccessible(Map context, Object target, Member member, String propertyName) { LOG.debug("Checking access for [target: {}, member: {}, property: {}]", target, member, propertyName); @@ -105,8 +128,7 @@ public class SecurityMemberAccess extends DefaultMemberAccess { return false; } - // Now check for standard scope rules - return super.isAccessible(context, target, member, propertyName) && isAcceptableProperty(propertyName); + return Modifier.isPublic(member.getModifiers()) && isAcceptableProperty(propertyName); } protected boolean checkStaticMethodAccess(Member member) { @@ -132,7 +154,7 @@ public class SecurityMemberAccess extends DefaultMemberAccess { if (targetPackage == null || memberPackage == null) { LOG.warn("The use of the default (unnamed) package is discouraged!"); } - + final String targetPackageName = targetPackage == null ? "" : targetPackage.getName(); final String memberPackageName = memberPackage == null ? "" : memberPackage.getName(); @@ -142,7 +164,7 @@ public class SecurityMemberAccess extends DefaultMemberAccess { } } - for (String packageName: excludedPackageNames) { + for (String packageName : excludedPackageNames) { if (targetPackageName.startsWith(packageName) || targetPackageName.equals(packageName) || memberPackageName.startsWith(packageName) || memberPackageName.equals(packageName)) { return true; diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/OgnlTool.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/OgnlTool.java index 952575503..9f6e8513a 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/OgnlTool.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/OgnlTool.java @@ -18,7 +18,7 @@ */ package org.apache.struts2.views.jsp.ui; -import ognl.Ognl; +import com.opensymphony.xwork2.ActionContext; import ognl.OgnlException; import com.opensymphony.xwork2.inject.Inject; @@ -30,18 +30,18 @@ import com.opensymphony.xwork2.ognl.OgnlUtil; public class OgnlTool { private OgnlUtil ognlUtil; - + public OgnlTool() { } - + @Inject public void setOgnlUtil(OgnlUtil ognlUtil) { this.ognlUtil = ognlUtil; } - + public Object findValue(String expr, Object context) { try { - return Ognl.getValue(ognlUtil.compile(expr), context); + return ognlUtil.getValue(expr, ActionContext.getContext().getContextMap(), context); } catch (OgnlException e) { return null; } diff --git a/core/src/main/resources/struts-default.xml b/core/src/main/resources/struts-default.xml index 27462a1e4..204c5f1c0 100644 --- a/core/src/main/resources/struts-default.xml +++ b/core/src/main/resources/struts-default.xml @@ -49,7 +49,6 @@ ognl.ClassResolver, ognl.TypeConverter, ognl.MemberAccess, - ognl.DefaultMemberAccess, com.opensymphony.xwork2.ognl.SecurityMemberAccess, com.opensymphony.xwork2.ActionContext" /> diff --git a/core/src/test/java/com/opensymphony/xwork2/ActionContextTest.java b/core/src/test/java/com/opensymphony/xwork2/ActionContextTest.java index ed8f39b31..05fcc3540 100644 --- a/core/src/test/java/com/opensymphony/xwork2/ActionContextTest.java +++ b/core/src/test/java/com/opensymphony/xwork2/ActionContextTest.java @@ -88,8 +88,9 @@ public class ActionContextTest extends XWorkTestCase { public void testContextMap() { Map map = new HashMap<>(); - context.setContextMap(map); - assertEquals(map, context.getContextMap()); + ActionContext.setContext(new ActionContext(map)); + + assertEquals(map, ActionContext.getContext().getContextMap()); } public void testParameters() { diff --git a/core/src/test/java/com/opensymphony/xwork2/DefaultActionInvocationTest.java b/core/src/test/java/com/opensymphony/xwork2/DefaultActionInvocationTest.java index 91b6b11b9..fc5e2c2a9 100644 --- a/core/src/test/java/com/opensymphony/xwork2/DefaultActionInvocationTest.java +++ b/core/src/test/java/com/opensymphony/xwork2/DefaultActionInvocationTest.java @@ -91,11 +91,8 @@ public class DefaultActionInvocationTest extends XWorkTestCase { public void testInvokingExistingExecuteMethod() throws Exception { // given - DefaultActionInvocation dai = new DefaultActionInvocation(new HashMap(), false) { - public ValueStack getStack() { - return new StubValueStack(); - } - }; + DefaultActionInvocation dai = new DefaultActionInvocation(ActionContext.getContext().getContextMap(), false); + container.inject(dai); SimpleAction action = new SimpleAction() { @Override @@ -106,6 +103,7 @@ public class DefaultActionInvocationTest extends XWorkTestCase { MockActionProxy proxy = new MockActionProxy(); proxy.setMethod("execute"); + dai.stack = container.getInstance(ValueStackFactory.class).createValueStack(); dai.proxy = proxy; dai.ognlUtil = new OgnlUtil(); @@ -118,11 +116,8 @@ public class DefaultActionInvocationTest extends XWorkTestCase { public void testInvokingMissingMethod() throws Exception { // given - DefaultActionInvocation dai = new DefaultActionInvocation(new HashMap(), false) { - public ValueStack getStack() { - return new StubValueStack(); - } - }; + DefaultActionInvocation dai = new DefaultActionInvocation(ActionContext.getContext().getContextMap(), false); + container.inject(dai); SimpleAction action = new SimpleAction() { @Override @@ -140,6 +135,7 @@ public class DefaultActionInvocationTest extends XWorkTestCase { } }; + dai.stack = container.getInstance(ValueStackFactory.class).createValueStack(); dai.proxy = proxy; dai.ognlUtil = new OgnlUtil(); dai.unknownHandlerManager = uhm; @@ -159,11 +155,8 @@ public class DefaultActionInvocationTest extends XWorkTestCase { public void testInvokingExistingMethodThatThrowsException() throws Exception { // given - DefaultActionInvocation dai = new DefaultActionInvocation(new HashMap(), false) { - public ValueStack getStack() { - return new StubValueStack(); - } - }; + DefaultActionInvocation dai = new DefaultActionInvocation(ActionContext.getContext().getContextMap(), false); + container.inject(dai); SimpleAction action = new SimpleAction() { @Override @@ -174,6 +167,7 @@ public class DefaultActionInvocationTest extends XWorkTestCase { MockActionProxy proxy = new MockActionProxy(); proxy.setMethod("execute"); + dai.stack = container.getInstance(ValueStackFactory.class).createValueStack(); dai.proxy = proxy; dai.ognlUtil = new OgnlUtil(); @@ -192,11 +186,8 @@ public class DefaultActionInvocationTest extends XWorkTestCase { public void testUnknownHandlerManagerThatThrowsException() throws Exception { // given - DefaultActionInvocation dai = new DefaultActionInvocation(new HashMap(), false) { - public ValueStack getStack() { - return new StubValueStack(); - } - }; + DefaultActionInvocation dai = new DefaultActionInvocation(ActionContext.getContext().getContextMap(), false); + container.inject(dai); UnknownHandlerManager uhm = new DefaultUnknownHandlerManager() { @Override @@ -213,6 +204,7 @@ public class DefaultActionInvocationTest extends XWorkTestCase { MockActionProxy proxy = new MockActionProxy(); proxy.setMethod("notExists"); + dai.stack = container.getInstance(ValueStackFactory.class).createValueStack(); dai.proxy = proxy; dai.ognlUtil = new OgnlUtil(); dai.unknownHandlerManager = uhm; @@ -233,11 +225,8 @@ public class DefaultActionInvocationTest extends XWorkTestCase { public void testUnknownHandlerManagerThatReturnsNull() throws Exception { // given - DefaultActionInvocation dai = new DefaultActionInvocation(new HashMap(), false) { - public ValueStack getStack() { - return new StubValueStack(); - } - }; + DefaultActionInvocation dai = new DefaultActionInvocation(ActionContext.getContext().getContextMap(), false); + container.inject(dai); UnknownHandlerManager uhm = new DefaultUnknownHandlerManager() { @Override @@ -254,6 +243,7 @@ public class DefaultActionInvocationTest extends XWorkTestCase { MockActionProxy proxy = new MockActionProxy(); proxy.setMethod("notExists"); + dai.stack = container.getInstance(ValueStackFactory.class).createValueStack(); dai.proxy = proxy; dai.ognlUtil = new OgnlUtil(); dai.unknownHandlerManager = uhm; @@ -273,11 +263,8 @@ public class DefaultActionInvocationTest extends XWorkTestCase { public void testUnknownHandlerManagerThatReturnsSuccess() throws Exception { // given - DefaultActionInvocation dai = new DefaultActionInvocation(new HashMap(), false) { - public ValueStack getStack() { - return new StubValueStack(); - } - }; + DefaultActionInvocation dai = new DefaultActionInvocation(ActionContext.getContext().getContextMap(), false); + container.inject(dai); UnknownHandlerManager uhm = new DefaultUnknownHandlerManager() { @Override @@ -294,6 +281,7 @@ public class DefaultActionInvocationTest extends XWorkTestCase { MockActionProxy proxy = new MockActionProxy(); proxy.setMethod("notExists"); + dai.stack = container.getInstance(ValueStackFactory.class).createValueStack(); dai.proxy = proxy; dai.ognlUtil = new OgnlUtil(); dai.unknownHandlerManager = uhm; diff --git a/core/src/test/java/com/opensymphony/xwork2/conversion/impl/AnnotationXWorkConverterTest.java b/core/src/test/java/com/opensymphony/xwork2/conversion/impl/AnnotationXWorkConverterTest.java index d75c6dd5b..0d7bbcd3e 100644 --- a/core/src/test/java/com/opensymphony/xwork2/conversion/impl/AnnotationXWorkConverterTest.java +++ b/core/src/test/java/com/opensymphony/xwork2/conversion/impl/AnnotationXWorkConverterTest.java @@ -24,6 +24,7 @@ import com.opensymphony.xwork2.test.ModelDrivenAnnotationAction2; import com.opensymphony.xwork2.util.Bar; import com.opensymphony.xwork2.util.ValueStack; import com.opensymphony.xwork2.util.reflection.ReflectionContextState; +import ognl.Ognl; import ognl.OgnlException; import ognl.OgnlRuntime; diff --git a/core/src/test/java/com/opensymphony/xwork2/ognl/OgnlUtilTest.java b/core/src/test/java/com/opensymphony/xwork2/ognl/OgnlUtilTest.java index 741a39678..dec0cc0ff 100644 --- a/core/src/test/java/com/opensymphony/xwork2/ognl/OgnlUtilTest.java +++ b/core/src/test/java/com/opensymphony/xwork2/ognl/OgnlUtilTest.java @@ -803,6 +803,24 @@ public class OgnlUtilTest extends XWorkTestCase { assertEquals(expected.getMessage(), "It isn't a simple method which can be called!"); } + public void testAccessContext() throws Exception { + Map context = ognlUtil.createDefaultContext(null); + + Foo foo = new Foo(); + + Object result = ognlUtil.getValue("#context", context, null); + Object root = ognlUtil.getValue("#root", context, foo); + Object that = ognlUtil.getValue("#this", context, foo); + + assertNotSame(context, result); + assertNull(result); + assertNotNull(root); + assertSame(root.getClass(), Foo.class); + assertNotNull(that); + assertSame(that.getClass(), Foo.class); + assertSame(that, root); + } + public static class Email { String address; diff --git a/core/src/test/java/com/opensymphony/xwork2/ognl/SetPropertiesTest.java b/core/src/test/java/com/opensymphony/xwork2/ognl/SetPropertiesTest.java index e9d8b9aa3..84e4de658 100644 --- a/core/src/test/java/com/opensymphony/xwork2/ognl/SetPropertiesTest.java +++ b/core/src/test/java/com/opensymphony/xwork2/ognl/SetPropertiesTest.java @@ -57,7 +57,7 @@ public class SetPropertiesTest extends XWorkTestCase { } public void testOgnlUtilEmptyStringAsLong() { Bar bar = new Bar(); - Map context = Ognl.createDefaultContext(bar); + Map context = Ognl.createDefaultContext(bar, new SecurityMemberAccess(false)); context.put(XWorkConverter.REPORT_CONVERSION_ERRORS, Boolean.TRUE); bar.setId(null); diff --git a/core/src/test/java/org/apache/struts2/factory/StrutsResultFactoryTest.java b/core/src/test/java/org/apache/struts2/factory/StrutsResultFactoryTest.java index 694f32cb1..37f43c5e1 100644 --- a/core/src/test/java/org/apache/struts2/factory/StrutsResultFactoryTest.java +++ b/core/src/test/java/org/apache/struts2/factory/StrutsResultFactoryTest.java @@ -18,6 +18,7 @@ */ package org.apache.struts2.factory; +import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.Result; import com.opensymphony.xwork2.config.entities.ResultConfig; @@ -39,10 +40,9 @@ public class StrutsResultFactoryTest extends StrutsInternalTestCase { params.put("accept", "ok"); params.put("reject", "bad"); ResultConfig config = new ResultConfig.Builder("struts", MyResult.class.getName()).addParams(params).build(); - Map context = new HashMap(); // when - Result result = builder.buildResult(config, context); + Result result = builder.buildResult(config, ActionContext.getContext().getContextMap()); // then assertEquals("ok", ((MyResult)result).getAccept()); diff --git a/core/src/test/java/org/apache/struts2/result/ServletActionRedirectResultTest.java b/core/src/test/java/org/apache/struts2/result/ServletActionRedirectResultTest.java index b7ed61c41..e0c955b40 100644 --- a/core/src/test/java/org/apache/struts2/result/ServletActionRedirectResultTest.java +++ b/core/src/test/java/org/apache/struts2/result/ServletActionRedirectResultTest.java @@ -179,7 +179,7 @@ public class ServletActionRedirectResultTest extends StrutsInternalTestCase { .build(); ObjectFactory factory = container.getInstance(ObjectFactory.class); - ServletActionRedirectResult result = (ServletActionRedirectResult) factory.buildResult(resultConfig, new HashMap()); + ServletActionRedirectResult result = (ServletActionRedirectResult) factory.buildResult(resultConfig, ActionContext.getContext().getContextMap()); assertNotNull(result); } diff --git a/core/src/test/java/org/apache/struts2/result/ServletDispatcherResultTest.java b/core/src/test/java/org/apache/struts2/result/ServletDispatcherResultTest.java index 7578f54d0..4a90ae443 100644 --- a/core/src/test/java/org/apache/struts2/result/ServletDispatcherResultTest.java +++ b/core/src/test/java/org/apache/struts2/result/ServletDispatcherResultTest.java @@ -57,8 +57,6 @@ public class ServletDispatcherResultTest extends StrutsInternalTestCase implemen Mock responseMock = new Mock(HttpServletResponse.class); responseMock.expectAndReturn("isCommitted", Boolean.TRUE); - ActionContext ac = new ActionContext(Ognl.createDefaultContext(null)); - ActionContext.setContext(ac); ServletActionContext.setRequest((HttpServletRequest) requestMock.proxy()); ServletActionContext.setResponse((HttpServletResponse) responseMock.proxy()); @@ -92,8 +90,6 @@ public class ServletDispatcherResultTest extends StrutsInternalTestCase implemen Mock responseMock = new Mock(HttpServletResponse.class); responseMock.expectAndReturn("isCommitted", Boolean.FALSE); - ActionContext ac = new ActionContext(Ognl.createDefaultContext(null)); - ActionContext.setContext(ac); ServletActionContext.setRequest((HttpServletRequest) requestMock.proxy()); ServletActionContext.setResponse((HttpServletResponse) responseMock.proxy()); @@ -127,14 +123,11 @@ public class ServletDispatcherResultTest extends StrutsInternalTestCase implemen Mock responseMock = new Mock(HttpServletResponse.class); responseMock.expectAndReturn("isCommitted", Boolean.FALSE); - ActionContext ac = new ActionContext(Ognl.createDefaultContext(null)); - ac.setContainer(container); - ActionContext.setContext(ac); ServletActionContext.setRequest((HttpServletRequest) requestMock.proxy()); ServletActionContext.setResponse((HttpServletResponse) responseMock.proxy()); MockActionInvocation mockActionInvocation = new MockActionInvocation(); - mockActionInvocation.setInvocationContext(ac); + mockActionInvocation.setInvocationContext(ActionContext.getContext()); mockActionInvocation.setStack(container.getInstance(ValueStackFactory.class).createValueStack()); try { diff --git a/core/src/test/java/org/apache/struts2/result/ServletRedirectResultTest.java b/core/src/test/java/org/apache/struts2/result/ServletRedirectResultTest.java index b17907f04..aa15c3e0b 100644 --- a/core/src/test/java/org/apache/struts2/result/ServletRedirectResultTest.java +++ b/core/src/test/java/org/apache/struts2/result/ServletRedirectResultTest.java @@ -34,6 +34,7 @@ import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import com.opensymphony.xwork2.ognl.SecurityMemberAccess; import ognl.Ognl; import org.apache.struts2.ServletActionContext; @@ -342,7 +343,7 @@ public class ServletRedirectResultTest extends StrutsInternalTestCase implements ActionConfig actionConfig = new ActionConfig.Builder("", "", "") .addResultConfigs(results).build(); - ActionContext ac = new ActionContext(Ognl.createDefaultContext(null)); + ActionContext ac = new ActionContext(Ognl.createDefaultContext(null, new SecurityMemberAccess(false))); ac.put(ServletActionContext.HTTP_REQUEST, requestMock.proxy()); ac.put(ServletActionContext.HTTP_RESPONSE, responseMock.proxy()); MockActionInvocation ai = new MockActionInvocation(); diff --git a/plugins/oval/src/main/java/org/apache/struts2/oval/interceptor/OValValidationInterceptor.java b/plugins/oval/src/main/java/org/apache/struts2/oval/interceptor/OValValidationInterceptor.java index bf660c25b..f7d7aa24f 100644 --- a/plugins/oval/src/main/java/org/apache/struts2/oval/interceptor/OValValidationInterceptor.java +++ b/plugins/oval/src/main/java/org/apache/struts2/oval/interceptor/OValValidationInterceptor.java @@ -18,6 +18,7 @@ */ package org.apache.struts2.oval.interceptor; +import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.ActionProxy; import com.opensymphony.xwork2.ModelDriven; @@ -27,6 +28,11 @@ import com.opensymphony.xwork2.inject.Inject; import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor; import com.opensymphony.xwork2.interceptor.PrefixMethodInvocationUtil; import com.opensymphony.xwork2.util.ValueStack; +import net.sf.oval.exception.ExpressionEvaluationException; +import net.sf.oval.expression.ExpressionLanguage; +import net.sf.oval.expression.ExpressionLanguageOGNLImpl; +import ognl.Ognl; +import ognl.OgnlException; import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.LogManager; import com.opensymphony.xwork2.validator.DelegatingValidatorContext; @@ -43,6 +49,7 @@ import org.apache.struts2.oval.annotation.Profiles; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.List; +import java.util.Map; /* This interceptor provides validation using the OVal validation framework @@ -59,6 +66,12 @@ public class OValValidationInterceptor extends MethodFilterInterceptor { protected boolean validateJPAAnnotations; protected TextProviderFactory textProviderFactory; + private ExpressionLanguage ognlExpressionLanguage; + + public OValValidationInterceptor() { + ognlExpressionLanguage = new ExpressionLanguageOGNL(); + } + @Inject public void setValidationManager(OValValidationManager validationManager) { this.validationManager = validationManager; @@ -153,6 +166,7 @@ public class OValValidationInterceptor extends MethodFilterInterceptor { List configurers = validationManager.getConfigurers(clazz, context, validateJPAAnnotations); Validator validator = configurers.isEmpty() ? new Validator() : new Validator(configurers); + validator.addExpressionLanguage("ognl", ognlExpressionLanguage); //if the method is annotated with a @Profiles annotation, use those profiles Method method = clazz.getMethod(methodName, new Class[0]); if (method != null) { @@ -284,4 +298,20 @@ public class OValValidationInterceptor extends MethodFilterInterceptor { return message; } } + } + +class ExpressionLanguageOGNL extends ExpressionLanguageOGNLImpl { + + private static final Logger LOG = LogManager.getLogger(ExpressionLanguageOGNL.class); + + public Object evaluate(final String expression, final Map values) throws ExpressionEvaluationException { + try { + LOG.debug("Evaluating OGNL expression: {1}", expression); + return Ognl.getValue(expression, ActionContext.getContext().getContextMap(), values); + } catch (final OgnlException ex) { + throw new ExpressionEvaluationException("Evaluating script with OGNL failed.", ex); + } + } +} + diff --git a/pom.xml b/pom.xml index e66c475cd..60e630997 100644 --- a/pom.xml +++ b/pom.xml @@ -98,7 +98,7 @@ UTF-8 4.3.13.RELEASE - 3.1.15 + 3.2.5 5.2 3.0.7 1.0.6 @@ -1072,7 +1072,7 @@ jackson-dataformat-xml ${jackson.version} - + javax.enterprise