private string getCDSchema(WFnode node) { string ret = "<xs:sequence>"; ret += "<xs:sequence>"; ret += "<xs:element name=\"" + XmlConvert.EncodeLocalName(node.NodeTypeName) + "\" type=\"" + XmlConvert.EncodeLocalName(node.NodeTypeName) + "\"/>"; WFnode endNode = node; List <WFnode> tmp = null; while (endNode == null || (tmp = editedWf.connectionGraph.getOutcomingNodes(endNode)).Count == 1) { endNode = tmp[0]; ret += "<xs:element name=\"" + XmlConvert.EncodeLocalName(tmp[0].NodeTypeName) + "\" type=\"" + XmlConvert.EncodeLocalName(tmp[0].NodeTypeName) + "\"/>"; } ret += "</xs:sequence>"; if (editedWf.connectionGraph.getOutcomingNodes(endNode).Count != 0) { ret += "<xs:choice>"; foreach (WFnode nn in editedWf.connectionGraph.getOutcomingNodes(endNode)) { ret += getCDSchema(nn); } ret += "</xs:choice>"; } ret += "</xs:sequence>"; return(ret); }
/// <summary> /// Checks if there are the intial node and the final nodes /// </summary> /// <returns>True there are the intial node and the final nodes. False otherwise </returns> private bool findInitialAndFinalNodes() { initialNode = null; finalNodes.Clear(); foreach (WFnode nd in connectionGraph.Nodes) { if (connectionGraph.GetOutgoingEdges(nd).Count == 0) { finalNodes.Add(nd); } if (connectionGraph.GetIncomingEdges(nd).Count == 0) { if (initialNode != null) { return(false); } else { initialNode = nd; } } } if (!(initialNode != null && finalNodes.Count > 0)) { return(false); } return(true); }
/// <summary> /// Constructor for ComputableWorkflow /// </summary> /// <param name="wf">A workflow to extract the information</param> public ComputableWorkflow(Workflow wf) { editedWf = wf; actualState = wf.initialNode; finalDocument = new FinalWFdocument(wf.workflowName); rollbackWFnodes = new Stack <WFnode>(); }
/// <summary> /// Construct a WFnode clone of ndClone. /// </summary> /// <param name="ndClone">The node to clone.</param> public WFnode(WFnode ndClone) { this.nodeSchemas = ndClone.nodeSchemas; this.myBaseTypes = ndClone.myBaseTypes; this.nodeTypeName = ndClone.nodeTypeName; this.renderDocument = ndClone.renderDocument; }
/// <summary> /// Return true if the edge could be traversed, false otherwise. /// This valutation is done having the previous node (filled) /// </summary> /// <param name="previousNode"></param> /// <returns>Control </returns> internal bool VerifyPrecondition(WFnode previousNode) { if (EdgeLabelInterpreter.InterpretPreconditions(previousNode.Value, preconditions.DocumentElement)) { return(true); } return(false); }
public void MarkAsFinalNode(WFnode id) { if (!connectionGraph.ContainsNode(id)) { throw new ArgumentException("Node not in the workflow"); } finalNodes.Add(id); }
/// <summary> /// Mark the node id as the InitialNode of the workflow.Throws ArgumentException if the node doesn't exists /// </summary> /// <param name="id">the node</param> /// <returns></returns> public WFnode MarkAsInitialNode(WFnode id) { if (!connectionGraph.ContainsNode(id)) { throw new ArgumentException("Node doesn't exist"); } WFnode tmp = initialNode; initialNode = id; return(tmp); }
/// <summary> /// Reset the computation and clear the final Document /// </summary> public void ResetComputation() { actualState = editedWf.initialNode; foreach (WFnode n in editedWf.connectionGraph.Nodes) { var ls = new List <XmlNode>(); ls.Add(null); n.SetValue(ls); } finalDocument.Clear(); }
private void renderNode(Core.WF.WFnode state) { Trace.Warn("Begin render node"); //nodePlaceHolder.Controls.Clear(); presenPanel.Controls.Clear(); var cmplexRenering = state.GetRenderingDocument().DocumentElement.FirstChild; presenPanel.Controls.Add(state.GetWebControl(Page.Server, cmplexRenering)); //nodePlaceHolder.Controls.Add(state.GetWebControl(Page.Server, cmplexRenering)); Trace.Warn("End render node"); }
private void renderFinal(Core.WF.WFnode state, XmlNode nodeV) { //presenPanel3.Visible = false; clear.Visible = false; Panel pf = new Panel(); pf.Attributes.Add("class", "header"); HyperLink h = new HyperLink(); h.Attributes.Add("href", "#"); h.Text = state.Name; pf.Controls.Add(h); presenPanel2.Controls.Add(pf); state.Value = nodeV; var cmplexRenering = state.GetRenderingDocument().DocumentElement.FirstChild; Control wc = state.GetWebControl(Page.Server, cmplexRenering); Panel p = new Panel(); Panel pControls = new Panel(); Panel pModify = new Panel(); pControls.Enabled = false; pControls.Controls.Add(wc); for (int i = 0; i < presenPanel3.Controls.Count; i++) { if (presenPanel3.Controls[i] != null) { if (((ImageButton)presenPanel3.Controls[i]).ToolTip == state.Name) { ((ImageButton)presenPanel3.Controls[i]).Visible = true; ((ImageButton)presenPanel3.Controls[i]).ImageUrl = "../lib/image/Modify32.PNG"; ((ImageButton)presenPanel3.Controls[i]).Enabled = true; ((ImageButton)presenPanel3.Controls[i]).ToolTip = "Modify"; pModify.Controls.Add(presenPanel3.Controls[i]); } } }// TO DO : clear presenpanel3 pModify.CssClass = "pModify"; p.Controls.Add(pModify); p.Controls.Add(pControls); presenPanel2.Controls.Add(p); }
/// <summary> /// Removes a node from the workflow /// </summary> /// <param name="id">the node that will be removed</param> public void RemoveNode(WFnode id) { connectionGraph.RemoveEdgesANDNode(id); id.FieldModified -= nd_FieldModified; id.NodeNameModified -= nd_NodeNameModified; string info; if ((info = informativeIsValid()) != null) { OnWorkflowInvalidationEvent(new WorkflowValidationEventArgs(info, false)); } }
/// <summary> /// Adds a node to the workflow /// </summary> /// <param name="nd">the node to add </param> public void AddNode(WFnode nd) { connectionGraph.AddNode(nd); //FIXME: Must check doubled names in types and nodes!! nd.FieldModified += nd_FieldModified; nd.NodeNameModified += nd_NodeNameModified; string info; if ((info = informativeIsValid()) != null) { OnWorkflowInvalidationEvent(new WorkflowValidationEventArgs(info, false)); } }
/// <summary> /// Adds the edge edge between nodes from and to. Throws ArgumentException if a node doesnt'exist. /// </summary> /// <param name="edge">the edge to add</param> /// <param name="from">the starting node of edge</param> /// <param name="to">the target node of edge</param> public void AddEdge(WFedgeLabel edge, WFnode from, WFnode to) { if (!(connectionGraph.ContainsNode(from) && connectionGraph.ContainsNode(to))) { throw new ArgumentException("Starting/Target node not inserted in workflow or removed."); } connectionGraph.AddEdge(from, to, edge); edge.EdgeModified += ed_EdgeModified; string info; if ((info = informativeIsValid()) != null) { OnWorkflowInvalidationEvent(new WorkflowValidationEventArgs(info, false)); } }
/// <summary> /// NOT still defined!! /// </summary> /// <param name="nextNode"></param> /// <param name="previousNode"></param> /// <returns></returns> internal WFnode ExecuteActions(WFnode nextNode, WFnode previousNode) { return(null); }
public WFedgeLabel GetEdgeBetween(WFnode from, WFnode to) { return(connectionGraph.GetEdgeBetween(from, to)); }
public IEnumerable <WFnode> GetConnectedNodes(WFnode nd) { throw new NotImplementedException(); }
public IEnumerable <WFedgeLabel> GetIncoming(WFnode nd) { throw new NotImplementedException(); }
private string informativeIsValid() { /*Every node is valid...itself*/ foreach (WFnode wnd in connectionGraph.Nodes) { if (!wnd.isValid) { try { return("The editor you are using pass me some invalid datas for node " + wnd.Name); } catch { return("The editor you are using pass me some invalid datas for a node"); } } } if (!findInitialAndFinalNodes()) { return("No Initial node or no recognized final nodes in workflow"); } /*Initial should be really initial*/ if (connectionGraph.GetIncomingEdges(initialNode).Count != 0) { return("Initial node has incoming edges"); } /*Each node should be reached from initial node*/ Stack <WFnode> stack = new Stack <WFnode>(); HashSet <WFnode> visited = new HashSet <WFnode>(); HashSet <WFnode> nodeInStack = new HashSet <WFnode>(); stack.Push(initialNode); nodeInStack.Add(initialNode); visited.Add(initialNode); WFnode popped = null; while (stack.Count > 0) { WFnode top = stack.Peek(); List <WFnode> lst = connectionGraph.getOutcomingNodes(top); if (lst.Count > 0) { if (popped != null) { int num = lst.IndexOf(popped); if (num + 1 < lst.Count) { if (nodeInStack.Contains(lst[num + 1])) { return("Workflow contains cycle"); } nodeInStack.Add(lst[num + 1]); stack.Push(lst[num + 1]); visited.Add(lst[num + 1]); } else { popped = stack.Pop(); nodeInStack.Remove(popped); } } else { if (stack.Contains(lst[0])) { return("Workflow contains cycle"); } nodeInStack.Add(lst[0]); stack.Push(lst[0]); visited.Add(lst[0]); } } else { popped = stack.Pop(); nodeInStack.Remove(popped); } } if (visited.Count != connectionGraph.Nodes.Count) { return("Not all nodes could be reached from initial node"); } try { XmlSchemaSet resSchema = new XmlSchemaSet(); resSchema.Add(Fields.FieldsManager.FieldTypesXSD); foreach (WFnode nd in connectionGraph.Nodes) { resSchema.Add(nd.GetNodeSchemasWithoutBaseTypes()); } resSchema.Compile(); } catch (Exception err) { return("Problems with nodes schemas:\n\n" + err.Message); } /*Verify edge precondition*/ foreach (WFedgeLabel edg in connectionGraph.Edges) { var tr = connectionGraph.GetConnectingNodes(edg); if (!EdgeLabelInterpreter.VerifyPreconditionsCorrectness(tr.SecondMember.GetNodeSchemas(), XmlConvert.EncodeLocalName(tr.SecondMember.NodeTypeName), edg.GetPrecondition().FirstChild)) { return("The edge between " + XmlConvert.EncodeLocalName(tr.SecondMember.NodeTypeName) + " and " + XmlConvert.EncodeLocalName(tr.ThirdMember.NodeTypeName) + " contains wrong preconditions"); } } return(null); }
/// <summary> /// Transit from one state to another, after consider the event verified and which edge verify precondition /// </summary> /// <param name="evt">The event verified</param> /// <param name="data">The actual node</param> /// <param name="handler">Validation Handler</param> /// <returns></returns> public ActionResult ComputeNewStatus(WFeventType evt, XmlDocument data, ValidationEventHandler handler) { if (evt == WFeventType.TRYGOON) { actualState.Value = data.DocumentElement; if (actualState.Validate(handler)) { if (editedWf.finalNodes.Contains(actualState)) { /*Save data */ finalDocument.Push(actualState); actualState = null; return(new ActionResult(true)); } /*Compute new status*/ List <WFedgeLabel> edges = editedWf.connectionGraph.GetOutgoingEdges(actualState); edges.Sort((x, y) => x.Priority - y.Priority); foreach (WFedgeLabel edgeIdToEval in edges) { //COMMENTATO PER SICUREZZA DI FUNZIONAMENTO WFedgeLabel edgeToEval = edgeIdToEval; if (edgeToEval.VerifyPrecondition(actualState)) { /*Save data */ finalDocument.Push(actualState); //aggiunto controllo sullo stack di rollback (vuoto / non vuoto) if (rollbackWFnodes.Count != 0) { WFnode rollbackNode = rollbackWFnodes.Pop(); //recupero sia il WFnode che la sua istanza dal top dei 2 stack WFedgeLabel rollbackEdge = editedWf.connectionGraph.GetEdge(actualState, rollbackNode); if (edgeIdToEval != rollbackEdge) { rollbackWFnodes = new Stack <WFnode>(); actualState = editedWf.connectionGraph.GetDestination(actualState, edgeIdToEval); } else { actualState = rollbackNode; } } else { actualState = editedWf.connectionGraph.GetDestination(actualState, edgeIdToEval); } return(new ActionResult(true)); } } Debug.WriteLine("Not avery edges precondition is satisfied"); return(new ActionResult(false)); } else { actualState.Value = null; } Debug.WriteLine("Passed node is not valid! Validation failed"); return(new ActionResult(false)); } else if (evt == WFeventType.ROLLBACK) { if (IsInitialState()) { Debug.WriteLine("Cannot rollback from initial node!"); return(new ActionResult(false)); } if (actualState != null) { rollbackWFnodes.Push(actualState); } actualState = finalDocument.Pop(); return(new ActionResult(true)); } return(new ActionResult(false)); }