Software Engineering I/II

Werbung
Software Factories
Skript zur Lehrveranstaltung
Hartmut Fritzsche
Hochschule für Technik und Wirtschaft Dresden
Fakultät Informatik/Mathematik
11. Januar 2016
Inhaltsverzeichnis
1 Grundlagen der Softwaretechnik
1.1 Der Softwareentwicklungsprozess . . . . . . . . . . . . . . . . . . . .
1.1.1 Die Phasen des Softwareentwicklungsprozesses . . . . . . . .
1.1.2 Prozessmodellierung . . . . . . . . . . . . . . . . . . . . . . .
1.1.3 Konfigurationsmanagement . . . . . . . . . . . . . . . . . . .
1.1.3.1 Verwaltung von Konfigurationselementen: Mercurial
1.1.3.2 Build-Management . . . . . . . . . . . . . . . . . . .
1.2 Methodologie der Softwareentwicklung . . . . . . . . . . . . . . . . .
1.2.1 Objekttechnologie/UML . . . . . . . . . . . . . . . . . . . . .
1.2.2 Agile Softwareentwicklung/eXtreme-Programming . . . . . .
1.2.3 Generatoren . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.3 Softwareentwicklungswerkzeuge . . . . . . . . . . . . . . . . . . . . .
1.3.1 CASE-Tools . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.3.2 Die Plattform Eclipse . . . . . . . . . . . . . . . . . . . . . .
1.3.2.1 Installieren neuer Software (Features, Plug-ins) . . .
1.3.2.2 Entwicklung von Java-Applikationen . . . . . . . . .
1.3.2.3 Unterstützung der UML . . . . . . . . . . . . . . . .
2 Werkzeugentwicklung mit Eclipse
2.1 Plug-ins . . . . . . . . . . . . . . . . . . . . .
2.2 Technologie zur Entwicklung von Plug-ins . .
2.3 Kommunikation zwischen Plug-ins . . . . . .
2.3.1 Erstellen des ersten Plug-ins . . . . .
2.3.2 Erstellung eines Plug-ins, welches vom
werden kann . . . . . . . . . . . . . .
2.3.3 Testen der Kommunikation . . . . . .
2.4 Features und Update-Sites . . . . . . . . . .
2.4.1 Features erzeugen . . . . . . . . . . .
2.4.2 Erzeugung einer Eclipse-Update-Site .
1
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
ersten Plugin aufgerufen
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
4
4
4
8
8
8
8
9
9
9
10
10
10
11
12
13
13
.
.
.
.
16
16
19
38
38
.
.
.
.
.
40
41
43
43
47
INHALTSVERZEICHNIS
2.5
2.6
2
Entwicklung von RCP-Applikationen . . . . . . . . . . . . . . . . . . . . 51
Eclipse: Produkt und Applikation . . . . . . . . . . . . . . . . . . . . . . 53
3 Modellgetriebene Softwareentwicklung
3.1 Modelle und Modellebenen . . . . . . . . . . . . . . . . . . . . .
3.2 Definition und Verarbeitung formaler Sprachen . . . . . . . . . .
3.2.1 Formale Sprachen (Wiederholung) . . . . . . . . . . . . .
3.2.2 Abstrakte und konkrete Syntax . . . . . . . . . . . . . . .
3.2.3 Semantik . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.2.4 Lexikalische und syntaktische Analyse . . . . . . . . . . .
3.3 MOF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.4 Domänenspezifische Sprachen . . . . . . . . . . . . . . . . . . . .
3.5 Plattformen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.6 Werkzeuge zur Metamodellierung: EMF . . . . . . . . . . . . . .
3.6.1 Einführungsbeispiel . . . . . . . . . . . . . . . . . . . . .
3.6.2 Erstellung von EMF-Modellen aus UML-Diagrammen . .
3.6.3 Erstellen von EMF-Modellen mit Hilfe des Ecore-Editors
3.7 Modellaustausch . . . . . . . . . . . . . . . . . . . . . . . . . . .
4 Werkzeuge zur Unterstützung der MDSD
4.1 Überblick . . . . . . . . . . . . . . . . . . . . . . . . . .
4.2 Xtext . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.2.1 Installation . . . . . . . . . . . . . . . . . . . . .
4.2.2 Erstes Anwendungsbeispiel . . . . . . . . . . . .
4.2.3 Zweites Anwendungsbeispiel . . . . . . . . . . . .
4.2.4 Die Xtext-Grammatiksprache . . . . . . . . . . .
4.3 Xtend . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.3.1 Die Sprache Xtend . . . . . . . . . . . . . . . . .
4.3.2 Entwicklung eines Code-Generators mit Xtend .
4.3.3 Beispiel . . . . . . . . . . . . . . . . . . . . . . .
4.4 Xpand . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.5 Aspektorientierte Programmierung . . . . . . . . . . . .
4.6 Grafische Beschreibung einer DSL . . . . . . . . . . . .
4.6.1 GMF . . . . . . . . . . . . . . . . . . . . . . . .
4.6.2 Beispiel . . . . . . . . . . . . . . . . . . . . . . .
4.6.3 Beispiel: Erstellen eines grafischen Klasseneditors
4.7 AndroMDA . . . . . . . . . . . . . . . . . . . . . . . . .
4.7.1 Beispiel . . . . . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
60
60
61
61
65
65
65
73
73
74
74
75
91
95
97
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
99
99
101
102
102
105
107
110
110
110
112
114
115
117
117
118
118
119
119
INHALTSVERZEICHNIS
5 Software Factories
5.1 Der Begriff „Software Factory” . . . . . . . . .
5.2 Anforderungen an eine Factory . . . . . . . . .
5.3 Ein Fallbeispiel:
Architektur von Java-Enterprise-Applikationen
5.3.1 DSL . . . . . . . . . . . . . . . . . . . .
5.3.2 Konzept . . . . . . . . . . . . . . . . . .
5.3.3 Implementierung . . . . . . . . . . . . .
5.3.4 Installation der Factory . . . . . . . . .
Literaturverzeichnis
3
120
. . . . . . . . . . . . . . 120
. . . . . . . . . . . . . . 121
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
121
122
124
124
127
128
Kapitel 1
Grundlagen der Softwaretechnik
Ziel dieses Kapitels ist die Schaffung einer einheitlichen fachlichen Basis - hinsichtlich
Begrifflichkeit, Methodenwissen und Fähigkeiten zur Werkzeuganwendung - für die
Behandlung der Themen, die nachfolgend Gegenstand der Lehrveranstaltung „Software
Factories” sind.
Im praktischen Teil basiert die Lehrveranstaltung ausschließlich auf Open-SourceProdukten. Das bedeutet aber nicht, dass auch alle in der Lehrveranstaltung entwickelten Produkte Open-Source-Produkte sein werden.
1.1
1.1.1
Der Softwareentwicklungsprozess
Die Phasen des Softwareentwicklungsprozesses
Der Softwareentwicklungsprozess (SEP) lässt sich als Menge von Aktivitäten definieren, die zur Produktion eines Softwaresystems führen (vgl. [Som07], S. 94). Dabei sind
folgende Fälle zu unterscheiden:
1. es handelt sich um eine komplette Neuentwicklung,
2. bestehende Systeme werden erweitert bzw. verändert (Rekonstruktion, Refactoring),
3. Systemkomponenten werden konfiguriert oder integriert,
4. Konsistenz- und Äquivalenzprüfungen auf verschiedenen Abstraktionsstufen (Validation und Verifikation).
Für die Beschreibung des Softwareentwicklungsprozesses existieren Lebenszyklusmodelle, Vorgehensmodelle und Phasenmodelle (V-Modell, vgl. Abb. 1.1.1). Grundlegende
Abläufe, die alle Softwareentwicklungsprozesse gemeinsam haben, sind:
4
KAPITEL 1. GRUNDLAGEN DER SOFTWARETECHNIK
5
• Analyse (Definition der Anforderungen)
• Entwurf (Spezifikation, Definition der Funktion und der Constraints, Algorithmenentwurf),
• Implementierung (Algorithmenentwurf, Erstellung der Software, die der Spezifikation genügt, weitestgehend Generierung)
• Validation und Verifikation (entwicklungsbegleitend und phasenübergreifend, Nachweise für Konsistenz und Äquivalenz auf verschiedenen Entwicklungsstufen, Test)
• Evolution (Wartung, Weiterentwicklung, Anpassung an Kundenwünsche)
Abbildung 1.1.1: V-Modell
Kernaktivitäten der Analysephase sind die Problemdefinition, die Anforderungsanalyse, die Anforderungsdefinition (mit Lastenheft und Pflichtenheft), Aufwands- und
Risikoabschätzungen, Festlegung des Vorgehens. Die Analysephase bei Einsatz der Objekttechnologie schließt die objektorientierte Analyse ein.
In der Entwurfsphase werden die Systemarchitektur und die Softwarearchitektur
festgelegt. Die Entwurfsphase schließt den objektorientierten Entwurf ein.
Abbildung 1.1.2 zeigt den traditionellen, Code- bzw. Programmzentrierten SEP im
Überblick. Das „Werkzeug” Compiler besteht aus einem Frontend und einem Backend.
Der Syntaxbaum (allgemein ein Graph) bildet die zentrale Datenstruktur (vgl. Abb.
1.1.3).
KAPITEL 1. GRUNDLAGEN DER SOFTWARETECHNIK
6
Abbildung 1.1.2: SEP - Programm-zentriert: Ps - Quellprogramm, Sp - Programmspezifikation, PT - Zielprogramm, RError - Fehlerbericht, RT est - Testbericht
KAPITEL 1. GRUNDLAGEN DER SOFTWARETECHNIK
Abbildung 1.1.3: SEP - Programm-zentriert
7
KAPITEL 1. GRUNDLAGEN DER SOFTWARETECHNIK
1.1.2
8
Prozessmodellierung
Die Prozessmodellierung im Software Engineering befasst sich damit, Teile des Softwareentwicklungsprozesses zu modellieren und damit zu automatisieren. Versuche, den
gesamten Softwareentwicklungsprozess umfassend zu automatisieren, waren bisher wenig erfolgreich.
Die am besten verstandene Form der Automatisierung bezieht sich auf das Übersetzen, Verbinden und Laden von Programmen, geht also vom Quelltext aus. Andererseits
sind heute Modelle verschiedener Art (UML-Diagramme) als Ausgangspunkt der Programmerzeugung Stand der Technik. Es ist deshalb sinnvoll, zwischen Codezentrierter
und Modellzentrierter Entwicklung unterschieden.
1.1.3
Konfigurationsmanagement
Für diesen Abschnitt dient [Pop06] als Quelle.
Ziele des Konfigurationsmanagements (KM):
• Im SEP entstehende Artefakte sicher verwalten
• Zugriffskontrolle für verteilt arbeitende Entwickler
• Kontrolle über Veränderungen an Artefakten im Laufe der Entwicklung
Das KM umfasst Aufgaben wie
• die Kontrolle der entwickelten Quellprogramme
• die Bereitstellung von „Build“-Funktionalität
• das Release-Engineering
1.1.3.1
Verwaltung von Konfigurationselementen: Mercurial
Als ein neueres Versionsverwaltungssystem wird nachfolgend Mercurial betrachtet. Für
Mercurial steht ein Kommandozeilen-orientiertes Werkzeug zur Verfügung (alle Kommandos beginnen mit hg, vgl. http://mercurial.selenic.com/, Distributionen sind
plattformspezifisch). Dieses System wird in einem online verfügbaren Buch von Bryan
O’Sullivan beschrieben. Eine integrierte Webschnittstelle steht ebenfalls zur Verfügung.
Drittanbieter stellen grafische Frontends oder Plug-ins für Entwicklungsumgebungen
zur Verfügung.
1.1.3.2
Build-Management
Hier wird wesentlich auf ANT und Maven fokussiert.
KAPITEL 1. GRUNDLAGEN DER SOFTWARETECHNIK
1.2
9
Methodologie der Softwareentwicklung
Gegenstand der nachfolgenden Betrachtungen ist die Methodik zur Entwicklung von
Anwendungssystemen.
Programmcode soll vorrangig nicht mehr “per Hand” als Quellcode geschrieben werden. Modelle repräsentieren Spezifikationen verschiedener Aspekte der zu entwickelnden Software. Modelle dienen als Ausgangspunkt für die Generierung von Quellcode
und ausführbarem Code während eines Build-Prozesses, wir sprechen von Modellgetriebener Softwareentwicklung (MDSD).
Zunehmende Bedeutung hat das Roundtrip Engineering erlangt (vgl. Abb. 1.2.1).
Diagramme als grafische Darstellungen und Quellcode sind gleichermaßen Repräsentationen von Modell-Aspekten eines zu entwickelnden Anwendungssystems. Dabei führen
Änderungen der grafischen Darstellung zu Änderungen am Modell und über das Modell
zu Änderungen im Quell-Code und umgekehrt werden Codeänderungen unmittelbar
im Modell verortet und führen zu Änderungen grafischer Darstellungen. Erreicht wird
ein Roundtrip Engineering dadurch, dass ein Syntaxbaum (Syntaxgraph) die zentrale
Datenstruktur bildet (die das Modell verkörpert), auf den alle Änderungen abgebildet
werden und der jeweils Änderungen in die konkrete Darstellung überführt.
1.2.1
Objekttechnologie/UML
Die Objekttechnologie gibt eine technische Unterstützung für verschiedene Abstraktionen und für die Darstellung von Verhalten.
• Klassen-Instanzen-Abstraktion
• Generalisierung-Spezialisierung
• Assoziationen zwischen Klassen
Die UML ist zu einem Standard zur Modellierung auf der Basis der Objekttechnologie
geworden. Diagramme visualisieren Ausschnitte aus bzw. Sichten auf Modelle. Die
UML ist eine grafische Sprache, die auch zur Metamodellierung geeignet ist, d.h. die
Konzepte der UML lassen sich mit der UML selbst beschreiben.
1.2.2
Agile Softwareentwicklung/eXtreme-Programming
Ziel der Agilen Softwareentwicklung ist es, den Softwareentwicklungsprozess gegenüber
herkömmlichen Vorgehensmodellen „beweglicher” zu machen. eXtreme Programming
ist ein Beispiel für Agile Softwareentwicklung.
KAPITEL 1. GRUNDLAGEN DER SOFTWARETECHNIK
10
Abbildung 1.2.1: SEP - Roundtrip Engineering
1.2.3
Generatoren
Generatoren spielen Traditionell bei der Herstellung von Werkzeugen für die Verarbeitung von Programmiersprachen eine wichtige Rolle (Scanner/Parser).
1.3
1.3.1
Softwareentwicklungswerkzeuge
CASE-Tools
Softwareentwicklungsumgebungen (SEU) sind komplexe Werkzeugverbünde, die für die
Entwicklung von Software eingesetzt werden und die in der Regel alle Phasen des Softwareentwicklungsprozesses unterstützen. Solche Verbünde von Werkzeugen werden oft
auch als CASE (Computer Aided Software Engineering) bzw. CASE-Tools bezeichnet.
Case-Tools werden in „upper CASE” und „lower CASE” klassifiziert. „lower CASE”Umgebungen unterstützen die „späten” Pasen der Softwareentwicklung (hauptsächlich
Implementation und Test) und sind damit im wesentlichen Programmierumgebungen.
„upper CASE”-Umgebungen unterstützen insbesondere die „frühen” Phasen der Softwareentwicklung.
KAPITEL 1. GRUNDLAGEN DER SOFTWARETECHNIK
11
SEU, die Werkzeuge für unterschiedliche Sprachen und Zielplattformen integrieren
bzw. die Integration ermöglichen, werden als IDE (Integrated Development Environment) bezeichnet. Eine Liste freier und proprietärer integrierter Entwicklungsumgebungen ist unter
http://de.wikipedia.org/wiki/Liste_von_integrierten_Entwicklungsumgebungen veröffentlicht.
Die Lehrveranstaltung baut wesentlich auf der Entwicklungsplattform Eclipse auf.
Als Werkzeug zur Modellierung wird TOPCASED verwendet, das die UML unterstützt.
1.3.2
Die Plattform Eclipse
Eclipse ist eine der meist genutzten Integrierten Entwicklungsumgebungen (IDE - Integrated Development Environment) und Open Source-Software (EPL - Eclipse Public
License) [Ecl]. Aktuell verwendet wird zu Beginn des Jahres 2011 die Eclipse Version
3.6.1- Helios. Eclipse ist keine Softwareentwicklungsumgebung (SEU) im herkömmlichen Sinne. Es ist eine Plattform, die zu einer komfortablen Softwareentwicklungsumgebung erweitert werden kann.
In der Lehrveranstaltung wird Eclipse Helios (3.6) verwendet. Eine onlineDokumentation mit zahlreichen Hilfe-Themen steht unter
http://help.eclipse.org/helios/index.jsp bereit. Zu installieren ist zunächst ein Eclipse
SDK. Es umfasst:
• die Eclipse-Plattform,
• Werkzeuge zur Java-Entwicklung (Java Development Tools - JDT ),
• eine Umgebung zur Entwicklung von Plug-ins (Plug-in Development Environment - PDE).
Eclipse basiert auf einer „Plug-in”-Technologie, die es erlaubt, ein System zur Laufzeit (d.h. ohne neu zu compilieren) um vorgefertigte Komponenten zu erweitern, wenn
sie eine vorgegebene Schnittstellenkonvention erfüllen. Das Konzept der Plug-ins kennt
Erweiterungspunkte (engl. extension points) und Erweiterungen (engl. extensions). Erweiterungen sind Applikationen, die in Erweiterungspunkte „eingehängt” werden können. Solche Erweiterungen können ihrerseits wieder Erweiterungspunkte anbieten.
Das System Eclipse selbst besteht bereits weitgehend aus Plug-ins. Was übrig
bleibt, wenn man alle Plug-ins wegnimmt, ist ein Kern. Auch das grafische Benutzerinterface (GUI) von Eclipse ist ein Plug-in. Abb. 1.3.2 zeigt die Architektur von
Eclipse.
KAPITEL 1. GRUNDLAGEN DER SOFTWARETECHNIK
12
Abbildung 1.3.1: Eclipse-Helios Hilfe - Themenübersicht
Eclipse besteht aus Subsystemen (und Plug-ins sind), die auf einer Runtime-Maschine
arbeiten. Der Begriff „Workbench” wird in Eclipse zur Bezeichnung der Desktop-Entwicklungsumgebung verwendet. SWT ist das (open source) Standard Widget Toolkit
für Java. JFace ist ein UI-Framework und enthält Klassen, die von UI-Plug-ins benötigt
werden. Team ist ein Subsystem zur Unterstützung der Versionsverwaltung.
Die meisten Komponenten von Eclipse sind Plug-ins (vgl. Kapitel 1.3.3).
Abb. 1.3.3 zeigt das GUI der um Plug-ins zur Unterstützung der UML erweiterten Eclipse-IDE (Topcased) in einer Perspektive, in der die Herstellung von UMLDiagrammen unterstützt wird.
1.3.2.1
Installieren neuer Software (Features, Plug-ins)
Viele Komponenten (Features, Plug-ins) stehen bei http://www.eclipse.org/downloads/
zum Download bereit. Plug-ins können auf unterschiedliche Art und Weise zur Nutzung
KAPITEL 1. GRUNDLAGEN DER SOFTWARETECHNIK
Abbildung
1.3.2:
Architektur
http://help.eclipse.org/helios/index.jsp)
von
Eclipse
13
(Abb.
nach
bereitgestellt werden:
1. es wird ein bereits spezialisiertes Eclipse aus dem Netz installiert (Beispiel Topcased),
2. direkt aus Eclipse heraus: Zunächst Help →Install New Software... und
Angabe des entfernten Download-Archives oder
3. download von Installationsdateien und Ausführen (im Falle von .jar-Archiven
oder Speichern in die Ordener Plugin und Features oder
4. Platzierung in einem separaten, Produkt-spezifischen Verzeichnis und Erzeugung
eines Link-Files, so dass Eclipse die Plug-ins findet.
Die zuletzt aufgeführte Variante eignet sich besonders gut, wenn ein Plug-in in verschiedenen Eclipse-Installationen genutzt werden soll.
1.3.2.2
Entwicklung von Java-Applikationen
Die Entwicklung von Java-Applikationen - beginnend mit der Erstellung von JavaQuelltexten - erfolgt in der Java-Perspektive.
1.3.2.3
Unterstützung der UML
Zur Unterstützung der UML 2 in Eclipse gibt es verschiedene Erweiterungen. Wir
beschreiben nachfolgend eine auf EMF basierende Erweiterung zu Eclipse, die eine
Implementierung des UML 2.1.1 - Metamodells darstellt.
KAPITEL 1. GRUNDLAGEN DER SOFTWARETECHNIK
14
Abbildung 1.3.3: Eclipse in der TOPCASED-Perspektive
Ein Werkzeug, das die Erstellung von UML-Diagrammen in Eclipse unterstützt, ist
das Plug-in UML2-Tools. Dazu ist mittels des Update-Managers die aktuelle Version
der UML2-Tools zu installieren (vgl. Abb. 1.3.4):
Help → Install New Software ... → unter Work with eintragen:
http://download.eclipse.org/modeling/mdt/updates/releases/
KAPITEL 1. GRUNDLAGEN DER SOFTWARETECHNIK
Abbildung 1.3.4: Installation MDT
15
Kapitel 2
Werkzeugentwicklung mit Eclipse
In dieser Lehrveranstaltung liegt der Fokus auf der Entwicklung von Anwendungen,
die Werkzeuge für die Softwareentwicklung sind. Nachfolgend soll die Entwicklung von
Softwareentwicklungswerkzeugen auf zwei unterschiedlichen Wegen betrachtet werden:
1. Die IDE Eclipse wird selbst als Softwareentwicklungswerkzeug weiter spezialisiert. Dazu werden Plug-ins entwickelt und integriert, die bereits bestehende
Erweiterungspunkte nutzen und so die Workbench erweitern.
2. Es werden Applikationen entwickelt, die nur den minimalen Kern von Eclipse
nutzen und diesen um Plug-ins erweitern. Die minimale Menge von Plug-ins, die
für die Erzeugung einer Client-Applikation erforderlich ist, wird als Rich Client
Platform (RCP) bezeichnet. Dazu werden zwei Plug-ins und deren Voraussetzungen benötigt:
org.eclipse.ui und
org.eclipse.core.runtime.
Mehr über RCP erfährt man unter http://wiki.eclipse.org/index.php/Rich_Client_Platform.
Anwendungen der zweiten Art können insbesondere eine eigene Art von GUIs besitzen,
die von der Eclipse-GUI verschieden sein kann. Für beide Fälle ist es erforderlich,
zunächst das Konzept der Plug-ins kennen zu lernen.
Der Inhalt dieses Kapitels basiert im wesentlichen auf dem Buch eclipse Plug-ins
von E. Clayberg und D. Rubel [CR09].
2.1
Plug-ins
Eclipe besteht aus einem kleinen Kern, der einen Plug-in-Loader enthält, und einer
Vielzahl von Plug-ins, die in ihrer Gesamtheit eine Struktur bilden. Der Kern, der
die Mechanismen zur Unterstützung der Verarbeitung von Plug-ins enthält, ist eine
16
KAPITEL 2. WERKZEUGENTWICKLUNG MIT ECLIPSE
17
Implementation der OSGi R4 -Spezifikation und stellt eine Umgebung bereit, in der
Plug-ins ausgeführt werden können. Diese Laufzeitumgebung Equinox ist die Referenzimplementierung von OSGi. Ein Plug-in entspricht in der OSGi-Terminologie einem
OSGi-Bundle. Ein Bundle und die zugeordneten Klassen spezifizieren und implementieren den Prozess des Ladens von Java-Klassen und den Lebenszyklus des Bundles.
Jedes Plug-in kann auf Diensten aufbauen, die andere Plug-ins bereitstellen. Plug-ins
werden bei Bedarf geladen, aber nicht entladen (aus: Platform Plug-in Developer
Guide → Programmer’s Guide → Runtime overview → The runtime plug-in
model).
Das Verhalten von Plug-ins wird in Code beschrieben, Abhängigkeiten und Dienste
in den Dateien MANIFEST.MF (darin die „Require-Bundle”-Deklaration) und plugin.xml.
Plug-in-Code wird erst geladen, wenn er benötigt wird (lazy loading, „as needed”). Der
Plug-in-Loader analysiert die Dateien MANIFEST.MF und plugin.xml und erzeugt für
jedes Plug-in eine Struktur, die diese Informationen enthält (nur im workspace). Der
Plug-in-Loader instantiiert einen separaten Class-Loader für jedes Plug-in.
Erweiterungen (Extensions) und Erweiterungspunkte (Extension Points) werden
für jedes Plug-in in der XML-Datei plugin.xml beschrieben. Die Plug-in-Konfiguration
und ihre Integration in die Plattform werden in der Datei MANIFEST.MF beschrieben. In dem in Abb. 2.1.1 gezeigten Beispiel hängt sich ein neues Plug-in („BundleSymbolicName” = com.qualityeclipse.favorites ) in den Erweiterungspunkt
org.eclipse.ui.views des Plug-ins org.eclipse.ui ein.
KAPITEL 2. WERKZEUGENTWICKLUNG MIT ECLIPSE
Abbildung 2.1.1: Struktur von Plug-ins nach [CR09]
18
KAPITEL 2. WERKZEUGENTWICKLUNG MIT ECLIPSE
2.2
19
Technologie zur Entwicklung von Plug-ins
Um als Anwender selbst Plug-ins entwickeln zu können, muss das Plug-in Development
Environment (PDE) in der Eclipse-IDE verfügbar sein.
Das PDE-Subprojekt ist in drei Teilprojekte (und entsprechende Komponenten) unterteilt:
1. PDE Build (Ant-basierte Tools und Scripts um den build-Prozess zu automatisieren)
2. PDE UI (eine Menge von Modelllen, Buildern, Editoren und weiteren Werkzeugen, um Plug-ins (bzw. OSGi bundles) zu entwickeln),
3. PDE API Tooling (Unterstützung der Dokumentation und Wartung der API)
Zusätzlich gibt es PDE Doc zur Weiterentwicklung der HELP-Dokumentation als übergreifendes Projekt und PDE Incubator für die Entwicklung neuer Werkzeuge, die bisher
nicht zum Eclipse SDK gehören.
Nachfolgend wird zunächst die Entwicklung eines Plug-ins beschrieben, das die
Eclipse-IDE um eine neue Sicht (View) erweitert. Bei der durch Eclipse gesteuerten
Erzeugung eines neuen Plug-ins wird auch Programmcode (z.B. für Editoren oder
Views) - hier aus bereits vorgefertigten Vorlagen (Templates) - erzeugt.
Zur Entwicklung eines neuen Plug-ins sind folgende Aktivitäten erforderlich:
1. Erzeugen eines Plug-in-Projektes
2. Review des generierten Codes (optional)
3. „Build” des Plug-ins
4. Installation und Ausführung des Plug-ins
Diese Aktivitäten werden nachfolgend im Detail beschrieben.
1. Erzeugen eines Plugin-Projektes
Zum Erzeugen eines Plug-in-Projektes wird typischerweise ein Wizard (mit 5 Schritten)
verwendet.
Erster Schritt ist das Starten des Wizards: » File → New → Project... (vgl.
Abb. 2.2.1) und die Auswahl Plug-in Project.
Ein Wechsel in die PDE-Perspektive erfolgt automatisch beim Erzeugen eines PDEProjekts.
KAPITEL 2. WERKZEUGENTWICKLUNG MIT ECLIPSE
20
Abbildung 2.2.1: Wizard zum Erzeugen eines Plugin-Projektes
Im zweiten Schritt wird (vgl. Abb. 2.2.2)
• der Projektname (= Plug-in-Identifier) festgelegt,
• Create a Java-Project markiert (sonstige Voreinstellungen beibehalten),
• die Zielplattform festgelegt (hier Eclipse IDE).
Im dritten Schritt wird (vgl. Abb. 2.2.3)
• die Versionsnummer festgelegt, hier 1.0.0.1,
• der Name des Plug-ins festgelegt,
• der Provider festgelegt (kann zunächst entfallen),
• festgelegt, dass eine Activator-Klasse generiert werden soll (ein Activator (.classDatei) kontrolliert den Lebenszyklus des Plug-ins, wird benachrichtigt, wenn das
Bundle startet oder stoppt),
• festgelegt, dass sich das Plug-in auf die grafische Oberfläche von Eclipse beziehen
soll,
KAPITEL 2. WERKZEUGENTWICKLUNG MIT ECLIPSE
21
Abbildung 2.2.2: Wizard zum Erzeugen eines Plugin-Projektes, Seite 2
• festgelegt, dass das entwickelte Plug-in keine Rich Client Applikation sein soll.
Im vierten Schritt kann spezifiziert werden, welche vorgefertigten Code-Stücke integriert werden sollen. Zur Erzeugung von Plug-ins können solche Code-Stücke (Templates) verwendet werden. Das als Beispiel erzeugte Plug-in soll das UI der Eclipse-IDE
um eine View erweitern (vgl. Abb. 2.2.4, Plug-in with a view ausgewählt).
Im fünften Schritt wird die View genauer definiert (vgl. Abb. 2.2.5): Der „Java
Package Name” de.htwdd.sf.favorites ist schon voreingestellt und wird beibehalten. In diesem Package ist später der generierte Programmcode zu finden. FavoritesView
als Klassenname und Favorites als View-Name werden eingetragen und ersetzen die
Vorgaben. Das vorgegebene Sample Category wird ersetzt durch
de.htw-dresden.sf.favorites. Die Boxen „Add the View ...” und „Add context ...”
werden unchecked gesetzt (vereinfacht die generierte Manifest-Datei).
Nach Klicken von Finish wird zum Schluss der Wechsel in die „Plug-in Development Perspective” mit Yes bestätigt (vgl. Abb. 2.2.6 ). Das Plug-in-Projekt wird
erzeugt und der Plug-in-Manifest-Editor wird automatisch geöffnet. Der Plug-in Mani-
KAPITEL 2. WERKZEUGENTWICKLUNG MIT ECLIPSE
22
Abbildung 2.2.3: Wizard zum Erzeugen eines Plugin-Projektes, Seite 3
fest Editor wird nach Beenden des beschriebenen Wizards automatisch mit der ersten
Seite (Registerkarte) geöffnet (vgl. Abb. 2.2.8). Dieser Editor kann - falls geschlossen später auch jederzeit duch Doppelklick auf MANIFEST.MF im Projektmanager geöffnet
werden. Man beachte die Registerkarten („Seiten”) am unteren Rand der Abbildung.
KAPITEL 2. WERKZEUGENTWICKLUNG MIT ECLIPSE
Abbildung 2.2.4: Wizard zum Erzeugen eines Plugin-Projektes, Seite 4
23
KAPITEL 2. WERKZEUGENTWICKLUNG MIT ECLIPSE
Abbildung 2.2.5: Wizard zum Erzeugen eines Plugin-Projektes, Seite 5
Abbildung 2.2.6: Wizard zum Erzeugen eines Plugin-Projektes, Seite 6
24
KAPITEL 2. WERKZEUGENTWICKLUNG MIT ECLIPSE
25
2. Review des generierten Codes
Nachfolgend ist die Perspektive Plug-in Development eingestellt. Im Projekt-Manager
wird die in Abb. 2.2.7 dargestellte Struktur gezeigt. Im src-Verzeichnis wurden die
Packages de.htwdd.sf.favorites und de.htwdd.sf.favorites.views generiert.
Abbildung 2.2.7: Sicht des Plug-ins im Projekt-Manager
Ein Review der Ergebnisse der Generierung des Projektes wird anhand der Registerkarten des Plug-in Manifest Editors durchgeführt. Jedes erzeugte Plug-in hat ein
Verzeichnis/eine Datei META-INF/MANIFEST.MF. Im Projekt-Verzeichnis können sich
außerdem eine Datei plugin.xml und eine .class-Datei befinden.
Eine zentrale Datenstruktur in jedem Plugin ist der Plug-in Descriptor, als Datei
plugin.xml gespeichert. Darin werden wesentliche Eigenschaften festgelegt (vgl. Abb.
2.2.9):
• der Plugin-Name,
• der Classpath,
• benötigte Extensions,
• implementierte Extensions,
• selbst publizierte Extension-Points,
• etc.
Die Datei plugin.xml kann mit dem Plugin-Manifest-Editor bearbeitet werden
(entsprechende Registerkarte). Für das Favorietes-Plug-in ist die Datei plugin.xml in
Abb. 2.2.10 dargestellt.
KAPITEL 2. WERKZEUGENTWICKLUNG MIT ECLIPSE
Abbildung 2.2.8: Plug-in-Manifest-Editor, Übersichtsseite
Ein Plug-in kann als .jar-File (Java-Archiv) abgespeichert werden.
26
KAPITEL 2. WERKZEUGENTWICKLUNG MIT ECLIPSE
Abbildung 2.2.9: Bild aus der Eclipse Slide Show
Abbildung 2.2.10: Datei plugin.xml für das Favorites-Plug-in
27
KAPITEL 2. WERKZEUGENTWICKLUNG MIT ECLIPSE
28
Im MANIFEST.MF (vgl. Abb. 2.2.11) werden Abhängigkeiten beschrieben. Die Angaben beziehen sich auf die Laufzeit der Plug-ins, sollten aber mit dem build-Pfad
synchronisiert sein. Die in der Übersichtsseite des Plug-in-Manifest-Editors gezeigten
Informationen entsprechen den Einträgen in MANIFEST.MF.
Abbildung 2.2.11: Plug-in-Manifest-Editor: MANIFEST.MF
Die ersten zwei Zeilen definieren die Datei als OSGi Manifest Datei. Danach sind
der Plug-in-Name, die Version etc festgelegt. Reqire-Bundle enthält die Namen der
Plug-ins, die von dem neuen Plug-in benötigt werden (auf denen es aufbaut, von
denen es abhängt). Die Activator-Klasse beschreibt, wie sich das Plug-in beim Laden und Beenden verhalten soll. Die Klasse heißt im Beispiel Activator und ist von
AbstractUIPlugin abgeleitet.
Im Beispiel wird beim Erzeugen des Plug-in-Projekts auch Code für eine einfache
View generiert. Die Klasse heißt FavoritesView und wird von ViewPart abgeleitet.
Auf der Dependencies-Seite wird gezeigt, welche Plug-ins zum Laufen des Plug-ins
erforderlich sind (vgl. Abb. 2.2.12). Diese Angaben entsprechen den Zeilen 8 und 9 des
Manifests (vgl. Abb. 2.2.11).
Es ist zu beachten, dass diese Angaben verschieden von denen im Java-Classpath
sind. Die Angaben im Classpath werden zur Compilezeit ausgewertet, während die
KAPITEL 2. WERKZEUGENTWICKLUNG MIT ECLIPSE
29
Abbildung 2.2.12: Manifest Editor, Seite „Dependencies”
Dependencies-Angaben während der Ausführung des Plug-ins ausgewertet werden. Die
Dependencies-Angaben wirken sich auf den Build-Pfad aus, aber nicht umgekehrt.
Die Registerkarte Runtime (vgl. Abb. 2.2.13) korrespondiert mit dem Bundle-ClasspathAbschnitt der Manifest-Datei. Speziell für das Favorites-Plug-in sind keine Deklarationen erforderlich. Es werden keine Packages exportiert.
Die Registerkarte Extensions zeigt die implementierten Extensions (vgl. Abb.
2.2.14). Die Angaben korrespondieren mit den Extension-Angaben in der Datei plugin.xml.
Es wird gezeigt, dass die Extension am Extension-Point org.eclipse.ui.views hängt.
Bei Auswahl eines Eintrags auf der linken Seite werden rechts im Fenster die zugeordneten Eigenschaften gezeigt. Die Angaben korrespondieren wieder mit den Einträgen
in der plugin.xml-Datei.
Die Registerkarte Extension Points zeigt die Definition neuer Extension Points.
Das Favorites-Plug-in definiert keine Extension Points.
Die Activator-Klasse Activator.java enthält den Programmcode, der das Plug-in
steuert. Im Beispiel des Favorites-Plug-ins hat sie den in Abb. 2.2.15 gezeigten Inhalt.
Das Eclipse-System instantiiert die Activator-Klasse, bevor irgendwelche Klassen geladen werden. Diese Activator-Instanz wird während des gesamten Lebenszyklus des
Plug-ins benutzt, es wird keine andere Instanz erzeugt (Singleton). Die static-Variable
plugin bekommt eine Referenz auf das Singleton zugewiesen.
UI-basierte Plug-ins besitzen einen Activator, der von AbstractUIPlugin abgeleitet ist, Nicht-UI-basierte Plug-ins sind von Plugin abgeleitet.
Der Wizard „New Plug-in Project” hat außerdem Code für eine einfache View
generiert (vgl. Abb. 2.2.16, 2.2.17). Die View erzeugt und visualisiert Informationen
von einem einfachen Modell.
KAPITEL 2. WERKZEUGENTWICKLUNG MIT ECLIPSE
Abbildung 2.2.13: Manifest Editor, Seite Runtime
Abbildung 2.2.14: Manifest Editor: Extensions von Favorites
30
KAPITEL 2. WERKZEUGENTWICKLUNG MIT ECLIPSE
Abbildung 2.2.15: Activator-Klasse
31
KAPITEL 2. WERKZEUGENTWICKLUNG MIT ECLIPSE
Abbildung 2.2.16: View von Favorites (1)
32
KAPITEL 2. WERKZEUGENTWICKLUNG MIT ECLIPSE
Abbildung 2.2.17: View von Favorites (2)
33
KAPITEL 2. WERKZEUGENTWICKLUNG MIT ECLIPSE
Abbildung 2.2.18: View von Favorites (3)
34
KAPITEL 2. WERKZEUGENTWICKLUNG MIT ECLIPSE
Abbildung 2.2.19: View von Favorites (4)
Abbildung 2.2.20: View von Favorites (5)
35
KAPITEL 2. WERKZEUGENTWICKLUNG MIT ECLIPSE
36
3. „Build” des Plug-ins
Das Build kann manuell oder mittels eines ANT-Scipts (oder eines anderen Skripts)
erfolgen. Das Endprodukt kann als komprimiertes File (mit oder ohne Quelltexte)
geliefert werden.
1. Manuelles Build: Ein Start des build-Prozesses erfolgt mittels des Export-Wizards,
der mittels » File → Export gestartet wird. Auf der ersten Wizard-Seite wird
Deployable plug-ins and fragments ausgewählt.
Auf der 2. Seite des Export-Wizards werden die zu exportierenden Plug-ins ausgewählt und der Name des zip-Files festgelegt, das das Ergebnis enthält.
Im Beispiel wird ein .zip-File erstellt, das ein .jar-File enthält.
2. Alternativ zur manuellen Erzeugung des Plug-ins wird ein ANT-Script erstellt.
Der Export-Wizard generiert ein ANT-Skript, das für das Favorites-Beispiel in
der Datei build-favorites.xml in de.htwdresden.sf.favorites enthalten ist.
Um das ANT-Skript auszuführen, ist ein Rechtsklick auf die Datei build-favorites.xml
auszuführen und die Option Run in the same JRE as the workspace zu wählen.
Die durch Build erzeugte .jar-Datei enthält
• Klassen (.class-Dateien, inklusive Package-Struktur)
• Image-Dateien in einem Verzeichnis icons (falls benötigt), sie werden in pugin.xml
oder in .class-Dateien referenziert
• MANIFEST.MF (beschreibt Laufzeitaspekte)
• plugin.xml (beschreibt extensions und extension points)
4. Installation und Ausführung des Plug-ins
Um das Plug-in auszuführen (zu testen), gibt es zwei Möglichkeiten.
1. Nutzung der Debug-Umgebung mit dem im Workspace entwickelten Plug-in
2. Beenden und Neustart von Eclipse
Zu (1):
• Erzeugung einer Debug-Konfiguration
Zu (2):
KAPITEL 2. WERKZEUGENTWICKLUNG MIT ECLIPSE
37
• Beenden von Eclipse
• Entpacken des .zip-Files in das Eclipse-Verzeichnis (z.B. C:/eclipse). Das
Plug-in soll anschließend im /plugins-Verzeichnis sein.
Beispiel: C:/eclipse/plugins/com.qualityeclipse.favorites_1.0.0.jar
• Neustart von Eclipse
Um das Plugin "In Aktion" zu erleben, muss der Punkt "Launch an Eclipse application"
ausgeführt werden. Es wird eine neue Eclipse-Umgebung gestartet, mit der man in der
Lage ist, die entwickelten Plugins zu testen.
Im Falle des Favorite-Plug-ins kann vom Window-Menü Show View > Other...
ausgewählt werden, um den neuen Dialog zu öffnen.
KAPITEL 2. WERKZEUGENTWICKLUNG MIT ECLIPSE
2.3
38
Kommunikation zwischen Plug-ins
Dieser Abschnitt beschäftigt sich mit der Entwicklung von zwei Plug-ins mit dem Ziel,
die Ansteuerung und Ausführung von Funktionen darzustellen. Aufgabe ist es, beide
Plug-ins zu erstellen und diese miteinander kommunizieren zu lassen. Ein Plug-in A
ruft über einen definierten Extension Point eine in einer Extension des Plug-ins B
definierte Funktion (d.h. JAva-Methode) auf, welche ihrerseits einen einfachen Text
anzeigen soll.
Dabei ist das den Extension Point definierende Plug-in A als Sender und das die
Extension definierende Plug-in B als Empfänger bzw. Ausführender zu betrachten. Das
Plug-in B wird als "Ausführbares Plugin" betrachtet, welches bei dem Funktionsaufruf erst instanziiert wird. Um bereits „laufende” Plug-ins zu steuern, müssen deren
Instanzen ermittelt werden. Dazu muss allerdings die rufende Funktion des Extension
Point-Plug-ins modifiziert werden.
2.3.1
Erstellen des ersten Plug-ins
Nach der Erzeugung eines neuen Plug-in-Projektes kann ein Extension Point definiert
werden.
Beispiel: Erzeugen eines Plug-in-Projektes mit dem Namen de.htwdd.sf.provider,
„Activator generieren” auswählen, „contributions to UI” auswählen, Template „Hello, World” auswählen. Nach Beenden des Wizards sind bereits auch .class-Dateien
erzeugt worden. Die über das Template vordefinierte Klasse SampleAction enthält
zunächst Code, um ein Fenster zu öffnen und darin einen Text anzuzeigen.
Die Definition des Extension Points erfolgt mittels des Eclipse-Manifest-Editors
über die Registerkarte „Extension Points”. Der Extension Point wird mit add ... hinzugefügt und erhält die ID de.htwdd.sf.extensionpoint.aufruf sowie den Namen
"Aufruf". Die Eingabe der Daten bestätigen wir mit "Finish" und sehen im Anschluss
die Übersicht des neuen Extension Points. Um die Definition des Punktes einzusehen,
muss nach Öffnen des Extension Point Schemas (→ „Open extension point schema”)
der untere Reiter "Definition" gewählt werden.
Es wird ein neues Element mit dem Namen „client” erstellt („extension” auswählen → „new element”) und ein Attribut mit dem Namen „class” („client” auswählen
→ „new attribute”) und dem Typ „java” hinzugefügt (vgl. Abb) 2.3.1. Die Klasse
soll das Interface IAufruf implementieren, de.htwdd.sf.provider.IAufruf (im Bild
wurde statt dessen de.htwdd.sf.prakt.prov1.IAufruf verwendet) kann aber erst
ausgewählt werden, nachdem es angelegt wurde.
KAPITEL 2. WERKZEUGENTWICKLUNG MIT ECLIPSE
39
Abbildung 2.3.1: Festlegen der Eigenschaften des definierten Extension Points
Deshalb wird das Interface IAufruf im Quellcode-Verzeichnis zunächst hinzugefügt (vgl. Abb. 2.3.2), anschließend erfolgt dann der Eintrag hinter „Implements”.
Abbildung 2.3.2: Bereitstellen des Interfaces IAufruf im Provider
Abb. 2.3.3 zeigt die Interface-Datei.
Nachdem das Plug-in erstellt wurde, ist ein Build durchzuführen.
Mittels Export ... kann ein Verzeichnis (oder alternativ eine .zip-Datei) erzeugt
werden, das (die) das Plugin als .jar Datei enthält. Der Dateiname wird wie folgt
gebildet: <Plug-in-Name>_<versionsnummer>.jar .
Die Methode run(IAction action) der Klasse SampleAction ist zu erweitern und
wird wie folgt realisiert:
Der Code in diesem Codefragment bewirkt, dass (nach Klicken auf „OK” im Frame)
in allen Plug-ins nach dem Extensionpoint de.htwdd.sf.extensionpoint.aufruf gesucht wird und für den gefundenen Extensionpoint dessen Funktion aufruf() aufge-
KAPITEL 2. WERKZEUGENTWICKLUNG MIT ECLIPSE
40
package de . htwdd . s f . p r a k t . prov1 ;
public i n t e r f a c e I A u f r u f {
void a u f r u f ( ) ;
}
Abbildung 2.3.3: Interface-Datei IAufruf.java
rufen wird.
2.3.2
Erstellung eines Plug-ins, welches vom ersten Plugin aufgerufen
werden kann
Zunächst erstellen wir ein vorlagenloses Plug-in Project mit dem Namen de.htwdd.sf.Usage.
Um den ExtensionPoint des ersten Plugins nutzen zu können, muss die Abhängigkeit
von diesem angegeben werden. Diese Einstellung ist unter "Dependencies" vorzunehmen. Dort fügen wir Plugin
"de.htwdd.sf.Provider" hinzu (nach Eingabe „de” im Textfeld des Wizards werden
Plug-ins angegeben, dort auswählen). Danach ist unter „Extensions” der Extension
Point de.htwdd.sf.extensionpoint.aufruf hinzuzufügen.
Als letzter Schritt ist eine Klasse ExternerAufruf hinzuzufügen, der die Funktion
Aufruf() implementiert.
Der Quellcode kann wie folgt aussehen:
public class ExternerAufruf implements IAufruf {
public void Aufruf () {
System . out . println ( " Aufruf des Plug - ins de . htwdd . sf . Usage " );
Display display = Display . getDefault ();
Shell shell = new Shell ( display );
shell . setText ( " Aufruf des Plug - ins " );
shell . setBounds (100 ,100 ,200 ,50);
shell . setLayout ( new FillLayout ());
Label label = new Label ( shell , SWT . CENTER );
label . setText ( " Aufruf des Plug - ins " );
shell . open ();
while (! shell . isDisposed ()){
if (! display . readAndDispatch ())
display . sleep ();
}
display . dispose ();
}
}
KAPITEL 2. WERKZEUGENTWICKLUNG MIT ECLIPSE
41
public void run ( I A c t i o n a c t i o n ) {
MessageDialog . openInformation (
window . g e t S h e l l ( ) , " Provid1 " , " H e l l o , E c l i p s e world " ) ;
try {
IConfigurationElement [ ] c o n f i g = Platform . getExtensionRegistry ( )
. g e t C o n f i g u r a t i o n E l e m e n t s F o r ( " de . htwdd . s f . e x t e n s i o n p o i n t . a u f r u f " ) ;
System . out . p r i n t l n ( " In run d e s P r o v i d e r s . . . " ) ;
for ( IConfigurationElement e : c o n f i g ) {
f i n a l Ob ject o = e . c r e a t e E x e c u t a b l e E x t e n s i o n ( " c l a s s " ) ;
i f ( o instanceof I A u f r u f ) {
I S a f e R u n n a b l e r u n n a b l e = new I S a f e R u n n a b l e ( ) {
@Override
public void h a n d l e E x c e p t i o n ( Throwable e x c e p t i o n ) {
System . out . p r i n t l n ( " E x c e p t i o n i n c l i e n t " ) ;
}
@Override
public void run ( ) throws E x c e p t i o n {
(( IAufruf ) o ) . aufruf ( ) ;
}
};
SafeRunner . run ( r u n n a b l e ) ;
}
}
}
catch ( E x c e p t i o n ex ) {
System . out . p r i n t l n ( ex . getMessage ( ) ) ;
}
}
Abbildung 2.3.4: Quelltext der Methode run
Es ist zu beachten, dass die Klasse Label aus dem Package org.eclipse.swt.widgets
zu verwenden ist (nicht java.awt)!
2.3.3
Testen der Kommunikation
Um die Plug-ins in Aktion zu erleben, ist zunächst eine Testumgebung zu konfigurieren
(» Run → Run Configurations... → Eclipse Application → New launch configuration
). Danach ist eine neue Eclipse-Instanz zu erzeugen und in deren Oberfläche ist der
Menüpunkt » Sample Menu → Sample Action auszuwählen. Die Dialogabfrage in dem
sich öffnenden Fenster ist mit „OK” zu bestätigen. Die Ausgaben erscheinen auf der
Console der ursprünglichen Eclipse-Instanz.
KAPITEL 2. WERKZEUGENTWICKLUNG MIT ECLIPSE
Abbildung 2.3.5: Festlegung der Klasse die IAufruf implementiert
42
KAPITEL 2. WERKZEUGENTWICKLUNG MIT ECLIPSE
2.4
43
Features und Update-Sites
Features gruppieren Plug-ins und unterstützen so das Laden (load), das Managen (manage) und das Branding (brand, Markenmanagement) der Plug-ins als Einheit („single
unit“). Mittels Features können Plug-ins - zusammengepackt - über eine Web-Site zur
Nutzung angeboten werden. Für das Laden solcher „single units“ in Eclipse kann der
Eclipse Update Manager eingesetzt werden.
2.4.1
Features erzeugen
Ein Feature wird mit Hilfe des „New Project”-Wizards als Feature-Projekt erstellt (vgl.
Abb. 2.4.1). Als Projektname wird beispielsweise de.htwdd.sf.favorites.feature festgelet.
Beim Erzeugen eines Feature-Projektes soll die Feature-ID mit der ID des Haupt-Plugins übereinstimmen. Außerdem wird ein Feature-Name festgelegt (vgl. Abb. 2.4.2).
Abbildung 2.4.1: Erstellen eines Feature-Projektes mittels des „New Project”-Wizards
Aus der nachfolgend im Wizard angezeigten Liste von Plug-ins werden zum Beispiel
zwei Plug-ins ausgewählt (vgl. Abb. 2.4.3).
Danach wird der Wizard mit „Finish” abgeschlossen. In einem Feature-ManifestEditor wird die vom Wizard erzeugte Manifest-Datei feature.xml geöffnet (vgl. Abb.
2.4.4). Auf der Seite „Overview” kann unter „Branding Plug-in:” der Name des Plug-ins
angegeben werden, das die „Branding Files” des Features enthält.
KAPITEL 2. WERKZEUGENTWICKLUNG MIT ECLIPSE
44
Abbildung 2.4.2: Feature spezifizieren
Die Register-Seite „Information” ermöglicht die Notation von Lizenz-Vereinbarungen,
Copyright-Angaben und anderen Angaben. Über die Register-Seite „Plug-ins” werden
die als Inhalt des Features vorgesehenen Plug-ins angezeigt (vgl. Abb. 2.4.5).
Die Register-Seite „Included Features” enthält eine Liste von Sub-Features.
Die Register-Seite „Dependencies” zeigt eine Liste aller Features und Plug-ins, die
für das Feature benötigt werden. Fehlen benötigte Features oder Plug-ins, kann das
Feature nicht geladen werden. Mittels „Compute” kann die Liste neu erzeugt werden
(vgl. Abb. 2.4.6).
Mit Hilfe des Export-Wizards (vgl. Abb. 2.4.4) kann das neu erstellte Feature
exportiert und anschließend installiert werden, um es zu testen.
KAPITEL 2. WERKZEUGENTWICKLUNG MIT ECLIPSE
Abbildung 2.4.3: Auswahl der in das Feature aufzunehmenden Plug-ins
Abbildung 2.4.4: Feature-Manifest-Editor
45
KAPITEL 2. WERKZEUGENTWICKLUNG MIT ECLIPSE
Abbildung 2.4.5: Ausgewählte Plug-ins des Features
Abbildung 2.4.6: Abhängigkeiten des Features
46
KAPITEL 2. WERKZEUGENTWICKLUNG MIT ECLIPSE
2.4.2
47
Erzeugung einer Eclipse-Update-Site
Eclipse unterstützt die Web-basierte Verteilung, Installation und das Updaten von
Features. Eine Eclipse-Update-Site ist eine speziell konstruierte Web-Site, die entworfen
wird, um Features und Plug-ins zu hosten. Eine Update-Site enthält eine spezielle
Beschreibung in Form einer Manifest-Datei site.xml. Der Eclipse-Update-Manager
kann diese Datei lesen und daraufhin Updates automatisch laden und installieren.
Es ist zunächst ein Update Site Project zu erzeugen (vgl. Abb. 2.4.7). Auf der
zweiten Wizard-Seite ist „Generate a web page ...” anzuklicken (vgl. Abb. 2.4.8).
Abbildung 2.4.7: Wizard zur Erstellung eines Update-Site-Projektes (1)
Nach der Erstellung des Projektes können die erzeugten Dateien im Projekt Manager betrachtet werden (vgl. Abb. 2.4.9).
Ein Doppelklick auf site.xml öffnet den Site-Manifest-Editor.
Jetzt können Features hinzugefügt werden (vgl. Abb. 2.4.11). Sollen mehr als ein
Feature auf einer Update-Site bereit gestellt werden, können sie in Kategorien (Category) zusammengefasst werden.
Nach Klicken auf ein Feature im „Managing the Site”-Editor können „Feature Properties” und „Feature Environments” angegeben werden. Das erforderliche URL-Feld
spezifiziert die Lage des Features auf der Update-Site (relativ zur Lage der site.xml),
wo der Update-Manager das jar-File finden soll.
Das Klicken auf „Build All” ist notwendig und bewirkt, dass die Verzeichnisse
KAPITEL 2. WERKZEUGENTWICKLUNG MIT ECLIPSE
48
Abbildung 2.4.8: Wizard zur Erstellung eines Update-Site-Projektes (2)
Abbildung 2.4.9: Update-Site-Projekt
features und plugins zum Update-Site-Projekt hinzugefügt werden.
Die Archiv-Auswahlkarte beschreibt die Update-Site. und spezifiziert die WebAdresse (vgl. Abb. 2.4.12).
KAPITEL 2. WERKZEUGENTWICKLUNG MIT ECLIPSE
Abbildung 2.4.10: Site-Manifest-Editor
Abbildung 2.4.11: Feature Selection
49
KAPITEL 2. WERKZEUGENTWICKLUNG MIT ECLIPSE
Abbildung 2.4.12: „Archives”-Auswahl
50
KAPITEL 2. WERKZEUGENTWICKLUNG MIT ECLIPSE
2.5
51
Entwicklung von RCP-Applikationen
Eine Basis für diesen Abschnitt bildet [Dau08]. Ein Tutorial ist unter
www. eclipse. org/ articles/ Article-RCP-1/ tutorial1. html zu finden. Ein weiteres Tutorial dazu ist www. vogella. com/ articles/ EclipseRCP/ article. html .
Die Architektur von Eclipse ist so gestaltet, dass dessen Komponenten zum Bau
einer beliebigen Anwendung genutzt werden können. Die minimal erforderliche Menge
von Plug-ins (einschließlich deren Voraussetzungen), die zum Bau einer Rich Client
Application mit einer grafischen Benutzeroberfläche benötigt wird, wird als Rich Client
Platform bezeichnet. Es werden mindestens zwei Plug-ins benötigt: org.eclipse.ui und
org.eclipse.core.runtime.
Eine Eclipse-RCP-Applikation muss folgende Elemente definieren:
• eine Hauptklasse (Hauptprogramm), die das Interface IApplication implementiert. Eclipse erwartet, dass diese Anwendungsklasse über den Extension Point
org.eclipse.core.runtime.applications definiert ist.
• Eine Perspektive
• Workbench-Advisor als unsichtbare technische Komponente.
Darüber hinaus sind folgende Konfigurationsdateien erforderlich:
• die Datei MANIFEST.MF
• die Datei plugin.xml
Beispielprojekt
Zur Entwicklung einer RCP-Applikation beginnen wir praktisch mit der Entwicklung
eines Plug-in-Projektes. Mittels des Wizards legen wir fest:
• Projektname: de.htwdd.sf.rcp.firsttool
• Auswahl „Rich Client Application”; Optionen: Generierung einer Activator-Klasse,
Bezug des Plug-ins zum UI herstellen.
• Nutzen der Template-Klasse „Hello RCP”
• Anklicken „Add branding”
Nach der Generierung des Projektes wird eine Inspektion mit Hilfe des Plug-inEditors durchgeführt.
Die Anwendung nutzt folgende Extension Points:
KAPITEL 2. WERKZEUGENTWICKLUNG MIT ECLIPSE
52
Abbildung 2.5.1: RCP-Projekt in der Navigator-View
• org.eclipse.core.runtime.applications
• org.eclipse.ui.perspectives
• org.eclipse.core.runtime.products
In Abb. 2.5.1 sind die bei der Erzeugung des Plug-in-Projektes generierten Dateien
dargestellt.
Launch einer Eclipse-Application ( Run → Run Configurations ... ) erzeugt die
in Abb. 2.5.2 dargestellte Anwendung.
Während des Starts wird durch die Eclipse Runtime überprüft, welche Klasse im
Extension Point org.eclipse.core.runtime.applications angegeben ist. Diese Klasse heißt
typischerweise Application und implementiert das Interface IApplication. Diese
Klasse ist verantwortlich für die Erstellung der SWT-Oberfläche und das Starten der
Schleife der Ereignissteuerung.
Display display = PlatformUI.createDisplay();
PlatformUI.createAndRunWorkbench(display, new ApplicationWorkbenchAdvisor());
KAPITEL 2. WERKZEUGENTWICKLUNG MIT ECLIPSE
53
Abbildung 2.5.2: Launch einer einfachen RCP-Application aus einem Plug-in im
Workspace
PlatformUI.createAndRunWorkbench( ... ) erzeugt und startet eine Workbench.
Die Workbench repräsentiert das grafische User-Interface von Eclipse. Der visuelle Teil
der Workbench wird über die Klasse WorkbenchWindow dargestellt. Eine Workbench
kann mehrere Objekte vom Typ
WorkbenchWindow geöffnet haben. Der innere Teil eines WorkbenchWindow wird über
die Klasse WorkbenchPage repräsentiert.
Eine einfache SWT-Anwendung erfordert es, die SWT-Bibliothek zum Klassenpfad
des Projektes hinzuzufügen. Dies erfolgt in folgenden Schritten:
• Öffnen des Properties-Dialogs zum Projekt (über das Kontextmenü)
• Java Build Path → Libraries → Add External JARs auswählen
• plug-in-Verzeichnis auswählen
• org.eclipse.swt.win32.win32 (oder entsprechendes) wählen
2.6
Eclipse: Produkt und Applikation
Ein „Produkt” im Verständnis von Eclipse definiert alle Ressourcen, die mit der Applikation geliefert werden. Ein Produkt ist ein Entwicklungs-Artefakt und wird zur
Laufzeit nicht benötigt. Die Eclipse-Applikation entspricht der Klasse, die normalerweise die Java- main-Methode enthält. Applikationen werden über den Extension Point
org.eclipse.core.runtime.applications definiert und müssen IApplication implementieren. Einem Produkt ist immer eine Applikation zugeordnet. Die Produkt-Konfiguration
wird in der Datei .product definiert.
KAPITEL 2. WERKZEUGENTWICKLUNG MIT ECLIPSE
54
Abb. 2.6.1 zeigt den Aufruf des Wizards zum Erstellen einer neuen Produktkonfiguration. Abb. 2.6.2 zeigt die im Wizard vorgenommenen Einstellungen. Ein Dateiname
ist festzulegen. Hier ist es tool3.product.
Abbildung 2.6.1: Erstellen eines Produktes initiieren
Nach dem Erstellen der Produktkonfiguration wird automatisch der ProduktkonfigurationsEditor geöffnet (vgl. Abb. 2.6.3). Mittels new ... kann eine neue Produkt-Extension
erzeugt werden (Abb. 2.6.4).
Das exportierte Produkt (Abb. 2.6.7) kann per Doppelklick auf „eclipse” gestartet
werden.
KAPITEL 2. WERKZEUGENTWICKLUNG MIT ECLIPSE
Abbildung 2.6.2: Wizard zum Erstellen einer Produktkonfiguration
55
KAPITEL 2. WERKZEUGENTWICKLUNG MIT ECLIPSE
Abbildung 2.6.3: Produktkonfigurations-Editor
56
KAPITEL 2. WERKZEUGENTWICKLUNG MIT ECLIPSE
Abbildung 2.6.4: Neue Produkt-Extension
57
KAPITEL 2. WERKZEUGENTWICKLUNG MIT ECLIPSE
Abbildung 2.6.5: Export der erzeugten Produktkonfiguration
58
KAPITEL 2. WERKZEUGENTWICKLUNG MIT ECLIPSE
Abbildung 2.6.6: Export der erzeugten Produktkonfiguration - Wizard Seite 2
Abbildung 2.6.7: Exportiertes Produkt
59
Kapitel 3
Modellgetriebene
Softwareentwicklung
3.1
Modelle und Modellebenen
Ein Softwaresystem (Programm, Programmsystem) wird zentral durch ein (Hauptspeicherintern und persistent verwaltetes) Modell repräsentiert. Modell und Programm werden gleichgesetzt, ein Programm ist ein Modell. Das Modell besitzt damit wie das
Programm eine Struktur (Syntax - Datenstruktur) und eine Bedeutung (Semantik Verhalten, Interpretation).
Dient die Objekttechnologie als Entwicklungsbasis, handelt es sich um Klassen
(Situation nach dem Laden zur Ausführungszeit), die den Gegenstandsbereich (die
Domäne) des Softwaresystems modellieren. Dabei stellt sowohl der Quelltext als auch
die grafische Repräsentation einer Klasse eine erste Abstraktionsebene im Vergleich
zur Ausführung des Programmes zur Laufzeit dar.
Objekte (jeder Abstraktionsebene) besitzen jeweils eine interne Repräsentation (als
Modell bezeichnet). Der Quellcode ist eine der möglichen Sichten (View) auf dieses
Modell des Objektes. Klassendiagramme oder Steuerflussgraphen sind andere mögliche Sichten. Unterschiedliche Sichten spiegeln unterschiedliche Aspekte eines Modells
wieder.
Die OMG hat mit der Model Driven Architecture (MDA) einen Vorschlag zur Standardisierung der MDSD gemacht. Modellierung im Sinne der MDSD unterscheidet
mehrere Stufen bzw. Ebenen bezüglich einer Klasse-Instanzen-Abstraktion:
• ein Modell (Ebene M1) beschreibt Instanzobjekte (Objekte der Ebene M0). Ein
Modell ist in einer (grafischen oder textuellen) Sprache ausgedrückt. Instanzobjekte sind Laufzeitobjekte.
• Ein Metamodell (Ebene M2) beschreibt die zur Modellierung verwendbaren Aus60
KAPITEL 3. MODELLGETRIEBENE SOFTWAREENTWICKLUNG
61
drucksmittel. Es definiert die Konstrukte einer Modellierungssprache. Je nach
Gegenstandsbereich spricht man von einer domänenspezifischen Sprache (DSL).
• Ein MetaMetamodell (Ebene M3) ist das Metamodell eines Metamodells.
Modelle sind hier immer formale Modelle.
Beispiel (vgl. Abb. 3.1.1): Eine Klasse Person beschreibt Eigenschaften und Verhalten von Personen und definiert u.a. das Attribut Name. Eine Klasse Person ist ein
Objekt (ein Modellelement) auf der Modellebene M1. Eine Person Peter (Ausprägung
eines Attributes Name) ist ein Instanzobjekt, also ein Objekt der Ebene M0. Das Metamodell auf der Ebene M2 definiert, dass es Klassen gibt und diese u.a. Attribute
haben. Auf der Ebene M3 existiert ein Metametamodell, das Elemente zum Klassifizieren definiert. Eine spezielle Ausprägung (Instanz) des Metametamodells ist das
Metamodell, das es erlaubt, Klassen zu bilden.
Meta ist relativ: Die UML als Sprache ist das Metamodell für ein konkretes UMLModell (das z.B. einen Kaffeeautomaten beschreibt). Die Meta Object Facility (MOF)
ist das Metamodell der UML. Die MOF ist ein im MDSD-Umfeld gängiges (textuelles)
Metametamodell. Die MOF wird speziell im Abschnitt 3.3 behandelt.
Seit der MOF 2.0 gibt es ein vereinfachtes Modell „Essential MOF”, kurz EMOF
genannt.
3.2
Definition und Verarbeitung formaler Sprachen
3.2.1
Formale Sprachen (Wiederholung)
Alphabet Ein Alphabet, bezeichnet mit Σ, ist eine nichtleere, endliche Menge. Die
Elemente dieser Menge nennen wir Symbole.
Beispiel: Σ = { a, b, c, d }
Wort Sei Σ ein Alphabet. Ein Wort (eine Zeichenreihe) w über Σ ist eine endliche
Folge von Symbolen aus Σ. Die Folge kann eine beliebige Länge k ≥ 0 haben.
Die Länge eines Wortes ist die Anzahl der Symbole in der Folge und wird mit
| w | bezeichnet. Das leere Wort, bezeichnet mit ε, ist das Wort der Länge 0. ε
enthält kein Symbol.
Beispiele für Wörter über Σ = { a, b, c, d } sind ab, bc, a, ad
Die Menge aller Wörter über Σ wird mit Σ∗ bezeichnet und ist folgendermaßen
definiert:
• Das leere Wort ist ein Wort über Σ, d.h. ∈ Σ∗ .
KAPITEL 3. MODELLGETRIEBENE SOFTWAREENTWICKLUNG
62
Abbildung 3.1.1: Metamodellarchitektur nach [MOF05]
• Wird ein Symbol x ∈ Σ an ein Wort w ∈ Σ∗ angehängt, dann ist auch wx
ein Wort über Σ, d.h. wx ∈ Σ∗ .
• Andere Wörter in Σ∗ gibt es nicht.
Beispiel: Sei Σ = { a, b, c, d }, dann gilt Σ∗ = { ε, a, b, c, d, aa, ab, ac, ad, . . . },
abcdabcd ∈Σ∗
Eine häufig verwendete Menge ist Σ+ = Σ∗ \ {ε}.
Formale Sprache Eine formale Sprache L über Σ ist eine Menge von Wörtern über
Σ, d.h. L ⊆ Σ∗ bzw. L ∈ P(Σ∗ ). P(Σ∗ ) ist die Potenzmenge von Σ∗ , d.h. die
Menge aller Teilmengen von Σ∗ .
Grammatik Eine Grammatik G ist ein 4-Tupel G = (N, T, P, S0 ) mit
KAPITEL 3. MODELLGETRIEBENE SOFTWAREENTWICKLUNG
63
N : nichtleere Menge der Nichtterminalsymbole (kurz als Nichtterminale bezeichnet)
T : nichtleere Menge der Terminalsymbole (kurz als Terminale bezeichnet)
P : endliche Menge von Regeln aus (N ∪ T )+ × (N ∪ T )∗
S0 ∈ N : Startsymbol
Eine so definierte Grammatik wird von Stetter et al. [Ste88] als Regelgrammatik
bezeichnet. Die Menge N ∪ T heißt Vokabular. In Beispielen werden häufig Nichtterminale mit großen Buchstaben und Terminale mit kleinen Buchstaben bezeichnet.
Verbreitet ist auch eine Notation, bei der Nichtterminale in spitze Klammern eingeschlossen werden (< ... > bzw. h. . . i). Regeln werden auch als Produktionen oder
Produktionsregeln bezeichnet.
Jede Regel ist ein geordnetes Paar (u, v) ∈ (N ∪ T )+ × (N ∪ T )∗ und wird als
u → v notiert. Jede Regel enthält in u mindestens ein Nichtterminal.
Die Menge aller Wörter aus Σ∗ , die aus S0 ableitbar ist, heißt die von G erzeugte
Sprache L(G).
Beispiel 1. G1 = (N1 , T1 , P1 , SAT Z) mit
N1
T1
=
=
{SAT Z, S, P, O, SU BST }
{prof essoren, studenten, und, evaluieren, ärgern}
SAT Z
→
SPO
P
→
P und P
O
→
SU BST
S
→
SU BST
SU BST → prof essoren
SU BST →
studenten
P
→ evaluieren
P
→
ärgern
Ableitbar sind z.B.
SAT Z → studenten evaluieren prof essoren
SAT Z → professoren evaluieren und ärgern studenten
SAT Z → prof essoren evaluieren und evaluieren und evaluieren studenten
P1
=
Chomsky-Hierarchie
Sei G = (N, T, P, S0 ) eine Grammatik mit
N : nichtleere Menge der Nichtterminale.
T : nichtleere Menge der Terminale
P : endliche Menge von Regeln aus (N ∪ T )+ ×(N ∪ T )∗
S0 ∈ N : Startsymbol
KAPITEL 3. MODELLGETRIEBENE SOFTWAREENTWICKLUNG
64
Entscheidend für eine Klassifizierung von Grammatiken (und der entsprechenden
formalen Sprachen) ist die Struktur der Regeln einer Grammatik.
Es gelten: w1 , w2 ∈ T ∗ ; y1 , y2 ∈ T + ; A, B ∈ N .
Regeln der Form A → v werden in Abhängigkeit der Gestalt der rechten Seite v
der Regel wie folgt benannt:
Regel
linear
rechtslinear
linkslinear
abschließend
rekursiv
rechtsrekursiv
linksrekursiv
v
w1 Bw2
w1 B
Bw2
w1
y1 A y2
y1 A
A y2
Sind alle Regeln einer Grammatik von derselben Art oder abschließend, so nennt
man die Grammatik entsprechend. Zum Beispiel ist eine Grammatik linear, wenn alle
Regeln abschließend oder linear sind (rechtslineare Regeln und linkslineare Regeln sind
auch linear).
Man unterscheidet nach dem Linguisten Noam Chomsky vier verschiedene Typen
von Grammatiken (und damit auch von Sprachen).
Typ
Name
Regelform
3
regulär
alle nichtabschließenden Regeln sind entweder
linkslinear/linksrekursiv oder
rechtslinear/rechtsrekursiv,
es gibt keine Regel der Form A → ε
2
kontextfrei
u ∈ N , v ∈ (N ∪T )+ für alle Regeln u → v
1
kontextabhängig
u = w1 Aw2 ,v = w3 mit A ∈ N und
wi ∈ (N ∪ T )∗ sowie
| w1 Aw2 |5| w3 |
für alle Regeln u → v
0
allgemein
keine Einschränkungen
Der Name „kontextfrei” bei einer Grammatik bedeutet, dass bei den Ableitungen
ein Nichtterminal unabhängig von den im Kontext links oder rechts davon stehenden
Zeichen ersetzt werden darf.
Alle regulären Sprachen sind auch kontextfrei, da die abschließenden Regeln sowie
die linkslinearen bzw. rechtslinearen Regeln von der Form A → w sind mit A ∈ N und
w ∈ (N ∪ T )+ .
KAPITEL 3. MODELLGETRIEBENE SOFTWAREENTWICKLUNG
65
Alle kontextfreien Sprachen sind auch kontextsensitiv (d.h. kontextabhängig), wegen | A |≤| w | und (A→w) = (εAε →w).
Die vier Sprachtypen bilden eine Hierarchie, die sog. Chomsky-Hierarchie.
Aus praktischen Gründen wird eine ε-Sonderregel eingefüht, die es erlaubt, aus
dem Startsymbol auch das leere Wort ε abzuleiten.
3.2.2
Abstrakte und konkrete Syntax
Die Syntax einer formalen Sprache umfasst die abstrakte Syntax und die konkrete Syntax. Die abstrakte Syntax beschreibt die Modellelemente und die zwischen ihnen bestehenden Beziehungen. Die konkrete Syntax beschreibt, wie Quelltexte oder Diagramme
tatsächlich aussehen. Zu einer abstrakten Syntax können mehrere unterschiedliche konkrete „Syntaxen” existieren. Eine konkrete Syntax kann grafisch oder textuell sein, für
eine abstrakte Syntax gibt es diese Unterscheidung nicht.
Die konkrete Syntax wird im Rahmen der lexikalischen und syntaktischen Analyse untersucht, sie drückt externe Repräsentationen aus. Die abstrakte Syntax ist
beispielsweise die Grundlage für eine denotationelle Definition der Semantik.
Ein Metamodell definiert die abstrakte Syntax und die statische Semantik einer
formalen Sprache. Ein Metamodell definiert die abstrakte Syntax, nicht die konkrete
Syntax der Modellierungssprache.
3.2.3
Semantik
Es gibt unterschiedliche Arten der formalen Definition der Semantik von Programmiersprachen. Für Scheme z.B. ist im definierenden Bericht eine denotationelle Semantikdefinition angegeben.
Die Semantik einer formalen Sprache umfasst die statische Semantik und die dynamische Semantik. Die statische Semantik legt Bedingungen (constraints) fest, die ein
Modell erfüllen muss. Constraints werden gegen die abstrakte Syntax definiert, d. h.
sie sind von ihr abhängig. Constraints sind besonders wichtig, um Modellierungsfehler
möglichst früh zu erkennen. Zum Beispiel ist die Überprüfung der Typkonformität ein
Problem der statischen Semantik.
3.2.4
Lexikalische und syntaktische Analyse
Scheme
Die Programmiersprache Scheme ist ein Dialekt der Programmiersprache LISP. Programme in der Programmiersprache Scheme sind auf der Ebene M1 einzuordnen: Programme der Programmiersprache Scheme sind Modelle.
KAPITEL 3. MODELLGETRIEBENE SOFTWAREENTWICKLUNG
66
Das Metamodell definiert auf der Ebene M2 die Programmiersprache Scheme. Es
umfasst die Definition der formalen Syntax, die die Definition der lexikalen Struktur,
der externen Repräsentation (einschließlich der Repräsentation von Ausdrücken), die
Verwendung von Quasiquotationen sowie die Definition von Programmen und Definitionen enthält, und die Definition der formalen denotationellen Semantik. Die formale
Semantikdefinition baut auf einer abstrakten Syntax von Programmen (hprogrami)
auf, wobei ein hprogrami eine Folge von Definitionen (hdefinitioni) oder Ausdrücken
(hexpressioni) ist.
Mit der Definition der Programmiersprache in M2 werden die Struktur und das
Verhalten von Programmen in M1 beschrieben.
Die lexikale Struktur gibt an, wie Token aus Sequenzen von Zeichen gebildet werden. Zeichen der Art hintertoken spacei können auf beiden Seiten jedes Tokens stehen,
aber nicht innerhalb eines Tokens.
htokeni −→ hidentifieri | hbooleani | hnumberi | hcharacteri | hstringi | ( | ) | #( | ’ |
‘ | , | ,@ | .
hdelimiteri −→ hwhitespacei | ( | ) | " | ;
hwhitespacei −→ hspace or newlinei
hcommenti −→ ; hall subsequent characters up to a linebreaki
hatmospherei −→ hwhitespacei | hcommenti
hintertoken spacei −→ hatmospherei∗
hidentifieri −→ hinitialihsubsequenti∗ | hpeculiar identifieri
hinitiali −→ hletteri | hspecial initiali
hletteri −→ a | b | c | · · · | z
hscpecial initiali −→ ! | $ | % | & | * | / | : | < | = | > | ? | _ | ^
hsubsequenti −→ hinitiali | hdigiti | hspecial subsequenti
hdigiti −→ 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
hspecial subsequenti −→ . | + | hpeculiar identifieri −→ + | −
Lexikale Analyse am Beispiel von Scheme
Problem:
Eingabe von Zeichenreihen
→ Identifizierung der Lexeme (auch als Morpheme bezeichnet),
Zuordnung der Lexeme entsprechend Syntaxdefinition
zu Klassen, den Symbolen (auch: Morphemklassen)
Lösungsschritte: 1. Modellierung als Zustandsgraph
KAPITEL 3. MODELLGETRIEBENE SOFTWAREENTWICKLUNG
67
(→ endlicher Automat)
2. Konstruktion eines Programms (Entscheidungstabelle + Interpreter)
zur Analyse vorgelegter Zeichenreihen
Der Definition für htokeni entspricht der in Abb. 3.2.1 bis Abb. 3.2.3 dargetellte
Automat. Im ersten Schritt werden htokeni noch nicht spezialisiert (vgl. Abb. 3.2.1).
Auch ein Dateiende (eof) kann ein htokeni begrenzen.
Abbildung 3.2.1: Tokenerkennung in Scheme
Aber auch manche anderen Zeichen - wie z.B. Klammern - können htokeni begrenzen, sie werden als Begrenzerzeichen (delimeter) bezeichnet (vgl. Abb. 3.2.2).
Die in Abb. 3.2.3 gelb markierten Bezeichner stehen für weitere Teilmengen von
Zeichen. Zur programmtechnischen Realisierung eines Automatenmodells - bei der lexikalen Analyse handelt es sich immer um einen deterministischen endlichen Automaten
(DEA) - wird eine Entscheidungstabelle und ein Interpreter für die Entscheidungstabelle erstellt.
KAPITEL 3. MODELLGETRIEBENE SOFTWAREENTWICKLUNG
Abbildung 3.2.2: Erkennung von Kommentaren in Scheme
68
KAPITEL 3. MODELLGETRIEBENE SOFTWAREENTWICKLUNG
Abbildung 3.2.3: Automat zur lexikalen Analyse von Scheme
69
KAPITEL 3. MODELLGETRIEBENE SOFTWAREENTWICKLUNG
70
Generatorwerkzeug JLex ist ein Werkzeug, dass eine Spezifikation der lexikalen
Struktur aus einer Eingabedatei (Dateinamenerweiterung .lex) liest und ein JavaQuellprogramm generiert, das - nachdem es übersetzt wurde - Lexeme aus einer Eingabedatei erkennen und bereitstellen kann. JLex ist also ein Scanner-Generator.
Eine .lex-Datei besteht aus drei Teilen, die jeweils durch %% voneinander getrennt
sind.
%{
Definitionen, die unverändert in
C-Code des Scanners übernommen werden
(z.B. symbolische Konstanten)
%}
Definitionen regulärer Ausdrücke
%%
Muster und zugeordnete Aktionen
%%
benötigte Hilfsfunktionen
(evtl. Main-Funktion, falls der Scanner als selbständiges Programm
arbeiten soll)
Syntaktische Analyse
Die Verfahren der Syntaxanalyse können eine Top-down- oder Bottom-up-Strategie
verfolgen. Bei Top-down-Verfahren erfolgt die Analyse durch Herleitung eines Satzes
der Sprache vom Startsymbol ausgehend. Wird während der Analyse ein Parse-Baum
aufgebaut, so wird dieser von der Wurzel zu den Blättern hin konstruiert. Bei Bottomup-Verfahren erfolgt die Analyse durch Reduktion, von einem Satz der Sprache ausgehend hin zum Startsymbol. Wird ein Parse-Baum aufgebaut, so wird dieser von den
Blättern zur Wurzel hin konstruiert. Die Anwendbarkeit einzelner Verfahren hängt von
Eigenschaften der die jeweilige Sprache definierenden Grammatik ab.
Die Symbole der Eingabe werden von Links nach rechts verarbeitet (der erste Buchstabe der Bezeichnung eines Verfahrens soll dies verdeutlichen).
Bei LL(k)-Verfahren wird eine Linkskanonische Herleitung (Linksherleitung) realisiert (zweiter Buchstabe). Bei einer linkskanonischen Herleitung wird jeweils das am
KAPITEL 3. MODELLGETRIEBENE SOFTWAREENTWICKLUNG
71
Abbildung 3.2.4: Klassifikation von Verfahren zur syntaktischen Analyse
weitesten links stehende Nichtterminalsymbol einer Satzform ersetzt.
Bei LR(k)-Verfahren wird eine linkskanonische Reduktion realisiert. Eine linkskanonische Reduktion entspricht einer Rechtskanonischen Herleitung.
Der Parameter k zeigt die Anzahl der benötigten „Lookahead”-Symbole an, die zur
eindeutigen Identifizierung eines Satzes der Sprache benötigt werden.
Syntaktische Analyse am Beispiel von Ausdrücken in PL/0
Die Grammatik für Ausdrücke in PL/0 ist durch G2 wie in Abb. 3.2.5 dargestellt
definiert.
G2 = ( N2 , T2 , R2 , < expr > ) mit
N2 = { < expr >, < vz >, < term >, < eterm >, < fz >, < fact >, <
efact > }
T2 = { ident, number, +, -, *, /, lparen, rparen}
<
<
<
R2 = <
<
<
<
<
expr >
vz >
eterm >
term >
efact >
fact >
fz >
kexpr >
→
→
→
→
→
→
→
→
[ < vz > ] < term > < eterm >∗
+|< vz > < term >
< fact > < efact >∗
< fz > < fact >
ident | number | < kexpr >
*|/
lparen < expr > rparen
Abbildung 3.2.5: Grammatik G2 : Ausdrücke in PL/0
Die folgende Scheme-Prozedur realisiert einen RD-Parser für die Grammatik G2 .
KAPITEL 3. MODELLGETRIEBENE SOFTWAREENTWICKLUNG
72
(define parser
(lambda()
(letrec
( ; Prozeduren fuer die Nichtterminalsymbole:
(expr
(lambda () (and (or (vz) #t)
(term)
(let loop () (if (eterm)
(loop) #t ))) ))
(vz
(lambda () (or (match ’+)
(match ’-)) ))
(eterm (lambda () (and (vz)(term))))
(term
(lambda () (and (fact)
(let loop () (if (efact)
(loop) #t ))) ))
(efact (lambda () (and (fz)(fact))))
(fz
(lambda () (or (match ’* )(match ’/ )) ))
(fact
(lambda () (or (match ’ident)
(match ’number)
(kexpr)
(error 1) )))
(kexpr (lambda () (and (match ’lparen )
(expr)
(or (match ’rparen)
(error 2))) ))
; lokale Hilfsfunktionen:
(error (lambda (x) (write ‘(error!! ,x)) #f))
(match (lambda (c) (and (eq? symbol c) (Getsym))))
)
(Getsym)
(expr) )))
Erläuterung zu match: Zur Bereitstellung eines Lexems wird die parameterlose Prozedur Getsym aufgerufen. (Getsym) liefert immer true, wenn ein Lexem bereitgestellt
werden kann. Liefert das 1. Argument des (and ... ) -Ausdruckes true, d.h. es handelt sich um das genannte Eingabezeichen, so liefert in diesem Fall auch der gesamte
Ausdruck true.
Bottom-up-Analyseverfahren arbeiten tabellengesteuert und werden nicht von Hand
programmiert. Das Erstellen der Tabellen (Aktionstabelle und Sprungtabelle) ist sehr
aufwändig.
KAPITEL 3. MODELLGETRIEBENE SOFTWAREENTWICKLUNG
3.3
73
MOF
Die von der OMG definierte Meta Object Facility (MOF) ist das Metamodell der
UML, selbst also ein Metametamodell. Die UML wird von der OMG als Metamodell
standardisiert. Die UML ist eine Instanz der MOF.
Sowohl die MOF als auch die UML basieren auf der UML 2.0 Superstructure.
3.4
Domänenspezifische Sprachen
Eine Domänenspezifische Sprache (DSL) ist eine Programmiersprache, die in der Regel
für ein begrenztes Wissensgebiet bestimmt ist. Eine DSL ist nach [SMSH07] eine in
der Regel eingeschränkte und Turing-unvollständige Sprache. Eine DSL ist dadurch
von universell einsetzbaren Programmiersprachen - wie Java oder C++ - abgegrenzt.
Beispiele für DSLs sind LaTex, SQL oder das find in Shell-Sprachen. Eine DSL
soll Sprachelemente enthalten, die sich auf die Domäne beziehen und mit denen die
Experten der Domäne möglichst intuitiv umgehen können.
Domänenspezifische Sprachen (DSL) definieren
• ein Metamodell mit abstrakter Syntax und statischer Semantik (Constraints)
• die konkrete Syntax (und damit auch die Werkzeuge) zur Erstellung, Modifikation und Speicherung von Programmen (Modellen).
• die dynamische Semantik (formal oder informal)
Häufig wird dabei die grafische Modellierung mit der UML favorisiert. In jedem Fall
benötigt man ein Sprachverarbeitungssystem (Parser + Interpreter, evtl. mit Compiler).
Der Aufwand zur Entwicklung einer DSL muss sich lohnen. Zur Findung einer DSL
wird zuerst die Domäne untersucht. Dabei werden Konzepte identifiziert und in Form
eines Metamodells in Zusammenhang gebracht. Erst danach wird für das definierte
Metamodell eine Syntax festgelegt.
Kategorisierung von DSLs:
• Eine interne DSL ist eine Sprache, die in eine Wirtsssprache (Host-Sprache)
eingebettet ist, d.h. sie wird mit Mitteln der Hostsprache unter Nutzung ihrer
Erweiterungskonzepte beschrieben. Hostsprachen sind typischerweise dynamisch
getypte Sprachen wie Ruby oder LISP. Einige Werkzeuge, die für die Wirtssprache vorhanden sind, können auch für die interne DSL genutzt werden (z.B.
die Wiederverwendbarkeit von Editoren und Parsern der Wirtssprache, auch von
Sprachunterstützungen wie Auto-Vervollständigung, Syntax-Highlighting u.a.).
KAPITEL 3. MODELLGETRIEBENE SOFTWAREENTWICKLUNG
74
• Eine externe DSL ist nicht in eine andere Sprache eingebettet, sondern wird
von Grund auf neu definiert. Sie macht einen speziell für sie entwickelten Parser
erforderlich.
• grafische DSLs: Es kann mehrere Sichten auf verschiedene Teile eines Modells
geben.
• textuelle DSLs: Unterstützung der Tastaturbedienung und der Teamarbeit sind
wichtige Aspekte.
• architekturzentrierte DSLs: Es handelt sich um eine architekturzentrierte Domäne, es werden Aspekte der Softwarearchitektur mit der DSL beschrieben.
Ein in einer DSL geschriebenes Programm soll in wesentlichen Teilen automatisiert in
ein ausführbares Programm transformiert werden können.
3.5
Plattformen
Der aus einem formalen Modell generierte Code verwendet üblicherweise Programmbibliotheken, Middleware-Komponenten usw., um seine Aufgaben erfüllen zu können.
Entsprechende Bausteine können als Third-Party-Produkte „von außen” kommen oder
im Projekt selbst entwickelt werden. Eine Plattform hat die Aufgabe, die Umsetzung
der Domäne zu stützen.
Eine DSL der Domäne beschreibt den Problemraum, eine Plattform beschreibt den
Lösungsraum.
Transformationen sind das Bindeglied zwischen Modellierung und Plattform. Es
gibt Modell-zu-Code-Transformationen (M2C) und Modell-zu-Modell-Transformationen
(M2M).
3.6
Werkzeuge zur Metamodellierung: EMF
Es gibt spezielle IDEs zur Unterstützung der Metamodellierung. Konkret wird die Definition von Metamodellen, Bedingungen, der konkreten Syntax von DSLs unterstützt.
Außerdem werden Werkzeuge zur Verwendung der DSLs zur Verfügung gestellt. Das
sind in erster Linie Editoren (z.B. GMF), aber auch andere Werkzeuge.
Das Eclipse Modeling Framework (EMF) unterstützt die Definition von Metamodellen und damit auch die Entwicklung von domänenspezifischen Sprachen in der EclipseIDE.
Das EMF legt als Metametamodell Ecore zugrunde, d.h. das entsprechende EMFPlug-in bringt Ecore mit. Ecore ist eine vereinfachte Untermenge der MOF. Ecore lässt
KAPITEL 3. MODELLGETRIEBENE SOFTWAREENTWICKLUNG
75
sich gleichzeitig mit den Mitteln der UML (welche ja durch die MOF beschrieben ist)
ausdrücken und kann daher auch als UML-Dialekt aufgefasst werden.
Das Metametamodell ist in einer Datei .ecore abgelegt. Diese enthält eine XMLbasierte Beschreibung der Metamodellelemente und der Beziehungen zwischen ihnen.
Es existiert als EMF-Werkzeug ein Generator, der aus der .ecore-Datei Java-Klassen
erzeugt. Diese beschreiben ebenfalls das Metametamodell (vgl. Abb. 3.6.1).
Abbildung 3.6.1: Ecore-Klassenhierarchie
Das Eclipse-UML-2-Projekt definiert das UML-2-Metamodell mit den Mitteln des
Ecore-Metametamodells [SMSH07].
3.6.1
Einführungsbeispiel
Wir wollen den Einstieg in die Nutzung des EMF anhand der offiziell zur Verfügung
stehenden Tutorials und der mit EMF mitgelieferten Beispiele vornehmen.
Die Tutorials „Generating an EMF Model“ und „Generating an Extended EMF
Model“ beschreiben die Modellierung einer Bibliothek und sind Bestandteil der OnlineHilfe des EMF. Innerhalb von Eclipse findet man sie unter Help → Help Contents
→ EMF Developer Guide → Tutorials. Da die Tutorials jeden Schritt vollständig
KAPITEL 3. MODELLGETRIEBENE SOFTWAREENTWICKLUNG
76
beschreiben, sollen im Folgenden nur die wichtigsten Aspekte herausgearbeitet werden.
Die Adresse des Tutorials “Generating an EMF Model” ist:
http://help.eclipse.org/ganymede/index.jsp?topic=/org.eclipse.emf.doc/tutorials/clibmod/clibmod.ht
Die zu modellierende Bibliothek (Library) soll - wie in Abb. 3.6.2 dargestellt Buchautoren (Writer) und Bücher (Book) umfassen. Außerdem sollen Bücher einer
Kategorie zugeordnet werden können. In einer Aufzählung sind die verfügbaren Buchkategorien (BookCategory) enthalten (es ist zu betonen, dass es sich tatsächlich um
ein Metamodell handeln soll, im „UML-Turm” der Metamodellebenen lässt sich das
Klassendiagramm auch auf der Ebene M1 verorten).
Abbildung 3.6.2: Klassendiagramm zum Beispiel „Bibliothek”
Das Projekt
Bezugspunkt ist das Tutorial “Generierung eines EMF-Modells” (siehe oben). Das
nachfolgende Beispiel demonstriert die Erstellung eines Metamodells auf der Basis von
Java-Quellcode und entspricht genau dem Tutorial. Es umfasst folgende Schritte:
• Step 0: Vorbereitungen
• Step 1: Definieren eines EMF-Modells unter Nutzung von Annotated Java (alternativ kann ein Modell auch importiert werden)
• Step 2: Generierung des Codes für das EMF-Modell
• Step 3: Generierung eines syntaxgesteuerten Editors aus dem EMF-Modell
• Step 4: Ausführen des generierten syntaxgesteuerten Editors
KAPITEL 3. MODELLGETRIEBENE SOFTWAREENTWICKLUNG
77
Step0
Die Vorbereitungen umfassen die oben beschriebene Bereitstellung des EMF in Eclipse
(mittels Update Manager).
Step 1
Es muss zunächst zur Realisierung des Bibliotheks-Projektes ein neues EMF-Projekt
(Empty EMF Project) kreiert werden:
File →New →Project... (vgl. Abb. 3.6.3)
Abbildung 3.6.3: EMF-Projekt kreieren
Mittels des Wizards wird ein Name für das Bibliotheks-Projekt festgelegt (z.B.
de.htwdd.sf.library). Nach Beendigung des Wizards existiert eine Projektstruktur (vgl.
Abb. 3.6.4). Die Verzeichnisse src und model werden erzeugt, sind aber noch leer.
Danach werden per Hand Quelltexte für die Java-Interfaces und Klassen erzeugt
(Ablage in
de.htwdd.sf.library/src, über Kontextmenü des src-Verzeichnisses → New
Java Interface ... ), die den Ausgangspunkt der Modellerstellung bilden (drei Interfaces und eine Klasse, vgl. Abb. 3.6.5 bis 3.6.8). Der Code ist jeweils mit @model-Tags
in Javadoc-Kommentaren annotiert. Achtung: Die Interfaces und die Klasse sind einem
package zugeordnet!
Hier in diesem Beispiel ist der Quelltext der Ausgangspunkt der Modellerstellung. Alternativ wäre es auch möglich, z.B. von UML-Klassendiagrammen auszugehen.
KAPITEL 3. MODELLGETRIEBENE SOFTWAREENTWICKLUNG
78
Abbildung 3.6.4: EMF-Projektstruktur nach dem Erzeugen eines Projekts, es existiert
noch kein Modell
Ecore-basierte Modelle werden in XMI-Dateien serialisiert, wodurch eine Weitergabe
entlang einer Werkzeugkette unterstützt wird.
package de . htwdd . s f . l i b r a r y ;
import j a v a . u t i l . L i s t ;
/∗ ∗
∗ @model
∗/
public i n t e r f a c e L i b r a r y {
/∗ ∗
∗ @model
∗/
S t r i n g getName ( ) ;
/∗ ∗
∗ @model t y p e =" Writer " co n t ai n m en t =" t r u e "
∗/
L i s t <Writer> g e t W r i t e r s ( ) ;
/∗ ∗
∗ @model c o n t ai n m en t =" t r u e "
∗/
L i s t <Book> getBooks ( ) ;
}
Abbildung 3.6.5: Library.java
KAPITEL 3. MODELLGETRIEBENE SOFTWAREENTWICKLUNG
package de . htwdd . s f . l i b r a r y ;
/∗ ∗
∗ @model
∗/
public i n t e r f a c e Book {
/∗ ∗
∗ @model
∗/
String getTitle ( ) ;
/∗ ∗
∗ @model d e f a u l t ="100"
∗/
int getPages ( ) ;
/∗ ∗
∗ @model
∗/
BookCategory g e t C a t e g o r y ( ) ;
/∗ ∗
∗ @model o p p o s i t e =" b o o k s "
∗/
W r i t e r getAuthor ( ) ;
}
Abbildung 3.6.6: Book.java
package de . htwdd . s f . l i b r a r y ;
/∗ ∗
∗ @model
∗/
public i n t e r f a c e W r i t e r {
/∗ ∗
∗ @model
∗/
S t r i n g getName ( ) ;
/∗ ∗
∗ @model o p p o s i t e =" a u t h o r "
∗/
j a v a . u t i l . L i s t <Book> getBooks ( ) ;
}
Abbildung 3.6.7: Writer.java
79
KAPITEL 3. MODELLGETRIEBENE SOFTWAREENTWICKLUNG
package de . htwdd . s f . l i b r a r y ;
/∗ ∗
∗ @model
∗/
public c l a s s BookCategory {
/∗ ∗
∗ @model name="Mystery "
∗/
public s t a t i c f i n a l i n t MYSTERY = 0 ;
/∗ ∗
∗ @model name=" S c i e n c e F i c t i o n "
∗/
public s t a t i c f i n a l i n t SCIENCE_FICTION = 1 ;
/∗ ∗
∗ @model name=" Bio graphy "
∗/
public s t a t i c f i n a l i n t BIOGRAPHY = 2 ;
}
Abbildung 3.6.8: BookCategory.java
80
KAPITEL 3. MODELLGETRIEBENE SOFTWAREENTWICKLUNG
81
Das Erzeugen des EMF-Modells (vgl. Abb. 3.6.9) erfolgt wiederum mit Hilfe eines Wizards. Es ist - ausgehend vom Kontextmenü des model-Verzeichnisses - “EMF
Generator Model” auszuwählen (vgl. Abb. 3.6.10).
AndroMDA
Abbildung 3.6.9: Erzeugen eines neuen EMF-Modells
Im nächsten Schritt wird der Dateiname library.genmodel für das Modell festzulegen (vgl. Abb. 3.6.11).
Danach wird „Annotated Java” als Typ der Quelle ausgewählt (vgl. Abb. 3.6.12).
Nach der Wahl des bereitgestellten Packages (vgl. Abb. 3.6.13) wird der Wizard
beendet.
KAPITEL 3. MODELLGETRIEBENE SOFTWAREENTWICKLUNG
Abbildung 3.6.10: Generieren eines EMF-Modells
Abbildung 3.6.11: Festlegung des Dateinamens
82
KAPITEL 3. MODELLGETRIEBENE SOFTWAREENTWICKLUNG
Abbildung 3.6.12: Auswahl „Annotated Java”
Abbildung 3.6.13: Wahl des Packages
83
KAPITEL 3. MODELLGETRIEBENE SOFTWAREENTWICKLUNG
84
Durch den Wizard sind ein Ecore-Modell (library.ecore) und ein GeneratorModell (library.genmodel) erzeugt worden (vgl. Abb. 3.6.14 ). Das Generator-Modell
dient zur Steuerung der Codegenerierung. Eine View, die dieses Modell zeigt, wird
nach Beenden des Wizards automatisch geöffnet. Das Wurzelobjekt repräsentiert das
gesamte Modell. Durch Expandieren können seine Elemente angezeigt werden (packages, classifier, attributes etc., siehe unten). Über Kontextmenü → Show Properties
View können die Eigenschaften eingesehen und geändert werden.
Abbildung 3.6.14: Ecore- und Generator-Modell
Ein EMF-Projekt besteht aus mehreren Ordnern:
• src enthält im Verzeichnis de.htwdd.sf.library die Java-Quelltexte der Interfaces und Klassen für die Modellerzeugung (die später durch die Codegenerierung um Codebestandteile ergänzt werden) und später auch die generierten
Java-Quellen für den Modell-Editor,
• model enthält die .ecore-, .ecorediag- und .genmodel-Quelldateien,
• Das Verzeichnis META-INF.
KAPITEL 3. MODELLGETRIEBENE SOFTWAREENTWICKLUNG
85
Step 2
Vom Generator-Modell aus erfolgt jetzt die Code-Generierung für das EMF-Modell:
Das Generator-Modell besitzt ein Wurzelobjekt, das das gesamte Modell umfasst. In
Abb. 3.6.15 ist das Modell expandiert (d.h. „aufgeklappt”).
Abbildung 3.6.15: Das library.genmodel
Das Domänenmodell library.ecore enthält xml-Code des Modells. Abb. 3.6.16
zeigt den xml-Code für das vorliegende Beispiel (Datei mit Texteditor geöffnet). Über
EClass, EDataType usw. wird ein Bezug zum Ecore-Framework hergestellt.
Über die „Properties”-Einstellungen im Kontextmenü kann das Verhalten des CodeGenerators gesteuert werden. Zum Beispiel kann festgelegt werden, ob für einen Knoten
Kindknoten eingefügt werden können.
Durch Rechtsklick auf ein Modell-Objekt wird die Art des zu generierenden Codes
ausgewählt (vgl. Abb. 3.6.17). Zunächst wird der Code für das Modell erzeugt.
Nach der Generierung sind neue Klassen erzeugt und bestehende Klassen um Code
ergänzt worden (vgl. Abb. 3.6.18).
Ein neues Paar von Interfaces ist erzeugt worden, für das Package selbst und für
die Factory. Es gibt außerdem zwei neue Packages mit den Suffixen .impl und .util.
Und es gibt neue Dateien plugin.xml und MANIFEST.MF.
Step 3
In diesem Schritt erfolgt die Generierung eines Editors für das Modell: Es werden
drei neue Plug-ins generiert:
KAPITEL 3. MODELLGETRIEBENE SOFTWAREENTWICKLUNG
86
• das edit-Plug-in enthält Adapter und unterstützt ein Command-basiertes Editieren.
• das editor-Plug-in enthält die GUI für den Editor und den Wizard.
• das tests-Plug-in enthält Skelette (Templates) für Testfallspezifikationen für JUnit.
Die Generierung des entsprechenden Quellcodes wird über das Kontextmenü des library.genmodel angestoßen („Generate Edit Code”, ”Generate Editor Code”, „Generate
Test Code” einzeln oder „Generate All” für alle zusammen).
Es werden drei neue Projekte (Plug-ins) erzeugt, die im Package-Explorer angezeigt
werden:
Die Körper der Skelette im tests-Plug-in dienen der Vorbereitung von JUnit-Tests
und müssen vom Entwickler selbst ausgefüllt werden. Das tests-Plug-in enthält auch
eine Beispiel-Klasse, die zeigt, wie ein Modell in einer Standalone-Anwendung geladen
und validiert werden kann.
Der Generierte Code sollte automatisch compiliert werden (Alternative: manuelles
Build durch „Build All”).
KAPITEL 3. MODELLGETRIEBENE SOFTWAREENTWICKLUNG
<?xml version=" 1 . 0 " e n c o d i n g="UTF−8" ?>
<e c o r e : E P a c k a g e
x m i : v e r s i o n=" 2 . 0 "
xmlns:xmi=" h t t p : //www. omg . o r g /XMI"
x m l n s : x s i=" h t t p : //www. w3 . o r g /2001/XMLSchema−i n s t a n c e "
x m l n s : e c o r e=" h t t p : //www. e c l i p s e . o r g / emf /2002/ Ecore "
name=" l i b r a r y "
nsURI=" h t t p : /// de /htwdd/ s f / l i b r a r y . e c o r e "
n s P r e f i x=" de . htwdd . s f . l i b r a r y ">
< e C l a s s i f i e r s x s i : t y p e=" e c o r e : E C l a s s " name=" Book ">
<e S t r u c t u r a l F e a t u r e s
x s i : t y p e=" e c o r e : E A t t r i b u t e "
name=" t i t l e "
eType=" ecore:EDataType
h t t p : //www. e c l i p s e . o r g / emf /2002/ Ecore#// E S t r i n g " />
<e S t r u c t u r a l F e a t u r e s
x s i : t y p e=" e c o r e : E A t t r i b u t e "
name=" p a g e s "
eType=" ecore:EDataType
h t t p : //www. e c l i p s e . o r g / emf /2002/ Ecore#//EInt "
d e f a u l t V a l u e L i t e r a l=" 100 " />
<e S t r u c t u r a l F e a t u r e s
x s i : t y p e=" e c o r e : E A t t r i b u t e "
name=" c a t e g o r y "
eType=" #//BookCategory " />
<e S t r u c t u r a l F e a t u r e s
x s i : t y p e=" e c o r e : E R e f e r e n c e "
name=" a u t h o r "
eType=" #//W r i t e r "
e O p p o s i t e=" #//W r i t e r / books " />
</ e C l a s s i f i e r s>
< e C l a s s i f i e r s x s i : t y p e=" ecore:EEnum " name=" BookCategory ">
< e L i t e r a l s name=" Mystery " />
< e L i t e r a l s name=" S c i e n c e F i c t i o n " v a l u e=" 1 " />
< e L i t e r a l s name=" Biography " v a l u e=" 2 " />
</ e C l a s s i f i e r s>
< e C l a s s i f i e r s x s i : t y p e=" e c o r e : E C l a s s " name=" L i b r a r y ">
<e S t r u c t u r a l F e a t u r e s
x s i : t y p e=" e c o r e : E A t t r i b u t e "
name=" name "
eType=" ecore:EDataType
h t t p : //www. e c l i p s e . o r g / emf /2002/ Ecore#// E S t r i n g " />
<e S t r u c t u r a l F e a t u r e s
x s i : t y p e=" e c o r e : E R e f e r e n c e "
name=" w r i t e r s " upperBound="−1"
eType=" #//W r i t e r "
c o n t a i n m e n t=" t r u e "
r e s o l v e P r o x i e s=" f a l s e " />
<e S t r u c t u r a l F e a t u r e s
x s i : t y p e=" e c o r e : E R e f e r e n c e "
name=" books " upperBound="−1"
eType=" #//Book "
c o n t a i n m e n t=" t r u e "
r e s o l v e P r o x i e s=" f a l s e " />
</ e C l a s s i f i e r s>
< e C l a s s i f i e r s x s i : t y p e=" e c o r e : E C l a s s " name=" W r i t e r ">
<e S t r u c t u r a l F e a t u r e s
x s i : t y p e=" e c o r e : E A t t r i b u t e "
name=" name "
eType=" ecore:EDataType
h t t p : //www. e c l i p s e . o r g / emf /2002/ Ecore#// E S t r i n g " />
<e S t r u c t u r a l F e a t u r e s
x s i : t y p e=" e c o r e : E R e f e r e n c e "
name=" books " upperBound="−1"
eType=" #//Book " e O p p o s i t e=" #//Book/ a u t h o r " />
</ e C l a s s i f i e r s>
</ e c o r e : E P a c k a g e>
Abbildung 3.6.16: xml-Code in der Datei library.ecore
87
KAPITEL 3. MODELLGETRIEBENE SOFTWAREENTWICKLUNG
Abbildung 3.6.17: Library - Code-Generierung
Abbildung 3.6.18: EMF-Modell nach der Code-Generierung
88
KAPITEL 3. MODELLGETRIEBENE SOFTWAREENTWICKLUNG
89
Step 4
Der generierte Modell-Editor liegt in Form von Plug-ins vor. Um die neu erstellten
Plug-ins zu testen bzw. zu erproben, muss eine weitere Eclipse-Instanz erzeugt
werden (Auswahl des Plug-ins im Projekt-Manager, dann Run As →
Eclipse-Application). Die Plug-ins laufen dann in dieser Umgebung.
Abbildung 3.6.19: Kontrolle, dass die erzeugten Plug-ins auch verfügbar sind
Als nächstes können Modell-Instanzen mittels des generierten syntaxgesteuerten
Editors erstellt werden. Der Model-Wizard kann benutzt werden, um eine neue Instanz des Modells zu kreieren (über File →New →Project..., „General Project”). Das
Projekt muss noch einen Namen erhalten (z.B. librarytest). Über das Kontextmenü
des angelegten Projektes librarytest kann eine neue Library-Modell-Instanz erzeugt
werden. „Library Model” wird mit angeboten (vgl. Abb. 3.6.20).
Der Bibliotheksname kann präzisiert werden, in dem für das Attribut Name ein
Wert festgelegt wird:
KAPITEL 3. MODELLGETRIEBENE SOFTWAREENTWICKLUNG
90
Abbildung 3.6.20: Wizard zum Erzeugen einer „Library Model” - Instanz
Änderungen, die mit dem Editor vorgenommen wurden, werden meist erst nach
einem „Refresh” (im Kontextmenü enthalten) sichtbar.
Alternativ zu textuellen Editoren gibt es die Möglichkeit, mittels GEF und GMF
grafische Modell-Editoren zu erstellen.
KAPITEL 3. MODELLGETRIEBENE SOFTWAREENTWICKLUNG
3.6.2
91
Erstellung von EMF-Modellen aus UML-Diagrammen
Anstelle von annotierten Java-Interfaces/Klassen können auch UML-Diagramme als
Ausgangspunkt für die Modellerstellung dienen.
Erprobt wurde die Modellerstellung auf der Basis von Diagrammen, die mittels der
UML2-Tools erstellt wurden. Auch Topcased-UML-Modelle können verwendet werden.
Abb. 3.6.21 zeigt die Bereitstellung der UML2-Tools.
Abbildung 3.6.21: Plug-ins der UML2-Tools
Die Erstellung eines UML-Diagramms soll beispielhaft mit Topcased vorgenommen
werden.
Nach der Fertigstellung eines UML-Klassendiagrammes ist es möglich, ein GeneratorModell aus diesem zu erzeugen. Dazu wird mittels New → Other oder STRG+N das
„EMF Generator Model“ (Ordner Eclipse Modeling Framework) erstellt.
KAPITEL 3. MODELLGETRIEBENE SOFTWAREENTWICKLUNG
92
Es folgt die Auswahl des zu importierenden Modells (Model Importer). Wir nutzen
das erstellte UML Diagramm und wählen hier UML model.
KAPITEL 3. MODELLGETRIEBENE SOFTWAREENTWICKLUNG
93
Danach wird die UML-Datei importiert. Unter „Browse Workspace“ ist im passenden Ordner die *.uml-Datei auszuwählen.
KAPITEL 3. MODELLGETRIEBENE SOFTWAREENTWICKLUNG
94
Als letzter Schritt erfolgt die Paketauswahl. Dort wählen wir die passenden Pakete
(hier: „student“ und „ecore“) aus und bestätigen mit „Finish“.
KAPITEL 3. MODELLGETRIEBENE SOFTWAREENTWICKLUNG
95
Nun hat das System ein .genmodel angelegt. Per Rechtsklick auf „Student“ in
der student.genmodel-View ist es jetzt möglich, „Edit Code“ und „Editor Code“ zu
generieren (vgl. Abschnitt 3.6.1, Step 3).
3.6.3
Erstellen von EMF-Modellen mit Hilfe des Ecore-Editors
Mittels des Wizards kann verlangt werden, den Ecore-Editor zur Erstellung eines
Ecore-Modells zu nutzen.
KAPITEL 3. MODELLGETRIEBENE SOFTWAREENTWICKLUNG
96
KAPITEL 3. MODELLGETRIEBENE SOFTWAREENTWICKLUNG
97
Ein so erstelltes .ecore-Modell kann anschließend importiert werden:
3.7
Modellaustausch
Die MOF-Spezifikation definiert ein serialisierbares Modellformat, das XML Metadate
Interchange (XMI). Die Unterstützung des XMI-Formates durch die derzeit auf dem
Markt erhältlichen Modellierungswerkzeuge ist teilweise noch mangelhaft.
Abb. 3.7.1 zeigt eine Klasse in XMI-Darstellung.
EMF serialisiert Ecore-basierte Modelle in XMI-Dateien und ermöglicht damit
KAPITEL 3. MODELLGETRIEBENE SOFTWAREENTWICKLUNG
98
Abbildung 3.7.1: Klasse C1 in XMI-Darstellung
ebenso wie MOF das Weiterreichen von Modellen entlang einer Werkzeugkette, wobei EMF die Integration in die Eclipse-Plattform in den Vordergrund stellt.
Kapitel 4
Werkzeuge zur Unterstützung
der MDSD
Nachfolgend werden Werkzeuge betrachtet, die Java-basiert sind. Das bedeutet nicht,
dass auch die Zielsprache Java sein muss.
Es gibt Projekte im EMF-Umfeld, die das Erstellen von textuellen und grafischen
Editoren für Ecore-basierte Metamodelle weiter vereinfachen. Diese Werkzeuge sollen
nachfolgend vorgestellt werden.
4.1
Überblick
Graphical Modeling Framework
Das Graphical Modeling Framework (GMF) unterstützt die Entwicklung grafischer
Editoren und basiert auf dem Eclipse Modeling Framwork (EMF) und dem Graphical
Editing Framework (GEF). Zum Erstellen eines Editors sind folgende Schritte erforderlich:
1. Erstellen eines EMF-Metamodells (als Instanz von Ecore),
2. Erstellen von EMF-Konfigurationsmodellen,
3. Generieren des Editors,
4. Hinzufügen von Funktionalität an dafür vorgesehenen Erweiterungspunkten (optional).
Beispiel. Editor für Klassendiagramme
• Es wird ein EMF-Projekt erstellt
99
KAPITEL 4. WERKZEUGE ZUR UNTERSTÜTZUNG DER MDSD
100
• Zum Projekt wird ein Ecore-Modell hinzugefügt
Ein Klassendiagramm wurde wie in Abb. 4.1.1dargestellt beschrieben. Als Quelle
des Modellimports wird das erstellte Ecore-Model ausgewählt.
Abbildung 4.1.1: Ecore-Modell eines Klasseneditors
Anschließend wird ein Plug-in-Projekt für den grafischen Editor erstellt.
Werkzeuge aus dem Projekt openArchitectureWare
Das Projekt openArchitectureWare ist ein Unterprojekt von Eclipse-GMT. Es ist wie
folgt charakterisiert:
• Werkzeugsuite auf Basis eines Generatorframeworks
• Framework, Bereitstellung einer Infrastruktur zur Entwicklung von Generatoren
• Einbindung in Eclipse
• oAW kann beliebige Modellformate, Metamodelle und Ausgabeformate verarbeiten, keine Angebote für bestimmte Zielarchitekturen.
Bestandteile:
KAPITEL 4. WERKZEUGE ZUR UNTERSTÜTZUNG DER MDSD
101
1. Workflow-Engine
2. Typsystem und Expression Language
3. Templatesprache Xpand
Die Workflowengine ermöglicht die Ausführung, d.h. die sequentielle Abarbeitung vordefinierter Komponenten (z.B. Modellinstanziierung, Modellvalidierung, Modelltransformation). Der Workflow wird in einer XML-Datei festgelegt (ähnliche Syntax wie
Apache Ant). Konzepte wie das Definieren von Eigenschaften, das Referenzieren weiterer Workflow-Dateien sind aus Ant bekannt. Die Ausführung eines oAW-Workflows
kann angestoßen werden:
• aus einem Programm über das Workflow-API
• einem Ant-Skript
• die Eclipse-Oberfläche
• Kommandozeilenaufruf
Das oAW-eigene Typsystem ist eine Abstraktionsschicht über die verschiedenen Metamodelle, die als Eingabe für die Generierung verwendet werden können. Bei der
Instantiierung eines Metamodells wird dieses in das Typsystem umgesetzt. In der oAWDistribution sind Adaptionen für einige Metamodelle enthalten: EMF, ...
Mit der Templatesprache Xpand lassen sich Modelltransformationen beschreiben.
4.2
Xtext
Das Framework Xtext dient zur Definition von textuellen DSLs [xte] durch Angabe
von Grammatiken. Xtext stellt als Notationsmittel für Grammatiken eine vereinfachte
EBNF-Notation zur Verfügung (sog. Xtext-Grammatiksprache). Damit können sowohl
abstrakte als auch konkrete Syntax einer DSL definiert werden.
Aus einer Xtext-Grammatik werden Werkzeuge und andere Artefakte generiert.
Dazu gehören:
• ein Metamodell, welches die einzelnen AST-Typen repräsentiert
• ein Parser
• ein Eclipse-basierter Texteditor mit einer Menge von DSL-spezifischen Features:
Syntax Highlighting, Code Completion, Validierung, Code Folding, Outline View.
KAPITEL 4. WERKZEUGE ZUR UNTERSTÜTZUNG DER MDSD
102
Ein generierter Parser verarbeitet den Text einer DSL-Instanz und erzeugt eine ObjektGraph-Struktur, die eine Instant des EMF-Modells (Metamodell) ist. Bei der Generierung des Metamodells wird ein EPackage erzeugt, das EClasses, EDataTypes und
EEnums enthält.
Mit der Grammatiksprache von Xtext können nicht alle Programmiersprachen beschrieben werden, sie ist spezifisch auf die Belange von DSLs zugeschnitten. Die XtextGrammatiksprache wird im Abschnitt 4.2.4 behandelt.
Das Xtext-Framework nutzt intern den Parser-Generator Antlr. Antlr ist ein objektorientierter Top-down-Parser-Generator, der Lexer/Parser für LL(k)-Grammatiken
erzeugt. Antlr ist in Java implementiert.
4.2.1
Installation
Das Xtext-Framework (in der Version 2.2.0) wird wie in Abb. 4.2.1 beschrieben mit
Hilfe des Update-Managers von der Adresse
http://download.eclipse.org/modeling/tmf/xtext/updates/composite/releases/
bereitgestellt.
Abbildung 4.2.1: Installierung von Xtext
Nach der Installation können Xtext-Projekte angelegt werden. In der Installation
sind bereits Beispiele zur Xtext-Anwendung enthalten (vgl. Abb. 4.2.2).
Über das HELP-Menü von Eclipse steht eine Xtext 2.1-Dokumentation zur Verfügung.
4.2.2
Erstes Anwendungsbeispiel
Tatsächlich kann der Menüpunkt Xtext Project from Existing Ecore Models
ausgewählt werden. Beispielsweise werden drei bisher in Projekten im Workspace er-
KAPITEL 4. WERKZEUGE ZUR UNTERSTÜTZUNG DER MDSD
103
Abbildung 4.2.2: Wizard zur Erstellung von Xtext-Projekten
stellte Modelle angeboten (vgl. Abb. 4.2.3).
Für das Library.genmodel wird nach Bestätigen mit OK folgender Code erzeugt.
Der Code ist in der Datei
c:\Dokumente und Einstellungen\fritzsch
\workspace\org.xtext.example.mydsl1\src\org\xtext\example\mydsl1\
enthalten.
KAPITEL 4. WERKZEUGE ZUR UNTERSTÜTZUNG DER MDSD
Abbildung 4.2.3: Auswahl eines Metamodells
Abbildung 4.2.4: Xtext-generierter Code
104
KAPITEL 4. WERKZEUGE ZUR UNTERSTÜTZUNG DER MDSD
4.2.3
105
Zweites Anwendungsbeispiel
Das Beispiel ist an ein Tutorial angelehnt, das in der Xtext 2.1 Documentation enthalten ist.
Es wird zunächst ein Xtext-Projekt angelegt:
File → New → Project... → Xtext → Xtext Project. Im Wizard werden festgelegt:
Projektname: de.htwdd.sf.domainmodel
DSL-Name: de.htwdd.sf.domainmodel.Domainmodel
DSL-File-Extension: dmodel
Der Wizard ist mit „finish” zu beenden. Nach Beenden des Wizards befinden sich
drei neue Projekte im Workspace:
de.htwdd.sf.domainmodel - enthält die Grammatikdefinition und alle LaufzeitKomponenten
de.htwdd.sf.domainmodel.tests - Platz, um JUnit-Tests zu spezifizieren
de.htwdd.sf.domainmodel.ui - Eclipse-basierter Editor und Funktionalität, die
auf die Workbench bezogen ist.
Jetzt ist die Grammatik anzugeben. Die die Grammatik enthaltende Datei
Domainmodel.xtext (allgemein <DSL-Name>.xtext) wird nach Abschluss des Wizards automatisch als Eclipse-Editor geöffnet und kann editiert werden. Nach dem
Öffnen ist zunächst eine „Hello World” - Grammatik enthalten, die zu ersetzen ist.
Wir tragen folgende Grammatik für unsere Sprache ein:
grammar de . htwdd . sf . domainmodel . Domainmodel with
org . eclipse . xtext . common . Terminals
generate domainmodel " http :// www . htwdd . de / sf / domainmodel / Domainmodel "
Domainmodel :
elements += Type *
;
Type :
DataType | Entity
;
DataType :
KAPITEL 4. WERKZEUGE ZUR UNTERSTÜTZUNG DER MDSD
106
’ datatype ’ name = ID
;
Entity :
’ entity ’ name = ID ( ’ extends ’ superType = [ Entity ])? ’{ ’
features += Feature *
’} ’
;
Feature :
many ?= ’ many ’? name = ID ’: ’ type = [ Type ]
;
Die erste Zeile (grammar ...) definiert den Namen der Sprache. Als Name ist jeder
gültige „Java-Qualifier” erlaubt. Er entspricht dem Dateinamen, dem noch die Endung
.xtext angehängt ist. Es wird außerdem eine andere Sprachdefinition einbezogen, hier
org.eclipse.xtext.common.Terminals.
Die generate-Anweisung legt fest, dass ein Ecore-Modell erzeugt wird. domainmodel
ist darin der EPackage-Name. Alternativ könnte auch ein bestehendes Ecore-Modell
verwendet werden.
Die Startregel ist eine Parser-Regel und besagt, dass das Domänenmodell Domainmodel
eine beliebige Anzahl von Types besitzt, die zu einem elements genannten Feature hinzugefügt werden können. Type ist wiederum durch eine Parser-Regel usw.
Liegt die Grammatik-Definition vollständig vor, ist der Xtext-Language-Generator
(eine „Workflow Engine”) auszuführen, der die verschiedenen Sprachkomponenten aus
der Grammatik-Definition ableitet. Die Aktivierung der „Workflow Engine” erfolgt
über das Kontextmenü der Datei
GenerateDomainModel.mwe2 im Package de.htwdd.sf.domainmodel (vgl. Abb. 4.2.5).
Der Generator erzeugt den Parser, den Serializer und einigen weiteren InfrastrukturCode.
Nunmehr ist die Integration in die Eclipse-IDE zu testen. Mittels Run → Run
Configurations ist eine neue Eclipse-Applikation zu erzeugen. In der erzeugten EclipseWorkbench sind die neu entwickelten Plug-ins verfügbar. In dieser Eclipse-Instanz
kann ein neues Java-Projekt (z.B. Sample) erzeugt werden. In dem generierten Ordner
src wird nachfolgend eine Datei erzeugt, die eine Endung entsprechend der obigen
Festlegung haben muss (hier: .dmodel). Die nachfolgende Frage nach der „Xtext
nature” wird erwartet und ist mit „Yes” zu bestätigen.
Mit dem erzeugten Editor kann nun gearbeitet werden (vgl. Abb. 4.2.7). Mit dem
„content assistent” (Ctrl+Space) können Einträge ausgewählt werden.
KAPITEL 4. WERKZEUGE ZUR UNTERSTÜTZUNG DER MDSD
107
Abbildung 4.2.5: Aktivierung des Xtext-Language-Generators
Abbildung 4.2.6: Abfrage beim Erzeugen einer .dmodel-Datei
Es gibt zusätzlich eine entsprechende Outline-View. Abbildung 4.2.8 zeigt eine mit
dem generierten Editor erstellte Instanz dmtest.dmodel zur DSL.
4.2.4
Die Xtext-Grammatiksprache
de Spezifikation einer Xtext-Grammatik beginnt mit einem Kopf, der die Eigenschaften
der Grammatik beschreibt.
Terminalregeln
Aufgabe ist es, aus einer Folge von Zeichen der Eingabe Token zu erkennen. Die Namen
der Terminalregeln werden mit Großbuchstaben geschrieben.
KAPITEL 4. WERKZEUGE ZUR UNTERSTÜTZUNG DER MDSD
108
Abbildung 4.2.7: Nutzung des generierten DSL-Editors
Abbildung 4.2.8: Beispiel-Instanz zur DSL „Domainmodel”
Parserregeln
Parserregeln bilden den Bauplan zur Konstruktion von EObject-Objekten, aus denen
der abstrakte Syntaxgraph eines Programms (AST) aufgebaut wird. Der Typ des jeweils aktuellen Objekts wird durch den Rückgabe-Typ der Parser-Regel spezifiziert.
Es wird implizit angenommen, dass der Typname dem Regelnamen entspricht. Actions und Assignments werden benutzt, um Typen abzuleiten und die semantischen
Objekte entsprechend zu initialisieren.
Assignments dienen der Zuweisung von Informationen zu einem Feature (dem aktuell produzierten Objekt).
Syntax:
name = Regelaufruf | Schlüsselwort | Cross-Reference|
Der Typ des Features name wird durch den rechtsseitig notierten Ausdruck bestimmt.
KAPITEL 4. WERKZEUGE ZUR UNTERSTÜTZUNG DER MDSD
109
Der Operator += erwartet ein mehrwertiges Feature und fügt den rechtsseitigen
Wert zu einer Liste hinzu.
Der Operator ?= wird für Features vom Typ Boolean (d.h. EBoolean) verwendet.
Eine Cross-Reference ist ein Link innerhalb der Grammatik. Solche Links werden
vom Programmverbinder (Linker) verarbeitet.
Syntax:
Cross-Reference = ’[’ type = TypeRef ( ’|’ t̂erminal-CrossreferenceableTerminal)?
’]’
Actions Das Objekt, das bei der Verarbeitung einer Parser-Regel zurückgegeben
wird, wird gewöhnlich von der ersten Zuweisung (Assignment) erzeugt. Der Typ wird
implizit durch den Rückgabetyp der Parser-Regel bestimmt. Mittels Actions kann der
Rückgabetyp explizit gemacht werden.
Es werden Simple Acions und Assigned Actions unterschieden.
KAPITEL 4. WERKZEUGE ZUR UNTERSTÜTZUNG DER MDSD
4.3
110
Xtend
Wir wollen in diesem Abschnitt beschreiben
1. welche Charakteristika die Sprache Xtend besitzt,
2. wozu Xtend im Rahmen von Xtext-Projekten verwendet wird und
3. ein Beispiel: Verarbeitung von Expressions der Spache PL/0 durch einen Kellerautomaten.
4.3.1
Die Sprache Xtend
Xtend ist eine statisch getypte Sprache, die auf der JVM läuft. Xtend erfordert Eclipse
3.5 oder höher und ein Java SDK Version 5 oder höher.
So entspricht die STruktur von Xtend-Programmen der von Java-Programmen,
bzgl. der Notation gibt es Einsparungen bzw. Verkürzungen. Es gibt z.B. keine Semikolons am Ende von Anweisungen (auch package- und import-Anweisungen) und
keine explizite Angabe von Rückgabetypen.
Jede Xtend-Klasse ist implizit public. Parametrisierte Klassen werden unterstützt.
Xtend-Konstruktor-Deklarationen enthalten keinen Klassennamen, also nur new(
paramtype param){ ... }.
Instanzvariablen (Fields) werden wie in Java gehandhabt, zusätzlich gibt es sog.
extension methods.
Assignments sind Expressions, die den zugewiesenen Wert zurückgeben.
Xtend-Metoden werden innerhalb einer Klasse deklariert und in entsprechende
Java-Methoden transformiert.
4.3.2
Entwicklung eines Code-Generators mit Xtend
Bei einem Xtext-Projekt wird im Runtime-Projekt der DSL ein Stub (Quelltext) eines
Code-Generators als Xtend-Klasse erzeugt. Die Datei dslnameGenerator.xtend im
Package
dslname .generator des src-Verzeichnisses enthält diese (rudimentäre) Xtend-Klasse,
die benutzt werden kann, um Code für Modelle zu generieren.
Nachdem der Quellcode in dieser Datei entsprechend der Aufgabenstellung angepasst wurde, kann eine neue Eclipse-Applikation für das Xtext-Projekt erzeugt werden.
Darin ist zunächst von Hand ein Source-Verzeichnis src-gen anzulegen.
Der Generator wird durch einen Builder
(org.eclipse.xtext.builder.IXtextBuilderPerticipant) aufgerufen, wenn das File gespeichert wird, das die DSL-Instanz enthält.
KAPITEL 4. WERKZEUGE ZUR UNTERSTÜTZUNG DER MDSD
111
Grundlage für die nachfolgenden Darstellungen zur Nutzung des Codegenerators
ist das Xtext-Tutorial „15 Minutes Tutorial - Extended” (vgl. Abb. 4.3.1).
Abbildung 4.3.1: Lernen von Xtend mittels Eclipse → Help → Xtext-Dokumentation
Die Datei dslnameGenerator.xtend nimmt den Generator-Code (formuliert mit
Xtend) auf.
Diese Xtend-Klasse (z.B. DomainmodelGenerator im Tutorial) wird verwendet, um
Code zu generieren:
class DomainmodelGenerator implements IGenerator {
override void doGenerate(Resource resource, IFileSystemAccess fsa) {
}
}
Die Methode doGenerate wird ausgeführt, wenn von dem syntaxgesteuerten Editor
eine DSL-Instanz gespeichert wird.
Innerhalb des Körpers der Methode doGenerate kann die Erzeugung einer TextDatei programmiert werden (Anwendung der Methode generateFile auf das Parameterobjekt fsa):
fsa.generateFile("KAData.java", code)
In einem hier code genannten String wird zuvor der Text-Inhalt der Datei zusammengestellt, die hier den Namen KAData.java bekommt.
KAPITEL 4. WERKZEUGE ZUR UNTERSTÜTZUNG DER MDSD
112
Die nachfolgende Schleife ist innerhalb von doGenerate zu platzieren und erlaubt
den Zugriff auf alle Objekte des angegebenen Typs (hier vom Typ Ident) im Syntaxbaum.
for(e:resource.allContents.toIterable.filter(typeof(Ident))) {
// Zugriff auf resourcen und Generierung von code-Strings,
// hier für Objekte des Typs "Ident"
}
Auf die Objekte e des angegebenen Typs können nun Methoden angewandt werden,
die innerhalb der Klasse zu definieren sind, z.B. e.traversiere.
Schleifen werden wie folgt behandelt (Beispiel sind hier die Expressions von PL0):
def traversiere(Term t) {
System::out.println("traversiere Term!")
if(t.facte != null) t.facte.traversiere
if(t.efacte != null) for(allEFacte:t.efacte) allEFacte.traversiere
}
Wenn es einen Fact gibt (facte ist der Feature-Name), wird zunächst auf diesen
die Funktion traversiere angewendet. Wenn es Efact-Objekte gibt, wird anschließend
auf diese sukzessive die Funktion traversiere angewendet.
Die Definition einer solchen Methode kann auch mittels Template-Code efolgen
(s.u.).
4.3.3
Beispiel
Gegeben ist die Grammatik G2 für Ausdrücke in PL/0 (vgl. Abb. 3.2.5). Angenommen,
es wurde zur Grammatik G2 folgende Xtext-DSL erstellt:
grammar de.htwdd.sf.pl0v3.PL0v3 with org.eclipse.xtext.common.Terminals
generate pL0v3 "http://www.htwdd.de/sf/pl0v3/PL0v3"
Pl0v3 :
pl0=Expr ;
Expr returns Expr:
(vz=Vz)? terme=Term eterme+=(Eterm)* ;
Eterm returns Eterm:
vze=Vz terme=Term ;
Term:
facte=Fact efacte+=(Efact)* ;
KAPITEL 4. WERKZEUGE ZUR UNTERSTÜTZUNG DER MDSD
113
Efact:
fze=Fz facte=Fact ;
Fact:
elemf = (Ident | Number | Kexpr) ;
Kexpr:
lpar=Lparen ex=Expr rpar=Rparen ;
Vz:
vz=("+" | "-") ;
Fz:
fz=("*" | "/") ;
Ident :
name=ID ;
Number :
wert=INT ;
Lparen:
lp=’(’ ;
Rparen:
rp=’)’ ;
Es soll für eine DSL-Instanz (einen Ausdruck) automatisch eine Postfix-Notation
erstellt werden. Es soll ferner Code für eine Kellermaschine generiert werden.
Templates
Da durch den auszuführenden Xtend-Code wesentlich Code durch String-Verkettung
erzeugt wird, der zu weiten Teilen aus dem Xtend-Code übernommen wird, bietet
Xtend eine vereinfachte Schreibweise (Template Expressions) an:
def compile(Entity e)”’
package
public class e.name{
}
”’
Ein Template wird umschlossen von drei einfachen Quotes. Der Templatetext kann
durch ein Paar französischer Klammern („guillemets”, «... », einfügen erfolgt über das
Kontextmenü) unterbrochen werden. In « » eingeschlossene Textteile werden ausgewertet. Ein Template ist ein Ausdruck und kann überall stehen, wo ein Ausdruck stehen
kann.
KAPITEL 4. WERKZEUGE ZUR UNTERSTÜTZUNG DER MDSD
4.4
114
Xpand
Xpand ist eine Sprache, die mit EMF-basierten Metamodellen umgehen kann. Mittels
Xpand können Modelle weiter verarbeitet werden (Transformationen), die mit dem
Xtext-Generator erzeugt wurden. Mit Xpand können domänenspezifische Sprachen in
bekannte Programmiersprachen übersetzt werden.
Xpand greift auf den abstrakten Syntaxbaum zu.
Xpand-Template-Datei
Algorithmus 4.1 Grundgerüst
IMPORT
EXTENSION
Xpand kann durch die funktionale Sprache Xtend um zusätzliche Logik erweitert
werden. Xtend kennt wie Xpand alle Knotentypen des abstrakten Syntaxbaumes.
KAPITEL 4. WERKZEUGE ZUR UNTERSTÜTZUNG DER MDSD
4.5
Aspektorientierte Programmierung
Zuerst wird ein AspectJ-Projekt angelegt:
AOPDemo wird als Klasse angelegt:
Tracing wird als Aspect angelegt:
115
KAPITEL 4. WERKZEUGE ZUR UNTERSTÜTZUNG DER MDSD
Die Ausführung:
Ergebnis der Ausführung:
116
KAPITEL 4. WERKZEUGE ZUR UNTERSTÜTZUNG DER MDSD
4.6
117
Grafische Beschreibung einer DSL
Die konkrete Syntax einer DSL kann auch grafisch beschrieben werden.
Die grafische Notation wird in der Praxis oft durch UML-Diagramme realisiert.
Beispiel: Entwicklung einer grafischen DSL für Ontologie-Darstellungen.
4.6.1
GMF
Das Graphical Modeling Framework (GMF) basiert auf dem EMF. Es unterstützt die
Generierung von grafischen Editoren aus EMF-Metamodellen mit Hilfe von Wizards.
Zum Erstellen eines Editors sind folgende Schritte erforderlich, die in der EclipseView „GMF-Dashboard” dargestellt sind:
1. Erstellen eines Metamodells mit EMF.
2. Erstellen von GMF-Konfigurationsmodellen.
3. Generieren des Editors
4. Optional an dafür vorgesehenen Erweiterungspunkten Funktionalität hinzufügen
(Java)
Abbildung 4.6.1: GMF Dashboard
GMF basiert auf dem Graphical Editing Framework (GEF).
Das GEF [GEF]ist ein Framework zur Erstellung grafischer Editoren und gehört
zum Eclipse Modeling Project. Es stellt u. a. folgende Funktionen zur Verf¨ugung:
• Figuren und Formen, die sich miteinander verbinden lassen
KAPITEL 4. WERKZEUGE ZUR UNTERSTÜTZUNG DER MDSD
118
• Ein Überblicksfenster zur schnellen Navigation
• Eine Werkzeugleiste für die Erstellung und Markierung von Figuren
• Grafische und hierarchische Visualisierung
• Druckerausgabe
Als Zielarchitektur für den GMF-Generator dient das Graphical Editing Framework
(GEF).
4.6.2
Beispiel
Anlegen eines Plug-in-Projekts und Erstellen eines grafischen Editorfensters. In der
Manifest-DAtei müssen folgende Abhängigkeiten festgelegt werden:
org.eclipse.ui
org.eclipse.core.runtime
4.6.3
Beispiel: Erstellen eines grafischen Klasseneditors
Es wird zunächst in Eclipse ein Ecore-Modell erstellt.
Abbildung 4.6.2: Ecore-Modell
KAPITEL 4. WERKZEUGE ZUR UNTERSTÜTZUNG DER MDSD
4.7
119
AndroMDA
AndroMDA ist ein Framework für modellgetriebene Softwareentwicklung gemäß dem
MDA-Paradigma. AndroMDA ist in Java implementiert und quelloffen.
AndroMDA unterstützt die Erzeugung von Quellcode aus Plattform-unabhängigen
Modellen (PIM). Als Modellierungssprache wird nur die UML unterstützt.
4.7.1
Beispiel
Kapitel 5
Software Factories
Der Inhalt dieses Kapitels basiert weitgehend auf der Diplomarbeit von S. Bley an der
HTW Dresden [Ble08].
5.1
Der Begriff „Software Factory”
Der Begriff „Software Factories” stammt aus der Microsoft Software-Factory-Initiative
und wird von Greenfield und Short in [GS06] erklärt. Es existiert ein enger Bezug zu „Product Line Engineering”. In einer Produktlinie (= Produktfamilie) werden
ähnliche Softwareprodukte in einer einheitlichen Softwareentwicklungsumgebung hergestellt, die dynamisch an die Besonderheiten der einzelnen Produkte angepasst werden
kann.
„Software Factory” nach Bley [Ble08]:
1. Das gemeinsame Konzept der Produktfamilie ist in einer Domäne zusammengefasst
2. Festlegung definierter Punkte, an denen sich die Produkte unterscheiden
Ein Generator erzeugt aus dem Modell der gemeinsamen Domäne die Artefakte für
alle Familienmitglieder.
Mit einer Software Factory können verschiedene Produkte einer Produktfamilie
erzeugt werden. Zum Beispiel kann es sich bei der Produktfamilie um Java-EnterpriseAnwendungen handeln (vgl. [Ble08]).
Eine Softwarefabrik ist eine für eine bestimmte Domäne angepasste IDE. Es kommen Wizards, Patterns, Frameworks, Templates, DSLs und dafür angepasste Editoren
zum Einsatz.
120
KAPITEL 5. SOFTWARE FACTORIES
5.2
121
Anforderungen an eine Factory
Die fachlichen Belange einer Domäne sind unabhängig von der vorgesehenen Zieltechnologie vom Anwendungsentwickler in einer DSL zu formulieren, die DSL muss für die
Beschreibung der Fachlichkeit geeignet sein.
Spezifika der Zieltechnologie (z.B. Plattformen, verwendete Frameworks) sollen für
ein konkretes Produkt individuell auswählbar sein. Zieltechnologiespezifische Artefakte sollen dann aus dem fachlichen Modell generiert werden können. Eine „Cartridge”
enthält die Funktionalität, die für die automatische Codeerzeugung aus Modellen notwendig ist. Die Erweiterung um neue Cartridges soll mit geringem Aufwand möglich
sein.
5.3
Ein Fallbeispiel:
Architektur von Java-Enterprise-Applikationen
Das gemeinsame Merkmal der Produkte, die im folgenden Fallbeispiel mit der Software
Factory erstellt werden, liegt darin, dass sie (Java-) Enterprise-Anwendungen sind.
Das heißt, es handelt sich um verteilte Anwendungen, in denen Daten verarbeitet
und persistent gespeichert werden, und die in der Regel eine Benutzerschnittstelle
anbieten. Daraus ergibt sich die Domäne der Software Factory: die Architektur von
Java-Enterprise-Anwendungen.
Eine Besonderheit dieses Fallbeispiels besteht darin, dass viele Aspekte von JavaEE-Anwendungen bereits durch die Eclipse-IDE abgedeckt werden. Es bietet sich deshalb an, die Factory in die Eclipse-IDE zu integrieren.
Ausgangspunkt der Betrachtungen ist das Domänenmodell einer Enterprise-Anwendung,
nach E. Evans [Eva03]. Abb. 5.3.1 zeigt dieses Modell. Entitäten repräsentieren Objekte einer Domäne. Entitäten können über die Laufzeit des Systems hinaus fortbestehen.
Wertobjekte (Value Objecs) besitzen keine Objektidentität und sollen unveränderlich
sein. Services beschreiben domänenspezifisches Verhalten, das nicht Objektklassen in
Methoden zugeordnet ist. Die Domäne wird in Module unterteilt, die hauptsächlich
Funktionen gruppieren. Module sind untereinander lose gekoppelt. Darüber hinaus
haben sich Muster etabliert, die sich mit der Lebenszyklusverwaltung von Objekten
befassen. Die Muster Aggregat, Fabrik und Repository adressieren diese Problematik.
Aggregate gewährleisten die Datenintegrität. Umfangreiche Erzeugungslogik wird in eigene Objekte - die Fabriken (Factories) - ausgelagert. Repositories kapseln den Zugriff
auf persistierte Objekte.
KAPITEL 5. SOFTWARE FACTORIES
122
Abbildung 5.3.1: Domänenmodell nach E. Evans
5.3.1
DSL
Stefan Bley legt für die Entwicklung einer Factory für Enterprise-Applikationen die in
Abb. 5.3.2 dargestellte DSL zugrunde. Es handelt sich um eine „architekturzentrierte” DSL. Eine Entität enthält eine Menge von Attributen. Die Beziehungen zwischen
Entitäten werden durch Referenzen ausgedrückt. Attribute und Referenzen sind unter einer gemeinsamen Oberklasse Entity Feature zusammengefasst. Entit¨aten können
auch Operationen enthalten, jedoch sollten diese sich nicht über den Bereich der Entität hinaus auswirken.
Abbildung 5.3.2: Domänenmodell (= Metamodell) „Domain” von S. Bley
Die statische Semantik des Metamodells beinhaltet Zusicherungen, die für ein Modell gelten müssen, damit es als gültig angesehen werden kann. In Abb. 5.3.4 sind
solche Zusicherungen zusammengefasst.
KAPITEL 5. SOFTWARE FACTORIES
Abbildung 5.3.3: Vererbung
Abbildung 5.3.4: Statische Semantik des Metamodells
123
KAPITEL 5. SOFTWARE FACTORIES
5.3.2
124
Konzept
Ein Kern-Plug-in (Core) stellt die Basis des Systems dar (vgl. Abb. 5.3.5). Es übernimmt die Steuerung. Das Kern-Plug-in definiert Extension-Points, an die sich die
Cartridges andocken. Eine GUI-Komponente realisiert die Integration in die grafische
Benutzeroberfläche von Eclipse. Eine weitere Komponente beinhaltet die („Domain”
genannte) DSL. Die DSL umfasst das Metamodell und die konkrete Syntax zur Modellierung des Domänenwissens. Cartridges besitzen das „Wissen”, wie aus den Modellen
Zielartefakte generiert werden. Die Ablaufsteuerung der CArtridge wird über einen
konfigurierbaren Workflow organisiert. Bei der Konfiguration wird die Ablaufreihenfolge der Workflowkomponenten festgelegt.
Abbildung 5.3.5: Konzept der Software Factory
5.3.3
Implementierung
Unterschiede zwischen den von einer Factory erzeugten Produkten liegen in der Fachlichkeit sowie in der Wahl der Technologie, mit der sie implementiert werden. Dabei
dient die Java-Enterprise-Plattform als Basis. Die weiteren für eine Software verwendeten Technologien sind jedoch meist durch projektspezifische Rahmenbedingungen
bestimmt und somit nicht für alle Produkte der Software Factory gleich. Diese variablen Eigenschaften sind in Bausteinen zusammengefasst, die Cartridges genannt
KAPITEL 5. SOFTWARE FACTORIES
125
werden.
Die als Beispiel realisierte Software Factory stellt eine Entwicklungsumgebung zur
Verfügung, indem sie die IDE Eclipse durch Plugins erweitert. Dadurch muss kein
weiteres Werkzeug in den Softwareentwicklungsprozess eingebunden werden. Die Cartridges werden ebenfalls als Eclipse-Plugins in die Software Factory integriert.
Im Beispiel ist eine Cartridge ein Eclipse-Plug-in, das den Extension-Point com.saxsys.cartridge
erweitert, der vom Software-Factory-Kern bereitgestellt wird. Verlangt wird:
• Cartridge-ID
• eine Workflow-Datei, die den Ablauf der Komponenten festlegt,
• Angabe von weiteren Cartridges:
– Erforderliche (requires) Cartridges müssen vor der betreffenden Cartridge
ausgeführt werden und
– eingeschlossene (advices) Cartridges werden während der Ausführung der
betreffenden Cartridge von ihr aufgerufen.
Über Schnittstellen können Cartridges Wissen austauschen. Es gibt verschiedene Ansätze für Schnittstellen:
• Metamodell-Extensions,
• Aspektorientierte Templates,
• Java-Code.
Cartridges sind oft auf die Funktionalität anderer Cartridges angewiesen (use).
Metamodell-Extensions definieren zusätzliche Eigenschaften und Hilfsmethoden für
Metamodellelemente. Sie bilden eine Programmierschnittstelle für andere Codebestandteile. So kann gewährleistet werden, dass mehrfach gebrauchter Code zentral
gehalten wird.
Mittels aspektorientierter Programmierung (AOP) ist es möglich, dass eine Cartridge zusätzliche Informationen in ein Artefact generieren kann, das bereits von einer
anderen Cartridge erstellt wurde. Xtend stellt einen AOP-Mechanismus zur Verfügung
(vgl. [Asp15]).
Zur Arbeit mit AspectJ in Eclipse können die AspectJ Development Tools (AJDT)
als Plug-in genutzt werden. Abb. 5.3.6 zeigt die Installation der notwendigen Plug-ins.
Eher selten wird von der Möglichkeit Gebrauch gemacht, dass eine Cartridge JavaCode einer anderen Cartridge referenziert. Genutzt werden kann diese Möglichkeit
zum Beispiel, um in den Workflow einer Cartridge Workflow-Komponenten anderer
Cartridges einzubeziehen.
KAPITEL 5. SOFTWARE FACTORIES
126
Abbildung 5.3.6: AJDT - update-Site
Verwendete Hilfs-Plug-ins
Bestimmte Plug-ins sind keine Cartridges, werden aber von Cartridges verwendet. So
enthält ein spezielles Plug-in die in Check formulierten Validierungsregeln für Modelle
der Domäne „Domain”. Diese werden z.B. aus der POJO-Creater-Cartridge heraus
geprüft.
Exemplarische Cartridges
Module Project Creator ist eine Cartridge zur Erstellung von Projekten im EclipseWorkspace. Die Cartridge erstellt ein Java-Projekt (genauer: ein AJDT-Projekt (AspectJ
Development Tools)) für jeden „Domain”-Modul. Nachfolgende Cartridges können Ihre
Artefakte in dieses Projekt hinein speichern. Es werden Unterverzeichnisse für manuell
erzeugte und für generierte Artefakte angelegt und in den classpath eingetragen. Der
Module Project Creator erstellt außerdem ein Java-Projekt, welches alle Bibliotheken
aus Cartridges enthält, die im Extension Point classpathContribution angegeben
KAPITEL 5. SOFTWARE FACTORIES
127
werden. Artefakte werden nur generiert, wenn sie noch nicht vorhanden sind.
POJO-Creator erzeugt Java-Klassen und AspectJ-Aspekte für die Elemente eines
Domain-Modells. Generierte Klassen sind sog. Plain Old Java Objects (POJOs), die
dadurch gekennzeichnet sind, dass sie keine weiteren Abhängigkeiten von Klassenbibliotheken oder Frameworks besitzen. Dadurch unterscheiden sie sich z.B. von Entity
Beans (EJB). Die Cartridge prüft Zusicherungen, modifiziert das Modell und generiert
Code-Artefakte.
JPA Annotation Creator generiert Artefakte für das Persistenzframework JPA
(Java Persitence API ). Es stellt eine einheitliche Schnittstelle für die Verwendung von
objekt-relationalen Mappern bereit.
Data Access Object Generator Der Zugriff auf persistente Objekte erfolgt über
einheitliche Datenzugriffsschnittstellen (DAO), die für den jeweiligen Persistenzmechanismus implementiert werden müssen. Die Cartridge erstellt diese Schnittstelle für alle
Entitäten des Domain-Moduls.
JPA Data Access Object Generator Der Generator ist für die Implementation
der mittels Data Access Object Generator erzeugten Schnittstellen zuständig.
Spring 2.0 Service Beans Generator Die Cartridge erstellt Artefakte für das
Spring-Framework. Durch die Verwendung von Dependency Injection (DI) können Abhängigkeiten zwischen Objekten „von außen” verwaltet werden, sie müssen nicht schon
zur Übersetzungszeit festgelegt werden.
5.3.4
Installation der Factory
Zur Installation sind zunächst die Plugins über den Update-Manager in Eclipse bereitzustellen. Es ist ein Softwareentwicklungsprojekt im Workspace anzulegen. Im Unterverzeichnis models ist das Domänenmodell bereitzustellen. Welche Cartridges beim
Build angewendet werden, ist in den Software-Factory-Einstellungen festgelegt.
KAPITEL 5. SOFTWARE FACTORIES
128
Literaturverzeichnis
[Asp15]
; Xerox Corporation (Veranst.): The AspectJTM Programming Guide. https://eclipse.org/aspectj/doc/released/progguide/index.
html. Version: 2015, Abruf: 09.06.2015
[Ble08]
Bley, S.: Konzeption und Entwicklung einer Software Factory für JavaEnterprise-Anwendungen basierend auf der Eclipse-Plattform, Hochschule
für Technik und Wirtschaft Dresden, Fakultät Informatik/Mathematik, Diplomarbeit, 2008
[CR09]
Clayberg, E. ; Rubel, D.: Eclipse Plug-ins. Third Edition. AddisonWesley, 2009
[Dau08]
Daum, Berthold: Rich-Client-Entwicklung mit Eclipse 3.3. 3., aktualisierte
und erweiterte Auflage. dpunkt.verlag, 2008
[Ecl]
Eclipse Project Site. URL: http://www.eclipse.org,
[Eva03]
Evans, E.: Domain-Driven Design: Tackling Complexity in the Heart of
Software. Amsterdam : Addison-Wesley Longman, 2003
[GEF]
Graphical Editing Framework Project Site. www.eclipse.org/gef, Abruf:
2.1.2008
[GS06]
Greenfield, J. ; Short, K.: Software Factories - Moderne SoftwareArchitekturen mit SOA, MDA, Patterns und agilen Methoden. mitp-Verlag,
2006 www.softwarefactories.com
[MOF05] Meta Obect Facility (MOF) Specification.
(OMG), 2005
[Pop06]
Object Management Group
Popp, G.: Konfigurationsmanagement mit Subversion, Ant und Maven Grundlagen für Softwarearchitekten und Entwickler. dpunkt.verlag, 2006
129
LITERATURVERZEICHNIS
130
[SMSH07] Stahl, T. ; M.Völter ; S.Efftinge ; Haase, A.: Modellgetriebene Softwareentwicklung - Techniken, Engineering, Management. 2., aktualisierte
und erweiterte Auflage. dpunkt.Verlag, 2007
[Som07]
Sommerville, I.: Software Engineering. Addison-Wesley, 2007
[Ste88]
Stetter, Franz: Theoretische Informatik. Springer-Verlag, 1988
[xte]
Xtext - Open Source Framework für die Entwicklung von Programmiersprachen und domänenspezifischen Sprachen. http://www.eclipse.org/Xtext
Index
A
abstrakte Syntax, 65
Activator-Klasse, 20
Agile Softwareentwicklung, 9
AndroMDA, 119
ANT, 8
Antlr, 102
AOP, 125
AOP-Mechanismus, 125
Assignment, 108
Export-Wizards, 36
B
Build, 19
I
IDE, 11
interne DSL, 73
C
Cartridge, 124
CASE-Tools, 10
Chomsky-Hierarchie, 63
Class-Loader, 17
classpath, 126
D
DSL, 73
E
Eclipse, 11
Eclipse Update Manager, 43
Eclipse-Applikation, 106
Ecore, 74
EMF, 13, 74, 99
Entitäten, 121
Entity Beans, 127
Equinox, 17
F
Feature, 43
Feature-Manifest-Editor, 43
Feature-Projekt, 43
G
GEF, 99, 117
GMF, 99, 117
Grammatik, 62
J
JFace, 12
JLex, 70
JPA, 127
K
Konfigurationsmanagement, 8
konkrete Syntax, 65
kontextsensitiv, 65
L
LISP, 73
M
M2C, 74
M2M, 74
MANIFEST.MF, 17
Maven, 8
MDSD, 60
131
INDEX
Mercurial, 8
Metametamodell, 73
Metamodell-Extensions, 125
Model Driven Architecture, 60
Module Project Creator, 126
N
Nichtterminal, 63
O
openArchitectureWare, 100
OSGi-Bundle, 17
P
PDE, 19
PIM, 119
Plug-in-Loader, 16
Plug-ins, 11
plugin.xml, 17
POJO-Creator, 127
Produktionsregeln, 63
Programming, 9
R
Regelgrammatik, 63
Rich Client Application, 51
Rich Client Platform, 16
Roundtrip Engineering, 9
Ruby, 73
S
Semantik, 65
Services, 121
SEU, 10, 11
site.xml, 47
Softwareentwicklungsumgebungen, 10
Sprache, formale, 62
SQL, 73
SWT, 12
Syntax, 65
132
T
Terminal, 63
Terminalsymbol, 63
tests-Plug-in, 86
Token, 107
TOPCASED, 11
Topcased, 12
Turing-unvollständig, 73
U
Update Manager, 77
Update Site Project, 47
V
ε-Sonderregel, 65
W
Wirtsssprache, 73
X
Xpand, 114
Xtend, 110, 114
Xtext, 101
Xtext-Language-Generator, 106
Xtext-nature, 106
Herunterladen