• Keine Ergebnisse gefunden

Prozedurale Elemente im Bugtracker

5.4 Informelle Spracheinf¨ uhrung am Beispiel

5.4.3 Prozedurale Elemente im Bugtracker

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 ;

5 . . .

6 protected i n t runningNo = RUNNING NO EDEFAULT ;

7 . . .

Auflistung 5.2: Java Implementierung der MethodegetNextNumber() der KlasseBugTracker

auf. Die Regel beinhaltet neben dem bereits bekannten Knoten f¨ur das aktuelle Objekt this einen mehrwertigen, ungebundenen Knoten. Er ist durch eine verdoppelte, leicht verschobene Silhouette dargestellt. Mehrwertige Knoten repr¨asentieren mehrere Objekte gleichen Typs. Hierbei reicht auch die Typisierung ¨uber eine gemeinsame Oberklasse aus. Zudem sind neben den ungebundenen Knoten auch gebundene mehrwertige Knoten m¨oglich, die mehrwertige, nicht-primitive Parameter der Operation repr¨asentieren.

Der hier abgebildete Knoten wird durch die Markierung mit<< out >>als R¨ uckgabe-wert der Operation definiert. Er repr¨asentiert alle Tickets, die von genau dem Benutzer, der durch das aktuelle Objekt repr¨asentiert ist, erstellt wurden. Dies wird durch den zu erhaltenden Link reporter vom Ticket zu dessen Ersteller gefordert. Der Link ist je-doch unidirektional, da die instanziierte Referenz es auch ist. Damit kann hier nicht vom Nutzer (this) zu den Tickets navigiert werden, da auch sonst keine direkte Verbin-dung zwischen einem Nutzer und seinen Tickets besteht. Deshalb nutzt man einen Pfad.

Dieser wird als dicker, grauer Pfeil dargestellt und verbindet zwei Knoten. Er stellt eine abgeleitete Referenz dar und muss einen Pfadausdruck tragen. Der Pfadausdruck ist hier in OCL verfasst und wird auf dem Quellobjekt, hier dem Benutzer, ausgewertet. Er gibt eine Menge von Zielobjekten, hier Tickets, zur¨uck. Er ruft die OperationrelatedProjects() auf, die alle mit dem Nutzer zusammenh¨angenden Projekte zur¨uck gibt und holt sich aus diesen Projekten alle Tickets. Man beachte, dass dies genau der Fall eines geschachtelten Operationsaufrufes ist, da die Regel selbst eine Operation implementiert. Die durch den Pfad ermittelte Ticketliste enth¨alt jedoch mehr als die vom aktuellen Nutzer erstellten Tickets. Sie wird durch den Link zum aktuellen Objekt nochmals gefiltert, bevor die resultierenden Objekte dem mehrwertigen Knoten zugewiesen werden.

5.4.3 Prozedurale Elemente im Bugtracker

Im vorangegangenen Abschnitt wurden Beispiele f¨ur die Implementierung von Operatio-nen auf Modellebene betrachtet. Dabei zeigt sich, dass Graphtransformationsregeln sehr gut zur Modellierung von komplexen Strukturver¨anderungen an der Bugtracker-Instanz

37 runningNo = runningNo + 1

38 return runningNo

39 }

40 } . . .

Auflistung 5.3: Ausschnitt aus dem generierten Xcore-Modell der Bugtrackers: Klassen Group undBugTrackermit Erg¨anzung um die Methoden zur Berechnung der laufenden Nummer f¨ur Tickets

geeignet sind. Prozedurale Elemente werden von den Regeln selbst nicht angeboten.

Einzige Ausnahme bilden hier die Operationsaufrufe innerhalb der Regel. Sie stellen geschachtelte Operationsaufrufe - eine Art prozeduralen Kontrollfluss - dar. Dadurch d¨urfen sich die Regeln einerseits gegenseitig aufrufen, andererseits auf einfache Ope-rationen zur¨uckgreifen. Beispielsweise wird in der Regel createTicket eine prozedurale Methode des Bugtrackers aufgerufen, die laufende Nummern an die Tickets verteilt.

Weiterhin ruft die Regel reportedTickets die durch die Regel relatedProjects implemen-tierte gleichnamige Operation auf.

Die aus createTicket aufgerufene Methode getNextNumber() hat stark prozeduralen Charakter. In der abgebildeten Regel (siehe Abbildung 5.6) wird daher vorausgesetzt, das sie in Java geschrieben ist (siehe Auflistung 5.2). Da in ModGraph durch die Integra-tion von Xcore totale modellgetriebene Softwareentwicklung erm¨oglicht wird, soll diese

Methode nun ebenfalls auf Modellebene spezifiziert werden. So wird sie, den Richtlinien des ModGraph-Ansatzes folgend, in Xcore verfasst. Xcore mit Xbase wird in ModGraph als prozedurale Sprache zur Unterst¨utzung und Steuerung der Regeln gew¨ahlt, da nach den Ergebnissen von Buchmann et al. [20], eine graphische Sprache keinerlei Vorteile in der prozeduralen Verhaltensmodellierung bringt. Gleichzeitig bietet Xcore eine gut verst¨andliche, kompakte und konzise textuelle Syntax. Zudem folgt der Einsatz von Xcore der Linie des ModGraph-Ansatzes, die vorgibt, dass hier eine echte Erweiterung von EMF stattfinden soll, ohne EMF unn¨otig zu belasten. Dazu werden bereits be-stehende Sprachbestandteile wiederverwendet. Die resultierende, strikte Trennung von prozeduraler und regelbasierter Verhaltensmodellierung in Kombination mit deren sym-biotischer Zusammenarbeit ist dabei als Vorteil zu sehen, weil diese unter anderem zur Ubersichtlichkeit des Modells beitr¨¨ agt. Dies wird im Folgenden deutlich.

Zur Spezifikation von prozeduralen Anteilen des Modells muss zun¨achst das Ecore-Modell des Bugtrackers in ein Xcore-Ecore-Modell ¨uberf¨uhrt werden. Dies ist problemlos m¨oglich, da das zum Ecore-Modell geh¨orende Generator-Modell - durch Nutzung sei-nes Export-Rahmenwerks - in ein Xcore-Modell transformiert werden kann.

Das erzeugte Xcore-Modell ist in Auflistung 5.3 ausschnittsweise gezeigt. Die Klasse BugTracker ist bereits um die Ermittlung der laufenden Nummer (Zeilen 36-39) erwei-tert. Diese wird jedem Ticket, unabh¨angig von seiner Projektzugeh¨origkeit, zugewiesen.

Dazu wird im Bugtracker eine Variable initialisiert, welche die Nummer des n¨achsten zu verwaltenden Tickets speichert (Zeile 13) sowie eine Methode, die diese ermittelt (Zeilen 36-39). Sie wird nun auch aus der RegelcreateTicketaufgerufen. Um die modellierte Ope-ration korrekt aufzurufen, muss die Zuweisung innerhalb der Regel ver¨andert werden in den Xbase-Ausdrucknumber = ((eContainer().eContainer()) as BugTracker).getNextNumber(), da Xbase keine Java-Typumwandlungen unterst¨utzt, jedoch seine eigenen durch das Schl¨usselwort as anbietet.

Neben diesen einfachen Methoden kommt kaum ein Programm ohne die aus der struk-turierten Programmierung bekannten Kontrollstrukturen aus. Eine einfache Sequenz zur Initialisierung des Bugtrackers ist in Auflistung 5.3 in Zeilen 30-35, gezeigt. Hier wird zuerst eine Gruppe namens

”Initiatoren“, danach ein Benutzer mit Benutzernamen

” Ers-ter“ und zuletzt ein Projekt namens

”erstes Projekt“ angelegt. Zudem werden Schleifen und Bedingungen ben¨otigt. Angenommen, ein Nutzer des Bugtrackers m¨ochte mehrere Tickets zu einem Projekt auf einmal erstellen, w¨are es von Vorteil, eine Schleife zur Verf¨ugung zu haben. M¨ochte ein Nutzer ein Ticket zu einem noch nicht existenten Pro-jekt in den Bugtracker einpflegen, ist es f¨ur ihn bequemer, wenn bei der Erstellung eines Tickets das zugeh¨orige neue Projekt mit angelegt werden kann. Dazu w¨are es vorteil-haft, die Regel nicht einfach scheitern zu lassen, sondern eine M¨oglichkeit anzubieten, das Projekt direkt an dieser Stelle zu erstellen. Hier kommt Xcore als Kontrollflusssprache ins Spiel. In Auflistung 5.4 wird die Operation createProjectAndTickets der Klasse Bug-Tracker dargestellt. Diese wird dem Bugtracker-Xcore-Modell als komplexe Operation hinzugef¨ugt.

Die Operation legt zun¨achst ein neues Projekt durch Aufruf der Regel createProject an (Zeile 6). Scheitert dies, wird gepr¨uft, ob ein Projekt mit identischem Namen bereits existiert (Zeile 10). Dies ist genau dann der Fall, wenn die Regel an ihrer NAC

Auflistung 5.4: Xcore als Kontrollflussprache zur korrekten Kombination von Projekt und Ticketerstellung

scheitert ist. Hierzu wird eine interne Xbase-Funktion verwendet, die das erste Projekt mit dem angegebenen Namen zur¨uckliefert. Da die Regel zur Erzeugung eines Projekts festlegt, dass Namen eindeutig sein m¨ussen, ist es auch das einzige Projekt dieses Na-mens. Ist die Regel anderweitig gescheitert, beispielsweise durch einen mit dem Wert null ¨ubergebenen Parameter, false zur¨uckgegeben (Zeile 12). In einem n¨achsten, aus Gr¨unden der ¨Ubersichtlichkeit nicht gelisteten Schritt, wird der Nutzer benachrichtigt, dass die Tickets in ein bereits bestehendes Projekt eingepflegt werden, sofern er an die-ser Stelle nicht widerspricht. Anschließend werden die Tickets erzeugt. Da die Titel, die Beschreibungen und die Dringlichkeit separat ¨ubergeben werden, muss zun¨achst deren Konsistenz ¨uberpr¨uft werden (Zeile 19): Sie m¨ussen die gleiche L¨ange haben. Ist dies erf¨ullt, werden die Tickets in einer Schleife erstellt (Zeilen 21-25). Dabei werden die Ein-tr¨age der Listen ihrer Position gem¨aß zu Tickets zusammengefasst. Ist dies erfolgreich, gibt die Methode truezur¨uck, andernfallsfalse. Auff¨allig ist hier, dass jede der mit Mod-Graph implementierten Operationen innerhalb eines Blocks zur Ausnahmebehandlung aufgerufen wird (try-catch-Bl¨ocke Zeilen 5-16 und 18-29). Dies ist notwendig, da jede Regel bei ihrem Scheitern eine Ausnahme ausl¨ost. Diese wird hier durch die aufrufende Methode behandelt, da sie selbst einen Wahrheitswert zur¨uckgibt.