public Statements.WorkflowActivity Parse(string key, string workflowDefinition, IEnumerable <ActivitySetting> activitySettings) { var settings = GetActivitySettings(); var flow = new Statements.WorkflowActivity(); var v1 = new Variable <string>("v1"); flow.Variables.Add(v1); var third = WorkflowBuilder.CreateServer(settings.ElementAt(2), "节点3", "'1'", null, v1, flow.CustomActivityResult, null, null); var second = WorkflowBuilder.CreateSubProcess(settings.ElementAt(1) , "子流程-节点2" , new Dictionary <string, string>() { { "error", this._finishRule } } , null, null , third); SequenceWorkflowParser.Second = second.Action as SubProcess; flow.Body.StartNode = WorkflowBuilder.CreateHuman(settings.ElementAt(0) , "节点1" , new GetUsers(this._actionerRule) , flow.CustomActivityResult , null , second); SequenceWorkflowParser.First = (flow.Body.StartNode as FlowStep).Action as Human; return(flow); }
public Statements.WorkflowActivity Parse(string key, string workflowDefinition, IEnumerable <ActivitySetting> activitySettings) { var settings = GetActivitySettings(); var flow = new Statements.WorkflowActivity(); ParallelWorkflowParser.Human = WorkflowBuilder.CreateHuman(settings.ElementAt(1) , "并行子节点1" , new GetUsers(this._actionerRule) , null); ParallelWorkflowParser.SubProcess = WorkflowBuilder.CreateSubProcess(settings.ElementAt(2) , "并行子节点2" , new Dictionary <string, string>() { { "error", this._finishRule } } , null); flow.Body.StartNode = WorkflowBuilder.CreateParallel(settings.ElementAt(0) , "并行节点" , this._completion , null , ParallelWorkflowParser.Human , ParallelWorkflowParser.SubProcess); Parallel = (flow.Body.StartNode as FlowStep).Action as Parallel; return(flow); }
public HumanWorkflow() { this.DisplayName = "NTFE Workflow"; this.Body = new Flowchart(); this.CustomResult = new Variable <string>("CustomResult"); this.Body.StartNode = WorkflowBuilder.CreateHuman(new ServerSetting(0, "节点1", "", "", null, null, false) , "节点1" , o => new string[] { } //{ "user1", "user2", "user3" } , this.CustomResult , null , null); }
//通过Flowchart节点和自定义活动列表解析NTFE-BPM活动树 private Taobao.Workflow.Activities.Statements.WorkflowActivity ParseWorkflowActivity(XElement root , IList <ActivitySetting> activitySettings , bool isCacheMetaData) { var activity = new WorkflowActivity(); var variableElements = root.Descendants("Variable").ToList(); //设置变量集合 this.SetVariablesForActivity(variableElements, activity); var nodeDataElements = root.Descendants("NodeData") .Where(o => o.Attribute("Category").Value != "Comment") .ToList(); var linkDataElements = root.Descendants("LinkData").ToList(); var flowNodes = new Dictionary <string, FlowNodeInfo>(); //定义点集合 var temp = new List <string>(); foreach (var nodeDataElement in nodeDataElements) { var category = nodeDataElement.Attribute("Category").Value; if (category == "HumanPar" || category == "ServerPar" || category == "ChildPar" || category == "Start") { continue; } var activityName = nodeDataElement.Attribute("Text").Value; var key = nodeDataElement.Attribute("Key").Value; if (temp.Contains(activityName)) { throw new InvalidOperationException("流程中包括重复名称的节点,请检查!"); } temp.Add(activityName); var activitySetting = activitySettings.FirstOrDefault(o => o.ActivityName == activityName); if (activitySetting == null) { throw new Exception(string.Format(@"解析出错,找不到名称为“{0}”的ActivitySetting", activityName)); } Taobao.Activities.Statements.FlowStep flowStep = null; if (activitySetting is HumanSetting) { var humanSetting = activitySetting as HumanSetting; //创建人工节点 flowStep = WorkflowBuilder.CreateHuman(activitySetting , activitySetting.ActivityName , new GetUsers(humanSetting.ActionerRule.Scripts) , activity.CustomActivityResult , new Dictionary <string, Taobao.Activities.Statements.FlowNode>() , null); } else if (activitySetting is ServerSetting) { var customSetting = activitySetting as CustomSetting; var serverSetting = activitySetting as ServerSetting; var resultTo = activity.Variables.ToList().FirstOrDefault(o => o.Name == serverSetting.ResultTo); //创建人工节点 flowStep = WorkflowBuilder.CreateServer(activitySetting , activitySetting.ActivityName , serverSetting.Script , customSetting.FinishRule.Scripts , resultTo != null ? (Variable <string>)resultTo : null , activity.CustomActivityResult , new Dictionary <string, Taobao.Activities.Statements.FlowNode>() , null); } else if (activitySetting is SubProcessSetting) { var customSetting = activitySetting as CustomSetting; var subProcessSetting = activitySetting as SubProcessSetting; //创建子流程节点 flowStep = WorkflowBuilder.CreateSubProcess(activitySetting , activitySetting.ActivityName , customSetting.FinishRule.Scripts , activity.CustomActivityResult , new Dictionary <string, Taobao.Activities.Statements.FlowNode>() , null); } else if (activitySetting is ParallelSetting) { IList <Custom> customs = new List <Custom>(); //遍历customs var customParElements = nodeDataElements.Where(o => o.Attribute("SubGraphKey") != null && o.Attribute("SubGraphKey").Value == key).ToList(); foreach (var customParElement in customParElements) { var customeCategory = customParElement.Attribute("Category").Value; var customeActivityName = customParElement.Attribute("Text").Value; if (temp.Contains(customeActivityName)) { throw new InvalidOperationException("流程中包括重复名称的节点,请检查!"); } temp.Add(customeActivityName); var customActivitySetting = activitySettings.FirstOrDefault(o => o.ActivityName == customeActivityName); if (customActivitySetting == null) { throw new Exception(string.Format(@"解析出错,找不到名称为“{0}”的ActivitySetting", customeActivityName)); } if (customActivitySetting is HumanSetting) { var humanSetting = customActivitySetting as HumanSetting; //创建并行容器中人工节点 var human = WorkflowBuilder.CreateHuman(customActivitySetting , customActivitySetting.ActivityName , new GetUsers(humanSetting.ActionerRule.Scripts) , activity.CustomActivityResult); customs.Add(human); } else if (customActivitySetting is ServerSetting) { var customSetting = customActivitySetting as CustomSetting; var serverSetting = customActivitySetting as ServerSetting; var resultTo = activity.Variables.ToList().FirstOrDefault(o => o.Name == serverSetting.ResultTo); //创建并行容器中自动节点 var server = WorkflowBuilder.CreateServer(customActivitySetting , customActivitySetting.ActivityName , serverSetting.Script , customSetting.FinishRule.Scripts , resultTo != null ? (Variable <string>)resultTo : null , activity.CustomActivityResult); customs.Add(server); } else if (customActivitySetting is SubProcessSetting) { var customSetting = customActivitySetting as CustomSetting; var subProcessSetting = customActivitySetting as SubProcessSetting; //创建并行容器中子流程节点 var subprocess = WorkflowBuilder.CreateSubProcess(customActivitySetting , customActivitySetting.ActivityName , customSetting.FinishRule.Scripts , activity.CustomActivityResult); customs.Add(subprocess); } } //创建并行容器节点 flowStep = WorkflowBuilder.CreateParallel(activitySetting , activitySetting.ActivityName , (activitySetting as ParallelSetting).CompletionCondition , null , customs.ToArray()); } flowNodes.Add(key, new FlowNodeInfo() { FlowStep = flowStep }); } if (nodeDataElements.Count(o => o.Attribute("Category").Value == "Start") != 1) { throw new InvalidOperationException("不包括Start开始节点"); } //创建流程节点 this.BuildFlowNode(flowNodes, linkDataElements); var startLinkElement = linkDataElements.FirstOrDefault(o => o.Attribute("From").Value == "Start"); if (startLinkElement == null) { throw new InvalidOperationException("不包含Start到初始点连线"); } activity.Body.StartNode = flowNodes[startLinkElement.Attribute("To").Value].FlowStep; //初始化Flowchart节点的元素 if (isCacheMetaData) { CacheMetadata(activity.Body); } return(activity); }
public void AppendHumanActivity(Guid processId, Client.AppendHumanMode mode, Client.AppendHumanSetting appendHumanSetting) { //HACK:动态节点出于重复考虑,总是会先移除重名的节点,此设计会存在意外的情况 string reason; HumanSetting currentHumanSetting; if (!this.CanAppendHumanActivity(processId, mode, appendHumanSetting.ActivityName, out currentHumanSetting, out reason)) { throw new InvalidOperationException(reason); } if (appendHumanSetting == null) { throw new ArgumentNullException("humanSetting"); } var process = this.GetProcessById(processId); var currentProcessType = process.ProcessType; //获取所有节点设置的副本 var clonedSettings = new List <ActivitySetting>(currentProcessType.ActivitySettings.Select(o => o.Clone())); var workflow = this._workflowParser.Parse(currentProcessType.Workflow.Serialized, clonedSettings); var originalWorkflowDefinition = currentProcessType.Workflow.Serialized; #region 查找节点信息 var currentNode = this.GetFlowStep(workflow, currentHumanSetting.ActivityName); var currentSetting = clonedSettings.FirstOrDefault(o => o.ActivityName == currentNode.Action.DisplayName) as HumanSetting; var nextNode = this.GetNextFlowStep(workflow, currentNode); if (currentNode == null || currentSetting == null) { throw new InvalidOperationException(string.Format( "没有在流程中找到节点“{0}”的定义", currentHumanSetting.ActivityName)); } #endregion #region 修改当前节点 clonedSettings.Remove(currentSetting); var finishRule = currentSetting.FinishRule.Scripts; //总是先移除避免多次重复追加 finishRule.Remove(appendHumanSetting.EnterFinishRuleName); //新增完成规则用于满足后进入新节点 //必须将新规则插入在第一个规则位置,避免原有规则的影响 用atMostOf?该细节不能出现在Model层 finishRule = new Dictionary <string, string>() { { appendHumanSetting.EnterFinishRuleName, string.Format("all('{0}')", appendHumanSetting.EnterAction) } } .Concat(finishRule) .ToDictionary(o => o.Key, o => o.Value); currentSetting = new HumanSetting(currentSetting.FlowNodeIndex , currentSetting.ActivityName , currentSetting.Actions , currentSetting.SlotCount , currentSetting.SlotMode , currentSetting.Url , currentSetting.StartRule , currentSetting.ActionerRule , new FinishRule(finishRule) , currentSetting.EscalationRule , currentSetting.IsChildOfActivity); clonedSettings.Add(currentSetting); #endregion #region 新增节点设置 var newHumanSetting = new HumanSetting(0//此时无需设置实际值,最终创建流程类型时会由转换器填充实际值 , appendHumanSetting.ActivityName , appendHumanSetting.Actions , appendHumanSetting.SlotCount , (HumanSetting.SlotDistributionMode)(int) appendHumanSetting.SlotMode , appendHumanSetting.Url , null , new HumanActionerRule(appendHumanSetting.ActionerRule) , this.GetFinishRule(appendHumanSetting) , null , false); clonedSettings.Add(newHumanSetting); #endregion #region 将新节点与左右节点连接 FlowStep newNode = null; if (mode == Client.AppendHumanMode.Wait) { newNode = WorkflowBuilder.CreateHuman(newHumanSetting , newHumanSetting.ActivityName , new GetUsers(appendHumanSetting.ActionerRule) , null , null , currentNode);//总是返回当前节点 } else if (mode == Client.AppendHumanMode.Continues) { newNode = WorkflowBuilder.CreateHuman(newHumanSetting , newHumanSetting.ActivityName , new GetUsers(appendHumanSetting.ActionerRule) , workflow.CustomActivityResult , nextNode == null ? null //HACK:下一节点的进入与否将根据新节点的完成规则而定,若满足则继续,若不满足则流程结束,常见于加签的情况 : new Dictionary <string, FlowNode>() { { appendHumanSetting.FinishRuleName, nextNode } } , null); } //总是先移除避免多次重复追加 (currentNode.Next as FlowSwitch <string>).Cases.Remove(appendHumanSetting.EnterFinishRuleName); (currentNode.Next as FlowSwitch <string>).Cases.Add(appendHumanSetting.EnterFinishRuleName, newNode); //总是先移除避免多次重复追加 workflow.Body.Nodes.Remove(this.GetFlowStep(workflow, newHumanSetting.ActivityName)); //由于解析需要应同时补充此元数据 workflow.Body.Nodes.Add(newNode); #endregion //创建新流程定义,动态变更 this._processService.DynamicChangeProcessType(process , this.CreateProcessType(currentProcessType.Name , this._workflowParser.Parse(workflow, originalWorkflowDefinition) , this._workflowParser.Parse(clonedSettings) , currentProcessType.Description , currentProcessType.Group , false)); }
public WorkflowActivity Parse(string key, string workflowDefinition, IEnumerable <ActivitySetting> activitySettings) { //本测试工程的大部分测试均基于此工作流定义,需谨慎变更 禁止修改 var flow = new Statements.WorkflowActivity(); IEnumerable <ActivitySetting> settings; if (key.IndexOf("SubProcess") >= 0) { //0 节点1 同意|否决 //1 节点2 完成 //2 节点3 完成 settings = GetSubProcessActivitySettings(); var third = WorkflowBuilder.CreateServer(settings.ElementAt(2) , "节点3" , "'1'" , null , null , flow.CustomActivityResult , null , null); var second = WorkflowBuilder.CreateHuman(settings.ElementAt(1) , "节点2" , new GetUsers("originator") , flow.CustomActivityResult , new Dictionary <string, FlowNode>() { { "同意", third } } , null); flow.Body.StartNode = WorkflowBuilder.CreateHuman(settings.ElementAt(0) , "节点1" , new GetUsers("originator") , flow.CustomActivityResult , new Dictionary <string, FlowNode>() { { "同意", second } } , null); } else if (key.IndexOf("ParentProcess") >= 0) { //0 节点1 同意|否决 //1 节点2 完成 //2 节点3 完成 //3 节点4 完成 settings = GetParentProcessActivitySettings(); var forth = WorkflowBuilder.CreateServer(settings.ElementAt(3) , "节点4" , "'1'" , null , null , flow.CustomActivityResult , null , null); var third = WorkflowBuilder.CreateHuman(settings.ElementAt(2) , "节点3" , new GetUsers("originator") , flow.CustomActivityResult , new Dictionary <string, FlowNode>() { { "同意", forth } } , null); var second = WorkflowBuilder.CreateSubProcess(settings.ElementAt(1) , "节点2" , null , flow.CustomActivityResult , null , third); flow.Body.StartNode = WorkflowBuilder.CreateHuman(settings.ElementAt(0) , "节点1" , new GetUsers("originator") , flow.CustomActivityResult , new Dictionary <string, FlowNode>() { { "同意", second } } , null); } else { settings = GetTemplateProcessActivitySettings(); var forth = WorkflowBuilder.CreateServer(settings.ElementAt(3) , "节点4" , "'1'" , null , null , flow.CustomActivityResult , null , null); var third = WorkflowBuilder.CreateHuman(settings.ElementAt(2) , "节点3" , new GetUsers("originator") , flow.CustomActivityResult , new Dictionary <string, FlowNode>() { { "同意", forth } } , null); var second = WorkflowBuilder.CreateHuman(settings.ElementAt(1) , "节点2" , new GetUsers("originator") , flow.CustomActivityResult , new Dictionary <string, FlowNode>() { { "同意", third } } , null); flow.Body.StartNode = WorkflowBuilder.CreateHuman(settings.ElementAt(0) , "节点1" , new GetUsers("originator") , flow.CustomActivityResult , new Dictionary <string, FlowNode>() { { "同意", second } } , null); } return(flow); }
public virtual Statements.WorkflowActivity Parse(string key, string workflowDefinition, IEnumerable <ActivitySetting> activitySettings) { //是否是子流程测试模式 var isSubMode = key.Contains(BaseTest.SubFlag); var settings = isSubMode ? GetSubProcessActivitySettings() : GetActivitySettings(); var flow = new Statements.WorkflowActivity(); var v1 = new Variable <string>("v1"); flow.Variables.Add(v1); //0 节点1 同意|否决 //2 节点2 完成 startRule 10s //4 节点3 完成 OneAtOnce slot=2 发起人->主管->username1 //6 节点4 Server //8 并行节点 子节点1完成则完成 //8 并行子节点1 发起人 startRule 无限期延迟 需要提前唤醒 //8 并行子节点2 主管 //9 节点6 完成 AllAtOnce slot=2 发起人 同意|否决 //11 节点7 完成 AllAtOnce slot=1 发起人|主管 同意|否决 //根据参数追加一个子流程节点 //13 节点8 子流程节点 var eighth = isSubMode ? WorkflowBuilder.CreateSubProcess(settings.ElementAt(9), BaseTest.SubProcessNode, null, null, null, null) : null; var seventh = WorkflowBuilder.CreateHuman(settings.ElementAt(8) , "节点7" , new GetUsers("originator", "getSuperior()") , flow.CustomActivityResult , null , isSubMode ? eighth : null); var sixth = WorkflowBuilder.CreateHuman(settings.ElementAt(7) , "节点6" , new GetUsers("originator") , flow.CustomActivityResult , null , seventh); var parallel_1 = WorkflowBuilder.CreateHuman(settings.ElementAt(5), "并行子节点1", new GetUsers("originator"), null); var parallel_2 = WorkflowBuilder.CreateHuman(settings.ElementAt(6), "并行子节点2", new GetUsers("getSuperior()"), null); //true var parallel = WorkflowBuilder.CreateParallel(settings.ElementAt(4), "并行节点", "true", sixth, parallel_1, parallel_2); var forth = WorkflowBuilder.CreateServer(settings.ElementAt(3) , "节点4", "'1'", null, v1, flow.CustomActivityResult, null, parallel); var third = WorkflowBuilder.CreateHuman(settings.ElementAt(2) , "节点3" , new GetUsers("originator", "getSuperior()", BaseTest.VariableUser) , flow.CustomActivityResult , null , forth); var second = WorkflowBuilder.CreateHuman(settings.ElementAt(1) , "节点2" , new GetUsers("originator") , flow.CustomActivityResult , null , third); flow.Body.StartNode = WorkflowBuilder.CreateHuman(settings.ElementAt(0) , "节点1" , new GetUsers("originator") , flow.CustomActivityResult , new Dictionary <string, FlowNode>() { { "同意", second } } , null); //有需要可在此初始化元数据 //Taobao.Activities.ActivityUtilities.InitializeActivity(flow); return(flow); }
//通过Flowchart节点和自定义活动列表解析NTFE-BPM活动树 private Statements.WorkflowActivity ParseWorkflowActivity(System.Activities.Statements.Flowchart flowchart , IList <ActivitySetting> activitySettings , bool isCacheMetaData) { var activity = new WorkflowActivity(); //设置变量集合 this.SetVariablesForActivity(flowchart.Variables, activity); var flowNodes = new Dictionary <int, FlowNodeInfo>(); //定义点集合 var flowLines = new List <FlowLineInfo>(); //定义线段集合 var temp = new List <string>(); foreach (var wf_node in flowchart.Nodes) { if (wf_node is System.Activities.Statements.FlowSwitch <string> ) { var wf_FlowSwitch = wf_node as System.Activities.Statements.FlowSwitch <string>; var literal = (System.Activities.Expressions.Literal <string>)wf_FlowSwitch.Expression; if (literal == null || literal.Value == string.Empty) { throw new Exception(@"流程中包括名称为空的节点,请检查!"); } var expression = literal.Value; var activityName = ParseActivityName(expression); if (temp.Contains(activityName)) { throw new InvalidOperationException("流程中包括重复名称的节点,请检查!"); } temp.Add(activityName); var activitySetting = activitySettings.FirstOrDefault(o => o.ActivityName == activityName); if (activitySetting == null) { throw new Exception(string.Format(@"解析出错,找不到名称为“{0}”的ActivitySetting", activityName)); } Taobao.Activities.Statements.FlowStep flowStep = null; if (activitySetting is HumanSetting) { var humanSetting = activitySetting as HumanSetting; //创建人工节点 flowStep = WorkflowBuilder.CreateHuman(activitySetting , activitySetting.ActivityName , new GetUsers(humanSetting.ActionerRule.Scripts) , activity.CustomActivityResult , new Dictionary <string, Taobao.Activities.Statements.FlowNode>() , null); } else if (activitySetting is ServerSetting) { var customSetting = activitySetting as CustomSetting; var serverSetting = activitySetting as ServerSetting; //创建自动节点 var resultTo = activity.Variables.ToList().FirstOrDefault(o => o.Name == serverSetting.ResultTo); flowStep = WorkflowBuilder.CreateServer(activitySetting , activitySetting.ActivityName , serverSetting.Script , customSetting.FinishRule.Scripts , resultTo != null ? (Variable <string>)resultTo : null , activity.CustomActivityResult , new Dictionary <string, Taobao.Activities.Statements.FlowNode>() , null); } flowNodes.Add(wf_FlowSwitch.GetHashCode(), new FlowNodeInfo() { WF_FlowNode = wf_FlowSwitch, FlowStep = flowStep }); } else if (wf_node is System.Activities.Statements.FlowStep) { var wf_FlowStep = wf_node as System.Activities.Statements.FlowStep; if (typeof(System.Activities.Statements.Parallel).IsAssignableFrom(wf_FlowStep.Action.GetType())) { IList <Custom> customs = new List <Custom>(); var wf_Parallel = wf_FlowStep.Action as System.Activities.Statements.Parallel; foreach (var wf_Activity in wf_Parallel.Branches) { if (typeof(ICustom).IsAssignableFrom(wf_Activity.GetType())) { var expression = (wf_Activity as ICustom).DisplayName; if (string.IsNullOrEmpty(expression)) { throw new Exception(@"流程中包括名称为空的节点,请检查!"); } var activityName = ParseActivityName(expression); if (temp.Contains(activityName)) { throw new InvalidOperationException("流程中包括重复名称的节点,请检查!"); } temp.Add(activityName); var activitySetting = activitySettings.FirstOrDefault(o => o.ActivityName == activityName); if (activitySetting == null) { throw new Exception(string.Format(@"解析出错,找不到名称为“{0}”的ActivitySetting", activityName)); } if (activitySetting is HumanSetting) { var humanSetting = activitySetting as HumanSetting; var human = WorkflowBuilder.CreateHuman(activitySetting , activitySetting.ActivityName , new GetUsers(humanSetting.ActionerRule.Scripts) , activity.CustomActivityResult); customs.Add(human); } else if (activitySetting is ServerSetting) { var customSetting = activitySetting as CustomSetting; var serverSetting = activitySetting as ServerSetting; var resultTo = activity.Variables.ToList().FirstOrDefault(o => o.Name == serverSetting.ResultTo); var server = WorkflowBuilder.CreateServer(activitySetting , activitySetting.ActivityName , serverSetting.Script , customSetting.FinishRule.Scripts , resultTo != null ? (Variable <string>)resultTo : null , activity.CustomActivityResult); customs.Add(server); } } } var p_expression = wf_Parallel.DisplayName; if (string.IsNullOrEmpty(p_expression)) { throw new Exception(@"流程中包括名称为空的节点,请检查!"); } var p_activityName = ParseActivityName(p_expression); if (temp.Contains(p_activityName)) { throw new InvalidOperationException("流程中包括重复名称的节点,请检查!"); } temp.Add(p_activityName); var p_activitySetting = activitySettings.FirstOrDefault(o => o.ActivityName == p_activityName); if (p_activitySetting == null) { throw new Exception(string.Format(@"解析出错,找不到名称为“{0}”的ActivitySetting", p_activityName)); } var flowStep = WorkflowBuilder.CreateParallel(p_activitySetting , p_activitySetting.ActivityName , (p_activitySetting as ParallelSetting).CompletionCondition , null , customs.ToArray()); flowNodes.Add(wf_FlowStep.GetHashCode(), new FlowNodeInfo() { WF_FlowNode = wf_FlowStep, FlowStep = flowStep }); } } } var flowNode = flowchart.StartNode; if (flowNode == null) { throw new InvalidOperationException("不包括StartNode开始节点"); } //创建流程节点 BuildFlowNode(flowNode, flowNodes, flowLines, 0); //将节点树连接到NTFE activity.Body.StartNode = flowNodes[flowNode.GetHashCode()].FlowStep; //初始化Flowchart节点的元素 if (isCacheMetaData) { CacheMetadata(activity.Body); } return(activity); }