// проверка дорожки участника
 public void checkSwimlane(Swimlane swimlane)
 {
     swimlaneCount++;
     // проверка на уникальность имени
     if (participantNames.Contains(swimlane.getName().ToLower()))
     {
         ADMistakeFactory.createMistake(MistakesSeriousness.mistakes[MISTAKES.REPEATED_NAME], MistakeAdapter.toString(MISTAKES.REPEATED_NAME), swimlane, ALL_MISTAKES.REPEATED_NAME);
         return;
     }
     else
     {
         participantNames.Add(swimlane.getName().ToLower());
     }
     // проверка на заглавную букву
     if ((!swimlane.getName().Substring(0, 1).ToUpper().Equals(swimlane.getName().Substring(0, 1))))
     {
         ADMistakeFactory.createMistake(Level.HARD, MistakeAdapter.toString(MISTAKES.SMALL_LETTER), swimlane, ALL_MISTAKES.SMALL_LETTER);
     }
     // проверка на колво дочерних элементов
     if (swimlane.ChildCount == 0)
     {
         ADMistakeFactory.createMistake(Level.EASY, MistakeAdapter.toString(MISTAKES.EMPTY_SWIMLANE), swimlane, ALL_MISTAKES.EMPTY_SWIMLANE);
     }
     // проверка на спец символ
     if (hasSpecialSymbol(swimlane.getName()))
     {
         ADMistakeFactory.createMistake(Level.HARD, MistakeAdapter.toString(MISTAKES.STRANGE_SYMBOL), swimlane, ALL_MISTAKES.STRANGE_SYMBOL);
     }
 }
        // проверка перехода
        public void checkFlow(ControlFlow flow)
        {
            bool notCondButHaveMark = false;
            bool isCond             = false;

            // если это не условие, проверяем подпись
            if (diagramElements.get(flow.getTarget()).getType() != ElementType.DECISION)
            {
                if (!flow.getText().Equals(""))
                {
                    notCondButHaveMark = true;
                }
            }
            else
            {
                isCond = true;
            }

            if (diagramElements.get(flow.getSrc()).getType() != ElementType.DECISION)
            {
                if (!flow.getText().Equals(""))
                {
                    if (!isCond)
                    {
                        ADMistakeFactory.createMistake(Level.HARD, MistakeAdapter.toString(MISTAKES.HAVE_MARK) + " - \"" + flow.getText() + "\"", flow, ALL_MISTAKES.HAVE_MARK);
                    }
                }
                else if (notCondButHaveMark)
                {
                    ADMistakeFactory.createMistake(Level.HARD, MistakeAdapter.toString(MISTAKES.HAVE_MARK) + " - \"" + flow.getText() + "\"", flow, ALL_MISTAKES.HAVE_MARK);
                }
            }
        }
        // проверка активности
        public void checkActivity(ActivityNode activity, ADNodesList.ADNode node)
        {
            if (activity.getName().Length == 0)
            {
                ADMistakeFactory.createMistake(Level.HARD, MistakeAdapter.toString(MISTAKES.NO_NAME), node, ALL_MISTAKES.NO_NAME);
            }
            else
            {
                // проверка на уникальность имени
                if (activityNames.Contains(activity.getName().ToLower()))
                {
                    ADMistakeFactory.createMistake(MistakesSeriousness.mistakes[MISTAKES.REPEATED_NAME], MistakeAdapter.toString(MISTAKES.REPEATED_NAME), diagramElements.getNode(activity.getId()), ALL_MISTAKES.REPEATED_NAME);
                    return;
                }
                else
                {
                    activityNames.Add(activity.getName().ToLower());
                }

                // проверка на заглавную букву
                if ((!activity.getName().Substring(0, 1).ToUpper().Equals(activity.getName().Substring(0, 1))))
                {
                    ADMistakeFactory.createMistake(Level.HARD, MistakeAdapter.toString(MISTAKES.SMALL_LETTER), node, ALL_MISTAKES.SMALL_LETTER);
                }
                // получаем первое слово существительного и проверяем, что оно не заканчивается на ь или т
                string firstWord = activity.getName().Split(' ')[0];
                //Console.WriteLine(firstWord);

                if (firstWord.EndsWith("те") || firstWord.EndsWith("чи") || firstWord.EndsWith("ти") || firstWord.EndsWith("ть") || firstWord.EndsWith("чь") || firstWord.EndsWith("т"))
                {
                    ADMistakeFactory.createMistake(Level.EASY, MistakeAdapter.toString(MISTAKES.NOT_NOUN), node, ALL_MISTAKES.NOT_NOUN);
                }
            }
        }
        public void check()
        {
            lexicalAnalizator.setDiagramElements(diagramElements);

            // прохождение по всем элементам и их проверка
            for (int i = 0; i < diagramElements.size(); i++)
            {
                BaseNode currentNode = diagramElements.get(i);
                switch (diagramElements.get(i).getType())
                {
                case ElementType.FLOW:
                    lexicalAnalizator.checkFlow((ControlFlow)diagramElements.get(i));
                    break;

                case ElementType.INITIAL_NODE:
                    checkIfInPartion((DiagramElement)currentNode, "", diagramElements.getNode(i));
                    if (((DiagramElement)currentNode).outSize() == 0)
                    {
                        ADMistakeFactory.createMistake(MistakesSeriousness.mistakes[MISTAKES.NO_OUT], MistakeAdapter.toString(MISTAKES.NO_OUT), diagramElements.getNode(i), ALL_MISTAKES.NO_OUT);
                    }
                    checkInitial();
                    break;

                case ElementType.FINAL_NODE:
                    checkIfInPartion((DiagramElement)currentNode, "", diagramElements.getNode(i));
                    if (((DiagramElement)currentNode).inSize() == 0)
                    {
                        ADMistakeFactory.createMistake(MistakesSeriousness.mistakes[MISTAKES.NO_OUT], MistakeAdapter.toString(MISTAKES.NO_IN), diagramElements.getNode(i), ALL_MISTAKES.NO_IN);
                    }
                    checkFinal();
                    break;

                case ElementType.FORK:
                    checkIfInPartion((DiagramElement)currentNode, "", diagramElements.getNode(i));
                    checkInOut((DiagramElement)currentNode, "", diagramElements.getNode(i));
                    checkFork((ForkNode)currentNode, diagramElements.getNode(i));
                    break;

                case ElementType.JOIN:
                    checkIfInPartion((DiagramElement)currentNode, "", diagramElements.getNode(i));
                    checkInOut((DiagramElement)currentNode, "", diagramElements.getNode(i));
                    break;

                case ElementType.MERGE:
                    checkIfInPartion((DiagramElement)currentNode, "", diagramElements.getNode(i));
                    checkInOut((DiagramElement)currentNode, "", diagramElements.getNode(i));
                    break;

                case ElementType.ACTIVITY:
                    lexicalAnalizator.checkActivity((ActivityNode)diagramElements.get(i), diagramElements.getNode(i));

                    checkIfInPartion((DiagramElement)currentNode, ((ActivityNode)currentNode).getName(), diagramElements.getNode(i));
                    checkInOut((DiagramElement)currentNode, ((ActivityNode)currentNode).getName(), diagramElements.getNode(i));
                    checkActivity((ActivityNode)diagramElements.get(i), diagramElements.getNode(i));
                    break;

                case ElementType.DECISION:
                    lexicalAnalizator.checkDecision((DecisionNode)diagramElements.get(i), diagramElements.getNode(i));

                    checkIfInPartion((DiagramElement)currentNode, ((DecisionNode)currentNode).getQuestion(), diagramElements.getNode(i));
                    checkInOut((DiagramElement)currentNode, ((DecisionNode)currentNode).getQuestion(), diagramElements.getNode(i));
                    checkDecision((DecisionNode)diagramElements.get(i), diagramElements.getNode(i));
                    break;

                case ElementType.SWIMLANE:
                    lexicalAnalizator.checkSwimlane((Swimlane)diagramElements.get(i));
                    break;

                case ElementType.UNKNOWN:
                    break;
                }
            }
            if (finalCount == 0)
            {
                ADMistakeFactory.createMistake(MistakesSeriousness.mistakes[MISTAKES.NO_FINAL], MistakeAdapter.toString(MISTAKES.NO_FINAL), ALL_MISTAKES.NO_FINAL);
            }
            if (initialCount == 0)
            {
                ADMistakeFactory.createMistake(MistakesSeriousness.mistakes[MISTAKES.NO_INITIAL], MistakeAdapter.toString(MISTAKES.NO_INITIAL), ALL_MISTAKES.NO_INITIAL);
            }
            if (activityCount == 0)
            {
                ADMistakeFactory.createMistake(MistakesSeriousness.mistakes[MISTAKES.NO_ACTIVITIES], MistakeAdapter.toString(MISTAKES.NO_ACTIVITIES), ALL_MISTAKES.NO_ACTIVITIES);
            }
            if (lexicalAnalizator.swimlaneCount == 0)
            {
                ADMistakeFactory.createMistake(MistakesSeriousness.mistakes[MISTAKES.NO_SWIMLANE], MistakeAdapter.toString(MISTAKES.NO_SWIMLANE), ALL_MISTAKES.NO_SWIMLANE);
            }
        }
        private void checkDecision(DecisionNode decision, ADNodesList.ADNode node)
        {
            bool checkAlt = true;

            // проверка, что альтернативы есть
            if (decision.alternativeSize() == 0)
            {
                ADMistakeFactory.createMistake(MistakesSeriousness.mistakes[MISTAKES.DO_NOT_HAVE_ALT], MistakeAdapter.toString(MISTAKES.DO_NOT_HAVE_ALT), node, ALL_MISTAKES.DO_NOT_HAVE_ALT);
                checkAlt = false;
            }

            // проверка, что альтернатив больше одной
            if (checkAlt)
            {
                if (decision.alternativeSize() == 1)
                {
                    ADMistakeFactory.createMistake(MistakesSeriousness.mistakes[MISTAKES.ONLY_ONE_ALT], MistakeAdapter.toString(MISTAKES.ONLY_ONE_ALT), node, ALL_MISTAKES.ONLY_ONE_ALT);
                }
            }

            // проверка, что альтернативы не ведут в один и тот же элемент
            if (checkAlt)
            {
                for (int i = 0; i < decision.outSize() - 1; i++)
                {
                    string targetId = ((ControlFlow)diagramElements.get(decision.getOutId(i))).getTarget();
                    for (int j = i + 1; j < decision.outSize(); j++)
                    {
                        if (targetId.Equals(((ControlFlow)diagramElements.get(decision.getOutId(j))).getTarget()))
                        {
                            ADMistakeFactory.createMistake(MistakesSeriousness.mistakes[MISTAKES.SAME_TARGET], MistakeAdapter.toString(MISTAKES.SAME_TARGET), node, ALL_MISTAKES.SAME_TARGET);
                        }
                    }
                    if (diagramElements.get(targetId).getType() == ElementType.DECISION)
                    {
                        ADMistakeFactory.createMistake(MistakesSeriousness.mistakes[MISTAKES.NEXT_DECISION], MistakeAdapter.toString(MISTAKES.NEXT_DECISION), node, ALL_MISTAKES.NEXT_DECISION);
                    }
                }
                // проверка на последовательность условных операторов
                string targetId2 = ((ControlFlow)diagramElements.get(decision.getOutId(decision.outSize() - 1))).getTarget();
                if (diagramElements.get(targetId2).getType() == ElementType.DECISION)
                {
                    ADMistakeFactory.createMistake(MistakesSeriousness.mistakes[MISTAKES.NEXT_DECISION], MistakeAdapter.toString(MISTAKES.NEXT_DECISION), node, ALL_MISTAKES.NEXT_DECISION);
                }
            }
        }
 private void checkActivity(ActivityNode activity, ADNodesList.ADNode node)
 {
     activityCount++;
     // активность имеет больше одного выходящего перехода
     if (activity.outSize() >= 2)
     {
         ADMistakeFactory.createMistake(MistakesSeriousness.mistakes[MISTAKES.MORE_THAN_ONE_OUT], MistakeAdapter.toString(MISTAKES.MORE_THAN_ONE_OUT), node, ALL_MISTAKES.MORE_THAN_ONE_OUT);
     }
 }
 private void checkInitial()
 {
     initialCount++;
     if (initialCount > 1)
     {
         ADMistakeFactory.createMistake(MistakesSeriousness.mistakes[MISTAKES.MORE_THAN_ONE_INIT], MistakeAdapter.toString(MISTAKES.MORE_THAN_ONE_INIT), ALL_MISTAKES.MORE_THAN_ONE_INIT);
     }
 }
 private void checkFork(ForkNode fork, ADNodesList.ADNode node)
 {
     for (int i = 0; i < fork.outSize(); i++)
     {
         ElementType elementType = diagramElements.get(((ControlFlow)diagramElements.get(fork.getOutId(i))).getTarget()).getType();
         Console.WriteLine("elementType=" + elementType);
         if (elementType != ElementType.ACTIVITY && elementType != ElementType.DECISION && elementType != ElementType.FORK && elementType != ElementType.MERGE)
         {
             ADMistakeFactory.createMistake(MistakesSeriousness.mistakes[MISTAKES.OUT_NOT_IN_ACT], MistakeAdapter.toString(MISTAKES.OUT_NOT_IN_ACT), node, ALL_MISTAKES.OUT_NOT_IN_ACT);
         }
     }
 }
 /**
  * Проверка, что имеется хотя бы один входящий\выходящий переход
  */
 private void checkInOut(DiagramElement currentNode, string name, ADNodesList.ADNode node)
 {
     if (currentNode is MergeNode || currentNode is JoinNode)
     {
         if ((currentNode).inSize() == 1)
         {
             ADMistakeFactory.createMistake(MistakesSeriousness.mistakes[MISTAKES.HAS_1_IN], MistakeAdapter.toString(MISTAKES.HAS_1_IN), node, ALL_MISTAKES.HAS_1_IN);
         }
     }
     if ((currentNode).inSize() == 0)
     {
         ADMistakeFactory.createMistake(MistakesSeriousness.mistakes[MISTAKES.NO_IN], MistakeAdapter.toString(MISTAKES.NO_IN), node, ALL_MISTAKES.NO_IN);
     }
     if ((currentNode).outSize() == 0)
     {
         ADMistakeFactory.createMistake(MistakesSeriousness.mistakes[MISTAKES.NO_OUT], MistakeAdapter.toString(MISTAKES.NO_OUT), node, ALL_MISTAKES.NO_OUT);
     }
 }
 /**
  * Проверка, что элемент принадлежит какому-либо участнику
  */
 private void checkIfInPartion(DiagramElement currentNode, string name, ADNodesList.ADNode node)
 {
     if (currentNode.getInPartition().Equals(""))
     {
         ADMistakeFactory.createMistake(MistakesSeriousness.mistakes[MISTAKES.NO_PARTION], MistakeAdapter.toString(MISTAKES.NO_PARTION), node, ALL_MISTAKES.NO_PARTION);
     }
 }
Exemplo n.º 11
0
        /// <summary>
        /// Распарсить XMI файл и создать объекты соответствующих классов
        /// </summary>
        /// <param name="diagram">Исходная диаграмма</param>
        /// <param name="hasJoinOrFork">Имеется ли join\fork</param>
        /// <returns></returns>
        public bool Parse(Diagram diagram, ref bool hasJoinOrFork)
        {
            xmlFile = diagram.doc;
            XmlNodeList xPackagedList;

            try {
                xPackagedList = xmlFile.GetElementsByTagName("packagedElement");
            } catch (NullReferenceException) {
                //Console.WriteLine("[x] Тег packagedElement не найден");
                return(false);
            }


            // получим корневой элемент
            XmlNode xRoot = FindActivePackageEl(xPackagedList);

            if (xRoot == null)
            {
                //Console.WriteLine("[x] Вид диаграммы не AD");
                return(false);
            }

            var attr = xRoot.Attributes["xsi:type"];

            if (attr == null)
            {
                //Console.WriteLine("[x] Не удалось распарсить xmi файл");
                return(false);
            }
            if (!attr.Value.Equals("uml:Activity"))
            {
                //Console.WriteLine("[x] Вид диаграммы не AD");
                return(false);
            }

            // пройтись по всем тегам и создать объекты
            foreach (XmlNode node in xRoot.ChildNodes)
            {
                var elAttr = node.Attributes["xsi:type"];
                if (elAttr == null)
                {
                    continue;
                }

                if (elAttr.Value == "uml:OpaqueAction" || elAttr.Value == "uml:InitialNode" || elAttr.Value == "uml:ActivityFinalNode" ||
                    elAttr.Value == "uml:FlowFinalNode" || elAttr.Value == "uml:DecisionNode" || elAttr.Value == "uml:MergeNode" ||
                    elAttr.Value == "uml:ForkNode" || elAttr.Value == "uml:JoinNode")
                {
                    DiagramElement nodeFromXMI = null;
                    switch (elAttr.Value)
                    {
                    // активность
                    case "uml:OpaqueAction":
                        nodeFromXMI = new ActivityNode(node.Attributes["xmi:id"].Value,
                                                       AttrAdapter(node.Attributes["inPartition"]), AttrAdapter(node.Attributes["name"]));
                        nodeFromXMI.setType(ElementType.ACTIVITY);
                        adNodesList.addLast(nodeFromXMI);
                        break;

                    // узел инициализации
                    case "uml:InitialNode":
                        nodeFromXMI = new InitialNode(node.Attributes["xmi:id"].Value, AttrAdapter(node.Attributes["inPartition"]));
                        nodeFromXMI.setType(ElementType.INITIAL_NODE);
                        adNodesList.addLast(nodeFromXMI);
                        break;

                    // конечное состояние
                    case "uml:ActivityFinalNode":
                    case "uml:FlowFinalNode":
                        nodeFromXMI = new FinalNode(node.Attributes["xmi:id"].Value, AttrAdapter(node.Attributes["inPartition"]));
                        nodeFromXMI.setType(ElementType.FINAL_NODE);
                        adNodesList.addLast(nodeFromXMI);
                        break;

                    // условный переход
                    case "uml:DecisionNode":
                        nodeFromXMI = new DecisionNode(node.Attributes["xmi:id"].Value, AttrAdapter(node.Attributes["inPartition"]), AttrAdapter(node.Attributes["question"]));
                        nodeFromXMI.setType(ElementType.DECISION);
                        adNodesList.addLast(nodeFromXMI);
                        break;

                    // узел слияния
                    case "uml:MergeNode":
                        nodeFromXMI = new MergeNode(node.Attributes["xmi:id"].Value, AttrAdapter(node.Attributes["inPartition"]));
                        nodeFromXMI.setType(ElementType.MERGE);
                        adNodesList.addLast(nodeFromXMI);
                        break;

                    // разветвитель
                    case "uml:ForkNode":
                        nodeFromXMI = new ForkNode(node.Attributes["xmi:id"].Value, AttrAdapter(node.Attributes["inPartition"]));
                        nodeFromXMI.setType(ElementType.FORK);
                        adNodesList.addLast(nodeFromXMI);
                        hasJoinOrFork = true;
                        break;

                    // синхронизатор
                    case "uml:JoinNode":
                        nodeFromXMI = new JoinNode(node.Attributes["xmi:id"].Value, AttrAdapter(node.Attributes["inPartition"]));
                        nodeFromXMI.setType(ElementType.JOIN);
                        adNodesList.addLast(nodeFromXMI);
                        hasJoinOrFork = true;
                        break;
                    }
                    // добавляем ид входящих и выходящих переходов
                    if (nodeFromXMI != null)
                    {
                        string idsIn  = node.Attributes["incoming"]?.Value;
                        string idsOut = node.Attributes["outgoing"]?.Value;
                        nodeFromXMI.addIn(idsIn ?? "");
                        nodeFromXMI.addOut(idsOut ?? "");
                    }
                }
                // создаем переход
                else if (node.Attributes["xsi:type"].Value.Equals("uml:ControlFlow"))
                {
                    // находим подпись перехода
                    var    markNode = node.ChildNodes[1];
                    string mark     = markNode.Attributes["value"].Value.Trim();    // если подпись является "yes", значит это подпись по умолчанию

                    ControlFlow temp = new ControlFlow(node.Attributes["xmi:id"].Value, mark.Equals("true") ? "" : mark);
                    temp.setType(ElementType.FLOW);
                    temp.setSrc(AttrAdapter(node.Attributes["source"]));
                    temp.setTarget(AttrAdapter(node.Attributes["target"]));
                    adNodesList.addLast(temp);
                }
                // создаем дорожку
                else if (node.Attributes["xsi:type"].Value.Equals("uml:ActivityPartition"))
                {
                    Swimlane temp = new Swimlane(node.Attributes["xmi:id"].Value, AttrAdapter(node.Attributes["name"]))
                    {
                        ChildCount = node.Attributes["node"] == null ? 0 : node.Attributes["node"].Value.Split().Length
                    };
                    temp.setType(ElementType.SWIMLANE);
                    if (temp.Name != "")
                    {
                        diagram.Actors.Add(temp);
                    }
                    adNodesList.addLast(temp);
                }
                // неизвестный элемент
                else
                {
                    var unknownNode = new UnknownNode(node.Attributes["xmi:id"].Value);
                    unknownNode.setType(ElementType.UNKNOWN);
                    unknownNodes.Add(unknownNode);
                }
            }

            XmlNode coordRoot = null;

            try {
                coordRoot = xmlFile.GetElementsByTagName("plane")[0];
            } catch (NullReferenceException) {
                //Console.WriteLine("[x] Тег packagedElement не найден");
            }

            if (coordRoot != null)
            {
                FindCoordinates(coordRoot, diagram);
            }
            for (int i = 0; i < adNodesList.size(); i++)
            {
                var node = adNodesList.get(i);
                if (node is DiagramElement)
                {
                    var nodeFromXMI = (DiagramElement)node;
                    switch (nodeFromXMI.getType())
                    {
                    case ElementType.FINAL_NODE:
                        if (nodeFromXMI.inSize() == 0)
                        {
                            // ошибка
                            ADMistakeFactory.createMistake(MistakesSeriousness.mistakes[MISTAKES.NO_IN], MistakeAdapter.toString(MISTAKES.NO_IN), new ADNodesList.ADNode(nodeFromXMI), ALL_MISTAKES.NO_IN);
                        }
                        break;

                    case ElementType.INITIAL_NODE:
                        if (nodeFromXMI.outSize() == 0)
                        {
                            // ошибка
                            ADMistakeFactory.createMistake(MistakesSeriousness.mistakes[MISTAKES.NO_OUT], MistakeAdapter.toString(MISTAKES.NO_OUT), new ADNodesList.ADNode(nodeFromXMI), ALL_MISTAKES.NO_OUT);
                        }
                        break;

                    default:
                        if (nodeFromXMI.inSize() == 0 || nodeFromXMI.outSize() == 0)
                        {
                            // ошибка
                            if (nodeFromXMI.inSize() == 0)
                            {
                                ADMistakeFactory.createMistake(MistakesSeriousness.mistakes[MISTAKES.NO_IN], MistakeAdapter.toString(MISTAKES.NO_IN), new ADNodesList.ADNode(nodeFromXMI), ALL_MISTAKES.NO_IN);
                            }
                            if (nodeFromXMI.outSize() == 0)
                            {
                                ADMistakeFactory.createMistake(MistakesSeriousness.mistakes[MISTAKES.NO_OUT], MistakeAdapter.toString(MISTAKES.NO_OUT), new ADNodesList.ADNode(nodeFromXMI), ALL_MISTAKES.NO_OUT);
                            }
                        }
                        break;
                    }
                }
            }
            // ошибка - тип элемента не принадлежит AD
            foreach (var node in unknownNodes)
            {
                ADMistakeFactory.createMistake(MistakesSeriousness.mistakes[MISTAKES.FORBIDDEN_ELEMENT], MistakeAdapter.toString(MISTAKES.FORBIDDEN_ELEMENT), node, ALL_MISTAKES.FORBIDDEN_ELEMENT);
            }

            return(true);
        }
Exemplo n.º 12
0
        public void check(ADNodesList adList)
        {
            Queue <List <Token> > leaves      = new Queue <List <Token> >();                          // необработанные маски
            HashSet <string>      masksInUsed = new HashSet <string>(adList.getPetriElementsCount()); // использованные маски

            // ищем начальное состояние
            ADNodesList.ADNode initNode = adList.findInitial();
            var finalNode          = adList.findFinal();
            var indexesOfFinalNode = finalNode.Select(x => ((DiagramElement)x.getValue()).petriId).ToList();

            // создаем маску и добавляем ее в необработанные
            List <Token> maskTmp = createEmptyMask(adList.getPetriElementsCount());

            setNewPaleToken(maskTmp, ((DiagramElement)initNode.getValue()).petriId);

            leaves.Enqueue(maskTmp);
            masksInUsed.Add(maskToString(maskTmp));   // добавляем в множество использованных

            bool canReachFinal = false;

            List <List <Token> > stepResultMasks = new List <List <Token> >();       // содержит маски, кот могут получиться на каждом шаге
            string originMaskString = "";

            // главный цикл прохода по всем элементам, участвующих в проверке
            while (leaves.Count > 0)
            {
                List <Token> originMask = leaves.Dequeue();  // берем первую маску
                originMaskString = maskToString(originMask);
                stepResultMasks.Clear();
                List <Token> stepMask = copyMask(originMask); // маска, которую будем изменять по мере деактивации токенов
                stepResultMasks.Add(copyMask(stepMask));      // Если список масок не изменится, то будет тупик, тк текущая маска уже добавлена в использованные

                int i = 0;
                // Console.WriteLine("Or: " + maskToString(originMask));

                // проходим по всем элементам маски, находим активированные
                // и проверяем, можно ли активировать следующий элемент
                for (int stepProhod = 0; stepProhod < 2; stepProhod++)       // сначала проходим по условным, затем по остальным эл-м
                {
                    i = 0;
                    while (i < stepMask.Count)
                    {
                        if (stepProhod == 0 && adList.getNodeByPetriIndex(i).getValue().getType() != ElementType.DECISION)
                        {
                            i++;
                            continue;   // интересуют только эл-ты, содержащие токены на данном шаге
                        }
                        if (stepProhod == 0 && adList.getNodeByPetriIndex(i).getValue().getType() == ElementType.DECISION && stepMask[i].type != TOKEN)
                        {
                            i++;
                            continue;   // интересуют только эл-ты, содержащие токены на данном шаге
                        }
                        if (stepProhod == 1 && stepMask[i].type != TOKEN)
                        {
                            i++;
                            continue;   // интересуют только эл-ты, содержащие токены на данном шаге
                        }
                        // нашли активный элемент
                        ADNodesList.ADNode curNode = adList.getNodeByPetriIndex(i);     //индекс в списке совпадает с петри ид эл-та
                        int        curNodeIndex    = ((DiagramElement)curNode.getValue()).petriId;
                        List <int> colorsCurToken  = new List <int>(stepMask[curNodeIndex].colors);

                        // особо обрабатываем ситуации, когда элемент имеет несколько выходных переходов
                        if (curNode.nextSize() > 1)
                        {
                            // если эл-т разветвитель, то последующее состояние единственно, однако надо установить несколько токенов за раз
                            if (curNode.getValue().getType() == ElementType.FORK)
                            {
                                colorsCurToken.Add(generateRandomColor());

                                // активируем все следующие элементы
                                for (int j = 0; j < curNode.nextSize(); j++)
                                {
                                    // сразу после форка не может быть join'a, поэтому все эл-ты будут активированы
                                    int indexOfNewToken = ((DiagramElement)curNode.getNext(j).getValue()).petriId;
                                    // проверка, что эл-т не был раннее активирован
                                    if (wasAlreadyActive(indexOfNewToken, stepResultMasks, curNode.getNext(j)))
                                    {
                                        return;
                                    }
                                    // изменяем существующие результирующие маски
                                    updateStepMasks(((DiagramElement)curNode.getValue()).petriId, indexOfNewToken, stepResultMasks, colorsCurToken);
                                }
                                setNewEmptyToken(stepMask, curNodeIndex);
                            }
                            // если это условный оператор, то он порождает несколько возможных последующих состояний
                            else
                            {
                                List <List <Token> > decisionMasks = new List <List <Token> >();   // содержит все возможные маски вариантов перемещения токена
                                bool tokenWasRemoved = false;
                                // активируем следующие элементы по одному
                                for (int j = 0; j < curNode.nextSize(); j++)
                                {
                                    int indexOfNewToken = ((DiagramElement)curNode.getNext(j).getValue()).petriId;      // индекс активируемого эл-та
                                                                                                                        // проверка, что эл-т не был раннее активирован
                                    if (wasAlreadyActive(indexOfNewToken, stepResultMasks, curNode.getNext(j)))
                                    {
                                        return;
                                    }
                                    // Join обрабатывается с помощью reverse проверки
                                    if ((curNode.getNext(j).getValue()).getType() == ElementType.JOIN)
                                    {
                                        List <List <Token> > temp   = copyMasks(stepResultMasks);
                                        List <Token>         result = activateJoin(curNode.getNext(j), stepMask, temp, colorsCurToken);
                                        if (result != null)
                                        {
                                            stepMask = result;
                                            decisionMasks.AddRange(temp);
                                            tokenWasRemoved = true;
                                        }
                                    }
                                    else
                                    {
                                        // в каждой существующей результирующей маске меняем токен и сохраняем в промежуточный список
                                        // в итоге получится новый список, содержащий несколько вариантов результирующих масок,
                                        // в каждом из которых создан новый токен в зависимости от активированного следующего эл-та
                                        foreach (List <Token> resultMask in stepResultMasks)
                                        {
                                            List <Token> temp = copyMask(resultMask);
                                            setToken(temp, indexOfNewToken, NEW_TOKEN, colorsCurToken); // добавляем новый токен

                                            setNewEmptyToken(temp, curNodeIndex);                       // удаляем токен текущего эл-та
                                            decisionMasks.Add(temp);
                                            tokenWasRemoved = true;
                                        }
                                    }
                                }
                                // изменяем маску шага и список результирующих масок, если токен был удален
                                if (tokenWasRemoved)
                                {
                                    setNewEmptyToken(stepMask, ((DiagramElement)curNode.getValue()).petriId);
                                    // меняем результирующую маску
                                    stepResultMasks = decisionMasks;
                                }
                            }
                        }
                        else           // если выходной переход один
                        {
                            int indexOfNewToken = ((DiagramElement)curNode.getNext(0).getValue()).petriId;
                            // проверка, что эл-т не был раннее активирован
                            if (wasAlreadyActive(indexOfNewToken, stepResultMasks, curNode.getNext(0)))
                            {
                                return;
                            }
                            // если следующий Join
                            if ((curNode.getNext(0).getValue()).getType() == ElementType.JOIN)
                            {
                                List <Token> result = activateJoin(curNode.getNext(0), stepMask, stepResultMasks, colorsCurToken);
                                if (result != null)
                                {
                                    stepMask = result;
                                }
                            }
                            else
                            {
                                updateStepMasks(((DiagramElement)curNode.getValue()).petriId, indexOfNewToken, stepResultMasks, colorsCurToken);
                                setNewEmptyToken(stepMask, curNodeIndex);
                            }
                        }
                        i++;
                    }
                }
                // в результирующих масках заменяем NEW_Token на TOKEN
                foreach (List <Token> stepResultMask in stepResultMasks)
                {
                    stepResultMask.ForEach(x => x.type = x.type == NEW_TOKEN ? TOKEN : x.type);
                    //Console.WriteLine("Re: " + maskToString(stepResultMask));
                    if (originMaskString == maskToString(stepResultMask))
                    {
                        ADMistakeFactory.createMistake(MistakesSeriousness.mistakes[MISTAKES.DEAD_ROAD], MistakeAdapter.toString(MISTAKES.DEAD_ROAD), ALL_MISTAKES.DEAD_ROAD);
                        //Console.WriteLine("Again?: "+originMaskString);
                        return;
                    }
                }
                // проверяем, что новой маски нет во множестве обработанных и добавляем в необработанные в таком случае
                foreach (List <Token> resultMask in stepResultMasks)
                {
                    if (!findInMasksInUsed(masksInUsed, resultMask))
                    {
                        int indexOfFinalNode = -1;

                        // проверяем, не достигли ли конечной маркировки (существует путь позволяющий добраться хоть до какого-н finalNode)
                        foreach (var ind in indexesOfFinalNode)
                        {
                            if (resultMask[ind].type == TOKEN)
                            {
                                indexOfFinalNode = ind;
                                break;
                            }
                        }
                        if (indexOfFinalNode != -1)
                        {
                            canReachFinal = true;
                            if (resultMask[indexOfFinalNode].peekLastColor() != NO_COLOR)
                            {
                                ADMistakeFactory.createMistake(MistakesSeriousness.mistakes[MISTAKES.FINAL_COLOR_TOKEN], MistakeAdapter.toString(MISTAKES.FINAL_COLOR_TOKEN), ALL_MISTAKES.FINAL_COLOR_TOKEN);
                                return;
                            }
                            //Проверка, что не осталось токенов
                            int tokenCount = 0;
                            for (int j = 0; j < resultMask.Count && tokenCount <= 1; j++)
                            {
                                if (resultMask[j].type == TOKEN)
                                {
                                    tokenCount++;
                                }
                            }
                            if (tokenCount > 1)
                            {
                                ADMistakeFactory.createMistake(MistakesSeriousness.mistakes[MISTAKES.MANY_TOKENS_IN_END], MistakeAdapter.toString(MISTAKES.MANY_TOKENS_IN_END), ALL_MISTAKES.MANY_TOKENS_IN_END);
                                return;
                            }
                        }
                        else
                        {
                            leaves.Enqueue(copyMask(resultMask));
                        }
                        masksInUsed.Add(maskToString(resultMask));      // добавляем полученную маску в множество обработанных
                    }
                }
            }

            // проверяем, что конечное состояние было достигнуто
            if (!canReachFinal)
            {
                ADMistakeFactory.createMistake(MistakesSeriousness.mistakes[MISTAKES.COULD_NOT_REACH_FINAL], MistakeAdapter.toString(MISTAKES.COULD_NOT_REACH_FINAL), ALL_MISTAKES.COULD_NOT_REACH_FINAL);
            }
        }
Exemplo n.º 13
0
 /**
  * Проверка был ли данный элемент раннее активирован. Если да, то проверка завершается
  */
 private bool wasAlreadyActive(int tokenIndex, List <List <Token> > stepResultMasks, ADNodesList.ADNode curNode)
 {
     foreach (List <Token> stepResultMask in stepResultMasks)
     {
         if (stepResultMask[tokenIndex].type != NO_TOKEN)
         {
             if (curNode.getValue().getType() != ElementType.FINAL_NODE)
             {
                 ADMistakeFactory.createMistake(MistakesSeriousness.mistakes[MISTAKES.TWO_TOKENS], MistakeAdapter.toString(MISTAKES.TWO_TOKENS), ALL_MISTAKES.TWO_TOKENS);
             }
             else
             {
                 ADMistakeFactory.createMistake(MistakesSeriousness.mistakes[MISTAKES.MANY_TOKENS_IN_END], MistakeAdapter.toString(MISTAKES.MANY_TOKENS_IN_END), ALL_MISTAKES.MANY_TOKENS_IN_END);
             }
             return(true);
         }
     }
     return(false);
 }
        // проверка условного перехода
        public void checkDecision(DecisionNode decision, ADNodesList.ADNode node)
        {
            // добавляем вопрос для перехода
            BaseNode flowIn = diagramElements.get(decision.getInId(0));
            string   quest  = ((ControlFlow)flowIn).getText();

            decision.setQuestion(quest.Trim());

            // добавляем альтернативы -> проходим по всем выходящим переходам и получаем подписи
            for (int i = 0; i < decision.outSize(); i++)
            {
                BaseNode flow = diagramElements.get(decision.getOutId(i));
                decision.addAlternative(((ControlFlow)flow).getText());
            }

            // проверяем подписи альтернатив, если их больше одной
            bool checkAlt = decision.alternativeSize() >= 2;

            // поиск совпадающих названий
            if (checkAlt)
            {
                decision.findEqualAlternatives().ForEach(x => ADMistakeFactory.createMistake(Level.HARD, MistakeAdapter.toString(MISTAKES.REPEATED_ALT) + " - " + x, node, ALL_MISTAKES.REPEATED_ALT));
            }

            // проверка на альтернативу без подписи
            if (checkAlt)
            {
                if (decision.findEmptyAlternative())
                {
                    ADMistakeFactory.createMistake(Level.HARD, MistakeAdapter.toString(MISTAKES.HAVE_EMPTY_ALT), node, ALL_MISTAKES.HAVE_EMPTY_ALT);
                }
            }

            // проверка, что альтернативы начинаются с заглавных букв
            //if (checkAlt)
            //    for (int i = 0; i < decision.alternativeSize(); i++)
            //    {
            //        String alter = decision.getAlternative(i);
            //        if (!alter.Equals(""))
            //            if (!alter.Substring(0, 1).ToUpper().Equals(alter.Substring(0, 1)))
            //                ADMistakeFactory.createMistake(Level.EASY,  " альтернатива \"" + alter + "\"" + MistakeAdapter.toString(MISTAKES.SMALL_LETTER), node);
            //    }


            bool checkQuest = true;

            // проверка, что имеется условие
            if (decision.getQuestion().Equals(""))
            {
                ADMistakeFactory.createMistake(Level.HARD, MistakeAdapter.toString(MISTAKES.HAVE_NOT_QUEST), node, ALL_MISTAKES.HAVE_NOT_QUEST);
                checkQuest = false; // дальнейшие проверки условия не требуются (его нет)
            }

            // проверка на заглавную букву
            if (checkQuest)
            {
                if ((!decision.getQuestion().Substring(0, 1).ToUpper().Equals(decision.getQuestion().Substring(0, 1))))
                {
                    ADMistakeFactory.createMistake(Level.EASY, MistakeAdapter.toString(MISTAKES.SMALL_LETTER), node, ALL_MISTAKES.SMALL_LETTER);
                }
            }
            // заканчивается на знак вопроса
            if (checkQuest)
            {
                if ((!decision.getQuestion().EndsWith("?")))
                {
                    ADMistakeFactory.createMistake(Level.EASY, MistakeAdapter.toString(MISTAKES.END_WITH_QUEST), node, ALL_MISTAKES.END_WITH_QUEST);
                }
            }
        }