Überprüfung Syntaktischer Robustheit von Statecharts auf...
Transcript of Überprüfung Syntaktischer Robustheit von Statecharts auf...
Christian-Albrechts-Universität zu Kiel
Diplomarbeit
Überprüfung SyntaktischerRobustheit von Statecharts auf
der Basis von OCL
cand. inf. Ken Bell(Mat.Nr. 574455)
November 2006
Institut für InformatikLehrstuhl für Echtzeitsysteme und Eingebettete Systeme
Prof. Dr. Reinhard von Hanxleden
betreut durch:Steffen H. Prochnow
Eidesstattliche Erklärung
Hiermit erkläre ich an Eides statt, dass ich die vorliegende Arbeit selbstständigverfasst und keine anderen als die angegebenen Hilfsmittel verwendet habe.
Kiel,
Zusammenfassung
Die Verbreitung von eingebetteten Echtzeitsystemen wird immer größer. Insbesonde-re die Systeme, die zur Steuerung von sicherheitskritischen Anwendungen entwickeltwerden, sollten fehlerfrei sein. Zur Fehlervermeidung in der Softwareentwicklung gibtes verschiedene Style-Guides, mit denen eine Programmiersprache auf einen Umfangeingeschränkt wird, von dem man annimmt, dass dieser weniger fehleranfällig ist.Statecharts sind ein Formalismus zur Beschreibung reaktiver, eingebetteter Systeme.Klassische, d. h. für textuelle Programmiersprachen entwickelte Style-Guides, lassensich nicht ohne weiteres auf Statecharts übertragen. Diese Diplomarbeit befasst sichmit der Fehlervermeidung in der Softwareentwicklung mit Statecharts.
Danksagungen
Als erstes möchte ich Steffen Prochnow für seine unermüdliche Betreuung danken.Die Diskussionen mit ihm haben die vorliegende Arbeit ermöglicht.
Als nächstes danke ich meinen Eltern, die mich stets unterstützt haben.
Herzlicher Dank gilt natürlich auch meinen beiden Korrektoren: Christiane Stiefelund Christopher Hlubek.
Abschließend möchte ich mich bei der b+m Informatik AG für die freundliche Zu-sammenarbeit bedanken.
vii
Inhaltsverzeichnis
Tabellenverzeichnis xi
Abbildungsverzeichnis xiii
Verzeichnis der Auflistungen xv
1. Einleitung 11.1. Verwandte Arbeiten . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2. Entwicklung eingebetteter, reaktiver Systeme 52.1. Statecharts als Entwicklungstechnik . . . . . . . . . . . . . . . . . . . 52.2. Statechart Dialekte . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
3. Einführung der OCL 153.1. Constraint-Sprachen . . . . . . . . . . . . . . . . . . . . . . . . . . . 153.2. Anwendungsgebiete der OCL . . . . . . . . . . . . . . . . . . . . . . 193.3. Werkzeugunterstützung . . . . . . . . . . . . . . . . . . . . . . . . . . 20
4. Style-Checking von Statecharts 254.1. Taxonomie des Style-Checking von Statecharts . . . . . . . . . . . . . 254.2. Ein Style-Guide für Statecharts . . . . . . . . . . . . . . . . . . . . . 274.3. Style-Checker . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
5. Implementierung 355.1. KIEL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 355.2. Verfahren für das Style-Checking . . . . . . . . . . . . . . . . . . . . 365.3. Style-Checking in KIEL . . . . . . . . . . . . . . . . . . . . . . . . . 37
5.3.1. OCL-Toolkits . . . . . . . . . . . . . . . . . . . . . . . . . . . 395.3.2. Verwendung des Dresden OCL Toolkits . . . . . . . . . . . . . 425.3.3. Arbeitsweise des Style-Checkers . . . . . . . . . . . . . . . . . 46
5.4. XMI-Import . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
6. Ergebnisse 516.1. KOCL Usability-Analyse . . . . . . . . . . . . . . . . . . . . . . . . . 516.2. Laufzeitanalyse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 536.3. Ein reales Beispiel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
ix
Inhaltsverzeichnis
7. Zusammenfassung und Ausblick 61
A. Literaturverzeichnis 63
B. Regelprofile 71
C. Die EBNF von KOCL 75
D. Das Metamodell 77
E. Parserspezifikationen im SableCC Format 79E.1. KOCL-Grammatik . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79E.2. JavaTransitionLabels-Grammatik . . . . . . . . . . . . . . . . . . . . 80
F. KOCL-Spezifikationen 87F.1. Well-formedness-Regeln . . . . . . . . . . . . . . . . . . . . . . . . . 87
F.1.1. UML 1.3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87F.1.2. UML 2.0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
F.2. Robustheitsregeln . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
G. Java Code 95G.1. XMI-Konverter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
G.1.1. XMIConverter.java . . . . . . . . . . . . . . . . . . . . . . . . 96G.1.2. XMISaxConverter.java . . . . . . . . . . . . . . . . . . . . . . 98
G.2. Regel-Generator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102G.2.1. RuleParser.java . . . . . . . . . . . . . . . . . . . . . . . . . . 102G.2.2. RuleSemanticAnalyzer.java . . . . . . . . . . . . . . . . . . . . 104G.2.3. Translator.java . . . . . . . . . . . . . . . . . . . . . . . . . . 105
G.3. Checking-Plug-In . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112G.3.1. StateChartCheckerBase.java . . . . . . . . . . . . . . . . . . . 112G.3.2. BaseCheck.java . . . . . . . . . . . . . . . . . . . . . . . . . . 119G.3.3. CheckerOutputGUI.java . . . . . . . . . . . . . . . . . . . . . 121G.3.4. CheckingProblem.java . . . . . . . . . . . . . . . . . . . . . . 122G.3.5. CheckingProperties.java . . . . . . . . . . . . . . . . . . . . . 123G.3.6. MyCellRenderer.java . . . . . . . . . . . . . . . . . . . . . . . 127G.3.7. IStateChartVisitor.java . . . . . . . . . . . . . . . . . . . . . . 128G.3.8. StateChartDepthFirstAdapter.java . . . . . . . . . . . . . . . 129
G.4. XMI-Fileinterface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130G.4.1. XMI.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130G.4.2. XMIFileFilter.java . . . . . . . . . . . . . . . . . . . . . . . . 132G.4.3. ArgoUMLReader.java . . . . . . . . . . . . . . . . . . . . . . . 133G.4.4. KielUMLAttribute.java . . . . . . . . . . . . . . . . . . . . . . 146G.4.5. KielUMLDataType.java . . . . . . . . . . . . . . . . . . . . . 147G.4.6. LabelGenerator.java . . . . . . . . . . . . . . . . . . . . . . . 149G.4.7. XMIGenerator.java . . . . . . . . . . . . . . . . . . . . . . . . 153
x
Tabellenverzeichnis
2.1. Übersicht ausgewählter Statechart-Elemente und deren Bedeutung . . 9
3.1. Spezifikationssprachen und deren zugehörige Constraint-Sprachen . . 183.2. Modellierungswerkzeuge mit OCL-Unterstützung . . . . . . . . . . . 21
5.1. Anforderungen an untersuchte OCL-Toolkits . . . . . . . . . . . . . . 41
6.1. Umgesetzte Well-formedness-Regeln . . . . . . . . . . . . . . . . . . . 516.2. Umgesetzte Regeln syntaktische Robustheit . . . . . . . . . . . . . . 536.3. Laufzeitergebnisse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
xi
Abbildungsverzeichnis
1.1. Fehlervermeidung in der Softwareentwicklung . . . . . . . . . . . . . 1
2.1. Grundelemente von Statecharts . . . . . . . . . . . . . . . . . . . . . 72.2. Ein Statechart in UML-Notation . . . . . . . . . . . . . . . . . . . . 102.3. Ein Statechart in Safe State Machine Notation . . . . . . . . . . . . . 112.4. Ein Statechart in Stateflow Notation . . . . . . . . . . . . . . . . . . 12
3.1. In Z -Notation spezifiziertes Geburtstagsverzeichnis . . . . . . . . . . 163.2. Klassifikation der Notation von Constraint-Sprachen . . . . . . . . . . 183.3. Beziehungen von Sprachen, die zur OCL geführt haben . . . . . . . . 193.4. Constraints im Softwareentwicklungsprozess . . . . . . . . . . . . . . 19
4.1. Statechart Style Checking Taxonomie . . . . . . . . . . . . . . . . . . 264.2. Beispiel der Well-formedness-Regel CompositeState Nummer 1 . . . . 284.3. Beispiel für die Regel ORStateCount . . . . . . . . . . . . . . . . . . 294.4. Beispiel für die Regel DefaultFromJunction . . . . . . . . . . . . . . . 304.5. Beispiel für die Regel InterlevelTransition . . . . . . . . . . . . . . . . 314.6. Beispiel für die Regel Connectivity . . . . . . . . . . . . . . . . . . . 32
5.1. Die Komponenten von KIEL nach dem MVC-Konzept geordnet . . . 365.2. Darstellung der durchgeführten Arbeitsschritte zur Übersetzung von
OCL in Java-Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . 385.3. Illustration der Beziehung zwischen dem Checking-Plug-In und den
unterschiedlichen Regelmengen . . . . . . . . . . . . . . . . . . . . . . 395.4. Übersicht über die Funktionsweise des XMI-Konverters . . . . . . . . 435.5. An der OCL-Transformation beteiligte Module des Dresden OCL
Toolkits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 445.6. Screenshot von KIEL mit ausgeklappten Checking-Menüpunkt . . . . 475.7. Das Fileinterface-Modul . . . . . . . . . . . . . . . . . . . . . . . . . 485.8. Visualisierung der Zwischenschritte des implementierten Reader-Moduls 495.9. Arbeitsweise des XMI-Exports . . . . . . . . . . . . . . . . . . . . . . 50
6.1. Laufzeiten des Style-Checkers . . . . . . . . . . . . . . . . . . . . . . 556.2. Ein transformiertes Aktivitätsdiagramm . . . . . . . . . . . . . . . . 576.3. Verletztes Constraint der bmiag . . . . . . . . . . . . . . . . . . . . . 586.4. Verletzte Well-formedness-Regel PseudoState 1 . . . . . . . . . . . . 586.5. Überlappende Transitionen . . . . . . . . . . . . . . . . . . . . . . . . 59
xiii
Abbildungsverzeichnis
C.1. Die KOCL-Grammatik in EBNF. . . . . . . . . . . . . . . . . . . . . 76
D.1. Das vereinfachte Metamodell der topologischen Statechart Daten-struktur. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
G.1. Übersicht über die Abhängigkeiten des Checking-Plug-Ins. . . . . . . 95
xiv
Verzeichnis der Auflistungen
3.1. OCL-Ausdruck für die Bedingung an die AddBirthday-Methode . . . 185.1. Kommandozeilenausgabe des XMI-Konverters . . . . . . . . . . . . . 435.2. OCL-Ausdruck der Well-formedness-Regel CompositeState-1 . . . . . 445.3. Erzeugter Java-Code . . . . . . . . . . . . . . . . . . . . . . . . . . . 445.4. Ein KOCL-Beispiel für das KIEL-Metamodell . . . . . . . . . . . . . 455.5. Kommandozeilenausgabe des RuleParser . . . . . . . . . . . . . . . . 46
xv
Liste der Abkürzungen
CASE Computer Aided Software Engineering
DOM Document Object Model
KIEL Kiel Integrated Environment for Layout
KOCL KIEL wrapped OCL
MAAB MathWorks Automotive Advisory Board
MISRA Motor Industry Software Reliability Association
OCL Object Constraint Language
OMG Object Management Group
OMT Object Modelling Technique
PRG Programming Research Group
SAX Simple API for XMI
UML Unified Modelling Language
XMI XML Metadata Interchange
XML Extended Markup Language
xvii
1. Einleitung
Eingebettete Systeme sind Computer, die in größere Umgebungen integriert sind undhäufig nicht als solche wahrgenommen werden. Das immer größer werdende Anwen-dungsgebiet von Computern führt insbesondere durch die eingebetteten Systeme zueiner Vielzahl von Anwendungen, bei denen ein Ausfall der Software schwere Folgenfür Mensch und Umwelt nach sich ziehen kann. Längst übersteigen die Kosten, die fürdas Testen neu entwickelter Systeme und die später anfallenden Wartungsarbeitenaufgewendet werden, die reinen Entwicklungskosten um ein Vielfaches. Dementspre-chend wird versucht, die Fehlervermeidung in möglichst großem Umfang zu automa-tisieren und damit die Kosten zu senken, denn von Programmen detektierte Fehlerverursachen weniger Kosten als vom Menschen detektierte Fehler [93].
Software Error Prevention
Automated Error Prevention Human Code Review
Dynamic Testing Static Code Analysis
Style Checking Model Checking
Layout Style
Robustness Analysis
Syntactic Robustness Semantic Robustness
Abbildung 1.1.: Fehlervermeidung in der Softwareentwicklung (Quelle: [85])
Die Arten der Fehlervermeidung lassen sich, wie in Abbildung 1.1 angegeben,grundsätzlich in zwei Bereiche aufteilen. Auf der einen Seite die manuellen Code-Reviews (human code review). Das Hauptaugenmerk sollte in diesem Bereich demZusammenhang der einzelnen Funktionen in einem Programm gelten, da sich die-ser meist nicht automatisch überprüfen lässt. Die Qualität der unter diesem Aspekt
1
1. Einleitung
durchgeführten Arbeiten basiert auf der Erfahrung der Entwickler, der noch vorhan-denen Zeit bis zum Auslieferungstermin und vor allem von der Qualität des Quellco-des ab. Denn wie unter anderem Parnas [72] beobachtet hat, lassen sich Entwicklerschnell durch Programm unabhängige Probleme von der eigentlichen Problemstel-lung ablenken.
Die automatisierte Fehlervermeidung (automated error prevention), auf der ande-ren Seite, versucht daher Programm-unabhängige Fehler vor den manuellen Code-Reviews mit verschiedenen Mitteln zu beseitigen, oder zumindest zu lokalisieren,falls eine automatische Beseitigung des Problems nicht möglich ist. Ein Teilgebietder automatisierten Fehlervermeidung ist, wie dargestellt, der Vorgang des StyleCheckings. Im Rahmen des Style-Checkings werden Regeln überprüft, die in spezi-ellen Dokumenten gesammelt wurden. Diese Regelsammlungen heißen Style-Guides.Ein Teil der in den Style-Guides gesammelten Regeln behandelt das Layout vonQuellcode, ein anderer Teil gibt Kriterien für robusten Quellcode an. Diese robustenRegeln schränken eine Programmiersprache auf eine sichere Teilmenge (safe subset)des möglichen Gesamtumfangs ein von der man annimmt, dass sie weniger fehler-trächtig ist [60, 84]. Style-Guides haben zwei Hauptanwendungsgebiete. Zum Einendienen sie als Richtlinie für Entwickler. Zum Anderen können sie als Konfigurationfür spezielle Programme verwendet werden, die automatisiert überprüfen, ob dieRegeln eingehalten werden. Diese speziellen Programme heißen Style-Checker.
Es hat sich gezeigt, dass es wichtig ist, in der Softwareentwicklung konsistentzu einem Style-Guide zu arbeiten, da durch die Anwendung von Style-Guides dieWartbarkeit von Software stark verbessert wird. Und da etwa 80% der gesamtenEntwicklungskosten einer Software in Wartungsarbeiten investiert wird [88], ist dieEinhaltung von Style-Guides von entsprechend großer Bedeutung.
Eingebettete Systeme werden mit graphischen Sprachen entwickelt. Statecharts [34]haben sich zur Entwicklung eingebetteter Systeme bewährt. Statecharts sind ein vi-sueller Formalismus mit denen das Verhalten von eingebetteten Systemen beschrie-ben werden kann. Style-Guides für klassische, d.h. textuelle, Programmiersprachenlassen sich jedoch nicht auf Statecharts übertragen. Daher wurden auch für die mo-dellbasierte Entwicklung verschiedene Style-Guides entwickelt.
Im Rahmen dieser Arbeit wird der von Schaefer [85] vorgestellte Statechart Style-Guide aufgegriffen und erweitert. Zur automatischen Überprüfung der im entwi-ckelten Style-Guide enthaltenen Regeln wurde ein Style-Checker als Plug-In in dasModellierungswerkzeug Kiel Integrated Environment for Layout (KIEL) [43] inte-griert. KIEL ist ein prototypisches Modellierungswerkzeug, das am Lehrstuhl fürEchtzeitsysteme und Eingebettete Systeme an der Christian-Albrechts-Universitätzu Kiel entwickelt wird.
Die Konfiguration des entwickelten Style-Checkers erfolgt in dieser Arbeit mitRegeln, die mit der Object Constraint Language (OCL) [92] formuliert werden. DieOCL wurde gewählt, da diese keine Kenntnisse einer Programmiersprache voraus-setzt [63] und eine leicht verständliche Syntax besitzt. Die Auswertung von OCLkann mittels eines interpretativen oder eines transformativen Ansatzes durchgeführtwerden. Der interpretative Ansatz verwendet ein Interpreter genanntes Programm,
2
das den OCL-Code zur Laufzeit einliest, analysiert und anschließend die entspre-chenden Überprüfungen vornimmt. Beim transformativen Ansatz wird der OCL-Code in eine Programmiersprache übersetzt und anschließend wird dieser Code zurAusführung compiliert. In dieser Arbeit wird eine transformative Auswertung vonOCL-Code vorgestellt.
Die Beiträge dieser Diplomarbeit zur Fehlervermeidung in der Softwareentwick-lung mit Statecharts sind: (1) Die Erweiterung eines generellen Style-Guides fürStatecharts um syntaktische Korrektheit und syntaktische Robustheit betreffendeRegeln. (2) Die Entwicklung eines dialektunabhängigen Statechart Style-Checkersauf Basis einer transformativen OCL-Auswertung und (3) die Beurteilung der durch-geführten Analyse der Robustheit industrieller Statecharts.
Diese Arbeit ist wie folgt aufgebaut:
• Im nächsten Abschnitt dieses Kapitels werden verwandte Arbeiten zur Feh-lervermeidung in der modellbasierten Softwareentwicklung und deren Defizitebetrachtet, die zu der Entwicklung des in dieser Arbeit vorgestellten StatechartStyle-Checkers geführt haben.
• In Kapitel 2 werden Statecharts und verschiedene Dialekte vorgestellt.
• Im darauffolgenden Kapitel werden Constraint-Sprachen und die Entstehungder OCL vorgestellt. Des Weiteren werden Einsatzgebiete und Werkzeugun-terstützung untersucht.
• In Kapitel 4 wird eine Taxonomie zur Fehlervermeidung auf Statecharts vorge-stellt. Anschließend wird der im Rahmen dieser Arbeit erweiterte Style-Guidezur Fehlervermeidung in der modellbasierten Entwicklung vorgestellt. Basie-rend auf der eingeführten Taxonomie werden verschiedene Modellierungswerk-zeuge und Style-Checker untersucht und die Entwicklung eines Style-Checkersmotiviert.
• Kapitel 5 betrachtet als erstes verschiedene Techniken, die zur Auswertungvon Regeln auf Statecharts angewendet werden können. Anschließend werdendie Ergebnisse einer Untersuchung verschiedener Toolkits zur Arbeit mit OCLvorgestellt. Die Integration des gewählten Dresden OCL Toolkits [19] in KIELund welche Arbeiten durchgeführt wurden, um ein flexibles Checking-Plug-In zu entwickeln, werden anschließend beschrieben. Damit die Regeln des hierentwickelten Style-Guides auch auf Statecharts aus der Unified Modelling Lan-guage (UML) angewendet werden können, wird abschließend der entwickelteXML Metadata Interchange (XMI)-Importer vorgestellt.
• Im Kapitel 6 werden die Ergebnisse einer Usability-Analyse des entwickeltenStyle-Checker vorgestellt.
• Im abschließenden Kapitel wird eine Zusammenfassung der Arbeit und einAusblick auf offene Aufgaben gegeben.
3
1. Einleitung
Die in dieser und der verwandten Diplomarbeit [85] beschriebenen Ergebnisse sindim Oktober 2006 in Genua auf einem Workshop mit dem Titel Modeling and Analysisof Real-Time and Embedded Systems (MARTES’ 06) vorgestellt worden [75].
1.1. Verwandte Arbeiten
Wie einleitend erwähnt, enthalten Style-Guides Regeln zur Vermeidung fehleran-fälliger Konstruktionen. Style-Guides für die modellbasierte Entwicklung mit State-charts wurden unter anderem von der Ford Motor Company [28] und dem MathworksAutomitive Advisory Board (MAAB) [54] entwickelt. Diese beiden Style-Guides sindauf den Statechart-Dialekt Matlab Simulink/Stateflow beschränkt. Scaife et al. [84]haben außerdem eine sichere Teilmenge der Stateflow -Sprache vorgestellt. Die vor-gestellten Style-Guides sind dialektspezifisch und eignen sich daher nicht für die indieser Arbeit angestrebte dialektunabhängige Analyse der Robustheit von State-charts.
Für UML StateMachines erklären die in der UML-Spezifikation [66] enthalte-nen Well-formedness-Regeln die Bedeutung der Statechart-Elemente. Darüberhin-aus wurden weitere Regeln für UML StateMachines unter anderem von Mutz [63]aufgestellt. In den in dieser Arbeit vorgestellten dialektunabhängigen Style-Guidefür Statecharts wurden geeignete, d. h. dialektunabhängige, Regeln der vorgestelltenStyle-Guides und aus der eigenen Erfahrung stammende Regeln aufgenommen.
Die Überprüfung der Regeln eines Style-Guides kann, wie erwähnt, mit Hilfe ei-nes Style-Checkers automatisiert durchgeführt werden. Die ModellierungswerkzeugeEsterel Studio und Matlab Simulink/Stateflow beinhalten bereits Funktionen zurstatischen Analyse. Diese sind jedoch nicht explizit aufrufbar und die mitgeliefertenAnalysen lassen sich weder erweitern, noch an eigene Bedürfnisse anpassen. Ein wei-terer Nachteil der mitgelieferten Analysen ist, dass sie entweder sehr einfache odersehr anspruchsvolle Analysen von der Art eines Model Checkings bieten [33, 46, 64].Die in dieser Arbeit betrachtete Analyse der syntaktischen Robustheit von State-charts lässt sich nicht durchführen.
Neben den in die Modellierungswerkzeuge integrierten Analysefunktionen wur-den kommerzielle und nicht-kommerzielle Style-Checker zur Analyse entwickelt. DieWerkzeuge Mint [81], State Analyzer [32, 46] und Guideline Checker [61] sind spezi-ell für den Dialekt Stateflow entwickelt worden und eigenen sich daher ebenfalls nichtfür die in dieser Arbeit angestrebte dialektunabhängige Analyse der syntaktischenRobustheit von Statecharts.
Der dialektunabhängige Regel Checker [64] bietet die Möglichkeit, die Regelmen-ge flexibel mit Java-Klassen und OCL-Ausdrücken zu erweitern und mitgelieferteRegeln an eigene Bedürfnisse anzupassen. Die Auswertung von OCL-Ausdrückenerfolgt im Regeln Checker in einem interpretativen Ansatz. Dieses Vorgehen zurAuswertung schließt die vorgestellten Nachteile einer interpretativen Auswertungmit ein. Ein weiterer Nachteil ist, dass mit dem Regel Checker keine Analysen dersemantischen Robustheit auf der Basis eines Theorembeweisers möglich ist.
4
2. Entwicklung eingebetteter,reaktiver Systeme
Ein reaktives System ist nach Harel ein System, das ereignisgesteuert arbeitet undfortwährend auf innere und äußere Einflüsse reagiert [34]. Beispiele für reaktive Sys-teme sind der Thermostat einer Klimaanlage oder die Airbagsteuerung. Zur Steue-rung der meisten reaktiven Systeme werden eingebettete Systeme verwendet. ImFall der Airbagsteuerung wird im besonderen Maße die sicherheitskritische Bedeu-tung solcher Systeme bewusst. Da die hergestellten reaktiven Systeme jedoch im-mer komplexer werden, hat sich relativ bald herausgestellt, dass die vormals häu-fig zur visuellen Beschreibung eines Systems verwendeten Zustandsdiagramme dengesteigerten Anforderungen an Komplexität, Simulierbarkeit und Sicherheit nichtgewachsen waren. Daher wurde lange Zeit nach einem Weg gesucht, wie sich auchkomplexe reaktive Systeme präzise, formal und vor allem intuitiv beschreiben lassenund dabei gleichzeitig von einem Computer simuliert werden können. Insbesonderedie Simulation von reaktiven Systemen im sicherheitskritischen Umfeld muss zuver-lässig durchführbar sein, um schon während der Entwicklung möglichst alle Fehlerauszuschließen. Schließlich könnten bei einem Ausfall eines reaktiven Systems Men-schenleben gefährdet sein. Beispiele für den Ausfall eingebetteter Systeme sind dieExplosion einer Rakete vom Typ Ariane [52] (1996), das Unglück des Lufthansa-Flugs DLH-2904 bei der Landung in Warschau [50] (1993) und die Fehlfunktion desSteuerungssystems von Raketen des Typs Patriot im Golfkrieg [10] (1991).
1987 hat David Harel eine Forschungsarbeit [34] veröffentlicht, in der die Proble-me, die bei der Verwendung von Zustandsdiagrammen in der Softwaremodellierungauftreten, analysiert werden. Basierend auf den Ergebnissen hat Harel die endlichenAutomaten erweitert und die Statecharts vorgestellt. Im folgenden Abschnitt wirddie Entwicklung der Statecharts vorgestellt. Anschließend werden verschiedene, fürdiese Arbeit relevante, Statechart-Dialekte betrachtet.
2.1. Statecharts als Entwicklungstechnik
In den 1950er Jahren haben Rabin und Scott [78], basierend auf den Erfahrungen mitTuringmaschinen und beeinflusst von Kleene’s Arbeit [44] zu McCulloch und Pittsnerve-nets [56], die endlichen Automaten (Finite State Machines) zur Beschreibungvon Computersystemen vorgestellt. Endliche Automaten zeichnen sich dadurch aus,dass die benötigte Menge von Arbeitsmaterial, im Gegensatz zur Verwendung vonTuringmaschinen, endlich ist, und dass sie dabei gleichzeitig vollkommen ausreichend
5
2. Entwicklung eingebetteter, reaktiver Systeme
zur Formalisierung von Computern sind. Da sich ein Computer zu jedem diskretenZeitpunkt immer in genau einem wohldefinierten Zustand befindet, und Transitio-nen (Zustandsübergänge) durch eine Eingabe ausgelöst werden, sind Zustände undTransitionen die einzigen beiden benötigten Elemente, um einen Computer essentiellzu beschreiben [78, S. 116].
Endliche Automaten können durch gerichtete Graphen visualisiert werden. DieKnoten des Graphen repräsentieren die Zustände des Automaten, die gerichtetenKanten die Transitionen, und Kantenbeschriftungen die Bedingung, unter welcherEingabe die Transition ausgelöst wird, repräsentieren. Gerichtete Graphen, die zurRepräsentation von Endlichen Automaten verwendet werden, werden als Zustands-Übergangs-Diagramm oder kurz Zustandsdiagramm (state-diagramm) bezeichnet.
Endliche Automaten nach Rabin und Scott berechnen bool’sche Funktionen undliefern als Ergebnis yes oder no [78]; weitere Ausgaben etwa zur Interaktion mit derUmgebung werden nicht erzeugt. Dies ist jedoch für die Modellierung von reaktivenSystemen notwendig, da diese relevante Ereignisse von der Umgebung als Eingabeerhalten und entsprechende Ausgaben erzeugen. Unter anderem Moore und Mealyerweitern daher das Konzept der endlichen Automaten um Techniken zur Erzeugungvon Ausgaben. Moore [59] verknüpft Ausgaben mit Zuständen, Mealy [57] hingegenverknüpft die Ausgabe mit Transitionen.
Die endlichen Automaten nach Rabin und Scott weisen einige gravierende Schwä-chen auf. Aufgrund dieser ist ihr Einsatz zur Visualisierung von komplexen Systemenmit enormen Aufwand verbunden und ab einer gewissen Größe des Automaten imGrunde nicht mehr vom Menschen durchführbar. Eine Ursache ist die exponentiellwachsende Anzahl von Zuständen – bedingt durch fehlende Methoden zur Struk-turierung – die bei der Modellierung von komplexen (reaktiven) System benötigtwerden. Dieses Problem wurde bereits 1969 von Parnas beschrieben [71].
Als Erweiterung der endlichen Automaten und deren visueller Repräsentationdurch Zustandsdiagramme führt Harel die Statecharts [34] ein, um mit ihnen einigeder Probleme zu beseitigen. Es ist besonders interessant, dass die Autoren des Ar-tikels schreiben: „. . . we strongly believe in the virtues of visual descriptions“ [34, S.233]. Daher werden die Statecharts nur in graphischer Notation eingeführt.
Harel analysiert die Probleme, die bei der Verwendung von Zustandsdiagrammeauftreten, und führt Lösungen für diese ein. Er stellt unter anderem fest, dass einProblem klassischer Zustandsdiagramme die unvollständige Nutzung der Fläche derZeichnung ist. Grund hierfür ist, dass sie nur aus Knoten, in Form von Punktenoder Kreisen, für die Zustände und gerichteten Kanten, in Form von Linien, fürdie Transitionen bestehen. Um den Platz besser ausnutzen zu können, führt HarelHigraphen ein [35]. In diesen werden für die visuelle Repräsentation von ZuständenRechtecke mit abgerundeten Ecken und optionaler Beschriftung wie in Abb. 2.1averwendet. Die so dargestellten Zustände nutzen den Platz aus und bieten gleichzei-tig die Möglichkeit weitere Zustände in ihrem Inneren anzuordnen (depth), so dasssich verschiedene Hierarchie-Ebenen modellieren lassen. Hierarchische Zustände, dieweitere Zustände enthalten, nennt Harel „OR“-Zustände. Des Weiteren greift HarelMoores Konzept auf und sieht vor, das Ausgaben von Zuständen erzeugt werden
6
2.1. Statecharts als Entwicklungstechnik
(a) Ein einfacher Zustand. (b) Transition mit Beschriftung.
Abbildung 2.1.: Grundelemente von Statecharts
können. Diese Ausgabe erfolgt mit Aktionen. Harel definiert Entry-, During- undExit-Aktionen vor, die beim Betreten, beim Verweilen und beim Verlassen einesZustands ausgelöst werden.
Die Transitionen erweitert Harel um die Möglichkeit, wie bei Mealy, Aktionen indie Beschriftung einzufügen. In Abb. 2.1b ist eine Transition mit einer Beschriftungim Format Trigger [Bedingung] /Aktion angegeben. Ein Trigger ist ein von außen,das heißt von der Umgebung, in der das System eingebettet ist, in das Statecharteingegebenes oder durch das Statechart generiertes Signal. Ist das im Trigger an-gegebene Signal vorhanden wird die Transition gefeuert und die Aktion ausgelöst.Ein Beispiel für eine Aktion kann etwa die Generierung eines solchen Signals sein.Mit einer optionalen Bedingung können weitere Einschränkungen an eine Transitiongemacht werden. Die abgebildete Transition darf nur genommen werden, wenn dasSignal A anwesend ist und die Variable X größer zehn ist.
Die bisher noch nicht berücksichtigte Parallelität (orthogonality) führt Harel miteiner einfachen Technik ein. Für zwei parallele, voneinander unabhängige Bereicheeines Systems wird ein OR-Zustand durch eine gestrichelte Linie geteilt und dieparallelen Bereiche des modellierten Systems werden in den so entstandenen Flä-chen angeordnet. Diese so konstruierten parallelen Zustände nennt Harel „AND“-Zustände [34, S. 242].
Zusätzlich definiert Harel, dass es innerhalb des Statecharts Datenaustausch übereinen Broadcasting-Mechanismus gibt. Der Datenaustausch erfolgt mit Hilfe von Si-gnalen und Variablen. Diese Daten sollten in der Statechart Definition berücksichtigtwerden. Harels ursprüngliche Statechart Definition [34, Seite 233] wurde daher wiefolgt erweitert [36]:
Statecharts = state-diagrams + depth + orthogonality + broadcast-communication + data.
Harels Vorschläge wurden von Softwareentwicklern aufgenommen und haben inverschiedenen Statechart-Dialekten Anwendung gefunden, da die originale State-chart-Definition in verschiedenen Punkten unterschiedliche Interpretation zulässt.Eine detaillierte Untersuchung von 21 verschiedenen Dialekten und deren Unter-schiede hat von der Beeck bereits 1994 veröffentlicht [8]. Die in dieser Arbeit rele-vanten Dialekte werden im folgenden Abschnitt vorgestellt.
7
2. Entwicklung eingebetteter, reaktiver Systeme
2.2. Statechart Dialekte
Die verschiedenen Dialekte, in welchen Harels Statecharts angewandt wurden, weisenzwei Hauptunterschiede auf: Zum Einen mögliche Unterschiede in der Syntax undzum Anderen unterschiedliche Ausführungsmodelle.
Die Syntaxen selbst weisen Unterschiede sowohl in der graphischen Repräsen-tation, als auch in der Menge der zur Verfügung stehenden Statechart-Elementeauf. Tabelle 2.1 listet einige verschiedene zur Verfügung stehende Elemente undderen Bedeutung auf. Unterschiede in der graphischen Ausprägung der einzelnenElemente können den abgebildeten Beispielen der nachfolgend betrachteten State-chart-Dialekte entnommen werden.
Die Ausführungsmodelle lassen sich, basierend auf dem zugrundeliegenden Zeit-modell, in zwei verschiedene Kategorien unterteilen: Zum Einen das synchrone undzum Anderen das asynchrone Zeitmodell [8]. Die im Rahmen dieser Arbeit betrach-teten Dialekte und einige Werkzeuge, in welchen diese umgesetzt sind, werden imFolgenden vorgestellt.
StateMachines
Die UML [66, 67, 90] als graphische Spezifikationssprache enthält Statecharts zurSpezifikation des Verhaltens modellierter Elemente. Beispielsweise kann mit ihnendie Interaktion zwischen verschiedenen Klassen modelliert werden. Die graphischeRepräsentation einiger Statechart-Elemente ist in Abbildung 2.2 enthalten. State-charts werden in der UML StateMachines genannt.
Die Semantik von StateMachines ist in textueller Notation in UML-Spezifikationenenthalten. Eine Referenzimplementierung zur Simulation existiert jedoch nicht, sodass Entwickler von Computer Aided Software Engineering (CASE)-Tool oftmalsdamit werben, dass ihr entwickeltes Produkt „UML-konform“ ist. Dennoch gibt esunterschiedliche Ansätze, um Unklarheiten aus der Spezifikation der Object Mana-gement Group (OMG) zu beseitigen und StateMachines simulieren zu können.
Grundsätzlich unterscheidet sich der Einsatzzweck von StateMachines und derdafür angebotene Funktionsumfang von Programm zu Programm zum Teil jedochenorm. Ein frei verfügbares CASE-Programm ist ArgoUML [4]. Dieses Programmbietet die Möglichkeit, mit der UML Software-Systeme ausgehend von Klassendia-grammen zu spezifizieren. Die StateMachines dienen in diesem Programm – wie vonder OMG vorgesehen – dazu, Verhalten und Interaktion von modellierten Kompo-nenten zu visualisieren. Das Werkzeug bietet jedoch keinerlei Möglichkeit zur Si-mulation der StateMachines. Der Entwickler ist also auf seine eigenen Kenntnisseund ausgiebiges Testen der Software angewiesen, um eventuelle Fehler zu lokalisie-ren. Des Weiteren liefert das Werkzeug bei der Modellierung von StateMachinesnur Hinweise, wenn etwas im Widerspruch zur StateMachine-Spezifikation model-liert wurde. Syntaktische Fehler, die im Grunde leicht zu vermeiden sind, werdennicht ausgeschlossen. Beispielsweise ist es möglich, beliebig viele initiale Zustände
8
2.2. Statechart Dialekte
Tabelle 2.1.: Übersicht ausgewählter Statechart-Elemente und deren Bedeutung
Element Bedeutung
Zustand Graphisches Element zur Illustration diskreter Zustände eines model-lierten Systems (siehe Abbildung 2.1a).
Transition Grundlegendes Element zur Modellierung von (bedingten) Zustands-übergängen. Transitionen können Beschriftungen der Form Trigger[Bedingung] / Aktion tragen. Eine Transition wird nur ausgelöst,wenn das triggernde Signal präsent und die Bedingung erfüllt ist.Im Dialekt Safe State Machine optionale Prioritäten bestimmen dieReihenfolge, in der Transitionen genommen werden.
Root-Zustand In der topologischen Sicht der oberste Zustand eines Statecharts. Alleweiteren Zustände sind in diesem enthalten. In der UML Top-Zustandgenannt.
Pseudozustand Eine Klasse von Zuständen, in denen ein modelliertes System nichtverweilt. Als Transition wird die Sequenz bestehend aus einer hinein-und einer hinausgehenden Transition bezeichnet. Solche Transitionenwerden auch zusammengesetzt (compound) genannt. Teilstücke hei-ßen Segment.
OR-Zustand Ein hierarchischer Zustand, der weitere Zustände enthält. Ist ein ent-haltener Zustand aktiv, ist auch der OR-Zustand aktiv.
AND-Zustand Ein hierarchischer, paralleler Zustand. Enthält Regionen, die sich wieOR-Zustände verhalten. Alle enthaltenen parallelen Regionen sindgleichzeitig aktiv.
Initialer Zustand Ein Pseudozustand. In solch einem Zustand wird die Ausführung einesStatechart, beziehungsweise eines hierarchischen Zustand begonnen.
Finaler Zustand Wird ein solcher Zustand erreicht, ist die Ausführung des Statechart,beziehungsweise des ihn enthalteden Zustand beendet. Im DialektSSM können sogar Hierarchische Zustände als Final gekennzeichnetwerden.
Shallow History Ein Pseudozustand. Wird mit einem hierarchischen Zustand verwen-det. Wird der enthaltende hierarchische Zustand verlassen, speichertder Shallow History Zustand, in welchem enthaltenen Zustand dasSystem beim Verlassen war. Beim erneuten Betreten des enthaltendenZustands wird der zuletzt aktive Zustand wieder hergestellt. DiesesVerhalten ist beschränkt auf die Hierarchiebene, in der ein ShallowHistory Zustand enthalten ist.
Deep History Ein Pseudozustand. Die Variante Deep History stellt das Verhaltendes Shallow History Zustands über alle weiteren Hierarchieebenenzur Verfügung. Dieser Zustand ist eine Besonderheit des StatechartDialekts der UML.
Choice (oder Condi-tional oder Connectivejunction)
Ein Pseudozustand. Ein Choice-Zustand dient der bedingten Struk-turierung des Kontrollflusses.
9
2. Entwicklung eingebetteter, reaktiver Systeme
Finaler Zustand
Initialer ZustandOR−Zustand
Transition mit Bedingung
History Zustand Zustand mit AktionenInterleveltransition
Kommentar
Conditional
Abbildung 2.2.: Ein Statechart in UML-Notation (Quelle: [4])
in einem OR-Zustand zu verwenden. Die OMG spezifiziert jedoch, dass es in einemOR-Zustand nur maximal einen initialen Zustand geben darf [66, Kapitel 2.12.3.1].Auch die in ArgoUML enthaltene Funktion zur Codegenerierung bietet keinen großenFunktionsumfang. Aus den modellierten Klassen werden Quellcode-Dateien für Ja-va erzeugt. Die erzeugten Klassendateien enthalten jedoch nur die Attribute undMethodenrümpfe. Verhalten, das mit StateMachines spezifiziert wurde, wird nichtberücksichtigt.
Neben ArgoUML gibt es andere Werkzeuge, wie die Rational -Werkzeugfamilie [79]von IBM, Rhapsody [80] von I-Logix und ARTiSAN Studio [5], die auch die UML zurSpezifikation verwenden. Im Gegensatz zu ArgoUML ist in letzteren eine Semantikfür StateMachines implementiert, mit der Simulationen des Modells durchgeführtwerden können. Es ist also möglich, Fehler im Programm schon während der Spezi-fikation aufzudecken. Rhapsody und ARTiSAN Studio sind Entwicklungswerkzeuge,die von ihren Herstellern explizit zur Entwicklung von eingebetteten Echtzeitsyste-men angepriesen werden. ARTiSAN Studio wird unter anderem in der Entwicklungvon Systemen im Luftfahrtbereich, in der Automobilindustrie oder im medizinischenUmfeld eingesetzt [5].
Aber auch diese Entwicklungswerkzeuge weisen Schwächen in der Statechart-Analyse auf. Beispielsweise lassen sich keine syntaktische Analysen durchführen, dieauf eventuelle Fehler im modellierten Statechart im Sinne der Robustheit hinweisen.Semantische Analysen sind häufig nicht vorhanden.
10
2.2. Statechart Dialekte
Abbildung 2.3.: Ein Statechart in Safe State Machine Notation (Quelle: [22])
Safe State Machines
Ein weiterer Statechart Dialekt ist Safe State Machine (SSM) [3]. Dieser Dialektist eine kommerzielle Erweiterung der von André entwickelten SyncCharts [2]. DerDialekt SSM weist sowohl syntaktische als auch semantische Unterschiede zu Ha-rels Statecharts auf; beispielsweise sind keine Interlevel-Transitionen erlaubt. Diegraphische Repräsentation einiges SSM-Statecharts ist in Abbildung 2.3 angegeben.Den SSMs ist ein synchrones Zeitmodell mit der „Null-Zeit“-Annahme zugrundegelegt [9]. Der Dialekt wurde im Werkzeug Esterel Studio umgesetzt. Mit diesemWerkzeug lässt sich aus modellierten Systemen unter anderem C- und C++-Codeerzeugen, der für die Zielplattform des Systems übersetzt und anschließend direktauf der Zielplattform ausgeführt werden kann. Aufgrund der Tatsache, dass der Dia-lekt, wie bereits im Namen enthalten, safe – also sicher – ist, existieren keine exter-nen Analyse-Werkzeuge. Der syntaxgerichtete Editor von Esterel Studio verhindertdurch integrierte Funktionen syntaktisch fehlerhafte Konstrukte, so z. B. Interlevel-Transitionen. Über die Syntax hinausgehende Analysen werden mit Modellchecking,welches im Build -Prozess durchgeführt wird, vorgenommen.
Stateflow
Statecharts im Stateflow-Dialekt sind in Simulink -Modelle in Mathworks MatlabSimulink/Stateflow Entwicklungswerkzeug eingebettet [55, 89]. Die graphische Re-präsentation eines Stateflow-Statecharts ist in Abbildung 2.4 dargestellt. MatlabSimulink/Stateflow wird vor Allem in der Automobilindustrie verwendet. Ähnlichwie in Esterel Studio lässt sich auch in diesem Werkzeug eine Simulation des entwi-
11
2. Entwicklung eingebetteter, reaktiver Systeme
Abbildung 2.4.: Ein Statechart in Stateflow Notation (Quelle: [89])
ckelten Systems durchführen, um so Fehler frühzeitig zu erkennen. Die im Werkzeugenthaltenen Analysefunktionen sind auf statische Analysen beschränkt.
Diese werden mit Matlab Simulink/Stateflow entwickelt. Im Dialekt Stateflowsind, im Gegensatz zum Dialekt SSM, Interlevel-Transitionen erlaubt. Style-Guidesraten jedoch von deren Verwendung ab [28, 54]. Weitere Probleme der Semantiksind unter Anderem die nicht intuitive Auswertungsstrategie, welche Transition alsnächstes genommen wird, da es keine Möglichkeit gibt, explizit Prioritäten zu verge-ben. Sind alle von einem Zustand ausgehende Transitionen unbeschriftet, basiert dieStrategie auf einer Auswertung der Anordnung der Transitionen um den Zustandherum im Uhrzeigersinn von zwölf Uhr ausgehend. Diese Strategie stellt insbesonderefür ungeübte Entwickler eine häufige Fehlerquelle dar, da die graphische Anordnungin der Modellierung oft unberücksichtigt bleibt. Darüberhinaus kann die Verwen-dung von graphischen Informationen in der Auswertungsstrategie beim Einsatz vonLayout-Werkzeugen zu Problemen führen. Ändern solche Werkzeuge beim automati-schen Layout die Anordnung von Transitionen, wird auch das Verhalten des Modellsgeändert.
12
2.2. Statechart Dialekte
Fazit
Statecharts haben sich als Technik zur Entwicklung von eingebetteten, reaktivenSystemen bewährt. Die unterschiedlichen der Ausführung zugrunde gelegten Zeit-modelle bieten die Möglichkeit, je nach Situation das bessere Modell zu wählen undsich die jeweiligen Stärken eines Modells zu Nutze zu machen.
Die UML, die als Industriestandard angesehen wird, weist einige Schwächen hin-sichtlich der Semantik auf. Außerdem möchte sie als Sprache für viele Einsatzberei-che in der Softwarespezifikation verstanden werden [66] und ist daher nicht speziellauf die Entwicklung eingebetteter, reaktiver Systeme ausgerichtet. Wie vorgestellt,gibt es neben der allgemeinen Umsetzung von Statecharts in der UML spezielleImplementierungen von Statecharts zur Modellierung eingebetteter, reaktiver Sys-teme. Solche Implementierungen von Statecharts konzentrieren sich jedoch auf dieModellierung von eingebetteten, reaktiven Systemen mit Statecharts und deren Si-mulation. Im Gegensatz zur UML ist der Einsatzzweck also beschränkt.
Die visuellen Formalismen zur Spezifikation von Softwaresystemen – wie die hierbetrachteten Statecharts – reichen jedoch nicht immer aus, um alle Anforderungenan eine Software zu formulieren. Bestimmte Sachverhalte, wie etwa vom modelliertenSystem unabhängige Anforderungen an Statecharts selbst, können nicht oder nursehr umständlich spezifiziert werden. Dazu gibt es Constraintsprachen wie die OCL.Diese wird von der OMG in der UML zur Formulierung von Well-formedness-Regelnverwendet, die in dieser Arbeit ebenfalls in der Analyse von Statecharts ausgewertetwerden. Daher wird im folgenden Kapitel eine Einführung in die OCL gegeben.
13
3. Einführung der OCL
Spezifikationssprachen werden seit den 1970er Jahren eingesetzt, um die verschiede-nen Anforderungen an eine Software formal zu formulieren. Einschränkungen, denenSysteme unterliegen, lassen sich mit den allgemeinen Spezifikationssprachen jedochschlecht erfassen. Daher gibt es für einige Spezifikationssprachen eine Constraint-Sprache, mit der sich zusätzliche Einschränkungen formulieren lassen. Mitte der1990er Jahre gab es einige miteinander konkurrierende Spezifikationssprachen, bisdie OMG die UML veröffentlicht hat. Nach der Vorstellung der UML stellten dieAnwender fest, dass auch die von der UML vereinigten objekt-orientierten Methodender Softwaremodellierung alleine nicht ausreichen, um alle Facetten eines Systemszu erfassen [67]. Daher wurde die UML in Version 1.1 um die 1995 von IBM ent-wickelte Object Constraint Language (OCL) [92] erweitert. Mit der OCL könnenEinschränkungen an Objekte genauer spezifiziert werden, als es mit der graphischenNotation der UML möglich wäre.
Einschränkungen, die mit der OCL formuliert werden, heißen Constraints. EinConstraint, auch Assertion genannt, ist in der Informatik bereits seit längerem be-kannt. Sie sind ein Ausdruck zur Beschreibung des Zwecks eines Elements. Assertionswerden in die folgenden drei Klassen eingeteilt: (1) Vorbedingungen, (2) Nachbedin-gungen und (3) Invarianten. Assertions werden bezüglich einer Klasse definiert. Siekommen in der Sprache Eiffel [58] zum Einsatz und stellen dort die Basis für dasdort umgesetzte Design-by-Contract-Prinzip dar. Für die in dieser Arbeit umgesetz-te Robustheitsanalyse von Statecharts werden Invarianten bezüglich des StatechartMetamodells ausgewertet. Zur Formulierung dieser Invarianten wird die Constraint-Sprache OCL verwendet.
Welchen Ursprung die OCL hat, welche Einsatzmöglichkeiten es gibt, und wie sichdie Unterstützung der OCL durch aktuelle Werkzeuge im Softwareentwicklungspro-zess darstellt, wird im Folgenden aufzeigt.
3.1. Constraint-Sprachen
Der Software-Entwicklungsprozess beginnt immer mit dem Erfassen und Formulierenvon Anforderungen, die die zu entwickelnde Software erfüllen muss. Werden dieerfassten Anforderungen in einem umgangssprachlich formulierten Text festgehalten,kann es zu Mehrdeutigkeiten kommen, die wiederum zu Fehlern in der Softwareführen können. Der Fokus von Spezifikationssprachen liegt daher auf der formalenBeschreibung zu entwickelnder Systeme, ohne dabei Details der Implementierung zubetrachten. Bereits Ende der 1970er Jahre begann am Oxford University Computing
15
3. Einführung der OCL
[NAME ,DATE ]
BirthdayBookknown : P NAMEbirthday : NAME 7→ DATE
known = dom birthday
(a) Basistypen und Zustandsraum des Geburtstagskalenders in Schema-Schreibweise
AddBirthday∆BirthdayBookname? : NAMEdate? : DATE
name? /∈ known
birthday ′ = birthday ∪ {name? 7→ date?}
(b) Bedingungen an die Methode zum Hinzufügen eines Geburtstags zum Verzeichniss
Abbildung 3.1.: In Z -Notation spezifiziertes Geburtstagsverzeichnis (Quelle: [86])
Laboratory die Programming Research Group (PRG) [68] mit Arbeiten an einerSprache, die durch ihre formale Grundlage keinen Raum für Mehrdeutigkeiten inSoftwarespezifikationen lassen sollte.
Die schließlich von der PRG entwickelte formale und typisierte Spezifikationsspra-che Z [14] basiert auf der Mengentheorie von Zermelo-Fraenkel und Prädikatenlogikerster Ordnung und wurde nicht entworfen, um ausführbar zu sein, sondern um aus-sagekräftig und für Menschen lesbar zu sein [14, S. 4]. Dies wird vor allem durch eineeinheitliche Formatierung, kombiniert mit algebraischer Notation, erreicht. In Abbil-dung 3.1 ist exemplarisch ein Teil einer Spezifikation eines Geburtstagskalenders in Zangegeben [86]. Die verwendete Formatierung ist von der Spezifikation vorgegeben.Eine Einführung in die Syntax und die Verwendung von Z wurde von Spivey [86]veröffentlicht. Die Strukturierung wird durch eine Unterteilung in Schemata vorge-nommen. In Abbildung 3.1a werden die im Geburtstagskalender enthaltenen Klas-sen definiert. Mit diesen wird in Abbildung 3.1a anschließend der Zustandsraum desGeburtstagskalenders definiert. Für die Methode AddBirthday wird anschließend inAbbildung 3.1b spezifiziert, dass ein Paar, bestehend aus einem Namen und einemGeburtstag, nur zum Verzeichnis hinzugefügt werden darf, wenn der Name vorhernicht bereits im Verzeichnis vorhanden ist.
Für die Unterstützung bei der Arbeit mit Z gibt es verschiedene Programmemit zum Teil vollkommen unterschiedlichen Einsatzgebieten. Die Palette reicht vonWYSIWYG-Editoren für die Erstellung von Z -Spezifikationen bis hin zu Program-
16
3.1. Constraint-Sprachen
men, die Z -Spezifikationen aus LATEX-Quellen [51] extrahieren und die extrahiertenSpezifikationen auf Typsicherheit und korrekte Syntax überprüfen. Z wurde in den1980er Jahren in verschiedenen Projekten in der Industrie eingesetzt [16, 7] und 2002als ISO-Standard verabschiedet [41]. Dennoch konnte sich die Sprache bisher nichtentscheidend durchsetzen, da Entwickler Sprachen mit hohem Anteil algebraischerNotation ungern einsetzen [26].
Mit dem Aufkommen der objektorientierten Methoden zur Modellierung von Soft-ware Anfang der 1990er Jahre wurden neue Techniken zur Spezifikation, wie die Ob-ject Modelling Technique (OMT ) [83] und Booch [12], vorgestellt. Techniken dieserArt haben durch die visuelle Notation mit grafischen Symbolen eine große Anzahlvon Anwendern gefunden, da für diese nicht mehr das mathematische Hintergrund-wissen nötig ist, wie dies etwa bei der Verwendung von Z der Fall war. Allerdings hatsich gezeigt, dass den Diagrammen durch die nicht vorhandene Constraint-SpracheMöglichkeiten fehlen. Modellierungssprachen ohne Möglichkeiten zur Spezifikationvon Anforderungen, die über das mit grafischen Ausdrücken Formulierbare hinaus-gehen, werden im Allgemeinen auch als Objekt-Modellierungssprachen der erstenGeneration bezeichnet.
In den frühen 1990er Jahren haben Steve Cook und John Daniels gemeinsam ander Sprache Syntropy [17] gearbeitet, um akzeptierte graphische Notationen einerModellierungssprache mit eine Constraint-Sprache zu vereinen. Die Sprache Syntro-py ist eine objekt-orientierte Modellierungssprache, die Konzepte der Modellierungs-sprachen der ersten Generation (insbesondere OMT ) aufgreift, verfeinert und durcheine Constraint-Sprache erweitert. Die Constraint-Sprache von Syntropy basiert da-bei auf einer Teilmenge von Z, so dass es auch in Syntropy zu der Verwendung vonmathematischen Symbolen aus der Mengentheorie und der Prädikatenlogik kommt.Es war nun immerhin möglich, die grafischen Modelle um zusätzliche Einschränkun-gen und Anforderungen zu erweitern, so dass die Probleme der Modellierungsprachender ersten Generation beseitigt waren. Aber auch Syntropy konnte sich nicht ent-scheidend durchsetzen, da es daneben weitere Modellierungssprachen der zweitenGeneration gibt und sich die Anwender nicht auf einen Standard einigen konnten.Ein Problem war, dass Syntropy, wie auch die anderen Modellierungssprachen derzweiten Generation, zwar eine Constraint-Sprache enthält, die Constraints aber,ähnlich wie in Z, hauptsächlich in algebraischer Notation formuliert werden.
Das Problem mit der algebraischen Notation war, dass die wenigsten Anwendereine entsprechende mathematische Ausbildung hatten, um mit ihr umgehen zu kön-nen [26, 67]. Daher wurde 1995 bei IBM (durch Jos Warmer und Steve Cook) ander OCL gearbeitet, die ohne algebraische Notationen auskommt und ein formalesmathematisches Fundament hat [92]. Eine Einordnung der Notation verschiedenerConstraint-Sprachen ist in Abbildung 3.2 dargestellt.
In Auflistung 3.1 sind die Constraints an die AddBirthday-Methode der KlasseBirthdayBook aus Abbildung 3.1 mit der OCL formuliert. Wie mit Z spezifiziert,werden auch mit der OCL Vor- und Nachbedingungen an die Methode formuliert.Die Vorbedingung – gekennzeichnet durch den Identifier pre – besagt, dass der hin-zuzufügende Name nicht in der Menge known enthalten sein darf. Die Nachbedingung
17
3. Einführung der OCL
algebraische Notation
objektorientierte Notation
ZLaarch
Syntropy
OCL
Abbildung 3.2.: Klassifikation der Notation von Constraint-Sprachen
Auflistung 3.1: OCL-Ausdruck für die Bedingung an dieAddBirthday-Methode
context BirthdayBook::AddBirthday(name: NAME, date: DATE)pre: self.known.select(n | n = name)->size = 0;post: self.known.select(n | n = name)->size = 1;
– gekennzeichnet durch den Identifier post – stellt sicher, dass der Name nur einmalhinzugefügt wurde.
Die OCL wurde, wie erwähnt, von der OMG in die Version 1.1 der UML aufge-nommen und dient seitdem, wie in Tabelle 3.1 dargestellt, als Constraint-Sprachefür die UML. Die Ursprünge der OCL liegen in der Constraint-Sprache von Syn-tropy [67, 92]. Die historische Entwicklung der OCL ist in der Darstellung in Ab-bildung 3.3 aufgezeigt. Die UML bietet seit der Integration der OCL also die Mög-lichkeit, zusätzliche Einschränkungen modellierter Systeme formal zu spezifizieren.Zusätzliche Einschränkungen an ein Softwaresystem können auf verschiedene Pha-sen des Softwareentwicklungsprozesses Einfluss haben. Im folgenden Abschnitt wirddieser Einfluss betrachtet.
Tabelle 3.1.: Spezifikationssprachen und deren zugehörige Constraint-Sprachen
Spezifikationssprache Constraint-Sprache
Z Z constraintsOMT -Booch -Syntropy Syntropy constraintsUML OCL
18
3.2. Anwendungsgebiete der OCL
Z
Syntropy
OCL
OMT Booch
Abbildung 3.3.: Beziehungen von Sprachen, die zur OCL geführt haben
3.2. Anwendungsgebiete der OCL
Verschiedene Phasen der Softwareentwicklung werden, basierend auf ihrer zeitlichenReihenfolge, in eine Sequenz aufeinander folgender Phasen unterteilt. Ein bekanntesModell für die Anordnung dieser Phasen ist das Wasserfallmodell [31]. Die verschie-denen Phasen (Analysieren, Designen, Implementieren, Testen) sind als Sequenzin Abbildung 3.4a enthalten. Im Wasserfallmodell haben Erfahrungen, die in einerPhase gemacht werden, Einfluss auf vorhergegangene Phasen. Wurden diese Erfah-rungen entsprechend umgesetzt, werden die Aufgaben aller nachfolgenden Phasenerneut ausgeführt.
Constraints werden, wie dargestellt, im Softwareentwicklungsprozess aus den, inder Analyse erhobenen, Daten parallel zum Design angelegt. Die aufgestellten Cons-traints haben Einflüsse auf das Design und können dann in der Implementierung indie Software integriert werden. So kann sichergestellt werden, dass die im Programmerzeugten Instanzen des entworfenen Modells den analysierten Anforderungen ent-sprechen. Werden geeignete Mechanismen in der Software bereitgestellt, lassen sichConstraints auch zur Laufzeit des entwickelten Softwaresystems auf den erzeugten
Anforderungen
Analyse
Design Constraints
Implementierung
Style−Guide
Programm−konstrukte
Integration und Test
Testfälle
(a) Einflüsse im Wasserfallmodell
M3
M2
M1
M0
Style-Guide
(b) Einflüsse auf Metamodellebene
Abbildung 3.4.: Constraints im Softwareentwicklungsprozess
19
3. Einführung der OCL
Modellinstanzen überprüfen. Auf Instanzen, die in Datenbanken verwaltet werden,können Invarianten mit Datenbankanfragen in der Structured Query Language (SQL)ausgewertet werden [18, 24, 53].
Die Softwareentwicklung mit Statecharts erfolgt in der Design-Phase des Wasser-fallmodells. Der Einfluss von Constraints auf diese Phase ist die Einschränkung desSprachumfangs auf eine robuste Teilmenge. Mit den in dieser Arbeit aufgestelltenConstraints (siehe Kapitel 4.2) wird das Metamodell der Statecharts eingeschränkt.Betrachtet man die vier Ebenen der Metamodellierung [66, Kapitel 2.2.1], haben dieConstraints des in dieser Arbeit aufgestellten Statechart Style-Guides also Einflussauf Ebene M1. Dies ist in Abbildung 3.4b dargestellt.
Die OMG schlägt die OCL unter anderem zur Spezifikation der folgenden Artenvon Constraints vor [67, Kap. 6.1.2]:
Invarianten: Diese werden bezogen auf Typen und Klassen im Klassendiagramm(Metamodell) spezifiziert. Die Einhaltung von Invarianten kann über geeig-nete Routinen in der entwickelten Software sichergestellt werden. Zusätzlichlassen sich die Invarianten zu einem diskreten Zeitpunkt auf einer Modellin-stanz, die in der Software erstellt wird, über geeignete Methoden auswerten.Diese Auswertung kann keine Änderungen an der Instanz vornehmen, weil dieAuswertung von OCL frei von Nebeneffekten ist [67].
Vor- und Nachbedingungen: Diese werden auf Methoden bezogen spezifiziert. Siesollten in der Software umgesetzt werden, denn häufig sind in ihnen Informa-tionen zur Funktionsweise einer Methode enthalten.
Die Auswertung von Constraints ist gemäß der einleitend vorgestellten Taxonomiezur Fehlervermeidung in Software (Abbildung 1.1) den Methoden zur automatisier-ten Fehlervermeidung zuzuordnen. Constraints werden auf dem Metamodell einerSoftware spezifiziert. Eine Auswertung erfolgt auf Instanzen des Metamodells, oderauch Modellinstanzen. Erfüllt eine Modellinstanz nicht alle Constraints, ist die Im-plementierung fehlerhaft. Auf diese Arbeit bezogen bedeutet dies, dass die Regelnzur Robustheit von Statecharts auf dem Metamodell der Statecharts formuliert wer-den. Der Inhalt der Regeln ist somit unabhängig von dem zu entwickelnden System.Konkrete Statecharts, mit denen ein System modelliert wurde, sind also Instanzendes Metamodells.
Damit die OCL zur Spezifikation von zusätzlichen Bedingungen in der Softwa-reentwicklung verwendet werden kann, muss es Werkzeuge geben, die zur Softwa-remodellierung eingesetzt werden und geeignete Techniken zur Unterstützung an-bieten. Im nächsten Abschnitt wird eine Auswahl einiger CASE-Programme mitOCL-Unterstützung vorgestellt.
3.3. Werkzeugunterstützung
In diesem Abschnitt werden die Ergebnisse einer Untersuchung verschiedener Model-lierungswerkzeuge mit OCL-Unterstützung präsentiert. Das Ziel der Untersuchung
20
3.3. Werkzeugunterstützung
Tabelle 3.2.: Modellierungswerkzeuge mit OCL-Unterstützung
Werkzeug OCL- Funktionalität Editor Add-In
Synt
ax-/
Typ
über
prüf
ung
Sem
antisc
heÜ
berp
rüfu
ng
Cod
eG
ener
ator
Con
stra
int
Aus
wer
tung
Synt
axH
ighl
ight
ing
Cod
eVer
volls
tänd
igun
g
ArgoUML - - ◦1 - - - -Bold for Delphi • - - • - • •KeY • • - • - • •Oclarity • • - - • - •OCLE • • • • • • -Octopus • • • - - - -UMLAUT • - • - - - -USE • • - • • - -
1 OCL-Ausdrücke werden bei der Generierung nicht berück-sichtigt.
war die Beurteilung, ob eines der betrachteten Modellierungswerkzeuge als Style-Checker für die in dieser Arbeit vorgestellte Robustheitsanalyse von Statechartsverwendet werden kann und welche Techniken bei der Auswertung von OCL zumEinsatz kommen. Für die Robustheitsanalyse ist eine Auswertung von Constraintsauf Instanzen des Statechart-Metamodells notwendig. Tabelle 3.2 listet eine Aus-wahl verfügbarer CASE-Programme und Add-Ins auf, die OCL-Unterstützung inverschiedener Ausführung anbieten. Es wurden Funktionen aus zwei Bereichen un-tersucht.
Der erste betrachtete und für diese Arbeit relevante Bereich ist der Umfang derangebotenen OCL-Funktionalität. Zu diesem Bereich gehört unter anderem die Aus-wertung von Constraints auf Modellinstanzen. Diese Funktion ist wichtig für einenEinsatz als Style-Checker. Weitere betrachtete Funktionen dieses Bereichs sind dieSyntax-Überprüfung, semantische Checks und der Umfang des Code Generators.Die Syntax-Überprüfung analysiert, ob eingegebene OCL-Ausdrücke eine korrekteSyntax aufweisen; beispielsweise sollte eine falsche Schreibweise der OCL-Identifiererkannt werden. Die semantischen Checks überprüfen, ob die verwendeten Klassen-,Methoden- und Attributnamen in den eingegebenen OCL-Ausdrücken dem Modellentsprechend korrekt verwendet werden. Ist ein Code Generator in einem Werkzeugenthalten, wurde betrachtet, ob eingegebene OCL-Ausdrücke im erzeugten Codeberücksichtigt wurden.
Die daneben betrachteten Funktionen des in allen Werkzeugen vorhandenen OCL-Editors sind keine Voraussetzung zur Arbeit mit der OCL. Diese Funktionen werdenjedoch bei einem Einsatz eines der betrachteten Werkzeuge als Style-Checker inter-essant, wenn Robustheisregeln angelegt oder bearbeitet werden sollen. Insbesondere
21
3. Einführung der OCL
Funktionen, die den Entwickler bei der Arbeit mit OCL unterstützen, wurden hierbetrachtet. Dies sind etwa Syntax-Highlighting und Funktionen zur Code-Vervoll-ständigung. Die in Tabelle 3.2 aufgeführten Werkzeuge werden im Folgenden kurzvorgestellt.
ArgoUML: Das Open Source UML Modellierungswerkzeug ArgoUML [4] ist voll-ständig kompatibel zum UML 1.4 Standard. Aus den erstellten Diagrammenlässt sich Java-Code automatisch generieren. Jedoch werden eventuell einge-gebene Constraints in Java Kommentaren im Quellcode eingefügt. Die OCL-Ausdrücke lassen sich gezielt zu Klassen, Attributen und Methoden hinzu-fügen und auch nachträglich bearbeiten. Die Unterstützung bei der Eingabeder OCL-Ausdrücke ist auf einige Schlüsselwörter und mathematische Opera-toren beschränkt, die aus einer Drop-down Liste ausgewählt werden müssen.Am Ende der Eingabe wird die korrekte Syntax, nicht aber die korrekte Typi-sierung überprüft. Eine Auswertung der Constraints auf Modellinstanzen istnicht möglich.
Bold for Delphi: Bold for Delphi von Borland [13] ist eine CASE-Programm, dasals Bestandteil der Borland Delphi Entwicklungsumgebung kommerziell ver-trieben wird. Die im angebotenen OCL-Editor eingegeben Bedingungen wer-den auf korrekte Syntax überprüft. Aus den eingegebenen Bedingungen las-sen sich SQL-Abfragen erzeugen. Im entwickelten Programm lässt sich zurLaufzeit durch den Aufruf spezieller Methoden überprüfen, ob die Instanzenmodellierter Klassen alle formulierten Bedingungen erfüllen. Die aktuelle Wei-terentwicklung von Bold for Delphi wird unter dem Namen ECO ebenfalls alsBestandteil der Borland Entwicklungsumgebungen vermarktet.
KeY: Das an der Universität Karlsruhe entstandene Projekt KeY [42] ist ein Add-Infür TogetherCC. Mit Hilfe von KeY lassen sich zum Einen die OCL-Ausdrückeauf korrekte Typisierung und Semantik überprüfen, und zum Anderen lassensich konkrete Implementierungen gegen das Modell verifizieren. KeY übersetztdie OCL-Bedingungen in Ausdrücke in dynamischer Logik, die wiederum alsEingabe eines Theorem-Beweisers verwendet werden.
Oclarity: Das kommerziell vertriebene Rational Rose Add-In Oclarity der FirmaEmPowerTec [21] integriert verschiedene Funktionen zur Arbeit mit OCL indas CASE-Werkzeug. Neben Funktionen zur Überprüfung der Syntax und Se-mantik der Ausdrücke gemäß OCL 2.0, bietet der Editor Syntax-Highlightingund Code-Vervollständigung. Die Überprüfung der Syntax und Semantik ein-zelner Constraints lässt sich an verschiedenen Stellen im Programm aufrufen.Um einen Überblick über alle spezifizierten Constraints zu erhalten, lassen sichalle Constraints über einen Menüpunkt einer Überprüfung unterziehen.
OCLE: Das Object Constraint Language Environment (OCLE ) ist an der Universi-tät in Cluj-Napoca (Rumänien) entwickelt worden [6]. Schwerpunkt des Pro-
22
3.3. Werkzeugunterstützung
gramms ist das Anlegen und die Überprüfung von OCL-Ausdrücken auf be-stehenden UML-Modellen. Der bereitgestellte Editor unterstützt den Benut-zer bei der Eingabe mit Syntax-Highlighting und Code-Vervollständigung. Dieeingegebenen OCL-Ausdrücke lassen sich auf korrekte Syntax und Semantiküberprüfen. Der integrierte Code-Generator erzeugt aus ausgewählten Model-len und den darüber spezifizierten OCL-Ausdrücken Java-Code.
Octopus: Das OCL Tool for Precise UML Specifications (Octopus) ist ein Eclipse-Plugin [91]. Mit Octopus können Syntax, Semantik und korrekte Typisierungvon OCL-Ausdrücken der OCL (Version 2.0) überprüft werden. Zusätzlichbietet Programm die Möglichkeit Java-Code zu erzeugen.
UMLAUT: Das Werkzeug Unified Modeling Language All pUrposes Transformer(UMLAUT ) [40] wird nach seiner Fertigstellung als Freeware verfügbar sein. Esist ein Werkzeug, das zur Bearbeitung von UML-Modellen eingesetzt werdenkann. Für die Arbeit mit OCL bietet UMLAUT einen Syntax-Checker und dieMöglichkeit Eiffel-Code zu erzeugen.
USE: Das UML-based Specification Environment (USE ) [82] wurde von Mark Rich-ters an der Universität Bremen entwickelt. Als Implementationssprache wurdeJava verwendet. Das Programm arbeitet mit einer Teilmenge der UML unddient zur Spezifikation von Informationssystemen. Das spezifizierte Systemlässt sich visuell simulieren. Auf Zuständen eines simulierten Systems lassensich alle eingegebenen OCL Bedingungen überprüfen, um sicherzustellen, obdas System die Anforderungen erfüllt.
Neben diesen hier vorgestellten Programmen gibt es Programme, wie etwa Fuja-ba [69], die OCL-Unterstützung für kommende Versionen geplant haben. Basierendauf dem Dresden OCL Toolkit wird eine OCL-Unterstützung für Fujaba entwickelt.So soll es möglich sein, mit OCL Bedingungen für Klassen- und Story-Diagrammezu formulieren, die automatisch überprüft werden können [87].
Des Weiteren wurde im Rahmen des IST Omega Projektes [1] durch Kyas eine for-male Verifikation von OCL-Ausdrücken und den zugehörigen UML-Modellen umge-setzt. Im Rahmen dieses Projektes wurde der Sprachumfang der UML und der OCLjedoch beschränkt, um als Eingabesprache für den Theorembeweiser PVS dienen zukönnen. Mit Hilfe des Theorembeweisers lässt sich die formale Verifikation entspre-chend übersetzter UML-Modelle und OCL-Ausdrücke manuell durchführen [48, 49].
Fazit
Die untersuchten Modellierungswerkzeuge bieten OCL-Unterstützung in verschie-denster Ausprägung an. Allen gemein ist, dass sie die Möglichkeit bieten, OCL-Ausdrücke aufzunehmen. Die vom Werkzeug angebotene Unterstützung bei der Ein-gabe wie Syntax-Highlighting oder Code-Vervollständigung ist bei der Arbeit mitOCL-Code keineswegs selbstverständlich – nur OCLE bietet beides. Auch bei den
23
3. Einführung der OCL
angebotenen Funktionen zur Analyse der Eingabe fallen gravierende Unterschiedeauf. Die meisten der untersuchten Werkzeuge bieten zwar eine Überprüfung derSyntax – eine semantische Überprüfung ist jedoch keineswegs Standard. Auch beider unterstützten Version der OCL fallen Unterschiede auf. Bisher unterstützen nurOclarity, Octopus und OCLE die Version 2.0 der Constraint-Sprache.
Funktionen zur Auswertung der Constraints werden nur von drei der untersuch-ten Werkzeugen angeboten. (1) Bold bietet diese Funktion jedoch nur aus Delphi-Programmen heraus an, was einer plattformunabhängigen Verwendung entgegen-wirkt. (2) OCLE bietet zur Auswertung auf Modellinstanzen eine Übersetzung inJava an. Die erzeugten Java-Code-Fragmente müssen jedoch manuell in ein Pro-gramm integriert werden, was wiederum Kenntnisse der Programmiersprache undder Anwendung voraussetzt und damit für jede neu formulierte Bedingung mituntertiefgreifende Anpassungen an einem (bereits bestehenden) Programm nötig macht.(3) USE bietet eine Auswertung nur während der Simulation eines modelliertenInformationssystems an. Eine ausschließliche Simulation von Statecharts ist jedochnicht vorgesehen. Auch hier ergeben sich also gravierende Nachteile für die Ver-wendung in der Robustheitsanalyse von Statecharts liegen. Also eignet sich keinesdieser Werkzeuge für einen Einsatz als Style-Checker auf der Basis von OCL. EinStyle-Checker auf der Basis von OCL sollte die folgenden drei Funktionen bein-halten: (1) Syntaxprüfung von OCL-Ausdrücken, (2) Semantische Überprüfung derOCL-Ausdrücke und (3) Methoden zur Constraint-Auswertung. Die ersten beidenFunktionen sind für Entwickler von neuen Regeln hilfreich, da der Style-Checkerbei fehlerhafter Syntax oder semantischen Fehlern entsprechende Meldungen zu-rückliefern kann. Funktionen zur Constraint-Auswertung sollten bei nicht erfülltenConstraints entsprechende Hinweise liefern und bilden die Kernfunktionalität einesStyle-Checkers.
In der UML wurde die OCL zur Spezifikation von Regeln der syntaktischen Kor-rektheit verwendet. Neben anderen Regeln wurden auch die Regeln aus der UML inden im nächsten Kapitel vorgestellten Style-Guide aufgenommen. Bevor der Style-Guide jedoch vorgestellt wird, erfolgt zu Anfang des Kapitels die Einführung einerTaxonomie des Style-Checkings auf Statecharts. Basierend auf dieser Taxonomiewird die Regelmenge des Style-Guides in drei Bereiche unterteilt. Neben den Regelnaus der UML werden auch die Regeln aus dem Bereich der syntaktischen Robustheitmit der OCL spezifiziert.
24
4. Style-Checking von Statecharts
Statecharts, die zu den visuellen Programmiersprachen zählen, werden, wie bereitserwähnt, in der modellbasierten Entwicklung von zum Teil sicherheitskritischen Soft-und Hardware-Systemen verwendet. Insbesondere in der Entwicklung von solchensicherheitskritischen Systemen ist Fehlervermeidung wichtig, da ein Ausfall des Sys-tems, wie erwähnt, enormen wirtschaftlichen Schaden nach sich ziehen kann (sieheKapitel 2). Wie einleitend erwähnt, wurden auch für die modellbasierte EntwicklungStyle-Guides zum Style-Checking von Statecharts entwickelt. Das Style-Checkinglässt sich auch auf Statecharts mit Style-Checkern automatisiert durchführen. Ausder automatischen Anwendung von Style-Guides auf Statecharts ergeben sich hierebenfalls die Vorteile wie bessere Lesbarkeit, Wartbarkeit und geringere Fehleran-fälligkeit. Ein besonderer Vorteil der Anwendung von Style-Guides auf Statechartsist, dass der Datenaustausch zwischen verschiedenen Modellierungswerkzeugen er-möglicht wird [62].
Im Folgenden wird die von Schaefer [85] eingeführte Taxonomie des Style-Checkingsauf Statecharts kurz vorgestellt. Dieser Taxonomie folgend, wird anschließend einRegelkatalog für das Style-Checking auf Statecharts eingeführt. Abschließend wirddie Unterstützung bei der Robustheitsanalyse durch verschiedene Modellierungs-werkzeuge und Style-Checker betrachtet.
4.1. Taxonomie des Style-Checking vonStatecharts
Statische Analysen von Statecharts werden nach Schaefer wie in Abbildung 4.1 inzwei Bereiche unterteilt [85, S. 40ff]: Zum Einen in den Bereich der die syntakti-sche und semantische Korrektheit analysiert (Correctness), und zum Anderen inden Bereich des Style-Checkings. Die syntaktische Korrektheit eines Statecharts istGrundvoraussetzung bevor das Style-Checking wertvolle Hinweise liefern kann undsollte daher immer vor dem Style-Checking überprüft werden. Das Style-Checkingwird weiter in die Bereiche der syntaktischen Analysen und den Bereich der Seman-tischen Robustheit unterteilt. Im Bereich der syntaktischen Analysen wird zwischenfolgenden Bereichen unterschieden
Lesbarkeitsanalysen werden in Style-Guides für Statecharts verwendet, um ein ein-heitliches Layout zu garantieren (bspw. „Einen Initial-Zustand immer links,einen Final-Zustand immer rechts im Statechart anordnen.“). Im Projekt KIEL,in dem der im Rahmen dieser Arbeit entwickelte Style-Checker als Plug-In
25
4. Style-Checking von Statecharts
Static Analysis of Statecharts
Correctness Style Checkingin Statecharts
SyntacticAnalysis
SemanticRobustness
Readability Efficiency SyntacticRobustness
Abbildung 4.1.: Statechart Style Checking Taxonomie (Quelle: [85])
integriert wurde, wird die Lesbarkeit durch integrierte Funktionen zum auto-matischen Layout gewährleistet [45, 74].
Die Effizienz von Statecharts, in diesem Fall gemessen an der Anzahl der Zustände,auch als Kompaktheit bezeichnet, lässt sich durch das Optimieren von model-lierten Systemen beeinflussen. Beispielsweise kann ein OR-CompositeState mitnur einem enthaltenen Zustand durch einen einzigen Zustand ersetzt werden(vergleiche Abbildung 4.3). Eine Funktion, die diese und andere Optimierun-gen automatisiert durchführt, wurde in das KIEL-Projekt integriert [47, 76].
Syntaktische Robustheit Die Regeln zur Syntaktischen Robustheit zielen daraufab, fehleranfällige Konstruktionen oder solche, die das Verständnis des Mo-dells erschweren (z.B. Interlevel Transitionen in Stateflow/Simulink [54]), zuvermeiden, beziehungsweise Fehler, die im Entwicklungsprozess entstehen („Je-der Zustand außer dem Root-Zustand und Initial-Zuständen sollte mindestenseine eingehende Transition besitzen.“ [63]), aufzuzeigen. Es gibt Regeln, diedialektspezifisch d.h. nur auf einem Statechart-Dialekt gültig sind, und dia-lektübergreifende, die auf jedem Dialekt ausgewertet werden können.
Die Semantische Robustheit von Statecharts befaßt sich mit Problemen der Mo-dellierung, die weit über syntaktische Analysen hinausgehen, wie beispielsweise dieÜberprüfung auf Deadlocks oder Erreichbarkeit. Style-Guides, mit Regeln aus denvorgestellten Bereichen, wurden unter Anderem von Mutz [63], dem MathWorksAutomotive Advisory Board (MAAB) [60] und der Ford Motor Company [28] veröf-fentlicht. Die letzten beiden Arbeiten befassen sich explizit mit Matlab Simulink/-Stateflow. Scaife et al. [84] und Huuck [39] haben daneben weitere Ansätze für diesichere Entwicklung mit Simulink/Stateflow vorgestellt, indem sie die Sprache auf
26
4.2. Ein Style-Guide für Statecharts
eine „sichere“ Teilmenge einschränken. Im folgenden Abschnitt wird ein dialektüber-greifender Style-Guide, entsprechend der eingeführten Taxonomie (Abbildung 4.1),vorgestellt.
4.2. Ein Style-Guide für Statecharts
In dem Bestreben einen Style-Guide für Statecharts zu entwickeln, der möglichst aufeiner Vielzahl von Dialekten, wie UML, Safe State Machines oder Simulink/State-flow anwendbar ist, wurden Regeln verschiedener Style-Guides hinsichtlich ihrer An-wendbarkeit auf andere Dialekte untersucht. Die Regeln wurden gemäß der oben ein-geführten Taxonomie kategorisiert. Wie erwähnt, ist syntaktische Korrektheit vonStatecharts die Grundvoraussetzung, bevor weitergehende Checks die Robustheit be-treffend ausgewertet werden können. Die also in diesen Style-Guide aufgenommenenRegeln zur Syntaktischen Korrektheit werden im folgenden Abschnitt vorgestellt.
Syntaktische Korrektheit
Es gibt CASE-Programme zur Modellierung mit der UML, die die korrekte Syn-tax von StateMachines nicht überprüfen (z. B. ArgoUML, vergleiche Kapitel 2.2).Also sollte die korrekte Syntax von StateMachines explizit überprüft werden, umverlässliche Aussagen über die Robustheit zu erhalten. Eine Überprüfung der kor-rekten Syntax von Statecharts, die aus Modellen im XMI-Format eingelesen werden,ist ebenfalls unerlässlich, da nicht sicher gestellt werden kann, dass das erzeugendeProgramm die korrekte Syntax der exportierten Statecharts überprüft. Die syntakti-sche Korrektheit von Statecharts anderer Dialekte wird durch einige Modellierungs-werkzeuge, wie Esterel Studio oder Matlab Simulink/Stateflow, über einen syntax-gerichteten Editor oder Syntax-Checks während der Code-Erzeugung sichergestellt.
Der hier entwickelte Style-Guide zielt, wie erwähnt, jedoch darauf ab, die Robust-heit von Statecharts verschiedener Dialekte analysieren zu können. Damit auch fürStateMachines verlässliche Aussagen über die Robustheit getroffen werden können,enthält dieser hier vorgestellte Style-Guide also auch die syntaktische Korrektheitvon StateMachines betreffende Regeln. Diese Regeln sind der UML-Spezifikation [66,65] entnommen. Sie werden in der UML Well-formedness-Regeln genannt. Ihr Zweckwird von der OMG wie folgt beschrieben: Die Well-formedness-Regeln „[. . . ] specifyconstraints over attributes and associations defined [with]in the [Statechart] me-ta model“ [66, Kapitel 2.3.2.2]. Die Regeln sind in der UML durch einen entspre-chenden OCL Ausdruck und eine natürlich-sprachliche Beschreibung der jeweiligenRegel angegeben. Die Well-formedness-Regel CompositeState-1 beispielsweise be-sagt: „A composite can have at most one initial vertex“ [66, Kapitel 2.12.3.1]. InAbbildung 4.2a ist der zugehörige OCL-Ausdruck angegeben. Eine Verletzung derRegel CompositeState-1 ist in Abbildung 4.2b angegeben. Zusätzlich zu der Mög-lichkeit, mit den Well-formedness-Regeln Bedingungen an einzelne Modellelementeund deren Beziehungen untereinander zu definieren, werden mit ihnen auch Mehr-
27
4. Style-Checking von Statecharts
self.subvertex->select(v | v.oclIsKindOf(Pseudostate))->select(p: Pseudostate | p.kind = #initial)->size <= 1
(a) Der OCL-Ausdruck(b) Verletzung der Regel
Abbildung 4.2.: Beispiel der Well-formedness-Regel CompositeState Nummer 1
deutigkeiten, die sich aus der UML-Spezifikation ergeben, beseitigt. Die in Version1.3 der UML angegebenen 31 Well-formedness-Regeln für StateMachines wurden inVersion 2.0 der UML auf eine Gesamtanzahl von 57 erweitert, um auf Änderungenim Metamodell zu reagieren.
Mit den oben erwähnten und in diesen Style-Guide aufgenommenen Well-formed-ness-Regeln lässt sich also die syntaktische Korrektheit von Statecharts – insbeson-dere den StateMachines – überprüfen. Wie aus dem angegebenen Beispiel einer Well-formedness-Regel ersichtlich, sind die überprüften Sachverhalte nicht kompliziert.Sie können sicherlich durch den Menschen überprüft werden, führen aber in einermanuellen Code-Review oft dazu, dass der Entwickler von den eigentlichen Proble-men abgelenkt wird [72]. Eine automatisierte Überprüfung dieser Regeln ist deshalbzu bevorzugen. Über die relativ einfachen Überprüfungen im Rahmen der Well-formedness-Regeln hinausgehend, sind Robustheitsanalysen der nächste Schritt, derim Rahmen des Style Checking durchgeführt werden kann. Gemäß der vorgestelltenTaxonomie (vergleiche Abbildung 4.1) enthält dieser hier vorgestellte Style-Guideauch Regeln zur syntaktischen und semantischen Robustheit. Die bereits in derverwandten Diplomarbeit [85] vorgestellten Regeln zur syntaktischen Robustheitwerden im folgenden Abschnitt aufgegriffen, ausführlich beschrieben, und um neueRegeln erweitert.
Syntaktische Robustheit
Die Regeln für die Syntaktische Robustheit von Statecharts, die in diesem Abschnittpräsentiert werden, stellen das Ergebnis einer Untersuchung verschiedener State-chart Style-Guides, beziehungsweise Arbeiten und praktischer Erfahrungen aus derModellierung auf diesem Gebiet dar.
Die folgenden Regeln sind, durch die Arbeit von Mutz [63, Seite 144f] inspiriert,in das Regelwerk aufgenommen worden.
EqualNames : Alle Zustände eines Statecharts sollten unterschiedlich benannt wer-den. Wird diese Regel in einem Statechart durchgängig eingehalten, so werdenanfallende Wartungsarbeiten oder Fehlerlokalisationen erheblich vereinfacht,da zu bearbeitende Zustände einwandfrei anhand des Namens identifiziertwerden können. Eine Verletzung dieser Regel kann in jeder Phase der Mo-dellierung durch Unachtsamkeit des Entwicklers verursacht werden, indem er
28
4.2. Ein Style-Guide für Statecharts
(a) Fehlerhaftes Statechart. (b) Optimiertes Statechart.
Abbildung 4.3.: Beispiel für die Regel ORStateCount
einen Zustand hinzufügt und einen Namen für den neuen Zustand vergibt, derbereits einmal verwendet wurde oder einen Bereich eines Statecharts kopiertund einfügt.
IsolatedState: Alle Zustände sollten ein- und ausgehende Transitionen haben. Aus-nahmen sind finale und initiale Zustände und der Root-Zustand, für die ent-sprechend der syntaktischen Korrektheit andere Richtlinien gelten. Finale Zu-stände dürfen keine ausgehenden Transitionen haben. Dies wird durch dieWell-formedness-Regel FinalState-1 (Siehe Kapitel 6, Tabelle 6.1) überprüft.Initiale Zustände dürfen keine eingehenden Transitionen aufweisen. Auch hier-für existiert eine Well-formedness-Regel (PseudoState-1, siehe Tabelle 6.1).Root-Zustände dürfen weder ein- noch ausgehende Zustände aufweisen. Hateine Zustand weder ein- noch ausgehende Transitionen ist er isoliert (isolated).Ein isolierter Zustand besitzt keinerlei Funktion und sollte daher ebenfalls ver-mieden werden, um die Wartbarkeit des Systems zu erhöhen.
InitialState: Alle Regionen, beziehungsweise nicht-parallelen hierarchischen Zustän-de, sollten genau einen initialen Zustand enthalten. Diese Regel geht einhermit der Regel InterlevelTransition. Wird ein hierarchischer Zustand über eineInterlevel-Transition betreten, beginnt die Ausführung des betretenen hierar-chischen Zustands während der Simulation nicht an einem initialen Zustand.Das Verständnis des Modells wird jedoch erleichtert, wenn die Ausführung ineinem Statechart immer an einem initialen Zustand beginnt.
OrStateCount : Alle OR-Zustände sollten mehr als einen Zustand enthalten. EineAuswertung dieser Regel liefert Hinweise für mögliche Optimierungen einesStatecharts, da OR-Zustände, die nur einen Zustand enthalten dialektunab-hängig optimiert werden können. Ein in dieser Hinsicht optimiertes Statecharterhöht die Lesbarkeit für den Entwickler, da die Anzahl der benötigten graphi-schen Objekte verringert wird. In Abbildung 4.3a ist exemplarisch ein State-chart angegeben, in dem der OR-Zustand A wie in Abbildung 4.3b angegebenoptimiert werden kann.
29
4. Style-Checking von Statecharts
(a) Fehlerhaftes Statechart. (b) Korrigiertes Statechart.
Abbildung 4.4.: Beispiel für die Regel DefaultFromJunction
RegionStateCount : Alle parallelen Regionen eines AND-Zustands sollten mehr alseinen Zustand enthalten. Eng verwandt mit der Regel OrStateCount, liefertauch die Auswertung dieser Regel Hinweise auf Optimierungen, mit denen dieLesbarkeit erhöht werden kann.
Aus dem Ford-Style-Guide [28] wurde die folgende Regel extrahiert, da diese auchauf anderen Dialekten ausgewertet werden kann.
DefaultFromJunction: Von Connective junctions (Siehe Tabelle 2.1) sollte immer einTeilstück einer Transition ohne Trigger und Bedingung abgehen, damit derProgrammablauf nicht stoppt. Das unbeschriftete Teilstück einer Transitionwird dann die Default-Transition genannt. Diese wird genommen, wenn dieBedingungen aller anderen ausgehenden Transitionen nicht erfüllt sind. Fehlerim Zusammenhang mit dieser Regel werden sowohl durch Unachtsamkeit alsauch durch Unwissenheit des Entwicklers verursacht. In Abbildung 4.4a ist derfehlerhafte Teil eines Statecharts angegeben. In dem Fall, daß die Variable xden Wert 10 hat, ist keine der beiden Bedingungen erfüllt. Der Kontrollflussstoppt, weil kein unbeschriftetes Segment modelliert wurde. In Abbildung 4.4bist ein Beispiel für die entsprechende Korrektur angegeben.
Aus der eigenen praktischen Erfahrung im Umgang mit Statecharts wurden diefolgenden Regeln erstellt.
InterlevelTransition: In einem Statechart sollten keine Interlevel-Transitionen ver-wendet werden. Interlevel-Transitionen sind Transitionen, die Hierarchie-Gren-zen überschreiten, wie in Abbildung 4.5a gezeigt. Solche Transitionen solltenvermieden werden, weil ihre Verwendung gegenüber einer entsprechenden Mo-dellierung mit initialen Zuständen keinen Mehrwert bietet und zudem dasVerständnis eines Modells erschwert wird. Insbesondere ungeübte Entwicklerkönnen das mit Interlevel-Transitionen ausgedrückte Verhalten missverstehen;beispielsweise die Reihenfolge der ausgeführten (Entry-)Aktivitäten und die
30
4.2. Ein Style-Guide für Statecharts
(a) Fehlerhaftes Statechart. (b) Korrigiertes Statechart.
Abbildung 4.5.: Beispiel für die Regel InterlevelTransition
gleichzeitige Aktivierung aller parallelen Bereiche. Neben der Erleichterung fürden Entwickler, ist die Einhaltung dieser Regel außerdem ein wichtiger Aspektbeim Datenaustausch zwischen verschiedenen Modellierungswerkzeugen, da esin einigen Dialekten (u. a.Safe State Machines) keine Interlevel-Transitionengibt. Werden durch die Auswertung dieser Regel Interlevel-Transitionen ineinem Statechart lokalisiert, können diese wie in Abbildung 4.5b dargestelltbehoben werden. Man setzt als Ziel der Interlevel-Transition den umgebendenhierarchischen Zustand des vorherigen Zielzustands und fügt entsprechend in-itiale Zustände in den hierarchischen Zustand ein.
TransitionLabels : Alle Transitionen sollten mit einem Trigger beschriftet werden.Für zusammengesetzte Transitionen bedeutet dies, dass mindestens ein Teil-stück einer Transition mit einem Trigger beschriftet sein sollte. Diese Regelsoll das Verständnis des Lesers erhöhen, da die Bedeutung sofort ersichtlichist. Es gibt Statechart Dialekte mit einem Default-Signal (z.B. tick in EsterelStudio). Ist kein Trigger für eine Transition beschriftet, so wird das Default-Signal während der Simulation für den Entwickler unsichtbar einer Transitionzugeordnet. Daher sollten alle Transitionen explizit beschriftet werden.
Connectivity : Für jeden Zustand sollte es einen gerichteten Pfad von einem initialenZustand geben. Diese Regel erweitert die Regel MiracleStates von Mutz [63,Seite 144], die besagt, dass alle Zustände außer initialem und root-Zustand ein-gehende Transitionen haben sollten. Darüber hinaus zeigt die Regel Connec-tivity aber wie in Abbildung 4.6a sogar Fehler im Modell auf, in denen einZustand (C1, C2) nicht betreten werden kann, obwohl er eingehende Transi-tionen aufweist. Die Abbildungen 4.6b und 4.6c zeigen zwei Möglichkeiten, wiefehlerhafte Statecharts korrigiert werden können.
So unterschiedlich die Regeln für die syntaktische Robustheit sind, so vielfältigsind auch die Vorgehensweisen zur Behebung von Verletzungen der Regeln. Wie vor-gestellt, muss in jedem Fall von Neuem mit der Spezifikation abgeglichen werden,
31
4. Style-Checking von Statecharts
(a) Fehlerhaftes Statechart.
(b) Korrektur durch Transition von A nach C1.
(c) Korrektur durch Transition von A nach C2.
Abbildung 4.6.: Beispiel für die Regel Connectivity
was zu tun ist, um ein fehlerhaftes Statechart zu korrigieren. Die hier angegebenenkorrigierten Statecharts stellen nur Beispiele zur Illustration möglicher Korrektu-ren dar. Eine Ergebnisanalyse über alle im entwickelten Style-Checker umgesetztenRegeln ist in Kapitel 6 enthalten.
Semantische Robustheit
Die folgenden Regeln für den Bereich der Semantischen Robustheit werden hier derVollständigkeit halber angegeben, sind allerdings Gegenstand der engverwandtenDiplomarbeit von Schaefer und werden dort ausführlich behandelt [85]. Als Prädikatewerden hier die Trigger und optionalen Bedingungen einer Transition bezeichnet.
Dwelling : Die Prädikate aller eingehenden und ausgehenden Transitionen eines Zu-stands sollten paarweise disjunkt sein oder zumindest nicht vollständig über-lappend sein.
Race Condition: Nebenläufige Schreib- oder Lese-/Schreibzugriffe auf eine Variablesollten in parallelen Zuständen nicht auftreten.
Transition Overlap: Alle von einem Zustand (direkt oder indirekt) ausgehendenTransitionen sollten disjunkte Prädikate haben.
Wie erwähnt können Regeln aus Style-Guides von Style-Checkern automatischüberprüft werden. Im folgenden Abschnitt werden exemplarisch verschiedene Model-lierungswerkzeuge und Style-Checker für Statecharts untersucht. Es wird betrachtet,wie ausgeprägt die Unterstützung zur Analyse der Robustheit von Statecharts imRahmen des hier vorgestellten Style-Guides ist.
32
4.3. Style-Checker
4.3. Style-Checker
Wie einleitend erwähnt, werden Style-Checker zur automatisierten Überprüfung vonDesignregeln, die in Style-Guides gesammelt werden, verwendet. In der textuellenProgrammierung sind diese Style-Checker sehr ausgereift und lassen sich umfassendan eigene Bedürfnisse anpassen. In der modellbasierten Entwicklung, in der eine au-tomatische Analyse von Designregeln – wie den vorgestellten Regeln zur Robustheit– wertvolle Unterstützung bei der Fehlervermeidung darstellt, ist das Style-Checkingbisher jedoch nicht sehr ausgereift.
Wie schon erwähnt, ist bereits in der Entwicklung insbesondere mit der UML ei-ne Überprüfung auf Korrektheit eines Statecharts unerlässlich. Denn obwohl dieseleicht automatisch durchführbar ist, existieren CASE-Werkzeuge (wie ArgoUML),die keine entsprechende Funktion besitzen (siehe Kapitel 4.2). Die Korrektheit vonStatecharts anderer Dialekte, etwa Safe State Machine und Stateflow, wird von denentsprechenden Entwicklungsumgebungen (Esterel Studio und Matlab Simulink/-Stateflow) durch syntax-gerichtete Editoren und durch integrierte Funktionen in derCode-Generierung gewährleistet und muss daher auf solchen Statecharts nicht über-prüft werden. In beiden Werkzeugen gibt es darüber hinaus bereits Funktionen zurstatischen Analyse. Diese sind jedoch nicht explizit abrufbar und die mitgeliefertenAnalysen lassen sich weder erweitern, noch an eigene Anforderungen anpassen. Einweiterer Nachteil der mitgelieferten Analysen ist, dass sie entweder sehr einfache odersehr anspruchsvolle Analysen von der Art eines Model Checking bieten [33, 46, 64].Analysen der Robustheit, wie sie in dieser Arbeit betrachtet werden und zwischenden beiden Arten liegen, lassen sich nicht durchführen. Um diese Lücke zu füllen,wurden einige nicht-kommerzielle und auch kommerzielle Style-Checker entwickelt.Die Werkzeuge Mint [81], State Analyzer [32, 46] und Guideline Checker [61] sindfür den Dialekt Stateflow entwickelt worden. Statecharts anderer Dialekte lassen sichnicht analysieren. Daher sind diese Style-Checker für eine hier angestrebte dialekt-übergreifende Robustheitsanalyse nicht anwendbar.
Im Gegensatz zu den bereits vorgestellten Style-Checkern ist der Regel Che-cker [63, 64] dialektunabhängig. Mit dem Regel Checker ist es möglich 71 verschie-dene Checks auf Statecharts verschiedener Dialekte auszuführen. Die mitgelieferten,auf syntaktische Abfragen beschränkten Checks, lassen sich über verschiedene Pa-rameter an eigene Bedürfnisse anpassen. Weitere Checks können entweder in OCLoder direkt in Java programmiert werden. Der Einsatz von OCL bietet bei der Er-weiterung des Regelwerks Vorteile, da eine Erweiterung leicht möglich ist. Denn fürdie Formulierung neuer Checks mittels OCL werden, wie erwähnt, keine detaillier-ten Kenntnisse einer Programmiersprache benötigt [63, Seite 126]. Jedoch werdendie mit OCL formulierten Regeln im Regel Checker in einem interpretativen Ansatzausgewertet. Größter Nachteil dieses Vorgehens ist die geringe Geschwindigkeit derAusführung. Insbesondere im Umfeld kommerzieller Softwareentwicklung ist die Ge-schwindigkeit eingesetzter Style-Checker jedoch ein wichtiges Kriterium, das überden Einsatz eines solchen Werkzeugs entscheidet. Zudem sind Erweiterungen des
33
4. Style-Checking von Statecharts
interpretierten Sprachumfangs ohne zum Teil tiefgreifende Veränderungen des zu-grunde liegenden Interpreters nicht durchführbar. Ein weiterer Nachteil des RegelCheckers ist, dass sich keine der im letzten Abschnitt vorgestellten anspruchsvol-len Analysen der semantischen Robustheit auf der Basis eines Theorembeweisersdurchführen lassen [85].
Vor dem Hintergrund dieser Ergebnisse wurde der in dieser Arbeit entwickelteStyle-Checker als Plug-In für das CASE-Tool KIEL mit den folgenden Zielen entwi-ckelt:
• Der Style-Checker soll die Möglichkeit bieten, sowohl syntaktische, als auchTheorembeweiser basierte semantische Analysen durchführen zu können.
• Die Regelmenge des Style-Checker soll möglichst einfach erweiterbar sein.
• Es sollen sich sowohl dialektspezifizische als auch allgemeingültige Regeln spe-zifizieren lassen.
• Die tatsächlich auszuführenden Checks sollen sich durch den Benutzer vorjedem Start des Checkings auswählen lassen.
Fazit
Wie beschrieben, erfüllt auch keines der oben eingeführten Programme alle Anforde-rungen an einen Style-Checker, der die gesamte vorgestellte Taxonomie abdeckt undleicht erweiterbar ist. Basierend auf der hier behandelten Thematik zur automatisier-ten Fehlervermeidung in der Modellierung, wurde zusammen mit den vorgestelltenAnsätzen zum Style-Checking auf Statecharts, ein flexibler Style-Checker für KIELentwickelt. Die genauen Details der Implementierung – wie OCL verwendet wird undwelche Werkzeugketten verwendet wurden – werden im nächsten Kapitel dargelegt.
34
5. Implementierung
Neben der Formulierung von Robustheitsregeln und der Untersuchung geeigneterMethoden, diese auf Statecharts auszuwerten, war ein Ziel dieser Diplomarbeit dieEntwicklung eines Style-Checkers zur automatisierten Überprüfung der vorgestelltenStatechart-Regeln (siehe Kapitel 4.2). Der entwickelte Style-Checker wurde in dasStatechart-Modellierungswerkzeug KIEL integriert. Im folgenden Abschnitt wird ei-ne kurze Einführung in den Aufbau von KIEL gegeben. Danach werden verschiedeneHerangehensweisen an die Überprüfung von Design-Regeln auf Statecharts bewer-tet. Auf den Ergebnissen dieser Bewertung basierend, werden anschließend verschie-dene Werkzeuge zur Umsetzung der gewählten Technik betrachtet. Anschließendwerden die technischen Details der Implementierung, basierend auf dem gewähltenWerkzeug, beschrieben. Zum Abschluss dieses Kapitels wird die Entwicklung einesXMI-Fileinterface für KIEL beschrieben, um den Style-Checker auch auf Modellenvon Modellierungswerkzeugen, die XMI-Dateien exportieren, anwenden zu können.
5.1. KIEL
Das dialekt-übergreifende Statechart Modellierungswerkzeug Kiel Integrated Envi-ronment for Layout wird am Lehrstuhl für Echtzeitsysteme und Eingebettete Syste-me der Christian-Albrechts-Universität zu Kiel zur Unterstützung bei der Entwick-lung von komplexen reaktiven Systemen entwickelt [74]. Eine zentrale Komponentevon KIEL ist eine Funktion zum automatischen Layout von Statecharts [45]. Da-mit können Statecharts, mit dem Ziel der Erhöhung der Lesbarkeit, automatischlayoutet werden. Eine weitere zentrale Funktion ist die Simulation von Statecharts.Im Gegensatz zur meist statischen Visualisierung während der Simulation wurde inKIEL eine Simulation mit dem dynamischem-Focus-und-Context Prinzip [74] um-gesetzt. Damit werden während einer Simulation nur die Bereiche des simuliertenStatecharts angezeigt, die aktiv sind. Andere Bereiche werden über geeignete Me-chanismen ausgeblendet. Insgesamt soll so das Verständnis des in der Entwicklungbefindlichen Systems erheblich vereinfacht werden.
KIEL wurde nach dem Model-View-Controller (MVC) Prinzip entwickelt und un-terteilt sich wie in Abbildung 5.1 dargestellt in verschiedene Komponenten. Die Kom-munikation der Komponenten untereinander erfolgt über wohldefinierte Schnittstel-len. Daher ist der Austausch einzelner Komponenten relativ einfach möglich. DieErweiterung von KIEL ist durch eben diese Voraussetzung gleichfalls leicht möglich.Daher wurde der in dieser Arbeit entwickelte Style-Checker als Plug-In für KIELrealisiert. Im Folgenden wird dieser auch als Checking-Plug-In bezeichnet.
35
5. Implementierung
Model
Controller
View
KIELDataStructure
Editor
Browser
FileInterface
Layouter
Simulator
Checking
KielFrame
Abbildung 5.1.: Die Komponenten von KIEL nach dem MVC-Konzept geordnet
Die in Abbildung 5.1 hervorgehobene Komponente Checking ist im Rahmen dieserDiplomarbeit entwickelt worden. Die Komponenten Kiel Datastructure, Browserund KielFrame sind für die Entwicklung und Integration des Checking-Plug-In vonentscheidender Bedeutung. In der Datenstruktur wird ein Statechart topologischabgebildet. Im Browser wird ein Statechart visualisiert. KielFrame ist die grafischeOberfläche von KIEL über die der Zugriff auf die meisten Funktionen erfolgt. DerZugriff auf den Style-Checker erfolgt über einen Menüpunkt im KielFrame (verglei-che Abbildung 5.6. Bevor die technischen Details der Implementierung vorgestelltwerden, wird im nächsten Abschnitt eine Bewertung verschiedener Verfahren für dasStyle-Checking auf Statecharts vorgenommen.
5.2. Verfahren für das Style-Checking
Pap et al. haben vier verschiedene Verfahren zur automatisierten Überprüfung vonSicherheitskriterien auf Statecharts untersucht und bewertet [70]. Von den Autorenwurden Verfahren basierend auf der (1) Auswertung von OCL, (2) Graphtransfor-mation, (3) problemspezifischen Programmen und (4) Erreichbarkeits-Analysen un-tersucht. Das im Rahmen dieser Diplomarbeit entwickelte Plug-in soll sparsam mitvorhandenen Ressourcen (Laufzeit des Programms und Speicherkapazität) umgehenund die Anforderungen aus Kapitel 4.3 erfüllen. Vor dem Hintergrund dieser An-forderungen wurden die von Pap et al. vorgestellten Verfahren auf Anwendbarkeituntersucht. Problemspezifische Programme und Erreichbarkeits-Analysen entspre-chen nicht der Anforderung, dass das zu entwickelnde Plug-in möglichst flexibel
36
5.3. Style-Checking in KIEL
erweiterbar sein soll, und wurden daher für den Bereich der syntaktischen Analysennicht weiter verfolgt.
Regeln für Graphtransformationen sind in zwei Teile unterteilt, die linke undrechte Seite. Die linke Seite einer Regel stellt die Bedingung dar, unter der eineÜberführung des Ausgangsgraphen in die rechte Seite erfolgt. Die Durchführungeiner Graphtransformation basiert grundsätzlich auf dem Auffinden von Überein-stimmungen der linken Seite in einem gegebenen Ausgangsgraph. Dieser Vorgangist als Pattern Matching bekannt und hat eine Komplexität von O(N L), wobei Nder Anzahl der Knoten im gegebenen Graphen und L der Anzahl der Knoten in derlinken Seite der Regel entspricht [94]. Dies kann bei großen Statecharts, wie sie inder Industrie keine Seltenheit sind, schnell zu nicht tolerierbaren Laufzeiten führen.
Bedingt durch die Tatsache, dass das zu überprüfende in KIEL geladene State-chart nicht modifiziert werden darf, muss also für jede Regel mindestens eine weitereKopie angelegt werden [70]. Bei Statecharts aus industriellen Projekten mit mehre-ren Tausend Zuständen und Transitionen stellt dies zusätzliche, nicht unerhebliche,Anforderungen an die Ressourcen (Speicherkapazität, Prozessorgeschwindigkeit) desausführenden Computers dar und widerspricht damit dem Vorhaben, möglichst res-sourcensparsam in der Ausführung zu sein.
Die Überprüfung der Regeln aus dem Katalog zur syntaktischen Robustheit wirddaher aufgrund der genannten Probleme der obigen Verfahren mittels Auswertungvon OCL-Ausdrücken durchgeführt. Dieses Vorgehen bietet mehrere Vorteile. Wiebereits erwähnt ist ein Vorteil der OCL, dass detaillierte Kenntnisse einer Program-miersprache nicht nötig sind, um neue Constraints zu spezifizieren. Die weiterenVorteile sind, dass die Auswertung von OCL-Ausdrücken ressourcenschonend durch-geführt werden kann und der Regelkatalog nicht auf wenige Probleme beschränkt ist.Die Auswertung von OCL-Ausdrücken lässt sich mit zwei Techniken durchführen.Zum Einen kann ein geeigneter Interpreter verwendet und zum Anderen kann eineexekutive Auswertung durchgeführt werden. Wie einleitend erwähnt, ist die Verwen-dung eines Interpreters im Allgemeinen langsamer als eine exekutive Auswertung.Daher wurde in dieser Arbeit eine exekutive Auswertung der OCL umgesetzt. Dieexekutive Auswertung erfolgt, unter Verwendung eines geeigneten Werkzeugs, durcheine Übersetzung der OCL-Ausdrücke in Java-Klassen. Die aus OCL generiertenJava-Klassen werden kompiliert und in den entwickelten Style-Checker eingebun-den. Im folgenden Abschnitt wird die Implementierung der exekutiven Auswertungvon OCL beschrieben.
5.3. Style-Checking in KIEL
Für die implementierte Übersetzung von OCL-Ausdrücken in Java-Klassen wurdeeine Auswahl verschiedener OCL-Werkzeuge untersucht. Die Kriterien anhand de-rer die Werkzeuge in der durchgeführten Untersuchung beurteilt wurden sowie dieermittelten Ergebnisse werden im Abschnitt 5.3.1 präsentiert. Unter Verwendungdes gewählten Dresden OCL Toolkits [19] werden, wie in Abbildung 5.2 dargestellt,
37
5. Implementierung
Entwickler
MetamodellXMI V. 1.1
ArgoUML
Benutzer
Regeln(KOCL)
MetamodellXMI V. 1.0
XMI-Konverter
Dresden OCL Toolkit
AST(Java)
KOCL-Parser
OCL-Ausdruck
OCL-Handler
Nachrichten
Message-Handler
KIEL Checking(Java)
Nachrichten-Code(Java)
Message-Handler
Message-Handler
Java-OCL-Code
OCL-Handler
Abbildung 5.2.: Darstellung der durchgeführten Arbeitsschritte zur Übersetzungvon OCL in Java-Code
OCL-Ausdrücke in entsprechenden Java-Code übersetzt.Wie dargestellt spezifiziert der Benutzer des Style-Checkers bei Bedarf Regeln
mit der eigens entwickelten Sprache KIEL wrapped OCL (KOCL). Diese werdenmit dem entwickelten KOCL-Parser verarbeitet. Der in der KOCL-Spezifikationenthaltene OCL-Ausdruck wird vom OCL-Handler an das gewählte Dresden OCLToolkit übergeben. Dieses Toolkit erzeugt aus dem OCL-Ausdruck Java-Code. Diein der KOCL-Spezifikation enthaltenen Nachrichten werden durch den Message-Handler in entsprechenden Java-Code übersetzt. Der Regel-Generator vereinigt dieerzeugten Java-Code-Fragmente zu einer Java-Klasse.
Zur Überprüfung des OCL-Ausdrucks auf korrekte Typisierung benötigt das ge-wählte Dresden OCL Toolkit das Metamodell der Datenstruktur, auf der ein OCL-Ausdruck ausgewertet wird. Dieses Metamodell wurde im Rahmen dieser Arbeit,
38
5.3. Style-Checking in KIEL
Modul Checking
Regeln Syntaktische Korrektheit
Regeln Syntaktische Robustheit
Regeln Semantische Robustheit
Abbildung 5.3.: Illustration der Beziehung zwischen dem Checking-Plug-In und denunterschiedlichen Regelmengen
wie dargestellt, mit ArgoUML erstellt und mit dem entwickelten XMI-Konverterfür das Dresden OCL Toolkit vorbereitet.
Die Details der in Abbildung 5.2 dargestellten Werkzeuge werden im Abschnitt 5.3.2beschrieben. Als erstes werden die Notwendigkeit des XMI-Konverters und dessentechnische Details erläutert. Danach wird die Arbeitsweise des Dresden OCL Tool-kits beschrieben. Dieses wird von dem entwickelten Regel-Generator verwendet. DasWerkzeug Regel-Generator fasst die verschiedenen an der Verarbeitung der Regelnbeteiligten Werkzeuge in einem Programm zusammen und wird im Abschnitt KIELwrapped OCL beschrieben.
Wie in Abbildung 5.3 dargestellt, wurde das in dieser Arbeit implementierteChecking-Plug-In so entwickelt, dass die Auswertung von Regeln aus allen drei,in Kapitel 4 vorgestellten, Bereichen der Taxonomie möglich ist. Im Abschnitt 5.3.3werden die technischen Details der Regelauswertung beschrieben. Abschließend wer-den die Integration der entwickelten Werkzeugkette in KIEL und die Erweiterungs-möglichkeiten der Regelmenge beschrieben.
5.3.1. OCL-Toolkits
Die Unterstützung von OCL in CASE-Programmen hängt von den Anforderun-gen der Anwender und der verfügbaren Bibliotheken ab. Bis etwa zum Jahr 2000hatte der Großteil der Anbieter kommerzieller CASE-Programme keine OCL Un-terstützung in ihre Produkte integriert [38]. In der Folgezeit wurden daher Toolkitsentwickelt, um die Arbeit mit OCL zu erleichtern und den Entwicklern der CA-SE-Programme die Möglichkeit zu bieten, OCL-Unterstützung in ihre Programmeaufzunehmen. Die entwickelten OCL-Toolkits haben bislang jedoch kaum zur Un-terstützung der OCL in kommerziellen CASE-Programmen beigetragen. Für das indieser Arbeit entwickelte Checking-Plug-In wird in diesem Abschnitt eine Evalua-tion ausgewählter OCL-Toolkits präsentiert. Die Kriterien anhand derer die OCL-Toolkits untersucht wurden, sind die Folgenden:
Syntaktische Analysen: Das einzusetzende Toolkit sollte Fehler in der Syntax vonOCL-Ausdrücken finden können [38].
39
5. Implementierung
Typüberprüfung: Das Toolkit sollte die korrekte Typisierung der Ausdrücke über-prüfen können [38].
OCL-Auswertung: Das Toolkit sollte Methoden bieten, um den übergebenen OCL-Ausdruck auf einer Instanz eines Modells zu überprüfen [38].
Sprache: Um die Arbeit mit dem Toolkit so einfach wie möglich zu halten, solltedas Toolkit direkt aus Java verwendet werden können. Ideal wäre es, wenn dasToolkit bereits in Java programmiert ist.
Plattform: Das KIEL-Projekt ist auf Linux- und Windows-Plattformen lauffähig.Die Einbindung eines OCL-Toolkits sollte die Plattformunabhängigkeit nichtaufheben.
Anhand dieser Kriterien wurde eine Auswahl frei verfügbarer Toolkits zur Arbeitmit OCL untersucht. Die Ergebnisse der Untersuchung sind in Tabelle 5.1 aufgelistet.Die einzelnen Toolkits werden im Folgenden kurz beschrieben. Besondere Merkmalesind entsprechend hervorgehoben.
Dresden OCL Toolkit: Das Dresden OCL Toolkit [19] wird an der TechnischenUniversität Dresden in Java entwickelt und unter der LGPL Lizenz bereitge-stellt. Das Toolkit teilt sich in verschiedene Module auf, die als Bibliothek inanderen Programmen verwendet werden können. Ein für diese Arbeit wich-tiger Bestandteil des Toolkits ist der OCLCompiler, der mit Hilfe eines ge-eigneten UML-Klassenmodells OCL-Ausdrücke auf korrekte Typisierung hinüberprüft und einen Abstrakten Syntax Baum (AST) zurückliefert. Aus solcheinem erzeugten AST lässt sich mit einem weiteren mitgelieferten Modul Java-Quellcode erzeugen, der einer in Java ausführbaren Version des geparsten OCL-Ausdrucks entspricht. Der Quellcode kann in anderen Programmen unter Ein-bindung der bereitgestellten OCL-Klassenbibliothek verwendet werden.
C#/OCL Compiler: Der C#/OCL-Compiler [23] ist in C# entwickelt worden.Mit Hilfe des C#/OCL-Compilers lassen sich OCL-Ausdrücke in C# Codeübersetzen. Dieser erzeugte C#-Code lässt sich, wie auch der Compiler selbst,unter der Verwendung des .NET -Frameworks und Visual Studio .NET 2003kompilieren.
OSLO: Die Open Source Library for OCL (OSLO) [37] ist eine Bibliothek, die ver-wendet werden kann, um OCL-Unterstützung in Softwareprojekte zu integrie-ren. Mit Hilfe der Bibliothek kann überprüft werden, ob Instanzen von UML-Modellen die übergebenen OCL-Ausdrücke erfüllen. Die OSLO-Bibliothek istin Java entwickelt worden.
PWAN: Die OCL-Bibliothek des Project without a name (PWAN) [77] beinhalteteinen Parser, der für syntaktisch korrekte OCL-Ausdrücke einen Syntaxbaumerzeugt. Der Parser unterstützt OCL aus Version 1.3 der UML-Spezifikation.
40
5.3. Style-Checking in KIEL
Tabelle 5.1.: Anforderungen an untersuchte OCL-Toolkits
Toolkit Funktion Sprache
Synt
aktisc
heA
naly
sen
Typ
über
prüf
ung
OC
LA
usw
ertu
ng
Dresden OCL Toolkit • • • JavaC# / OCL Compiler - - - C#OSLO - - • JavaPWAN • - - C++
Der C# / OCL Compiler bietet keine Funktionen, um eingegebene OCL-Ausdrückeauf korrekte Syntax oder Typisierung hin zu überprüfen. Aufgrund der Beschrän-kung auf die Kombination aus Microsoft VisualStudio .NET 2003 und .NET -Frame-work ist dieses Toolkit nicht für einen plattformübergreifenden Einsatz geeignet. Dievorliegende Version von OSLO wertet OCL-Ausrücke auf geladenen Modellinstanzenaus, bietet aber keine Überprüfung der Syntax und Typisierung. Die PWAN -OCL-Bibliothek liefert für einen korrekt formulierten OCL-Ausdruck einen AST. EineTypüberprüfung oder sogar eine Auswertung des OCL-Ausdrucks ist jedoch nichtmöglich. Die Weiterverarbeitung des AST bleibt somit dem Anwender überlassen.
Wie Tabelle 5.1 zeigt, erfüllt nur das Dresden OCL Toolkit alle gestellten An-forderungen. Mit Hilfe des Dresden OCL Toolkits lassen sich OCL-Ausdrücke aufkorrekte Syntax und Typisierung hin überprüfen. Da die ImplementationsspracheJava ist, kann somit die Plattformunabhängigkeit weiterhin gewährleistet werden.
Weitere Kriterien, die die Auswahl beeinflusst haben, sind die Aktualität, dieEinsätze in anderer Software und die Dokumentation der Bibliotheken. Die PWAN -Bibliothek steht auch bei diesen Kriterien hinten an. Die letzte Aktualisierung derBibliothek war 1999 und die Dokumentation beschränkt sich auf einige Kommen-tare im Quellcode. Einsätze in anderen Programmen sind genau wie für den C# /OCL Compiler nicht bekannt. Die Internetpräsenz von OSLO weist Modelware alsein Projekt auf, in dem die Bibliothek eingesetzt wird. Die bisher verfügbare Do-kumentation beschränkt sich auf Hinweise zur Bedienung einer Demo-Applikation.Jegliche benötigte Information muss dem Quellcode entnommen werden.
Die Dokumentation des Dresden OCL Toolkits von Finger [25] hat sich nach kurz-er Einarbeitungszeit als hinreichend gut erwiesen. Daneben weist das Dresden OCLToolkit bereits eine Reihe bekannter Projekte als Einsatzgebiete auf, so dass dieEntscheidung auf das Dresden OCL Toolkit fiel. Die zur Anbindung des gewähl-ten Dresden OCL Toolkits an KIEL durchgeführten Arbeiten werden im Folgendenbeschrieben.
41
5. Implementierung
5.3.2. Verwendung des Dresden OCL Toolkits
Im Folgenden werden die im Rahmen der Implementierung durchgeführten Arbeitenvorgestellt, um einen Überblick über die Funktionsweise des entwickelten Plug-Inszu geben.
XMI-Konverter
Eine Voraussetzung für das verwendete OCL-Toolkit ist, dass die Typsicherheit vonOCL-Ausdrücken überprüft werden kann. Für diese Funktion benötigt das gewähl-te Dresden OCL Toolkit Informationen über das Meta-Modell (Abbildung D.1), aufdem ein OCL-Ausdruck formuliert wurde. Diese Informationen können dem DresdenOCL Toolkit auf verschiedene Arten zur Verfügung gestellt werden. Es ist beispiels-weise möglich, dass das Toolkit die benötigten Daten mittels Reflection [27] ausvorhandenen Java-Klassen selbstständig ausliest. Mit dieser Möglichkeit werden je-doch Einschränkungen bezüglich der verfügbaren OCL-Funktionen gemacht, die eineffektives Arbeiten behindern. Es ist unter Anderem nicht mehr möglich Mengen-Funktionen auf Assoziationen aufzurufen, da die Multiplizität einer Assoziation perReflection nicht bestimmt werden kann. Ein weiterer Mechanismus, die Typinforma-tionen an das Toolkit zu übergeben, ist, das Metamodell in einem CASE-Programmzu modellieren und als XMI-Datei zu exportieren. Wird das Metamodell als XMI-Datei bereitgestellt, stehen alle OCL-Funktionen zur Verfügung. Daher wurde dasMetamodell der in KIEL verwendeten Statechart Datenstruktur mit ArgoUML [4]modelliert und als XMI-Datei exportiert. Ein Nebeneffekt dieser Vorgehensweise ist,dass Änderungen an der Datenstruktur auch in das Metamodell eingepflegt werdenmüssen. Der Arbeitsaufwand ist also etwas höher, als wenn man die Meta-Datenmittels Reflection auslesen würde.
Obwohl bereits Version 2.0 des gewählten Dresden OCL Toolkit existiert, wurdefür diese Implementierung die Version 1.3 verwendet, da die neue Version noch keinenJava-Codegenerator bietet. Die ältere Version des Toolkits setzt als Metamodell einemit ArgoUML Version 0.0.7 erzeugte XMI-Datei voraus. Diese Version von ArgoUMList jedoch nicht mehr verfügbar. Der XMI-Export der Version 0.20 von ArgoUMLführt den Export mit XMI Version 1.1 durch, die von der gewählten Version desToolkits nicht verarbeitet werden kann. Um dieses Problem zu lösen, wurde einProgramm entwickelt, das eine Transformation der XMI-Dateien, die durch die neueArgoUML Version erzeugt wurden, in XMI Version 1.0 automatisiert durchführt.
Der hierzu entwickelte XMI-Konverter (Anhang G.1) wurde als Kommandozei-lenprogramm entworfen (siehe Auflistung 5.1). Als Eingabe erwartet das Programmden Dateinamen des Quell-Dokuments und den des Ausgabe-Dokuments. Für dieTransformation wird das Extended Markup Language (XML)-Dokument mit Metho-den aus der Simple API for XMI (SAX)-Bibliothek sequentiell durchlaufen. Überdie generierten Call-back -Ereignisse des XMI-Parsers wird mit Methoden des Do-cument Object Model (DOM) ein neues Dokument erzeugt. Die Arbeitsweise desXMI-Konverters ist in Abbildung 5.4 dargestellt.
42
5.3. Style-Checking in KIEL
Auflistung 5.1: Kommandozeilenausgabe des XMI-Konverters
KIEL xmi-file converter.Used for converting xmi-files generated by argoUML v. 0.2.xinto the format readable by the Dresden OCL Toolkit v. 1.3.Usage: xmiConverter <Inputfile> <Outputfile>
MetamodellXMI V. 1.1
XMI(Java)
SAX MetamodellXMI V. 1.0
DOM
Abbildung 5.4.: Übersicht über die Funktionsweise des XMI-Konverters
Code-GeneratorDas Dresden OCL Toolkit bietet, wie erwähnt, die Möglichkeit OCL-Ausdrücke inausführbaren Java-Code zu übersetzen. Der im Toolkit enthaltene Parser erzeugt auseinem übergebenen OCL-Ausdruck einen OCLTree [25]. Der Typchecker des DresdenOCL Toolkits überprüft anschließend anhand des Metamodells auf dem OCLTree,ob der eingelesene OCL-Ausdruck korrekt typisiert ist. Ist der Ausdruck korrekttypisiert, kann der OCLTree an den Java-Codegenerator übergeben werden. DerCodegenerator erzeugt, unter Anwendung des Visitor-Design-Patterns [30], aus demOCLTree den Java-Code [25]. Der erzeugte Java-Code lässt sich vom Codegeneratorabfragen und steht zur weiteren Verwendung bereit. Abbildung 5.5 visualisiert diean der Übersetzung beteiligten Module des Dresden OCL Toolkits.
Hauptbestandteil des erzeugten Java-Codes ist die im Toolkit vorhandene Java-Implementierung der OCL-Bibliothek [24]. Die OCL-Bibliothek wird benötigt, umMethoden der Sprache in Java ausführen zu können und ist Kapselung für die zu-grunde liegenden Klassen des Metamodells. Damit der erzeugte Java-Code ausge-führt werden kann, muss die OCL-Bibliothek also in das Programm aufgenommenwerden, das den erzeugten Java-Code ausführt. Der OCL-Ausdruck in Auflistung 5.2ist in den Java-Code in Auflistung 5.3 übersetzt worden.
Auflistung 5.2 zeigt den an das Dresden OCL Toolkit übergebene OCL-Ausdruckfür die bereits in Abschnitt 4.2 beschriebene Well-formedness-Regel CompositeState-1 [66]. In Zeile eins ist – ausgezeichnet durch das Schlüsselwort context – die Klasseangegeben, die den nachfolgenden Ausdruck erfüllen muss. In diesem Fall soll derAusdruck auf allen Instanzen der Klasse CompositeState ausgewertet werden. DieseKlasse repräsentiert hierarchische Zustände. In diesem Beispiel ist eine Invariante –ausgezeichnet durch das Schlüsselwort inv – spezifiziert. Der Bezeichner self dientzur Referenzierung des Kontextes, ähnlich wie der Bezeichner this in Java. DasAttribut subnodes der referenzierten Klasse enthält alle Zustände die in einem hier-archischen Zustand enthalten sind. Der Pfeil-Operator ist ein Operator der OCLmit dem nachfolgende Funktionen auf einer Menge ausgeführt werden. In diesemFall wird – ausgezeichnet durch select – eine Teilmenge gebildet, die alle initialenZustände enthält. Abschließend wird der Vergleich durchgeführt, ob die ermittelte
43
5. Implementierung
Metamodell
Model-Wrapper
OCL-Ausdruck
OCL-Parser
Type-Checker
Typ-informationen OCLTree
JavaCode-Generator
OCLTree
Java-Code
Abbildung 5.5.: An der OCL-Transformation beteiligte Module des Dresden OCLToolkits
Auflistung (5.2) OCL-Ausdruck der Well-formedness-Regel CompositeState-1
1 context CompositeState;2 inv: self.subnodes->select (v |v.oclIsTypeOf(InitialState))->size <= 1
Auflistung (5.3) Erzeugter Java-Code
1 final OclAnyImpl tudOclNode0=Ocl.toOclAnyImpl( Ocl.getFor(o) );2 final OclSequence tudOclNode1=Ocl.toOclSequence(3 tudOclNode0.getFeature("subnodes"));4
5 final OclIterator tudOclIter0=tudOclNode1.getIterator();6 final OclBooleanEvaluatable tudOclEval0=new OclBooleanEvaluatable() {7 public OclBoolean evaluate() {8 final OclType tudOclNode2=OclType.getOclTypeFor(o, "InitialState");9 final OclBoolean tudOclNode3=Ocl.toOclAnyImpl(tudOclIter0.getValue()).
oclIsTypeOf(tudOclNode2);10 return tudOclNode3;11 }12 };13
14 final OclSequence tudOclNode4=Ocl.toOclSequence(tudOclNode1.select(tudOclIter0,tudOclEval0));
15
16 final OclInteger tudOclNode5=tudOclNode4.size();17 final OclInteger tudOclNode6=new OclInteger(1);18 final OclBoolean tudOclNode7=tudOclNode5.isLessEqual(tudOclNode6);
44
5.3. Style-Checking in KIEL
Teilmenge höchstens einen initialen Zustand enthält.Der mit dem Java-Codegenerator erzeugte Java-Code ist in Auflistung 5.3 ent-
halten. In Zeile eins wird die Instanz des zu überprüfenden Objekts von der OCL-Basisbibliothek des Toolkits gekapselt. Alle weiteren Zugriffe auf das Objekt erfolgenüber die Kapselung. In Zeile zwei wird die Menge subnodes in einer Variable vomTyp OclSequence gekapselt. In den Zeilen sechs bis zwölf wird die Filterbedingungdes eingegebenen OCL Ausdrucks als Java-Funktion deklariert. Dieser Filter wirdin Zeile zwölf auf der Kapselung der Menge subnodes angewendet. In den Zeilen 16bis 18 wird verglichen, ob die Anzahl der selektierten initialen Zustände kleiner odergleich eins ist.
Kiel Wrapped OCLDamit das Ergebnis aussagekräftig an den Benutzer des entwickelten Checking-Plug-in zurückgeliefert werden kann, wird ein geeigneter Hinweistext benötigt. DieserHinweistext lässt sich nicht aus dem OCL-Ausdruck herauslesen und auch nicht mitihm spezifizieren. Damit das entwickelte Plug-in dennoch entsprechende Meldun-gen zurückliefern kann, müssen diese mit dem OCL-Ausdruck in geeigneter Weisekombiniert werden.
Zu diesem Zweck wurde die Spezifikationssprache KOCL entwickelt. Mit dieserSprache werden Hinweismeldungen und OCL-Ausdrücke kombiniert. Damit ist esmöglich mehrere Hinweistexte zu deklarieren und je nach Context eine unterschied-liche Meldung zurückzuliefern. In Auflistung 5.4 ist der OCL-Ausdruck aus Auf-listung 5.2 in KOCL mit einer zugehörigen aussagekräftigen Meldung präsentiert.In den Zeilen zwei bis vier ist die Nachrichten Deklaration – eingeleitet durch denIdentifier declarations – angegeben. Die Regel ist in den Zeilen fünf bis acht – aus-gezeichnet durch den Identifier constraint – spezifiziert. Zeile sieben enthält denOCL Ausdruck – angepasst an KIELs Metamodell. In Zeilen neun bis elf ist – aus-gezeichnet durch den Identifier fails – die Deklaration enthalten, welche Nachrichtzurückgeliefert wird, wenn das Constraint nicht erfüllt ist.
Die Verarbeitung der KOCL-Dateien geschieht durch einen mit dem Parser Gene-
Auflistung 5.4: Ein KOCL-Beispiel für das KIEL-Metamodell
1 rule UML13CompositeStateRule1 {2 declarations {3 message "A composite state can have at most one initial vertex.";4 }5 constraint {6 context ORState or Region;7 "self.subnodes->select (v | v.oclIsTypeOf(InitialState))->size <= 1";8 }9 fails {
10 message;11 }12 }
45
5. Implementierung
Auflistung 5.5: Kommandozeilenausgabe des RuleParser
KIEL Rule to Java ConverterUsage: RuleParser <ModelFile> <RuleDir> <Base Output Directory> <BasePackage>
rator SableCC [29] erzeugten Parser. Die EBNF der Grammatik ist in Abbildung C.1angegeben. Die Eingabe für den SableCC befindet sich im Anhang (Abschnhitt E.1).
Basierend auf dem Visitor-Design-Pattern wird aus KOCL-Spezifikationen proRegel (rule) eine Java-Datei erzeugt. Damit die Verwendung der erzeugten Java-Dateien im Vorgang der Auswertung einheitlich durchgeführt werden kann, wurde ei-ne gemeinsame Basisklasse (BaseCheck, Anhang G.3) für alle Regeln implementiert.Die Basisklasse bietet alle wichtigen Funktionen, die zur reibungslosen Integration indas Checking-Plug-In benötigt werden. Von der Basisklasse werden die übersetztenKOCL-Spezifikationen abgeleitet. Die Transformation wird durch den RuleParser(Anhang G.2) durchgeführt. Er ist, wie der XMI-Konverter, als Kommandozeilen-programm ausgelegt und in den Build -Prozess von KIEL integriert. Auflistung 5.5zeigt die Ausgabe eines Aufrufs ohne Parameter.
5.3.3. Arbeitsweise des Style-Checkers
Im vorigen Abschnitt wurde die Verwendung des Dresden OCL Toolkits beschrieben.Die erzeugten Java-Klassen kommen durch den Style-Checker zur Anwendung aufStatecharts. Die Arbeitsweise des entwickelten Style-Checkers und die Integrationin KIEL wird im Folgenden beschrieben.
RegelanwendungDie Anwendung der Regeln auf ein Statechart erfolgt über den Call-back -Mechanis-mus des Visitor-Design-Patterns. Das zu überprüfende Statechart ist in der State-chart Datenstruktur von KIEL baumartig abgebildet. Ein Knoten eines Baums istein Zustand des Statecharts. Transitionen sind Zuständen zugeordnet. Dieser Baumwird mittels Tiefensuche traversiert. Für jeden besuchten Zustand wird überprüft,ob eine Regel basierend auf dem context anwendbar ist. Ist der Typ des Zustandsgültig, wird die Bedingung ausgewertet und im Bedarfsfall eine definierte Nachrichtzurückgeliefert.
Die flexible Arbeitsweise der Regelauswertung ermöglicht es, verschiedene Artenvon Regeln auszuwerten. Dies ist insbesondere hilfreich, da die Auswertung der Re-geln semantischer Robustheit, wie oben erwähnt, einen externen Theorembeweiserbenötigt [85]. Auch diese Regeln sind von der gemeinsamen Basisklasse abgeleitet.Die erste Anforderung an das entwickelte Checking-Plug-in – sowohl syntaktischeals auch Theorembeweiser-basierte semantische Analysen sollen durchgeführt wer-den können (vergleiche Kapitel 4.3) – wurde also erfüllt. Die in dieser Arbeit im-plementierten Regeln und die Ergebnisse eine Laufzeitanalyse werden in Kapitel 6präsentiert.
46
5.3. Style-Checking in KIEL
Abbildung 5.6.: Screenshot von KIEL mit ausgeklappten Checking-Menüpunkt
Integration in KIELEine Erweiterung der Regelmenge erfolgt durch das Hinzufügen einer neuen rule-Deklaration in die Regeldateien mit KOCL. Die implementierte Werkzeugkette wur-de so in den Build -Prozess von KIEL integriert, dass keine Änderungen benötigtwerden, wenn neue Regeln an den bisher vorgesehenen Stellen im Dateisystem hin-zugefügt werden. Regeln, die sich nicht in KOCL formulieren lassen, wie etwa solchedie externe Programme ansteuern, werden von der Basisklasse abgeleitet und an derentsprechenden Stelle im Dateisystem des KIEL-Projektes abgelegt. Diese Regelnwerden ebenfalls automatisch im Build -Prozess übersetzt und sind beim nächstenStart von KIEL verfügbar. Das Style-Checker-Plug-In bestimmt bei jedem Start vonKIEL welche Regeln zur Verfügung stehen und stellt entsprechende Menüpunktezur Aktivierung automatisch bereit. Der Benutzer kann über diese erzeugten Menü-punkte vor jedem Checking-Vorgang bestimmen, welche Regeln ausgewertet werdensollen (siehe Abbildung 5.6).
Wird ein Statechart in KIEL importiert, verarbeitet das Checking-Plug-In au-ßerdem ein Regel-Profil, passend zum Dialekt in dem das Statechart entworfenwurde. In solch einem Profil werden all die Regeln angegeben, die standardmä-
47
5. Implementierung
Esterel StudioPlugin XMI Plugin Stateflow Plugin
FileInterface
KIEL Datastructure
.scg .xmi .stfl
(a) Generelle Arbeitsweise des Fileinterfa-ces.
XMI-Plugin
XMI1
XMI2
XMI3
ArgoUMLv. 0.07
ArgoUMLv. 0.20
Rhapsody
(b) Modulsicht des XMI-Fileinterface.
Abbildung 5.7.: Das Fileinterface-Modul
ßig auf Statecharts eines Dialekts ausgewertet werden sollen. So kann auch für dieKommandozeilen-Variante von KIEL angegeben werden, welche Regeln ausgewertetwerden sollen und welche nicht. Ist kein Profil vorhanden werden standardmäßig alleRegeln ausgewertet. Die bisher definierten Profile sind im Anhang B enthalten.
5.4. XMI-Import
KIEL bietet über die Komponente FileInterface bislang unter anderem Import-funktionen für Statecharts, die mit den Modellierungswerkzeugen Esterel Studio,Matlab Simulink/Stateflow und mit KIEL selbst entworfen wurden. Das File-Interfacevon KIEL ist, wie in Abbildung 5.7a dargestellt, modular konzipiert. Für jedes Da-teiformat, das in KIEL verarbeitet werden soll, wird ein Plug-In entwickelt. Einezu öffnende Datei wird an das entsprechende zum Dateiformat gehörende Plug-Inübergeben und dieses liefert eine Instanz eines Statecharts in der Datenstruktur zu-rück [47, 73]. Damit der Einsatz des Checking-Plug-Ins nicht auf Statecharts ausdiesen Werkzeugen beschränkt bleibt, und um der zunehmenden Verbreitung derUML gerecht zu werden, ist das File-Interface um ein Modul zum Im- und Exportvon Statecharts aus und in das XMI-Format erweitert worden.
Bei der Entwicklung des XMI-File-Interface (Anhang G.4) musste besonderes Au-genmerk auf die Möglichkeit gelegt werden, dass sich die Namen der Tags des XMI-Formats sowohl zwischen einzelnen XMI- und UML-Versionen, als auch zwischenModellierungswerkzeugen unterscheiden können. Informationen darüber, in welcherXMI- und UML-Version und von welchem Programm eine zu importierende XMI-Datei erzeugt wurde, sind in den META-Tag-Informationen am Anfang einer XMI-Datei enthalten.
Um dem Umstand verschiedener Versionen gerecht zu werden und möglichst fle-xibel auf Änderungen reagieren zu können, wurde das entwickelte XMI-Fileinterfacemodular konzipiert. Für jede Variation des XMI Dateiformats wird ein eigenes Mo-
48
5.4. XMI-Import
XMI-Datei
XMI-Dokument(Java)
SAX
Topologie(Java)
Topologie-Reader(SAX)
Transitionslabels(XMI)
Label-Reader(SAX)
Statechart(KIEL)
Topologie-Handler
Transitionslabels(KIEL)
Transitionslabel-Parser
Transitions-Handler
Abbildung 5.8.: Visualisierung der Zwischenschritte des implementierten Reader-Moduls
dul, das Statecharts aus den zu importierenden Dateien in die Datenstruktur vonKIEL einliest, angelegt. Die Verwaltung der einzelnen Module geschieht durch dasXMI-Plug-In (Vergleiche Abbildung 5.7b).
Der Import einer XMI-Datei erfolgt grundsätzlich in einem mehrteiligen Prozess.Im ersten Schritt überprüft ein SAX-Parser, ob es sich bei der ihm übergebenenDatei um eine syntaktisch gültige XMI-Datei handelt. Ist dies der Fall, wird imnächsten Schritt anhand der META-Tag-Informationen der übergebenen Datei be-stimmt, welches Reader -Modul die State Machine in die KIEL-Datenstruktur ein-liest. Ist kein Modul im XMI-File-Interface für das Format der XMI-Datei geladen,wird der Vorgang abgebrochen.
Bisher wurde ein Reader -Modul implementiert, das mit ArgoUML erzeugte XMI-Dateien verarbeitet (Anhang G.4). Dieses Modul liest das erste in der zu impor-tierenden Datei gefundene Statechart in die topologische Statechart Datenstruk-tur von KIEL ein. Das Einlesen erfolgt mittels SAX-Methoden. Die Topologie desStatecharts wird ohne Veränderungen in die Statechart Datenstruktur überführt,Beschriftungen von Transitionen werden jedoch gesondert behandelt. Diese werdenmit einem Transitionslabel-Parser (Anhang G.4) in die einzelnen Bestandteile einerBeschriftung zerlegt und in die dafür vorgesehenen Klassen in der Datenstrukturüberführt. Mit den so erzeugten Instanzen von Transitionslabels lässt sich eine Si-mulation eines importierten Statecharts in KIEL durchführen. Der Transitionslabel-
49
5. Implementierung
Statechart(KIEL) XMI-DateiDOM
Abbildung 5.9.: Arbeitsweise des XMI-Exports
Parser wurde mit SableCC erzeugt. Als Eingabe für SableCC dient eine an dieJava-Syntax angelehnte Grammatik (Anhang E.2) von Etienne Gagnon [29]. In Ab-bildung 5.8 ist die Reihenfolge der Arbeitsschritte zur Übersicht visualisiert worden.
Der Export von Statecharts erfolgt ebenfalls über das File-Interface. Die Modulezum Import von Statecharts enthalten die Routinen, die den Export eines State-charts in das gewählte Dateiformat vornehmen. Statecharts sind in der UML Teileiner Klasse oder Methode. Der Export erzeugt daher ein generisches UML-Modellund legt in diesem Modell eine Klasse an. Dieser erzeugten Klasse wird das zuexportierende Statechart zugeordnet. Die XMI-Datei wird mit Methoden des DOMangelegt. Die Arbeitsweise des XMI-Exports (Anhang G.4) ist in Abbildung 5.9dargestellt.
Fazit
Alle in Kapitel 4.3 formulierten Anforderungen an das Checking-Plug-in wurden er-füllt. Es ist leicht erweiterbar, flexibel in der Anwendung und bietet Möglichkeitenzur Überprüfung von Regeln die sowohl mit OCL formuliert, als auch direkt in Javaimplementiert wurden. Durch die Erweiterung um das XMI-Fileinterface ist zudemder Zugriff auf weitere Statecharts ermöglicht worden. Die in KOCL formulierten Re-geln aus Kapitel 4.2 sind im Anhang (Abschnitt F) enthalten. Im folgenden Kapitelwerden die Ergebnisse einer Usability-Analyse vorgestellt.
50
6. Ergebnisse
Zur Beurteilung des entwickelten Checking-Plug-ins wurden verschiedene Untersu-chungen vorgenommen. Als erstes wurden die in Kapitel 4.2 vorgestellten Regeln um-gesetzt, um den Nutzen von KOCL zu beurteilen. Anschließend wurden die erstelltenRegeln zur Beurteilung der Geschwindigkeit des Checking-Plug-ins auf verschiedeneStatecharts angewendet. Zum Abschluss wurde der entwickelte Style-Checker aufBeispiele aus der Industrie angewendet. Im Folgenden werden die gesammelten Er-gebnisse präsentiert.
6.1. KOCL Usability-Analyse
Die Well-formedness-Regeln sind ein bekanntes Beispiel für die Verwendung vonOCL. Daher wurden als erste Anwendung 26 der Well-formedness-Regeln mit KOCLspezifiziert. Einige in der UML formulierten Well-formedness-Regeln wurden nichtumgesetzt, da diese Regeln Eigenschaften von UML-Modellen selbst behandeln unddaher keine Relevanz für Statecharts haben. Tabelle 6.1 listet alle umgesetzten Well-formedness-Regeln und die jeweils benötigte Zeit für deren Umsetzung auf. Durch-schnittlich werden zur Spezifikation einer Regel in KOCL zwei Minuten benötigt.Die benötigte Zeit hängt von der Anzahl der getippten Zeichen ab. Man kann al-so nachvollziehen, dass es also schneller ist mit KOCL zu arbeiten, als eine Regelin Java zu programmieren. Die vorgestellten Regeln zur syntaktischen Robustheitwurden ebenfalls mit KOCL umgesetzt. Die Spezifikation einer solchen Regel hatbis zu elf Minuten gedauert (vergleiche Tabelle 6.2). Die Differenzen bezüglich derDauer hängen direkt von der jeweiligen Komplexität des Problems ab.
Tabelle 6.1.: Übersicht der umgesetzten Well-formedness-Regeln der UML 1.3 und2.0; aufgelistet sind die Hinweise und Namen aus der UML und die zur Spezifikationin KOCL benötigte Zeit
Regel UML 1.3 UML 2.0 Zeit(min:sec)
A composite state can have at most one initialvertex.
CompositeState 1 Region 1 2:15
A composite state can have at most one deep his-tory vertex.
CompositeState 2 Region 2 1:59
A composite state can have at most one shallowhistory vertex.
CompositeState 3 Region 3 2:01
Fortsetzung auf der nächsten Seite
51
6. Ergebnisse
Regel UML 1.3 UML 2.0 Zeit(min:sec)
There have to be at least two composite substatesin a concurrent composite state.
CompositeState 4 State 1 2:02
A concurrent state can only have composite statesas substates.
Composite State 5 - 1:51
The substates of a composite state are part ofonly that composite state.
Composite State 6 - 1:45
A final state cannot have any outgoing transiti-ons.
FinalState 1 FinalState 1 1:40
An initial vertex can have at most one outgoingtransition and no incoming transition.
PseudoState 1 - 2:08
An initial vertex can have at most one outgoingtransition.
- PseudoState 1 1:59
History vertices can have at most one outgoingtransition.
PseudoState 2 PseudoState 2 1:58
A join vertex must have at least two incomingtransitions and exactly one outgoing transition.
PseudoState 3 PseudoState 3 2:02
A fork vertex must have at least two outgoingtransitions and exactly one incoming transition.
PseudoState 4 PseudoState 5 2:01
A junction vertex must have at least one incomingand one outgoing transition.
PseudoState 5 PseudoState 7 2:00
A choice vertex must have at least one incomingand one outgoing transition.
PseudoState 6 PseudoState 8 1:55
A top state is always a composite. StateMachine 2 - 2:15A top state cannot have any containing states. StateMachine 3 - 2:07The top state cannot be the source of a transition Statemachine 4 - 2:07
The value of a bound value must be a positiveinteger, or unlimited.
SynchState 1 - 1:11
All incoming transitions to a SynchState must co-me from the same region and all outgoing tran-sitions from a SynchState must go to the sameregion.
SynchState 2 - 2:21
A fork segment should not have guards or trig-gers.
Transition 1 Transition 1 2:23
A join segment should not have guards or triggers. Transition 2 Transition 2 1:56A fork segment should always target a state. Transition 3 Transition 3 1:53A join segment must always originate from astate.
Transition 4 Transition 4 1:53
Transitions outgoing pseudostates may not havea trigger.
Transition 5 Transition 5 2:13
Join segments should originate from orthogonalstates.
Transition 6 - 2:05
Fork segments should target orthogonal states. Transition 7 - 2:07
52
6.2. Laufzeitanalyse
Tabelle 6.2.: Umgesetzte Regeln der syntaktischen Robustheit mit Hinweistext undbenötigter Zeit zur Spezifikation
Regel Hinweis Zeit(min:sec)
InitialStateCount An ORState or a Region can have at most oneinitial vertex.
2:45
ORStateCount An Orstate should contain at least one state. 2:17RegionStateCount A region should contain at least one state. 2:21TransitionLabels The transition has no label or no trigger. 4:01IsolatedStates The state is isolated. 2:36InterlevelTransitions The source and the target of the transition have
different parent states.4:46
EqualNames All states should have different names. 10:45DefaultFromJunction There should be a default transition from each
connective junction.6:37
Connectivity There is no path from an initial state to this state. 1:45
6.2. Laufzeitanalyse
Damit ein Style-Checker von Entwicklern in der täglichen Arbeit akzeptiert wird,muss solch ein Programm Hinweise auf mögliche Problemstellen im Modell ausrei-chend schnell liefern. Zur Beurteilung der Geschwindigkeit des entwickelten Checking-Plug-Ins und der Regeln wurde daher eine Laufzeitanalyse für Beispiele unterschied-licher Größe durchgeführt. Die zur Laufzeitanalyse verwendeten Beispiele stammenaus der Estbench (Esterel benchmark) Sammlung [15] und der Columbia EsterelCompiler Distribution [20]. Die gewählten Beispiele aus beiden Sammlungen wurdenmit KIELs integrierter Esterel Transformation [76] in equivalente SSMs überführt,bevor das Checking-Plug-In angewendet wurde. Die Analyse wurde auf den nicht-optimierten Varianten der importierten Statecharts ausgeführt, d.h. sie enthalteneine große Anzahl an graphischen Elementen (Zustände, Pseudozustände, Transi-tionen, etc.) – perfekt für eine quantitative Analyse der Laufzeit. Tabelle 6.3 undAbbildung 6.1 zeigen die Ergebnisse der Zeitmessungen. Die Zeiten wurden auf ei-nem PC mit Linux OS, einem 2,6 GHz AMD Athlon 64 Prozessor und 2 GB RAMgemessen.
Die Well-formedness-Regeln überprüfen, wie erwähnt, ob das untersuchte State-chart syntaktisch korrekt gemäß der UML Spezifikation ist. Bis auf das BeispielSTOPWATCH sind alle untersuchten Statecharts gemäß den ausgewerteten Regelnsyntaktisch korrekt. Die für die Regeln der syntaktischen Korrektheit ermitteltenLaufzeiten spiegeln also einzig die Auswertung der Regelmenge auf dem untersuchtenStatechart wieder, da die Nachrichtenerstellung einen deutlich messbaren Anteil ander Laufzeit hätte [85, Seite 62]. Die Laufzeit für die syntaktischen Analysen skaliert,wie in Abbildung 6.1a dargestellt, direkt mit der Anzahl der Graphischen Elementeeines Charts. Die gesammelten Daten lassen den Schluss zu, dass die Laufzeit derAnalysen der syntaktischen Korrektheit in O(n) liegt, mit n der Anzahl graphischer
53
6. Ergebnisse
Tabelle 6.3.: Ergebnisse experimenteller Laufzeitanalysen der syntaktischen Korrekt-heit und Robustheits Regeln; angegeben sind die Anzahl der graphischen Elemente,die Laufzeiten und die Anzahl der erzeugten Warnungen
Modell GraphischeElemente
SyntaktischeKorrektheit
Syntaktische Robustheit
ohneEqualNames
mitEqualNames
Zei
t(m
s)
Zei
t(m
s)
War
nung
en
Zei
t(m
s)
War
nung
en
ABRO 37 23 10 4 37 11STOPWATCH 57 27 11 3 24 6
SCHIZOPHRENIA 42 27 12 8 43 13JACKY1 98 56 25 18 216 45RUNNER 131 69 32 16 343 32REINCARANATION 132 79 34 16 381 34ABCD 750 407 183 134 10387 254GREYCOUNTER 768 396 180 99 9925 211WW 1167 673 274 181 26005 355MEJIA 1317 733 303 169 30325 367TCINT 1614 913 377 206 46587 482ATDS-100 3308 1847 772 432 - 967MCA200 19156 10690 4705 2954 - -
BINTREE-2 25 13 6 0 12 6BINTREE-4 121 65 28 0 168 30BINTREE-6 505 273 116 0 2509 126BINTREE-8 2041 1113 464 0 40988 510BINTREE-10 8185 4455 1882 0 - 2046
QUADTREE-1 21 11 4 1 14 8QUADTREE-2 101 54 21 5 210 40QUADTREE-3 421 230 89 21 3296 168QUADTREE-4 1701 920 365 85 52650 680QUADTREE-5 6821 3668 1445 341 - 2728QUADTREE-6 27285 14833 5860 1381 - -
TOKENRING-3 272 152 65 30 1389 68TOKENRING-10 874 488 210 93 13341 215TOKENRING-50 4314 2401 1047 453 317614 1055TOKENRING-100 8614 4748 2083 903 - -TOKENRING-300 25814 14618 6338 2703 - -
54
6.2. Laufzeitanalyse
20 50 100 200 500 1000 2000 5000 104 2×104
10
100
1000
104
Anzahl Graphischer Elemente
Zei
t(m
s)
(a) Laufzeiten der Analysen der syntaktischen Korrektheit
ohne EqualNames
mit EqualNames
20 50 100 200 500 1000 2000 5000 104 2×104
10
100
1000
104
105
Anzahl Graphischer Elemente
Zei
t(m
s)
(b) Laufzeiten der syntaktischen Robustheitsanalysen
Abbildung 6.1.: Graphische Darstellung der Laufzeiten des entwickelten Style-Checkers im Bezug zur Anzahl der Elemente untersuchter Statecharts
55
6. Ergebnisse
Elemente (Zustände, Pseudozustände, Transitionen, etc.) des untersuchten State-charts.
Im Gegensatz zur Auswertung der syntaktischen Korrektheitsregeln liefern diesyntaktischen Robustheitsregeln für jedes untersuchte Statechart Nachrichten zu-rück, d. h. es werden Verletzungen der vorgestellten Regeln in den betrachtetenStatecharts gefunden. Viele der Nachrichten werden von den Regeln ORStateCountund TransitionenLabels generiert. Die Laufzeiten für die Robustheitsregeln wurdein zwei Kategorien aufgeteilt. Zum Einen, die Anwendung des Checking-Plug-Insmit allen Regeln, und zum Anderen die Anwendung des Plug-Ins ohne die RegelEqualNames. Wie in Abbildung 6.1b dargestellt, liegt die Laufzeit der syntaktischenRobustheitsanalysen ohne EqualNames ebenfalls in O(n), mit n wie oben.
Durch die technischen Beschränkungen der OCL ermittelt die Regel EqualNa-mes für jeden einzelnen Zustand eines Statecharts, ob die Menge aller Zustände desCharts mindestens einen anderen Zustand mit gleichem Namen enthält. Sei n dieAnzahl der Zustände eines untersuchten Charts, dann führt die Anwendung der Re-gel zu n ∗n Vergleichen. Die Laufzeit für die Regel EqualNames liegt also in O(n2).Aufgrund dieser Tatsache wurden die Laufzeiten auf den für diese Laufzeitanaly-se verwendeten Statecharts MCA200, BINTREE-10, QUADTREE-5 und -6 sowieTOKENRING-100 und -300 für die Regel EqualNames nicht gemessen, da diesejeweils mehrere tausend Zustände enthalten (vergleiche Tabelle 6.3).
Es konnte beobachtet werden, dass die Laufzeiten der syntaktischen Robustheits-analyse mit Equalnames auf den Beispielen STOPWATCH und den Statecharts derBINTREE-Reihe kürzer sind, als auf anderen Statecharts mit vergleichbarer An-zahl an graphischen Elementen. Diese Abweichungen sind darin begründet, dass dasVerhältnis Transitionen/Zustände der Statecharts STOPWATCH und BINTREE-2bis -8 größer ist als bei den übrigen Beispielen. Daher muss die Regel EqualNa-mes auf den Statecharts STOPWATCH, BINTREE-2, BINTREE-4, BINTREE-6,BINTREE-8 nicht so oft ausgewertet werden.
6.3. Ein reales Beispiel
In Kooperation mit der Firma b+m Informatik AG (im Folgenden: bmiag) [11]wurde das im Rahmen dieser Arbeit entwickelte Framework zum Style-Checkingauf industriellen Statecharts angewendet; die bmiag verwendet zur Modellierungdas UML-CASE-Werkzeug Rational XDE. Zur Entwicklung von Web-basierten Ap-plikation setzt die bmiag Aktivitäts-, Use-Case-, Klassen- und Prozesssteuerungs-Diagramme ein. Aktivitätsdiagramme beschreiben die mögliche Navigation in einemSystem; Aktivitäten repräsentieren Web-Seiten. Das Verhalten der Web-Seiten wirdmit Statecharts spezifiziert.
Bei der Arbeit mit Statecharts wird in dem Unternehmen ein eigens entwickel-ter, stringenter Style-Guide verwendet. Der aufgestellte Style-Guide lässt nur dieVerwendung der Statechart-Elemente Zustand, initialer Zustand, finaler Zustand,Choice-Zustand und Transition mit Signal, Guard und Action zu. Darüber hinaus
56
6.3. Ein reales Beispiel
Abbildung 6.2.: Ein transformiertes Aktivitätsdiagramm
werden einfache Zustände mit zwei unterschiedlichen Stereotypen (DoActionStateund ActorActionState) weiter unterteilt. Die insgesamt 34 aufgestellten Constraintsschränken die Verwendung dieser Elemente zusätzlich ein.
Von den 34 aufgestellten Constraints schränken zehn die Verknüpfung mit Akti-vitäten ein und wurden nicht berücksichtigt. Die 24 übrigen Constraints befassensich ausschließlich mit den Statechart-Elementen. Die eingeführten Stereotypen vonZuständen sind Gegenstand von fünf Regeln und wurden nicht weiter berücksichtigt.Acht Regeln sind identisch mit in der vorliegenden und Schaefers Arbeit aufgestell-ten Regeln. Die übrigen Regeln des Style-Guides von der bmiag wurden im Rahmendieser Untersuchung mit der hier entwickelten Sprache KOCL spezifiziert, um eineautomatische Analyse der Regeln durchzuführen. Dabei hat sich die Verwendungvon KOCL bewährt. Pro Regel aus dem Style-Guide der bmiag wurden weniger als3 Minuten zur Spezifikation mit KOCL benötigt.
Wie erwähnt, werden Statecharts bei der bmiag zur Verhaltensbeschreibung vonAktivitäten verwendet. Zur Anwendung des entwickelten Statechart Style-Checkerswurden Aktivitätsdiagramme in Statecharts umgewandelt. Im Rahmen der Um-wandlung wurden die Aktivitäten durch hierarchische Zustände ersetzt und das zu-gehörige Statechart wurde als Sub-Statechart des so erzeugten Zustands modelliert.Abbildung 6.2 zeigt stark reduziert den Ausschnitt eines Aktivitätsdiagramms miteingebetteten Statecharts. Signal-Events sind mit S, Methodenaufrufe mit M alsPräfix gekennzeichnet.
In diesem Statechart wurden mit dem in dieser Arbeit entwickelten Style-Checker
57
6. Ergebnisse
Abbildung 6.3.: Verletztes Constraint der bmiag
Abbildung 6.4.: Verletzte Well-formedness-Regel PseudoState 1
Inkonsistenzen sowohl zu dem in dieser Arbeit aufgestellten, als auch zu dem von derbmiag bereitgestellten Style-Guide, aufgezeigt. Aus dem Statechart-Style-Guide derbmiag wurde das Constraint „Als mögliche Zielzustände [von Choice-Zuständen] aus-gehender Transitionen sind derzeit nur DoAction- und ActorActionStates erlaubt“verletzt (vergleiche Abbildung 6.3). Diese Inkonsistenz ist darin begründet, dass einfinaler Zustand kein Actor- oder DoActionState ist. Eine Anpassung des verletztenConstraints, indem man auch finale Zustände als Zielzustände zulässt, würde diesesProblem beseitigen.
In Abbildung 6.4 ist eine Verletzung der Well-formedness-Regel PseudoState 1(vergleiche Tabelle 6.1) dargestellt. Dieser Fehler resultiert aus der durchgeführ-ten Umwandlung von Aktivitätsdiagrammen in Statecharts. In Statecharts dürfeninitiale Zustände nur eine ausgehende Transition besitzen. Demgegenüber dürfenAktivitätsdiagramme auch mehrere ausgehende Transitionen aufweisen.
Die letzte aufgezeigte Inkonsistenz zu dem in dieser und Schaefers Arbeit aufge-stellten Style-Guide ist eine Verletzung der Regel TransitionOverlap [85]. In Abbil-dung 6.5 sind Transitionen mit überlappenden Prädikaten markiert. Die Prädikateder Transitionen überlappen, da für keine der beiden das Komplement der jeweilsanderen modelliert wurde.
Der von der bmiag aufgestellte Style-Guide für die Modellierung schränkt denverfügbaren Funktionsumfang, wie erwähnt, stark ein. Daher werden bereits bei derModellierung viele fehleranfällige Konstruktionen ausgeschlossen. Die Anwendungdes in dieser Arbeit entwickelten Style-Checkers hat nur wenige Inkonsistenzen auf-gedeckt. Diese Inkonsistenzen zeigen jedoch keine Fehler innerhalb des von der bmiag
58
6.3. Ein reales Beispiel
Abbildung 6.5.: Überlappende Transitionen
entwickelten Programms auf, sondern sind als Hinweise auf vermeintlich fehleranfäl-lige Konstruktionen zu verstehen oder sind in der durchgeführten Einbettung vonStatecharts begründet. Modifikationen an den zur Verfügung gestellten Statechartssind daher nicht zwingend notwendig. Die Aufarbeitung aller Hinweise, die durchdie Auswertung von TransitionOverlap erzeugt werden, wirkt beispielsweise demWrite-Things-Once-Prinzip entgegen [85]. Der Entwickler muss also für jeden vomStyle-Checker gelieferten Hinweis mit der Intention des Systems abstimmen, ob eineÄnderung des Modells notwendig ist.
59
7. Zusammenfassung undAusblick
In dieser Arbeit wurde zur Fehlervermeidung in der Softwareentwicklung die An-wendung von Style-Guides auf Statecharts untersucht. Die Anwendung von Style-Guides erfolgt klassischerweise mittels Style-Checkern. Eine Betrachtung verschie-dener Style-Checker zur Durchführung dieser Aufgabe lieferte das Ergebnis, das dieuntersuchten Werkzeuge verschiedene Schwächen aufweisen. Sei es, dass der über-prüfte Regelkatalog entweder einen zu geringen Umfang hat und nicht erweitertwerden kann oder Erweiterungsmöglichkeiten gegeben sind, dafür aber keine seman-tischen Analysen durchgeführt werden können. Daher wurde im Rahmen dieser Di-plomarbeit als erstes ein Style-Guide aufgestellt, der Regeln sowohl die syntaktischeKorrektheit, als auch die syntaktische und semantische Robustheit betreffend ent-hält. Die in den Style-Guide aufgenommenen Regeln wurden verschiedenen Quellenentnommen und in dieser Arbeit anhand einiger Beispiele erläutert.
Die syntaktische Korrektheit betreffende Regeln wurden aufgenommen, da es be-obachtet werden konnte, dass die Überprüfung der syntaktischen Korrektheit beider Arbeit mit UML-Statecharts notwendig ist. Die die syntaktische Korrektheitbetreffenden, aufgenommenen Regeln wurden der UML-Spezifikation entnommen.Verletzungen dieser Regeln zeigen Fehler in Statecharts auf, die eine Simulation desmodellierten Systems verhindern.
Eine Überprüfung der syntaktischen Robustheit von Statecharts liefert im Gegen-satz zur Überprüfung der syntaktischen Korrektheit keine Fehler, die eine Weiter-verarbeitung von Statecharts verhindern. Ein Ziel dieser Regeln ist es, den Spra-chumfang der Statechart-Syntax auf eine Teilmenge einzuschränken, von der manannimmt, dass sie weniger fehleranfällig ist. Darüberhinaus sollen einige der in die-ser Arbeit vorgestellten Regeln das Verständnis eines Statecharts erhöhen und evtlanfallende Wartungsarbeiten erleichtern.
In dieser Arbeit wurde insbesondere der Aspekt der syntaktischen Robustheit ein-gehend betrachtet. Die semantische Robustheit von Statecharts wurde von Schaeferin der engverwandten Diplomarbeit untersucht und entsprechende Regeln wurdendort implementiert [85].
Zur automatischen Überprüfung der Regeln des aufgestellten Style-Guides wurdeim Rahmen dieser Arbeit anschließend ein Framework entwickelt, das die Regeln aufverschiedenen Statechart Dialekten auswerten kann. Diese Checking-Framework istmodular konzipiert, damit es sich einfach erweitern lässt. Dafür wurde eine Werk-zeugkette entwickelt mit der sich Regeln in der OCL spezifizieren lassen. Dies hatden Vorteil, dass weitere Regeln zur Untersuchung der syntaktischen Korrektheit
61
7. Zusammenfassung und Ausblick
und Robustheit ohne Kenntnisse einer Programmiersprache werden können.Die OCL bietet keine Möglichkeit, Nachrichten zu formulieren und zurückzulie-
fern. Daher wurde das textuelle Dateiformat KOCL zur Kombination von Nachrich-ten und OCL-Ausdrücken entwickelt.
Die abschließende usability-Analyse hat gezeigt, dass sich Regeln in dem entwi-ckelten Framework schnell formulieren lassen. Die Analyse der Laufzeiten zeigt, dassder gewählte Ansatz zur Auswertung von OCL für die meisten Regeln eine sehr guteGeschwindigkeit bietet. Die Regel EqualNames ist als einziges nicht effizient mit derderzeitigen OCL-Bibliothek umsetzbar. Eine geeignete Implementierung direkt inJava führt in diesem Fall sicherlich zu besseren Ergebnissen, ist aber für die Zukunftnoch offen. Die Anwendung des entwickelten Frameworks auf einem Beispiel ausindustriellem Umfeld hat Inkonsistenzen zu dem bereitgestellten Style-Guide auf-gezeigt. Ein entsprechend konfigurierter Style-Checker für die modellbasierte Ent-wicklung kann also im Sinne der eingeführten Taxonomie bei der Fehlervermeidunghelfen.
Für die Zukunft ist eine Erweiterung der Regelmenge um weitere Regeln, etwaaus der Literatur, wünschenswert. Unter anderem Scaife et al. [84] haben sieben Kri-terien vorgestellt, anhand derer fehleranfällige Stateflow Modelle identifiziert wer-den können. Der in dieser Arbeit entwickelte Style-Checker bietet alle technischenVoraussetzungen, um diese zu überprüfen. Jedoch gehen alle von Scaife et al. vor-gestellten Kriterien über den Funktionsumfang der OCL heraus. Daher müssen dieentsprechenden Checks direkt in Java programmiert werden und wurden in dieserArbeit nicht berücksichtigt. Drei der Kriterien weisen Ähnlichkeiten zu den vonSchaefer implementierten Regeln TransitionOverlap und RaceCondition auf, so dasseine Implementierung entsprechender Checks keine Schwierigkeiten bereiten sollte.Die vier übrigen Kriterien überprüfen Beziehungen von Statechart-Elementen. DieseBeziehungen sind syntaktischer Natur aber bisher nicht behandelt worden. Eine Im-plementierung entsprechender Java-Klassen zur automatischen Überprüfung dieserKriterien sollte jedoch auch keine Schwierigkeiten verursachen.
62
A. Literaturverzeichnis
[1] IST-2001-33522 OMEGA Correct Development of Real-Time Embedded Sys-tems, 2001. http://www-omega.imag.fr.
[2] André, Charles: SyncCharts: A Visual Representation of Reactive Beha-viors. Technischer Bericht RR 95–52, rev. RR (96–56), I3S, Sophia-Antipolis,France, Rev. April 1996. http://www.i3s.unice.fr/~andre/CAPublis/SYNCCHARTS/SyncCharts.pdf.
[3] André, Charles: Semantics of S.S.M (Safe State Machine). TechnischerBericht, Esterel Technologies, Sophia-Antipolis, France, April 2003. availableat http://www.esterel-technologies.com, in the download section.
[4] ArgoUML: Tigris.org: Open Source Software Engineering Tools. http://argouml.tigris.org/.
[5] Artisan Software: UML Modeling Tools for Real-time Embedded SystemsModeling and Systems Engineering. http://www.artisansw.com/.
[6] “BABES-BOLYAI” University of Cluj-Napoca: Object Constraint Lan-guage Environment. http://lci.cs.ubbcluj.ro/ocle/index.htm.
[7] Barrett, Geoff: Formal Methods Applied to a Floating-Point Number Sys-tem. IEEE Transactions on Software Engineering, 15(5):611–621, 1989.
[8] Beeck, Michael von der: A Comparison of Statecharts Variants. In: Lang-maack, H., W. P. de Roever und J. Vytopil (Herausgeber): Formal Tech-niques in Real-Time and Fault-Tolerant Systems, Band 863 der Reihe LectureNotes in Computer Science, Seiten 128–148. Springer-Verlag, 1994.
[9] Berry, Gérard: The Esterel v5 Language Primer, Version v5 91. Centrede Mathématiques Appliquées Ecole des Mines and INRIA, 06565 Sophia-Antipolis, 2000.
[10] Blair, Michael, Sally Obenski und Paula Bridickas: PATRIOTMISSILE DEFENSE: Software Problem Led to System Failure at Dhahran,Saudi Arabia, Februar 1992. http://161.203.16.4/t2pbat6/145960.pdf.
[11] B+M Informatik AG: B+M Informatik AG Homepage, 2006. http://www.bmiag.de.
63
A. Literaturverzeichnis
[12] Booch, Grady: Object-oriented Analysis and Design with Applications. Ben-jamin Cummings, Redwood City, 2nd Auflage, 1993.
[13] Borland: Borland Homepage. http://www.borland.com.
[14] Bowen, Jonathan: Formal Specification And Documentation Using Z – ACase Study Approach. Thomson Publishing, 1996.
[15] Estbench Esterel Benchmark Suite. http://www1.cs.columbia.edu/~sedwards/software/estbench-1.0.tar.gz.
[16] Collins, B. P., J. E. Nicholls und I. H. Sorensen: Introducing formalmethods: The CICS experience with Z. Technischer Bericht TR12.260, IBM,IBM UK Labs Ltd., Hursley Park, UK, 1987.
[17] Cook, Steve und John Daniels: Designing Object Systems: Object-orientedmodelling with Syntropy. Prentice-Hall, 1994.
[18] Demuth, Birgit, Heinrich Hussmann und Sten Loecher: OCL as aSpecification Language for Business Rules in Database Applications. LectureNotes in Computer Science, 2185:104–117, 2001. http://link.springer-ny.com/link/service/series/0558/papers/2185/21850104.pdf.
[19] Dresden OCL Toolkit, 2006. http://dresden-ocl.sourceforge.net/.
[20] Edwards, Stephen A.: CEC: The Columbia Esterel Compiler. http://www1.cs.columbia.edu/~sedwards/cec/.
[21] EmPowerTec: Oclarity. http://www.empowertec.de/products/rational-rose-ocl.htm.
[22] Esterel Technologies: Esterel Studio User Manual, 5.2 Auflage, Juli 2004.
[23] eWebSimplex: C#/OCL Compiler, 2004. http://www.ewebsimplex.net/csocl/.
[24] Finger, Frank: Java-Implementierung der OCL-Basisbibliothek. TechnischerBericht, Technische Universität Dresden, Fakultät Informatik, Lehrstuhl Soft-waretechnologie, 1999.
[25] Finger, Frank: Design and Implementation of a Modular OCL Compiler.Diploma Thesis, Dresden University of Technology - Department of ComputerScience - Software Engineering Group, März 2000.
[26] Finney, Kate: Mathematical Notation in Formal Specification: Too Difficultfor the Masses? IEEE Transactions on Software Engineering, 22(2):158–159,Februar 1996.
[27] Flanagan, David: Java. in a Nutshell. O’Reilly, 5. Auflage, März 2005.
64
A. Literaturverzeichnis
[28] Ford Motor Company: Structured Analysis Using Matlab/Simulink/-Stateflow Modeling Style Guidelines, 1999. http://vehicle.berkeley.edu/mobies/papers/stylev242.pdf.
[29] Gagnon, Etienne: SableCC: Java parser generator. http://sablecc.org/.
[30] Gamma, Erich, Richard Helm, Ralph Johnson und John Vlissides:Design Patterns. Addison-Wesley, 1995.
[31] Gernert, Christiane: Agiles Projektmanagement. Hanser, 2003.
[32] Hanxleden, Reinhard von, Ritwik Bhattacharya und Kay Kosso-wan: The State Analyzer, Version 0.1. Project Report FT3/AS-1999-002,DaimlerChrysler, Februar 1999.
[33] Hanxleden, Reinhard von, Kay Kossowan und Jörg Donandt: Ro-bustheitskriterien für Statecharts. Project Report FT3/AS-2000-003, Daimler-Chrysler, März 2000.
[34] Harel, David: Statecharts: A Visual Formalism for Complex Systems. Scienceof Computer Programming, 8(3):231–274, Juni 1987.
[35] Harel, David: On visual formalisms. Communications of the ACM,31(5):514–530, 1988.
[36] Harel, David und Michal Politi: Modeling Reactive Systems withStatecharts: The Statemate Approach. McGraw-Hill, New York, 1998.
[37] Hein, Christian, Tom Ritter und Michael Wagner: Open Source Li-brary for OCL, 2005. http://oslo-project.berlios.de/.
[38] Hussmann, Heinrich, Birgit Demuth und Frank Finger: Modular ar-chitecture for a toolset supporting OCL. Lecture Notes in Computer Science,1939:278–293, 2000.
[39] Huuck, Ralf: Sanity Checks for Stateflow Diagrams. In: Edwards, Ste-phen A., Nicolas Halbwachs, Reinhard v. Hanxleden und ThomasStauner (Herausgeber): Synchronous Programming – SYNCHRON’04, Num-mer 04491 in Dagstuhl Seminar Proceedings, Dagstuhl, Germany, 2005. Inter-nationales Begegnungs- und Forschungszentrum (IBFI), Schloss Dagstuhl, Ger-many.
[40] IRISA/CNRS: Unified Modeling Language All pUrposes Transformer, 2004.http://www.irisa.fr/UMLAUT/.
[41] ISO/IEC: Information technology – Z formal specification notation – Syntax,type system and semantics, Juli 2002.
65
A. Literaturverzeichnis
[42] Karlsruhe, Universität von: KeY, 1998. http://key-project.org/.
[43] KIEL Project, The: Project Homepage, 2004. Kiel Integrated Environmentfor Layout.
[44] Kleene, Stephen Cole: Representation of Events in Nerve Nets and FiniteAutomata. In: Shannon, C. E. und J. McCarthy (Herausgeber): AutomataStudies, Seiten 3–41. Princeton University Press, Princeton, New Jersey, 1956.
[45] Kloss, Tobias: Flexibles und Automatisiertes Layout von Statecharts. Stu-dent resarch project, Christian-Albrechts-Universität zu Kiel, Department ofComputer Science, Juli 2003.
[46] Kossowan, Kay: Automatisierte Überprüfung semantischer Modellierungs-richtlinien für Statecharts. Diplomarbeit, Technische Universität Berlin, 2000.
[47] Kühl, Lars: Transformation von Esterel nach Esterel Studio. Diploma the-sis, Christian-Albrechts-Universität zu Kiel, Department of Computer Science,September 2005.
[48] Kyas, Marcel: Object Constraint Language Verification Platform.
[49] Kyas, Marcel, Harald Fecher, Frank S. de Boer, Joost Jacob, Jo-zef Hooman, Mark van der Zwaag, Tamarah Arons und Hillel Kug-ler: Formalizing UML Models and OCL Constraints in PVS. In: ElectronicNotes in Theoretical Computer Science. Elsevier, April 2004.
[50] Ladkin, Peter B.: Causal Reasoning about Aircraft Accidents. In: Koorn-neef, Floor und Meine van der Meulen (Herausgeber): Computer Safe-ty, Reliability and Security, 19th International Conference, SAFECOMP 2000,Rotterdam, The Netherlands, October 24-27, 2000, Band 1943 der Reihe LectureNotes in Computer Science, Seiten 344–360. Springer, 2000.
[51] Lamport, Leslie: LaTEX A Document Preparation System. Adddison-Wesley, 1994.
[52] Lions, Jacques-Louis: Ariane 5: Flight 501 failure – report by the inquiryboard. Press Release 33, Juli 1996. http://www.esa.int/esaCP/Pr_33_1996_p_EN.html.
[53] Löcher, Sten: UML/OCL für die Integritätssicherung in Datenbankanwen-dungen. Diplomarbeit, Technische Universität Dresden, 2001.
[54] MathWorks Automotive Advisory Board (MAAB): Controller Sty-le Guidelines for Production Intent Using MATLAB, Simulink and Stateflow,April 2001. http://www.mathworks.com/industries/auto/maab.html.
66
A. Literaturverzeichnis
[55] Mathworks Inc.: Stateflow and Stateflow Coder for use with Simulink —User’s Guide. Mathworks Inc., 6 Auflage, 2004.
[56] McCulloch, W. S. und W. Pitts: A Logical Calculus of the Ideas Immanentin Nervous Activity. Bulletin of Mathematical Biophysics, 5:115–133, 1943.
[57] Mealy, G. H.: A Method for Synthesizing Sequential Circuits. Bell SystemTechnical Journal, 34:1045–1079, September 1955.
[58] Monninger, Frieder: Eiffel. Objektorientiertes Programmieren in der Pra-xis. Heise Heinz, 1993.
[59] Moore, Edward F.: Gedanken-Experiments on Sequential Machines. In:Shannon, C. E. und J. McCarthy (Herausgeber): Automata Studies, Num-mer 34 in Annals of Mathematical Studies, Seiten 129–153. Princeton UniversityPress, Princeton, NJ, 1956.
[60] Motor Industry Software Reliability Association (MISRA):MISRA-C:2004. Guidelines for the Use of the C Language in Critical Systems.Motor Industry Research Association (MIRA), Nuneaton CV10 0TU, UK, 2004.
[61] Moutos, Miltiadis, Albrecht Korn und Carsten Fisel: Guideline-Checker. Studienarbeit, University of Applied Sciences in Esslingen, Juni 2000.
[62] Mutz, Martin: Ein Regel Checker zur Verbesserung des modellbasierten Soft-wareentwurfs. Toolpräsentation, Technische Universität Braunschweig, 2003.http://www.cs.tu-bs.de/ips/mutz/papers/EKA2003.pdf.
[63] Mutz, Martin: Eine durchgängige modellbasierte Entwurfsmethodik für ein-gebettete Systeme im Automobilbereich. Dissertation, Technische UniversitätBraunschweig, 2005.
[64] Mutz, Martin und Michaela Huhn: Automated Statechart Analysis forUser-defined Design Rules. Technischer Bericht, Technische Universität Braun-schweig, 2003. http://www.cs.tu-bs.de/ips/mutz/papers/TR2003-10.pdf.
[65] Object Management Group: Unified Modeling Lanugage—UML ResourcePage. http://www.uml.org.
[66] Object Management Group: Unified Modeling Language (UML) 1.3 spe-cification, Februar 2000. http://www.omg.org/cgi-bin/apps/doc?formal/00-03-01.pdf.
[67] Object Management Group: OMG Unified Modeling Language Specifica-tion, Version 1.5, März 2003. http://www.omg.org/cgi-bin/doc?formal/03-03-01.
67
A. Literaturverzeichnis
[68] Oxford Univerity Computing Laboratory: Programming ResearchGroup Homepage, 2004. http://web.comlab.ox.ac.uk/oucl/about/prg/.
[69] Paderborn Software Engineering Group, University of: Fujaba,2006. http://www.fujaba.de/.
[70] Pap, Zsigmond, Istvan Majzik und Andras Pataricza: Checking GeneralSafety Criteria on UML Statecharts. Lecture Notes in Computer Science, 2187,2001.
[71] Parnas, David L.: On the Use of Transition Diagrams in the Design of aUser Interface for an Interactive Computer System. In: Proceedings of the 24thNational ACM Conference, Seiten 379–385, 1969.
[72] Parnas, David L.: Some Theorems We Should Prove. In: HUG ’93: Procee-dings of the 6th International Workshop on Higher Order Logic Theorem Pro-ving and its Applications, Seiten 155–162, London, UK, 1994. Springer-Verlag.
[73] Posor, Adrian: Extension of KIEL by Stateflow Charts. Diploma thesis,Christian-Albrechts-Universität zu Kiel, Department of Computer Science, De-zember 2005.
[74] Prochnow, Steffen und Reinhard von Hanxleden: Comfortable Mode-ling of Complex Reactive Systems. In: Proceedings of Design, Automation andTest in Europe (DATE’06), Munich, März 2006.
[75] Prochnow, Steffen, Gunnar Schaefer, Ken Bell und Reinhard vonHanxleden: Analyzing Robustness of UML State Machines. In: Proceedingsof the Workshop on Modeling and Analysis of Real-Time and Embedded Sys-tems (MARTES’06), held in conjunction with the 9th International Conferenceon Model Driven Engineering Languages and Systems, MoDELS/UML 2006,Genua, Oktober 2006.
[76] Prochnow, Steffen, Claus Traulsen und Reinhard von Hanxleden:Synthesizing Safe State Machines from Esterel. In: Proceedings of ACM SIG-PLAN/SIGBED Conference on Languages, Compilers, and Tools for EmbeddedSystems (LCTES’06), Ottawa, Canada, Juni 2006.
[77] Project without a name: PWAN OCL, 1999. http://pwan.sourceforge.net/index.html.
[78] Rabin, M. O. und D. Scott: Finite Automata and their Decision Problems.IBM Journal of Research and Development, 3:114–125, 1959.
[79] Rational Software: Rational Rose Technical Developer. http://www-306.ibm.com/software/awdtools/developer/technical/.
[80] Rhapsody: I-Logix, Inc. http://www.ilogix.com/products/.
68
A. Literaturverzeichnis
[81] Ricardo Company, The: Mint – A Style checker for Simulinkand Stateflow, 2006. http://www.ricardo.com/engineeringservices/controlelectronics.aspx?page=mint.
[82] Richters, Mark: UML-based Specification Environment, 2001. http://www.db.informatik.uni-bremen.de/projects/USE/.
[83] Rumbaugh, James, Michael Blaha und Wiliam Premerlani: Objekt-orientiertes Modellieren und Entwerfen. Hanser Fachbuch, 1993.
[84] Scaife, N., C. Sofronis, P. Caspi, S. Tripakis und F. Maraninchi: De-fining and translating a “safe” subset of Simulink/Stateflow into Lustre. Tech-nischer Bericht 2004-16, Verimag, Centre Équation, 38610 Gières, Juli 2004.http://www-verimag.imag.fr/index.php?page=techrep-list.
[85] Schaefer, Gunnar: Statechart Style Checking – Automated Semantic Robust-ness Analysis of Statecharts. Diploma Thesis, Christian-Albrechts-Universitätzu Kiel, Department of Computer Science, Juni 2006.
[86] Spivey, J. M.: The Z notation: a reference manual. Prentice-Hall, Inc., UpperSaddle River, NJ, USA, 1989.
[87] Stölzel, Mirko, Steffen Zschaler und Leif Geiger: Integrating OCLand Model Transformations in Fujaba. Technischer Bericht, Dresden Universityof Technology, Department of Computer Science, 2006.
[88] Sun Microsystems, Inc.: Code Conventions for the Java Programming Lan-guage, 1997. http://java.sun.com/docs/codeconv/.
[89] The MathWorks Inc.: Stateflow and Stateflow Coder User’s Guide, Ver-sion 6. Natick, MA, September 2005. http://www.mathworks.com/access/helpdesk/help/pdf_doc/stateflow/sf_ug.pdf.
[90] The Object Management Group: UML Homepage.
[91] Warmer, Jos und Anneke Kleppe: OCL Tool for Precise UML Specificati-ons. http://www.klasse.nl/octopus/index.html.
[92] Warmer, Jos B. und Anneke G. Kleppe: The object constraint language:precise modeling with UML. Addison-Wesley, Reading, Massachusetts, 1998.
[93] Zheng, Jiang, Laurie Williams, Nachiappan Nagappan, Will Snipes,John Hudepohl und Mladen Vouk: A Study of Static Analysis for FaultDetection in Software. Technischer Bericht, Department of Computer Science,North Carolina State University, Microsoft Research, Nortel Networks SoftwareDependability Design, 2005.
69
A. Literaturverzeichnis
[94] Zündorf, Albert: Graph Pattern Matching in PROGRES. In: Selected papersfrom the 5th International Workshop on Graph Gramars and Their Applicationto Computer Science, Seiten 454–468, London, UK, 1996. Springer-Verlag.
70
B. Regelprofile
Die auf einem Statechart ausgewerteten Regeln können abhängig vom Dialekt überProfile ausgewählt werden. Diese Profile werden in den Einstellungen von KIELgespeichert. Ein Profil wird geladen, sobald ein Statechart in KIEL geladen wird. Inder visuellen Variante des Programms können die zu überprüfenden Regeln über denentsprechenden Menüpunkt vor dem Vorgang an- und abgewählt werden (VergleicheAbbildung 5.6). Folgende Profile wurden bisher für die Regeln der syntaktischenRobustheit (Kapitel 4.2) angelegt:
Esterel Studio V. 5.01. IsolatedStates
2. EqualNames
3. OrStateCount
4. RegionStateCount
5. DefaultFromJunction
6. TransitionLabels
MatlabStateflow V. 6.11. IsolatedStates
2. EqualNames
3. OrStateCount
4. RegionStateCount
5. DefaultFromJunction
6. TransitionLabels
7. Connectivity
8. InterlevelTransition
9. InitialState
71
B. Regelprofile
ArgoUML V. 0.2.0.x1. IsolatedStates
2. EqualNames
3. OrStateCount
4. RegionStateCount
5. DefaultFromJunction
6. TransitionLabels
7. Connectivity
8. InterlevelTransition
9. InitialState
Für die Überprüfungen aus dem Bereich der syntaktischen Korrektheit wurdenbisher folgende Profile angelegt (Die Regeln bezeichnen die entsprechende KOCL-Spezifikation):
Esterel Studio V. 5.01. UMLCompositeStateRule1
2. UML13CompositeStateRule3
3. UML13FinalStateRule1
4. UML13PseudoStateRule1
5. UML13PseudoStateRule5
6. UML13PseudoStateRule6
7. UMLFinalStateConstraint1
8. UMLPseudostateConstraint1
9. UMLTransitionConstraint5
MatlabStateflow V. 6.11. UML13CompositeStateRule1
2. UML13CompositeStateRule2
3. UML13CompositeStateRule3
4. UML13CompositeStateRule4
72
5. UML13CompositeStateRule5
6. UML13CompositeStateRule6
7. UML13FinalStateRule1
8. UML13PseudoStateRule1
9. UML13PseudoStateRule2
10. UML13PseudoStateRule6
11. UML13SynchStateRule1
12. UML13SynchStateRule2
13. UMLStateMachineRule4
14. UMLFinalStateConstraint1
15. UMLPseudostateConstraint1
16. UMLTransitionConstraint2
17. UMLTransitionConstraint5
ArgoUML V. 0.2.0.x1. UML13CompositeStateRule1
2. UML13CompositeStateRule2
3. UML13CompositeStateRule3
4. UML13CompositeStateRule4
5. UML13CompositeStateRule5
6. UML13CompositeStateRule6
7. UML13FinalStateRule1
8. UML13PseudoStateRule1
9. UML13PseudoStateRule2
10. UML13PseudoStateRule3
11. UML13PseudoStateRule4
12. UML13PseudoStateRule5
73
B. Regelprofile
13. UML13PseudoStateRule6
14. UML13SynchStateRule1
15. UML13SynchStateRule2
16. UMLFinalStateConstraint1
17. UMLPseudostateConstraint1
18. UMLTransitionConstraint1
19. UMLTransitionConstraint2
20. UMLTransitionConstraint3
21. UMLTransitionConstraint4
22. UMLTransitionConstraint5
23. UMLTransitionConstraint6
24. UMLTransitionConstraint7
74
C. Die EBNF von KOCL
In Abbildung C.1 ist die EBNF der KOCL-Grammatik angegeben. Mit KOCL (sie-he Kapitel 5.3.2) werden OCL-Ausdrücke mit Hinweistexten kombiniert. Es gibt dieMöglichkeit mehrere Hinweisetexte in einer Regel zu spezifizieren. Der Kontext desOCL-Ausdrucks wurde erweitert, so dass die spezifizierte OCL-Bedingung auf meh-reren Klassen ausgewertet werden kann. Dadurch wird vermieden, die gleiche Regelfür unterschiedliche Klassen mehrfach spezifizieren zu müssen. Der Umstand, dasseine Regel auf verschiedenen Klassen ausgewertet werden kann, wurde in der Defi-nition der Nachrichtenbehandlung berücksichtigt. Abhängig von der Klasse, auf derdie OCL-Bedingung ausgewertet wird, lässt sich eine der deklarierten Nachrichtenzurückliefern.
75
C. Die EBNF von KOCL
〈booleanops〉 := ‘and’ | ‘or’
〈identifier〉 ::= 〈nondigit〉 (〈digit〉 | 〈nondigit〉)*
〈string〉 ::= ‘"’ (〈digit〉 | 〈nondigit〉)* ‘"’
〈rules〉 ::= 〈rule〉+
〈rule〉 ::= 〈rule-heading〉 ‘{’ 〈error-part〉? 〈declaration-part〉?〈constraint-definition〉 〈conforms-part〉? 〈fails-part〉? ‘}’
〈rule-heading〉 ::= ‘rule’ 〈identifier〉
〈error-part〉 ::= ‘error’ ‘;’
〈declaration-part〉 ::= ‘declarations’ ‘{’ 〈message-definition〉+ ‘}’
〈message-definition〉 ::= 〈identifier〉 〈string〉 ‘;’
〈constraint-definition〉 ::= ‘constraint’ ‘{’ 〈context-part〉 〈constraint-part〉 ‘}’
〈context-part〉 ::= ‘context’ 〈identifiert-list〉 ‘;’
〈identifier-expression〉 ::= ‘not’* 〈identifier〉
〈identifier-list〉 ::= 〈identifier-expression〉 〈identifier-list-tail〉?
〈identifier-list-tail〉 ::= 〈booleanops〉 〈identifier-list〉
〈constraint-part〉 ::= 〈string〉 ‘;’
〈conforms-part〉 ::= ‘conforms’ ‘{’ 〈eval-statement-part〉? ‘}’
〈fails-part〉 ::= ‘fails’ ‘{’ 〈eval-statement-part〉? ‘}’
〈eval-statement-part〉 ::= 〈if-then-statement〉| 〈if-then-else-statement〉| 〈expression-semicolon〉
〈if-then-statement〉 ::= ‘if’ 〈expression〉 ‘then’ 〈identifier〉 ‘;’
〈if-then-else-statement〉 :== 〈if-then-statement〉 ‘else’ 〈identifier〉 ‘;’
〈expression〉 ::= 〈identifier〉| ‘{’ 〈identifier〉 〈booleanops〉 〈expression〉 ‘}’
Abbildung C.1.: Die KOCL-Grammatik in EBNF.
76
D. Das Metamodell
Abbildung D.1 enthält eine vereinfachte Version des Metamodells der in KIEL ver-wendeten Statechart Datenstruktur. Die vollständige Version des Metamodells wirdals XMI-Datei an das im Regel-Generator verwendete Dresden OCL Toolkit über-geben (siehe Kapitel 5.3.2). Das Metamodell wurde mit ArgoUML angelegt und ausdem Werkzeug ebenfalls als XMI-Datei exportiert. Alle KOCL-Regeln wurden überdiesem Metamodell definiert.
77
D. Das Metamodell
GraphicalObject
equals(o : Object) : boolean
numberCountid : Stringnumber
Node
getName() : String
parent : CompositeStatename : StringisConnectedToInitial : booleanoutgoingTransitions : TransitionincomingTransitions : Transition
Edge
source : Nodetarget : Node
State
getInternalTransition() : Transition
internalTransition : Transitionvariables : Variableconstants : ConstantincomingTransitions : Transition
CompositeState
subnodes : Node
Transition
getLabel() : TransitionLabelgetPriority() : Priority
label : TransitionLabelpriority : Priority
TransitionLabelPriority
value : int
ANDState ORState
FinalANDState FinalORState
Region
Variable
isInitialized() : booleantoDeclaration() : StringtoExpString() : StringtoString() : String
idCounteridname : String
StateChart
getModelSource() : StringgetModelVersion() : StringgetObjectFromID(id : String) : GraphicalObjectgetRootNode() : StategetAllObjects() :
isChanged : booleanmodelSource : StringmodelVersion : StringrootNode : CompositeStateinputVariables : VariableoutputVariables : Variablevariables : Variableconstants : intoutputEvents : EventinputEvents : EventlocalEvents : Event
ActionsEvent Constant
PseudoState
Junction Choice DynamicChoice ForkConnector Join
HistorySuspendInitialStateSynchState
bound : int
SimpleState
FinalSimpleState
CompoundLabel
text : Stringtrigger : DelayExpressioncondition : BooleanExpression
StringLabel
labelString : String
InitialArc
DelayExpression
toString : String
BooleanExpression
toString : String
chart
0..*
list
0..*
parentStates{ordered}
0..*childStates{ordered}
DeepHistory
Abbildung D.1.: Das vereinfachte Metamodell der topologischen Statechart Daten-struktur.
78
E.
Par
sers
pez
ifika
tion
enim
Sab
leCC
For
mat
Die
ser
Abs
chni
tten
thäl
tdi
eG
ram
mat
iken
für
KO
CL
und
den
Tran
sition
slab
el-P
arse
r.B
eide
Gra
mm
atik
ensi
ndim
Sabl
eCC
-For
mat
ange
gebe
n.D
erm
itSa
bleC
Cer
-ze
ugte
KO
CL-
Par
ser,
Abs
chni
ttE
.1,is
tB
esta
ndte
ilde
sR
egel
-Gen
erat
ors.
Für
den
Tran
siti
onsl
abel
-Par
ser
(sie
heK
apit
el5.
3.2)
,Abs
chni
ttE
.2,w
urde
eine
Java
1.4
Gra
m-
mat
ikvo
nE
tien
neG
rago
n[2
9]m
odifi
zier
t.
E.1
.K
OCL-G
ram
mat
ik
Packag
ekiel.util.
checkingHelp
ers.synrule;
/*****
************
************
**************
************
************
***Helper
s*
********
************
************
************
************
*************/
Helper
sall=
[0..
127];
digit
=[’0’
..’9
’];
nondig
it=[’_’
+[’#’
+[[’a’
..’z’]
+[’
A’..
’Z’]]]
];10
cr=13
;lf
=10
;
c_char
=[all
-[’
"’+[10+13
]]];
c_char
_sequence=
c_char+;
tab=
9;not_cr
_lf=[[all
-cr]-lf];
20and=’a
nd’;
or=’o
r’;
not_star
=[all-
’*’];
not_star
_slash
=[
not_star
-’/’];
/*******
************
************
************
************
**************
*Tokens
*********
************
************
************
************
************
*/30
Tokens
semicolo
n=’;’;
endofrul
edot
=’.’;
l_scope
=’{’;
r_scope
=’}’;
l_brace
=’(’;
r_brace
=’)’;
rule
=’rule’;
error=
’error’;
40declarat
ions
=’decla
rations’;
constrai
nt=’constra
int’;
context
=’context’;
conforms
=’conforms’
;fails=
’fails’;
if=’i
f’;
then
=’then’;
else
=’else’;
this
=’this’;
not=’n
ot’;
50booleano
ps=(and
|or);
identifi
er=nondigit
(nondigit
|digit)*;
string
=’"’c_char_s
equence?
’"’;
blank=
(cr|lf
|cr
lf|tab
|’’)+;
comment
=’/*’
not_st
ar*’*’+(
not_star_sla
shnot_star
*’*’+)*
’/’;
/*******
************
************
************
************
**************
60*Ignore
dTokens
*********
************
************
************
************
************
*/Ignored
Tokens
blank,
comment;
/*******
************
************
************
************
**************
*Produc
tions*
********
************
************
************
************
************
*/70
Producti
ons
//More
than
oneru
leperfile
rules= P.rule+;
//rule
syntax
rule
=rule_h
eading
l_scop
e
79
E. Parserspezifikationen im SableCC Format
80is_error
_part?
decl_par
t?constrai
nt_definitio
n_part
conforms
_return_part
?fails_re
turn_part?
r_scope;
//Head
oftherule
rule_hea
ding
=T.rule
identifier;
90//
opti
onal
declarat
ionof
erro
rtype
is_error
_part=
T.error
semicolon;
//mess
agedeclarat
ions
decl_par
t=
declarat
ions
l_scope
message_defi
nition+r_sc
ope;
message_
definition
=identifi
erstring
semicolon;
100
//cons
traint
declar
ation
constrai
nt_definitio
n_part
=constrai
ntl_scopeco
ntext_part
constraint_p
artr_scope;
context_
part
=context
identifier_l
istsemicolo
n;identifi
er_expr=
T.not*
identifier;
identifi
er_list=
identi
fier_exprid
entifier_list_
tail?;
110
identifi
er_list_tail
=booleano
psidentifi
er_list;
//{sin
gle}
T.not*
identifier
|//
{bra
ce}l_brace
identifier_l
istbooleano
psidentifier
_listr_brac
e;
constrai
nt_part=
string
semicolon;
//mess
agereturn
part
ifthech
artconforms
tothecons
traint
120
conforms
_return_part
=conforms
l_scopeeval
_statement_p
art?
r_scop
e;
//mess
agereturn
part
ifthech
artdoes
notconformto
theconstrai
ntfails_re
turn_part=
failsl_
scopeeval_s
tatement_par
t?r_scope;
//opti
onal
ifthen
else
statem
entwithin
both
messagere
turn
parts
eval_sta
tement_part
={onlyif}
if_then_stat
ement
130
|{else}
if_then_else
_statement
|{direc
t}expression
semicolon;
if_then_
statement=
ifexpr
ession
then
identifier
semicolon;
if_then_
else_stateme
nt=
if_then_
statementel
seidentifier
semicolon;
expressi
on=
{simple}
identifier
|l_brac
eidentifier
booleanops
expression
r_brace;
E.2
.Ja
vaTra
nsitio
nLab
els-
Gra
mm
atik
/***
******
******
******
******
******
**This
file
ispart
ofJ11.
**Seeth
efile
"J11-L
ICENSE"for
Copyrightin
formationan
dthe*
*terms
andconditio
nsforcopyin
g,distribu
tion
and*
*modifi
cation
ofJ1
1.*
****
******
******
******
******
******/
/*****
************
**************
************
************
************
*Etienn
eGagnon:I
have
builtth
isgrammar
basedto
the
*10
*inform
ationon
page
s19-23of
the"Inner
ClassesSpecif
ication*
*docume
nt.*
*Sunha
snotreleas
edyetan
official
gramma
rforJava
1.1andI*
*suspec
tthat
thede
finition
ofJava
identi
fiershaschan
gedand*
*is
diff
erentfrom
theJava
1.02
version.
This
intuition
comes*
*from
noticing
the
deprecation
ofCharacter.
isJavaLetter
()and*
*isJava
LetterOrDigi
t()methods.
**In
this
grammar,
Ihave
notch
angedthele
xer.
SoIscan
**Java
1.02
identifi
ers.
This
istheonly
documented
defi
nition
**of
iden
tifiersthat
Ihave.If
somebody
hasbetter
info
rmation,
*20
*please
letme
know
.*
* *Change
sincluding
innerclass
updates,
more
robust
semi
colon
*proces
sing
andstri
ctfp
keywor
dby:
*Thomas
Leonhardt
* ********
************
************
************
**************
*********/
Packag
ekiel.fileI
nterface.JavaT
ransitionLab
els;
30/*****
************
**************
************
************
************
*Helper
s*
********
************
************
************
**************
*********/
Helper
s
unicod
e_input_char
acter=[0..
0xffff];
ht=0x
0009;
lf=0x
000a;
ff=0x
000c;
40cr
=0x
000d;
sp=’
’;
line_t
erminator=
lf|cr
|cr
lf;
input_
character=
[unicode_inp
ut_character
-[cr+lf]]
;
not_st
ar=[input_c
haracter
-’*’]
|line_t
erminator;
not_st
ar_not_slash
=[input_cha
racter
-[’
*’+’/’]]|
line_termina
tor;
unicod
e_letter
=50
[0x0041.
.0x005a]
|[0x0061..0x007
a]|[0x00a
a..0x00aa]
|[0x00b
5..0x00b5]
|[0x00ba.
.0x00ba]
|[0x00c0..0x00d
6]|[0x00d
8..0x00f6]
|
80
E.2. JavaTransitionLabels-Grammatik
[0x00f
8..0x01f5]
|[0x01fa.
.0x0217]
|[0x0250..0x0
2a8]
|[0x02b
0..0x02b8]
|[0x02b
b..0x02c1]
|[0x02d0.
.0x02d1]
|[0x02e0..0x0
2e4]
|[0x037
a..0x037a]
|[0x038
6..0x0386]
|[0x0388.
.0x038a]
|[0x038c..0x0
38c]
|[0x038
e..0x03a1]
|[0x03a
3..0x03ce]
|60
[0x03d0.
.0x03d6]
|[0x03da..0x0
3da]
|[0x03d
c..0x03dc]
|[0x03d
e..0x03de]
|[0x03e0.
.0x03e0]
|[0x03e2..0x0
3f3]
|[0x040
1..0x040c]
|[0x040
e..0x044f]
|[0x0451.
.0x045c]
|[0x045e..0x0
481]
|[0x049
0..0x04c4]
|[0x04c
7..0x04c8]
|[0x04cb.
.0x04cc]
|[0x04d0..0x0
4eb]
|[0x04e
e..0x04f5]
|[0x04f
8..0x04f9]
|[0x0531.
.0x0556]
|[0x0559..0x0
559]
|[0x056
1..0x0587]
|[0x05d
0..0x05ea]
|70
[0x05f0.
.0x05f2]
|[0x0621..0x0
63a]
|[0x064
0..0x064a]
|[0x067
1..0x06b7]
|[0x06ba.
.0x06be]
|[0x06c0..0x0
6ce]
|[0x06d
0..0x06d3]
|[0x06d
5..0x06d5]
|[0x06e5.
.0x06e6]
|[0x0905..0x0
939]
|[0x093
d..0x093d]
|[0x095
8..0x0961]
|[0x0985.
.0x098c]
|[0x098f..0x0
990]
|[0x099
3..0x09a8]
|[0x09a
a..0x09b0]
|[0x09b2.
.0x09b2]
|[0x09b6..0x0
9b9]
|[0x09d
c..0x09dd]
|[0x09d
f..0x09e1]
|80
[0x09f0.
.0x09f1]
|[0x0a05..0x0
a0a]
|[0x0a0
f..0x0a10]
|[0x0a1
3..0x0a28]
|[0x0a2a.
.0x0a30]
|[0x0a32..0x0
a33]
|[0x0a3
5..0x0a36]
|[0x0a3
8..0x0a39]
|[0x0a59.
.0x0a5c]
|[0x0a5e..0x0
a5e]
|[0x0a7
2..0x0a74]
|[0x0a8
5..0x0a8b]
|[0x0a8d.
.0x0a8d]
|[0x0a8f..0x0
a91]
|[0x0a9
3..0x0aa8]
|[0x0aa
a..0x0ab0]
|[0x0ab2.
.0x0ab3]
|[0x0ab5..0x0
ab9]
|[0x0ab
d..0x0abd]
|[0x0ae
0..0x0ae0]
|90
[0x0b05.
.0x0b0c]
|[0x0b0f..0x0
b10]
|[0x0b1
3..0x0b28]
|[0x0b2
a..0x0b30]
|[0x0b32.
.0x0b33]
|[0x0b36..0x0
b39]
|[0x0b3
d..0x0b3d]
|[0x0b5
c..0x0b5d]
|[0x0b5f.
.0x0b61]
|[0x0b85..0x0
b8a]
|[0x0b8
e..0x0b90]
|[0x0b9
2..0x0b95]
|[0x0b99.
.0x0b9a]
|[0x0b9c..0x0
b9c]
|[0x0b9
e..0x0b9f]
|[0x0ba
3..0x0ba4]
|[0x0ba8.
.0x0baa]
|[0x0bae..0x0
bb5]
|[0x0bb
7..0x0bb9]
|[0x0c0
5..0x0c0c]
|10
0[0x0c0e.
.0x0c10]
|[0x0c12..0x0
c28]
|[0x0c2
a..0x0c33]
|[0x0c3
5..0x0c39]
|[0x0c60.
.0x0c61]
|[0x0c85..0x0
c8c]
|[0x0c8
e..0x0c90]
|[0x0c9
2..0x0ca8]
|[0x0caa.
.0x0cb3]
|[0x0cb5..0x0
cb9]
|[0x0cd
e..0x0cde]
|[0x0ce
0..0x0ce1]
|[0x0d05.
.0x0d0c]
|[0x0d0e..0x0
d10]
|[0x0d1
2..0x0d28]
|[0x0d2
a..0x0d39]
|[0x0d60.
.0x0d61]
|[0x0e01..0x0
e2e]
|[0x0e3
0..0x0e30]
|[0x0e3
2..0x0e33]
|11
0[0x0e40.
.0x0e46]
|[0x0e81..0x0
e82]
|[0x0e8
4..0x0e84]
|[0x0e8
7..0x0e88]
|[0x0e8a.
.0x0e8a]
|[0x0e8d..0x0
e8d]
|[0x0e9
4..0x0e97]
|
[0x0e99.
.0x0e9f]
|[0x0ea
1..0x0ea3]
|[0x0ea5..0x0
ea5]
|[0x0ea
7..0x0ea7]
|[0x0eaa.
.0x0eab]
|[0x0ea
d..0x0eae]
|[0x0eb0..0x0
eb0]
|[0x0eb
2..0x0eb3]
|[0x0ebd.
.0x0ebd]
|[0x0ec
0..0x0ec4]
|[0x0ec6..0x0
ec6]
|[0x0ed
c..0x0edd]
|[0x0f40.
.0x0f47]
|12
0[0x0f4
9..0x0f69]
|[0x10a0..0x1
0c5]
|[0x10d
0..0x10f6]
|[0x1100.
.0x1159]
|[0x115
f..0x11a2]
|[0x11a8..0x1
1f9]
|[0x1e0
0..0x1e9b]
|[0x1ea0.
.0x1ef9]
|[0x1f0
0..0x1f15]
|[0x1f18..0x1
f1d]
|[0x1f2
0..0x1f45]
|[0x1f48.
.0x1f4d]
|[0x1f5
0..0x1f57]
|[0x1f59..0x1
f59]
|[0x1f5
b..0x1f5b]
|[0x1f5d.
.0x1f5d]
|[0x1f5
f..0x1f7d]
|[0x1f80..0x1
fb4]
|[0x1fb
6..0x1fbc]
|[0x1fbe.
.0x1fbe]
|13
0[0x1fc
2..0x1fc4]
|[0x1fc6..0x1
fcc]
|[0x1fd
0..0x1fd3]
|[0x1fd6.
.0x1fdb]
|[0x1fe
0..0x1fec]
|[0x1ff2..0x1
ff4]
|[0x1ff
6..0x1ffc]
|[0x207f.
.0x207f]
|[0x210
2..0x2102]
|[0x2107..0x2
107]
|[0x210
a..0x2113]
|[0x2115.
.0x2115]
|[0x211
8..0x211d]
|[0x2124..0x2
124]
|[0x212
6..0x2126]
|[0x2128.
.0x2128]
|[0x212
a..0x2131]
|[0x2133..0x2
138]
|[0x300
5..0x3005]
|[0x3031.
.0x3035]
|14
0[0x304
1..0x3094]
|[0x309b..0x3
09e]
|[0x30a
1..0x30fa]
|[0x30fc.
.0x30fe]
|[0x310
5..0x312c]
|[0x3131..0x3
18e]
|[0x4e0
0..0x9fa5]
|[0xac00.
.0xd7a3]
|[0xf90
0..0xfa2d]
|[0xfb00..0xf
b06]
|[0xfb1
3..0xfb17]
|[0xfb1f.
.0xfb28]
|[0xfb2
a..0xfb36]
|[0xfb38..0xf
b3c]
|[0xfb3
e..0xfb3e]
|[0xfb40.
.0xfb41]
|[0xfb4
3..0xfb44]
|[0xfb46..0xf
bb1]
|[0xfbd
3..0xfd3d]
|[0xfd50.
.0xfd8f]
|15
0[0xfd9
2..0xfdc7]
|[0xfdf0..0xf
dfb]
|[0xfe7
0..0xfe72]
|[0xfe74.
.0xfe74]
|[0xfe7
6..0xfefc]
|[0xff21..0xf
f3a]
|[0xff4
1..0xff5a]
|[0xff66.
.0xffbe]
|[0xffc
2..0xffc7]
|[0xffca..0xf
fcf]
|[0xffd
2..0xffd7]
|[0xffda.
.0xffdc];
unicode_
digit=
[0x003
0..0x0039]
|[0x0660..0x0
669]
|[0x06f
0..0x06f9]
|[0x0966.
.0x096f]
|16
0[0x09e
6..0x09ef]
|[0x0a66..0x0
a6f]
|[0x0ae
6..0x0aef]
|[0x0b66.
.0x0b6f]
|[0x0be
7..0x0bef]
|[0x0c66..0x0
c6f]
|[0x0ce
6..0x0cef]
|[0x0d66.
.0x0d6f]
|[0x0e5
0..0x0e59]
|[0x0ed0..0x0
ed9]
|[0x0f2
0..0x0f29]
|[0xff10.
.0xff19];
java_let
ter=unicod
e_letter
|’$’|’_’;
java_let
ter_or_digit
=unicode_
letter
|unic
ode_digit|
’$’|’_’;
170
non_zero
_digit
=[’
1’..’9’];
digit=
[’0’..’9’];
hex_digi
t=[’0’..’9
’]|[’a’..
’f’]
|[’A’..
’F’];
81
E. Parserspezifikationen im SableCC Format
octal_
digit=[’0’
..’7’];
zero_t
o_three=[’
0’..’3’];
decima
l_numeral=
’0’|non_ze
ro_digit
digi
t*;
hex_nu
meral=’0’
(’x’
|’X’)
hex_digit+;
octal_
numeral=’0
’octal_digi
t+;
180
intege
r_type_suffi
x=’l’|’L
’;
expone
nt_part=(’
e’|’E’)
(’+’
|’-’)?di
git+;
float_
type_suffix
=’f’|’F’
|’d’|’D’;
single
_character
=[input_chara
cter
-[’’’
+’\’]];
octal_
escape
=’\’
(octal_digit
octal_digit?
|zero_to_
threeoctal_
digit
octal_
digit);
escape
_sequence=
’\b’
|’\t’
|’\n’
|’\f’
|’\r’
|’\
"’|’\’’’’
|19
0’\\’
|octal_escape
;string
_character
=[input_chara
cter
-[’"’
+’\’]]|es
cape_sequenc
e;
/*******
************
************
************
************
************
*Toke
ns*
******
************
************
**************
************
***********/
Tokens white_
space=(sp
|ht
|ff
|li
ne_terminato
r)*;
200
tradit
ional_commen
t=’/*’
not_
star+’*’+
(not_star_not_
slashnot_st
ar*
’*’+)*
’/’;
docume
ntation_comm
ent=’/**’’*
’*(not_sta
r_not_slash
not_star*
’*’+)*
’/’;
/*******
************
************
************
************
************
********
********
*****
*Here,
wetake
into
accountthe
possibilily
that
theline
terminator
mightbe
missing*
210
*at
the
endof
the
last
line
ofafile.This
isimprecis
ein
theJava
Language
**Specif
ication,
beca
useit
isno
tclearif
aline
termin
ator
should
beaddedto
the*
*last
line,or
not.
"javac",
thereference
compiler,acce
ptsand
end-of-l
ine-comment,
**even
iftheline
terminator
ismissingfrom
thelast
line.
* ********
************
************
************
************
************
********
220
********
****/
end_of
_line_commen
t=’//’
inpu
t_character*
line_termina
tor?;
true
=’true’;
false
=’false’;
null
=’null’;
l_pare
nthese
=’(’;
r_pare
nthese
=’)’;
230
l_brac
e=’{’;
r_brac
e=’}’;
l_brac
ket=’[’;
r_brac
ket=’]’;
semico
lon=’;’;
comma
=’,’;
dot=
’.’;
assign
=’=’;
lt=’<
’;24
0gt
=’>
’;comple
ment
=’!’;
bit_co
mplement
=’~
’;questi
on=’?’;
colon
=’:’;
eq=’=
=’;
lteq
=’<=’;
gteq
=’>=’;
neq=
’!=’;
250
and=
’&&’;
or=’|
|’;
plus_p
lus=’++’;
minus_
minus=’--’
;
plus
=’+’;
minus
=’-’;
star
=’*’;
div=
’/’;
bit_an
d=’&’;
260
bit_or
=’|’;
bit_xo
r=’^’;
mod=
’%’;
shift_
left
=’<<’;
signed
_shift_right
=’>>’;
unsign
ed_shift_rig
ht=’>>>’;
plus_a
ssign=’+=’
;minus_
assign
=’-=’
;star_a
ssign=’*=’
;27
0div_as
sign
=’/=’;
bit_an
d_assign
=’&
=’;
bit_or
_assign=’|
=’;
bit_xo
r_assign
=’^
=’;
mod_as
sign
=’%=’;
shift_
left_assign
=’<<=’;
signed
_shift_right
_assign=’>
>=’;
unsign
ed_shift_rig
ht_assign=
’>>>=’;
decima
l_integer_li
teral=deci
mal_numeralin
teger_type_s
uffix?;
280
hex_in
teger_litera
l=hex_nume
ralinteger_ty
pe_suffix?;
octal_
integer_lite
ral=octal_
numeralintege
r_type_suffi
x?;
floati
ng_point_lit
eral
=digit+
’.’digit*
exponent_part?
float_type_s
uffix?
|’.’digi
t+exponent_p
art?
float_
type_suffix?
|digit+
exponent_part
float_type_s
uffix?
|digit+
exponent_part?
float_type
_suffix;
charac
ter_literal
=’’’(singl
e_character|
escape_seque
nce)
’’’;
290
string
_literal
=’"
’string_cha
racter*’"’;
identi
fier
=java_l
etterjava_l
etter_or_dig
it*;
82
E.2. JavaTransitionLabels-Grammatik
/*****
************
************
**************
************
************
*Ignore
dTokens
*********
************
************
************
************
***********/
Ignore
dTokens
white_sp
ace,
traditio
nal_comment,
300
document
ation_commen
t,end_of_l
ine_comment;
/*****
************
************
**************
************
************
*Produc
tions*
********
************
************
************
************
***********/
Produc
tions
/*****
************
************
**************
************
************
*19.2
Grammarfrom
§2.3:
TheSy
ntacticGram
mar§2.3
310
******
************
************
**************
************
************
/
goal
=transiti
on_label;
transi
tion_label
=trigger?
guard?
effe
ct?;
trigge
r=simple_n
ame;
320
guard
=l_bracket
expression
r_bracket;
effect
= {single}
divst
atement_expres
sion
|
{multipl
e}divexpr
ession_state
ment+;
330
/*****
************
************
**************
************
************
*19.3
Grammarfrom
§3:
Lexical
Structure§
3******
************
************
**************
************
************
/
litera
l=
{integer
_literal}
integer_
literal|
{floatin
g_point_lite
ral}
floating
_point_liter
al|
340
{boolean
_literal}
boolean_
literal|
{charact
er_literal}
characte
r_literal|
{string_
literal}
string_l
iteral
|
350
{null_li
teral}
null_lit
eral;
/*******
************
************
************
************
*************
19.4
Grammarfrom
§4:
Types,
Values,andVa
riables§4
type
={primiti
ve_type}
primit
ive_type
|
360
{referen
ce_type}
refere
nce_type;
primitiv
e_type
={numeric
_type}
numeri
c_type
|
{boolean
}boolea
n;
370
numeric_
type
={integra
l_type}
integr
al_type|
{floatin
g_point_type
}floati
ng_point_typ
e;
integral
_type=
{byte} byte
|38
0{short}
short
|
{int} int|
{long} long
|
390
{char} char;
floating
_point_type
={float}
float
|
{double}
double
;
400
referenc
e_type
={class_o
r_interface_
type}
class_
or_interface
_type|
{array_t
ype}
array_
type;
class_or
_interface_t
ype=
name;
410
class_ty
pe=
class_or
_interface_t
ype;
83
E. Parserspezifikationen im SableCC Format
interf
ace_type
=class_
or_interface
_type;
array_
type
={primi
tive_type}
primitiv
e_type
dims
|
420
{name} name
dims
;
******
**************
************
************
************
************
/
/*****
**************
************
************
************
************
*19.5
Grammarfrom
§6:
Names§
6******
**************
************
************
************
************
/
430
name
={simpl
e_name}
simple_n
ame|
{quali
fied_name}
qualifie
d_name;
simple_n
ame=
identi
fier;
440
qualifie
d_name
=name
dotidentifier
;
/*******
************
************
************
************
************
*19.11Gr
ammarfrom
§14:Blocks
andStatemen
ts§14
********
************
************
************
************
************
/
expressi
on_statement
=statem
ent_expressi
onsemicolon;
450
statemen
t_expression
={assig
nment}
assignme
nt|
{singl
e_identifier
}simple_n
ame;
/*******
************
************
************
************
************
*46
019.12Gr
ammarfrom
§15:Expres
sions§15
********
************
************
************
************
************
/
primary
={prima
ry_no_new_ar
ray}
primar
y_no_new_arr
ay;
primary_
no_new_array
={liter
al}
litera
l|
470
{l_par
enthese}
l_parent
hese
expressi
onr_parent
hese
;
postfi
x_expression
={prima
ry}
primary
|
{name}
480
name
|
{post_
increment_ex
pression}
post_inc
rement_expre
ssion|
{post_
decrement_ex
pression}
post_dec
rement_expre
ssion;
post_i
ncrement_expre
ssion=
postfi
x_expression
plus_plus;
490
post_d
ecrement_expre
ssion=
postfi
x_expression
minus_minus;
unary_
expression
={pre_i
ncrement_exp
ression}
pre_incr
ement_expres
sion
|
{pre_d
ecrement_exp
ression}
pre_decr
ement_expres
sion
|50
0{plus} plus
unary_expression
|
{minus
}minusun
ary_expressi
on|
{unary
_expression_
not_plus_min
us}
unary_ex
pression_not
_plus_minus;
510
pre_in
crement_expres
sion
=plus_p
lusunary_ex
pression;
pre_de
crement_expres
sion
=minus_
minusunary_
expression;
unary_
expression_not
_plus_minus
={postf
ix_expressio
n}postfix_
expression
|
520
{bit_c
omplement}
bit_comp
lement
unary_
expression
|
{compl
ement}
compleme
ntunary_expr
ession;
multip
licative_expre
ssion=
{unary
_expression}
unary_ex
pression
|53
0
84
E.2. JavaTransitionLabels-Grammatik
{star} multipli
cative_expre
ssionstar
unary_expressi
on|
{div} multipli
cative_expre
ssiondivun
ary_expressi
on|
{mod} multipli
cative_expre
ssionmodun
ary_expressi
on;
540
additive
_expression
={multipl
icative_expr
ession}
multipli
cative_expre
ssion|
{plus} additive
_expression
plus
multip
licative_exp
ression|
{minus}
additive
_expression
minusmultip
licative_exp
ression;
550
shift_ex
pression
={additiv
e_expression
}additive
_expression
|
{shift_l
eft}
shift_ex
pression
shift_left
addi
tive_express
ion|
{signed_
shift_right}
shift_ex
pression
signed_shift_r
ight
additive
_expression
|
560
{unsigne
d_shift_righ
t}shift_
expression
unsigned_shift
_right
additi
ve_expressio
n;
relation
al_expressio
n=
{shift_e
xpression}
shift_
expression
|
{lt}relati
onal_expressio
nlt
shift_
expression
|
570
{gt}relati
onal_expressio
ngt
shift_
expression
|
{lteq} relati
onal_expressio
nlteq
shif
t_expression
|
{gteq} relati
onal_expressio
ngteq
shif
t_expression
;
equality
_expression
=58
0{relatio
nal_expressi
on}
relati
onal_expressio
n|
{eq}equali
ty_expression
eqrelation
al_expressio
n|
{neq} equali
ty_expression
neqrelation
al_expressio
n;
and_expr
ession
=59
0{equalit
y_expression
}
equali
ty_expressio
n|
{and_e
xpression}
and_ex
pression
bit_
andequality
_expression;
exclusiv
e_or_express
ion=
{and_e
xpression}
and_ex
pression
|
600
{exclu
sive_or_expres
sion}
exclus
ive_or_expre
ssionbit_xor
and_expressi
on;
inclusiv
e_or_express
ion=
{exclu
sive_or_expres
sion}
exclus
ive_or_expre
ssion|
{inclu
sive_or_expres
sion}
inclus
ive_or_expre
ssionbit_or
exclusive_or
_expression;
610
conditio
nal_and_expr
ession
={inclu
sive_or_expres
sion}
inclus
ive_or_expre
ssion|
{condi
tional_and_exp
ression}
condit
ional_and_ex
pression
and
inclusive_or
_expression;
conditio
nal_or_expre
ssion=
{condi
tional_and_exp
ression}
condit
ional_and_ex
pression
|62
0{condi
tional_or_expr
ession}
condit
ional_or_exp
ressionor
conditional_an
d_expression
;
conditio
nal_expressi
on=
{condi
tional_or_expr
ession}
condit
ional_or_exp
ression|
{questio
n}condit
ional_or_exp
ressionquesti
onexpressi
oncolon
630
conditio
nal_expressi
on;
assignme
nt_expressio
n=
{condi
tional_express
ion}
condit
ional_expres
sion
|
{assignm
ent}
assign
ment;
assignme
nt=
640
left_han
d_side
assi
gnment_opera
torassignme
nt_expression;
left_han
d_side
={name} name;
assignme
nt_operator
={assign}
assign
|
650
{star_as
sign}
85
E. Parserspezifikationen im SableCC Format
star_ass
ign|
{div_a
ssign}
div_assi
gn|
{mod_a
ssign}
mod_assi
gn|
{plus_
assign}
660
plus_ass
ign|
{minus
_assign}
minus_as
sign
|
{shift
_left_assign
}shift_le
ft_assign|
{signe
d_shift_righ
t_assign}
signed_s
hift_right_a
ssign|
670
{unsig
ned_shift_ri
ght_assign}
unsigned
_shift_right
_assign|
{bit_a
nd_assign}
bit_and_
assign
|
{bit_x
or_assign}
bit_xor_
assign
|
680
{bit_or_
assign}
bit_or_a
ssign;
expres
sion
=assignme
nt_expressio
n;
consta
nt_expressio
n=
expressi
on;
690
/*****
************
**************
************
************
************
*Litera
ls******
************
**************
************
************
************
/
boolea
n_literal=
{true}
true
|{false}
false;
null_l
iteral
=70
0null;
intege
r_literal=
{decimal
}decimal_in
teger_litera
l|
{hex}he
x_integer_li
teral|
{octal}
octal_intege
r_literal;
86
F.
KO
CL-S
pez
ifika
tion
en
Imfo
lgen
den
sind
die
KO
CL-
Spez
ifika
tion
enal
ler
um-
gese
tzte
nR
egel
nan
gege
ben.
Die
seR
egel
nw
erde
nim
Bui
ld-P
roze
ssvo
nK
IEL
auto
mat
isch
inJa
va-K
lass
enüb
erse
tzt.
F.1
.W
ell-fo
rmed
ness
-Reg
eln
F.1
.1.
UM
L1.
3
rule
UML13Composite
StateRule1
{error;
declarat
ions
{message
"Acomposite
statecanha
veat
most
oneinitial
vertex.";
} constrai
nt{
context
ORStateor
Region;
"self.su
bnodes->sele
ct(v
|v.oc
lIsTypeOf(In
itialState))->
size
<=1";
10} fails{
message;
}} rule
UML13Composite
StateRule2
{error;
20declarat
ions
{message
"Acomposite
statecanha
veat
most
onedeep
hist
oryvertex."
;} constrai
nt{
context
ORStateor
Region;
"self.su
bnodes->sele
ct(v
|v.oc
lIsTypeOf(De
epHistory))-
>size<=
1";
} fails
{30
message;
}
} rule
UML13CompositeSt
ateRule3
{error;
declar
ations
{message
"Acomposit
estatecan
have
atmost
oneshallow
historyvert
ex.";
}40
constr
aint
{context
ORStateor
Region;
"self.su
bnodes->sele
ct(v
|v.oc
lIsTypeOf(Hi
story))->siz
e<=
1";
} fails
{message;
}}
50rule
UML13CompositeSt
ateRule4
{error;
declar
ations
{message
"There
have
tobe
atle
asttwocompos
itesubstate
sin
aconc
urrent
compos
itestate
.";
} constr
aint
{context
ANDState;
"subnode
s->select(v
|v.oclIsT
ypeOf(Region))
->size
>=2"
;60
} fails
{message;
}} rule
UML13CompositeSt
ateRule5
{error;
declar
ations
{70
message
"Aconcurre
ntstatecan
only
have
compositestat
esas
substa
tes.";
} constr
aint
{context
ANDState;
"subnode
s->forAll(s
|(s.oclIsTy
peOf(Region)
))";
} fails
{message;
80}
} rule
UML13Composite
StateRule6
{
87
F. KOCL-Spezifikationen
error;
declarat
ions
{messag
e"The
substa
tesof
acomp
ositestate
arepart
ofonly
that
compositestat
e.";
90} constrai
nt{
contex
tRegion
orORState;
"subno
des->forAll(
s|s.parent.id
=self.id)";
} fails{
messag
e;}
100
} rule
UML13FinalStat
eRule1
{error;
declarat
ions
{messag
e"A
finalst
atecannot
have
anyoutg
oing
transiti
ons";
} constrai
nt{
110
contex
tFinalSimpl
eState
orFina
lANDStateor
FinalORSta
te;
"outgo
ingTransitio
ns->size
=0"
;} fails{
messag
e;}
} rule
UML13PseudoSta
teRule1{
120
error;
declarat
ions
{messag
e"Aninitia
lvertex
can
have
atmost
oneoutgoing
transition
andno
inco
ming
transi
tion.";
} constrai
nt{
contex
tInitialSta
te;
"(outg
oingTransiti
ons->size<=
1)and(incom
ingTransitio
ns->size
=0)";
}13
0fails{
messag
e;}
} rule
UML13PseudoSta
teRule2{
140
error;
declarat
ions
{messag
e"History
vertices
canha
veat
most
oneoutgoing
transition."
;}
constrai
nt{
contex
tHistoryor
DeepHistory;
"outgo
ingTransitio
ns->size
<=1";
}
150
fails{
messag
e;}
} rule
UML13PseudoSta
teRule3{
error;
declarat
ions
{16
0messag
e"A
join
vertex
must
have
atleast
twoincoming
transitions
andexactly
oneoutgoing
transi
tion.";
} constrai
nt{
contex
tJoin;
"(inco
mingTransiti
ons->size>=
2)and(out
goingTransitio
ns->size
=1)";
} fails{
messag
e;17
0}
} rule
UML13PseudoSta
teRule4{
error;
declarat
ions
{messag
e"A
fork
vertex
must
have
atleast
twooutgoing
transitions
andexactly
oneincoming
transi
tion.";
}
180
constrai
nt{
contex
tForkConnec
tor;
"(inco
mingTransiti
ons->size=
1)and(outgo
ingTransitio
ns->size
>=2)";
} fails{
messag
e;}
}
190
rule
UML13PseudoSta
teRule5{
error;
declarat
ions
{messag
e"A
junction
vertex
must
have
atle
astoneincomi
ngandone
outgoing
tran
sition.";
} constrai
nt{
contex
tJunction;
200
"(inco
mingTransiti
ons->size>=
1)and(outgo
ingTransitio
ns->size
>=1)";
}
88
F.1. Well-formedness-Regeln
fails{
message;
}} rule
UML13PseudoSta
teRule6{
210
error;
declarat
ions
{message
"Achoice
vertex
must
have
atleast
oneincoming
andoneoutg
oing
transiti
on.";
} constrai
nt{
context
Choice;
"(incomi
ngTransition
s->size>=
1)and(outgo
ingTransitio
ns->size
>=1)
";}
220
fails{
message;
}} rule
UML13StateMach
ineRule2
{
error;
declarat
ions
{23
0message
"Atopstate
isalways
acomposite.";
} constrai
nt{
context
StateChart;
"self.ro
otNode.oclIs
KindOf(Compo
siteState)";
} fails{
message;
240
}
} rule
UML13StateMach
ineRule3
{
error;
declarat
ions
{message
"Atopstate
cannot
have
anycontaini
ngstates."
;}
250
constrai
nt{
context
StateChart;
"self.ro
otNode.paren
tStates->siz
e=0";
} fails{
message;
}}
260
rule
UMLStateMachineR
ule4
{
error;
declar
ations
{message
"The
topst
atecannot
bethesource
ofatransiti
on.";
} constr
aint
{27
0context
StateChart;
"self.ro
otNode.outgo
ingTransitio
ns->size=0";
} fails
{message;
}}
280
rule
UML13SynchStateR
ule1
{
error;
declar
ations
{message
"The
value
ofthebound
attributemu
stbe
aposi
tive
integer,
orunlimite
d.";
}
constr
aint
{context
SynchState;
"bound>0
";29
0} fails
{message;
}} rule
UML13SynchStateR
ule2
{
300
error;
declar
ations
{message
"All
incomi
ngtransition
sto
aSynchS
tate
must
come
from
the
same
region
andall
outgoing
transition
sfrom
aSync
hState
must
goto
thesa
meregion.";
} constr
aint
{context
SynchState;
"(incomi
ngTransition
s->forAll(t1
,t2|t1.sou
rce.parent
=t2.source.pa
rent))
and
(outgoing
Transitions-
>forAll(t1,t
2|t1.targe
t.parent
=t2
.target.pare
nt))";
}
310
fails
{message;
}}
89
F. KOCL-Spezifikationen
F.1
.2.
UM
L2.
0
rule
UMLPseudostate
Constraint1
{error;
declarat
ions
{messag
e"Aninitia
lvertex
can
have
atmost
oneoutgoing
transition
.";
} constrai
nt{
context
InitialState
;10
"self.ou
tgoingTransi
tions->size
<=1";
} fails{
messag
e;}
} rule
UMLTransitionC
onstraint1
{20
error;
declarat
ions
{messag
e"A
fork
segmentmust
nothave
guards
ortriggers
.";
} constrai
nt{
contex
tTransition
;"(sour
ce.oclIsType
Of(ForkConnect
or)andself
.label.oclIs
TypeOf(Compo
undLabel))
implies((
self.l
abel.oclAsTy
pe(CompoundL
abel).trigger.
toString
=’’)and(sel
f.label.oclA
sType(
Compou
ndLabel).con
dition.toStr
ing=’’))";
}30
fails{
messag
e;}
} rule
UMLTransitionC
onstraint2
{
error;
declarat
ions
{40
messag
e"A
join
segmentmust
nothave
guards
ortriggers
.";
} constrai
nt{
contex
tTransition
;"(targ
et.oclIsType
Of(Join)
and
self.label.o
clIsTypeOf(C
ompoundLabel
))implies((
self.label.
oclAsT
ype(Compound
Label).trigg
er.toString=
’’)and(sel
f.label.oclA
sType(Compou
ndLabel).
condit
ion.toString
=’’))";
} fails{
messag
e;50
}}
rule
UMLTransitionC
onstraint3
{
error;
declarat
ions
{messag
e"A
fork
segmentmust
always
target
astate.";
}
60constrai
nt{
context
Transition;
"source.
oclIsTypeOf(
ForkConnecto
r)impliesta
rget.oclIsTy
peOf(State)"
;} fails{
message;
}}
70rule
UMLTransitionC
onstraint4
{
error;
declarat
ions
{message
"Ajoin
segm
entmust
alwa
ysoriginat
efrom
astat
e.";
} constrai
nt{
context
Transition;
80"target.
oclIsTypeOf(
Join)implie
ssource.ocl
IsTypeOf(State
)";
} fails{
message;
}} rule
UMLTransitionC
onstraint5
{90
error;
declarat
ions
{message
"Transitions
outgoing
pseudostates
maynothave
atrigger.";
} constrai
nt{
context
Transition;
"source.
oclIsKindOf(
PseudoState)
impliesif
(label.oclIs
TypeOf(StringL
abel))
then
(label.
oclAsTyp
e(StringLabe
l).labelStri
ng=’’)else
(label.ocl
AsType(Compo
undLabel).trig
ger=’’)
endif";
}10
0fails{
message;
}} rule
UMLTransitionC
onstraint6
{
error;
110
declarat
ions
{
90
F.1. Well-formedness-Regeln
message
"Joinsegmen
tsshould
originatefrom
orthogonal
states.";
} constrai
nt{
context
Transition;
"target.
oclIsTypeOf(
Join)implie
starget.par
ent.parent.o
clIsTypeOf(AND
State)";
} fails{
120
message;
}} rule
UMLTransitionC
onstraint7
{error;
declarat
ions
{message
"Forksegmen
tsshould
target
orthogon
alstates."
;}
130
constrai
nt{
context
Transition;
"source.
oclIsTypeOf(
ForkConnecto
r)impliesta
rget.parent.
parent.oclIs
TypeOf(ANDSt
ate)";
} fails{
message;
}}
91
F. KOCL-Spezifikationen
F.2
.Rob
usth
eits
rege
ln
rule
InitialStateCo
unt{
declarat
ions
{failor
"Anorstatesh
ould
contai
nexactlyon
einitialvert
ex.";
failregi
on"A
region
should
cont
ainexactly
oneinitialve
rtex.";
} constrai
nt{
contex
tRegion
orORState;
10"subnode
s->select(oc
lIsTypeOf(In
itialState))
->size
=1";
} fails{ if
ORSt
atethen
failor;
else
failregi
on;
}
20} rule
ORStateCount_1
{declarat
ions{
messag
e"AnOrstat
eshould
cont
ainat
least
onestate.";
} constrai
nt{
contex
tORState;
30"self.
subnodes->si
ze>0";
} fails{
messag
e;}
} rule
RegionStateCou
nt_1
{declarat
ions{
40messag
e"The
region
contains
nostates.";
} constrai
nt{
contex
tRegion;
"self.
subnodes->si
ze>0";
} fails{
messag
e;50
}} rule
ORStateCount
{declarat
ions{
failme
ssage"AnOr
stateshould
containat
leasttwostat
es.";
} constrai
nt{
context
ORState;
60"subnode
s->select(oc
lIsKindOf(Si
mpleState)
oroclIsKindO
f(ANDState)
oroclIsKindO
f(ORState
))->size
>=2";
}
fails{failme
ssage;
}
} rule
MiracleState
{70
declarat
ions
{message
"The
state
hasno
incomi
ngtransition
.";
} constrai
nt{
contex
tSimpleStat
eandnotIn
itialState
andnotDeepHi
storyandno
tHistory;
"not
(parentStates-
>size=0)
impliesincomi
ngTransition
s->size>0"
;}
80fails{messag
e;}
} rule
TransitionLabe
ls{
declarat
ions
{message
"The
transi
tion
hasno
labelor
noTr
igger.";
}90
constrai
nt{
contex
tTransition
;"(not
(self.source
.oclIsKindOf(P
seudoState))
)impliesif
(label.ocl
IsTypeOf(Strin
gLabel))
then
(label.oclAsType
(StringLabel
).labelStrin
g<>
’’)el
se(label.ocl
AsType(Compo
undLabel).
text
<>’’)endif";
} fails{
message;
}}
100
rule
IsolatedStates
{declarat
ions
{message
"Eitherthe
stateis
isolated
orone
ofitschil
dren
isente
redby
anin
terlevel
transiti
on.";
} constrai
nt{
context
Node
andno
tRegion;
"(parent
States->size
=0)
or((
incomingTransi
tions->size
+outgoingTr
ansitions->s
ize)
>0)
";}
110
92
F.2. Robustheitsregeln
fails{
message;
}} rule
InterlevelTran
sitions{
declarat
ions
{12
0failsm
essage
"The
transition
isinterlevel."
;} constrai
nt{
contex
tTransition
;"self.
target.paren
t.id
=self.s
ource.parent
.id";
} fails{
failsm
essage;
}}
130
rule
Connectivity
{
declarat
ions
{message
"The
node
isnoton
apa
thfrom
anin
itialstate.
";} constrai
nt{
context
Stateandno
tRegion;
140
"(self.i
ncomingTrans
itions->size
>0)
implie
sself.isCon
nectedToInitia
l";
} fails{
message;
}} rule
EqualNames{
150
declarat
ions
{message
"Another
stat
ehasthesa
mename.";
} constrai
nt{
context
Stateandno
tRegion;
"(self.c
hart.list->s
elect(s|
s.oc
lIsKindOf(No
de)))->selec
t(s|s.oclAsT
ype(Node).na
me=self.
name)->s
ize<=
1";
} fails{
160
message;
}} rule
DefaultFromJun
ction{
declarat
ions
{message
"There
should
beadefaul
ttransition
from
each
connective
junction.";
}
170
constr
aint
{contex
tChoice;
"self.
outgoingTransi
tions->selec
t(t|if(t.lab
el.oclIsType
Of(StringLab
el))
then
t.label.
oclAsTyp
e(StringLabe
l).labelStri
ng=’’
else
t.label.oclA
sType(Compou
ndLabel).tex
t=’’
endif)->
size
=1";
} fails
{message;
}}
93
G. Java Code
In diesem Abschnitt wird der Quellcode des in Kapitel 5.3 beschriebenen Checking-Plug-Ins präsentiert. Abschnitt G.1 enthält den entwickelten XMI-Konverter. Dieserkonvertiert das mit ArgoUML angelegt Metamodell so, dass es vom Dresden OCLToolkit eingelesen werden kann. Anschließend, im Abschnitt G.2, ist der Quellco-de des Regel-Generators enthalten. Dieser erzeugt aus KOCL-Spezifikation unterVerwendung des Dresden OCL Toolkits Java-Klassen für das Checking-Plug-In. DerQuellcode des Checking-Plug-Ins ist in Abschnitt G.3 enthalten. Abschließend (Ab-schnitt G.4) wird der Quellcode des entwickelten XMI-Fileinterfaces präsentiert.Abbildung G.1 zeigt die Struktur des Checking-Plug-Ins.
<<interface>>
IStateChartVisitor
BaseCheck StateChartCheckerBase CheckerOutputGui MyCellRenderer
StateChartDepthFirstAdapter
Abbildung G.1.: Übersicht über die Abhängigkeiten des Checking-Plug-Ins.
95
G. Java Code
G.1
.X
MI-K
onve
rter
G.1
.1.
XM
ICon
vert
er.jav
a
packag
ekiel.util.ch
eckingHelper
s.XMIConvert
er;
import
org.xml.sax.
XMLReader;
import
org.xml.sax.
helpers.Defa
ultHandler;
/** *<p>D
escription:
ThexmiConve
rter
classis
themain
classof
theto
ol*used
forbackport
ingXMImeta
data
filesge
nerated
*by
argoUML0.20
totheformat
generatedby
argoUML0.
0.7.
10*This
ismandator
ydueto
limi
tationsof
theused
vers
ion
*of
theDresdenOC
LToolkit.
Itcanproces
stheolder
versiononly
.*It
uses
theXMIS
axConverter
toperformth
econversion
.</p>
*<p>C
opyright:(c
)2006</p>
*<p>C
ompany:Uni
Kiel</p>
*@aut
hor<a
href="
mailto:kbe@i
nformatik.un
i-kiel.de">K
enBell</a>
*@ver
sion
$Revisio
n:1.3$la
stmodified
$Date:
2006/1
0/31
09:37:53
$*/ public
finalclass
XMIConverter
{
20/** *Theco
nstructorof
theclass.
Itis
privat
eto
prevent
instantation
.* */ privat
eXMIConvert
er()
{
}
30/** *Thefi
eldcontaini
ngtheoutput
file.
*/ privat
estatic
Stri
ngoutput;
/** *Intern
almethod,th
atloadsth
exmimeta
modell
file
toan
instance
of*XMISax
Converter.
*@param
inputThena
meof
thein
putfile.
40*@retur
nTrue,if
noerroroccu
red.
*/ privat
estatic
bool
eanconvertF
ile(finalSt
ring
input)
{
boolean
result
=true
;
try{ DefaultH
andler
hand
ler=newXMIS
axConverter(
output);
50XMLReade
rparser
=(XMLReader)(C
lass.forName
(
XMISaxCo
nverter.DEFA
ULT_PARSER_N
AME).newInst
ance());
parser.s
etFeature("h
ttp://xml.or
g/sax/featur
es/validatio
n",
false);
parser.s
etFeature("h
ttp://xml.or
g/sax/featur
es/namespace
s",
false);
parser.s
etFeature(
"http://
apache.org/x
ml/features/
validation/s
chema",
false);
60parser.s
etFeature(
"http:
//apache.org
/xml/feature
s/validation
/"+"sch
ema-full-che
cking",fals
e);
parser.s
etContentHan
dler(handler
);parser.s
etErrorHandl
er(handler);
parser.p
arse(input);
}catch
(Exception
e){
e.printS
tackTrace();
70result
=false;
} return
result;
} /** *Thema
inmethod
ofthetool.
*It
needstwoargu
ments.
Thefi
rstargument
hasto
beth
einputfile
.80
*These
cond
argume
ntis
thename
oftheoutp
utfile.
*@param
args
Thein
putparamete
rs.
*/ public
static
void
main(final
String[]
args)
{
if(arg
s.length
!=2)
{System.o
ut.println(
"\nKIEL
xmi-file
conv
erter.\n"
+"Used
forconverti
ngxmi-files
generatedby
"+"argoU
MLv.
0.2.0\
n"90
+"into
theformat
readable
byth
eDresdenOC
L"
+"Toolk
itv.
1.3.\n
\n"
+"Usage
:xmiConvert
er<Inputfile
><Outputfil
e>\n");
System.e
xit(1);
} output
=args[1];
if(con
vertFile(arg
s[0]))
{System.o
ut.println(a
rgs[0]
+"
convertedsu
ccessful.");
100
}else
{
96
G.1. XMI-Konverter
System
.out.println(a
rgs[0]
+"
notconverte
d."
+"See
output
formo
reinformatio
n.");
}
}
}
97
G. Java Code
G.1
.2.
XM
ISax
Con
vert
er.jav
a
packag
ekiel.util.ch
eckingHelper
s.XMIConvert
er;
import
java.io.File
;import
java.io.File
NotFoundExce
ption;
import
java.io.File
OutputStream
;import
java.io.IOEx
ception;
import
javax.xml.pa
rsers.Docume
ntBuilder;
import
javax.xml.pa
rsers.Docume
ntBuilderFac
tory;
10import
javax.xml.pa
rsers.Parser
Configuratio
nException;
import
org.apache.x
ml.serialize
.OutputForma
t;import
org.apache.x
ml.serialize
.XMLSerializ
er;
import
org.w3c.dom.
Attr;
import
org.w3c.dom.
Document;
import
org.w3c.dom.
Element;
import
org.w3c.dom.
Node;
import
org.xml.sax.
Attributes;
import
org.xml.sax.
helpers.Defa
ultHandler;
20
/** *<p>D
escription:
Thetranslat
orclass.
Ituses
aSaxPar
serto
trav
erse
the
*XML
tree.</p>
*<p>C
opyright:(c
)2006</p>
*<p>C
ompany:Uni
Kiel</p>
*@aut
hor<a
href="
mailto:kbe@i
nformatik.un
i-kiel.de">K
enBell</a>
*@ver
sion
$Revisio
n:1.4$la
stmodified
$Date:
2006/1
0/31
09:37:54
$*/
30public
classXMISax
Converterex
tendsDefaul
tHandler
{
/**De
faultparser
name.*/
public
static
fina
lString
DEFAULT_
PARSER_NAME
="org.apach
e.xerces.par
sers.SAXParser
";
/**
40*Thena
meof
thefi
leto
write
thechanges
to.
*/ privat
eString
outp
utfile;
/** *TheXM
LDocumentth
atgets
crea
ted.
*/ privat
eDocument
output;
/**
50*Thecu
rrentnode.
*/ privat
eNode
curren
t;
/** *Intern
ally
used
field.
Needed
incertainsi
tuations
todecide
ifa
node
*hasto
behandled
ornot.
*/ private
booleanhand
leElement=
true;
60/** *Intern
ally
used.
*/ private
booleanisTy
peElement=
false;
/** *Intern
ally
used
fieldto
deno
teif
thecurr
entnode
isamultiplici
ty*node.
*/ private
booleanisMu
ltiplicity
=false;
70/** *Counte
rforthehe
ader
nodes.
*/ private
intheaderNr
=0;
/** *Theco
nstructorof
theclass.
*Initia
lizesaDocu
mentBuilder
andcreates
theoutput
document.
*@param
oThename
oftheoutp
utfile.
80*/ public
XMISaxConverte
r(finalStri
ngo)
{super();
this.out
putfile=o;
current
=null;
Document
BuilderFacto
rydbf=Do
cumentBuilderF
actory.newIn
stance();
output
=null;
Document
Builderdb;
90try{ db
=db
f.newDocumen
tBuilder();
output
=db.newDocu
ment();
}catch
(ParserConfi
gurationExce
ptione1){
//TODO
Auto-generat
edcatchbl
ock
e1.pri
ntStackTrace()
;}
}
100
/** *Intern
ally
used
method
toremo
veastring
from
aname
ofanode.
*@param
name
Thest
ring,where
thepart
isremovedfrom
.*@param
toRemove
Thepart
tobe
removed.
*@retur
nTheinput
string
wher
ethepart
wasremovedfr
om.
*/ private
static
String
removeFrom
Name(final
String
name,
final
String
toRemo
ve){
intinde
x=name.ind
exOf(toRemov
e);
110
if(ind
ex>-1){
98
G.1. XMI-Konverter
return
name.substri
ng(0,index)
+name
.substring(ind
ex+toRemo
ve.length())
;}else
{return
name;
}} /** *This
method
transf
orms
aname
ofthecurr
entlyhandled
node
tothe
old
120
*format
.*@param
rawThere
adname
ofth
enode.
*@retur
nThetransf
ormednode
name.
*/ private
static
String
createVali
dNodeName(fi
nalString
raw)
{
String
nodeName
=ra
w;
nodeName
=removeFr
omName(nodeN
ame,
"UML:");
nodeName
=removeFr
omName(nodeN
ame,
"Namespa
ce.");
130
nodeName
=removeFr
omName(nodeN
ame,
"Classif
ier.");
nodeName
=removeFr
omName(nodeN
ame,
"Behavio
ralFeature."
);nodeName
=removeFr
omName(nodeN
ame,
"Structu
ralFeature."
);nodeName
=removeFr
omName(nodeN
ame,
"Paramet
er.");
nodeName
=removeFr
omName(nodeN
ame,
"Associa
tion.");
nodeName
=removeFr
omName(nodeN
ame,
"Associa
tionEnd.");
if(nod
eName.equals
IgnoreCase("
generalization
.child")){
nodeNa
me="subtype
";}
140
if(nod
eName.equals
IgnoreCase("
generalization
.parent"))
{nodeNa
me="superty
pe";
} if(nod
eName.equals
("participan
t"))
{nodeNa
me="type";
} return
nodeName;
}15
0
/** *Messag
ehandlerfo
rprocessing
instruncti
ons.
*Writes
thetarget
anddata
totheprompt.
*@param
target
Ast
ring.
*@param
data
Adata
string.
*/ public
finalvoid
processingInst
ruction(fina
lString
targ
et,
final
String
data)
{16
0System.o
ut.println(t
arget+"**
"+data);
} /** *Messag
ehandlerfo
rthestartD
ocumenteven
t.*/ public
finalvoid
startDocument(
){
System.o
ut.println("
");
}
170
/**
*Inte
rnally
used
method
forco
rrecttransf
ormation
ofthemultipli
city
*tag.
*@par
amrawThera
wstring
ofthenode.
*@par
amattrsThe
list
ofattr
ibutes
ofth
enode.
*/ private
void
handle
Multiplicity
(final
String
raw,
final
Attributes
attrs)
{String
nodename
=createValidNod
eName(raw);
if(nod
ename.indexO
f("Range")
!=-1){
180
String
endval
=at
trs.getValue
("upper");
if(Int
eger.parseIn
t(endval)==
-1){
endval
="*";
} curren
t.appendChil
d(output.cre
ateTextNode(
attrs.ge
tValue("lowe
r")+".."
+endval));
}19
0} /** *Meth
odto
create
aType
Elem
ent.
*@par
amrawThest
ring
ofthe
handlednode
.*@par
amattrsThe
list
ofthe
attributes
ofthenode.
*/ private
void
handle
TypeElement(
finalString
raw,
finalAt
tributes
attrs)
{Elemen
tnewEle
=ou
tput.createE
lement("XMI.
reference");
200
newEle
.setAttribut
e("target",at
trs.getValue
("xmi.idref"
));
curren
t.appendChil
d(newEle);
} /** *Add
anewelemen
tto
thedocu
ment.
*@par
amrawThest
ring
ofthe
currentnode
.*@par
amattrsThe
list
ofthe
attributes.
*/ private
void
create
NewElement(f
inal
String
raw,
finalAt
tributes
attr
s){
210
Elemen
tnewEle
=nu
ll;
if(isT
ypeElement
||(attrs.get
Index("xmi.i
dref")
>-1))
{handle
TypeElement(
raw,
attrs);
return
;} if
(isM
ultiplicity)
{handle
Multiplicity
(raw,attrs)
;22
0return
;}
newEle
=output.cre
ateElement(c
reateValidNode
Name(raw));
if(cur
rent
==null
){
output
.appendChild
(newEle);
curren
t=newEle;
}else
{curren
t.appendChil
d(newEle);
230
curren
t=newEle;
99
G. Java Code
} if(isT
ypeElement){
return;
} isTypeEl
ement=newE
le.getNodeNa
me().equalsI
gnoreCase("typ
e");
isMultip
licity
=newE
le.getNodeNa
me().indexOf
("multiplici
ty")
!=-1;
240
if(isT
ypeElement
||isMultiplici
ty){
}else
{
//no
subnodes
for
thefirstXM
Inode
if(new
Ele.getNodeN
ame().equals
IgnoreCase("xm
i"))
{return
;}
250
//XMI
metamodelin
formationha
veto
bepara
meterised
if(new
Ele.getNodeN
ame().equals
IgnoreCase("XM
I.metamodel"
)){
for(i
ntindex=0;
index<attr
s.getLength(
);index++)
{newEle
.setAttribut
e(attrs.getQ
Name(index),
attrs.ge
tValue(index
));
} return
;}
260
for(int
index=0;
index<attr
s.getLength(
);index++)
{
//only
addxmi.id
asattribute.
//all
others
become
children
if(att
rs.getQName(
index).toLow
erCase().ind
exOf(
"xmi.id"
)>-1){
Attr
a=output.cre
ateAttribute
("XMI.id");
a.setN
odeValue(att
rs.getValue(
index));
newEle
.setAttribut
eNode(a);
270
}else
{ //all
attributes
except
"name",
gettheirva
lues
aspara
msElemen
tchild;
if(att
rs.getQName(
index).equal
sIgnoreCase(
"ordering"))
{child=
output.creat
eElement("is
Ordered");
}else
{child=
output.creat
eElement(att
rs.getQName(
index));
} newEle
.appendChild
(child);
280
if(chi
ld.getNodeNa
me().equalsI
gnoreCase("n
ame"))
{
child.ap
pendChild(ou
tput.createT
extNode(
attrs.ge
tValue(index
)));
}else
{if
(child
.getNodeName
().equalsIgn
oreCase("isO
rdered")){
/* *-th
evalueis
setto
falsepe
rdefault.
*/ if(att
rs.getValue(
index).equals(
"ordered"))
{29
0child.se
tAttribute("
XMI.value",
"true");
}else
{child.
setAttribute
("XMI.value",
"false");
}}else
{child.se
tAttribute("
XMI.value",
attrs.
getValue(ind
ex));
}}
300
}
} if(cur
rent.getNode
Name().equal
sIgnoreCase(
"AssociationEn
d")
&&(att
rs.getIndex(
"name")==
-1))
{Elemen
tnamechild
=output.creat
eElement("na
me");
curren
t.appendChil
d(namechild);
}
310
}
} /** *Start
anewelemen
taccording
totheparame
nters.
*@param
uriTheur
iof
thenode
.*@param
local.
*@param
rawThest
ring
represen
tation
ofth
enode.
320
*@param
attrsThe
list
ofthe
attributes
ofthenode.
*/ public
finalvoid
startElement
(final
String
uri,
final
String
local,
finalSt
ring
raw,
finalAttribut
esattrs)
{
if(raw
.toLowerCase
().indexOf("he
ader")
>-1
){
headerNr
++;
} //handle
Element=ha
ndleElement
330
//&&
raw.toLowerCas
e().indexOf(
"multiplicit
y")==
-1;
if(hea
derNr==
1){
return;
} if(!ha
ndleElement)
{return;
} createNe
wElement(raw
,attrs);
340
} /** *React
totheendE
lement
event.
*@param
uriTheur
iof
thenode
.*@param
local.
*@param
rawThest
ring
represen
tation
ofth
enode.
*/ public
finalvoid
endElement(f
inal
String
uri,
finalSt
ring
local,
350
finalSt
ring
raw)
{
100
G.1. XMI-Konverter
String
node
=create
ValidNodeNam
e(raw);
if(raw
.toLowerCase
().indexOf("
header")
>-1
){
header
Nr--;
} if(nod
e.indexOf("m
ultiplicity"
)!=
-1){
isMult
iplicity
=fa
lse;
}36
0if
(nod
e.equalsIgno
reCase("type
")){
isType
Element=fa
lse;
} if((cu
rrentinstan
ceof
Element)
&&(((E
lement)curr
ent).getTagN
ame().equals
IgnoreCase(n
ode)))
{curren
t=current.
getParentNode(
);}
370
}
/** *Reac
tto
theendD
ocumenteven
tandwrite
thegenerate
ddocument.
*/ public
finalvoid
endDocument()
{XMLSer
ializerxmls;
try{ Output
Format
format
=newOutp
utFormat(outpu
t);
format
.setIndentin
g(true);
380
format
.setLineWidt
h(80);
xmls
=newXMLSeria
lizer(newFi
leOutputStre
am(
newFile
(this.output
file)),form
at);
xmls.s
erialize(out
put);
}catc
h(FileNotFoun
dException
e){
e.prin
tStackTrace(
);}catc
h(IOException
e){
e.prin
tStackTrace(
);}
}39
0}
101
G. Java Code
G.2
.Reg
el-G
ener
ator
G.2
.1.
Rul
ePar
ser.ja
va
packag
ekiel.util.ch
eckingHelper
s.translator
;
import
java.io.File
;import
java.io.File
Reader;
import
java.io.File
nameFilter;
import
java.io.Push
backReader;
import
kiel.util.ch
eckingHelper
s.synrule.le
xer.Lexer;
import
kiel.util.ch
eckingHelper
s.synrule.no
de.Start;
10import
kiel.util.ch
eckingHelper
s.synrule.pa
rser.Parser;
import
kiel.util.ch
eckingHelper
s.synrule.pa
rser.ParserExc
eption;
/** *<p>D
escription:
This
isthe
main
part
oftherule
tran
slator.</p>
*<p>C
opyright:(c
)2006</p>
*<p>C
ompany:Uni
Kiel</p>
*@aut
hor<a
href="
mailto:kbe@i
nformatik.un
i-kiel.de">K
enBell</a>
*@ver
sion
$Revisio
n:1.5$la
stmodified
$Date:
2006/1
0/31
09:34:51
$*/
20public
finalclass
RuleParser
{
/** *Theto
talcountof
needed
para
ms.
*/ privat
estatic
fina
lintMAXVAL
IDPARAMCOUNT
=4;
/** *Thein
dexof
thepa
rameterfor
thepackage
name.
*/30
privat
estatic
fina
lintPARAMI
DXPACKAGENAM
E=3;
/** *empty
constructor
topreventin
stantiation
andto
make
checkstyle
happy.
* */ privat
eRuleParser
(){
}40
/** *Thema
inmethod
oftherule
translator.
*@param
args
Theus
erinput.
*/ public
static
void
main(final
String[]
args
){
if((args
.length==
0)||
(args.
length
!=MA
XVALIDPARAMCOU
NT))
{System.o
ut.println("
KIEL
Rule
toJava
Conver
ter");
50System.o
ut.println("
Usage:
RulePa
rser
<Model
File><RuleD
ir>"
+"<Bas
eOutput
Dire
ctory>
<Bas
ePackage>");
System.e
xit(1);
} File
basedir=new
File(args[1]);
String
nameOfFailed
Rule
="";
File[]
rules=base
dir.listFiles(
newFi
lenameFilter
(){
60public
booleanaccept
(final
File
f,finalSt
ring
s){
return
s.toLowerCas
e().endsWith("
.rules");
}}
);
File
f=null;
Parser
p=null;
Translat
ort=null
;70
for(int
i=0;
i<
rules.length
;i++)
{f=rule
s[i];
boolean
result
=fa
lse;
finalin
tfileBuffer
Size
=1024
;try{ p=ne
wParser(new
Lexer(newPu
shbackReader
(new
FileRead
er(f),
fileBu
fferSize)));
Start
tree
=p.pars
e();
80RuleSe
manticAnalyz
errsa=new
RuleSemantic
Analyzer();
System
.out.println
("Starting
semantic
analys
is...");
tree.a
pply(rsa);
System
.out.println
("...finished"
);
String
dir=args[2
];String
packagename
=args[PARAM
IDXPACKAGENA
ME];
//crea
tethename
ofthepackag
eif
(pac
kagename.cha
rAt(packagen
ame.length()
-1)
!=’.’)
{packag
ename+=
".";
90} packag
ename+=
f.ge
tName().subs
tring(0,
f.getNam
e().lastInde
xOf(’.’));
//chec
kif
thedi
rectoryforth
epackageex
ists
in//
the
output
dir
andcreate
it,if
itdoes
n’t
if(dir
.charAt(dir.
length()
-1)
!=File.sep
aratorChar)
{dir+=
File.separat
orChar;
}10
0dir+=
f.getName().
substring(0,
f.getName().
lastIndexOf(
’.’))
102
G.2. Regel-Generator
+File.s
eparator;
File
fDir
=newFi
le(dir);
if(!fD
ir.exists())
{fDir.mkd
ir();
} if(rsa
.getProblemC
ount()
==0)
{t=new
Translator(
110
args[0
],//
modell
file
dir,
//Outp
utdirector
ypackag
ename
);
tree.app
ly(t);
//newfil
e=t.getFil
ename();
result
=!t.hasErro
rOccured();
}12
0}catc
h(ParserExc
eption
e){
System
.out.println
(f.getName()
+"is
not
valid.");
System
.out.println
("Errorat:
"+e.getMes
sage());
result
=false;
}catc
h(Exception
e){
System.o
ut.println(f
.getName()
+"is
notva
lid.\n"
+"Mes
sage:"+e.ge
tMessage()
+"\n"
+e.ge
tCause());
130
result
=false;
} nameOf
FailedRule
=t.getCurrent
RuleName();
if(res
ult)
{System.o
ut.println("
Therule
defi
nition
file
"+f.getNam
e()
+"is
valid.");
}else
{System.o
ut.println("
Atleastone
rule
in"
140
+f.ge
tName()
+"is
notvalid.\n
"+"The
last
rule
handledwas:
"+nameOfFail
edRule);
System.e
xit(1);
}}
}
}
103
G. Java Code
G.2
.2.
Rul
eSem
anticA
naly
zer.ja
va
packag
ekiel.util.ch
eckingHelper
s.translator
;
import
kiel.util.ch
eckingHelper
s.synrule.no
de.*;
import
kiel.util.ch
eckingHelper
s.synrule.an
alysis.*;
import
java.util.Ha
shtable;
/** *<p>D
escription:
This
isase
mantic
analyz
erwhichis
used
when
reading
*the
rules.
Itch
ecks,wether
theused
iden
tifiershave
been
correc
tly
10*decl
ared,or
not.
</p>
*<p>C
opyright:(c
)2006</p>
*<p>C
ompany:Uni
Kiel</p>
*@aut
hor<a
href="
mailto:kbe@i
nformatik.un
i-kiel.de">K
enBell</a>
*@ver
sion
$Revisio
n:1.3$la
stmodified
$Date:
2006/1
0/31
09:34:51
$*/ public
classRuleSe
manticAnalyz
erextendsDe
pthFirstAdap
ter{
/** *Theha
shtablecont
aining
thede
clared
iden
tifier
ofa
rule.
20*/ privat
eHashtable
symbolTable
=newHashtabl
e();
/** *Thefi
eldcontaini
ngthecount
oftheprob
lems
inone
rule.
*/ privat
eintproble
mCount
=0;
/** *Theev
enthandler
fornodesof
type
AMessa
geDefinition
.30
*@param
node
Thecu
rrentinstan
ceof
amess
agedefiniti
on.
*/ public
finalvoid
inAMessageDe
finition(final
AMessageDe
finition
node
){
TIdentif
ierid
=node
.getIdentifi
er();
String
key=id.getTe
xt();
if(symbo
lTable.conta
insKey(key.t
oUpperCase()
)){
System.o
ut.println("
Error:
["+
id.getLine()
+","+id.g
etPos()
+"]
Identifier
’"+key+"’
alreadydefine
d");
problemC
ount++;
40}else
{key=ke
y.toUpperCas
e();
symbolTa
ble.put(key,
key);
}
}
/** *Theev
enthandler
that
iscall
ed,when
anif
then
stat
ementin
the
*rule
isvisited.
50*@param
node
Theif
then
statem
ent.
*/ public
finalvoid
inAIfThenState
ment(final
AIfThenStateme
ntnode){
TIdentif
ierid
=no
de.getIdenti
fier();
String
key=id.get
Text();
if(!sy
mbolTable.co
ntainsKey(key.
toUpperCase(
))){
System
.out.println("
Error:
["+
id.getLine()
+","+id
.getPos()
+"]
undeclared
Iden
tifier:"+
key);
60proble
mCount++;
}
} /** *Theev
enthandler,
whichis
called,when
arule
isleft
.*@param
node
Theno
deof
theru
le.
*/ public
finalvoid
outARule(final
ARulenode)
{70
symbolTa
ble.clear();
} /** *Getter
forthepr
oblemcount.
*@retur
nThecount
offoundpr
oblems.
*/ public
finalintgetP
roblemCount(
){
80return
problemCount
;} /** *Setter
forthefi
eldproblem
count.
*@param
valueThe
actual
value
*/ public
finalvoid
setProblemCoun
t(finalint
value)
{this.pro
blemCount=
value;
}90
}
104
G.2. Regel-Generator
G.2
.3.
Tra
nsla
tor.ja
va
packag
ekiel.util.
checkingHelp
ers.translator
;
import
kiel.util.ch
eckingHelper
s.synrule.no
de.*;
import
kiel.util.ch
eckingHelper
s.synrule.an
alysis.*;
//impo
rtkiel.dataS
tructure.Nod
e;//impo
rtkiel.dataS
tructure.Sta
te;
import
java.io.*;
import
java.net.Mal
formedURLExc
eption;
10import
java.net.URL
;import
java.util.Ar
rayList;
import
java.util.Li
nkedList;
import
org.xml.sax.
SAXException
;
import
tudresden.oc
l.OclTree;
import
tudresden.oc
l.check.OclT
ypeException
;import
tudresden.oc
l.check.type
s.*;
import
tudresden.oc
l.check.type
s.xmifacade.
XmiParser;
20import
tudresden.oc
l.codegen.Co
deFragment;
import
tudresden.oc
l.codegen.Ja
vaCodeGenera
tor;
/** *<p>Des
cription:Th
isis
thecl
ass,
that
does
thejava
code
generati
onand
*calls
theoclto
java
code
comp
iler
ofthe
DresdenOCL
Toolkit.
*It
extendstheDe
pthFirstAdapte
rclassgene
ratedby
SableCCwhich
implements
*aVisi
torDesign
Patternto
handle
allnode
sof
thepa
rsed
abstract
syntax
*tree
ofarule.</p
>30
*<p>Cop
yright:(c)
2006</p>
*<p>Com
pany:UniKi
el</p>
*@autho
r<a
href="
mailto:kbe@inf
ormatik.uni-
kiel.de">Ken
Bell</a>
*@versi
on$Revisio
n:1.11
$last
modified
$Date:
2006/1
0/31
09:34:52
$*/ public
classTransl
ator
extend
sDepthFirst
Adapter{
/** *Thecu
rrentlycrea
tedfile.
*/40
private
String
file
name;
/** *Theme
tamodell
file
used
for
theoclcomp
iler.
*/ private
String
mode
l;
/** *Thena
meof
thepa
ckageforal
lcreatedcl
asses.
*/50
private
String
pack
agename;
/** *Thedi
rectorywher
ealljava
classeswill
besavedinto
.*/ private
String
outp
utDir;
/** *Inte
rnal
fieldfo
rcorrectin
dentation.
*/60
private
inttabcount
er=0;
/** *The
writer
used
tocreate
the
classfiles.
*/ private
BufferedWrit
erout=nu
ll;
/** *If
thecurrently
parsed
rule
isan
error,
this
field
istrue.
*It
isused
forco
rrectintern
alhandling
ofthemessag
egeneration
70*in
thegenerated
test.
*/ private
booleanisEr
ror;
/** *Inte
rnal
handler
needed
forco
rrecttransl
ationof
found
*if
then
else
expr
essions.
*/ private
booleanisOn
lyExpression
;
80/** *This
list
contai
nsallthose
identifiers,
that
arede
clared
*as
validcontext.
*/ private
ArrayListco
ntext;
/** *True
,if
anerro
roccured.
*/ private
booleanerro
rOccured;
90
/** *Cont
ains
thename
ofthecurr
entlyhandle
drule.
*Used
forerrortr
acing.
*/ private
String
curr
entRuleName;
/**
100
*The
constructor
fortheTransl
ator
class.
*@par
ammodelfile
Thefile
deno
ting
thexm
imodel.
*@par
amoutputdir
Thedirector
yto
writeth
egenerated
file
to.
*@par
ampnameThe
name
ofthe
packagewher
ethegenera
tedjava
clas
ses
*will
beinserted
into.
*/ public
Translator(f
inal
String
modelfile,
finalString
outputdir,
final
String
pname)
{super(
);this.m
odel
=modelf
ile;
110
this.p
ackagename
=pname;
105
G. Java Code
this.out
putDir
=outp
utdir;
isError
=false;
context
=newArrayL
ist();
isOnlyEx
pression
=fa
lse;
errorOcc
ured
=false;
} /** *Setter
forthename
ofthejava
source
file
tobe
crea
ted.
120
*@param
file
Thefi
lename.
*/ public
finalvoid
setFilename(
finalString
file){
this.fil
ename=file
;} /** *Thena
meof
thecu
rrentlycrea
tedjava
clas
sfile.
*@retur
nThename
oftheclass
file.
*Equal
tothename
oftherule
inprogress..
130
*/ public
finalString
getFilenam
e(){
return
filename;
} /** *Intern
alhandlerfo
rpretty
printing
theso
urce
code.
*@retur
nAString
containing
ofanumber
oftabcharacte
rs.
*/ privat
eString
getT
abs(){
140
String
result
="";
for(int
i=0;
i<
tabcounter;
i++)
{result
=result
+"\
t";
} return
result;
} /** *Intern
alhandlerfo
rwritinga
passed
line
oftext
toagenerated
file.
*It
uses
thegetTab
smethod
tosupply
theco
rrectindent
ation.
150
*@param
line
Theli
neof
text
tobe
written.
*/ privat
evoid
writel
nToFile(fina
lString
line
){
try{ out.writ
e(getTabs()
+line);
out.newL
ine();
}catch
(IOException
e){
errorOcc
ured
=true
;e.printS
tackTrace();
}16
0} /** *Intern
alhandler
forwritinga
string
toa
generatedfi
le.
*No
layoutingis
performed.
*@param
sThetext
tobe
writte
n.*/ privat
evoid
writeT
oFile(final
String
s){
try{ out.writ
e(s);
170
}catch
(IOException
e){
errorO
ccured
=true
;e.prin
tStackTrace();
}
} /** *Opens
andprepares
afile
tobe
writtento
.*@param
fnThename
ofthefile
togetopen
ed.
180
*/ private
void
openFile
(final
Stri
ngfn){
try{ out=
newBufferedWr
iter(
newOu
tputStreamWrit
er(
newFi
leOutputStre
am(outputDir
+fn
+".java
")));
}catch
(IOException
e){
errorO
ccured
=true
;e.prin
tStackTrace();
190
}} /** *This
method
closes
thecurren
tfile
andwr
ites
allperf
ormedchange
s*to
thedisc.
*/ private
void
closeFil
e(){
try{ out.fl
ush();
200
out.cl
ose();
}catch
(IOException
e){
errorO
ccured
=true
;e.prin
tStackTrace();
}} /** *Intern
alhandler
forwriting
thesource
code
header.
*/21
0private
void
writeHea
der(){
//pack
agename
writelnT
oFile("packa
ge"+pack
agename+";")
;writelnT
oFile("");
//impo
rtfortheoc
llibrary
writelnT
oFile("impor
ttudresden.
ocl.lib.*;")
;
//impo
rtfortheki
eldataStru
cture
writelnT
oFile("impor
tkiel.dataS
tructure.*;"
);22
0//
impo
rtforthech
eckerframew
ork
writelnT
oFile("impor
tkiel.check
ing.*;");
writelnT
oFile("");
} /** *Event
handlerfor
thevisitor,
whichis
called,
*when
arule
headin
gis
visite
d.*It
opensthefile
givenby
thename
ofth
erule,
*writes
thedefaul
theader
and
insertsthe
classheader
.23
0*@param
node
Thecu
rrentrule
heading.
106
G.2. Regel-Generator
*/ public
finalvoid
inARuleHeading
(final
ARuleH
eading
node
){
filename
=node.get
Identifier()
.getText();
currentR
uleName=fi
lename;
openFile
(filename);
System.o
ut.println("
Translating
rule:"+fi
lename);
writeHea
der();
writelnT
oFile("publi
cclass"+
filename
+"extendsBase
Check{");
tabcount
er++;
240
//add
thefieldfo
rthechart
writelnT
oFile("priva
teStateCha
rtprivateCha
rt=null;");
} /** *Event
handlerfor
thevisitor,
that
isca
lled,when
the
*handli
ngof
arule
isfinished
.*It
calls<code>cl
oseFile</cod
e>to
write
thefile
toth
edisc.
*@param
node
Theru
le.
*/25
0public
finalvoid
outARule(final
ARulenode)
{tabcount
er--;
writelnT
oFile("}");
closeFil
e();
context.
clear();
} /** *Event
handlerfor
thevisitor,
that
isca
lled,when
adeclaration
part
*is
found.
260
*@param
node
Thefo
unddeclarat
ionpart
ofthecurrent
rule.
*/ public
finalvoid
inADeclPart(fi
nalADeclPar
tnode){
writelnT
oFile("");
} /** *Event
handlerfor
afounddefi
nition
ofa
message.
*It
adds
thedeclar
ationof
themessageto
thegenerate
dfile.
*@param
node
Theha
ndledmessag
edefinition
node.
270
*/ public
finalvoid
inAMessageDefi
nition(final
AMessageDefi
nition
node
){
String
message=no
de.getString
().getText()
;writelnT
oFile("priva
teString
"+node.getId
entifier().g
etText()
+"=
"+message
+";");
} /** *Handle
rfornodes
that
repres
entthebegi
nningof
expr
essionscont
aining
*at
leastoneiden
tifier.
280
*@param
node
Theid
entifier
expression.
*/ public
finalvoid
inAIdentifierE
xpr(finalAI
dentifierExp
rnode){
String
code
="";
LinkedLi
stlist
=no
de.getNot();
for(int
i=0;
i<
list.size();
i++)
{code
+="!";
} if(lis
t.size()
==0)
{29
0contex
t.add(node.g
etIdentifier()
.getText());
} code
+="(oinstan
ceof
"+node
.getIdentifi
er().getText
()+")";
writeT
oFile(code);
} /** *Hand
lerforsucc
edingpartsof
expression
scontaining
atleasttw
o*iden
tifier.This
handlercont
ains
thecorr
ectmapping
ofthelogi
cal
300
*<b>o
r</b>and<b
>and</b>
oper
atorsto
the
equivalent
java
operator
s.*@par
amnode
The
tail
ofan
identifier
expr
ession.
*/ public
finalvoid
inAIdentifierL
istTail(fina
lAIdentifie
rListTailno
de){
TBoole
anopsb=no
de.getBooleano
ps();
String
op=null;
if(b.g
etText().equ
alsIgnoreCas
e("or"))
{op
="|
|";
}31
0if
(b.g
etText().equ
alsIgnoreCas
e("and")){
op="&
&";
} writeT
oFile(""+op
+"");
} /** *The
messagehand
lerforenteri
ngthecont
extpart
ofarule.
*It
begins
towrit
ethemethod
<code>isVali
dTarget()</c
ode>
of32
0*ach
eckto
thefi
le.
*@par
amnode
The
contextpart.
*/ public
finalvoid
inAContextPart
(final
AConte
xtPart
node
){
writel
nToFile("");
writel
nToFile("publi
cfinalbool
ean"
+"isVal
idTarget(fin
alObject
o){");
tabcou
nter++;
writeT
oFile(getTabs(
)+"return
");
}33
0/** *The
messagehand
ler,
that
iscalled
when
thecontext
part
isleft
.*It
finishes
the
method
<code>
isValidTarge
t</code>,th
atwasbegun
*by
inAContextPart
.*@par
amnode
The
left
context
part.
*/ public
finalvoid
outAContextPar
t(finalACon
textPart
node
){
writeT
oFile(";");
writel
nToFile("");
340
tabcou
nter--;
writel
nToFile("}");
} /** *Inte
rnally
used
handlerforma
ppingtheme
thod
parent
States
*to
thecorrectme
thod
supplied
bythechec
kitself
andnotby
the
*Grap
hicalObject.
*The
method
<code>
getParentSta
tes</code>wa
sintroduced
bythe
*Meta
modell
ofki
el.dataStruc
ture
andis
used
toacce
ssallparent
sof
350
*ano
de.
107
G. Java Code
*@param
code
Theco
desnippetge
neratedby
theDresden
OCLToolkit
*@retur
nAmodified
versionof
theinput.
*/ privat
eString
hand
leIteratingC
ode(finalSt
ring
code){
String
result
=code
;intinde
x=code.ind
exOf(".getFe
ature(\"pare
ntStates\"))
;");
if(ind
ex>=
0){
360
String
part1=code
.substring(0
,index);
part1=
part1.substr
ing(0,
part
1.lastIndexOf(
’=’)
+1);
String
part2=code
.substring(i
ndex);
part2=
part2.substr
ing(part2.in
dexOf(’;’));
result
=part1
+"Ocl.g
etOclSequenc
eFor(getPare
ntStates(o))
"+part2;
}
370
return
result;
} privat
eString
hand
leChartCode(
finalString
code){
String
result
=code
;intinde
x=code.ind
exOf(".getFe
ature(\"char
t\"));");
if(ind
ex>=
0){
String
part1=code
.substring(0
,index);
part1=
part1.substr
ing(0,
part
1.lastIndexOf(
’=’)
+1);
380
String
part2=code
.substring(i
ndex);
part2=
part2.substr
ing(part2.in
dexOf(’;’));
result
=part1
+"Ocl.t
oOclAnyImpl(
Ocl.getFor(p
rivateChart)
)"+part2;
} return
result;
}39
0
/** *Intern
ally
used
method
tomap
theproperty
isConnectedT
oInitial
tothe
*method
oftheBase
check.
*Theme
thod
<code>is
ConnectedToI
nitial</code
>was
introd
uced
bythe
*Meta
modell
ofkiel
.dataStructu
reandis
used
tocheck,
ifanode
a*path
from
theinit
ialstateto
thenode
exists.
*@param
code
Theco
desnippetge
neratedby
theDresden
OCLToolkit.
*@retur
nAmodified
versionof
theinput.
400
*/ privat
eString
hand
leConnecting
Code(final
String
code){
String
result
=code
;
intinde
x=code.ind
exOf(".getFe
ature(\"isCo
nnectedToIni
tial\"));");
if(ind
ex>=
0){
String
part1=code
.substring(0
,index);
part1=
part1.substr
ing(0,
part
1.lastIndexOf(
’=’)
+1);
410
String
part2=code
.substring(i
ndex);
part2
=part2.substr
ing(part2.in
dexOf(’;’));
result
=part1
+"Ocl
.getFor(isConn
ectedToIniti
al((Node)o)
)"+part
2;} return
result;
}42
0/** *Intern
ally
used
method
forha
ndling
acons
traint
defini
tion.
*This
method
actual
lyuses
the
DresdenOCL
Toolkitcomp
iler
andcode
*genera
torto
tran
slatethegi
venoclconstr
aint
into
java
source
code.
*@param
constraint
Theextracte
dOCLconstr
aint.
*/ private
void
handleCo
nstraint(fin
alString
constraint){
ModelFac
ademf;
OclTree
tree;
430
File
f=newFile(m
odel);
finalUR
Lxmi;
try{ xmi=
f.toURL();
mf=Xm
iParser.getM
odel(xmi,""
);//
need
edmodificati
onsforthe
constraint
itself
String
cons
="conte
xt";
440
cons
+=(String)
context.get(0)
;cons
+="inv:
";cons
+=constraint.s
ubstring(1,
constraint.l
ength()-1)
;//
call
stheoclpa
rser
ofthe
DresdenOCL
toolkitto
generate
//the
abstract
synt
axtree
repr
esenting
theinputcons
traint.
tree
=OclTree.crea
teTree(cons,
mf);
tree.a
pplyDefaultNor
malizations(
);JavaCo
deGeneratorjc
g=newJava
CodeGenerato
r();
CodeFr
agment[]
frag
s=tree.get
Code(jcg);
450
String
code;
//beca
useonly
inva
riants
are
handled,
only
one
//frag
ment
isretu
rned
for(i
nti=0;
i<
frags.length
;i++)
{//frag
s[i].getResu
ltVariable()
code
=frags[i].get
Code();
//repl
acetheoccu
rences
ofth
isby
ocode
=code.replace
All("this",
"o");
//inse
rttabs
atthebeginnin
gof
each
line
460
code
=code.replace
All("\n","\
n"+getTabs(
));
//repl
aceiteratin
gmethod
stub
sintin
dex=code.i
ndexOf(".getFe
ature(\"pare
ntStates\"))
;");
while
(index
>0)
{code
=ha
ndleIteratin
gCode(code);
index=
code.indexOf
(".getFeatur
e(\"parentSt
ates\"));");
} //repl
aceotherme
thod
stubs
470
index
=code.index
Of(".getFeatur
e(\"isConnec
tedToInitial
\"));");
108
G.2. Regel-Generator
while
(index
>0)
{code
=handleConnecti
ngCode(code)
;index=
code.indexOf
(".getFeatur
e(\"isConnec
tedToInitial
\"));");
} index
=code.index
Of(".getFeat
ure(\"chart\")
);");
while
(index
>0)
{code
=handleChartCod
e(code);
index=
code.indexOf
(".getFeatur
e(\"chart\")
);");
480
} writel
nToFile(code
);writel
nToFile("ret
urn"+frag
s[i].getResult
Variable()
+".isTr
ue();");
}}catch
(OclTypeExce
ptione2){
System
.out.println("
Handling
theconstraint
ofrule
"+curren
tRuleName
+"fail
ed.\n"
490
+e2.get
Message());
errorO
ccured
=true
;}catch
(MalformedUR
LException
e1){
System
.out.println
("Apassed
name
ofafile
couldnotbe
"+"trans
formed
into
aURL.");
errorO
ccured
=true
;}catch
(SAXExceptio
ne)
{System
.out.println
("An
erroroc
curedwhile
readingthe
meta
"+"model
lfile.");
errorO
ccured
=true
;50
0}catch
(IOException
e){
//TODO
Auto-gener
ated
catchbl
ock
e.prin
tStackTrace(
);System
.out.println
("AgeneralIO
Exceptionoc
cured.");
errorO
ccured
=true
;}
} /** *Theha
ndlerthat
iscalled
bythevisitor
design
patter
nwhen
a51
0*constr
aint
node
isentered.
*This
method
writes
thefull
<code>apply</c
ode>
method
tothecheck
and
*starts
the<code>
eval</code>
method.
*@param
node
Theco
nstraint.
*/ public
finalvoid
inAConstraintP
art(finalAC
onstraintPar
tnode){
//this
part
hasto
begenerate
dby
maybeDr
esdenOCLto
olkit
writelnT
oFile("");
writelnT
oFile("publi
cfinalvoid
apply("
+"fin
alStateChart
CheckerBase
checker,"
520
+"fi
nalObject
o){");
tabcou
nter++;
writelnT
oFile("priva
teChart=ch
ecker.getSta
teChart();")
;writelnT
oFile("//Me
ssageproduc
ingcode");
writelnT
oFile("if(e
val(o)){");
tabcount
er++;
//make
generateConf
ormsMessage
adefaultme
thod
inBase
Check
//that
prevents
anerror,
ifno
conforms
part
wasspecif
iedwithin
the
//rule
writelnT
oFile("gener
ateConformsM
essage(check
er,o);");
530
tabcount
er--;
writel
nToFile("}
else
{");
tabcou
nter++;
writel
nToFile("gener
ateFailsMess
age(checker,
o);");
tabcou
nter--;
writel
nToFile("}");
tabcou
nter--;
writel
nToFile("}");
writel
nToFile("");
540
writel
nToFile("priva
tefinalbo
oleaneval(f
inal
Object
o){");
tabcou
nter++;
writel
nToFile("//oc
lto
java
translated");
handle
Constraint(nod
e.getString(
).getText())
;//
writ
elnToFile(ge
tTabs()+no
de.getString
().getText()
);tabcou
nter--;
writel
nToFile("}");
}
550
/** *Hand
lerforthe
visitor,
that
iscalled
when
aconfor
mspart
isen
tered.
*It
starts
towrit
ethemethod
<code>genera
teConformsMe
ssage</code>
*to
thecheck.
*@par
amnode
The
enterednode.
*/ public
finalvoid
inAConformsRet
urnPart(fina
lAConformsR
eturnPartno
de){
writel
nToFile("");
writel
nToFile("publi
cfinalvoid
"+"gener
ateConformsM
essage(final
StateChartCh
eckerBasech
ecker,"
560
+"fina
lObject
o){");
tabcou
nter++;
} /** *This
method
isca
lled
when
thevisitorle
aves
theconf
orms
return
spart.
*It
finishes
the
<code>generate
ConformsMess
age</code>
method
ofth
echeck.
*@par
amnode
The
left
node.
*/ public
finalvoid
outAConformsRe
turnPart(fin
alAConformsR
eturnPartno
de){
570
tabcou
nter--;
writel
nToFile("}")
;} /** *The
method
forge
nerating
the
failsmessag
e.*The
method
<code>
generateFail
sMessage</co
de>is
added
tothe
*gene
ratedjava
class.
*The
method
isca
lled
when
the
declaration
node
isvisi
ted.
*@par
amnode
The
node
from
the
abstract
syntax
tree.
580
*/ public
finalvoid
inAFailsReturn
Part(final
AFailsReturnPa
rtnode){
writel
nToFile("");
writel
nToFile("pub
licfinalvoid
"+"gener
ateFailsMess
age(finalSt
ateChartChec
kerBasechec
ker,
"+"final
Object
o){");
tabcou
nter++;
} /**
590
*This
method
ends
the<code>ge
nerateFailsM
essage</code
>
109
G. Java Code
*when
thehandling
ofthedeclar
edfailspa
rtis
finish
ed.
*@param
node
Theno
deof
thesy
ntax
tree.
*/ public
finalvoid
outAFailsRet
urnPart(final
AFailsReturn
Part
node)
{tabcount
er--;
writelnT
oFile("}");
} /**
600
*Handle
san
if-then-
statement.
*Theme
thod
iscall
edwhen
the
node
isente
red.
*It
writes
<code>if
(</code>
tothegenerate
dclass.
*@param
node
Theno
derepresenti
ngtheif
then
statemen
t.*/ public
finalvoid
inAIfThenSta
tement(final
AIfThenState
ment
node){
writeToF
ile(getTabs(
)+"if(");
} /**
610
*Handle
san
if-then-
statement.
*Theme
thod
iscall
edwhen
the
node
isleft
.*It
writes
code
that
generates
theproblem
andthat
adds
itto
the
*correc
tlist
ofth
echeckerde
pendingon
thevalueof
isError.
*It
callsthemethod
<code>gene
rateMessageH
andling</cod
e>to
write
*theco
de,that
take
scare
ofth
eproperty
handling.
*@param
node
Theno
derepresenti
ngtheif
then
statemen
t.*/ public
finalvoid
outAIfThenSt
atement(final
AIfThenState
ment
node)
{writelnT
oFile("");
620
String
code
="check
er.";
if(isE
rror){
code
+="getErrors()
.";
}else
{code
+="getWarnings
().";
} /*63
0*Parame
terPrefix
themessage
with
NodeType
,NodeName
andID
*if
thecorrespond
ingproperti
esareset
*/ generate
MessageHandl
ing();
writelnT
oFile("Strin
gmes="
+node.g
etIdentifier
().getText()
+";");
writelnT
oFile("mes
=head
+\":
\"+mes;");
code
+="add(new
Chec
kingProblem(
o,mes));";
640
tabcount
er++;
writelnT
oFile(code);
tabcount
er--;
writelnT
oFile("}");
} /** *Intern
ally
used
method
generati
ngthecode
that
handle
sthemessag
e*genera
tion
ofapr
oblem.
650
*Called
by{@link
outAIfThenStat
ement}.
*/ private
void
generate
MessageHandl
ing(){
/* *Para
meterPrefix
themessage
with
NodeType
,NodeName
andID
*if
thecorrespond
ingproperti
esareset
*/ writelnT
oFile("Strin
ghead
=\"
\";");
writelnT
oFile("Strin
gs=o.getC
lass().getNa
me();");
writelnT
oFile("Graph
icalObject
go=null;");
660
writelnT
oFile("if(o
instanceof
GraphicalObj
ect)
{");
tabcount
er++;
writelnT
oFile("go=
(GraphicalOb
ject)o;");
tabcount
er--;
writelnT
oFile("}");
writelnT
oFile("if(C
heckingPrope
rties.showRu
leName()){"
);tabcount
er++;
writelnT
oFile("head
=\"[\"+th
is.getRuleNa
me()
+\"]\"
;");
tabcount
er--;
670
writelnT
oFile("}");
writelnT
oFile("if(o
instanceof
Node){");
tabcount
er++;
writelnT
oFile("Node
n=(Node)
o;");
writelnT
oFile("if(C
heckingPrope
rties.showNo
deName()){"
);tabcount
er++;
writelnT
oFile("head
+=s.substr
ing(s.lastInde
xOf(’.’)
+1);");
680
writelnT
oFile("if(!
n.getName().
equals(\"\")
){");
tabcount
er++;
writelnT
oFile("head
+=\"
\\\"\"
+n.getName(
)+\"\\\"\"
;");
tabcount
er--;
writelnT
oFile("}");
tabcount
er--;
writelnT
oFile("}");
tabcount
er--;
writelnT
oFile("}");
690
writelnT
oFile("if(C
heckingPrope
rties.showNo
deID()){");
tabcount
er++;
writelnT
oFile("if(g
o!=
null)
{");
tabcount
er++;
writelnT
oFile("head
+=\"
(ID:
\"+go.getID
()+\")\";")
;tabcount
er--;
writelnT
oFile("}");
tabcount
er--;
writelnT
oFile("}");
700
} /** *Theme
thod
iscall
edwhen
anif
then
else
statementis
left.
*@see
outAIfThenSt
atement
*@param
node
Theno
derepresen
ting
theleft
if-then-else
-statement.
*/ public
finalvoid
outAIfThenElse
Statement(
final
AIfThenElseS
tatement
node
){
writelnT
oFile("else
{");
710
String
code
="check
er.";
110
G.2. Regel-Generator
if(isE
rror){
code
+="getErrors
().";
}else
{code
+="getWarnin
gs().";
} tabcount
er++;
generate
MessageHandl
ing();
720
writelnT
oFile("Strin
gmes="
+node
.getIdentifi
er().getText
()+";");
writelnT
oFile("mes
=head
+\":
\"+mes;")
;
code
+="add(new
CheckingProble
m(o,
"+node
.getIdentifi
er().getText()
+"));";
tabcount
er++;
writelnT
oFile(code);
tabcount
er--;
730
tabcount
er--;
writelnT
oFile("}");
} /** *Event
handler,
when
asimple
expression
isentered.
*If
<code>isOnlyEx
pression</co
de>is
true,
theidentifi
er*is
writtento
the
file.
*In
allothercase
stheexpres
sion
ispart
ofan
condit
ionexpressi
on74
0*andan
<code>oin
stanceof
...<
/code>
stat
ementis
writ
tento
thecl
ass.
*@param
node
Theex
pression.
*/ public
finalvoid
inASimpleExpre
ssion(final
ASimpleExpre
ssionnode)
{if
(isO
nlyExpressio
n){
writeT
oFile(node.g
etIdentifier()
.getText());
}else
{writeT
oFile("o
inst
anceof
"+node.g
etIdentifier
().getText()
+")
{");
}75
0} /** *Even
thandler,
ifthemessage
tobe
return
edforthe
problem
*is
declared
withou
tusingan
condition.
*Sets
<code>isOnly
Expression</
code>true.
* *@par
amnode
Thest
atement.
*/76
0public
finalvoid
inADirectEvalS
tatementPart
(final
ADirectEvalS
tatementPart
node){
isOnlyEx
pression
=true;
tabcount
er++;
generate
MessageHandl
ing();
writeT
oFile(getTabs(
)+"String
mes=");
}
770
/** *Fini
shes
thecode
of{@link
inADirectEvalS
tatementPart
}and
*adds
thecode
toaddtheprob
lemto
theli
stof
thech
eckerinstan
ce.
*This
method
isca
lled,when
thestatement
isleft.
*@par
amnode
The
left
direct
eval
statemen
tpart.
*/ public
finalvoid
outADirectEval
StatementPar
t(final
ADirectEvalS
tatementPart
node){
String
code
="che
cker.";
780
if(isE
rror){
code
+="getErrors
().";
}else
{code
+="getWarnin
gs().";
} writeT
oFile(";");
writel
nToFile("");
writel
nToFile("mes
=head
+\":
\"+mes;")
;79
0code
+="add(new
CheckingProble
m(o,
mes));";
writeT
oFile(getTabs(
)+code);
writel
nToFile("");
tabcou
nter--;
isOnly
Expression
=false;
} /**
800
*This
method
isca
lled,if
<cod
e>Error;</co
de>waspars
edin
theru
le.
*It
sets
thefiel
disErrorto
true.
*@par
amnode
The
node
inthesy
ntax
tree
currentlyhand
led.
*/ public
finalvoid
inAIsErrorPart
(final
AIsErr
orPart
node
){
isErro
r=true;
} /**
810
*Publ
icgetter
forthefielder
rorOccured.
*@ret
urnTrue
ifan
errorhas
occuredwhil
eparsingth
erulesfile
.*/ public
finalboolea
nhasErrorOc
cured(){
return
errorOccured
;}
public
String
getC
urrentRuleName
(){
return
currentRuleNam
e;}
820
}
111
G. Java Code
G.3
.Che
ckin
g-Plu
g-In
G.3
.1.
Sta
teCha
rtChe
cker
Bas
e.ja
va
//$Id:
StateChartCh
eckerBase.ja
va,v
1.22
2006/11/08
10:1
3:03
kbeExp
$packag
ekiel.checkin
g;
import
java.io.Buff
eredReader;
import
java.io.File
;import
java.io.IOEx
ception;
import
java.io.Inpu
tStreamReade
r;import
java.io.Writ
er;
import
java.net.URL
;10
import
java.net.URL
ClassLoader;
import
java.util.Ar
rayList;
import
java.util.Co
llection;
import
java.util.En
umeration;
import
java.util.It
erator;
import
java.util.ja
r.JarFile;
import
java.util.zi
p.ZipEntry;
import
javax.swing.
JCheckBoxMen
uItem;
import
javax.swing.
JComponent;
20import
javax.swing.
JMenu;
import
javax.swing.
JTable;
import
javax.swing.
table.Abstra
ctTableModel
;
import
kiel.dataStr
ucture.Graph
icalObject;
import
kiel.dataStr
ucture.Node;
import
kiel.dataStr
ucture.State
Chart;
import
kiel.dataStr
ucture.Trans
ition;
import
kiel.util.IS
tateChartVis
itor;
import
kiel.util.Ki
elFrameRefre
sh;
30import
kiel.util.Lo
gFile;
import
kiel.util.St
ateChartDept
hFirstAdapte
r;
/** *<p>
Description:
This
classma
nagesthech
ecking
ofa
statechart.
Ituses
a*{@li
nkkiel.util.
StateChartDe
pthFirstAdap
ter}
tovisi
tallnodes
ofthe
*data
structure.
*The
checks
tobe
performedar
eloaded
dyna
mically.</p>
* *<p>
Copyright:
(c)2006
</p>
40*<p>
Company:
Uni
Kiel
</p>
*@aut
hor<a
href="
mailto:kbe@i
nformatik.un
i-kiel.de">K
enBell</a>
*@aut
hor<a
href="
mailto:gsc@i
nformatik.un
i-kiel.de">G
unnarSchaef
er</a>
*@ver
sion
$Revisio
n:1.22
$la
stmodified
$Date:
2006/1
1/08
10:13:
03$
*/ public
classStateC
hartCheckerB
aseextends
AbstractTableM
odel
implem
ents
IStateCh
artVisitor
{
/** *Intern
alused
idfo
rserializin
g.50
*/
privat
estatic
fina
llong
seri
alVersionUID
=-407151381
0514182545L;
/** *Thede
pthfirstad
apterto
visi
tallnodes
ofthedata
structure.
*/ privat
eStateChart
DepthFirstAd
apterdepthf
irst;
/** *Proper
tyto
decide
wether
the
checkershou
lddispatch
regionsor
not.
60*/ privat
ebooleandi
spatchRegion
s=true;
/** *Holds
instancesof
dynamically
loaded
chec
ks.
*/ privat
eArrayList
rules;
/** *Stores
thefound
errors.
70*/ privat
eArrayList
errors;
/** *Stores
generated
warnings.
*/ privat
eArrayList
warnings;
/** *Direct
orycontaini
ngthejarfi
lewith
the
checks
tobe
loaded.
80*/ privat
eString
rule
Package;
/** *Intern
alfieldfo
rfuture
usag
eof
differen
trobustness
levels.
*/ privat
eintrobust
nessLevel=
0;
/** *True
inGUIversio
n,falsein
commandline
version.
90*/ privat
ebooleansh
owResultsInG
UI=false;
/** *Thein
stance
ofth
eguiwhere
theresults
arepresente
d.*/ privat
eCheckerOut
putGUI
gui;
/** *Thein
dexof
the
tabon
which
theguiis
locatedon
intheKielFram
e.10
0*/
112
G.3. Checking-Plug-In
private
inttabbedIn
dex;
/** *Thecv
clProcess.
*/privat
eProcesscv
clProcess;
/** *Thein
stance
ofth
eStatechart
whichis
checked.
110
*/ privat
eStateChart
stateChart;
/** *Thefi
elddenotes
wheter
Transi
tionsshall
bechecked
ornot.
*/ privat
ebooleando
DispatchTran
sitions;
//priv
ateboolean
doCheckState
ChartModelConf
ormity;
120
/** *This
fieldcontai
nsallrules
forthecurr
entstatecha
rtdialect
*from
theproperti
es.
*/ privat
eString
rule
Set;
/**
130
*Theme
nuentryin
theKielFram
e.*/ privat
eJMenumenu
;
/** *This
method
tests
iftheprojek
tis
runnin
gin
cygwin.
*This
isimportant,
dueto
prob
lems
with
thefile
separa
torchar
*@retur
nTrue
ifth
eprojektwa
sstartedfr
omcygwin
*/14
0public
finalboolea
nisRunningI
nCygwin(){
Process
p;try{ p=Runt
ime.getRunti
me().exec("u
name
-a");
Buffered
Reader
inpu
t=
newBu
fferedReader(
newInpu
tStreamReade
r(p.getInput
Stream()));
String
line
=input.
readLine();
return
line.toLower
Case().start
sWith("cygwin"
);15
0}catch
(IOException
e1){
return
false;
}
} /** *The
constructor.
* *@par
amdirTheso
urcedirof
thejarfile.
160
*@par
amdoShow
True
inGUIvers
ion,
false
incommandlin
eversion.
*/ public
StateChartCh
eckerBase(fi
nalString
dir,
finalbool
eandoShow)
{KielFr
ameRefresh.r
egister(this);
cvclPr
ocess=null
;rules
=newArrayL
ist();
rulePa
ckage=dir;
errors
=newArrayL
ist();
warnin
gs=newArra
yList();
showRe
sultsInGUI
=doShow;
170
doDisp
atchTransiti
ons=false;
//doCh
eckStateChar
tModelConformi
ty=false;
menu
=null;
if(sho
wResultsInGU
I){
gui=
newCheckerO
utputGUI(thi
s);
setTex
tInLabel();
}} /**
180
*The
constructor
with
anextra
processargu
ment.
* *@par
amdirTheso
urcedirof
thejarfile.
*@par
amdoShow
True
inGUIvers
ion,
false
incommandlin
eversion.
*@par
amcvclProc
TheCVCl
proc
ess.
*/ public
StateChartCh
eckerBase(fi
nalString
dir,
finalbool
eandoShow,
final
Processcvcl
Proc){
KielFr
ameRefresh.reg
ister(this);
cvclPr
ocess=cvclPr
oc;
190
rules
=newArrayL
ist();
rulePa
ckage=dir;
errors
=newArrayL
ist();
warnin
gs=newArra
yList();
showRe
sultsInGUI
=doShow;
doDisp
atchTransition
s=false;
menu
=null;
//doCh
eckStateChartM
odelConformi
ty=false;
if(sho
wResultsInGU
I){
gui=
newCheckerO
utputGUI(thi
s);
200
setTex
tInLabel();
}} /** *Perf
orms
adepth
firstsearch
tovisital
lsubnodes
ofthepassed
node.
* *@par
amchartThe
currentStat
eChart.
*@ret
urnReturns
True
ifno
errors
andno
warnings
were
found.
*/21
0public
finalboolea
ncheckDataS
tructure(final
StateChart
chart)
{errors
.clear();
warnin
gs.clear();
stateC
hart
=chart;
chart.
setChanged();
chart.
getAllObjects(
);dispat
chChart(chart)
;
depthf
irst
=newSt
ateChartDept
hFirstAdapte
r();
depthf
irst.traverse(
this,stateC
hart.getRoot
Node(),disp
atchRegions)
;22
0if
(sho
wResultsInGU
I){
113
G. Java Code
this.fir
eTableDataCh
anged();
setTextI
nLabel();
} return
((getErrors().
size()
==0)
&&(getWarn
ings().size(
)==
0));
} privat
efinalvoid
dispatchChar
t(finalStat
eChart
chart)
{BaseChec
krule;
230
for(int
i=0;
i<
rules.size()
;i++)
{rule
=(BaseCheck)
rules.get(i)
;if
((ru
le.isEnabled
())
&&(rul
e.isValidTar
get(chart)))
{rule.a
pply(this,
chart);
}}
} /**
240
*@param
oTheobje
ctto
perform
allchecks
on.
*/ public
finalvoid
dispatch(fin
alGraphicalO
bjecto)
{BaseChec
krule;
for(int
i=0;
i<
rules.size()
;i++)
{rule
=(BaseCheck)
rules.get(i)
;if
((ru
le.isEnabled
())
&&(rul
e.isValidTar
get(o)))
{rule.a
pply(this,
o);
}25
0if
((do
DispatchTran
sitions)
&&(o
instanceof
Node))
{Node
n=(Node)
o;
Iterat
oriter
=n.ge
tOutgoingTra
nsitions().i
terator();
while
(iter.hasNext(
)){
Transi
tion
t=(Tra
nsition)
iter.next();
if(rul
e.isValidTar
get(t)
260
&&(rul
e.isEnabled())
){
rule.app
ly(this,
t);
}}
}}
} /** *Return
sthetype
oftheStateC
hart.
270
*@retur
nThetype
oftheStateC
hart.
*/ public
finalString
getStateCh
artType(){
return
stateChart.get
ModelSource(
);} /** *Return
sthemodel
versionof
thecurrently
checkedstat
echart.
*@retur
nTheversio
nnumber
stri
ng.
*/28
0public
finalString
getStateCh
artVersion()
{
return
stateChart.g
etModelVersion
();
} /** *@retur
nThecollec
tion
ofall
warnings
that
occureddu
ring
thelast
run
*of
checkDataStruc
ture.
*/ public
finalCollecti
ongetWarni
ngs(){
return
warnings;
290
} /** * *@retur
nThecollec
tion
ofall
errors
that
occuredduri
ngthelast
runof
*checkD
ataStructure
.*/ public
finalCollecti
ongetError
s(){
return
errors;
}30
0/** * *@retur
nDoes
the
actual
instan
cedispatch
objectsof
type
Region?
*/ public
finalboolean
isDispatchRe
gions(){
return
dispatchRegi
ons;
} /**
310
* *@param
doDispatch
Denote
ifth
einstance
should
dispat
chRegion.
*/ public
finalvoid
setDispatchReg
ions(final
booleandoDisp
atch){
this.dis
patchRegions
=doDispat
ch;
} /** *This
method
loads
therulesfr
omthedire
ctorypassed
totheconstr
uctor.
*Theru
lesaredyna
micallyload
from
ajar
file
andinst
ancesof
thefound
320
*checks
arestored
inthe
*/ public
finalvoid
loadRules(){
rules.cl
ear();
File
f=newFile(t
his.rulePack
age);
if(!f.
exists()){
Checki
ngProperties
.getRobustness
Log().log(Lo
gFile.ALL,
"Passed
package"+
this.rulePac
kage
+"does
notexist.
"33
0+"No
rulesloaded
.");
return
;}else
{Checki
ngProperties
.getRobustness
Log().log(Lo
gFile.DETAIL
,"Startin
gto
load
rulesfrom:"
+this.ruleP
ackage);
} String
classname=
"";
Classc;
Object
o;34
0JarFile
jar=null;
114
G.3. Checking-Plug-In
//Mani
fest
m=null
;try{ jar=
newJarFile(
f);
if(jar
!=null){
Enumer
ationentrie
s=jar.entr
ies();
URL[]
url={(new
File(jar.get
Name())).toU
RL()};
URLCla
ssLoader
ucl
=newURLCla
ssLoader(url
,this
.getClas
s().getClass
Loader());
while
(entries.has
MoreElements
()){
350
classnam
e=((ZipEnt
ry)entries.
nextElement(
)).getName()
;if
((cl
assname.indexO
f(".class")
>-1)
&&(cla
ssname.index
Of("$")==
-1))
{
classn
ame=classnam
e.replaceAll
("/",".");
classnam
e=classnam
e.substring(
0,classn
ame.lastInde
xOf("."));
c=ucl.
loadClass(cl
assname);
360
if(c.g
etSuperclass
()==
BaseCh
eck.class)
{o=c.
newInstance();
if(o
instanceof
BaseCheck&&
cvclProcess!=
null){
((Base
Check)
o).set
CvclProcess(
cvclProcess)
;} if
(o!=
null){
rules.
add(o);
Checki
ngProperties
.getRobustne
ssLog().log(
LogFile.
DETAIL,
"Loading
ofrule:"
+classname
370
+"succ
essful.");
}}
}
}}else
{Checki
ngProperties
.getRobustne
ssLog().log(Lo
gFile.ERROR,
"Novali
djarfilesp
ecified.");
}38
0//load
RuleStatuses()
;}catch
(Exception
e){
e.prin
tStackTrace();
Checki
ngProperties.g
etRobustness
Log().log(Lo
gFile.ERROR,
"Rulelo
adingfailed
.");
}} /** *Loads
thestatuses
ofallrule
sin
thecu
rrentrulePack
age.
390
*/ /*privat
evoid
loadRu
leStatuses()
{BaseChec
kb;
for(int
i=0;
i<
rules.size()
;i++)
{b=(B
aseCheck)rule
s.get(i);
b.setE
nabled(Checkin
gProperties.
getRuleStatu
s(b.getCla
ss().getName
()));
/*b.se
tEnabled(Che
ckingPropert
ies.getRuleS
tatus(
this.r
ulePackage.s
ubstring(
this.rul
ePackage.las
tIndexOf(Fil
e.separatorC
har)
+1,
400
this.rul
ePackage.las
tIndexOf(’.’
))
+"."+
b.getRuleNam
e()));
*/ /*} }*
/
/** * *@ret
urnTheleve
lof
semantic
robustness
checks
*/41
0public
finalintge
tRobustnessL
evel()
{return
robustnessLe
vel;
} /** *Set
thelevelof
thechecks
manually.
*@par
amlevelThe
levelof
the
checks.
*/ public
finalvoid
setRobustnessL
evel(final
intlevel)
{this.r
obustnessLevel
=level;
420
} /** *This
method
prin
tstheerrors
andwarnings
,that
were
generateddu
ring
*chec
kDataStructu
re.
*@par
amwThedest
inationwrit
er,whereth
emessages
will
bewritte
nto.
**/
public
finalvoid
printMessages(
finalObject
w){
Checki
ngProblemr;
430
try{ for(i
nti=0;
i<errors.siz
e();
i++)
{r=(Che
ckingProblem
)errors.get
(i);
((Writer
)w).write("
Error"+(i
+1)
+":
"+r.ge
tProblem()
+"\n");
//Checki
ngProperties
.getSemLog()
.log(LogFile
.ERROR,
//);
} for(i
nti=0;
i<warnings.s
ize();
i++)
{44
0r=(Che
ckingProblem
)warnings.g
et(i);
((Writer
)w).write("
Warning"+
(i+1)
+":
"+r.ge
tProblem()
+"\n");
}}catc
h(IOException
e){
Checki
ngProperties
.getRobustne
ssLog().log(Lo
gFile.ERROR,
"Printin
gtheproble
mfailed.");
}}
450
/** *@ret
urnOnecolu
mnis
needed
fordisplayi
ngtheproble
msin
atabl
e.*/ public
finalintge
tColumnCount
(){
return
1;} /** *The
countof
rows
iscalculat
edby
adding
thesize
oftheerrors
and
*warn
ings
vector.
460
*@ret
urnThecoun
tof
rows
the
tablehasto
display.
115
G. Java Code
*/ public
finalintge
tRowCount()
{return
errors.size()
+warnings.s
ize();
} /** *This
method
transf
orms
thegive
ncell
coor
dinatesto
theappropriat
e*robust
ness
problem
andreturns
themessage
oftheprob
lem.
*@param
rowIndex
Theindexof
therowto
bedisplayed
470
*@param
colIndex
.*@retur
nThetext
tobe
displaye
din
thece
llwith
the
givencoordina
tes.
*/ public
finalObject
getValueAt
(final
intro
wIndex,fina
lintcolInd
ex){
String
result;
Checking
Problemp;
if(row
Index>=
erro
rs.size())
{p=(Che
ckingProblem
)(warnings.
get(rowIndex
-errors.siz
e()));
if(Che
ckingPropert
ies.showClas
sification())
{if
(Che
ckingPropert
ies.showCoun
ters()){
480
result
="[Warning
"+(rowInde
x-errors.s
ize()+1)
+"]
";}else
{result
="[Warning]
";}
}else
{if
(Che
ckingPropert
ies.showCoun
ters()){
result
="["+(row
Index-erro
rs.size()+
1)+"]
";}else
{result
="";
490
}}
}else
{p=(Che
ckingProblem
)(errors.ge
t(rowIndex))
;if
(Che
ckingPropert
ies.showClassi
fication())
{if
(Che
ckingPropert
ies.showCoun
ters()){
result
="[Error"
+(rowIndex
+1)
+"]
";}else
{result
="[Error]
";}
500
}else
{if
(Che
ckingPropert
ies.showCoun
ters()){
result
="["+(row
Index+1)
+"]
";}else
{result
="";
}}
} return
result
+p.ge
tProblem();
510
} /** *@param
col.
*@retur
nThestring
,whichis
shownin
the
header
ofthe
outputtable.
*/ public
finalString
getColumnNam
e(finalint
col)
{return
"Messages";
}
520
/**
* *@param
indexThe
indexof
the
Problem.
*@retur
nTheGraphi
calobjectof
theProblem.
* */ public
finalArrayL
istgetProbl
emsByIndex(f
inal
intinde
x){
Checking
Problemp;
if(ind
ex>(errors.
size()
+warn
ings.size())
){
530
return
null;
}else
{
if(ind
ex<errors.s
ize())
{p=(C
heckingProblem
)errors.get
(index);
}else
{p=(C
heckingProblem
)warnings.g
et(index
-errors.size(
));
} return
p.getObjects
();
540
}} /** * *@retur
nThetable
iftheguiis
shown.
*/ public
finalJTable
getOutputT
able()
{if
(sho
wResultsInGUI)
{return
gui.getTable
();
550
}else
{return
null;
}} /** * *@retur
nThecompon
entfrom
the
gui.
*/ public
finalJCompo
nent
getCom
ponent()
{56
0return
gui.getCompo
nent();
} /** *This
method
sets
thewarningan
derrormess
ages.
*/ privat
evoid
setTex
tInLabel()
{gui.setL
abelText(get
Summary());
}
570
/** *This
method
builds
thewarning
anderrorme
ssages.
*@retur
nThewarnin
ganderror
messages.
*/ public
finalString
getSummary
(){
String
result
="";
if(err
ors.size()
==1)
{result
=errors.siz
e()+"Erro
r,";
}else
{58
0result
=errors.siz
e()+"Erro
rs,";
116
G.3. Checking-Plug-In
} if(war
nings.size()
==1)
{result
+=warnings
.size()+"Wa
rning";
}else
{result
+=warnings
.size()+"Wa
rnings";
} return
result;
}59
0/** * *@retur
nIndexof
theappropri
atetabin
KIELFrame.
*/ public
finalintge
tTabbedIndex()
{return
tabbedIndex;
} /**
600
*Setter
fortheru
les.
*@param
tiTheinde
xof
theta
b.*/ public
finalvoid
setTabbedIndex
(final
intti
){
this.tab
bedIndex
=ti;
} /** *Getter
fortheru
les.
*@retur
nTherules.
610
*/ public
finalArrayL
istgetRules()
{return
(ArrayList)
rules.clone(
);} /** *Enable
sor
disabl
esarule.
*@param
ruleName
Thename
ofth
erule.
*@param
isEnabled
.*/
620
public
finalvoid
setEnabled(fin
alString
ruleName,
final
booleanisEn
abled)
{BaseChec
kitem;
JCheckBo
xMenuItemmI
tem;
for(int
i=0;
i<
rules.size()
;i++)
{item
=(BaseCheck)
rules.get(i)
;if
(ite
m.getRuleNam
e().equals(r
uleName)){
/*Checki
ngProperties
.setRuleStat
us(this.rule
Package.subs
tring(
this.rul
ePackage.las
tIndexOf(Fil
e.separatorC
har)
+1,
this.rul
ePackage.las
tIndexOf(’.’
))63
0+"."+
ruleName,is
Enabled);*/
item.set
Enabled(isEn
abled);
if(menu
!=null){
mItem=
(JCheckBoxMe
nuItem)menu
.getItem(i
+2);
mItem.se
tSelected(is
Enabled);
}
}}
640
} /** *Clea
rstheerrors
andwarnings
inthetabl
e.*/ public
finalvoid
refresh(){
errors
.clear();
650
warnin
gs.clear();
if(sho
wResultsInGU
I){
this.set
TextInLabel(
);this.fir
eTableDataCh
anged();
}} /** *Clea
rsalluser
input.
*/66
0public
finalvoid
clearUserInput
(){
JTable
table=getO
utputTable()
;table.
clearSelecti
on();
} /** *Sett
erforthepr
operty
DoDisp
atchTransiti
ons.
*If
theproperty
issetto
true,theloaded
checks
will
also
be*appl
iedto
transi
tions.
670
*@par
amdoDispatch
Booleanvalu
e,denoting
if*tran
sitionswill
bechecked
also.
*/ public
finalvoid
setDoDispatchT
ransitions(f
inal
boolean
doDispatch)
{this.d
oDispatchTra
nsitions
=do
Dispatch;
} /** *Mess
agehandler
forthemessag
e,that
ane
wstatechart
wasloaded.
680
*@par
amsc
Thene
wstatechart
*/ public
finalvoid
newStateChartL
oaded(final
StateChart
sc){
//Syst
em.out.print
ln("NewStatec
hart
loaded
");
String
model=sc.g
etModelSourc
e()+sc.get
ModelVersion
();
//repl
aceallwhit
espaces
model
=model.repl
aceAll("
",""
);//
all
othercharak
ters
that
needed
tobe
replaced
model
=model.repl
aceAll("[-|+|*
|.|#|’|/|(|)
]","");
690
String
rule
=Chec
kingProperties
.modelRuleSe
t(model);
//Syst
em.out.print
ln("Loading
rulesetfor
"+model+
"...");
//Syst
em.out.print
ln(rule);
if(rul
e==
null)
{rule
="";
} if(rul
e.equals("")
){
//No
Rulesetfor
theactual
Statechart
available
//enab
leallrule
sby
default
for(i
nti=0;
i<rules.size
();i++)
{70
0BaseChec
kc=(BaseC
heck)rules.
get(i);
117
G. Java Code
this.s
etEnabled(c.ge
tRuleName(),
true);
}}else
{//
ifth
erule
isin
therulese
t,enable
it.
for(int
i=0;
i<
rules.size()
;i++)
{BaseCh
eckc=(BaseC
heck)rules.
get(i);
this.s
etEnabled(c.ge
tRuleName(),
rule.ind
exOf(c.getRu
leName())>
-1);
}71
0}
} /** *Setter
forthemain
menu
item
that
reflects
thestatus
esof
*thelo
aded
rules.
*@param
mAmenu,
that
hasthe
rulesas
item
s*/
720
public
finalvoid
setMenu(fina
lJMenum)
{this.men
u=m;
} /** *Getth
echartcurr
entlybeing
checked.
*@retur
nAStatecha
rt.
*/
public
finalStateCha
rtgetState
Chart(){
return
this.stateCh
art;
730
} /** *Useth
ismethod
toenable
load
edrulesacco
rdingto
aprofile.
*@param
profileA
string
contai
ngtherules
toenable
separatedby
*comma.
*/ public
finalvoid
applyRuleProfi
le(final
Stri
ngprofile)
{
740
//disa
bleallrule
sat
first
for(int
i=0;
i<
rules.size()
;i++)
{BaseCh
eckc=(BaseC
heck)rules.
get(i);
setEna
bled(c.getRu
leName(),fals
e);
} //now
enable
theru
lesfoundin
theprofile
for(int
i=0;
i<
rules.size()
;i++)
{BaseCh
eckc=(BaseC
heck)rules.
get(i);
this.s
etEnabled(c.ge
tRuleName(),
750
profile.
indexOf(c.ge
tRuleName())
>-1);
}}
}
118
G.3. Checking-Plug-In
G.3
.2.
Bas
eChe
ck.jav
a
//$Id:
BaseCheck.ja
va,v
1.10
2006/08/04
09:5
4:13
kbeEx
p$
packag
ekiel.check
ing;
import
java.util.Ar
rayList;
import
java.util.It
erator;
import
kiel.dataStr
ucture.Compo
siteState;
import
kiel.dataStr
ucture.Initi
alState;
import
kiel.dataStr
ucture.Node;
10import
kiel.dataStr
ucture.Trans
ition;
/** *<p>Des
cription:Th
isinterface
definesame
thod
tobe
implemented
byall
*custom
robustness
checks.</p>
*<p>Cop
yright:(c)
2006</p>
*<p>Com
pany:UniKi
el</p>
20*@autho
r<a
href="
mailto:kbe@inf
ormatik.uni-
kiel.de">Ken
Bell</a>
*@autho
r<a
href="
mailto:gsc@inf
ormatik.uni-
kiel.de">Gun
narSchaefer
</a>
*@versi
on$Revisio
n:1.10
$last
modified
$Date:
2006/0
8/04
09:54:13
$* */ public
abstract
classBaseChec
k{
/** *True,
ifthechec
kis
enabled.
*/30
private
booleanenab
led=true;
/** *This
method
isca
lled
from
aninstance
of*{@link
kiel.check
ing.StateCha
rtCheckerBas
e}.
*@param
checkerTh
echeckerwh
erethe
*{@link
kiel.check
ing.Checking
Problem}
will
be*added.
*@param
oThecurr
entobject
inthedepth
firstsearch
ofthestatec
hart.
*/40
public
abstract
void
apply(StateC
hartCheckerB
asechecker,
Object
o);
/** *Determ
ines
ifthis
rule
should
beinvoked
onthe
*curren
t{@link
kiel.dataStruc
ture.Graphic
alObject}.
*@param
oThecurr
entobject
inthedepth
firsttraversa
l.*@retur
nReturnstr
ueif
theru
leshould
beappliedto
object
o.*/ public
abstract
bool
eanisValidT
arget(final
Object
o);
50/** *.
*@param
isEnabled
.*/ public
finalvoid
setEnabled(fin
albooleanis
Enabled)
{
this.e
nabled
=isEn
abled;
} /**
60*.
*@ret
urnTrue,if
thecheckis
enabled.
*/ public
finalboolea
nisEnabled(
){
return
this.enabled
;} /** *Retu
rnsthename
oftherule.
*@ret
urnThename
oftherule.
70*/ public
finalString
getRuleName(
){
String
name;
name
=this.getClas
s().getName(
);return
name.substri
ng(name.last
IndexOf(’.’)
+1);
} /** *Plac
eholderfor
theautogenera
tedchecks.
*Call
edif
astat
echart
confor
msto
thech
eck.
80*@par
amoThesour
ceof
aprob
lem
*@par
amcheckerTh
einstance
ofthechecke
rthat
holds
theproblems
.*/ public
void
generate
ConformsMess
age(finalSt
ateChartChec
kerBasechec
ker,
final
Object
o){
} /** *Plac
eholderfor
theautogenera
tedchecks.
Called
ifa
checkfailed
.90
*@par
amoThesour
ceof
aprob
lem.
*@par
amcheckerTh
einstance
ofthechecke
rthat
holds
theerror.
*/ public
void
generate
FailsMessage
(final
StateC
hartCheckerB
asechecker,
final
Object
o){
} /** *Sets
therobustne
ssproperties
.10
0*@par
ampropsThe
robustness
properties
tobe
set.
*/ public
void
setPrope
rties(final
CheckingProp
erties
props)
{
} /** *Sets
theCVCL
process.
*@par
amcvclProc
Theprocessob
ject.
*/11
0public
void
setCvclP
rocess(final
Processcv
clProc){
119
G. Java Code
} /** *This
method
will
getallparent
sof
thepa
ssed
node.
*@param
nThenode
tocollectal
lparentsfo
r.*@retur
nAlist
ofallnodes,
that
arepare
ntnodesof
thepassed
node.
*/12
0public
finalArrayL
istgetParen
tStates(fina
lObject
n){
ArrayLis
tresult
=ne
wArrayList(
);
if(n
instanceof
Node
){
Composit
eState
c=
((Node)n).g
etParent();
while(c
!=null){
result
.add(c);
c=c.
getParent();
}13
0} return
result;
} /** *This
isonly
ameth
odstub.
*Canbe
used
tofill
with
anal
gorithmto
getallchildr
enof
anode
.*@param
nThenode
tocollectal
lchildnode
sfor.
*@retur
nAlist
ofallchildren
nodes.
140
*/ public
finalArrayL
istgetChild
States(final
Node
n){
//TODO
Evaluate
ifthemethod
isneeded
return
null;
} /** *This
method
checks
,wheterna
path
from
thepassed
Node
tothe
*Initia
lStateof
thesame
Regi
onrespektivl
yORStateex
ists.
150
*@param
nThenode
tocheckif
itcanbe
reachedfrom
theInitialSta
te.
*@retur
nTrue,if
aconnection
exists,fals
eotherwise.
*/ public
finalboolean
isConnectedT
oInitial(fin
alNode
n){
ArrayLis
twhite=ne
wArrayList(
);ArrayLis
tblack=ne
wArrayList(
);
white.ad
d(n);
Node
wNode=null;
160
Transiti
ont=null
;Iterator
iter
=null
;
while(w
hite.size()
>0)
{wNode
=(Node)
whit
e.get(0);
if(wNo
deinstance
ofInitialSta
te){
return
true;
}
170
white.
remove(0);
if(bla
ck.indexOf(w
Node)==
-1)
{black.ad
d(wNode);
} iter
=wNode.getInc
omingTransit
ions().itera
tor();
while
(iter.hasNex
t())
{t=(Tra
nsition)
iter.next();
if((wh
ite.indexOf(
t.getSource())
==-1)
&&(bla
ck.indexOf(t
.getSource())
==-1))
{18
0white.
add(t.getSou
rce());
}}
} return
false;
}
}
120
G.3. Checking-Plug-In
G.3
.3.
Che
cker
Out
putG
UI.ja
va
//$Id:
CheckerOutpu
tGUI.java,v
1.12006/04/
1010:22:22
gscExp$
packag
ekiel.check
ing;
import
java.awt.Bor
derLayout;
import
javax.swing.
JComponent;
import
javax.swing.
JLabel;
import
javax.swing.
JPanel;
import
javax.swing.
JScrollPane;
10import
javax.swing.
JTable;
import
javax.swing.
ListSelectio
nModel;
/** *<p>Des
cription:Th
isclassdisp
lays
thepr
oblems
found
byarobust
ness
*checke
r.</p>
* *<p>Cop
yright:(c)
2006</p>
*<p>Com
pany:UniKi
el</p>
*@autho
r<a
href="
mailto:kbe@inf
ormatik.uni-
kiel.de">Ken
Bell</a>
20*@autho
r<a
href="
mailto:gsc@inf
ormatik.uni-
kiel.de">Gun
narSchaefer
</a>
* *@versi
on$Revisio
n:1.1$last
modified
$Date:
2006/04/
1010:22:22
$*/ public
classChecke
rOutputGUI
{
/** *Theta
blethat
displays
theda
ta.
*/30
private
JTable
tabl
e;
/** *Thepa
nelthat
holdsthetabl
eandthela
bel.
*/ private
JPanel
pane
l;
/** *Thela
beldisplys
thenumber
oferrors
andwarnings.
40*/ private
JLabel
labe
l;
/** *This
method
isus
edto
create
andsetupth
etable
*which
isdisplaye
din
thefram
e.*@param
cTheStat
eChartChecke
rBase.
*/ private
void
create
Table(finalSt
ateChartChec
kerBasec)
{
50table
=newJTable(c
);/*
Set
theselectio
nmode
tofu
llrowselect
ion*/
table.
setSelectionMo
de(ListSelec
tionModel.MU
LTIPLE_INTER
VAL_SELECTIO
N);
/*Set
thecell
rend
erer.*/
table.
getColumnModel
().getColumn
(0).setCellR
enderer(
newMyCe
llRenderer(c
));
} /** *The
constructor
oftheframe.
60*It
sets
thetitl
eof
thefram
e,createsan
dadds
the
tableto
itse
lf.
*@par
amcTheStat
eChartChecke
rBase.
*/ public
CheckerOutpu
tGUI(final
StateChartChec
kerBasec)
{
create
Table(c);
label
=newJLabel("
");
panel
=newJPanel()
;panel.
setLayout(new
BorderLayout
());
panel.
add(label,
BorderLayout.N
ORTH);
70panel.
add(newJScrol
lPane(table)
,BorderLayo
ut.CENTER);
} /** *Get
thetable.
*@ret
urnTheinst
ance
oftheta
ble.
*/ public
finalJTable
getTable()
{return
table;
}80
/** *@ret
urnReturn
theScrollpane
*/ public
finalJCompo
nent
getCompo
nent()
{return
panel;
} /** *
90*@par
amtText
tobe
displayed
inthelabe
labovethe
table.
*/ public
finalvoid
setLabelText(f
inal
String
t){
label.
setText(t);
}}
121
G. Java Code
G.3
.4.
Che
ckin
gPro
blem
.jav
a
//$Id:
CheckingProb
lem.java,v
1.42006/07/21
17:51:56
kbeExp$
packag
ekiel.checkin
g;
import
java.util.Ar
rayList;
import
kiel.dataStr
ucture.Graph
icalObject;
/**
10* *<p>D
escription:
This
classho
ldstheinfo
rmations
abou
tproblems
that
*occu
redwhen
pars
ingthedata
structure.
Instanceswill
bestored
inan
*inst
ance
of{@li
nkkiel.check
ing.StateCha
rtCheckerBas
e}.</p>
*<p>C
opyright:(c
)2006</p>
*<p>C
ompany:Uni
Kiel</p>
*@aut
hor<a
href="
mailto:kbe@i
nformatik.un
i-kiel.de">K
enBell</a>
*@aut
hor<a
href="
mailto:gsc@i
nformatik.un
i-kiel.de">G
unnarSchaef
er</a>
*@ver
sion
$Revisio
n:1.4$la
stmodified
$Date:
2006/0
7/21
17:51:56
$*
20*/ public
classChecki
ngProblem{
/** *Holds
ashortdesc
riptionof
theproblem.
*/ privat
eString
prob
lem;
/*30
*Holds
theobject
whichis
the
source
ofth
eproblem.
*/ //priv
ateGraphica
lObjectobject
;
/** *Holds
theobject
that
arethe
source
ofth
eproblem.
*/ privat
eArrayList
objects;
/**
40*Theco
nstructorof
therobustne
ssproblem.
*@param
oThesource
oftheprob
lem.
*@param
pAproblem
description.
*/ public
CheckingProb
lem(finalOb
ject
o,fina
lString
p){
this.obj
ects
=newAr
rayList();
this.pro
blem
=p;
this.obj
ects.add(o);
}
50/** * *@param
oAn
ArrayL
istcontaini
ngthesource
oftheprob
lem.
*@param
pAdescript
ionof
the
problem.
*/ public
CheckingProb
lem(finalAr
rayListo,
finalString
p){
this.pro
blem
=p;
this.obj
ects
=new
ArrayList(o);
}60
/** * *@retur
nReturnsth
esource
oftheproblem.
*/ public
finalGraphica
lObjectgetF
irstObject()
{return
(GraphicalOb
ject)objects.
get(0);
}
70/** *Setth
esource
ofaproblemma
nually.
*@param
oThesour
ceof
thepr
oblem.
*/ public
finalvoid
setFirstObject
(final
Object
o){
this.obj
ects.set(0,
o);
} /**
80* *@retur
nAshortde
scriptionof
theproblem.
*/ public
finalString
getProblem()
{return
problem;
} /** *
90*@param
pSetthe
description
oftheproble
mmanually.
*/ public
finalvoid
setProblem(fin
alString
p){
this.pro
blem
=p;
} /** * *@retur
nThesource
sof
thepr
oblemin
anArrayList.
100
*/ public
finalArrayLis
tgetObjects
(){
return
objects;
} /** * *@param
oAn
ArrayL
istcontaini
nggraphica
lobjects.
*/11
0public
finalvoid
setObjects(fin
alArrayList
o){
this.obj
ects
=o;
}
}
122
G.3. Checking-Plug-In
G.3
.5.
Che
ckin
gPro
per
ties
.jav
a
//$Id:
CheckingProp
erties.java,
v1.12
2006/1
1/08
10:13:
03kbeExp$
packag
ekiel.check
ing;
import
java.awt.Col
or;
import
java.util.Ar
rayList;
import
java.util.It
erator;
import
java.util.Se
t;
import
kiel.util.pr
eferences.Pr
eferences;
10import
kiel.util.Lo
gFile;
/** *<p>Des
cription:Us
edto
load
andstoreuser
defineable
properties.<
/p>
* *<p>Cop
yright:(c)
2006</p>
*<p>Com
pany:UniKi
el</p>
*@autho
r<a
href="
mailto:gsc@inf
ormatik.uni-
kiel.de">Gun
narSchaefer
</a>
*@autho
r<a
href="
mailto:kbe@inf
ormatik.uni-
kiel.de">Ken
Bell</a>
*@versi
on$Revisio
n:1.12
$last
modified
$Date:
2006/1
1/08
10:13:03
$20
*/ public
finalclass
CheckingProp
erties
{
/** *These
aretheinte
rnal
proper
ties.
*/ private
static
Pref
erencesprefs;
/** *This
thekeyfor
theresouce
file
containi
ngthedefaul
tvalues.
30*/ private
static
fina
lString
DEFA
ULTRESOURCE
="checking.
properties";
/** *Thero
bustness
log.
*/ private
static
LogF
ilecheckingLo
g=newLogF
ile("Checkin
g",0);
static
{prefs=
Preferences.
createInstan
ce("checking
",40
Checki
ngProperties
.class.getRe
source(DEFAULT
RESOURCE),
checki
ngLog);
checking
Log.setLogLe
vel(getRobus
tnessLogLeve
l());
} /** *@retur
nTherobust
ness
log.
*/ public
static
LogFil
egetRobustn
essLog()
{return
checkingLog;
50} /** *The
semantic
chec
kerlog.
*/ private
static
LogF
ilecorrLog=
newLogFile(
"Correctness
",
getCor
rLogLevel())
;
/** *@ret
urnThesema
ntic
checker
log.
60*/ public
static
LogFil
egetCorrLog
(){
return
corrLog;
} /** *The
semantic
chec
kerlog.
*/ private
static
LogF
ilesemLog
=newLogFile(
"SemanticRo
bustness",
getSem
LogLevel());
70/** *@ret
urnThesema
ntic
checker
log.
*/ public
static
LogFil
egetSemLog(
){
return
semLog;
} /** *The
syntacticch
eckerlog.
80*/ private
static
LogF
ilesynLog
=newLogFile(
"Syntactic
Robustness",
getSyn
LogLevel());
/** *@ret
urnThesynt
acticchecker
log.
*/ public
static
LogFil
egetSynLog(
){
return
synLog;
}90
/** *Stat
icclass,
donotinstanti
ate.
*/ private
CheckingProp
erties()
{
} /** *This
isthekey
forproperty
keydelimite
r.10
0*/ private
static
fina
lString
DELI
MITER=".";
/** *This
isthekey
forthechec
king
properti
es.
*/ private
static
fina
lString
CHEC
KING
="che
cking";
/** *This
isthekey
fortheprop
erty
holding
thecolorfo
rerrors.
110
*/
123
G. Java Code
privat
estatic
fina
lString
ERRORCOLOR
="e
rrorColor";
/** *This
isthekeyfo
rtheproper
tyholdingth
ecolorfor
warnings.
*/ privat
estatic
fina
lString
WARNINGSCOLOR=
"warningColo
r";
/** *This
isthekeyfo
rtheproper
tydenoting
ifasingle
rule
isenab
led.
120
*/ privat
estatic
fina
lString
RULESENABLED
="ruleEnabled
";
/** *Thena
meof
theke
yforthecv
clMode.
*/ privat
estatic
fina
lString
CVCLMODE
="cvc
lMode";
/** *Thena
meof
theke
yforthelo
glevel.
130
*/ privat
estatic
fina
lString
CHECKINGLOGLEVEL
="Checkin
gLogLevel";
/** *Thena
meof
theke
yforthelo
glevelof
correctnessch
ecks.
*/ privat
estatic
fina
lString
CORRECTNESSLOGLE
VEL="CorrL
ogLevel";
/** *Thena
meof
theke
yforthelo
glevelof
semantic
chec
ks.
140
*/private
static
fina
lString
SEMA
NTICLOGLEVEL
="SemLogLev
el";
/** *The
name
ofthe
keyforthe
loglevelof
syntacticch
ecks.
*/ private
static
fina
lString
SYNT
ACTICLOGLEVE
L="SynLogL
evel";
/** *Theke
ydenoting
ifto
show
theID
ofthe
Object
inth
emessage.
150
*/ privat
estatic
fina
lString
SHOWNODEID
="s
howNodeID";
/** *Thena
meof
theke
yforthepr
operty
ifth
ename
ofth
eobject
is*return
edin
theme
ssage.
*/ privat
estatic
fina
lString
SHOWNODENAME
="showNodeNam
e";
/**
160
*Thena
meof
theke
y.*/ privat
estatic
fina
lString
SHOWRULENAME
="showRuleNam
e";
/** *Proper
tyname.
*/ privat
estatic
fina
lString
SHOWCLASSIFICATI
ON="showC
lassificatio
n";
/**
170
*Thepr
operty
ifth
ecounters
areshown.
*/ private
static
final
String
SHOW
COUNTERS
="s
howCounters"
;
/** * */ private
static
final
String
SHOW
TRANSITIONS
="showTransit
ions";
/**
180
* */ private
static
final
String
SHOW
PRIORITY
="s
howPriority"
;
/** *Thepr
operty
ofth
ebenchmarki
ngpart.
*/ private
static
final
String
TIMI
NG="timing"
;
/**
190
*Thepr
efix
forth
ebenchmark
file.
*/ private
static
final
String
TIMI
NGPRESTRING
="timingPre
string";
/** *Thepo
stfixforth
ebenchmark
file.
*/ private
static
final
String
TIMI
NGPOSTSTRING
="timingPos
tstring";
/**
200
*Proper
tyforthe
transition
overlapcheck.
*/ private
static
final
String
OVER
LAPHIERARCHY
="transitio
nOverlapHier
archy";
/** *Theke
yforthepr
ofiles.
*/ private
static
final
String
MODE
LRULESET
="m
odelRuleSet"
;
/**
210
*Reload
stheproper
ties
file.
*/ protecte
dstatic
void
reload()
{prefs.re
load();
} /** * *@retur
nThecolor
oferrors.
*/22
0public
static
Color
getErrorColo
r(){
return
prefs.getRGB
Color(CHECKI
NG+DELIMITE
R+ERRORCOL
OR);
} /** * *@retur
nThecolor
ofwarnings
.*/ public
static
Color
getWarningCo
lor(){
return
prefs.getRGB
Color(CHECKI
NG+DELIMITE
R+WARNINGS
COLOR);
230
}
124
G.3. Checking-Plug-In
/** *Reads
therule
status
from
theproperties
.*@param
ruleName
Thename
ofth
erule.
*@retur
nThestatus
oftherule
.*/
/*publ
icstatic
booleangetRul
eStatus(fina
lString
rule
Name){
return
prefs.getBoo
lean(CHECKIN
G+DELIMITE
R+RULESENABL
ED+DELI
MITER+ruleNa
me,true);
240
}*/
/** *Sets
therule
stat
usin
thepr
operties.
*@param
ruleName
Thename
ofth
erule.
*@param
valueThe
value.
*/ public
static
void
setRuleStatus(
finalString
ruleName,
final
booleanvalu
e){
prefs.se
tBoolean(rul
eName,
valu
e);
250
} /** *@retur
n.
*/ public
static
intge
tRobustnessL
ogLevel(){
return
prefs.getInt
(CHECKING+
DELIMITER+
CHECKINGLOGLEV
EL);
} /**
260
*@retur
n.
*/ public
static
intge
tCorrLogLeve
l(){
return
prefs.getInt
(CHECKING+
DELIMITER+
CORRECTNESSLOG
LEVEL);
} /** *@retur
n.
*/ public
static
intge
tSemLogLevel
(){
270
return
prefs.getInt
(CHECKING+
DELIMITER+
SEMANTICLOGLEV
EL);
} /** *@retur
n.
*/ public
static
intge
tSynLogLevel
(){
return
prefs.getInt
(CHECKING+
DELIMITER+
SYNTACTICLOGLE
VEL);
}
280
/** *@ret
urnWhetherto
useCVCL
libor
bin.
*/ public
static
boolea
nisCvclMode
Bin(){
return
prefs.getStr
ing(CHECKING
+DELIMITER
+CVCLMODE)
.equalsI
gnoreCase("b
in");
} /** *@ret
urn.
290
*/
public
static
boolea
nshowNodeID
(){
return
prefs.getStr
ing(CHECKING
+DELIMITER
+SHOWNODEID
).equals(
"true");
} /** * */
300
public
static
boolea
nshowRuleNa
me()
{return
prefs.getStr
ing(CHECKING
+DELIMITER
+SHOWRULENA
ME)
.equal
s("true");
} /** *@ret
urn.
*/ public
static
boolea
nshowNodeNa
me()
{return
prefs.getStr
ing(CHECKING
+DELIMITER
+SHOWNODENA
ME)
310
.equals(
"true");
} /** *@ret
urn.
*/ public
static
boolea
nshowClassi
fication()
{return
prefs.getStr
ing(CHECKING
+DELIMITER
+SHOWCLASSI
FICATION)
.equals(
"true");
}32
0/** *@ret
urn.
*/ public
static
boolea
nshowCounte
rs()
{return
prefs.getStr
ing(CHECKING
+DELIMITER
+SHOWCOUNTE
RS)
.equals(
"true");
} /**
330
*@ret
urn.
*/ public
static
boolea
nshowTransi
tions(){
return
prefs.getStr
ing(CHECKING
+DELIMITER
+SHOWTRANSI
TIONS)
.equals(
"true");
} /** *@ret
urn.
*/34
0public
static
boolea
nshowPriori
ty()
{return
prefs.getStr
ing(CHECKING
+DELIMITER
+SHOWPRIORI
TY)
.equals(
"true");
} /** *@ret
urn.
*/ public
static
boolea
ntiming()
{return
prefs.getStr
ing(CHECKING
+DELIMITER
+TIMING).eq
uals("true")
;35
0}
125
G. Java Code
/** *@retur
n.
*/ public
static
Stri
ngtimingPres
tring(){
return
prefs.getStrin
g(CHECKING
+DELIMITER
+TIMINGPRES
TRING);
} /**
360
*@retur
n.
*/ public
static
Stri
ngtimingPost
string()
{return
prefs.getStrin
g(CHECKING
+DELIMITER
+TIMINGPOST
STRING);
} /** *@retur
n.
*/ public
static
bool
eanoverlapH
ierarchy()
{37
0return
prefs.getStrin
g(CHECKING
+DELIMITER
+OVERLAPHIE
RARCHY)
.equals(
"true");
} /** *Getth
eprofileof
rulesfora
modelaccord
ingto
aru
leset.
*@param
modelString
Astring
containing
the
modelsource
andversion.
*@retur
nAstring
containing
allrules,
that
areautoma
ticallyenable
d*when
loadingastat
echart.
380
*/ public
static
Stri
ngmodelRuleS
et(final
Stri
ngmodelStr
ing)
{//
retu
rnprefs.getS
tring(CHECKI
NG+DELIMI
TER+MODELR
ULESET
//+DE
LIMITER+ru
leSet+DELI
MITER+mode
lString);
return
prefs.getStrin
g(CHECKING
+DELIMITER
+MODELRULES
ET+DELI
MITER+modelS
tring);
} /** *Useth
ismethod
togettheli
stof
availabl
eprofiles.
390
*@retur
nList
cont
aining
thena
mesof
availa
bleprofiles
.*/ public
static
ArrayL
istgetAvail
ableProfiles
(){
ArrayLis
tresult
=newArrayLis
t();
Setkeys
=prefs.ge
tUserKeySet(
);String
key="";
String
id=CHECKING
+DELIMITE
R+MODELRULES
ET+DELIMI
TER;
Iterator
iter
=keys
.iterator();
while(i
ter.hasNext(
)){
key=
(String)
iter
.next();
400
if(key
.indexOf(id)
>-1){
result
.add(key.sub
string(id.leng
th()));
}} return
result;
} /**
410
*This
method
return
sthevalue
fortheprof
ilepassed
intheparam.
*@param
profileNam
eThename
oftheprofile
toreturn
*@retur
nAcommase
paratedstri
ngcontaining
namesof
rules.
*/ public
static
String
getProfile(f
inal
String
profileName)
{return
prefs.getStr
ing(CHECKING
+DELIMITER
+MODELRULES
ET+DELI
MITER+prof
ileName);
}
}
126
G.3. Checking-Plug-In
G.3
.6.
MyC
ellR
ende
rer.ja
va
//$Id:
MyCellRender
er.java,v1.
42006/05/31
15:00:20
kbeExp$
packag
ekiel.check
ing;
import
java.awt.Col
or;
import
java.awt.Com
ponent;
import
javax.swing.
JTable;
import
javax.swing.
JTextArea;
import
javax.swing.
table.TableC
ellRenderer;
10/** *Descri
ption:
The
cell
renderer
forthetabl
eof
errors
andwarnings
.*<p>Cop
yright:(c)
2006</p>
*<p>Com
pany:UniKi
el</p>
*@autho
r<a
href="
mailto:kbe@inf
ormatik.uni-
kiel.de">Ken
Bell</a>
*@autho
r<a
href="
mailto:gsc@inf
ormatik.uni-
kiel.de">Gun
narSchaefer
</a>
*@versi
on$Revisio
n:1.4$last
modified
$Date:
2006/05/
3115:00:20
$*/ public
classMyCell
Renderer
extendsJTextAre
aimplements
TableCellR
enderer{
20/** *Theau
tomatically
generatedse
rial
Versio
nUID.
*/ private
static
final
long
serial
VersionUID
=809947178181
1987891L;
/** *TheSt
ateChartChec
kerBase.
*/ private
StateChartCh
eckerBasech
ecker;
30/** *Constr
uctorof
aCellRenderer
.*@param
cTheStat
eChartChecke
rBase.
*/ public
MyCellRender
er(final
Stat
eChartChecke
rBasec)
{this.che
cker
=c;
setLin
eWrap(true);
setWra
pStyleWord(tru
e);
}40
/** *@par
amaTable
Thetableof
whichthegive
ncell
hasto
berendered
.*@par
amvalueThe
valuethat
hasto
bedisp
layed.
*@par
amisSelected
Denoting
ifthecell
isselected.
*@par
amhasFocus
Denoting
ifth
ecell
has
thefocus.
*@par
amrowThero
windex
ofth
ecell.
*@par
amcolumn
Thecolumnindex
ofthecell
.*@ret
urnAinstan
ceof
therend
erer.
*/50
public
finalCompon
entgetTable
CellRenderer
Component(fi
nalJTable
aTable,
finalOb
ject
value,
finalboolea
nisSelected
,finalbo
oleanhasFoc
us,finalin
trow,
final
intcolumn)
{this.set
Text(value.t
oString());
setSize(
aTable.getCo
lumnModel().
getColumn(co
lumn).getWidth
(),
getPrefe
rredSize().h
eight);
if(row
<checker.ge
tErrors().si
ze()){
this.set
Foreground(C
heckingPrope
rties.getErr
orColor());
}else
{this.set
Foreground(C
heckingPrope
rties.getWar
ningColor())
;60
} if(aTabl
e.getRowHeig
ht(row)!=
getPreferred
Size().height)
{aTable.s
etRowHeight(
row,
getPre
ferredSize()
.height);
} if(isSel
ected)
{this.set
Background(a
Table.getSel
ectionBackgr
ound());
this.set
Foreground(C
olor.BLACK);
}else
{this.set
Background(C
olor.WHITE);
}70
return
this;
}}
127
G. Java Code
G.3
.7.
ISta
teCha
rtV
isitor
.jav
a
packag
ekiel.util;
import
java.util.Co
llection;
import
kiel.dataStr
ucture.Graph
icalObject;
import
kiel.dataStr
ucture.State
Chart;
/**
*10
*<p>T
itle:Kiel
CheckerInterf
ace.</p>
* *<p>D
escription:An
interface
forcheckers
workingon
*kiel
.datastructure
.StateChart.
</p>
* *<p>C
opyright:Copy
right(c)20
06</p>
* *<p>C
ompany:UniKi
el</p>
* *@aut
hor<a
href="
mailto:kbe@i
nformatik.un
i-kiel.de">Ken
Bell</a>
20*@aut
hor<a
href="
mailto:gsc@i
nformatik.un
i-kiel.de">Gun
narSchaefer
</a>
*@ver
sion
$Revisio
n:1.4$last
modified
$Date:
2006/04/
0309:29:59
$*/ public
interfaceIS
tateChartVis
itor
{
/** *This
method
does
thedatastruct
urechecking
.
*@param
chartASt
atechart
*@retur
nbooleantr
ueif
there
whereno
prob
lems
inthe
parsetree.
30*/ boolean
checkDataStr
ucture(State
Chartchart)
;
/** *This
method
isca
lled
when
anobject
hasto
bedispatch
ed.
*<br>Se
eStateChart
DepthFirstAd
apterfora
sample.
*@param
oThecurr
entlyhandle
dobject
ofth
eStatechart
.*@see
kiel.util.St
ateChartDept
hFirstAdapter
*/40
void
disp
atch(final
GraphicalObj
ecto);
/** *Askth
ismethod
forwarnings
foundin
the
StateChart
datastructure.
*@retur
nCollection
ofStateCha
rtProblems
describing
thewarnings.
*/ Collecti
ongetWarning
s();
/** *Askth
ismethod
forerrors
foundin
theSt
ateChart
data
structure.
50*@retur
nCollection
ofStateCha
rtProblems
describing
theerrors.
*/Collecti
ongetErrors(
);}
128
G.3. Checking-Plug-In
G.3
.8.
Sta
teCha
rtD
epth
First
Ada
pter
.jav
a
//$Id:
StateChartDe
pthFirstAdap
ter.java,v
1.62006/07/21
17:52:47
kbeExp$
packag
ekiel.util;
import
java.util.Ar
rayList;
import
kiel.dataStr
ucture.Compo
siteState;
import
kiel.dataStr
ucture.Node;
import
kiel.dataStr
ucture.Regio
n;
10/** *<p>Des
cription:St
atechartvi
sitorusing
thedepthfi
rstsearch
to*traver
sethedata
structure</p>
*<p>Cop
yright:(c)
2006</p>
*<p>Com
pany:UniKi
el</p>.
*@autho
r<a
href="
mailto:kbe@inf
ormatik.uni-
kiel.de">Ken
Bell</a>
*@autho
r<a
href="
mailto:gsc@inf
ormatik.uni-
kiel.de">Gun
narSchaefer
</a>
*@versi
on$Revisio
n:1.6$last
modified
$Date:
2006/07/
2117:52:47
$*/ public
classStateC
hartDepthFir
stAdapter{
20/** * *@param
intf
Thevi
sitorwhose
dispatch
method
iscalled
when
anode
is*found
*@param
root
Thest
artnode
ofthesearch
*@param
doVisitReg
ions
Denoting
wheter
todispatch
regi
onsto
thevi
sitor
*or
not
*@retur
nCanbe
modified
forla
terusage.
*/30
public
finalboolea
ntraverse(f
inal
IStateCh
artVisitor
intf,
final
Node
root,fi
nalboolean
doVisitRegio
ns){
ArrayL
iststack=ne
wArrayList(
);Node
n;
stack.
add(root);
while
(stack.size()
>0)
{
40n=(N
ode)
stack.re
move(0);
/** *Theno
deis
dispat
ched
ifeith
ertheparame
terdoVisitR
esions
is*true
orthenode
isnotaregi
on.
*/ if(doV
isitRegions
||(!(n
inst
anceof
Region
))){
intf.dis
patch(n);
}
50if
(ninstanceof
CompositeState
){
stack.ad
dAll(((Compo
siteState)
n).getSubnodes
());
}} return
true;
}}
129
G. Java Code
G.4
.X
MI-File
inte
rfac
e
G.4
.1.
XM
I.ja
va
packag
ekiel.fileInt
erface.xmi;
import
java.io.File
;
import
javax.swing.
filechooser.
FileFilter;
import
kiel.dataStr
ucture.State
Chart;
import
kiel.fileInt
erface.FileI
nterface;
import
kiel.fileInt
erface.FileI
nterfaceExce
ption;
10import
kiel.graphic
alInformatio
ns.View;
/** *<p>D
escription:
Themain
modu
leof
theXM
Ifileinterf
aceplugin..
</p>
*<p>C
opyright:(c
)2006</p>
*<p>C
ompany:Uni
Kiel</p>
*@aut
hor<a
href="
mailto:kbe@i
nformatik.un
i-kiel.de">K
enBell</a>
*@ver
sion
$Revisio
n:1.3$la
stmodified
$Date:
2006/1
0/25
15:27:10
$*/ public
classXMIex
tendsFileIn
terface{
20/** *An
instance
ofthe
classreader
module.
*Contai
nsinformatio
nof
availa
bleXMI-Read
ers.
*/ privat
eClassReade
rcr
=null;
/** *Method
from
thein
terface.
Used
toread
astatechart
from
aXMIfile
.30
*@param
arg0
Thefi
leto
beread
.*@retur
nAstatecha
rtinstance.
*@throw
sFileInterf
aceException
.*/ public
finalStateC
hart
readStat
eChartDocume
nt(final
File
arg0)
throws
FileInterfaceE
xception
{
if(cr==
null){
cr=ne
wClassReade
r();
}40
XMIInfoR
eaderxmiinf
o=newXMII
nfoReader();
xmiinfo.
assignFile(a
rg0.toString
());
if(xmiin
fo.isAssigne
d())
{Abstract
XMIReaderre
ader
=cr.cre
ateReaderMod
ule(
xmiinf
o.getExporte
rName(),
xmiinf
o.getExporte
rVersion(),
xmiinf
o.getXMIVers
ion(),
50xmiinf
o.getUMLVers
ion(),
xmiinfo.
getDoc(),
xmiinfo.
getFilename(
));
if(rea
der!=
null)
{try{ return
reader.createS
tateChartFro
mFile();
}catc
h(Exception
e){
kiel.fil
eInterface.F
ileInterface
Model.
getFileI
nterfaceLog(
).log(10,e.
getMessage()
);60
return
null;
}}else
{FileIn
terfaceExcep
tion
ex=new
FileInterfac
eException(
"Noread
erforthe
passed
XMI-fi
lefound.");
throw
ex;
}
}else
{FileInte
rfaceExcepti
onex
=new
FileInterfac
eException(
70"The
selected
xmi-
file
isinva
lid.");
throwex
;}
} /** *Unused
interface
method.
*@retur
n<code>null
</code>.
*@throw
sFileInterf
aceException
.80
*/ public
finalView
getReadView(
)throws
File
InterfaceExc
eption
{return
null;
} /** *Interf
acemethod
toexport
astatechart.
*@param
arg0
Thest
atechart
toexport.
*@param
arg1
unused
.*@param
arg2
Thefi
leto
write
theexport
to.
90*@retur
nAfile
containing
the
exported
stat
echart.
*.
*/ public
finalFile
writeStateCh
artDocument(
finalStateCha
rtarg0,
finalVi
ewarg1,fi
nalFile
arg2
){
XMIGener
ator
gen=
newXMIGenerat
or();
return
gen.generate
Chart(arg0,ar
g2);
} /**
100
*Return
stheglobal
filefilter
instance.
130
G.4. XMI-Fileinterface
*@retur
naFileFilt
erinstance
.*/ public
finalFileFilt
ergetState
ChartFileFil
ter(){
return
XMIFileFilte
r.getInstanc
e();
} /** *As
of2006-07-28
this
Plug-In
canalso
writeXMIfiles.
110
*@retur
ntrue.
*/ public
finalboolea
ncanWrite()
{return
true;
} /**
*As
of2006-07-10
this
Plug-In
isable
toread
XMIfile
s.*@ret
urnTrue
*/12
0public
finalboolea
ncanRead()
{return
true;
} /** *The
name
ofthis
plugin.
*@ret
urnThename
ofthis
File
plugin.
*/ public
finalString
getName(){
return
"XMI
FilePlug
in";
130
}
}
131
G. Java Code
G.4
.2.
XM
IFile
Filt
er.jav
a
packag
ekiel.fileInt
erface.xmi;
import
java.io.File
;import
javax.swing.
filechooser.
FileFilter;
/** *<p>D
escription:
Thefile
filt
erforXMIfi
les.
Used
byFileinterf
ace.</p>
*<p>C
opyright:(c
)2006</p>
*<p>C
ompany:Uni
Kiel</p>
10*@aut
hor<a
href="
mailto:kbe@i
nformatik.un
i-kiel.de">K
enBell</a>
*@ver
sion
$Revisio
n:1.2$la
stmodified
$Date:
2006/1
0/25
15:27:11
$*/ public
classXMIFil
eFilterexte
ndsFileFilt
er{
/**an
intancecoun
ter.*/
privat
estatic
XMIF
ileFilterin
stance
=null
;
/**
20*Return
stheglobal
xmifile
filter.
*@retur
nAglobal
file
filter
instance.
*/ public
static
XMIF
ileFiltergetI
nstance(){
if(insta
nce==
null
){
instance
=newXMIF
ileFilter();
} return
instance;
}
30
/** *Tests
ifapassed
file
isacce
pted
bythis
file
filter
.*@param
pathname
Aname
ofafi
le.
*@retur
n<code>true
</code>if
thefile
isac
cepted.
*/ public
finalboolean
accept(final
File
pathna
me){
if(pat
hname.isDire
ctory())
{return
true;
40} return
(pathna
me.canRead()
&&path
name.isFile(
)&&
path
name.getPath
().toLowerCa
se().endsWit
h(".xmi"));
} /** *@retur
n"XMI
File
s.xmi"
50*/ public
finalString
getDescripti
on()
{return
"XMI
Files.x
mi";
}
}
132
G.4. XMI-Fileinterface
G.4
.3.
Arg
oUM
LRea
der.ja
va
packag
ekiel.fileI
nterface.xmi
.ArgoUML;
import
java.util.Co
llection;
import
java.util.Ha
shtable;
import
java.util.It
erator;
import
java.util.Ve
ctor;
import
org.w3c.dom.
Node;
import
org.w3c.dom.
NodeList;
10//impo
rtkiel.dataS
tructure.*;
import
kiel.dataStr
ucture.ANDSt
ate;
import
kiel.dataStr
ucture.Choic
e;import
kiel.dataStr
ucture.Compo
siteState;
import
kiel.dataStr
ucture.Condi
tionalTransi
tion;
import
kiel.dataStr
ucture.Delim
iterLine;
import
kiel.dataStr
ucture.Graph
icalObject;
import
kiel.dataStr
ucture.Initi
alArc;
import
kiel.dataStr
ucture.Initi
alState;
20import
kiel.dataStr
ucture.Regio
n;import
kiel.dataStr
ucture.State
;import
kiel.dataStr
ucture.State
Chart;
import
kiel.dataStr
ucture.Strin
gLabel;
import
kiel.dataStr
ucture.Trans
ition;
import
kiel.dataStr
ucture.event
exp.Event;
import
kiel.dataStr
ucture.event
exp.Signal;
import
kiel.dataStr
ucture.intex
p.IntegerVar
iable;
import
kiel.fileInt
erface.FileI
nterfaceExce
ption;
import
kiel.fileInt
erface.xmi.A
bstractXMIRe
ader;
30import
kiel.fileInt
erface.xmi.X
MIReaderDesc
riptor;
import
kiel.fileInt
erface.xmi.c
ommon.KielUM
LAttribute;
import
kiel.fileInt
erface.xmi.c
ommon.KielUM
LDataType;
import
kiel.fileInt
erface.JavaT
ransitionLab
els.lexer.Le
xer;
import
kiel.fileInt
erface.JavaT
ransitionLab
els.node.Sta
rt;
import
kiel.fileInt
erface.JavaT
ransitionLab
els.parser.P
arser;
import
kiel.fileInt
erface.JavaT
ransitionLab
els.parser.P
arserExcepti
on;
import
java.io.Push
backReader;
40import
java.io.Stri
ngReader;
/** *<p>Des
criptionThe
ArgoUMLReade
rreadsXMI-
filesgenera
tedby
*ArgoUM
LVersion0.
20.x.
*Useth
emethod
<code>createStat
eChartFromFi
le</code>to
*parse
thegivenXM
I-File.
*TheAr
goUMLReader
utilizes
the
LabelGenerat
orto
parse
theTransiti
on*labels
.It
isadop
tedfrom
aRh
apsody
XMI
reader.
*<p>Cop
yright:(c)
2006</p>
50*<p>Com
pany:UniKi
el</p>
*@autho
r<a
href="
mailto:kbe@inf
ormatik.uni-
kiel.de">Ken
Bell</a>
*@versi
on$Revisio
n:1.8$last
modified
$Date:
2006/11/
0810:26:20
$* */ public
classArgoUM
LReaderexte
ndsAbstract
XMIReader{
/** *The
maxsize
oftheXMIreader
buffer.
60*/ private
finalintma
xbuffersize
=1024;
/** *The
supportedex
porter.
*/ private
finalString
supportedE
xporter=
"ArgoU
ML(using
Netb
eans
XMIWr
iter
version
1.0)";
/**
70*The
versionof
theexporter
supportedby
this
module.
*/ private
finalString
supportedE
xporterVersion
="0.20.x"
;
/** *The
versionof
xmisupported
bythis
modu
le.
*/ private
finalString
supportedX
MIVersion="1
.2";
/**
80*The
versionof
UMLsupported
bythis
modu
le.
*/ private
finalString
supportedU
MLVersion=
"1.4";
/** *The
date
ofthe
revision.
*/ private
finalString
sRevisionD
ate="0.2
-August
2006";
/**
90*The
author
ofth
ismodule.
*/ private
finalString
sModulAuth
or="Ken
Bell";
/** *Ash
ortdescript
ionof
this
module.
*/ private
finalString
sModulDesc
ription=
"Modul
eforimport
ingxmifiles
generatedby
ArgoUML";
100
/** *The
name
ofthis
module.
*/ private
finalString
sModuleNam
e="ArgoUML
.Importer";
/** *Deno
tes,
ifther
ecanbe
more
than
onest
atechart.
*/ private
finalboolea
nbMultipleS
CSupport
=true;
110
/**
133
G. Java Code
*Thena
meof
theXM
ITagforps
eudo
states.
*/ privat
efinalStri
ngtagPseudoS
tate
="UML:P
seudostate";
/** *Thena
meof
theXM
Itagforst
ates.
*/ privat
efinalStri
ngtagState
="UML:State";
120
/** *Thena
meof
theXM
Itagforsi
mple
states.
*/ privat
efinalStri
ngtagSimpleS
tate
="UML:S
impleState";
/** *Thena
meof
theXM
Itagforco
mpositestat
es.
*/ privat
efinalStri
ngtagComposi
teState="U
ML:Composite
State";
130
/** *Thena
meof
theXM
Itagforfi
nalstates.
*/ privat
efinalStri
ngtagFinalSt
ate="UML:F
inalState";
/** *Thena
meof
theXM
Itagforsy
nchstates.
*/ privat
efinalStri
ngtagSynchSt
ate="UML:S
ynchState";
140
/** *Thena
meof
theXM
Itagforth
eexporter.
*/ privat
efinalStri
ngtagExporte
rName="XMI
.exporter";
/** *Thena
meof
theXM
Itagforth
eexporter
version.
*/ privat
efinalStri
ngtagExporte
rVersion
="X
MI.exporterV
ersion";
150
/** *Thena
meof
theXM
Itagforth
eid
referenc
e.*/ privat
efinalStri
ngattrIDRef
="xmi.idref
";
/** *Thena
meof
theat
tributeof
theitem
id.
*/ privat
efinalStri
ngattrID
="xmi.id";
160
/** *Thena
meof
theXM
Itagcontai
ning
thevalu
eof
some
fields.
*/ privat
efinalStri
ngattrXMIVal
ue="xmi.val
ue";
/** *Thena
meof
theXM
Itagcontai
ning
thevers
ionof
XMI.
*/ privat
efinalStri
ngattrXMIVer
sion
="xmi.v
ersion";
170
/**
*Alltr
ansitionsar
eaddedto
this
vector.
*/ privat
eVector
vGlo
balTransitio
ns=null;
/** *Allat
tributes
areaddedto
this
vector
whileparsing
thedocument
.*/ privat
eVector
vGlo
balAttribute
s=null;
180
/** *Allsi
gnalsaread
dedto
this
vector
while
parsingthe
document.
*/ privat
eVector
vGlo
balPackageSi
gnals=null
;
/** *Allsi
gnal
events
areaddedto
this
vector
whileparsin
gthedocume
nt.
*/ privat
eVector
vGlo
balSignalEve
nts=null;
190
/** *Allsi
gnal
event
receptions
areaddedto
this
vector
*while
parsingthe
document.
*/ privat
eVector
vGlo
balEventRece
ption=null
;//
RPSC
lassEventRec
eption
/** *Allda
tatypesare
addedto
this
vector
whil
eparsingth
edocument.
*/ privat
eVector
vGlo
balDatatypes
=null;
200
/** *AllSt
atechartsar
eaddedto
this
vector
whileparsing
thedocument
.*/ privat
eVector
vSta
teCharts
=null;
/** *Theha
shtablefor
theinternal
lycreatedid
s.*This
dictionary
isused
asalo
okup
refere
nce.
*/21
0privat
eHashtable
idDictionary
=null;
/** *Acoun
terforcrea
ting
ids.
*/ privat
eintidCoun
ter;
/** *Creato
rfortheXM
IReader
modu
le.
220
* */ public
ArgoUMLReade
r(){
super();
vGlobalT
ransitions
=newVector()
;vGlobalA
ttributes=
newVector()
;vGlobalP
ackageSignal
s=newVect
or();
vGlobalS
ignalEvents
=newVector
();
vGlobalE
ventReceptio
n=newVect
or();
vGlobalD
atatypes
=ne
wVector();
230
vStateCh
arts
=newVe
ctor();
134
G.4. XMI-Fileinterface
idDictio
nary
=new
Hashtable();
idCounte
r=0;
} /** *Intern
ally
used
method
toclea
ralltempor
arydata.
* */24
0private
void
clearA
llXMIData(){
vGlobalT
ransitions.c
lear();
vGlobalA
ttributes.cl
ear();
vGlobalP
ackageSignal
s.clear();
vGlobalS
ignalEvents.
clear();
vGlobalE
ventReceptio
n.clear();
vGlobalD
atatypes.cle
ar();
vStateCh
arts.clear()
;idDictio
nary.clear()
;idCounte
r=0;
250
} /** *Return
sthelist
ofallfound
statecharts.
*@retur
nThelist
ofallstatec
hartsfound
inthefile.
*/ public
finalVector
getStatechar
tList(){
if(vSt
ateCharts.si
ze()
<1)
{FileIn
terfaceExcep
tion
ex=new
FileInterfac
eException(
260
"The
selected
XMI-Fi
ledoes
not
containany
statecharts.
");
ex.sho
wMessageBox(
);return
null;
//thro
wex;
}else
{return
vStateCharts
;}
}
270
/** *This
method
return
sthefirst
statechart.
* *@ret
urnThefirst
statechart
foundin
the
file
tobe
read.
*/ public
finalStateC
hart
createSt
ateChartFrom
File()
{StateCha
rtsc
=null
;
if(vSt
ateCharts.si
ze()
>0)
{sc
=(S
tateChart)
vStateCharts.g
et(0);
280
}else
{FileIn
terfaceExcep
tion
ex=new
FileInterfac
eException(
"The
selected
XMI-Fi
ledoes
not
containany
statecharts.
");
ex.sho
wMessageBox(
);//thro
wex;
} /*Vector
v=getSCC
lassList();
if(v.s
ize()==
1){
XMIClass
Info
classInf
o=(XMIClas
sInfo)v.elem
entAt(0);
290
sc=cr
eateStateChart
FromFile(cla
ssInfo.class
ID);
}*/
return
sc;
} /** *Crea
tesaandre
turnsthestat
echart
from
theclasswi
ththepass
edid.
*@par
amclassIDTh
eid
ofthe
classto
get
thestatecha
rt.
*@ret
urnThestat
echart
associ
ated
with
thepassed
clas
s.*/
300
public
finalStateC
hart
createSt
ateChartFrom
File(final
String
classI
D){
StateC
hart
sc=nu
ll;
/*UMLC
lass
c=ge
tClass(classID
);if
(c!=
null){
//Stat
echart
erstel
len
sc=ne
wStateChart
("Statechart
of"+c.getNam
e(),
c.getN
ame());
sc.setGe
neratorName(
"Importmodul
für
I-Lo
gix"
+"Rhaps
odyv4.0,St
effenPietsc
h");
RPSPacka
gep=getP
ackage(c.get
PackageID());
if(p
!=null)
310
sc.set
PackageName(
p.getName())
;//
Zust
�n
dehinz
uf�g
enVector
vRPSStates
=getStatesByC
lassID(class
ID);
sc.addSt
ates(convert
RPSToNormalS
tates(vRPSSt
ates));
sc.findR
oot();
//Trig
gerhinzufï¿
½gen
Vector
vRPSPackageS
ignals
=getP
ackageSignal
sByClassID(c
lassID);
sc.addEv
ents(convert
RPSPackageSi
gnalsToNorma
lTrigger(
vRPSPa
ckageSignals))
;//
Tran
sitionen
hinz
uf�g
en32
0Vector
vRPSTransiti
ons=getTra
nsitionsByClas
sID(classID)
;sc.addTr
ansitions(co
nvertRPSTran
sitionsToNor
malTransitio
ns(
vRPSTr
ansitions));
//Attr
ibute
Vector
vRPSAttribut
es=getAttri
butesByClass
ID(classID);
sc.addCl
assAttribute
s(convertRPS
AttributesTo
NormalAttrib
utes(
vRPSAt
tributes));
}*/
return
sc;
330
} /** *This
file
filter
canread
mult
iple
statec
hartsfrom
afile.
*@ret
urnTrue.
*/ public
finalboolea
nsupportsMu
ltipleSCInFi
le()
{return
true;
}
340
/** *Clas
sesarenot
handledin
KIEL.Therfore
thenumber
ofclasses
*equa
lszero.
*@ret
urnThenumb
erof
classes
found.
*/ private
intgetClass
Count(){
return
0;}
350
/**
135
G. Java Code
*Getth
eID
ofthe
classassoci
ated
with
thepassed
inde
x.*This
function
will
beuseful,
asadialogue
tochoose
acertain
*statec
hart
from
thesetof
defi
nedones
will
beread.
*@param
indexThenu
mber
ofthe
classto
beretrieved.
*/ privat
evoid
getCla
ss(final
intindex)
{//return
(RPSClass)vG
lobalClasses
.elementAt(i
ndex);
}
360
/** *Geta
classby
id.
*@param
iDAid
stri
ng.
*/ privat
evoid
getCla
ss(final
String
iD){
/*RPSCla
ssuc
=null
;for(int
i=0;
i<
getClassCoun
t();
i++)
{if
(get
Class(i).get
ID().equals(
ID))
return
getClass(i);
}37
0return
uc;*/
} /** *Return
sthenumber
offoundst
atecharts.
*@retur
nThenumber
ofread
Stat
echartsread
from
thefi
le.
*/ public
finalintge
tStateChartC
ount()
{intiSCC
ounter
=0;
for(int
i=0;
i<
getClassCoun
t();
i++)
{38
0return
0;/*
if(g
etClass(i).h
asStateChart
())
iSCCount
er++;*/
} return
iSCCounter;
} /** *Classe
sarenotha
ndledin
KIEL
therefore
<code>null</
code>is
retu
rned.
*@retur
nThelist
ofallclasse
s.39
0*/ public
finalVector
getSCClass
List()
{return
null;
} /** *Implem
entation
ofan
abstract
method.
*@retur
nThename
ofthis
module
.*/ public
finalString
getModuleN
ame(){
400
return
sModuleName;
} /** *Implem
entation
ofan
abstract
method.
*@retur
nThedate
ofthecurren
trevision.
*/ public
finalString
getRevisio
nDate(){
return
sRevisionDate;
}41
0
/** *Implem
entation
ofan
abstract
method.
*@retur
nAstring
describing
this
module.
*/ public
finalString
getModuleDes
cription()
{return
sModulDescri
ption;
} /**
420
*Implem
entation
ofan
abstract
method.
*@retur
nThename
oftheauthor
ofthis
import
module.
*/ public
finalString
getModuleAut
hor(){
return
sModulAuthor
;} /** *Implem
entation
ofan
abstract
method.
*@retur
nThesuppor
tedUMLvers
ion.
430
*/ public
finalString
getUMLVersio
n(){
String
sVersion
="?";
NodeLi
stnl
=getD
ocument().getE
lementsByTag
Name("XMI.me
tamodel");
if(nl.
getLength()
==1)
{sVersi
on=nl.item(
0).getAttrib
utes().getNa
medItem(
"xmi.ver
sion").getNo
deValue();
} return
sVersion;
}44
0
/** *Implem
entation
ofan
abstract
method.
*@retur
nThesuppor
tedversion
ofXMI.
*/ public
finalString
getXMIVersio
n(){
String
sVersion
="?";
NodeLi
stnl
=getD
ocument().getE
lementsByTag
Name("XMI");
if(nl.
getLength()
==1)
{45
0sVersi
on=nl.item(
0).getAttrib
utes().getNa
medItem(
attrXMIV
ersion).getN
odeValue();
} return
sVersion;
} /** *Curren
tlynotimpl
emented.
*@retur
nThename
oftheexport
erfound.
*/46
0public
finalString
getExporterN
ame(){
//TODO
Auto-generat
edmethod
stub
return
null;
} /** *Curren
tlynotimpl
emented.
*@retur
nTheversio
nof
theex
porter.
*/ public
finalString
getExporterV
ersion()
{47
0//
TODO
Auto-generat
edmethod
stub
136
G.4. XMI-Fileinterface
return
null;
} /** *@retur
nAstring
that
hasto
matchtheex
porter
specif
iedin
the
*XMIfi
le.
*/ public
finalString
getSupported
ExporterName
(){
return
supportedExp
orter;
480
} /** *@retur
nAversion
string
that
hasto
matc
htheexport
erversion
*as
itis
specifie
din
theXMI
file.
*/ public
finalString
getSupported
ExporterVers
ion(){
return
supportedExp
orterVersion
;}
490
/** *@ret
urnTheversio
nof
thesu
pportedXMI
version.
*/ public
finalString
getSupported
XMIVersion()
{return
supportedXMI
Version;
} /** *@ret
urnThesuppor
tedversion
ofUML.
*/50
0public
finalString
getSupported
UMLVersion()
{return
supportedUML
Version;
} /** *@ret
urnAn
instan
ceof
theXM
IReaderDescr
iptorcontaini
ngallneed
ed*info
rmations.
*/ public
finalXMIRea
derDescriptor
getDescripto
r(){
XMIReade
rDescriptor
xrd=newXM
IReaderDescr
iptor(null);
510
xrd.modu
leName
=sM
oduleName;
xrd.revi
sionDate
=getRevisionD
ate();
xrd.modu
leAuthor
=getModuleAut
hor();
xrd.modu
leDescriptio
n=getModul
eDescription
();
xrd.expo
rterName
=getSupported
ExporterName
();
xrd.expo
rterVersion
=getSupport
edExporterVe
rsion();
xrd.xmiV
ersion
=ge
tSupportedXM
IVersion();
xrd.umlV
ersion
=ge
tSupportedUM
LVersion();
return
xrd;
}52
0
/** *Retu
rnsthefirst
node
oftype
ELEMENT_NO
DEfrom
the
node
list
*that
matchesthe
passed
name.
*@par
amnl
Source
list.
*@par
amelementNam
eThename
ofthenode
tobe
returned
.*@ret
urnAnode
that
matchesth
egivenname
.*/ private
Node
getFir
stNodeFromList
(final
Node
List
nl,
530
final
String
elemen
tName)
{
if(nl.
getLength()
>0)
{for(i
nti=0;
i<nl.getLeng
th();i++)
{if
(nl.
item(i).getN
odeType()==
Node.ELEMENT
_NODE)
{if
(nl.
item(i).getN
odeName().eq
uals(element
Name))
{return
nl.item(i);
}}
}}
540
return
null;
} /** *Retu
rnsthefirs
tnode
oftype
ELEMENT_NO
DEfrom
the
list.
*@par
amnl
Alist
ofnodes.
*@ret
urnThefirs
tnode
from
thelist
with
node
type
ELEMENT_NODE.
*/ private
Node
getFir
stNodeFromLi
stNoText(fin
alNodeList
nl){
if(nl.
getLength()
>0)
{55
0for(int
i=0;
i<
nl.getLength
();i++)
{if
(nl.
item(i).getN
odeType()==
Node.ELEMENT
_NODE)
{return
nl.item(i);
}}
} return
null;
} /**
560
*Impl
ementation
oftheabstra
ctmethod
stub
.*Read
sallstatec
hartsfrom
thecurrently
handledXMI
file.
*/ public
finalvoid
readAll(){
//alle
Vektoren
leeren
clearA
llXMIData();
//Einl
esen
beginn
enNodeLi
stnl
=getD
ocument().getE
lementsByTag
Name("UML:Mo
del");
if(nl.
getLength()
==1)
{Node
ndMa
inModel=nl
.item(0);
570
if(ndMai
nModel.hasCh
ildNodes())
{NodeList
nlFoundati
onNodes=ndMa
inModel.getC
hildNodes();
Node
ndOwnedElement
=getFirstNo
deFromList(
nlFoun
dationNodes,
"UML:Namespa
ce.ownedElem
ent");
if(ndO
wnedElement
!=null){
if(ndO
wnedElement.
hasChildNode
s())
{Vector
vPackages=
getNodesFrom
List(
ndOwnedE
lement.getCh
ildNodes(),
"UML:Package
");
/*for
(int
i=0;
i<vPackage
s.size();i+
+){
try{
580
readPack
age((Node)vP
ackages.elem
entAt(i),"")
;}catch
(FileInterfa
ceException
e){
e.printS
tackTrace();
}}*/
//now
read
allmode
linformatio
nsfrom
the
defaultpack
age
readPack
age(ndMainMo
del,
"");
/*Vect
orvClasses
=getNodesFr
omList(
590
ndOwnedE
lement.getCh
ildNodes(),
"UML:Class")
;
137
G. Java Code
for(int
i=0;
i<
vClasses.siz
e();
i++)
{try{ readCl
assFromPackage
((Node)
vClasses.eleme
ntAt(i),"","
");
}catch
(FileInterfa
ceException
e){
e.prin
tStackTrace();
}}*/
}60
0}
}}else
{getPrint
Stream().pri
ntln("Es
isteinfataler
Fehler
aufg
etreten:
"+"Das
Element\"Mo
del_Manageme
nt.Model\"
"+"kon
ntenichtge
funden
werden
.");
getPrint
Stream().pri
ntln("DerVo
rgangwird
abgebrochen.")
;}
}61
0
/** *This
method
return
sallnodes
ofthepassed
elementfr
omalist
*of
nodes.
*@param
nlThesour
celist.
*@param
elementName
Thename
ofthenodesto
bereturned
.*@retur
nAlist
cont
aining
all
nodeswith
thegivenname
.*/ privat
eVector
getN
odesFromList
(final
NodeLi
stnl,
620
finalSt
ring
elemen
tName)
{Vector
vResult=new
Vector();
if(nl.
getLength()>
0){
for(int
i=0;
i<
nl.getLength
();i++)
{if
(nl.
item(i).getN
odeType()==
Node.ELEMENT
_NODE)
{if
(nl.
item(i).getN
odeName().eq
uals(element
Name))
{vResult.
add(nl.item(
i));
}}
}63
0} return
vResult;
} /** *Proces
sesthepack
age.
*@param
ndModelPacka
geThenode
from
thexm
itree.
*@param
parentPackag
eIDTheid
oftheowning
package.
*/64
0public
finalvoid
readPackage(
finalNode
ndModelPackage
,finalSt
ring
parent
PackageID)
{String
sPackageName
="";
String
sPackageID
="";
Vector
vDataTypes
=null;
Vector
vClasses
=nu
ll;
Vector
vSignals
=nu
ll;
Vector
vInnerPackages
=null;
if(ndM
odelPackage.ha
sChildNodes(
)){
//Pack
agedaten
ausl
esen
650
NodeList
nlModelChi
ldNodes=nd
ModelPackage.g
etChildNodes
();
Node
ndOwnedElement
=getFirstNo
deFromList(n
lModelChildN
odes,
"UML:Nam
espace.owned
Element");
if(ndO
wnedElement
!=null){
NodeLi
stnlOwned=
ndOwnedEleme
nt.getChildN
odes();
vDataT
ypes
=getNod
esFromList(n
lOwned,"UML
:DataType");
vClass
es=getNodes
FromList(nlO
wned,"UML:C
lass");
vSigna
ls=getNodes
FromList(nlO
wned,"UML:S
ignalEvent")
;vInner
Packages
=ge
tNodesFromLi
st(nlOwned,
"UML:Package
");
}else
{66
0vDataT
ypes
=newVe
ctor();
vClass
es=newVect
or();
vSigna
ls=newVect
or();
vInner
Packages
=ne
wVector();
} //Pack
agealsObje
kterzeugen
u.globalem
Vektor
hinzuf
�g
en/*
RPSP
ackage
up=
newRPSPacka
ge(sPackageI
D,sPackageNa
me);
up.set
ParentPackag
e(parentPackag
eID);
vGloba
lPackages.ad
d(up);
670
if(!pa
rentPackageI
D.equals("")
){
RPSPac
kage
parent
=getPackage(p
arentPackage
ID);
parent
.addInnerPac
kage(sPackageI
D);
}*/
//zuge
h�rige
Klassen,
Events
,weitereUn
terpackages
etc.
auslesen
for(int
i=0;
i<
vSignals.siz
e();
i++)
{readCl
assSignalEve
ntFromNode((No
de)vSignals
.elementAt(i
));
680
} for(int
i=0;
i<
vClasses.siz
e();
i++)
{readCl
assFromPacka
ge((Node)vCla
sses.element
At(i),
sPackage
ID,"");
} //for(i
nti=0;
i<vInnerPack
ages.size();
i++)
//read
Package((Nod
e)vInnerPack
ages.elementAt
(i),
sPacka
geID);
690
for(int
i=0;
i<
vDataTypes.s
ize();
i++)
{readDa
taTypeFromNo
de((Node)vDat
aTypes.eleme
ntAt(i));
}
}} /** *Reads
thedatatype
from
thepa
ssed
node.
700
*@param
ndDatatype
Thenode
from
thexmitr
ee.
*/ privat
evoid
readDa
taTypeFromNo
de(final
Node
ndDatatype
){
String
sDatatypeID
="";
String
sDatatypeNam
e="";
if(ndD
atatype.hasC
hildNodes())
{//
Read
data
sDatatyp
eID=ndData
type.getAttr
ibutes().get
NamedItem(
attrID
).getNodeVal
ue();
710
NodeList
nlDTChildN
odes
=ndData
type.getChil
dNodes();
138
G.4. XMI-Fileinterface
Node
ndName
=getFir
stNodeFromLi
st(nlDTChild
Nodes,
"Foundat
ion.Core.Mod
elElement.na
me");
sDatat
ypeName=ndNa
me.getFirstC
hild().getNo
deValue();
} //Base
Elementdt
=newBaseElem
ent(sDatatyp
eID,
sDatatyp
eName);
//vGloba
lDatatypes.a
dd(dt);
}72
0/** *Reads
astatemachi
nefrom
the
node.
*@param
ndStateMac
hine
Thenode
from
thexm
itree.
*@param
sClassID
Theid
ofthe
owning
clas
s.*/ private
void
readSt
ateMachineFrom
Node(final
Node
ndStateM
achine,
final
String
sClass
ID){
String
sMachineName
="";
730
Vector
vTransitions
=newVector
();
StateCha
rtscChart
=newStateC
hart();
scChart.
setModelSour
ce(supported
Exporter);
scChart.
setModelVers
ion(supporte
dExporterVer
sion);
for(int
i=0;
i<
vGlobalSigna
lEvents.size
();i++)
{scChar
t.addInputEv
ent((Event)vG
lobalSignalE
vents.get(i)
);}
740
/*TODO
:2006-08-02
*Dist
inguishthe
type
oftheat
tributeand
addthevari
able
of*the
righttype
tothechart
*/ for(int
i=0;
i<
vGlobalAttri
butes.size()
;i++)
{KielUM
LAttribute
ua=(KielUMLAt
tribute)
vGlobalAttribu
tes.get(i);
Intege
rVariablev
=newIntegerV
ariable(ua.g
etAttrName()
);v.setI
DManual(ua.g
etAttrID());
scChar
t.addVariabl
e(v);
}75
0
NodeList
nlMachineC
hildNodes=
ndStateMachi
ne.getChildNod
es();
if(ndS
tateMachine.
getAttribute
s().getNamed
Item("name")
!=null){
if(ndS
tateMachine.
getAttribute
s().getNamed
Item("name")
!=null){
sMachi
neName
=ndSt
ateMachine.g
etAttributes
().getNamedI
tem(
"name").
getNodeValue
();
}}else
{76
0sMachi
neName
="";
} Node
ndTop=getFir
stNodeFromLi
st(nlMachine
ChildNodes,
"UML:Sta
teMachine.to
p");
Node
ndTransitions
=getFirstNo
deFromList(n
lMachineChildN
odes,
"UML:Sta
teMachine.tr
ansitions");
//Read
states
ofth
ecurrentst
atemachine
andaddthem
totheglobal
//vect
or77
0Node
ndRootState=
getFirstNode
FromListNoTe
xt(ndTop.getCh
ildNodes());
readSt
ateFromStateNo
de(scChart,
ndRootSt
ate,
true,""
);
//Read
transition
sandaddall
availableto
theglobal
vector
if(ndT
ransitions
!=null){
Vector
vTransitionN
odes
=getN
odesFromList(
ndTransi
tions.getChi
ldNodes(),
"UML:Transitio
n");
if(vTr
ansitions!=
null){
780
for(int
i=0;
i<
vTransitionN
odes.size();
i++)
{Node
ndTrans=(Nod
e)vTransitio
nNodes.eleme
ntAt(i);
readTran
sitionFromNo
de(scChart,
ndTrans,
fals
e,null);
}}
} vState
Charts.add(scC
hart);
scChar
t.getRootNode(
).setName(sM
achineName);
}79
0
/** *This
internally
used
method
normalizes
theidsfound
inxmifiles
*gene
ratedby
Argo
UML.
*@par
amid
Theid
tobe
normal
ized.
*@ret
urnThenorm
alized
id.
*/ private
String
norm
alizeID(fina
lString
id)
{
800
String
s="";
Object
o=idDictio
nary.get(id)
;
if(o
==null){
s="#
"+(idCount
er++);
idDict
ionary.put(i
d.toString()
,s.toString()
);}else
{s=(S
tring)
o;}
810
return
s;} /** * *@par
amsignalID
Theid
ofthe
signal
tobe
returned.
*@ret
urnThesign
alif
found,
null
otherwis
e.*/
820
private
Signal
getS
ignalByID(fi
nalString
signalID){
Signal
result
=null
;Iterat
oriter
=vGlo
balSignalEve
nts.iterator
();
while
(iter.hasNext(
)){
result
=(Signal)
iter.next();
if(!re
sult.getID()
.equals(sign
alID))
{result
=null;
830
}else
{
139
G. Java Code
break;
}} return
result;
} /**
840
*Reads
atransition
from
anode
.*@param
scChartThe
actually
createdstatec
hart.
*@param
ndTransition
Thenode
from
thexmi
tree.
*@param
isInternal
Denoting
weth
erthecurr
enttransiti
onis
internal
.*@param
transThetr
ansition.
*/ privat
evoid
readTr
ansitionFrom
Node(final
StateChart
scChart,
finalNo
dendTransi
tion,final
booleanisInte
rnal,
finalTr
ansition
trans)
{String
sTransitionID
="";
850
String
sTargetStateID
="";
String
sSignalEventID
="";
String
sSignalEventEx
p="";
String
sGuardExpressi
on="";
String
sActionStateme
nts="";
sTransit
ionID=norm
alizeID(ndTr
ansition.get
Attributes().g
etNamedItem(
attrID
).getNodeValue
());
NodeList
nlTransition
ChildNodes
=ndTransiti
on.getChildN
odes();
Node
ndTarget
=getF
irstNodeFrom
List(nlTrans
itionChildNode
s,86
0"UML:T
ransition.targ
et");
if(ndT
arget!=
null
){
sTargetS
tateID
=no
rmalizeID(getF
irstNodeFrom
ListNoText(
ndTarg
et.getChildN
odes()).getAtt
ributes().ge
tNamedItem(
attrIDRe
f).getNodeVa
lue());
} Node
ndSignalEvent=
getFirstNode
FromList(nlT
ransitionChi
ldNodes,
"UML:T
ransition.trig
ger");
if(ndS
ignalEvent
!=null){
870
sSignalE
ventID
=ge
tFirstNodeFrom
ListNoText(
ndSign
alEvent.getC
hildNodes()).g
etAttributes
().
getNam
edItem(attrI
DRef).getNodeV
alue();
} //Trig
gerbzw.
Guar
dauslesen
Node
ndTransGuard
=getFirstNode
FromList(nlT
ransitionChild
Nodes,
"UML:Tra
nsition.guar
d");
if(ndT
ransGuard!=
null){
Node
ndStatemachine
Guard=getF
irstNodeFromLi
st(
880
ndTran
sGuard.getCh
ildNodes(),
"UML:Guard");
if(ndS
tatemachineG
uard
!=null
){
Node
ndGuardExpress
ion=getFir
stNodeFromLi
st(
ndStatem
achineGuard.
getChildNode
s(),
"UML:Gua
rd.expressio
n");
if(ndG
uardExpressi
on!=
null)
{Node
ndTemp
=getF
irstNodeFromLi
st(
ndGuardE
xpression.ge
tChildNodes(
),"UML:Boo
leanExpressi
on");
if(ndT
emp!=
null
){
890
sGuardEx
pression
=nd
Temp.getAttr
ibutes().get
NamedItem(
"body").
getNodeValue
();
}}
}} //
Acti
onauslesen
Node
ndTransEffect
=getFirstNode
FromList(
nlTran
sitionChildN
odes,
"UML:T
ransition.ef
fect");
900
if(ndT
ransEffect
!=null){
Node
ndUninterprete
dAction=ge
tFirstNodeFr
omList(
ndTransE
ffect.getChi
ldNodes(),
"UML:Cal
lAction");
if(ndU
ninterpreted
Action
!=nu
ll){
Node
ndScriptExpres
sion
=getFir
stNodeFromLi
st(
ndUninte
rpretedActio
n.getChildNo
des(),
"UML:Act
ion.script")
;if
(ndS
criptExpress
ion!=
null)
{Node
ndTe
mp=getFir
stNodeFromLi
st(
910
ndScript
Expression.g
etChildNodes
(),
"UML:Act
ionExpressio
n");
if(ndTem
p!=
null)
{sActionS
tatements=
ndTemp.getAt
tributes().g
etNamedItem(
"body").
getNodeValue
();
}}
}}
920
Transiti
ont=null
;if
(isI
nternal)
{t=tran
s;}else
{kiel.dat
aStructure.N
odetarget
=null;
Collecti
onobjects
=scChart.ge
tAllObjects(
);Iterator
iter
=obje
cts.iterator
();
Graphica
lObjectgo
=null;
while(i
ter.hasNext(
)){
930
go=nu
ll;
try{ Object
o=iter.next(
);if
(oin
stanceof
Grap
hicalObject)
{go
=(G
raphicalObje
ct)o;
}else
{System.o
ut.println("
Instance
of"
+o.ge
tClass().get
Name()
+"fo
und.");
} if(go!=
null){
940
if(go.
getID().equa
ls(sTransition
ID))
{t=(Tra
nsition)
go;
} if(go.
getID().equa
ls(sTargetStat
eID)){
target
=(kiel.data
Structure.No
de)go;
}}
}catc
h(Exception
e){
System.o
ut.println(
"Error
whileassign
ingtransiti
onwith
id"
950
+sTrans
itionID
140
G.4. XMI-Fileinterface
+".
Foundobject
with
id"+go
.getID());
}} if
((t
!=null)&&
(target!=
null))
{t.setT
arget(target
);}
}
960
if((t
!=null)
&&((!s
SignalEventI
D.equals("")
)||
(!sG
uardExpressi
on.equals(""
))||
(!sA
ctionStateme
nts.equals("
")))){
//set
thetrigger,
guardandef
fect
//get
theaccordin
gsignal
even
tfrom
the
global
vector
if(!sS
ignalEventID
.equals(""))
{Signal
s=getSigna
lByID(normal
izeID(sSigna
lEventID));
if(s
!=null){
sSignalE
ventExp=s.
getName();
970
}else
{sSignalE
ventExp=""
;}
} String
label=sSig
nalEventExp;
if(!sG
uardExpressi
on.equals(""
)){
label
+="["+sG
uardExpressi
on+"]";
} if(!sA
ctionStateme
nts.equals("
")){
label
+="/"
+sA
ctionStateme
nts;
980
} //new
handling
meth
odologyuse
xmi.transiti
onLabel.pars
erif
(!la
bel.equals("
")){
Parser
p;try{ //
fina
lstatement
p=new
Parser(new
Lexer(newPush
backReader(
newSt
ringReader(lab
el),
maxbuf
fersize)));
//Stat
ementfortest
ingpurposes
/*p=
newParser(new
Lexer(new
PushbackRead
er(
990
newSt
ringReader("[a
==5]/a=6;e;"
),1024))
);*/
Start
tree
=p.pars
e();
LabelG
enerator
lg=
newLabelGen
erator(scCha
rt);
tree.a
pply(lg);
t.setL
abel(lg.getTra
nsitionLabel
());
}catc
h(ParserExc
eption
ex){
StringLa
bell=new
StringLabel(
label);
t.setLab
el(l);
System.o
ut.println("
Thelabelst
ring
("10
00+labe
l+")co
uldnotbe
parsed:"
+ex.g
etMessage());
}catc
h(Exception
e){
FileInte
rfaceExcepti
onex
=new
FileInterfac
eException(
"Handl
ingof
transi
tion
labelfa
iled.\n"
+"Fou
ndlabel:
"+
label+"\n"
+e.ge
tMessage());
StringLa
bell=new
StringLabel(
label);
t.setLab
el(l);
1010
ex.showM
essageBox();
}}else
{StringLa
bell=new
StringLabel(
label);
t.setLab
el(l);
}}
}
1020
/** *Hand
leastatecha
rtstatenode
.*@par
amscChartTh
eactual
stat
echart.
*@par
amndStateTh
enode
from
thexmitree
.*@par
amisRoot
Deno
ting
ifthe
actual
read
statewill
become
thero
ot*stat
e.*@par
amparentStat
eIDTheid
oftheparent
state.
*/ private
void
readSt
ateFromStateNo
de(final
StateChart
scCh
art,
final
Node
ndState,
finalbool
eanisRoot,
1030
final
String
parent
StateID)
{
String
sStateID
=""
;String
sStateName
="";
boolean
bIsConcurren
t=false;
kiel.dat
aStructure.N
odekielNode
=null;
NodeList
nlStateChi
ldNodes=nd
State.getChi
ldNodes();
1040
sStateID
=normaliz
eID(
ndState.
getAttribute
s().getNamed
Item(attrID)
.getNodeValue(
));
if(ndS
tate.getAttr
ibutes().get
NamedItem("n
ame")!=
null
){
sState
Name
=ndStat
e.getAttribu
tes().getNam
edItem(
"name").
getNodeValue
();
}else
{sState
Name
=sState
ID;
1050
} if(ndS
tate.getNode
Name().equal
s(tagPseudoS
tate))
{String
sKind=ndSt
ate.getAttri
butes().getN
amedItem(
"kind").
getNodeValue
();
if(sKi
nd.equals("c
hoice"))
{//
TODO:
Distinguish
betweenChoi
ceor
Dynami
cChoice
kielNode
=newkiel.d
ataStructure
.Choice();
}else
if(sKind.e
quals("deepHis
tory")){
1060
kielNode
=newkiel.d
ataStructure
.DeepHistory
();
}else
if(sKind.e
quals("fork"))
{kielNode
=newkiel.d
ataStructure
.ForkConnect
or();
}else
if(sKind.e
quals("initial
")){
kielNode
=newkiel.d
ataStructure
.InitialStat
e();
}else
if(sKind.e
quals("join"))
{kielNode
=newkiel.d
ataStructure
.Join();
}else
if(sKind.e
quals("junctio
n"))
{kielNode
=newkiel.d
ataStructure
.Junction();
}else
if(sKind.e
quals("shallow
History"))
{10
70kielNode
=newkiel.d
ataStructure
.History();
141
G. Java Code
}else
{FileIn
terfaceExcepti
onex
=new
FileInterfac
eException(
"Apars
edpseudostat
ecouldnot
bemapped
to"
+"the
KIEL
datastru
cture.");
ex.sho
wMessageBox();
//thro
wex;
}
}else
if(ndState.g
etNodeName()
.equals(tagC
ompositeStat
e)){
1080
String
sConcurrent
=ndState.ge
tAttributes().
getNamedItem
("isCon
current").ge
tNodeValue()
;if
(sCo
ncurrent.equ
als("true"))
{bIsCon
current=true
;} if
(bIs
Concurrent)
{kielNo
de=newkiel
.dataStructu
re.ANDState(
);}else
{kielNo
de=newkiel
.dataStructu
re.ORState()
;10
90}
}else
if(ndState.g
etNodeName()
.equals(tagS
impleState)
||ndSt
ate.getNodeN
ame().equals
(tagState))
{kielNode
=newkiel
.dataStructu
re.SimpleState
();
}else
if(ndState.g
etNodeName()
.equals(tagF
inalState))
{kielNode
=newkiel
.dataStructu
re.FinalSimple
State();
1100
}else
if(ndState.g
etNodeName()
.equals(tagS
ynchState))
{kielNode
=newkiel
.dataStructu
re.SynchState(
);
}else
{FileInte
rfaceExcepti
onex
=new
FileInterfac
eException(
"Apars
edtagname
couldnotbe
mapped
to"
+"th
eKIEL
datast
ructure.");
1110
ex.showM
essageBox();
//throw
ex;
return;
} if(kie
lNode==
null
){
kielNo
de=newkiel
.dataStructu
re.SimpleSta
te();
} kielNode
.setIDManual
(sStateID);
1120
kielNode
.setName(sSt
ateName);
//ausg
ehende
Transi
tionen
Node
ndOutgoing
=ge
tFirstNodeFr
omList(nlSta
teChildNodes
,"UML:S
tateVertex.out
going");
if(ndO
utgoing!=
null){
NodeList
nlOut=nd
Outgoing.get
ChildNodes();
for(int
i=0;
i<
nlOut.getLen
gth();
i++)
{Node
ndOutTrans
=nl
Out.item(i);
if(ndO
utTrans.getN
odeType()==
Node.ELEMENT
_NODE)
{11
30Transi
tion
t;
if(kie
lNodeinstance
ofInitialS
tate){
t=new
InitialArc()
;}else
if(kielNode
instanceof
Choice){
t=new
ConditionalT
ransition();
}else
{t=new
Transition()
;} t.setIDM
anual(normal
izeID(
ndOutT
rans.getAttrib
utes().getNa
medItem(
1140
attrIDRe
f).getNodeVa
lue()));
t.setSou
rce(kielNode
);}
}} //
inte
rneTransiti
onen
Node
ndInner=getF
irstNodeFrom
List(nlStateCh
ildNodes,
"UML:S
tate.interna
lTransition"
);if
(ndI
nner
!=null
){
1150
NodeLi
stnlInner=
ndInner.getC
hildNodes();
Iterat
oriter
=null
;Collec
tion
objects
=kielNode.g
etOutgoingTr
ansitions();
Transi
tion
t=null
;for(i
nti=0;
i<
nlInner.getL
ength();
i++)
{if
(nlI
nner.item(i)
.getNodeType
()==
Node.E
LEMENT_NODE)
{//
Inte
rnal
transiti
onshave
been
createdby
//read
ingtheoutgoi
ngtransiti
ons
//so
getit
from
thecollection
ofallobje
cts
t=null
;11
60iter
=objects.iterat
or();
String
sTransID
=no
rmalizeID(
nlInne
r.item(i).getA
ttributes().
getNamedItem
(attrID).
getNodeValue
());
while(i
ter.hasNext(
)){
t=(Tra
nsition)
iter.next();
if(t.g
etID().equal
s(sTransID))
{break;
1170
}else
{t=nu
ll;
}} if
(t!=
null){
//t.setT
arget(kielNo
de);
kielNode
.removeOutgo
ingTransitio
n(t);
((State)
kielNode).
setInternalT
ransition(t);
readTran
sitionFromNo
de(scChart,
nlInner.item
(i),
1180
true,
t);
}}
}} //
Entr
y/*Node
ndEntry=ge
tFirstNodeFr
omList(nlState
ChildNodes,
"UML:Sta
te.entry");
1190
if(ndE
ntry
!=null
){
142
G.4. XMI-Fileinterface
NodeList
nlEntry=nd
Entry.getChi
ldNodes();
Node
ndAc
tionSequence
=getFirst
NodeFromList
(ndEntry.getCh
ildNodes(),
"Behavio
ral_Elements
.Common_Beha
vior.ActionS
equence");
Node
ndActionSequence
Action
=ge
tFirstNodeFr
omList(
ndAction
Sequence.get
ChildNodes()
,"Behavio
ral_Elements
.Common_Beha
vior.ActionS
equence.acti
on");
Node
ndUninterpretedA
ction=getF
irstNodeFrom
List(
ndActi
onSequenceAc
tion.getChildN
odes(),
"Behav
ioral_Elemen
ts.Common_Beha
vior.Uninter
pretedAction
");
1200
if(ndU
ninterpretedAc
tion
!=null
){
String
sID=ndUnin
terpretedAct
ion.getAttri
butes().getN
amedItem(
AttrID).
getNodeValue
();
String
sActions
=getNameFromNod
eList(
ndUninte
rpretedActio
n.getChildNo
des());
RPSTra
nsitioninne
rTrans
=new
RPSTransitio
n(sID);
innerT
rans.setActi
onStatements(s
Actions);
innerT
rans.setSign
alEventID("");
//kein
Triggerundke
ineGuards
innerT
rans.setGuar
dExpression(""
);innerT
rans.setClas
sID(classID);
1210
innerT
rans.setSour
ceID(sStateID)
;innerT
rans.setTarg
etID(sStateID)
;innerT
rans.setType
(Transition.EN
TRY);
vGloba
lTransitions
.add(innerTran
s);
vTrans
Internal.add
(innerTrans.ge
tID());
}} //
EXIT
Node
ndExit
=getFir
stNodeFromLi
st(nlStateCh
ildNodes,"U
ML:State.exi
t");
if(ndE
xit!=
null)
{12
20NodeList
nlExit
=nd
Exit.getChil
dNodes();
Node
ndActionSequence
=getFirst
NodeFromList
(ndExit.g
etChildNodes
(),
"Behavio
ral_Elements
.Common_Beha
vior.ActionS
equence");
Node
ndActionSequence
Action
=ge
tFirstNodeFr
omList(
ndActi
onSequence.g
etChildNodes()
,"Behav
ioral_Elemen
ts.Common_Beha
vior.ActionS
equence.acti
on");
Node
ndUninterpretedA
ction=getF
irstNodeFrom
List(
ndAction
SequenceActi
on.getChildN
odes(),
"Behav
ioral_Elemen
ts.Common_Beha
vior.Uninter
pretedAction
");
1230
if(ndU
ninterpretedAc
tion
!=null
){
String
sID=ndUnin
terpretedAct
ion.getAttri
butes().getN
amedItem(
AttrID).
getNodeValue
();
String
sActions
=getNameFromNod
eList(
ndUninte
rpretedActio
n.getChildNo
des());
RPSTra
nsitioninne
rTrans
=new
RPSTransitio
n(sID);
innerT
rans.setActi
onStatements(s
Actions);
innerT
rans.setSign
alEventID("");
//kein
Triggerundke
ineGuards
innerT
rans.setGuar
dExpression(""
);innerT
rans.setClas
sID(classID);
1240
innerT
rans.setSour
ceID(sStateID)
;innerT
rans.setTarg
etID(sStateID)
;innerT
rans.setType
(Transition.EX
IT);
vGloba
lTransitions
.add(innerTran
s);
vTrans
Internal.add
(innerTrans.ge
tID());
}}*/
//defe
rrableEvents
Node
ndDef=getFir
stNodeFromLi
st(nlStateCh
ildNodes,
1250
"UML:Sta
te.deferrabl
eEvent");
if(ndD
ef!=
null)
{NodeList
nlDefEvents
=ndDef.getC
hildNodes();
for(int
i=0;
i<
nlDefEvents.
getLength();
i++)
{Node
ndDefEvent
=nl
DefEvents.it
em(i);
if(ndD
efEvent.getN
odeType()==
Node.ELEMENT
_NODE)
{
String
nodeId
=norm
alizeID(
ndDefEve
nt.getAttrib
utes().getNa
medItem(
1260
attrIDRe
f).getNodeVa
lue());
Signal
s=getSigna
lByID(nodeId
);Signal
newSignal=
newSignal(s
.getName());
((State)
kielNode).
addDeferrabl
eEvent(newSi
gnal);
}}
}
1270
if(isR
oot)
{try{ scChart.
setRootNode(
(CompositeSt
ate)
kielNode
);}catch
(Exception
e){
FileInte
rfaceExcepti
onex
=new
FileInterfac
eException(
"The
XMIfile
cont
ains
aroot
node
ofawron
gtype.");
ex.showM
essageBox();
//throw
ex;
}}else
{12
80try{ Collecti
onallObjec
ts=scChart.
getAllObject
s();
Iterator
iter
=allO
bjects.itera
tor();
kiel.dat
aStructure.G
raphicalObje
ctgo
=null
;
while(i
ter.hasNext(
)){
go=(k
iel.dataStru
cture.Graphi
calObject)
iter.next();
if(go.
getID().equa
ls(parentSta
teID))
{break;
}else
{12
90go
=nu
ll;
}} if
(go
!=null){
if((go
instanceof
ANDState)
&&(kielN
odeinstance
ofComposit
eState))
{Region
r=newRegi
on();
r.setI
DManual(kiel
Node.getID());
1300
r.setN
ame(kielNode
.getName());
((ANDS
tate)go).ad
dSubnode(r);
if(((A
NDState)
go).getSubnodes(
).size()
>1)
{Delimite
rLinedelLin
e=newDeli
miterLine();
((ANDSta
te)go).addD
elimiterLine
(delLine);
}}else
{((Comp
ositeState)
go).addSubnode
(kielNode);
1310
}
143
G. Java Code
scChar
t.setChanged
();
}}catch
(Exception
e){
FileIn
terfaceExcepti
onex
=new
FileInterfac
eException(
"Adding
thenode
with
theID
"+
kielNode.get
ID()
+"to
thedatastruct
urewasnot
possible.");
ex.sho
wMessageBox();
//thro
wex;
1320
}} //
Reku
rsion
Node
ndSubVertex=ge
tFirstNodeFr
omList(nlSta
teChildNodes
,"UML:C
ompositeState.
subvertex");
if(ndS
ubVertex
!=nu
ll){
NodeList
nlSubVerte
x=ndSubVer
tex.getChildNo
des();
for(int
i=0;
i<
nlSubVertex.
getLength();
i++)
{Node
ndSubState
=nl
SubVertex.it
em(i);
1330
if(ndS
ubState.getN
odeType()==
Node.ELEMENT
_NODE)
{readSt
ateFromState
Node(scChart,
ndSubState,
false,
sStateID
);}
}}
} /**
1340
*Read
asignal
from
thexmidocu
ment.
*@param
ndSignal
Thenode
from
thexmitree
.*/ privat
evoid
readCl
assSignalEve
ntFromNode(f
inal
Node
ndSignal){
//nur
Referenz
auf
eigentliches
Signal
String
sSignalEvtID
="";
String
sSignalName=
"";
sSignalE
vtID
=ndSign
al.getAttrib
utes().getNa
medItem(
attrID).
getNodeValue
();
sSignalN
ame=ndSign
al.getAttrib
utes().getNa
medItem(
1350
"name").
getNodeValue
();
Signal
s=newSignal
(sSignalName
);s.setIDM
anual(normal
izeID(sSigna
lEvtID));
vGlobalS
ignalEvents.
add(s);
} /**
1360
*An
attributefrom
thexmi.
*@param
ndAttribute
Thenode
from
thexmitr
ee.
*/ privat
evoid
readCl
assAttribute
FromNode(fin
alNode
ndAt
tribute)
{String
sAttributeID
="";
String
sAttributeName
="";
String
sDataTypeID=
"";
sAttribu
teID
=ndAttr
ibute.getAtt
ributes().ge
tNamedItem(
attrID).
getNodeValue
();
1370
sAttribu
teName
=ndAt
tribute.getA
ttributes().
getNamedItem
(
"name"
).getNodeVal
ue();
NodeList
nlAttrChil
dNodes
=ndAt
tribute.getC
hildNodes();
Node
ndDT
=getFirst
NodeFromList
(nlAttrChild
Nodes,
"UML:S
tructuralFea
ture.type");
sDataTyp
eID=getFir
stNodeFromLi
stNoText(
1380
ndDT.g
etChildNodes
()).getAttribu
tes().getNam
edItem(
attrIDRe
f).getNodeVa
lue();
KielUMLA
ttribute
ua=newKielUM
LAttribute(s
AttributeID,
sAttri
buteName,sD
ataTypeID);
vGlobalA
ttributes.ad
d(ua);
}
1390
/** *Handle
aclass.
*@param
ndClassTh
enode
from
thexmitree.
*@param
sPackageID
Theid
ofth
eowning
pack
age.
*@param
sParentCla
ssThename
oftheowning
class.
*/ private
void
readClas
sFromPackage
(final
Node
ndClass,
finalSt
ring
sPacka
geID,final
String
sParen
tClass){
1400
String
className=
"";
String
classID=""
;
Vector
vStateMachin
es=null;
Vector
vSignalEvent
s=null;
Vector
vFeatureAttr
=null;
Vector
vDataTypes
=null;
Vector
vClasses
=nu
ll;
1410
if(ndC
lass.hasChil
dNodes()){
//Date
nderKlasse
auslesen
classID
=ndClass.ge
tAttributes(
).getNamedIt
em(
attrID).
getNodeValue
();
NodeList
nlClassChi
ldNodes=nd
Class.getChi
ldNodes();
classNam
e=ndClass.
getAttribute
s().getNamed
Item(
"name").
getNodeValue
();
KielUMLD
ataTypedt
=newKielUM
LDataType(cl
assName,
clas
sID);
if(dt.
isPrimitive(
)){
1420
vGloba
lDatatypes.a
dd(dt);
} Node
ndOwnedElement
=getFirstNo
deFromList(n
lClassChildN
odes,
"UML:N
amespace.own
edElement");
if(ndO
wnedElement
!=null){
NodeLi
stnlOwned=
ndOwnedEleme
nt.getChildN
odes();
vState
Machines
=ge
tNodesFromLi
st(nlOwned,
"UML:Sta
teMachine");
1430
vSigna
lEvents=ge
tNodesFromList
(nlOwned,
144
G.4. XMI-Fileinterface
"UML:Sig
nalEvent");
//vCal
lEvents=ge
tNodesFromLi
st(nlOwned,"U
ML:CallEvent
");
vDataT
ypes
=getNod
esFromList(n
lOwned,"UML
:Datatype");
vClass
es=getNodes
FromList(nlO
wned,"UML:C
lass");
} Node
ndFeature=ge
tFirstNodeFr
omList(nlCla
ssChildNodes
,"UML:Cla
ssifier.feat
ure");
if(ndF
eature
!=nu
ll){
NodeLi
stnlFeatures
=ndFeatur
e.getChildNode
s();
1440
vFeatu
reAttr
=getN
odesFromList
(nlFeatures,
"UML:Att
ribute");
}} if
(vSt
ateMachines
!=null){
if(vDa
taTypes!=
null){
for(i
nti=0;
i<vDataTypes
.size();
i++)
{14
50readData
TypeFromNode
((Node)vDat
aTypes.eleme
ntAt(i));
}} if
(vCl
asses!=
null
){
for(i
nti=0;
i<vClasses.s
ize();
i++)
{readClas
sFromPackage
((Node)vCla
sses.element
At(i),
sPacka
geID,classID)
;}
}14
60
if(vFe
atureAttr!=
null){
for(int
i=0;
i<
vFeatureAttr
.size();
i++)
{readClas
sAttributeFr
omNode(
(Node)
vFeatureAttr
.elementAt(i
));
}}
1470
if(vSi
gnalEvents
!=null){
for(int
i=0;
i<
vSignalEvent
s.size();i+
+){
readClas
sSignalEvent
FromNode(
(Node)
vSignalEvent
s.elementAt(
i));
}} /*if
(vCallEvents
!=null){
for(int
i=0;
i<
vCallEvents.
size();i++)
{
1480
}}*/
for(i
nti=0;
i<vStateMach
ines.size();
i++)
{readStat
eMachineFrom
Node((Node)
vStateMachin
es.elementAt(i
),"");
}}
}14
90}
145
G. Java Code
G.4
.4.
Kie
lUM
LAtt
ribu
te.jav
a
packag
ekiel.fileInt
erface.xmi.c
ommon;
/** *<p>D
escription:
Helper
class
forUMLAttr
ibuteinform
ation.
</p>
*<p>C
opyright:(c
)2006</p>
*<p>C
ompany:Uni
Kiel</p>
*@aut
hor<a
href="
mailto:kbe@i
nformatik.un
i-kiel.de">K
enBell</a>
*@ver
sion
$Revisio
n:1.2$la
stmodified
$Date:
2006/1
1/08
10:26:21
$*/
10public
classKielUM
LAttribute
{
/** *Theid
oftheattr
ibute.
*/ privat
eString
attr
ID;
/** *Thena
meof
theat
tribute.
20*/ privat
eString
attr
Name;
/** *Theid
ofthedata
type.
*/ privat
eString
data
TypeID;
/**
30*Creato
rof
anAttr
ibute.
*@param
aIDTheid
oftheattrib
ute.
*@param
aNameThena
meof
theat
tribute
*@param
aDataTypeID
Theid
ofth
eassociated
datatype.
*/ public
KielUMLAttri
bute(final
String
aID,
finalSt
ring
aName,
finalString
aDataTypeID)
{this.att
rID=aID;
this.att
rName=aNam
e;this.dat
aTypeID=aD
ataTypeID;
40} /** *Return
stheID
oftheattribut
e.*@retur
nAString
containing
theID.
*/ public
finalString
getAttrID(
){
return
attrID;
}50
/** *Setth
eID
ofthe
attribute.
*@param
sAttrIDTh
enewID.
*/ public
finalvoid
setAttrID(fina
lString
sAtt
rID)
{this.att
rID=sAttrI
D;}
60/** *Return
sthename
oftheattrib
ute.
*@retur
nThename
oftheattrib
ute.
*/ public
finalString
getAttrName(
){
return
attrName;
}
70/** *Setth
ename
ofth
eattribute.
*@param
sAttrName
Aname.
*/ public
finalvoid
setAttrName(fi
nalString
sAttrName)
{this.att
rName=sAtt
rName;
} /**
80*Return
stheID
oftheattribur
te’s
dataty
pe.
*@retur
nAn
ID.
*/ public
finalString
getDataTypeI
D(){
return
dataTypeID;
} /** *Setth
eID
ofthe
attribute’s
datatype.
90*@param
sDataTypeI
DAn
ID.
*/ public
finalvoid
setDataTypeID(
finalString
sDataTypeID)
{this.dat
aTypeID=sD
ataTypeID;
}}
146
G.4. XMI-Fileinterface
G.4
.5.
Kie
lUM
LD
ataT
ype.
java
packag
ekiel.fileI
nterface.xmi
.common;
/** *<p>Des
cription:He
lper
classfo
rtheDataty
petranslat
ion.
</p>
*<p>Cop
yright:(c)
2006</p>
*<p>Com
pany:UniKi
el</p>
*@autho
r<a
href="
mailto:kbe@inf
ormatik.uni-
kiel.de">Ken
Bell</a>
*@versi
on$Revisio
n:1.2$last
modified
$Date:
2006/11/
0810:26:21
$10
*/ public
classKielUM
LDataType{
/** *Thear
rayformapp
ingprimitiv
etypes.
*/ private
static
Stri
ng[]
primitiv
eTypes
={"int",
"integer",
"int8","int16
","int32",
"bool",
"boolean",
20"float",
"numeric",
"long"};
/** *Thear
rayof
poss
ible
integer
types.
*/ private
static
Stri
ng[]
integerN
ames
={"int",
"integer",
"int8","int16
","int32"}
;
/** *Thear
rayof
poss
ible
floating
types.
30*/ private
static
Stri
ng[]
floatNam
es=
{"float"
,"numeric",
"long"};
/** *Thear
rayof
poss
ible
namesfo
rbooleanty
pes.
*/ private
static
Stri
ng[]
boolName
s=
{"bool",
"boolean"}
;
40/** *Thena
meof
theda
tatype.
*/ private
String
name
;
/** *Theid
ofthedata
type.
*/ private
String
id;
50/** *Creato
rforadata
type
wrappe
r.*@param
sNameName
ofthedata
type.
*@param
sIDID
from
theXMIfi
le.
*/
public
KielUMLDataT
ype(finalSt
ring
sName,
finalString
sID)
{super(
);this.n
ame=sName;
this.i
d=sID;
60} /** *.
*@ret
urn.
*/ public
finalString
getId(){
return
id;
}
70/** *.
*@par
amsID.
*/ public
finalvoid
setId(finalSt
ring
sID)
{this.i
d=sID;
} /** *.
80*@ret
urn.
*/ public
finalString
getName(){
return
name;
} /** *.
*@par
amsName.
*/90
public
finalvoid
setName(final
String
sNam
e){
this.n
ame=sName;
} /** *Deci
desif
theda
tatype
isa
primitive.
*@ret
urnBoolean
value.
*/10
0public
finalboolea
nisPrimitiv
e(){
boolea
nresult
=fa
lse;
for(i
nti=0;
i<primitiveTyp
es.length;
i++)
{result
=primitiveT
ypes[i].equa
lsIgnoreCase
(name);
if(res
ult)
{break;
}} return
result;
110
}
147
G. Java Code
/** *Return
theClassof
primitives
.*@retur
nAClass.
*/ public
finalClass
getPrimitive
(){
Classre
sult
=null;
120
for(int
i=0;
i<
integerNames
.length;
i++)
{if
(int
egerNames[i]
.equalsIgnor
eCase(name))
{result
=int.class;
}} if
(res
ult!=
null)
{return
result;
}
130
for(int
i=0;
i<
floatNames.l
ength;
i++)
{
if(flo
atNames[i].e
qualsIgnoreC
ase(name))
{result
=float.clas
s;}
} if(res
ult!=
null)
{return
result;
}
140
for(int
i=0;
i<
boolNames.le
ngth;i++)
{if
(boo
lNames[i].eq
ualsIgnoreCa
se(name)){
result
=boolean.cl
ass;
}} return
result;
}
}
148
G.4. XMI-Fileinterface
G.4
.6.
Lab
elG
ener
ator
.jav
a
packag
ekiel.fileI
nterface.xmi
.ArgoUML;
import
kiel.dataStr
ucture.actio
n.Action;
import
kiel.dataStr
ucture.actio
n.GenerateEv
ent;
import
kiel.dataStr
ucture.actio
n.IntegerAss
ignment;
import
kiel.dataStr
ucture.boole
xp.*;
import
kiel.dataStr
ucture.event
exp.*;
import
kiel.dataStr
ucture.intex
p.*;
10import
java.util.It
erator;
import
java.util.St
ack;
import
kiel.dataStr
ucture.Compo
undLabel;
import
kiel.dataStr
ucture.State
Chart;
import
kiel.dataStr
ucture.Trans
itionLabel;
import
kiel.fileInt
erface.FileI
nterfaceExce
ption;
import
kiel.fileInt
erface.JavaT
ransitionLab
els.analysis
.DepthFirstA
dapter;
import
kiel.fileInt
erface.JavaT
ransitionLab
els.node.*;
20/** *<p>Des
cription:La
belgenerato
rcalled
bytheArgoUMLR
eader.
*This
classextend
saDepthFirst
Adaptergene
ratedwith
SableCC.
</p>
*<p>Cop
yright:(c)
2006</p>
*<p>Com
pany:UniKi
el</p>
*@autho
r<a
href="
mailto:kbe@inf
ormatik.uni-
kiel.de">Ken
Bell</a>
*@versi
on$Revisio
n:1.3$last
modified
$Date:
2006/11/
0810:26:20
$*/ public
classLabelG
enerator
extendsDepthFir
stAdapter{
30/** *Thest
atechart
ofwhichthege
neratedlabe
lis
part
of.
*/ private
StateChart
sc;
/** *Astac
kforparsin
g.*/ private
Stackstack;
40/** *Thege
neratedlabe
l.*/ private
CompoundLabe
llabel;
/** *Flag
forparsing.
*/ private
booleaninTr
iggerMode=
false;
50/** *Flag
forparsing.
*/ private
booleaninGu
ardMode=fa
lse;
/** *Flag
forparsing.
*/ private
booleaninAc
tionMode
=false;
60/** *Flag
forparsing.
*/ private
booleaninAs
signment
=false;
/** *Inte
rnal
method
toshow
thepa
ssed
error
inamessage
box.
*@par
amaError
String
descript
ionof
theer
ror.
*/70
private
void
printE
rror(final
String
aError)
{FileIn
terfaceExcepti
onex
=new
FileInterfac
eException(a
Error);
ex.sho
wMessageBox();
//Syst
em.out.println
(aError);
} /** *Crea
torforthe
LabelGenerator
.*The
labels
create
darerefere
ncingtheva
riablesand
signalsfoun
d80
*with
inthepassed
statechart.
*@par
amchartThe
chartto
look
forvariab
lenames.
*/ public
LabelGenerat
or(final
Stat
eChart
chart)
{super(
);sc
=ch
art;
label
=newCompou
ndLabel();
stack
=newStack(
);}
90/** *Retu
rnsthecrea
tedtransition
label.
*@ret
urnThetran
sition
label
object.
*/ public
finalTransi
tionLabelge
tTransitionLab
el()
{return
label;
}
100
/** *@par
amnode
The
triggernode.
*/ public
finalvoid
inATrigger(fin
alATrigger
node){
inTrig
gerMode=tr
ue;
} /** *Mess
agehandler
fortheevent
when
atrig
gernode
isleft.
*@par
amnode
The
triggernode.
110
*/
149
G. Java Code
public
finalvoid
outATrigger(
finalATrigger
node){
label.se
tTrigger((De
layExpressio
n)stack.pop(
));
inTrigge
rMode=fals
e;} /**
120
*Event
handlercall
edwhen
anEx
pression
statementis
left.
*@param
node
.*/ public
finalvoid
outAExpressi
onStatement(fi
nalAExpress
ionStatement
node){
label.ge
tEffect().ad
dAction((Act
ion)
stack.po
p());
} /** *Event
handlercall
edwhen
asi
ngle
effect
statementis
left.
*@param
node
.13
0*/ public
finalvoid
outASingleEf
fect(final
ASingleEffect
node){
label.ge
tEffect().ad
dAction((Act
ion)
stack.po
p());
} /** *Event
handlercall
edwhen
asi
ngle
effect
statementis
entered.
*@param
node
.*/
140
public
finalvoid
inASingleEff
ect(finalASin
gleEffectno
de){
inAction
Mode
=true;
} /** *Event
handlercall
edwhen
amu
ltiple
effect
statement
isentered.
*@param
node
.*/ public
finalvoid
inAMultipleE
ffect(finalAM
ultipleEffec
tnode){
inAction
Mode
=true;
150
} /** *Called
when
aassi
gnementstat
ementis
ente
red.
*@param
node
.*/ public
finalvoid
inAAssignmen
t(finalAAssig
nmentnode)
{inAssign
ment
=true;
}
160
/** *Called
when
anassi
gnementstat
ementis
left.
*@param
node
.*/ public
void
outAAs
signment(final
AAssignmen
tnode){
IntegerE
xpressionex
p=(Integer
Expression)
stack.pop();
IntegerV
ariablevar
=(IntegerVa
riable)stac
k.pop();
IntegerA
ssignmentas
signment
=ne
wIntegerAss
ignment(var,
exp);
stack.pu
sh(assignmen
t);
170
inAssign
ment
=false;
} /** *Called
when
aguar
dis
entere
d.*@param
node
.*/ public
finalvoid
inAGuard(final
AGuard
node
){
stack.cl
ear();
180
inGuardM
ode=true;
} /** *Called
when
aguar
dis
left.
*@param
node
.*/ public
finalvoid
outAGuard(fina
lAGuard
node
){
label.se
tCondition((
BooleanExpre
ssion)
stack.
pop());
inGuardM
ode=false;
190
stack.cl
ear();
} /** *Called
when
astat
ementsurrou
nded
bybrac
kets
isleft
.*@param
node
.*/ public
finalvoid
outALParenthes
ePrimaryNoNe
wArray(
final
ALParenthesePr
imaryNoNewAr
raynode){
200
Object
item;
item
=stack.pop();
BooleanB
racketsbrac
ket=
newBo
oleanBrackets(
(BooleanExpr
ession)item
);stack.pu
sh(bracket);
} /** *Called
when
adeci
malinteger
literalis
parsed.
*@param
node
.21
0*/ public
finalvoid
inADecimalInte
gerLiteral(f
inal
ADecimal
IntegerLiter
alnode){
IntegerC
onstantcons
tant
=new
IntegerConstan
t();
constant
.setValue(In
teger.parseI
nt(
node.g
etDecimalInt
egerLiteral(
).getText()));
stack.pu
sh(constant)
;} /**
220
*Intern
ally
used
method
toget
theinteger
expression
from
thestat
echart
*by
thepassed
name
.*@param
itemName
Name
ofthein
tegervariab
le.
*@retur
nTheIntege
rExpression
object
from
thestatecha
rtif
found.
*/ private
IntegerExpre
ssiongetVar
iableByName(
finalString
itemName){
IntegerV
ariablev=
null;
Iterator
iter
=sc.g
etAllVariabl
es().iterato
r();
230
while(i
ter.hasNext(
)){
150
G.4. XMI-Fileinterface
v=(I
ntegerVariable
)iter.next(
);
if(v.g
etName().equ
als(itemName
)){
return
v;}
} return
null;
}
240
/** *Return
sthesignal
object
for
thepassed
signal
name.
*@param
signalName
Name
ofthe
signal
tore
turn
*@retur
nEventobje
ctif
amatc
hing
signal
wasfound.
*/ private
EventgetSig
nalByName(fi
nalString
signalName){
Eventev
=null;
250
Iterator
iter
=sc.g
etInputEvent
s().iterator
();
while(i
ter.hasNext(
)){
ev=(E
vent)iter.n
ext();
if(ev.
getName().eq
uals(signalN
ame)){
return
ev;
}} return
null;
}
260
/** *Called
when
asimp
lename
was
parsed.
*@param
node
.*/ public
finalvoid
inASimpleName(
finalASimpl
eNamenode)
{//
TODO
:As
of2006
-08-02:
//All
variablesan
dSignalsin
thestacks
//are
oftype
inte
gerforthe
sake
ofsimp
licity
//Inte
gerVariable
v=newInte
gerVariable(
270
//node
.getIdentifi
er().getText
(),
//null
);
Object
o=null;
if(inG
uardMode){
o=ge
tVariableByN
ame(node.getId
entifier().g
etText());
} if(inT
riggerMode)
{o=ne
wDelayExpre
ssion();
((Dela
yExpression)
o).setEventE
xpression(
280
getSigna
lByName(node
.getIdentifi
er().getText
()));
} if(inA
ctionMode)
{if
(inA
ssignment)
{o=ge
tVariableByN
ame(node.get
Identifier()
.getText());
}else
{Event
e=getSigna
lByName(node
.getIdentifi
er().getText()
);o=ne
wGenerateEv
ent(e);
}}
290
if(o
!=null){
stack.
push(o);
}else
{if
((in
TriggerMode
||(inActio
nMode&&
!inA
ssignment)))
{o=new
Signal("erro
r_"
+node
.getIdentifier
().getText()
);if
(!in
TriggerMode)
{o=new
GenerateEven
t((Event)o)
;30
0}
}else
{o=new
IntegerVaria
ble("error_"
+node
.getIdentifier
().getText()
);} //
push
theevent
onthestack.
otherwise,
anaccessviol
ation
//will
occur.
stack.
push(o);
printE
rror("Thesi
mple
name
\""
310
+node.g
etIdentifier
().getText()
+"\"at
position
["+node.g
etIdentifier
().getLine()
+","
+node.g
etIdentifier
().getPos()
+"]
wasnotresolv
ed.");
}} /**
320
*Call
edwhen
anEq
uality
espres
sion
waspa
rsed.
*@par
amnode
.*/ public
finalvoid
outAEqEquality
Expression(
final
AEqEqualityE
xpressionno
de){
Intege
rExpressionri
ght=(Integ
erExpression
)stack.pop(
);Intege
rExpressionle
ft=(Integ
erExpression
)stack.pop(
);Equal
e=newEqua
l(left,right)
;stack.
push(e);
}33
0
/** *Call
edwhen
apa
rsed
nonequa
lity
expressi
onis
left.
*@par
amnode
.*/ public
finalvoid
outANeqEqualit
yExpression(
final
ANeqEquality
Expression
node){
Intege
rExpressionri
ght=(Integ
erExpression
)stack.pop(
);Intege
rExpressionle
ft=(Integ
erExpression
)stack.pop(
);34
0NotEqu
alneq=new
NotEqual(lef
t,right);
stack.
push(neq);
} /** *Call
edwhen
atw
opart
condit
ionalexpres
sion
combined
with
andis
left.
*@par
amnode
.*/ public
finalvoid
outAConditiona
lAndExpressi
onConditiona
lAndExpressi
on(
350
final
AConditional
AndExpressio
nConditionalAn
dExpression
node){
151
G. Java Code
BooleanE
xpressionri
ght=(Boole
anExpression
)stack.pop();
BooleanE
xpressionle
ft=(Boolean
Expression)
stack.pop();
BooleanA
ndand=new
BooleanAnd(l
eft,
right)
;stack.pu
sh(and);
} /**
360
*Called
when
atwo
part
conditio
nalexpressi
oncombined
with
oris
left.
*@param
node
.*/ public
finalvoid
outAConditio
nalOrExpressio
nConditional
OrExpression
(finalAC
onditionalOr
ExpressionCo
nditionalOrE
xpressionno
de){
BooleanE
xpressionri
ght=(Boole
anExpression
)stack.pop();
BooleanE
xpressionle
ft=(Boolean
Expression)
stack.pop();
BooleanO
ror
=newBo
oleanOr(left
,right);
stack.pu
sh(or);
370
} /** *Called
when
aless
equalthan
expression
isleft.
*@param
node
.*/ public
finalvoid
outALteqRela
tionalExpressi
on(
finalAL
teqRelationa
lExpression
node){
IntegerE
xpressionri
ght=(Integ
erExpression
)stack.pop();
380
IntegerE
xpressionle
ft=(Integer
Expression)
stack.pop();
LessOrEq
uallteq
=ne
wLessOrEqua
l(left,righ
t);
stack.pu
sh(lteq);
} /** *Called
when
aless
than
expres
sion
isleft
.*@param
node
.*/
390
public
finalvoid
outALtRelati
onalExpression
(finalAL
tRelationalE
xpressionno
de){
IntegerE
xpressionri
ght=(Integ
erExpression
)stack.pop();
IntegerE
xpressionle
ft=(Integer
Expression)
stack.pop();
LessThan
lt=newLe
ssThan(left,
right);
stack.pu
sh(lt);
} /**
400
*Called
when
agrea
terthan
equalexpression
isleft.
*@param
node
.*/ public
finalvoid
outAGteqRelati
onalExpressi
on(
finalAG
teqRelationa
lExpression
node){
IntegerE
xpressionri
ght=(Integ
erExpression
)stack.pop(
);IntegerE
xpressionle
ft=(Integer
Expression)
stack.pop();
GreaterO
rEqual
gteq
=newGreate
rOrEqual(lef
t,right);
stack.pu
sh(gteq);
410
} /** *Called
when
agrea
terthan
expression
isle
ft.
*@param
node
.*/ public
finalvoid
outAGtRelation
alExpression
(finalAG
tRelationalE
xpressionno
de){
IntegerE
xpressionri
ght=(Integ
erExpression
)stack.pop(
);IntegerE
xpressionle
ft=(Integer
Expression)
stack.pop();
420
GreaterT
hangt
=ne
wGreaterThan(
left,right)
;stack.pu
sh(gt);
} /** *Called
when
acomp
lementaryex
pression
isleft.
*@param
node
.*/ public
finalvoid
outAComplement
UnaryExpress
ionNotPlusMinu
s(43
0final
AComplementUna
ryExpression
NotPlusMinus
node){
BooleanE
xpressionex
=(BooleanEx
pression)st
ack.pop();
BooleanN
otnot=ne
wBooleanNot(e
x);
stack.pu
sh(not);
}
440
}
152
G.4. XMI-Fileinterface
G.4
.7.
XM
IGen
erat
or.jav
a
packag
ekiel.fileI
nterface.xmi
;
import
java.io.File
;import
java.io.File
NotFoundExce
ption;
import
java.io.File
Writer;
import
java.io.IOEx
ception;
import
java.util.Co
llection;
import
java.util.It
erator;
10import
org.jdom.Doc
ument;
import
org.jdom.Ele
ment;
import
org.jdom.Nam
espace;
import
org.jdom.out
put.Format;
import
org.jdom.out
put.XMLOutpu
tter;
import
kiel.dataStr
ucture.State
Chart;
import
kiel.dataStr
ucture.Trans
ition;
20/** *<p>Des
cription:Th
isclassis
used
towrit
ean
instance
ofastatec
hart
*to
aXMIfile.</p
>*<p>Cop
yright:(c)
2006</p>
*<p>Com
pany:UniKi
el</p>
*@autho
r<a
href="
mailto:kbe@inf
ormatik.uni-
kiel.de">Ken
Bell</a>
*@versi
on$Revisio
n:1.3$last
modified
$Date:
2006/11/
0810:26:20
$*/ public
classXMIGen
erator
{
30/** *Thena
meof
theex
porter.
*It
iswrittento
theMeta-Tag
sectionof
thegenerated
XMIfile.
*/ private
static
String
sXMIEXPORT
ERNAME
="ArgoUML
(using
Netb
eans
XMIWr
iter
version
1.0)";
//"KIE
L(Kielinte
grated
enviro
nmentforLa
yout)-XMI
Exporter";
/**
40*Theve
rsionof
theexporter.
*It
iswrittento
theMeta-Tag
sectionof
thegenerated
XMIfile.
*/ private
static
Stri
ngsXMIEXPORT
ERVERSION=
"0.20.x"
;
/** *Thege
neratedxmi
document.
*/50
private
Document
output;
/** *Thena
mespaceto
useforthe
generateddo
cument.
*/ private
Namespacens
UML;
/** *Writ
estheMeta-T
aginformatio
nto
thedo
cument.
*/60
private
void
writeX
MIHeader()
{Elemen
troot
=new
Element("XMI
");
nsUML
=Namespace.
getNamespace("
UML","org.o
mg.xmi.names
pace.UML");
root.s
etAttribute("x
mi.version",
"1.2");
root.a
ddNamespaceDec
laration(nsU
ML);
output
.setRootElemen
t(root);
Elemen
theader
=ne
wElement("X
MI.header");
Elemen
theader2=
newElement("X
MI.header");
70header
.addContent(he
ader2);
Elemen
tdocumentat
ion=newElem
ent("XMI.doc
umentation")
;header
2.addContent(d
ocumentation
);Elemen
texporter
=newElement(
"XMI.exporte
r");
export
er.setText(sXM
IEXPORTERNAM
E);
Elemen
tversion=
newElement("X
MI.exporterV
ersion");
versio
n.setText(sXMI
EXPORTERVERS
ION);
Elemen
tmetamodel
=newElement(
"XMI.metamod
el");
metamo
del.setAttribu
te("xmi.name
","UML");
metamo
del.setAttribu
te("xmi.vers
ion","1.4")
;80
docume
ntation.addCon
tent(exporte
r);
docume
ntation.addCon
tent(version
);docume
ntation.addCon
tent(metamod
el);
root.a
ddContent(head
er);
} /** *Crea
tesapackag
estub
andan
classstub
intheXMIfi
le.
*The
statechart
isassigned
totheclassaf
terwards.
*The
modelis
give
nthename
oftheexport
edstatechart
.90
*@par
amchartName
Thename
ofthestatecha
rt.
*@ret
urnAn
XMIel
ement.
*/ private
Elementwrit
eStateChartP
requel(final
String
char
tName)
{
Elemen
tcontent=
newElement("X
MI.content")
;output
.getRootElemen
t().addConte
nt(content);
Elemen
tmodel=ne
wElement("Mod
el",
nsUML)
;conten
t.addContent(m
odel);
100
model.
setAttribute("
xmi.id",
"a");
model.
setAttribute("
name",
char
tName);
model.
setAttribute("
isSpecificat
ion","false
");
model.
setAttribute("
isRoot",
"false");
model.
setAttribute("
isLeaf",
"false");
model.
setAttribute("
isAbstract",
"false");
Elemen
tnsOwned=
newElement("N
amespace.own
edElement",
nsUML);
model.
addContent(nsO
wned);
110
Elemen
teleClass
=newElement(
"Class",
nsUM
L);
153
G. Java Code
nsOwned.
addContent(e
leClass);
eleClass
.setAttribut
e("xmi.id",
"#class01");
eleClass
.setAttribut
e("name",""
);eleClass
.setAttribut
e("visibilit
y","public"
);eleClass
.setAttribut
e("name",""
);eleClass
.setAttribut
e("isSpecifi
cation",
"fal
se");
eleClass
.setAttribut
e("isRoot",
"false");
eleClass
.setAttribut
e("isLeaf",
"false");
120
eleClass
.setAttribut
e("isAbstrac
t","false")
;eleClass
.setAttribut
e("isActive"
,"false");
nsOwned
=newElemen
t("Namespace
.ownedElemen
t",nsUML);
eleClass
.addContent(
nsOwned);
return
nsOwned;
} /**
130
*Writes
informations
abouttran
sitionsto
theXMIfile
inthestate
*tag.
*@param
labelThena
meof
thest
atevertex.
*@param
transitions
Thecollecti
onof
alltr
ansitions.
*@param
eleTheXMI
element.
*/ privat
evoid
handle
Transitions(
finalString
label,
finalCo
llection
transitions,
finalElement
ele)
{
if(tra
nsitions.size(
)<1)
{14
0return;
} Element
transVertex
=newElemen
t("StateVert
ex."
+label,
nsUML);
ele.addC
ontent(trans
Vertex);
Iterator
iter
=tran
sitions.iter
ator();
while(i
ter.hasNext(
)){
Transiti
ont=(Tra
nsition)
iter
.next();
Element
eleTrans
=newElement(
"Transition",
nsUML);
150
eleTrans
.setAttribut
e("xmi.idref
",t.getID())
;transVer
tex.addConte
nt(eleTrans)
;}
} /** *Return
stheTagfo
rthepassed
KIEL
node.
*@param
nThenode
from
thestat
echart.
*@retur
nAstring
containing
thetype
string
ofthenode
.16
0*/ privat
eString
getU
MLNodeTagFro
mKielNode(fi
nalkiel.dat
aStructure.N
oden)
{String
result
="";
if(n
instanceof
kiel
.dataStructu
re.Composite
State)
{result
="Composite
State";
}else
if(n
instance
ofkiel.dat
aStructure.F
inalSimpleSt
ate)
{result
="FinalStat
e";
}else
if(n
instance
ofkiel.dat
aStructure.S
impleState)
{result
="SimpleSta
te";
}else
if(n
instance
ofkiel.dat
aStructure.P
seudoState)
{17
0result
="Pseudosta
te";
} return
result;
} /** *This
method
recurs
ivelytraver
sesthetree
structure.
*@param
stateThe
currentstat
e.*@param
eleThecu
rrentXMIel
ement.
*/18
0private
void
writeSta
te(final
kiel.dataStruc
ture.Nodest
ate,
final
Elementele)
{Element
eleState
=null;
eleState
=newElem
ent(getUMLNo
deTagFromKielN
ode(state),
nsUML);
ele.addC
ontent(eleSt
ate);
eleState
.setAttribut
e("xmi.id",
state.getID(
));
eleState
.setAttribut
e("name",st
ate.getName(
));
eleState
.setAttribut
e("isSpecifi
cation",
"fal
se");
190
if(sta
teinstanceof
kiel.dataS
tructure.Compo
siteState)
{eleSta
te.setAttribut
e("isConcurr
ent",
Boolean.
toString(
state
instanceof
kiel.dataStruc
ture.ANDStat
e));
}else
if(state
instanceof
kiel
.dataStructu
re.PseudoSta
te){
String
kind
="";
if(sta
teinstanceof
kiel.dataS
tructure.For
kConnector)
{kind
="fork";
}else
if(state
instanceof
kiel
.dataStructu
re.InitialSt
ate)
{kind
="initial";
200
}else
if(state
instanceof
kiel
.dataStructu
re.Join)
{kind
="join";
}else
if(state
instanceof
kiel
.dataStructu
re.History)
{kind
="shallowHist
ory";
}else
if(state
instanceof
kiel
.dataStructu
re.DeepHisto
ry){
kind
="deepHistory
";}else
if(state
instanceof
kiel
.dataStructu
re.Junction)
{kind
="junction";
}else
if(state
instanceof
kiel
.dataStructu
re.Choice)
{kind
="choice";
210
} eleState
.setAttribut
e("kind",ki
nd);
} if(ele
State!=
null
){
handleTr
ansitions("i
ncoming",st
ate.getIncom
ingTransitio
ns(),
eleState
);handleTr
ansitions("o
utgoing",st
ate.getOutgo
ingTransitio
ns(),
eleState
);}
220
if(sta
teinstanceof
kiel.dataStr
ucture.Compo
siteState)
{Element
subVertex=
newElement(
"CompositeSt
ate.subverte
x",nsUML);
eleState
.addContent(
subVertex);
kiel.dat
aStructure.C
ompositeStat
ecomp
=(kiel.
dataStructur
e.CompositeSta
te)state;
for(int
i=0;
i<
comp.getSubn
odes().size(
);i++)
{writeS
tate((kiel.d
ataStructure.N
ode)
comp.g
etSubnodes()
.get(i),
230
subVerte
x);
154
G.4. XMI-Fileinterface
}}
} /** *Writes
informatio
naboutall
transitions
afterallstat
einformatio
n*waspr
ocessedto
theXMIfile
.24
0*@param
transition
sTheXMIel
ementto
writ
ethetransi
tion
informat
ion
*to.
*@param
chartThe
handledstat
echart.
*/ private
void
writeTra
nsitions(fin
alElement
transitions,
final
StateChart
chart)
{
Iterator
iter
=char
t.getAllObje
cts().iterat
or();
while(i
ter.hasNext(
)){
Object
o=iter.nex
t();
250
if(o
instanceof
Transition){
Transi
tion
t=(Tra
nsition)
o;
Elemen
teleTrans
=newElement(
"Transition"
,nsUML);
transi
tions.addCon
tent(eleTran
s);
eleTra
ns.setAttrib
ute("xmi.id"
,t.getID());
eleTra
ns.setAttrib
ute("isSpeci
fication",
"false");
Elemen
tsource
=ne
wElement("T
ransition.so
urce",
nsUML)
;26
0Elemen
ttarget
=ne
wElement("T
ransition.ta
rget",
nsUML)
;Elemen
tsrcInstanc
e=newElem
ent(
getUMLNo
deTagFromKie
lNode(t.getS
ource()),ns
UML);
srcIns
tance.setAtt
ribute("xmi.
idref",t.getS
ource().getI
D());
source
.addContent(
srcInstance)
;Elemen
ttrgInstanc
e=newElem
ent(
getUMLNo
deTagFromKie
lNode(t.getT
arget()),ns
UML);
trgIns
tance.setAtt
ribute("xmi.
idref",t.getT
arget().getI
D());
target
.addContent(
trgInstance)
;
270
eleTra
ns.addConten
t(source);
eleTra
ns.addConten
t(target);
}}
} /** *Writes
thestatec
hart
informat
ionto
the
XMIDocument.
280
*@param
chartThe
statechart
toexport.
*/ private
void
writeSta
teChart(fina
lStateChart
chart)
{
Element
ownedElement
=writeSta
teChartPrequ
el(
chart.
getRootNode(
).getName())
;
Element
stateMachine
=newElem
ent("StateMa
chine",nsUML)
;ownedEle
ment.addCont
ent(stateMac
hine);
stateMac
hine.setAttr
ibute("xmi.i
d","machine
ID001");
290
stateMac
hine.setAttr
ibute("isSpe
cification",
"false");
Elemen
tsmCtx=new
Element("Sta
teMachine.co
ntext",nsUM
L);
stateM
achine.addCont
ent(smCtx);
Elemen
tclassRef
=newElement(
"Class",
nsUM
L);
classR
ef.setAttribut
e("xmi.idref
","#class0
1");
smCtx.
addContent(cla
ssRef);
Elemen
ttop=newEl
ement("State
Machine.top"
,nsUML);
300
stateM
achine.addCont
ent(top);
//hand
lenodes
writeS
tate(chart.get
RootNode(),
top);
//hand
leTransition
sElemen
ttransitions
=newElemen
t("StateMach
ine.transiti
ons",nsUML)
;stateM
achine.addCont
ent(transiti
ons);
writeT
ransitions(tra
nsitions,ch
art);
310
} /** *Crea
torforthe
XMIexporter.
TheXMIdocu
ment
iscrea
tedhere.
*/ public
XMIGenerator
(){
output
=newDocume
nt();
}
320
/** *Writ
esthecreate
dXMIDocume
ntto
thepa
ssed
file.
*@par
amfThefile
towriteth
edocument
to.
*@ret
urn<code>tr
ue</code>if
successful.
*/ private
booleanwrit
eXMIToFile(f
inal
File
f){
XMLOut
putter
writer
=newXMLOut
putter();
FileWr
iter
fw=nu
ll;
330
Format
outputFormat
=writer.get
Format();
output
Format.setInde
nt("
");
writer
.setFormat(out
putFormat);
boolea
nresult
=fa
lse;
try{ fw
=ne
wFileWriter
(f);
if(fw
!=null){
writer.o
utput(output
,fw);
result
=true;
}34
0}catc
h(FileNotFoun
dException
e){
e.prin
tStackTrace(
);}catc
h(IOException
e){
e.prin
tStackTrace(
);} return
result;
} /** *This
method
call
sallnecessar
ymethodsto
writethe
passed
statec
hart
350
*to
thepassed
file.
155
G. Java Code
*@param
chartThest
atechart
toexport.
*@param
fThedestin
ationfile.
*@retur
nThefile.
*/ public
finalFile
generateChar
t(finalStateC
hart
chart,
finalFi
lef)
{
writeXMI
Header();
writeSta
teChart(char
t);
360
writeXMI
ToFile(f);
return
f;}
}
156