-
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