From 5cd409d382e00b190bfe4e957c4167d06b8f9da1 Mon Sep 17 00:00:00 2001 From: Lukasz Lenart Date: Mon, 22 May 2017 08:30:46 +0200 Subject: [PATCH] Uses OGNL 3.2.2 which always requires MemberAccess --- .../opensymphony/xwork2/ActionContext.java | 6 +++ .../opensymphony/xwork2/ognl/OgnlUtil.java | 2 +- .../xwork2/ognl/OgnlValueStack.java | 2 +- .../xwork2/ognl/SecurityMemberAccess.java | 38 +++++++++++--- .../apache/struts2/views/jsp/ui/OgnlTool.java | 10 ++-- core/src/main/resources/struts-default.xml | 1 - .../xwork2/DefaultActionInvocationTest.java | 48 +++++++----------- .../impl/AnnotationXWorkConverterTest.java | 1 + .../xwork2/ognl/SetPropertiesTest.java | 2 +- .../factory/StrutsResultFactoryTest.java | 4 +- .../ServletActionRedirectResultTest.java | 2 +- .../result/ServletDispatcherResultTest.java | 9 +--- .../result/ServletRedirectResultTest.java | 3 +- .../OValValidationInterceptor.java | 49 +++++++++++++++++++ 14 files changed, 118 insertions(+), 59 deletions(-) diff --git a/core/src/main/java/com/opensymphony/xwork2/ActionContext.java b/core/src/main/java/com/opensymphony/xwork2/ActionContext.java index 4e4367fcb..e2c8b8048 100644 --- a/core/src/main/java/com/opensymphony/xwork2/ActionContext.java +++ b/core/src/main/java/com/opensymphony/xwork2/ActionContext.java @@ -18,8 +18,10 @@ */ package com.opensymphony.xwork2; +import com.opensymphony.xwork2.conversion.TypeConverter; import com.opensymphony.xwork2.inject.Container; import com.opensymphony.xwork2.util.ValueStack; +import ognl.OgnlContext; import org.apache.struts2.dispatcher.HttpParameters; import java.io.Serializable; @@ -184,6 +186,10 @@ public class ActionContext implements Serializable { * @return the context map. */ public Map getContextMap() { + Map context = getContext().context; + if (context instanceof OgnlContext) { + ((OgnlContext) context).put(TypeConverter.TYPE_CONVERTER_CONTEXT_KEY, ((OgnlContext) context).getTypeConverter()); + } return context; } 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 17bbf9c1b..0982936dc 100644 --- a/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlUtil.java +++ b/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlUtil.java @@ -677,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 d766241e8..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,7 +94,7 @@ 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); ((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..092cb8aad 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.TRUE; + 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/DefaultActionInvocationTest.java b/core/src/test/java/com/opensymphony/xwork2/DefaultActionInvocationTest.java index 334839082..4e8eea573 100644 --- a/core/src/test/java/com/opensymphony/xwork2/DefaultActionInvocationTest.java +++ b/core/src/test/java/com/opensymphony/xwork2/DefaultActionInvocationTest.java @@ -105,11 +105,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 @@ -120,6 +117,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(); @@ -132,11 +130,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 @@ -154,6 +149,7 @@ public class DefaultActionInvocationTest extends XWorkTestCase { } }; + dai.stack = container.getInstance(ValueStackFactory.class).createValueStack(); dai.proxy = proxy; dai.ognlUtil = new OgnlUtil(); dai.unknownHandlerManager = uhm; @@ -173,11 +169,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 @@ -188,6 +181,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(); @@ -206,11 +200,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 @@ -227,6 +218,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; @@ -247,11 +239,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 @@ -268,6 +257,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; @@ -287,11 +277,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 @@ -308,6 +295,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 bca99e5c2..6d9398bbe 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/SetPropertiesTest.java b/core/src/test/java/com/opensymphony/xwork2/ognl/SetPropertiesTest.java index c19895ff7..68d792d8d 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..ccc2edf55 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 @@ -26,7 +26,13 @@ import com.opensymphony.xwork2.Validateable; import com.opensymphony.xwork2.inject.Inject; import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor; import com.opensymphony.xwork2.interceptor.PrefixMethodInvocationUtil; +import com.opensymphony.xwork2.ognl.OgnlUtil; +import com.opensymphony.xwork2.ognl.SecurityMemberAccess; 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.*; import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.LogManager; import com.opensymphony.xwork2.validator.DelegatingValidatorContext; @@ -43,6 +49,8 @@ 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; +import java.util.Objects; /* This interceptor provides validation using the OVal validation framework @@ -59,6 +67,8 @@ public class OValValidationInterceptor extends MethodFilterInterceptor { protected boolean validateJPAAnnotations; protected TextProviderFactory textProviderFactory; + private ExpressionLanguage ognlExpressionLanguage; + @Inject public void setValidationManager(OValValidationManager validationManager) { this.validationManager = validationManager; @@ -77,6 +87,16 @@ public class OValValidationInterceptor extends MethodFilterInterceptor { this.validateJPAAnnotations = Boolean.parseBoolean(validateJPAAnnotations); } + @Inject + public void setOgnlUtil(OgnlUtil ognlUtil) { + SecurityMemberAccess securityMemberAccess = new SecurityMemberAccess(false); + securityMemberAccess.setExcludedClasses(ognlUtil.getExcludedClasses()); + securityMemberAccess.setExcludedPackageNamePatterns(ognlUtil.getExcludedPackageNamePatterns()); + securityMemberAccess.setExcludedPackageNames(ognlUtil.getExcludedPackageNames()); + + ognlExpressionLanguage = new ExpressionLanguageOGNL(securityMemberAccess); + } + /** * Determines if {@link com.opensymphony.xwork2.Validateable}'s validate() should be called, * as well as methods whose name that start with "validate". Defaults to "true". @@ -153,6 +173,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 +305,32 @@ public class OValValidationInterceptor extends MethodFilterInterceptor { return message; } } + } + +class ExpressionLanguageOGNL extends ExpressionLanguageOGNLImpl { + + private static final Logger LOG = LogManager.getLogger(ExpressionLanguageOGNL.class); + + private MemberAccess memberAccess; + + public ExpressionLanguageOGNL(MemberAccess memberAccess) { + this.memberAccess = memberAccess; + } + + public Object evaluate(final String expression, final Map values) throws ExpressionEvaluationException { + try { + final OgnlContext ctx = (OgnlContext) Ognl.createDefaultContext(null, memberAccess); + + for (final Map.Entry entry : values.entrySet()) { + ctx.put(entry.getKey(), entry.getValue()); + } + + LOG.debug("Evaluating OGNL expression: {1}", expression); + return Ognl.getValue(expression, ctx, ctx); + } catch (final OgnlException ex) { + throw new ExpressionEvaluationException("Evaluating script with OGNL failed.", ex); + } + } +} +