private FlowStep GetFlowStep(WorkflowActivity workflow, string activityName) { return workflow.Body.Nodes.FirstOrDefault(o => o is FlowStep && (o as FlowStep).Action.DisplayName == activityName) as FlowStep; }
private FlowStep GetNextFlowStep(WorkflowActivity workflow, FlowStep step) { var flowSwitch = step.Next as FlowSwitch<string>; return flowSwitch.Cases.Count > 0 ? flowSwitch.Cases.First().Value as FlowStep : flowSwitch.Default as FlowStep; }
public virtual string Parse(WorkflowActivity workflowActivity, string originalWorkflowDefinition) { return Resource.WorkflowDefinition5; }
//将工作流转换为定义文本 public virtual string Parse(WorkflowActivity activity, string originalWorkflowDefinition) { return this._workflowConverterFactory.Create().Parse(activity, originalWorkflowDefinition); }
//设置变量集合 private void SetVariablesForActivity(System.Collections.ObjectModel.Collection<System.Activities.Variable> variables , WorkflowActivity activity) { foreach (var variable in variables) { //判断变量名称是否合法 if (Regex.IsMatch(variable.Name, @"[a-zA-Z][a-zA-Z_0-9]*")) { if (variable.GetType().IsGenericType) { var dataType = variable.GetType().GetGenericArguments()[0]; if (dataType == typeof(String)) activity.Variables.Add(new Taobao.Activities.Variable<String>(variable.Name)); else if (dataType == typeof(Int32)) activity.Variables.Add(new Taobao.Activities.Variable<Int32>(variable.Name)); else if (dataType == typeof(Int64)) activity.Variables.Add(new Taobao.Activities.Variable<Int64>(variable.Name)); } } } }
//通过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; }
string IWorkflowConverter.Parse(WorkflowActivity activity, string originalWorkflowDefinition) { return null; }
//设置变量集合 private void SetVariablesForActivity(List<XElement> variableElments , WorkflowActivity activity) { foreach (var variableElment in variableElments) { //当变量为设计器变量时跳过 if (variableElment.Attribute("Mode") != null && variableElment.Attribute("Mode").Value.Trim() == "design") continue; var variableName = variableElment.Attribute("Name").Value; //判断变量名称是否合法 if (Regex.IsMatch(variableName, @"[a-zA-Z][a-zA-Z_0-9]*")) activity.Variables.Add(new Taobao.Activities.Variable<String>(variableName)); } }
string IWorkflowConverter.Parse(WorkflowActivity activity, string originalWorkflowDefinition) { if (activity == null) throw new ArgumentException("activity is null."); #region 记录位置信息 //判断原始格式是否是Xaml格式 var isXaml = this.CheckIsXamlFormat(originalWorkflowDefinition); var location_dict = new Dictionary<string, string>(); IList<XElement> designVariableElements = new List<XElement>(); var element = XElement.Parse(originalWorkflowDefinition); if (isXaml) { var elements = element.DescendantNodes() .Select(o => o as XElement) .Where(o => o != null); //解析活动节点 var activityNode_elements = elements.Where(o => o.Name.LocalName == "FlowSwitch" || o.Name.LocalName == "FlowStep").ToList(); foreach (var activityNode_element in activityNode_elements) { var viewState_element = activityNode_element.Nodes() .Select(o => o as XElement) .Where(o => o.Name.LocalName == "WorkflowViewStateService.ViewState") .FirstOrDefault(); var point_element = viewState_element.DescendantNodes() .Select(o => o as XElement) .Where(o => o != null && o.Name.LocalName == "Point") .FirstOrDefault(); string parallelName = ""; if (activityNode_element.Name.LocalName == "FlowStep") { var activityNode_element_nodes = activityNode_element.Nodes().Select(o => o as XElement).Where(o => o != null).ToList(); //获取并行容器节点 var parallel_element = activityNode_element_nodes.FirstOrDefault(o => o.Name.LocalName == "Parallel"); if (parallel_element != null) { parallelName = parallel_element.Attribute("DisplayName").Value; } } //设置位置信息 location_dict[activityNode_element.Name.LocalName == "FlowSwitch" ? ReplaceExpression(activityNode_element.Attribute("Expression").Value) : parallelName] = point_element.Value.Replace(",", " "); } //UNDONE:目前WF4格式以及originalWorkflowDefinition无法得到设计器变量 } else { var nodeDataElements = element.Descendants("NodeData") .Where(o => o.Attribute("Category").Value != "Comment") .ToList(); foreach (var nodeDataElement in nodeDataElements) { var category = nodeDataElement.Attribute("Category").Value; if (category == "HumanPar" || category == "ServerPar" || category == "ChildPar") continue; var activityName = nodeDataElement.Attribute("Text").Value; var location = nodeDataElement.Attribute("Location") != null ? nodeDataElement.Attribute("Location").Value : "308 0"; //设置位置信息 location_dict[activityName] = location; } //获取设计器变量 var variableElements = element.Descendants("Variable"); variableElements.Where(o => o.Attribute("Mode").Value.ToLower() == "design").ToList().ForEach(o => { designVariableElements.Add(new XElement("Variable" , new XAttribute("Name", o.Attribute("Name").Value) , new XAttribute("Value", o.Attribute("Value").Value) , new XAttribute("Mode", "design"))); }); } #endregion var root = new XElement("FlowChart"); var variablesElement = new XElement("Variables"); //添加变量节点 foreach (var variable in activity.Variables) variablesElement.Add(new XElement("Variable" , new XAttribute("Name", variable.Name) , new XAttribute("Value", "") , new XAttribute("Mode", "flow"))); //遍历添加设计器变量 foreach (var variable in designVariableElements) variablesElement.Add(variable); root.Add(variablesElement); //添加开始节点 root.Add(new XElement("NodeData" , new XAttribute("Key", "Start") , new XAttribute("Category", "Start") , new XAttribute("Location", location_dict.ContainsKey("Start") ? location_dict["Start"] : "308 0") , new XAttribute("Text", "Start"))); var dict = new Dictionary<Taobao.Activities.Statements.FlowStep, string>(); int counter = 0; foreach (var node in activity.Body.Nodes) { if (node is Taobao.Activities.Statements.FlowStep) { var flowStep = node as Taobao.Activities.Statements.FlowStep; //判断节点是否为NTFE-BPM平行节点 if(flowStep.Action is Taobao.Workflow.Activities.Statements.CustomParallel) { var parallel = flowStep.Action as Taobao.Workflow.Activities.Statements.CustomParallel; int parallel_counter = counter; var parallel_key = _activityidPrefix + (counter++); //构造平行容器类型节点 root.Add(new XElement("NodeData" , new XAttribute("Key", parallel_key) , new XAttribute("Category", "ParallelContainer") , new XAttribute("IsSubGraph", true) , new XAttribute("Location", location_dict.ContainsKey(parallel.DisplayName) ? location_dict[parallel.DisplayName] : "600 0") , new XAttribute("Text", parallel.DisplayName))); int[] array = location_dict.ContainsKey(parallel.DisplayName) ? location_dict[parallel.DisplayName].Split(' ').Select(o => Convert.ToInt32(o)).ToArray() : new int[] { 600, 0 }; dict.Add(flowStep, parallel_key); int c = 0; //遍历分支 foreach(var p_activity in parallel.Branches) { if (p_activity is Taobao.Workflow.Activities.Statements.Human) { var p_human = p_activity as Taobao.Workflow.Activities.Statements.Human; //构造平行容器中的人工节点 root.Add(new XElement("NodeData" , new XAttribute("Key", _activityidPrefix + (counter++)) , new XAttribute("Category", "HumanPar") , new XAttribute("IsSubGraph", true) , new XAttribute("SubGraphKey", _activityidPrefix + parallel_counter) , new XAttribute("Location", (array[0] + (c++) * 105) + " " + array[1]) , new XAttribute("Text", p_human.DisplayName))); } else if (p_activity is Taobao.Workflow.Activities.Statements.Server) { var p_server = p_activity as Taobao.Workflow.Activities.Statements.Server; //构造平行容器中的自动节点 root.Add(new XElement("NodeData" , new XAttribute("Key", _activityidPrefix + (counter++)) , new XAttribute("Category", "ServerPar") , new XAttribute("IsSubGraph", true) , new XAttribute("SubGraphKey", _activityidPrefix + parallel_counter) , new XAttribute("Location", (array[0] + (c++) * 105) + " " + array[1]) , new XAttribute("Text", p_server.DisplayName))); } else if (p_activity is Taobao.Workflow.Activities.Statements.SubProcess) { var p_subProcess = p_activity as Taobao.Workflow.Activities.Statements.SubProcess; //构造平行容器中的子流程节点 root.Add(new XElement("NodeData" , new XAttribute("Key", _activityidPrefix + (counter++)) , new XAttribute("Category", "ChildPar") , new XAttribute("IsSubGraph", true) , new XAttribute("SubGraphKey", _activityidPrefix + parallel_counter) , new XAttribute("Location", (array[0] + (c++) * 105) + " " + array[1]) , new XAttribute("Text", p_subProcess.DisplayName))); } } } else if (flowStep.Action is Taobao.Workflow.Activities.Statements.Human) { var human = flowStep.Action as Taobao.Workflow.Activities.Statements.Human; var key = _activityidPrefix + (counter++); //构造人工节点 root.Add(new XElement("NodeData" , new XAttribute("Key", key) , new XAttribute("Category", "Human") , new XAttribute("IsSubGraph", true) , new XAttribute("Location", location_dict.ContainsKey(human.DisplayName) ? location_dict[human.DisplayName] : "600 0") , new XAttribute("Text", human.DisplayName))); dict.Add(flowStep, key); } else if (flowStep.Action is Taobao.Workflow.Activities.Statements.Server) { var server = flowStep.Action as Taobao.Workflow.Activities.Statements.Server; var key = _activityidPrefix + (counter++); //构造自动节点 root.Add(new XElement("NodeData" , new XAttribute("Key", key) , new XAttribute("Category", "Server") , new XAttribute("IsSubGraph", true) , new XAttribute("Location", location_dict.ContainsKey(server.DisplayName) ? location_dict[server.DisplayName] : "600 0") , new XAttribute("Text", server.DisplayName))); dict.Add(flowStep, key); } else if (flowStep.Action is Taobao.Workflow.Activities.Statements.SubProcess) { var subProcess = flowStep.Action as Taobao.Workflow.Activities.Statements.SubProcess; var key = _activityidPrefix + (counter++); //构造子流程节点 root.Add(new XElement("NodeData" , new XAttribute("Key", key) , new XAttribute("Category", "Child") , new XAttribute("IsSubGraph", true) , new XAttribute("Location", location_dict.ContainsKey(subProcess.DisplayName) ? location_dict[subProcess.DisplayName] : "600 0") , new XAttribute("Text", subProcess.DisplayName))); dict.Add(flowStep, key); } } } if (activity.Body.StartNode != null && activity.Body.StartNode is Taobao.Activities.Statements.FlowStep) { var startFlowStep = activity.Body.StartNode as Taobao.Activities.Statements.FlowStep; var toKey = dict[startFlowStep]; //构造开始连线 root.Add(new XElement("LinkData" , new XAttribute("From", "Start") , new XAttribute("To", toKey) , new XAttribute("IsDefault", true))); } foreach (var node in activity.Body.Nodes) { if (node is Taobao.Activities.Statements.FlowStep) { var flowStep = node as Taobao.Activities.Statements.FlowStep; var fromKey = dict[flowStep]; if (flowStep.Next != null) { var flowSwitch = flowStep.Next as Taobao.Activities.Statements.FlowSwitch<string>; foreach (var caseNode in flowSwitch.Cases) { var linkText = caseNode.Key; if (caseNode.Value is Taobao.Activities.Statements.FlowStep) { var caseFlowStep = caseNode.Value as Taobao.Activities.Statements.FlowStep; var toKey = dict[caseFlowStep]; //构造case连线 root.Add(new XElement("LinkData" , new XAttribute("From", fromKey) , new XAttribute("To", toKey) , new XAttribute("Text", linkText) , new XAttribute("IsDefault", false))); } } if (flowSwitch.Default != null && flowSwitch.Default is Taobao.Activities.Statements.FlowStep) { var defaultFlowStep = flowSwitch.Default as Taobao.Activities.Statements.FlowStep; var toKey = dict[defaultFlowStep]; //构造默认连线 root.Add(new XElement("LinkData" , new XAttribute("From", fromKey) , new XAttribute("To", toKey) , new XAttribute("Text", "Default") , new XAttribute("IsDefault", true))); } } } } return root.ToString(); }
//通过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 override string Parse(WorkflowActivity workflowActivity, string originalWorkflowDefinition) { return Resource.WorkflowDefinition4; }