String viewId = facesContext.getViewRoot() != null ? facesContext.getViewRoot().getViewId() : null;
NavigationCase navigationCase = getNavigationCommandFromGlobalNavigationCases(
facesContext, viewId, navigationContext, fromAction, outcome);
if (outcome != null && navigationCase == null)
{
FlowHandler flowHandler = facesContext.getApplication().getFlowHandler();
List<Flow> activeFlows = FlowHandlerImpl.getActiveFlows(facesContext, flowHandler);
// JSF 2.2 section 7.4.2: "... When outside of a flow, view identifier
// has the additional possibility of being a flow id.
Flow targetFlow = calculateTargetFlow(facesContext, outcome, flowHandler, activeFlows, toFlowDocumentId);
Flow currentFlow = navigationContext.getCurrentFlow(facesContext);
FlowCallNode targetFlowCallNode = null;
boolean startFlow = false;
String startFlowDocumentId = null;
String startFlowId = null;
boolean checkFlowNode = false;
String outcomeToGo = outcome;
String actionToGo = fromAction;
if (currentFlow != null)
{
// JSF 2.2 section 7.4.2: When inside a flow, a view identifier has
// the additional possibility of being the id of any node within the
// current flow or the id of another flow
if (targetFlow != null)
{
if (flowHandler.isActive(facesContext, targetFlow.getDefiningDocumentId(), targetFlow.getId()))
{
// If the flow is already active, there is a chance that a node id has the same name as
// the flow and if that so, give preference to that node instead reenter into the flow.
FlowNode flowNode = targetFlow.getNode(outcome);
if (flowNode != null)
{
checkFlowNode = true;
}
else
{
startFlow = true;
}
}
else
{
startFlow = true;
}
}
else
{
// Check if thie
checkFlowNode = true;
}
}
else
{
if (targetFlow != null)
{
// start flow!
startFlow = true;
}
}
if (!startFlow)
{
for (Flow activeFlow : activeFlows)
{
FlowNode node = activeFlow.getNode(outcome);
if (node != null)
{
currentFlow = activeFlow;
break;
}
_FlowNavigationStructure flowNavigationStructure = _flowNavigationStructureMap.get(
activeFlow.getId());
navigationCase = getNavigationCaseFromFlowStructure(facesContext,
flowNavigationStructure, fromAction, outcome, viewId);
if (navigationCase != null)
{
currentFlow = activeFlow;
break;
}
}
}
// If is necessary to enter a flow or there is a current
// flow and it is necessary to check a flow node
if (startFlow || (checkFlowNode && currentFlow != null))
{
boolean complete = false;
boolean checkNavCase = true;
while (!complete && (startFlow || checkFlowNode))
{
if (startFlow)
{
if (flowHandler.isActive(facesContext, targetFlow.getDefiningDocumentId(), targetFlow.getId()))
{
// Add the transition to exit from the flow
Flow baseReturnFlow = navigationContext.getCurrentFlow(facesContext);
// This is the part when the pseudo "recursive call" is done.
while (baseReturnFlow != null && !(baseReturnFlow.getDefiningDocumentId().equals(