Ein Differenzanzeige- Plugin für Klassendiagramme in...

74
Fachbereich 12 – Elektrotechnik und Informatik Fachgruppe Praktische Informatik Prof. Dr. Udo Kelter Ein Differenzanzeige- Plugin für Klassendiagramme in Fujaba Studienarbeit von Stephan Lück Pfarrwiese 12 57234 Wilnsdorf [email protected] vorgelegt bei Dr. rer. nat. Jörg Niere Siegen, im November 2004

Transcript of Ein Differenzanzeige- Plugin für Klassendiagramme in...

  • Fachbereich 12 – Elektrotechnik und Informatik

    Fachgruppe Praktische Informatik

    Prof. Dr. Udo Kelter

    Ein Differenzanzeige- Plugin für Klassendiagramme in Fujaba

    Studienarbeit

    von

    Stephan Lück

    Pfarrwiese 12

    57234 Wilnsdorf

    [email protected]

    vorgelegt bei

    Dr. rer. nat. Jörg Niere

    Siegen, im November 2004

  • So, let us not be blind to our differences - but let us also direct attention to our common interests and to the means by which those differences can be resolved.

    John F. Kennedy (1917 – 1963),

    aus einer Rede an einer amerikanischen Universität,

    10. Juni 1963

  • Zusammenfassung

    Die Entwicklung und Wartung von Software erfordert oft die Möglichkeit, Änderungen zwischen den einzelnen Versionen des Systems zu erkennen, so dass die Fortschritte des Projekts überwacht und angemessene Entscheidungen über Analyse und Design getroffen werden können. Diese Änderungen werden durch die Berechnung der Differenzen zwischen den betroffenen Dokumenten ermittelt. Neben dem Hauptproblem der Berechnung besteht jedoch ein weiteres Problem: es muss eine angemessene Anzeige der Differenzen ermöglicht werden, so dass der Entwickler die Informationen gut erkennen und verwerten kann. Da UML- Klassendiagramme bei der Modellierung von Softwaresystemen sehr häufig zum Einsatz kommen, besteht hier ein besonderer Bedarf, eine Lösung zu finden.

    Diese Ausarbeitung stellt das im Rahmen der Studienarbeit entwickelte Werkzeug DifferenceViewer zur Anzeige von Differenzen zwischen zwei Klassendiagrammen vor. Das hierzu notwendige Verfahren zur Berechnung der Unterschiede sowie dessen Implementierung liegen bereits vor. Des Weiteren sind Ansätze vorhanden, die Möglichkeiten zur grafischen Darstellung in sehr naher Anlehnung an die UML vorschlagen. Die Verwendung eines erweiterbaren UML- Werkzeuges zur Visualisierung ist daher naheliegend. Da Fujaba über geeignete Mechanismen verfügt, wurde hierfür ein Plugin entwickelt, dessen Aufbau und Funktionsumfang im Folgenden dargestellt werden soll. Als besonderer Untersuchungsgegenstand galt die Herausarbeitung generischer Lösungen zur Differenzanzeige für beliebige UML- Diagrammtypen. Somit konnten wiederverwendbare Module für zukünftige Projekte realisiert werden.

  • Inhaltsverzeichnis

    Abbildungsverzeichnis ..............................................................................................................iii

    1 Einleitung und Motivation ................................................................................................. 1

    1.1 Anwendungsszenario ................................................................................................. 1

    1.2 Mögliche Ansätze....................................................................................................... 5

    1.2.1 SCM- Systeme.................................................................................................... 5

    1.2.2 Der Model Integrator.......................................................................................... 5

    1.2.3 Fazit .................................................................................................................... 6

    1.3 Lösungsansatz ............................................................................................................ 6

    2 Verwendete Technologien, Werkzeuge und Konzepte ...................................................... 8

    2.1 Das XMI- Format und dessen Erweiterbarkeit .......................................................... 8

    2.2 Fujaba ....................................................................................................................... 10

    2.2.1 Die Visualisierung von Diagrammen............................................................... 10

    2.2.2 Der Plugin- Mechanismus................................................................................ 16

    2.2.3 Der Parser......................................................................................................... 17

    3 Differenzen zwischen UML- Klassendiagrammen .......................................................... 21

    3.1 Arten von Differenzen.............................................................................................. 21

    3.2 Integration von Differenzen in XMI ........................................................................ 22

    3.3 Grafische Darstellung von Differenzen in Klassendiagrammen.............................. 26

    4 Das Metamodell und die technische Realisierung der Differenz- darstellung................. 30

    4.1 Entwurf des Metamodells......................................................................................... 30

    4.1.1 Intuitive Ansätze .............................................................................................. 30

    4.1.2 Metamodell- Erweiterung für Differenzinformationen.................................... 33

    4.2 Visualisierung........................................................................................................... 35

    4.3 Cook- Book .............................................................................................................. 40

    5 Guided Tour ..................................................................................................................... 44

    5.1 Der Aufbau von DiffViewer .................................................................................... 44

    5.2 Die Benutzerinteraktionen........................................................................................ 46

    6 Zusammenfassung und Ausblick ..................................................................................... 53

    ANHANG A XMI.................................................................................................................... 54

    i

  • ANHANG B Die Datei plugin.xml .......................................................................................... 64

    Literatur.................................................................................................................................... 65

    ii

  • Abbildungsverzeichnis

    Abbildung 1.1: Auszug aus dem OOA- Klassendiagramm des Altsystems .............................. 2

    Abbildung 1.2: Auszug aus dem OOA- Klassendiagramm des neuen Systems ........................ 3

    Abbildung 1.3: Das Differenzdiagramm zu den Abbildungen 1.1 und 1.2 ............................... 4

    Abbildung 1.4: Das Zusammenwirken von Fujaba, DiffCalculator und DiffViewer ................ 7

    Abbildung 2.1: Die Model View Controller Architektur......................................................... 11

    Abbildung 2.2: Diagrammvisualisierung in Fujaba [Tic] ........................................................ 12

    Abbildung 2.3: Eine Klassendarstellung in Fujaba.................................................................. 13

    Abbildung 2.4: Zu Abb. 2.3 korrespondierendes Objektdiagramm......................................... 13

    Abbildung 2.5: Klassendiagramm des Differenzdiagramm- Imports ...................................... 19

    Abbildung 2.6: Der ClassDiagParser und die DiffParserFactory ............................................ 20

    Abbildung 3.1: Das Entwurfs- Klassendiagramm vor den Änderungen.................................. 28

    Abbildung 3.2: Das Entwurfs- Klassendiagramm nach den Änderungen ............................... 28

    Abbildung 3.3: Das Differenz- Diagramm............................................................................... 29

    Abbildung 4.1: Sequenzdiagramm: Laden eines Unparse- Moduls......................................... 31

    Abbildung 4.2: Generischer Ansatz zur Speicherung der Differenzinformationen ................. 34

    Abbildung 4.3: Die generischen Visualisierungs- Komponenten............................................ 36

    Abbildung 4.4: Grafische Darstellung des JComponent- Objekts eines Attributs................... 37

    Abbildung 4.5: Grafische Darstellung des Kind- JComponent- Objekts für den Datentyp eines Attributs............................................................................................................................ 37

    Abbildung 4.6: Grafische Darstellung der JComponent- Instanz eines Attributs, einschließlich Differenzinformation........................................................................................................ 38

    Abbildung 4.7: Auszug aus dem Differenz- Klassendiaramm- Metamodell ........................... 40

    Abbildung 4.8: Die Factory- Klassen....................................................................................... 41

    Abbildung 5.1: Plugin- Verzeichnisstruktur ............................................................................ 44

    Abbildung 5.2: Die Pakethierarchie von DiffViewer............................................................... 44

    Abbildung 5.3: Die Pakethierarchie von DiffExtension.jar ..................................................... 45

    Abbildung 5.4: Der Menüpunkt View Difference Class Diagram........................................... 46

    Abbildung 5.5: Dialog zur Auswahl des einzulesenden XMI- Files........................................ 46

    Abbildung 5.6: Anzeige eines Differenz- Diagramms............................................................. 47

    Abbildung 5.7: Der Menüpunkt Plug-ins Preferences............................................................. 47

    iii

  • Abbildung 5.8: Der Plug-ins Preferences- Dialog................................................................... 48

    Abbildung 5.9: Ausblenden von Update- Differenzen............................................................. 49

    Abbildung 5.10: Dialog zur Auswahl der Farben .................................................................... 49

    Abbildung 5.11: Überblick über die geänderten Differenz- Einstellungen ............................. 49

    Abbildung 5.12: Die Import- Einstellungen............................................................................. 50

    Abbildung 5.13: Ein Differenzdiagramm nach einem Autolayout .......................................... 51

    Abbildung 5.14: Ein Diagramm mit gefilterten Differenzen und geänderter Farbeinstellung 51

    Abbildung A.1: Die MOF und die vierschichtige Metamodell- Architektur [IB00] ............... 54

    Abbildung A.2: XMI und die MOF ......................................................................................... 55

    Abbildung A.3: Die relevanten XMI- Elemente und deren Beziehungen zueinander............. 56

    iv

  • 1 Einleitung und Motivation Die Komplexität großer Softwaresysteme1 erfordert einen besonders hohen Aufwand bezüglich Entwicklung und Wartung. Die für die Erstentwicklung eingesetzten Konzepte und Vorgehensmodelle wie zum Beispiel evolutionäre Softwareentwicklung, Rational Unified Process (RUP), Fujaba Unified Process (FUP) u.a. weichen in der Praxis von der idealtypisch linearen Abfolge der Entwicklungsphasen anderer Modelle (zum Beispiel Wasserfallmodell) ab. Gründe hierfür sind zum Einen die Unvorhersehbarkeit von Änderungen im Laufe der Entwicklungszeit, zum Anderen sind bei der Entdeckung von Fehlern oft Rücksprünge in frühere Phasen notwendig. In den Varianten des Unified Process werden sowohl evolutionäre Vorgehensweisen als auch eine phasenparallele Entwicklung angestrebt [Kel01]. Muss ein Softwaresystem gewartet werden, das heißt die Funktionalität muss erweitert oder Fehler müssen im Nachhinein behoben werden, so sind Maßnahmen des Reengineering anzuwenden. Diese beinhalten im schlimmsten Fall die Wiederherstellung aller notwendigen Dokumente [Nie04] (zum Beispiel Klassendiagramme), falls diese entweder nicht mehr vorhanden sind, oder deren Format inkompatibel zu den Umgebungen der Weiterentwicklung ist. Solche Tätigkeiten werden als Reverse Engineering bezeichnet. Die eigentlichen Entwicklungsarbeiten erfolgen dann wiederum gemäß bestimmten Vorgehensmodellen.

    Parallele Entwicklung sowie Reengineering erfordern in erhöhtem Maße die Möglichkeit, Unterschiede zwischen zwei Versionen von Dokumenten anzuzeigen. In der Parallelentwicklung ist dies notwendig, damit die Designer des Systems erkennen können, welche Analyseergebnisse neu hinzugekommen sind und in den Entwurf überführt werden müssen. Im Reengineering ist es notwendig, sämtliche Änderungen am Ausgangszustand der Dokumente zu überwachen und zu protokollieren, da ja die Differenz zwischen dem Ausgangszustand des Systems und der Weiterentwicklung die wichtige Grundlage zur Realisierung der neuen Systemanforderungen sind. Zum besseren Verständnis ist im folgenden Teilabschnitt ein einfaches Szenario als Beispiel aufgeführt, welches sowohl eine parallele Systementwicklung als auch Reengineering beinhaltet.

    1.1 Anwendungsszenario

    Um die Notwendigkeit zur Berechnung von Differenzen zwischen UML- Diagrammen zu veranschaulichen, sei ein praxisnahes Beispiel zur Wartung einer bestehenden betrieblichen Anwendungssoftware gegeben:

    Die GoodBuySoft GmbH, ein mittelständisches Unternehmen zur Herstellung von Software für handlesbetriebliche Zwecke (zum Beispiel Warenwirtschaftssysteme), erhält von dem Neukunden Großkauf KG, einer Lebensmittel- Großhandlung, den Auftrag, ein von einem mittlerweile insolventen Mitanbieter entwickeltes System zu erweitern. Die Implementierung erfolgte in C++. Da weder Analyse- und Entwurfsdiagramme, noch ausreichende

    1 Gemeint sind Softwaresysteme, die mit mindestens einer Million Zeilen Quellcode implementiert sind.

    1

  • EIN DIFFERENZANZEIGE- PLUGIN FÜR KLASSENDIAGRAMME IN FUJABA

    Dokumentationen vorhanden sind, werden durch werkzeuggestütztes Reengineering (durch Quellcode- Parsing) mit manueller Abstraktion (Ergänzung und Korrektur von Assoziationen, Löschung von Referenzattributen und Zugriffsmethoden etc.) objektorientierte Analyse- Klassendiagramme (OOA- Klassendiagramme) der jeweils betroffenen Systemkomponenten erzeugt und den zuständigen Analytikern überreicht. Der in diesem Beispiel betrachtete Ausschnitt betrifft den Verkauf von Waren und wird von Frau Meyer bearbeitet (siehe Abbildung 1.1).

    Abbildung 1.1: Auszug aus dem OOA2- Klassendiagramm des Altsystems

    Ein Gespräch mit dem Kunden ergab, das unter anderem folgende neue Funktionalitäten und Änderungen implementiert werden müssen:

    1. Mitarbeiter der Großkauf KG sollen jetzt auch als Kunden geführt werden, so dass sie Waren für den Eigenbedarf aus dem Sortiment erwerben dürfen.

    2. Großkauf hat vor kurzem feste Lagerorte für vorrätige Artikel eingeführt. Diese sollen in das erweiterte System eingepflegt werden können.

    3. Das Altsystem ist aufgrund eines Analysefehlers nicht großabnehmerfähig: es können keine Zusatzrabatte für die Abnahme von größeren Verpackungseinheiten vergeben werden.

    2 Fujaba unterstützt keinen eigenen OOA- Klassendiagrammtyp, sondern nur OOD- Diagramme. Daher sind in der Grafik Datentypen für Attribute angegeben. Diese sind allerdings Void, was heißen soll, dass noch keine Festlegung erfolgt.

    2

  • 1 EINLEITUNG UND MOTIVATION

    Zur Lösung des Problems soll die Verpackungseinheit in einer getrennten Klasse geführt werden. Verpackungseinheiten können zu günstigeren Preisen verkauft werden, was durch die Vergabe eines Mengenrabatts realisiert wird.

    Alle Änderungen, welche andere Komponenten, bzw. Abschnitte des Systems betreffen, werden nicht von Frau Meyer, sondern von anderen Mitarbeitern umgesetzt.

    Herr Meyer fügt nun das Attribut lagerort in die Klasse Artikel ein, entfernt das Attribut vpe und legt hierfür eine neue Klasse VPE mit den Attributen bezeichnung und mengenrabatt an. Diese Klasse wird durch eine Assoziation mit Artikel verbunden: jeder Artikel wird in einer oder in vielen VPE geliefert; jede VPE kann null oder vielen Artikel- Objekten zugeordnet werden. Zuletzt wird noch die typhierarchische Position der Klasse Mitarbeiter verändert: diese ist jetzt Subklasse von Kunde und erbt somit deren Fähigkeit, Artikel zu erwerben.

    Nach Fertigstellung oben genannte. Änderungen benachrichtigt Frau Meyer ihren für den Entwurf zuständigen Kollegen Müller. Dieser kann nun, auch wenn die komplette Systemanalyse noch nicht abgeschlossen ist, bereits die von Frau Meyer bearbeiteten Klassen in den Entwurf überführen.

    Das OOA- Klassendiagramm des neuen Systems ist in Abbildung 1.2 zu sehen:

    Abbildung 1.2: Auszug aus dem OOA- Klassendiagramm des neuen Systems

    3

  • EIN DIFFERENZANZEIGE- PLUGIN FÜR KLASSENDIAGRAMME IN FUJABA

    Herr Müller fragt sich nun, was genau von Frau Meyer am Ausgangszustand des OOA- Diagramms geändert wurde.

    Würde nun ein Werkzeug zur Berechnung und Anzeige der Unterschiede zwischen beiden Diagrammen existieren, so wäre dies eine große Hilfe für Herrn Müller: hinzugekommene Klassen (wie in diesem Beispiel VPE) und Attribute würden hervorgehoben und könnten direkt nach der Überführung in ein OOD- Diagramm verarbeitet werden. Des weiteren könnte angezeigt werden, welche Diagrammelemente gelöscht wurden (hier: das Attribut vpe aus der Klasse Artikel), was ebenfalls eine wichtige Information wäre.

    Verschiebungen von Elementen (zum Beispiel das ausschneiden einer Methode in einer Klasse und anschließende Einfügung in eine andere Klasse) und Änderungen von Meta- Attributwerten (zum Beispiel Umbenennung einer Klasse) wären ebenfalls mögliche Differenzen, die angezeigt werden sollten. Hierauf wird später noch eingegangen. Zunächst soll einmal in Abbildung 1.3 die gewünschte Darstellung der Differenzen gezeigt werden.

    Abbildung 1.3: Das Differenzdiagramm zu den Abbildungen 1.1 und 1.2

    Die geänderten Stellen in dem Klassendiagramm sind farbig markiert. Auch wenn sich die Semantik der Farben hier leicht erahnen lässt, wird diese erst in Abschnitt 3 näher erläutert. Dort werden dann auch weitere Arten von Differenzen und Möglichkeiten zu deren Anzeige

    4

  • 1 EINLEITUNG UND MOTIVATION

    vorgestellt. Bevor jedoch die Entscheidung zur Neuentwicklung eines Berechnungs- und Anzeigewerkzeuges erfolgt, sollten, wie es in Teilabschnitt 1.2 geschieht, bereits verfügbare Werkzeuge und deren Ansätze und Funktionalitäten betrachtet werden.

    1.2 Mögliche Ansätze

    Im Folgenden sollen existierende Möglichkeiten zur Berechnung und Anzeige von Differenzen diskutiert werden, da sie auf verbreiteten Werkzeugen basieren und eventuell zur Problemlösung verwendet werden könnten.

    1.2.1 SCM- Systeme

    Eine Möglichkeit wäre, zur Archivierung der Dokumente einfach Konfigurations- (und Versions-) Managementsysteme (SCM3- Systeme), wie zum Beispiel CVS, zu verwenden. Diese ermöglichen in der Regel nämlich neben der Versionierung selbst auch ein Aufzeigen von Unterschieden zwischen den Versionen. Das Problem bei der Verwendung solcher, zum Teil sogar frei erhältlichen und praxiserprobten Tools ist die Tatsache, dass sie nur mit Textdateien arbeiten und somit nur für Dokumente späterer Entwicklungsphasen wie zum Beispiel Implementierung und Integration verwendet werden können. Außerdem sind gewöhnliche Algorithmen zur Berechnung von Differenzen zwischen Texten ungeeignet, um Unterschiede zwischen Diagrammen zu berechnen, da sie nicht deren logische Struktur berücksichtigen. Es unterstützen nur wenige SCM- Systeme die Versionierung von Analyse- und Design- Dokumenten sowie deren Differenzberechnung [OWK03b].

    1.2.2 Der Model Integrator

    Das von Rational angebotene Tool Rational Rose ist ein weitverbreitetes kommerzielles UML- Werkzeug. Da Rational Rose selbst keine Differenzen zwischen Diagrammen erkennen und anzeigen kann, wurde ein Werkzeug zum Vergleichen von Diagrammen, Berechnen von Differenzen und anschließendem Mischen entwickelt: der Model Integrator. Dieser läuft außerhalb von Rational Rose und bietet zur Integration bestimmte Schnittstellen an.

    Die Benutzerschnittstelle lässt sich in drei Hauptbereiche untergliedern [RSC01]:

    1. Browser View Hier werden die Dokumente und deren Elemente hierarchisch in einer Baumstruktur dargestellt. Die Darstellung erfolgt nicht durch von Rational Rose importierte Grafikelemente (wie zum Beispiel UML- Klassen- Darstellungen), sondern überwiegend durch Text.

    2. Property View Diese Sicht liefert die Eigenschaften des aktuell in der Browser View markierten Elements.

    3 englische Bezeichnung: Software Configuration Management

    5

  • EIN DIFFERENZANZEIGE- PLUGIN FÜR KLASSENDIAGRAMME IN FUJABA

    3. Text View Hier werden die Werte für die aktuell in der Property View markierte Eigenschaft angezeigt.

    Für die Anzeige von Differenzen ist in erster Linie die Browser View relevant. Die hier gewählte Darstellung von UML- Diagrammen durch Baumstrukturen weist einen erheblichen Nachteil auf: Da Layoutinformationen in der Baumdarstellung ignoriert werden, ist es für den Entwickler schwierig, die Knoten des Baumes gedanklich den entsprechenden UML- Diagrammelementen zuzuordnen und eine bildliche Wahrnehmung der Differenzen zu erreichen [OWK03b]. Dies kann negative Auswirkungen auf die effiziente Verwendbarkeit der Informationen haben. Außerdem sind Kenntnisse über das Meta- Modell der Diagramme notwendig. Der Model Integrator kann also nur bedingt und für Szenarien mit wenig Differenzen einigermaßen effizient eingesetzt werden. Der Algorithmus zur Berechnung der Differenzen kann nicht vom Model Integrator losgelöst genutzt werden und es bestehen keine ausreichenden Adaptionsmöglichkeiten zur Visualisierung.

    1.2.3 Fazit

    Aus 1.2.1 und 1.2.2 ergibt sich, dass sowohl gewöhnliche SCM- Systeme als auch der Model- Integrator keine ausreichende Eignung zur Berechnung und Darstellung von Differenzen haben. Diese Tatsache liefert die Motivation zu der Neuentwicklung eines Differenzberechnungs- und eines Differenzanzeige- Werkzeuges. Ersteres wurde durch den DiffCalculator umgesetzt, letzteres durch den mit dieser Studienarbeit entwickelten DiffViewer.

    1.3 Lösungsansatz

    Im Rahmen einer Diplomarbeit wurde das Werkzeug DiffCalculator zur Berechnung von Differenzen zwischen generell beliebigen UML- Diagrammen entwickelt. Als besonderer Entwurfsaspekt galt es hier, einen Algorithmus zu entwickeln, der für die Identifikation von korrespondierenden Diagrammelementen auf die Verwendung von persistenten Objektidentifizierern verzichtet, da diese unter gewissen Umständen (wie zum Beispiel Reengineering) verloren gehen können. Nähere Erläuterung können [Weh04] entnommen werden.

    Die zu vergleichenden Dokumente liegen im XMI- Format vor, über das in Anhang A ein grober Überblick vermittelt wird. Für die Konfiguration des Werkzeugs bezüglich Diagrammart und unterschiedlicher XMI- Versionen und Ausprägungen wurde ein XML- basiertes Format entworfen.

    Das im Zusammenhang mit dieser Ausarbeitung entwickelte Anzeigewerkzeug DiffViewer bezieht sich auf den Output von DiffCalculator. Auf den Entwurf von DiffViewer wird in Abschnitt 4 vertiefend eingegangen. Da jedes der beiden Tools in einem eigenen Projekt

    6

  • 1 EINLEITUNG UND MOTIVATION

    entwickelt wurde, ist eine Umsetzung durch zwei getrennte Fujaba- Plugins erfolgt, auch wenn nur der Einsatz beider Plugins in kombinierter Form Sinn macht. Da DiffCalculator werkzeugunabhängig anwendbar sein soll, existiert auch eine völlig isoliert lauffähige Version.

    Das Zusammenwirken von Fujaba, DiffCalculator und DiffViewer kann schematisch veranschaulicht werden:

    DiffViewer DiffCalculator

    Fujaba

    integriert integriert

    Abbildung 1.4: Das Zusammenwirken von Fujaba, DiffCalculator un

    Durch die dünnen, grauen Pfeile werden die von Fujaba veranlassten Sveranschaulicht. Die dicken schwarzen Pfeile hingegen modellieren den In

    Die Erzeugung der beiden XMI- Dokumente (Dok. 1 und Dok. 2) erselbst4. Da XMI in Fujaba nicht das Standardformat zur Speicherung vomuss ein Export veranlasst werden. Das DiffCalculator- Plugin wird vonBenutzerinteraktionen gesteuert. Es kann zwei Fujaba- XMI- kompeinlesen, die Differenzen berechnen, ein Vereinigungsdokument eentsprechenden Differenzinformationen an geeigneten Stellen in dem Verablegen. Dieses Vereinigungsdokument fasst sämtliche Elemente dezusammen und markiert auf geeignete Weise die Differenzen; es ist danDiffViewer- Plugin. Dieses wird ebenfalls von Fujaba gemäß Begesteuert. Beim Einlesen werden die XMI- Elemente des VereiniguInstanzen des Differenz- Meta- Modells abgebildet und die Visualisieruvom DiffViewer gesteuert und durch Fujaba realisiert.

    4 Genauer gesagt werden die Dokumente durch ein neu entwickeltes Plugin, das den ExpPoseidon- XMI umsetzt, erzeugt. Es könnten also theoretisch auch von Poseidon erzeugtewerden

    7

    Visualisierung

    Dok. 1

    Dok. 2

    Vereingung

    erzeugt

    d DiffV

    teuerunformati

    folgt dun Doku Fujabaatible rzeugen

    einigunr Basi

    n der Innutzerinngsdokng wir

    ort von D Dokume

    realisiert

    Steuerung

    Informationsfluss

    iewer

    gsaktivtäten onsfluss.

    rch Fujaba menten ist,

    gemäß den Dokumente und die

    gsdokument sdokumente put für das teraktionen uments auf d hierdurch

    iagrammen in nte verwendet

  • 2 Verwendete Technologien, Werkzeuge und Konzepte In diesem Abschnitt soll ein Überblick über die von DiffViewer genutzten Technologien, Werkzeuge und Konzepte vermittelt werden. Da bereits im vorherigen Abschnitt der DiffCalculator für den Kontext dieser Ausarbeitung hinreichend dargestellt wurde, soll nun ein Überblick über die Erweiterbarkeit des XMI- Formats und das UML- Werkzeug Fujaba und dessen besondere Eignung zur Integration von DiffViewer vermittelt werden. Anschließend wird die Funktionsweise des verwendeten SAX- Parsers in rudimentärer Form erläutert.

    2.1 Das XMI- Format und dessen Erweiterbarkeit

    Wie schon erwähnt, legt DiffCalculator die Differenzinformationen in der Transportdatei für die Klassendiagramme ab. Dies erfordert eine Erweiterbarkeit des Austauschformats. XMI bietet die Möglichkeit, dessen DTD um beliebige Elementtypen zu erweitern [JS02]. Dieser Abschnitt veranschaulicht anhand eines Beispiels, wie das XMI- Metamodell erweitert werden kann und wie dies von DiffCalculator umgesetzt wird. In Anhang A ist eine kurze Einführung in XMI sowie eine Darstellung der für DiffViewer relevanten Elementtypen zu finden.

    Erweiterungen von XMI werden durch den Elementtyp XMI.extension umgesetzt. Dieser hat den Inhaltstyp ANY und darf potentiell beliebige XML- Elementstypen enthalten. Welche Elemente letztendlich tatsächlich eingefügt werden dürfen, muss in einer Erweiterungs- DTD festgelegt werden. Diese kann entweder extern abgelegt oder in das XMI- Dokument eingebettet werden. Da die Erweiterungs- DTD für die Differenzinformationen sehr kompakt ist, wird diese grundsätzlich vom DiffCalculator in das XMI- Dokument eingebettet. Dies erfolgt direkt nach der - Processing Instruction am Kopf des Dokuments. Die XMI.extension- Elemente dürfen überall dort stehen, wo das XMI- Metamodell (also die XMI- DTD) sie zulässt. Dies wären zum Beispiel sämtliche UML- Elementtypen.

    Die von DiffCalculator genutzte Erweiterungs- DTD sieht wie folgt aus:

    | structure | move))>

    version1 CDATA #IMPLIED>

    8 value0 CDATA #IMPLIED

  • 2 VERWENDETE TECHNOLOGIEN, WERKZEUGE UND KONZEPTE

    value1 CDATA #IMPLIED>

    idref0 IDREF #IMPLIED

    idref1 IDREF #IMPLIED>

    version1 (true|false) #REQUIRED>

    ]>

    Die genaue Bedeutung der Elementtypen wird in Abschnitt 3 deutlich werden, da dort auf die verschiedenen Arten von Differenzen eingegangen wird. Anhand eines Beispiels für eine strukturelle Differenz (das heißt ein UML- Diagrammelement existiert in dem einen, jedoch nicht in dem anderen Dokument) soll veranschaulicht werden, wie die Differenzinformationen in das Vereinigungsdokument eingebettet werden:

    9

  • EIN DIFFERENZANZEIGE- PLUGIN FÜR KLASSENDIAGRAMME IN FUJABA

    Gegeben sei also das Attribut vpe der Klasse Artikel aus dem bisherigen Beispiel des ursprünglichen Klassendiagrams (siehe Abbildung 1.1). Dieses Attribut ist im Zuge der Weiterentwicklung des Systems gelöscht worden. Wie zu sehen ist, wird das Element vom Typ XMI.extension direkt hinter dem öffnenden Tag des betroffenen Elements (hier: die UML:Attribute- Instanz vpe) eingefügt. Die durch die Löschung entstandene strukturelle Differenz wird durch den Elementtyp structure angegeben, welcher zwei bool’sche Attribute beinhaltet, die das Vorhandensein von Elementen in den jeweiligen Ursprungsdokumenten angeben. Es ist leicht zu erkennen, dass das Attribut vpe in Dokument 0 vorhanden, in Dokument 1 jedoch nicht vorhanden ist. Durch den Elementtyp originalID kann die XMI- ID des jeweiligen Ausgangsdokuments angegeben werden.

    2.2 Fujaba

    Das UML- Werkzeug Fujaba (ein Akronym für „From UML to Java And Back Again“) ist ein im Zusammenhang mit einer Projektgruppe an der Universität Paderborn 1998 entstandenes CASE- Tool, das von der bundesweit zahlreiche Mitglieder umfassenden Fujaba Group laufend weiterentwickelt wird. Es ist selbst in Java implementiert und sowohl in ausführbarer Form als auch im Quellcode frei erhältlich5. Neben zahlreichen Features wie Reengineering- Unterstützung und Entwurfsmustererkennung6 [Nie04], Unterstützung didaktischer Tätigkeiten7 [NS02], Meta- CASE, quellcodefreier Programmierung durch Activity Diagrams [UP02] und anderen, bietet Fujaba mit seinem Plugin- Mechanismus eine einfache Möglichkeit, weiterentwickelt zu werden, was gerade für die Integration von zusätzlichen Werkzeugen wie DiffViewer sehr nützlich ist. Der Mechanismus wird in Teilabschnitt 2.2.2 vorgestellt.

    2.2.1 Die Visualisierung von Diagrammen

    Nachdem in Abschnitt 2.1 die verwendete Möglichkeit zum Transport und zur persistenten Speicherung von Diagrammen dargestellt wurde, soll nun deren Anzeige durch das Werkzeug erläutert werden. Ein wichtiger Gesichtspunkt ist auch hierbei, wie es im Allgemeinen bei der Entwicklung von komplexeren Anwendungen sein sollte, die Trennung zwischen Anwendungslogik und Benutzerschnittstelle. Problematisch ist, dass die Visualisierung von Diagrammen immer ein korrektes Abbild der internen Speicherstruktur des Modells (zum Beispiel: UML- Klassendiagramm) liefern muss. Die initiale grafische Darstellung von Diagrammen ist einfach: es müssen nur die Meta- Attributwerte entsprechend auf die Grafikelemente abgebildet werden. Dies erfolgt in Fujaba durch so genannte Unparse- Module.

    In der initialen Phase (das heißt bei der Erzeugung eines Logik- Objekts) sorgt das zuständige Unparse- Modul für die Visualisierung. Hierfür ist jeder Diagramm- Metamodell- Klasse (zum Beispiel UMLClass, UMLMethod, UMLAttribute etc.) eine entsprechende Unparse- 5 www.fujaba.de 6 FUJABA Tool Suite RE 7 FUJABA life³; http://life.upb.de/

    10

  • 2 VERWENDETE TECHNOLOGIEN, WERKZEUGE UND KONZEPTE

    Modul- Klasse zuzuordnen. Deren Name ist so zu wählen, dass dieser dem Namen der Logik- Klasse entspricht, jedoch mit vorangestelltem „UM“. Ausnahmen gibt es bei Meta- Modell- Klassen, deren Namen ohnehin mit „UM“ beginnt: dort darf nur ein führendes „UM“ existieren (zum Beispiel: das Unparse- Modul zu UMLClass darf UMClass, nicht jedoch UMUMLClass heißen). Sämtliche Unparse- Modul- Klassen müssen sich im Unterpaket unparse des Pakets der korrespondierenden Meta- Modell- Klassen befinden. Diese Vorschrift ist im Fujaba- Kern „hartverdrahtet“ und nicht dynamisch änderbar.

    Werden Änderungen an bereits initialisierten Objekten vorgenommen, verhält es sich komplizierter: Ändern sich Meta- Attributwerte direkt in der Logik (wie zum Beispiel der Name einer Methode, nach einer Änderung durch einen speziellen Dialog), so muss diese Änderung unmittelbar in der grafischen Darstellung nachgezogen werden. Bei Änderungen des Modells an dessen grafischer Darstellung (zum Beispiel: Benutzer löscht Attribut direkt in der Klassendarstellung) muss diese sofort auch in der Logik vorgenommen werden. Werden solche Veränderungen am Modell nicht unmittelbar an der jeweils anderen Schicht angepasst, entstehen Inkonsistenzen zwischen Darstellung und interner Speicherung von Diagrammen. Eine Möglichkeit zur Lösung des Problems wäre, bei jeder Änderung eine vollständige Neuabbildung der Logik auf die Darstellung beziehungsweise umgekehrt vorzunehmen. Dies wäre jedoch in keiner akzeptablen Laufzeit zu lösen. Die Model View Controller Architektur (MVC) bietet einen weitaus besseren Ansatz. Sie ermöglicht die Umsetzung verschiedener Darstellungen von ein und derselben logischen Struktur. Das wohl anschaulichste Beispiel für den Einsatz von MVC- Architekturen ist die Darstellung von Statistiken sowohl durch Tabellen, als auch durch sonstige Diagrammarten (zum Beispiel: Balkendiagramm, Kuchendiagramm, etc.). Ziel ist es hierbei, zum Einen eine bidirektionale Beziehung zwischen Logik und GUI- Instanzen zu schaffen, zum Anderen Benachrichtigungen über jeweilige Veränderungen zu realisieren.

    Meta- Mode

    Instanz

    Da es sich bei dBlick auf deren Bsind Komponentesind die Schnittsdas Modell (MoKonnektoren hab

    Logik- Änderungen

    Grafische

    Darstellung Controller ll-

    Abbildung 2.1: Die Model Vi

    em MVC- Konzept um eine Aestandteile vorgenommen werdn und Konnektoren [GS94]. Ktellen zwischen diesen Moduledel), die Sicht (View) und deen die Aufgabe, den Informa

    11

    Benutzer- Änderungen

    ew Controller Architektur

    rchitektur handelt, soll ein etwas genauerer en: generelle Bestandteile einer Architektur omponenten sind Module und Konnektoren n. Auf MVC übertragen bedeutet dies, dass r Controller die Komponente darstellt. Die tionsfluss zwischen den Komponenten zu

  • EIN DIFFERENZANZEIGE- PLUGIN FÜR KLASSENDIAGRAMME IN FUJABA

    ermöglichen. Dies erfolgt durch eine Implementierung des Observer- Design- Patterns8 nach [GHJV95], so dass dessen Instanzen die Konnektoren sind. Der PropertyChange- Mechanismus liefert eine Implementierungs- Möglichkeit hierfür in Java [Krü00].

    Abbildung 2.2: Diagrammvisualisierung in Fujaba [Tic]

    In der initialen Phase erfolgt die Visualisierung von Diagrammen alleine durch die Unparse- Module. Unter dem Begriff des Unparsings kann im Allgemeinen das Abbilden eines im Arbeitsspeicher vorliegenden Syntaxgrafen auf eine sichtbare Form (Dokument, grafische Präsentation) verstanden werden. Also muss in den Unparse- Modulen festegelegt werden, durch welche grafische Darstellung die entsprechende Meta- Modellinstanz angezeigt werden soll.

    Wird eine Metamodell- Instanz später geändert, so wird dies nicht durch ihr Unparse- Modul realisiert. Jedes Unparse- Modul erzeugt so genannte Updater. Durch sie wird der PropertyChange- Mechanismus umgesetzt. Jede Metamodell- Instanz erhält einen PropertyChangeSupport, das heißt sie meldet jede Attributänderung einem oder mehreren PropertyChangeListener- Objekten, die wiederum Änderungen an den entsprechenden GUI- Elementen vornehmen. Die Eigenschaft eines PropertyChangeListeners wird von jeder Updater- Klasse durch die Implementierung der Schnittstelle PropertyChangeListener erworben. Wird dessen propertyChange- Methode aufgerufen, erfolgt eine Abbildung der neuen Logik- Attributwerte auf die grafische Präsentation.

    Ungeklärt ist bislang, wie die jeweiligen GUI- Elemente realisiert und angesprochen werden. Abbildung 2.2 kann entnommen werden, dass Klassen aus dem Standard- Paket javax.swing.* verwendet werden. Doch eine direkte Initialisierung der Swing- Elemente in den Unparse-

    8 das Entwurfsmuster „Beobachter“

    12

  • 2 VERWENDETE TECHNOLOGIEN, WERKZEUGE UND KONZEPTE

    Modulen würde im Allgemeinen zu folgendem Problem führen: sollen Logik und Präsentation aneinander anpassbar sein, so besteht die Notwendigkeit einer bidirektionalen Beziehung zueinander, denn eine Änderung von Attributwerten auf der einen Seite muss ja auch auf die anderen Seite übertragen werden. Als Lösung wird jedem Swing- Element ein so genannter Fujaba- Swing- Adapter (FSA) vorgeschaltet. Alle wichtigen Swing- Elemente haben eine entsprechende FSA- Klasse, die den gleichen Namen hat, jedoch statt mit „J“ mit „FSA“ beginnt (zum Beispiel JPanel hat den Fujaba- Swing- Adapter FSAPanel). Somit können Änderungen an der grafischen Präsentation durch den Benutzer (zum Beispiel: Änderung eines Klassen- Namens) auf die Logik übertragen werden. Die genaue Funktionsweise der FSA- Objekte ist hier jedoch irrelevant, da Differenzdiagramme ein Abbild einer im voraus geleisteten Berechnung sind, und somit nicht von außen änderbar sein sollen. Sie werden im Prinzip so wie die eigentlichen Swing- Klassen instanziiert und gehandhabt. Dies erfolgt in den Unparse- Modulen. Die wichtigste Methode in einem Unparse- Modul heißt create() und wird zur initialen Erzeugung und Visualisierung eines Diagrammelements aufgerufen. Zur besseren Veranschaulichung soll die Funktionsweise der Diagrammvisualisierung anhand eines Beispiels für UML- Klassendiagramme erläutert werden:

    Gegeben sei folgende Klasse, als Klassendiagramm in Fujaba dargestellt:

    Abbildung 2.3: Eine Klassendarstellung in Fujaba

    Hierzu existiert zur Laufzeit folgendes Metamodell als Objektdiagramm:

    Abbildung 2.4: Zu Abb. 2.3 korrespondierendes Objektdiagramm

    In der feingranulare Metamodellierung werden also für Klassen, Attribute und Datentypen die Metamodell- Klassen UMLClass, UMLAttr und UMLBaseType verwendet. Deren Attributwerte müssen nun durch die Auswahl geeigneter FSA- Komponenten grafisch dargestellt werden und durch die Erzeugung und Zuordnung von Updatern muss die Konsistenz zwischen Modell und Metamodell gewährleistet werden. Beides geschieht in dem

    13

  • EIN DIFFERENZANZEIGE- PLUGIN FÜR KLASSENDIAGRAMME IN FUJABA

    betroffenen Unparse- Modul. In diesem Beispiel soll das Unparse- Modul zu UMLAttr betrachtet werden, also die Klasse UMAttr, die sich relativ zu den Metamodell- Klassen im Unterpaket unparse befindet.

    Anhand der Methode create() des Unparse- Moduls UMAttr soll die Implementierung von Updatern und FSA- Komponenten veranschaulicht werden. Dabei wird nicht der komplette Code erläutert, sondern nur exemplarische Auszüge. Zunächst soll die Schnittstelle betrachtet werden:

    public FSAObject create (FSAObject parent, LogicUnparseInterface incr)

    {

    Die Methode create() erzeugt und liefert das FSA- Objekt, welches das entsprechende Logik- Attribut grafisch darstellt. In diesem Fall wäre das ein Panel, auf dem die Sichtbarkeit, der Name, der Typ und ein eventueller Initialwert des Attributs platziert würde. Die Fujaba- Klassenbibliothek bietet hierzu die Klasse FSAUnderlinedObject an. Diese ist direkt von FSAPanel abgeleitet und stellt ein unterstreichbares Panel dar. Die Unterstreichbarkeit wird für statische Attribute benötigt.

    Da die verschiedenen Panel einer Klasse, die zur Darstellung von Attributen dienen, in das entsprechende Panel der Klassendarstellung eingefügt werden müssen9, und auch diese Panel selbst wieder aus FSA- Objekten bestehen kann, ergibt sich eine hierarchische Baumstruktur aus FSA- Objekten. Somit muss bei dem Aufruf von create() die entsprechende Vater- FSAObject- Instanz angegeben werden, damit eine korrekte Zuordnung erfolgen kann. Dies geschieht durch den Parameter parent.

    Der zweite Parameter incr beinhaltet eine Referenz auf das bezogene Logik- Objekt. Sämtliche Objekte der UML- Metamodells implementieren in Fujaba das LogicUnparseInterface. In diesem Falle würde eine Instanz von UMLAttr übergeben. Also erfolgen folgende Deklarationen und Zuweisungen:

    UMLAttr attr = (UMLAttr) incr;

    FSAUnderlinedObject mainPanel = null;

    9 Dies gilt analog auch für die Panel der Methoden, Stereotypen etc.

    14

  • 2 VERWENDETE TECHNOLOGIEN, WERKZEUGE UND KONZEPTE

    Nach der Instanziierung von mainPanel werden die FSA- Komponenten für die Sichtbarkeit, den Namen, die Wertzuweisung etc. für die Darstellung des UMLAttr- Objekts erzeugt. Für den Attributnamen sieht die Implementierung wie folgt aus:

    FSATextFieldLabel nameField =

    new FSATextFieldLabel (incr, "nameUpdate", mainPanel.getJComponent());

    Es wird also ein Objekt der Klasse FSATextFieldLabel erzeugt. Hierbei handelt es sich um eine editierbare Komponente, denn der Attributwert soll ja direkt im UML- Diagramm geändert werden können. An den Konstruktor von FSATextFieldLabel wird das Logikobjekt incr, ein eindeutiger Name („nameUpdate“) und die Referenz auf die Swing- Komponente von mainPanel übergeben.

    Anschließend erfolgt die Erzeugung und die Zuweisung des Updaters:

    nameField.addToUpdater (nameField.createDefaultUpdater());

    }

    Updater können beliebigen Code ausführen (zum Beispiel das Ein- oder Ausblenden von grafischen Elementen) [Tic]. Diese Ausführungen werden durch PropertyChangeEvents angestoßen. In diesem Beispiel wird ein Default- Updater verwendet, der durch die von FSAObject geerbte Factory- Methode createDefaultUpdater() erzeugt wird. Jede FSA- Komponente hat einen solchen Default- Updater, der Standardfunktionalitäten wie zum Beispiel das Ändern von Textinhalten in der grafischen Darstellung, wenn sich ein Logik- Attribut ändert.

    Zwei wichtige Operationen werden sind in den Updatern implementiert:

    1. public Object translateFsaToLogic (Object data)

    2. public Object translateLogicToFsa (Object data)

    Beide Operationen nehmen durch data die Änderungsdaten entgegen. Die Operation translateFsaToLogic überträgt Änderungen in der grafischen Darstellung auf die entsprechenden Logik- Objekte während Operation 2 in der entgegengesetzten Richtung wirkt: sie bildet Änderungen in der Logik auf die grafische Präsentation ab. Für die Entwicklung von DifferenceViewer wäre selbstverständlich nur translateLogicToFsa() relevant, da beim Einlesen von Diagrammen zwar Logikattribute gesetzt werden müssen,

    15

  • EIN DIFFERENZANZEIGE- PLUGIN FÜR KLASSENDIAGRAMME IN FUJABA

    jedoch eine Editierbarkeit der Diagramme ausgeschlossen werden soll. In Abschnitt 4 wird das Visualisierungskonzept von DiffViewer vorgestellt, das Updater durch einen einfacheren Mechanismus ersetzt.

    2.2.2 Der Plugin- Mechanismus

    Fujaba ist ein Werkzeug, das ursprünglich monolithisch entwickelt wurde, das heißt es gab nur einen großen Kern, der sämtliche Funktionalität beinhaltete. Da jedoch die Implementierungssprache Java seit Version 1.1 über den Reflection- Mechanismus [Krü00] verfügt, kann seit dem ausführbarer Code in Anwendungen eingebunden werden, auch wenn dieser zur Compile- Zeit nicht bekannt ist. Somit bot sich die Möglichkeit, ein Werkzeug mit einem minimalen Kern zu entwickeln, das nur solche Funktionalitäten enthält, die der Anwender auch wirklich benötigt. Außerdem könnten hierdurch ständig neue Funktionalitäten ergänzt werden, ohne dass der Kern geändert werden muss. Der Fujaba- Plugin- Mechanismus ermöglicht eine solche dynamische Integration von zusätzlichem Code. Daher soll dieser im Folgenden näher dargestellt werden, da er die Basis zur Einbindung von DiffViewer ist. Bislang sind noch einige spezielle Anwendungsfunktionen im Fujaba- Kern „hartverdrahtet“ (wie zum Beispiel der Entwurf von Klassendiagrammen), jedoch konzentrieren sich laufende Entwicklungstätigkeiten auf die Schaffung eines minimalen Kerns10. Dieser Anschnitt skizziert grob den generellen Aufbau eines Fujaba- Plugins, so dass anschließend vorab eine Übersicht über die Bestandteile von DiffViewer geliefert werden kann. Einzelheiten können [Wen] und [Alp02] entnommen werden.

    Im Installationsverzeichnis von Fujaba befindet sich ein Verzeichnis mit dem Namen plugins. Die zu integrierenden Plugins müssen sich in diesem Verzeichnis befinden, damit sie vom Plugin- Manager gefunden werden. Ein Plugin besteht aus einem Verzeichnis, in dem sich die notwendigen Dateien befinden. Diese sind in drei Kategorien zu untergliedern:

    1. JAVA- Bytecode, als jar- File(s)

    2. die Datei plugin.xml

    3. die Datei stable.xml

    1. JAVA- Bytecode

    Um die Funktionalität von Fujaba zu erweitern, muss zusätzlicher Code an den Kern angebunden werden. Dieser wird durch ein JAVA- Archiv (jar- File) an Fujaba übergeben. Damit jedoch Instanzen der darin enthaltenen Klassen erzeugt werden können, muss Fujaba zumindest die Schnittstellen einer der im Plugin enthaltenen Klassen kennen, beziehungsweise dem Plugin- Entwickler vorgeben, welche Schnittstellen er zu implementieren hat. Hierzu gibt es zwei Möglichkeiten: entweder kann das Interface 10 Die Festlegung, welche Funktionalitäten zum minimalen Kern gehören sollten, dürfte, analog zu den Betriebssystemen, nicht trivial sein, da es hierzu unterschiedliche Auffassungen geben könnte.

    16

  • 2 VERWENDETE TECHNOLOGIEN, WERKZEUGE UND KONZEPTE

    de.upb.lib.plugins.PluginInterface implementiert, oder die abstrakte Klasse de.upb.lib.plugins.AbtractPlugin abgeleitet werden. Im DiffViewer- Plugin leitet die Klasse DifferenceViewerPlugin aus dem Paket de.usi.diffview (siehe Abbildung 5.2, Guided Tour) die Klasse AbtractPlugin ab. Zur Anbindung zusätzlicher Bibliotheken können diese in einem Unterverzeichnis libs eingefügt werden. Für den DiffViewer selbst wurden sämtliche Bytecode- Dateien in das Archiv DifferenceViewerPlugin.jar gepackt. Da Bestandteile des Plugins mit dem Ziel zur Wiederverwendbarkeit für beliebige Diagrammtypen entwickelt wurden, werden sie vom eigentlichen DiffViewer- Code abgespalten und in einem eigenen Jar- Archiv DiffExtension.jar im Verzeichnis libs abgelegt.

    2. plugin.xml

    Hier werden generelle Eigenschaften des Plugins beschrieben, so dass diese vom Fujaba Plugin- Manager eingelesen und verarbeitet werden können. Die Beschreibung erfolgt in XML, gemäß einer vorgegebenen DTD [Alp02]. Beispiele für Inhalte von plugin.xml (Quellcode s. Anhang B), mit nachgestellten XML- Elementtypen:

    - Name des Plugins:

    - Name derjenigen Klasse, die das PluginInterface implementiert: , gesetzt in dessen Attribut pluginClass)

    - Eventuelle Erweiterung des Klassenpfades um zusätzliche Bibliotheken (hier: im libs- Verzeichnis): und

    - Textuelle Beschreibung des Plugins: und dessen Unterelemente

    3. stable.xml

    Diese Datei beschreibt, um welche Interaktionselemente das GUI von Fujaba erweitert werden soll und welche Aktionen bei deren Betätigung ausgeführt werden müssen. Zuerst werden die Aktionen durch Angabe der entsprechenden ActionHandler definiert (zum Beispiel Anlegen eines neuen Klassendiagramms). Dies sind Klassen innerhalb des Plugins, welche die AbstractAction ableiten. Anschließend werden die Interaktionselemente (wie zum Beispiel MenueItems, Pop- Up- Menues, der ToolBar) beschrieben. Jeder Aktionsquelle wird durch eine XML- idref ein oder mehrere der definierten ActionHandler zugewiesen. Für die ActionHandler wird das Unterpaket actions angelegt. Es ergibt sich die Verzeichnisstruktur aus Abbildung 5.1 (siehe Guided Tour).

    2.2.3 Der Parser

    Java unterstützt zur Verarbeitung von XML- Dokumenten zwei verschiedene Parser- Modelle. Zum Einen das Simple API for XML (SAX), zum Anderen das Document Object Model (DOM) [RRZN04]. Da DOM ein komplettes Abbild des eingelesenen XML- Dokuments durch Erzeugung eines Syntaxbaumes im Arbeitsspeicher erzeugt, ist dieser

    17

  • EIN DIFFERENZANZEIGE- PLUGIN FÜR KLASSENDIAGRAMME IN FUJABA

    Parser- Typ mächtiger als der SAX- Parser11, welcher lediglich das Dokument sequenziell durchläuft und über Ereignisse mit der Anwendung kommuniziert. Für die Entwicklung des DiffViewer wurde jedoch der SAX- Parser verwendet, da dieser für die Problemstellung besser geeignet zu sein scheint: DiffViewer soll Dokumente einlesen und direkt auf das UML- Metamodell für Klassendiagramme in Fujaba abbilden. Daher könnte die Erzeugung der DOM- Baumstruktur des Dokuments störend sein, da diese nach dem Einlesen komplett durchlaufen werden müsste. Das Vorhandensein der Baumstruktur des Dokuments würde jedoch auch einen Vorteil bieten: liest zum Beispiel ein SAX- Parser gerade ein Attribut einer Klasse ein, so werden Name, Sichtbarkeit etc. per Ereignis gemeldet. Werden jedoch zum Beispiel Datentypen mit XML- IDREFs referenziert, weil sie an anderer Stelle im Dokument definiert sind (so wie es bei XMI der Fall ist), so ist zu diesem Zeitpunkt die Erzeugung der Logik- Instanz des Attributs unvollständig, denn der Typ ist ja nicht bekannt. Daher müssen bei der Verwendung des SAX- Parsers öfters zumindest Teile das Dokumentbaumes (wie hier die Zuordnung einer Typ- ID zu einem Attribut) während des Parsens zwischengespeichert werden, so dass „unvollständige“ Metamodellinstanzen nach dem Einlesen des kompletten Dokuments um ihre noch fehlenden Bestandteile ergänzt werden können. Da es schwierig abzusehen ist, ob nun der SAX- oder der DOM- Parser letztendlich ein effizienteres Einlesen der XMI- Dokumente ermöglicht, wurde aufgrund seiner Schnelligkeit, seines niedrigeren Speicherverbrauchs und seiner einfachen Verwendbarkeit der SAX- Parser zur Implementierung von DiffViewer verwendet. Das Java Software Development Kit (SDK) liefert ein API für beide Parsertypen. Da Fujaba selbst jedoch die Xerces- Programmierschnittstelle von Apache12 nutzt, greift hierauf auch DiffViewer zurück.

    Das Klassendiagramm aus Abbildung 2.5 liefert eine Übersicht über den Diagramm- Import von Diffviewer.

    11 Genauer gesagt ist DOM eine Erweiterung von SAX, da es zum Einlesen des Dokuments in den Speicher den SAX- Parser nutzt. 12 www.apache.org

    18

  • 2 VERWENDETE TECHNOLOGIEN, WERKZEUGE UND KONZEPTE

    Abbildung 2.5: Klassendiagramm des Differenzdiagramm- Imports

    Die Klasse AbstractDiffParser befindet sich im Paket de.uni.diffextension.parser, die Super- Klassen für die Handler DefaultDiffHandler, AbstractDiffContentHandler und AbstractDiffErrorHandler befinden sich in dessen Unterpaket handler. Die Klasse org.xml.sax.helpers.DefaultHandler ist eine Adapterklasse, die alle wichtigen Handlerschnittstellen (ContentHandler, ErrorHandler, DTDHandler, EntityResolver) leer implementiert. Daher ist sie Superklasse sowohl des verwendeten AbstractDiffContentHandler als auch des AbstractDiffErrorHandler. Deren Unterklassen ClassDiagContentHandler und ClassDiagErrorHandler sind die eigentlichen Handler von DiffViewer. Sie sind beide im Paket de.usi.diffview.parser.handler implementiert. Die abstrakte Klasse AbstractDiffParser ist für die Erzeugung des org.xml.sax.XMLReader- Objekts und somit auch für die Zusammenführung der Handler zuständig. Aus ihr ist dann die konkrete Parserklasse abzuleiten. In diesem Falle wäre dies de.usi.diffview.parser.ClassDiagParser.

    19

    Die Erzeugung der Differenzdiagrammelemente beim Einlesen des XMI- Dokuments erfolgt ereignisgesteuert im ClassDiagContentHandler. Die konkrete Realisierung ist zu komplex, um hier dargestellt zu werden; sie kann jedoch dem Quellcode und dessen Dokumentation entnommen werden. Allgemein muss der ContentHandler dafür sorgen, dass wichtige Ereignisse (zum Beispiel: ein öffnendes Tag vom Typ UML:Class wurde erreicht) so verarbeitet werden, dass korrekte Meta- Modellinstanzen erzeugt werden. Oft müssen hierzu, wie schon erwähnt, Daten zur späteren Verarbeitung zwischengespeichert werden.

  • EIN DIFFERENZANZEIGE- PLUGIN FÜR KLASSENDIAGRAMME IN FUJABA

    Interessant ist, wie der SAX- Parser zu erzeugen ist. Neben der Möglichkeit, zuerst die beiden Handler- Instanzen, dann den ClassDiagParser zu erzeugen und anschließend die Handler dem Parser zu übergeben wäre eine Möglichkeit. Etwas einfacher wäre jedoch die Verwendung einer Factory, so wie es in DiffViewer umgesetzt wird:

    Abbildung 2.6: Der ClassDiagParser und die DiffParserFactory

    Die abstrakte Klasse DiffParserFactory befindet sich im Paket de.usi.diffview.parser. Durch Aufruf der statischen Methode createClassDiagParser() wird eine Instanz von ClassDiagParser einschließlich der Handler erzeugt. Vor dem Aufruf können Features gesetzt werden, die der Parser unterstützen soll: mit setNoValidation() kann bestimmt werden, ob der Parser anhand einer externen DTD, die im XMI- Strom angegeben ist, validieren soll; mit setPrintParserOutput() kann festgelegt werden, ob während des Parse- Vorganges Ausgaben des Parsers in den Standard- OutputStream ausgegeben werden sollen. Nähere Erläuterungen hierzu erfolgen im Abschnitt 5.

    Sämtliche herstellerspezifischen SAX- Features können durch die Methode setFeature() gesetzt werden. Hierbei muss der URI des Features als String übergeben werden. Mit getFeature() kann überprüft werden, ob ein bestimmtes Feature unterstützt wird. Soll jetzt ein XMI- Dokument eingelesen werden, ist die von AbstractDiffParser geerbte Methode parse() aufzurufen und der Dateiname als String zu übergeben.

    20

  • 3 Differenzen zwischen UML- Klassendiagrammen In Abschnitt 2.1 wurde bereits anhand eines Beispiels gezeigt, wie eine bestimmte, durch DiffCalculator berechnete Differenzart in ein XMI- Dokument eingebettet wird. Dieser Abschnitt soll alle Arten von Differenzen zwischen zwei Diagrammen eines Typs vorstellen und einen Ansatz zu deren Integration in XMI- Dokumente liefern.

    3.1 Arten von Differenzen

    Allgemein sind mit dem Begriff der Differenz Unterschiede zwischen UML- Diagrammen gemeint. Diese entstehen durch bestimmte Benutzeraktionen auf dem Ursprungsdokument und können anhand deren unterschieden werden [OWK03a]:

    1. Löschen von Diagrammelementen

    Der Benutzer entfernt Elemente aus dem Ursprungsdiagramm (zum Beispiel eine Klasse).

    2. Hinzufügen neuer Diagrammelemente

    Der Benutzer fügt dem Ursprungsdiagramm neue Elemente hinzu (zum Beispiel eine Klasse).

    3. Umplatzieren von Diagrammelementen

    Der Benutzer entfernt ein Diagrammelement und fügt es an anderer Stelle wieder ein. Mit „an anderer Stelle“ ist ein anderer Kontext im logischen Modell gemeint (zum Beispiel: Entfernen einer Methode aus einer Klasse mit anschließendem Einfügen der Methode in eine andere Klasse) und keine bloße layoutbezogene Änderung (zum Beispiel einfache Veränderung der Position durch Verschiebung). Diese Benutzeraktion ist im Prinzip eine Kombination aus den beiden vorangegangenen Aktionen. Es besteht jedoch eine zusätzliche Semantik der Differenzart, da sich beide Aktionen auf dasselbe Element beziehen.

    4. Änderung von Attributwerten

    Der Benutzer ändert den Wert eines Attributs (zum Beispiel Änderung der Sichtbarkeit einer Methode von public auf private). Hiermit sind Attribute der Meta- Modell- Ebene gemeint; ändert man zum Beispiel den Namen eines Attributes in einer UML- Klasse (Modellebene), so hätte dies die Änderung des Attributes name des Entitäts- Typs Attribute (Meta- Modell- Ebene) zur Folge.

    In Punkt 3 wurde die Betrachtung des Layouts ausgeschlossen. Dies ließe annehmen, dass die Position und Größe von Diagrammelementen uninteressant seien. Das Gegenteil ist jedoch der Fall, denn oft ist die Überschaubarkeit von UML- Diagrammen nur bei sinnvoller Positionierung (zum Beispiel durch Gruppierung von Klassen) der einzelnen Elemente möglich. Die Darstellung von Layout- Differenzen lässt allerdings ein Problem aufkommen:

    21

  • EIN DIFFERENZANZEIGE- PLUGIN FÜR KLASSENDIAGRAMME IN FUJABA

    die Überschaubarkeit könnte unter Umständen sehr darunter leiden, zumal selbst geringe und aus Benutzersicht irrelevante Verschiebungen dargestellt würden. Daher sollte das Layout des Differenzdokuments aus einem der beiden Basisdokumente generiert werden [OWK03a]. Da in XMI jedoch bis Version 2.0 keine Layoutinformationen standardisiert hinterlegt werden können [Weh04] und DiffCalculator keine Layoutdifferenzberechnung unterstützt, erübrigt sich das Problem der Anzeige. Bei Fujaba besteht die Möglichkeit, einen Autolayouter zu benutzen.

    3.2 Integration von Differenzen in XMI

    Bevor die von DiffViewer umgesetzte Möglichkeit zur Anzeige von Differenzen vorgestellt werden kann, muss jedoch verdeutlicht werden, wie die oben aufgeführten Differenzarten gemäß der in 2.1 dargestellten DTD auf XMI- Dokumente abgebildet werden. Diese unterscheidet zwischen vier verschiedenen Arten von Differenzen und setzt diese durch XMI- Elementtypen gleichen Namens um. Wie die Differenz- Informationen erzeugt werden, soll an dem bisherigen Beispiel aus Abschnitt 1.1 gezeigt werden.

    Das Beispiel soll zuerst um folgendes Szenario fortgeführt werden:

    Nach der Entwurfsüberführung führt Herr Müller folgende Aktionen am Diagramm aus Abbildung 1.2 aus:

    - die Sichtbarkeiten der Attribute von public auf private ändern

    - Datentypen für alle neu hinzugekommenen Attribute erfassen

    - Die Methode berechneUmsatz() in die Klasse Mitarbeiter einfügen

    Danach verreist er für fünf Wochen nach Timbuktu. Vorher übergibt er den Entwurf an Frau Meyer, die ihn im Urlaub vertritt, um ihn weiter zu bearbeiten. Frau Meyer merkt sofort, dass Herr Müller folgende Fehler gemacht hat:

    - die Methode berechneUmsatz() ist falsch in der Klasse Mitarbeiter, denn der Umsatz soll allgemein für Kunden berechnet werden

    - er hat vergessen, das Attribut bezeichnung der Klasse VPE auch auf private zu ändern

    - das Attribut lagerort der Klasse Artikel hat er fälschlicherweise mit dem Datentyp Integer versehen; dieser erlaubt keine alphanumerischen Daten, so wie es eigentlich sein sollte

    Frau Meyer kümmert sich um die Angelegenheit.

    Gemäß dem ersten Fehler bewegt sie die Methode berechneUmsatz() von Mitarbeiter nach Kunde. Den zweiten Fehler behebt sie einfach durch Korrektur der Sichtbarkeit. Durch Abänderung des Datentyps von Integer auf String behebt sie den letzten Fehler. Die Klassendiagramme können den Abbildungen 3.1 und 3.2 entnommen werden.

    Nach der Rückkehr aus seinem Urlaub möchte Herr Müller natürlich wissen, was Frau Meyer an seinem Entwurf alles ergänzt oder geändert hat. Hierzu verwendet er DiffCalculator und

    22

  • 3 DIFFERENZEN ZWISCHEN UML- KLASSENDIAGRAMMEN

    DiffViewer. Er generiert mit DiffCalculator ein Differenzdokument zwischen dem OOD- Diagramm vor und nach seinem Urlaub.

    a) structure

    Zuerst lässt sich Herr Müller noch mal die Differenzen zwischen den beiden Analysediagrammen aus Abbildung 1.1 und 1.2 anzeigen. Dieses beinhaltet ausschließlich strukturelle Differenzen, das heißt Unterschiede, die durch das Löschen und Hinzufügen von Diagrammelementen entstanden sind. Somit muss in dem XMI- Dokument an dem entsprechenden Element gekennzeichnet werden, ob es nur in dem ersten oder nur in dem zweiten Dokument vorkommt. Hierzu wird der Elementtyp structure der Erweiterungs- DTD verwendet. Folgendes Beispiel bezieht sich auf das Attribut vpe, das aus der Klasse Artikel gelöscht wurde:

    Durch die Attribute version0 und version1 wird durch einen bool’schen Wert bestimmt, in welchem der beiden Basisdokumente das betroffene Element vorkommt (in dem Beispiel kommt das Element nur in Dokument 0 vor, ist also gelöscht worden).

    b) move

    Das neu generierte Differenzdokument der beiden OOD- Diagramme beinhaltet alle Entwurfsänderungen durch Frau Meyer während Herrn Müllers Urlaub. Die Verschiebung der Methode berechneUmsatz() wird durch den XMI- Elementtyp move ausgezeichnet.

    23

  • EIN DIFFERENZANZEIGE- PLUGIN FÜR KLASSENDIAGRAMME IN FUJABA

    Das Attribut otherParentID des Elementtyps move ist vom XML- Typ IDREF und beinhaltet die ID des Elements, in das die Verschiebung erfolgte, welches das verschobene Element also in dem zweiten Dokument enthält. In diesem Beispiel wäre dies id27, welche zu der Klasse Kunde gehört.

    c) update

    Die von Frau Meyer geänderte Sichtbarkeit des Attributs bezeichnung von public auf private beinhaltet die Änderung eines entsprechenden UML- Meta- Attributwerts. Um eine solche Änderung auszuzeichnen, wird eine Element vom Typ update eingebettet:

    24

  • 3 DIFFERENZEN ZWISCHEN UML- KLASSENDIAGRAMMEN

    Durch das Attribut name des Typs update wird der Name des geänderten Meta- Attributs spezifiziert. Mit value0 wird der alte, mit value1 der neue Attributwert angegeben.

    d) reference

    Diese Differenzart ist motiviert durch einen besonderen Implementierungsaspekt von XMI: wie schon erwähnt verwendet XMI IDREFs zur Referenzierung von bestimmten Elementen (wie zum Beispiel Klassen oder Typen). Ändert sich eine solche Referenz (zum Beispiel durch Änderung des Rückgabe- Datenwertes einer Methode), generiert DifferenceCalculator eine Differenz von Typ reference. Aus Sicht des Anwenders hat sich jedoch nur, wie in c), ein Meta- Attributwert geändert. Daher werden durch DiffViewer reference- Differenzen wie update- Differenzen angezeigt.

    Der von Frau Meyer geänderte Datentyp des Attributs lagerort der Klasse Artikel wäre also eine solche Differenz:

    25

  • EIN DIFFERENZANZEIGE- PLUGIN FÜR KLASSENDIAGRAMME IN FUJABA

    Die Attribute idref0 und idref1 geben den alten und den neuen Wert der ID an. Der Datentyp String hätte also die XMI- ID id203, der Datentyp Integer hingegen id197. Die grafische Darstellung der Differenzen kann der Abbildung 3.3 auf Seite 33 entnommen werden. Folgender Abschnitt zeigt Möglichkeiten zur grafischen Anzeige von Differenzen und veranschaulicht diese durch DiffViewer- Differenzdiagramme.

    3.3 Grafische Darstellung von Differenzen in Klassendiagrammen

    Dieser Abschnitt soll einen kurzen Überblick über einen grundlegenden Ansatz zur Visualisierung von Differenzen direkt in Klassendiagrammen liefern. Dieser Ansatz basiert auf [OWK03a]. Wie schon erwähnt wird durch DiffCalculator ein Vereinigungsdokument mit integrierten Differenz- Informationen erzeugt. Die grafische Darstellung des Dokuments geschieht durch Erzeugung eines Klassendiagramms einschließlich Einbettung der Informationen an geeigneter Stelle. Da somit die festgelegte Syntax von UML- Diagrammen verletzt wird, handelt es sich strenggenommen also gar nicht mehr um UML- Klassendiagramme. Im Folgenden werden für die in Abschnitt 3.1 definierten Differenzarten grundsätzliche Möglichkeiten zur Anzeige aufgezeigt.

    1. Löschen oder Hinzufügen von Diagrammelementen (=strukturelle Differenz)

    Da im Vereinigungsdiagramm sämtliche Diagrammelemente beider Basisdokumente angezeigt werden, muss eine gut überschaubare Markierung erfolgen, aus der sich die Zugehörigkeit der Elemente ersehen lässt. Es gibt hier grundsätzlich drei Klassen von Differenz- Elementen:

    a) Elemente, die nur in Dokument 1 vorkommen

    b) Elemente, die nur in Dokument 2 vorkommen

    c) Elemente, die in beiden Dokumenten vorkommen

    Eine geeignete Markierungsmethode wäre, jeder der drei Klassen eine Farbe zuzuordnen und die Elemente der Klasse entsprechend einzufärben. Auch wenn die Wahl der Farben grundsätzlich frei erfolgen kann, dürfte die Berücksichtigung farbpsychologischer Gesichtspunkte hilfreich sein, so dass eine schnelle und vielleicht auch intuitive Zuordnung erfolgen kann. Elemente, die beiden Dokumenten vorkommen, sollten in der gewöhnlichen Farbe von Klassendiagrammelementen des verwendeten CASE- Tools sein (meist schwarz). Diese Elemente empfindet der Benutzer dann nicht als hervorgehoben und assoziiert sie intuitiv mit beiden Basisdokumenten. Für die anderen Elemente sollten Farben gewählt werden, die sich deutlich voneinander abheben. Elemente, die nur in Dokument 1 vorkommen, wurden im Vergleich zu Dokument 2 gelöscht13. Daher empfiehlt sich die Farbe rot, da diese einen warnenden Charakter hat. Für Elemente, die nur in Dokument 2 vorkommen, bietet sich die Farbe grün an, da sich diese gut von rot abhebt und durch ihren entwarnenden Charakter das Hinzukommen neuer Elemente aufzeigt. Man beachte, dass es 13 Dies impliziert, dass Dokument 1 das Ursprungsdokument ist und Dokument 2 hieraus später entstanden ist.

    26

  • 3 DIFFERENZEN ZWISCHEN UML- KLASSENDIAGRAMMEN

    sich nur um einen subjektiven Vorschlag handelt. Ideal wäre ein konfigurierbares Anzeigewerkzeug, dass eine freie Wahl der Farben zulässt.

    2. Umplatzieren von Diagrammelementen

    Die Visualisierung von Element- Umplatzierungen könnte eventuell durch Pfeile vom Quellelement zum Zielelement realisiert werden. Es ist jedoch zu befürchten, dass die Überschaubarkeit des Vereinigungsdokuments enorm darunter leidet, zumal Pfeile und sonstige Linien elementarer Bestandteil der UML sind (Assoziationen, Subklassenpfeile, etc.). Eine weitere Möglichkeit wäre eine entsprechende Markierung der betroffenen Elemente und eine textuelle Angabe des Quell- bzw. Zielelements. Zwar muss hierbei Zeit zum Suchen des Elements aufgewendet werden, jedoch wäre dies besser für die Überschaubarkeit des gesamten Elements und wesentlich einfacher zu implementieren.

    3. Änderung von Attributwerten

    Die Änderung von Meta- Attributwerten innerhalb eines Elements könnte einfach durch Angabe beider Werte nebeneinander erfolgen. Den Werten würde man dann durch Einfärbung gemäss den in Punkt 1 gewählten Farben entweder Dokument 1 oder Dokument 2 zuordnen.

    Generell kann gesagt werden, dass Differenzdokumente bei einer hohen Anzahl von Differenzen schnell unübersichtlich werden. Dies betrifft besonders die Differenzarten aus Punkt 2 und 3, da hier zusätzliche Werte angezeigt werden müssen. Ein Ansatz zur Behebung dieses Problems wäre, eine Filterung von Differenzinformationen durch Ein- und Ausblendung von Werten durch den Benutzer zu ermöglichen. Dieser kann sich dann auf die für ihn relevanten Informationen beschränken.

    Bevor nun in Abschnitt 4 auf die technische Realisierung eingegangen wird, sollen gezeigt werden, wie DiffViewer die Differenzarten 1.- 3. darstellt. Gegeben sei das Bespielszenario aus Teilbschnitt 3.2. Abbildung 3.1 zeigt das von Herrn Müller entworfene System, bevor er in den Urlaub geflogen ist: Das Attribut bezeichnung der Klasse VPE hat als Sichtbarkeit noch public, der Lagerort den Datentyp Integer und die Methode berechneUmsatz() befindet sich an der falschen Stelle.

    27

  • EIN DIFFERENZANZEIGE- PLUGIN FÜR KLASSENDIAGRAMME IN FUJABA

    Abbildung 3.1: Das Entwurfs- Klassendiagramm vor den Änderungen

    Durch Frau Meyers Korrekturen ergibt sich das Klassendiagramm aus Abbildung 3.2.

    Abbildung 3.2: Das Entwurfs- Klassendiagramm nach den Änderungen

    28

  • 3 DIFFERENZEN ZWISCHEN UML- KLASSENDIAGRAMMEN

    Nach der Rückkehr aus dem Urlaub lässt sich Herr Müller die Unterschiede zwischen beiden Diagrammen anzeigen (Abbildung 3.3).

    Abbildung 3.3: Das Differenz- Diagramm

    Die Änderung der Sichtbarkeit von bezeichnung wird durch das Icon der neuen Sichtbarkeit (private) angezeigt. Bei dem Attribut lagerort wird der neue Datentyp in der Farbe Grün, der alte in der Farbe Rot angegeben. Die Visualisierung der Verschiebung von berechneUmsatz() erfolgt durch die Nennung der Ziel- Klasse, welche grün gefärbt ist. Auf alle diese Differenzen wird durch ein Icon hingewiesen. Update und Reference- Differenzen erhalten das gelbe Icon mit dem „U“, Move- Differenzen erhalten das blaue Icon mit dem „M“. Die Grünfärbungen soll andeuten, dass es sich die jeweilige Differenzinformation auf das Dokument 2 bezieht, Integer also der Attributtyp von lagerort in Dokument 2 ist und berechneUmsatz() in Dokument 2 in der Klasse Kunde vorzufinden ist. Alle Differenzinformationen sind durch Anklicken des Icons ein- und ausblendbar.

    29

  • 4 Das Metamodell und die technische Realisierung der Differenz- darstellung Dieser Abschnitt liefert intuitive Ansätze zum Entwurf eines Metamodells für Differenz- Klassendiagramme und zeigt hierbei auftretende Probleme auf und folgert so auf eine realisierbare Lösung. Danach wird auf die Visualisierung eingegangen. Abschließend wird der gewählte Ansatz in Form eines Cook- Books präsentiert. Als besonders wichtig wird die Umsetzung generischer Komponenten erachtet, so dass diese auch für die Entwicklung von Anzeige- Werkzeugen für Differenzdiagramme anderen Typs verwendet werden können.

    4.1 Entwurf des Metamodells

    Wiederverwendbarkeit ist eines der wichtigsten Charakteristika der objektorientierten Programmierung. Da bereits ein Metamodell für UML- Klassendiagramme existiert und Differenzklassendiagramme zumindest syntaktisch fast identisch zu gewöhnlichen Klassendiagrammen sind, ist zu überlegen, inwiefern alle relevanten Klassen der Fachlogik durch DiffViewer verwenden werden können. Im Folgenden werden Lösungsansätze vorgestellt.

    4.1.1 Intuitive Ansätze

    Zuerst sollen zwei Möglichkeiten vorgestellt werden, die zumindest intuitiv dazu geeignet wären, ein Metamodell für Differenz- Klassendiagramme zu implementieren.

    Intuitiver Ansatz 1:

    Die direkte Instanziierung der UML- Metamodell- Klassen und deren Verwendung als Differenzklassen könnte ein einfacher und geeigneter Ansatz sein. Es müssten dann lediglich geeignete Unparse- Module zur Anzeige der Differenzen implementiert werden. Würde zum Beispiel ein Attribut nur in Dokument 1, jedoch nicht in Dokument 2 auftreten, müsste eine Instanz von UMLAttr (die Metamodell- Klasse für UML- Attribute) erzeugt und durch ein neu implementiertes Unparse- Modul, welches dann Bestandteil des Plugins wäre, angezeigt werden.

    Dieser Ansatz weist mehrere Probleme auf:

    Das dynamische Laden von Unparse- Modulen ist im Fujaba- Kern „hartverdrahtet“. Sämtliche Unparse- Module werden grundsätzlich im Unterverzeichnis unparse der Metamodell- Klassen gesucht und von dort aus geladen. Somit würde Fujaba die Unparse- module für Differenzdiagramme im Unterverzeichnis der UML- Meta- Modell- Klassen suchen, wo sie natürlich nicht sind. Das Sequenzdiagramm aus Abbildung 4.1 soll die Arbeitsweise von Fujaba zum Auffinden von unparse- Modulen veranschaulichen. Zuerst wird die Methode getUnparseModule() auf der Singleton- Instanz von UnparseManager aufgerufen. Hierbei wird ein Objekt vom Typ LogicUnparseInterface übergeben, einer Schnittstelle, die von allen Meta- Modell- Klassen implementiert werden muss (somit also auch von UML- Metamodell- Klassen wie zum Beispiel UMLAttr). Auf diesem Logik- Objekt kann nun die Methode getUnparseModuleName() aufgerufen werden. Diese ruft wiederum

    30

  • 4 DAS METAMODELL UND DIE TECHNISCHE REALISIERUNG DER DIFFERENZDARSTELLUNG

    getUnparseModuleName(this) auf der Singleton- Instanz von UnparseManager auf, welche dann mit getUnparseModuleImpl() das entsprechende Unparse- Modul lädt:

    Abbildung 4.1: Sequenzdiagramm: Laden eines Unparse- Moduls

    Interessant ist nun, wie die Funktion getUnparseModuleName() der Klasse UnparseManager implementiert ist:

    public String getUnparseModuleName (LogicUnparseInterface iface)

    {

    String className = iface.getClass().getName();

    int packageClassSeparator = className.lastIndexOf ('.');

    if (moduleNameStringBuffer == null)

    {

    moduleNameStringBuffer = new StringBuffer();

    }

    else

    {

    moduleNameStringBuffer.

    31

  • EIN DIFFERENZANZEIGE- PLUGIN FÜR KLASSENDIAGRAMME IN FUJABA

    delete(0, moduleNameStringBuffer.length());

    }

    //the following operations convert a

    //qualified classname of

    //qual.ified.pack.age.name.ClassName

    //to qual.ified.pack.age.name.unparse.UMClassName

    moduleNameStringBuffer.append (className);

    //insert this between package- and classname

    moduleNameStringBuffer.insert (packageClassSeparator + 1,

    "unparse.UM");

    return moduleNameStringBuffer.toString();

    }

    Wie leicht zu erkennen ist, wird in der letzten Anweisung vor dem return- Statement der String "unparse.UM" vor den Logik- Klassennamen eingefügt. Der Ort der Unparse- Module kann also nicht dynamisch angepasst werden. Um diesen Ansatz zum Laden der Module trotzdem zu verwenden, müsste also der Kern von Fujaba verändert werden. Eine Möglichkeit wäre, durch die Implementierung eines Strategy- Patterns [GHJV95] in der Klasse UnparseManager die dynamische Austauschbarkeit der Verzeichnisangabe zu erreichen. Eine Veränderung des Fujaba- Kerns soll jedoch, soweit es eben möglich ist, vermieden werden, denn in den Entwurf, die Implementierung und auch in die Tests dieser Erweiterung müsste ein hoher Aufwand investiert werden, da negative Seiteneffekte auf andere Module und Plugins vermieden werden müssen. Sie könnte außerdem nur von berechtigten Entwicklern durchgeführt werden.

    Eine weitere Schwierigkeit ergibt sich in der Unterbringung der Differenzinformationen. Verwendet man die UML- Metamodell- Objekte als Differenz- Objekte, ist eine Speicherung der Differenzinformationen in den Objekten selbst nicht möglich. Da es sich bei diesen Informationen jedoch um Eigenschaften der Differenzobjekte handelt, sollten diese auf jeden Fall dort gespeichert werden.

    Letztendlich führen auch noch semantische Probleme (Erläuterung siehe unten: „Allgemeines Problem“) dazu, dass dieser erste intuitive Ansatz unbrauchbar ist.

    Intuitiver Ansatz 2:

    Es werden alle benötigten Meta- Modell- Klassen für das Plugin implementiert. Dies erfolgt durch Ableiten der UML- Klassen mit entsprechender Spezialisierung (zum Beispiel würde die Klasse DiffAttr die Klasse UMLAttr ableiten).

    Auf den ersten Blick scheint dieser Ansatz sehr sinnvoll zu sein, da eine hohes Maß an Wiederverwendung erfolgt und den in Ansatz 1 erkannten Problemen vorgebeugt wird: die Unparse- Module können jetzt problemlos in die Unterpakete der Differenzklassen gepackt

    32

  • 4 DAS METAMODELL UND DIE TECHNISCHE REALISIERUNG DER DIFFERENZDARSTELLUNG

    werden und die Unterbringung der Differenzinformationen in den Klassen selbst ist jetzt möglich.

    Aber auch hier ergeben sich Probleme. Zum Einen entsteht eine Abhängigkeit vom Fujaba- Kern. Werden im Laufe der Zeit die Schnittstellen zu den (noch) im Kern vorhandenen UML- Meta- Klassen verändert, ohne dass die alte Schnittstelle als deprecated verfügbar bleibt, könnte dies negative Seiteneffekte auf das Plugin haben (zum Beispiel Laufzeitfehler). Dies sollte auf jeden Fall vermieden werden. Des Weiteren ist die Unterbringung der Differenzinformationen sehr unkomfortabel und redundant: in jeder Meta- Klasse müssen sie neu implementiert werden, da es keine für den Entwickler veränderbare Wurzelklasse in der Vererbungshierarchie gibt, in der sie untergebracht werden könnten: die Wurzelklasse UMLIncrement wäre zwar eine Wurzelklasse, sie gehört jedoch zum Fujaba- Kern und ist nicht veränderbar.

    Allgemeines Problem:

    Sowohl in Ansatz 1 als auch in Ansatz 2 besteht ein allgemeines Problem: bei der direkten Verwendung der UML- Meta- Modell- Klassen und auch bei deren Ableitung wird die Semantik von Klassen- Diagrammen mit der von Differenz- Klassendiagrammen gleichgesetzt. Dabei ist ein Differenz- Klassendiagramm eben kein gewöhnliches Klassendiagramm, auch wenn die grafische Darstellung an den meisten Stellen oft identisch ist. Klassendiagramme sollen konsistent sein, das heißt sie müssen dem Ausschnitt der Wirklichkeit entsprechen, den sie modellieren. Differenzdiagramme modellieren keinen Ausschnitt der Wirklichkeit, da sie eine Vereinigung von (idealerweise konsistenten) Basisdokumenten darstellen. Entstehen zum Beispiel Differenzen durch Verschiebung von Elementen, müsste gegebenenfalls das betroffene Element doppelt angezeigt werden: einmal im alten und einmal im neuen Kontext.

    4.1.2 Metamodell- Erweiterung für Differenzinformationen

    Auch wenn es sehr aufwändig ist, so scheint es unvermeidbar zu sein: aufgrund der oben genannten Probleme muss das komplette Metamodell für Differenz- Klassendiagramme neu implementiert und in das Plugin eingebunden werden. Hilfreich ist hierbei, dass Fujaba im Quellcode verfügbar ist und somit die benötigten UML- Meta- Klassen kopiert, umbenannt und entsprechend angepasst werden können. Die neu implementierten Klassen müssten dann so um die Differenzinformationen erweitert werden, dass sie wiederverwendbar sind. In Abschnitt 4.3 soll ein Auszug aus dem Differenzdiagramm- Metamodell als Klassendiagramm vorgestellt werden. Folgendes Klassendiagramm aus dem Paket de.usi.diffextension.metamodell zeigt, wie ein generischer Ansatz zum Halten der Differenzinformationen gefunden wurde:

    33

  • EIN DIFFERENZANZEIGE- PLUGIN FÜR KLASSENDIAGRAMME IN FUJABA

    Abbildung 4.2: Generischer Ansatz zur Speicherung der Differenzinformationen

    DiffIncrement ist in der Vererbungshierarchie der Meta- Modell- Klassen das Wurzelelement. Die Speicherung der Differenzinformation wird durch Implementierung der Schnittstelle DiffInfoHolder realisiert. Da Interfaces keine Attribute beinhalten dürfen, kann die Referenz auf das DiffInfo- Objekt nicht vererbt werden, sondern muss implementiert werden. Dazu muss die Anweisung aus einem Kommentar in DiffInfoHolder ausgeführt werden, nämlich die Implementierung des Referenzattributs. Zunächst einmal soll das Konzept zur Speicherung der einzelnen Differenzarten betrachtet werden:

    1. Strukturelle Differenzen

    Das Attribut structuralDiffState speichert die Art der strukturellen Differenz. Die Definition der Integer- Konstanten EXISTS_IN_BOTH, EXISTS_ONLY_IN_DOC_0, und EXISTS_ONLY_IN_DOC_1 geben die möglichen Werte an, wobei EXISTS_IN_BOTH der Default- Wert ist.

    2. Move- Differenzen

    Das Attribut movedFromSource zeigt auf ein Objekt vom Typ DiffIncrement, also einem beliebigen Differenz- Diagramm- Element. Dies ist das Quell- Objekt, von dem aus das Element bewegt wurde. Der Default- Wert hierzu ist natürlich null.

    3. Update- Differenzen

    In der Datenstruktur updateDifference vom Typ HashMap werden die Änderungen von Meta- Attributwerten gespeichert. Dies erfolgt folgendermaßen: es muss ein String- Array mit zwei Feldern erzeugt werden. In Feld 0 wird dann der alte Wert des Attributs, in Feld 1 der neue Wert des Attributs eingefügt. Dieses String- Array wird dann mit dem Meta- Attributnamen als Schlüssel in updateDifference eingefügt.

    34

  • 4 DAS METAMODELL UND DIE TECHNISCHE REALISIERUNG DER DIFFERENZDARSTELLUNG

    Bsp.:

    Die Sichtbarkeit einer Methode hat sich von public auf private geändert:

    Unter dem Schlüssel “visibility“ wird {“public“, “private“} in updateDifference eingefügt.

    4. Move- Differenzen

    Die Speicherung von Move- Differenzen erfolgt im Prinzip genauso wie die von Update- Differenzen. Die HashMap referenceDifference speichert unter dem Namen des IDREF- Attributs (wahrscheinlich immer xmi.idref, theoretisch sind aber auch andere Namen möglich) die Namen der in Dokument 1 und Dokument 2 referenzierten Elemente in Form eines String- Arrays.

    Bsp.:

    Der Typ eines Attributs hat sich von String auf Integer geändert:

    Unter “xmi.idref“ wird {“String“, “Integer“ } eingefügt.

    4.2 Visualisierung

    Analog zum Metamodell kann auch bei der Implementierung der Unparse- Module vorgegangen werden. Wie in Teilabschnitt 2.2.1 erläutert, muss jeder Meta- Modell- Klasse genau ein Unparse- Modul im Unterpaket unparse zugeordnet werden. Dieses wird ebenfalls aus dem Fujaba- Quellcode kopiert, umbenannt und angepasst, so dass Differenzinformationen angezeigt werden können.

    Wenn der in Abbildung 2.10 vorgestellte Parser auf ein Differenz- Element trifft, müssen die Differenzinformationen in dem betroffenen Meta- Modell- Objekt gemäß der im vorherigen Abschnitt vorgestellten Haltung der Informationen gesetzt werden. Bei der Anwendung des bisherigen Konzepts würden die Updater dann dafür sorgen, dass die Differenz- Informationen visualisiert werden. DiffViewer verwendet einen etwas anderen Ansatz. Da Differenzdiagramme lediglich ein Abbild der Unterschiede und Gemeinsamkeiten zweier Diagramme sind, dürfen sie nicht veränderbar sein. Daher wäre eine Ersetzung des bisherigen, auf der Model- View- Controller- Architektur basierenden Visualisierungskonzepts durch ein wesentlich einfacheres sicherlich sinnvoll. Ziel soll hierbei sein, auf Updater völlig zu verzichten und generisch verwendbare Komponenten zu realisieren, deren Funktionalitäten auch für andere Diagrammtypen verwendbar sind (z.B. Einfärbung, das Ausblenden von Informationen durch Buttons, etc.). Abbildung 4.3 zeigt eine Übersicht über Klassen, deren Objekte die Updater ersetzen und für die Einbettung der Differenz- Informationen in das Diagramm verantwortlich sind.

    35

  • EIN DIFFERENZANZEIGE- PLUGIN FÜR KLASSENDIAGRAMME IN FUJABA

    Abbildung 4.3: Die generischen Visualisierungs- Komponenten

    Die abstrakte Wurzel- Klasse VisDiff beinhaltet drei Attribute. Das Erste ist eine Referenz auf das JComponent- Objekt originalSwing. Diese zeigt auf die Swing- Komponente, durch die das UML- Element visualisiert wird, auf das sich die entsprechende Differenz- Information bezieht (zum Beispiel ein JPanel, durch das ein Attribut angezeigt wird, dessen Name sich geändert hat). Die anderen beiden Attribute sind die Referenzen auf die zur Differenz- darstellung notwendigen Farben. Die anderen Klassen sind Subtypen von DiffVis. Alle Klassen sind im Paket de.usi.diffextension.visualization zu finden (Abschnitt 5). Soll nun eine bestimmte Differenz dargestellt werden (z.B. als Update), so muss aus den oben aufgeführten Klassen eine geeignete, innerhalb des Unparse- Moduls, das zur betroffenen Metamodell- Klasse gehört (z.B. UMAttr), instanziiert werden (analog zum bisherigen Updater- Konzept). Hierbei müssen dann die betroffene Swing- Komponente und die Differenzinformationen an den Konstruktor übergeben werden. Die Swing- Komponente ist im Unparse- Modul

    36

  • 4 DAS METAMODELL UND DIE TECHNISCHE REALISIERUNG DER DIFFERENZDARSTELLUNG

    definiert, die Differenz- Informationen lassen sich aus dem Logikobjekt auslesen, das beim Aufruf von create() übergeben wird. Die Visualisierungs- Komponente arbeitet nun wie folgt: Nachdem das Differenz- Diagramm eingelesen wurde, wird für jedes Logik- Objekt (z.B. DiffClass, DiffAttr etc.) create() in dessen Unparse- Modul aufgerufen. Liegen Differenz- Informationen vor, so wird eine entsprechende Visualisierungs- Komponente erzeugt, welche die grafische Differenzdarstellung an der richtigen Stelle platziert. Dies erfolgt unter zu Hilfenahme des originalSwing- Objekts. Abbildung 4.4 zeigt das Panel, welches zur Darstellung des Attributs lagerort dient.

    Abbildung 4.4: Grafische Darstellung des JComponent- Objekts eines Attributs

    Es ist, wie in dem Beispiel bereits gesehen, eine reference- Differenz entstanden, da der Datentyp von Integer auf String geändert wurde. Diese kann als DiffInfo- Objekt aus der Logik- Instanz des Attributs ausgelesen werden. Die Differenz soll jedoch, aus bereits erwähntem Grund, als update- Differenz angezeigt werden und zwar hinter folgendem Kind- JComponent- Objekt:

    Abbildung 4.5: Grafische Darstellung des Kind- JComponent- Objekts für den Datentyp eines Attributs

    Beim Aufruf von create() des entsprechenden UMDiffAttr- Objekts wird für die Darstellung der Update- Differenz folgender Code ausgeführt:

    public FSAObject create (FSAObject parent, LogicUnparseInterface incr) {

    … FSAComboBoxLabel typeLabel = new FSAComboBoxLabel (attr, "attrType",

    mainPanel.getJComponent());

    DiffInfo diffInfo = incr.getDiffInfo();

    if(diffInfo != null) {

    HashMap referenceDifference =

    diffInfo.getReferenceDifference();

    if(referenceDifference != null) 37

  • EIN DIFFERENZANZEIGE- PLUGIN FÜR KLASSENDIAGRAMME IN FUJABA

    {

    String [] diffValues = (String[])referenceDifference.get("xmi.idref");

    String diffText = diffValues[1]; Color existsOnlyInDoc1 =

    DifferenceViewerOption.get().getExistsOnlyInDoc1Color();

    Color existsOnlyInDoc2 =

    DifferenceViewerOption.get().getExistsOnlyInDoc2Color(); new VisUpdateTextDiff(typeLabel.getJComponent(),

    diffText, existsOnlyInDoc2, existsOnlyInDoc1);

    }

    }

    }

    Zuerst wird die FSA- Komponente für die Darstellung des Attribut- Typs erzeugt. Anschließend werden die Informationen zu der Referenz- Differenz aus dem Logik- Objekt ausgelesen. Diese sind als zweifeldiges String- Array unter dem Schlüssel „xmi.idref“ in einer HashMap gespeichert. Danach wird der Name des in Dokument 2 referenzierten Elements ausgelesen: dies ist unter Index 1 in dem String- Array gespeichert. Bei der Erzeugung des VisUpdateTextDiff- Objekts wird dieser Name als darzustellender Text angegeben. Dieser wird dann so eingefärbt, dass das ausschließliche Vorkommen des Attributs in Dokument 2 zu erkennen ist (hier also grün). Die zur Anzeige benötigten Farben müssen aus dem de.usi.diffview.options.DifferenceViewerOption- Objekt ausgelesen werden. Es handelt sich hierbei um eine Singleton- Instanz, in der sämtliche durch den Anwender vorgenommenen Einstellungen an DiffViewer (siehe Abschnitt 5, Guided Tour) gespeichert werden. Da der Attributtyp von lagerort aus Diagramm 2 zusätzlich angezeigt werden soll, muss dieser entsprechend mit der Farbe für Elemente, die nur in Dokument 2 vorkommen, eingefärbt werden. Analog hierzu muss der andere Attributwert so eingefärbt werden, dass er dem Dokument 1 zugeordnet werden kann (hier: rot). Beide Farben werden ebenfalls bei der Objekterzeugung dem Konstruktor übergeben. In dem bisherigen Beispiel wurde der Attributtyp aus Abbildung 4.4 von Integer auf String geändert. Die VisUpdateTextDiff- Instanz sorgt nun dafür, dass die Differenz wie folgt dargestellt wird:

    Abbildung 4.6: Grafische Darstellung der JComponent- Instanz eines Attributs, einschließlich Differenzinformation

    38

  • 4 DAS METAMODELL UND DIE TECHNISCHE REALISIERUNG DER DIFFERENZDARSTELLUNG

    Durch das Button mit dem gelben U- Icon („U“ wie „Update“) kann die Differenzinformation ein- und ausgeblendet werden. Zu klären wäre nur noch, wie VisUpdateTextDiff sich selbst korrekt in der grafischen Darstellung platziert. Da bei der Erzeugung das die Differenz betreffende JComponent- Objekt (originalSwing) übergeben wird, k