static void Main(string[] args) { Console.WriteLine("◆実行したいワークフローを選択してください。"); Console.WriteLine(" 1: Sequenceのサンプル"); Console.WriteLine(" 2: Flowchartのサンプル"); Console.WriteLine(" 3: StateMachineのサンプル"); Console.Write("何番を実行しますか?:"); var num = Console.ReadLine(); Console.WriteLine(""); Activity act; if (num == "1") { act = new Sequence(); } else if (num == "2") { act = new Flowchart(); } else if (num == "3") { act = new StateMachine(); } else { throw new NotSupportedException(); } //ワークフローの実行 WorkflowInvoker.Invoke(act); }
/// <summary> /// The create state machine. /// </summary> /// <returns> /// </returns> private static StateMachine CreateStateMachine() { var state1 = new State { DisplayName = "state1" }; var state2 = new State { DisplayName = "state2" }; var state3 = new State { IsFinal = true, DisplayName = "state3" }; state1.Transitions.Add(new Transition { To = state2 }); state2.Transitions.Add(new Transition { To = state3 }); var stateMachine = new StateMachine { InitialState = state1, States = { state1, state2, state3 } }; return stateMachine; }
private static List<object> FindDescendentFromStateMachine(StateMachine machine, object descendent) { List<object> path = new List<object>(); path.Add(machine); foreach (State state in machine.States) { if (state == descendent) { break; } else if (state.Entry == descendent) { path.Add(state); break; } else if (state.Exit == descendent) { path.Add(state); break; } else { Transition foundTransition = null; bool transitionAlone = false; foreach (Transition transition in state.Transitions) { foundTransition = transition; if (transition == descendent) { transitionAlone = true; break; } else if (transition.Trigger == descendent) { break; } else if (transition.Action == descendent) { break; } else if (transition.Condition == descendent) { break; } else { foundTransition = null; } } if (foundTransition != null) { path.Add(state); if (!transitionAlone) { path.Add(foundTransition); } break; } bool isVariableError = false; foreach (Variable variable in state.Variables) { if (variable.Default == descendent) { isVariableError = true; } } if (isVariableError) { path.Add(state); break; } } } path.Add(descendent); return path; }
private static List<object> FindRelativePath(StateMachine machine, object descendent) { List<object> path = FindDescendentFromStateMachine(machine, descendent); path.Reverse(); return path; }
public static Flowchart ConvertToFlowchart(XmlDocument jobSpec) { //Flowchart chart = new Flowchart(); StateMachine chart = new StateMachine(); int cntr = 1; try { var modules = from m in XDocument.Parse(jobSpec.InnerXml).Descendants() where m.Name.LocalName.Equals("Module") select new MyFlowStep(new XElement(m)); Dictionary<string, Object> enrichedSteps = new Dictionary<string, Object>(); foreach (MyFlowStep m in modules) { //for debugging if (cntr++ >= 5) break; foreach (string input in m.Inputs) { var p = from ip in modules where ip.Name.Equals(input) select ip; FlowNode fn = m.Activity as FlowNode; if (p != null && p.First<MyFlowStep>() != null && fn != null) { MyFlowStep pfs = p.First<MyFlowStep>(); #region identify which tyoe of step that the input is bool isFlowSwitch = false; MyFlowSwitch ms = enrichedSteps[pfs.Name] as MyFlowSwitch; if (ms != null) isFlowSwitch = true; #endregion if (enrichedSteps.ContainsKey(pfs.Name)) { //first time -- no prior add destination to step if (enrichedSteps[pfs.Name] != null && !isFlowSwitch && ((MyFlowStep)enrichedSteps[pfs.Name]).Activity.Next == null) { ((MyFlowStep)enrichedSteps[pfs.Name]).SetNextActivity(m.Name, fn); } //multiple inputs encountered else if (enrichedSteps[pfs.Name] != null && !isFlowSwitch && ((MyFlowStep)enrichedSteps[pfs.Name]).Activity.Next != null) { //convert FlowStep to Parallel Step MyFlowSwitch mpls = new MyFlowSwitch(((MyFlowStep)enrichedSteps[pfs.Name]).Elem); mpls.Activity.Cases.Add(m.Name, m.Activity); enrichedSteps[pfs.Name] = mpls; foreach (string name in enrichedSteps.Keys) { MyFlowStep cfs = enrichedSteps[name] as MyFlowStep; if (cfs != null && cfs.NextName == pfs.Name) { ((MyFlowStep)enrichedSteps[pfs.Name]).SetNextActivity(mpls.Name, mpls.Activity); } else { MyFlowSwitch cfsw = enrichedSteps[name] as MyFlowSwitch; if (cfsw != null) { foreach (string s in cfsw.Activity.Cases.Keys) { if (s == name) { cfsw.Activity.Cases.Remove(s); cfsw.Activity.Cases.Add(s, mpls.Activity); break; } } } } } } //add to multiple inputs else if (enrichedSteps[pfs.Name] != null && isFlowSwitch) { //convert FlowStep to Parallel Step ((MyFlowSwitch)enrichedSteps[pfs.Name]).Activity.Cases.Add(m.Name, m.Activity); } //else if (((MyFlowStep)enrichedSteps[pfs.Name]) == null) //{ // MyFlowSwitch mpls = enrichedSteps[pfs.Name] as MyFlowSwitch; // if (mpls != null) // { // mpls.Activity.Cases.Add(m.Name, m.Activity); // enrichedSteps[pfs.Name] = mpls; // } // //else throw error //} } else { //pfs.SetNextActivity(fn); enrichedSteps[pfs.Name] = pfs; } } } if (!enrichedSteps.ContainsKey(m.Name)) enrichedSteps.Add(m.Name, m); } chart.DisplayName = ""; // jobSpec.SelectSingleNode("/Job").Attributes["name"].Value; MyBaseStep mfs = null; foreach (KeyValuePair<string, Object> kvp in enrichedSteps) { ////for debugging //if (cntr++ >= 2) // break; mfs = kvp.Value as MyFlowStep; if (mfs != null) { if (chart.StartNode == null) chart.StartNode = ((MyFlowStep)mfs).Activity; chart.Nodes.Add(((MyFlowStep)mfs).Activity); } else { mfs = kvp.Value as MyFlowSwitch; if (mfs != null) { if (chart.StartNode == null) chart.StartNode = ((MyFlowSwitch)mfs).Activity; chart.Nodes.Add(((MyFlowSwitch)mfs).Activity); } } if (mfs != null && mfs.Attributes != null) { foreach (XAttribute attr in mfs.Attributes) { string attrName = String.Format("{0}_{1}", kvp.Key, attr.Name.LocalName); Variable v = Variable.Create(attrName, Type.GetType("System.String"), VariableModifiers.ReadOnly); chart.Variables.Add(v); } } } } catch (Exception ex) { } return chart; }
/// <summary> /// Creates a large StateMachine /// </summary> /// <param name="stateCount"> /// The state Count. /// </param> /// <returns> /// A StateMachine /// </returns> internal static Activity CreateLargeStateMachine(int stateCount) { var initialState = new State { DisplayName = "State1", }; var largeStateMachine = new StateMachine { InitialState = initialState, States = { initialState } }; var prevState = initialState; for (var i = 1; i < stateCount; i++) { var state = new State { DisplayName = string.Format("State{0}", i + 1), IsFinal = i == stateCount - 1 }; largeStateMachine.States.Add(state); prevState.Transitions.Add(new Transition { DisplayName = string.Format("T{0}", i), To = state }); prevState = state; } return largeStateMachine; }
public static bool ConvertToFlowchart(ref StateMachine chart, XmlDocument jobSpec) { int cntr = 1; Dictionary<string, Object> enrichedSteps = new Dictionary<string, Object>(); try { var modules = from m in XDocument.Parse(jobSpec.InnerXml).Descendants() where m.Name.LocalName.Equals("Module") select new MyState(new XElement(m)); IEnumerable<MyState> myStates = modules as IList<MyState> ?? modules.ToList(); foreach (MyState m in myStates) { //for debugging //if (cntr++ >= 5) // break; IEnumerable<MyState> enumerable; foreach (string input in m.Inputs) { var myInputState = myStates.Where(ip => input != null && input.Equals(ip.Name)); enumerable = myInputState as IList<MyState> ?? myInputState.ToList(); if (myInputState != null && enumerable.First<MyState>() != null && m.State != null) { MyState inputState; inputState = enumerable.First<MyState>(); if (enrichedSteps.ContainsKey(inputState.Name)) { string transitionKey = String.Format("{0}_{1}", input, m.Name); if (!transitions.ContainsKey(transitionKey)) { Transition t = new Transition(); //t.DisplayName = transitionKey; t.To = m.State; transitions.Add(transitionKey, t); } ((MyState)enrichedSteps[input]).State.Transitions.Add(transitions[transitionKey]); } } } if (!enrichedSteps.ContainsKey(m.Name)) enrichedSteps.Add(m.Name, m); if (chart.InitialState == null) chart.InitialState = m.State; } chart.DisplayName = ""; // jobSpec.SelectSingleNode("/Job").Attributes["name"].Value; foreach (KeyValuePair<string, Object> kvp in enrichedSteps) { chart.States.Add(((MyState)kvp.Value).State); } } catch (Exception ex) { return false; } return true; }