1
////////////////////////////////////////////////////////////////////////////////
3
// This file is part of Toolkit for Conceptual Modeling (TCM).
4
// (c) copyright 1997, Vrije Universiteit Amsterdam.
5
// Author: Frank Dehne (frank@cs.vu.nl).
7
// TCM is free software; you can redistribute it and/or modify
8
// it under the terms of the GNU General Public License as published by
9
// the Free Software Foundation; either version 2 of the License, or
10
// (at your option) any later version.
12
// TCM is distributed in the hope that it will be useful,
13
// but WITHOUT ANY WARRANTY; without even the implied warranty of
14
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
// GNU General Public License for more details.
17
// You should have received a copy of the GNU General Public License
18
// along with TCM; if not, write to the Free Software
19
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
21
////////////////////////////////////////////////////////////////////////////////
25
#include "transition.h"
27
#include "initialstate.h"
29
STChecks::STChecks(Diagram *d, Graph *g): DiagramChecks(d,g) { }
31
unsigned STChecks::CheckUnreachableStates(string &chkbuf) {
33
List<Subject *> initStates, States;
35
GetGraph()->GetNodes(&initStates, Code::INITIAL_STATE);
36
GetGraph()->GetNodes(&States, Code::STATE);
37
GetGraph()->GetNodes(&States, Code::DECISION_POINT);
38
if (initStates.count() == 0)
41
initState = initStates[0];
42
for (States.first(); !States.done(); States.next()) {
43
Subject *state = States.cur();
44
if (!GetGraph()->PathExists(initState, state)) {
45
chkbuf += "* Error: ";
46
chkbuf += Code::GetName(state->GetClassType());
48
chkbuf += *state->GetName();
50
chkbuf += "is not reachable from the initial state\n";
51
GetDiagram()->SelectSubject(state);
58
unsigned STChecks::CheckNoActions(string &chkbuf) {
59
List<Subject *> transitions;
60
GetGraph()->GetEdges(&transitions, Code::TRANSITION);
61
for (transitions.first(); !transitions.done(); transitions.next()) {
62
Transition *transition = (Transition *)transitions.cur();
63
if (transition->NrActions() > 0)
64
// ok there is an action in a transition.
67
List<Subject *> initStates;
68
GetGraph()->GetNodes(&initStates, Code::INITIAL_STATE);
69
for (initStates.first(); !initStates.done(); initStates.next()) {
70
InitialState *initState = (InitialState *)initStates.cur();
71
if (initState->NrActions() > 0)
72
// ok there is an action in an initial state.
75
// there is no action.
76
chkbuf += "* Error: the diagram does not contain any action\n";
80
unsigned STChecks::CheckEmptyActions(string &chkbuf) {
82
List<Subject *> transitions;
83
GetGraph()->GetEdges(&transitions, Code::TRANSITION);
84
for (transitions.first(); !transitions.done(); transitions.next()) {
85
Transition *transition = (Transition *)transitions.cur();
86
// transitions from and to the same node should have
88
if (transition->GetSubject1() == transition->GetSubject2()) {
89
if (transition->NrActions() > 0)
91
chkbuf += "* Error: the transition from and to ";
92
Subject *n = transition->GetSubject1();
93
chkbuf += Code::GetName(n->GetClassType());
95
chkbuf += *n->GetName();
96
chkbuf += "' should have actions\n";
97
GetDiagram()->SelectSubject(transition);
104
unsigned STChecks::CheckEmptyEvents(string &chkbuf) {
106
List<Subject *> transitions;
107
GetGraph()->GetEdges(&transitions, Code::TRANSITION);
108
for (transitions.first(); !transitions.done(); transitions.next()) {
109
Transition *transition = (Transition *)transitions.cur();
110
const string *event = transition->GetEvent();
112
GetDiagram()->SelectSubject(transition);
117
chkbuf += "* Error: there ";
119
chkbuf += "is a Transition";
123
chkbuf += " Transitions";
125
chkbuf += " without an event\n";
130
unsigned STChecks::CheckDoubleEvents(string &chkbuf) {
132
List<Subject *> transitions; // all transitions.
133
List<Subject *> transitions2; // transitions between same states.
134
List<Subject *> transitions3; // already checked transitions.
135
GetGraph()->GetEdges(&transitions, Code::TRANSITION);
136
for (transitions.first(); !transitions.done(); transitions.next()) {
137
Transition *transition = (Transition *)transitions.cur();
138
if (transitions3.find(transition) == -1) {
139
const string *event = transition->GetEvent();
142
transitions2.empty();
143
GetGraph()->GetEdges(&transitions2,
144
transition->GetSubject1(),
145
transition->GetSubject2(),
148
for (transitions2.first(); !transitions2.done();
149
transitions2.next()) {
150
Transition *transition2 =
151
(Transition *)transitions2.cur();
152
if (transition2 != transition &&
153
*event == *transition2->GetEvent()) {
154
transitions3.add(transition2);
155
GetDiagram()->SelectSubject(transition);
156
GetDiagram()->SelectSubject(transition2);
162
chkbuf += "* Error: there are ";
164
chkbuf += " transitions between node '";
165
chkbuf += *transition->GetSubject1()->GetName();
166
chkbuf += "' and node '";
167
chkbuf += *transition->GetSubject2()->GetName();
168
chkbuf += "' having event ";
173
transitions3.add(transition);