Universität Augsburg Institut für Informatik Programmierung verteilter Systeme Modellbasierte Softwareentwicklung WS 2008/2009 Seminarband Prof. Dr. Bernhard Bauer Dipl.-Inf. Benjamin Honke Dipl.-Inf. Stefan Fenn Dipl.-Inf. Raphael Romeikat Dipl.-Inf. Christian Saad Vorwort Dieser Band enthält die studentischen Arbeiten des Seminars ’Modellbasierte Softwareentwicklung’, das im Wintersemester 2008 / 2009 and der Universität Augsburg abgehalten wurde. In der ersten Arbeit wurde von Phillip Stadler auf die Grundlagen der modellbasierten Softwareentwicklung eingegangen. Neben den grundlegenden Techniken wie Metamodellierung wird dabei auch der konkrete Einsatz, z.B. im Gebiet Model-Driven Engineering, behandelt. Das zweite Thema, bearbeitet von Markus Bickelmaier, erörtert die Grundlagen modellbasierter Testfallgenerierung. Ziel ist es dabei Tests auf Modellebene durchzuführen um bereits auf diesem abstrakten Level das Verhalten zu untersuchen und potentielle Fehler feststellen zu können. Die Arbeit von Robert Freudenreich untersucht Entwicklungsprozesse im Kontext des Eclipse Process Framework (EPF). Dabei wird auf dessen Anwendungsbereiche anhand verschiedener Prozessmodelle eingegangen und die Erweiterbarkeit anhand einer Fallstudie illustriert. Panayot Radinski geht im nächsten Thema detailliert auf die Bindingtechnik JAXB ein die einen Datentransfer zwischen XML und Java ermöglicht. In der letzten Seminararbeit die von Matthias Drexl und Maximilian Koch gemeinsam erstellt wurde werden verschiedene Notationen für die Modellierung von Geschäftsregeln vorgestellt und evaluiert sowie im Rahmen einer Fallstudie näher beleuchtet. April 2009 Die Editoren Inhaltsverzeichnis Einführung in die modellbasierte Softwareentwicklung . . . . . . . . . . . . . . . . . 1 Grundlagen der modellbasierten Testfallgenerierung . . . . . . . . . . . . . . . . . . . 18 Evaluierung der Potentiale des Eclipse Process Frameworks . . . . . . . . . . . . 34 Binding zwischen XML-Schema-Modellen und Java-Beans (JAXB) . . . . . . 54 Modellierung von Geschäftsregeln . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103 IV Einführung in die modellbasierte Softwareentwicklung Philipp Stadler Universität Augsburg [email protected] Zusammenfassung Die Softwareentwicklung hat in den letzten Jahrzehnten immer mehr an Bedeutung gewonnen. Um im Gegenzug dazu die Komplexität, den Aufwand und die damit verbundenen Kosten in einem moderaten Bereich zu halten bedient man sich unter anderem dem Hilfsmittel der modellbasierten Softwareentwicklung. Im Rahmen dieser Arbeit soll nun eine Einführung in die modellbasierte Softwareentwicklung gegeben werden und auf die Modelle, die Metamodelle und Modellierung sowie auf Anwendungsszenarien eingegangen werden. 1 Einleitung und Motivation Frederick P. Brooks, einer der großen Informatik Pioniere, unter anderem Leiter der System/360 - Entwicklung und des OS/360 - Projektes von IBM, sowie ausgezeichnet mit dem Turing-Preis, schrieb 1986 in seinem Essay No Silver Bullet: Essence and Accidents of Software Engineering folgendes Paradigma: The familiar software project, at least as seen by the nontechnical manager, has something of this character; it is usually innocent and straightforward, but is capable of becoming a monster of missed schedules, blown budgets, and flawed products. So we hear desperate cries for a silver bullet–something to make software costs drop as rapidly as computer hardware costs do. [1, S.1] Nach Brooks können Softwareprojekte also unberechenbare Monster sein, bei denen Zeit und Kostenplan vollkommen aus dem Ruder laufen können. Somit sucht man natürlich nach dem magischen Tool, also nach der Silver Bullet, mit der sich Kosten und Aufwand senken lassen könnten. Die Standish Group hat 1994 den ersten CHAOS-Bericht herausgebracht. Im Jahre 1994 haben sich, laut dem bereits genannten Bericht, 31,1 Prozent aller in diesem Jahr gestarteten IT-Projekte als komplette Fehlplanungen erwiesen. Während dieser Untersuchung wurden mehr als 100.000 IT-Projekte in den USA untersucht. Diese Projekte wurden wiederum von der Standish Group in die Cluster successful, challenged sowie failed eingeteilt. [12] Welchen Zusammenhang haben nun die, vom CHAOS-Report herausgefundenen Verbesserungen, bezogen auf die Softwareentwicklung, mit der modellgetriebenen Softwareentwicklung? 2 P. Stadler Kategorie 1994 2004 Veränderung successful 16% 34% Verdopplung challenged 53% 51% wenig failed 31% 15% Halbierung Tabelle 1. Ergebnisse des CHAOS - Reports Die modellgetriebene Softwareentwicklung, bzw. Model Driven Software Development, kurz MDSD, befasst sich mit der Automatisierung der Softwareherstellung. Mit Hilfe dieser werden Modelle nicht nur als Dokumente verwendet, sie können mit dem Code gleichgesetzt werden. Es wäre jetzt etwas übertrieben zu behaupten, dass man es allein den verschiedenen Forschungsgebieten innerhalb der Softwareentwicklung, zu dem auch die MDSD gehört, zu verdanken hätte, dass sich die Werte welche durch die Standish Group ermittelt wurden verbessert haben. Es wird sich aber zeigen, dass man durch den Ansatz der modellgetriebenen Softwareentwicklung Fehlerquellen schon von vornherein, also z.B. in der Analyse bzw. Planungs- und Simulationsphase, dezimieren kann. Dadurch, dass Fehler in den meisten Fällen mit einem Kostenaufwand verbunden sind kann auch davon ausgegangen werden, dass sich dieser wohl ebenso verringern lassen könnte. Das international tätige IT-Marktforschungs- und Beraterunternehmen IDC (International Data Corporation www.idc.com) hat in ihrer Abschlussstudie 2008 für den deutschen IT-Markt eine etwas düstere Prognose für die ersten zwei Quartale 2009 herausgegeben. [4] Das IDC hat, in dem für diese Arbeit interessanten Bereich des IT-Marktes, nämlich den Softwarebereich, eine Wachstumsrate von fünf Prozent für den Zeitraum bis 2012 analysiert. Ob und inwieweit Softwareentwicklungsschmieden, welche sich mit der modellgetriebenen Softwareentwicklung beschäftigen, davon profitieren können lässt sich an dieser Stelle leider nicht fundiert feststellen. Frei nach der deutschen Redewendung Wer kein Ziel hat, kann auch keins erreichen stellt sich hier auch die Frage welche motivierenden Ziele die modellgetriebene Softwareentwicklung nun verfolgt [9, 6]. Erhöhung der Entwicklungsgeschwindigkeit: durch Automation kann aus formalen Modellen in einem oder mehreren Transformationsschritten lauffähiger Code generiert werden. Einsatz von Transformationen: Qualitätssteigerung in der Softwareentwicklung, die auch eine Steigerung der Softwarequalität zur Folge haben kann. Dealing with complexity: durch verschiedene Abstraktionsebenen kann und soll die Komplexität besser gehandhabt werden. Standardisierung: die Object Management Group strebt mit der MDA, der Modell Driven Architecture, eine Standardisierungsrichtung an mit der v.a. eine plattformunabhängige Herstellerunabhängigkeit erziehlt werden kann. Einführung in die modellbasierte Softwareentwicklung 3 Mit diesen, mitunter allgemein gehaltenen, Fragen haben die Entwickler, Forscher und Wissenschaftler rund um das Gebiet der modellbasierten Softwareentwicklung das Rad natürlich nicht neu erfunden. Dies sind grundlegende Fragen und Ziele wie sie überall in der Informationstechnik zu finden sind. Daher stellt dies nur eine weiter Bestätigung derer dar. In dieser Arbeit sollen nun die Grundlagen über Modelle (Kap. 3.1) der modellbasierten Softwareentwicklung (Kap. 3.2) erläutert werden. Aufbauend auf diesen werden ausgewählte Details der modellbasierten Softwareentwicklung und der MDA (Kap. 3.3) herrausgearbeitet, Anwendungen erörtert (Kap. 4) und zuletzt ein Blick auf die gegenwärtige Nutzung und Forschung (Kap. 5) geworfen. 2 Metamodelle und Metamodellierung Metamodellierung ist eine Konkatenation aus den beiden Worten Modellierung und meta. Das griechische Wort meta bedeutet so viel wie zwischen, neben, über und nach. Also sind Metamodelle, schlicht gesagt, Modelle von Modellen, da Metamodelle Modelle sind, die etwas über Modellierung aussagen. Eine genauere Ausführung dieser Formulierung wäre [9, 91]: Ein Metamodell beschreibt die mögliche Struktur von Modellen - es definiert damit in abstrakter Weise die Konstrukte einer Modellierungssprache, ihre Beziehungen untereinander sowie Einschränkungen bzw. Modellierungsregeln, nicht jedoch die konkrete Syntax dieser Sprache. Man benötigt konsequenterweise eine (Meta-)Modellierungssprache, welche wiederum durch ein (Meta-)Modell beschrieben wird. Nach Stahl et. al. definiert ein Metamodell also die abstrakte Syntax, sowie die statische Semantik einer (Modellierungs-)Sprache. Syntax und Semantik von Metamodellen wird in Kapitel 2.1 näher beschrieben. Im Umkehrschluss hat jede formale Sprache (wie z.B. Java oder UML) auch ein Metamodell. Die folgende Abbildung, nach Völter und Stahl [9, 92], verdeutlicht diesen Sachverhalt: Abbildung 1. Beziehungen wirkliche Welt - Modell - Metamodell Metamodell und Modell stehen in einer Beziehung von einer Klasse zu einer Instanz. Dies bedeutet, dass jedes Modell die Instanz eines Metamodells ist. Eine Herausforderung bei den Metamodellen besteht darin eine Modellierungssprache für sie zu definieren. 4 P. Stadler Es ist prinzipiell möglich Modelle in einer beliebigen Modellierungssprache zu beschreiben. Der jeweilige Ausgangspunkt bei der Modellierung in der modellbasierten Softwareenwicklung ist die Domäne.[9] Dies ist, wie aus der IT bekannt, ein Gebiet, in Bezug auf die MDSD ist es ein, für die jeweilige Anforderung, begrenztes Wissensgebiet. Bei der Auswahl der Modellierungssprache ergibt sich daraus die Anforderung ob überhaupt genügend Werkzeuge, welche für die Modellierung der (Meta-)Sprache nötig sind, zur Verfügung stehen. Abbildung 2, welche offiziel von der OMG definiert wurde, zeigt die vier Metaschichten der OMG [9]: Abbildung 2. Die vier Metaschichten der OMG Eine Instanz während der Laufzeit der Klasse Person mit den dazugehörigen Attributen des Modells M1 ist in diesem Beispiel der Typ Person mit dem Namen Völter. Der Classifier des Metamodells-M2 bekommt den Namen des zu beschreibenden Modells, hier Name: Klasse von M1 (Typ). Die Schicht M3 ist die Abstraktionsschicht der MOF, welche dazu benötigt wird die Metamodelle zu beschreiben. Sie wurde von der Object Management Group innerhalb der Meta Object Facility Architectur definiert. Die Meta Object Facility verwendet einerseits eine Teilmenge der UML und Einführung in die modellbasierte Softwareentwicklung 5 andererseits wird sie zum Entwurf von Metamodellen verwendet. Die offizielle Spezifikation der MOF, Schicht M3 in Abb. 2, beinhaltet eine abstrakte Sprachbeschreibung und ein Basisgerüst, das MOF - Modell. Mit diesem können plattformunabhängige Metamodelle erzeugt und spezifiziert werden. Um Metadaten innerhalb der MOF auszutauschen wurde von der OMG das XMI XML Metadata Interchange spezifiziert. Dieses Format erlaubt den Austausch von MOF-basierten Modellen und Metamodellen im XML-Format. [9] XML kann hier bei entscheidendte Vorteile zu anderen Formaten vorweisen: . . . . Ähnlichkeiten zu HTML, daher leichte Einarbeitung sehr strukturiert und dadurch leicht zu generieren und zu lesen plattformunabhänig und unterstützt Internationalisierung sowie Unicode modular sowie erweiterbar und enthält im Grunde die Obermenge für eine ganze Familie von Techniken • Xlink (Überführung von Hyperlinks zu XML) • XPointer (Syntax um auf Teile eines XML-Dokuments zu verweisen) • CSS (Style-Sheet-Sprache; analog zu CSS in HTML) • DOM (Document Object Model -Standardmenge an Funktionen) . lizenzfrei und weit verbreitet Man kann die Meta Object Facility aus zwei verschiedenen Perspektiven betrachten. 1. die Modellierungsperspektive und 2. die Datenperspektive Bei der Modellierungsperspektive verläuft die Blickrichtung top-down entlang der Modellebenen. Hierbei kann die MOF entsprechende Informationsmodelle auf unterschiedlichen Ebenen für bestimmte Domänen definieren und diese anschließend durch Implementierungs- und Softwareentwurfstätigkeiten im Rahmen der Entwicklung nutzen. Die Datenperspektive legt ihren Fokus auf eine bestimmte Ebene eines gegebenen Modells. Dadurch können z.B. Strukturen im Rahmen der CORBA (Common Object Request Broker Architecture) Schnittstelle genutzt werden. Die CORBA Schnittstelle wird auch von der OMG entwickelt und soll das Erstellen verteilter Anwendungen in einem homogenen Umfeld vereinfachen. Zusammenfassend muss man an dieser Stelle festhalten dass Metamodelle von essentieller Wichtigkeit für die Beschreibung von Modellen sind. Sie dienen infolgedessen auch zu einer besseren Verständlichkeit und der Vergleichbarkeit von Modellen, da man sich bei beiden unterschiedlichsten Arten von Modellen auf vergleichbare Eigenschaften etc. geeinigt hat, denn ohne eine vergleichbare Gesamtmenge könnte man grundlegend keine Vergleiche machen. 2.1 Syntax und Semantik der Metamodelle Die Syntax der Metamodelle befasst sich, wie auch in allgemein in Programmiersprachen, mit der grammatikalischen Struktur der Metamodelle. Eine Sprache 6 P. Stadler wird also durch ihre, nach ihren jeweils definierten Regeln, Konkatenation von Zeichen gebildet. Bei den Metamodellen wird zwischen konkreter und abstrakter Syntax unterschieden. Die konkrete Syntax ist der Bereich, der vom Anwender bzw. Modellierer direkt wahrgenommen und verarbeitet wird. Er stellt also eine spezifische Notation für die jeweilige Sprache bereit.[7] Die abstrakte Syntax ist die Realisierung zu einem Abstrakten System. Sie beinhaltet zwar das Vokabular sowie die Grammatik der Modellierungssprache aber sie definiert nicht wie die abstrakte Syntax dem Enandwender präsentiert wird. Die abstrakte Syntax definiert jedoch die Notationskonventionen und Schlüsselwörter, welche vom Compiler verwendet werden. Hierbei werden Strukturen und Konzepte definiert, die dem Programmierer, Anwender und Modellierer die Lesbarkeit vereinfachen. Die Schlüsselwörter, die der Endbenutzer nutzt sind jedoch aus abstrakter Sichtweise weniger relevant. Diese Aufgabe übernimmt die konkrete Syntax. Laut Stahl et. al könnte man sagen dass eine konkrete Syntax die Realisierung einer abstrakten Syntax ist. Hierbei ist die Tatsache besonders hervorzuheben, dass verschiedene konkrete Syntaxformen eine gemeinsame abstrakte Syntax haben können. Bei den Metamodellen unterscheidet man auch zwischen statischer und dynamischer Semantik. Die dynamische Semantik ist der Teil der Modellierungssprache der während der Programmausführung im Speicher existiert. So nimmt diese direkten Bezug auf die Lebensdauer („Runtime“) bei der Ausführung von Programmabschnitten. Die statische Semantik setzt ihren Anspruch auf die Wohlgeformtheitsregeln der Sprache. Dies können auf der einen Seite Deklarationen von Variablen, Übergabeparameter oder aber auch Gültigkeitsbereiche, welche auf Gültigkeitsregeln beruhen, sein. [9] 2.2 Object Constraint Language and Domain Specific Language Um Modellierungsregeln für beispielsweise MOF-basierte Modellierungssprachen zu beschreiben, braucht man eine Sprache um diese Regeln oder Einschränkungen (bzw. Constraints) zu definieren. Diese Aufgabe übernimmt die Object Constraint Language. Die Object Constraint Language (OCL) ist eine Erweiterung der Unified Modeling Language (UML) und ihre Standard-Abfragesprache. Ursprünglich wurde sie als eigene Technik entwickelt und ist inzwischen Teil des Object Management Group bzw. OMG-Standards. Die Syntax der Object Constraint Language basiert teilweise auf der objektorientierten Programmiersprache Smalltalk-80 und hat neben dieser weitgehend intuitiven Syntax auch Bestandteile aus der Prädikatenlogik. Die OCL dient hauptsächlich der Beschreibung von Bedingungen für die UML Notationen, also Diagramme oder besser Klassendiagramme. Hier sind wiederum auch die Anteile der Prädikatenlogik ersichtlich, denn mit der OCL beschreibt Einführung in die modellbasierte Softwareentwicklung 7 man Invarianten sowie Vor- und Nachbedingungen von Operationen und Methoden. Die Object Constraint Language kommt, verglichen mit der UML relativ wenig zum Einsatz. Der Grund hierfür liegt schätzungsweise darin, dass es vielen Anwendern schwerfällt eine texturelle Sprache innerhalb der visuellen Sprache UML zu verwenden. Die OCL ist, im Gegensatz zu Smalltalk-80, eine getypte Sprache.[7, 282] Neben den Standard- und Basistypen gibt es noch die Tupel und Containertypen. Zusammenfassend beschreibt die OCL 2.0 Spezifikation der Object Management Group die oft eingesetzten Datentypen wie String, Integer aber auch Aufzählungstypen. Sowie die jeweiligen Datentypen des zugrundeliegenden Modells. Dies bedeutet dass beispielsweise alle im UML-Modell definierten Typen auch in OCL bekannt sind. Jeder der aufgezählten Datentypen hat für ihn definierte Operationen. Die Aufzählung dieser würde den Umfang dieser Arbeit jedoch sprengen und sind außerdem in der Spezifikation für den OCL Standard für jeden frei verfügbar. Aus der theoretischen Informatik kennt man das Constraint-Satisfaction-Problem, welches sich zur Aufgabe gemacht hat die Belegungen zu finden welche alle Bedingungen, also Constraints, erfüllen. Ist dies der Fall spricht man, in der theoretischen Informatik, von einem Modell. Die Constraints, also Regeln und Einschränkungen zwischen verschiedenen Metaklassen machen neben den Metaattributen und Metaassoziationen einen großen Teil der Bedeutung des Metamodells aus. Dies ist auch der Grund warum man sich überhaupt für die Spezifizierung der OCL entschieden hat. Wie man aus der Beschreibung der statischen Semantik bereits weiß kann z.B. eine Modellierungssprache wie UML mit Hilfe der OCL formal definiert werden. OCL-Ausdrücke nehmen also, mit Hilfe der statischen Semantik Bezug auf die abstrakte Syntax (d.h. die Klassenstruktur des Profils) auf eine Sprache wie z.B. UML.[9, 68] Ein Teilgebiet der OMG ist die QVT, kurz Query View Transformation. Diese Spezifikation wird benötigt, da zwar mit MOF, UML und XMI die Standardisierung des Gebietes Modellierung relativ weit vorangeschritten ist, aber mit diesen noch keine Standards für Transformationen gegeben sind. Hier kommt die Query View Transformation zum Tragen.[6] Diese Transformationen zwischen Modellen ermöglichen beispielsweise eine Transformation von einem Klassenmodell zu einem ER-Modell. Die Object Management Group unterscheidet bei der Spezifizierung der QVT zwischen zwei Arten von Sprachen: . deklarative und . imperative Der deklarative Teil der Spezifikation wurde von der OMG wiederum in die Two Level Declarative Architekture unterteilt. Diese beiden Layers (Schichten) sind zum einen die benutzerfreundliche Relations-Schicht und zum anderen der QVT-Core, welcher für den Endanwender meist weniger von Bedeutung ist. Zusätzlich zu dem deklarativen Teil, welcher im Grunde die selben semantischen Inhalte nur auf unterschiedlichen Abstraktionsebenen darstellt, ist der imperative Teil dazu da imperative Implementierungen aus Transformationen des QVT-Cores 8 P. Stadler sowie der QVT-Relation Sprache zu vereinheitlichen. Dies geschieht über das Operational Mapping. Algorithmen die komplexer sind, bzw. nicht einheitlich standardisiert sind werden über die Black-Box geführt. Genauer gesagt für Black-box MOF Operation implemenations. http://www.omg.org/docs/formal/08-04-03.pdf Abbildung 3. Relationships between QVT metamodells Um die Kernaspekte einer Domäne, speziell ihre formalen Aspekte formal modellierbar zu machen greift man auf das Konzept der domänenspezifischen Sprache (DSL = Domain Specific Language) zurück. Diese DSL besitzt nun ein Metamodell, welches eine, wie in (Kap. 2.1) beschriebene, statische Semantik und eine dazugehörende konkrete Syntax hat. Der jeweiligen domänenspezifischen Sprache fehlt jedoch noch eine Semantik, welche den Konstrukten des Metamodells, eine für den Menschen sinnvolle Bedeutung geben. Genauer gesagt fehlt ihr eine dynamische Semantik, wie sie in (Kap. 2.1) beschrieben wurde. Ob man synonym zu der Domain Specific Language nun Modellierungssprache sagt hängt ganz davon ab wie stark man vom Kontext der jeweiligen Domäne abhängig ist.[9] 3 3.1 Grundlagen Modelle Was ist unter Modellen und der dazugehörigen Modellierung überhaupt zu verstehen? An dieser Stelle soll nun Anspruch darauf gelegt werden einen formalen, wissenschaftlichen Ansatz zu beschreiben. Der deutsche Philosoph Klaus D. Wüsteneck definierte 1963 [11] den Begriff Modell folgendermaßen: Ein Modell ist ein System, das als Repräsentant eines komplizierten Originals auf Grund mit diesem gemeinsamer, für eine bestimmte Aufgabe Einführung in die modellbasierte Softwareentwicklung 9 wesentlicher Eigenschaften von einem dritten System benutzt, ausgewählt oder geschaffen wird, um letzterem die Erfassung oder Beherrschung des Originals zu ermöglichen oder zu erleichtern, beziehungsweise um es zu ersetzen. So wird ersichtlich, dass Modelle dazu dienen sollen einerseits die Realität abzubilden und andererseits zwischen verschiedenen Wahrnehmungsdimensionen innerhalb eines bestimmten Abstraktionslevels zu vermitteln. Es ergibt sich also die Möglichkeit, mithilfe eines Modells, ein vereinfachtes Abbild der Realität bzw. eines Ausschnittes der Realität wiederzugeben. Des Weiteren eignen sich Modelle zur Beschreibung, Gestaltung und Erklärung der Realität. Nun kann man, nach Stachowiak [8], die grundsätzliche Definition der Modelle folgendermaßen klassifizieren: . Abbildungsmerkmale, welche das Modell als Abbildung des Originalen kennzeichnen . Verkürzungsmerkmale, die die meist aus subjektiver Sicht betrachteten, relevanten Merkmale eines realen Systems abbilden, um dem Modellierer ein leichter zu überblickendes Modellgerüst präsentieren . pragmatische Merkmale beschreiben Modelle nach ihrem (Einsatz-)Zweck, also für was sie gebraucht werden, wo und warum. So entscheidet der Modellierer selbst auf pragmatische Weise welche Orientierung und Zielgebundenheit er, dem Modell bezogen auf das Original beimisst. In vielen Bereichen des alltäglichen Lebens ist man von Modellen umgeben ohne es überhaupt zu wissen. So ist z.B. eine Deutschlandkarte mit der dazugehörigen Agenda auch als ein Modell anzusehen, da die Karte innerhalb ihres Maßstabes beispielsweise die wichtigen Verkehrspunkte Deutschlands klar und übersichtlich darstellt. Neben der Anwendung von Modellen in der Softwareentwicklung findet sich diese Technik auch in der Wirtschaftsinformatik. Dazu gehören vor allem Geschäftsprozessmodellierung und die Entity-Relationship Modellierung. Die Geschäftsprozessmodellierung kann hier einen sehr interessanten Einblick in die Arbeitsweise und Struktur eines Unternehmens bringen. Unternehmen können die modellierten Geschäftsprozesse einerseits dafür nutzen die Wiederverwendbarkeit von Prozessen zu garantieren. Diese Wiederverwendbarkeit kann z.B. gefordert werden durch den Umzug eines Produktionsstandortes oder durch Abgang von Wissensträgern im Unternehmen. Andererseits dient die Geschäftsprozessmodellierung auch der Präsentation des Unternehmens nach außen, also der Öffentlichkeitsarbeit.[3] Im Unternehmen ist der Ausgangspunkt des Geschäftsprozesses in den meisten Fällen auch das Ziel. Dass das Ziel ungleich dem Ergebnis ist, kann durch einen Pfeil verdeutlicht werden der beim Ziel beginnt und über eine Prozesskette zum Ergebnis gelangt. Ziel → Prozesskette → Prozesskette → ..... → Prozesskette → Ergebnis 10 P. Stadler In der Wirtschaftsinformatik sowie in der Softwareentwicklung ist das Wasserfallmodell und das Spiralmodell seit vielen Jahrzehnten ein Begriff.[2] Die folgende Abbildung verdeutlicht dies. Abbildung 4. Vorgehensweise der Softwareentwicklung: Wasserfall- und Spiralmodell Der durch die Abbildung schon ersichtliche Unterschied besteht darin, dass das Spiralmodell während des Entwicklungsprozesses Möglichkeiten zur Intervention bietet. Würde man sich allein nach dem Wasserfallmodell richten wäre es wohl schwer einen während der Implementation enteckten Designfehler auszubessern, vorausgesetzt man würde sich alleine an dieses recht starre und theoretische Modell halten. 3.2 Modellbasierte Softwareentwicklung Um das Gesamtkonzept der modellbasierten Softwareentwicklung zu verstehen sollte man sich vor Auge halten dass das Ziel der MDSD darin besteht durch eine oder mehrere Transformationen ein Software-Produkt ganz oder teilweise herzustellen. Bisher wurden Transformationen in Verbindung mit der Query View Transformation (QVT) in Verbindung mit dem Meta-Metamodell, M3 der Meta Object Facility (Abb. 2), gebracht. In der Informatik lassen sich in aller Regel folgende Phasen beim SoftwareEntwicklungsprozess unterscheiden:[10] . Anforderungen - den Business-Kontext und die Softwareanforderungen ermitteln . Analyse - die Anforderungen und Problemstellungen verstehen . Design - die Lösung beschreiben . Realisierung - die Anwendung erstellen . Testen - die Erfüllung der Anforderungen, Fehlerfreiheit etc. überprüfen . Installation und Betrieb - die Hardware und Software in Betrieb nehmen . Wartung - die Anwendung pflegen, verbessern und anpassen Einführung in die modellbasierte Softwareentwicklung 11 Abbildung 5. Phasen der konventionellen objektorientierten Softwareentwicklung Das folgende Schaubild verdeutlicht diesen Prozess: Wie wir in Kap. 1 vermutet haben erfindet die modellgetriebene Softwareentwicklung das Rad nicht neu, es stellt einen entscheidenen Anspruch darauf diese Phasenfolge teilweise zu automatisieren. Damit soll erreicht werden dass die Fehler welche, beim scheinbar erfolgversprechendem Roundtrip-Engineering - Änderungen am Quelltext werden hierbei ins Design-Modell übetragen, entstehen auszugleichen. Das große Problem beim Roundtrip-Engineering besteht, nach Trompeter et. al. [10], darin dass die Änderungen, also die Fehlerkorrektur, auf einem falschen Abstraktionsniveau liegen. So sind zum Beispiel Strukturen wie Vererbungshierarchien und Beziehungen zwischen Objekten im Quelltext nicht auf einen Blick erkennbar, während Klassendiagramme es erlauben, den Überblick zu behalten. Deshalb führt das ausschließliche Arbeiten im Quelltext schnell zu unübersichtlichen und damit schlecht wartbaren Lösungen. Diese Fehler gleicht nun die modellgetriebene Softwareentwicklung aus, indem Teile dieser Phasenfolge automatisiert, sowie Implementierungsschritte (Realisierung in Abb. 5) durch Transformationen aus dem Design-Modell generiert.[10] Dies verdeutlicht folgende Abbildung: Für die verschiedenen Vorgehensweisen welche in Kap. 4 beschrieben werden, gibt es im Grunde ein „festes“ Schema welche viele gemeinsam haben. Bei der Implementierung eines modellgetriebenen Entwicklungsprojektes teilt sich diese Vorgehensweise in zwei Teilbereiche: [10] . Genarator-Entwicklung: Definition der Software-Architektur und Entwicklung des Generators, der diese Architektur umsetzt und . Anwendungs-Entwicklung: Entwicklung der Fachanwendung, basierend auf der definierten Architektur unter Nutzung des Generators 12 P. Stadler Abbildung 6. Phasen der objektorientierten und modellgetriebenen Softwareentwicklung Nach Trompeter et. al müssen in einem MDSD-Entwicklungsprojekt für beide Teilbereiche Lösungen erarbeitet werden. 3.3 Model Driven Architecture - der MDSD-Ansatz der OMG Die Object Management Group hat die Idee der MDSD aufgegriffen und daraus einen Standard für ein modellbasiertes Softwareentwicklungskonzept herausgearbeitet. Diesen Standard der OMG nennt man Model Driven Architecture, kurz MDA, dieser wurde im Jahr 2000 vorgestellt. MDA basiert auf den OMG - Basistechnologien UML, MOF, XMI, CWM (Common Warehouse Metamodel), sowie auf den OMG-Schnittstellendefinitionssprachen IDL (Interface Description Language) und CORBA (Common Object Request Broker Architecture)[5] Zeppenfeld et al [12] motivieren die Model Driven Architecture folgendermaßen: Ziel dieses Standards ist es, die Plattformunabhänigkeit und Interopabilität von Metamodellen herzustellen. Die Interopabilität wird insbesondere durch Modell-Transformationen erreicht, die es erlauben, ein Metamodell in ein anderes zu transformieren. Der Einsatz verschiedener Abstraktionsgrade, wie schon in der Einleitung 1 erklärt wurde, sowie die Entwicklung technologieneutraler Anwendungsmodelle ziehen innerhalb der MDA einige Vorteile nach sich [12]: . Das in den Modellen enthaltene Fachwissen kann über lange Zeiträume festgehalten werden. . Bei einem technologiebedingten Plattformwechsel kann immerwieder auf dasselbe fachliche Modell zurückgegriffen bzw. kann dasselbe Modell auf verschiedensten Plattformen umgesetzt werden. Bevor mit der Umsetzung eines Softwareprojektes unter Benutzung der MDA begonnen werden kann, muss an dieser Stelle noch geklärt werden was man unter Einführung in die modellbasierte Softwareentwicklung 13 Plattformen und Modellen versteht. Man versteht unter einer Plattform innerhalb der MDA die Zusammenführung von (Sub-)Systemen oder Technologien, die ein gemeinsames Konstrukt von Funktionalität durch Schnittstellen und Anwendungsmuster darstellt. Es wird die für die Implementierung des Systems gewünschte Plattform ausgewählt und letztlich die allgemeine Systemspezifikation in eine für die entsprechende Plattform benötigte Spezifikation transformiert. Für diese Vorgehensweise definiert die MDA die folgenden aufeinander aufbauenden Modelle [12]: . . . . das das das das Computation Independent Model CIM, Platform Independent Model PIM, Platform Specific Model PSM und Implement Specific Model ISM. Wie schon genannt bauen die verschiedenen Modelle aufeinander auf. Das Computation Independent Model (CIM) beschreibt die Anforderungen des zu erstellenden Softwaresystems. Dieses Modell wird auch Domänenmodell oder Geschäftsmodell genannt. In diesem Modell ist typischerweise nicht ersichtlich wie die Software im Endresultat implementiert werden soll, das Modell zeigt eher die Umgebung in der das System später eingebettet werden soll und kann daher genau darstellen welche Aufgaben das zu entwerfende System zu erfüllen hat. Das Computation Independent Model besitzt nach Zeppenfeld et. al [12] eine vergleichsweise geringe Bedeutung und wird deshalb in dem offiziellen White Paper der OMG Developing in OMG´s Model-Driven Architecture [5] nicht erwähnt. Es begründet seine Hauptaufgabe damit dem Systemanalytiker Klarheit für die weitere Umsetzung der MDA zu geben. Nun kann man sich laut Jon Siegel et. al. [5] an folgender Vorgehensweise orientieren: 1. Schritt 1: Erstellen eines PIM Alle MDA -Entwicklungsprojekte starten mit der Erstellung eines (PIM). Modelle auf dieser hohen Abstraktionsebene werden oft von Geschäftsexperten und nicht von den eigentlichen Systemprogrammierern erstellt. Dabei werden häufig Erweiterungen und Spezialisierungen von UML (UML -Profile) eingesetzt, um gewisse Details in den Modellen darzustellen. 2. Schritt 2: Erstellen eines (PSM) Hier wird das (PIM) durch ein Werkzeug in (PSM) übersetzt. Ein (PSM) ist an eine bestimmte Technologie (Betriebsysteme, Programmiersprache, Middleware, Applikationsserver etc.) adaptiert. Es beschreibt ihre Anwendung mit den Mitteln der konkreten Implementierungstechnologie. 3. Schritt 3: Generierung der Anwendung Schließlich wird das Plattform- und technologiespezifische (PSM) in Quellcode übersetzt. Weil ein (PSM) seine Basistechnologie kennt, ist diese relativ einfach. 14 P. Stadler Die in den Kapiteln 2.2 und 2.1 beschriebenen Metamodelle und MOF sowie OCL-Ausdrücke finden sich hier auch in der Abgrenzung der MDA von der MDSD wieder [9]: MDA ist bezüglich der Ontologie einer Spezialisierung von MDSD mit folgenden Eigenschaften: . MDA verwendet MOF als das Metamodell (d.h. als Mittel, um Metamodelle zu definieren). . MDA sieht vor, dass die DSL´s auf Basis der MOF definiert werden. Es sind also beliebige Notationen und Metamodelle möglich, solange sie mit Hilfe des OMG-Metamodells definiert wurden. In der Praxis regt MDA die Verwendung von UML-Profilen als konkrete Syntax für eine DSL an. Damit ist die DSL im Kern dann auf UML festgelegt. Die statische Semantik wird dementsprechend mit OCL-Ausdrücken spezifiziert. . Software-Systemfamilien und Produktlinien haben in der MDA- Terminologie keine direkte Entsprechung und stehen auch inhaltlich nicht im Fokus. . Es werden verschiedene Sichtwinkel auf formale Modelle definiert: Ein fachliches Modell kann relativ zu einer Plattform spezifisch (PSM) oder unspezifisch (PIM) sein. Die MDA legt mehrschichtige Transformationen zwischen Modellen nah, verbietet aber auch eine direkte PIM-zu-Code-Transformation nicht. . Um auch die letzte Transformation, also die zur Plattform hin, als Modell-zu-Modell-Transformation notieren zu können, muss auch die Plattform mittels eines Metamodells beschrieben werden. Dazu werden PDM´s, die Plattform Description Models, verwendet. . Es gibt noch keine standardisierte Transformationssprache, aber ein Request for Proposal für Query/Views/Transformations (QVT). Ziel ist es Transformationen zwischen Quell- und Ziel-Metamodell für Modell-zu-Modell-Transformationen zu beschreiben. So detailliert die MDA beschrieben werden kann, so problematisch ist aber im Gegenzug ihre (alleinige) Praxistauglichkeit. Die reine, vollständige Anwendung, ist laut Stahl et. al. [9] nicht ohne weiteres möglich. Sie postulieren den Vergleich dass man sich nur vor Augen führen muss wie lange es gedauert hat bis wirklich praxistaugliche UML-Tools auf dem Markt waren. Unter anderem gehen sie auch auf den Aspekt der Interopabilität ein, der die Fähigkeit zur Zusammenarbeit von verschiedenen Systemen beschreibt. Die modellgetriebene Softwareentwicklung (MDSD) an sich benötigt die Eigenschaft der Interopabilität nicht zwangsläuftig. Für MDA ist sie von zentraler Bedeutung, weil sonst viele ihrer Ziele nicht realisiert werden können. Einführung in die modellbasierte Softwareentwicklung 4 15 Anwendung modellbasierte SE: MDSD - Abgrenzung und Möglichkeiten Es werden nun zwei Vorgehensmodelle für die modellbasierte Softwareentwicklung erörtert. Es wird sich aber zeigen das allein die Anwendung dieser Modelle keine Garantie bietet dass ein Softwareprojekt erfolgreich ist. Im folgenden sollen Anhand des . V-Modell XT des BSI (Beauftragte der Bundesregierung für Informationstechnik) und des . Rational Unified Process (RUP) der Firma Rational Abgrenzung und Möglichkeiten für die modellbasierten Softwareentwicklung aufgezeigt werden. Das V-Modell XT des Bundes ist ein generisches Vorgehensmodell zum Planen und Durchführen von Entwicklungsprojekten[10]. Dieses Vorgehensmodell soll dazu genutzt werden, dass die komplette Software-Entwicklung und das Software-Management abgedeckt werden können. Von ihm werden dafür die Aktivitäten und Ergebnisse, die während der Entwicklung von Systemen durchzuführen bzw. zu erstellen sind definiert. Bestimmte Aufgaben des Projektes, wie z.b. das Projektmanagement, werden durch verschiedene verpflichtende und optionale Vorgehensbausteine wie Aktivitäten, Produkte und Rollen vorgegeben. Eine zeitliche Ablaufreihenfolge wird erst durch Strategien für die Projektdurchführung vorgegeben. Laut Trompeter et. al. [10] kommen Petrasch und Fieber zu dem Ergebnis, dass sich die vorhandenen Durchführungsstrategien des V-Modells nicht ohne Änderungen für MDA-Projekte anwenden lassen, da entscheidende Meilensteine aus dem MDA Guide der OMG nicht als so genannte Entscheidungspunkte im V-Modell XT abgebildet sind. Um das V-Modell an eigene Bedürfnisse anzupassen wurde mit der Version XT im Jahr 2005 das so genannte Tailoring eingeführt. Dies rechtfertigt auch das Suffix XT = Extreme Tailoring. Zum Stand dieser Arbeit (April 2009) ist die Version 1.3 des V-Modell XT aktuell: http://vmodell.iabg.de/dmdocuments/V-Modell-XT-Gesamt-Deutsch-V1.3.pdf. Mit Hilfe der Möglichkeit des Tailoring kann man Anpassungen an den Vorgehensbausteinen und Durchführungsstrategien im V-Modell XT vornehmen. Trompeter et. al.[10] unterstellen dem V-Modell XT die Fähigkeit für ein modellgetriebenes Vorgehen geeignet zu sein, wenn an ihm Anpassungen bzw. Erweiterungen vorgenommen werden. Diese Änderungen sollen an bestimmten Entscheidungspunkten ansetzten. Kapitel 3.3 beschreibt die Platform Independent Models, und wie in der Vorgehensweise beschrieben wurde braucht das iterative Vorgehen des MDAAnsatzes den Entscheidungspunkt PIM erstellt. Vollständigkeitshalber wird auch die positive Bestätigung dieses Vorganges PSM erstellt eingefügt. Damit wird deutlich dass das V-Modell XT grundsätzlich geeignet ist für die modellgetriebene Softwareentwicklung. Der Rational Unified Process (RUP) ist ein objektorientiertes Vorgehensmodell zur Softwareentwicklung. Der RUP wurde 1996 von der Firma Rational 16 P. Stadler Software, welche mittlerweile zu IBM gehört, vorgestellt. Die Vorgehensweise des RUP ist iterativ, architekturzentriert, klar definiert und strukturiert. Das zentrale Element der RUP ist die Unified Modelling Language. Laut Trompeter et. al. [10] ist der Rational Unified Process eine konkrete Implementierung des Unified Process; ein Metamodell für Vorgehensmodelle. Der praktische Einsatz des Rational Unified Process für die modellbasierte Softwareentwicklung lässt sich anhand einiger Gemeinsamkeiten ausmachen. Der Ansatz der modellbasierten Softwareentwicklung sowie der Model Driven Architecture zeigt durch seine Kompabilität zur Unified Modeling Language die Gemeinsamkeit zum Rational Unified Process, da dieser komplett darauf basiert. Dies verwundert nicht denn die Urväter der UML (G. Booch, I. Jacobson und J. Rumbaugh) entwickelten parallel zur UML den Unified Process. Das iterative Vorgehen des RUP zeigt ebenso die Verwendungsmöglichkeiten für die modellbasierte Softwareenwicklung die diese iterative Vorgehensweise auch voraussetzt, siehe Abb. 6. Der RUP bietet ebenso wie das V-Modell XT die Möglichkeit das Modell für eigene Bedürfnisse anzupassen. Dadurch kann, laut Trompeter et. al., für einen modellgetriebenen Ansatz die Elaborations-Phase, also die konkrete Umsetzung angepasst werden, um den Grundstein für die Systemarchitektur zu legen. 5 Kritische Würdigung und Fazit Die Recherche für diese Arbeit hat gezeigt das Modellierung mehr ist als UML. Die Unified Modelling Language ist zwar, bis jetzt, der erfolgreichste und am weitesten verbreiteste Ansatz für Modellierung aber es zeigt sich doch das der Wunsch besteht für jedes erdenkliche Anwendungsgebiet die optimale Modellierungssprache zu finden. Die modellgetriebene Softwareentwicklung ist ein vergleichsweise junger Entwicklungszweig der das Ziel verfolgt einen durchgängigen Entwicklungsprozess für eine möglichst weitgehende Automatisierung der Softwareherstellung zu erreichen. Im Kern von MDSD stehen formale, durch einen Generator auswertbare Modelle, aus denen weite Teile eines Softwaresystems automatisiert erzeugt werden. Die entscheidenden Vorteile der modellgetriebenen Softwareentwicklung sind Produktivitätssteigerungen und insbesondere Qualitätsverbesserungen für die langfristige Wartbarkeit der Softwaresysteme. In Kap. 4 wurde gezeigt das sich etablierte Vorgehensmodelle wie der Rational Unified Process für einen modellgetriebenen Entwicklungsansatz anpassen lassen können. Vergleichend lässt sich feststellen das der reine Ansatz der MDSD wohl mehr Potential hat sich in der Zukunft durchzusetzten da er Open-Source und flexibel ist. Die MDA ist sehr stark abhängig von den Richtlinien zur UML, OCL und der Meta Object Facility. Literatur [1] F. P. Brooks Jr.. No Silver Bullet: Essence and Accidents of Software Engineering. Computer, 20(4):1–2, April 1986. Einführung in die modellbasierte Softwareentwicklung 17 [2] N. de Lange. Grundlagen aus der Informatik. Springer, 2005. [3] G. Disterer, F. Fels, and A. Hausotter. Taschenbuch der Wirtschaftsinformatik. Hanser, 2002. [4] J. Hackmann. Der deutsche It-markt steht vor einer Rezession. Computerwoche/2008, December 2008. [5] Jon Siegel. Developing in Omg Model-Driven Architecture. Object Management Group White Paper, 2.6:12, 2001. [6] M. Kempa and Z. A. Mann. Modell Driven Architecture. Informatik Spektrum, 28(4):298–302, August 2005. [7] J. Seemann and J. W. von Gudenberg. Software-Enwurf mit der UML2. Springer/Xpert.press, 2006. [8] H. Stachowiak. Allgemeine Modelltheorie. Spektrum, 1973. [9] T. Stahl and M. Völter. Modellgetriebene Softwareentwicklung: Techniken, Engineering, Management. Dpunkt, 2005. [10] J. Trompeter and G. Pietrek. Modellgetriebene Softwareentwicklung MDA und MDSD in der Praxis. Software & Support, 2007. [11] K. D. Wüsteneck. Zur philosophischen Verallgemeinerung und Bestimmung des Modellbegriffs. Deutsche Zeitschrift für Philosophie, 12(12):1504, 1963. [12] K. Zeppenfeld and R. Wolters. Generative Software-Entwicklung mit der MDA. Springer, 2005. Grundlagen der modellbasierten Testfallgenerierung Markus Bickelmaier Universität Augsburg Zusammenfassung In dieser Seminararbeit werden Möglichkeiten zum automatisierten Erkennen von Softwarefehlern untersucht. Die Betrachtung führt hin zum Begriff des modellbasierten Testens. Neben einem Einblick in die Grundlagen dieser Testmöglichkeit werden aber auch andere Testansätze aufgegriffen. Stellvertretend für alternative Testansätze wird das sourcecodebasierte Testen am Beispiel eines JUnit Tests vorgestellt. Das Verfahren des modellbasierten Testens wird in seiner Grundidee und seiner darauf aufbauenden Struktur beschrieben. Dabei werden die Unterschiede und Vorteile des modellbasierten Testens gegenüber anderen Testverfahren diskutiert und untersucht. An praktischen Beispielen wird die Prüfung einer Software unter verschiedenen Aspekten vorgestellt. Die Generierung der Testfälle kann dabei sowohl aus statischen als auch dynamischen Modellen heraus erfolgen. Auf die Unterschiede und Möglichkeiten zwischen den aus statischen und dynamischen Modellen erzeugbaren Tests wird eingegangen. Abschließend werden (nicht-)kommerzielle Tools vorgestellt, die die Modellierung und die Generierung von modellbasierten Tests wesentlich unterstützen können. Anhand eines einfachen Beispiels wird die Anwendung verdeutlicht. Grundlagen der modellbasierten Testfallgenerierung 1 19 Einführung Die Komplexität von Softwaresystemen steigt immer weiter. Softwarefehler die zu spät erkannt werden verursachen hohe, unnötige Kosten, sowie einen Mehraufwand zur Beseitung dieser. Entdeckt man diese Fehler jedoch frühzeitig, so ist die Beseitigung einfacher, die Wahrscheinlichkeit von Folgefehlern oder abgeleiteten Fehlern geringer und das Produkt wesentlich preiswerter. Ein Lösungsversuch Fehler bereits in der Modellierungsphase aufzuspüren ist das modellbasierte Testen. Modellbasierte Tests werden aus (bestehenden) Modellen eines SUT1 gewonnen und testen vorrangig die Umsetzung der Spezifikation im Design. Als Ergebnis zeigen sich, abhängig von der Komplexität des zu entwicklenden Softwaresystems, geringere Kosten in der Entwicklung, weniger Fehler in der Implementierung und qualitativ bessere und verlässlichere Software. Zudem verfügen Entwickler mit modellbasierten Tests über ein starkes Zertifizierungswerkzeug. 2 Testen von Software 2.1 Sourcecodebasiertes Testen 2.1.1 Was ist sourcecodebasiertes Testen? Sourcecodebasiertes Testen beschäftigt sich, wie der Name schon sagt, mit dem Testen eines SUT, wobei die verwendeten Tests direkt als Sourcecode vorliegen. Es müssen also keinerlei Modelle zu diesen Tests oder der Software an sich existieren. Ein sehr einfaches Beispiel für sourcecodebasiertes Testen ist das Hinzufügen einer main-Methode in einer Java Klasse um die Funktionalität der Klasse mit simulierten Daten zu überprüfen. Dies ist natürlich eine stark vereinfachte Betrachtungsweise, denn korrekt durchgeführte, toolgestützte sourcecodebasierte Tests bieten eine solide Grundlage für stabile und fehlerfreie Software. Da bei sourcecodebasierten Tests vollständiges, oder nahezu vollständiges Wissen über die Funktionsweise des SUT angenommen werden eignen sich diese besonders für White-Box Tests2 , jedoch sind logischer Weise auch Black-Box Tests3 möglich. 2.1.2 Beispiel: JUnit JUnit ist ein Test-Framework für die Programmiersprache Java. JUnit Tests sind Unit Tests, also Tests einzelner Units wie Methoden oder Klassen eines Softwareprojekts. Das Kernprinzip von JUnit Tests sind Zusicherungen, sogenannte Asserts, die entweder wahr oder falsch sein können [14]. Ein Beispiel hierfür wäre Assert.assertEquals(„Test“, 6, 3 * 2). Dies würde true liefern, falls die JVM 3*2 zu 6 berechnet und ansonsten false [3]. 1 2 3 System under Test; Das zu testende System White-Box Tests sind Tests bei denen Informationen über innere Abläufe eines SUT vorliegen und diese somit in den Testablauf mit einbezogen werden können [1]. Black-Box Tests sind Tests bei denen nur nach aussen sichtbare Schnittstellen bekannt sind, jedoch keinerlei Wissen über interne Abläufe eines SUT besteht [2]. 20 M. Bickelmaier Die Idee hinter den JUnit Tests ist, dass nichts implementiert wird was nicht auch getestet wurde. Dies hat den Vorteil, dass ein Programmierer der neu zu einem bestehenden Softwareprojekt hinzukommt, oder einfach Änderungen an bestehender Software vornehmen möchte, zunächst alle JUnit Tests durchführt. Liefern alle Tests true zurück, so weiß der neue Programmierer, dass der Code zu Beginn seiner Arbeit, fehlerfrei war. Liefern einige Tests nach seinen Änderungen false zurück, so sind diese Fehler mit Sicherheit auf den von ihm geänderten Code zurückzuführen. Ein weiterer Vorteil ist in der Übersichtlichkeit der Überprüfung zu sehen. Strebt man eine möglichst geringe Größe der zu prüfenden Units an, so lassen sich eventuelle Fehler leichter lokalisieren. Liefert ein JUnit test false zurück, so liegt der Fehler mit hoher Wahrscheinlichkeit in dieser Unit [16]. import org.junit.*; public class MultiplicationTest { /** Test whether 3 * 2 = 6, according to the JVM. */ @Test public void testMultiplication() { Assert.assertEquals("Multiplication", 6, 3 * 2); } } Abbildung 1. Beispiel eines JUnit Tests 2.2 Modellbasiertes Testen 2.2.1 Was ist modellbasiertes Testen Modellbasiertes Testen beschreibt das Testen eines SUT, wobei die verwendeten Tests teilweise oder vollständig aus Modellen generiert werden (siehe Abbildung 2). Das Modell eines Tests beschreibt diesen abstrakt, ist also nicht lauffähig. Damit ein modellierter Test lauffähig wird muss er über Modelltransformationen in einen ausführbaren Test umgewandelt werden (z.B. das Erzeugen lauffähigen Codes aus UML-Diagrammen; siehe auch Abbildung 3) [4]. Da diese Tests auf der Grundlage von Modellen gewonnen werden und nicht aus dem eigentlichen Sourcecode des SUT, spricht man im Zusammenhang mit modellbasierten Tests oft auch von Black-Box Tests. Es können jedoch auch Aspekte des Testens auf Sourcecodeebene einbezogen werden, so dass hier eine Mischform von Black-Box und White-Box Testen entstehen kann (Gray-Box Testen) [12]. Man unterscheidet bei der Durchführung modellbasierter Test grundsätzlich zwischen Online und Offline Tests. Von einem Onlinetest spricht man, wenn sich das Test-Tool direkt zum SUT verbindet und dynamisch generierte Tests automatisch auf diesem durchführt. Dies ist vor allem für längere und größere Testreihen von Vorteil, da man diese ohne jegliche Betreuung längere Zeit, Grundlagen der modellbasierten Testfallgenerierung 21 Abbildung 2. Testfallgenerierung aus Modellen [13] z.B. über Nacht, laufen lassen kann um am Ende die gesammelten Ergebnisse abzurufen. Von einem Offlinetest spricht man, wenn die Tests in einem maschinenlesbaren Format erzeugt und gespeichert werden. Dies hat den Vorteil dass man spezielle Tests gezielt durchführen kann wann immer diese benötigt werden. Es ist ebenfalls mögliche die generierten Tests automatisiert durchzuführen, um so längere Prüfläufe zu absolvieren [15]. 2.2.2 Unterschiede zum sourcecodebasierten Testen Zwar beanspruchen sowohl das sourcecodebasierte, als auch das modellbasierte Testen den Vorteil der Wiederverwendbarkeit, auch im laufenden Entwicklungsprozess, für sich, jedoch wird, betrachtet man die Grundlage auf der die beiden Arten von Tests aufgebaut sind, relativ schnell deutlich, dass man beim sourcecodebasierten Testen recht schnell in Gefahr läuft den Überblick zu verlieren. Tests werden einmal verfasst und zu größeren Testsuites zusammengefasst. Mit steigender Komplexität eines SUT erhöht sich die Anzahl der Testsuites. Es ist jedoch klar, dass sich das (manuelle) Anpassen jeder einzelnen Testsuite bedeutend aufwändiger gestaltet, als ein paar Modelle anzupassen und sich sämtliche Testsuites neu und zu dem aktuellen Stand der Software passend, generieren zu lassen. Dies wird deutlicher, je größer die Änderung am System ist. Da die Generierung und Durchführung der modellbasierten Tests automatisiert und ohne personelle Betreuung erfolgen kann, spart dies Kosten und Zeit. Ein weiterer Unterschied liegt aber auch in den Vorausetzungen zum Testen. Beim sourcecodebasierten Testen kann nur getestet werden was bereits programmiert wurde. Das bedeutet, dass je weiter der Softwareentwicklungsprozess 22 M. Bickelmaier voranschreitet, auch immer neue Tests entstehen. Man wird quasi zu einem parallelen Vorgehen gezwungen. Beim modellbasierten Testen stehen jedoch bereits von Anfang an alle Modelle, bevor auch nur eine Zeile Sourcecode programmiert wurde. Das heißt, dass bereits in einer sehr frühen Phase des Entwicklungsprozesses das SUT auf seine gewünschten Eigenschaften getestet werden kann. Auf diese Weise lässt sich ein Design frühzeitig gegen die vorgegebene Spezifikation verifizieren. Findet man in dieser Phase des Entwicklungsprozesses bereits Fehler, die sonst erst wesentlich später entdeckt worden wären, lassen sich diese bedeutend kosteneffizienter und einfacher beseitigen. Ein weiterer Vorteil des modellbasierten Testens liegt darin, dass gleichzeitig ein Modell des erwarteten Nutzerverhaltens entsteht (siehe auch Kapitel 2.5.2). Mit beiden Untersuchungsmethoden steht ein wertvolles Werkzeug zum Nachweis der Funktion, insbesondere gegenüber Dritten und Kunden zur Verfügung. Sourcecodebasierte Tests beschränken sich meist auf die fehlerfreie Funktion einer Software. Modellbasierte Tests jedoch können zudem zertifizieren dass gegebene Spezifikationen eingehalten wurden. Abbildung 3. Ablauf eines Tests [10] 2.3 Ableiten von Testfällen aus statischen Modellen Statische Modelle beschreiben den grundsätzlichen Aufbau des SUT, sagen allerdings nichts über das Verhalten des SUT aus. Die statischen Modelle eignen Grundlagen der modellbasierten Testfallgenerierung 23 sich deshalb vorrangig dazu Schwächen und Fehler in der Struktur eines SUT aufzudecken. Hier kann man also überprüfen ob ein SUT prinzipiell „dem ersten Anschein“ nach eine Spezifikation erfüllt, bzw überhaupt erfüllen kann. 2.3.1 Klassendiagramm Klassendiagramme eignen sich besonders gut, um die theoretische Korrektheit eines SUT zu testen, da in ihnen sämtliche strukturellen Informationen des SUT festgehalten sind. Zu diesen Informationen gehören Abhängigkeitsklauseln zwischen Klassen. Diese Klauseln wiederum ermöglichen Tests der Initialisierbarkeit dieser Klassen. Assoziationen geben Aufschluss über Beziehungen zwischen Klassen und deren Realisierbarkeit. Besonders spannend sind die Schnittstelleninformationen eines SUT. Diese lassen beispielsweise Tests auf Existenz einzelner Methoden (Method-Coverage) und ihrer Sichtbarkeit zu. Dazu wird einfach versucht alle Methoden der Reihe nach aufzurufen [11]. 2.4 Ableiten von Testfällen aus dynamischen Modellen Dynamische Modelle haben gegenüber statischen Modellen den Vorteil, dass in ihnen, wie der Name schon sagt, Informationen über das dynamische Verhalten eines SUT festgehalten sind. Dies bietet die Möglichkeit Benutzerinteraktionen mit dem SUT zu simulieren und zu testen. Auf diese Weise erhält man einerseits Tests die besonders für Code- / Method- und Action-Coverage geeignet sind. Andererseits wird während dem Testen bereits auch schon das erwartete Benutzerverhalten simuliert und es können Schwachstellen oder Abweichungen im gewünschten Verhalten des SUT entdeckt werden. Es werden nun einige Verfahren vorgestellt wie aus unterschiedlichen Vertretern von dynamischen Modellen Testfälle generiert werden können. 2.4.1 Finite-State-Machine (FSM) Hier gibt es mehrere Möglichkeiten Tests abzuleiten. Je nachdem welche Ziele verfolgt werden bieten sich unterschiedliche Algorithmen zur Testfallgenerierung an. Das Ableiten von Testfällen aus FSM wird anhand eines simplen Telefonsystem veranschaulicht. Beispielsweise besteht die Möglichkeit eine Testsequenz abzuleiten, welche jede verfügbare Aktion in jedem Zustand mindestens einmal ausführt (Action Coverage). Tabelle 1 zeigt eine mögliche solche Testsequenz. 24 M. Bickelmaier Abbildung 4. FSM eines einfachen Telefonsystems [7] Aktion Zustand Bereit Abheben Freizeichen Wählen / Gegenüber belegt Belegt Auflegen Bereit Abheben Freizeichen Wählen / Gegenüber bereit Klingeln Auflegen Bereit Abheben Freizeichen Aktion Zustand Wählen / Gegenüber bereit Klingeln Gegenüber hebt ab Sprechen Gegenüber legt auf Freizeichen Auflegen Bereit Abheben Freizeichen Wählen / Gegenüber bereit Klingeln Gegenüber hebt ab Sprechen Auflegen Bereit Tabelle 1. Test Sequenz zum erreichen von Action-Coverage [7] Grundlagen der modellbasierten Testfallgenerierung 25 Betrachtet man einen Test als eine zusammenhängende Sequenz von Aktionen die jeweils im Zustand „Bereit“ beginnen und enden, so sind in obiger Tabelle also vier Testfälle enthalten. Es ist durchaus möglich dass eine, durch einen anderen Algorithmus, abgeleitete Testsequenz aus mehr oder weniger solcher Einzeltests bestehen kann [10]. Ein Testfall sollte erwartete Ausgabewerte angeben, ebenso wie die Sequenz der Eingaben. Ginge man davon aus, dass dieses Telefonsystem so konfiguriert wäre, dass es selbst seine Zustände ausgibt, so bräuchte man in diesem Fall kein seperates Testorakel, da diese Funktion bereits die FSM übernehmen würde. Action-Coverage ist das einfachste zu testende Kriterium einer FSM. Ein weiteres wichtiges Kriterium ist das Switch-Coverage Kriterium. Dieses ist erfüllt wenn jedes Tupel von Aktionen (Aktion in den Zustand, Aktion aus dem Zustand) durch die Testsequenz überprüft wird. Eines dieser Tupel wäre beispielsweise: (Gegenüber hängt auf, Wählen / Gegenüber bereit). Dieses Tupel ist nicht in Tabelle 1 enhalten. Mithilfe von Switch-Coverage kann man unter anderem zeigen, dass ein System Deadlock frei ist. Genau wie bei Action-Coverage sind auch hier Testfälle nicht eindeutig bestimmt, je nachdem welche Pfadfindungsalgorithmen man verwendet [7]. 2.4.2 Sequenzdiagramm Sequenzdiagramme haben den Vorteil, dass in ihnen nicht nur Informationen über Methodenaufrufe festgehalten sind, sondern auch Interaktionen mit anderen Objekten. Ausserdem sind Sequenzdiagramme über, in OCL definierte, Bedingungen dahingehend erweiterbar, dass Objektzustände während der Laufzeit überprüft werden können [13]. Testfälle die aus Sequenzdiagrammen generiert werden spielen Schritte der Sequenzdiagramme ab. Sie vergleichen erhaltene Ergebnisse mit den Ergebnisse die in Sequenzdiagrammen enthalten sind oder mittels Testorakel generiert wurden. Um einen Testfall aus einem Sequenzdiagramm zu generieren, interpretiert man die Nachrichten des Sequenzdiagramms. Dabei werden Systemfunktionen, also vom Akteuer zum System gehende Nachrichten, zu Testschritten des Testfalls. Systemreaktionen, also vom System zum Akteur gehende Nachrichten, dienen dem Ergebnisabgleich und der Verifikation. Die interne Interaktion zwischen Subsystemen kann, abhängig von der Testtiefe, auf die gleiche Weise mit einbezogen werden [8]. 26 M. Bickelmaier Abbildung 5. Testfallgenerierung aus Sequenzdiagrammen 2.4.3 Aktivitätsdiagramm Die Pfade durch den Graphen des Aktivitätsdiagramms sind die einzelnen Testfälle. Welche Pfade gewählt werden wird durch das zu bestimmende Überdeckungskriterium bestimmt. Will man MethodCoverage testen, so wird man Graphen wählen, welche alle Zustände enthalten. Für Transition-Coverage hingegen wird man Graphen wählen die alle Pfade / Transitionen im Graphen enthalten. Wie schon in der FSM, so gibt es auch hier, abhängig vom Pfadfindungsalgorithmus, wieder sehr viele, unterschiedliche Testfälle. Auch hier werden, wie bei Sequenzdiagrammen, die Systemfunktionen wieder zu Testschritten. Die Ergebnisse von Systemreaktionen werden wiederum mit den erwarteten Ergebnissen verglichen. Aktivitätsdiagramme weisen eine Ähnlichkeit zur mathematischen Grundlage von Petrinetzen auf. Es ist also relativ einfach mit formalen Methoden bestimmte Eigenschaften zu validieren. Zu diesen zählen unter anderem DeadlockSituationen, Abhängigkeiten, Vollständigkeiten und Zyklen [8]. Grundlagen der modellbasierten Testfallgenerierung 2.5 27 Toolgestützes modellbasiertes Testen Toolgestütztes modellbasiertes Testen bietet weitere Vorteile. Dazu gehören die Bereitstellung von Informationen über die durchgeführten Tests und deren Ergebnisse in aufbereiteter Form. Durch eine automatisierte Durchführung können ausserdem Personalkosten gespart werden. Sie können ohne Aufsicht über Nacht laufen, oder parallel zum Entwicklungsprozess durchgeführt werden. Dies hat wiederum eine Zeitersparnise zur Folge. Die Algorithmen zur Testfallgenerierung können des weiteren teilweise sehr komplex sein (siehe 2.4.1). Dies kann bei einer manuellen Durchführung zu einer erhöhten Fehleranfälligkeit führen. Tools hingegen führen solche Tätigkeiten verlässlich und vollautomatisch durch. Hierbei gibt es auch die Möglichkeit Prüfprotokolle erstellen zu lassen, welche als Nachweise gegenüber Dritten (dem Kunden) als Zertifizierungswerkzeug dienen können. 2.5.1 Conformiq Qtronic Conformiq Qtronic von der Firma Conformiq Software Ltd (www.conformiq.com) wird als Plugin für die Entwicklungsumgebung Eclipse vertrieben. Es unterstützt sowohl das Einbinden bestehender Modelle, beispielsweise mit Rhapsody erzeugte UML Diagramme, als auch die Erstellung eigener Prüfmodelle. Conformiq Qtronic unterstützt den modellbasierten Testvorgang auf Basis von UML Diagrammen [5] sowie der Java Action Language. Conformiq Software Ltd vertreibt sowohl eine Version für Windows als auch eine für Linux. 28 M. Bickelmaier Abbildung 6. Anlegen einer State Machine Abbildung 7. Festlegen der Testziele Grundlagen der modellbasierten Testfallgenerierung 29 Abbildung 8. Durchführen der Tests und Ausgabe der Ergebnisse Conformiq Qtronic ist kostenpflichtig, jedoch gibt es die Möglichkeit eine vergünstigte akademische Lizenz für eine nicht-kommerziellen Nutzung zu erwerben. Unabhängig davon besteht die Möglichkeit eine kostenfreie Testversion zu erhalten [9]. 2.5.2 ModelJUnit ModelJUnit (czt.sourceforge.net/modeljunit/) ist ein Testframework mit dem Ziel die Ideen von JUnit Tests in den Bereich des modellbasierten Testens zu übertragen. In ModelJUnit werden FSM oder EFSM als Javaklassen geschrieben. Aus diesen Klassen werden anschließend Tests generiert. ModelJUnit ist derzeit sowohl als jar-Datei als auch als Eclipse-Plugin verfügbar. ModelJUnit ist kostenfrei von der Homepage der Entwickler herunterladbar. ModelJUnit kann Überdeckungskriterien testen, sowie deren Ergebnisse in ausgewerteter und „roher“ Form ausgeben. Ein weiteres Feature von ModelJUnit ist die Ausgabe von .dot Dateien, welche mit Visualisierungstools wie zum Beispiel Graphviz (www.graphviz.org) grafisch ausgewertet werden können (siehe Abbildung 9) [6]. Nachfolgend wird am Beispiel der Handlungsabläufe an einem Snack-Automaten der Ablauf eines ModelJUnit Tests veranschaulicht. Der Automat unterstützt das Einwerfen von 25 und 50 Cent. Für den Kauf sind 100 Cent erforderlich. 30 M. Bickelmaier Abbildung 9. Der von ModelJUnit während des Testens erzeugte Graph import net.sourceforge.czt.modeljunit.*; public class VendingMachineModel implements FsmModel { private int state = 0; // 0..2 public VendingMachineModel() { state = 0; } public String getState() { return String.valueOf(state); } public void reset(boolean testing) { state = 0; } public boolean vendGuard() { return state == 100; } public @Action void vend() { state = 0; } public boolean coin25Guard() { return state <= 75; } public @Action void coin25() { state += 25; } public boolean coin50Guard() { return state <= 50; } public @Action void coin50() { state += 50; } } Abbildung 10. Anlegen einer FSM in ModelJUnit Grundlagen der modellbasierten Testfallgenerierung 31 public static void main(String[] args) { Tester tester = new RandomTester(new VendingMachineModel()); tester.buildGraph(); ArrayList<CoverageMetric> metric = new ArrayList<CoverageMetric>(); metric.add(new ActionCoverage()); metric.add(new StateCoverage()); metric.add(new TransitionCoverage()); metric.add(new TransitionPairCoverage()); for (CoverageMetric cm : metric) { tester.addCoverageMetric(cm); } tester.addListener("verbose"); tester.generate(20); System.out.println("Metrics Summary:"); for (CoverageMetric cm : metric) { tester.getModel().printMessage(cm.getName() + " was " + cm); } GraphListener graphListener = tester.getModel().getGraphListener(); graphListener.printGraphDot("vending.dot"); System.out.println("Graph contains " + graphListener.getGraph().numVertices() + " states and " + graphListener.getGraph().numEdges() + " transitions."); } Abbildung 11. Testen einer FSM in ModelJUnit 32 M. Bickelmaier done (0, coin50, 50) done (50, coin25, 75) done (75, coin25, 100) done Random reset(true) done (0, coin50, 50) done (50, coin25, 75) done (75, coin25, 100) done (100, vend, 0) done (0, coin50, 50) done (50, coin50, 100) done (100, vend, 0) done (0, coin25, 25) done (25, coin25, 50) done Random reset(true) done (0, coin50, 50) done (50, coin25, 75) done (75, coin25, 100) done (100, vend, 0) done (0, coin50, 50) done (50, coin25, 75) ================================== Metrics Summary: action coverage was 3/3 state coverage was 5/5 transition coverage was 7/8 transition-pair coverage was 8/12 ================================== Graph contains 5 states and 8 transitions. Abbildung 12. Ergebnis des ModelJUnit Tests Grundlagen der modellbasierten Testfallgenerierung 3 33 Ergebnisse In der Betrachtung zeigten sich wichtige Vorteile der Methode des modellbasierten Testens im Vergleich zur Alternative des sourcecodebasierten Testen. Bei der Erstellung komplexer Softwarelösungen ist es immer das Ziel etwaige Programmfehler in der neuen Software so früh wie möglich zu erkennen. Die Prüfung soll dabei durch übersichtliche und klar strukturierte Testmodelle vorgenommen werden und nach Möglichkeit bereits erste Nachweise für die Erfüllung der Spezifikation gegenüber dem Auftraggeber liefern. Hier zeigten sich die Stärken des modellbasierten Testens. Auf dem Markt befinden sich bereits geeignete Softwaretools, die das Erstellen von modellbasierten Tests unterstützen. Die Testsuites lassen sich damit relativ einfach aus den Designdiagrammen generieren. Das hat den Vorteil, dass man auch dem Auftraggeber gegenüber, relativ früh das spätere Funktionsverhalten modellieren und simulieren kann. Aus diesem Grund sollte das Verfahren des modellbasierten Testens in jedem umfangreicheren Softwareprojekt eingesetzt werden. Literatur [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15] [16] http://en.wikipedia.org/wiki/White_box_testing. http://en.wikipedia.org/wiki/Black_box_testing. http://en.wikipedia.org/wiki/Junit. http://en.wikipedia.org/wiki/Model-based_testing. http://en.wikipedia.org/wiki/Model-based_testing_tools. http://www.cs.waikato.ac.nz/ marku/mbt/modeljunit/. Software acquisition gold practice: Model-based testing. Software Acquisition Gold Practice, 2004. http://www.goldpractices.com/practices/mbt/. T. Q. Benjamin Wilmes, Natalia Freijnik. Modellbasiertes testen (ableiten von tests aus anwendungsfällen, aktivitätsdiagrammen und statecharts), klassifikationsbaummethode, testwerkzeuge. Technical report, TU Berlin, 2008. Conformiq Ltd. Conformiq Qtronic - Automate Test Design. http://www.conformiq.com/qtronic.php. I. K. El-Far and J. A. Whittaker. Model-based software testing. Technical report, Florida Institute of Technology, 2001. M. Köhler. Uml-basiertes testen. Technical report, Eberhard-Karls-Universität Tübingen, 2006. S. Lawalata. Study literature of model-based testing for test integrity. Technical report, TU Hamburg Harburg, 2006. B. Rumpe. Model-based testing of object-oriented systems. Technical report, IRISA-Université de Rennes, TU München. J. Tulach. Practical API Design - Confessions of a Java Framework Architect. Apress, 2008. M. Utting. Position paper: Model-based testing. Technical report, University of Waikato, 2005. F. Westphal. Extreme programmer, unit tests mit junit. FrankWestphal.de, 2001. http://www.frankwestphal.de/UnitTestingmitJUnit.html. Evaluierung der Potentiale des Eclipse Process Frameworks Robert Freudenreich Universität Augsburg [email protected] Zusammenfassung Diese Seminararbeit evaluiert die Potentiale des Eclipse Process Framework. Es wird zunächst auf die Entwicklungsprozesse RUP, Scrum und OpenUP eingegangen sowie das Metamodell UMA und der EPF Composer thematisiert. Es folgt eine Erörterung der Anwendungsgebiete und Best Practices bevor mit einer prototypischen Implementierung die Erweiterbarkeit des EPF demonstriert wird. 1 Einleitung Als es noch keine Rechner gab, war auch das Programmieren noch kein Problem, als es dann ein paar leistungsschwache Rechner gab, war das Programmieren ein kleines Problem und nun, wo wir gigantische Rechner haben, ist auch das Programmieren zu einem gigantischen Problem geworden. Dieses Zitat von Edsger Dijkstra [1] beschreibt mit einfachen Worten die Explosion der Komplexität der Softwareentwicklung, der sich die Softwareindustrie durch die Dynamik der Hardware-Entwicklung, die zunehmende Zerstreuung der Entwicklungsteams sowie immer komplexeren und integrierteren SoftwareSystemen ausgesetzt ist. In [8] wird diese Explosion mit dem Faktor 50 innerhalb von 10 Jahren quantifiziert. Um diese Komplexität beherrschen zu können, werden Softwareentwicklungsprozesse eingesetzt. 2 Softwareentwicklungsprozesse Liggesmeyer beschreibt einen Softwareentwicklungsprozess in [11] als „eine zielorientierte Aktivität zur Erzeugung eines Produktes oder zur Durchführung einer anderen Aufgabe im Rahmen der ingenieurmäßigen Softwareentwicklung“. Die Grundlage für solche Prozesse sind Vorgehensmodelle, mit deren Entwicklung sich die Disziplin des Software-Engineering befasst. Dabei unterscheidet man klassische schwergewichtige und agile leichtgewichtige Vorgehensmodelle. Klassische Vorgehensmodelle eignen sich für große Entwicklungsprojekte und sind eher statisch und dokumentationslastig - Beispiele sind das Wasserfallmodell, V-Modell oder der Rational Unified Process. Agile Vorgehensmodelle eignen sich hingegen für kleinere und mittlere Entwicklungsprojekte und sind eher flexibel und anpassungsfähig - Beispiele sind Extreme Programming, Scrum und der Open Unified Process. Evaluierung der Potentiale des EPF 2.1 35 Rational Unified Process Der Rational Unified Process (RUP) ist ein iteratives und inkrementelles, aber dennoch klassisches Vorgehensmodell, das Anwendungsfall- und Architekturgetrieben ist. Es verwendet als Sprache die Unified Modeling Language (UML) und basiert auf diversen Erfahrungen der Softwareentwicklung, die sich in den folgenden sechs Software Best Practices wiederspiegeln: 1. 2. 3. 4. 5. 6. Iterative Software-Entwicklung Anforderungsmanagement Verwendung komponentenbasierter Architekturen Visuelle Software-Modellierung Prüfung der Software-Qualität Kontrolliertes Änderungsmanagement Der Lebenszyklus des RUP besteht aus vier Phasen1 , welche wiederum in Iterationen unterteilt sind und an deren Ende jeweils ein Meilenstein erreicht wird. Aufgaben innerhalb einer Iteration sind sechs Kern-Workflows2 und drei unterstützenden Workflows3 zugeordnet, die in jeder Iteration unterschiedlich intensiv angewandt werden. Abbildung 1 veranschaulicht diese Zusammenhänge. Abbildung 1. Workflows und Phasen des Rational Unified Process [10] 1 2 3 Inception, Elaboration, Construction und Transition Business Modeling, Requirements, Analysis & Design, Implementation, Test, Deployment Configuration & Change Management, Project Management und Environment 36 R. Freudenreich 2.2 Scrum Scrum ist ein agiles Vorgehensmodell mit kurzen, iterativen Entwicklungszyklen, das von Ken Schwaber, Jeff Sutherland und Mike Beedle erfunden wurde. Die Grundlage für agile Vorgehensmodelle ist die Annahme, dass ein Softwareentwicklungsprozess zu komplex ist, als dass er sich weder im Voraus in unabhängige Stufen, noch in detaillierte Arbeitsschritte planen lässt. Agile Vorgehensmodelle sind daher sehr flexibel um gut auf Änderungen reagieren zu können. Scrum definiert nur wenige Rollen4 und Artefakte. Das Product Backlog5 , wird zu Beginn des Prozesses initial gefüllt und vom Product Owner priorisiert. Für jeden Sprint6 wird ein Sprint Backlog mit den Anforderungen erstellt, die dabei umgesetzt werden sollen. Das Team organisiert sich innerhalb des Sprints selbst und das Ergebnis soll ein lauffähiges Inkrement der Software sein. Abbildung 2 stellt diesen Prozess als Diagramm dar. Abbildung 2. Der Scrum Prozess 2.3 OpenUP A couple of years ago, several colleagues and I started to think about how you could create a stripped-down version of the Rational Unified Process reflecting an agile approach to using RUP, while at the same time leverage all the good things we liked in other agile processes, such as Scrum and XP. 4 5 6 Product Owner, Team und Scrum Master Das Product Backlog enthält die Anforderungen an das Produkt Bezeichnet eine Iteration mit einer Dauer von ca. 30 Tagen Evaluierung der Potentiale des EPF 37 Diese Aussage von Per Kroll [9], Projektleiter des Eclipse Process Framework, beschreibt die Motivation hinter der Entwicklung des Open Unified Process (OpenUP). Es handelt sich dabei um ein agiles, iteratives Vorgehensmodell, das an den Rational Unified Process angelehnt ist und dessen grundlegende Charakteristika, u.a. Anwendungsfälle und ein architekturgetriebenes Vorgehen, einhält. Im Gegensatz zu diesem ist OpenUP aber ein minimaler Prozess, der nur grundlegende Inhalte enthält und auf viele weiterführende Themen verzichtet und sich daher vor allem für kleine Projekte eignet. OpenUP ist aber auch ein vollständiger und erweiterbarer Prozess, so dass er als Grundlage für andere Prozesse dienen kann, um ebenfalls höhere Anforderungen erfüllen zu können. OpenUP ist Open Source und basiert auf den folgenden Kernprinzipien, die sich am Agilen Manifest [18] orientieren: 1. 2. 3. 4. Collaborate to align interests and share understanding Balance competing priorities to maximize stakeholder value Focus on the architecture early to minimize risks and organize development Evolve to continuously obtain feedback and improve Abbildung 3. Ebenen des OpenUP [9] 38 R. Freudenreich OpenUP definiert sowohl Rollen, Aufgaben und Artefakte als auch Ebenen, die verschiedene Sichten mit einem unterschiedlichen Detailgrad auf das Projekt ermöglichen. Die Ebene des Projektlebenszyklus ähnelt dem Lebenszyklus des RUP und ermöglicht den Stakeholdern und Teammitgliedern einen effektiven Überblick über das Projekt. Er besteht aus den selben Phasen wie RUP, wird im Project Plan definiert und das Ergebnis ist eine freigabefähige Anwendung. Jede Phase besteht aus einer oder mehreren Iterationen, die ein funktionierendes Softwareinkrement hervorbringen und in der Ebene des Iterationslebenszyklus abgebildet sind. Das Team organisiert sich dabei selbst und verpflichtet sich auf den Iteration Plan, der festlegt, was in der Iteration geliefert werden soll. Die Ebene des Mikroinkrements befasst sich mit kleinen Arbeitseinheiten, die einen steten und messbaren Beitrag zum Projekterfolg leisten und typischerweise in einigen Stunden bis Tagen abgearbeitet werden können. Abbildung 3 veranschaulicht dies. 2.4 Vorteile Modellbasierter Unterstützung Lee Osterweil schrieb bereits im Jahr 1987: „Software processes are software, too“ [16]. In der Tat ist ein Entwicklungsprozess im Grunde ein Programm, das von den Projektmitgliedern ausgeführt wird. Ein Prozess an sich ist abstrakt und schwer zu fassen. Durch das Erstellen eines Modells wird ein Prozess greifbar und dies ist Voraussetzung für das Verstehen, Analysieren, Ausführen und Lernen eines Prozesses. Die Formalisierung und Modellierung eines Entwicklungsprozesses bietet daher viele Vorteile. Henderson-Sellers führt in [5] u.a. an, dass dadurch ein konsistenter, reproduzierbarer Ansatz für die Entwicklung von Software sichergestellt wird und die Unzulänglichkeit und Unvollkommenheit eines Ad-hocProzesses beseitigt wird. Desweiteren nennt er in diesem Zusammenhang, dass die Komplexität der heutigen Anforderungen verringert wird und die enorme Größe durch Dekomposition in handhabbare Teile gemeistert werden kann. Weitere Vorteile eines modellierten Entwicklungsprozesses sind verringerte Abhängigkeiten von Personen, Vergleichbarkeit mit anderen Entwicklungsprozessen, bessere Projektplanung und -controlling sowie einfachere Kommunikation der beteiligten Personen (intern und extern) untereinander, da eine gemeinsame Spache vorhanden ist. Trotz all dieser Vorteile, die mit Sicherheit überwiegen, gibt es in Verbindung mit der Prozessmodellierung auch einige wenige Nachteile. Dazu gehört, dass diese die Kreativität der Softwareentwicklung einschränken können und Neuerungen in der Softwareentwicklung langsamer übernommen werden können. Ein weiterer Punkt, dem Beachtung geschenkt werden muss, ist der Aufwand für die Erstellung und die Weiterentwicklung des Modells. 3 Eclipse Process Framework Projekte haben heute eine große Auswahl an unterschiedlichen Softwareentwicklungsprozessen. Am besten geeignet wäre jedoch oft eine Kombination ver- Evaluierung der Potentiale des EPF 39 schiedener Prozesse oder eine angepasste Version eines bestehenden Prozesses. Durch die unterschiedlichen Metamodelle der verschiedenen Vorgehensmodelle ist dies allerdings nahezu unmöglich, bzw. mit einem sehr hohen Aufwand verbunden. Eine Lösung für dieses Problem ist das Eclipse Process Framework (EPF), ein erweiterbares Open Source Prozess-Framework unter dem Dach der Eclipse Foundation, dessen Ziel ein offenes und kollaboratives Ecosystem für die Entwicklung von Softwareentwicklungsprozessen ist. Dazu stellt des EPF mit UMA ein Metamodell, mit dem EPF-Composer ein Entwicklungswerkzeug und Entwicklungsprozesse wie OpenUP bereit. Abbildung 4 stellt dieses Ecosystem dar. Abbildung 4. Ecosystem des Eclipse Process Framework [3] 3.1 Unified Method Architecture Die Unified Method Architecture (UMA) ist eine Evolution des Software Process Engineering Metamodel (SPEM) 1.1, das von der Object Management Group (OMG) spezifiziert wurde um einen Metamodell-Standard für Vorhergehensmodelle in der Softwareentwicklung zu schaffen [13]. Im Mai 2005 reichte IBM zusammen mit anderen Firmen7 bei der OMG einen Vorschlag auf Grundlage der UMA für den offiziellen Nachfolger der SPEM 1.1 ein [12]. Die aktuelle, noch in der Entwicklung befindliche Version von SPEM 2.0 basiert zum großen Teil 7 Adaptive Ltd., Fujitsu, Fundacion European Software Institue, Osellus Inc., Softeam 40 R. Freudenreich auf diesem Vorschlag und wird derzeit noch an die Bedürfnisse anderer OMGMitglieder angepasst [15]. Das Eclipse Process Framework unterstützt derzeit die UMA und erste Teile von SPEM 2.0, wobei die volle Unterstützung von SPEM 2.0 nach deren Verabschiedung als Standard geplant ist. Abbildung 5. Trennung von Method Content und Process Eine wesentliche konzeptionelle Eigenschaft der UMA ist die Trennung von Method Content (Methodeninhalt) und Process (Prozess), die in Abbildung 5 graphisch darstellt ist. Im Method Content werden wiederverwendbare Work Products (Arbeitsergebnisse), Tasks (Aufgaben), Roles (Rollen) und Guidances (Anleitungen) definiert, die beschreiben, wie gewisse Entwicklungsziele erreicht werden. Ein Prozess verwendet den Method Content in einer spezifischen Reihenfolge, so dass die speziellen Eigenheiten eines Projekts abgebildet werden. Diese Trennung ermöglicht eine hohe Wiederverwendbarkeit und Anpassbarkeit, da ein allgemeiner, prozessübergreifender Method Content definiert wird, der in verschiedenen Prozessen unterschiedlich verwendet werden kann. Um diese Eigenschaften auch für Bestandteile eines Prozesses zu erreichen, gibt es neben Delivery Processes (Bereitstellungsprozessen) sogenannte Capability Patterns (Prozessmuster), bei denen es sich um wiederverwendbare Prozessbausteine handelt. Beispiel Die Aufgabe „Anforderungsanalyse“ wird im Method Content mit den beteiligten Rollen und Artefakten definiert. In einem agilen Prozess wird diese Aufgabe mehrmals in den einzelnen Iterationen durchgeführt, wohingegen ein anderer Prozess nach dem Wasserfallmodell diese Aufgabe nur genau einmal am Anfang spezifiziert. Neue Erkenntnisse zu dieser Aufgabe können zentral im Method Content ergänzt werden und die Prozesse werden automatisch aktualisiert. UMA definiert eine Method Library (Methodenbibliothek) als Container für Method Plug-Ins (Methoden-Plug-Ins), die den Method Content und die Prozesse Evaluierung der Potentiale des EPF 41 enthalten. Ein Method Plug-In ist in Packages (Pakete) unterteilt und kann andere Method Plug-Ins referenzieren um deren Elemente verwenden zu können. Das Konzept der Variability (Variabilität) entspricht in ungefähr der objektorientierten Vererbung und ermöglicht die Erweiterung von Elementen. Auf dieses Konzept wird genauer im Kapitel 4.3.2 Variability eingegangen. 3.2 EPF Composer Der Eclipse Process Framework Composer (EPF Composer) ist ein Open Source Autorenwerkzeug für das Erfassen und Veröffentlichen von Prozessen, das im Rahmen des EPF entwickelt wurde. Er implementiert in der aktuellen Version 1.5 als Metamodell sowohl die UMA als auch bereits erste Teile von SPEM 2.0. Abbildung 6. Benutzeroberfläche des EPF Composer Abbildung 6 zeigt die Benutzeroberfläche des EPF Composers in der ein Teil des OpenUP zu sehen ist. Die Benutzeroberfläche ist in die Bereiche Library (Bibliothek), Configuration (Konfiguration) und Editor unterteilt. Die Library enthält die Method Library mit den Method Plug-Ins und die Sicht entspricht deren physischen Struktur inklusive der Trennung zwischen Method Content und Process. Die aktuelle Konfiguration, die eine logische Teilmenge der Method Library ist und durch das Auswählen von Method Content Packages und Prozessen 42 R. Freudenreich entsteht, wird darunter angezeigt. Der Editor-Bereich dient dem Bearbeiten aller Elemente. Die Implementierung des EPF Composer ist Java-basiert und baut auf der Eclise Rich Client Plattform sowie den Projekten Graphical Editing Framework (GEF)8 , JTidy9 und International Components for Unicode for Java (ICU4J)10 auf. Eine weitere wichtige Komponente ist das Eclipse Modeling Framework (EMF)11 , das für die auf dem Metamodell basierende Generierung der entsprechenden Klassen und des zugehörigen Codes sowie für die Persistenz der Method Library in XMI Dateien benötigt wird. Abbildung 7 veranschaulicht diese Architektur. Abbildung 7. Architektur des EPF Composer [2] Für die Veröffentlichung der erstellten Inhalte generiert der EPF Composer eine Webseite nach dem DHTML-Standard, so dass ein einheitlicher Zugriff (z.B. über das Intranet) auf die Informationen von verschiedensten Endgeräten aus möglich ist. Zusätzlich ist ein Export nach XML und Microsoft Project möglich. 4 Anwendbarkeit des EPF Für die Aktzeptanz in der Industrie ist die Anwendbarkeit des EPF ein entscheidendes Kriterium. Interessante Fragestellungen dazu sind, in welchen Bereichen 8 9 10 11 Ein Framework für die Entwicklung von graphischen Editoren und Diagrammen Ein Syntaxprüfer und Pretty Printer für HTML Eine Java Bibliothek für Unicodeunterstützung Ein Modellierungs- und Codeerzeugungsframework für strukturierte Datenmodelle Evaluierung der Potentiale des EPF 43 das EPF eingesetzt werden kann, wie gut die Dokumentation für Anwender ist und welche Best Practices für den Umgang mit dem EPF Composer bekannt sind. 4.1 Anwendungsgebiete Das Ziel des EPF darin liegt ein erweiterbares Framework sowie exemplarische Werkzeuge und Inhalte für das Entwickeln von Softwareentwicklungsprozessen bereitzustellen. Daher liegt in der Domäne der Softwareentwicklung auch dessen Hauptanwendungsgebiet. Neben OpenUP wurden einige andere Entwicklungsprozesse bzw. -ansätze bereits prototypisch oder auch vollständig modelliert. Dazu zählen u.a. Scrum, Extreme Programming, Rational Unified Process, Microsoft Solution Framework und Model Driven Architecture. [14] Doch obwohl das EPF in der o.g. Domäne seine Wurzeln hat, ist sein Anwendungsgebiet nicht auf diese beschränkt. UMA bzw. SPEM 2.0 definieren lediglich ein grundlegendes und allgemeingültiges Gerüst für die Modellierung von Prozessen, z.B. dass diese durch Phasen und Aufgaben beschrieben werden, in denen Rollen Arbeitsergebnisse erstellen können. Theoretisch werden damit die unterschiedlichsten Domänen abgedeckt. In der Praxis wurde dies bereits durch einige Fallstudien bewiesen, in denen Prozesse mit dem EPF modelliert wurden, die mit der Softwareentwicklung nichts zu tun haben. Ein Beispiel für weitere Anwendungsgebiete des EPF sind Managementmethoden. Neben dem Tivoli Unified Process (ITIL) wurde in dieser Domäne u.a. auch die SOA Governance Lifecycle and Management Method, die IBM World Wide Project Management Method und die IBM Global Services Method erfolgreich modelliert. Beispiele für hardwarenahe Prozesse sind die Application Specific Integrated Circuits Method und der Ericsson’s Product Lifecycle Management Process. Auch die Implementierung des Money-Lover-Prozesses für Investement Clubs zeigt, dass sich das EPF nicht auf einzelne Domänen beschränkt, sondern sich für die verschiedensten Bereiche und Branchen eignet. [14] 4.2 Anwenderdokumentation Eine gute Dokumentation für Anwender ist eine Bedingung, dass eine Software in Unternehmen eingesetzt wird und das EPF erfüllt diese Anforderung voll und ganz. Neben einem Wiki12 bietet die EPF-Webseite eine „Getting Started“Seite13 auf der man anhand von Dokumenten, Tutorials, Präsentationen und auch Screencasts einen guten Überblick und viele Informationen über das EPF und den EPF Composer bekommt. Hervorzuheben ist vor allem die sehr gute integrierte Hilfe des EPF Composers. Neben einer detaillierten und ausführlichen Dokumentation des Programms enthält sie gut ausgearbeitete Tutorials mit 12 13 http://epf.eclipse.org http://www.eclipse.org/epf/general/getting_started.php 44 R. Freudenreich Schritt-für-Schritt-Anleitungen, die einen einfachen Einstieg in das Programm ermöglichen. Für den Fall dass die vorhandene Dokumentation für manche Probleme nicht ausreicht, gibt es eine Newsgroup14 , in der weiterführende Fragen u.a. direkt von den EPF-Verantwortlichen beantwortet werden. 4.3 Best Practices In diesem Kapitel werden zwei wesentliche Best Practices beschrieben, die die Potentiale des EPF Composer in der täglichen Arbeit ausnutzen können. 4.3.1 Synchronisation Aufgrund der Tatsache, dass der Method Content in Prozessen referenziert wird und um die Inhalte iterativ und von mehreren Personen entwickeln zu können, besitzt der EPF Composer einen SynchronisationMechanismus für Descriptoren. Descriptoren sind Referenzobjekte, die Elemente des Methode Content (z.B. einen Task) in einem Prozess referenzieren. Durch Drag-and-Drop eines Tasks kann dieser einem Prozess hinzugefügt werden. Anstatt dabei jedoch den Task zu kopieren, erstellt der EPF Composer einen Task Descriptor, der auf den Task im Method Content referenziert. Zusätzlich zur Referenz hat ein Descriptor eigene Beziehungs- und Dokumentationseigenschaften anhand derer das entsprechende Element an dieser speziellen Position im Prozess vom Original im Method Content abweichen kann. Abbildung 8. Task Descriptor Neben einer Standard-Synchronisation, die alle Eigenschaften eines Elementes angleicht, existiert eine benutzerdefinierte Synchronisation, in der die anzugleichenden Eigenschaften ausgewählt werden können. Die Synchronisationsrichtung 14 news://news.eclipse.org/eclipse.technology.epf http://www.eclipse.org/newsportal/thread.php?group=eclipse.technology. epf Evaluierung der Potentiale des EPF 45 erfolgt dabei immer vom Method Content zum Descriptor. Eine Synchronisierung in die andere Richtung existiert hingegen nicht, so dass Änderungen an Descriptoren nicht automatisch auf Elemente des Method Content übertragen werden können. Beim Authoring ist daher darauf zu achten, dass globale Änderungen am Method Content und nicht an den Descriptoren im Prozess vorgenommen werden. Eine Synchronisierungsmöglichkeit für Capability Patters und Delivery Processes ist nicht vorhanden. Für die Verwendung von Patterns in einen Delivery Process können diese entweder ohne Verbindung zum Original Pattern kopiert oder dynamisch eingebunden werden, so dass es das Original Pattern erweitert und Änderungen an diesem automatisch übernommen werden. Im Delivery Process kann das Pattern dann durch das Hinzufügen oder Unterdrücken von Elementen erweitert werden. Das Ändern von bestehenden Elementen des dynamisch eingebunden Patterns ist im Delivery Process nicht möglich. 4.3.2 Variability Ein wichtiges Konzept der Wiederverwendbarkeit und Anpassbarkeit ist die Method Content Variability (Variabilität). Diese ermöglicht die Erweiterung von Elementen und entspricht in ungefähr der objektorientierten Vererbung. D.h. ein Element kann ein anderes Element auf verschiedene Art und Weisen erweitern. Dabei wird das Original nicht verändert, sondern als Grundlage für neue Inhalte verwendet. Variability ermöglicht somit auch das Erstellen von Method Plug-Ins, die andere Method Plug-Ins erweitern. Eine Anwendungsmöglichkeit dieses Mechanismus liegt darin, eine vorhandene Basismethode (z.B. OpenUP) an die eigenen Bedürfnisse anzupassen ohne das Method Plug-In der Basismethode selbst zu verändern. Da die Änderungen lediglich im neuen Method Plug-In vorgenommen werden, kann die Basismethode mit wenig Aufwand und ohne den Verlust der eigenen Änderungen aktualisiert werden, sobald eine neue Version veröffentlicht wird. Es existieren die folgenden vier Arten der Method Content Variability um ein vorhandenes Element (Original) durch ein neues Element (Erweiterung) anzupassen: Contribute Die Inhalte der Erweiterung werden in das Original übernommen und an das Ende der dortigen Inhalte angehängt. Die veröffentlichte HTMLWebseite enthält nur das Original. Extend Die Erweiterung enthält die eigenen Inhalte und erbt alle Inhalte des Originals, die es nicht selbst definiert. Die HTML-Webseite enthält sowohl das Original als auch die Erweiterung. Replace Die Erweiterung ersetzt das Original. Alle anderen Elemente, die vorher das Original referenzierten, zeigen nun auf die Erweiterung. Die HTML-Webseite enthält nur die Erweiterung. Extend and Replace Die Erweiterung enthält die eigenen Inhalte und erbt alle Inhalte des Originals, die es nicht selbst definiert. Das Original wird von der Erweiterung ersetzt und die Referenzierungen auf die Erweiterung geändert. Die HTML-Webseite enthält nur die Erweiterung. 46 R. Freudenreich Abbildung 9. Variability eines Tasks 4.3.3 Verwendung eines Versionsverwaltungssystems Der EPF Composer speichert alle Daten in XMI-Dateien, die auf dem XML-Format basieren, so dass bei der Entwicklung der Inhalte ein Versionskontrollsystem eingesetzt werden kann, dessen Vorteile in [19] beschrieben sind. Der EPF Composer unterstützt von Haus aus IBM Rational ClearCase und das Concurrent Versions System (CVS), aber auch andere Versionskontrollsysteme (z.B. Subversion) können verwendet werden. Dabei ist darauf zu achten, dass bereits relativ geringe Änderungen im EPF Composer mehrere Dateien betreffen können. Eine Datei sollte dabei aber nicht parallel bearbeitet werden, weil ein Merge der XMI Dateien möglichst zu vermeiden ist. Dateisperren (Locks) sind dafür gut geeignet und sollten verwendet werden. Da die Datei plugin.xmi eines Methoden Plug-Ins bei vielen Änderungen betroffen ist, empfiehlt es sich den Inhalt auf verschiedene Method Plug-Ins aufzuteilen. Pro Method Plug-In sollte eine Person die Rolle des Method Designer übernehmen und zu Beginn einen Method Sketch erstellen, um spätere strukturelle Veränderungen der XMI Dateien zu minimieren [17]. Beim Authoring ist häufiges Committen hilfreich um eine Korruption des Repositorys zu vermeiden. Treten dabei trotz Dateisperren Konflikte auf, sollte die Verantwortung für deren Beseitigung beim Method Designer liegen. Weitere hilfreiche Informationen enthält [7]. 5 Erweiterbarkeit des EPF Eine der wichtigsten Eigenschaften des EPF ist die Tatsache, dass es sich um ein Open Source Projekt handelt. Die zahlreichen Vorteile von Open Source gelten somit auch für das EPF. Einer der entscheidenden Vorteile ist dabei die freie Evaluierung der Potentiale des EPF 47 Verfügbarkeit des Quelltextes des EPF Composer und die daraus resultierende Möglichkeit, dass jeder den EPF Composer weiterentwickeln und an die eigenen Bedürfnisse anpassen kann. Dies eröffnet vollkommen neue Möglichkeiten, die proprietären Alternativen vorenthalten sind. 5.1 Entwicklerdokumentation So gut die Dokumentation für Anwender ist, so schlecht ist die Dokumentation für Entwickler. Sie ist nur spärlich vorhanden, über verschiedenste Dokumente verteilt und teilweise nicht aktuell. Die zentrale Anlaufstelle bietet die Developers Resources Webseite15 , auf der u.a. die beiden wichtigsten Dokumente verlinkt sind. Diese sind der EPF Composer Architecture Overview16 und der EPF Composer Development Guide17 . Der Development Guide enthält allerdings lediglich eine Anleitung wie die Eclipse IDE einzurichten ist, um mit dem Quelltext des EPF Composers zu arbeiten. Diese Anleitung ist dafür aber sehr gut und detailliert. Weiterführende Informationen (z.B. Tutorials, How-Tos, etc.) sind nicht vorhanden. Auch die Dokumentation des Quelltextes ist schlecht und nur in begrenztem Umfang umgesetzt. Das entsprechende Javadoc18 ist daher nur schlecht zu gebrauchen. Die Hürde für die Einarbeitung in den Quelltext des EPF Composers ist dadurch hoch und erfordert eine Menge Geduld. Aufgrund dieses Umstands kann der EPF Composer einen seiner größten Trümpfe gegenüber propietären Konkurrenzprodukten leider nur begrenzt ausspielen - die freie Verfügbarkeit des Quelltextes und der damit einhergehenden Möglichkeit für Entwickler weltweit den EPF Composer an eigene Bedürfnisse anzupassen und weiterzuentwickeln. 5.2 Extension Point Mechanismus Der EPF Composer basiert auf der Eclipse Rich Client Plattform (RCP) mit seiner Plug-In Architektur, dessen Kern der Extension Point Mechanismus darstellt. Ein Extension Point stellt eine definierte Schnittstelle bereit, um ein Plug-In zu erweitern. Eine Extension kann an einem solchen Extension Point ansetzen um dem Plug-In zusätzliche Funktionalität bereitzustellen. Ein Beispiel für diesen Mechanismus ist ein E-Mail-Programm das einen Extension Point für zusätzliche Spam-Filter definiert, die von Extensions bereitgestellt werden. Auch die Plug-Ins des EPF Composer bieten diverse Extension Points an. Eine Besonderheit ist die im Gegensatz zur objektorientierten Vererbung gegenläufige Nutzungs- und Abhängigkeitsrichtung. Ein Extension Point nutzt eine Extension, ist aber gemäß dem Hollywood-Prinzip „We call you, don’t call us“ nicht von dieser abhängig. 15 16 17 18 http://www.eclipse.org/epf/general/developers_documentation.php http://www.eclipse.org/epf/composer_architecture/ http://www.eclipse.org/epf/composer_dev_guide/ http://www.eclipse.org/epf/composer_javadoc/epf1.5javadoc.zip 48 R. Freudenreich Abbildung 10. Extension Point-Mechanismus 5.3 Fallbeispiel Prozess ausführen Im Rahmen dieser Arbeit sollte eine prototypische Erweiterung des EPF Composers als Fallbeispiel implementiert werden. Diese Erweiterung sollte untersuchen ob und wie es möglich ist, einen Prozess nicht nur als HTML-Webseite anschauen zu können, sondern diesen im weitesten Sinne „ausführen“ zu können. D.h. dass ein Benutzer direkt aus der Prozessdokumentation heraus eine bestimmte Anwendung starten kann, um ein Artefakt zu erstellen, das in diesem Prozessschritt benötigt wird. 5.3.1 Möglichkeiten des EPF Der EPF Composer kann diese Anforderung bereits ohne Erweiterung mit gewissen Einschränkungen erfüllen. Es existiert der Guidance-Typ Template, in dem eine Vorlage für Work Products definiert werden kann. Ein Template kann beschreibenden Text und angefügte Dateien enthalten. Die Dateien werden in das Method Plug-In importiert und dort gespeichert. Beim Veröffentlichen der Methode werden die angefügten Dateien in die Dateistruktur der HTML-Webseite übernommen und können von der entsprechenden TemplateSeite heruntergeladen werden. Moderne Browser bieten die Möglichkeit, Dateien direkt zu öffnen ohne diese explizit speichern zu müssen, so dass direkt die mit dem Dateityp assoziierte Anwendung startet und die Datei darin geöffnet wird. Abbildung 11 zeigt ein Artefakt mit zugehörigem Template. Diese Vorgehensweise hat mehrere Nachteile. Da die Anwendung durch das Öffnen einer Datei gestartet wird, muss eine Verknüpfung von Dateityp und Anwendung vorhanden sein. Dies kann zu Problemen führen, weil manche Anwendungen mit keinerlei Dateityp verknüpft sind oder ein Dateityp standardmäßig mit einer anderen Anwendung verknüpft ist. 5.3.2 Erweiterung des EPF Aufgrund der freien Verfügbarkeit des Quellcodes des EPF Composer kann die Erweiterung selbst implementiert werden. Ziel der Erweiterung ist ein neues Attribut für Artefakte, in dem der Pfad der Anwendung gespeichert wird. Für die Implementierung der Erweiterung sind die folgenden Schritte notwendig: Erweiterung des Metamodells, Programmierung des Authoring Plug-Ins und Änderung der XSL Dateien. Evaluierung der Potentiale des EPF 49 Abbildung 11. Artefakt mit zugehörigem Template Erweiterung des Metamodells Grundlage für die Entwicklung der Erweiterung ist das UMA Metamodell und dessen Implementierung mit dem EMF. Da diese kein Attribut für den Anwendungspfad definiert, muss dieses in der Datei uma.ecore im Verzeichnis model/1.0.5 des Packets org.eclipse.epf.uma hinzugefügt werden. Dies geschieht über den Eintrag New Child → EAttribute im Kontextmenü des ArtifactDescription-Elements, wobei die Eigenschaften des neuen Attributs noch bearbeitet werden müssen (EAttributeType soll vom Typ String und der Name soll appPath sein). Nach dem Speichern werden über das Kontextmenü der Datei uma.genmodel im selben Verzeichnis die Klassen und der dazugehörige Code generiert (Eintrag Generate Model Code). Programmierung des Authoring Plug-Ins Der nächste Schritt besteht nun darin einen neuen Bereich im Artefakt-Editor zu erstellen, damit beim Authoring der Anwendungspfad angegeben werden kann. Da der EPF Composer hierfür keinerlei Automatismus besitzt, muss der Quelltext selbst erstellt werden. Anstatt das Plug-In org.eclipse.epf.authoring.ui zu verändern, bietet es sich an, dessen Extension Point descriptionPageSectionProvider für ein eigenes Plug-In zu erweitern. Die Klasse DescriptionFormPageApplicationSection im neuen Plug-In de.uniaugsburg.epf.authoring.ui muss dafür das Interface ISectionProvider und im speziellen dessen Methode createSection() implementieren, wobei auf diverse Hilfsmethoden für das Erstellen von UI-Elementen zurückgegriffen werden kann. Das Erstellen der UI-Elemente wird in der Methode createApplicationSectionContent() und das Laden der Daten in der Methode loadApplicationSectionData() gekapselt. Listing 3.1. Ausschnitt der Datei DescriptionFormPageApplicationSection.java 1 public void createSection ( M e t h o d E l e m e n t E d i t o r editor , 2 FormToolkit toolkit , Composite parent ) { this . editor = editor ; 4 // Get the element that is being edited 6 methodElement = editor . g e t M e t h o dE l e m e n t (); // Create this section only if editing an artifact 50 R. Freudenreich 8 if (!( methodElement instanceof Artifact )) { return ; } 10 // Get the description for the artifact artifactDescription = ( ArtifactDescription ) (( Conten tElement ) methodElement ). g et Pr es e nt at io n (); 12 // Create the new section with appropriate name and description text a p p l i c a t i o n S e c t i o n = createSection ( toolkit , parent , APPLICATION_SECTION_NAME , A P P L I C A T I O N _ S E C T I O N _ D E S C ); // Create composite for the new section a p p l i c a t i o n C o m p o s i t e = cr e at eC om p os it e ( toolkit , a p p l i c a t i o n S e c t i o n ); // Set layout (( GridLayout ) a p p l i c a t i o n C o m p o s i t e . getLayout ()). numColumns = 4; // Create content for the new section ( textboxes , etc .) c r e a t e A p p l i c a t i o n S e c t i o n C o n t e n t ( toolkit ); 14 16 18 20 22 // Load data for the new section l o a d A p p l i c a t i o n S e c t i o n D a t a (); // Get the ActionManager actionMgr = editor . g e t A c t i o n M a n a ge r (); 24 26 28 30 32 34 36 38 40 42 44 } // Add Listeners for new section ( Modify , Action , etc .) addListeners (); protected void c r e a t e A p p l i c a t i o n S e c t i o n C o n t e n t ( FormToolkit toolkit ) { // Create the label and textbox for the application path ctrl_appPath = c r e a t e T e x t E d i t W i t h L a b e l 3 ( toolkit , applicationComposite , APPPATH_TEXT , SWT . DEFAULT , SWT . SINGLE ); // Set layout options ctrl_appPath . setLayoutData ( new GridData ( GridData . FI L L_ HO RI ZO N TA L | GridData . BEGINNING )); // Create the button for the file choosing dialog c t r l _ s l o t _ b u tt o n = toolkit . createButton ( applicationComposite , A ut ho ri ng U IT ex t . SELECT_BUTTON_TEXT , SWT . SIMPLE ); // Set layout data c t r l _ s l o t _ b u tt o n . setLayoutData ( new GridData ( GridData . H O R I Z O N T A L _ A L I G N _ E N D )); } 46 protected void l o a d A p p l i c a t i o n S e c t i o n D a t a () { // Get application path for the method element and set text String appPath = a r t i f a c t D e s c r i p t i o n . getAppPath (); 50 ctrl_appPath . setText ( appPath == null ? "" : appPath ); } 48 Änderung der XSL Dateien Als letzter Schritt muss die Generierung der HTML-Webseite angepasst werden. Die HTML-Webseite wird mit einer XSL Transformation der in XML gespeicherten Daten generiert, so dass das Erscheinungsbild der Webseiten durch einfaches Ändern der XSL Dateien bearbeitet werden kann. Diese Dateien befinden sich im Verzeichnis layout/xsl des Pakets org.eclipse.epf.library. Die Änderungen müssen direkt im jeweiligen XSL Template descriptionSection der Dateien artifact.xsl und artifact_descriptor.xsl vorgenommen werden, da es keinen entsprechenden Extension Point gibt. Listing 3.2. Ausschnitt des XSL Templates descriptionSection 1 < xsl : template name =" d e s c r i p t i o n S e c t i o n " > 2 < xsl : param name =" description "/ > {...} 4 < xsl : variable name =" appPath " select =" $description / attribute [ @name = ' appPath ']"/ > Evaluierung der Potentiale des EPF 51 6 < xsl : if test =" $briefOutline != '' or {...} or $appPath != ' '" > < div class =" sect ionHeadi ng " > < xsl : value - of select =" $ d e s c r i p t i o n T e x t "/ > </ div > 8 < div class =" sect ionConte nt " > < table class =" sectionTable " border ="0" cellspacing ="0" cellpadding ="0" > 10 {...} < xsl : if test =" $appPath != ' '" > 12 < script type =" text / vbscript " for =" runApp " event =" onClick " > set oShell = CreateObject (" WScript . Shell ") 14 oShell . run """ < xsl : value - of select =" $appPath "/ >""" ,1 </ script > 16 < tr valign =" top " > < th class =" s e c t i o n T a b l e H e a d i n g " scope =" row " > Application </ th > 18 < td class =" s e c t i o n Ta b l e C e l l " > < img src ="{ $backPath }/ images / run . gif " name =" runApp " alt =" Run Application " 20 title =" Run Application " style =" vertical - align : middle ; cursor : pointer ;"/ > < xsl : value - of select =" concat ( ' ', $appPath )"/ > 22 </ td > </ tr > 24 </ xsl : if > </ table > 26 </ div > </ xsl : if > 28 {...} </ xsl : template > Falls für ein Artefakt ein Anwendungspfad angegeben ist, enthält die entsprechende HTML-Seite einen neuen Eintrag mit einer kleinen Grafik und einem Text mit dem Anwendungspfad. Durch einen Klick auf die Grafik soll die Anwendung dann gestartet werden. Ein Problem ist dabei, dass es eine große Sicherheitslücke darstellen würde, wenn eine Webseite ohne weiteres ein Programm auf einem anderen Computer ausführen könnte. Aus diesem Grund erlauben dies gängige Webbrowser bis auf eine Ausnahme nicht. Beim Internet Explorer ist dies durch eine Kombination aus VBScript und ActiveX möglich. Diese Funktionalität erfordert beim Benutzer daher zwingend den Einsatz des Internet Explorers. Abbildung 12. Editor und Webseite mit Erweiterung Den EPF Composer selbst zu erweitern hat eindeutig den Vorteil, dass die Anforderungen sehr gut erfüllt werden können. Die Implementierung kommt den eigenen Wünschen sehr nahe (siehe Abbildung 12). Aber auch diese hat Nachteile. Die Änderung des Metamodells ist eine Verletzung des (zukünftigen) SPEM 52 R. Freudenreich 2.0 Standards und wegen fehlender Extension Points muss der Quelltext von zwei EPF Composer Plug-Ins geändert werden. Eine reibungslose Aktualisierung auf eine neue Version des EPF Composers ist dadurch nicht möglich, da diese Änderungen manuell übertragen werden müssen. 6 Alternativen Die Firma IBM ist nicht nur die treibende Kraft hinter dem EPF, sondern bietet außerdem mit dem Rational Method Composer (RMC) eine kommerzielle Alternative zu diesem an. Das EPF basiert entscheidend auf großen Teilen des RMC, die IBM als Spende in das Eclipse Projekt einbrachte, und bildet nun den Kern des RMC. Auf diesen Kern baut der RMC mit speziellen Features und zusätzlichen Inhalten auf. Hervorzuheben ist vor allem die Integration mit anderen Anwendungen von IBM Rational und der Rational Unified Process, der im RMC enthalten ist. [4] Eine weitere Alternative mit einem dem EPF ähnlichen Funktionsumfang ist der IRIS Process Author (IPA) der Firma Osellus. Der IPA ist eine Webanwendung und enthält diverse Entwicklungsprozesse (u.a. RUP, OpenUP) basierend auf dem SPEM 1.1 Metamodell. Die mit dem IPA erstellten Inhalte können als Webseite, Wiki oder als ausdruckbares Dokument veröffentlicht werden. Osellus bietet desweiteren mit dem IRIS Process Live ein Werkzeug an, um Prozesse in Verbindung mit dem Microsoft Visual Studio Team System auszuführen. Ein Blick über den Tellerrand liefert mit Anwendungen für domänenspezifische Sprachen (z.B. MetaEdit+) und für die Geschäftsprozessmodellierung im weitesten Sinne weitere Alternativen zum EPF. Die Unterschiede sind allerdings sehr groß. 7 Schluss Das EPF ist ein mächtiges Prozess-Framework, das aufgrund seiner Flexibilität in vielen Anwendungsgebieten eingesetzt werden kann und durch seinen Status als Open Source Projekt eine gute Erweiterbarkeit besitzt. [6] zeigt dass auch fortgeschrittenere Erweiterungen möglich sind. Es besteht allerdings Verbesserungsbedarf bei der Dokumentation für Entwickler. Das EPF ist eines der ersten Frameworks, das den zukünftigen SPEM 2.0 Standard unterstützen wird. Es ist daher gut für die Zukunft aufgestellt eine wichtige Rolle in der modellbasierten Softwareentwicklung zu spielen, denn eine Modellierung der Softwareentwicklungsprozesse ist für alle Entwicklungsprojekte sinnvoll. Vor allem mittlere und große Projekte profitieren davon. Literatur [1] E. Dijkstra. The Humble Programmer. Commun. ACM 15, 10:859–866, 1972. Evaluierung der Potentiale des EPF 53 [2] EPF. Eclipse Process Framework (EPF) Composer 1.0 Architecture Overview. http://www.eclipse.org/epf/composer_architecture/, Abruf am 24.03.2009. [3] EPF. What is the Eclipse Process Framework. http://www.eclipse.org/epf/ community/Whats_EPF.ppt, Abruf am 18.03.2009. [4] P. Haumer. IBM Rational Method Composer: Part 1: Key concepts, Dezember 2005. http://www.ibm.com/developerworks/rational/library/dec05/haumer/, Abruf am 24.03.2009. [5] B. Henderson-Sellers, M. Serour, T. McBride, C. Gonzalez-Perez, and L. Dagher. Process Construction and Customization. Journal of Universal Computer Science, 10(4):326–358, 2004. [6] M. Hermanns. Erweiterung der ViPER-Umgebung zur methodengestützten Entwicklung mit MeDUSA, Juli 2007. http://www.viper.sc/images/c/c8/Marcel_ Hermanns_Intermediate_Talk.ppt, Abruf am 26.03.2009. [7] IBM. Using Eclipse Process Framework Composer with a Version Control System, 2006. http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.epf/ docs/Using%20EPF%20with%20a%20Version%20Control%20System.rtf?root= Technology_Project&view=log, Abruf am 08.04.2009. [8] B. Kahlbrandt. Software-Engineering mit der Unified Modeling Language. Springer, 2001. [9] P. Kroll. OpenUP in a Nutshell, 2007. http://www.ibm.com/developerworks/ rational/library/sep07/kroll/index.html, Abruf am 26.03.2009. [10] P. Kruchten. Der Rational Unified Process. Addison-Wesley, 1999. [11] P. Liggesmeyer and D. Rombach. Software-Engineering eingebetteter Systeme: Grundlagen-Methodik-Anwendungen. Spektrum Akademischer Verlag, 2005. [12] OMG. Software Process Engineering Meta-Model 2.0 OMG Draft Adopted Specification. ad/05-05-06, Mai 2005. [13] OMG. Software Process Engineering Metamodel Specification Version 1.1. formal/05-01-06, January 2005. [14] OMG. Second Revised SPEM 2.0 Submission. ad/06-04-12, April 2006. [15] OMG. Software & Systems Process Engineering Meta-Model Specification. formal/08-04-01, April 2008. [16] L. Osterweil. Software processes are software too. In ICSE ’87: Proceedings of the 9th international conference on Software Engineering, pages 2–13, Los Alamitos, CA, USA, 1987. IEEE Computer Society Press. [17] C. Péraire. A roadmap to method development, 2007. http://www.ibm. com/developerworks/rational/library/feb07/peraire/index.html, Abruf am 09.04.2009. [18] K. Schwaber et al. Manifesto for Agile Software Development, 2001. http: //agilemanifesto.org/, Abruf am 15.03.2009. [19] J. Vesperman. CVS. Versionskontrolle und Quellcode-Management. O’Reilly, 2004. Binding zwischen XML-Schema-Modellen und Java-Beans (JAXB) Panayot Radinski Universität Augsburg [email protected] Zusammenfassung Im Rahmen dieser Seminararbeit wird die modellbasierte Softwareentwicklung vorgestellt. Speziell wird die Bindung zwischen XML-Schema-Modellen und Java-Beans untersucht. Java Architecture for XML Binding (JAXB) ist eine der populärsten Techniken für die Modelltransformation bzw. Datentransfer zwischen Java und XML. Im Gegensatz zu anderen parser-basierten Ansätzen wie SAX oder DOM bietet JAXB eine höhere Flexibilität und einen vereinfachten Zugriff auf XML Dateien an, so dass Programmierer unkompliziert XML in ihren Java Anwendungen integrieren können. Wie genau JAXB diese Bindung zwischen Java und XML herstellt, wird anhand mehrerer Beispiele veranschaulicht. 1 1.1 Einleitung Modellbasierte Softwareentwicklung Die heutigen Krisenzeiten, die vielfältigen Bedürfnisse der Kunden, der sich ständig ändernde Gesetzesrahmen erfordern von den IT-Unternehmen eine neue, flexiblere Art der Softwareentwicklung. Einen relativ neuen Ansatz stellt die Modellbasierte Softwareentwicklung, die sich gegenüber der klassischen Softwareentwicklung durch etliche Vorteile auszeichnet - mehr Effizienz, höhere Softwarequalität und bessere Wiederverwendbarkeit. Im Mittelpunkt der Modellbasierten Softwareentwicklung stehen formale Modelle, die die charakteristischen Domainbegriffe und die Beziehungen zwischen diesen Domainbegriffen, ohne Bezug auf die Softwaresysteme, beschreiben. Diese Modelle werden mit Hilfe von Werkzeugen für einen Anwendungsbereich spezifische, aber von den technologischen Details abstrahierte, plattformunabhängige Modelle transformiert. Anschließend werden automatisch aus den transformierten Modellen detailierte, plattformspezifische Modelle generiert, die möglichst große Teile der Implementierung beinhalten und manuell erweitert werden können. 1.2 Die Bindung zwischen Java und XML Java hat sich in den letzten Jahren zu einer der meist verbreiteten objektorientierten Programmiersprachen entwickelt. Plattformunabhängigkeit, Portierbarkeit, Binding zwischen XML-Schema-Modellen und Java-Beans (JAXB) 55 Robustheit, Sicherheit, Modularität und viele mehr zählen zu den wichtigsten Eigenschaften, die diese Sprache so beliebt machen. Neben der Java Standard Edition (SE), die für die Implementierung von allgemeinen, portablen Anwendungen eingesetzt wird, gibt es die Java Micro Edition (ME) für Mobiltelefone oder PDAs und die Java Enterprise Edition (EE) für transaktionsbasierte Systeme. In der Spezifikation von Java wurden Softwarekomponenten und Dienste definiert, die die Grundbausteine für mehrschichtige, verteilte (Web)-Architekturen bereitstellen, um die stets steigende Komplexität zu beherrschen. Solche wiederverwendbaren Softwarekomponenten werden im Java Umfeld Beans genannt. Es gibt die Java Beans (JB) und die Enterprise Java Beans (EJB), die sich in der Aufgabe und im Einsatzgebiet unterscheiden. Die JBs werden als Container für die Datenübertragung verwendet und können überall ausgeführt werden, wo es eine Java Virtual Machine gibt. Dagegen bieten die EJBs in erster Linie Servermechanismen wie Persistenz, Load Balancing, Sicherheit, Transaktionsunterstützung und können ausschließlich in einem EJB-Container eines J2EE Application-Servers ablaufen (vgl. [3]). Im Allgemeinen bestehen beide Typen von Beans aus Java Klassen, die einem Java-Bean-Komponentenmodell entsprechen. Die Kommunikation zwischen den einzelnen Beans wird durch klar definierte Schnittstellen sichergestellt, die das Geheimnisprinzip wahren. Das bedeutet, dass die innere Anwendungslogik verborgen bleibt und die Kommunikation mit der Umwelt über eine äußere Hülle stattfindet, die mit öffentlichen getter- und setter-Methoden ausgestattet ist. So können Komponenten unterschiedlicher Hersteller problemlos miteinander verknüpft werden, wenn sie sich an die JavaBean-Spezifikation halten. XML stellt eine einfache Möglichkeit dar, Daten strukturiert auszutauschen. Da aber XML eine Metasprache ist, die die zu übertragenden Daten nur beschreibt, muss in einer Programmiersprache die notwendige Funktionalität implemeniert werden, um mit XML umgehen zu können. Es gibt verschiedene Techniken, wie DOM, SAX, Pull API, Data Binding usw., die auch in Java vorhanden sind und XML Dateien verarbeiten können. Die Parser-basierten DOM, SAX und Pull API sind aber nicht immer optimal. DOM verbraucht viel Speicher, SAX arbeitet sequentiell, Pull API ist sehr speichereffizient, hat aber auch eine sequentielle Arbeitsweise. Der wesentliche Nachteil der parser-basierten Ansätze ist, dass nicht alle Programmierer mit solchen komplizierten Techniken anvertraut sind. Data Binding benutzt einen eigenen XML-Parser und transformiert im Gegensatz zu diesen Verfahren die XML Daten in Java Objekte, die so für den direkten Programmzugriff bereitgestellt werden (vgl. [4]). Java Architecture for XML Binding (JAXB) ist ein Ansatz, der auf dem Data Binding Modell basiert. Im Rahmen dieser Arbeit wird nicht näher auf die Java Beans eingegangen, sondern man setzt sich mit der Bindung zwischen den beiden Technologien XML und Java auseinander. Im Nachfolgenden Kapitel wird genau erklärt, wie JAXB Java Datenmodelle in XML Schema, Java Objekte in XML Dateien und dann beides umgekehrt transformieren kann. Dafür ist es nicht notwendig, den genauen Aufbau der Beans zu kennen. Viel wichtiger ist es, wie diese äußere Bean-Hülle mit XML interagiert. 56 2 2.1 P. Radinski Hauptteil XML und XML-Schema 2.1.1 XML (kurz gefasst) XML ist allgemein bekannt und wird hier nur kurz zur Wiederholung vorgestellt. Ein großer Vorteil von dieser erweiterbaren Auszeichnungssprache ist, dass sie, obwohl sie strengen Syntaxregeln unterliegt, für einen Menschen sehr einfach zu lesen ist. Um das Verarbeiten durch Parsern zu ermöglichen, wird XML als eine hierarchische Baumstruktur organisiert. Dies bringt aber den Nachteil mit sich, dass viele redundante Informationen gespeichert werden müssen. Der grundsätzliche Aufbau eines XML Dokuments wird anhand eines kurzen Beispiels veranschaulicht, in dem einem Einwohner eine Frau mit Name, Geburtsdatum und Bild zugeordnet wird. Listing 4.1. Das XML Dokument 1 <? xml version ="1.0" encoding =" UTF -8" standalone =" yes "? > 2 < Einwohner > < Frau Name =" Stephanie Müller " > 4 < Geburtsdatum >15.11.1980 </ Geburtsdatum > < Visitenkarte Pfad =" D :\ stephie . doc " / > 6 < Haustier > Katze </ Haustier > </ Frau > 8 <! - - Ein Kommentar --> </ Einwohner > Ein XML Dokument fängt immer mit einer Deklaration (Zeile 1) an, in der die XML Version und die Zeichenkodierung definiert werden. Mit standalone wird angegeben, ob ein externes XML Schema bzw. Document Type Definition (DTD) angebunden wird. Einwohner, Frau und Geburtsdatum sind XML-Elemente. Sie fangen immer mit einem in spitzen Klammern geschriebenen Start-Tag <name> an und werden mit einem Ende-Tag </name> abgeschlossen. Elemente haben gewöhnlich einen Inhalt (Zeile 4 - 15.11.1980 ) oder sie sind leer. Bild ist ein leeres Element und besteht aus einem Tag in der Form <elementname / >. XML-Attribute sind Zusatzinformationen über Elemente. Stephanie Müller ist der Inhalt des Attributs Name, das das Element Frau näher beschreibt. Wie ein Kommentar aufgebaut wird, ist in der Zeile 7 zu sehen. Damit XML Dateien auch richtig von Parsern gelesen werden können, müssen sie eine wohlgeformte Dokumentenstruktur haben. D.h. sie dürfen genau ein Wurzelelement besitzen (<Einwohner>), die Schachtelung und die Namen der Elemente müssen korrekt sein und die Attribute innerhalb eines Elementes dürfen nicht dieselbe Bezeichnung haben. In XML wird ausserdem zwischen Groß- und Kleinschreibung unterschieden. Wenn XML für den Datenaustausch eingesetzt wird, muss es sichergestellt werden, dass die Informationsquelle und der Datenempfänger „dieselbe Sprache sprechen“. Dafür muss die für die Kommunikation eingesetzte XML Datei wohlgeformt sein und nach den Vorgaben eines Schema-Modells aufgebaut sein. Die XML Datei muss also auf ihre Gültigkeit überprüft werden (vgl. [2]). Ein Binding zwischen XML-Schema-Modellen und Java-Beans (JAXB) 57 Schema-Modell definiert, ob die prinzipielle Struktur eines XML Dokumentes und der Inhalt der darin verwendeten Tags valide sind. Unter der Benutzung von DTD oder XML-Schema können Modelle definiert werden, die die Gültigkeit von XML Dateien überprüfen. In dieser Arbeit wird beschrieben, wie XML-Schema-Modelle den Datentransfer zwischen Java Komponenten herstellen können. 2.1.2 XML-Schema Mit einem XML-Schema kann genau festgelegt werden, wie ein gültiges XML Dokument aussehen muss. Eine Menge Merkmale zeichnen das XML-Schema im Vergleich zu anderen Definitionssprachen aus (vgl. [1]): . Die Syntax von XML wird in XML-Schema-Dateien benutzt, deshalb ist es nicht notwendig, eine neue Definitionssprache (wie z.B. DTD) zu erlernen. . XML-Schema bietet eine Menge von einfachen und komplexen Datentypen. . Die Kardinalität (Wertebereich) von Elementen kann genau angegeben werden. . XML-Namensräume (namespaces) werden unterstützt. Damit können Elemente, die in verschiedenen XML-Schemata benutzt werden, eindeutig unterschieden werden. . XML-Schema bietet ein besser ausgeprägtes Schlüsselkonzept, so dass Elemente eindeutig referenziert werden können. . Inhaltsmodelle von Elementen lassen sich mit XML-Schema auch lokal definieren, typisieren und wiederverwenden - mehrfach verwendete Elemente werden nur einmal definiert. . Aber: XML-Schema unterstützt so viele Möglichkeiten zur Definition von XML-Dokumenten, dass die XML-Schema-Dateien oft sehr groß, kompliziert und schwer zu lesen werden. In Listing 4.2 wird der Aufbau einer XML-Schema-Datei eingeführt, die die in Listing 4.1 dargestellte XML Datei auf ihre Gültigkeit überprüft. Listing 4.2. Das XML-Schema 1 <? xml version ="1.0" encoding =" UTF -8" standalone =" yes "? > 2 < xs : schema version ="1.0" xmlns : xs =" http :// www . w3 . org /2001/ XMLSchema " > < xs : c o m p l e x T y p e name =" Frau " > 4 < xs : a t t r i b u t e name =" Name " type =" xs : string " use =" required "/ > < xs : sequence > 6 < xs : element name =" Geburtsdatum " type =" xs : string " minOccurs ="1" maxOccurs ="1"/ > 8 < xs : element name =" Visitenkarte " type =" xs : string "/ > < xs : element name =" Haustier " type =" xs : string " 10 default =" Hund "/ > </ xs : sequence > 12 </ xs : complexType > </ xs : schema > Die XML-Schema-Datei beginnt wie eine normale XML Datei mit einer XML-Deklaration und besitzt genau ein Wurzelelement - das ist immer der Tag <xs:schema>. Mit den Attributen version und xmlns wird angegeben, um welche XML-Schema-Version es sich handelt und welche XML-Namensräume benutzt werden. <xs:complexType> definiert die zusammenhängende Elementenstruktur Frau. Sie besteht aus dem Attribut (<xs:attribute>) Name und den 58 P. Radinski drei Elementen (<xs:element>) Geburtsdatum, Visitenkarte und Haustier. Mit der Angabe use=“required“ muss der Name einer Frau stets vorhanden sein. <xs:sequence> bestimmt die Reihenfolge, in der die Elemente eines komplexen Datentyps vorkommen - Visitenkarte darf z.B. nicht vor Geburtsdatum auftreten. Ausserdem werden innerhalb des <xs:sequence> Tags die Wertebereiche der enthaltenen Elemente durch minOccurs=“1 “ und maxOccurs=“1 “ definiert. Im Beispiel bedeutet das, dass für eine Frau nur ein Geburtsdatum gespeichert wird. Falls keine occurs-Attribute vorhanden sind, wird der Standardwert 1 benutzt. Mit der default Angabe in Zeile 10 wird ein Standardwert vorgegeben - falls in der XML Datei das Element Haustier keinen Inhalt hat, so wird die Belegung „Hund“ verwendet. Ein XML-Schema kann abhängig von den Anforderungen die Struktur und den Inhalt einer XML Datei viel oder wenig einschränken. Im Listing 4.2 wird z.B. keine Vorgabe für das Attribut Pfad des Elementes Visitenkarte gemacht und auch die Anzahl der Haustiere wird nicht durch ein occur-Attribut beschränkt. Einige von den wichtigen Eigenschaften und Funktionalitäten der XMLSchemata wurden bereits angesprochen. Diese Definitionssprache bietet aber viel mehr an (vgl. [2]). Für das Element Haustier kann eine Liste mit den zulässigen Werten für den Inhalt hinzugefügt werden. Ein neuer Datentyp <xs:simpleType> mit dem Namen alleHaustiere sowie eine Liste dieses neuen Typs werden dem Element Haustier zugeordnet (siehe Listing 4.3). In der XML Datei wird dann der Inhalt von Haustier so aussehen: (Hund), (Katze), (Vogel) , aber auch (Hund Katze Vogel) ist möglich - (Rex) ist dann eine falsche Eingabe. Listing 4.3. XML-Schema Erweiterung 1 1 < xs : simpleType name =" alleHaustiere " > 2 < xs : restriction base =" xs : string " > < xs : enumeration value =" Katze "/ > 4 < xs : enumeration value =" Hund "/ > < xs : enumeration value =" Vogel "/ > 6 </ xs : restriction > </ xs : simpleType > 8 < xs : simpleType name =" Haustier " > < xs : list itemType =" alleHaustiere "/ > 10 </ xs : simpleType > Für ein Haustier kann ein beliebiger Datentyp (xs:anyType) definiert werden, so dass als Elementinhalt die Anzahl der Haustiere, ihre Namen usw. zulässig sind (siehe Listing 4.4). Listing 4.4. XML-Schema Erweiterung 2 1 < xs : element name =" Haustier " type =" xs : anyType "/ > Der komplexe Datentyp Frau kann um das Element Ehemann erweitert werden (xs:extension) und so wird der neue Typ neueFrau entstehen (siehe Listing 4.5). Binding zwischen XML-Schema-Modellen und Java-Beans (JAXB) 59 Listing 4.5. XML-Schema Erweiterung 3 1 < xs : c o m p l e x T y p e name =" neueFrau " > 2 < xs : complexContent > < xs : extension base =" Frau " > 4 < xs : sequence > < xs : element name =" Ehemann " type =" xs : string "/ > 6 </ xs : sequence > </ xs : extension > 8 </ xs : complexContent > </ xs : complexType > Das Format des Geburtsdatums lässt sich durch einen regulären Ausdruck ebenfalls einschränken (xs:restriction). So muss der Geburtstag immer die Form JJJJ.MM.TT haben (siehe Listing 4.6). Listing 4.6. XML-Schema Erweiterung 4 1 < xs : simpleType name =" Geburtsdatum " > 2 < xs : restriction base =" xs : string " > < xs : pattern value ="[0 -9]{4}[.][0 -9]{2}[.][0 -9]{2}"/ > 4 </ xs : restriction > </ xs : simpleType > Anhand des XML-Schemas können eindeutige Schlüssel festgelegt werden. So kann für den komplexen Datentyp Frau definiert werden, dass alle darin enthaltenen Elemente eine eindeutige (unique) Kombination bilden müssen - eine Frau mit denselben Merkmalen darf nur einmal vorkommen. Zu dieser Elementenkombination kann dann ein Schlüssel (key) bereitgestellt werden, so dass von außen auf die Daten referenziert werden kann. Das XML Schema erlaubt sogar fremde Schemata wieder zu verwenden. Die Verknüpfung zwischen verschiedenen Schema Dateien wird von den include-, import- und redefine-Klauseln gewährleistet. Der Typ Frau kann durch den Import einer anderen Frau-Definition so angepasst werden, dass von beiden Schemata kompatible XML Dateien abgeleitet werden können. Beispiele zu den Schlüssel- und Importeigenschaften des XML-Schemas wurden herausgelassen, da sie zu kompliziert und eigentlich für dieses Seminarthema nicht relevant sind. 2.2 JAXB Java Architecture for XML Binding (JAXB) stellt einen innovativen Ansatz dar, mit dem Entwickler XML als Schnittstelle zwischen Java Anwendungen einfach benutzen können. Es ist nicht notwendig, in Java die XML Dateien zu parsen bzw. zu validieren - diese Aufgabe übernimmt JAXB. In den früheren Versionen (1.x) von JAXB gab es aber mehrere Probleme beim Einsatz dieser Technologie. Laufzeitfehler auf den unterschiedlichen Java Virtual Machines haben die wesentlichen Vorteile von Java wie Plattformunabhängigkeit und Portabilität beeinträchtigt. Der Fokus bei der Entwicklung von JAXB lag nur auf der Transformation von XML-Schema zu Java Datenmodelle und nicht umgekehrt, was die Kommunikation zwischen Java Anwendungen sehr erschwerte (vgl. [5]). Mit der aktuellen JAXB Version 2.x wurden die meisten Probleme behoben und viele innovative Verbesserungen eingeführt (vgl. [6]): 60 P. Radinski . Eine High-Level-XML-API erleichtert die Integration von XML, indem sie die Komplexität von XML Parsern von den Java Entwicklern fernhält und stattdessen eine allgemein bekannte und einfache Art für die Bindung von XML anbietet - nämlich die Java Beans (auch POJOs genannt - Plain Old Java Objects). Der jüngste Trend zu den POJOs basiert auf dem Streben nach mehr Einfachheit bei der Implementierung von Java Objekten und passt sehr gut in das Konzept von JAXB. . Um die Transformation zwischen Java und XML speziell anpassen zu können, werden Java Annotationen eingesetzt, die erst mit der Java Standard Edition 5 eingeführt wurden. Die JAXB-charakteristischen Annotationen werden im Kapitel 2.2.1 näher erläutert. . Ein weiteres Ziel von JAXB ist es, das XML-Schema - wie von W3C definiert - möglichst vollständig zu unterstützen, um sich als Standard durchzusetzen. . Mit der bidirektionalen Bindung zwischen Java und XML in JAXB 2.0 wurde ein sehr wichtiger Schritt gemacht, um die Verbindung von Java Anwendungen (auch Java Webservices) anhand XML zu ermöglichen. Das bedeutet, dass die Generierung einer XML Datei aus einem Java Objekt und die Transformation dieser XML Datei danach in einem zu dem ursprünglichen, äquivalenten Java Objekt unterstützt wird. . Die Validierung von XML Dokumenten mit Hilfe des XML-Schemas ist auch ein Teil der Verbesserungen in JAXB. Bei der Kommunikation zwischen Java Programmen ist es sehr wichtig, dass gültige XML Daten ausgetauscht werden. Wie diese Verbesserungen eine korrekte, bidirektionale Bindung zwischen Java und XML ermöglichen, wird in den nächsten Kapiteln dieser Seminararbeit anhand ausführlicher Beispiele veranschaulicht, die auf Windows Vista mit der Entwicklungsumgebung Eclipse 3.3.2 und der Java Version jdk1.6.0_07 erstellt wurden. Es gibt zwei Arten, wie JAXB auf einem Betriebssystem installiert werden kann. Einerseits ist JAXB ein Teil von Java geworden (die Klassen sind unter javax.xml.bind.* zu finden), andererseits kann die aktuelle JAXB Version von der Homepage (https://jaxb.dev.java.net/) heruntergeladen werden und in Eclipse entsprechend importiert werden (für die Beispiele wird hier die aktuellste 2.1.10 Version von JAXB benutzt). Auf der Abbildung 1 sind die fünf grundlegenden Bausteine von JAXB dargestellt. Zu jedem wird jeweils ein Kapitel mit Beispielen gewidmet. Der vollständige Quellcode zu den Beispielen ist immer im Anhang zu finden. . Deserialisieren (Unmarshalling) - Die Transformation von einer XML Datei in ein Java Objekt (automatische Validierung möglich). . Serialisieren (Marshalling) - Die Transformation von einem Java Objekt in eine XML Datei (automatische Validierung möglich). . Schemakompiler - Die Transformation von einem XML-Schema in ein Java Datenmodell. . Schemagenerator - Die Transformation von einem Java Datenmodell in ein XML-Schema. Binding zwischen XML-Schema-Modellen und Java-Beans (JAXB) 61 . Annotationen - Mit den JAXB Annotationen werden alle vier oben aufgeführten Funktionen konfiguriert. Es gibt die Mapping-Annotationen, die in Java definiert werden und die Bindungskonfigurationen - die Annotationen die im XML-Schema zum Einsatz kommen. Abbildung 1. JAXB Schema 2.2.1 JAXB Java-Annotationen In diesem Kapitel liegt der Schwerpunkt auf den Mapping-Annotationen, da sie für einen Java Programmierer, der sich mit XML-Schema und XML Parsern nicht auskennt, von großer Bedeutung sind. Die Bindungskonfigurationen werden im Kapitel Schemakompiler näher erläutert. Um die volle Funktionalität von JAXB nutzen zu können, muss ein Programmierer die dafür spezifischen Java-Annotationen gut kennen. Sie steuern die korrekte Bindung zwischen Java und XML. Es sind insgesamt 29 Annotationen verfügbar, die auf verschiedenen Ebenen eingesetzt werden können. Es gibt die Package-, Class-, Enum type-, JavaBean Property/field- und ParameterEbenen. Die Annotationen werden vor dem Java Element deklariert, auf dem sie angewendet werden sollen (siehe Listing 4.7). Sie haben folgenden Standardaufbau (@Annotationsname(Parameter)) und die wichtigsten davon werden nun näher erläutert (vgl. [11]). Listing 4.7. JAXB Annotationen Anwendung 1 2 4 6 8 10 ... // Annotation auf Class - Ebene @ Xm lR oo t El em en t public class Frau { // Annotation auf JavaBean Property / field - Ebene @XmlElement public String Name ; // Annoation auf JavaBean Property / field - Ebene 62 12 14 16 } P. Radinski @XmlTransient public void setName ( String Name ){ this . Name = Name ; } ... @XmlRootElement: XmlRootElement gibt an, dass die nachfolgende Java Klassendefinition einem XML Wurzelelement entspricht. Mit der Angabe @XmlRootElement(name=“XMLFrau“) wird vorgegeben, dass die Java Klasse Frau in XML den Namen XMLFrau hat. Diese Annotation kann auf Class- und Enum type-Ebenen angewendet werden. @XmlElement: Mit XmlElement werden Java Attribute gekennzeichnet, die in XML als XMLElemente dargestellt werden. @XmlElement(defaultValue=“Hund“) definiert den Standardwert für ein Element. Andere wichtige Parameter, die diese Annotation spezifizieren können, sind name, namespace, nillable, required und type. XmlElement kann nur auf JavaBean Property/field-Ebene angewendet werden. @XmlAccessorType: Die Annotation XmlAccessorType legt fest, welche Attribute einer Java Klasse in XML abgebildet werden sollen. Es gibt vier Parametererweiterungen, die abhängig von der Sichtbarkeit (public, private usw.) der Java Attribute ein entsprechendes Verhalten steuern. Mit @XmlAccessorType(XmlAccessType.NONE) werden nur die Attribute serialisiert, die auf @XmlElement und @XmlAttribute folgen. Mit XmlAccessType.PUBLIC_MEMBER werden alle public Attribute serialisiert. Mit XmlAccessType.PROPERTY werden nur Attribute abgebildet, die öffentliche getter- oder setter-Methoden haben. XmlAccessType.FIELD sagt aus, dass alle Attribute, außer der statischen, serialisiert werden sollen. Diese Annotation kann auf Package- und Class-Ebenen angewendet werden. @XmlAccessorOrder: XmlAccessorOrder erlaubt, die Reihenfolge der in XML abgebildeten Elemente zu ändern. Mit dem Parameter @XmlAccessorOrder(XmlAccessOrder. ALPHABETICAL) wird eine alphabetische Anordnung erzwungen, ansonsten erfolgt eine beliebige Sortierung. Diese Annotation kann auf Package- und ClassEbenen angewendet werden. @XmlTransient: Über die Annotation XmlTransient wird angegeben, dass ein Java Attribut nicht serialisiert werden darf. Diese Annotation kann auf JavaBean Property/fieldEbene angewendet werden. @XmlAttribute: Mit XmlAttribute werden die Attribute einer Java Klasse als XML Atrribute abgebildet. Diese Annotation kann auf JavaBean Property/field-Ebene angewendet werden. @XmlType: Die Annotation XmlType wird benutzt, um komplexe bzw. einfache XML Datentypen (<xs:complexType>, <xs:simpleType>) zu definieren. Diese Annotation kann auf Class- und Enum-Ebenen angewendet werden. @XmlValue: Binding zwischen XML-Schema-Modellen und Java-Beans (JAXB) 63 Mit der Annotation XmlValue wird ein Java Attribut in ein XML Wert transformiert (<xml>XMLWert</xml>). XmlValue und XmlElement können nicht gleichzeitig in derselben Klasse benutzt werden. Diese Annotation kann auf JavaBean Property/field-Ebene angewendet werden. Die bereits vorgestellten und die restlichen JAXB Annotationen erlauben eine präzise Bindung zwischen Java und XML. Sowohl Listen (@XmlElementWrapper, @XmlElements), als auch der Umgang mit verschiedenen Datentypen (@XmlJavaTypeAdapter), Schlüsseleigenschaften (@XmlID) und Importeigenschaften (@XmlAttachmentRef, @XmlNs) des XML-Schemas werden unterstützt. Damit schafft JAXB einen weiteren Schritt in Richtung seiner primären Ziele, nämlich das XML-Schema möglichst vollständig zu unterstützen. 2.2.2 Schemakompiler Beim Schemakompiler werden XML-Schemata in Java Datenmodelle umgewandelt. Für seine Anwendung ist also ein XML-Schema erforderlich. Dieses Schema kann dann über zwei verschiedenen Wege in ein fertiges Java Datenmodell transformiert werden - entweder die Kommandozeile oder viel bequemer, ein ANT-Skript in Eclipse (auch Build-Skript genannt), welches später im Abschnitt noch genauer erläutert wird. Beim Ausführen des ANT-Skripts werden mindestens zwei Java Klassen erstellt - mindestens eine Java Klasse zum XML-Schema und genau eine ObjectFactory.java Klasse. Im Beispiel mit der Frau wird nun das XML-Schema Frau.xsd aus Listing 4.2 benutzt, mit dem einzigen Unterschied, dass <xs:attribute name=“Name“> erst nach dem <xs:sequence> Attribut vorkommen darf (siehe Listing 4.27 im Anhang) - ansonsten meldet Eclipse einen Fehler, dass <xs:sequence> falsch aufgebaut wurde. Diese Frau.xsd wird im Projektordner schema abgelegt. Das ANT-Skript SchemaKompiler.xml wird im Projekt-Root-Ordner erstellt und wird über Run As -> Ant Build ausgeführt. Ein neuer Ordner generated wird automatisch angelegt und in diesem sind die fertigen Java Klassen Frau.java und ObjectFactory.java zu finden. Bevor aber gezeigt und erklärt wird, wie der Ablauf des Schemakompilers tatsächlich ist, müssen einige Begriffe und Zusammenhänge näher erläutert werden. Einige Grundbausteine sind beim Schemakompiler und beim Schemagenerator sehr ähnlich und werden nun hier vorgestellt. Folgende Transformationsregeln gelten in beiden Richtungen - also von XML-Schema zu Java Datenmodell (Schemakompiler) und umgekehrt (Schemagenerator) (vgl. [7]): . XML Namespace <=> Java Paket. Ein <targetNamespace=http://frau> wird zu einem package frau übersetzt und umgekehrt. . XML komplexer Datentyp <=> Java Klasse. Ein <xs:complexType name=“frau“> wird zu einem public class Frau übersetzt und umgekehrt. . XML einfacher Datentyp <=> Java Datentypen und Wrapper Klassen. Ein <xs:simpleType name=“ehemann“> wird z.B. zu einem protected String ehemann übersetzt und umgekehrt. 64 P. Radinski . XML einfacher Datentyp mit Enumeration <=> Java Enumeration. Siehe 4.8. Listing 4.8. Enumeration 6 < xs : simpleType name =" Beziehung " > < xs : restriction base =" xs : string " > < xs : enumeration value =" freund " / > < xs : enumeration value =" ehemann " / > </ xs : restriction > </ xs : simpleType > 8 ... in beiden Richtungen ... 1 2 4 10 12 public enum Beziehung { FREUND , EHEMANN ; } . XML Element <=> Java Attribut. Ein <xs:element name=“haustier“ type=“xs:string“> wird zu einem protected String Haustier übersetzt und umgekehrt. Ein ANT-Skript wird beim Schemakompiler und beim Schemagenerator eingesetzt und automatisiert die Umwandlungen in beiden Richtungen (Java nach XML bzw. XML nach Java). Er hat in beiden Fällen denselben Aufbau, aber verschiedene Parameter. ANT ist eine Java-basierte XML Sprache, mit der BuildSkripten erstellt werden, die verschiedene Aufgaben zusammenfassen (wie z.B. Kompilieren von Quellcode). Um nicht jedes Mal die JAXB Transformationsbefehle manuell anzustoßen, werden sie in Eclipse in einem ANT-Skript gepackt und ausgeführt. Dieses Skript besteht gewöhnlich aus folgenden Bereichen (vgl. [12]): . Im Bereich <project> wird das Default Projekt definiert - zu jedem Projekt gehört genau eine Build Datei. . Eine Beschreibung bzw. Kommentare können im <description> Tag angegeben werden. . <property name=“var“...> wird angewendet, um Redundanz im Quellcode zu vermeiden. Die Variable var kann dann durch ${var} angesprochen werden. . In <path> muss angegeben werden, wo sich das JDK und die JAXB Klassen befinden, da sie für die Transformation notwendig sind. Über <classpath> kann eine Funktion referenziert werden, die nicht in einer Datei mit einem existierenden Pfad auf dem System gespeichert ist. . Ein Projekt besteht aus mindestens einem <target> Bereich. Die Targets sind sozusagen die Ablauflogik eines ANT-Skripts. Sie können sich untereinander aufrufen und stoßen verschieden Aufgaben an - beispielsweise die Kompilierung des Quellcodes, oder das Verpacken in einem JAR-Archiv usw. . Funktionen werden in ANT mit dem <task> Tag bezeichnet. Es gibt vordefinierte Tasks (der Java-Compiler javac, ANT Tasks wie copy, delete, zip und mail) und benutzerdefinierte Tasks. xjc und schemaGen sind JAXB spezifische Tasks, die in ANT als “benutzerdefiniert“ mit dem Tag <taskdef > angegeben werden, da sie dem ANT Kompiler nicht direkt bekannt sind. Binding zwischen XML-Schema-Modellen und Java-Beans (JAXB) 65 In Listing 4.9 wird das ANT-Skript vorgeführt, das die Transformation von XML-Schema (Frau.xsd) nach Java steuert. Die ANT Datei beginnt mit der Angabe der XML Version. Wenn kein Target spezifiziert sein sollte, wird im <project> Tag mit dem Attribut default den default-Target definiert - xjc ist das JAXB-Task für die Schemakompilierung. Mit basedir wird das Hauptverzeichnis vorgegeben, wo sich alle Dateien zu dem gegebenen Projekt befinden. Ohne die Angabe der Ordner <path><fileset dir=...>, wo sich die JDK und JAXB Quelldaten auf dem System befinden, kann das ANT-Skript nicht funktionieren. Der <path> Tag besitzt außerdem das Attribut id=“classpath“, das später in der benutzerdefinierten Funktion <taskdef name=“xjc“...> referenziert wird. So wird dem ANT Compiler mitgeteilt, wo das xjc Task zu finden ist. Jetzt kann auch ein <target name=...> spezifiziert werden, das das xjc Task ausführt. Hier werden die Quell- und die Zielverzeichnisse angegeben - in welchem Ordner das Schema liegt (<schema dir=“schema“>), wie das Schema heisst (Frau.xsd) und wo sollen die neuen Java Datenmodelle (Klassen) erstellt werden (<xjc destdir=“.“>). Listing 4.9. ANT Skript - SchemaKompiler.xml 1 <? xml version ="1.0"? > 2 < project default =" xjc " basedir ="." > 4 6 8 10 12 14 16 18 20 < path id =" classpath " > < fileset dir =" C :\ Sun \ jaxb - ri -20090206\ lib " includes ="*. jar " / > < fileset dir =" C :\ Program Files \ Java \ jdk1 .6.0 _07 \ lib " includes ="*. jar " / > </ path > < taskdef name =" xjc " classname =" com . sun . tools . xjc . XJCTask " classpathref =" classpath " / > < target name =" xjc " > < xjc destdir ="." > < schema dir =" schema " > < include name =" Frau . xsd " / > </ schema > </ xjc > </ target > </ project > Nach dem Ausführen von SchemaKompiler.xml entstehen die Frau.java (Listing 4.11) und ObjectFactory.java (Listing 4.10) Klassen. In der ObjectFactory werden create-Methoden zu allen erzeugten Java Klassen gesammelt (vgl. [8]). Falls in einem XML-Schema zwei komplexe Datentypen definiert sind, werden bei der Transformation zwei Java Klassen erzeugt (z.B. Frau1.java und Frau2.java). In der ObjectFactory Klasse werden dann entsprechend zwei create-Methoden createFrau1() und createFrau2() generiert. Diese Factory-Klasse ist eine Art zentrale Verwaltung. Dort können alle erzeugten Java Klassen instanziert werden. Sie wird durch die Annotation @XmlRegistry auf Class-Ebene gekennzeichnet und kann ebenso manuell erstellt und angepasst werden. Die zu Listing 4.10 vollständige Klasse ist im Anhang unter Listing 4.29 zu finden. Listing 4.10. Automatisch generierte ObjectFactory.java (abgekürzt) 1 package generated ; 66 P. Radinski 2 import javax . xml . bind . annotation . XmlRegistry ; 4 ... @XmlRegistry 6 public class ObjectFactory { public ObjectFactory () { } 8 10 12 14 } public Frau createFrau () { return new Frau (); } Die Frau Klasse wird durch JAXB automatisch mit Java-Annotationen versehen, die die Struktur des XML-Schemas widerspiegeln. Alle Elemente <xs:element> aus dem komplexen Datentyp Frau sind erforderlich und zwar in der gegebenen Reihenfolge. Dies wird in Java auf Class-Ebene durch die Annotationen @XmlAccessorType, @XmlType und auf JavaBean Property /field - Ebene durch die Angabe required = true definiert. Alle mit @XmlElement und @XmlAttribute bezeichneten Java Attribute können über getter- und setter-Methoden angesprochen werden. Die zu Listing 4.11 vollständige Klasse ist im Anhang unter Listing 4.28 zu finden. Listing 4.11. Automatisch generierte Frau.java (abgekürzt) 1 package generated ; 2 import javax . xml . bind . annotation . XmlAccessType ; 4 import javax . xml . bind . annotation . X ml Ac ce s so rT yp e ; import javax . xml . bind . annotation . XmlAttribute ; 6 import javax . xml . bind . annotation . XmlElement ; import javax . xml . bind . annotation . XmlType ; 8 ... @ X m l A c c e s s o r T yp e ( XmlAccessType . FIELD ) 10 @XmlType ( name = " Frau " , propOrder = { " geburtsdatum " , 12 " visitenkarte " , " haustier " 14 }) public class Frau { 16 @XmlElement ( name = " Geburtsdatum " , required = true ) 18 protected String geburtsdatum ; ... 20 @XmlAttribute ( name = " Name " , required = true ) protected String name ; 22 public String g et G eb ur ts d at um () { 24 return geburtsdatum ; } 26 public void s et Ge bu r ts da tu m ( String value ) { this . geburtsdatum = value ; 28 } ... Die Transformation von XML-Schema nach Java kann auf zwei Arten beeinflusst werden - einerseits durch die XML-Schema-eigenen Sprachelemente, andererseits durch die JAXB Bindungskonfigurationen. An dieser Stelle werden einige interessante Transformationen vorgestellt, die teilweise auf den im Kapitel Binding zwischen XML-Schema-Modellen und Java-Beans (JAXB) 67 2.1.2 gezeigten XML-Schema Erweiterungen basieren. Ein komplexer Datentyp im XML-Schema kann durch <xs:sequence>, <xs:all> oder <xs:choice> angepasst werden. . <xs:sequence> bedeutet, dass alle Elemente in der gegebenen Reihenfolge auftreten müssen. Wie die Übersetzung in Java funktioniert, wurde in diesem Kapitel vorgestellt. . <xs:all> bedeutet, dass alle Elemente ohne eine bestimmte Reihenfolge vorhanden sein müssen. Der einzige Unterschied zu der Abbildung von <xs:sequence> ist, dass das Attribut propOrder von @XmlType leer ist. . <xs:choice> bedeutet, dass nur ein Element und nicht mehrere vorkommen dürfen. Der einzige Unterschied zu der Abbildung von <xs:sequence> ist, dass das Attribut required = true von @XmlType fehlt. Die Angabe von Kardinalitäten durch die minOccur und maxOccur Attribute im XML Schema wird von Java in folgender Weise interpretiert. Falls maxOccur vorhanden ist, kann minOccur ausgelassen werden - der Wert wird per default auf 1 gesetzt: . minOccur=“0 “ und maxOccur=“0 “ - das XML-Schema Element wird in Java überhaupt nicht abgebildet. . minOccur=“1 “ und maxOccur=“1 “ - normale Abbildung wie in Listing 4.28. . minOccur=“0 “ und maxOccur=“2 “ - alle Schema-Elemente, die mit maxOccur größer 1 (auch maxOccur=“unbounded“) markiert sind, werden als Java Listen interpretiert und nur mit getter- und ohne setter-Methoden abgebildet. Die setter-Methoden werden dann in einer anderen Weise implementiert (siehe Listing 4.12). Listing 4.12. min- und maxOccurs Variationen 1 ... 2 /* * * Gets the value of the geburtsdatum property . 4 * * <p > 6 * This accessor method returns a reference to the live list , * not a snapshot . Therefore any modification you make to the 8 * returned list will be present inside the JAXB object . * This is why there is not a < CODE > set </ CODE > method for the geburtsdatum property . 10 * * <p > 12 * For example , to add a new item , do as follows : * < pre > 14 * ge t Ge bu rt s da tu m (). add ( newItem ); * </ pre > 16 * * 18 * <p > * Objects of the following type ( s ) are allowed in the list 20 * { @link String } * 22 * */ 24 public List < String > ge t Ge bu rt s da tu m () { 68 P. Radinski 26 28 30 ... } if ( geburtsdatum == null ) { geburtsdatum = new ArrayList < String >(); } return this . geburtsdatum ; Die Anpassungen durch XML-Sprachelemente sind ein spannender Aspekt von JAXB, werden aber hier nicht mehr behandelt. Der interessierte Leser kann sich jedoch unter [9] mit dem Thema auseinandersetzen. Hier sollen nun auch die Anpassungen durch Bindungskonfigurationen vorgestellt werden. Mit ihnen kann das Verhalten des Schemakompilers weiter verfeinert werden. Diese Arbeit zeigt jedoch nur Grundzüge der Möglichkeiten - für ein besseres Verständnis der Bindungskonfigurationen siehe [10]. Die JAXB-Bindungskonfigurationen können inline (direkt im XML-Schema) oder extern (in einer Datei) definiert werden. Inline ist es viel komfortabler, da die Bindungskonfigurationen immer in der Datei “mitgenommen“ werden und das ANT-Skript auch nicht zusätzlich angepasst werden muss. Es wird anhand eines Beispiels (Listing 4.13) demonstriert, wie eine Bindungskonfiguration direkt im XML-Schema vom Listing 4.27 angebunden werden kann. Im Bereich <xs:annotation>...</xs:annotaion> eines XML-Schemas werden die Bindungskonfigurationen normalerweise definiert. Ganz wichtig ist die Zeile 3 im Beispiel - ohne die Angabe des Namespace können die Bindungskonfigurationen nicht aufgelöst werden. In Zeile 6 wird generateIsSetMethod=true benutzt, um in allen generierten Java Klassen (globalBindings) und für alle darin enthaltenen Attribute eine boolean isSet-Methode anzulegen. Sie überprüft, ob ein Attribut mit einem Wert belegt ist. Listing 4.13. Bindungskonfigurationen im XML-Schema 1 <? xml version ="1.0" encoding =" UTF -8" standalone =" yes "? > 2 < xs : schema version ="1.0" xmlns : xs =" http :// www . w3 . org /2001/ XMLSchema " xmlns : jaxb =" http :// java . sun . com / xml / ns / jaxb " jaxb : version ="2.0" > 4 < xs : annotation > < xs : appinfo > 6 < jaxb : globalBi ndings g e n e r a t e I s S e t M e t h o d =" true " / > </ xs : appinfo > 8 </ xs : annotation > < xs : c o m p l e x T y p e name =" Frau " > 10 ... Durch den Einsatz von jaxb:collectionType (Listing 4.14) kann beispielsweise das in Listing 4.12 als List<String> interpretierte Geburtsdatum in einem java.util.Vector transformiert werden (Listing 4.15). Mit der Angabe von globalBindings wird diese Regel auf alle Attribute vom Typ List<String> angewendet. Listing 4.14. jaxb:collectionType Einsatz 1 ... 2 < jaxb : globalBi ndings coll ectionTy pe =" java . util . Vector " / > ... Binding zwischen XML-Schema-Modellen und Java-Beans (JAXB) 69 Listing 4.15. Automatisch generierte Frau.java 1 ... 2 @XmlElement ( name = " Geburtsdatum " , required = true ) protected List < String > geburtsdatum = new Vector < String >(); 4 ... public List < String > ge t Ge bu rt s da tu m () { 6 if ( geburtsdatum == null ) { geburtsdatum = new Vector < String >(); 8 } return this . geburtsdatum ; 10 } ... Diese und viele andere Anpassungen im XML-Schema sind möglich. Mit der Annotation jaxb:class kann z.B. der Name der zu generierenden Java Klasse unabhängig vom Namen des komplexen Datentyps im XML-Schema geändert werden. Mit jaxb:property können die Namen der zu generierenden Java Attribute angepasst werden. 2.2.3 Schemagenerator Der Schemagenerator transformiert Java Datenmodelle zu XML-Schemata. Er steht erst seit der JAXB Version 2.0 zur Verfügung. Dafür notwendig sind mit JAXB Annotationen versehene Java Datenmodelle und ein ANT Skript. Die Transformation kann ebenfalls wie beim Schemakompiler auf zwei verschiedenen Wegen stattfinden - über die Kommandozeile oder über ein ANT-Skript in Eclipse. In dieser Arbeit wird aus Platzgründen jedoch nur auf den “bequemeren“ Weg in Eclipse eingegangen. Nach dem Ausführen des Skripts entsteht dann ein XML-Schema, das das Schema für alle Java Datenmodelle beinhaltet - also in einer Datei werden die Beschreibungen für alle Datenmodelle gesammelt. Im Beispiel wird die bereits im Schemakompiler generierte Frau.java Klasse (siehe 4.28) benutzt, um zu überprüfen, ob die Transformation “rückwärts“, also von der automatisch generierten Java Klasse nach XML-Schema dasselbe ergibt. Die im Schemakompiler erzeugte Klasse ObjectFactory.java kann “mitgenommen“ werden, ist aber für die Schemagenerierung nicht unbedingt erforderlich. Falls die getter- und setter-Methoden gleichzeitig fehlen, findet keine korrekte Umwandllung statt. Mindestens eine set- bzw. get-Methode für jedes Java Attribut muss im Quelltext verfügbar sein. Eine Transformation ist sogar ohne JAXB-Annotationen möglich, nur die getter- oder setter-Methoden müssen vorhanden sein, ansonsten wird dieses Attribut nicht in XML-Schema übersetzt. Das ANT-Skript (siehe 4.16) ist ähnlich wie beim Schemakompiler aufgebaut, hat aber natürlich andere Parameter. Im <taskdef > Tag wird ein benutzerdefiniertes Task angelegt, in dem das JAXB spezifische schemagen-Task für die Umwandlung von Java Datenmodelle nach XML-Schema eingefügt wird. Zu beachten ist, dass schemagen klein geschrieben wird und nicht schemaGen. Im Zielordner schemafolder wird das fertige XML-Schema ausgegeben. Listing 4.16. ANT Skript SchemaGenerator.xml 70 P. Radinski 1 <? xml version ="1.0"? > 2 < project name =" Frau " default =" schemagen " basedir ="." > 4 6 8 10 12 14 16 18 20 < path id =" classpath " > < fileset dir =" C :\ Sun \ jaxb - ri -20090206\ lib " includes ="*. jar " / > < fileset dir =" C :\ Program Files \ Java \ jdk1 .6.0 _07 \ lib " includes ="*. jar " / > </ path > < taskdef name =" schemagen " classname =" com . sun . tools . jxc . SchemaGenTask " classpathref =" classpath " > </ taskdef > < target name =" schemagen " > < schemagen destDir =" schemafolder " srcdir =" src " classpathref =" classpath " > </ schemagen > </ target > </ project > Das Ergebnis der Transformation ist in Schema1.xsd (Listing 4.17) zu sehen. Es ist bemerkenswert, dass es zum größten Teil dem ursprünglichen Schema vom Schemakompiler (Listing 4.27) entspricht. Es fehlen nur die occur-Attribute des Geburtsdatum-Elements. Sie sind aber eigentlich überflüssig, weil die Zusammensetzung minOccurs=“1“ und maxOccurs=“1“ nur besagt, dass das Geburtsdatum-Attribut vorhanden sein muss. Diese Anforderung ist durch die in der Java-Annotation @XmlElement vorhandene Eigenschaft required=“true“ gegeben. Die Übersetzung in XML-Schema erfordert dann keine Angabe von occur-Attributen. Listing 4.17. Automatisch generierte Schema1.xsd 1 <? xml version ="1.0" encoding =" UTF -8" standalone =" yes "? > 2 < xs : schema version ="1.0" xmlns : xs =" http :// www . w3 . org /2001/ XMLSchema " > 4 6 8 10 12 < xs : c o m p l e x T y p e name =" Frau " > < xs : sequence > < xs : element name =" Geburtsdatum " type =" xs : string "/ > < xs : element name =" Visitenkarte " type =" xs : string "/ > < xs : element name =" Haustier " type =" xs : string " default =" Hund "/ > </ xs : sequence > < xs : a t t r i b u t e name =" Name " type =" xs : string " use =" required "/ > </ xs : complexType > </ xs : schema > Die Umwandlung von Java Datenmodell nach XML-Schema kann durch die bereits im Kapitel 2.2.1 erwähnten Java-Annotationen weiter angepasst werden. Einige davon haben ihre äquivalenten XML-Schema Annotationen - d.h. sie sind bidirektional verknüpft. Aus der Annotation @XmlType(name = “Frau“, propOrder = “X“, “Y“) entsteht immer ein komplexer Datentyp <xs:complexType name = “Frau“> und umgekehrt. Andere werden im XML-Schema nicht direkt abgebildet. @XmlTransient gibt das Nichtvorhandensein eines Java Attributs vor. Das Beispiel in Listing 4.18 bedeutet, dass kein geburtsdatum-Element im XML-Schema vorkommen soll. Listing 4.18. Java-Annotation 1 Binding zwischen XML-Schema-Modellen und Java-Beans (JAXB) 71 1 ... 2 @XmlType ( name = " Frau " , propOrder = { " visitenkarte " , 4 " haustier " }) 6 public class Frau { 8 10 ... @XmlTransient protected String geburtsdatum ; Wenn zwei oder mehr Java Klassen beim Schemagenerator transformiert werden, so entstehen im XML-Schema zwei oder mehr komplexe Datentypen. Dasselbe gilt auch umgekehrt - die Anzahl der Java Klassen ist abhängig von der Anzahl der komplexen Datentypen. Solche Abhängigkeiten wurden bereits im Kapitel 2.2.2 Schemakompiler ausführlich beschrieben. Im selben Kapitel wurde auch angesprochen, dass eine manuelle Anpassung der ObjectFactory.java Klasse möglich ist. Bei der Validierung der XML-Daten durch das XML-Schema, was im nächsten Kapitel (Serialisieren) vorgestellt wird, ist es notwendig, dass zu dem komplexen Datentyp Frau eine <xs:element name=“frau“ type=“Frau“/ > Angabe im XML-Schema vorhanden ist. So ein Element wird von der Frau.java Klasse aus Listing 4.28 nicht automatisch erzeugt. Deshalb muss die ObjectFactory angepasst werden. Das funktioniert über die Annotation @XmlElementDecl (siehe Listing 4.19). In diesem Fall muss die ObjectFactory.java Klasse zusammen mit der Frau.java Klasse durch den Schemagenerator transformiert werden. Listing 4.19. ObjectFactory.java Anpassung 1 ... 2 @XmlRegistry public class ObjectFactory { 4 private final static QName _Frau_QNAME = new QName ("" , " frau "); 6 public ObjectFactory () { 8 } public Frau createFrau () { 10 return new Frau (); } 12 /* * 14 * Create an instance of { @link JAXBElement }{ @code <}{ @link Frau }{ @code >}} * 16 */ @ Xm lE le m en tD ec l ( namespace = "" , name = " frau ") 18 public JAXBElement < Frau > createFrau ( Frau value ) { return new JAXBElement < Frau >( _Frau_QNAME , Frau . class , null , value ); 20 } } 2.2.4 Serialisieren Beim Serialisieren (Marshalling) werden Java Objekte in XML Dateien umgewandelt. Dabei können die XML Daten durch das XML Schema validiert werden (auf Gültigkeit überprüft werden). Eine so genannte Serialisierer Java Klasse und mindestens eine Java Klasse mit JAXB Annotationen sind notwendig für die Datenübertragung in XML. Die Java Klassen können 72 P. Radinski direkt oder über die ObjectFactory Klasse instanziert werden. Beim Serialisieren und Deserialisieren wird kein ANT Skript gebraucht, da keine Java Datenmodelle bzw. XML-Schema transformiert werden - in Java werden jeweils XML Daten eingelesen (Deserialisieren) oder ausgegeben (Serialisieren). Im Beispiel wird manuell die Serialisierer.java Klasse angelegt, welche dann die Frau.java Klasse aufruft. Um über die Seminararbeit hinweg konsistent zu bleiben, wird hier die bereits beim Schemakompiler generierte Frau.java (siehe Listing 4.28) benutzt. Da es sich um nur eine Java Klasse handelt, wird die ObjectFactory nicht verwendet, sondern die Objekte werden direkt erzeugt. In der Serialisierer Klasse (Listing 4.20) findet die Transformation des Java Objektes in eine XML Datei statt. Am Anfang muss immer ein JAXBContext Objekt erstellt werden - dort ist die Bindung zwischen Java Datenmodell und XML-Schema definiert. Dann wird ein Marshaller Objekt aufgerufen, das alle für die Transformation notwendigen Methoden beinhaltet. Die Angabe JAXB_FORMATTED_OUTPUT bedeutet, dass die auszugebende XML-Datei entsprechend formatiert sein muss. Mit der Initialisierung der Frau Klasse können ihre Attribute über die setter-Methoden mit Werten belegt werden. Diese Werte werden durch die Angabe marshaller.marshal in eine XML-Datei (Listing 4.37) umgewandelt. Die zu Listing 4.20 vollständige Klasse ist unter Listing 4.34 zu finden. Listing 4.20. Serialisierer.java 1 import javax . xml . bind . JAXBContext ; 2 import javax . xml . bind . Marshaller ; 4 public class Serialisierer { public static void main ( String [] args ) { 6 try { JAXBContext context = JAXBContext . newInstance ( Frau . class ); Marshaller marshaller = context . c r e a t e M a r s h a l l e r (); 8 10 12 marshaller . setProperty ( Marshaller . JAXB_FORMATTED_OUTPUT , true ); 14 Frau frau = new Frau (); frau . se tG eb u rt sd at u m (" 11 . 11 .1 11 1 ") ; ... marshaller . marshal ( frau , System . out ); 16 18 20 22 } } } catch ( Exception e ) { e . p ri nt St a ck Tr ac e (); } Die in Schemakompiler automatisch erzeugte Frau.java Klasse (Listing 4.28) ist aber noch nicht für die Serialisierung vorbereitet und muss leicht angepasst werden. Eine Zeile muss noch eingefügt werden (siehe Listing 4.21) - die vollständige Klasse ist in Listing 4.35 zu finden. Ohne die Angabe der @XmlRootElement Annotation kann das Serialisieren nicht funktionieren. Auch ohne Angabe von JAXB-Annotationen in der Frau Klasse kann die Serialisierung auskommen, nur die setter-Methoden und die @XmlRootElement Annotation müssen vorhanden Binding zwischen XML-Schema-Modellen und Java-Beans (JAXB) 73 sein. Listing 4.21. Angepasste Frau.java 1 ... 2 @ Xm lR oo t El em en t public class Frau { 4 ... } Bei der Transformation können kein oder alle Java Attribute über die setterMethoden mit Inhalten belegt werden - es wird immer eine XML-Datei erstellt. Wenn aber die XML-Datei auch validiert werden muss, dann müssen in Java die Wertebelegungen und die JAXB Annotationen entsprechend dem XML-Schema erfolgen. Im Beispiel hier müssen wegen <xs:sequence> alle im XML-Schema definierten Elemente und Attribute initialisiert werden. In der Serialisierer Klasse wird auch die Validierung der XML Datei implementiert (Listing 4.22). Die Validierung der XML Daten beim Seralisieren gleicht der Validierung beim Deserialisieren. In beiden Fällen wird eine XML-Datei durch ein XML-Schema auf Gültigkeit überprüft. Listing 4.22. Für die Validierung angepasste Serialisierer.java 1 ... 2 import java . io . File ; import javax . xml . validation . Schema ; 4 import javax . xml . validation . SchemaFactory ; ... 6 public class Serialisierer { ... 8 SchemaFactory sf = SchemaFactory . newInstance ( javax . xml . XMLConstants . W 3 C _ X M L _ S C H E M A _ N S _ U R I ); 10 Schema schema = sf . newSchema ( new File (" Frau . xsd ")); 12 marshaller . setSchema ( schema ); // unmarshaller . setSchema ( schema );// beim De se r ia li si e re r 14 ... Frau frau = new Frau (); 16 frau . setHaustier (" rexi "); frau . se tG e bu rt sd at u m (" 1 1. 11 .1 1 11 ") ; 18 frau . se tV i si te nk ar t e (" D :\ visitenkarte . doc "); frau . setName (" Stephie Müller "); 20 ... } Das hier benutzte XML-Schema aus Listing 4.27 ist aber für die Validierung noch nicht ausreichend. Eine Zeile mit der Angabe des komplexen Datentyps Frau als <xs:element> (siehe Listing 4.23) fehlt noch. Im Kapitel Schemagenerator wurde bereits gezeigt, wie diese Zeile durch Anpassung der ObjectFactory Klasse auch automatisch generiert werden kann. Listing 4.23. Für die Validierung angepasste Frau.xsd 1 ... 2 < xs : schema version ="1.0" xmlns : xs =" http :// www . w3 . org /2001/ XMLSchema " > < xs : element name =" frau " type =" Frau " / > 4 < xs : c o m p l e x T y p e name =" Frau " > ... 74 P. Radinski 2.2.5 Deserialisieren Beim Deserialisieren (Unmarshalling) werden XML Dateien in Java Objekte transformiert. Die XML Dateien können auf derselben Art wie in Kapitel Serialisieren 2.2.4 auf Gültigkeit überprüft werden und ein ANT-Skript ist ebenfalls nicht notwendig. Die Java Klassen können direkt oder bei einer umfangreicheren Anwednung über die ObjectFactory Klasse instanziert werden. Für das Deserialisieren sind eine so genannte Deserialisierer Klasse, mindestens eine Java Klasse mit JAXB Annotationen und eine XML-Datei erforderlich. Die XML Daten werden dann nach der Deserialisierung als strukturierte Java Objekte bereitgestellt. Im Beispiel werden die in Kapitel 2.2.4 als Ergebnis des Serialisierens erzeugte XML Datei (Listing 4.37) und die angepasste Frau.java (Listing 4.35) benutzt. Eine ObjectFactory Klasse wird nicht verwendet. Es wird überprüft, ob die Daten, die vorher in eine XML-Datei ausgegeben wurden, korrekt wieder in Java eingelesen werden können. Im Gegenteil zum Serialisieren werden hier alle JAXB-Annotationen in der Frau Klasse gebraucht, ansonsten werden die Java Attribute mit dem Wert null belegt. Hier sind nur die getter-Methoden wichtig, die Anwendung kommt auch ohne die setter-Methoden aus. Die Deserialisierer Klasse ist ähnlich wie die Serialisierer Klasse aufgebaut. Am Anfang wird durch ein JAXBContext ein Unmarshaller Objekt erzeugt, das die XML-Datei einliest. Über die getter-Methoden der Frau Klasse werden die XML-Daten in Java angebunden. Listing 4.24. Deserialisierer.java 1 import java . io . File ; 2 import javax . xml . bind . JAXBContext ; import javax . xml . bind . Unmarshaller ; 4 public class D es er ia l is ie re r { 6 public static void main ( String [] args ) { 8 try { 10 JAXBContext context = JAXBContext . newInstance ( Frau . class ); Unmarshaller unmarshaller = context . c r e a t e U n m a r s h a l l e r (); 12 Frau frau = ( Frau ) unmarshaller . unmarshal ( new File ( 14 " frau . xml ")); System . out . println (" Frau : " + frau . getName ()); 16 18 20 22 } } } catch ( Exception e ) { e . p ri nt St a ck Tr ac e (); } Die Validierung der XML-Datei wird in der Deserialisierer Klasse implementiert. Dabei muss das im Kapitel Serialisieren 2.2.4 angepasste XML-Schema (Listing 4.23) benutzt werden - also mit der Angabe <xs:element> für den komplexen Datentyp Frau. Im Gegenteil zum Serialisieren müssen hier nicht unbedingt alle getter-Methoden benutzt werden, weil sie keine Auswirkung auf die XML-Datei haben. Über die setter-Methoden können die aus XML eingelese- Binding zwischen XML-Schema-Modellen und Java-Beans (JAXB) 75 nen Daten überschrieben werden. In Listing 4.22 wurde bereits gezeigt, wie die Validierung funktioniert. Beim Deserialisieren wird nur Zeile 6 - wie im Listing 4.25 - angepasst. Listing 4.25. Validierung beim Deserialisieren 1 ... 2 SchemaFactory sf = SchemaFactory . newInstance ( javax . xml . XMLConstants . W 3 C _ X M L _ S C H E M A _ N S _ U R I ); 4 Schema schema = sf . newSchema ( new File (" Frau . xsd ")); 6 unmarshaller . setSchema ( schema ); ... 8 // getter - Methoden ... 2.3 JAXB Beispiel In diesem Kapitel wird anhand eines frei gewählten Modells veranschaulicht, wie der JAXB Ansatz sich in die Modellbasierte Softwareentwicklung integrieren lässt. Am Anfang dieser Seminararbeit wurde die Frage gestellt, wie JAXB die Bindung zwischen Java und XML herstellen kann - diese Frage wurde ausführlich in den vorausgegangenen Kapitel mit zahlreichen Beispielen beantwortet und das Ergebnis wird hier mit einem im Vergleich zu den vorherigen, komplizierteren Beispiel untermauert. Es wird nun eine Java Anwendung vorgestellt (siehe Abbildung 2), die Deterministische Endliche Automaten (DEAs) einliest, sie ausführt und das Ergebnis ausgibt. Die Definition eines DEAs ist wie folgt vorgegeben: ein DEA hat Zustände, Übergänge und eine Eingabe. Ein Zustand wird durch ein Zeichen repräsentiert und kann ein Startzustand, ein Endzustand oder ein sonstiger Zustand sein. Ein Übergang wird durch ein Tripel (Quelle-Zustand, Buchstabe aus Alphabet, Ziel-Zustand) dargestellt, wobei die Elemente des Tripels jeweils aus einzelnen Zeichen bestehen. Die Eingabe des DEAs ist eine beliebige Folge aus Buchstaben des Alphabets und wird entweder mitgeliefert oder in der Anwendung zur Laufzeit eingegeben. Die Grundregeln eines DEAs dürfen nicht verletzt werden. Das Alphabet darf keine Schnittmenge mit den Zuständen bilden und die Übergänge müssen eindeutig sein. Es wird von einem gültigen DEA ausgegangen, deshalb muss das Alphabet zur Überprüfung nicht mitgeliefert werden. Im Beispiel werden der tatsächliche DEA (sein Modell - siehe Abbildung 3) in einer XML Datei Dea.xml (Listing 4.44) und die Vorgaben für seine Gültigkeitsüberprüfung (sein MetaModell) in einem XML-Schema Dea.xsd (Listing 4.43) gespeichert. Beide Dateien stellen die Eingabe des Programms dar. Die Anwendung hier ist zum größten Teil auf der DEA-Definition in Dea.xsd aufgebaut. Es ist aber auch möglich, dass eine Schnittstelle definiert wird, so dass über vorgegebenen Methoden auf die Daten des DEAs zugegeriffen wird - so können auch unterschiedliche XML-Schemata eingelesen werden. Wenn hier ein XMLSchema geliefert wird, das denselben Aufbau wie in Dea.xsd hat, aber auch noch 76 P. Radinski Abbildung 2. DEA Beispiel Ablauf das Alphabet des DEAs beinhaltet, stellt das für die Anwendung kein Problem dar, denn die nötigen Daten können trotzdem eingelesen werden. Beim ersten Schritt wird dem SchemaKompiler.xml (Listing 4.42) die Dea.xsd übergeben. Bei der Modelltransformation entstehen folgende Klassen - Dea.java (Listing 4.46), Eingabe.java (Listing 4.47), ObjectFactory.java (Listing 4.48), Zustaende.java (Listing 4.51), Zustand.java (Listing 4.52), Uebergaenge.java (Listing 4.49) und Uebergang.java (Listing 4.50). Diese Klassen sind die äußere Bean-Hülle und werden dann für die Bindung der XML Daten verwendet. Im nächsten Schritt werden in der Deserialisierer.java (Listing 4.53) Klasse diese automatisch generierten Klassen über ein Unmarshaller-Objekt für das Einlesen der XML Daten benutzt. Außerdem findet in der Deserialisierer Klasse die Validierung der eingelesenen Dea.xml durch die Dea.xsd und die Anbindung der Anwendungslogik DEA_Engine.java (Listing 4.45) statt. Nach dem Ausführen des Programms (Deserialisierer.java) mit einer beliebigen Zeichenfolge als Eingabe, die in der Dea.xml mitgeliefert wird, wird entweder “akzeptiert“ oder “nicht akzeptiert“ Binding zwischen XML-Schema-Modellen und Java-Beans (JAXB) 77 Abbildung 3. DEA Beispiel ausgegeben. Falls die Gültigkeitsüberprüfung der XML-Datei fehlschlägt, wird eine detaillierte Fehlermeldung angezeigt. 3 Schluss In dieser Seminararbeit wurde gezeigt, dass JAXB an sich sehr flexibel und vielseitig ist. Durch geringe Änderungen am Quellcode können verschiedene Erweiterungen eingefügt werden. Diese Erweiterungen wären bestimmt nicht notwendig, wenn die dargestellten Beispiele von Anfang an umfangreicher und komplizierter eingeplant wären. So wäre aber die Flexibilität von JAXB nicht eindeutig zum Vorschein gekommen und es hätte sich nicht gezeigt, wie einfach es ist, diese Erweiterungen einzubauen. Insgesamt erweist sich JAXB als eine sehr gute Alternative im Vergleich zu den parser-basierten Verfahren (SAX, DOM und Pull API), XML an Java anzubinden. Seit der Version 2.0 wurden erhebliche Verbesserungen erreicht, die einen großen Vorteil mit sich bringen, nämlich die bidirektionale Bindung zwischen den beiden Technologien Java und XML. Damit wurde der Weg freigemacht, XML als die Schnittstelle für Datentransfer zwischen Java Anwendungen einzusetzen. Im Sinne der Modellbasierten Softwareentwicklung ermöglicht JAXB eine vollständige und korrekte bidirektionale Modelltransformation zwischen Java und XML. Besonders bei den Service Orientierten Architekturen wird eine einfache und flexible Technologie gebraucht, um verschiedene Java Anwendungen bzw. Java Web Services anzubinden. JAXB ist diese Technologie. 4 4.1 Anhang Schemakompiler Listing 4.26. SchemaKompiler.xml 1 <? xml version ="1.0"? > 2 < project default =" xjc " basedir ="." > 78 P. Radinski Abbildung 4. Schemakompiler in Ecipse 4 6 8 10 12 14 16 18 20 < path id =" classpath " > < fileset dir =" C :\ Sun \ jaxb - ri -20090206\ lib " includes ="*. jar " / > < fileset dir =" C :\ Program Files \ Java \ jdk1 .6.0 _07 \ lib " includes ="*. jar " / > </ path > < taskdef name =" xjc " classname =" com . sun . tools . xjc . XJCTask " classpathref =" classpath " / > < target name =" xjc " > < xjc destdir ="." > < schema dir =" schema " > < include name =" Frau . xsd " / > </ schema > </ xjc > </ target > </ project > Listing 4.27. Frau.xsd 1 <? xml version ="1.0" encoding =" UTF -8" standalone =" yes "? > 2 < xs : schema version ="1.0" xmlns : xs =" http :// www . w3 . org /2001/ XMLSchema " > < xs : c o m p l e x T y p e name =" Frau " > 4 < xs : sequence > < xs : element name =" Geburtsdatum " type =" xs : string " 6 minOccurs ="1" maxOccurs ="1" / > < xs : element name =" Visitenkarte " type =" xs : string " / > 8 < xs : element name =" Haustier " type =" xs : string " default =" Hund " / > </ xs : sequence > 10 <! - - interessant ist , dass attribut vor s e q u e n c e verboten ist --> < xs : a t t r i b u t e name =" Name " type =" xs : string " use =" required "/ > 12 </ xs : complexType > </ xs : schema > Listing 4.28. Frau.java Binding zwischen XML-Schema-Modellen und Java-Beans (JAXB) 79 1 // 2 // This file was generated by the JavaTM Architecture for XML Binding ( JAXB ) Reference Implementation , vh // See <a href =" http :// java . sun . com / xml / jaxb " > http :// java . sun . com / xml / jaxb </ a > 4 // Any modifications to this file will be lost upon recompilation of the source schema . // Generated on : 2009.03.20 at 05:10:57 PM CET 6 // 8 package generated ; 10 import 12 import import 14 import import 16 javax . xml . bind . annotation . XmlAccessType ; javax . xml . bind . annotation . X ml Ac ce s so rT yp e ; javax . xml . bind . annotation . XmlAttribute ; javax . xml . bind . annotation . XmlElement ; javax . xml . bind . annotation . XmlType ; 18 /* * * <p > Java class for Frau complex type . 20 * * <p > The following schema fragment specifies the expected content contained within this class . 22 * * < pre > 24 * & lt ; complexType name =" Frau " > * & lt ; complexContent > 26 * & lt ; restriction base ="{ http :// www . w3 . org /2001/ XMLSchema } anyType " > * & lt ; sequence > 28 * & lt ; element name =" Geburtsdatum " type ="{ http :// www . w3 . org /2001/ XMLSchema } string "/ > * & lt ; element name =" Visitenkarte " type ="{ http :// www . w3 . org /2001/ XMLSchema } string "/ > 30 * & lt ; element name =" Haustier " type ="{ http :// www . w3 . org /2001/ XMLSchema } string "/ > * & lt ;/ sequence > 32 * & lt ; attribute name =" Name " use =" required " type ="{ http :// www . w3 . org /2001/ XMLSchema } string " / > * & lt ;/ restriction > 34 * & lt ;/ complexContent > * & lt ;/ complexType > 36 * </ pre > * 38 * */ 40 @ X m l A c c e s s o r T yp e ( XmlAccessType . FIELD ) @XmlType ( name = " Frau " , propOrder = { 42 " geburtsdatum " , " visitenkarte " , 44 " haustier " }) 46 public class Frau { 48 50 52 54 56 58 60 62 64 66 68 @XmlElement ( name = " Geburtsdatum " , required = true ) protected String geburtsdatum ; @XmlElement ( name = " Visitenkarte " , required = true ) protected String visitenkarte ; @XmlElement ( name = " Haustier " , required = true , defaultValue = " Hund ") protected String haustier ; @XmlAttribute ( name = " Name " , required = true ) protected String name ; /* * * Gets the value of the geburtsdatum property . * * @return * possible object is * { @link String } * */ public String g et G eb ur ts d at um () { return geburtsdatum ; } 80 70 72 74 76 78 80 82 84 86 88 90 92 94 96 98 100 102 104 106 108 110 112 114 116 118 120 122 124 126 128 130 132 134 136 P. Radinski /* * * Sets the value of the geburtsdatum property . * * @param value * allowed object is * { @link String } * */ public void s et Ge bu r ts da tu m ( String value ) { this . geburtsdatum = value ; } /* * * Gets the value of the visitenkarte property . * * @return * possible object is * { @link String } * */ public String g et V is it en k ar te () { return visitenkarte ; } /* * * Sets the value of the visitenkarte property . * * @param value * allowed object is * { @link String } * */ public void s et Vi si t en ka rt e ( String value ) { this . visitenkarte = value ; } /* * * Gets the value of the haustier property . * * @return * possible object is * { @link String } * */ public String getHaustier () { return haustier ; } /* * * Sets the value of the haustier property . * * @param value * allowed object is * { @link String } * */ public void setHaustier ( String value ) { this . haustier = value ; } /* * * Gets the value of the name property . * * @return * possible object is * { @link String } * */ Binding zwischen XML-Schema-Modellen und Java-Beans (JAXB) public String getName () { return name ; } 138 140 /* * * Sets the value of the name property . * * @param value * allowed object is * { @link String } * */ public void setName ( String value ) { this . name = value ; } 142 144 146 148 150 152 81 } Listing 4.29. ObjectFactory.java 1 // 2 // This file was generated by the JavaTM Architecture for XML Binding ( JAXB ) Reference Implementation , vh // See <a href =" http :// java . sun . com / xml / jaxb " > http :// java . sun . com / xml / jaxb </ a > 4 // Any modifications to this file will be lost upon recompilation of the source schema . // Generated on : 2009.03.20 at 05:10:57 PM CET 6 // 8 10 package generated ; import javax . xml . bind . annotation . XmlRegistry ; 12 14 /* * * This object contains factory methods for each 16 * Java content interface and Java element interface * generated in the generated package . 18 * <p > An ObjectFactory allows you to pr o gr am at i ca ll y * construct new instances of the Java rep resentat ion 20 * for XML content . The Java represe ntation of XML * content can consist of schema derived interfaces 22 * and classes representing the binding of schema * type definitions , element declarations and model 24 * groups . Factory methods for each of these are * provided in this class . 26 * */ 28 @XmlRegistry public class ObjectFactory { 30 /* * * Create a new ObjectFactory that can be used to create new instances of schema derived classes for * */ public ObjectFactory () { } 32 34 36 38 /* * * Create an instance of { @link Frau } * */ public Frau createFrau () { return new Frau (); } 40 42 44 46 } 82 P. Radinski 4.2 Schemagenerator Abbildung 5. Schemagenerator in Eclipse Listing 4.30. SchemaGenerator.xml 1 <? xml version ="1.0"? > 2 < project name =" Frau " default =" schemagen " basedir ="." > 4 6 8 10 12 14 16 18 20 < path id =" classpath " > < fileset dir =" C :\ Sun \ jaxb - ri -20090206\ lib " includes ="*. jar " / > < fileset dir =" C :\ Program Files \ Java \ jdk1 .6.0 _07 \ lib " includes ="*. jar " / > </ path > < taskdef name =" schemagen " classname =" com . sun . tools . jxc . SchemaGenTask " classpathref =" classpath " > </ taskdef > < target name =" schemagen " > < schemagen destDir =" schemafolder " srcdir =" src " classpathref =" classpath " > </ schemagen > </ target > </ project > Listing 4.31. Frau.java 1 Dieselbe Klasse wie in Schema kompiler ! 1 Dieselbe Klasse wie in Schema kompiler ! Listing 4.32. ObjectFactory.java Binding zwischen XML-Schema-Modellen und Java-Beans (JAXB) Listing 4.33. Schema1.xsd 1 <? xml version ="1.0" encoding =" UTF -8" standalone =" yes "? > 2 < xs : schema version ="1.0" xmlns : xs =" http :// www . w3 . org /2001/ XMLSchema " > 4 6 8 10 12 < xs : c o m p l e x T y p e name =" Frau " > < xs : sequence > < xs : element name =" Geburtsdatum " type =" xs : string "/ > < xs : element name =" Visitenkarte " type =" xs : string "/ > < xs : element name =" Haustier " type =" xs : string " default =" Hund "/ > </ xs : sequence > < xs : a t t r i b u t e name =" Name " type =" xs : string " use =" required "/ > </ xs : complexType > </ xs : schema > 4.3 Serialisieren Abbildung 6. Serialisieren in Eclipse Listing 4.34. Serialisierer.java 1 import javax . xml . bind . JAXBContext ; 2 import javax . xml . bind . Marshaller ; 4 public class Serialisierer { 6 8 10 12 14 16 public static void main ( String [] args ) { try { JAXBContext context = JAXBContext . newInstance ( Frau . class ); Marshaller marshaller = context . c r e a t e M a r s h a l l e r (); marshaller . setProperty ( Marshaller . JAXB_FORMATTED_OUTPUT , true ); Frau frau = new Frau (); frau . se tG eb u rt sd at u m (" 11 . 11 .1 11 1 ") ; 83 84 P. Radinski frau . setHaustier (" rexi "); frau . setName (" Stephie Müller "); 18 20 marshaller . marshal ( frau , System . out ); 22 24 26 } } } catch ( Exception e ) { e . p ri nt St a ck Tr ac e (); } Listing 4.35. Frau.java 1 // 2 // This file was generated by the JavaTM Architecture for XML Binding ( JAXB ) Reference Implementation , vh // See <a href =" http :// java . sun . com / xml / jaxb " > http :// java . sun . com / xml / jaxb </ a > 4 // Any modifications to this file will be lost upon recompilation of the source schema . // Generated on : 2009.03.18 at 07:16:25 PM CET 6 // 8 10 import 12 import import 14 import import 16 import 18 20 22 24 26 28 30 32 34 36 38 40 javax . xml . bind . annotation . XmlAccessType ; javax . xml . bind . annotation . X ml Ac ce s so rT yp e ; javax . xml . bind . annotation . XmlAttribute ; javax . xml . bind . annotation . XmlElement ; javax . xml . bind . annotation . XmlRoot Element ; javax . xml . bind . annotation . XmlType ; /* * * <p > Java class for Frau complex type . * * <p > The following schema fragment specifies the expected content contained within this class . * * < pre > * & lt ; complexType name =" Frau " > * & lt ; complexContent > * & lt ; restriction base ="{ http :// www . w3 . org /2001/ XMLSchema } anyType " > * & lt ; sequence > * & lt ; element name =" Geburtsdatum " type ="{ http :// www . w3 . org /2001/ XMLSchema } string "/ > * & lt ; element name =" Visitenkarte " type ="{ http :// www . w3 . org /2001/ XMLSchema } string "/ > * & lt ; element name =" Haustier " type ="{ http :// www . w3 . org /2001/ XMLSchema } string "/ > * & lt ;/ sequence > * & lt ; attribute name =" Name " use =" required " type ="{ http :// www . w3 . org /2001/ XMLSchema } string " / > * & lt ;/ restriction > * & lt ;/ complexContent > * & lt ;/ complexType > * </ pre > * * */ @ Xm lR oo t El em en t // Das muss manuell hinzugefügt werden , ansonsten wie in S chemakom piler ! 42 @ X m l A c c e s s o r T yp e ( XmlAccessType . FIELD ) 44 @XmlType ( name = " Frau " , propOrder = { " geburtsdatum " , 46 " visitenkarte " , " haustier " 48 }) 50 public class Frau { 52 54 @XmlElement ( name = " Geburtsdatum " , required = true ) protected String geburtsdatum ; @XmlElement ( name = " Visitenkarte " , required = true ) Binding zwischen XML-Schema-Modellen und Java-Beans (JAXB) 56 58 60 62 64 66 68 70 72 74 76 78 80 82 84 86 88 90 92 94 96 98 100 102 104 106 108 110 112 114 116 118 120 122 protected String visitenkarte ; @XmlElement ( name = " Haustier " , required = true , defaultValue = " Hund ") protected String haustier ; @XmlAttribute ( name = " Name " , required = true ) protected String name ; /* * * Gets the value of the geburtsdatum property . * * @return * possible object is * { @link String } * */ public String g et G eb ur ts d at um () { return geburtsdatum ; } /* * * Sets the value of the geburtsdatum property . * * @param value * allowed object is * { @link String } * */ public void s et Ge bu r ts da tu m ( String value ) { this . geburtsdatum = value ; } /* * * Gets the value of the visitenkarte property . * * @return * possible object is * { @link String } * */ public String g et V is it en k ar te () { return visitenkarte ; } /* * * Sets the value of the visitenkarte property . * * @param value * allowed object is * { @link String } * */ public void s et Vi si t en ka rt e ( String value ) { this . visitenkarte = value ; } /* * * Gets the value of the haustier property . * * @return * possible object is * { @link String } * */ public String getHaustier () { return haustier ; } /* * * Sets the value of the haustier property . 85 86 P. Radinski * * @param value * allowed object is * { @link String } * */ public void setHaustier ( String value ) { this . haustier = value ; } 124 126 128 130 132 /* * * Gets the value of the name property . * * @return * possible object is * { @link String } * */ public String getName () { return name ; } 134 136 138 140 142 144 /* * * Sets the value of the name property . * * @param value * allowed object is * { @link String } * */ public void setName ( String value ) { this . name = value ; } 146 148 150 152 154 156 } Listing 4.36. ObjectFactory.java 1 Dieselbe Klasse wie in Schema kompiler ! Listing 4.37. Ausgabe Serialisierer.java 1 <? xml version ="1.0" encoding =" UTF -8" standalone =" yes "? > 2 < frau Name =" Stephie Müller " > < Geburtsdatum >11.11.1111 </ Geburtsdatum > 4 < Haustier > rexi </ Haustier > </ frau > 4.4 Deserialisieren Listing 4.38. Deserialisierer.java 1 import java . io . File ; 2 import javax . xml . bind . JAXBContext ; 4 import javax . xml . bind . Unmarshaller ; 6 public class D es er ia l is ie re r { 8 10 public static void main ( String [] args ) { try { Binding zwischen XML-Schema-Modellen und Java-Beans (JAXB) Abbildung 7. Deserialisieren in Eclipse JAXBContext context = JAXBContext . newInstance ( Frau . class ); 12 Unmarshaller unmarshaller = context . c r e a t e U n m a r s h a l l e r (); 14 Frau frau = ( Frau ) unmarshaller . unmarshal ( new File ( " frau . xml ")); 16 System . out . println (" Frau : " + frau . getName ()); System . out . println (" Geboren am : " + frau . g et Ge bu r ts da tu m ()); System . out . println (" Tier : " + frau . getHaustier ()); 18 20 22 24 26 } } } catch ( Exception e ) { e . p ri nt St a ck Tr ac e (); } Listing 4.39. Frau.java 1 Dieselbe Klasse wie in Serialisieren ! 1 Dieselbe Klasse wie in Schema kompiler ! Listing 4.40. ObjectFactory.java Listing 4.41. Ausgabe Deserialisierer 1 Frau : Stephi Müller 2 Geboren am : 11.11.1111 Tier : rexi 4.5 JAXB Beispiel 87 88 P. Radinski Abbildung 8. JAXB Beispiel in Eclipse Listing 4.42. SchemaKompiler.xml 1 <? xml version ="1.0"? > 2 < project default =" xjc " basedir ="." > 4 6 8 10 12 14 16 18 20 < path id =" classpath " > < fileset dir =" C :\ Sun \ jaxb - ri -20090206\ lib " includes ="*. jar " / > < fileset dir =" C :\ Program Files \ Java \ jdk1 .6.0 _07 \ lib " includes ="*. jar " / > </ path > < taskdef name =" xjc " classname =" com . sun . tools . xjc . XJCTask " classpathref =" classpath " / > < target name =" xjc " > < xjc destdir ="." > < schema dir =" schema " > < include name =" Dea . xsd " / > </ schema > </ xjc > </ target > </ project > Binding zwischen XML-Schema-Modellen und Java-Beans (JAXB) Listing 4.43. Dea.xsd 1 <? xml version ="1.0" encoding =" UTF -8" ? > 2 < xs : schema xmlns : xs =" http :// www . w3 . org /2001/ XMLSchema " > < xs : element name =" dea " > 4 < xs : complexType > < xs : sequence > 6 < xs : element ref =" eingabe " / > < xs : element ref =" zustaende " / > 8 < xs : element ref =" uebergaenge " / > </ xs : sequence > 10 </ xs : complexType > </ xs : element > 12 < xs : element name =" eingabe " > < xs : c o m p l e x T y p e mixed =" true " / > 14 </ xs : element > < xs : element name =" uebergaenge " > 16 < xs : complexType > < xs : sequence > 18 < xs : element ref =" uebergang " maxOccurs =" unbounded " / > </ xs : sequence > 20 </ xs : complexType > </ xs : element > 22 < xs : element name =" uebergang " > < xs : c o m p l e x T y p e mixed =" true " > 24 < xs : a t t r i b u t e name =" ziel " type =" xs : string " use =" required " / > < xs : a t t r i b u t e name =" quelle " type =" xs : string " 26 use =" required " / > </ xs : complexType > 28 </ xs : element > < xs : element name =" zustaende " > 30 < xs : complexType > < xs : sequence > 32 < xs : element ref =" zustand " maxOccurs =" unbounded " / > </ xs : sequence > 34 </ xs : complexType > </ xs : element > 36 < xs : element name =" zustand " > < xs : c o m p l e x T y p e mixed =" true " > 38 < xs : a t t r i b u t e name =" isStart " type =" xs : boolean " use =" required " / > 40 < xs : a t t r i b u t e name =" isEnd " type =" xs : boolean " use =" required " / > </ xs : complexType > 42 </ xs : element > </ xs : schema > Listing 4.44. Dea.xml 1 <? xml version ="1.0" encoding =" UTF -8"? > 2 <dea > < eingabe >010 </ eingabe > 4 < zustaende > < zustand isStart =" true " isEnd =" false " >A </ zustand > 6 < zustand isStart =" false " isEnd =" false " >B </ zustand > < zustand isStart =" false " isEnd =" false " >C </ zustand > 8 < zustand isStart =" false " isEnd =" true " >D </ zustand > < zustand isStart =" false " isEnd =" true " >E </ zustand > 10 </ zustaende > < uebergaenge > 12 < uebergang quelle =" A " ziel =" B " >0 </ uebergang > < uebergang quelle =" A " ziel =" C " >1 </ uebergang > 14 < uebergang quelle =" B " ziel =" D " >1 </ uebergang > < uebergang quelle =" C " ziel =" E " >0 </ uebergang > 16 < uebergang quelle =" D " ziel =" B " >1 </ uebergang > < uebergang quelle =" D " ziel =" E " >0 </ uebergang > 18 </ uebergaenge > </ dea > 89 90 P. Radinski Listing 4.45. DEA-Engine.java 1 import java . util . Vector ; 2 public class DEA_Engine { 4 public DEA_Engine ( Dea dea ) { 6 int i = 0; int j = 0; 8 String tempEingabe = ""; String tempUebergang = ""; 10 String eingabe = dea . getEingabe (). getContent (); 12 String [] u e b e r g a n g s R e l a t i o n e n = new String [ dea . g etUeberg aenge () . getUebergang (). size ()]; 14 Vector < String > endZustaende = new Vector < String >(); String tempZustand = ""; 16 // Daten einlesen 18 for ( int a = 0; a < dea . getZustaende (). getZustand (). size (); a ++) { if ( dea . getZustaende (). getZustand (). get ( a ). isIsEnd () == false 20 && dea . getZustaende (). getZustand (). get ( a ). isIsStart () == true ) { tempZustand = dea . getZustaende (). getZustand (). get ( a ). content ; 22 } if ( dea . getZustaende (). getZustand (). get ( a ). isIsEnd () == true 24 && dea . getZustaende (). getZustand (). get ( a ). isIsStart () == false ) { endZustaende 26 . add ( dea . getZustaende (). getZustand (). get ( a ). content ); } 28 } for ( int b = 0; b < dea . getUebe rgaenge (). getUebergang (). size (); b ++) { u e b e r g a n g s R e l a t i o n e n [ b ] = dea . getUeb ergaenge (). getUebergang () . get ( b ). getQuelle () + dea . getUeber gaenge (). getUebergang (). get ( b ). content + dea . getUeber gaenge (). getUebergang (). get ( b ). getZiel (); } 30 32 34 36 boolean endzustand = false ; boolean durchlauf = true ; 38 40 42 44 46 48 50 52 54 56 // Wenn endzustand und durchlauf true , dann akzeptiere !!! // Dea ausführen for ( i = 0; i < eingabe . length (); i ++) { j = i + 1; tempEingabe = eingabe . substring (i , j ); tempUebergang = tempZustand + tempEingabe ; tempZustand = n e a c h s t e r Z u s t a n d ( tempUebergang , u e b e r g a n g s R e l a t i o n e n ); if ( tempZustand . equals (" kein ")) { i = eingabe . length (); durchlauf = false ; } endzustand = istEndZustand ( tempZustand , endZustaende ); } if ( endzustand && durchlauf ) { System . out . println (" akzeptiert "); } else { System . out . println (" nicht akzeptiert "); } 58 } 60 public String n e a ch s t e r Z u s t a n d ( String tempUebergang , String [] u e b e r g a n g s R e l a t i o n e n ) { 62 64 66 for ( int i = 0; i < u e b e r g a n g s R e l a t i o n e n . length ; i ++) { if ( u e b e r g a n g s R e l a t i o n e n [ i ]. indexOf ( tempUebergang ) == 0) { return u e b e r g a n g s R e l a t i o n e n [ i ]. substring (2 , 3); } Binding zwischen XML-Schema-Modellen und Java-Beans (JAXB) 68 } 70 91 } return " kein "; public boolean istEndZustand ( String tempZustand , Vector < String > endZustaende ) { 72 74 76 78 80 } } for ( int i = 0; i < endZustaende . size (); i ++) { if ( tempZustand . equals ( endZustaende . elementAt ( i ). toString ())) { return true ; } } return false ; Listing 4.46. Dea.java 1 // 2 // This file was generated by the JavaTM Architecture for XML Binding ( JAXB ) Reference Implementation , vh // See <a href =" http :// java . sun . com / xml / jaxb " > http :// java . sun . com / xml / jaxb </ a > 4 // Any modifications to this file will be lost upon recompilation of the source schema . // Generated on : 2009.04.09 at 02:25:50 PM CEST 6 // 8 10 import import 12 import import 14 import 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 javax . xml . bind . annotation . XmlAccessType ; javax . xml . bind . annotation . X ml Ac ce s so rT yp e ; javax . xml . bind . annotation . XmlElement ; javax . xml . bind . annotation . XmlRoot Element ; javax . xml . bind . annotation . XmlType ; /* * * <p > Java class for anonymous complex type . * * <p > The following schema fragment specifies the expected content contained within this class . * * < pre > * & lt ; complexType > * & lt ; complexContent > * & lt ; restriction base ="{ http :// www . w3 . org /2001/ XMLSchema } anyType " > * & lt ; sequence > * & lt ; element ref ="{} eingabe "/ > * & lt ; element ref ="{} zustaende "/ > * & lt ; element ref ="{} uebergaenge "/ > * & lt ;/ sequence > * & lt ;/ restriction > * & lt ;/ complexContent > * & lt ;/ complexType > * </ pre > * * */ @ X m l A c c e s s o r T yp e ( XmlAccessType . FIELD ) @XmlType ( name = "" , propOrder = { " eingabe " , " zustaende " , " uebergaenge " }) @ Xm lR oo t El em en t ( name = " dea ") public class Dea { @XmlElement ( required = true ) protected Eingabe eingabe ; @XmlElement ( required = true ) protected Zustaende zustaende ; 92 52 54 56 58 60 62 64 66 68 70 72 74 76 78 80 82 84 86 88 90 92 94 96 98 100 102 104 106 108 110 112 114 116 118 P. Radinski @XmlElement ( required = true ) protected Uebergaenge uebergaenge ; /* * * Gets the value of the eingabe property . * * @return * possible object is * { @link Eingabe } * */ public Eingabe getEingabe () { return eingabe ; } /* * * Sets the value of the eingabe property . * * @param value * allowed object is * { @link Eingabe } * */ public void setEingabe ( Eingabe value ) { this . eingabe = value ; } /* * * Gets the value of the zustaende property . * * @return * possible object is * { @link Zustaende } * */ public Zustaende getZustaende () { return zustaende ; } /* * * Sets the value of the zustaende property . * * @param value * allowed object is * { @link Zustaende } * */ public void setZustaende ( Zustaende value ) { this . zustaende = value ; } /* * * Gets the value of the uebergaenge property . * * @return * possible object is * { @link Uebergaenge } * */ public Uebergaenge getUebe rgaenge () { return uebergaenge ; } /* * * Sets the value of the uebergaenge property . * * @param value * allowed object is Binding zwischen XML-Schema-Modellen und Java-Beans (JAXB) 93 * { @link Uebergaenge } * */ public void setUeber gaenge ( Uebergaenge value ) { this . uebergaenge = value ; } 120 122 124 126 } Listing 4.47. Eingabe.java 1 // 2 // This file was generated by the JavaTM Architecture for XML Binding ( JAXB ) Reference Implementation , vh // See <a href =" http :// java . sun . com / xml / jaxb " > http :// java . sun . com / xml / jaxb </ a > 4 // Any modifications to this file will be lost upon recompilation of the source schema . // Generated on : 2009.04.09 at 02:25:50 PM CEST 6 // 8 10 import import 12 import import 14 import 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 javax . xml . bind . annotation . XmlAccessType ; javax . xml . bind . annotation . X ml Ac ce s so rT yp e ; javax . xml . bind . annotation . XmlRoot Element ; javax . xml . bind . annotation . XmlType ; javax . xml . bind . annotation . XmlValue ; /* * * <p > Java class for anonymous complex type . * * <p > The following schema fragment specifies the expected content contained within this class . * * < pre > * & lt ; complexType > * & lt ; complexContent > * & lt ; restriction base ="{ http :// www . w3 . org /2001/ XMLSchema } anyType " > * & lt ;/ restriction > * & lt ;/ complexContent > * & lt ;/ complexType > * </ pre > * * */ @ X m l A c c e s s o r T yp e ( XmlAccessType . FIELD ) @XmlType ( name = "" , propOrder = { " content " }) @ Xm lR oo t El em en t ( name = " eingabe ") public class Eingabe { @XmlValue protected String content ; /* * * Gets the value of the content property . * * @return * possible object is * { @link String } * */ public String getContent () { return content ; } /* * * Sets the value of the content property . 94 * * @param value * allowed object is * { @link String } * */ public void setContent ( String value ) { this . content = value ; } 58 60 62 64 66 P. Radinski } Listing 4.48. ObjectFactory.java 1 // 2 // This file was generated by the JavaTM Architecture for XML Binding ( JAXB ) Reference Implementation , vh // See <a href =" http :// java . sun . com / xml / jaxb " > http :// java . sun . com / xml / jaxb </ a > 4 // Any modifications to this file will be lost upon recompilation of the source schema . // Generated on : 2009.04.09 at 02:25:50 PM CEST 6 // 8 10 import javax . xml . bind . annotation . XmlRegistry ; 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 /* * * This object contains factory methods for each * Java content interface and Java element interface * generated in the generated package . * <p > An ObjectFactory allows you to pr o gr am at i ca ll y * construct new instances of the Java rep resentat ion * for XML content . The Java represe ntation of XML * content can consist of schema derived interfaces * and classes representing the binding of schema * type definitions , element declarations and model * groups . Factory methods for each of these are * provided in this class . * */ @XmlRegistry public class ObjectFactory { /* * * Create a new ObjectFactory that can be used to create new instances of schema derived classes for * */ public ObjectFactory () { } /* * * Create an instance of { @link Uebergang } * */ public Uebergang c r ea te Ue b er ga ng () { return new Uebergang (); } /* * * Create an instance of { @link Zustaende } * */ public Zustaende c r ea te Zu s ta en de () { return new Zustaende (); } Binding zwischen XML-Schema-Modellen und Java-Beans (JAXB) 95 /* * * Create an instance of { @link Uebergaenge } * */ public Uebergaenge c r e a t e U e b e r g a e n g e () { return new Uebergaenge (); } 54 56 58 60 /* * * Create an instance of { @link Eingabe } * */ public Eingabe createEingabe () { return new Eingabe (); } 62 64 66 68 /* * * Create an instance of { @link Zustand } * */ public Zustand createZustand () { return new Zustand (); } 70 72 74 76 /* * * Create an instance of { @link Dea } * */ public Dea createDea () { return new Dea (); } 78 80 82 84 86 } Listing 4.49. Uebergaenge.java 1 // 2 // This file was generated by the JavaTM Architecture for XML Binding ( JAXB ) Reference Implementation , vh // See <a href =" http :// java . sun . com / xml / jaxb " > http :// java . sun . com / xml / jaxb </ a > 4 // Any modifications to this file will be lost upon recompilation of the source schema . // Generated on : 2009.04.09 at 02:25:50 PM CEST 6 // 8 10 import import 12 import import 14 import import 16 import 18 20 22 24 26 28 30 java . util . ArrayList ; java . util . List ; javax . xml . bind . annotation . XmlAccessType ; javax . xml . bind . annotation . X ml Ac ce s so rT yp e ; javax . xml . bind . annotation . XmlElement ; javax . xml . bind . annotation . XmlRoot Element ; javax . xml . bind . annotation . XmlType ; /* * * <p > Java class for anonymous complex type . * * <p > The following schema fragment specifies the expected content contained within this class . * * < pre > * & lt ; complexType > * & lt ; complexContent > * & lt ; restriction base ="{ http :// www . w3 . org /2001/ XMLSchema } anyType " > * & lt ; sequence > * & lt ; element ref ="{} uebergang " maxOccurs =" unbounded "/ > * & lt ;/ sequence > * & lt ;/ restriction > 96 32 34 36 38 40 42 * & lt ;/ complexContent > * & lt ;/ complexType > * </ pre > * * */ @ X m l A c c e s s o r T yp e ( XmlAccessType . FIELD ) @XmlType ( name = "" , propOrder = { " uebergang " }) @ Xm lR oo t El em en t ( name = " uebergaenge ") public class Uebergaenge { 44 @XmlElement ( required = true ) protected List < Uebergang > uebergang ; 46 /* * * Gets the value of the uebergang property . * * <p > * This accessor method returns a reference to the live list , * not a snapshot . Therefore any modification you make to the * returned list will be present inside the JAXB object . * This is why there is not a < CODE > set </ CODE > method for the uebergang property . * * <p > * For example , to add a new item , do as follows : * < pre > * getUebergang (). add ( newItem ); * </ pre > * * * <p > * Objects of the following type ( s ) are allowed in the list * { @link Uebergang } * * */ public List < Uebergang > getUebergang () { if ( uebergang == null ) { uebergang = new ArrayList < Uebergang >(); } return this . uebergang ; } 48 50 52 54 56 58 60 62 64 66 68 70 72 74 76 P. Radinski } Listing 4.50. Uebergang.java 1 // 2 // This file was generated by the JavaTM Architecture for XML Binding ( JAXB ) Reference Implementation , vh // See <a href =" http :// java . sun . com / xml / jaxb " > http :// java . sun . com / xml / jaxb </ a > 4 // Any modifications to this file will be lost upon recompilation of the source schema . // Generated on : 2009.04.09 at 02:25:50 PM CEST 6 // 8 10 import import 12 import import 14 import import 16 18 /* * javax . xml . bind . annotation . XmlAccessType ; javax . xml . bind . annotation . X ml Ac ce s so rT yp e ; javax . xml . bind . annotation . XmlAttribute ; javax . xml . bind . annotation . XmlRoot Element ; javax . xml . bind . annotation . XmlType ; javax . xml . bind . annotation . XmlValue ; Binding zwischen XML-Schema-Modellen und Java-Beans (JAXB) 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58 60 62 64 66 68 70 72 * <p > Java class for anonymous complex type . * * <p > The following schema fragment specifies the expected content contained within this class . * * < pre > * & lt ; complexType > * & lt ; complexContent > * & lt ; restriction base ="{ http :// www . w3 . org /2001/ XMLSchema } anyType " > * & lt ; attribute name =" ziel " use =" required " type ="{ http :// www . w3 . org /2001/ XMLSchema } string " / > * & lt ; attribute name =" quelle " use =" required " type ="{ http :// www . w3 . org /2001/ XMLSchema } string " / > * & lt ;/ restriction > * & lt ;/ complexContent > * & lt ;/ complexType > * </ pre > * * */ @ X m l A c c e s s o r T yp e ( XmlAccessType . FIELD ) @XmlType ( name = "" , propOrder = { " content " }) @ Xm lR oo t El em en t ( name = " uebergang ") public class Uebergang { @XmlValue protected String content ; @XmlAttribute ( required = true ) protected String ziel ; @XmlAttribute ( required = true ) protected String quelle ; /* * * Gets the value of the content property . * * @return * possible object is * { @link String } * */ public String getContent () { return content ; } /* * * Sets the value of the content property . * * @param value * allowed object is * { @link String } * */ public void setContent ( String value ) { this . content = value ; } 84 /* * * Gets the value of the ziel property . * * @return * possible object is * { @link String } * */ public String getZiel () { return ziel ; } 86 /* * 74 76 78 80 82 97 98 88 90 92 94 96 98 100 102 104 106 108 110 112 114 116 118 120 P. Radinski * Sets the value of the ziel property . * * @param value * allowed object is * { @link String } * */ public void setZiel ( String value ) { this . ziel = value ; } /* * * Gets the value of the quelle property . * * @return * possible object is * { @link String } * */ public String getQuelle () { return quelle ; } /* * * Sets the value of the quelle property . * * @param value * allowed object is * { @link String } * */ public void setQuelle ( String value ) { this . quelle = value ; } 122 } Listing 4.51. Zustaende.java 1 // 2 // This file was generated by the JavaTM Architecture for XML Binding ( JAXB ) Reference Implementation , vh // See <a href =" http :// java . sun . com / xml / jaxb " > http :// java . sun . com / xml / jaxb </ a > 4 // Any modifications to this file will be lost upon recompilation of the source schema . // Generated on : 2009.04.09 at 02:25:50 PM CEST 6 // 8 import 10 import import 12 import import 14 import import 16 java . util . ArrayList ; java . util . List ; javax . xml . bind . annotation . XmlAccessType ; javax . xml . bind . annotation . X ml Ac ce s so rT yp e ; javax . xml . bind . annotation . XmlElement ; javax . xml . bind . annotation . XmlRoot Element ; javax . xml . bind . annotation . XmlType ; 18 /* * * <p > Java class for anonymous complex type . 20 * * <p > The following schema fragment specifies the expected content contained within this class . 22 * * < pre > 24 * & lt ; complexType > * & lt ; complexContent > 26 * & lt ; restriction base ="{ http :// www . w3 . org /2001/ XMLSchema } anyType " > * & lt ; sequence > 28 * & lt ; element ref ="{} zustand " maxOccurs =" unbounded "/ > Binding zwischen XML-Schema-Modellen und Java-Beans (JAXB) 30 32 34 36 38 40 42 99 * & lt ;/ sequence > * & lt ;/ restriction > * & lt ;/ complexContent > * & lt ;/ complexType > * </ pre > * * */ @ X m l A c c e s s o r T yp e ( XmlAccessType . FIELD ) @XmlType ( name = "" , propOrder = { " zustand " }) @ Xm lR oo t El em en t ( name = " zustaende ") public class Zustaende { 44 46 48 50 52 54 56 58 60 62 64 66 68 70 72 74 @XmlElement ( required = true ) protected List < Zustand > zustand ; /* * * Gets the value of the zustand property . * * <p > * This accessor method returns a reference to the live list , * not a snapshot . Therefore any modification you make to the * returned list will be present inside the JAXB object . * This is why there is not a < CODE > set </ CODE > method for the zustand property . * * <p > * For example , to add a new item , do as follows : * < pre > * getZustand (). add ( newItem ); * </ pre > * * * <p > * Objects of the following type ( s ) are allowed in the list * { @link Zustand } * * */ public List < Zustand > getZustand () { if ( zustand == null ) { zustand = new ArrayList < Zustand >(); } return this . zustand ; } 76 } Listing 4.52. Zustand.java 1 // 2 // This file was generated by the JavaTM Architecture for XML Binding ( JAXB ) Reference Implementation , vh // See <a href =" http :// java . sun . com / xml / jaxb " > http :// java . sun . com / xml / jaxb </ a > 4 // Any modifications to this file will be lost upon recompilation of the source schema . // Generated on : 2009.04.09 at 02:25:50 PM CEST 6 // 8 10 import import 12 import import 14 import import 16 javax . xml . bind . annotation . XmlAccessType ; javax . xml . bind . annotation . X ml Ac ce s so rT yp e ; javax . xml . bind . annotation . XmlAttribute ; javax . xml . bind . annotation . XmlRoot Element ; javax . xml . bind . annotation . XmlType ; javax . xml . bind . annotation . XmlValue ; 100 P. Radinski 18 /* * * <p > Java class for anonymous complex type . 20 * * <p > The following schema fragment specifies the expected content contained within this class . 22 * * < pre > 24 * & lt ; complexType > * & lt ; complexContent > 26 * & lt ; restriction base ="{ http :// www . w3 . org /2001/ XMLSchema } anyType " > * & lt ; attribute name =" isStart " use =" required " type ="{ http :// www . w3 . org /2001/ XMLSchema } boolean " / > 28 * & lt ; attribute name =" isEnd " use =" required " type ="{ http :// www . w3 . org /2001/ XMLSchema } boolean " / > * & lt ;/ restriction > 30 * & lt ;/ complexContent > * & lt ;/ complexType > 32 * </ pre > * 34 * */ 36 @ X m l A c c e s s o r T yp e ( XmlAccessType . FIELD ) @XmlType ( name = "" , propOrder = { 38 " content " }) 40 @ Xm lR oo t El em en t ( name = " zustand ") public class Zustand { 42 @XmlValue 44 protected String content ; @XmlAttribute ( required = true ) 46 protected boolean isStart ; @XmlAttribute ( required = true ) 48 protected boolean isEnd ; 50 52 54 56 58 60 62 64 66 68 70 72 74 76 78 80 82 84 /* * * Gets the value of the content property . * * @return * possible object is * { @link String } * */ public String getContent () { return content ; } /* * * Sets the value of the content property . * * @param value * allowed object is * { @link String } * */ public void setContent ( String value ) { this . content = value ; } /* * * Gets the value of the isStart property . * */ public boolean isIsStart () { return isStart ; } /* * * Sets the value of the isStart property . * Binding zwischen XML-Schema-Modellen und Java-Beans (JAXB) */ public void setIsStart ( boolean value ) { this . isStart = value ; } 86 88 /* * * Gets the value of the isEnd property . * */ public boolean isIsEnd () { return isEnd ; } 90 92 94 96 /* * * Sets the value of the isEnd property . * */ public void setIsEnd ( boolean value ) { this . isEnd = value ; } 98 100 102 104 106 } Listing 4.53. Deserialisierer.java 1 import 2 import 4 import import 6 import 8 java . io . File ; javax . xml . bind . JAXBContext ; javax . xml . bind . Unmarshaller ; javax . xml . validation . Schema ; javax . xml . validation . SchemaFactory ; public class D es er ia l is ie re r { 10 public static void main ( String [] args ) { 12 14 try { JAXBContext context = JAXBContext . newInstance ( Dea . class ); 16 Unmarshaller unmarshaller = context . c r e a t e U n m a r s h a l l e r (); 18 // Validieren SchemaFactory sf = SchemaFactory . newInstance ( javax . xml . XMLConstants . W 3 C _ X M L _ S C H E M A _ N S _ U R I ); 20 Schema schema = sf . newSchema ( new File (" schema / Dea . xsd ")); unmarshaller . setSchema ( schema ); 22 24 Dea dea = new Dea (); 26 try { dea = ( Dea ) unmarshaller . unmarshal ( new File (" Dea . xml ")); 28 new DEA_Engine ( dea ); 30 } catch ( javax . xml . bind . U n m a r s h a l E x c e p t i o n e ) { System . out . println (" Fehler : " + e . toString ()); } 32 34 36 38 40 } } } catch ( Exception e ) { e . p ri nt St a ck Tr ac e (); } 101 102 P. Radinski Literatur [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] X. Clearinghouse. Xml-schema. u. Henry S. Thompson, David Beech. Xml schema teil 1: Strukturen. S. Kersken. It-handbuch für fachinformatiker. D. Matuszek. Jaxb. S. Michaelis and W. Schmiesing. Jaxb 2.0. In Ein Programmiertutorial Java Architecture for XML Binding, pages XI–XII. Hanser, 2007. S. Michaelis and W. Schmiesing. Jaxb 2.0. In Ein Programmiertutorial Java Architecture for XML Binding, pages 1–3, 14–16. Hanser, 2007. S. Michaelis and W. Schmiesing. Jaxb 2.0. In Ein Programmiertutorial Java Architecture for XML Binding, page 9. Hanser, 2007. S. Michaelis and W. Schmiesing. Jaxb 2.0. In Ein Programmiertutorial Java Architecture for XML Binding, pages 295–297. Hanser, 2007. S. Michaelis and W. Schmiesing. Jaxb 2.0. In Ein Programmiertutorial Java Architecture for XML Binding, pages 17–53. Hanser, 2007. S. Michaelis and W. Schmiesing. Jaxb 2.0. In Ein Programmiertutorial Java Architecture for XML Binding, pages 125–192. Hanser, 2007. S. Microsystems. Package javax.xml.bind.annotation. u. Stephane Bailliez, Nicola Ken Barozzi. Apache ant 1.7.1 manual. für die für die für die für die für die für die Modellierung von Geschäftsregeln Matthias Nicolas Drexl Maximilian Koch Universität Augsburg [email protected] [email protected] Zusammenfassung Bei der Geschäftsprozessmodellierung spielen Geschäftsregeln eine entscheidende Rolle, da sie zwischen Domänenexperten und Softwareingenieuren eine entscheidende Verbesserung, im Bezug auf Kommunikation und Verständnis ermöglichen. Diese Seminararbeit beschreibt die vier verschiedenen grafischen Notationen ROSS Notation, ORM (Object Rule Modeling), AORML (Agent Oriented Rule Modeling Language), und URML (UML-Based Rule Modeling Language) für die Modellierung von Geschäftsregeln. Basierend auf diesen Notationen wird im folgenden jeweils ein Überblick über die theoretischen Grundlagen, der Umsetzung, und der praktischer Anwendung vermittelt. Anhand einer Fallstudie werden Zusammenhänge und Unterschiede der Notationen detailliert erläutert. Abschließend werden die verschiedenen Ansätze miteinander verglichen und Vor- und Nachteile präsentiert. 1 Motivation Die Softwareentwicklung ist einem stetigen und agilen Wandel unterzogen. Klassische Methoden der Softwareentwicklung bestehend aus Analyse, Design, Implementierung und Test sind aufgrund immer komplexer werdender Anforderungen nicht mehr zeitgemäß. Einer IDC-Studie (International Data Corporation - Anbieter in den Bereichen Marktbeobachtung und Beratung der IT- und Telekommunikationsindustrie) zufolge ändern sich ca. 45% der Regeln, innerhalb eines angenommenen Softwarerelease-Zyklus von mindestens einem Monat [1]. Um eine höhere Flexibilität in Unternehmensprozessen zu gewährleisten, wird statt eines traditionellen Softwarerelease-Verfahrens ein dynamisches, kontinuierliches Lebenszyklusmanagement von Geschäftsregeln, verwendet - die grafische Modellierung von Geschäftsregeln. Die meist von Domänenexperten, in natürlicher Sprache formulierten Geschäftsregeln werden von Softwareentwicklern in eine formale, technische Sprache übersetzt, um damit automatisiert ablaufende Prozesse zu gestalten. Die grafische Notation von Geschäftsregeln bildet eine gemeinsame Ebene, welche die Kommunikationslücke zwischen den Domänen- und IT-Experten überbrückt. Verschiedene Regelmodellierungsmethoden dienen dabei beiden Seiten zu einem besseren Verständnis von Geschäftsregeln. Durch den grafischen, modularen Ansatz lassen sich Geschäftsregeln kurzfristig ergänzen und modifizieren, wodurch eine höhere Flexibilität in der konzeptionellen Phase erreicht wird, dass 104 M. Drexl und M. Koch sowohl Kosten- als auch Zeitersparnis zur Folge hat. Zusätzlich stellt die grafische Notation eine technische Dokumentation von Geschäftregeln dar. 2 Grundlagen - State of the art Bevor detailliert verschiedene Ansätze der Regelmodellierung diskutiert werden, gibt der folgende Abschnitt einen Überblick über die verschiedenen Abstraktionslevel von Geschäftsregeln. Die damit verbundenen Definitionen und Fachtermini tragen zum besseren Verständnis von Syntax und Semantik, der Regelmodellierung, bei. 2.1 Definitionen Geschäftsprozesse Unter einem Geschäftsprozess versteht man die Zusammenführung von fachlich zusammenhängenden Geschäftsaktivitäten, die schrittweise ausgeführt werden. Geschäftsprozesse können modular aus anderen Prozessen aufgebaut werden, oder selbst wieder Teil eines anderen Geschäftsprozesses sein. So werden beispielsweise Aktivitäten eines Unternehmens wie bestimmte Arbeitsabläufe als Geschäftsprozesse beschrieben. Genauer soll ein Geschäftsprozess ein Unternehmen unterstützen, Geschäftsobjekte so zu bearbeiten, dass Unternehmensziele vollständig erreicht werden. Dabei sind sowohl die Anzahl der am Prozess beteiligten Aktionen, als auch deren Ablauf von Bedeutung. Des Weiteren benötigt ein Prozess ein auslösendes Ereignis, das zur Ausführung von Aktivitäten führt. Ein Ereignis kann sowohl internen, als auch externen Quellen (Input) zugeordnet werden. Lediglich bedeutend ist das Ergebnis, das eine Ausgabe (Output) einer Aktivität beinhaltet, die wiederum für weitere Aktivitäten zur Verfügung steht[6]. Beispiele: . Ein Kunde möchte ein Auto bei einer Autovermietung reservieren. . Die Autovermietung kontrolliert den PKW vor der Rückgabe auf einen vollen Tank. . Ein Kunde möchte diese Auto mit der Kreditkarte bezahlen. Geschäftsprozesse können durch unterschiedliche Modellierungssprachen, wie Petrinetze, Aktivitätsdiagramme oder ereignisgesteuerte Prozessketten (EPKs), dargestellt werden. Geschäftsregeln Eine Geschäftsregel legt den genauen Ablauf von Geschäftsprozessen fest. Sie definiert präzise die geschäftsprozessspezifische Logik z.B. den elementaren technischen Ablauf von Prozessaktivitäten, Exception Handling und die Art und Weise Modellierung von Geschäftsregeln 105 der Abwicklung von Geschäftsprozessen. Zusätzlich wird die Entscheidungslogik von prozessübergreifenden Regelwerken beschrieben. Regeln sollten wegen der Widerverwendbarkeit modular und allgemeingültig definiert sein. Sie können analog zu den Prozessen wiederum Teil anderer Regeln sein oder bereits definierte Regeln enthalten. Eine einzelne Regel enthält auf der untersten Modellierungsebene als atomare Regel keine weiteren Regeln. Außerdem verwenden Geschäftsprozesse typischerweise mehrere Geschäftsregeln (1..n). Eine Regel kann komplementär in mehreren verschiedenen Prozessen vorkommen (1..m). Somit stehen Prozesse und Regeln im Verhältnis n:m zueinander. Laut der Business Rules Group (BRG) können Geschäftsregeln im Kontext der Prozessmodellierung zum einen aus der Sicht des Unternehmens (Betriebswirtschaftliche Sicht) und zum anderen aus der Sicht der IT (Technische Sicht) definiert werden.[8] Die Betriebswirtschaftliche Sicht beschreibt eine Direktive, „die das Verhalten des Unternehmens in eine bestimmte Richtung steuern und dabei die Einhaltung der Unternehmenspolitik unterstützen soll.“ Dabei beschreiben Geschäftsregeln die Organisationsstruktur von Unternehmen und deren Abläufe. Sie können wie oben definiert deren Geschäftslogik enthalten und sind somit Teil von Geschäftsprozessen und deren effizienter Durchführung. Die Technische Sicht beschreibt Geschäftsregeln als „Eine Aussage, die Verhaltensweisen oder Vorgänge innerhalb des Unternehmens einschränkt. Sie hat aus dieser Sicht die Aufgabe die Unternehmung zu strukturieren bzw. zu kontrollieren.“ Aus diesen beiden verschiedenen Sichtweisen entsteht das Problem eines gemeinsamen Dialogs von Domänenexperten auf der einen und Technikern auf der anderen Seite. Die visuelle Repräsentation von Regeln soll hierbei Abhilfe schaffen und dabei helfen Regeln aus der natürlichen Sprache zu erfassen und in die technische Domäne zu überführen. Beispiele: . Nur Kunden älter als 24 Jahre mit gültigem Führerschein können einen PKW mieten. . Der Kunde wird auf eine schwarze Liste gesetzt, falls der Tankinhalt bei der Rückgabe eines Mietwagens unter 50% liegt. . Bezahlt der Kunde mit einer Kreditkarte, erhält er 10% Rabatt auf einen Mietwagen. Geschäftsregeln können durch unterschiedliche Notationen, grafisch dargestellt werden, die grundlegend in Kapitel 2.3 definiert werden. Spezifische Modellierungssprachen werden anschließend detailliert in den Kapiteln 3 bis 6 vorgestellt. 2.2 Abgrenzung von Geschäftsregeln Die Abgrenzung von Geschäftsregeln basiert auf dem Ansatz der MDA (Model Driven Architecture) welcher als Strategie von der OMG (Object Management 106 M. Drexl und M. Koch Group) definiert wurde. Das Konzept der Model Driven Architecture geht davon aus, dass für die Konstruktion eines Softwaresystems ein einziges Gesamtmodell zu ungenau und unübersichtlich ist. Bei den meisten Modellen sind geschäftsrelevante mit technischen Informationen vermischt. Deshalb unterteilt die MDA das ursprüngliche Gesamtmodell in drei verschiedene Modellierungsebenen[13]die auch in Abbildung [1] dargestellt sind: Abbildung 1. Abgrenzung von Geschäftsregeln im Bezug auf die Modellierungsebenen CIM, PIM und PSM . CIM (Computation-Independent-Model) für die umgangssprachliche Beschreibung. . PIM (Platform-independent-Model) für die Modellierung und Verfeinerung von Geschäftsprozessen, bzw. -regeln. . PSM (Platform-Specific-Model) für Architektur und Services. CIM ist eine semi-formale Modellierungsebene. Hierbei beschreiben Geschäftsregeln Aussagen, über das Regelwerk von im Unternehmen auftretender Aktivitäten. Diese werden in einer deklarativen Art und Weise dargestellt, die einerseits der natürlichen Sprache und andererseits einer visuellen Repräsentation entsprechen. PIM ist eine formale Modellierungsebene. Fachliche Spezifikationen werden in pattformunabhängigen Modellen durch eine formal eindeutige Modellierungssprache definiert. PSM ist eine formale Modellierungsebene die plattformabhängig ist. Geschäftsregeln sind hier als Aussagen in einer spezifischen ausführbaren Sprache, wie MS Outlook 6 Rule oder Oracle 10g SQL View, beschrieben. Der Zusammenhang der verschiedenen Abstraktionsebenen ist in Abbildung [2] definiert. Eine umgangssprachlich formulierte Geschäftsregel auf CIM Ebene kann beispielsweise durch eine ECAA Regel auf PIM Ebene visualisiert werden. Dieses Modell kann wiederum durch Modelltransformation in ein spezifisches Modell, auf PSM Ebene, übersetzt werden. Die höchste Abstraktionsstufe wäre nun die automatisierte Sourcecodegenerierung aus dem plattformspezifischen Modell, was in dieser Arbeit jedoch nicht vertieft erläutert wird. Modellierung von Geschäftsregeln 107 Abbildung 2. Zusammenhang der Modellierungsebenen Regeln werden in folgende fünf verschiedene Arten kategorisiert: 1. Integrity Rules oder auch Constraints für Bedingungs- oder Einschränkungsregeln 2. Derivation Rules für Ableitungsregeln 3. Reaction Rules für Prozess- oder Verhaltensregeln 4. Production Rules für Produktionsregeln 5. Transformation Rules für Transformationsregeln Der Fokus dieser Arbeit liegt bei den ersten drei Regelarten, die im Folgenden detailliert anhand grafischer Notationen erklärt werden. Einschränkungs-, Ableitungs-, und Prozessregeln können sowohl textuell als auch visuell auf der PIM Ebene formuliert werden. Tabelle [1] zeigt Beispiele von der möglichen Überführung von Geschäftsregeln aus der CIM in die PIM Ebene Konzepzt Constraints Implementierung If-Then-Statements in Programmiersprachen, DOMAIN,CHECK und CONSTRAIN Klauseln in SQL Table Definitionen, CREATE, ASSERTION Statements in SQL Datenbank Schema Definitionen Derivation Rules Deduktive Datenbank Statements (oder Prolog) Regeln, SQL CREATE VIEW Statements Reaction Rules If-Then-Statements in Programmiersprachen, CREATE,TRIGGER Statements in SQL, Produktionsregeln in ’Experten Systemen’ Tabelle 1. Beispiele - CIM zu PIM 108 M. Drexl und M. Koch 2.2.1 Bedingungs- / Einschränkungsregeln (Integrity Rules / Constraints) Einschränkungsregeln beschreiben allgemeingültige Aussagen und Behauptungen, die immer wahr sind und somit uneingeschränkt gelten. Sie können auch als Verbote oder Gebote definiert werden. Analog zu den in 2.1 bereits definierten Beispielen kann folgende Regel als Einschränkungsregel eingeordnet werden. Beispiel: Nur Kunden älter als 24 Jahre mit gültigem Führerschein können einen PKW mieten Diese Regel beinhalten Statements über die Bedingungen, unter denen in einem Geschäftsprozess eine bestimmte Aktion ausgeführt wird (z.B.: PKW darf gemietet werden). Diese können nur ausgeführt werden, wenn sie danach in einem gültigen Zustand enden. 2.2.2 Ableitungsregeln (Derivation Rules): Unter Ableitungsregeln versteht man Regeln, bei denen neue Information aus bereits bestehenden Informationen abgeleitet werden. Beispiel: Der Kunde wird auf eine schwarze Liste gesetzt, falls der Tankinhalt bei der Rückgabe eines Mietwagens unter 90% liegt. 2.2.3 Prozess- oder Verhaltensregeln (Reaction Rules): Prozessregeln sind Anweisungen, die Aktionen anstoßen, verhindern oder erlauben. Gleichzeitig wird überprüft, ob diese Aktionen ausgeführt werden dürfen, müssen oder eben nicht ausgeführt werden. Darüber hinaus beschreiben Verhaltensregeln Statements über dynamische Aspekte in einem Unternehmen. Diese charakterisieren, inwiefern der Prozessstatus von einer Aktion beeinflusst wird. Beispiel: Bezahlt der Kunde mit einer Kreditkarte, erhält er bei positiver Bonität, 10% Rabatt auf einen Mietwagen 2.3 Existierende Modellierungsansätze von Geschäftsregeln: Wie oben bereits mehrfach erwähnt, gibt es für die Darstellung von Geschäftsregeln unterschiedliche Möglichkeiten. Im Folgenden werden vier verschieden Ansätze dargestellt. Eine erste Formulierung der Geschäftsregeln kann in einer natürlichen Sprache erfolgen, was durch das Regelbasierte System repräsentiert wird. Eine formalere Darstellung kann anhand des JBOSS-Rules Regelsystems durchgeführt werden. Eine Visualisierung der Geschäftsregeln kann entsprechend des E(vent)C(onditon)A(ction)A(ction)-Konzepts bzw. der Ereignisgesteuerte Prozessketten (EPK) vorgenommen werden. Die angesprochenen Konzepte werden im Folgenden detailliert erklärt. Modellierung von Geschäftsregeln 2.3.1 109 Regelbasiertes System Grundlagen: Geschäftsregeln können durch das regelbasierte System dargestellt werden, das aus den folgenden drei Bereichen besteht: . Faktenbasis: Datenbank an Fakten (Extraktion von Fakten aus Geschäftsprozessen) . Regelbasis: Menge an Regeln (Regeldatenbank) . Business-Rule-Engine: Kontrollsystem mit Regelinterpreter Die Business-Rule-Engine identifiziert Regeln in einem Geschäftsprozess der Faktenbasis und aktualisiert die angelegte Regeldatenbank mit neu angelegten Regeln. Des Weiteren wird von der Engine die als nächstes anzuwendende Regel ausgewählt. Formale Darstellung: Regeln werden durch Domänenexperten in natürlicher Sprache ausgedrückt und liegen in Form von: WENN DANN SONST (IF THEN ELSE) Abfragen vor. Dadurch wird eine bestimmte Regel (= EVENT) zerlegt und dargestellt. Dabei bildet der WENN Teil als Prämisse die Annahme einer bestimmten Voraussetzung für die Konklusion (= DANN) durch eine bestimmte Aktion. Eine weitere Abzweigung durch weitere Konklusionen (= SONST) als Alternative anderer Aktionen ist möglich. EVENT WENN ( Prämisse / Voraussetzung )... DANN ( Konklusion durch eine Aktion )... SONST ( Konklusion durch eine anderer Aktion ) ... Listing 5.1. Allgemeines Schema eines Regelsystems Listing 5.2 zeigt wie man die bereits definierten Beispiele in ein regelbasiertes System überführen kann. PKW Miete : WENN Kunde älter als 24 Jahre ist UND einen gültigen Führerschein besitzt , DANN wird der Mietwagen reserviert , SONST wird die Anfrage zurückg ewiesen PKW Rückgabe : WENN der Tankinhalt bei der PKW Rückgabe unter 90 Prozent liegt , DANN wird der Kunde in die schwarze Liste eingetragen UND der PKW wird aufgetankt SONST wird der PKW gereinigt PKW Bezahlung : WENN ein Kunde mit der Kreditkarte bezahlt , DANN werden 10 Prozent auf den Miet wagenpre is g utgeschr ieben SONST zahlt der Kunde 100 Prozent des M i e t w a g e n p r ei s e s Listing 5.2. Beispiel von Regeln innerhalb einer Autovermietung als Regelsystem 110 M. Drexl und M. Koch 2.3.2 JBOSS-Rules Um die Softwarequalität hinsichtlich Flexibilität, Wartbarkeit, Kosten und Stabilität zu verbessern, erfolgt bei JBOSS eine Unterteilung in ein prozessorientiertes System, welches aus Geschäftsprozessen, Geschäftsregeln und der Basisfunktionalität besteht. Bei den Regeln handelt es sich um ein Java basiertes Regelsystem, dessen Syntax sich eng an der formalen Darstellung des bereits vorgestellten regelbasierten Systems anlehnt. Die Trennung von Software in Basisfunktionalität, Geschäftsprozesse und Regeln erhöht die Flexibilität, indem Änderungen an Geschäftsprozessen und Regeln im laufenden Betrieb möglich und durch die jeweilige Fachabteilung mit wenig Hilfe von IT Spezialisten durchführbar sind. Basisfunktionalität, Geschäftsprozesse und Regeln sind unabhängig testbar und durch deren klare und strukturierte Definition ist neben dem geringen Wartungsaufwand gleichzeitig eine übersichtliche Dokumentation verfügbar. Dadurch wird auch die Stabilität des Regelsystems erhöht, da bereits getestete Methoden wiederverwendet werden. rule ' PKW_Miete ' when $c : Customer ( alterKunde >= 24 , DrivingL icence == TRUE ); then System . out . println ( ' Der PKW ' BMW Isetta ' wurde reserviert '); Car . reserve ( $c . getCarRequest ()); end rule ' PKW_Rückgabe ' when $p : Car ( gasoline . Value <= 50); then System . out . println ( ' Der Kunde Fritz wurde auf die Blacklist gesetzt '); Customer . addStatus ( ' Blacklisted '); end rule ' PKW_Bezahlung ' when $c : Customer ( carPayment == ' CreditCard '); then Car . setPrice ( Price . getDiscount (10)); end Listing 5.3. Beispiel von Regeln innerhalb einer Autovermietung, definiert als JBOSS-Rule 2.3.3 ECAA-Regeln und EPK Die ECAA-Regeln zur Modellierung von Geschäftsregeln wurde im regelbasierten Modellierungsansatz aufgegriffen und erweitert. Sie stellt die Grundlage für eine strukturierte Modellierung von Geschäftsregeln dar. Die explizite Modellierung einer Bedingungskomponente ermöglicht eine praxisnähere Modellierung von Geschäftsregeln, als es beispielsweise mit ereignisgesteuerten Prozessketten (EPK) möglich ist und bietet zusätzliche Möglichkeiten für eine Modellierung der Ablaufsteuerung. Der Grundaufbau der ECAA-Regel mit deren Hilfe Constraints und Reaction Rules formuliert werden können ist in Abbildung [3] dargestellt. Ein weiteres komplexeres Beispiel für einen regelbasierten modellierten Prozess wird in Abbildung [4] dargestellt. Hierbei stellt ein Kunde eine Anfrage an eine Autovermietung, einen PKW zu mieten. Modellierung von Geschäftsregeln 111 Abbildung 3. Grundaufbau einer ECAA Regel Dabei wird ersichtlich, dass eine Geschäftsregel nicht immer für sich alleine, als atomare Regel steht, sondern eng mit anderen Geschäftsregeln verknüpft sowie in den gesamten Prozessverlauf integriert ist. Eine Geschäftsregel die mit der Abbildung 4. Erweiterte ECAA Regel ECAA-Regel modelliert wurde und deren Überführung in ihre entsprechende EPK (Ereignisgesteuerte Prozesskette) ist in Abbildung [5] dargestellt. Will ein Kunde einen PKW mieten und ist Neukunde, muss dieser erst erfasst werden, ansonsten wird der Auftrag sofort erstellt. Der WENN/DANN/SONST Zweig der ECAA Regel wird in der EPK durch eine XOR Operator exemplarisch modelliert. Nachdem nun im letzten Kapitel Grundlegende Definitionen und Darstellungsweisen von Regeln vorgestellt wurden, kommen wir nun zu konkreten Modellierungsnotationen, die jeweils für spezifische Regelarten, wie Constraints, Derivation- oder Reaction Rules, entwickelt wurden. Zu Beginn werden die beiden 112 M. Drexl und M. Koch Abbildung 5. Exemplarische Darstellung einer ECAA-Regel und deren Modellierung als EPK Notationen R-Notation und ORM vorgestellt, die haupsächlich für Constraints und Derivation Rules verwendet werden. Danach werden die Agent-OrientedModeling-Language und die UML-Based-Rule-Modeling-Language präsentiert, die in der Praxis vor allem bei der Modellierung von Reaction Rules eingesetzt werden[13]. 3 3.1 Ross-Notation Definition Die von Ronald G. Ross entwickelte R-Notation definiert Regeln als Konstrukte die aus Termen und Fakten bestehen. Als Grundlage für die präzise und formale Klassifikation von Geschäftsregeln dient das von Ross entwickelte Business Rules Manifesto, das folgende wichtige Aspekte für Regeln beinhaltet: . Regeln sind essentiell für die Modellierung von Anforderungen innerhalb von Geschäftsmodellen, Systemmodellen und Implementierungsmodellen im Unternehmensumfeld. . Regeln sind weder Prozesse noch Prozeduren sondern stoßen diese an. . Regeln sind auf Fakten aufgebaut, die auf Geschäftskonzepten basieren, die wiederum aus Termen bestehen. . Eine Regel muss immer eindeutig definiert, und in natürlichen Sprache ausgedrückt werden (CIM-Ebene), und hat den Anspruch, allgemein verständlich zu sein. . Regeln sind Bedingungen (Constraint) für Verhalten. Modellierung von Geschäftsregeln 113 . Das Verhältnis zwischen Ereignissen (Event) und Regeln ist im allgemeine m:n. . Bei Regelverletzungen, muss eine alternative Aktivität (Activity) zur Verfügung stehen. . Regelausnahmen und Verfeinerungen werden wiederum durch andere Regeln modular ausgedrückt. . Regel sollen von Domänenexperten mittels eines Modellierungstools auf der PIM-Ebene entwickelt werden, damit die Geschäftsregeln flexibel auf andere Software- und Hardwareplattformen übertragen werden können. Die Eckpfeiler des soeben beschriebenen Manifest bilden die Grundlage für den textuellen und grafischen Modellierungsansatz der R-Notation. 3.2 Einsatz in der Praxis In der Praxis dient die R-Notation der formalen Beschreibung von Geschäftsregeln. Aufgrund fehlender Modellierungstools wird die Ross Notation vorwiegend als Grundlage für weitere Regelmodellierungssprachen, die ihren Schwerpunkt in der Formulierung von Constraints setzen, verwendet. Dazu gehört die im nächsten Kapitel beschriebene Object-Rule-Modeling-Language. Darüber hinaus bildet die R-Notation einen guten Einblick in die Komplexität von Geschäftsregeln und stellt diese auf verständliche aber bereits formal definierte Weise dar. Die formale Definition einer Regel der R-Notation basiert auf der Beschreibung des Regelbasierten Systems und wird ebenfalls durch eine Implikation ausgedrückt[7]: IF p THEN q . . . . . p und q entsprechende Boolschen Ausdrücken. p nennt man Antecedent (vorangehend) bzw. Prämisse (Voraussetzung). q nennt man Consequent (folgend) bzw. conclusion (Folgerung). p impliziert q (p → q) ist ebenfalls ein gültiger Ausdruck für diese Beispiel Die Sprache enthält weitere logische Operatoren wie AND, OR, NOT etc. und logische Quantifikatoren wie EXISTS, FORALL etc., um komplexere Regeln auszudrücken. . (OR(NOT p)), q ist ebenfalls ein gültiger Ausdruck für obiges Beispiel. Die Implikation beschreibt einen logischen Ausdruck, der auf einen Wahrheitswert abgebildet wird (TRUE, FALSE). Um im Speziellen auszudrücken, dass es sich bei der Regel um einen Constraint handelt, erhällt der Antecedent einen Rule Type Indicator. Dieser wird durch eine hochgestelltes T für True beim Antecedenten hinzugefügt. MT → A AND F (PKW Mieten)T → Älter als 24 AND Führerschein ist vorhanden Falls die logische Implikation statt einem Constraint eine Abfrage formuliert, wird das hochgestellte T durch ein hochgestelltes Fragezeichen ersetzt. 114 M. Drexl und M. Koch M? → A AND F (PKW Mieten)? → Älter als 24 AND Führerschein ist vorhanden Frage: Impliziert das Mieten eines PKWs, dass der Kunde älter als 24 ist und einen gültigen Führerschein hat? Damit Regeln untereinander eindeutig referenziert werden können, wird vor den logischen Ausdruck der Name der Regel geschrieben. R1: MT → A AND F Regel-für-Miete-PKW: (PKW Mieten)T → Älter als 24 AND Führerschein ist vorhanden 3.3 Konkrete Syntax und Semantik Eine Entity entspricht einem Objekt im Regeldiagramm, das einen Namen und Attribute besitzt und mit anderen Entitäten über Assoziationen verbunden ist. Die oben beschriebenen Constraints bestehen hierbei aus zwei Varianten, den Integrity Constraints und den Conditions[4]. Die beiden Constraintarten können durch 42 Regeltypen repräsentiert werden. Dazu gehören z.B. RESTRICTED, EQUALITY und EXISTS, das im folgenden Beispiel verwendet wird. Ein Integrity Constraint ist eine Bedingung, die im Bezug auf eine Assoziation zwischen zwei Entitäten oder eines Attributes, nach Definition immer wahr sein muss. Eine Condition ist ebenfalls eine Bedingung, die wahr oder falsch sein kann. Je nachdem können, abhängig vom Ergebnis, andere Constraints oder Aktionen aufgerufen werden. Sowohl Integrity Constraints als auch Conditions besitzen jeweils eine eingehende Kante, die vom Antecedent ausgeht. Die Integrity Constraints besitzen mehrere ausgehende Kanten, die zum Consequent führt. Conditions können auch mehrere ausgehende Kanten besitzen, um auf den Consequent und andere Constraints zu referenzieren. Folgendes Beispiel verdeutlicht die Visualisierung von Geschäftsregeln innerhalb der R-Notation. Die Integrity Rule mit dem Abbildung 6. Modellierungsbeispiel der Ross-Notation logischen Quantifikator EXISTS sagt aus, dass die Zweigstelle (Entity) einer Autovermietung eine Adresse (Attribut) besitzen muss. Modellierung von Geschäftsregeln 115 Formal ausgedrückt: Regel1: ZweigstelleT → Adresse Die Condition mit dem logischen Quantifikator EXISTS sagt aus, dass eine Zweigstelle (Entity) einer Autovermietung die eine Adresse (Attribut) besitzt auf das Constraint Regel2 verweist. Formal ausgedrückt: Regel1: ZweigstelleT → Adresse → Regel2 Durch den Gebrauch von 42 Regelarten kann durch die R-Notation jeglicher Fall von möglichen Contraints als Geschäftsregel abgedeckt werden, was bei der Modellierung das Problem der Komplexität erhöht. Im nächsten Kapitel soll deshalb die übersichtlichere ORM Notation vorgestellt werden, welche ebenfalls die Möglichkeit der Contraintmodellierung bietet. 4 4.1 ORM - Objekt Role Modeling Language Definition ORM (Objekt Role Modeling Language) visualisiert reale Anwendungsfälle als eine Reihe von Objekten (Entities) die Rollen übernehmen und damit miteinander in Beziehung stehen (Relationship). Diese Objekte und Rollen werden entweder in natürlicher Sprache und in intuitiven Diagrammen beschrieben. ORM wird darüber hinaus auch als faktenbasierte Modellierungstechnik bezeichnet[2], da Daten als atomaren Fakten formuliert werden und diese ohne Verlust von Information nicht weiter zerlegt werden können. 4.2 Einsatz in der Praxis ORM dient in der Praxis als Sprache um die Komplexität von Betrieben zu erfassen. Auf Grund einer klaren und detaillierten Formulierung ist ORM als Modellierungstechnik sehr anpassungsfähig, um schnell auf Änderungen in Unternehmensprozessen und -Strukturen reagieren zu können. ORM basiert auf der Idee der ER-Modellierung und ist eine Methode, für die konzeptionelle Erstellung von Datenbanken, die im Rahmen der Datenmodellierung einen Ausschnitt der realen Welt beschreibt. Somit dient zum einen das ORM-Modell in der Implementierungsphase als Grundlage für das Design der Datenbank, zum anderen in der konzeptionellen Phase der Anwendungsentwicklung zur Verständigung zwischen Anwendern und Entwicklern. Hierbei wird ausschließlich die Sachlogik, und nicht die Technik, dargestellt. 116 M. Drexl und M. Koch Abbildung 7. Konkreter Syntax von ORM 4.3 ORM - Modellierung 4.3.1 Konkrete Syntax und Semantik - Grundelemente Im folgenden Kapitel werden alle relevanten Grundelemente definiert, welche für die Modellierung von Geschäftsregeln unter ORM nötig sind. Nach Abbildung [7] sind dies: Um den genauen Zusammenhang der Objekte zu verstehen werden die Grundelemente und ihre Funktionsweise definiert und in Abbildung [8] deren Zusammenhang präsentiert. Objekte sind allgemein formulierte Entitäten, die sich aus der zugrundeliegenden Datentabelle (Faktenbasis) erschließen. Diese Tabelle enthält Daten über Objekte des realen Lebens, wie Fahrzeugklassen oder Kunden, bezogen auf das Beispiel der Autovermietung. Um den Objekttypen genau zu identifizieren, werden den Objekten spezifische Datentypen (Schemes) zugewiesen. So wird der Objekttyp Fahrzeugklasse beispielsweise anhand des Typs PKW-Klasse und der Kunde anhand seines Namens identifiziert. Objekte werden über Kanten mit Fakten verbunden, wodurch eine spezifische Rolle entsteht. ORM erlaubt Verbindungen mit einer Rolle (unär), oder auch mehreren Rollen (binär, ternär) wobei aufgrund der atomaren Definition von Fakten in der Praxis nicht mehr als vier Rollen mit Objekten verbunden sind. Rollen stellen, anhand ihrer Beschriftung und Bedingungen (Constraints), die genaue Beziehung zwischen Objekttypen dar und sind mittels Kanten mit mindestens einem Objekttyp verbunden. Für jede Rolle existiert eine entsprechende Faktentabelle. Eine Rolle kann auch als Faktentyp bezeichnet werden. Modellierung von Geschäftsregeln 117 Verbindungen sind Kanten zwischen Rollen und Objekten. Sie können zusätzlich durch deren Semantik Contsraints definieren. Die genaue Funktionsweise wird jedoch der Übersicht halber in Kapitel 4.3.2 erklärt. Faktentabellen enthalten Objekte, von Objekttypen, die mit der zugehörigen Rolle über Kanten verbunden sind. Der Aufbau der Faktentabellen orientiert sich an der tabellarische Darstellung der Datentabelle. Abbildung [8] präsentiert ein ORM-Diagramm mit den Objekttypen Kunde und PKW, die zum einen anhand ihres Namens und zum anderen anhand der KFZ-Klasse identifiziert werden. Dabei sind die beiden Obekttypen mittels Kanten mit dem binären Faktentypen (zwei Rollen) „mieten“ verbunden. So wird exemplarisch von Person1 eine Mittelklassewagen und ein Kleinwagen von Person2 gemietet. Abbildung 8. Beispiel - Zusammenhang der Grundelemente 4.3.2 Konkrete Syntax und Semantik - Constraints Aufbauend auf den ORM-Grundelementen wird in diesem Kapitel nun die Regelmodellierung mit Constraints innerhalb von ORM beschrieben. Dafür wird die Syntax um folgende Elemente erweitert: Um den Gesamtzusammenhang der Constraints innerhalb der ORM-Modellierung zu verstehen, wird im Folgenden der erweiterte Syntax präzise definiert und erneut in zwei weiteren Beispielen (Abbildung [10] und [11]) diskutiert. Folgende Constrainttypen können in ORM modelliert werden: Mandatory Role Constraint Jeder Objekttyp ist bezüglich seiner Rolle mit einem anderen Objekttypen verbunden d.h. jedes Objekt ist in der Faktentabelle immer mit einem anderen Objekt verknüpft. Leere Einträge in der Faktentabelle sind hier nicht erlaubt. Uniqueness Constraint (1:1) Jedes Objekt in der Faktentabelle ist eindeutig einem anderen Objekt zugeordnet und umgekehrt analog. 118 M. Drexl und M. Koch Abbildung 9. Erweiterte Syntaxelemente für die Constraints Modellierung von Geschäftsregeln 119 Uniqueness Constraint (n:1) Jedes Objekt in der Faktentabelle ist eindeutig einem anderen Objekt zugeordnet, umgekehrt jedoch können auch mehrere Objekte zugeordnet werden. Uniqueness Constraint (m:n) Jedem Objekt können in der Faktentabelle mehrere andere Objekt zugeordnet werden und umgekehrt analog. Pair-Exclusion Constraint Zwischen unterschiedlichen Rollen sind gleiche Paare von Objekten aus den jeweiligen unterschiedlichen Faktentabellen verboten. Asymmetric Constraint Assymetrische Verbindungen von Objekten untereinander sind verboten. z.B. Es gilt nicht: x → a AND a → x ⇒ x → x External-Uniqueness Constraint Innerhalb unterschiedlicher Faktentabelle sind Dublikate von Objekten verboten und somit eindeutig. Pair-Subset Constraint Pair-Subset Constraints definieren Subtypen zwischen Rollen bzw. Objekttypen. Beispiel: Jeder Angestellte hat genau einen Namen. Außerdem besitz der Auftrag genau einen Mitarbeiter, der diesen bearbeitet. Jeder Mitarbeiter berichtet genau einem Vorgesetzen (Uniqueness Constraint n:1). Es besteht die Möglichkeit, dass mehrere Angestellte mehr als einen Auftrag prüfen und Aufträge von mehr als einem Mitarbeiter geprüft werden (Uniqueness Constraint m:n). Jeder Mitarbeiter besitzt immer einen Namen und Aufträge werden immer von Mitarbeitern ausgeführt (Mandatory-Role Constraint). Kein Mitarbeiter prüft und führt Aufträge gleichzeitig aus (Pair-Exklusion Constraint). Wenn ein Mitarbeiter den anderen überwacht, ist das Gegenteil nicht möglich (Asymmetric Constraint). Weitere Constraints werden in Abbildung [11] dargestellt. Innerhalb einer Abteilung sind Namen eindeutig vergeben (ExternalUniqueness Constraint). Jeder Manager, der eine Abteilung leitet arbeitet auch für diese und ist somit auch ein ein Mitarbeiter (Pair-Subset Constraint). Derivation Rules besitzen innerhalb der ORM Modellierung keinen konkreten Syntax sondern müssen logisch aus den ORM Diagrammen abgeleitet werden. Die Tatsache, dass ein Manager seine Mitarbeiter leitet, muss aus dem Umstand abgeleitet werden, dass ein Manager eine Abteilung leitet, die Mitarbeiter beschäftigt (Derivation Rule). Um aus einer Datentabelle die oben beschriebenen ORM-Diagramme zu modellieren, führen Entwickler bzw. Anwender, folgenden Algorithmus in sieben Schritten aus[3]. 1. Wandle bekannte Informationen in elementare Fakten um und mache einen Qualitäts Check. 2. Zeichne das ORM-Diagramm und überprüfe die Modellierung mit Beispielen aus der Faktentabelle. 120 M. Drexl und M. Koch Abbildung 10. Exemplarische Darstellung verschiedener Constraintformen 1/2 Abbildung 11. Exemplarische Darstellung verschiedener Constraintformen 2/2 Modellierung von Geschäftsregeln 121 3. Teste, ob Objekt Typen zusammengefasst werden sollten und kennzeichne alle Typen, die aus den Bestehenden generiert werden können. 4. Füge Uniqueness Constraints hinzu, und teste diese. 5. Füge Mandatory-Role Constraints hinzu und teste ob etwas logisch ableitbar ist. 6. Füge einschränkende Constraints, Pair-Constraints und Subset-Constraints ein. 7. Füge restliche Bedingungen ein und führe letzten Check durch. Anschließend kann der Entwickler bzw. der Anwender auf Basis des erstellten ORM-Diagramms (CIM) mittels des Frameworks automatisch Code für beispielsweise relationale Datenbankmanagementsysteme (PSM) generieren lassen. Das folgende Beispiel zeigt die automatisierte Codegnerierung in SQL-92 aus Abbildung [10]. Hier werden zur Vereinfachung Exclusion Constraints und Asymmetric Constraints als Zusicherungen (Assertions) implementiert. create assertion ' berichten ist assymetrisch ' check ( not exists ( select * from Mitarbeiter X , Mitarbeiter Y where X . angestel ltennr = Y . vorgesetzter and X . vorgesetzter = Y . angestel ltennr )) Listing 5.4. Beispielcode nach automatisierter Codegenerierung (PSM) 5 5.1 AORML - Agent Object Relationship Modeling Language Definition AORML (Agent-Object-Relationship Modeling Language) ist ein agentenbasierter Modellierungsansatz, der auf Basis von AOR (Agent Object Relationship Modeling) die bereits existierenden Modellierungsansätze wie ER (Entity Relationship Modeling) und UML (Unified Modeling Language), erweitert[12]. Im Mittelpunkt stehen Konzepte, welche auf die Bedürfnisse von Unternehmenskommunikation zwischen der beteiligten Kommunikationspartnern zugeschnitten sind. Diese werden im Folgenden als Agenten bezeichnet. Kommunikation und Interaktion können dadurch besser dargestellt werden. 5.2 Einsatz in der Praxis AORML dient den Anwendungsentwicklern in der konzeptionellen Phase zur Modellierung von Geschäftsprozessen bzw. von Geschäftsregeln. Die Agenten-Orientierung wird als neues Paradigma im Software und Informationsengineering angesehen. Sie bietet dabei höchstes Abstaktionsniveau, das die Konzepte von Kommunikation und Interaktion in bereits bestehede Informationssysteme ermöglicht. Da Geschäftsprozesse meist auf Agenten (oder auch Akteure) ausgerichtet sind, ist der agentenorientierte Ansatz hier aufgrund 122 M. Drexl und M. Koch der physikalischen und sozialen Interaktion der verschiedenen Individuen oder Institutionen sehr bedeutend. Es können Modelle für den externen und für den internen Betrachter existieren[5]. In der Analysephase werden in einem externen Modell die Hauptakteue modelliert. In der Designphase wird für jeden dieser Haupagenten ein internes AOR Modell erstellt. Abschließend werden die internen AOR-Modelle in die plattformabhängige Zielsprache wie Java oder SQL übersetzt (PSM). 5.3 AORML - Modellierung 5.3.1 Grundelemente Basierend auf 19 Onthologieprinzipien, sowie einer zugehörige Diagrammsprache wurde ein Framework für die Modellierung entwickelt. Die Onthologieprinzipien erweitern die Entity-Relationship Prinzipien um wichtige Aspekte der agentenbasierten Kommunikation in Unternehmen. Dazu gehören die aus entities abgeleiteten Kategorien der Agenten (agents), Ereignisse (events), Aktionen (actions), Rechte (claims), Verbindlichkeiten (commitments) und gewöhnliche Objekte (ordinary objects). Der genaue Zusammenhang wird in Abbildung [12] als Metamodell dargestellt. Abbildung 12. Metamodell Entity - AORML Grundelemente . Entity (Entität) ist ein bekanntes Prinzip aus der ER Modellierung und beschreibt innerhalb eines Softwaresystems, abstrakte oder materielle Objekte der Wirklichkeit. Sie werden in die oben beschriebene Kategorien eingeteilt, die im Folgenden detailliert definiert werden. . Commitment (Verbindlichkeit)/Claim (Recht) sind immer mit einem ActionEvent gekoppelt und sind fundamentale Komponenten im sozialen Interaktionsprozess, um präzises Verhalten vorherzusagen und zu gewährleisten. Beispiel Commitment:Der Kunde hat die Verbindlichkeit den PKW bei der Modellierung von Geschäftsregeln . . . . 123 Autovermietung zurückzugeben. Beispiel Claim: Die Autovermietung hat das Recht, das Auto vom Kunden zurück zu fordern. Ein Event beschreibt ein Ereignis, dass während eines Prozessworkflows auftreten kann. Hierbei wird zwischen dem ActionEvent und dem NonActionEvent unterschieden, wobei ActionEvents von Aktionen ausgelöst werden. ActionEvents können mit Commitments und Claims wie bereits beschrieben gekoppelt werden. Non-ActionEvents finden unabhängig von Aktionen statt. Außerdem können ActionEvents in Communicative- und NonCommunicative-ActionEvent unterschieden werden. Beispiel Non-ActionEvents: Die Tempertaur steigt über 30 Grad Celsius (⇒ Alle Klimaanlagen der Mietwagen checken. Beispiel Non-Communicative-ActionEvent: Die Autovermietung stellt dem Kunden einen PKW zur Verfügung. Beispiel CommunicativeActionEvent: Der Kunde stellt eine Reservierungsanfrage an eine Autovermietung. Actions stoßen Events an, die ActionEvents genannt werden. Objekte entsprechen den Entity-Typen im ER-Diagramm bzw. den ObjektKlassen im UML-Klassendiagramm. Sie stehen mit anderen Agenten oder Objekten in Verbindung. Agenten lassen sich in Artificial-, Institutional- und BiologicalAgents untergliedern. ArtificialAgents sind Kommunikationsagenten die auf einem Softwaresystem basieren. Dazu zählen Roboter, Softwareagenten und eingebettete Systeme. InstituationalAgents sind soziale Konstrukte wie Organisationen und Organisationseinheiten. Zu den BiologicalAgents gehören nur menschliche Akteure. Beispiel ArtificalAgents: Buchungssystem. Beispiel InstitutionalAgents: Autovermietung. Beispiel BiologicalAgents: Kunde. Zusätzlich werden bei Organisationen zwischen internen- und externen Agenten unterschieden, wobei eine Organisationseinheit immer aus mehreren internen Agenten besteht und gleichzeitig mit mehreren externen Agenten in Beziehung treten kann. Beispiel: Aus der Sicht der „Autovermietung“ (Organisation) steht diese mit dem externen Agenten „Kunde“ in Beziehung. Außerdem besteht die Organisation aus mehrere internen Agenten (Organisationseinheiten wie z.B. Zweigstellen) die wiederum aus weiteren internen Agenten besteht (z.B. Mitarbeiter als HumanAgent) 124 M. Drexl und M. Koch Abbildung 13. Metamodell Agent - AORML Grundelemente 5.3.2 Konkrete Syntax und Semantik - Grundelemente Agenten können im Gegensatz zu Objekten Events erkennen, Nachrichten (MessageTypes) senden und empfangen, Non-CommunicativeActionsEvents ausführen und Rechte (Claims) bzw. Verbindlichkeiten (Commitments) einfordern. Der konkrete Syntax und die jeweiligen Relation der beschriebenen Grundelemente sind in Abbildung [14] dargestellt. Abbildung 14. Konkreter Syntax - Grundelemente 5.3.3 Konkrete Syntax und Semantik - Reaction Rules Nachdem der Zusammenhang der verschiedenen Grundelemente erläutert wurde, wird nun detailliert auf die visuelle Darstellung von Geschäftsregeln eingegangen, die allerdings sehr eng mit dem Aufbau der AOR Grundelemente in Verbindung steht. Regeln werden als ReactionRule durch einen Kreis mit folgenden ein- und ausgehenden Kannten beschrieben, welche die Funktionsweise, das Verhalten und die Semantik der Regel erst abstrakt definieren. Modellierung von Geschäftsregeln 125 Abbildung 15. Konkreter Syntax einer Regel . Triggering Event (eingehende Kante die immer vorkommt): Bedingung, die ein Ereignis auslöst und die Reaction Rule instanziiert . State Condition (eingehende Kante): Kante gibt Bezug zu anderen dazugehörigen Entity Typen an . Outgoing Message (ausgehende Kante): Mentale Auswirkung (Belief/Commitment) . Action (ausgehende Kante): Ausführen einer Aktion . State Change (ausgehende Kante): Mentale Auswirkung (Belief/Commitment) Abbildung 16. Beispiel - Regelemodellierung innerhalb einer Autovermietung Events können von Akteuren, als MessageTypes, an andere Akteure oder auch Regeln übergeben werden. Folgender Messagetype beschreibt eine Überprüfung, ob eine Kunde bereits auf einer schwarzen Liste steht und somit einen 126 M. Drexl und M. Koch PKW überhaupt mieten darf. Der Messagetype löst als triggering event eine Regel aus und ist dadurch eine Vorbedingung für die Regel. Beispiel: askIf(blacklisted(?Customer)) Zusätzlich zur visuellen Darstellung von Reaction Rules, können diese auch in eine textuelle Form übertragen werden. R1 : 1: ON RECEIVE r e q u e s t R e s e r v a t i o n (? CarGrp , ? Period ) FROM ? Customer 2: IF ? CarGrp . hasCapacity (? Period ) 3: THEN 4: SEND askIf ( blacklisted (? Customer )) TO headquarter Listing 5.5. Beispiel für eine Reaction Rule - Reservierung in einer Autovermietung Die Syntax einer Reaction Rule lehnt sich am Syntax der EACC Regel an. Der in der erste Zeile beschriebene Event Messagetype ist Triggering Event für das schalten der Regel R1. Die zweite Zeile überprüft den aktuellen Status einer Bedingung, der für die Statusänderung in Zeile 4 Voraussetzung ist. Erst wenn der Status erfüllt ist, kann eine Aktion ausgeführt werden oder sich ein Status ändern. Die Statusänderung dient darüber hinaus noch als Triggering Event für das schalten von Regel R2. Um die Ablaufsteuerung einer Reaction Rule präzise zu gestalten sind erweiterte Boolsche Operatoren nötig, die folgendermaßen modelliert werden: AND-Split: Die Regel R1 führt einen AND-Split aus indem sie ausgehend von ActionEvent1 sowohl eine neue Message, als auch einen neuen ActionEvent2 gleichzeitig schaltet. Abbildung 17. Modellierung eines AND-Split in AORML AND-Join: Die Regel R1 führt einen AND-Join aus indem sie ausgehend von den eingehenden Nachrichten Message1 und Message2 eine neue Message3 sendet, falls die eingehenden Kannten gleichzeitig gelten. OR-Split: Die Regel R1 führt einen OR-Split aus indem sie ausgehend von ActionEvent1 entweder eine neue Message, oder einen neuen ActionEvent2 schaltet. Modellierung von Geschäftsregeln 127 Abbildung 18. Modellierung eines AND-Join in AORML Abbildung 19. Modellierung eines OR-Split in AORML OR-Join: Die Regel R1 führt einen OR-Join aus indem sie ausgehend von den eingehenden Nachrichten Message1 und Message2 eine neue Message3 sendet, falls mindestens eine der eingehenden Kannten gilt. Abbildung 20. Modellierung eines OR-Join in AORML ELSE: Wenn eine Bedingung (Condition) war ist, sendet die Regel R1 die Nachricht Message1, ansonsten wird das ActionEvent2 geschalten. NOT: Wenn eine Bedingung (Condition) falsch ist, sendet die Regel R1 die Nachricht Message1, ansonsten wird das ActionEvent2 geschalten. 6 6.1 URML - UML-Based Rule Modeling Language Definition MOF/UML Klassendiagramme sind Schlüsseltechnologien für die visuelle Repräsentation von Domänenkonzepten. Das klassische UML Metamodell wurde um neue Regelkonzepte erweitert um neben den Geschäftsprozessen auch detailliert Geschäftsregeln darzustellen. Diese Erweiterung wird in der Fachliteratur als URML-Standard (UML-Based-Rule-Modeling-Language) bezeichnet[10]. URML wurde, wie die bereits vorgestellten Modellierungssprachen entwickelt, um die Kommunikation zwischen Domänen- und Softwareexperten zu verbessern. Hierbei steht wiederum eine natürliche, (semi-)visuelle Darstellung von Regeln im Vordergrund. Neben der Analyse erfüllt URML auch den Zweck der Dokumentation der 128 M. Drexl und M. Koch Abbildung 21. Modellierung von ELSE in AORML Abbildung 22. Modellierung von NOT in AORML Systemanforderungen innerhalb von Unternehmen. Bei der Regeldarstellung liegt der Fokus auf der Modellierung von Derivation-Rules. Aber auch Production- und Integrity-Rules können visualisiert werden. Außerdem wird darüber nachgedacht, Reaction-Rules in den URML Standard zu integrieren. 6.2 Einsatz in der Praxis Die Industrie fordert aufgrund von fehlender Erfahrung bei der visuelle Darstellung von Geschäftsregeln und Onthologien für das semantische Web, Modellierungstools, die auf der bereits bekannten und umfangreich eingesetzten Unified Modeling Language (UML) basieren. Zu diesem Zweck wurde das Strelka Plugin für das JAVA Modellierungstool Fujaba entwickelt (PIM-Ebene)[9]. Dieses Modellierungstool arbeitet auf der Grundlage von URML und erweitert somit wie oben beschrieben UML-Modellierung um Regelkonzepte, die im Folgenden dargestellt werden. Darüber hinaus bietet Strelka die Möglichkeit aus Regelmodellen automatisiert Code auf Plattformen wie beispielsweise JBOSS-Rules zu generieren (PSM-Ebene). 6.3 URML - Modellierung Da URML das umfangreiche Metamodell von UML erweitert, und dieses als bekannt vorausgesetzt wird, soll im Folgenden nur auf das erweiterte Konzept betrachtet werden. 6.3.1 Grundlagen Innerhalb von UML werden die URML Regeln als Erweiterung eines, im UML Metamodell definierten, TypedElement mit einem Namespace Modellierung von Geschäftsregeln 129 integriert. Somit repräsentieren Regeln, Elemente mit einem bestimmten Typen und werden durch ihren Namen identifiziert. Nach Abbildung 23 werden Regeln in Abbildung 23. Metamodell der Ruleinterpretation in folgende drei bekannten Typen unterschieden, die im Modell folgende Funktionen beinhalten: Derivation Rules: Ableitungsregeln besitzen mindestens eine Vorbedingung (RuleCondition) und genau eine Folgerung (RuleConclusion). Diese Regel definiert, in wieweit bestimmte Modellelemente aus der Regel abgeleitet werden können. Production Rule: Produktionsregeln besitzen wie Derivation Rules mindestens eine Vorbedingung (RuleCondition), genau eine resultierende Aktion (RuleAction) sowie optionale Nachbedingung (PostCondition). Reaction Rule: Prozess- / Verhaltensregeln können mehrere Vorbedingungen (RuleConditions) enthalten und besitzen wie die ProductionRules genau eine resultierende Aktion (RuleAction) sowie optionale Nachbedingung (PostCondition). Außerdem benötigt diese Regel ein auslösendes Element (RuleEvent). ReactionRules repräsentieren somit eine ECAA Struktur. 6.3.2 Konkrete Syntax und Semantik In folgendem Abschnitt werden alle relevanten URML Regelelemente, deren Zusammenhang untereinander, sowie die 130 M. Drexl und M. Koch Abbildung 24. Konkreter Syntax einer Regel in URML Integration in das UML Prozessmodell erläutert. Nach Abbildung [24] sind dies: Regeln werden durch Kreise mit ihrem zugehörigen Namen und einer eindeutigen ID modelliert. Zusätzlich besitzen sie ein- und ausgehende Kanten. Eingehende Kanten (ConditionArrow) repräsentieren Vorbedingungen (RuleCondition) und definieren die Beziehung zwischen Modellelementen und der Regel. Darüber hinaus können die eingehende Kanten negiert werden (NegatedConditionArrow) um eine Negation der Vorbedingung zu überprüfen. Einschränkungen einer Vorbedingung werden durch textuelle Ausdrücke (FilterExpression) auf den Kanten vorgenommen. Ausgehende Kanten (ConclusionArrow) repräsentieren die Folgerung (RuleConclusion) und definieren die Beziehung zwischen der Regel und dem Modellelement. Auf ein- und ausgehenden Kanten werden für die Parameterübergabe, an die Conditions bzw. Conclusions, Variablen verwendet. Für das bessere Verständnis dient folgendes Beispiel [25] bei dem eine Derivation Rule modelliert wurde. Hierbei überprüft die Regel DR mit der ID 8 ob ein Mietwagen vollgetankt (Filter Expression) bei einer bestimmten Zweigstelle untergebracht ist (Condition Arrow) und ob der Mietwagen momentan nicht anderweitig zugeteilt wurde (NegatedConditionArrow). Aus diesen Überprüfungen, leitet die Derivation Rule ab, das der PKW zum Verleih zur Verfügung (ConclusionArrow) steht. Einund ausgehende Kanten sind zudem mit Variablen belegt, die hier zum besseren Verständnis der Derivation Rule, in folgender logischen Formulierung verwendet werden. . istVerfügbarBei(mw, zs) ← istUntergebrachtBei(mw, zs) AND tankInhalt(mw)≥ 90 AND ¬∃ma(istZugeteiltZu(mw, ma)) Modellierung von Geschäftsregeln 131 Abbildung 25. Modellierung einer Derivation Rule über URML 7 Gegenüberstellung und Vergleich der RegelModellierungsmethoden In diesem Abschnitt werden die vorgestellten Regelmodellierungsmethoden bewertet. Dafür müssen zunächst eine Reihe von geeigneten Bewertungskriterien ausgearbeitet werden. Als Vorlage dient die DIN-ISO-Norm 9126, die zur Untersuchung der Softwarequalität herangezogen wird. Softwarequalität wird dabei in dieser Norm folgendermaßen abgegrenzt: „Software-Qualität ist die Gesamtheit der Merkmale und Merkmalswerte eines Software-Produkts, die sich auf dessen Eignung beziehen, festgelegte Erfordernisse zu erfüllen“. Nach dieser Definition gibt es nicht nur ein einziges Merkmal, an dem die Qualität festgemacht werden kann. Nicht alle Merkmale eignen sich dabei auch für die Evaluierung von Regel-Modellierungsmethoden. Es wird daher zunächst eine Auswahl aus den vorhandenen Merkmalen getroffen bevor deren Begriffsbestimmungen an die spezifischen Erfordernisse der Qualitätsbeurteilung von Regel-Modellierungsmethoden angepasst wird. Zu den geeigneten Merkmalen zählen Funktionalität, Benutzbarkeit und Änderbarkeit. Zunächst muss der Begriff der Funktionalität definiert werden. Bei einer Software versteht man hierunter die Frage, inwieweit diese einen spezifizierten Funktionsumfang erfüllt und was damit umgesetzt werden kann. Übertragen auf Regelmodellierungsmethoden sind hier die Ausdrucksstärke, die Praxisnähe und eventuelle Alleinstellungsmerkmale eines Modells sinnvolle Bewertungskriterien. Benutzbarkeit hingegen wird bei Software als Summe „alle[r] Eigenschaften eines Systems, die sich mit der Mensch-Maschine-Schnittstelle und 132 M. Drexl und M. Koch damit in direkter Weise mit der Benutzerinteraktion befassen“, festgelegt. Bei den Regelmodellierungsmethoden ist dabei die Sicht des Benutzers, der das Modell später betrachtet gemeint. Hierbei wird nach Erlernbarkeit der Syntax sowie der Verständlichkeit des gesamten Modells differenziert. Als letztes Merkmal wird die Änderbarkeit herangezogen. Sie soll die Sichtweise des Modellierers darstellen. Interessante Teilbereiche sind hierbei der Modellierungsaufwand sowie die Möglichkeit, ein bestehendes Modell nach der Umstellung einer Regeländerung anzupassen und dessen anschließende Stabilität zu beurteilen. Diese an die Erfordernisse der Beurteilung von Regelmodellen adaptierten Bewertungskriterien bilden nunmehr die Basis für die Evaluierung der vorgestellten Modellierungssprachen. Funktionalität Zuerst soll die Ausdrucksstärke einer jeden Sprache miteinander verglichen werden. Im Bezug auf die Ausdrucksstärke unterstütz URML die meisten Regelarten. Darunter befinden sich Constraints und Derivation Rules, die ebenfalls mit der Ross Notation und ORM modelliert werden können. Außerdem können Production Rules dargestellt werden und die Integration von Reaction Rules befindet sich in Planung. Bisher ist AORML im Vergleich die einzige Modellierungssprache, mit der Reaction Rules überhaupt dargestellt werden können, was somit auch als Alleinstellungsmerkmal angesehen werden kann. Tabelle [2] zeigt die verwendeten Regeltypen der jeweiligen Modellierungssprachen noch einmal im übersichtlichen Vergleich. Regelmodellierungssprache Ross Notation ORM AORML URML Verwendete Regeltypen Constraints, Derivation Rules Constraints, Derivation Rules Reaction Rules Constraints, Derivation Rules, Production Rules Tabelle 2. Regeltypen der jeweiligen Modellierungssprache Zur Praxisnähe ist zu sagen, das sich ORM im Bereich der Regelmodellierung für Datenbanken etabliert hat und somit einen Vorteil im Vergleich zu den anderen Sprachen hat[11]. Der umfangreiche Toolsupport von ORM (NORMA: Plugin für Visual Studio) und URML (Fujaba: Rule Plugin) unterstreicht den intuitiven Einsatz in der Praxis. Für AORML ist ebenfalls ein Plugin für MS Visio verfügbar, dass aber aufgrund der Modellierungsmöglichkeit von nur einer Regelart weniger Relevanz als die bereit erwähnten Sprachen hat. Für die Ross-Notation existiert kein bekannter Toolsupport. Benutzbarkeit Für den Benutzer, der das Modell am Ende verstehen und anwenden soll, ist zum einen die Verständlichkeit ein wichtiges Kriterium. Dabei stellt sich die Modellierung von Geschäftsregeln 133 Frage, ob das Regelmodell übersichtlich und der Ablauf der modellierten Regel einfach nachzuvollziehen ist. Die Praxis zeigt, dass ORM und AORML durch die intuitive Darstellung von Regeln, in natürlicher Sprache kombiniert mit sinnvoll verwendeten grafischen Elementen, einfach zu verstehen und zu erlernen ist. Da URML eine Erweiterung von UML ist, ist es leichter als ORM und AORML zu erlernen, durch die technische Sicht jedoch schwieriger zu verstehen. Die Ross-Notation die weniger eine einfache grafische Notation besitzt, sondern eher eine aus logischen Ausdrücken bestehende formale Sprache darstellt, ist somit schwierig zu erlernen. Dazu kommt, dass 42 verschiedene Regeltypen existieren. Änderbarkeit Schließlich wird noch die Sicht des Modellierers betrachtet. Wie bereits erwähnt, soll dabei auf die Änderbarkeit eines Regelmodells eingegangen werden. Komplexe Modelle sind selbstverständlich aufwendiger zu konstruieren und schwerer zu verstehen. ORM ist die stabilste Sprache, da sie im Gegensatz zu den anderen Notation nicht zwischen Klassen und Attributen unterscheidet, sondern sie als unabhängige Konzepte betrachtet. Somit ist die Änderbarkeit bei ORM sehr hoch und weniger mit Seiteneffekten behaftet. Vergleichstabelle Die Ergebnisse der vorangegangenen Abschnitte werden zum Abschluss noch einmal übersichtlich in Vergleichstabelle [3] dargestellt. Dabei stellt ein „+“ eine starke Ausprägung dar und ist als positiv anzusehen. Die „0“ steht für eine neutrale Ausprägung, während das „-“ eine schwache Ausprägung ist und eine Schwäche der Sprache im jeweiligen Bereich darstellt. Beurteilungskriterium/Notation Ross-Notation ORM AORML URML Ausdrucksstärke 0 0 0 + Praxisnähe + 0 + Alleinstellunsgmerkmale 0 0 + 0 Verständlichkeit 0 + + 0 Erlernbarkeit 0 0 + Änderbarkeit 0 + 0 0 Tabelle 3. Übersicht Vergleichskriterien 8 Fazit Zusammenfassend lässt sich feststellen, dass bei der Modellierung von Geschäftsprozessen die zusätzlich integrierte Geschäftsregelmodellierung essenziell für die umfassende Darstellung, und Anpassung von Prozessabläufen ist und 134 M. Drexl und M. Koch somit die Flexibilität und Konkurenzfähigkeit von Unternehmen im Alltag steigert. Der Kerngedanke der Regelmodellierung besteht in der Verbesserung der Kommunikation zwischen Domänen- und IT-Experten. Dafür verwenden alle vier vorgestellten Sprachen eine relativ sachliche Darstellungsweise, wobei im Detail folgende Unterschiede anzumerken sind. Alle betrachteten Methoden weisen Spezialisierungen im Bezug auf verwendete Regeltypen auf, wobei URML die nötige Integration mehrerer Regelarten erkennen lässt. Hierbei ist jedoch darauf zu achten, dass durch den universellen Ansatz nicht die Erlernbarkeit darunter leidet. ORM und URML sind darüber hinaus am weitesten verbreitet und bieten deshalb den besten Toolsupport. Zu AORML ist zu sagen, dass die Sprache zwar einen sehr guten Ansatz hinsichtlich der Verständlichkeit aufweist, allerdings durch die Spezialisierung auf einen Regeltypen nur bedingt für den umfassenden, betrieblichen Einsatz geeignet ist. Die Ross-Notation ist in ihrer gesamten Komplexität, durch ihr formales Gerüst, nur schwer für den Regelmodellierer zu erlernen und damit bedingt praxisnah. Wünschenswert für die Zukunft wäre natürlich die Möglichkeit, verschiedene Modellierungssprachen für unterschiedliche Regelarten in einem Unternehmen, abhängig von den darzustellenden Regeltypen und der Präferenz des Modellierers, zu verwenden. Literatur [1] T. C. u. L. W. Dr. Wolfgang Martin. Das Ende des Software-Release-Zyklus? Business Rules Management. JAXenter, Januar 2008. [2] T. Halpin. Business Rules and Object Role Modeling. Database Programming and Design, Oktober 1996. [3] T. Halpin. Object-Role Modeling: an overview. Microsoft Corporation, 2001. [4] D. C. Hay. The Business Constraint Model. TDAN.com, Juli 2004. [5] G. W. Kular Taveter. Agent-Oriented Enterprise Modeling Based on Business Rules. 2001. [6] J. Müller. Workflow-based Integration Grundlagen, Technologien, Management. Springer, Berlin, 2005. [7] R. G. Ross. Principles of the Business Rule Approach. Addison-Wesley, 2003. [8] R. G. Ross. Business Rules and Events: The Crux of the Matter. Business Rules Solutions - LLC, Mai 2005. [9] G. W. Sergey Lukichev. UML-Based Rule Modeling with Fujaba. Institute of Informatics, Brandenburg University of Technology at Cottbus, Deutschland, 2006. [10] G. W. Sergey Lukichev. Visual Rules Modeling. Institute of Informatics, Brandenburg University of Technology at Cottbus, Deutschland, 2006. [11] M. J. Sergey Lukichev. Graphical Notations for Rule Modeling - Handbook of Research on Emerging Rule-Based Languages and Technologies. Idea Group Inc., 2009. [12] G. Wagner. The Agent-Object-Relationship Metamodel: Towards a Unified View of State and Behavior. Eindhoven University of Technology, In Information Systems 28:5, 2003. [13] G. Wagner. The Abstract Syntax of RuleML: Towards a General Web Rule Language Framework. Proceedings of the IEEE,WIC,ACM International Conference on Web Intelligence, 2004.