/// <summary> /// Builds the next element. /// </summary> /// <param name="runner">The runner.</param> /// <param name="currentElement">The current element.</param> /// <param name="endElement">The end element.</param> /// <param name="wfInstance">The wf instance.</param> private void BuildNextElement(WFRunner runner, WFElement currentElement,WFElement endElement, Workflow wfInstance) { WFElement outElement = null; if (currentElement.GetType() == typeof (Boundary)) { // This should only be entered into during the top level invocation // i.e. for the "Start" boundary itself. string nextActivity = currentElement.NextActivityID(); //TransformationEngine.Call aCall = // wfInstance.Call.Find(x => x.activityID.Equals(nextActivity)); TransformationEngine.Call aCall = wfInstance.Call.Find(x=>x.activityID.Equals(nextActivity));//[WorkflowFactory.IndexOfActivity(nextActivity)]; if ( null != aCall ) { // Create and add the new call...set this boundary as one of it's predecessors outElement = new Call(aCall, wfInstance); outElement.PreviousElements.Add(currentElement); runner.WorkflowElements.Add(outElement); BuildNextElement(runner, outElement, endElement, wfInstance); } else { if (currentElement.NextActivityID().Equals(endElement.GetActivityID())) { // Empty workflow...just add the start as a previous element to the end. endElement.PreviousElements.Add(currentElement); } } } else if (currentElement.GetType() == typeof(Call)) { ConstructCall(runner, currentElement, endElement, wfInstance); } else if (currentElement.GetType() == typeof(Decision)) { TransformationEngine.Decision decision = ((Decision) currentElement).DecisionModel; string successID = decision.successPathID; string failID = decision.failPathID; currentElement.DefaultNextActivityID = successID; if (null == runner.WorkflowElements.Find(x => (x.GetActivityID().Equals(successID)))) { // Find the item that this is // Construct the Success Branch ConstructDecisionBranch(runner,currentElement,successID,endElement,wfInstance); } if (null == runner.WorkflowElements.Find(x => x.GetActivityID().Equals(failID))) { // Find the item that this is // Construct the Fail Branch ConstructDecisionBranch(runner, currentElement, failID, endElement, wfInstance); } } }
/// <summary> /// Constructs the call. /// </summary> /// <param name="runner">The runner.</param> /// <param name="currentElement">The current element.</param> /// <param name="endElement">The end element.</param> /// <param name="wfInstance">The wf instance.</param> private void ConstructCall(WFRunner runner, WFElement currentElement, WFElement endElement, Workflow wfInstance) { WFElement outElement = null; Call theCall = (Call) currentElement; string callToDecision = theCall.CallModel().CallToDecision; string callToBoundary = theCall.CallModel().CallToBoundary; TransformationEngine.Boundary calledBoundary = (!string.IsNullOrEmpty(callToBoundary)) ? wfInstance.Boundary[WorkflowFactory.IndexOfActivity(callToBoundary)] : null; TransformationEngine.Decision calledDecision = (!string.IsNullOrEmpty(callToDecision)) ? wfInstance.Decision[WorkflowFactory.IndexOfActivity(callToDecision)] : null; if (null != calledBoundary ) { if (calledBoundary.Type.Equals(TransformationEngine.BoundaryType.End)) { if( (null != calledDecision ) && (null == currentElement.PreviousElements.Find(x=>x.GetActivityID().Equals(calledDecision.activityID)))) { throw new Exception( "Call Cannot be Connected to a Decision and End Elements without having parsed the Decision"); } currentElement.DefaultNextActivityID = endElement.GetActivityID(); endElement.PreviousElements.Add(currentElement); return; // If I've hit an END Boundary node, no need to look at the Decision node } } if (null != calledDecision) { if (null != currentElement.PreviousElements.Find(x => x.GetActivityID().Equals(calledDecision.activityID))) { throw new Exception("Decision was already connected to this Call"); } else { outElement = new Decision(calledDecision, wfInstance); // Add the Call to the Decision's PreviousElements outElement.PreviousElements.Add(currentElement); // Set Default Next Activity ID currentElement.DefaultNextActivityID = outElement.GetActivityID(); // Add the Decision to the Workflow runner.WorkflowElements.Add(outElement); // Try to build next Element BuildNextElement(runner, outElement, endElement, wfInstance); } } }