Exemple #1
0
 public void addActivityNode(XNode node, LoopNode loopNode, Activity activity)
 {
 }
Exemple #2
0
 public void addActivityEdge(XNode node, LoopNode activity)
 {
 }
Exemple #3
0
        //TODO
        public void addActivityGroup(XElement node, Activity activity)
        {
            string type = "";
            if (node.Attribute("{http://schema.omg.org/spec/XMI/2.1}type") != null)
                type = node.Attribute("{http://schema.omg.org/spec/XMI/2.1}type").Value;
            else
                type = node.Attribute("{http://www.omg.org/spec/XMI/20131001}type").Value;

            if (type == "uml:ActivityPartition")
            {
                string name = node.Attribute("name").Value;
                ActivityPartition partition = new ActivityPartition(name);
                //Debug.Log("   ---> Partition : " + name);
                string id = "";
                if (node.Attribute("{http://schema.omg.org/spec/XMI/2.1}id") != null)
                    id = node.Attribute("{http://schema.omg.org/spec/XMI/2.1}id").Value;
                else
                    id = node.Attribute("{http://www.omg.org/spec/XMI/20131001}id").Value;

                _partitions.Add(id, partition);
                activity.addPartition(partition);
            }
            else if (type == "uml:LoopNode")
            {
                LoopNode loopNode = new LoopNode(node.Attribute("name").Value, "Loop");
                loopNode.Description = getComment(node);

                activity.addNode(loopNode);

                string idPartition = node.Attribute("inPartition").Value;
                if (_partitions.ContainsKey(idPartition))
                {
                    loopNode.Partitions.Add(_partitions[idPartition]);
                    _partitions[idPartition].Node.Add(loopNode);
                }

                /*
                string isTestedFirst = node.Attribute("isTestedFirst").Value;
                if (isTestedFirst == "true")
                {
                    loopNode.setTestedFirst(true);
                }
                else
                {
                    loopNode->setTestedFirst(false);
                }*/

                _activityNodes.Add(node.Attribute("{http://schema.omg.org/spec/XMI/2.1}id").Value, loopNode);
                //string testId = node.Attribute("test").Value;
                /*
                map<string, shared_ptr<Expression> >::iterator it =	_activityExpressions.find(testId);
                if (it != _activityExpressions.end())
                {
                    loopNode->setCondition(it->second);
                }
                else
                    cerr << "Test for LoopNode : " << loopNode->getName()
                        << " not found" << endl;
                */

                foreach (XElement child in node.Elements())
                {
                    if (child.Name.LocalName == "node")
                    {
                        string inPart = node.Attribute("inPartition").Value;
                        //child.->setProperty(string("inPartition"), inPart);
                        //cerr << "././././././././././. transferring property: " << inPart << endl;
                        addActivityNode(child, loopNode, activity);
                    }
                }
                foreach (XElement child in node.Elements())
                {
                    if (child.Name.LocalName == "edge")
                        addActivityEdge(child, loopNode);
                }
            }
        }
        protected bool tryToAdvanceToken(ActivityExecutionToken token, ActionNode doneAction, bool gotTicketToUseAction)
        {
            //TODO : current implementation will fail if the loop node has branches which are not joined together at the end

            //TODO : setup part of loop nodes not implemented
            //TODO : careful if the loop node contains only an initial node :: ENDLESS LOOP

            //		Debug.Log(" current token : " + token.currentLocation.name);

            if (token.currentLocation.Kind == "action")
            {
                ActionNode aNode = (ActionNode)(token.currentLocation);
                if (actionIsCurrentlyRunning(aNode))
                {
                    System.Console.WriteLine(" ACTION is RUNNING : " + aNode.Action.name);
                    //token busy...
                    return(false);
                }
            }


            if (token.outgoingEdge == null)
            {
                //if (ACTIVATE_DEBUG_CONSOLE_OUTPUT_TOKENS) cerr << "dbg Part1: edge null" << endl;
                //Debug.Log(" NO OUTGOING EDGES....");
                //my work here is done *flies away*
                return(false);
            }

            //evaluate guard(s). Normal behavior for fork, but I treat decision nodes here, if there are more paths going out, I will take the first one.
            if (token.currentLocation.Kind == "fork")
            {
                //if (ACTIVATE_DEBUG_CONSOLE_OUTPUT_TOKENS) cerr << "dbg Part1: fork" << endl;

                //normal behavior for fork (should not have guard, but hell... it doesn't hurt to check)
                if (token.outgoingEdge.Guard != null && (!(token.outgoingEdge.Guard.eval(procedure.Activity.Context))))
                {
                    return(false); //eval failed
                }
            }
            else
            {
                //if (ACTIVATE_DEBUG_CONSOLE_OUTPUT_TOKENS) cerr << "dbg Part1: no fork" << endl;

                List <ActivityEdge> outgoingNormal = token.currentLocation.getOutgoingControlFlowEdges();
                bool foundWayOut = false;
                for (int i = 0; i < outgoingNormal.Count; ++i)
                {
                    //if <no guard> or <guard but evaluates ok>
                    if ((outgoingNormal[i].Guard == null) || (outgoingNormal[i].Guard != null && (outgoingNormal[i].Guard.eval(procedure.Activity.Context))))
                    {
                        foundWayOut        = true;
                        token.outgoingEdge = outgoingNormal[i]; //set new direction, we take the first possible one, remember ?
                    }
                }

                if (!foundWayOut)
                {
                    //if (ACTIVATE_DEBUG_CONSOLE_OUTPUT_TOKENS) cerr << "dbg Part1: didn't find way out" << endl;

                    return(false); //no way out... leave for later
                }
            }

            ActivityNode nextLocation = token.outgoingEdge.Target;

            //test allowed action
            if (nextLocation.Kind == "action")
            {
                if ((nextLocation != doneAction) || (!gotTicketToUseAction))
                {
                    //not allowed to advance to this action

                    //if (ACTIVATE_DEBUG_CONSOLE_OUTPUT_TOKENS) cerr << "dbg Part1: action not allowed" << endl;

                    return(false);
                }

                gotTicketToUseAction = false;
            }


            //Debug.Log("Next Location : " + nextLocation);

            //if (ACTIVATE_DEBUG_CONSOLE_OUTPUT_TOKENS) cerr << "adv tok from '" << token->currentLocation->getName() << "' to '" << nextLocation->getName() << "'" << endl;

            //Advance
            ActivityEdge dummyActivityEdge = null;

            token.currentLocation = nextLocation;
            token.outgoingEdge    = dummyActivityEdge;

            List <ActivityEdge> outgoingAfterAdvance = token.currentLocation.getOutgoingControlFlowEdges();

            List <ActivityExecutionToken> nextTokens = new List <ActivityExecutionToken>();

            if (token.currentLocation.Kind == "fork")
            {
                //time to split token into pieces, in order to follow all fork branches

                token.forkStack.Add(token.currentLocation); //push this fork to the stack

                //remove this token from the active list
                for (int i = 0; i < activeTokens.Count; ++i)
                {
                    if (activeTokens[i].ToString() == token.ToString())
                    {
                        activeTokens.RemoveAt(i);
                        break;
                    }
                }

                for (int i = 0; i < outgoingAfterAdvance.Count; ++i)
                {
                    ActivityExecutionToken tok = new ActivityExecutionToken();
                    tok.currentLocation = token.currentLocation;
                    tok.forkStack       = token.forkStack;
                    tok.loopNodeStack   = token.loopNodeStack;
                    tok.outgoingEdge    = outgoingAfterAdvance[i]; //set outgoing, to know which branch to follow

                    //push to active list
                    activeTokens.Add(tok);

                    //save for further use
                    nextTokens.Add(tok);
                }
            }
            else if (token.currentLocation.Kind == "join")
            {
                //we can only pass by a join, if all other branched tokens have arrived in this join
                //the point is that the number of tokens which have the same last fork as this one, should be the same as the nr of incoming links to this join
                //i hope i understand this next time i read it

                List <ActivityEdge> incoming = token.currentLocation.Incoming;        //so get the incoming

                //see which is the last fork of this token
                ActivityNode lastFork = null;
                if (token.forkStack.Count > 0)
                {
                    lastFork = token.forkStack[token.forkStack.Count - 1];
                }

                if (lastFork != null)
                {
                    //find all tokens that have this fork and see if they all finished their branch // TODO: remember that actually, the forkStacks should be identical for paired tokens... if they're not, we've got a problem....
                    List <ActivityExecutionToken> finishedTokens = new List <ActivityExecutionToken>();
                    for (int i = 0; i < activeTokens.Count; ++i)
                    {
                        //if found a token with this last fork
                        if ((activeTokens[i].forkStack.Count > 0) && (activeTokens[i].forkStack[activeTokens[i].forkStack.Count - 1] == lastFork))
                        {
                            //check to see if it's finished (arrived at the same join)
                            if (activeTokens[i].currentLocation == token.currentLocation)
                            {
                                //add to finished tokens list
                                finishedTokens.Add(activeTokens[i]);
                            }
                        }
                    }

                    //now check to see if the number of found tokens equals the number of incoming links to this join
                    if (finishedTokens.Count == incoming.Count)
                    {
                        //then all should be great.... we can merge all tokens into a single one
                        for (int i = 0; i < finishedTokens.Count; ++i)
                        {
                            //skip the current token, this one will remain
                            if (finishedTokens[i].ToString() == token.ToString())
                            {
                                continue;
                            }

                            //seek and destroy
                            for (int j = 0; j < activeTokens.Count; ++j)
                            {
                                if (finishedTokens[i].ToString() == activeTokens[j].ToString())
                                {
                                    //destroy
                                    activeTokens.RemoveAt(j);
                                }
                            }
                        }

                        if (outgoingAfterAdvance.Count == 1)
                        {
                            token.outgoingEdge = outgoingAfterAdvance[0];
                            token.forkStack.RemoveAt(token.forkStack.Count - 1);//pop last fork
                            nextTokens.Add(token);
                        }
                        else if (outgoingAfterAdvance.Count > 1)
                        {
                        }
                    }
                }
                else
                {
                }
            }
            else if (token.currentLocation.Kind == "loop")
            {
                LoopNode loopNode = (LoopNode)(token.currentLocation);

                bool skipThisLoopNode = false;

                if (loopNode.TestedFirst)
                {
                    if (loopNode.eval())             //thou shall pass
                    {
                        skipThisLoopNode = true;
                    }
                }

                ActivityNode        initLoop             = loopNode.Initial;
                List <ActivityEdge> outgoingFromInitLoop = null;

                if (initLoop != null)
                {
                    outgoingFromInitLoop = initLoop.getOutgoingControlFlowEdges();
                }

                if (skipThisLoopNode || (initLoop == null) || (outgoingFromInitLoop.Count < 1))
                {
                    //I don't care which path to take, so I will just take the first one. In the advance part (see above) if it's a decision node, it will take the first possible path, if any
                    if (outgoingAfterAdvance.Count >= 1)
                    {
                        token.outgoingEdge = outgoingAfterAdvance[0];
                        nextTokens.Add(token);
                    }
                }
                else
                {
                    //enter the loop node, we'll get the edge which exits the loopnode's initial node

                    token.currentLocation = initLoop;
                    token.outgoingEdge    = outgoingFromInitLoop[0];
                    token.loopNodeStack.Add(loopNode);
                }
            }
            else
            {
                //I don't care which path to take, so I will just take the first one. In the advance part (see above) if it's a decision node, it will take the first possible path, if any
                if (outgoingAfterAdvance.Count >= 1)
                {
                    token.outgoingEdge = outgoingAfterAdvance[0];
                    nextTokens.Add(token);
                }
                else if (token.loopNodeStack.Count != 0) //check if we're in a loop node
                {
                    //if (ACTIVATE_DEBUG_CONSOLE_OUTPUT_TOKENS) cerr << "dbg Part1: edge null, but in loop node" << endl;

                    while (((token.outgoingEdge == null)) && (token.loopNodeStack.Count != 0)) //while we are still in a loopnode and it is finished
                    {
                        LoopNode lastLoop = token.loopNodeStack[token.loopNodeStack.Count - 1];
                        if (lastLoop.eval()) //test exit condition
                        {
                            //exiting loop node

                            List <ActivityEdge> outgoingFromLoop = lastLoop.getOutgoingControlFlowEdges();

                            if (outgoingFromLoop.Count != 0)
                            {
                                token.currentLocation = lastLoop;
                                token.outgoingEdge    = outgoingFromLoop[0];
                            }

                            token.loopNodeStack.RemoveAt(token.loopNodeStack.Count - 1); //remove last loop from stack (exit)
                        }
                        else
                        {
                            //restarting loop node

                            ActivityNode        initLoop             = lastLoop.Initial;
                            List <ActivityEdge> outgoingFromInitLoop = initLoop.getOutgoingControlFlowEdges();

                            token.currentLocation = initLoop;
                            token.outgoingEdge    = outgoingFromInitLoop[0]; //it should exist, given the fact that we've entered this loop node already
                        }
                    }

                    if (token.outgoingEdge != null)
                    {
                        nextTokens.Add(token);
                    }
                }
            }


            //continue to advance
            for (int i = 0; i < nextTokens.Count; ++i)
            {
                tryToAdvanceToken(nextTokens[i], doneAction, gotTicketToUseAction);
            }

            return(true);
        }