예제 #1
0
            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);
            }
예제 #2
0
 /// <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);
 }
예제 #3
0
            /// <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>();
            }
예제 #4
0
 /// <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;
 }
예제 #5
0
 /// <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);
 }
예제 #6
0
 public void MarkAsFinalNode(WFnode id)
 {
     if (!connectionGraph.ContainsNode(id))
     {
         throw new ArgumentException("Node not in the workflow");
     }
     finalNodes.Add(id);
 }
예제 #7
0
        /// <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);
        }
예제 #8
0
 /// <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();
 }
예제 #9
0
        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");
        }
예제 #10
0
        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);
        }
예제 #11
0
        /// <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));
            }
        }
예제 #12
0
        /// <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));
            }
        }
예제 #13
0
        /// <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));
            }
        }
예제 #14
0
/// <summary>
/// NOT still defined!!
/// </summary>
/// <param name="nextNode"></param>
/// <param name="previousNode"></param>
/// <returns></returns>
        internal WFnode ExecuteActions(WFnode nextNode, WFnode previousNode)
        {
            return(null);
        }
예제 #15
0
 public WFedgeLabel GetEdgeBetween(WFnode from, WFnode to)
 {
     return(connectionGraph.GetEdgeBetween(from, to));
 }
예제 #16
0
 public IEnumerable <WFnode> GetConnectedNodes(WFnode nd)
 {
     throw new NotImplementedException();
 }
예제 #17
0
 public IEnumerable <WFedgeLabel> GetIncoming(WFnode nd)
 {
     throw new NotImplementedException();
 }
예제 #18
0
        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);
        }
예제 #19
0
            /// <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));
            }