diff --git a/spring-webflow/pom.xml b/spring-webflow/pom.xml
index 76e80ac2..6b3358f9 100644
--- a/spring-webflow/pom.xml
+++ b/spring-webflow/pom.xml
@@ -5,7 +5,7 @@
spring-webflow
jar
Spring Web Flow
- 2.0-m4-SNAPSHOT
+ 2.0-m4
Spring Web Flow
http://www.springframework.org
@@ -107,7 +107,7 @@
true
- org.springframework
+ org.springframework.security
spring-security-core
2.0-M2
true
diff --git a/spring-webflow/src/main/java/org/springframework/webflow/expression/WebFlowOgnlExpressionParser.java b/spring-webflow/src/main/java/org/springframework/webflow/expression/WebFlowOgnlExpressionParser.java
index adefc92b..021e7d01 100644
--- a/spring-webflow/src/main/java/org/springframework/webflow/expression/WebFlowOgnlExpressionParser.java
+++ b/spring-webflow/src/main/java/org/springframework/webflow/expression/WebFlowOgnlExpressionParser.java
@@ -21,9 +21,15 @@ import ognl.ObjectPropertyAccessor;
import ognl.OgnlException;
import ognl.PropertyAccessor;
+import org.springframework.beans.factory.BeanFactory;
+import org.springframework.beans.factory.support.StaticListableBeanFactory;
import org.springframework.binding.collection.MapAdaptable;
import org.springframework.binding.expression.ognl.OgnlExpressionParser;
+import org.springframework.security.context.SecurityContextHolder;
+import org.springframework.util.ClassUtils;
import org.springframework.webflow.core.collection.MutableAttributeMap;
+import org.springframework.webflow.engine.AnnotatedAction;
+import org.springframework.webflow.execution.Action;
import org.springframework.webflow.execution.RequestContext;
/**
@@ -37,16 +43,12 @@ public class WebFlowOgnlExpressionParser extends OgnlExpressionParser {
* Creates a webflow-specific ognl expression parser.
*/
public WebFlowOgnlExpressionParser() {
- addPropertyAccessor(RequestContext.class, new RequestContextPropertyAccessor(new ObjectPropertyAccessor()));
addPropertyAccessor(MapAdaptable.class, new MapAdaptablePropertyAccessor());
addPropertyAccessor(MutableAttributeMap.class, new MutableAttributeMapPropertyAccessor());
+ addPropertyAccessor(RequestContext.class, new RequestContextPropertyAccessor(new ObjectPropertyAccessor()));
+ addPropertyAccessor(Action.class, new ActionPropertyAccessor());
}
- /**
- * The {@link MapAdaptable} property accessor.
- *
- * @author Keith Donald
- */
private static class MapAdaptablePropertyAccessor implements PropertyAccessor {
public Object getProperty(Map context, Object target, Object name) throws OgnlException {
return ((MapAdaptable) target).asMap().get(name);
@@ -58,11 +60,6 @@ public class WebFlowOgnlExpressionParser extends OgnlExpressionParser {
}
}
- /**
- * The {@link MutableAttributeMap} property accessor.
- *
- * @author Keith Donald
- */
private static class MutableAttributeMapPropertyAccessor extends MapAdaptablePropertyAccessor {
public void setProperty(Map context, Object target, Object name, Object value) throws OgnlException {
((MutableAttributeMap) target).put((String) name, value);
@@ -70,6 +67,12 @@ public class WebFlowOgnlExpressionParser extends OgnlExpressionParser {
}
private static class RequestContextPropertyAccessor implements PropertyAccessor {
+
+ private static boolean securityPresent = ClassUtils
+ .isPresent("org.springframework.security.context.SecurityContextHolder");
+
+ private static final BeanFactory EMPTY_BEAN_FACTORY = new StaticListableBeanFactory();
+
private PropertyAccessor delegate;
public RequestContextPropertyAccessor(PropertyAccessor delegate) {
@@ -79,6 +82,16 @@ public class WebFlowOgnlExpressionParser extends OgnlExpressionParser {
public Object getProperty(Map context, Object target, Object name) throws OgnlException {
String property = name.toString();
RequestContext requestContext = (RequestContext) target;
+ if (property.equals("flowRequestContext")) {
+ return requestContext;
+ }
+ if (securityPresent && property.equals("currentUser")) {
+ if (SecurityContextHolder.getContext() != null) {
+ return SecurityContextHolder.getContext().getAuthentication();
+ } else {
+ return null;
+ }
+ }
if (requestContext.getRequestScope().contains(property)) {
return requestContext.getRequestScope().get(property);
} else if (requestContext.getFlashScope().contains(property)) {
@@ -87,14 +100,39 @@ public class WebFlowOgnlExpressionParser extends OgnlExpressionParser {
return requestContext.getFlowScope().get(property);
} else if (requestContext.getConversationScope().contains(property)) {
return requestContext.getConversationScope().get(property);
- } else {
- return delegate.getProperty(context, target, name);
}
+ BeanFactory bf = getBeanFactory(requestContext);
+ if (bf.containsBean(property)) {
+ return bf.getBean(property);
+ }
+ return delegate.getProperty(context, target, name);
}
public void setProperty(Map context, Object target, Object name, Object value) throws OgnlException {
delegate.setProperty(context, target, name, value);
}
+ private BeanFactory getBeanFactory(RequestContext requestContext) {
+ if (requestContext.getActiveFlow().getBeanFactory() != null) {
+ BeanFactory factory = requestContext.getActiveFlow().getBeanFactory();
+ return factory;
+ } else {
+ return EMPTY_BEAN_FACTORY;
+ }
+ }
}
+
+ private static class ActionPropertyAccessor implements PropertyAccessor {
+ public Object getProperty(Map context, Object target, Object name) throws OgnlException {
+ Action action = (Action) target;
+ AnnotatedAction annotated = new AnnotatedAction(action);
+ annotated.setMethod(name.toString());
+ return annotated;
+ }
+
+ public void setProperty(Map context, Object target, Object name, Object value) throws OgnlException {
+ throw new OgnlException("Cannot set properties on a Action instance - operation not allowed");
+ }
+ }
+
}
\ No newline at end of file
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 ba5b8fb3..0428ea97 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
@@ -25,6 +25,9 @@ import org.springframework.webflow.execution.RequestContext;
*/
public class WebFlowELExpressionParser extends ELExpressionParser {
+ private static boolean securityPresent = ClassUtils
+ .isPresent("org.springframework.security.context.SecurityContextHolder");
+
public WebFlowELExpressionParser(ExpressionFactory expressionFactory) {
super(expressionFactory);
putContextFactory(RequestContext.class, new RequestContextELContextFactory());
@@ -36,13 +39,13 @@ public class WebFlowELExpressionParser extends ELExpressionParser {
RequestContext context = (RequestContext) target;
List customResolvers = new ArrayList();
customResolvers.add(new RequestContextELResolver(context));
- customResolvers.add(new ImplicitFlowVariableELResolver(context));
- customResolvers.add(new ScopeSearchingELResolver(context));
- customResolvers.add(new ActionMethodELResolver());
- if (ClassUtils.isPresent("org.springframework.security.context.SecurityContextHolder")) {
+ if (securityPresent) {
customResolvers.add(new SpringSecurityELResolver());
}
+ customResolvers.add(new ImplicitFlowVariableELResolver(context));
+ customResolvers.add(new ScopeSearchingELResolver(context));
customResolvers.add(new SpringBeanWebFlowELResolver(context));
+ customResolvers.add(new ActionMethodELResolver());
ELResolver resolver = new DefaultELResolver(null, customResolvers);
return new WebFlowELContext(resolver);
}
diff --git a/spring-webflow/src/test/java/org/springframework/webflow/engine/builder/support/TextToTargetStateResolverTests.java b/spring-webflow/src/test/java/org/springframework/webflow/engine/builder/support/TextToTargetStateResolverTests.java
index 87ff4aa2..a8834121 100644
--- a/spring-webflow/src/test/java/org/springframework/webflow/engine/builder/support/TextToTargetStateResolverTests.java
+++ b/spring-webflow/src/test/java/org/springframework/webflow/engine/builder/support/TextToTargetStateResolverTests.java
@@ -39,7 +39,7 @@ public class TextToTargetStateResolverTests extends TestCase {
}
public void testDynamic() {
- String expression = "#{flowScope.lastState}";
+ String expression = "${flowScope.lastState}";
TargetStateResolver resolver = (TargetStateResolver) converter.convert(expression);
MockRequestContext context = new MockRequestContext();
context.getFlowScope().put("lastState", "mockState");