>>>>> On Mon, 04 Mar 2013 14:22:46 -0700, David Schneider <david.schneider_at_oracle.com> said:
DS> On 02/28/2013 07:41 AM, Leonardo Uribe wrote:
>>> In section 7.4.2.1, Requirements for Explicit Navigation in Faces Flow
EB> Call Nodes other than ViewNodes, here is the new text regarding return
EB> nodes.
EB> If the node is a ReturnNode obtain its navigation case and call
EB> FlowHandler.setReturnMode(true). This enables the navigation to
EB> proceed with respect to the calling flow's navigation rules, or the
EB> application's navigation rules if there is no calling flow. Start the
EB> navigation algorithm over using it as the basis but pass the value of
EB> the symbolic constant javax.faces.flow.FlowHandler.NULL_FLOW as the
EB> value of the toFlowDocumentId argument. If this does not yield a
EB> navigation case, call FlowHandler.getLastDisplayedViewId(), which will
EB> return the last displayed view id of the calling flow, or null if
EB> there is no such flow. In a finally block, when the re-invocation of
EB> the navigation algorithms completes, call
EB> FlowHandler.setReturnMode(false).
>>> >
LU> I don't get these lines. In theory flowDocumentId to use should be the
LU> parent flow flowDocumentId. So, if the node is a ReturnNode, it should
LU> take the outcome, and try to resolve it under the parent flow and if
LU> it resolves to something else the parent flowDocumentId should be
LU> used. If it founds another ReturnNode it should do the same until
LU> the top. The rules that are on top (not bound to any flow and set
LU> globally) only should be consulted if no parent flow is found, respecting
LU> encapsulation principle.
DS> I believe I agree. When exiting a flow the flow being exited should be
DS> "popped" from the flow call stack and navigation should proceed in the
DS> context of the calling flow, with navigation originating from that
DS> flow's call node, and using that flow's navigation rules.
Yes, this is what I have.
DS> The only time navigation should use the null flow is when the whole
DS> call stack has been popped.
The NULL_FLOW value for the toFlowDocumentId argument is just a flag
that means we are in the midst of a flow return and the popped flow is
the one that should be used as the context of the navigation algorithm.
DS> The existence of the return mode attribute in the interface contract
DS> seems to suggest we don't have the separation of responsibilities of the
DS> classes well thought out. It looks like we have a somewhat obtuse way
DS> of performing a push and pop of a window's flow stack using
DS> FlowHandler.transition(), FlowHandler.getCurrentFlow(), and
DS> FlowHandler.setReturnMode(). Maybe it would be more clear if the
DS> operations on the FlowHandler interface were described as stack
DS> operations such as push, pop, and peek.
As I said before, I don't want to expose the stack data structure to the
API to allow for greater flexibility in implementation choice.
>>>>> On Sun, 10 Mar 2013 18:10:55 -0500, Leonardo Uribe <lu4242_at_gmail.com> said:
LU> Thanks David for the clarification. So in this case it is better that the
LU> "global rules" only apply if the stack is clear. I agree. What's important
LU> here is ensure that the developer can nest 2, 3 or many more flows and
LU> in all cases it will work correctly. The API no matter how is done should
LU> reflect that.
Yes, of course the ability to do this nesting is essential, and we have
a working testcase that shows this ability.
LU> I totally agree with you in this case. Currently we have this:
LU> public abstract Flow getCurrentFlow(FacesContext context)
LU> public abstract void setReturnMode(FacesContext context,
LU> boolean returnMode)
LU> public abstract void transition(FacesContext context,
LU> Flow sourceFlow,
LU> Flow targetFlow,
LU> FlowCallNode outboundCallNode,
LU> String toViewId)
LU> transition() method is ok, because you can't nest the same flow twice.
LU> But trying to implement transition() method, I have found that internally
LU> this method requires a stack to do the job.
Yes, of course one needs a stack inside to do the job.
LU> We need an API that can do
LU> two things:
LU> 1. Handle transitions or when to go in/out of a flow, and apply operations
LU> like clear/init flow scope and so on.
LU> 2. Calculate the navigation case taking into account the current context,
LU> traversing the flow structure but without execute any of the steps to be
LU> done for the real navigation.
LU> The api we need is something that can do the calculation without affect
LU> the current state, because that part will be done later in
LU> NavigationHandler.handleNavigation() / FlowHandler.transition()
Yes, and I assert that those operations can be done as an implementation
detail. The important thing is to specify the behavior of the flow
nodes with respect to navigation.
Ed