• Keine Ergebnisse gefunden

Graphtransformationsregeln f¨ ur den Bugtracker

5.4 Informelle Spracheinf¨ uhrung am Beispiel

5.4.2 Graphtransformationsregeln f¨ ur den Bugtracker

Auflistung 5.1:EMFs L¨ucke: Verhalten muss in reinem EMF in Java beschrieben werden; Aus-schnitt aus dem EMF-generierten Quelltext f¨ur die modellierte Klasse Project des Bugtracker Ecore-Modells

Die Umsetzung einer Operation in eine Java-Methode ist in Auflistung 5.1 darge-stellt. Sie zeigt am Beispiel von createTicket(...) den generierten Quelltext. Dabei wird der Rumpf der Methode mit einer Ausnahme bef¨ullt und der Modellierer in einem Kom-mentar dazu aufgerufen, die Methode per Hand in Java zu implementieren.

5.4.2 Graphtransformationsregeln f¨ ur den Bugtracker

EMFs Aufruf, die Methoden per Hand in Java zu implementieren, ist der urspr¨ungliche Ansatzpunkt dieser Arbeit. Ecore bietet keine M¨oglichkeit, Verhalten zu modellieren.

Hier setzt ModGraph mit den Graphtransformationsregeln an. Diese beschreiben das Verhalten der Operation deklarativ auf Modellebene. Sie kommen zum Einsatz, wenn komplexe strukturelle ¨Anderungen am Modell vorgenommen werden oder es auf eine komplexe Bedingung hin getestet wird. Damit werden die Regeln nur genutzt, wenn sie einen echten Mehrwert bieten. Im Vergleich zu dem geforderten Java-Quelltext ist dies ein echter Gewinn bez¨uglich des Abstraktionsniveaus. Der Modellierer muss sich dabei nicht mit der Mustersuche innerhalb der Instanz besch¨aftigen. Er gibt lediglich, wie im Folgenden gezeigt wird, den gew¨unschten Vor- und Nachzustand der Instanz an.

Zudem sind die Regeln sehr leicht verst¨andlich, da sie gr¨oßtenteils grafisch dargestellt werden und dabei intuitiv farbkodiert sind. Zu erstellende Elemente sind beispielsweise immer gr¨un und mit ++ markiert, zu l¨oschende immer rot und mit −−. Außerdem weisen die Regeln immer den gleichen Aufbau auf: Das Graphmuster ist zentral links angeordnet, die NACs rechts daneben. Die Vorbedingungen befinden sich oberhalb beider und die Nachbedingungen darunter. Dies erleichtert dem Nutzer die Handhabung.

Implementiert man eine Methode, wie die eben betrachtete createTicket, mit einer Graphtransformationsregel, ist ein Eingriff in das Ecore-Modell n¨otig, der auch bereits in Abbildung 5.5 zu sehen ist: Jeder Operation, die durch eine Regel implementiert ist, wird eine Ausnahme des Typs GTFailure zugeordnet. Diese wird ben¨otigt, sobald eine

Abbildung 5.6: ModGraph-Regel zur Erzeugung eines Tickets innerhalb eines Projekts im Bugtracker; Implementierung der Operation createTicket((severity:Severity, tit-le:EString, description:EString, reporter:User):Ticket der KlasseProject

Bedingung der Regel verletzt ist. Sind Vorbedingungen, Graphmuster oder NAC Ursa-che der Ausnahme, ist die Regel nicht ausf¨uhrbar. Ist das Scheitern der Nachbedingung Grund f¨ur das Ausl¨osen der Ausnahme, ist die Regel bereits angewendet, jedoch ist die Instanz inkonsistent. Da die Regeln selbst nicht invertierbar sind, muss das Schei-tern der Regel durch den Kontrollfluss, aus dem die Regel aufgerufen wurde, behandelt werden. Dieser kann beispielsweise alternative Regeln oder, im Falle des Scheiterns der Nachbedingung, Reparaturregeln definieren, um die Ausnahme zu behandeln.

Welche Bedingungen an eine Regel gestellt werden k¨onnen und wie diese formuliert werden, wird nun exemplarisch an einigen Regeln gezeigt. Des Weiteren wird die Defi-nition von Struktur¨anderungen in der Regel erl¨autert.

Implementierung der Operation createTicket der Klasse Project

Abbildung 5.6 zeigt die Implementierung der Operation createTicket als Graphtransfor-mationsregel. Zun¨achst stellen OCL-Vorbedingungen sicher, dass die ¨ubergebenen Zei-chenketten f¨ur den Titel und die Beschreibung des Tickets nicht leer sein d¨urfen und der Berichterstatter Zugriff auf das Projekt hat, welchem das Ticket zugeordnet werden soll. Ist die Vorbedingung verletzt, wird eine Ausnahme ausgel¨ost. Die Instanz bleibt unver¨andert. Ist sie nicht verletzt, wird das Graphmuster auf die Instanz abgebildet.

Das Graphmuster beinhaltet zun¨achst links oben ein aktuelles Objekt, das mit this gekennzeichnet ist und in diesem Fall eine Instanz der Projektklasse darstellt. Außerdem beinhaltet es links unten den nicht-primitiven Parameterreporter, der stellvertretend f¨ur eine Instanz der Klasse User steht. Beide Knoten werden nicht ver¨andert, weil ihr

Chan-ges-Bereich, in welchem die ¨Anderungen spezifiziert werden, leer ist. Sie werden auch nicht mit Bedingungen versehen, da ihr Constraints-Bereich, welcher der Spezifikation von Bedingungen an einen Knoten dient, ebenfalls leer ist. Der Parameter reporter ist grau hinterlegt und damit zu erhalten. Zu erhaltende oder zu l¨oschende obligatorische Knoten im Graphmuster m¨ussen zur Ausf¨uhrung der Regel auf Objekte abgebildet wer-den. Dies wird vor Anwendung der ¨Anderungen gepr¨uft. Sie stellen letztlich eine weitere Vorbedingung an die Anwendbarkeit der Regel dar, bei deren Scheitern wiederum eine Ausnahme ausgel¨ost wird.

Die beiden anderen Knoten werden erzeugt. Sie sind daher mit ++ und einem gr¨unen Hintergrund gekennzeichnet. Da keine Bedingungen an einen neu erzeugten Knoten ge-stellt werden k¨onnen, fehlt hier die M¨oglichkeit, Bedingungen zu spezifizieren. Oben rechts in Abbildung 5.6 wird eine Instanz der Klasse Ticket erzeugt. Dieser werden ein Erstellungsdatum und eine durch die Klasse BugTracker verwaltete, eindeutige laufende Nummer zugewiesen. Die Zuweisung erfolgt innerhalb des Knotens, imChanges-Bereich.

Zus¨atzlich ist dieser Knoten mit << out >> gekennzeichnet. Dies bedeutet, dass er als R¨uckgabewert der Operation dient. Unten rechts wird eine Revision dieses Tickets erzeugt und initialisiert. Hierbei wird dem Attributtitleder Wert des gleichnamigen pri-mitiven Parameters der Operation zugewiesen. Analog geschieht dies f¨ur die Beschrei-bung und die Dringlichkeit. Der Status bekommt das LiteralStatus.NEW (f¨ur ein neues Ticket) zugewiesen und das Datum der Revisionserstellung wird vermerkt.

Erzeugte Objekte m¨ussen in ihren Kontext eingebettet werden. Dazu werden alle Beziehungen zwischen den existierenden und neuen Objekten erstellt. Die Links werden jeweils mit dem Namen der Referenz des Modells gekennzeichnet, die sie instanziieren.

Sofern sie erzeugt werden, sind sie zus¨atzlich gr¨un und mit ++ markiert. Dem Projekt wird das Ticket zugeordnet (Link reportedTickets), welchem wiederum ein Benutzer als Berichterstatter (Link reporter) zugeordnet wird. Zudem wird der Ticketrevision der erstellende Benutzer zugewiesen (Linkcreator). Die Revision wird einerseits als aktuelle Revision (Link currentRevision) des Tickets gekennzeichnet, andererseits direkt in die Historie (Link history) aufgenommen. Obwohl die Referenz geordnet ist, wird ein nicht geordneter Link eingezeichnet, da es sich hier um das erste Objekt im mehrwertigen Link handelt.

Unten in Abbildung 5.6 ist eine Nachbedingung angegeben. Sie muss nach Anwendung der im Graphmuster spezifizierten ¨Anderungen g¨ultig sein. In der betrachteten Regel ist gefordert, dass die laufende Nummer des Tickets eindeutig ist. Ist die Nachbedingung nicht erf¨ullt, scheitert die Regel. Die ¨Anderungen an der Instanz sind allerdings bereits vorgenommen worden. So liegt es am Modellierer, diese Ausnahme im Kontrollfluss geeignet zu behandeln, indem beispielsweise Reparaturaktionen definiert werden.

Aus dieser Regel kann nun Quelltext generiert werden, der direkt in den EMF-generier-ten eingef¨ugt wird. Bevor dies jedoch genauer betrachtet wird, werden einige weitere Operationen mit Graphtransformationsregeln implementiert, um die Einf¨uhrung in die Sprache zu vertiefen.

Abbildung 5.7: ModGraph-Regel zur Erzeugung eines Projekts im Bugtracker; Implementierung der OperationcreateProject(name:EString, leader:User, firstGroup:Group):Project der KlasseBugTracker

Implementierung der Operation createProject der Klasse BugTracker

Zur korrekten Funktionalit¨at des Bugtrackers ist es notwendig, vor der Erzeugung von Tickets zun¨achst ein Projekt zu erstellen, dem die Tickets, wie soeben beschrieben, zugeordnet werden m¨ussen.

Die Regel zur Implementierung der Operation createProject(...), die diese Aufgabe ubernimmt, ist in Abbildung 5.7 gezeigt. Sie besteht aus einem Graphmuster und ei-¨ ner negativen Anwendbarkeitsbedingung, die ebenfalls als Graph dargestellt wird. Im Graphmuster befinden sich zwei nicht-primitive Parameter der Methode, firstGroupoben links undleaderunten links. Der Linkmemberszwischen diesen beiden ist schwarz gef¨arbt und damit zu erhalten. Er stellt eine positive Anwendbarkeitsbedingung an die Regel und k¨onnte im ¨Ubrigen auch als Vorbedingung textuell spezifiziert werden. Hier zeigt sich die ¨Aquivalenz von Vorbedingungen und vorgegebenem Graphmuster deutlich. Der Benutzer, der durch den Parameter leaderrepr¨asentiert wird, muss Mitglied der Gruppe, die durchfirstGroupdargestellt wird, sein. Ist dies der Fall, so wird ein neues Projekt mit dem der Operation ¨ubergebenen Namen als Instanz der KlasseProjecterzeugt. Der hier-zu genutzte, ungebundene und hier-zu erstellende Knoten wird hier-zus¨atzlich als R¨uckgabewert der Methode durch << out >> markiert.

Das neue Projekt wird in seinen Kontext eingebettet, indem die Links zur Gruppe, dem Projektleiter und dem Bugtracker selbst - wie im vorangegangenen Abschnitt beschrie-ben - erzeugt werden. Allerdings werden die im Graphmuster spezifizierten ¨Anderungen nur ausgef¨uhrt, wenn der Bugtracker kein Projekt enth¨alt, das bereits den ¨ubergebenen Namen tr¨agt. Dieser Fakt kommt in einer negativen Anwendbarkeitsbedingung (NAC) zum Ausdruck. Sie beschreibt Sachverhalte, die zur Regelanwendung keinesfalls gegeben sein d¨urfen. Jede in einer Regel vorkommende NAC stellt ein Verbot dar. Ihre Knoten sind immer einwertig und enthalten nur Bedingungen. In Abbildung 5.7 wird gefordert, dass das aktuelle Objekt this - als Instanz der KlasseBugTracker - kein Projektp2 ent-halten darf, das bereits denselben Namen tr¨agt, welcher dem neuen Projekt zugewiesen werden soll.

Abbildung 5.8:ModGraph-Regel zur ¨Anderung des Status eines Tickets im Bugtracker; Imple-mentierung der Operation changeStatus(status:Status, author:User) der Klasse Ticket

Implementierung der Operation changeStatus der Klasse Ticket

Betrachtet man die Evolution eines erzeugten Tickets im Bugtracker, so kommt es vor, dass der Status eines bestehenden Tickets ge¨andert werden muss, z.B. weil das beschrie-bene Problem gel¨ost ist.

Die Regel zur Implementierung der zugeh¨origen Operation changeStatus ist in Abbil-dung 5.8 gezeigt. In ihr werden sowohl OCL als auch programmiersprachliche Konstrukte (z.B.!=) verwendet.

Zun¨achst muss die aktuelle (letzte) Revision des Tickets ermittelt werden. Diese ist durch einen ungebundenen Knoten mit der BezeichnungoldRevisionim Graphmuster

dar-Abbildung 5.9:Ausschnitt aus der alternativen Modellierung der ModGraph-Regel zur Imple-mentierung der Operation changeStatus(status:Status, author:User) der Klasse Ticket

Abbildung 5.10: ModGraph-Regel zur Zuweisung eines Tickets an einen Benutzer im Bugtra-cker; Implementierung der Operation reportedTickets():Ticket[0..]der Klasse User

gestellt, welcher erhalten werden soll. Er ist daher grau hinterlegt. Das Objekt, welches durch diesen Knoten repr¨asentiert wird, muss zur Laufzeit der Regel ermittelt werden.

Dabei muss die Bedingung an den Knoten eingehalten werden. Die vorangegangene ak-tuelle Revision darf keinesfalls den Status zur¨uckgewiesen haben. Diese Anforderung ist durch eine Bedingung direkt an den die Revision repr¨asentierenden Knoten gestellt und daher im Constraints-Bereich des Knotens zu finden. Sie kann - ebenso wie der existie-rende Link der Regel createProject- als positive Anwendbarkeitsbedingung an die Regel angesehen werden. Ausgehend von diesem Objekt wird eine beauftragte Person ermittelt.

Hierbei ist es zul¨assig, dass kein Nutzer zust¨andig ist. Dies wird durch die Markierung

<< optional >> am Knoten erreicht, die diesen als optionalen Knoten definiert.

Zur ¨Anderung des Status wird, ¨ahnlich zur Regel der Operation createTicket, eine neue Revision des Tickets erzeugt und in ihren Kontext eingebettet. Auff¨allig ist dabei die Referenzassignee, die den zust¨andigen Nutzer festlegt. Die implementierenden Links enden in einem optionalen Knoten und werden deswegen als optional angenommen.

Zudem muss der Link der aktuellen Revision umgesetzt werden. Dies geschieht hier durch explizites L¨oschen und erneutes Setzen des Links zur aktuellen Revision. Der zu l¨oschende Link zur vorangehenden aktuellen Revision ist, wie alle zu l¨oschenden Links, rot und mit−−markiert. Der Link history wird trotz der Instanziierung der geordneten Referenz wiederum als nicht explizit geordnet angegeben. Hierbei wird ausgenutzt, dass alle Referenzen in EMF implizit geordnet sind. Die erzeugte Revision wird am Ende der bereits inhistory enthaltenen Revisionen eingef¨ugt. Eine alternative Variante, welche die neue Revision vor allen bereits bekannten einf¨ugt, ist ausschnittsweise in Abbildung 5.9 dargestellt. Hier wird ein geordneter Link genutzt, der durch seine Kennzeichnung mit first das gew¨unschte Verhalten erm¨oglicht.

Implementierung der Operation reportedTickets der Klasse User

Ist ein Nutzer eines Bugtrackers sehr aktiv, so kann es f¨ur ihn von Vorteil sein, sich alle von ihm erstellten Tickets zur Ansicht ausgeben zu lassen. Dies wird durch die Operation reportedTickets modelliert, deren implementierende Regel in Abbildung 5.10 gezeigt ist. Die Operation weist einen mehrwertigen R¨uckgabeparameter des TypsTicket

1 public c l a s s BugTrackerImpl extends MinimalEObjectImpl . C o n t a i n e r

2 implements BugTracker {

3 . . .

4 protected s t a t i c f i n a l i n t RUNNING NO EDEFAULT = 0 ;