// involved.
return;
}
FlowHandler flowHandler = context.getApplication().getFlowHandler();
ConfigurableNavigationHandler nh =
(ConfigurableNavigationHandler) context.getApplication().getNavigationHandler();
if (FlowHandler.NULL_FLOW.equals(flowDocumentIdRequestParam))
{
// It is a return node. The trick here is we need to calculate
// where the flow should return, because that information was not passed
// in the parameters of the link.
String toFlowDocumentId = FlowHandler.NULL_FLOW;
String fromOutcome = flowIdRequestParam;
//Flow sourceFlow = null;
List<Flow> sourceFlows = null;
List<Flow> targetFlows = null;
boolean failed = false;
int i = 0;
while (FlowHandler.NULL_FLOW.equals(toFlowDocumentId) && !failed)
{
Flow currentFlow = flowHandler.getCurrentFlow(context);
if (currentFlow == null)
{
failed = true;
break;
}
String currentLastDisplayedViewId = flowHandler.getLastDisplayedViewId(context);
FlowNode node = currentFlow.getNode(fromOutcome);
if (node instanceof ReturnNode)
{
if (targetFlows == null)
{
sourceFlows = new ArrayList<Flow>(4);
targetFlows = new ArrayList<Flow>(4);
}
// Get the navigation case using the outcome
Flow sourceFlow = currentFlow;
flowHandler.pushReturnMode(context);
currentFlow = flowHandler.getCurrentFlow(context);
i++;
NavigationCase navCase = nh.getNavigationCase(context, null,
((ReturnNode) node).getFromOutcome(context), FlowHandler.NULL_FLOW);
if (navCase == null)
{
if (currentLastDisplayedViewId != null)
{
sourceFlows.add(sourceFlow);
if (currentFlow != null)
{
toFlowDocumentId = currentFlow.getDefiningDocumentId();
targetFlows.add(currentFlow);
}
else
{
// No active flow
toFlowDocumentId = null;
targetFlows.add(null);
}
}
else
{
// Invalid state because no navCase and
// no saved lastDisplayedViewId into session
failed = true;
}
}
else
{
if (FlowHandler.NULL_FLOW.equals(navCase.getToFlowDocumentId()))
{
fromOutcome = navCase.getFromOutcome();
}
else
{
sourceFlows.add(sourceFlow);
// The absence of FlowHandler.NULL_FLOW means the return went somewhere else.
if (currentFlow != null)
{
toFlowDocumentId = currentFlow.getDefiningDocumentId();
targetFlows.add(currentFlow);
}
else
{
// No active flow
toFlowDocumentId = null;
targetFlows.add(null);
}
}
}
}
else
{
// No return node found in current flow, push it and check
// the next flow
flowHandler.pushReturnMode(context);
currentFlow = flowHandler.getCurrentFlow(context);
i++;
if (currentFlow == null)
{
failed = true;
}
}
}
for (int j = 0; j<i; j++)
{
flowHandler.popReturnMode(context);
}
if (!failed)
{
//Call transitions.
for (int j = 0; j < targetFlows.size(); j++)
{
Flow sourceFlow = sourceFlows.get(j);
Flow targetFlow = targetFlows.get(j);
flowHandler.transition(context,
sourceFlow,
targetFlow, null, context.getViewRoot().getViewId());
}
}
}
else
{
// This transition is for start a new flow. In this case
// FlowHandler.FLOW_ID_REQUEST_PARAM_NAME could be the flow name to enter
// or the flow call node to activate.
// 1. check if is a flow
Flow targetFlow = flowHandler.getFlow(context, flowDocumentIdRequestParam, flowIdRequestParam);
Flow currentFlow = null;
FlowCallNode outboundCallNode = null;
FlowNode node = null;
if (targetFlow == null)
{
//Check if is a call flow node
List<Flow> activeFlows = FlowHandlerImpl.getActiveFlows(context, flowHandler);
for (Flow activeFlow : activeFlows)
{
node = activeFlow != null ? activeFlow.getNode(flowIdRequestParam) : null;
if (node != null && node instanceof FlowCallNode)
{
outboundCallNode = (FlowCallNode) node;
String calledFlowDocumentId = outboundCallNode.getCalledFlowDocumentId(context);
if (calledFlowDocumentId == null)
{
calledFlowDocumentId = activeFlow.getDefiningDocumentId();
}
targetFlow = flowHandler.getFlow(context,
calledFlowDocumentId,
outboundCallNode.getCalledFlowId(context));
if (targetFlow == null && !"".equals(calledFlowDocumentId))
{
targetFlow = flowHandler.getFlow(context, "",
outboundCallNode.getCalledFlowId(context));
}
if (targetFlow != null)
{
currentFlow = activeFlow;
break;
}
}
}
}
if (targetFlow != null)
{
if (flowHandler.isActive(context, targetFlow.getDefiningDocumentId(), targetFlow.getId()))
{
Flow baseReturnFlow = flowHandler.getCurrentFlow();
if (!(baseReturnFlow.getDefiningDocumentId().equals(targetFlow.getDefiningDocumentId()) &&
baseReturnFlow.getId().equals(targetFlow.getId())))
{
flowHandler.transition(context,
baseReturnFlow, targetFlow, outboundCallNode, context.getViewRoot().getViewId());
}
flowHandler.pushReturnMode(context);
Flow previousFlow = flowHandler.getCurrentFlow(context);
flowHandler.popReturnMode(context);
flowHandler.transition(context,
targetFlow, previousFlow, outboundCallNode, context.getViewRoot().getViewId());
}
// Invoke transition
flowHandler.transition(context,
currentFlow, targetFlow, outboundCallNode, context.getViewRoot().getViewId());
// Handle 2 or more flow consecutive start.
boolean failed = false;
String startNodeId = targetFlow.getStartNodeId();
while (startNodeId != null && !failed)
{
NavigationCase navCase = nh.getNavigationCase(context, null,
startNodeId, targetFlow.getDefiningDocumentId());
if (navCase != null && navCase.getToFlowDocumentId() != null)
{
currentFlow = flowHandler.getCurrentFlow(context);