internal static string ToDotWithHistory( this IWorkflowDefinition workflow, Workflow instance, string rankDir = "" ) { var history = instance.WorkflowHistories; var sb = new StringBuilder(); sb.AppendLine($"digraph {workflow.Type} {{"); if (!string.IsNullOrEmpty(rankDir)) { sb.AppendLine($" rankdir = {rankDir};"); } // sb.AppendLine($" {instance.State} [ style=\"filled\", color=\"#e95420\" ];"); foreach (var t in workflow.Transitions) { if (Exists(t, history)) { sb.AppendLine($" {t.State} -> {t.TargetState} " + $"[ label = {t.Trigger}, color =\"#e95420\", penwidth=3 ];"); } else { sb.AppendLine($" {t.State} -> {t.TargetState} [ label = {t.Trigger} ];"); } } sb.AppendLine("}"); return(sb.ToString()); }
public void Persist(IWorkflowDefinition workflowDefinition) { if (workflowDefinitions.ContainsKey(workflowDefinition.Identifier)) { workflowDefinitions.Remove(workflowDefinition.Identifier); } workflowDefinitions.Add(workflowDefinition.Identifier, workflowDefinition); }
public Execution(string identifier, string workflowInstanceIdentifier, IWorkflowDefinition workflowDefinition, IExecutionPlan executionPlan) { Identifier = identifier; WorkflowInstanceIdentifier = workflowInstanceIdentifier; Children = new List<IExecution>(); this.executionPlan = executionPlan; this.workflowDefinition = workflowDefinition; Data = new Dictionary<string, object>(); }
public static void setWorkflowProcess(IWorkflowDefinition wdf, WorkflowProcess workflowProcess) { wdf.ProcessId = workflowProcess.Id; wdf.Name = workflowProcess.Name; wdf.DisplayName = workflowProcess.DisplayName; wdf.Description = workflowProcess.Description; Dom4JFPDLSerializer ser = new Dom4JFPDLSerializer(); wdf.ProcessContent = ser.serialize(workflowProcess); }
private NodeModel CreateNode(IWorkflowDefinition parentWorkflow, INode node) { return new NodeModel { Identifier = node.Identifier, IsInitialNode = Equals(parentWorkflow.InitialNode, node), IsEndNode = parentWorkflow.EndNodes.Contains(node), OperationType = node.Operation.AssemblyQualifiedName, OutgoingTransitions = CreateOutgoingTransitions(node).ToList() }; }
private void passStringAction_Execute(object sender, ParametrizedActionExecuteEventArgs e) { IWorkflowDefinition definition = View.ObjectSpace.FindObject <EFWorkflowDefinition>(CriteriaOperator.Parse("Name = 'Custom start workflow'")); if (definition != null) { IPassStringData serverWorkflow = ChannelFactory <IPassStringData> .CreateChannel(new BasicHttpBinding(), new EndpointAddress(WorkflowServerAddress + definition.GetUniqueId())); serverWorkflow.PassStringData((string)e.ParameterCurrentValue); } }
// TODO: builder public Execution(IExecution parent, INode currentNode, bool isActive, bool isFinished, IDictionary<string, object> data, string incomingTransition, string identifier, string workflowInstanceIdentifier, IExecutionPlan executionPlan, IList<IExecution> children, IWorkflowDefinition workflowDefinition) : this(identifier, workflowInstanceIdentifier, workflowDefinition, executionPlan) { Parent = parent; IncomingTransition = incomingTransition; CurrentNode = currentNode; IsActive = isActive; Data = data; Children = children; IsFinished = isFinished; }
public virtual IWorkflowDefinition FindDefinition(string uniqueId) { IWorkflowDefinition definition = null; foreach (IWorkflowDefinition item in GetDefinitions()) { if (item.GetUniqueId() == uniqueId) { definition = item; } } return(definition); }
/// <summary> /// Exports the workflow definition to a dot directed graph. /// See: http://www.webgraphviz.com/ /// </summary> /// <param name="workflow"></param> /// <returns></returns> public static string ToDot(this IWorkflowDefinition workflow, string rankDir = "LR") { var sb = new StringBuilder(); sb.AppendLine($"digraph {workflow.Type} {{"); sb.AppendLine($" rankdir = {rankDir};"); foreach (var t in workflow.Transitions) { sb.AppendLine($" {t.State} -> {t.TargetState} [ label = {t.Trigger} ];"); } sb.AppendLine("}"); return(sb.ToString()); }
public IExecution TransformBack(ExecutionModel model, IWorkflowDefinition workflowDefinition, IExecutionPlan plan) { if (model == null) { return null; } var root = FindRoot(model); var transformedRoot = TransformBack(root, plan, workflowDefinition, null); var collector = new ExecutionCollector(e => e.Identifier == model.Identifier); transformedRoot.Accept(collector); return collector.Result.First(); }
public void Persist(IWorkflowDefinition workflowDefinition) { using (var session = sessionFactory.OpenSession()) { using (var txn = session.BeginTransaction()) { var entity = workflowDefinitionTransformer.Transform(workflowDefinition); session.SaveOrUpdate(entity); session.Flush(); txn.Commit(); } } }
/// <summary>获取业务流程对象</summary> public static WorkflowProcess getWorkflowProcess(IWorkflowDefinition wdf)// throws RuntimeException { if (!dic_wp.ContainsKey(wdf.Id)) { if (wdf.ProcessContent != null && !String.IsNullOrEmpty(wdf.ProcessContent.Trim())) { Dom4JFPDLParser parser = new Dom4JFPDLParser(); WorkflowProcess workflowProcess = parser.parse(wdf.ProcessContent); if (workflowProcess != null) dic_wp[wdf.Id] = workflowProcess; } } dic_wp[wdf.Id].Sn = wdf.Id; return dic_wp[wdf.Id]; }
public WorkflowDefinitionModel Transform(IWorkflowDefinition workflowDefinition) { var workflowDefinitionModel = new WorkflowDefinitionModel { Identifier = workflowDefinition.Identifier, OperationType = workflowDefinition.Operation.AssemblyQualifiedName }; foreach (var node in workflowDefinition.Nodes) { NodeModel nodeModel = CreateNode(workflowDefinition, (dynamic) node); workflowDefinitionModel.Nodes.Add(nodeModel); } return workflowDefinitionModel; }
/// <summary>获取业务流程对象</summary> public static WorkflowProcess getWorkflowProcess(IWorkflowDefinition wdf)// throws RuntimeException { if (!dic_wp.ContainsKey(wdf.Id)) { if (wdf.ProcessContent != null && !String.IsNullOrEmpty(wdf.ProcessContent.Trim())) { Dom4JFPDLParser parser = new Dom4JFPDLParser(); WorkflowProcess workflowProcess = parser.parse(wdf.ProcessContent); if (workflowProcess != null) { dic_wp[wdf.Id] = workflowProcess; } } } dic_wp[wdf.Id].Sn = wdf.Id; return(dic_wp[wdf.Id]); }
private NodeModel CreateNode(IWorkflowDefinition parentWorkflow, IWorkflowDefinition nestedWorkflow) { return Transform(nestedWorkflow); }
public void RegisterWorkflowDefinition(IWorkflowDefinition workflowDefinition) => _workflowDefinitions.Add(workflowDefinition);
public WorkflowExecution(IWorkflowDefinition definition) { _definition = definition; }
public void RegisterWorkflowDefinition(IWorkflowDefinition workflowDefinition) { throw new NotImplementedException(); }
public void Persist(IWorkflowDefinition workflowDefinition) { graphClient.Cypher .Merge("(wf:WorkflowDefinition {Identifier: {wfId}})") .Merge("(initialNode:Node {Identifier: {id}})") .Merge("(wf)-[:STARTS_AT]->(initialNode)") .Set("initialNode = {initialNode}") .WithParams(new { initialNode = new NodeModel { Identifier = workflowDefinition.InitialNode.Identifier, OperationType = workflowDefinition.InitialNode.Operation.AssemblyQualifiedName }, id = workflowDefinition.InitialNode.Identifier, wfId = workflowDefinition.Identifier }) .ExecuteWithoutResults(); PersistNode(workflowDefinition.InitialNode, workflowDefinition, graphClient); }
/******************************************************************************/ /************ **********/ /************ 存取流程定义文件 相关的持久化方法 **********/ /************ Persistence methods for workflow definition **********/ /************ **********/ /******************************************************************************/ /// <summary> /// Save or update the workflow definition. The version will be increased automatically when insert a new record. /// 保存流程定义,如果同一个ProcessId的流程定义已经存在,则版本号自动加1。 /// </summary> public bool SaveOrUpdateWorkflowDefinition(IWorkflowDefinition workflowDef) { if (String.IsNullOrEmpty(workflowDef.Id)) { Int32 latestVersion = FindTheLatestVersionNumberIgnoreState(workflowDef.ProcessId); if (latestVersion > 0) { workflowDef.Version=latestVersion + 1; } else { workflowDef.Version=1; } workflowDef.Id = Guid.NewGuid().ToString().Replace("-", ""); string insert = "INSERT INTO T_FF_DF_WORKFLOWDEF (" + "ID, DEFINITION_TYPE, PROCESS_ID, NAME, DISPLAY_NAME, " + "DESCRIPTION, VERSION, STATE, UPLOAD_USER, UPLOAD_TIME, " + "PUBLISH_USER, PUBLISH_TIME, PROCESS_CONTENT )VALUES(:1, :2, :3, :4, :5, :6, :7, :8, :9, :10, :11, :12, :13)"; OracleParameter[] insertParms = { OracleHelper.NewOracleParameter(":1", OracleType.VarChar, 50, workflowDef.Id), OracleHelper.NewOracleParameter(":2", OracleType.VarChar, 50, workflowDef.DefinitionType), OracleHelper.NewOracleParameter(":3", OracleType.VarChar, 100, workflowDef.ProcessId), OracleHelper.NewOracleParameter(":4", OracleType.VarChar, 100, workflowDef.Name), OracleHelper.NewOracleParameter(":5", OracleType.VarChar, 128, workflowDef.DisplayName), OracleHelper.NewOracleParameter(":6", OracleType.VarChar, 1024, workflowDef.Description), OracleHelper.NewOracleParameter(":7", OracleType.Int32, workflowDef.Version), OracleHelper.NewOracleParameter(":8", OracleType.Int16, OracleHelper.OraBit(workflowDef.State) ), OracleHelper.NewOracleParameter(":9", OracleType.VarChar, 50, workflowDef.UploadUser), OracleHelper.NewOracleParameter(":10", OracleType.Timestamp, 11, workflowDef.UploadTime), OracleHelper.NewOracleParameter(":11", OracleType.VarChar, 50, workflowDef.PublishUser), OracleHelper.NewOracleParameter(":12", OracleType.Timestamp, 11, workflowDef.PublishTime), OracleHelper.NewOracleParameter(":13", OracleType.NVarChar, workflowDef.ProcessContent) }; if (OracleHelper.ExecuteNonQuery(connectionString, CommandType.Text, insert, insertParms) != 1) return false; else return true; } else { string update = "UPDATE T_FF_DF_WORKFLOWDEF SET " + "PROCESS_ID=:3, NAME=:4, DISPLAY_NAME=:5, DESCRIPTION=:6, " + "STATE=:8, UPLOAD_USER=:9, UPLOAD_TIME=:10, PROCESS_CONTENT=:13 " + "WHERE ID=:1"; OracleParameter[] updateParms = { OracleHelper.NewOracleParameter(":3", OracleType.VarChar, 100, workflowDef.ProcessId), OracleHelper.NewOracleParameter(":4", OracleType.VarChar, 100, workflowDef.Name), OracleHelper.NewOracleParameter(":5", OracleType.VarChar, 128, workflowDef.DisplayName), OracleHelper.NewOracleParameter(":6", OracleType.VarChar, 1024, workflowDef.Description), OracleHelper.NewOracleParameter(":8", OracleType.Int16, OracleHelper.OraBit(workflowDef.State)), OracleHelper.NewOracleParameter(":9", OracleType.VarChar, 50, workflowDef.UploadUser), OracleHelper.NewOracleParameter(":10", OracleType.Timestamp, 11, workflowDef.UploadTime), OracleHelper.NewOracleParameter(":13", OracleType.NVarChar,workflowDef.ProcessContent), OracleHelper.NewOracleParameter(":1", OracleType.VarChar, 50, workflowDef.Id) }; if (OracleHelper.ExecuteNonQuery(connectionString, CommandType.Text, update, updateParms) != 1) return false; else return true; } }
private void PersistNode(INode node, IWorkflowDefinition definition, IGraphClient client) { foreach (var outgoingTransition in node.OutgoingTransitions) { client.Cypher.Match("(source:Node {Identifier: {sourceId}})") .Merge("(dest:Node {Identifier: {destId}})") .Merge("(source)-[t:TRANSITION]->(dest)") .Set("source = {source}") .Set("dest = {dest}") .Set("t = {transition}") .WithParams(new { source = new NodeModel { Identifier = node.Identifier, OperationType = node.Operation.AssemblyQualifiedName, IsEndNode = definition.EndNodes.Contains(node) }, dest = new NodeModel { Identifier = outgoingTransition.Destination.Identifier, OperationType = outgoingTransition.Destination.Operation.AssemblyQualifiedName, IsEndNode = definition.EndNodes.Contains(outgoingTransition.Destination) }, sourceId = node.Identifier, destId = outgoingTransition.Destination.Identifier, transition = new TransitionModel { Identifier = outgoingTransition.Identifier, IsDefault = outgoingTransition.IsDefault } }) .ExecuteWithoutResults(); PersistNode(outgoingTransition.Destination, definition, client); } }
public void RegisterNewWorkflowDefinition(IWorkflowDefinition definition) { persistenceProvider.Persist(definition); }
public IExecution StartNewInstance(IWorkflowDefinition definition) { return StartNewInstance(definition, null); }
/******************************************************************************/ /************ **********/ /************ 存取流程定义文件 相关的持久化方法 **********/ /************ Persistence methods for workflow definition **********/ /************ **********/ /******************************************************************************/ /// <summary> /// Save or update the workflow definition. The version will be increased automatically when insert a new record. /// 保存流程定义,如果同一个ProcessId的流程定义已经存在,则版本号自动加1。 /// </summary> public bool SaveOrUpdateWorkflowDefinition(IWorkflowDefinition workflowDef) { if (String.IsNullOrEmpty(workflowDef.Id)) { Int32 latestVersion = FindTheLatestVersionNumberIgnoreState(workflowDef.ProcessId); if (latestVersion > 0) { workflowDef.Version = latestVersion + 1; } else { workflowDef.Version = 1; } workflowDef.Id = Guid.NewGuid().ToString("N"); string insert = "INSERT INTO T_FF_DF_WORKFLOWDEF (" + "ID, DEFINITION_TYPE, PROCESS_ID, NAME, DISPLAY_NAME, " + "DESCRIPTION, VERSION, STATE, UPLOAD_USER, UPLOAD_TIME, " + "PUBLISH_USER, PUBLISH_TIME, PROCESS_CONTENT )VALUES(@1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @11, @12, @13)"; SqlParameter[] insertParms = { SqlServerHelper.NewSqlParameter("@1", SqlDbType.VarChar, 50, workflowDef.Id), SqlServerHelper.NewSqlParameter("@2", SqlDbType.VarChar, 50, workflowDef.DefinitionType), SqlServerHelper.NewSqlParameter("@3", SqlDbType.VarChar, 100, workflowDef.ProcessId), SqlServerHelper.NewSqlParameter("@4", SqlDbType.VarChar, 100, workflowDef.Name), SqlServerHelper.NewSqlParameter("@5", SqlDbType.VarChar, 128, workflowDef.DisplayName), SqlServerHelper.NewSqlParameter("@6", SqlDbType.VarChar, 1024, workflowDef.Description), SqlServerHelper.NewSqlParameter("@7", SqlDbType.Int, workflowDef.Version), SqlServerHelper.NewSqlParameter("@8", SqlDbType.SmallInt, SqlServerHelper.OraBit(workflowDef.State) ), SqlServerHelper.NewSqlParameter("@9", SqlDbType.VarChar, 50, workflowDef.UploadUser), SqlServerHelper.NewSqlParameter("@10", SqlDbType.DateTime, 11, workflowDef.UploadTime), SqlServerHelper.NewSqlParameter("@11", SqlDbType.VarChar, 50, workflowDef.PublishUser), SqlServerHelper.NewSqlParameter("@12", SqlDbType.DateTime, 11, workflowDef.PublishTime), SqlServerHelper.NewSqlParameter("@13", SqlDbType.NText, workflowDef.ProcessContent) }; if (SqlServerHelper.ExecuteNonQuery(connectionString, CommandType.Text, insert, insertParms) != 1) return false; else return true; } else { string update = "UPDATE T_FF_DF_WORKFLOWDEF SET " + "PROCESS_ID=@3, NAME=@4, DISPLAY_NAME=@5, DESCRIPTION=@6, " + "STATE=@8, UPLOAD_USER=@9, UPLOAD_TIME=@10, PROCESS_CONTENT=@13 " + "WHERE ID=@1"; SqlParameter[] updateParms = { SqlServerHelper.NewSqlParameter("@3", SqlDbType.VarChar, 100, workflowDef.ProcessId), SqlServerHelper.NewSqlParameter("@4", SqlDbType.VarChar, 100, workflowDef.Name), SqlServerHelper.NewSqlParameter("@5", SqlDbType.VarChar, 128, workflowDef.DisplayName), SqlServerHelper.NewSqlParameter("@6", SqlDbType.VarChar, 1024, workflowDef.Description), SqlServerHelper.NewSqlParameter("@8", SqlDbType.SmallInt, SqlServerHelper.OraBit(workflowDef.State)), SqlServerHelper.NewSqlParameter("@9", SqlDbType.VarChar, 50, workflowDef.UploadUser), SqlServerHelper.NewSqlParameter("@10", SqlDbType.DateTime, 11, workflowDef.UploadTime), SqlServerHelper.NewSqlParameter("@13", SqlDbType.Text,workflowDef.ProcessContent), SqlServerHelper.NewSqlParameter("@1", SqlDbType.VarChar, 50, workflowDef.Id) }; if (SqlServerHelper.ExecuteNonQuery(connectionString, CommandType.Text, update, updateParms) != 1) return false; else return true; } }
private IExecution TransformBack(ExecutionModel model, IExecutionPlan plan, IWorkflowDefinition workflowDefinition, IExecution parent) { IDictionary<string, object> data = new Dictionary<string, object>(); foreach (var variable in model.Variables) { data.Add(variable.VariableKey, serializer.Deserialize(variable.SerializedValue, Type.GetType(variable.ValueType))); } IList<IExecution> children = new List<IExecution>(); var execution = new Execution(parent, workflowDefinition.Nodes.FirstOrDefault(n => n.Identifier == model.CurrentNodeIdentifier), model.IsActive, model.IsFinished, data, model.IncomingTransition, model.Identifier, model.WorkflowInstanceIdentifier, plan, children, workflowDefinition); foreach (var child in model.Children) { children.Add(TransformBack(child, plan, workflowDefinition, execution)); } return execution; }
private void FillChildren(IExecution parent, List<IExecution> children, IExecutionPlan executionPlan, IWorkflowDefinition workflowDefinition) { var result = graphClient.Cypher .Match("(root:Execution {Identifier: {id}})") .Match("(root)-[:PARENT_OF]->(child:Execution)") .OptionalMatch("(child)-[:EXECUTES]->(currentNode:Node)") .WithParam("id", parent.Identifier) .Return((child, currentNode) => new { Child = child.As<ExecutionModel>(), CurrentNode = currentNode.As<NodeModel>() }); foreach (var r in result.Results) { Dictionary<string, object> data = (Dictionary<string, object>) objectSerializer.Deserialize(r.Child.Data, typeof (Dictionary<string, object>)); var childExecutions = new List<IExecution>(); var e = new Execution(parent, r.CurrentNode == null ? null : workflowDefinition.Nodes.First(n => n.Identifier == r.CurrentNode.Identifier), r.Child.IsActive, r.Child.IsFinished, data, r.Child.IncomingTransition, r.Child.Identifier, r.Child.WorkflowInstanceIdentifier, executionPlan, childExecutions, workflowDefinition); children.Add(e); FillChildren(e, childExecutions, executionPlan, workflowDefinition); } }
public bool SaveOrUpdateWorkflowDefinition(IWorkflowDefinition workflowDef) { throw new NotImplementedException(); }
public IExecution StartNewInstance(IWorkflowDefinition definition, object data) { RegisterNewWorkflowDefinition(definition); return StartNewInstance(definition.Identifier, data); }