openarchitectureware

Ähnliche Dokumente
WIRTSCHAFTSINFORMATIK

Model Driven Development im Überblick

MOF Meta Object Facility. Veranstaltungsvortrag im Rahmen der Projektgruppe ComponentTools

MDA-Praktikum, Einführung

Model-Driven Software Engineering (HS 2011)

openarchitectureware

Grundlagen von MOF. Alexander Gepting 1

Model Driven Architecture (MDA)

Eclipse Modeling Framework Modellgetriebene Softwareentwicklung Prof. Andreas Schmidt

Eclipse Modeling Framework

Michael Piechotta - CASE Tools. openarchitecture Ware

Validation und Quick Fixing mit Xtend. 3. Dezember 2014

Modellgetriebene Softwareentwicklung

Model Driven Architecture

Einführung in das Eclipse Modeling Framework (EMF)

Einführung in das Eclipse Modeling Framework (EMF)

Thema 3 Das UML- Metamodell

Einführung in die Modelltransformation mit Xtend

Poseidon for UML. Einführung. Andreas Blunk

UML (Unified Modelling Language) von Christian Bartl

Vortrag von: Ilias Agorakis & Robert Roginer

Software Engineering II

i n g e n i e u r b ü r o f ü r s o f t w a r e t e c h n o l o g i e w w w. v o e l t e r. d e Metamodellbasierte Codegenerierung in Java

Motivation Grundlagen Technologien Manipulation Ecore Genmodell Demo Persistenz Notification Ausblick GMF Fazit / Quellen

Modellgetriebene Entwicklung eingebetteter Systeme mit Eclipse

Modellgetriebene Entwicklungsprozesse in der Praxis - eine Bestandsaufnahme. Tillmann Schall, anaptecs GmbH

Model Querys zur Überprüfung von sicherheitsrelevanten Eigenschaften

Was ist EMF? Wie wird EMF eingesetzt? Was ist ecore? Das Generatormodell Fazit

Model Driven Architecture Praxisbeispiel

Modellgetriebene Softwareentwicklung: Zusammenfassung und Ausblick. 7. Februar 2013

Codegenerierung mit Xtend. 21. Januar 2015

Generischer Modellvergleich mit EMF Compare

COPE COuPled Evolution of metamodels and models

1 Klassen und Objekte

Einführung in das Eclipse Modeling Framework (EMF)

Best Practices für flexible und wartbare Codegeneratoren mit openarchitectureware Karsten Thoms Software Architekt

Software Engineering II

Innovator Anbindung an openarchitectureware. Connect. Klaus Weber.

Modellgetriebene Softwareentwicklung bei der IBYKUS AG

Ein Erfahrungsbericht beim Einsatz von generierenden Ansätzen im Vergleich zu generischen Lösungen

UML Modellierung und Model Driven Architecture (MDA) für Java mittels Rational Software Architect (RSA)

Algorithmen und Datenstrukturen 06

Metamodellierung mit MOF und Ecore

Ein Ansatz zum modellgetriebenen Integrationstest von EJB-basierten Informationssystemen

Beispielhaft MDSD in der Praxis. Dr. Shota Okujava

Unified Modeling Language 2

Definition von domänenspezifischen Sprachen mit Xtext: Einführung

Werkzeugunabhängigkeit bei der Modellierung Schwierigkeiten und mögliche Lösungsansätze

Modellgetriebene Softwareentwicklung: Zusammenfassung und Ausblick. 11. Februar 2015

Common Warehouse Metamodel und Imperfektion

Thema 5 Domain Specific Languages

Integration von openarchitectureware in Innovator am Beispiel eines WSDL/XSD Generators für SOA- Plattformen. Nürnberg,

Automatisierte Architekturanalyse mittels UML2.0 Diagrammen

Integration von Model-Driven Development und formaler Verfikation in den Softwareentwicklungsprozess

Modellgetriebene Softwareentwicklung. Gabriele Taentzer WS 2012/2013 Philipps-Universität Marburg

Software Factories SS Prof. Dr. Dirk Müller. 3 Modellgetriebene Softwareentwicklung

Graphischer Editor für die technologieunabhängige User Interface Modellierung

Handbuch für die Erweiterbarkeit

Repetitorium Informatik (Java)

Modellgetriebene Entwicklung einer Eclipse RAP-Anwendung unter Verwendung des Eclipse Modeling Frameworks

Herausforderung: Entwicklungsmethodik und technisches Umfeld

Systemmodellierung mit SysML - Stereotypen und Profile

Einführung in das Eclipse Modeling Framework. 5. November 2014

Einstieg in die Informatik mit Java

Software Engineering II

FH D. Objektorientierte Programmierung in Java FH D FH D. Prof. Dr. Ing. André Stuhlsatz. Wiederholung: Gerüstbeispiel. Vererbungshierarchie: Typ 0

Model Driven Architecture

Model Driven Architecture

Implementieren von Klassen

Sommersemester Implementierung I: Struktur

Software- und Systementwicklung

SEA. Modellgetriebene Softwareentwicklung in der BA

Vorlesung Programmieren

Software Factories SS Prof. Dr. Dirk Müller. 6 Eclipse Modeling Framework

Potentiale modellgetriebener Softwareentwicklung

Javakurs FSS Lehrstuhl Stuckenschmidt. Tag 3 - Objektorientierung

Vgl. Oestereich Kap 2.4 Seiten

Universität Stuttgart Institut für Automatisierungstechnik und Softwaresysteme Prof. Dr.-Ing. M. Weyrich

Übersicht Eclipse Modeling Project EMP. Zoltan Horvath

Einführung in Javadoc

Programmieren in Java

Modellgetriebene Softwareentwicklung (Model Driven Software Development - MDSD) SS 2014

Innovator 11 classix. Erweiterter XMI-Export aus Innovator Business und Object classix. HowTo.

Model-Driven Development in der Praxis. mit objectif. Herzlich willkommen

Konzeption und Realisierung eines logikbasierten Anfragewerkzeugs für UML-Modelle

Einfach generieren. Susanne Klar, Michael Klar. Generative Programmierung verständlich und praxisnah ISBN Inhaltsverzeichnis

Tag 7 Repetitorium Informatik (Java)

Faktor-IPS. Modellgetriebene Softwareentwicklung mit Faktor-IPS. Faktor Zehn AG. Seite 1

GERICHTETER GEWICHTETER GRAPH DESIGNDOKUMENT

Einführung in modellgetriebene Softwareentwicklung. 24. Oktober 2012

Codegeneratoren mit Xtend , A. Arnold

MDSD in der Praxis. Dr. Shota Okujava.

Objektorientierung. Klassen und Objekte. Dr. Beatrice Amrhein

Von der Prozessanalyse zur Prozessautomatisierung

Neben der Verwendung von Klassen ist Vererbung ein wichtiges Merkmal objektorientierter

Objektorientierte Modellierung (1)

Klausur. Softwareentwurf. 14. Februar 2011 Bearbeitungszeit: 120 Minuten

Datenhaltung für Android Model First Christian Ingenhaag, Frederik Götz, Carl Steeg

Transkript:

Westfälische Wilhelms-Universität Münster Ausarbeitung openarchitectureware im Rahmen des Hauptseminars Software Engineering Jan Schürmeier Themensteller: Prof. Dr. Herbert Kuchen Betreuer: Dipl.-Wirt.Inform. Christian Hermanns Institut für Wirtschaftsinformatik Praktische Informatik in der Wirtschaft

Inhaltsverzeichnis 1. Einleitung... 3 2. Grundlagen der modellgetriebenen Softwareentwicklung... 4 2.1 Motivation und Ziele... 4 2.2 Standard der Object Management Group... 5 2.3 Modelle und Modelltransformation... 8 2.4 Model Driven Software Development versus Model Driven Architecture... 10 3. Das openarchitecture Generator Framework... 11 3.1 Allgemeine Funktionsweise... 11 3.2 Die Komponenten von openarchitectureware... 12 3.2.1 Workflow... 12 3.2.2 Xpand... 13 3.2.3 Xtend... 14 3.2.4 Check... 16 3.2.5 Weitere Komponenten... 16 4. Anwendungsbeispiel... 18 4.1 Vorbereitung... 18 4.2 Definition von Workflow, Templates und Extensions... 19 4.3 Berücksichtigung von Assoziationen... 20 4.4 Überprüfungen... 21 4.5 Evaluation... 22 5. Zusammenfassung... 24 A Eclipse Ordnerstruktur des Anwendungsbeispiels... 25 B Definition der Metaklassen... 26 C Der Workflow... 27 D Die Templates... 28 E Extensions... 30 F Check... 32 G Generierter Quellcode... 33 Literaturverzeichnis... 37 II

Kapitel 1: Einleitung 1. Einleitung Nach der Entwicklung von der Maschinensprache zur Assembler-Sprache, zu den prozeduralen Sprachen und von diesen schließlich zu den objektorientierten Sprachen, scheint die modellgetriebene Softwareentwicklung bzw. Programmierung auf Modellebene (mittels Modellierungssprachen) der logisch nächste Schritt in der Evolution der Softwareentwicklung zu sein. Der Grundgedanke des modellgetriebenen Vorgehens besteht darin, den Modellen im Prozess der Softwareentwicklung eine stärkere Bedeutung zukommen zu lassen, so dass eine Anwendung in einem Modell abgebildet und die Implementierung mittels Generatoren daraus automatisch erzeugt werden kann. Mittlerweile existieren diverse Tools, die diese Generatoren bereitstellen. OpenArchitectureWare ist ein Framework, das modellgetriebene Entwicklung unterstützen und ermöglichen soll. Der Ursprung des Projektes ist eine kommerzielle Entwicklung der b+m Informatik AG, damals mit dem Namen b+m Generator Framework. Später wurde es unter dem Namen openarchitectureware als Open-Source Projekt angemeldet. Seitdem nehmen sowohl Entwickler von b+m als auch aus dem Open-Source Bereich an der Weiterentwicklung teil. Ziel dieser Arbeit ist es, eine Einführung in die Funktionsweise von openarchitectureware zu geben und seine Unterstützungsmöglichkeiten in Bezug auf die modellgetriebene Softwareentwicklung herauszustellen. Der folgende Abschnitt ist zunächst den Grundlagen der modellgetriebenen Softwareentwicklung gewidmet. Er soll einen Einblick in die Konzepte und damit einhergehenden Begriffe vermitteln, auf denen das Framework aufgebaut ist. Anschließend, im dritten Abschnitt, wird die Architektur von openarchitectureware vorgestellt, d.h. seine Komponenten und deren Interaktion erläutert. Darauf aufbauend, soll der dritte Abschnitt die Funktionsweise in der Praxis anhand eines kurzen Anwendungsbeispiels veranschaulichen. Der letzte Teil beendet die Arbeit mit einer zusammenfassenden und evaluierenden Betrachtung von openarchitectureware. 3

Kapitel 2: Grundlagen der modellgetriebenen Softwareentwicklung 2. Grundlagen der modellgetriebenen Softwareentwicklung 2.1 Motivation und Ziele Im Kontext der modellgetriebenen Softwareentwicklung ist inzwischen eine Vielzahl von Wortmarken vorhanden. Die geläufigsten sind die englische Übersetzung Model Driven Software Development (MDSD) und die Model Driven Architecture (MDA). Dabei stellt die MDA eine Spezifikation zur modellgetriebenen Entwicklung zur Verfügung, wohingegen das MDSD auf die Bereitstellung von praktisch einsetzbaren Methoden abzielt [SV05, S.5]. Eine genauere Abgrenzung der beiden Begriffe wird in Abschnitt 2.4 vorgenommen. Modelle stellen bei der modellgetriebenen Softwareentwicklung die zentralen Elemente dar. Sie dienen nicht nur der Dokumentation, sondern sind Bestandteil der Software [SV05, S.16]. Im Gegensatz zur Code-zentrierten Softwareentwicklung, bei der es beim Übergang vom Modell zum Code einen Bruch gibt, möchte die modellgetriebene Softwareentwicklung den Prozess vom Modell zur fertigen Anwendung, d.h. Quellcode, automatisieren. Treten neue oder veränderte Anforderungen auf, werden diese im Modell vorgenommen und der Quellcode neu generiert. Die Überführung vom Modell zum Code muss nur einmalig erarbeitet werden und kann immer wieder verwendet werden. Dadurch lassen sich folgende Anwendungen schneller und effizienter entwickeln. Neben einem konsistenten Modell im Lebenszyklus der Anwendung fordert die modellgetriebene Softwareentwicklung eine stärkere Trennung von fachlichen Anforderungen und technischen Details. Es soll erreicht werden, dass man sich bei der Definition der Anwendung auf das Wesentliche die fachlichen Anforderungen konzentrieren kann. Ein weiterer Effekt dieser Trennung ist eine bessere Wiederverwendbarkeit sowohl von den fachlichen Anforderungen als auch den technischen Details [PM06, S.33f.]. Zum einen kann eine Anwendung ohne Änderung der fachlichen Anforderungen auf eine neue technologische Basis portiert und zum anderen kann die Definition der technischen Details mehrfach genutzt werden. Ein weiterer Aspekt ist die Verbesserung der Softwarequalität, da durch den konsequenten Einsatz von Referenzarchitekturen und bewährten Mustern (Patterns) eine höhere Stabilität der Software erreicht wird [GPR06, S.22]. Des Weiteren ist bei einem modellgetriebenen Projekt eine Migration auf eine andere Plattform wesentlich leichter durchzuführen als bei einem konventionellen Projekt. 4

Kapitel 2: Grundlagen der modellgetriebenen Softwareentwicklung 2.2 Standard der Object Management Group Die Object Management Group (OMG) [Obja] ist eine internationale Vereinigung der Computerindustrie, die es sich zur Aufgabe gemacht hat, Standards im Bereich der Softwareentwicklung zu schaffen [PM06. S.35f.]. Dazu gehören u.a. MDA, Unified Modeling Language (UML) oder Common Object Request Broker (CORBA). Ziel der OMG ist es, interoperable und integrierbare Anwendungen zu schaffen. Der MDA Standard existiert seit Mitte 2000 und baut auf existierenden Spezifikationen auf. In Abbildung 2.2 ist dies dargestellt. Quelle: [Objb] Abb 2.21: Model Driven Architecture der Object Management Group Den Kern bilden die Meta Object Facility (MOF), die UML und das Common Warehouse Metamodel (CWM). Diese Modellierungsstandards sind plattformunabhängig, d.h., sie sind nicht von einer Technologie oder einem Hersteller abhängig. Den Kern umschließt ein Ring mit den möglichen Zielplattformen gefolgt von einem Ring mit den Pervasive Services. Damit sind weitere Aspekte einer Anwendung gemeint, wie beispielsweise Sicherheit oder Verzeichnisdienste. Diese Dienste sind in allen Umgebungen verfügbar, was durch die Darstellung des Ringes um die Plattformen herum verdeutlicht wird. 5

Kapitel 2: Grundlagen der modellgetriebenen Softwareentwicklung Wie beschrieben sind UML, MOF und CWM die zentralen Bestandteile der MDA. Bei der UML handelt es sich um eine visuelle Sprache zur Spezifizierung, Konstruktion und Dokumentation eines Systems [Objc]. Sie ist kein einzelnes Dokument, sondern eine Sammlung von unterschiedlichen Spezifikationen mit denen Softwaresysteme als Modelle beschrieben werden können. Das Wissen über die letztendliche Implementierung der gewählten Technologie ist hierbei nicht notwendig. Es wird lediglich Auskunft über den Zusammenhang der Softwarekomponenten untereinander (bspw. Klassendiagramme), die Möglichkeiten der Software für Interaktionen mit Benutzern (z.b. Use-Case-Diagramm) oder die Abläufe des Gesamtsystems (z.b. Aktivitätsdiagramm) gegeben. Zur Beschreibung von Softwaresystemen mittels UML ist eine gewisse Grammatik vorgegeben. Diese Grammatik ist in der Modellwelt ein Metamodell, im Fall der UML also ein UML-Metamodell. Ein Metamodell beschreibt die mögliche Struktur von Modellen es definiert damit in abstrakter Weise die Konstrukte einer Modellierungssprache, ihre Beziehungen untereinander sowie Gültigkeits- bzw. Modellierungsregeln. UML-Metamodelle können mittels UML- Profilen erweitert werden. Es besteht hierbei eine extends-beziehung des UML- Profils zu dem UML-Metamodell, vergleichbar mit einer extends-beziehung in Java. Zu einem UML-Profil gehören Eigenschaftswerte (tagged values), Einschränkungen (constraints) und Stereotype. Ein Stereotyp spezifiziert, wie eine bereits durch das UML-Metamodell vorgegebene Metaklasse für ein spezifisches Einsatzgebiet angepasst werden kann (z.b. Erweiterung der Metaklasse Class durch den Stereotyp OrganisationsEinheit). Ein Stereotyp kann Properties haben (z.b. kostenstelle:string, leiter:string), diese werden dann im Modell, in dem der Stereotyp verwendet wird, als Tagged Values dargestellt (z.b. leiter = Hans Meier, kostenstelle = AB1234). Constraints sind Begrenzungen bzw. Einschränkungen und sorgen für die Integrität eines UML-Modells (z.b. Einschränkung eines Attributs auf einen bestimmten Wertebereich). Sie werden in der Object Constraint Language (OCL) beschrieben. Die OMG definiert die MOF als ihr Metametamodell und die UML als standardisiertes Metamodell dazu [SV05, S. 64]. Die MOF ist also somit ein Metametamodell, das sich selbst beschreibt, und die UML ist eine Instanz der MOF. Konkrete UML-Modelle sind dann Instanzen des UML-Metamodells. Abbildung 2.22 verdeutlicht dieses Konzept. 6

Kapitel 2: Grundlagen der modellgetriebenen Softwareentwicklung Abb. 2.22: Metaschichten der OMG inkl. eines UML-Beispiels Die MOF beschreibt einzelne Modellkomponenten wie z.b. ModelElement und deren Eigenschaften. Auf die Darstellung wird hierbei nicht eingegangen. Assoziationen in UML-Metamodellen sieht die MOF beispielsweise als eine Komponente an. So kommt es auch, dass ein Attribut, das in der UML sicher nicht als Klasse bezeichnet werden kann, von der MOF aus gesehen eine Metaklasse darstellt. Des Weiteren wird die MOF in zwei Konformitätslevel unterteilt: Die Essential MOF (EMOF) stellt eine Teilmenge der MOF dar und enthält alle elementaren Konzepte der MOF, wohingegen die Complete MOF (CMOF) weiter reichende Funktionalität anbietet. Zum Austausch von Modellen wird der XML Metadata Interchange (XMI) Standard genutzt, welcher ein XML-Mapping für die MOF darstellt. Mittlerweile können auch Layoutinformationen von Diagrammen gespeichert werden. Somit ist auch die Anordnung von Elementen in einem Diagramm zwischen verschiedenen Werkzeugen austauschbar. 7

Kapitel 2: Grundlagen der modellgetriebenen Softwareentwicklung 2.3 Modelle und Modelltransformation Die OMG benutzt verschiedene Modellarten für die Beschreibung von Softwaresystemen. Der Standard definiert folgende: Computation Independent Model (CIM), Platform Independent Model (PIM), Platform Model (PM) und das Platform Specific Model (PSM). Das CIM beschreibt ein Gesamtsystem und dessen interagierende Umgebung [GPR06, S. 122]. Es soll möglichst alle Aspekte im Kontext einer Domäne darstellen, beispielsweise auch die Aspekte, die nicht softwaregestützt ablaufen. Deshalb wird das CIM auch als Domänenmodell (Domain Model) oder Geschäftsmodell (Business Model) bezeichnet und dient dem Zweck, eine gemeinsame Fachsprache zu schaffen [PM06, S. 100]. Das PIM beschreibt die Logik eines Systems oder Teilsystems des CIM und kann manuell aus diesem erstellt werden. Es besitzt Wissen über den Ablauf und die Funktionalitäten oder auch die Interaktionen die im System vorhanden sind. Im Vergleich zum CIM stellt es Aspekte konkreter dar und unterliegt formalen Regeln, da es automatisch in ein PSM transformierbar sein soll. Dennoch ist es plattformunabhängig. Das PM dient zur formalen Beschreibung der Zielplattform und zusammen mit dem PIM kann daraus das PSM transformiert werden. Obwohl der MDA Standard keine Vorgaben macht, mit welcher Sprache PMs modelliert werden sollen, bietet sich auch hier die UML an [PM06, S. 103ff.]. So können eigene Metamodelle, oder (UML-) Profile erstellt werden um die Zielplattform zu beschreiben. Das PSM stellt schließlich die fachlichen Aspekte aus dem PIM und zusätzliche plattformabhängige Aspekte dar. Diese plattformabhängigen Gesichtspunkte werden bei der Transformation eingewebt. Das PSM kann Modell, aber auch Quellcode sein. In diesem Fall wäre es ein sehr spezifisches PSM [GPR06, S. 121, 141]. Die Modelltransformation beinhaltet die Umsetzung der abstrakten Modelle hin zu den spezifischen. Dabei wird zunächst das PIM unter Zuhilfenahme des PM in ein PSM transformiert (Schicht M2 zu M1 in Abb. 2.22). Anschließend kann aus dem PSM der Quellcode generiert werden (Schicht M1 zu M0 in Abb. 2.22). An Transformationen werden verschiedene Anforderungen gestellt [K03. S74ff]. So sollte die Möglichkeit bestehen, Transformationen zu steuern und anzupassen (Tunability). Dazu können 8

Kapitel 2: Grundlagen der modellgetriebenen Softwareentwicklung Transformationsregeln manuell zugeordnet oder mit bestimmten Bedingungen verknüpft werden. Zusätzlich kann eine Transformation mittels Parameter angepasst werden. Diese können vor Ausführung bearbeitet werden, wodurch das Erscheinungsbild des Zielmodells beeinflussbar bleibt. Weiterhin sollen Transformationen zurückzuverfolgen sein (Traceablilty). Das bedeutet, von einem Element im Zielmodell soll das entsprechende Element im Quellmodell identifizierbar sein. Dies hat z.b. den Zweck, dass eine Namensänderung im PSM sich auch auf das PIM auswirkt. Andererseits trägt die Rückverfolgbarkeit dazu bei, vorhandene Fehler im Quellcode im Modell zu lokalisieren und zu beheben. Somit bedeutet Traceability nicht gleich Round-Trip-Engineering. Dies hingegen wird von der Bidirectionality angestrebt. Damit ist gemeint, dass Transformationen in beide Richtungen, also von Quell- in Zielmodell und zurück, möglich sind [K03, S.78]. Die Realisierung ist jedoch meist schwierig, sodass das Quellmodell zumeist eine abstraktere Sicht als das Zielmodell darstellt. Zudem kann das Zielmodell zusätzliche Informationen oder sogar wenigere als das ursprüngliche Quellmodell enthalten, da diese nicht relevant sind. Zur Umsetzung der Transformation existieren zwei Ansätze. Der metamodellorientierte Ansatz basiert auf zwei Metamodellen, jeweils eines für Quell- und Zielmodell. Dagegen verwendet der ausgabeorientierte Ansatz nur ein (Quell-) Metamodell und generiert den Quelltext direkt [SV05, S.23]. Für diesen Ansatz werden im Allgemeinen Templates (dt. Schablonen) definiert, die das Gerüst der Ausgabe enthalten. So ist es auch nicht notwendig, dass der Generator das Metamodell der Programmiersprache kennt. Aus diesem Grund wird der letztgenannte Ansatz hauptsächlich bei der Modellzu-Code Transformation angewandt, während der metamodellorientierte Transformationsansatz bei der Modell-zu-Modell Transformation genutzt wird. 9

Kapitel 2: Grundlagen der modellgetriebenen Softwareentwicklung 2.4 Model Driven Software Development versus Model Driven Architecture Wie zu Beginn dieses Kapitels schon erwähnt, muss zwischen den Begriffen MDSD und MDA differenziert werden. Beide bezeichnen prinzipiell ähnliche Konzepte, unterscheiden sich aber in verschiedenen Details zum Teil auch in der Motivation. So nimmt die MDA tendenziell Einschränkungen vor, wie z.b. die Fokussierung auf UMLbasierten Modellierungssprachen. Das Ziel von MDA ist in erster Linie, Interoperabilität zwischen Werkzeugen zu gewährleisten und auf längere Sicht die Standardisierung von Modellen für populäre Anwendungsbereiche. MDSD hingegen zielt auf die Bereitstellung von praktisch einsetzbaren Bausteinen für Softwareentwicklungsprozesse ab, welche heute im Zusammenhang mit modellgetriebenen Allgemeinen einsetzbar sind, und zwar unabhängig von der Werkzeugwahl oder dem Reifegerad der OMG-MDA-Standards [SV05, S.5]. Generell lässt sich sagen dass die MDA eine Standardisierungsinitiative der OMG zum Thema MDSD ist und eine konzeptionelle Spezialisierung vornimmt. 10

Kapitel 3: Das openarchitecture Generator Framework 3. Das openarchitecture Generator Framework 3.1 Allgemeine Funktionsweise OpenArchitectureWare ist Teil der Eclipse Foundation und gehört dem Generative Modeling Technologies (GMT) Projekt an. Das Framework verwendet existierende Eclipse Projekte wieder und integriert sich nahtlos in die Eclipse Entwicklungsumgebung. OAW definiert sich selbst als tool for building MDSD/MDA tools [Vö07, S. 1] und unterstützt Modellprüfungen, Transformationen und die Generierung von Code. Dabei findet die abstrakte Aufteilung der Modelle (s. Abschnitt 2.3) nur ansatzweise statt. Die verschiedenen Ebenen kommen also nicht nach dem Wasserfallprinzip zum Tragen, sondern werden vermischt. OAW bietet die Möglichkeit eine Vielzahl von Modellen zu verarbeiten. Dazu gehören EMF, XMI Dialekte der verschiedenen UML-Werkzeuge (z.b. MagicDraw oder Poseidon), das Eclipse UML2 XMI Format und XML. Für jedes Format ist ein Adapter vorhanden, der das Modell auf interne Modellinstanzen abbildet. Somit ist das Framework für andere Formate leicht erweiterbar, da lediglich ein entsprechender Adapter erstellt werden muss. Intern benutzt oaw das Ecore Metamodell des Eclipse Modeling Frameworks (EMF), um das Modell zu instanziieren. Dieses Metamodell ist bis auf einige Benennungen nahezu identisch mit EMOF. EMF ist ein Open-Source Framework zur Generierung von Quellcode aus Modellen heraus speziell für Java. Dabei erleichtert EMF die Entwicklerarbeit durch die Implementierung in die Eclipse-Entwicklungsumgebung. Im klassischen Fall sieht der Ablauf des Generatorprozesses so aus, dass zunächst ein UML-Modell entworfen (beispielsweise mit einem externen UML-Tool wie MagicDraw), mit speziellen Stereotypen, Tagged Values und Constraints belegt und als XMI-Datei abgespeichert wird. Anschließend kann das Modell innerhalb von Eclipse mittels eines XMI-Instantiators von oaw eingelesen werden. Dies geschieht auf Basis einer Workflow-Datei und deren Konfigurationen. Aus diesen geht ebenfalls hervor, welcher spezielle Tool-Adapter für das in der XMI-Datei befindliche Modell zuständig ist, um das Modell daraufhin in den Arbeitsspeicher zu laden. An dieser Stelle wird das Modell zunächst geparsed und auf Basis der vergebenen Stereotype festgestellt, welche Metaklassen (eigene und/oder Standardmetaklassen) angewandt werden sollen. Wurden keine speziellen Stereotype festgelegt, werden die Standardstereotype wie bspw. class für Klassen, interface für Interfaces etc. der Komponenten verwendet. 11

Kapitel 3: Das openarchitecture Generator Framework Somit weiß das Framework nun, welche Metaklassen (und somit welche Methoden dieser Metaklassen) auf das Modell mittels der Template-Engine angewendet werden können. Die Template-Engine ruft daraufhin das Standardstarttemplate auf, wendet dieses auf das Modell an und erzeugt die entsprechenden Quellcodedateien. Dabei kann das Starttemplate auf weitere Templates verweisen, auf die in den folgenden Abschnitten weiter eingegangen wird. 3.2 Die Komponenten von openarchitectureware Wie EMF ist auch oaw in Java programmiert und verwendet eine eigene statisch getypte Expression Language (EL), die zur Beschreibung von Prüfungen, Transformationen etc. genutzt wird. Sie ist ähnlich zur OCL und damit leicht zur erlernen. Sollten die Funktionalitäten der EL nicht ausreichen besteht die Möglichkeit zusätzlich Java Methoden zu implementieren, die aus der EL Verwendung finden können. Somit ist die gesamte Funktionalität des Java Frameworks nutzbar. OAW besteht im Kern aus den Komponenten Workflow, Xpand, Xtend, und Check. Darüber hinaus existieren Weitere, wie Xtext oder Recipe. Für die Module Xpand, Xtend und Check existieren eigene Eclipse Editoren, die Syntaxhervorhebung, Codevervollständigung und statische Fehlerprüfung bereitstellen. Im Gegensatz dazu verwendet der Workflow eine eigene XML-Syntax, die der von Ant [Apa] ähnelt. Die Komponenten werden im Folgenden detaillierter betrachtet. 3.2.1 Workflow Die Workflow Komponente verbindet die vorhandenen Komponenten zu einem Generator und kann damit als Herzstück von oaw angesehen werden. Besser gesagt steuert der Workflow, welche Komponenten wann und wie aufgerufen werden. Dazu werden alle benötigten Informationen in der Datei workflow.oaw gespeichert, die über die Datei workflow.properties mit Metadaten versorgt wird. Innerhalb des Workflows existieren sogenannte components, die über das Attribut class eine entsprechende Komponentenklasse erhalten, wobei weitere Eigenschaften für eine Komponente übergeben werden können. Im Beispiel (s.u.) wird als erstes eine Komponente definiert, die festlegt, welche Datei der XMI-Instantiator einlesen soll. 12

Kapitel 3: Das openarchitecture Generator Framework <workflow> <!--- read model --> <component class="oaw.emf.xmireader"> <modelfile value ="${uml2modelfile" /> <outputslot value="model" /> </component> <!--- generate code --> <component id="generator" class="oaw.xpand2.generator" skiponerrors="true"> <expand value="templates::root::root FOR model" /> </component> </workflow> Dazu verfügt die Komponente (oaw.emf.xmireader) über die Eigenschaft modelfile, über die der Pfad zur Modelldatei angegeben wird. Das Attribut outputslot dient zur Angabe eines Namens, unter dem die gelesene Modellinstanz im Workflow wiederverwendet werden kann. Als Slot wird der Speicherort des Modells in oaw bezeichnet. Beispielsweise nutzt die zweite Komponente (oaw.xpand.generator) das eingelesene Modell als Eingabe. Um das Beispiel übersichtlich zu halten, ist nur eine expand Anweisung dargstellt, die zur Folge hat, dass der Generator die Definition Root im Template template/root.xpt für die zuvor eingelesene Modellinstanz aufruft. Daneben können weitere Eigenschaften festgelegt werden. Es gibt weitere Komponenten für die Modellprüfung, Transformation, Modellausgabe etc. Darüber hinaus besteht die Möglichkeit, eigene Komponenten zu realisieren, indem von der abstrakten Klasse org.openarchitectureware.workflow.lib.abstractworkflowcompo nent geerbt wird. In Folge dessen kann der Workflow nach eigenen Bedürfnissen angepasst und erweitert werden. 3.2.2 Xpand Die verwendete Template-Engine in oaw ist die eigens für dieses Framework entwickelte Xpand Engine. Diese Komponente dient der Generierung von Ausgaben auf Basis von Vorlagen (Templates). Die Templates werden in einer Datei mit der Endung.xpt gespeichert. Innerhalb eines Templates werden Blöcke (Definitions) definiert, die für bestimmte Typen gelten. Dabei werden Kontrollstrukturen mit französischen Anführungszeichen (Guillemets: «und») gekennzeichnet. 13

Kapitel 3: Das openarchitecture Generator Framework «EXTENSION Xtend» «DEFINE javaclass FOR uml::class» «FILE filename()» package «javapackage()»; public class «name» { «FOREACH attribute AS a» «a.type.fqn()» «a.name» «ENDFOREACH» «ENDFILE» «ENDDEFINE» Das Beispiel zeigt die Definition eines Blocks. Die Definition javaclass gilt für Instanzen vom Typ uml::class. Für jede wird eine Ausgabedatei («FILE filename()») erzeugt, in die die Ausgaben innerhalb des «FILE»-Blocks geschrieben werden. Im Beispiel entspricht dessen Inhalt der Java-Syntax sodass zunächst das Package der Klasse, die Klassendefinition sowie für jedes Attribut ein Feld in die Datei geschrieben wird. Obwohl Xpand auf den ersten Blick ein einfaches Vorlagensystem zur Erzeugung von Code zu sein scheint, sind trotzdem Fähigkeiten wie Polymorphismus und Template- Aspekte vorhanden, die dazu führen, dass nicht-triviale Codegeneratoren entwickelt werden können. Besonders die Möglichkeit Xpand-Definitionen mit Template- Aspekten zu erweitern bzw. zu verändern, trägt dazu bei. In Kombination mit der Xtend-Komponente unterstützt Xpand den ausgabeorientierten Transformationsansatz, wobei mittels Xpand entsprechende Templates beschrieben werden und die Xtend- Dateien Transformationslogik beinhalten. 3.2.3 Xtend Die Komponente Xtend wird hauptsächlich zur Beschreibung von Transformationen und zur Metamodellierung genutzt. Dazu können sogenannte Extensions definiert werden, die einen bestimmten Zweck erfüllen. Die Syntax einer Extension könnte beispielsweise folgendermaßen aussehen: private cached ReturnType extensionname(paramtype1 paramname1,...) : expression-using-params; 14

Kapitel 3: Das openarchitecture Generator Framework Der Extension Ausdruck ähnelt einer Methodendefiniton in Java. Nach den optionalen Schlüsselwörtern private und cached folgt der Rückgabetyp, die Definition des Extension Namens und die Angabe von beliebig vielen Parametern. Daraufhin schließt der Extension-Rumpf mit Verarbeitungsanweisungen an. Extensions können von Workflow-, Xpand-, Check-Komponenten und sogar aus Java Code heraus aufgerufen werden. Da Extensions oft nur Hilfsdienste anbieten, die für andere Komponenten nicht von Bedeutung sind, können sie mittels des Schlüsselworts private unsichtbar gemacht werden. Zur Steigerung der Performanz kann zusätzlich cached eingesetzt werden, falls eine Extension für eine Parameterkombination nur einmalig ausgeführt wird und um das Ergebnis zwischen zu speichern. Das untere Beispiel zeigt gleich zwei Extensions, bei denen die erste (uppername) den Namen eines benannten UML- Elementes in Großbuchstaben zurückliefert und die zweite (hasname) ermittelt, ob das Element überhaupt einen Wert für das Attribut name besitzt. String uppername(uml::namedelement ne): me.name.touppercase(); private boolean hasname(uml::namedelement ne): ne.name!= null; Zusätzlich sind Java-Methoden aus Xtend heraus aufrufbar. Das folgende Beispiel zeigt eine Extension (complexoperation),die die statische Methode complexmethod der Helper Klasse aufruft. Xtend: uml::classifier complexoperation(uml::classifier c) : JAVA example.pack.helper.complexmethod(org.eclipse.uml2.uml.classifier) ; Java: package example.pack; import org.eclipse.uml2.uml.classifier; public class Helper { public static Classifier complexmethod(classifier c) { ///... return null; Daneben kann Extend bezüglich der MDA-Standards Teile der Anforderungen an eine Sprache zur Modell-zu-Modell Transformation erfüllen. Allerdings ist lediglich die Überführung eines Modells von einem auf ein anderes Metamodell möglich. Weitere 15

Kapitel 3: Das openarchitecture Generator Framework Aspekte einer Transformation, wie Traceability oder Bidirectionality können nicht erfüllt werden. 3.2.4 Check Diese Komponente kommt im Rahmen der Modellvalidierung zum Einsatz. Mit ihr können Modellprüfungen definiert werden, welche anschließend durch Aufruf im Workflow auf Modelle angewendet werden können, um die Korrektheit zu überprüfen. Eine solche Zusicherung besitzt dabei folgende Syntax: context TypeName [if guard-predicate] (ERROR WARNING) msg-expression: predicate; Mittels des Schlüsselworts context wird der Elementtyp angegeben, auf den die Zusicherung angewendet werden soll. Anschließend kann optional eine Bedingung formuliert werden, um nur bestimmte Instanzen des Elementtyps zu prüfen. Danach erfolgt die Definition des Fehlertyps (ERROR oder WARNING) und der auszugebenden Fehlermeldung. Zum Schluss folgt ein Ausdruck, dessen Auswertung einen Booleschen Wert zurückliefert. Im unteren Beispiel wird eine Zusicherung für das Konstrukt JavaClass, die sicherstellt, dass für jede Instanz des JavaClass Elements maximal eine Superklasse existiert. context JavaClass ERROR 'A javaclass must not have more than one superclass.': superclass.size <=1; Im Hinblick auf den von der OMG erarbeiteten MDA-Standard nimmt die Check- Komponente damit die Rolle von OCL, zur Modellvalidierung und zur Anreicherung mit zusätzlicher Semantik ein. 3.2.5 Weitere Komponenten Mit den Komponenten Recipe und Xtext existieren neben den Kernkomponenten zwei weitere Module, die zusätzliche Funktionalitäten liefern. So bietet das Recipe Framework Unterstützung im Entwicklungsprozess einer MDA-Anwendung. Da es bis heute noch nicht möglich ist, 100% des Quellcodes einer Anwendung automatisch 16

Kapitel 3: Das openarchitecture Generator Framework generieren zu lassen, wird häufig auf das Prinzip der abstrakten Klassen zurückgegriffen. Dazu werden beispielsweise abstrakte Klassen erstellt, die der Entwickler später manuell implementieren muss. Die Recipe Komponente ist in diesem Kontext insofern hilfreich als dass sich mit ihr geeignete Prüfungen formulieren lassen, die sicherstellen, dass es von jeder abstrakten Klasse eine Implementierung gibt. Die Prüfungen können über eine spezielle Eclipse View eingesehen werden, sodass der Entwickler weiß, welche Klassen bereits implementiert wurden und welche nicht, wodurch sich Fehler zur Laufzeit der Anwendung vermeiden lassen. Mit Xtext stellt oaw eine weitere optionale Komponente zur Verfügung, mit deren Hilfe sich sehr schnell mittels eines eigenen Eclipse-Editos eigene Metamodell konstruieren lassen. Die verwendete Grammatik ähnelt dabei der Syntax der Backus- Normalform. Ziel ist es, die Entwicklung und Wartung von Metamodellen zu beschleunigen, da die Verwendung von Standard UML-Werkzeugen zu einem unnötigen Zeitaufwand führen kann. Speziell was das Öffnen großer Modelldateien und den Export in das XMI-Format angeht, kann mittels der textbasierten Metamodelldefinitionen in Xtext zügiger gehandhabt werden. 17

Kapitel 4: Anwendungsbeispiel 4. Anwendungsbeispiel 4.1 Vorbereitung In diesem Abschnitt soll die Funktionsweise von oaw anhand eines kurzen Anwendungsbeispiels verdeutlicht werden. Das folgende Beispiel soll dabei auch die Integration eines externen UML-Werkzeugs in oaw zeigen. Es lässt sich dem sogenannten klassischen Stil [E08, S.157] zuordnen da das klassische UML- Metamodell als zugrundeliegendes Metamodell herangezogen wird. Abb 4.1: Beispielmodell Abbildung 4.1 zeigt das UML-Modell des Anwendungsbeispiels als Klassendiagramm. Für die Modellierung wurde das von oaw unterstützte UML-Tool MagicDraw UML 11.0 verwendet. Es wurde ein einfaches Bibliothekensystem bestehend aus den Klassen Autor, Buch, Exemplar und Bibliothek, gewählt. Alle Klassen basieren auf dem Stereotyp «Entity», der sich wiederum von Class des UML- Metamodells ableitet. Zusätzlich besitzt jede Klasse ein Attribut zur Identifikation (id bzw. inventarnr) mit dem Stereotyp «Key» der Metaklasse Property. Wenn das Modell fertig gestellt ist, kann in Eclipse ein neues oaw-projekt eingerichtet und eine entsprechende Ordnerstruktur hergestellt werden (s. Anh. A.1). Hierbei werden zunächst die Ordner templates und model erzeugt. In letzteren wird die MagicDraw Projektdatei im gepackten XMI-Format (Bibliothek.mdzip) sowie eine Profildatei (UML_Standard_Profile.xml) importiert. Anschließend kann mit der Definition der Metaklassen fortgefahren werden. In UML werden diese durch Stereotype repräsentiert. In unserem Beispielmodell sind dies «Entity» und «Key». Damit sie sinnvoll verwendet werden können, müssen sie zunächst oaw bekannt gemacht werden. Hierzu wird für jeden Stereotyp im Package oaw4.demo.classic.uml.meta eine Klasse erstellt, die eine entsprechende Implementierung vornimmt (s. Anhang B). Zusätzlich müssen die Stereotype noch den 18

Kapitel 4: Anwendungsbeispiel entsprechenden oaw Metaklassen zugeordnet werden. Dies geschieht mit Hilfe der Datei metamappings.xml im source-ordner. 4.2 Definition von Workflow, Templates und Extensions Der nächste Schritt beinhaltet die Definition des Workflow-Skripts innerhalb der Datei workflow.oaw (s. Anhang C), die ebenfalls direkt im source-ordner erstellt wird. In ihr wird zunächst die Umgebung für das klassische Metamodell initialisiert sowie die Tool-spezifische XMI-Datei und das Metamodell instanziiert. In der Datei workflow.properties (s. Anhang C) werden hierzu konkrete Konfigurationen gespeichert. So werden dort beispielsweise u.a. der Name der MagicDraw Projektdatei (model.xmi)und der speziell auf MagicDraw zugeschnittene Tool-Adapter (tooladapterclassname) hinterlegt. Des Weiteren wird im Workflow mittels der Komponente dircleaner das Ausgabeverzeichnis (src-gen) bereinigt und anschließend über die Komponente generator der Generatorprozess zu Erzeugung des Quellcodes gestartet. Im Beispiel-Workflow beginnt dieser mit der Definition <expand value="root::root FOREACH me.getelements('model')"/>. Das bedeutet der Generator wird für alle durch den Ausdruck <me.getelements('model')"/> selektierten Elemente nach einer Datei Root.xpt suchen, in der eine Definition namens Root existiert und diese anwenden. Im Fall eines UML-Modells existiert jedoch nur ein Element vom Typ Model sodass nur dieses selektiert wird. Die Template-Datei Root.xpt (s. Anhang D) beginnt mit dem Import der Metaklassen des gewählten Metamodells sowie der selbst geschriebenen Metaklassen. Anschließend werden entsprechende Blöcke definiert, mit denen die im Modell enthaltenen Elemente rekursiv durchlaufen werden. So kann im ersten Block durch die Assoziation OwnedElement auf alle Elemente eines Modells zugegriffen werden, die in diesem auf oberster Ebene enthalten sind. Ein OwnedElement umfasst dabei verschiedene Elementtypen wie Klassen, Pakete, Datentypen etc. Für Elemente vom Typ Package wird erneut das Root-Template ausgeführt, um auf Subelemente Zugriff zu erlangen. Bei Elementen des Typs Entity wird hingegen das Template 19

Kapitel 4: Anwendungsbeispiel BeanClass angewendet. Der letzte DEFINE Block dient zum Abfangen aller weiteren Elementtypen. Das Template BeanClass wird in der Datei JavaBean.xpt (s. Anhang D) beschrieben, die sich im Package Java des Template-Ordners befindet. Hier werden für jedes Entity bereits erste konkrete Ausgaben definiert. So legt der FILE- Ausdruck beispielsweise Pfad und Dateinamen fest und mittels package «packagename()»; wird der Name des Pakets in die Quellcodedatei geschrieben. Anschließend folgen der Klassenrumpf sowie der Aufruf weiterer Templates. Dabei werden für jedes Attribut die Templates PropertyDeclaration, Getter und Setter angewendet, die in der Datei Attribute.xpt definiert sind und für jedes Attribut entsprechende Instanzvariablen sowie Getter und Setter-Methoden erzeugen. In den Template-Dateien werden an mehreren Stellen Extensions aufgerufen, die in die Datei NamingConventions.ext (s. Anhang E) ausgelagert sind und über den «EXTENSION» Ausdruck den Templates bekannt gemacht werden. Von diesen bewirkt asparameter beispielsweise, dass Parametern bei Setter-Methoden ein p vorangestellt wird und assetter bzw. asgetter legen die Namenskonventionen für die Getter- bzw. Setter-Methoden insofern fest, dass der Attributsname mit einem Großbuchstaben beginnt. Auch die bereits im vorangegangenen Abschnitt erwähnte Möglichkeit aus den Extensions Java-Methoden aufzurufen wird verwendet. So wird in der Extension packagename zur Ermittlung der vollen Paketnamen die Java-Methode getpackagename() der Klasse ClassUtil (s. Anhang E) aufgerufen, die sich im Paket oaw4.demo.classic.uml.extend des source-ordners befindet. 4.3 Berücksichtigung von Assoziationen Die bis jetzt genannten Templates und Extensions definieren den Generatorprozess zur Quellcodeerzeugung insoweit, dass für jedes Entity unseres Beispielmodells eine eigene Java-Klasse inklusive aller Klassenvariablen sowie Getter- und Setter-Methoden für die Attribute erzeugt werden. Zusätzlich wird zu Beginn jeder Klasse das jeweilige Package angegeben. Da im Beispielmodell jedoch auch Assoziationen zwischen den Entities bestehen, müssen hierfür ebenfalls Templates erstellt werden, damit diese vom Generator berücksichtigt werden können. Im Beispiel geschieht dies mit Hilfe der Templates ReferenceVariables und AccessorMethods, die im Template 20

Kapitel 4: Anwendungsbeispiel BeanClass aufgerufen werden und in der Datei Association.xpt (s. Anhang C) definiert sind. Der erste Block ReferenceVariables durchläuft für jede Klasse alle navigierbaren, gegenüberliegenden Assoziationsenden und deklariert eine entsprechende Referenz. Dabei wird anhand der Extension fqn (s. Datei Associations.ext, Anhang E) überprüft, ob es sich um eine ToOne -oder ToMany-Assoziation handelt und der richtige Typ verwendet wird. Bezogen auf das Beispielmodell würden sich beispielsweise die folgenden beiden Deklarationen ergeben: //ToOne-Assoziation (Exemplar.java) private oaw4.demo.classic.uml.entity.bibliothek eigentuemer; //ToMany-Assoziation (Autor.java) private java.util.collection<oaw4.demo.classic.uml.entity.buch> verfasstesbuch; Der zweite Block AccessMethods durchläuft ebenfalls alle Klassen und ruft für jedes navigierbare ToOne-Assoziationsende das Template ToOneAccessorMethods und für jedes navigierbare ToMany-Assoziationsende das Template ToManyAccessorMethods auf. Diese kümmern sich anschließend um die Erzeugung der Getter- und Setter-Methoden (bzw. Add- und Remove- Operationen bei Collections). Damit ist die Erzeugung der Assoziationen komplett und der Generatorprozess vollständig definiert. Der Workflow kann nun angestoßen werden, worauf die generierten Quellcodedateien im Ordner src-gen erstellt werden. 4.4 Überprüfungen Um im Rahmen dieses Beispiels auch die Funktionsweise der Check Komponente zu zeigen, wurde zusätzlich eine Datei AssociationChecks.chk erstellt, die zwei Bedingungen formuliert: Zum einen wird für jedes navigierbare Assoziationsende überprüft, ob ein Name vergeben wurde und zum anderen sollen nicht-navigierbare Assoziationsenden unbenannt bleiben. Die Check-Datei wird anschließend über einen entsprechenden Komponentenblock mit der Klasse org.openarchitectureware.check.checkcomponent in den Workflow eingebunden. Würde nun im Ausgangsmodell beispielsweise zwischen Autor und 21

Kapitel 4: Anwendungsbeispiel Buch der Name des Assoziationsendes Autor entfernt und das andere Ende der Assoziation auf nicht-navigierbar gesetzt werden, käme es innerhalb des Workflow- Ablaufs zu einem ERROR sowie einer WARNING, da beide Bedingungen nicht mehr erfüllt wären. Im Falle eines ERRORs wird der Workflow unterbrochen. 4.5 Evaluation Zu openarchitectureware existiert eine Vielzahl von Tutorials die auch für Einsteiger leicht verständlich sind und zu einem schnellen Ergebnis führen. Eine Erleichterung ist dabei die Implementierung in die schon bekannte Eclipse-Entwicklungsumgebung. Der Benutzer muss im Gegensatz zum Entwickler des Codegenerators nur wissen wie er das neuerstellte UML-Modell einzubinden und den Generator auszuführen hat. In Bezug auf die Funktionalität wird bei der Codegenerierung nicht angestrebt, eine komplette Software über Modelle zu erzeugen, sondern vielmehr die Erzeugung von Teilen des Quellcodes mit dem Wissen, dass später manueller Code hinzugefügt werden muss. Somit ist oaw nicht schon im Vorfeld auf eine bestimmte Plattform beschränkt da der Entwickler die Möglichkeit hat, diese selbst festzulegen und zu erstellen. Unter dem Aspekt der Änderbarkeit soll hier betrachtet werden, wie schnell und effizient sich Änderungen in einem MDA-Tool erledigen lassen. Ein Beispiel hierfür wäre das Hinzufügen eines weiteren Attributes zu einer Klasse. Dabei muss unterschieden werden, ob es sich um ein Standard -Attribut handelt, das zu einer bestehenden Klasse hinzugefügt wird oder um ein neues nicht vorhergesehenes Attribut, das eventuell neue Stereotype benötigt. Bei einem Standard -Attribut wird keine Anpassung im MDA-Tool nötig, da das Tool über die schon vorhandenen Generatorroutinen das neue Attribut verarbeitet. Andernfalls sind ein solche Anpassung sowie eine entsprechende Änderung des UML-Profils durchzuführen. Insgesamt ergibt sich bei derartigen Anpassungen ein Arbeitsaufwand von etwa 4 Minuten für kleinere und 7 bis 9 Minuten für komplexere Erweiterungen des Systems. Von einer komfortablen Steuerbarkeit kann bis dato noch keine Rede sein, da das meiste über Konfigurationsdateien erledigt wird, die manuell bearbeitet werden müssen. Unterstützung liefern dabei die mitgelieferten Eclipse Editoren und die Möglichkeit den Workflow aus der Eclipse IDE heraus starten. Ebenfalls mitteliefert wird außerdem ein kleiner Eclipse Wizard, der bei der Erstellung eines neuen Projektes behilflich ist und 22

Kapitel 4: Anwendungsbeispiel die Möglichkeit bietet, ein Beispielprojekt anzulegen und eine Ordnerstruktur zu erstellen. Eine richtige Führung durch das Tool, angefangen mit der Erstellung eines neuen Projektes über das Erstellen von Templates bis hin zur Konfiguration der Hauptkonfigurationsdateien, wird jedoch nicht geboten. Die Fehlertoleranz kann bei oaw als noch nicht ausgereift bezeichnet werden. Nach Starten des Generatorprozesses kann dieser nicht mehr kontrolliert werden. Die Möglichkeit, wie bei der Standardsoftwareentwicklung, Haltepunkte (Breakpoints) zu setzten besteht hier nicht. Wird zur Laufzeit ein Fehler entdeckt, bricht der Workflow ab und es kommt meist zu einer Java Exception. Die angegebene Fehlerzeile befindet sich meist in einer Java-Klasse und ist schwierig auf die Konfigurationsdateien des Generators zurückzuführen. Mit Hilfe der Check Komponente können Fehlermeldungen definiert werden, die nach dem Lauf ausgegeben werden. Sie beziehen sich auf die vorher vom Entwickler erstellten Konfigurationen, die für das geladene Modell gelten müssen. Da diese Überprüfungen jedoch auch vom Entwickler implementiert werden, werden auch nur die Fehler erkannt, die selbst vorher als Fehler definiert wurden. Die Beurteilung der Mächtigkeit des Frameworks ist kaum möglich, da das in dieser Arbeit beschriebene, Anwendungsbeispiel die möglichen Funktionen nur ansatzweise ausreizt. Die Individualisierbarkeit erscheint jedoch fast grenzenlos, da der Entwickler über eigene Java-Komponenten viel Funktionalität zum Generatorprozess hinzufügen kann. So besteht beispielsweise die Möglichkeit, dass sich mehrere Modelle während eines Generatorprozesses gegenseitig beeinflussen, ein eingelesenes Modell geklont und anders als das erste behandelt wird oder lediglich einzelne Komponenten wie z.b. Attribute zu einer Klasse hinzugefügt werden können. 23

Kapitel 5: Zusammenfassung 5. Zusammenfassung Der erste Teil dieser Arbeit beschäftigte sich mit den Grundlagen der modellgetriebenen Softwareentwicklung. Im Vordergrund standen dabei vor allem die Ziele Automation, Effizienz, Wiederverwendbarkeit, Interoperabilität und Verbesserung der Qualität innerhalb des Entwicklungsprozesses. Es wurde außerdem der von der OMG festgelegte MDA Standard erläutert und die daran beteiligten Spezifikationen vorgestellt. In diesem Kontext ist insbesondere das Konzept der Metamodellierung als Basis der MDA hervorzuheben. Anschließend wurde auf die am MDA-Prozess beteiligten Modellarten eingegangen und ihr Zusammenwirken beschrieben. In Bezug auf Transformationen sind die Aspekte Tunability und Traceability maßgebend. Des Weiteren ist zwischen metamodellorientierten und ausgabeorientierten Transformationen zu unterscheiden. Zum Ende des ersten Teiles wurde noch eine Abgrenzung der MDA vom MDSD insofern vorgenommen als das die MDA als eine Spezialisierung des MDSD zu sehen ist. Im Mittelpunkt des zweiten Teils der Arbeit stand openarchitectureware als Framework zur Erstellung und Ausführung von MDA-Prozessen. Dieses setzt sich mit dem Workflow als verbindende Einheit aus mehreren Komponenten zusammen, die im Hinblick auf ihre Funktionsweise im Einzelnen dargestellt wurden. Eine praktische Umsetzung zur Erstellung eines Generatorprozesses wurde im letzten Abschnitt der Arbeit durchgeführt. Anhand eines simplen Modells, bestehend aus einer Handvoll Klassen inklusive Attribute, Stereotype und Assoziationen, wurde die automatische Generierung von entsprechendem Quellcode veranschaulicht. In der anschließenden Evaluation wurden insbesondere die Aspekte Dokumentation, Funktionalität, Änderbarkeit und Arbeitsaufwand, Fehlertoleranz sowie Mächtigkeit des Frameworks genauer betrachtet. Während die gute Dokumentation zu schnellen Lernerfolgen führt, scheinen Steuerbarkeit und Fehlertoleranz noch verbesserungswürdig. Im Hinblick auf die Mächtigkeit besitzt oaw mit der Implementierung von Java ein entscheidendes Feature. Insgesamt betrachtet macht oaw als Framework zur Entwicklung von MDA/MDSD- Projekten einen runden und geschlossenen Eindruck, was das zu Grunde liegende Konzept erfolgreich erscheinen und für die Zukunft vieles erhoffen lässt. 24

Anhang A Eclipse Ordnerstruktur des Anwendungsbeispiels 25

Anhang B Definition der Metaklassen Entity.java package oaw4.demo.classic.uml.meta; public class Entity extends org.openarchitectureware.meta.uml.classifier.class { //nothing to do in the simplest case Key.java package oaw4.demo.classic.uml.meta; public class Key extends org.openarchitectureware.meta.uml.classifier.attribute { metamappings.xml <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE MetaMap SYSTEM "http://www.openarchitectureware.org/dtds/metamap.dtd"> <MetaMap> <Mapping> <Map>Entity</Map> <To>oaw4.demo.classic.uml.meta.Entity</To> </Mapping> <Mapping> <Map>Key</Map> <To>oaw4.demo.classic.uml.meta.Key</To> </Mapping> </MetaMap> 26

Anhang C Der Workflow workflow.oaw <?xml version="1.0" encoding="utf-8"?> <workflow> <property file="workflow.properties"/> <cartridge file="org/openarchitectureware/workflow/oawclassic/classicstart.oaw"> <metaenvironmentslot value="me"/> <instantiatorenvironmentslot value="ie"/> </cartridge> <component class="org.openarchitectureware.core.frontends.xmi.workflow.xmiinstantiator"> <instantiatorenvironmentslot value="ie"/> <modelfile value="${model.xmi"/> <xmlmapfile value="${toolmappingfile"/> <metamapfile value="${metamapfile"/> <tooladapterclassname value="${tooladapterclassname"/> <modulefile value="${modulefile"/> <outputslot value ="model" /> </component> </workflow> <cartridge file="org/openarchitectureware/workflow/oawclassic/classicinit.oaw"> <metaenvironmentslot value="me"/> </cartridge> <component class="org.openarchitectureware.check.checkcomponent"> <metamodel class="org.openarchitectureware.type.impl.java.javametamodel"> <typestrategy class="org.openarchitectureware.type.impl.oawclassic.oawclassicstrategy" convertpropertiestolowercase="false"/> </metamodel> <checkfile value="java::associationchecks"/> <expression value="me.getelements('modelelement')"/> <abortonerror value="true"/> </component> <component id="dircleaner" class="org.openarchitectureware.workflow.common.directorycleaner" skiponerrors="true"> <directories value="${srcgenpath"/> </component> <component id="generator" class="org.openarchitectureware.xpand2.generator" skiponerrors="true"> <metamodel class="org.openarchitectureware.type.impl.java.javametamodel"> <typestrategy class="org.openarchitectureware.type.impl.oawclassic.oawclassicstrategy" convertpropertiestolowercase="false"/> </metamodel> <fileencoding value="iso-8859-1"/> <expand value="root::root FOREACH me.getelements('model')"/> <genpath value="${srcgenpath/"/> <srcpath value="${srcgenpath/"/> <beautifier class="org.openarchitectureware.xpand2.output.javabeautifier"/> <beautifier class="org.openarchitectureware.xpand2.output.xmlbeautifier"/> </component> <cartridge file="org/openarchitectureware/workflow/oawclassic/classicfinish.oaw"> <instantiatorenvironmentslot value="ie"/> <dumpfile value="${dumpfile"/> </cartridge> workflow.properties # Note: all paths must be found in the classpath! # the metamappings file metamapfile = metamappings.xml # model.xmi: name of the XMI export # toolmappingfile: tool mapping file to use # tooladapterclassname: tool adapter implementation # modulefile: profile files model.xmi = Bibliothek.mdzip toolmappingfile = magicdraw_xmi21_all.xml tooladapterclassname = org.openarchitectureware.core.frontends.xmi.toolsupport.uml.magicdraw.magicdrawadapter21 modulefile = magicdraw/md11/uml_standard_profile.xml # path to create the generated output to srcgenpath = src-gen # path where the dump file is created dumpfile = bin/dump 27

Anhang D Die Templates Root.xpt «IMPORT org::openarchitectureware::core::meta::core» «IMPORT org::openarchitectureware::meta::uml::classifier» «IMPORT oaw4::demo::classic::uml::meta» «DEFINE Root FOR Model» «EXPAND Root FOREACH OwnedElement» «ENDDEFINE» «DEFINE Root FOR Package» «EXPAND Root FOREACH OwnedElement» «ENDDEFINE» «DEFINE Root FOR Entity» «EXPAND java::javabean::beanclass» «ENDDEFINE» «DEFINE Root FOR Object»«ENDDEFINE» JavaBean.xpt «IMPORT org::openarchitectureware::meta::uml::classifier» «EXTENSION java::namingconventions» «DEFINE BeanClass FOR Class» «FILE packagepath()+"/"+names+".java"» package «packagename()»; public class «Name» «IF hassuperclass» extends «SuperClass.fqn()» «ENDIF» implements java.io.serializable { «EXPAND Attribute::PropertyDeclaration FOREACH Attribute» «EXPAND Attribute::Getter FOREACH Attribute» «EXPAND Attribute::Setter FOREACH Attribute» «EXPAND Association::ReferenceVariables» «EXPAND Association::AccessorMethods» «ENDFILE» «ENDDEFINE» 28

Anhang Association.xpt «IMPORT org::openarchitectureware::meta::uml::classifier» «EXTENSION java::namingconventions» «EXTENSION java::associations» «DEFINE ReferenceVariables FOR Class» «FOREACH AssociationEnd.Opposite.select(ae ae.isnavigable) AS ae» private «ae.fqn()» «ae.asinstancevar()»; «ENDFOREACH» «ENDDEFINE» «DEFINE AccessorMethods FOR Class» «EXPAND ToOneAccessorMethods FOREACH AssociationEnd.Opposite.select(ae!ae.isMultiple && ae.isnavigable)» «EXPAND ToManyAccessorMethods FOREACH AssociationEnd.Opposite.select(ae ae.ismultiple && ae.isnavigable)» «ENDDEFINE» «DEFINE ToOneAccessorMethods FOR AssociationEnd» public void «assetter()» («Class.fqn()» «asparameter()») { this.«asinstancevar()» = «asparameter()»; public «Class.fqn()» «asgetter()» () { return this.«asinstancevar()»; «ENDDEFINE» «DEFINE ToManyAccessorMethods FOR AssociationEnd» public void add«names.tofirstupper()» («Class.fqn()» «asparameter()») { this.«asinstancevar()».add(«asparameter()»); public void remove«names.tofirstupper()» («Class.fqn()» «asparameter()») { this.«asinstancevar()».remove(«asparameter()»); public «iterator()» «asgetter()» () { return this.«asinstancevar()».iterator(); «ENDDEFINE» 29