private CaseStruct findFacesFlowCallMatch(FacesContext context,
String fromAction, String outcome, String toFlowDocumentId) {
CaseStruct result = null;
FlowHandler flowHandler = context.getApplication().getFlowHandler();
if (null == flowHandler) {
return null;
}
Flow currentFlow = flowHandler.getCurrentFlow(context);
Flow newFlow = null;
FlowCallNode facesFlowCallNode = null;
if (null != currentFlow) {
FlowNode node = currentFlow.getNode(outcome);
if (node instanceof FlowCallNode) {
facesFlowCallNode = (FlowCallNode) node;
String flowId = facesFlowCallNode.getCalledFlowId(context);
String flowDocumentId = facesFlowCallNode.getCalledFlowDocumentId(context);
if (null != flowId) {
newFlow = flowHandler.getFlow(context, flowDocumentId, flowId);
if (null != newFlow) {
String startNodeId = newFlow.getStartNodeId();
result = synthesizeCaseStruct(context, newFlow, fromAction, startNodeId);
if (null == result) {
assert(null != currentFlow);
// If no CaseStruct can be synthesized, we must execute the
// navigation handler algorithm to try to find the CaseStruct
// for the start node. However, in order to do that, we
// must enter the new flow. To preserve the intergity
// of the state machine, we enter the flow now, and mark
// that we must not enter it later.
try {
setDidTransition(context, true);
flowHandler.transition(context, currentFlow, newFlow, null, startNodeId);
result = getViewId(context, fromAction, startNodeId, toFlowDocumentId);
}
finally {
if (null == result) {
// If we did not find a CaseStruct, preserve the
// integrity of the state machine by transitioning
// out of the flow.
flowHandler.transition(context, newFlow, currentFlow, null, outcome);
setDidTransition(context, false);
}
}
}
}
}
}
} else {
// See if we are trying to enter a flow.
newFlow = flowHandler.getFlow(context, toFlowDocumentId, outcome);
if (null != newFlow) {
String startNodeId = newFlow.getStartNodeId();
result = synthesizeCaseStruct(context, newFlow, fromAction, startNodeId);
if (null == result) {
assert(null == currentFlow);
// If no CaseStruct can be synthesized, we must execute the
// navigation handler algorithm to try to find the CaseStruct
// for the start node. However, in order to do that, we
// must enter the new flow. To preserve the intergity
// of the state machine, we enter the flow now, and mark
// that we must not enter it later.
try {
setDidTransition(context, true);
flowHandler.transition(context, null, newFlow, null, startNodeId);
result = getViewId(context, fromAction, startNodeId, toFlowDocumentId);
}
finally {
if (null == result) {
// If we did not find a CaseStruct, preserve the
// integrity of the state machine by transitioning
// out of the flow.
flowHandler.transition(context, newFlow, null, null, outcome);
setDidTransition(context, false);
}
}
} else if (!outcome.equals(startNodeId) && null != result.navCase) {
((MutableNavigationCase)result.navCase).setFromOutcome(outcome);