diff --git a/spring-faces/src/main/java/org/springframework/faces/expression/CompositeFlowPropertyResolver.java b/spring-faces/src/main/java/org/springframework/faces/expression/CompositeFlowPropertyResolver.java index b113ccf9..009bb345 100644 --- a/spring-faces/src/main/java/org/springframework/faces/expression/CompositeFlowPropertyResolver.java +++ b/spring-faces/src/main/java/org/springframework/faces/expression/CompositeFlowPropertyResolver.java @@ -18,8 +18,6 @@ public class CompositeFlowPropertyResolver extends ELDelegatingPropertyResolver private static final CompositeELResolver composite = new CompositeELResolver(); static { - composite.add(new RequestContextELResolver()); - composite.add(new ScopeSearchingELResolver()); composite.add(new MapAdaptableELResolver()); } diff --git a/spring-faces/src/main/java/org/springframework/faces/expression/CompositeFlowVariableResolver.java b/spring-faces/src/main/java/org/springframework/faces/expression/CompositeFlowVariableResolver.java index ff3c6d22..3edacd64 100644 --- a/spring-faces/src/main/java/org/springframework/faces/expression/CompositeFlowVariableResolver.java +++ b/spring-faces/src/main/java/org/springframework/faces/expression/CompositeFlowVariableResolver.java @@ -3,10 +3,10 @@ package org.springframework.faces.expression; import javax.el.CompositeELResolver; import javax.faces.el.VariableResolver; -import org.springframework.binding.expression.el.MapAdaptableELResolver; import org.springframework.webflow.expression.el.ImplicitFlowVariableELResolver; import org.springframework.webflow.expression.el.RequestContextELResolver; import org.springframework.webflow.expression.el.ScopeSearchingELResolver; +import org.springframework.webflow.expression.el.SpringBeanWebFlowELResolver; /** * Assembles {@link RequestContextELResolver} and {@link ScopeSearchingELResolver} into a composite that may be used @@ -20,9 +20,9 @@ public class CompositeFlowVariableResolver extends ELDelegatingVariableResolver static { composite.add(new RequestContextELResolver()); + composite.add(new SpringBeanWebFlowELResolver()); composite.add(new ImplicitFlowVariableELResolver()); composite.add(new ScopeSearchingELResolver()); - composite.add(new MapAdaptableELResolver()); } public CompositeFlowVariableResolver(VariableResolver nextResolver) { diff --git a/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/faces-config.xml b/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/faces-config.xml new file mode 100644 index 00000000..8a0d7056 --- /dev/null +++ b/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/faces-config.xml @@ -0,0 +1,11 @@ + + + + + + + com.sun.facelets.FaceletViewHandler + + \ No newline at end of file diff --git a/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/flows/main/.tmp_reviewHotels.xhtml b/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/flows/main/.tmp_reviewHotels.xhtml new file mode 100644 index 00000000..548c96f8 --- /dev/null +++ b/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/flows/main/.tmp_reviewHotels.xhtml @@ -0,0 +1,55 @@ + + + + + + +
+ +

Hotel Results

+

+ Search Criteria: #{searchCriteria}
+ +

+ +
+ + + + Name + #{hotel.name} + + + Address + #{hotel.address} + + + City, State + #{hotel.city}, #{hotel.state}, #{hotel.country} + + + Zip + #{hotel.zip} + + + Action + + + + + +
+
+
+
+
+
\ No newline at end of file diff --git a/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/flows/main/enterSearchCriteria.xhtml b/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/flows/main/enterSearchCriteria.xhtml index d847d98a..36022081 100644 --- a/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/flows/main/enterSearchCriteria.xhtml +++ b/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/flows/main/enterSearchCriteria.xhtml @@ -29,7 +29,7 @@
- +
diff --git a/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/web-application-config.xml b/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/web-application-config.xml index d72e2d30..deaabfc1 100755 --- a/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/web-application-config.xml +++ b/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/web-application-config.xml @@ -31,6 +31,14 @@ + + + + + + + + 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 5437cf0e..52d64381 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 @@ -23,13 +23,10 @@ public class ImplicitFlowVariableELResolver extends ELResolver { } public Class getType(ELContext context, Object base, Object property) { - if (base != null) { + if (base != null || RequestContextHolder.getRequestContext() == null) { return null; } RequestContext requestContext = RequestContextHolder.getRequestContext(); - if (requestContext == null) { - return null; - } if (ImplicitVariables.matches(property)) { context.setPropertyResolved(true); return ImplicitVariables.value(context, requestContext, property).getClass(); @@ -39,7 +36,7 @@ public class ImplicitFlowVariableELResolver extends ELResolver { } public Object getValue(ELContext context, Object base, Object property) { - if (base != null) { + if (base != null || RequestContextHolder.getRequestContext() == null) { return null; } RequestContext requestContext = RequestContextHolder.getRequestContext(); 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 9a2a8e04..9fa3f944 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 @@ -28,7 +28,7 @@ public class ScopeSearchingELResolver extends ELResolver { } public Class getType(ELContext elContext, Object base, Object property) { - if (base != null) { + if (base != null || RequestContextHolder.getRequestContext() == null) { return null; } RequestContext requestContext = RequestContextHolder.getRequestContext(); @@ -51,7 +51,7 @@ public class ScopeSearchingELResolver extends ELResolver { } public Object getValue(ELContext elContext, Object base, Object property) { - if (base != null) { + if (base != null || RequestContextHolder.getRequestContext() == null) { return null; } RequestContext requestContext = RequestContextHolder.getRequestContext(); @@ -74,7 +74,7 @@ public class ScopeSearchingELResolver extends ELResolver { } public boolean isReadOnly(ELContext elContext, Object base, Object property) { - if (base != null) { + if (base != null || RequestContextHolder.getRequestContext() == null) { return false; } RequestContext requestContext = RequestContextHolder.getRequestContext(); @@ -97,7 +97,7 @@ public class ScopeSearchingELResolver extends ELResolver { } public void setValue(ELContext elContext, Object base, Object property, Object value) { - if (base != null) { + if (base != null || RequestContextHolder.getRequestContext() == null) { return; } RequestContext requestContext = RequestContextHolder.getRequestContext(); 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 bd5426b0..aa6fdda1 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 @@ -4,14 +4,17 @@ import java.util.ArrayList; import java.util.List; import javax.el.ELContext; +import javax.el.ELException; import javax.el.ELResolver; import javax.el.ExpressionFactory; import javax.el.FunctionMapper; import javax.el.VariableMapper; +import org.springframework.beans.BeanUtils; import org.springframework.binding.expression.el.DefaultELResolver; import org.springframework.binding.expression.el.ELContextFactory; import org.springframework.binding.expression.el.ELExpressionParser; +import org.springframework.util.ReflectionUtils; import org.springframework.webflow.core.collection.MutableAttributeMap; import org.springframework.webflow.execution.RequestContext; @@ -23,6 +26,10 @@ import org.springframework.webflow.execution.RequestContext; */ public class WebFlowELExpressionParser extends ELExpressionParser { + private static final String EXPRESSION_FACTORY_PROPERTY = "javax.el.ExpressionFactory"; + + private static final String DEFAULT_EXPRESSION_FACTORY = "org.jboss.el.ExpressionFactoryImpl"; + public WebFlowELExpressionParser(ExpressionFactory expressionFactory) { super(expressionFactory); putContextFactory(RequestContext.class, new RequestContextELContextFactory()); @@ -34,10 +41,18 @@ public class WebFlowELExpressionParser extends ELExpressionParser { } private static ExpressionFactory getDefaultExpressionFactory() { - if (!System.getProperties().containsKey("javax.el.ExpressionFactory")) { - System.setProperty("javax.el.ExpressionFactory", "org.jboss.el.ExpressionFactoryImpl"); + if (!System.getProperties().containsKey(EXPRESSION_FACTORY_PROPERTY)) { + System.setProperty(EXPRESSION_FACTORY_PROPERTY, DEFAULT_EXPRESSION_FACTORY); + } + if (ReflectionUtils.findMethod(ExpressionFactory.class, "newInstance") != null) { + return ExpressionFactory.newInstance(); + } else { // Fallback in case using an older version of el-api + try { + return (ExpressionFactory) BeanUtils.instantiateClass(Class.forName(DEFAULT_EXPRESSION_FACTORY)); + } catch (Exception e) { + throw new ELException("Could not create the default ExpressionFactory", e); + } } - return ExpressionFactory.newInstance(); } private static class RequestContextELContextFactory implements ELContextFactory { diff --git a/spring-webflow/src/test/java/org/springframework/webflow/engine/builder/support/TextToTransitionCriteriaTests.java b/spring-webflow/src/test/java/org/springframework/webflow/engine/builder/support/TextToTransitionCriteriaTests.java index 75892a5d..34e54c31 100644 --- a/spring-webflow/src/test/java/org/springframework/webflow/engine/builder/support/TextToTransitionCriteriaTests.java +++ b/spring-webflow/src/test/java/org/springframework/webflow/engine/builder/support/TextToTransitionCriteriaTests.java @@ -23,6 +23,7 @@ import org.springframework.webflow.engine.TransitionCriteria; import org.springframework.webflow.engine.WildcardTransitionCriteria; import org.springframework.webflow.execution.Event; import org.springframework.webflow.execution.RequestContext; +import org.springframework.webflow.execution.RequestContextHolder; import org.springframework.webflow.test.MockFlowBuilderContext; import org.springframework.webflow.test.MockRequestContext; @@ -66,18 +67,11 @@ public class TextToTransitionCriteriaTests extends TestCase { } /* - public void testNonBooleanEvaluation() throws Exception { - String expression = "${flowScope.foo}"; - TransitionCriteria criterion = (TransitionCriteria) converter.convert(expression); - RequestContext ctx = getRequestContext(); - try { - criterion.test(ctx); - fail("Non-boolean evaluations are not allowed"); - } catch (IllegalArgumentException e) { - // success - } - } - */ + * public void testNonBooleanEvaluation() throws Exception { String expression = "${flowScope.foo}"; + * TransitionCriteria criterion = (TransitionCriteria) converter.convert(expression); RequestContext ctx = + * getRequestContext(); try { criterion.test(ctx); fail("Non-boolean evaluations are not allowed"); } catch + * (IllegalArgumentException e) { // success } } + */ public void testInvalidSyntax() throws Exception { try { @@ -90,16 +84,12 @@ public class TextToTransitionCriteriaTests extends TestCase { } /* - public void testEventId() throws Exception { - String expression = "${lastEvent.id == 'sample'}"; - TransitionCriteria criterion = (TransitionCriteria) converter.convert(expression); - RequestContext ctx = getRequestContext(); - assertTrue("Criterion should evaluate to true", criterion.test(ctx)); - expression = "${#result == 'sample'}"; - criterion = (TransitionCriteria) converter.convert(expression); - assertTrue("Criterion should evaluate to true", criterion.test(ctx)); - } - */ + * public void testEventId() throws Exception { String expression = "${lastEvent.id == 'sample'}"; + * TransitionCriteria criterion = (TransitionCriteria) converter.convert(expression); RequestContext ctx = + * getRequestContext(); assertTrue("Criterion should evaluate to true", criterion.test(ctx)); expression = + * "${#result == 'sample'}"; criterion = (TransitionCriteria) converter.convert(expression); assertTrue("Criterion + * should evaluate to true", criterion.test(ctx)); } + */ public void testBean() { TransitionCriteria myTransitionCriteria = new TransitionCriteria() { @@ -115,6 +105,7 @@ public class TextToTransitionCriteriaTests extends TestCase { private RequestContext getRequestContext() { Flow flow = new Flow("id"); MockRequestContext ctx = new MockRequestContext(flow); + RequestContextHolder.setRequestContext(ctx); ctx.getFlowScope().put("foo", "bar"); ctx.setLastEvent(new Event(this, "sample")); return ctx;