diff --git a/spring-binding/src/main/java/org/springframework/binding/expression/el/NullELResolver.java b/spring-binding/src/main/java/org/springframework/binding/expression/el/NullELResolver.java new file mode 100644 index 00000000..47ee3dac --- /dev/null +++ b/spring-binding/src/main/java/org/springframework/binding/expression/el/NullELResolver.java @@ -0,0 +1,60 @@ +package org.springframework.binding.expression.el; + +import java.util.Iterator; + +import javax.el.ELContext; +import javax.el.ELResolver; +import javax.el.PropertyNotWritableException; + +/** + * Resolves the special 'null' variable, indicating a null value. + * + * @author Keith Donald + */ +public class NullELResolver extends ELResolver { + + private static final String NULL_VARIABLE_NAME = "null"; + + public Class getCommonPropertyType(ELContext context, Object base) { + return null; + } + + public Iterator getFeatureDescriptors(ELContext context, Object base) { + return null; + } + + public Class getType(ELContext context, Object base, Object property) { + if (base == null && NULL_VARIABLE_NAME.equals(property)) { + context.setPropertyResolved(true); + return null; + } else { + return null; + } + } + + public Object getValue(ELContext context, Object base, Object property) { + if (base == null && NULL_VARIABLE_NAME.equals(property)) { + context.setPropertyResolved(true); + return null; + } else { + return null; + } + } + + public boolean isReadOnly(ELContext context, Object base, Object property) { + if (base == null && NULL_VARIABLE_NAME.equals(property)) { + context.setPropertyResolved(true); + return true; + } else { + return false; + } + } + + public void setValue(ELContext context, Object base, Object property, Object value) { + if (base == null && NULL_VARIABLE_NAME.equals(property)) { + context.setPropertyResolved(true); + throw new PropertyNotWritableException("The 'null' value cannot be set"); + } + } + +} diff --git a/spring-binding/src/test/java/org/springframework/binding/expression/el/ELExpressionParserTests.java b/spring-binding/src/test/java/org/springframework/binding/expression/el/ELExpressionParserTests.java index d3fab5f1..3fef293a 100644 --- a/spring-binding/src/test/java/org/springframework/binding/expression/el/ELExpressionParserTests.java +++ b/spring-binding/src/test/java/org/springframework/binding/expression/el/ELExpressionParserTests.java @@ -31,6 +31,11 @@ public class ELExpressionParserTests extends TestCase { assertEquals(new Long(7), exp.getValue(null)); } + public void testParseNull() { + Expression exp = parser.parseExpression("null", null); + assertEquals(null, exp.getValue(null)); + } + public void testParseNullExpressionString() { String expressionString = null; try { diff --git a/spring-webflow/src/main/java/org/springframework/webflow/expression/el/ActionMethodELResolver.java b/spring-webflow/src/main/java/org/springframework/webflow/expression/el/ActionMethodELResolver.java index edcf0bee..5d81b0aa 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/expression/el/ActionMethodELResolver.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/expression/el/ActionMethodELResolver.java @@ -21,8 +21,6 @@ import javax.el.ELContext; import javax.el.ELResolver; import javax.el.PropertyNotWritableException; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.springframework.webflow.engine.AnnotatedAction; import org.springframework.webflow.execution.Action; @@ -37,10 +35,12 @@ import org.springframework.webflow.execution.Action; */ public class ActionMethodELResolver extends ELResolver { - private static final Log logger = LogFactory.getLog(ActionMethodELResolver.class); - public Class getCommonPropertyType(ELContext elContext, Object base) { - return Action.class; + if (base instanceof Action) { + return String.class; + } else { + return null; + } } public Iterator getFeatureDescriptors(ELContext elContext, Object base) { diff --git a/spring-webflow/src/main/java/org/springframework/webflow/expression/el/ImplicitFlowVariableELResolver.java b/spring-webflow/src/main/java/org/springframework/webflow/expression/el/ImplicitFlowVariableELResolver.java index 1985ff24..3c606ac9 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/expression/el/ImplicitFlowVariableELResolver.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/expression/el/ImplicitFlowVariableELResolver.java @@ -65,7 +65,11 @@ public class ImplicitFlowVariableELResolver extends ELResolver { } public Class getCommonPropertyType(ELContext context, Object base) { - return Object.class; + if (base == null) { + return Object.class; + } else { + return null; + } } public Iterator getFeatureDescriptors(ELContext context, Object base) { diff --git a/spring-webflow/src/main/java/org/springframework/webflow/expression/el/RequestContextELResolver.java b/spring-webflow/src/main/java/org/springframework/webflow/expression/el/RequestContextELResolver.java index ad4378c9..bed1150e 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/expression/el/RequestContextELResolver.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/expression/el/RequestContextELResolver.java @@ -52,7 +52,10 @@ public class RequestContextELResolver extends ELResolver { } public Class getCommonPropertyType(ELContext elContext, Object base) { - return Object.class; + if (base == null) { + return RequestContext.class; + } + return null; } public Iterator getFeatureDescriptors(ELContext elContext, Object base) { diff --git a/spring-webflow/src/main/java/org/springframework/webflow/expression/el/ScopeSearchingELResolver.java b/spring-webflow/src/main/java/org/springframework/webflow/expression/el/ScopeSearchingELResolver.java index 832bac45..f7b24c36 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/expression/el/ScopeSearchingELResolver.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/expression/el/ScopeSearchingELResolver.java @@ -48,7 +48,11 @@ public class ScopeSearchingELResolver extends ELResolver { } public Class getCommonPropertyType(ELContext elContext, Object base) { - return Object.class; + if (base == null) { + return Object.class; + } else { + return null; + } } public Iterator getFeatureDescriptors(ELContext elContext, Object base) { diff --git a/spring-webflow/src/main/java/org/springframework/webflow/expression/el/SpringSecurityELResolver.java b/spring-webflow/src/main/java/org/springframework/webflow/expression/el/SpringSecurityELResolver.java deleted file mode 100644 index 9909a3db..00000000 --- a/spring-webflow/src/main/java/org/springframework/webflow/expression/el/SpringSecurityELResolver.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2004-2008 the original author or authors. - * - * Licensed 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.springframework.webflow.expression.el; - -import java.util.Iterator; - -import javax.el.ELContext; -import javax.el.ELResolver; -import javax.el.PropertyNotWritableException; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.security.Authentication; -import org.springframework.security.context.SecurityContextHolder; - -/** - * Custom EL resolver that resolves to the Spring Security Principal object for binding expressions prefixed with - * {@link #SECURITY_PRINCIPAL_VARIABLE_NAME}. For instance "#{currentUser}". - * - * @author Scott Andrews - */ -public class SpringSecurityELResolver extends ELResolver { - - private static final Log logger = LogFactory.getLog(SpringSecurityELResolver.class); - - /** - * Name of the security principal variable. - */ - public static final String SECURITY_PRINCIPAL_VARIABLE_NAME = "currentUser"; - - public Class getCommonPropertyType(ELContext elContext, Object base) { - return Object.class; - } - - public Iterator getFeatureDescriptors(ELContext elContext, Object base) { - return null; - } - - public Class getType(ELContext elContext, Object base, Object property) { - if (base == null && SECURITY_PRINCIPAL_VARIABLE_NAME.equals(property)) { - elContext.setPropertyResolved(true); - return Authentication.class; - } else { - return null; - } - } - - public Object getValue(ELContext elContext, Object base, Object property) { - if (base == null && SECURITY_PRINCIPAL_VARIABLE_NAME.equals(property)) { - if (logger.isDebugEnabled()) { - logger.debug("Successfully resolved implicit flow variable '" + property + "'"); - } - elContext.setPropertyResolved(true); - if (SecurityContextHolder.getContext() != null) { - return SecurityContextHolder.getContext().getAuthentication(); - } else { - return null; - } - } else { - return null; - } - } - - public boolean isReadOnly(ELContext elContext, Object base, Object property) { - if (base == null && SECURITY_PRINCIPAL_VARIABLE_NAME.equals(property)) { - elContext.setPropertyResolved(true); - return true; - } else { - return false; - } - } - - public void setValue(ELContext elContext, Object base, Object property, Object value) { - if (base == null && SECURITY_PRINCIPAL_VARIABLE_NAME.equals(property)) { - elContext.setPropertyResolved(true); - throw new PropertyNotWritableException("The " + SECURITY_PRINCIPAL_VARIABLE_NAME - + " cannot be set with an expression."); - } - } - -} diff --git a/spring-webflow/src/main/java/org/springframework/webflow/expression/el/WebFlowELExpressionParser.java b/spring-webflow/src/main/java/org/springframework/webflow/expression/el/WebFlowELExpressionParser.java index 23f8881b..06494a85 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/expression/el/WebFlowELExpressionParser.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/expression/el/WebFlowELExpressionParser.java @@ -27,6 +27,7 @@ import javax.el.VariableMapper; import org.springframework.binding.expression.el.DefaultELResolver; import org.springframework.binding.expression.el.ELContextFactory; import org.springframework.binding.expression.el.ELExpressionParser; +import org.springframework.binding.expression.el.NullELResolver; import org.springframework.webflow.execution.RequestContext; /** @@ -54,6 +55,7 @@ public class WebFlowELExpressionParser extends ELExpressionParser { RequestContext context = (RequestContext) target; List customResolvers = new ArrayList(); customResolvers.add(new RequestContextELResolver(context)); + customResolvers.add(new NullELResolver()); customResolvers.add(new ImplicitFlowVariableELResolver(context)); customResolvers.add(new ScopeSearchingELResolver(context)); customResolvers.add(new SpringBeanWebFlowELResolver(context));