| Category: |
-
+
@@ -41,12 +41,11 @@
| Is shipping required?: |
-
+
|
|
-
|
diff --git a/spring-webflow-samples/sellitem-jsf/src/main/webapp/priceAndItemCountForm.jsp b/spring-webflow-samples/sellitem-jsf/src/main/webapp/priceAndItemCountForm.jsp
index 328f2633..9b0842da 100644
--- a/spring-webflow-samples/sellitem-jsf/src/main/webapp/priceAndItemCountForm.jsp
+++ b/spring-webflow-samples/sellitem-jsf/src/main/webapp/priceAndItemCountForm.jsp
@@ -18,7 +18,6 @@
-
Enter price and item count
@@ -26,7 +25,7 @@
| Price: |
-
+
|
@@ -37,7 +36,7 @@
| Item count: |
-
+
|
@@ -47,7 +46,6 @@
|
-
|
|
diff --git a/spring-webflow-samples/sellitem-jsf/src/main/webapp/shippingDetailsForm.jsp b/spring-webflow-samples/sellitem-jsf/src/main/webapp/shippingDetailsForm.jsp
index 06ebcaad..3499d728 100644
--- a/spring-webflow-samples/sellitem-jsf/src/main/webapp/shippingDetailsForm.jsp
+++ b/spring-webflow-samples/sellitem-jsf/src/main/webapp/shippingDetailsForm.jsp
@@ -22,22 +22,22 @@
- | Price: | |
+ Price: | |
- | Item count: | |
+ Item count: | |
- | Category: | |
+ Category: | |
- | Shipping: | |
+ Shipping: | |
| Shipping type: |
-
+
@@ -45,7 +45,6 @@
|
|
-
|
diff --git a/spring-webflow/src/main/java/org/springframework/webflow/executor/jsf/DelegatingFlowVariableResolver.java b/spring-webflow/src/main/java/org/springframework/webflow/executor/jsf/DelegatingFlowVariableResolver.java
new file mode 100644
index 00000000..e9dd0eba
--- /dev/null
+++ b/spring-webflow/src/main/java/org/springframework/webflow/executor/jsf/DelegatingFlowVariableResolver.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2004-2007 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.executor.jsf;
+
+import javax.faces.context.FacesContext;
+import javax.faces.el.EvaluationException;
+import javax.faces.el.VariableResolver;
+
+import org.springframework.webflow.execution.FlowExecution;
+
+/**
+ * Custom variable resolver that searches the current flow execution for variables to resolve.
+ * The search algorithm looks in flash scope first, then flow scope, then conversation scope.
+ * If no variable is found, this resolver delegates to the next resolver in the chain.
+ *
+ * Suitable for use along side other variable resolvers to support EL binding expressions like
+ * {#bean.property} where "bean" could be a property in any supported scope.
+ *
+ * @author Keith Donald
+ */
+public class DelegatingFlowVariableResolver extends VariableResolver {
+
+ /**
+ * The standard variable resolver to delegate to if this one doesn't apply.
+ */
+ private VariableResolver resolverDelegate;
+
+ /**
+ * Create a new FlowExecutionVariableResolver, using the given original VariableResolver.
+ *
+ * A JSF implementation will automatically pass its original resolver into the constructor of a configured resolver,
+ * provided that there is a corresponding constructor argument.
+ *
+ * @param resolverDelegate the original VariableResolver
+ */
+ public DelegatingFlowVariableResolver(VariableResolver resolverDelegate) {
+ this.resolverDelegate = resolverDelegate;
+ }
+
+ /**
+ * Return the original VariableResolver that this resolver delegates to.
+ */
+ protected final VariableResolver getResolverDelegate() {
+ return resolverDelegate;
+ }
+
+ /**
+ * Check flash/flow/conversation scope. If the variable is not found, delegate to next variable resolver in the
+ * chain.
+ */
+ public Object resolveVariable(FacesContext context, String name) throws EvaluationException {
+ FlowExecution execution = FlowExecutionHolderUtils.getRequiredCurrentFlowExecution(context);
+ // try flash/flow/conversation
+ if (execution.getActiveSession().getFlashMap().contains(name)) {
+ return execution.getActiveSession().getFlashMap().get(name);
+ }
+ else if (execution.getActiveSession().getScope().contains(name)) {
+ return execution.getActiveSession().getScope().get(name);
+ }
+ else if (execution.getConversationScope().contains(name)) {
+ return execution.getConversationScope().get(name);
+ }
+ else {
+ // neither found a value, delegate to next resolver in the chain
+ return resolverDelegate.resolveVariable(context, name);
+ }
+ }
+}
\ No newline at end of file
diff --git a/spring-webflow/src/main/java/org/springframework/webflow/executor/jsf/FlowExecutionHolderUtils.java b/spring-webflow/src/main/java/org/springframework/webflow/executor/jsf/FlowExecutionHolderUtils.java
index 0c34d5d7..72ce5945 100644
--- a/spring-webflow/src/main/java/org/springframework/webflow/executor/jsf/FlowExecutionHolderUtils.java
+++ b/spring-webflow/src/main/java/org/springframework/webflow/executor/jsf/FlowExecutionHolderUtils.java
@@ -17,13 +17,15 @@ package org.springframework.webflow.executor.jsf;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
+import javax.faces.el.EvaluationException;
+
+import org.springframework.webflow.execution.FlowExecution;
/**
* A static utility class for accessing the current flow execution holder.
*
- * By default, the current flow execution holder is stored associated with the
- * current thread in the {@link FacesContext}'s
- * {@link ExternalContext#getRequestMap()}.
+ * By default, the current flow execution holder is stored associated with the current thread in the
+ * {@link FacesContext}'s {@link ExternalContext#getRequestMap()}.
*
* @author Keith Donald
* @author Craig McClanahan
@@ -36,7 +38,24 @@ public class FlowExecutionHolderUtils {
* @return the flow execution holder, or null if none set.
*/
public static FlowExecutionHolder getFlowExecutionHolder(FacesContext context) {
- return (FlowExecutionHolder)context.getExternalContext().getRequestMap().get(getFlowExecutionHolderKey());
+ return (FlowExecutionHolder) context.getExternalContext().getRequestMap().get(getFlowExecutionHolderKey());
+ }
+
+ /**
+ * Returns the current flow execution holder for the given faces context.
+ * @param context faces context
+ * @return the flow execution holder or null if none set
+ * @throws EvaluationException if no flow execution was bound
+ */
+ public static FlowExecution getRequiredCurrentFlowExecution(FacesContext context) throws EvaluationException {
+ FlowExecutionHolder holder = getFlowExecutionHolder(context);
+ if (holder != null) {
+ return holder.getFlowExecution();
+ }
+ else {
+ throw new EvaluationException(
+ "FlowExecution is not bound to current thread context - has the flow ended or expired?");
+ }
}
/**
@@ -48,11 +67,17 @@ public class FlowExecutionHolderUtils {
context.getExternalContext().getRequestMap().put(getFlowExecutionHolderKey(), holder);
}
+ /**
+ * Returns true if the flow execution has been restored in the current thread.
+ * @param context the faces context
+ * @return true if restored, false otherwise
+ */
+ public static boolean isFlowExecutionRestored(FacesContext context) {
+ return getFlowExecutionHolder(context) != null;
+ }
+
private static String getFlowExecutionHolderKey() {
return FlowExecutionHolder.class.getName();
}
- public static boolean isFlowExecutionRestored(FacesContext context) {
- return getFlowExecutionHolder(context) != null;
- }
}
\ No newline at end of file
diff --git a/spring-webflow/src/main/java/org/springframework/webflow/executor/jsf/FlowExecutionVariableResolver.java b/spring-webflow/src/main/java/org/springframework/webflow/executor/jsf/FlowExecutionVariableResolver.java
index e1f69082..7b2799e5 100644
--- a/spring-webflow/src/main/java/org/springframework/webflow/executor/jsf/FlowExecutionVariableResolver.java
+++ b/spring-webflow/src/main/java/org/springframework/webflow/executor/jsf/FlowExecutionVariableResolver.java
@@ -72,12 +72,7 @@ public class FlowExecutionVariableResolver extends VariableResolver {
return resolverDelegate.resolveVariable(context, name);
}
else {
- FlowExecutionHolder holder = FlowExecutionHolderUtils.getFlowExecutionHolder(context);
- if (holder == null)
- throw new EvaluationException("'" + FLOW_EXECUTION_VARIABLE_NAME
- + "' variable prefix specified but a FlowExecution is not bound to current thread context: "
- + "has the flow ended or expired?");
- return holder.getFlowExecution();
+ return FlowExecutionHolderUtils.getRequiredCurrentFlowExecution(context);
}
}
}
\ No newline at end of file
diff --git a/spring-webflow/src/main/java/org/springframework/webflow/executor/jsf/FlowVariableResolver.java b/spring-webflow/src/main/java/org/springframework/webflow/executor/jsf/FlowVariableResolver.java
index 2528ad3c..12c78f08 100644
--- a/spring-webflow/src/main/java/org/springframework/webflow/executor/jsf/FlowVariableResolver.java
+++ b/spring-webflow/src/main/java/org/springframework/webflow/executor/jsf/FlowVariableResolver.java
@@ -68,11 +68,7 @@ public class FlowVariableResolver extends VariableResolver {
return resolverDelegate.resolveVariable(context, name);
}
else {
- FlowExecutionHolder holder = FlowExecutionHolderUtils.getFlowExecutionHolder(context);
- if (holder == null)
- throw new EvaluationException(
- "'flowScope' variable prefix specified but a FlowExecution is not bound to current thread context - has the flow ended or expired?");
- return holder.getFlowExecution();
+ return FlowExecutionHolderUtils.getRequiredCurrentFlowExecution(context);
}
}
}
\ No newline at end of file
|