pdf 1.967 kB - Praktische Informatik - Universität Siegen
pdf 1.967 kB - Praktische Informatik - Universität Siegen
pdf 1.967 kB - Praktische Informatik - Universität Siegen
Erfolgreiche ePaper selbst erstellen
Machen Sie aus Ihren PDF Publikationen ein blätterbares Flipbook mit unserer einzigartigen Google optimierten e-Paper Software.
<strong>Universität</strong> <strong>Siegen</strong><br />
Fachbereich 12 - Elektrotechnik und <strong>Informatik</strong><br />
Diplomarbeit<br />
Testportal zur Unterstützung<br />
rechnerbasierter Experimente<br />
Roman Gad<br />
Erstprüfer: Prof. Dr. Udo Kelter, <strong>Universität</strong> <strong>Siegen</strong><br />
Zweitprüfer: Dr. Stefan Berlik, <strong>Universität</strong> <strong>Siegen</strong><br />
<strong>Siegen</strong>, im Juli 2007
Inhaltsverzeichnis<br />
1 Einleitung und Motivation 2<br />
2 Anforderungen und Randbedingungen 4<br />
3 Entwicklung des Systems 6<br />
3.1 Funktionsprinzip . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6<br />
3.2 Systemarchitektur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7<br />
3.3 Plugin-Struktur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8<br />
3.4 Datenbankanbindung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12<br />
3.5 Verwendete Datenstrukturen . . . . . . . . . . . . . . . . . . . . . . . . . 15<br />
3.6 Hibernate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17<br />
3.7 ID-Zuweisung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20<br />
3.8 Wichtige Variablen des Hauptsystems . . . . . . . . . . . . . . . . . . . . 21<br />
3.9 Einbindung von Plugins . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22<br />
3.10 Datenaustausch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25<br />
3.11 Sprachunterstützung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31<br />
3.12 Speicherung von Systeminformationen . . . . . . . . . . . . . . . . . . . . 33<br />
3.13 Aufbau der graphischen Oberfläche . . . . . . . . . . . . . . . . . . . . . . 34<br />
3.14 Behandlung von Ereignissen . . . . . . . . . . . . . . . . . . . . . . . . . . 38<br />
4 Installation und Ausführung des Programms 39<br />
4.1 Installation des Programms . . . . . . . . . . . . . . . . . . . . . . . . . . 39<br />
4.2 Starten des Programms . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40<br />
5 Bedienung des Werkzeugs 43<br />
5.1 Programmübersicht . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43<br />
5.1.1 Sprache wählen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44<br />
5.1.2 Modus wählen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44<br />
5.1.3 Erststart . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45<br />
5.1.4 Server hinzufügen . . . . . . . . . . . . . . . . . . . . . . . . . . . 45<br />
5.2 Algorithmen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47<br />
5.2.1 Importieren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47<br />
5.2.2 Eigenschaften verändern . . . . . . . . . . . . . . . . . . . . . . . . 50<br />
5.2.3 Kommentar verfassen oder ändern . . . . . . . . . . . . . . . . . . 51<br />
5.2.4 Datei-Freigabe und Archiv . . . . . . . . . . . . . . . . . . . . . . 51<br />
5.2.5 Zur Auswahl der Testläufe hinzufügen . . . . . . . . . . . . . . . . 51<br />
I
Inhaltsverzeichnis<br />
5.2.6 Algorithmus löschen . . . . . . . . . . . . . . . . . . . . . . . . . . 51<br />
5.3 Schemata und DTDs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52<br />
5.3.1 Die Schema/DTD-Ansicht . . . . . . . . . . . . . . . . . . . . . . . 52<br />
5.3.2 Neues Schema/DTD . . . . . . . . . . . . . . . . . . . . . . . . . . 53<br />
5.3.3 Importieren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53<br />
5.3.4 Den Namen ändern . . . . . . . . . . . . . . . . . . . . . . . . . . . 54<br />
5.3.5 Änderungen am Dokument oder Kommentar . . . . . . . . . . . . 54<br />
5.3.6 Löschen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54<br />
5.4 Eingabe-, Konfigurations- und Stylesheetdokumente . . . . . . . . . . . . 55<br />
5.4.1 Neues Dokument . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55<br />
5.4.2 Dokument importieren . . . . . . . . . . . . . . . . . . . . . . . . . 55<br />
5.4.3 Namen ändern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56<br />
5.4.4 Eigenschaften ändern . . . . . . . . . . . . . . . . . . . . . . . . . 56<br />
5.4.5 Inhalt und Kommentar ändern . . . . . . . . . . . . . . . . . . . . 57<br />
5.4.6 Datei-Freigabe und Archiv . . . . . . . . . . . . . . . . . . . . . . 57<br />
5.4.7 Zur Auswahl der Testläufe hinzufügen . . . . . . . . . . . . . . . . 58<br />
5.4.8 Löschen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58<br />
5.5 Testläufe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59<br />
5.5.1 Vorbedingung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59<br />
5.5.2 Definition von Testläufen . . . . . . . . . . . . . . . . . . . . . . . 60<br />
5.5.3 Komponenten aus der Run-Tabelle tauschen . . . . . . . . . . . . 60<br />
5.5.4 Testläufe aus der Tabelle entfernen . . . . . . . . . . . . . . . . . . 60<br />
5.5.5 Alle bevorstehenden Resultate anzeigen . . . . . . . . . . . . . . . 60<br />
5.5.6 Resultat-Graph . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61<br />
5.5.7 Testläufe starten . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61<br />
5.5.8 Testläufe speichern . . . . . . . . . . . . . . . . . . . . . . . . . . . 62<br />
5.6 Experimente . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63<br />
5.6.1 Einzel-Experimente . . . . . . . . . . . . . . . . . . . . . . . . . . 63<br />
5.6.2 Experimentsequenzen . . . . . . . . . . . . . . . . . . . . . . . . . 66<br />
5.7 Archiv . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68<br />
5.7.1 Die Archivansicht . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68<br />
5.7.2 Datei zum Arbeitsbereich verschieben oder löschen . . . . . . . . . 69<br />
5.8 Darstellung, Log und Beendigung des Programms . . . . . . . . . . . . . . 69<br />
5.8.1 Darstellung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69<br />
5.8.2 Log . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69<br />
5.8.3 Programm beenden . . . . . . . . . . . . . . . . . . . . . . . . . . . 69<br />
6 Erweiterungsmöglichkeiten 70<br />
6.1 Erstellung und Integration eines Plugins . . . . . . . . . . . . . . . . . . . 70<br />
6.2 Integration eines neuen Sprachpakets . . . . . . . . . . . . . . . . . . . . . 73<br />
7 Zusammenfassung und Ausblick 75<br />
8 Anhang 78<br />
II
Abbildungsverzeichnis<br />
3.1 Prinzipelle Funktionsweise des Systems . . . . . . . . . . . . . . . . . . . . 6<br />
3.2 Die Schichtenarchitektur des Systems . . . . . . . . . . . . . . . . . . . . . 7<br />
3.3 Modulare Struktur des Programms . . . . . . . . . . . . . . . . . . . . . . 9<br />
3.4 Vereinfachte Darstellung der Plugineinbindung . . . . . . . . . . . . . . . 24<br />
3.5 Vereinfachte Darstellung vom Ablauf des Datenaustauschs zwischen Scheduler,<br />
Client und Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30<br />
4.1 Der Installationsassistent . . . . . . . . . . . . . . . . . . . . . . . . . . . 40<br />
5.1 Das Startfenster . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44<br />
5.2 Plugins hinzufügen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45<br />
5.3 Server hinzufügen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45<br />
5.4 Die Table-View . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47<br />
5.5 Der Algorithm-Import-Wizard . . . . . . . . . . . . . . . . . . . . . . . . 48<br />
5.6 Die Detail-View mit selektiertem Reiter “Algorithmus-Details“ . . . . . . 50<br />
5.7 Die Schema/DTD-Ansicht . . . . . . . . . . . . . . . . . . . . . . . . . . . 53<br />
5.8 Import-Wizard für Eingabe-Dateien . . . . . . . . . . . . . . . . . . . . . 56<br />
5.9 Ein Dokument welches eine DTD einliest . . . . . . . . . . . . . . . . . . 57<br />
5.10 Die Detail-View mit selektiertem Reiter “Testläufe“ und hinzugefügten<br />
Dokumenten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59<br />
5.11 Der Resultat-Graph . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61<br />
5.12 Die Details eines Experimentes . . . . . . . . . . . . . . . . . . . . . . . . 64<br />
5.13 Ansicht einer gespeicherten Ausgabe-Datei . . . . . . . . . . . . . . . . . . 65<br />
5.14 Detail-Ansicht einer Experiment-Sequenz . . . . . . . . . . . . . . . . . . 66<br />
5.15 Die Archivansicht mit selektiertem Archivbereich “Algorithmus“ . . . . . 68<br />
6.1 Das Erscheinungsbild des Systems nach dem Einbinden des Testplugins . 72<br />
6.2 Wahl der neu hinzugekommenen Sprache . . . . . . . . . . . . . . . . . . 74<br />
III
Zusammenfassung<br />
Abbildungsverzeichnis<br />
In der heutigen Zeit werden zunehmend automatisierte Anlagen verwendet um den Alltag<br />
zu erleichtern oder ihn angenehmer zu gestalten. Somit werden nicht nur im Umfeld<br />
der Produktionsautomatisierung, sondern auch in allen Bereichen des alltäglichen Lebens<br />
Geräte eingesetzt, die verschiedene Funktionen bieten. Der Entwurf solcher Geräte aber<br />
vor allem die Entwicklung derer Funktionen, erfordert oft den Einsatz ausgeklügelter<br />
Algorithmen. Um die Effizienz solcher Algorithmen zu untersuchen und zu optimieren<br />
bedarf es meist experimenteller Testläufe unter Einsatz verschiedener Eingaben und<br />
Konfigurationen.<br />
In dieser Diplomarbeit soll die Entwicklung und der Gebrauch eines Werkzeugs vorgestellt<br />
werden, welches eine komfortable Experimentierumgebung bereitstellt, die einen<br />
Benutzer bei der Planung, Durchführung und Verwaltung rechnerbasierter Experimente<br />
unterstützt.<br />
1
1 Einleitung und Motivation<br />
Seit den frühen Anfängen der <strong>Informatik</strong> und der Entwicklung der ersten programmierbaren<br />
Rechner haben es sich viele Unternehmen zur Aufgabe gemacht, Programme zur<br />
Bewältigung diverser Probleme zu erstellen. Solche Programme werden für viele Bereiche<br />
der Industrie und der Unterhaltung benötigt. Sie dienen unter anderem zur Vereinfachung<br />
von diversen Finanzberechnungen, Datenerfassung- und haltung, Maschinenund<br />
Robotersteuerung, Kommunikation, bis hin zur privaten Unterhaltung in Form von<br />
Computerspielen und Multimediaanwendungen. Die Software, die dazu benötigt wird,<br />
erfordert oftmals den Einsatz spezieller Verfahren, sogenannter Algorithmen.<br />
So müssen Verfahren zur Berechnung verschiedener Problemstellungen entwickelt werden.<br />
Zu solchen Problemen gehören beispielsweise Algorithmen zur Sortierung der Daten<br />
einer Datenbank und Verfahren, die den Zugriff auf diese ermöglichen. In anderen Bereichen<br />
benötigt man wiederum Algorithmen, die bestimmte Arithmetische Werte, wie<br />
z.B. Mittelwete und Statistiken, berechnen. Bei der Steuerung von Fertigungsabläufen,<br />
in welche Roboter involviert sind, benötigt man Wegfindungs- und Wegbestimmungsalgorithmen.<br />
Sogar bei der Entwicklung von Computerspielen benötigt man Algorithmen,<br />
wie beispielsweise die erwähnten Wegfindungsalgorithmen aber auch Algorithmen zur<br />
Berechnung der Künstlichen Inteligenz - die heutzutage eine der größten Herausforderungen<br />
der Programmierung darstellen.<br />
Für viele dieser Probleme liegen bereits seit geraumer Zeit Lösungen bzw. Lösungsansätze<br />
vor. Da heutzutage die Menge der von Programmen zu verwaltenden Daten<br />
steigt, die Berechnungszeit jedoch konstant bleiben oder gar reduziert werden muss,<br />
kommt man nicht umher, die vorliegenden Algorithmen im Hinblick auf ihre Laufzeit zu<br />
optimieren oder gar neue, effizientere Algorithmen zu entwickeln.<br />
Um eine Aussage über die Effizienz bestehender Algorithmen treffen zu können oder<br />
diese zu verbessern, ist es notwendig die Algorithmen bezüglich ihrer Laufzeit und ihres<br />
Speicherbedarfs empirisch zu prüfen. Auch bei der Entwicklung neuer Algorithmen<br />
zeigt es sich als unumgänglich diese Werte auf der Basis verschiedener Testeingaben,<br />
die man auch als Benchmarks bezeichnet, empirisch zu erfassen um diese als Grundlage<br />
für Verbesserungen und Optimierungen des Algorithmus zu verwenden. Dabei liefert<br />
ein einzelner Testlauf in der Regel keine Aussage über die Effizienz eines Algorithmus.<br />
Vielmehr erfordert es eine ganze Reihe von Testläufen um über den direkten Vergleich<br />
der ermittelten Resultate die Leistungsfähigkeit eines Algorithmus zu bewerten.<br />
Da komplexere Algorithmen zudem konfigurierbar sein können, mag es durchaus vorkommen,<br />
dass diese nicht nur mit verschiedenen Eingabebenchmarks, sondern zudem<br />
mit einer ganzen Reihe verschiedener Konfigurationen solchen Testläufen unterzogen<br />
werden müssen. Dies führt dazu, dass bei der Optimierung eines einzelnen Algorithmus<br />
womöglich hunderte von Testläufen durchgeführt werden müssen, bevor dieser einen für<br />
2
KAPITEL 1. EINLEITUNG UND MOTIVATION<br />
den Entwickler akzeptablen Effizienzgrad vorweist.<br />
Das Durchführen solcher Testläufe und die Sammlung und Verwaltung der resultierenden<br />
Ergebnisse bezeichnet man auch als Experiment bzw. als Experimentsequenz. Ein<br />
Experiment ist somit durch die Kombination aus Eingabedaten, Algorithmen und ggf.<br />
Konfigurationen und Transformationen definiert.<br />
Um die Entwicklung und die Analyse solcher Algorithmen zu vereinfachen, soll im Rahmen<br />
dieser Diplomarbeit eine komfortable Experimentierumgebung bereitgestellt werden,<br />
welche auf den Namen “Cooperative Algorithm Engineering Workbench“ getauft<br />
wird. Diese soll den Entwickler in erster Linie bei der Planung, Durchführung, Verwaltung<br />
und Auswertung rechnerbasierender Experimente unterstützen.<br />
Die Entwicklung dieses Programms unterteilt sich in zwei Phasen. In der ersten Phase<br />
soll ein Einzelnutzersystem entwickelt und implementiert werden. Dieses soll dem potenziellen<br />
Nutzer einen einfachen Einstieg in die Benutzung dieses Experimentierportals<br />
bieten. Erreicht werden soll dies in erster Linie durch eine möglichst einfache Installation<br />
des Einzelnutzersystems und einen denkbar geringen Einarbeitungsaufwand.<br />
In der zweiten Phase soll die entwickelte Experimentierumgebung zu einem Mehrbenutzersystem<br />
ausgebaut werden. Dieses soll sowohl das kooperative als auch kompetitive<br />
Arbeiten verteilter Nutzer aber auch ganzer Benutzergruppen unterstützen.<br />
Die Entwicklung der zweiten Phase des Systems ist nicht Bestandteil dieser Diplomarbeit,<br />
sodass im weiteren Verlauf nur auf die Entwicklung und Funktionalität des Einzelnutzersystems<br />
eingegangen wird. Als erstes sollen die Anforderungen, die an das Einzelnutzersystem<br />
gestellt werden, ausführlich behandelt werden. Anschließend wird auf<br />
die wichtigsten bzw. interessantesten Aspekte der Entwicklung und Implementierung<br />
eingegangen. Das darauffolgende Kapitel konzentriert sich auf die Bedienung des Experimentiersystems.<br />
Abschließend sollen die Möglichkeiten der Weiterentwicklung und<br />
Erweiterung des Programms vorgestellt werden.<br />
Aufbau der Ausarbeitung<br />
Bei dieser Ausarbeitung wird der Erstellungsprozess eines Softwaresystems dokumentiert.<br />
Hierzu werden Zunächst im Kapitel 2 die einzelnen Anforderungen und aufgestellten<br />
Randbedingungen, welche an das zu entwickelnde System gestellt werden, ausführlich<br />
erläutert. Anschließend widmet sich Kapitel 3 der Ausarbeitung, dem Prozess der<br />
Planung und Entwicklung dieses Systems. Hierbei wird auf alle relevanten Aspekte<br />
der Entwurfs- und Implementierungsphase eingegangen. Das anschließende Kapitel beschreibt<br />
den Installations- und Startvorgang dieses Systems. Die Bedienung aller Funktionen<br />
dieses Programms wird in dem darauffolgendem Kapitel 5 detailliert beschrieben.<br />
Kapitel 6 behandelt die Möglichkeiten der modularen Erweiterung dieses Systems. Das<br />
Abschließende Kapitel 7 soll eine Zusammenfassung der Ausarbeitung und einen Ausblick<br />
auf die möglichen Folgeprojekte, welche der Weiterentwicklung des Systems dienen,<br />
bieten.<br />
3
2 Anforderungen und Randbedingungen<br />
Um das komfortable Experimentieren mit Algorithmen zu ermöglichen, werden an das<br />
zu entwerfende System verschiedene Anforderungen gestellt. Ein wichtiger Bestandteil<br />
des Systems soll eine Verwaltung aller Eingabedaten sein. Um solche Daten zu erfassen<br />
und vor allem persistent zu speichern, wird eine relationale Datenbank eingesetzt. Um<br />
den Installationsaufwand zu minimieren, wird bei dem Einzelnutzersystem auf eine integrierte<br />
Datenbank zurückgegriffen. Hierbei dient die Datenbank als ein dem Benutzer<br />
des Systems exklusiv zur Verfügung gestellter Speicherort. Sie stellt die Dokumentmappe<br />
des Benutzers dar, in der alle relevanten Dokumente - wie z.B. Algorithmen, Eingabedokumente<br />
oder auch Benchmarks, Konfigurationen, Transformationen, Ausgabedaten<br />
aber auch komplette Experimente - aufgenommen und verwaltet werden. Für Dokumente,<br />
die zwar aktuell nicht benötigt werden, bei denen jedoch ein späterer Einsatz nicht<br />
ausgeschlossen werden kann, soll ein Archiv zur Verfügung gestellt werden. Daten, die<br />
ins Archiv ausgelagert wurden, sollen zu jeder Zeit problemlos wieder in den Arbeitsbereich<br />
zurückverschoben werden können.<br />
Ein anderer wichtiger Punkt bei der Entwicklung des Systems ist die Vereinfachung<br />
der Durchführung von Einzelexperimenten aber auch kompletten Experimentsequenzen.<br />
Hierbei soll das Hauptaugenmerk auf eine übersichtliche und nach Möglichkeit intuitiv<br />
bedienbare Benutzeroberfläche gelegt werden. Es soll dem Benutzer die Möglichkeit<br />
geboten werden, einzelne Experimente bzw. komplette Sequenzen von Experimenten erneut<br />
Testläufen zu unterziehen.<br />
Ferner soll der Experimentierkontext automatisch erfasst werden und die Möglichkeit<br />
gegeben sein, diesen gegebenfalls in der Datenbank abzulegen. Der Kontext soll eine<br />
Beschreibung des Rechners darstellen, auf dem ein Experiment ausgeführt wurde. Zu<br />
den zu erfassenden Informationen des Kontextes gehören die Prozessorgeschwindigkeit,<br />
die Hauptspeichergröße und der Name des auf dem Rechner eingesetzten Betriebssystem.<br />
Zudem soll der Kontext den Namen des Rechners, auf dem der Testlauf ausgeführt<br />
wird, sowie die für den Testlauf benötigte Ausführungsdauer erfassen. Die Experimentierresultate,<br />
zu denen der Kontext aber auch die Ausgabe der Algorithmenberechnung<br />
gehören, sollen ebenfalls in der Datenbank verwaltet werden können. Dies bedeutet, dass<br />
die Option gegeben sein soll, diese Daten für eine mögliche Weiterverarbeitung bzw.<br />
Auswertung persistent abspeichern zu können. Bei der Entwicklung der einzelnen Funktionalitäten<br />
des Systems sollen einige Nebenbedingungen berücksichtigt werden. So soll<br />
die Einschränkung bezüglich der Art der möglichen Experimente so gering wie möglich<br />
gehalten werden. Ebenso sollen Ein- und Ausgabedokumente bezüglich ihres Formats<br />
möglichst einschränkungsfrei gehalten werden. Dies bedeutet, dass bei der Festlegung<br />
dieser Formate möglichst auf freie Standards zurückgegriffen werden soll. Bei dem Entwurf<br />
der Struktur des Programms soll unbedingt eine modulare, durch Plugins erweiter-<br />
4
KAPITEL 2. ANFORDERUNGEN UND RANDBEDINGUNGEN<br />
bare Architektur realisiert werden. Dies soll die Weiterentwicklung und die Erweiterung<br />
des Systems unterstützen. Um eine Abhängigkeit bezüglich des verwendeten Betriebssystems<br />
zu vermeiden, soll eine plattformunabhängige Realisierung garantiert werden. Dies<br />
soll durch den Einsatz der objektorientierten Programmiersprache Java T M , die unter<br />
Berücksichtigung einiger Regeln eine Plattformunabhängigkeit bietet, erreicht werden 1 .<br />
Da zur Analyse der Effizienz eines Algorithmus oft eine Vielzahl an Testläufen gestartet<br />
wird, soll die Option geboten werden, die Berechnung einzelner Testläufe auf mehrere<br />
Rechner eines Netzwerk-Clusters auszulagern. Dadurch soll eine parallele Abarbeitung<br />
ganzer Experimentsequenzen garantiert werden, wodurch Wartezeiten, die bei Testläufen<br />
entstehen, verringert werden.<br />
Als eine zusätzliche Basisfunktion soll das System die englische Sprache als Standard<br />
unterstützen, da die Möglichkeit geboten werden soll, das Programm Weltweit einzusetzen.<br />
Zusätzlich soll es möglich sein die Sprachunterstützung modular zu erweitern. Als<br />
eine Erweiterung der Sprachunterstützung soll bereits in der Basisversion Deutsch als<br />
zusätzliche Sprache zur Verfügung stehen. Weitere Sprachen sollen mit möglichst wenig<br />
Aufwand hinzugefügt werden können.<br />
1 Java ist ein eingetragenes Markenzeichen der Firma Sun Microsystems Inc.<br />
5
3 Entwicklung des Systems<br />
3.1 Funktionsprinzip<br />
Da das zu entwickelnde System eine Fülle von Funktionen bieten soll, war es vorab<br />
erforderlich eine grobe Planung des Ablaufs zu erstellen. Diese soll in diesem Kapitel<br />
vorgestellt werden. Hierzu wird zunächst in der folgenden Abbildung der prinzipielle<br />
Ablauf des Systems skizziert und anschließend erläutert.<br />
Abbildung 3.1: Prinzipelle Funktionsweise des Systems<br />
Das System soll bei der Durchführung rechnerbasierter Experimente unterstützen.<br />
Ein Experiment besteht dabei aus einem Testlauf, in den ein Algorithmus und ein oder<br />
mehrere Eingabedokumente - die in diesem Zusammenhang auch als Benchmarks bezeichnet<br />
werden - involviert sind. Sollte ein Algorithmus Konfigurationsdokumente oder<br />
6
KAPITEL 3. ENTWICKLUNG DES SYSTEMS<br />
Transformationsdokumente zum Ablauf benötigen, so können diese optional zum Testlauf<br />
hinzugefügt werden. Die so definierten Testläufe werden an einen Server, der die<br />
Berechnung durchführt, übergeben. Der Server gibt als Resultat der Berechnung die<br />
Ausgabe des Algorithmus in der Form eines Ausgabedokuments und den bei der Berechnung<br />
erfassten Kontext an das System zurück. Alle Dokumente die ein Benutzer erstellt<br />
bzw. importiert hat, wie beispielsweise Algorithmen oder Eingabedokumente aber auch<br />
komplette Experimente, können in einer relationalen Datenbank persistent gespeichert<br />
werden, von welcher sie zur jeder Zeit erneut eingelesen werden können.<br />
3.2 Systemarchitektur<br />
Eine der Anforderungen, die an das zu entwickelnde System gestellt werden, ist es eine<br />
Modulare Architektur zu entwerfen, die eine relativ leichte Weiterentwicklung, Erweiterung<br />
und Abänderung des Programms erlaubt. Um dies zu gewährleisten wurde als<br />
Basis für die Struktur des Aufbaus des Systems eine Schichtenarchitektur 1 gewählt. Diese<br />
unterteilt sich, wie in Abbildung 3.2 gezeigt, in die GUI-Schicht, Fachkonzeptschicht,<br />
Netzwerkschicht und die Datenhaltungsschicht.<br />
Abbildung 3.2: Die Schichtenarchitektur des Systems<br />
In der GUI-Schicht wird festgelegt wie der Benutzer auf das System zugreifen und mit<br />
diesem interagieren kann. Sie enthält Klassen, die die graphische Schnittstelle zwischen<br />
dem Benutzer und dem Programmkern realisieren. In dieser Schicht wird zudem festgelegt,<br />
wie einzelne Daten - z.B. Eingabedokumente, Konfigurationen, Algorithmen oder<br />
Experimente - dem Benutzer graphisch präsentiert werden. Es werden der Aufbau und<br />
1 “Grobarchitektur, bei der die Module in einer Folge von Gruppen (Schichten) eingeteilt werden, sodass<br />
jede Schicht nur die Dienste der tieferliegenden Schichten benutzt.“[Kel1]<br />
7
KAPITEL 3. ENTWICKLUNG DES SYSTEMS<br />
die Struktur der graphischen Oberfläche festgelegt. Die Fachkonzeptschicht stellt den<br />
funktionellen Kern des Systems dar, der auch als Fachlogik bezeichnet wird. Diese Schicht<br />
enthält Klassen, die die Verarbeitung der anwendungsspezifischen Funktionen übernehmen.<br />
Sie ist nicht nur für den Start und die Initialisierung des Programms zuständig,<br />
sondern fungiert auch teilweise als zentraler Knoten, an dem der Informationsfluß der<br />
anderen Schichten zusammenläuft.<br />
Die Datenhaltungsschicht beschreibt die Struktur aller im System persistent speicherbarer<br />
Daten. Sie legt auf eindeutige Weise fest, wie solche Daten in einer Datenbank<br />
abzulegen sind. Zudem beschreibt diese Schicht, zusammen mit der Fachkonzeptschicht,<br />
wie auf gespeicherte Daten zugegriffen werden kann. Sie dient als Schnittstelle zwischen<br />
dem Programmkern und der Datenbank selbst.<br />
Die Art, wie das System mit anderen Instanzen dieses Programms zwecks Datenübertragung<br />
kommuniziert, wird in der Netzwerkschicht definiert. Hier wird ebenfalls festgelegt,<br />
welche Funktionen das Programm in der Rolle des Servers, der für die Testläufe<br />
einzelner Clients zur Verfügung steht, bereit stellt.<br />
3.3 Plugin-Struktur<br />
Wie schon erwähnt, soll das System ohne größeren Aufwand erweitert und weiterentwickelt<br />
werden können. Dies wird teils durch die im vorherigen Kapitel aufgezeigte<br />
Schichtenarchitektur angestrebt. Um den Aufwand der Erweiterung von Systemen zu<br />
minimieren, hat sich in der Softwareentwicklung das Konzept des modularen Aufbaus<br />
als eine geeignete Methode erwiesen.<br />
Bei der Entwicklung eines Softwaresystems mit modularem Aufbau wird zunächst ein<br />
Kern implementiert, welches in erster Linie die Grundfunktionalität beinhaltet. Dieser<br />
Kern ist sowohl für das Starten als auch für die Initialisierung des Programms verantwortlich.<br />
Zu seinen wichtigsten Eigenschaften zählt jedoch die Bereitstellung von speziellen<br />
Schnittstellen, die dazu dienen, zusätzliche, kompatible Softwaremodule einzubinden.<br />
Diese sogenannten Plugins sind Teilprogramme, die zur Bewältigung verschiedener Aufgaben<br />
dienen und sind in der Regel ohne die Hauptanwendung, für die sie geschrieben<br />
wurden, nicht funktionsfähig.<br />
Die Idee einer Modularen Struktur soll auch in dem zu entwickelnden System aufgegriffen<br />
werden. Hierzu werden einzelne Teilfunktionen, wie z.B. die Verwltung und Umgang<br />
mit Algorithmen oder das Definieren und Starten von Testläufen, als einzelne Plugins<br />
realisiert. Die Abbildung 3.3 zeigt eine grobe Skizze dieser Architektur.<br />
Hauptsystem<br />
Die wichtigste Komponente der Architektur stellt das Hauptsystem dar, die den Kern<br />
des Programms repräsentiert. Diese wird durch die jeweiligen Plugins, die unabhängig<br />
voneinander agieren, erweitert. Alle Komponenten - das Hauptsystem und die einzelnen<br />
Plugins - sind wiederum nach dem Muster der im vorherigen Kapitel beschriebenen<br />
Schichtenarchitektur aufgebaut.<br />
8
KAPITEL 3. ENTWICKLUNG DES SYSTEMS<br />
Abbildung 3.3: Modulare Struktur des Programms<br />
Neben dem Start- und dem Initialisierungsvorgang bietet das Hauptsystem eine Reihe<br />
weiterer Funktionen:<br />
• Main-Frame - Das Hauptsystem stellt die wichtigste Komponente der graphischen<br />
Oberfläche zur Verfügung: das Hauptfenster, auch Main-Frame genannt. Das<br />
Hauptfenster fungiert als eine Art Container in dem alle graphischen Elemente untergebracht<br />
werden könen. Alle graphischen Elemente des Hauptsystems und das<br />
Main-Frame selbst befinden sich im Paket "de.usi.caew.gui".<br />
• Datenhaltung - Da eine Grundfunktionalität des Systems auch ohne Einbindung<br />
von Plugins gegeben sein soll, ist die Datenhaltung und somit die Definition der<br />
Struktur einzelner Daten ein Bestandteil des Hauptsystems. Der eigentliche Zugriff<br />
auf die Datenbank ist jedoch auf das Hauptsystem und die Plugins verteilt. Diese<br />
Aufteilung bietet den Vorteil, dass nachträglich hinzugefügte Plugins individuelle<br />
Datenbankzugriffsmethoden implementieren können.<br />
• ID-Verwaltung - Da die Daten, die persistent gespeichert werden sollen, in einer<br />
Datenbank abgelegt werden, ist es notwendig diesen Daten eindeutige Identifizierer<br />
zuzuweisen. Diese Aufgabe übernimmt ebenfalls das Hauptsystem. Hierzu bietet<br />
9
KAPITEL 3. ENTWICKLUNG DES SYSTEMS<br />
die Klasse "IDWatcher", die im Paket "de.usi.caew.system" liegt, spezielle Methoden,<br />
die die jeweiligen ID’s berechnen und als Resultat zurückgeben.<br />
• Netzwerkkommunikation - Wie bereits erwähnt, soll die Testlaufphase auf<br />
mehrere Rechner verteilt werden können. Um dies zu gewährleisten ist das Programm<br />
so aufgebaut, dass es zum Teil als als Server und zum Teil als Client<br />
betrieben wird. Dabei dient der Server, der als ein eigener Thread im Hintergrund<br />
ausgeführt wird, zum Berechnen von Testläufen. Das eigentliche, vom Nutzer sichtbare<br />
Programm, ist der Client, der die Aufträge an einen bzw. mehrere Server verteilt.<br />
Dies mag im ersten Moment widersprüchlich erscheinen, da womöglich davon<br />
ausgegangen wird, dass das Hauptprogramm der Server sei und die berechnenden<br />
Threads die Clients, denen Aufgaben zugeteilt werden. In der Praxis ist es jedoch<br />
so, dass ein Server seine Dienste anbietet, der Client diese wiederum nutzt. Somit<br />
ist die oben beschriebene Rollenverteilung korrekt.<br />
Die Funktionalität des Servers ist ebenfalls ein Bestandteil des Hauptsystems und<br />
wurde gezielt nicht als Plugin implementiert. Dies macht es möglich das Programm<br />
ohne Einbindung jeglicher Plugins als Server ausführen zu können. Dieser Server<br />
kann anderen Instanzen des Programms seine Dienste anbieten und beispielsweise<br />
zur verteilten Testlaufberechnung eingesetzt werden. Die dazugehörigen Klassen<br />
befinden sich im Paket "de.usi.caew.rmi" des Hauptsystems.<br />
• Sprachmanagement - Das System unterstützt den Einsatz verschiedener Sprachen.<br />
Die Sprachunterstützung kann im späteren Verlauf modular erweitert werden.<br />
Zwei Sprachen - Englisch und Deutsch - sind bereits ein Bestandteil der Basisversion.<br />
Die Funktionen, die zum Zugriff auf Sprachelemente genutzt werden, sind ebenfalls<br />
in das Hauptsystem integriert und lassen sich im Paket "de.usi.caew.lang"<br />
finden.<br />
• Dokumente im Hauptspeicher - Die Dokumente, die zur Ausführung von<br />
Testläufen benötigt werden, befinden sich zum Zeitpunkt des Startens in der Datenbank.<br />
Sollte man auf die Dokumente zugreifen wollen, so müssen diese zunächst<br />
in den Hauptspeicher geladen werden. Um dies zu ermöglichen bietet die Klasse<br />
"MainSys", die sich im Paket "de.usi.caew.system" befindet, verschiedene Variablen<br />
und Arrays, die solche Daten aufnehmen können. Die Klasse "MainSys" ist<br />
eine der wichtigsten Klassen des Hauptsystems, die einen zentralen Knotenpunkt<br />
zwischen den Plugins und dem Hauptsystem selbst darstellt. Alle Plugins haben<br />
die Möglichkeit auf die in ihr zentral abgelegten Daten zuzugreifen. Dies ermöglicht<br />
einen wechselseitigen Datenaustausch zwischen einzelnen Plugins.<br />
• Plugin-Nutzung - Da das Hauptsystem, abgesehen von seiner Funktion als<br />
Server, nur wenig Funktionalität bietet, ist die Einbindung von Plugins eine seiner<br />
Hauptaufgaben. Hierzu befinden sich Funktionen in der Klasse "MainSys", die<br />
diese Aufgabe übernehmen.<br />
10
KAPITEL 3. ENTWICKLUNG DES SYSTEMS<br />
Nachfolgend werden die einzelnen Plugins beschrieben, die bereits als Bestandteil des<br />
Basissystems implementiert sind. Je nach Wunsch des Nutzers kann das System mit<br />
relativ geringem Aufwand durch weitere Plugins erweitert werden. Auf diesen Vorgang<br />
wird im Kapitel 6 ausführlich eingegangen.<br />
Algorithm-Plugin<br />
Zum Umfang des Algorithm-Plugins gehören die meisten Funktionen, die eine Möglichkeit<br />
des Zugriffs und der Veränderung von Algoritmendokumenten bieten. Zu diesem<br />
Zweck stellt das Plugin diverse GUI-Elemente zur Verfügung, welche ins Hauptfenster<br />
bzw. Main-Frame des Hauptsystems eingebettet werden. Zu diesen Elementen gehören<br />
unter anderem die Exploreransicht, die die in der Datenbank abgespeicherten Algorithmendokumente<br />
visualisiert, sowie eine detaillierte Ansicht eines einzelnen Algorithmendokuments.<br />
Ferner bietet das Plugin verschiedene Zugriffsmethoden, die zur Interaktion mit der<br />
Datenbank dienen.<br />
Input-Plugin<br />
Das Input-Plugin bietet eine Reihe von Funktionen, mit denen der Zugriff auf Eingabedokumente<br />
realisiert wird. Ähnlich wie das Algorithm-Plugin stellt es verschiedene<br />
GUI-Komponenten, die ebenfalls in das Main-Frame eingebettet werden, zur Verfügung.<br />
Zudem erlaubt es den Zugriff auf die Eingabedokumente der Datenbank.<br />
Config-Plugin<br />
Analog zum Input-Plugin werden vom Config-Plugin verschiedene Funktionen und GUI-<br />
Elemente zum Zugriff auf Konfigurationsdokumente der Datenbank bereitgestellt.<br />
Transform-Plugin<br />
Das Transform-Plugin funktioniert ebenfalls in der selben Weise wie das Input-Plugin.<br />
Unter Verwendung dieses Plugins kann der Zugriff auf Stylesheetdokumente, die in der<br />
Datenbank abgelegt sind, erfolgen.<br />
Experiment-Plugin<br />
Das Experiment-Plugin dient zur Verwaltung von Experimenten und Experimentsequenzen.<br />
Es enthält diverse Funktionen, die das Manipulieren gespeicherter Experimente<br />
bzw. Sequenzen erlauben. Hierzu bietet das Experiment-Plugin verschiedene GUI-<br />
Komponenten, die diese Funktionalität ermöglichen.<br />
Archive-Plugin<br />
Das Archive-Plugin wird dazu verwendet ein Archiv zur Auslagerung nur noch selten<br />
benutzter Daten bzw. Dokumente bereitzustellen. Zur Verwaltung archivierter Daten<br />
11
KAPITEL 3. ENTWICKLUNG DES SYSTEMS<br />
werden dem Nutzer eine graphische Darstellung des Archivs und einige Zugriffsfunktionen<br />
geboten.<br />
Schema-Plugin<br />
Bei der Durchführung von Experimenten, die auf Dokumente im XML-Format zurückgreifen,<br />
ist es oftmals notwendig ihre Struktur zu beschreiben. Hierzu werden sogenannte<br />
DTDs und auch XML-Schemata 2 verwendet. Das Schema-Plugin bietet die Möglichkeit<br />
solche DTD- und Schemadokumente zu verwalten.<br />
Run-Plugin<br />
Das Run-Plugin ermöglicht in erster Linie das Definieren und Ausführen von Testläufen.<br />
Des weiteren bietet dieses Plugin die Option erfolgreich beendete Testläufe als Experimente<br />
aber auch Mengen solcher Testläufe als Experimentsequenzen in der Datenbank<br />
abzuspeichern. Wie bereits angesprochen basiert die Berechnung von Testläufen auf einer<br />
Client-Server-Architektur. Die Definition und Funktionalität des Servers ist ein Bestandteil<br />
des Hauptsystems. Im Run-Plugin hingegen wird der Aufbau des Clients definiert.<br />
Dieses Plugin enthält die relevanten Klassen, welche Methoden zur Kommunikation mit<br />
dem Server bieten.<br />
3.4 Datenbankanbindung<br />
Dieses Programm ermöglicht die rechnerunterstützte Experimentdurchführung an Algorithmen.<br />
Um dies gewährleisten zu können, verwaltet das System eine ganze Menge<br />
an Dokumenten, die zur Ausführung bzw. Auswertung von Algorithmen erforderlich<br />
sind. Solche vom Benutzer des Systems gesammelten bzw. erstellten Dokumente müssen<br />
effizient und dauerhaft gespeichert werden können. Diese Eigenschaften bieten unter<br />
anderem relationale Datenbanksysteme. Die Installation solcher Datenbanksysteme ist<br />
jedoch oft mit einem gewissen Aufwand verbunden. Dies widerspricht der Anforderung<br />
einer möglichst einfachen Installation, die an das System gestellt ist. Ein solcher Mehraufwand<br />
könnte womöglich einen potenziellen Nutzer bereits beim Installationsvorgang<br />
demotivieren das System zu nutzen. Der Einsatz einer Datenbank, wie beispielsweise<br />
“MySQL“, ist eher der Mehrbenutzerversion des Programms vorbehalten, deren Implementierung<br />
nicht zum Umfang dieser Diplomarbeit gehört. Dennoch müssen die besagten<br />
Dokumente abgespeichert und verwaltet werden können. So entstand bei der<br />
Planung die Idee - alternativ zu Datenbanksystemen - solche Dokumente direkt auf<br />
dem Datenträger als Dateien im XML-Format abzuspeichern. Diese Art der persistenten<br />
Datenhaltung wäre jedoch mit einem relativ großen Aufwand bei einem gezielten<br />
Zugriff auf die gespeicherten Daten verbunden. Somit wurde dieses Vorhaben verworfen<br />
und nach einer Alternative gesucht, welche die Vorteile beider Verfahren - geringer Installationsaufwand<br />
und effizienter Zugriff auf gespeicherte Daten - bietet. Eine Lösung<br />
2 Auf die Beschreibung und Definition von DTDs und XML-Schemata wird im weiteren Verlauf der<br />
Ausarbeitung näher eingegangen.<br />
12
KAPITEL 3. ENTWICKLUNG DES SYSTEMS<br />
dieses Problems boten die sogenannten “leichtgewichtigen Datenbanken“, die auch als<br />
“integrierbare Datenbanken“ bekannt sind. Diese haben den Vorteil, dass der Aufwand<br />
einer Installation komplett entfällt. Solche Datenbanksysteme werden direkt bei der Implementierung<br />
in das zu entwickelnde System integriert und mit dem fertigen Programm<br />
ausgeliefert. Dies wird aufgrund ihrer relativ geringen Größe, die in der Regel 4MB nicht<br />
überschreitet, ermöglicht. In diesem System wird die Derby-Datenbank eingesetzt, die<br />
ein Projekt der Apache Software Foundation ist und als freie Software von deren Website<br />
bezogen werden kann. Diese Software bietet zudem den Vorteil, dass sie komplett<br />
in der Programmiersprache Java implementiert ist und damit eine Betriebssystemübergreifende<br />
Kompatibilität garantiert. Dadurch ist diese Datenbank relativ leicht in das<br />
zu entwickelnde Projekt integrierbar.<br />
Geschichtliches<br />
Die Derby-Datenbank wurde ursprünglich unter dem Namen “JBMS“ von der Firma<br />
Cloudscape Inc entwickelt und 1997 veröffentlicht. Im Laufe der Zeit wurde das Produkt<br />
von “JBMS“ in “Cloudscape“ umbenannt. 1999 kaufte die Firma Informix Software Inc.<br />
die Rechte an der Weiterentwicklung auf, die diese im Jahr 2001 an den IBM-Konzern<br />
weitergab. IBM übergab 2004 die Cludscape-Software der Apache Software Foundation,<br />
die die Datenbank unter dem Namen Derby als Open Source Projekt anbietet. Seit 2006<br />
ist die Derby-Datenbank unter dem neuen Namen “Java DB“ ein fester Bestandteil des<br />
Sun JDK 6(Java Development Kit).<br />
Integration ins System<br />
Die Derby Datenbank kann in zwei verschiedenen Modi betrieben werden; zum einen als<br />
Netzwerkserver und zum anderen als eingebettetes Datenbanksystem. Im Netzwerkserver-<br />
Modus funktioniert Derby ähnlich wie beispielsweise MySQL. Dabei “horcht“ Derby über<br />
TCP/IP 3 an einem Netzwerkport, der standardmäßig auf den Wert 1527 eingestellt ist,<br />
auf eingehende Verbindungen. Über diesen Port können unterschiedliche Clients auf die<br />
Datenbank zugreifen. Der Betrieb der Datenbank in diesem Modus bringt jedoch ähnliche<br />
Nachteile wie der Einsatz anderer Netzwerkserver-Datenbanken mit sich - eine relativ<br />
aufwendige Installation der Datenbanksoftware und die Konfiguration des Betriebssystems.<br />
Im zweiten Modus, in dem Derby als eingebettete Datenbank genutzt wird, entfallen<br />
diese Nachteile. Es ist lediglich vom Programmierer darauf zu achten, dass die zu<br />
Derby zugehörigen Bibliotheken vor der Ausführung des Programms in den Klassenpfad<br />
hinzugefügt werden. Die Datenbankinstanz wird automatisch beim Start des entworfenen<br />
Systems aktiviert. Der Zugriff auf die Datenbank kann beispielsweise mittels der<br />
JDBC-Funktionalität von Java erfolgen. Hierzu muss zuerst ein JDBC-Treiber, welcher<br />
mit dem Derby-Paket mitgeliefert wird, geladen werden. Da hier die Funktionalität der<br />
integrierten Datenbank genutzt wird, muss der Treiber "EmbeddedDriver" aus dem Pa-<br />
3 Transmission Control Protocol - meist verwendetes Protokoll für zuverlässige Übertragung von Da-<br />
tenströmen<br />
13
ket "org.apache.derby.jdbc" verwendet weden.<br />
Somit ergäbe sich der folgende Aufruf:<br />
KAPITEL 3. ENTWICKLUNG DES SYSTEMS<br />
Class.forName("org.apache.derby.jdbc.EmbeddedDriver");<br />
Connection con = DriverManager.getConnection<br />
("jdbc:derby:MyDatabase;create=true");<br />
Mit dieser Codesequenz wurde der JDBC-Treiber geladen. Zudem wurde eine Verbindung<br />
zur Datenbank aufgebaut. Die hier genutzten Funktionen sind in den Klassen der<br />
JDK-Bibliothek im Paket "java.sql" enthalten.<br />
Um die Manipulation der sich in der Datenbank befindlichen Daten zu ermöglichen, ist es<br />
notwendig zunächst ein Anweisungsobjekt vom Typ "Statement" zu erzeugen. Hat man<br />
ein Statement-Objekt beschafft, kann dessen Methode "executeQuery" dazu verwendet<br />
werden, Daten aus der Datenbank zu lesen. Die Methode erwartet einen SQL-String<br />
in Form einer gültigen SELECT-Anweisung und gibt ein Objekt vom Typ ResultSet<br />
zurück, das die Ergebnismenge repräsentiert. Um Datenbankänderungen durchzuführen,<br />
stellt das Anweisungsobjekt die Methode "executeUpdate" zur Verfügung. Auch sie erwartet<br />
als Argument einen String mit einer gültigen SQL-Anweisung. Nachfolgend wird<br />
ein simples Beispiel präsentiert, in dem eine Tabelle in der Datenbank erstellt wird.<br />
Anschließend werden zwei Objekte vom Typ in die Tabelle eingefügt. Ein Objekt vom<br />
Typ "User" ist hierbei die Instanz einer Klasse, welche die beiden Strings "name" und<br />
surname sowie die entsprechenden Zugriffsmethoden beinhaltet. Als letzter Schritt werden<br />
die eingefügten Vornamen ausgelesen und mit Hilfe der Standardausgabe visualisiert.<br />
Hierbei wurde bereits im Vorfeld eine Verbindung, gemäß der oben gezeigten Methode,<br />
aufgebaut. Zu beachten ist, dass die hier verwendeten Methoden eine "SQLException"<br />
werfen können, welche aufgefangen oder weitergereicht werden muss.<br />
Statement stm = conn.createStatement();<br />
stm.executeUpdate("CREATE TABLE users<br />
(id INTEGER, name CHAR(30), surname CHAR(30))");<br />
String tempName = user1.getName();<br />
String tempSurname = user1.getSurname();<br />
stm.executeUpdate("INSERT INTO users VALUES<br />
(1, ’"+ tempName +"’, ’"+ tempSurname +"’)");<br />
String tempName2 = user2.getName();<br />
String tempSurname2 = user2.getSurname();<br />
stm.executeUpdate("INSERT INTO users VALUES<br />
(2, ’"+ tempName2 +"’, ’"+ tempSurname2 +"’)");<br />
ResultSet res1 = stm.executeQuery<br />
("SELECT name FROM users WHERE id=’"+user1.getID()+"’");<br />
ResultSet res2 = stm.executeQuery<br />
("SELECT surname FROM users WHERE id=’"+user2.getID()+"’");<br />
ResultSet res3 = stm.executeQuery<br />
("SELECT name FROM users WHERE id=’"+user1.getID()+"’");<br />
ResultSet res4 = stm.executeQuery<br />
14
KAPITEL 3. ENTWICKLUNG DES SYSTEMS<br />
("SELECT surname FROM users WHERE id=’"+user2.getID()+"’");<br />
User newUser1 = new User();<br />
User newUser2 = new User();<br />
newUser1.setName(res1.getString("name"));<br />
newUser1.setSurname(res3.getString("name"));<br />
newUser2.setName(res2.getString("name"));<br />
newUser2.setSurname(res4.getString("name"));<br />
System.out.println(newUser1.getName());<br />
System.out.println(newUser2.getName());<br />
3.5 Verwendete Datenstrukturen<br />
Ein Benutzer des Systems führt Experimente auf der Basis verschiedener Dokumente.<br />
Zu solchen Dokumenten gehören bespielsweise Algorithmen, Eingabedokumente, Konfigurationsdokumente<br />
etc. Damit das System diese Daten verarbeiten kann, müssen diese<br />
Dokumente Objekten verschiedener Typen zugewiesen werden. Diese Objekte enthalten<br />
alle relevanten Informationen über die zugehörigen Dateien. Im folgenden sollen all diese<br />
Datentypen und ihre Bedeutung kurz beschrieben werden. Sofern nicht anders angegeben,<br />
befinden sich alle Klassen, deren Instanzen durch die genannten Objekte dargestellt<br />
werden, im Paket "de.usi.caew.data". Die Beschreibung der Variablen der einzelnen<br />
Klassen kann im Anhang X nachgeschlagen werden.<br />
Beschreibung der Daten, die in der Datenbank persistent gespeichert werden:<br />
Algorithm Die Klasse "Algorithm" repräsentiert die einzelnen importierten Algorithmen.<br />
InputData Die Klasse "InputData" repräsentiert die Eingabedokumente bzw. Benchmarks.<br />
Config Die Klasse "Config" repräsentiert die Konfigurationsdokumente, die zur Ausführung<br />
einiger Algorithmen benötigt werden.<br />
Transformation Die Klasse "Transformation" repräsentiert die Stylesheetdokumente,<br />
die zur Ausführung mancher Algorithmen benötigt werden.<br />
Context Die Klasse "Context" repräsentiert den Kontext, der während eines Testlaufs<br />
vom System erfasst wurde. "Context"-Objekte werden im Programm von Dokumenten<br />
des Typs "Experiment" referenziert.<br />
OutputData Die Klasse "OutputData" repräsentiert die Ausgabe, die während eines<br />
Testlaufs erstellt wurde. "OutputData"-Objekte werden im Programm ebenfalls von Dokumenten<br />
des Typs "Experiment" referenziert.<br />
15
KAPITEL 3. ENTWICKLUNG DES SYSTEMS<br />
Experiment Die Klasse "Experiment" repräsentiert ein bestimmtes Experiment. Hierzu<br />
referenziert ein "Experiment"-Objekt den entsprechenden Algorithmus und die jeweiligen<br />
Eingabe-, Konfigurations- und Stylesheetdokumente, die bei diesem Experiment<br />
eingesetzt wurden. Zudem werden das Ausgabedokument, welches bei dem Testlauf des<br />
Experiments erzeugt wurde, und der vom System erfasste Kontext referenziert.<br />
ExpSequence Die Klasse "ExpSequence" repräsentiert eine Sequenz von Experimenten.<br />
Hierzu referenziert die Klasse einzelne "Experiment"-Objekte.<br />
Schema Die Klasse "Schema" repräsentiert die Schemata- bzw. DTD-Dokumente, die<br />
in manchen Fällen zur Beschreibung von Dokumenten im XML-Format benötigt werden.<br />
ResourcePart Den Dokumenten, die zur Ausführung von Experimenten benötigt werden,<br />
liegt immer eine importierte Datei zugrunde. Bei Algorithmen handelt es sich dabei<br />
meist um eigenständige Programme und bei Eingabedokumenten meist um textuelle<br />
Dateien, die beispielsweise im XML-Format vorliegen. Diese Dateien müssen neben anderen<br />
Informationen auch in der Datenbank abgespeichert werden. Im Programm wird<br />
dies durch das separate Ablegen der einzelnen Dateien, welche in 1MB große Blöcke aufgeteilt<br />
sind, realisiert. Diese Blöcke werden durch die Klasse ResourcePart repräsentiert.<br />
User Die Klasse "User" beschreibt einen Benutzer. Sie enthält Informationen über<br />
seine Zugriffsrechte und referenziert die Klasse "PersonallyData", die seine persönlichen<br />
Daten verwaltet. Diese Klasse wird im Einzelbenutzersystem genau ein Mal genutzt. Dies<br />
geschieht bei dem allerersten Start des Programms zur Erstellung eines Default-Users.<br />
Da es sich hierbei um ein Einzelnutzersystem handelt können keine weiteren Benutzer<br />
angelegt werden. Diese Klasse wurde bereits im Hinblick auf das Mehrbenutzersystem<br />
implementiert.<br />
PersonallyData Die Klasse "PersonallyData" beschreibt die persönlichen Daten eines<br />
Benutzers, beispielsweise den Vor- und Nachnamen und die Adresse aber auch optionale<br />
Daten wie die Telefonnummer oder Homepage des Benutzers. Die Objekte dieser Klasse<br />
werden von der Klasse "User" referenziert.<br />
UserGroup Die Klasse "UserGroup" repräsentiert eine komplette Benutzergruppe. Hierzu<br />
referenziert sie Objekte der Klasse "User", welche die einzelnen Gruppenmitglieder<br />
darstellen. Zudem verwaltet sie die Zugriffsrechte der Gruppe. Diese Klasse wurde ebenfalls<br />
im Hinblick auf das Mehrbenutzersystem implementiert.<br />
IDContainer Die Klasse "IDContainer" verwaltet die Identifizierer, die an alle im<br />
Programm verwendeten, persistent gespeicherten Objekte, vergeben werden müssen.<br />
16
KAPITEL 3. ENTWICKLUNG DES SYSTEMS<br />
Beschreibung der Daten, die das System zum Ablauf benötigt:<br />
Run Die Klasse "Run" dient zur Verwaltung von Dokumentsammlungen aber auch zur<br />
Verwaltung ganzer Testlaufdefinitionen.<br />
SysInfo Die Klasse "SysInfo" enthält Informationen über das System, die persistent<br />
auf der Festplatte abgespeichert werden. Diese werden beim Starten des Systems eingelesen.<br />
Result Die Klasse "Result" repäsentiert das Resultat eines Testlaufs. Hierzu verwaltet<br />
es alle vom System erfassten, relevanten Daten.<br />
3.6 Hibernate<br />
Im Abschnitt 3.4 wurde anhand eines Beispiels eine Möglichkeit vorgestellt, auf relationale<br />
Datenbanken mit Hilfe von JDBC und SQL-Anweisungen zuzugreifen. Hierbei muss<br />
der Programmierer das Abbilden von Objekten auf die Tabellen der Datenbank selbst<br />
übernehmen. Eine Alternative hierzu liefert das Open Source Framework “Hibernate“,<br />
welches unter http://www.hibernate.org/ heruntergaladen werden kann. Dieses Framework<br />
übernimmt durch objektrelationales Mapping die Abbildung der Objekte auf<br />
relationale Datenbanken. Dadurch bietet “Hibernate“ Programmierern eine objektorientierte<br />
Sicht auf Tabellen und Beziehungen in relationalen Datenbank-Management-<br />
Systemen. Statt mit SQL-Anweisungen wird mit Objekten operiert. Bei einer Vielzahl<br />
verschiedener zu implementierender Datenbankzugriffe kann hierdurch der Implementierungsaufwand<br />
wesentlich reduziert werden. Wegen der Vorteile, die sich aus der Nutzung<br />
dieses Frameworks ergeben, werden die Datenbankzugriffe im System nicht mittels<br />
JDBC, sondern mit Hilfe von “Hibernate“ realisiert. Zu diesem Zweck müssen die Bibliotheken,<br />
die im “Hibernate“-Paket als Dateien im ".jar"-Format vorliegen, ins Programm<br />
integriert werden. Um dies zu gewährleisten müssen diese zum Klassenpfad des<br />
Programms hinzugefügt werden.<br />
Nachfolgend soll anhand eines einfachen Beispiels die Nutzung von “Hibernate“ in Verbindung<br />
mit Java-Programmen verdeutlicht werden. Hierbei soll der gleiche Vorgang der<br />
im Beispiel des Kapitels 3.4 beschrieben wurde, mit Einsatz von “Hibernate“ umgesetzt<br />
werden. Hierzu wird ebenfalls auf die beiden Objekte "user1" und "user2" des Typs<br />
"User" des im Kapitel 3.4 aufgeführten Beispiels zurückgegriffen.<br />
Einsatz von Hibernate<br />
Zu Anfang sollte erwähnt werden, dass alle Objekte des Programms, die mittels der<br />
“Hibernate“-Funktionalität persistent in der Datenbank abgespeichert werden sollen,<br />
der POJO-Architektur entsprechen müssen. POJO is ein Akronym für “Plain Old Java<br />
Object“. Bei solchen Objekten muss zu jeder Variable die sie beinhalten eine “get“- und<br />
eine “set“- Methode vorhanden sein.<br />
17
KAPITEL 3. ENTWICKLUNG DES SYSTEMS<br />
“Hibernate“ kann mit vielen verschiedenen Datenbanken betrieben werden. Die Anpassung<br />
erfolgt in der SessionFactory-Konfigurationsdatei "hibernate.cfg.xml", die bei<br />
dem vorgestellten Beispiel wie folgt aussieht:<br />
<br />
<br />
<br />
<br />
<br />
org.apache.derby.jdbc.EmbeddedDriver<br />
<br />
<br />
jdbc:derby:derbyDB/db; create=true<br />
<br />
username<br />
password<br />
org.hibernate.dialect.HSQLDialect<br />
false<br />
<br />
org.hibernate.transaction.JDBCTransactionFactory<br />
<br />
<br />
org.hibernate.cache.HashtableCacheProvider<br />
<br />
create<br />
<br />
<br />
<br />
Alle Objekte, die mit Hilfe von “Hibernate“ persistent in der Datenbank gespeichert werden<br />
sollen, benötigen eine Mapping-XML-Datei. Diese sollte die Endung ".hbm.xml" haben<br />
und zur besseren Übersichtlichkeit den Namen der Klasse besitzen. Bei dem Beispiel<br />
der "User"-Klasse wäre es der Name "User.hbm.xml". Die relativen Pfade zu solchen<br />
Dateien müssen in den Tags " der SessionFactory-Konfigurationsdatei angegeben<br />
werden. Für die User-Klasse würde die Mapping-XML-Datei wie folgt aussehen:<br />
<br />
<br />
<br />
<br />
18
KAPITEL 3. ENTWICKLUNG DES SYSTEMS<br />
<br />
<br />
<br />
<br />
<br />
Die bei dem zu entwickelnden System verwendeten Konfigurations- und Mapping-Dateien<br />
können im Anhang B nachgeschlagen werden.<br />
Die SessionFactory-Konfigurationsdatei und die Mapping-XML-Dateien werden - für den<br />
Datenbankzugriff mit Hilfe von “Hibernate“ - einmalig angelegt. Um nun aus dem Programm<br />
auf die Datenbank zugreifen zu können, benötigt man ein Objekt, welches die<br />
Instanz der "SessionFactory"-Klasse aus dem Paket "org.hibernate" ist. Dieses Objekt<br />
wird zum Laden der SessionFactory-Konfigurationsdatei und der Mapping-XML-<br />
Dateien verwendet. Es ist üblich, pro Datenbank jeweils nur ein solches Objekt zu erzeugen.<br />
Für den eigentlichen Zugriff auf die Datenbank wird ein Objekt der Klasse<br />
"Session" desselben Pakets benötigt. Dieses Objekt stellt das Bindeglied zwischen der<br />
Applikation und den “Hibernate“-Diensten dar, indem es Methoden für Insert-, Update-,<br />
Delete- und Query-Operationen bereitstellt. Für jeden Datenbankzugriff wird jeweils ein<br />
"Transaction"-Objekt benötigt, dessen Klasse sich ebenfalls im Paket "org.hibernate"<br />
befindet. Die Verwendung dieser Objekte soll nun anhand eines Quellcodeausschnittes<br />
gezeigt werden.<br />
SessionFactury sessFact = new Configuration().<br />
configure().buildSessionFactory();<br />
Session sess = sessFact.openSession()<br />
Transaction trx = sess.beginTransaction();<br />
sess.save(user1);<br />
trx.commit();<br />
trx = sess.beginTransaction();<br />
sess.save(user2);<br />
trx.commit();<br />
trx = sess.beginTransaction();<br />
User newUser1 = (User) sess.load(User.class, user1.getID());<br />
trx.commit();<br />
trx = sess.beginTransaction();<br />
User newUser2 = (User) sess.load(User.class, user2.getID());<br />
trx.commit();<br />
System.out.println(newUser1.getName());<br />
System.out.println(newUser2.getName());<br />
Zudem ist es möglich, mit dem folgenden Befehl, eine Menge von Objekten als Resultat<br />
einer Datenbankabfrage zu erhalten:<br />
java.util.List moreUsers =<br />
sess.createQuery("from Users where NAME=’Michael’").list();<br />
19
KAPITEL 3. ENTWICKLUNG DES SYSTEMS<br />
Auf den ersten Blick mag es vorkommen, dass die Nutzung von “Hibernate“ aufwendiger<br />
als der Datenbankzugriff mittels JDBC erscheint. Dies liegt an der Erstellung<br />
der SessionFactory-Konfigurationsdatei und der Mapping-XML-Dateien, was auf einen<br />
Mehraufwand für den Benutzer deutet. Diese müssen jedoch nur einmal erstellt werden,<br />
die Einbindung dieser Dateien funktioniert dann automatisch. Vergleicht man hingegen<br />
die beiden Codesequenzen, erkennt man, dass durch den Einsatz von “Hibernate“ die<br />
Implementierung kompakter und intuitiver gestaltet wird. Dies wird dadurch erreicht,<br />
dass das Mapping der Objekte - wie schon erwähnt - von “Hibernate“ übernommen wird<br />
und nicht mehr zu den Aufgaben des Programmierers gehört. Zudem müssen Tabellen<br />
nicht explizit erstellt werden, diese Aufgabe wird beim Erzeugen des "SessionFactory"-<br />
Objektes ebenfalls automatisch von “Hibernate“ übernommen. Vergleicht man nun beide<br />
Verfahren, kommt man zu der Erkenntnis, dass sich JDBC eher für Applikationen mit<br />
wenigen zu implementierenden Datenbankzugriffen eignet. Ist eine Implementierung vieler<br />
verschiedener Datenbankzugriffe erforderlich, so sollte der Einsatz von “Hibernate“<br />
in Betracht gezogen werden.<br />
Eine ausführliche Beschreibung der Funktionsweise von “Hibernate“ kann im [BaKi05]<br />
nachgeschlagen werden.<br />
3.7 ID-Zuweisung<br />
Daten und Objekte, die in einer relationalen Datenbank abgelegt werden, benötigen zur<br />
deren Unterscheidung eindeutige Identifizierer, sogenannte IDs. Das bei der Entwicklung<br />
des Systems verwendete “Hibernate“-Framework bietet die Möglichkeit solche IDs automatisch<br />
erstellen zu lassen. Auf diese Funktion wurde bei der Implementierung jedoch<br />
bewusst verzichtet. Aus Gründen der Übersichtlichkeit und besserer Kontrolle über die<br />
IDs, übernimmt das System deren Verwaltung. Anhand einiger IDs soll der Aufbau bzw.<br />
die Struktur dieser Identifizierer aufgezeigt werden:<br />
alg01- Algorithmus-ID<br />
inp01- Eingabedokument-ID<br />
cfg01- Konfigurationsdokument-ID<br />
exp01- Experiment-ID<br />
Die ersten drei Zeichen beschreiben hierbei den Typ des Dokuments, dem diese ID<br />
zugeordnet ist. Die Nummer, die diesen Zeichen folgt, soll die Einduetigkeit der ID<br />
garantieren. Die Klasse "IDWatcher", die im Paket "de.usi.caew.system" aufzufinden<br />
ist, übernimmt die Verwaltung und die Vergabe der IDs. Für die Vergabe einer neuen<br />
ID bietet sie dokumenttypspezifische Zugriffsmethoden, die bei Bedarf vom System aufgerufen<br />
werden. Für eine solche Anfrage wird hierbei die zum Dokumenttyp passende<br />
Methode aufgerufen. Diese lädt die zuletzt verwendete ID aus der Datenbank und inkrementiert<br />
deren Zahlenwert. Die so gewonnene neue ID wird als Resultat der Anfrage<br />
20
zurückgegeben und der Eintrag der Datenbank aktualisiert.<br />
3.8 Wichtige Variablen des Hauptsystems<br />
KAPITEL 3. ENTWICKLUNG DES SYSTEMS<br />
Die Daten und Dokumente, die zum Durchführen von Experimenten benötigt werden,<br />
speichert das System - wie schon erwähnt - in einer Datenbank persistent. Um mit diesen<br />
Dokumenten arbeiten zu können, müssen sie zunächst in den Hauptspeicher geladen<br />
werden. Hierzu ist es notwendig, solche Daten im Programm in entsprechenden Variablen<br />
des jeweiligen Typs abzulegen. Da das System eine modulare Struktur besitzt und<br />
zum größten Teil aus separaten Plugins besteht, die keinen direkten Zugriff aufeinander<br />
haben, bietet es sich an die Implementierung so zu planen, dass solche Variablen<br />
möglichst zentral gehalten werden. Dies bietet den Vorteil des einfachen Austausches<br />
von benötigten Daten zwischen den einzelnen Plugins. So lag es nahe, eine Klasse des<br />
Hauptsystems für den Ort dieser Variablen zu wählen. Die Klasse "MainSys" des Pakets<br />
"de.usi.caew.system" erwies sich als besonders guter Kandidat für die Platzierung<br />
der Variablen, da alle Plugins direkten Zugriff auf diese Klasse besitzen. Die Ursache<br />
dieses direkten Zugriffs liegt in der Art wie das Programm Plugins einbindet und wird<br />
im Abschnitt 3.9 ausführlich beschrieben. Wie bereits erwähnt werden die Daten in die<br />
entsprechenden Variablen geladen, wenn ein Benutzer auf diese zugreift. Programmbedingt<br />
kann der Benutzer zum selben Zeitpunkt nur jeweils ein Dokument des gleichen<br />
Typs bearbeiten. So ergibt sich, dass für jeden Dokumenttyp, der beim Zugriff des Benutzers<br />
aus der Datenbank in den Hauptspeicher geladen wird, jeweils nur eine Variable<br />
zur Verfügung stehen muss.<br />
Um Dokumente für die Definition eines Testlaufs zur Verfügung zu stellen, müssen diese<br />
zunächst zur einer Auswahl, welche dem Benutzer in Form von mehreren Tabellen<br />
präsentiert wird, hinzugefügt werden. Aus diesen Tabellen kann der Benutzer anschließend<br />
die jeweiligen Dokumente wählen, die er zur Definition eines Testlaufs benötigt. Die<br />
Sammlung dieser Daten wird ebenfalls in einer Variable der Klasse MainSys abgelegt.<br />
Die Definition von Testläufen erzeugt wiederum eine Sammlung von Daten. Da hierbei<br />
die Dokumente einzelner Testläufe strikt voneinander getrennt werden müssen, legt das<br />
Programm diese jeweils in verschiedenen Bereichen eines Vectors 4 der Klasse MainSys<br />
ab. Es folgt nun eine tabellarische Auflistung dieser Variablen.<br />
Name Typ Beschreibung<br />
shownAlgorithm Algorithm Enthält das Algorithmendokument, welches aus<br />
der Exploreransicht der Datenbank ausgewählt<br />
wurde.<br />
shownInputData InputData Enthält das Eingabedokument, welches aus der<br />
Exploreransicht der Datenbank ausgewählt wurde.<br />
4 Hierbei handelt es sich um ein Objekt der Klasse “java.util.Vector“<br />
21
Name Typ Beschreibung<br />
KAPITEL 3. ENTWICKLUNG DES SYSTEMS<br />
shownConfiguration Config Enthält das Konfigurationsdokument, welches aus<br />
der Exploreransicht der Datenbank ausgewählt<br />
wurde.<br />
shownTransformation Transformation Enthält das Stylesheetdokument, welches aus der<br />
Exploreransicht der Datenbank ausgewählt wurde.<br />
shownExperiment Experiment Enthält das Experimentdokument, welches aus<br />
der Exploreransicht der Datenbank ausgewählt<br />
wurde.<br />
shownExpSequence ExpSequence Enthält das Experimentsequenzdokument, welches<br />
aus der Exploreransicht der Datenbank ausgewählt<br />
wurde.<br />
shownContext Context Enthält das Contextdokument, welches bei der<br />
Auswahl eines Experimentes automatisch geladen<br />
wurde.<br />
shownOutputData OutputData Enthält das Ausgabedokument, welches bei der<br />
Auswahl eines Experimentes automatisch geladen<br />
wurde.<br />
shownSchema Schema Enthält das Contextdokument, welches in der<br />
DTD-Ansicht des Programms selektiert wurde.<br />
collectedData Run Enthält Daten, die zu den Auswahltabellen für die<br />
Testlaufdefinition hinzugefügt worden sind.<br />
dataToRun Vector Enthält einen Vector mit den Daten aller<br />
Testläufe, die vom Benutzer definiert wurden.<br />
All diese Variablen besitzen geeignete Zugriffsmethoden, die die Plugins nutzen können<br />
um Werte in ihnen abzulegen oder diese aus ihnen auszulesen.<br />
3.9 Einbindung von Plugins<br />
Wie bereits im Abschnitt 3.3 erwähnt, ist der Aufbau des kompletten Systems in das<br />
Hauptsystem und die einzelnen Plugins aufgeteilt. Zu den Hauptaufgaben des Hauptsystems<br />
gehören einerseits seine Funktion als Server für die Testlaufberechnung, andererseits<br />
die Einbindung weiterer Programmblöcke, welche die Funktionalität des Programms<br />
ergänzen bzw. erweitern sollen - den Plugins. Dieses Kapitel soll nun aufzeigen, wie die<br />
im Abschnitt 3.3 vorgestellten Plugins in das System eingebunden werden.<br />
Zunächst soll das Interface "Plugin", welches sich im Paket "de.usi.caew.system"<br />
befindet, vorgestellt werden. Dieses bietet die folgenden zwei Methoden:<br />
public void setMainFrame(de.usi.caew.gui.MFrame mainFrame);<br />
public void setMainSys(de.usi.caew.system.MainSys mainSys);<br />
22
KAPITEL 3. ENTWICKLUNG DES SYSTEMS<br />
Es ist zwingend notwendig, dass dieses Interface von der Hauptklasse eines jeden Plugins<br />
implementiert wird. Es bildet die Schnittstelle bzw. die Verbindung zwischen dem<br />
Hauptsystem und den einzubindenden Programmblöcken.<br />
Mit der Methode "setMainFrame(...)" wird der Klasse, die das "Plugin"-Interface<br />
implementiert, eine Referenz auf die Hauptklasse der GUI-Verwaltung übergeben. Diese<br />
GUI-Hauptklasse bietet diverse Methoden, die dazu verwendet werden können die GUI-<br />
Elemente des Plugins in die graphische Benutzeroberfläche zu integrieren. Die Methode<br />
"setMainSys(...)" übergibt dem Plugin wiederum eine Referenz auf die Fachkonzept-<br />
Hauptklasse, welche diesem bestimmte Methoden zur Verfügung stellt, mit denen man<br />
den Ablauf des Programms beeinflussen kann. Ein Plugin, welches nach diesen Regeln<br />
entworfen und implementiert wurde, wird vermutlich eine ganze Reihe neuer Klassen<br />
beinhalten. Diese Klassen müssen in einem eigenen Ordner platziert werden. Der Name<br />
dieses Ordners kann frei gewählt werden. Es muss jedoch darauf geachtet werden, dass<br />
der gewählte Name nicht bereits einem der Unterordner des Verzeichnisses Plugin vergeben<br />
wurde. Beim Platzieren der Plugindateien im neuen Ordner muss unbedingt die<br />
Paketstruktur der Klassen beachtet werden. Der neu erstellte Ordner wird anschließend<br />
im Verzeichnis "Plugin" untergebracht.<br />
Das Hauptsystem besitzt zu diesem Zeitpunkt noch keine Kenntnis über den Ort und<br />
Namen der Klasse, die das "Plugin"-Interface implementiert. Damit es diese Informationen<br />
erhalten kann, werden diese in Form einer XML-Datei bereitgestellt. Die XML-Datei<br />
muss in dem neu erstellten Ordner deponiert werden und den Namen "plugin.xml" erhalten.<br />
Der Aufbau dieser Datei wird durch die folgende DTD definiert:<br />
<br />
<br />
<br />
Hierbei wird mit dem Attribut "Name" der Name angegeben, den der Entwickler diesem<br />
Plugin vergeben hat. Zwar ist die Wahl des zu vergebenen Namen beliebig, dennoch<br />
sollte ein Name gewählt werden, der eine ungefähre Aussage über die Funktion des<br />
Plugins liefert. Das Attribut "Classname" beschreibt den Namen der Klasse, die das<br />
"Plugin"-Interface implementiert und somit die Hauptklasse des Plugins darstellt. Sollte<br />
sich die Klasse in einer Paketstruktur befinden, so muss dies entsprechend angegeben<br />
werden. Für eine Klasse mit dem Namen "MyPlugin", welche sich beispielsweise im<br />
Paket "myPackage" befindet, würde die Angabe des "Classname"-Attributes wie folgt<br />
aussehen:<br />
Classname=’mypackage.MyClass’<br />
23
KAPITEL 3. ENTWICKLUNG DES SYSTEMS<br />
Beim Programmstart überprüft das System alle sich im Ordner "plugin" befindlichen<br />
Pluginverzeichnisse. Dabei liest es die jeweiligen "plugin.xml"-Dateien ein und<br />
übernimmt die darin enthaltenen Pluginnamen in eine Tabelle. Diese Tabelle beinhaltet<br />
die Namen aller verfügbaren Plugins und die Information, ob diese auch benutzt werden<br />
sollen. Sie wird vom System auf dem Datenträger gespeichert und bei jedem Starten<br />
des Programms erneut eingelesen. Ist der Zustand eines Plugins auf “nicht anwenden“<br />
gesetzt, so ignoriert das System dieses beim Einlesevorgang. Ein neu erstelltes Plugin<br />
wird dabei immer zunächst mit “nicht anwenden“ markiert. Ein Benutzer mit Administratorrechten<br />
hat die Möglichkeit die Tabelleneinträge jederzeit zu modifizieren. Wird<br />
der Zustand eines Plugins in der Tabelle auf “anwenden“ gesetzt, so wird bei einem<br />
Neustart die Funktionalität des Plugins vom System übernommen.<br />
Um ein Plugin einzulesen übernimmt das System zunächst den Klassennamen, den es<br />
aus der "plugin.xml"-Datei des jeweiligen Plugins bezieht. Diese Klasse wird mittels<br />
eines "URLClassLoader"-Objektes geladen und in einer Variable des Typs "Class" gespeichert.<br />
Da davon ausgegangen werden kann, dass diese Klasse das Interface "Plugin"<br />
implementiert, wandelt das System das Objekt der geladenen Klasse in ein "Plugin"-<br />
Objekt um. Anschließend werden die oben erwähnten Methoden - "setMainFrame(...)"<br />
und "setMainSys(...)" - des Plugins ausgeführt, wobei die Referenzen auf die Objekte<br />
der GUI- und der Fachkonzepthauptklasse übergeben werden. Das Plugin kann diese<br />
Referenzen nun zur Integration seiner Funktionalität in das System nutzen. Abbildung<br />
3.4 soll die Einbindung von Plugins in das System verdeutlichen.<br />
Abbildung 3.4: Vereinfachte Darstellung der Plugineinbindung<br />
24
3.10 Datenaustausch<br />
KAPITEL 3. ENTWICKLUNG DES SYSTEMS<br />
In vorherigen Kapiteln wurde bereits erwähnt, dass die Hauptaufgabe des Systems die<br />
Durchführung von algorithmenbasierenden Experimenten und die Verwaltung derer Resultate<br />
zum Zwecke der Optimierung von Algorithmen ist. Es wurde zudem auch schon<br />
darauf eingegangen, dass eine Verbesserung bzw. Optimierung eines Algorithmus in der<br />
Regel eine Vielzahl von Testläufen mit verschiedenen Benchmarks und Konfigurationen<br />
benötigt. Die Anzahl dieser Testläufe bis hin zu einer möglichst optimalen Implementierung<br />
solcher Algorithmen bzw. der Ermittlung zufriedenstellender Einstellungen der<br />
Konfigurationen steigt dabei oft mit der Komplexität dieser Algorithmen. Das Programm<br />
soll deswegen den Benutzer nicht nur bei der Verwaltung und Ausführung der Experimente<br />
unterstützen, sondern ihm die Möglichkeit bieten, die benötigte Zeit zur Ausführung<br />
der erforderlichen Testläufe zu minimieren. 5 Dies soll dadurch erreicht werden, dass mehrere<br />
Testläufe gleichzeitig auf mehreren Rechnern ausgeführt werden können, welche die<br />
Resultate an das System senden. In diesem Kapitel soll nun diese Funktionalität detailliert<br />
erklärt werden. Zunächst sei erwähnt, dass der Austausch von Daten zwischen den<br />
einzelnen Rechnern auf der “Remote Method Invocation“-Funktionalität, die auch unter<br />
dem Akronym RMI bekannt ist, basiert. Zum besseren Verständnis des netzwerkbasierten<br />
Datenaustauschs des Systems soll zunächst die RMI-Funktionalität des JDK 5 grob<br />
beschrieben werden.<br />
RMI - Remote Method Invocation<br />
Bei der Entwicklung objektorientierter Java-Programme ist bekannt, dass man innerhalb<br />
eines Programms, welches in einer Java-Virtual-Machine (JVM) abläuft, die Methoden<br />
verschiedener Klassen aufrufen kann. Dafür benötigt man lediglich ein Objekt, das eine<br />
Instanz dieser Klasse darstellt. RMI bietet einen ähnlichen Zugriff auf Methoden verschiedener<br />
Klassen, jedoch über die Grenzen der JVM und sogar über Rechnergrenzen<br />
hinaus. Hierzu müssen ein Paar zusätzliche Vorbedingungen erfüllt werden. Eine Klasse,<br />
die eine oder mehrere remote ausführbarer Methoden zur Verfügung stellt, wird als<br />
Server-Klasse bezeichnet, die Instanzen dieser Klasse werden Server-Objekte genannt.<br />
Es ist zwingend notwendig, dass eine sogenannte Remote-Schnittstelle bereitgestellt<br />
wird, welche von der Server-Klasse implementiert wird. Diese Schnittstelle beschreibt<br />
die Methoden, die netzwerkweit ausgeführt werden können. Die Protokolle wie beispielsweise<br />
TCP/IP, die zur Datenübertragung über das Netzwerk benötigt werden, erstellt<br />
der RMICompiler (rmic). Zu diesem Zweck muss die Server-Klasse mit rmic compiliert<br />
werden, worauf automatisch eine so genannte Stub-Klasse erzeugt wird, die diese Kommunikationsprotokolle<br />
einbindet. Um Programme über das Netzwerk miteinander mittels<br />
RMI kommunizieren lassen zu können, ist es notwendig,dass ein zusätzliches Programm<br />
im Hintergrund ausgeführt wird - die RMI-Registry. Die RMI-Registry könnte man auch<br />
als Knotenpunkt bei der Kommunikation zwischen Server und Client bezeichnen. Das<br />
Programm hat die Aufgabe, auf die Anfragen von angemeldeten Clients, die über einen<br />
5 Mit “minimieren“ ist hier eine Verkürzung der Zeit gemeint. Es ist nicht garantiert, dass durch die<br />
Verwendung dieses Systems wirklich eine minimale Zeit zur Durchführung der Testläufe erreicht wird.<br />
25
KAPITEL 3. ENTWICKLUNG DES SYSTEMS<br />
vordefinierten Netzwerk-Port ankommen, zu warten und diese dann an angemeldete Server<br />
weiterzuleiten. Genauso funktioniert es in die entgegengesetzte Richtung: die vom<br />
Server berechneten Resultate werden von der RMI-Registry weiter an die Clients geleitet.<br />
Die RMI-Registry liegt dem JDK bei und kann von dort aus gestartet werden. Es<br />
ist jedoch notwendig diesem Zusatzprogramm mitzuteilen, in welchem Ordner die mit<br />
Hilfe von rmic erstellten Stub-Klassen aufzufinden sind.<br />
Ein Aufruf von RMI-Registry könnte unter Linux beispielsweise folgendermassen aussehen:<br />
rmiregistry -J-Djava.class.path=’myProject/myStubClasses/’<br />
Bei der Implementierung der Server-Klasse ist es wichtig, dass diese entweder von der<br />
Klasse "UnicastRemoteObject", welche sich im Paket "java.rmi.server" des JDK<br />
befindet, abgeleitet ist oder sie beim initialisieren die statische Methode<br />
"exportObject(java.rmi.Remote)" der Klasse "UnicastRemoteObject" mit sich selbst<br />
als Argument aufruft. Die so erstellte Server-Klasse muss sich als nächstes bei der RMI-<br />
Registry anmelden. Dies geschieht über den Aufruf der Methode "rebind" der Klasse<br />
"Naming", welche sich im Paket "java.rmi" des JDK befindet. Als erster Parameter ist<br />
bei dieser Methode die URL des Servers anzugeben. Die als String übergebene URL hat<br />
die folgende Form: "rmi://Hostname/Servicename". Dabei beschreibt "rmi://" das<br />
zu verwendende Protokoll, "Hostname" den Namen des Servers und "ServiceName" den<br />
Namen der Verbindung über welchen potentielle Clients die RMI-Registry kontaktieren<br />
können. Als zweiter Parameter wird der "rebind"-Methode die Server-Klasse selbst<br />
übergeben. Ein Aufruf dieser Methode könnte beispielsweise folgendermaßen aussehen:<br />
Naming.rebind("rmi://MyServer.MyIdentification", this);<br />
Bei der Implementierung einer Client-Klasse ist darauf zu achten, dass sich diese ebenfalls<br />
bei der RMI-Registry anmeldet, jedoch mit der "lookup"-Methode der Klasse "Naming".<br />
Dieser Methode muss lediglich die URL des Servers in der vorhin beschriebenen Form<br />
übergeben werden. Sie liefert als Rückgabewert ein Objekt vom Typ der Schnittstelle,<br />
welche von der Server-Klasse implementiert wird. Über dieses Objekt kann man in<br />
der gewohnten Art der objektorientierten Programmierung auf die Remote-Methoden<br />
der Server-Klasse zugereifen. Ein Aufruf der "lookup"-Methode und ein anschließender<br />
Aufruf einer Remote-Methode des Servers könnte wie folgt aussehen:<br />
ServerInterface server =<br />
(ServerInterface)Naming.lookup("rmi://MyServer.MyIdentification");<br />
String result = server.myRemoteMethod();<br />
26
Netzwerkkommunikation des Systems<br />
KAPITEL 3. ENTWICKLUNG DES SYSTEMS<br />
Das zu entwickelnde System unterteilt sich, zwecks der Verteilung der Testläufe auf verschiedene<br />
Rechner, in einen Client- und einen Server-Part. Der Client ist dabei, aus der<br />
Sicht des Benutzers, das Programm selbst. Der Server wiederum läuft im Hintergrund<br />
als eigenständiger Thread bzw. als eine andere Instanz des Systems auf einem anderen<br />
Rechner. Das System startet das von RMI geforderte Hintergrundprogramm RMI-<br />
Registry automatisch beim Starten. Hierfür wird ein eigenständiger Prozess erweckt,<br />
in welchem das Zusatzprogramm ausgeführt werden kann. Zudem wird beim Start des<br />
Systems die Funktionalität des Servers als eigenständiger Thread gestartet. Die Server-<br />
Klasse "RunServer", welche sich im Paket "de.usi.caew.rmi" des Hauptsystems befindet,<br />
implementiert die speziell hierfür entworfene Schnittstelle "ServerInterface"<br />
des gleichen Pakets. Diese Schnittstelle beschreibt die folgenden Methoden:<br />
public void setExeVec(Vector exeVec) - dient zur Übertragung des Algorithmus-<br />
Programms in Form von einem oder mehreren Byte-Arrays.<br />
public void setInputVec(Vector inputVec) - dient zur Übertragung der eigentlichen<br />
Eingabedateien in Form von einem oder mehreren Byte-Arrays.<br />
public void setConfigVec(Vector configVec) - dient zur Übertragung der eigentlichen<br />
Konfigurationsdateien in Form von einem oder mehreren Byte-Arrays.<br />
public void setTrnfVec(Vector trnfVec) - dient zur Übertragung der eigentlichen Stylesheetdateien<br />
in Form von einem oder mehreren Byte-Arrays.<br />
public void setBuildVec(Vector buildVec) - dient zur Übertragung der vom Algorithmus<br />
benötigten Zusatzbibliotheken in Form von einem oder mehreren Byte-Arrays.<br />
public void setBuildDirVec(Vector buildDirVec) - dient zur Übertragung der vom<br />
Algorithmus benötigten Ordner in Form von einem oder mehreren Byte-Arrays.<br />
public void setConfigDTD(Vector configDTD) - dient zur Übertragung der Schemata<br />
bzw. DTDs, die zur Beschreibung der Eingabedokumente benötigt werden, in Form von<br />
einem oder mehreren Byte-Arrays.<br />
public void setInputDTD(Vector inputDTD) - dient zur Übertragung der Schemata<br />
bzw. DTDs, die zur Beschreibung der Konfigurationsdokumente benötigt werden, in<br />
Form von einem oder mehreren Byte-Arrays.<br />
public void setTrnfDTD(Vector trnfDTD) - dient zur Übertragung der Schemata bzw.<br />
DTDs, die zur Beschreibung der Stylesheetdokumente benötigt werden, in Form von<br />
einem oder mehreren Byte-Arrays.<br />
public Result runAlgorithm(Run run) - dient zum Starten des Testlaufs auf dem Server.<br />
Als Rückgabewert wird ein Objekt vom Typ "de.usi.caew.system.Result" geliefert,<br />
welches die relevanten Informationen zum abgeschlossenen Testlauf beinhaltet.<br />
public String getServerName() - dient zum Erfragen des Servernamens auf dem der<br />
Testlauf durchgeführt werden soll.<br />
public String getOS() - dient zum Erfragen des Betriebssystems des Rechners auf dem<br />
der Server ausgeführt wird.<br />
public boolean isBuisy() - dient zum Erfragen des Bereitschaftszustandes des Servers.<br />
27
KAPITEL 3. ENTWICKLUNG DES SYSTEMS<br />
Die Serverklasse ruft beim Initialisiarungsprozess die geforderte statische Methode<br />
"exportObject(java.rmi.Remote)" der Klasse<br />
"java.rmi.server.UnicastRemoteObject" auf. Anschließend meldet sie sich mit dem<br />
nachfolgenden Aufruf bei der RMI-Registry an und steht für die Aufträge potenzieller<br />
Clients zur Verfügung.<br />
Naming.rebind("rmi://"+<br />
InetAddress.getLocalHost().getHostName()+"/CAEWServer", this);<br />
Die Funktionalität des Clients gehört nicht mehr zu der Funktionalität des Hauptsystems,<br />
sondern wird als Plugin mit dem Namen "Run-Plugin" in das System integriert.<br />
Dies bietet den Vorteil, diese Funktionalität relativ einfach verändern, aktualisieren bzw.<br />
ersetzen zu können. Das System aktiviert die Client-Funktion erst nachdem ein Benutzer<br />
einen bzw. eine Reihe von Testläufen definiert hat und den Befehl zur Berechnung dieser<br />
gegeben hat. Die definierten Testläufe befinden sich in einer tabellarisch strukturierten<br />
Anordnung in einem Vector. 6 Wurde nun der Befehl erteilt eine Reihe von Testläufen<br />
zu starten, beschafft das System die vom Benutzer erstellte Liste der Servernamen, die<br />
für Testlaufberechnungen zur Verfügung stehen. Nach einer Verbindungsprüfung wird<br />
als nächstes zu jedem Server, der in der Liste als verfügbar eingetragen ist, ein Client-<br />
Objekt 7 erstellt. Somit ist jedem Client-Objekt genau ein Server zugeteilt mit dem dieser<br />
kommuniziert. Als nächstes werden diese Client-Objekte an ein Scheduler-Objekt<br />
des Typs "runPlugin.de.usi.caew.rmi.ServerScheduler" übergeben, welches unter<br />
anderem die Aufgabe hat, die definierten Testläufe an die einzelnen Clients zu verteilen.<br />
Das Scheduler-Objekt startet anschließend die Ausführung der einzelnen Client-Objekte,<br />
die als eigenständige Threads ausgeführt werden und wartet auf deren Anfragen.<br />
Nachdem ein Client-Objekt als eigener Thread gestartet wurde, fordert es beim Scheduler-<br />
Objekt den nächsten anstehenden Testlauf an.<br />
Um zu vermeiden, dass eine fehlerhafte Zuteilung von Testläufen an die Clients auftritt<br />
- wie beispielsweise das Berechnen der selben Läufe auf mehreren Servern zur gleichen<br />
Zeit oder das mehrmalige Zuteilen des gleichen Testlaufs an den selben Client - besitzen<br />
die definierten Testläufe zusätzliche Informationen. Diese Informationen stehen in Form<br />
einer Integer-Variablen bei jedem Testlauf zur Verfügung und geben den Zustand dieses<br />
Testlaufs an. Dabei haben die Zustände folgende Bedeutungen:<br />
0 - Testlauf bereit zur Vergabe an nächsten Client um die Berechnung zu durchlaufen.<br />
1 - Testlauf wird zur Zeit berechnet.<br />
2 - Testlauf wurde bereits erfolgreich berechnet<br />
Zudem übermittelt jeder Client bei der Anfrage an den Scheduler eine Liste der Testläufe,<br />
6 Objekte der Klasse java.util.Vector bieten eine ähnliche Funktionsweise wie Arrays. Somit ist es<br />
möglich, Werte bzw. Objekte in ihnen abzulegen und auf diese zuzugreifen.<br />
7 Die Client-Objekte sind Instanzen der Klasse “RunClient“, die im Paket “runPlugin.de.usi.caew.rmi“<br />
des Run-Plugins zu finden ist.<br />
28
KAPITEL 3. ENTWICKLUNG DES SYSTEMS<br />
deren Durchführung auf seinem zugeordneten Server bereits versucht worden ist. Aus<br />
diesen Informationen kann der Scheduler bestimmen welcher Testlauf an welches Client-<br />
Objekt weitergeleitet werden kann bzw. wann die Berechnung aller Testläufe abgeschlossen<br />
ist.<br />
Hat ein Client einen Testlauf zugeordnet bekommen, vermerkt er dies als allererstes, indem<br />
er dessen ID zu der Liste der versuchten Testläufe hinzufügt. Als nächstes nimmt er<br />
die Verbindung mit dem ihm zugeordneten Server auf. Dies geschieht durch den Aufruf<br />
der RMI-Methode "lookup". Der Methodenaufruf sieht folgendermaßen aus:<br />
ServerInterface server =<br />
(ServerInterface)Naming.lookup("rmi://"+serverName+"/CAEWServer");<br />
Wurde eine Verbindung erfolgreich aufgebaut, wird als nächstes der Status des Servers<br />
mit der Remote-Methode "server.isBuisy()" abgefragt. Ist dieser mit der Berechnung<br />
eines anderen Testlaufs, welcher ihm als Auftrag durch eine andere Instanz<br />
des Programms erteilt wurde, beschäftigt, wird solange abgewartet bis der Server das<br />
“Ready“-Signal zurückliefert. Ist der Server nicht beschäftigt, wird zunächst der Status<br />
des Testlaufs auf “Testlauf wird berechnet“ gesetzt. Als nächstes wird mit Hilfe der<br />
Remote-Methode "server.getOS()" das Betriebssystem des Rechners, auf dem der Server<br />
ausgeführt wird, abgefragt. Ist das Betriebssystem nicht kompatibel zu den Einstellungen<br />
des Algorithmus des Testlaufs, wird die Verbindung an dieser Stelle abgebrochen<br />
und die Zuweisung des nächsten Testlaufs beim Scheduler angefordert. Ist das Betriebssystem<br />
jedoch kompatibel, beginnt der eigentliche Datenaustausch zwischen Client und<br />
Server.<br />
Der erste Schritt ist hierbei die Übertragung aller relevanter Daten zum Server. Hierfür<br />
ruft der Client die Remote-Methoden des Servers auf, die für die Datenübermittlung<br />
zuständig sind:<br />
server.setExeVec(exeVec);<br />
server.setInputVec(inputVec);<br />
server.setConfigVec(configVec);<br />
server.setTrnfVec(trnfVec);<br />
server.setBuildVec(buildVec);<br />
server.setBuildDirVec(buildDirVec);<br />
server.setInputDTD(inputDTD);<br />
server.setConfigDTD(configDTD);<br />
server.setTrnfDTD(trnfDTD);<br />
Als Argumente werden hierbei Vectoren übergeben, welche die relevanten Daten in Form<br />
von Byte-Arrays beinhalten.<br />
Ist die Datenübertagung abgeschlossen, wird die Remote-Methode "server.run()" gestartet,<br />
die den Server anweist, die Berechnung des Testlaufs zu beginnen. Während<br />
die Berechnung durch den Server andauert, befindet sich der Client im Wartemodus.<br />
Ist der Testlauf nach der benötigten Zeit abgeschlossen, sammelt der Server alle relevanten<br />
Informationen zum Testlauf in Form eines "Result"-Objektes. Dieses Objekt<br />
29
KAPITEL 3. ENTWICKLUNG DES SYSTEMS<br />
bietet die entsprechenden Variablen und Methoden zur Speicherung dieser Werte. Anschließend<br />
wird das "Result"-Objekt als Rückgabewert der vom Client aufgerufenen<br />
"server.run()"-Methode an den Client zurück übertragen.<br />
Ist die Berechnung korrekt abgelaufen, setzt der Client den Status des Testlaufs auf<br />
“Testlauf wurde bereit erfolgreich berechnet“. War die Berechnung jedoch fehlerbehaftet,<br />
so setzt der Client den Status des Testlaufs auf “Testlauf bereit zur neuen Vergabe“.<br />
Als letzter Schritt wird das Result-Objekt an den Scheduler zur weiteren Verarbeitung<br />
übergeben und der nächste Testlauf beim Scheduler angefordert.<br />
Der Ablauf wiederholt sich solange, bis alle Testläufe an alle Clients zur Berechnung<br />
übergeben worden sind und dies mit einer erfolgreichen Berechnung oder einem Fehler<br />
endete.<br />
Die folgende Abbildung zeigt nochmals die wichtigsten Schritte bei der Kommunikation<br />
zwischen Scheduler, Client und Server.<br />
Abbildung 3.5: Vereinfachte Darstellung vom Ablauf des Datenaustauschs zwischen<br />
Scheduler, Client und Server<br />
30
3.11 Sprachunterstützung<br />
KAPITEL 3. ENTWICKLUNG DES SYSTEMS<br />
Eine der Anforderungen, die an das System gestellt worden sind, war die Unterstützung<br />
von mehr als nur einer Sprache, mit der Möglichkeit der modularen Erweiterung der unterstützten<br />
Sprachen. Dies wird mit Hilfe der Java-Internationalization-Funktionalität<br />
gewährleistet. Java-Internationalization ist auch unter dem Akronym “i18n“ bekannt,<br />
welches darauf zurückzuführen ist, dass sich zwischen dem ersten Buchstaben “i“ und<br />
dem letzten Buchstaben “n“ des Wortes “internalization“ genau achtzehn zusätzliche<br />
Buchstaben befinden. “i18n“ bietet die Möglichkeit, bei Textausgaben - beispielsweise<br />
bei einer graphischen Oberfläche - zwischen verschiedenen Sprachen zu wechseln ohne<br />
den Quellcode verändern zu müssen. Mit dieser Funktionalität kann - vorausgesetzt,<br />
dass das Programm entsprechend implementiert worden ist - sogar während des Ablaufs<br />
des Programms die textuelle Sprachausgabe umgeschaltet werden. Um “i18n“ nutzen zu<br />
können, ist es erforderlich für jede verwendete Sprache eine Textdatei zu erstellen, die<br />
die im Programm verwendeten Strings beinhaltet. Diesen Strings müssen zudem Identifizierungsschlüssel<br />
vergeben werden. Diese Schlüssel können beliebige Zeichenketten sein.<br />
Es ist jedoch darauf zu achten, dass jeder Schlüssel exakt nur ein mal in dieser Datei<br />
verwendet wird. Der Aufbau dieser Datei gestaltet sich nach folgendem Muster:<br />
key1=String1<br />
key2=String2<br />
key3=String3<br />
.<br />
.<br />
.<br />
Diese Dateien werden, wie schon erwähnt, für alle gewünschten Sprachen erstellt, wobei<br />
darauf zu achten ist, dass in jeder Version der Datei exakt die gleichen Schlüssel vorkommen<br />
und den Schlüsseln Strings mit gleicher Bedeutung zugewiesen werden. Nach der<br />
Fertigstellung dieser Dateien werden sie in einem vom Programm erreichbaren Ordner<br />
abgespeichert. Dabei müssen die Namen der Dateien nach folgendem Muster vergeben<br />
werden:<br />
Dateiname_SK_LK.properties<br />
Hierbei kann für den Platzhalter Dateiname ein beliebiger Name eingesetzt werden,<br />
dieser muss jedoch bei allen Versionen der Sprachdatei gleich sein. SB steht für den<br />
Sprach-Kennbuchstaben, der beispielsweise für englisch en ist und für deutsch de. LB<br />
hat eine ähnliche Bedeutung - es steht für den Länder-Kennbuchstaben. Für die meisten<br />
Länder entspricht dieser dem SK, wird jedoch in Großbuchstaben geschrieben. Mit dem<br />
LB wird die Möglichkeit geboten, zwischen verschiedenen Sprachdialekten unterscheiden<br />
zu können. So wird beim “englichen Englisch“ der Länder-Kennbuchstabe EN verwendet<br />
und beim “amerikanischen Englisch“ der Länder-Kennbuchstabe US. Die Endung<br />
“.properties“ muss genauso übernommen werden wie in dem Beispiel gezeigt.<br />
31
KAPITEL 3. ENTWICKLUNG DES SYSTEMS<br />
Im Programm selbst müssen nun zwei Objekte erzeugt werden. Als erstes ein<br />
"java.util.Locale"-Objekt, das die Informationen über die eingestellte Sprache beinhaltet.<br />
Dieses wird als Resultat des folgenden Aufrufs erstellt:<br />
Locale locale = new Locale(langStr, countryStr);<br />
Dem Konstruktor dieser Klasse werden beim Erstellen des Objekts die beiden Kennbuchstaben<br />
SK und LK einer der erzeugten Sprachdateien übergeben. Diese werden<br />
beispielsweise in dem zu entwickelnden System aus einer XML-Datei eingelesen. Die<br />
richtigen Kennbuchstaben werden mit Hilfe einer Abfragefunktion der graphischen Oberfläche<br />
ermittelt.<br />
Hiernach wird ein Objekt des Typs "java.util.ResourceBundle" mittels des folgenden<br />
Befehls beschafft:<br />
ResourceBundle ressBundle =<br />
ResourceBundle.getBundle(Dateiname,locale);<br />
Um das Objekt zu beschaffen, muss - wie oben gezeigt - die statische Methode der Klasse<br />
"ResourceBundle" aufgerufen werden. Bei diesem Aufruf werden zum einen der durch<br />
den Platzhalter Dateiname dargestellte Dateiname, welcher bei der Namensvergabe der<br />
einzelnen Sprachdateien verwendet wurde, zum anderen das erzeugte "Locale"-Objekt<br />
übergeben. Das "ResourceBundle"-Objekt dient zur Verknüpfung der Kennbuchstaben<br />
und der entsprechenden Textdateien. Das so erstellte "ResourceBundle"-Objekt kann<br />
nun zum Besorgen der gewünschten Zeichenketten verwendet werden. Hierzu wird der<br />
im folgenden Beispiel aufgezeigte Aufruf verwendet:<br />
String text = ressBundle.getString("key1");<br />
Der "getString"-Methode des "ResourceBundle"-Objektes wird hierbei der Schlüssel<br />
einer in der Sprachdatei gespeicherten Zeichenkette als String übergeben.<br />
Zur Unterstützung der “i18n“-Funktionalität befindet sich im Paket "de.usi.caew.lang"<br />
die Klasse "Lang", welche die beschriebenen Aufgaben beim Starten des Systems erledigt.<br />
Sie bietet zudem die statische Funktion<br />
"public static String getString(String key)", die mögliche Anfragen an das<br />
"ResourceBundle"-Objekt und die Ergebnisse an die anfragende Instanzen weiterleitet.<br />
32
3.12 Speicherung von Systeminformationen<br />
KAPITEL 3. ENTWICKLUNG DES SYSTEMS<br />
Bei der Nutzung des Systems werden Daten und Informationen erzeugt, die auf geeignete<br />
Weise persistent gespeichert werden müssen. Wie schon erwähnt, legt das System<br />
Dokumente und Daten, die ein Benutzer erstellt oder importiert bzw. vom System generieren<br />
lassen hat, in einer relationalen Datenbank ab, auf welche mit den Funktionen<br />
des Hibernate-Frameworks zugegriffen werden kann. Neben diesen Daten ergeben sich<br />
bei der Benutzung des Systems jedoch noch andere Informationen, die nicht unbedingt<br />
in einer Datenbak abgelegt werden sollten. Zu diesen Informationen zählen:<br />
• das Flag, welches angibt ob das System im Einzelnutzer- oder Mehrbenutzermodus<br />
betrieben wird<br />
• die Liste aller verfügbaren Plugins; mit der zusätzlichen Information, die angibt,<br />
welche der Plugins für den Betrieb genutzt werden sollen<br />
• die Liste aller Server; mit der zusätzlichen Information, die angibt, welche der<br />
Server für die Berechnung von Testläufen genutzt werden sollen<br />
• zusätzliche Systeminformationen, wie beispielsweise die Liste von definierten Interpretern,<br />
die für den Import von Algorithmen benötigt wird<br />
Da die Entwicklung des Einzelnutzersystems bereits mit dem Gedanken erfolgte, den<br />
Entwurf des Mehrbenutzersystems zu erleichtern und zu unterstützen, lag es nahe, die<br />
aufgezeigten Systeminformationen nicht Global in der Datenbank, sondern eher zentral<br />
auf dem Rechner, auf dem das Programm ausgeführt wird, zu speichern. Für diesen<br />
Zweck wurde die Klasse "SysInfo", die sich im Paket<br />
"de.usi.caew.system" befindet, implementiert. Diese stellt Variablen und Methoden<br />
zur Verfügung um die besagten Informationen in ihr abzuspeichern. Um das Objekt der<br />
Klasse "SysInfo" jedoch persistent zu speichern, wird die Funktionalität der Serialisierung<br />
des JDK genutzt. Hierzu befinden sich in der Klasse "MainSys" des gleichen<br />
Pakets zwei statische Methoden, welche von dem Hauptsystem und allen Plugins jederzeit<br />
aufgerufen werden können um das Objekt vom Datenträger zu laden bzw. um es<br />
abzuspeichern. Der Aufbau der Funktion zum Laden sieht wie folgt aus:<br />
public static SysInfo loadSysInfo()<br />
{<br />
java.io.FileInputStream fi =<br />
new java.io.FileInputStream("SystemData/system.sav");<br />
ObjectInputStream oi = new ObjectInputStream(fi);<br />
SysInfo sysInfo = (SysInfo)oi.readObject();<br />
oi.close();<br />
return sysInfo;<br />
}<br />
33
Die statische Speicherfunktion hat einen ähnlichen Aufbau:<br />
KAPITEL 3. ENTWICKLUNG DES SYSTEMS<br />
public static void saveSysInfo(SysInfo sysInfo)<br />
{<br />
java.io.FileOutputStream fs =<br />
new java.io.FileOutputStream("SystemData/system.sav");<br />
ObjectOutputStream os = new ObjectOutputStream(fs);<br />
os.writeObject(sysInfo);<br />
os.close();<br />
}<br />
Wie man an der Implementierung erkennen kann, befindet sich die abgespeicherte Datei<br />
im Ordner "SystemData" und trägt den Namen "system.sav".<br />
3.13 Aufbau der graphischen Oberfläche<br />
Um dem Benutzer eine möglichst intuitive und leicht bedienbare Benutzung des Programms<br />
zu ermöglichen, wird für die Interaktion zwischen dem System und dem Benutzer<br />
eine graphische Oberfläche vom System bereitgestellt. Die Nutzung von graphischen<br />
Oberflächen, die auch unter dem Akronym “GUI“ bekannt sind, gehört heutzutage zum<br />
Standard bei der Implementierung der meisten Softwarewerkzeuge. Der Hauptgrund<br />
hierfür ist die Tatsache, dass die Bedienung mittels graphischer Oberfläche dem Anwender<br />
eine komfortable Möglichkeit bietet, mit dem System zu interagieren. Systeme<br />
die auf eine GUI-Schnittstelle verzichten, bieten oft als Alternative der Kommunikation<br />
zwischen Anwender und System die Nutzung der angebotenen Funktionen mittels<br />
Kommandozeileneingabe. Dies geschieht mit Hilfe eines speziell dafür bereitgestellten<br />
Terminals, welches meist auch die Funktion der visuellen Ausgabe der Resultate übernimmt.<br />
Diese Art der Interaktion erfordert in der Regel eine relativ lange Phase der<br />
Einarbeitung, da hierbei oft eine ganze Reihe von werkzeugspezifischen textuellen Befehlen<br />
erlernt werden muss, welche für die Bedienung erforderlich sind. Da zudem die<br />
Bedienung bestimmter Funktionen mittels Kommandozeile in der Regel nicht intuitiv<br />
ist, ist diese Art der Interaktion für den Anwender wenig attraktiv. Aus den genannten<br />
Gründen scheint sich der Einsatz solcher Eingabefunktionalität eher für weniger umfangreiche<br />
Softwaresysteme zu eignen. Solche Systeme bieten oft relativ wenig Funktionalität,<br />
weswegen die Entwicklung einer graphischen Oberfläche den Aufwand der Implementierung<br />
des Fachkonzepts deutlich überwiegen würde.<br />
Das im Rahmen dieser Diplomarbeit zu entwickelnde System bietet, mit der in den vorherigen<br />
Abschnitten erwähnten Funktionalität, einen relativ großen Umfang an verschiedenen<br />
vom Benutzer aufrufbaren Funktionen. Dies und die Tatsache, dass die mittels des<br />
Programms errechneten Testlaufresultate dem Benutzer in geeigneter und übersichtlicher<br />
Weise präsentiert werden sollen, macht die Einbindung einer graphischen Oberfläche unverzichtbar.<br />
Bei der Wahl der gebotenen Softwarebibliotheken, welche die Entwichklung von graphischen<br />
Benutzerschnittstellen unterstützen, wurde bei der Implementierung dieses<br />
34
KAPITEL 3. ENTWICKLUNG DES SYSTEMS<br />
Systems auf die Graphikbibliothek “Swing“, welche mit dem JDK 5 mitgeliefert wird,<br />
zurückgegriffen. Diese Bibliothek bietet eine ganze Reihe von graphischen Elementen, die<br />
als leichtgewichtige Komponenten bezeichnet werden und bei der GUI-Entwicklung in<br />
das Programm eingebunden werden können. Die Bezeichnung “leichtgewichtige Kompnenten“<br />
beruht auf der Eigenschaft dieser Elemente, nicht mit Hilfe nativer Methoden<br />
des Betriebssystems, sondern von Java selbst gerendert zu werden. Die Vorteile, die<br />
sich daraus ergeben, sind zum einen die Möglichkeit einem Programm auf verschiedenen<br />
Plattformen - unabhängig vom Betriebssystem - gleiches Aussehen zu verleihen<br />
und zum anderen die Option die Optik der Swing-Komponenten zwischen vordefinierten<br />
Look-and-Feels[Sun99] zu wechseln. Mit Look-and-Feel wird das Erscheinungsbild und<br />
Verhalten von Swing-Komponenten bezeichnet, welche durch den Entwickler selbst definiert<br />
werden können. Die “Cooperative Algorithm Engineering Workbench“ nutzt die<br />
dem JDK 5 beiliegenden Look-and-Feels “Metal-Look-and-Feel“, “Motif-Look-amd-Feel“<br />
und “Windows-Look-and-Feel. Das letztgenannte Look-and-Feel ist jedoch aus rechtlichen<br />
Gründen nur bei der Verwendung des Programms unter Windows-Betriebssystemen<br />
auswählbar.<br />
Graphische Oberfläche des Systems<br />
Bei der Entwicklung des Aufbaus der graphischen Oberfläche musste, aufgrund der modularen<br />
Architektur des kompletten Systems, darauf geachtet werden, diese Struktur zu<br />
unterstützen. Dies wird mit Hilfe einer hierbei eingesetzten Container-Architektur sichergestellt.<br />
Diese Architektur bietet als Basis ein graphisches Element, meist ein Fenster<br />
bzw. Frame, das als Container betrachtet werden kann, welcher diverse andere graphische<br />
Elemente in seine innere Struktur aufnehmen kann. Um solche Elemente einbinden<br />
zu können, bietet der Container eine Reihe von geeigneten Funktionen bzw. Methoden.<br />
Durch den Aufruf solcher Methoden wird der Container dazu veranlasst, neue Komponenten<br />
aufzunehmen, deren derzeitige Position zu verändern oder bereits enthaltene<br />
Komponenten zu entfernen. Diese Art der GUI-Programmierung kann sehr gut dazu<br />
eingesetzt werden im nachhinein graphische Elemente einzubinden, die zur Zeit der Erstellung<br />
des Systems noch nicht verfügbar waren und die erst mit der Integration der<br />
Funktionalität eines Plugins dem Programm zur Verfügung gestellt werden.<br />
Bei der Implementierung der “CAEW“ wurde dieses Prinzip aufgegriffen, indem bei<br />
der Entwicklung der GUI-Struktur die benannte Methodik angewandt wurde. Als Container,<br />
der die Basis bildet, fungiert hierbei ein graphisches Fenster, welches eine Instanz<br />
der Klasse "JFrame" darstellt. Diese und andere Klassen, welche die jeweiligen<br />
Swing-Komponenten definieren, befinden sich im Paket "javax.swing" des JDK.<br />
Der Container wird hierbei als Hauptfenster angesehen und ist ein Objekt der Klasse<br />
"usi.caew.gui.MFrame" des Hauptsystems. Das Hauptfenster wird in drei Untersektionen<br />
aufgeteilt, die jeweils verschiedene Funktionsbereiche des Systems visualisieren<br />
sollen. Der Gedanke dabei ist, einen Teil des Fensters zur Anzeige eines Explorers 8<br />
8 Der Begriff Explorer bezeichnet in diesem Zusammenhang einen graphischen Dateimanager, der den<br />
Zugriff auf Dateisysteme bzw. Datenbanken visualisiert.<br />
35
KAPITEL 3. ENTWICKLUNG DES SYSTEMS<br />
für den Zugriff auf die Datenbank bereitzustellen. Der Zweite Teil des Hauptfensters<br />
soll zur detaillierten Ansicht der ausgewählten Dokumente aber auch zur Visualisierung<br />
diverser Arbeitsabläufe dienen. Der dritte und letzte Bereich soll der textuellen Erfassung<br />
der Arbeitsabläufe zur Verfügung gestellt werden. Nach der Initialisierung sieht die<br />
geometrische Anordnung der Bereiche wie folgt aus: Die komplette Hauptfensterdarstellungsfläche<br />
teilt sich zunächst horizontal in zwei Bereiche, wobei die untere Sektion ca.<br />
ein Viertel der Gesamtfläche zugeordnet bekommt. Die textuelle Erfassung von Arbeitsabläufen<br />
wird in diesem Bereich graphisch ausgegeben.<br />
Der obere Bereich teilt sich vertikal in zwei separate Gebiete. Der linke Bereich wird<br />
dabei für die Explorer-Ansicht reserviert, der rechte wird der Detail-Ansicht zugewiesen.<br />
Die Unterteilung in die jeweiligen Bereiche wird mit Hilfe von Objekten der Swing-Klasse<br />
"JSplitPane" realisiert.<br />
Um der Visualisierung der Swing-Elemente der zwei erstgenannten Bereiche eine geeignete<br />
Umgebung zur Verfügung zu stellen, werden in diese Untersektionen virtuelle Areale<br />
eingebunden, welche die Integration von bestimmten graphischen Elementen erlauben.<br />
Diese Areale sind Objekte der Swing-Klasse "JTabbedPane" und bieten die Möglichkeit,<br />
Objekte des Typs "JPanel" als durch Reiter anwählbare Graphikflächen einzubinden.<br />
Ein "JPanel"-Objekt ist wiederum die einfachste Form einer Fläche zur Darstellung aller<br />
graphischen Swing-Elemente. Der untere Bereich, der für die textuelle Erfassung von<br />
Arbeitsabläufen reserviert ist und auch als Log-Bereich bezeichnet wird, bekommt als<br />
Textdarstellungsfläche ein Objekt des Swing-Typs "JTextArea" zugewiesen. Der Log-<br />
Bereich ist als einziger der drei Bereiche nicht dazu geeignet graphische Elemente darzustellen.<br />
Das Hauptfenster stellt jedoch Methoden zur Verfügung, mit denen textuelle<br />
Nachrichten in diesem Bereich angezeigt werden können. Damit ein potentielles Plugin<br />
die Möglichkeit bekommt seine graphischen Elemente einzubinden, bietet das Hauptfenster<br />
die folgenden Funktionen:<br />
• public JTabbedPane getMainView()<br />
• public JTabbedPane getTreeView()<br />
• public void updateLog()<br />
Zudem wird in der Klasse "de.usi.caew.MainSys" die folgende Methode zur Verfügung<br />
gestellt:<br />
• public void updateLog(String text)<br />
Ein Plugin, welches graphische Elemente in der Detaillansicht anzeigen soll, muss zunächst<br />
ein Objekt des Typs "JPanel" erstellen, in dem er seine graphischen Elemente entsprechend<br />
platziert. Durch den Aufruf der Methode "getMainView()" erstellt das Plugin<br />
eine Referenz auf das "JTabbedPane"-Objekt des Hauptfensters. Anschließend ruft es<br />
die von der "JTabbedPane"-Klasse angebotene Methode<br />
"addTab(String tabname, Object jpanel);" auf. Der erste Parameter, der hierbei<br />
übergeben wird, stellt den Namen des Reiters dieser Ansicht dar. Als zweiter Parameter<br />
wird das erstellte "JPanel"-Objekt übergeben. Mit dieser Methode wird das "JPanel"<br />
36
KAPITEL 3. ENTWICKLUNG DES SYSTEMS<br />
mit all seinen enthaltenen Elementen zu der Detaillansicht hinzugefügt und kann über<br />
den Reiter mit dem als String übergebenen Namen angewählt werden.<br />
Der Ablauf des Hinzufügens graphischer Elemente zur Explorer-Ansicht verhält sich<br />
analog, wobei hier die Methode "getTreeView()" des Hauptfensters aufgerufen werden<br />
muss.<br />
Soll durch das Plugin die Ausgabe des Log-Bereichs aktualisiert werden, muss zunächst<br />
die Methode updateLog(String text) der "MainSys"-Klasse aufgerufen werden, welcher<br />
als Parameter die entsprechende auszugebende Nachricht als String übergeben wird.<br />
Diese Nachricht wird durch die "MainSys"-Klasse um eine vorangestellte Zeitangabe<br />
ergänzt und an die bereits vorhandenen Nachrichten angefügt. Anschließen muss der<br />
Aufruf der Methode "updateLog()" des Hauptfensters erfolgen um die Nachrichtenausgabe<br />
zu aktualisieren.<br />
Zu dem Aufgabengebiet des Hauptfensters gehört, neben der beschriebenen Funktion als<br />
Container für graphische Elemente, zusätzlich die visuelle Darstellung eines Hauptmenüs.<br />
Das Hauptenü hat die Aufgabe Funktionen des Systems zu aktivieren, welche durch Optionspunkte<br />
dieses Menüs dargestellt werden. Das Hauptsystem bietet eine Reihe von<br />
Grundfunktionen, die über dieses Menü aufrufbar sind. Es ist zudem möglich Funktionsaufrufe<br />
potentieller Plugins in das Hauptmenü zu integrieren. Hierfür bietet das<br />
Hauptfenster die Methode "public JMenuBar getMenu()". Mit dieser Methode kann<br />
dem Plugin eine Referenz auf das Hauptmenü-Objekt des Hauptfensters beschafft werden.<br />
Mit Hilfe dieses Objekts kann durch den Aufruf seiner Methoden "add(JMenuItem)"<br />
und "add(JMenu)" ein Optionspunkt des Typs "JMenuItem" bzw. ein komplettes Untermenü<br />
des Typs "JMenu" hinzugefügt werden.<br />
Die folgende Abbildung zeigt eine Skizze der hier beschriebenen Abläufe:<br />
37
3.14 Behandlung von Ereignissen<br />
KAPITEL 3. ENTWICKLUNG DES SYSTEMS<br />
Im vorherigen Kapitel wurde gezeigt, wie graphische Elemente in das System integriert<br />
werden. Diese Elemente können beispielsweise graphische Tasten, welche auch als<br />
“Buttons“ bezeichnet werden, Kontrollkästchen, aufklappbare oder erscheinende Menüs,<br />
auch Pull-Down- bzw. Pop-Up-Menüs genannt, Tabellen, Listen und andere Elemente<br />
sein. Diese Elemente haben zunächst noch keine definierte Funktion. Um nun die Elemente<br />
der graphischen Oberfläche mit den Funktionen des Fachkonzepts zu kombinieren,<br />
wird eine geeignete Schnittstelle benötigt. So eine Schnittstelle wird auch als Ereignisbehandlungsschnittstelle<br />
oder als Event-Handler bezeichnet.<br />
In dem zu entwickelnden Programm wird die von Java ab der Version 1.2 angebotene<br />
Ereignisbehandlungsmethodik angewandt.<br />
Prinzip der Ereignisbehandlung des JDK<br />
Zur Unterstützung der Ereignisbehandlung bietet Java eine Bibliothek mit Klassen und<br />
Schnittstellen, welche zu diesem Zweck eingesetzt werden können. Das Prinzip sieht<br />
dabei so aus, dass graphische Elemente mit speziell gekennzeichneten Klassen gekoppelt<br />
werden, die die Ereignisbehandlung übernehmen. Für verschiedene Ereignisse bzw.<br />
Events bietet das JDK wiederum spezielle Schnittstellen, die die geeigneten Behandlungsmethoden<br />
beschreiben. Eine Klasse, welche die Behandlung von diversen Events<br />
übernehmen soll, muss die entsprechende Schnittstelle und somit die von ihr beschriebenen<br />
Behandlungsmethoden in geeigneter Weise implementieren. Diese Klasse kann auch<br />
als Ereignisbehandlungsklasse oder auch Event-Listener bezeichnet werden.<br />
Die Klassen der graphischen Swing-Elemente verfügen alle über bestimmte Methoden,<br />
mit denen sie sich an diese Event-Listener koppeln können. Dabei kann ein einzelnes<br />
Swing-Element durchaus an mehrere Eventhandler gekoppelt sein. Wird nun eine Aktion<br />
vom Nutzer der graphischen Oberfläche gestartet - beispielsweise ein Klick mit der<br />
Maus auf einen Button oder das Verändern der Einträge einer Tabelle - so verschickt<br />
das jeweilige graphische Element die entsprechende Event-Mitteilung an die gekoppelten<br />
Event-Handler. Der Event-Handler entscheidet anhand des Typs der Event-Mitteilung,<br />
welche der zur Verfügung stehenden Methoden ausgeführt werden muss. Diese Methoden<br />
können den internen Ablauf des Systems beeinflussen und bieten somit die Verbindung<br />
der GUI mit dem Fachkonzept.<br />
Einbindung ins System<br />
Das zu entwickelnde System nutzt das genannte Prinzip der Ereignisbehandlung. Hierfür<br />
stehen dem Hauptsystem und allen entwickelten Plugins diese Ereignisbehandlungsklassen<br />
zur Verfügung. Diese implementieren in der Regel die folgenden Ereignisbehandlungsschnittstellen<br />
des JDK, welche sich im Paket "java.awt.event" befinden:<br />
• ActionListener - dient speziell zur Behandlung von Button-Events<br />
• MouseListener - dient zur Behandlung sonstiger Mausaktionen<br />
• ComponentListener - dient zur Behandlung von Komponentenverschiebungen<br />
38
4 Installation und Ausführung des<br />
Programms<br />
Für das Installieren, Starten und Ausführen des Programms wird eine funktionsfähige<br />
Java-Umgebung benötigt. Außerdem ist es notwendig, dass das SDK mindestens in der<br />
Version 5.0 vorliegt. Das neueste Java-Development-Kit kann von der Seite http://www.<br />
java.sun.com/ heruntergeladen werden. Zusätzlich sollte bei Verwendung einer Firewall<br />
der Port 1099 freigegeben werden.<br />
4.1 Installation des Programms<br />
Um die “Cooperative Algorithm Engineering Workbench“ auf einem Rechner zu installieren,<br />
muss zunächst die beigefügte CD ins Laufwerk eingelegt werden. Falls es sich bei<br />
dem verwendeten Betriebssystem um Windows handelt und die “Autostart“-Funktion<br />
aktiviert ist, startet der Insallationsassistent automatisch. Sollte diese Funktion ausgeschaltet<br />
sein bzw. es sich um ein anderes Betriebssystem handeln, muss der Startvorgang<br />
des Installationsassistenten manuell eingeleitet werden. Bei Windows startet man den<br />
Installationsprozess manuell, indem man die Datei “install.bat“ der CD mittels eines<br />
Doppelklicks aktiviert. Bei Linux-Systemen muss zunächst ein Terminal geöffnet werden,<br />
in welches der Befehl, der aus der Textdatei “command.txt“ der beigefügten CD<br />
kopiert werden kann, eingegeben wird. Dieser Befehl sieht wie folgt aus:<br />
cd /media/CAEW<br />
java -cp bin:CAEW_Single/bin: de.usi.caew.installer.Installer<br />
Nach dem Anklicken des “OK“-Buttons des Begrüßungsbildschirms erscheint ein Dialogfenster,<br />
das die Lizenzvereinbarung anzeigt. Möchte man diese Vereinbarung akzeptieren,<br />
muss der Optionspunkt “I agree“ selektiert und mittels eines Klicks auf den<br />
“OK“-Button bestätigt werden. Das Folgefenster ermöglicht es einen Ordner auf dem<br />
Datenträger für die Installation des Programms auszuwählen. Soll hierbei der Standardwert<br />
verändert werden, so drückt man auf den Button “Browse“ und wählt in dem<br />
erscheinenden Dateiexplorer den gewünschten Ordner aus. Zudem bietet dieser Bildschirm<br />
die Möglichkeit den Modus der Installation zu wählen. Wählt man hierbei den<br />
Optionspunkt “Singleuser mode“ so wird im späteren Verlauf das Programm als Einzelnutzersystem<br />
installiert. Andernfalls wird die Mehrbenutzerversion des Programms<br />
auf dem Datenträger eingerichtet. Bei dieser Version des Programms ist die Wahl der<br />
Installation des Mehrbenutzersystems jedoch noch nicht möglich, sie wurde allerdings im<br />
Hinblick auf die Weiterentwicklung in den Assistenten integriert. Wurde die Ordnerwahl<br />
39
KAPITEL 4. INSTALLATION UND AUSFÜHRUNG DES PROGRAMMS<br />
und die Wahl des Installationsmodus mit dem Drücken des “OK“-Buttons abgeschlossen,<br />
erscheint ein Fenster, welches den Benutzer auffordert, die Merkmale des Systems einzugeben.<br />
Durch Anklicken des “OK“-Buttons erscheint ein Bestätigungsfenster, in dem<br />
man den Installationsprozess starten kann. Nach dem Betätigen des Buttons “Install“<br />
wird das Programm in der gewünschten Weise auf dem Datenträger installiert. Nach<br />
Abschluss dieses Vorgangs ist das Programm auf dem Datenträger installiert und der<br />
Installationsassistent kann mittels eines Klicks auf den “Quit“-Button beendet werden.<br />
4.2 Starten des Programms<br />
Abbildung 4.1: Der Installationsassistent<br />
Die Standardmethode das Programm zu starten ist zugleich die einfachste. Hierzu öffnet<br />
man das Fenster des Ordners, in dem das Programm installiert wurde. In diesem<br />
Ordner befinden sich spezielle Dateien, die den Start des Programms ermöglichen. Unter<br />
Windows-Betriebssystemen ist hierbei die Datei “Start.bat“ und unter Linux Systemen<br />
die Datei “Start.sh“ mittels eines Doppelklicks zu aktivieren. Das Programm startet<br />
anschließend automatisch. Zusätzlich gibt es noch zwei alternative Methoden das Programm<br />
zu starten:<br />
• Benutzung des Eclipse-Workspaces<br />
• Manuelles Starten<br />
Eclipse-Workspace<br />
Für das Starten des Programms aus der Eclipse-Umgebung heraus, benötigt man zum<br />
einen das Entwicklungs-Werkzeug Eclipse, das unter http://www.eclipse.org/ heur-<br />
40
KAPITEL 4. INSTALLATION UND AUSFÜHRUNG DES PROGRAMMS<br />
untergeladen werden kann.<br />
Zum anderen benötigt man den kompletten Workspace-Ordner, welcher bei der<br />
Installation erstellt wurde. Da der Instalationsordner alle von Eclipse benötigten Initialisierungsdateien<br />
enthält, dient er zugleich als Workspace-Ordner. Das Workspace von<br />
Eclipse muss auf den kopierten Ordner gesetzt werden.<br />
Es ist darauf zu achten, dass der Compiler, der für dieses Projekt ausgewählt wurde,<br />
mindestens die Version 5.0 hat.<br />
Für den korrekten Ablauf des Programms ist es erforderlich, dem Java-Interpreter die<br />
folgenden zwei Attribute zu übergeben:<br />
• -Xms100m<br />
• -Xmx400m<br />
Diese Attribute bestimmen die Größe des Speichers, der minimal bzw. maximal zugewiesen<br />
wird. Die Klasse, die gestartet werden muss, hat den Namen “Start.class“ und<br />
befindet sich im Standard-Paket.<br />
Manuelles Starten<br />
Das manuelle Starten erfordert das Setzen aller mitgelieferten Hilfsdateien in den Klassenpfad.<br />
Folgende Dateien müssen im Klassenpfad enthalten sein:<br />
• asm.jar<br />
• cglib-2.1.3.jar<br />
• checkstyle-all.jar<br />
• commons-collections-2.1.1.jar<br />
• derby.jar<br />
• derbyclient.jar<br />
• derbyLocale.jar<br />
• derbynet.jar<br />
• derbyrun.jar<br />
• derbytools.jar<br />
• dom4j-1.6.1.jar<br />
• hibernate3.jar<br />
• jta.jar<br />
41
KAPITEL 4. INSTALLATION UND AUSFÜHRUNG DES PROGRAMMS<br />
• log4j-1.2.11.jar<br />
• mysql-connector-java-5.0.4-bin.jar<br />
Diese Dateien befinden sich im Ordner ’lib’“, welcher sich wiederum im Installationsordner<br />
befindet. Außerdem ist es notwendig, die Ordner “bin“, “Language“ und “Plugins“<br />
des Installationsordners zum Klassenpfad hinzuzufügen.<br />
Auch beim manuellen Start ist es erforderlich, für den korrekten Ablauf des Programms,<br />
dem Java-Interpreter die folgenden zwei Attribute zu übergeben:<br />
• -Xms100m<br />
• -Xmx400m<br />
Die Start-Klasse ist ebenfalls unter dem Namen “Start.class“ im Standard-Packet zu<br />
finden.<br />
In einer Konsole wechselt man zum Ordner CAEW-Aktuell und gibt das folgende<br />
Kommando ein:<br />
javaw.exe -cp “./bin;./plugins:./Language:./lib/asm.jar:./lib/cglib-2.1.3.jar:<br />
./lib/checkstyle-all.jar:./lib/commons-collections-2.1.1.jar:./lib/derby.jar:<br />
./lib/derbyclient.jar:./lib/derby-Locale de DE.jar:./lib/derbynet.jar:./lib/derbyrun.jar:<br />
./lib/derbytools.jar:./lib/dom4j-1.6.1.jar:./lib/hibernate3.jar:./lib/jta.jar:<br />
./lib/log4j-1.2.11.jar:./lib/mysql-connector-java-5.0.4-bin.jar“%CLASSPATH%<br />
-Xms100m -Xmx400m Start<br />
42
5 Bedienung des Werkzeugs<br />
5.1 Programmübersicht<br />
Um als allererstes einen Gesamtüberblick über das Erscheinungsbild des Programms<br />
zu erhalten, soll zunächst die Aufteilung der graphischen Oberfläche in verschiedene<br />
Bereiche anhand der unteren Abbildung erläutert werden. Wie schon angedeutet, ist<br />
die Ansicht des Programms in vier verschiedene Bereiche unterteilt: die Table-View, die<br />
Detail-View, das Hauptmenü und der Logbereich.<br />
• Die Table-View dient dem Benutzer als Browserfenster für den Zugriff auf die<br />
Dokumente, die in der Datenbank abgelegt sind. Um benötigte Daten schneller zu<br />
finden und auf sie zugreifen zu können, stellt die Table-View eine Filterfunktion<br />
zur Verfügung.<br />
• Die Detail-View hat einerseits die Aufgabe einzelne Dokumente detailiert darzustellen,<br />
andererseits dient sie auch als Arbeitsfläche, auf der man Dokumente<br />
verändern aber auch Testläufe definieren und starten kann.<br />
• Das Hauptmenü bietet verschiedene Optionspunkte um auf bestimmte Hauptfunktionen<br />
des Programms - u.a. Administratoroperationen - zugreifen zu können.<br />
• Der Log-Bereich dient dazu, verschiedene Aktionen und Arbeitsabläufe zu dokumentieren<br />
und diese als Folge von Einzelschritten darzustellen.<br />
43
5.1.1 Sprache wählen<br />
KAPITEL 5. BEDIENUNG DES WERKZEUGS<br />
Nachdem das Programm erfolgreich gestartet wurde, erscheint das Startfenster in dem<br />
die Möglichkeit gegeben wird, die gewünschte Sprache zu wählen. Standartmäßig stehen<br />
zwei Sprachen zur Verfügung: Englisch und Deutsch. Die gewünschte Sprache ist über<br />
das Pull-Down-Menü des Startfensters [Abbildung 5.1] zu wählen.<br />
5.1.2 Modus wählen<br />
Abbildung 5.1: Das Startfenster<br />
Bei der Basisversion des Programms stehen dem Benutzer zwei verschiedene Ausführungsmodi<br />
zur Verfügung:<br />
• Only-server-mode<br />
• Full-function-mode<br />
Der gewünschte Modus wird durch Anklicken des jeweiligen Buttons gewählt.<br />
Only-server-mode<br />
Im “Only-server-mode“-Modus wird das Programm lediglich als Server zur Berechnung<br />
von Algorithmen gestartet. In diesem Modus steht der Server anderen Rechnern zur<br />
Verfügung, die ihn zur Berechnung der gestarteten Experimente nutzen können.<br />
Full-function-mode<br />
Der “Full-function-mode“-Modus bietet die volle Funktionalität der Experimentierumgebung.<br />
Es wird sowohl das GUI-Basierte Hauptprogramm gestartet als auch der im<br />
“Only-server-mode“ erwähnte Server.<br />
44
5.1.3 Erststart<br />
KAPITEL 5. BEDIENUNG DES WERKZEUGS<br />
Bei dem ersten Starten des Programms werden zunächst keine Plugins geladen. Um<br />
diese dem Programm zur Verfügung zu stellen, muss man in der Hauptmenüleiste das<br />
Untermenü “Admin“ anwählen und den Punkt “Plugins“ anklicken.<br />
Für diese Aktion benötigt man allerdings eine Administrator-Berechtigung. Da es sich<br />
hierbei um die Basisversion im Einzelnutzerbetrieb handelt, wird dem Nutzer die Berechtigung<br />
automatisch zugewiesen.<br />
Es wird eine Liste [Abbildung 5.2] mit den verfügbaren Plugins angezeigt, die zu diesem<br />
Zeitpunkt nicht selektiert sind. Über die Check-Boxen wählt man die gewünschten Plugins<br />
aus und fügt sie mit dem “OK“-Button dem Hauptprogramm hinzu. Diese werden<br />
nach einem Neustart automatisch gestartet.<br />
5.1.4 Server hinzufügen<br />
Abbildung 5.2: Plugins hinzufügen<br />
Beim Erststart wird zur Berechnung von Experimenten nur der Rechner zur Verfügung<br />
gestellt, auf dem das Programm ausgeführt wird. Um weitere Server zur Verfügung<br />
zu stellen, öffnet man “Admin“ aus der Hauptmenüleiste und wählt den Menüpunkt<br />
“Server“ wonach eine Liste [Abbildung 5.3] mit den hinzugefügten Servern erscheint.<br />
Abbildung 5.3: Server hinzufügen<br />
45
KAPITEL 5. BEDIENUNG DES WERKZEUGS<br />
Als nächstes gibt man in dem unteren Textfeld den Namen des neuen Servers ein<br />
und bestätigt diesen mit dem Button “ADD“. Dieser erscheint selektiert in der Liste<br />
der verfügbaren Server. Nach dem Anklicken des Buttons “OK“ werden die Änderungen<br />
übernommen.<br />
46
5.2 Algorithmen<br />
KAPITEL 5. BEDIENUNG DES WERKZEUGS<br />
Algorithmen sind die wichtigsten Komponenten in der Workbench. “Ein Algorithmus ist<br />
ein Verfahren zur Lösung einer Klasse (Menge) von Einzelproblemen (Probleminstanzen).<br />
Das Verfahren legt auf eindeutige Weise fest, wie aus der Darstellung des Einzelproblems<br />
durch eine Folge primitiver Operationen die Darstellung der Lösung effektiv<br />
herzustellen ist.“[Merz04] Aus der Sicht des Programms sind Algorithmen wiederum Programme<br />
die genau das leisten 1 . Solche Algorithmen werden extern implementiert und<br />
compiliert und erst danach in das Programm importiert. Dabei werden sowohl selbstausführbare<br />
als auch zu interpretierende Programme von der Workbench akzeptiert und<br />
unterstützt. Somit ist es möglich, Algorithmen in Sprachen wie Java und Pearl aber auch<br />
C und C++ zu entwickeln und mittels dieser Workbench diese zu testen und mit denen<br />
zu experimentieren. Dazu soll gesagt werden, dass diese Workbench nicht dazu dient<br />
semantische bzw. syntaktische Fehler im Algorithmus-Programm zu finden, sondern vor<br />
allem um lauffähige Algorithmen bezüglich des Laufzeitverhaltens zu verbessern und zu<br />
perfektionieren und um rauszufinden, zu welchem Grad die an sie gestellten Anforderungen<br />
erfüllt werden.<br />
5.2.1 Importieren<br />
Hat man einen Algorithmus erfolgreich implementiert und compiliert, muss dieser in das<br />
Programm importiert werden. Um einen Algorithmus zu importieren wählt man in der<br />
Table-View 2 [Abbildung 5.4] den Reiter “Algorithmen“ und klickt dann mit der rechten<br />
Maustaste auf eine freie Fläche der Table-View, bzw. auf einen Eintrag der Tabelle.<br />
Abbildung 5.4: Die Table-View<br />
Bei dem nun erscheinenden Popup-Menü wählt man den Eintrag “Algorithmus importieren“,<br />
worauf ein Fenster mit dem Titel “Algorithm-Import-Wizard“ [Abbildung<br />
5.5] erscheint.<br />
1<br />
Im weiteren Verlauf wird öffters die Rede von Algorithmen sein, dabei sind i.d.R. die Algorithmen-<br />
Programme gemeint.<br />
2<br />
Die Tabel-View ist das linke Fenster, in dem eine Tabelle mit allen verfügbaren Dokumenten zu sehen<br />
ist.<br />
47
Name<br />
KAPITEL 5. BEDIENUNG DES WERKZEUGS<br />
Abbildung 5.5: Der Algorithm-Import-Wizard<br />
Als erstes wählt man für den Algorithmus einen beliebigen Namen, der aber mindestens<br />
ein Zeichen enthalten muss und gibt diesen in das oberste rechte Textfeld ein.<br />
Dateien<br />
Als nächstes wird die Algorithmus-Datei auf dem Datenträger gewählt. Dazu drückt man<br />
den Button “Suchen“ neben dem entsprechendem Textfeld. Es erscheint ein Dialog, in<br />
dem man die entsprechende Datei auf dem Datenträger finden kann. Hat man die Datei<br />
gefunden, bestätigt man dies mit einem Klick auf den Button “Öffnen“. Der Pfad zur<br />
Algorithmus-Datei wird nun in dem Textfeld angezeigt. Man hat auch die Möglichkeit,<br />
im Textfeld darunter, seine eigenen Kommentare und Erklärungen zum Algorithmus zu<br />
verfassen.<br />
Systemeinstellungen<br />
Mit dem Pull-Down-Menü “Betriebssystem“ wird das Betriebssystem eingestellt, auf<br />
dem der zu importierende Algorithmus ausführbar ist. Stellt man hierbei z.B. “Linux“<br />
ein, werden bei späteren Durchläufen alle Server mit anderen Betriebssystemen ignoriert.<br />
Zur Auswahl stehen drei Betriebssysteme: Windows, Linux und OSX. Man hat auch die<br />
Möglichkeit “All“ zu wählen, damit wird signalisiert, dass dieser Algorithmus auf allen<br />
Betriebssystemen lauffähig ist. Dies ist oft bei Programmen der Fall, die erst von einem<br />
Interpreter interpretiert werden müssen, wie z.B. Java.<br />
Mit dem Pull-Down-Menü “Art der Ausführung“ wird festgelegt, ob der Algorithmus<br />
selbstständig ausgeführt werden kann, wobei man hierbei den Punkt “Executable“<br />
wählen muss oder dieser mit Hilfe eines Interpreters gestartet werden muss. Hierbei<br />
wählt man den Menüeintrag “Interpreter“.<br />
48
Eingabe- und Ausgabedateien<br />
KAPITEL 5. BEDIENUNG DES WERKZEUGS<br />
Die nächsten drei Pull-Down-Menüs bieten die Möglichkeit die Art, in der die benötigten<br />
Dokumente (Eingabe-Dokumente, Konfigurationen und Stylesheets) eingelesen werden,<br />
einzustellen. Sollen die entsprechenden Dokumente dem Algorithmus als Argumente<br />
beim Aufruf übergeben werden, stellt man die Option auf “As Arguments“. Findet der<br />
Zugriff auf diese aus dem Algorithmus selbst statt, muss man die Option “From programm<br />
inside“ wählen.<br />
Beim Punkt “Aufruf-Schablone“ hat man die Möglichkeit mittels “Drag&Drop“ die<br />
Reihenfolge der einzulesenden Dokumentarten zu wählen, wobei hier nur diese beachtet<br />
werden, die dem Algorithmus beim Startaufruf als Argumente übergeben werden.<br />
Die Bedeutung der einzelnen Punkte ist:<br />
• {INP} - Alle Eingabe-Dokumente<br />
• {CONF} - Alle Konfigurations-Dokumente<br />
• {STY} - Alle Stylesheet-Dokumente<br />
Im untersten rechten Textfeld gibt man den relativen Pfad vom Algorithmus zu seiner<br />
Ausgabe-Datei an. Gibt dieser die Ausgabe-Datei in dem Ordner aus in dem er sich<br />
selbst befindet, lässt man dieses Feld frei.<br />
Nun gibt man in den drei rechten unteren Blöcken jeweils die Anzahl der Eingabe–<br />
Konfigurations– und Stylesheet–Dokumente an, die der Algorithmus benötigt. Beträgt<br />
diese bei einem Dokumenttyp mehr als null, wird der Button für die Namenseingabe<br />
aktiv. Hat man für diesen Dokumenttyp die Einleseart auf “From programm inside’“gestellt,<br />
so wird auch das Textfeld aktiv, in das man den relativen Pfad vom Algorithmus<br />
zu den jeweiligen Dokumenten eingibt. Nach dem Drücken des Buttons “Namen“<br />
erscheint ein Dialog mit einer Tabelle mit den Namen der einzelnen Dokumente. Hier<br />
gibt man diese genau so ein, wie sie später vom Algorithmus gelesen werden. Außerdem<br />
kann man, sofern die einzelnen Dokumente beim Startaufruf eigene Attribute benötigen,<br />
diese als Teil des Names eintragen.<br />
Beispiel: Der Algorithmus liest eine Eingabe-Datei mit dem Namen test.xml ein, diese<br />
benötigt ein Attibut um den Dateityp festzulegen. Der Name dieses Dokumentes könnte<br />
dann so eingegeben werden: −xml test.xml<br />
Interpreter<br />
Als letztes, sofern man “Art der Ausführung“ auf “Interpreter“ gestellt hat, führt man<br />
die Interpreter-Einstellungen durch.<br />
Zuerst stellt man hierzu mittels des Pull-Down-Menüs “Interpreter“ die Art des Interpreters<br />
ein. Sollte der gewünschte Interpreter in der Auswahl nicht vorhanden sein,<br />
kann man, indem man den Punkt “- - ADD OTHER - -“ wählt, einen neuen definieren.<br />
Dieser sollte so eingegeben werden, wie das System ihn auch später aufruft und nicht<br />
etwa wie der richtige Name lautet.<br />
49
KAPITEL 5. BEDIENUNG DES WERKZEUGS<br />
Abbildung 5.6: Die Detail-View mit selektiertem Reiter “Algorithmus-Details“<br />
- Hinweis: Bei der Programmiersprache Java T M 3 ist der Aufruf des Interpreters: java -<br />
Anschließend müssen alle Hilfsdateien und Ordner angegeben werden, die der Algorithmus<br />
benötigt um einwandfrei zu funktionieren. Hierzu betätigt man den Button “ADD“<br />
der sich im gleichen Block befindet. Dieser öffnet ein Datei-Auswahl-Dialog, in welchem<br />
man die benötigte Datei wählt. Dies führt man für alle Hilfsdateien und Ordner, die<br />
benötigt werden, durch.<br />
Hat man alle Informationen eingegeben, bestätigt man dies mit dem Button “OK“,<br />
wodurch der neue Algorithmus in die Workbench importiert wird. Die Zeit, die für den<br />
Datenimport benötigt wird, ist von der Rechnergeschwindigkeit und Gesamtgröße aller<br />
Dateien abhängig. Sobald der Import beendet ist, erscheint der neue Algorithmus in der<br />
Tabelle der Table-View. In der Detail-View 4 werden alle seine relevanten Eigenschaften<br />
und eine graphische Darstellung angezeigt.<br />
5.2.2 Eigenschaften verändern<br />
Alle Eigenschaften und Einstellungen, die man beim Import eines Algorithmus getätigt<br />
hat, kann man zu einem späteren Zeitpunkt noch verändern bzw. anpassen. Hierzu<br />
3 Java ist ein eingetragenes Markenzeichen der Firma Sun Microsystems Inc.<br />
4 Die Detail-View ist das rechte Fenster, in dem alle Details des ausgewählten Dokumentes angezeigt<br />
werden bzw. weitere Arbeitsschritte vorgenommen werden können<br />
50
KAPITEL 5. BEDIENUNG DES WERKZEUGS<br />
wählt man durch einen Linksklick den Algorithmus, den man bearbeiten möchte, aus<br />
der Tabelle der Table-View. Sobald der Algorithmus in der Detail-View angezeigt wird,<br />
betätigt man den Button “Eigenschaften ändern“, wodurch ein Dialog zum Verändern<br />
von Algorithmen-Eigenschaften erscheint. Dieser entspricht im Aussehen und in der<br />
Funktionalität dem Algorithm-Import-Wizard, der im Abschnitt “Importieren“ genau<br />
beschrieben wurde. Die einzige Abweichung besteht darin, dass man die Algorithmus-<br />
Datei nicht mehr neu bestimmen kann.<br />
5.2.3 Kommentar verfassen oder ändern<br />
Wie schon oben erwähnt besteht die Möglichkeit einen Kommentar zum gegebenen Algorithmus<br />
zu verfassen. Dies erledigt man im Kommentar-Textfeld der Detail-View. Nachdem<br />
man den Kommentar verfasst hat, muss man dies mittels des Buttons “Änderungen<br />
übernehmen“ bestätigen.<br />
5.2.4 Datei-Freigabe und Archiv<br />
Das Programm bietet die Möglichkeit Dokumente, die man zur Zeit nicht mehr benötigt,<br />
die womöglich zu einem Mangel an Übersichtlichkeit führen, in ein Archiv zu verschieben.<br />
Dies hat den Vorteil, dass die Tabelle der Table-View nicht mit alten Dokumenten<br />
überladen ist, was die Suche eines benötigten Dokumentes vereinfachen kann. Um einen<br />
Algorithmus in das Archiv zu verschieben, öffnet man, mittels eines Rechtsklicks auf dem<br />
richtigen Eintrag der Table-View, das Popup-Menü und wählt die Option “Zum Archiv“.<br />
Der Algorithmus wird ins Archiv verschoben und aus dem Arbeitsbereich entfernt.<br />
Desweiteren besteht die Möglichkeit eine Datei für andere Benutzer des Systems zum<br />
Kopieren freizugeben. Hierzu öffnet man, wie oben beschrieben, das Popup-Menü der<br />
Table-View und aktiviert das Kontrollkästchen “Freigabe“. Dieses Feature ist der Mehrbenutzer-Version<br />
der Workbench vorbehalten, weswegen hier nicht weiter auf diese Funktion<br />
eingegangen wird.<br />
5.2.5 Zur Auswahl der Testläufe hinzufügen<br />
Um einen Algorithmus ausführen zu können, muss man diesen erst einmal zur Auswahl-<br />
Tabelle der Testläfe hinzufügen. Dies erreicht man, indem man den gewünschten Algorithmus<br />
in der Tabelle der Table-View mittels Linksklick selektiert und, sobald dieser in<br />
der Detail-View angezeigt wird, den Button “Zur Testlauf-Auswahl hinzufügen“ betätigt.<br />
Die Detail-Ansicht wechselt anschließend zur Ansicht der Testläufe. Der weitere Ablauf<br />
wird im Kapitel “Testläufe“[Seite 59] beschrieben.<br />
5.2.6 Algorithmus löschen<br />
Um einen Algorithmus aus dem System endgültig zu entfernen, ruft man wiederum,<br />
mittels Rechtsklick auf dem gewünschten Eintrag der Table-View-Tabelle, das Popup-<br />
Menü und wählt den Menüpunkt “Löschen“, worauf eine Bestätigungsanfrage folgt.<br />
Bestätigt man diese, wird das Dokument unwiderruflich aus dem System entfernt.<br />
51
5.3 Schemata und DTDs<br />
KAPITEL 5. BEDIENUNG DES WERKZEUGS<br />
Um die Struktur XML-basierter Eingabedateien, Konfigurationen bzw. Stylesheets eindeutig<br />
beschreiben zu können, bietet das Programm die Möglichkeit, diesen Dokumenten<br />
DTDs bzw. Schemata zuzuordnen.<br />
Def.: Die Dokumenttyp-Definition (englisch Document Type Definition, DTD, auch<br />
Schema-Definition) ist ein Bestandteil der XML-Spezifikation. Sie wird dazu verwendet,<br />
die Struktur bzw. den Aufbau von XML-Dokumenten genau zu definieren. Dies bedeutet,<br />
sie legt fest welche Elemente es gibt und wie diese im Dokument angeordnet werden<br />
müssen.<br />
Def.: XML-Schemata liefern eine Alternative zu DTDs, da diese viele Schwächen, z.B.<br />
im Bezug auf datenbankorientierte Anwendungen von XML, aufweisen. Die Schemata<br />
bieten den Vorteil, dass sie selbst in der Form eines XML-Dokumentes vorliegen. Das<br />
W3C hat XML-Schema im Jahr 2001 zum offiziellen Standard gemacht.<br />
Die Entscheidung, welche dieser beiden Methoden man in der Workbench einsetzt,<br />
ist völlig freigestellt. Desweiteren besteht die Möglichkeit für seine Eingabe-Dokumente<br />
wie Eingabe-Dateien, Konfigurationen und Stylesheets keine DTD’s bzw Schemata zu<br />
verwenden, dazu in den folgenden Kapiteln mehr.<br />
Bedingung<br />
Um als Benutzer dieses Systems DTDs bzw. Schemata erstellen, importieren oder manipulieren<br />
zu können, benötigt man die “DTD-Developer“- Berechtigung. Da es sich<br />
hierbei, wie schon weiter oben erwähnt, um die Basisversion im Einbenutzerbetrieb handelt,<br />
wird dem Nutzer die Berechtigung automatisch zugewiesen.<br />
5.3.1 Die Schema/DTD-Ansicht<br />
Um zur Schema/DTD-Ansicht zu gelangen, öffnet man im Hauptmenü das Untermenü<br />
“Work“ und wählt den Punkt “Schema/DTD-View öffnen“, worauf ein neues Fenster<br />
zur Bearbeitung von DTDs bzw. Schemata erscheint [Abbildung 5.7]. Dieses ist ähnlich<br />
aufgebaut wie das Hauptprogramm selbst: Auf der linken Seite befindet sich die DTD-<br />
Table-View und auf der rechten die DTD-Detail-View.<br />
52
5.3.2 Neues Schema/DTD<br />
KAPITEL 5. BEDIENUNG DES WERKZEUGS<br />
Abbildung 5.7: Die Schema/DTD-Ansicht<br />
Um ein neues Schema 5 zu erstellen, klickt man mit der rechten Maustaste auf eiene freie<br />
Fläche oder einen Eintrag der DTD-Table-View um das Popup-Menü aufzurufen. Aus<br />
diesem Menü wählt man die Option “Neues Schema/DTD“, worauf ein Eingabedialog<br />
erscheint, in den man den Namen für das neue Schema eingibt. Nach der Bestätigung<br />
der Eingabe erscheint ein neuer Eintrag in der DTD-Table-View, außerdem wird das<br />
neue Schema auch in der DTD-Detail-View angezeigt. Man kann nun sein Schema in<br />
dem Editor der DTD-Detail-View erstellen, wobei man die Möglichkeit hat, mit dem<br />
Kontrollkästchen “XML-Highlighting aktivieren“ eine farbliche Text-Hervorhebung für<br />
XML-Dateien zu aktivieren. Nach Fertigstellung des Dokuments muss die Eingabe des<br />
Inhalts mit dem Button “Änderungen übernehmen“ bestätigt werden.<br />
5.3.3 Importieren<br />
Um ein vorhandenes Schema vom Datenträger zu importieren, öffnet man, wie im vorangehenden<br />
Abschnitt beschrieben, das Popup-Menü und wählt den Menüeintrag<br />
“Schema/DTD importieren“. Im erscheinenden “DTD/Schema-Import-Wizard“ gibt man<br />
den Namen des neuen Dokumentes ein und legt die Datei, die importiert werden soll,<br />
über den durch ein Betätigen des Buttons “Suchen“ erreichbaren Dateiexplorer fest.<br />
Zusätzlich kann man im Textfeld “Kommentare“ ein Kommentar für dieses Dokument<br />
verfassen. Diese Eingaben bestätigt man anschließend mit dem Button “OK“, wonach<br />
5 Der Einfachheit halber wird im weiteren Verlauf von “Schema“ gesprochen, gemeint ist in der Regel<br />
DTD oder Schema<br />
53
KAPITEL 5. BEDIENUNG DES WERKZEUGS<br />
ein neuer Eintrag in der Tabelle der DTD-Table-View erscheint und die Datei detailliert<br />
in der DTD-Detail-View angezeigt wird.<br />
5.3.4 Den Namen ändern<br />
Den Namen eines Schemas ändert man, indem man im Popup-Menü eines Tabelleneintrags<br />
den Punkt “Name ändern“ wählt, anschließend den Namen im erscheinenden<br />
Eingabedialog eingibt und die Eingabe mit “OK“ bestätigt.<br />
5.3.5 Änderungen am Dokument oder Kommentar<br />
Um Änderungen am Dokument vorzunehmen, wählt man dieses zunächst mit einem<br />
Linksklick aus der rechten Tabelle aus, welches darauf in der DTD-Detail-View erscheint.<br />
Für Änderungen am Inhalt des Dokuments steht ein Editor mit farblicher Texthervorhebung<br />
und einigen Editierfunktionen, die über ein Popup-Menü erreichbar sind, zur<br />
Verfügung. Im darunter liegenden Eingabefeld kann man einen Kommentar verfassen<br />
bzw. abändern. Verändert man den Inhalt oder den Kommentar des Dokumentes, müssen<br />
diese Änderungen anschließend mit dem Button “Änderungen übernehmen“ bestätigt<br />
werden.<br />
5.3.6 Löschen<br />
Schließlich hat man auch noch die Möglichkeit ein Schema endgültig aus dem System zu<br />
entfernen, was man durch das Anwählen des Menüpunktes “Löschen“ des Popupmenüs<br />
eines Tabelleneintrages erreichen kann.<br />
54
KAPITEL 5. BEDIENUNG DES WERKZEUGS<br />
5.4 Eingabe-, Konfigurations- und Stylesheetdokumente<br />
In der Regel benötigen Algorithmen ein bzw. mehrere Eingabe-Dokumente auf denen<br />
sie ihre Berechnung durchführen. Manche dieser Algorithmen benötigen zusätzlich<br />
Konfigurations-Dokumente um verschiedene Konfigurationseinstellungen zu übernehmen.<br />
Andere Algorithmen wiederum benötigen zusätzlich sogenannte Stylesheets um<br />
die Eingabe-Dokumente, die ggf. als XML-Dateien vorliegen, vor der Berechnung in ein<br />
geeignetes Format zu transformieren. Die Workbench bietet die Möglichkeit diese drei<br />
Dokumentarten getrennt voneinander zu verwalten. Um die gewünschte Dokumentart zu<br />
bearbeiten, wählt man in der Table-View bzw. Detail-View den entsprechenden Reiter:<br />
Dokumentart Table-View Detail-View<br />
Eingabe-Dokumente Eingabe-Dateien Eingabe-Details<br />
Konfigfigurations-Dokumente Konfigurationen Konfigurations-Details<br />
Stylesheet-Dokumente Stylesheets Stylesheet-Details<br />
5.4.1 Neues Dokument<br />
Um ein neues Dokument 6 anzulegen, ruft man durch einen Rechtsklick auf die jeweilige<br />
Table-View das Popup-Menü auf und wählt den Menüpunkt “Neue Eingabe-Datei“,<br />
“Neue Konfiguration“ bzw. “Neues Stylesheet“. Im erscheinenden Eingabedialog tippt<br />
man den Namen des neuen Dokumentes ein und bestätigt diesen mit “OK“. Hat man<br />
den Namen bestätigt, erscheint in der Tabelle der Table-View ein neuer Eintrag und das<br />
neue Dokument wird in der Detail-View angezeigt. Im Editor der Detail-View kann man<br />
nun den Inhalt des Dokumentes erstellen, wobei man die Editierfunktionen, die über das<br />
Popup-Menü des Editors erreichbar sind, und die farbliche Texthervorhebung für XML-<br />
Dateien zuhilfe nehmen kann. Im unteren Eingabefenster kann man ein Kommentar für<br />
dieses Dokument verfassen. Diese Eingaben muss man nach der Fertigstellung mit dem<br />
Button “Änderungen übernehmen“ bestätigen.<br />
5.4.2 Dokument importieren<br />
Möchte man eine vorhandene Datei vom Datenträger importieren, muss zunächst der<br />
Import-Wizard [Abbildung 5.8] über den Menüpunkt “Eingabe-Datei importieren“, “Konfig.<br />
importieren“, bzw. “Stylesh. importieren“ des Popup-Menüs der jeweiligen Table-View<br />
aufgerufen werden.<br />
Im Import-Wizard gibt man als erstes im obersten Textfeld einen Namen für dieses<br />
Dokument ein, danach öffnet man durch einen Klick auf den Button “Suchen“ die Datei-<br />
Ansicht und bestimmt mit deren Hilfe die Datei auf dem Datenträger, die importiert<br />
werden soll. Unterhalb des Eingabefeldes für Kommentare hat man die Möglichkeit, per<br />
6 Im Verlauf dieses Kapitels wird vom “Dokument“ gesprochen, idR. ist damit, je nach Fall, ein Eingabe-,<br />
Konfigurations- oder Stylesheet-Dokument gemeint<br />
55
KAPITEL 5. BEDIENUNG DES WERKZEUGS<br />
Abbildung 5.8: Import-Wizard für Eingabe-Dateien<br />
Auswahl einer Option zu bestimmen, ob dieses Dokument eine DTD bzw. Schema zur<br />
Validierung des Inhaltes nutzt oder nicht. Soll dieses Dokument ein Schema nutzen, muss<br />
der Optionspunkt “Nutzt ein Schema/DTD“ angewählt werden. Durch einen Klick auf<br />
den unteren Button “Suchen“ hat man die Möglichkeit, ein Dokument aus der Liste<br />
der verfügbaren DTDs bzw. Schemata zu wählen. Im Textfeld “Eingelesener Name des<br />
Schemas/DTDs“ gibt man den Namen des Schemas ein und im Textfeld “Relativer Pfad<br />
zum Schema/DTD“ den relativen Pfad vom Dokument zum Schema und zwar so wie<br />
das Dokument diese später einliest.<br />
Beispiel: In Abbildung 5.9 ist eine XML-Datei angezeigt, die die DTD “meineDTD.dtd“<br />
aus dem Ordner “./dtd“ einliest. Die Passage ist orange hervorgehoben.<br />
Die Eingaben bestätigt man mit dem Button “OK“, wonach ein neuer Eintrag in der<br />
Tabelle der Table-View erscheint und das neue Dokument in der Detail-View angezeigt<br />
wird.<br />
5.4.3 Namen ändern<br />
Um den Namen eines Dokuments zu ändern, wählt man im Popup-Menü des jeweiligen<br />
Tabelleneintrages in der Table-View die Option “Name ändern“. Im erscheinenden Dialog<br />
gibt man den neuen Namen ein und bestätigt diesen mit dem Button “OK“. Die<br />
Änderung kann man in der Tabelle und der Detail-View beobachten.<br />
5.4.4 Eigenschaften ändern<br />
Möchte man die Eigenschaften eines selektierten Dokumentes ändern, ruft man mit Hilfe<br />
des Buttons “Eigenschaften ändern“ den benötigten Wizard auf. Dieser entspricht<br />
56
KAPITEL 5. BEDIENUNG DES WERKZEUGS<br />
Abbildung 5.9: Ein Dokument welches eine DTD einliest<br />
im Aussehen und Funktionalität dem Import-Wizard, der im Abschnitt ”Dokument importieren“<br />
[Abschnitt 5.4.2] genau beschrieben wurde. Der einzige Unterschied zu dem<br />
Import-Wizard ist, dass man die eigentliche Datei vom Datenträger nicht mehr wählen<br />
kann.<br />
5.4.5 Inhalt und Kommentar ändern<br />
Um den Inhalt eines Dokumentes zu ändern, muss dieses erstmal in der Tabelle der Table-<br />
View selektiert werden. Anschließend hat man die Möglichkeit im Editor der Detail-View<br />
den Inhalt zu verändern und im unteren Eingabefenster einen Kommentar zu verfassen<br />
bzw. zu ändern. Hat man den Inhalt bzw. den Kommentar verändert, muss dies mit dem<br />
Button “Änderungen übernehmen“ bestätigt werden.<br />
5.4.6 Datei-Freigabe und Archiv<br />
Wie schon im Kapitel “Algorithmen“ erwähnt, bietet das Programm die Möglichkeit,<br />
Dokumente die man zur Zeit nicht mehr benötigt, in ein Archiv zu verschieben. Dies hat<br />
den Vorteil der schnelleren Auffindung von aktuellen Dokumenten. Um ein Dokument in<br />
das Archiv zu verschieben, öffnet man, mit einem Rechtsklick auf den jeweiligen Eintrag<br />
der Table-View, das Popup-Menü und wählt die Option “Ins Archiv“. Das Dokument<br />
wird ins Archiv verschoben und aus dem Arbeitsberech enfernt.<br />
Wie ebenfalls im Kapitel “Algorithmen“ erwähnt, besteht die Möglichkeit, ein Dokument<br />
für andere Benutzer des Systems zum Kopieren freizugeben. Hierzu öffnet man, wie<br />
oben beschrieben, das Popup-Menü der Table-View und aktiviert das Kontrollkästchen<br />
“Freigabe“.<br />
57
5.4.7 Zur Auswahl der Testläufe hinzufügen<br />
KAPITEL 5. BEDIENUNG DES WERKZEUGS<br />
Um eine der drei Dokumentarten einem bzw. mehreren Algorithmen für Testläufe zur<br />
Verfügung zu stellen, muss man das Dokument erst einmal zur Auswahl-Tabelle der<br />
Testläufe hinzufügen. Dies erreicht man indem man das gewünschte Dokument in der<br />
Tabelle der Table-View mittels Linksklick selektiert und nach Erscheinen in der Detail-<br />
View den Button “Zur Testlauf-Auswahl hinzufügen“ betätigt. Hierfür ist es notwendig,<br />
dass davor bereits mindestens ein Algorithmus vom Benutzer zur Auswahl-Tabelle der<br />
Testläufe hinzugefügt wurde. Die Detail-Ansicht wechselt anschließend zur Ansicht der<br />
Testläufe. Der weitere Ablauf wird im Kapitel “Testläufe“[Seite 59] näher beschrieben.<br />
5.4.8 Löschen<br />
Durch das Anklicken des Menüpunktes “Löschen“ des Popupmenüs eines Tabelleneintrages<br />
ist es möglich, nach dem Bestätigen einer Sicherheitsanfrage, dieses Dokument<br />
dauerhaft aus dem System zu entfernen.<br />
58
5.5 Testläufe<br />
KAPITEL 5. BEDIENUNG DES WERKZEUGS<br />
Der Grundgedanke dieses Systems ist es Algorithmen bezüglich ihrer Laufzeit und Funktionalität<br />
zu verfeinern und zu optimieren. Zu diesem Zweck ist es notwendig, einzelne<br />
Algorithmen oder Algorithmenreihen verschiedenen Tests zu unterziehen. Die so ermittelten<br />
Resultate und die daraus folgenden Überlegungen lässt man in die Optimierung<br />
dieser Algorithmen, zum Beispiel durch Anpassung von Konfigurationsdokumenten, einfliessen.<br />
Um solche Testläufe starten zu können, ist es notwendig, diese zunächst zu<br />
definieren.<br />
5.5.1 Vorbedingung<br />
Wählt man in der Detail-View den Reiter “Testläufe“ erscheint die Ansicht der Testläufe<br />
[Abbildung 5.10]. Um Testläufe definieren zu können, muss der Benutzer im Vorfeld,<br />
wie in den Kapiteln “Algorithmen“ und “Eingabe-, Konfigurations- und Stylesheet-<br />
Dokumente“ beschrieben, Algorithmen und Eingabe-Dokumente zur Testlaufauswahl<br />
hinzugefügt haben.<br />
Abbildung 5.10: Die Detail-View mit selektiertem Reiter “Testläufe“ und hinzugefügten<br />
Dokumenten<br />
59
5.5.2 Definition von Testläufen<br />
KAPITEL 5. BEDIENUNG DES WERKZEUGS<br />
Um einen oder mehrere Testläufe zu definieren, selektiert man per Linksklick den jeweiligen<br />
Algorithmus und die Eingabe-Dokumente in den entsprechenden Tabellen der<br />
Detail-View, anschließend bestätigt man diese Auswahl mit dem “ADD“-Button. Alle<br />
sich daraus ergebenden Kombinationen werden zur Tabelle “Testläufe“ hinzugefügt. Auf<br />
diese Art definiert man alle Kombinationen die man für das gewünschte Experiment 7<br />
benötigt.<br />
5.5.3 Komponenten aus der Run-Tabelle tauschen<br />
Es besteht die Möglichkeit einzelne Dokumente oder Dokumentgruppen, die zur Testlauftabelle<br />
hinzugefügt wurden, gegen andere Dokumente, die in den anderen Tabellen der<br />
Detail-View angezeigt werden, zu tauschen. Hierzu klickt man mit der rechten Maustaste<br />
auf die jeweilige Komponente der Testlauf-Tabelle um ein Popup-Menü zu öffnen. Über<br />
dieses Menü hat man nun die Möglichkeit, durch Drücken der jeweiligen Option, diese<br />
Komponente oder alle Komponenten dieser Spalte gegen das markierte Dokument der<br />
selben Art zu tauschen.<br />
5.5.4 Testläufe aus der Tabelle entfernen<br />
Es gibt drei Möglichkeiten die definierten Testläufe aus der Testlauftabelle zu entfernen:<br />
• in der Testlauftabelle, in der Spalte in der sich der zu entfernende Testlauf befindet,<br />
betätigt man den Button “DEL“. Hiermit wird der entsprechende Lauf aus der<br />
Testlauftabelle entfernt.<br />
• durch Betätigen des Buttons “Testlauftabelle“ löschen. Hiermit löscht man den<br />
gesamten Inhalt der Testlauftabelle.<br />
• durch Betätigen des Buttons “Alles löschen“. Diese Funktion entfernt nicht nur<br />
alle Einträge der Testlauftabelle, sondern löscht alle Einträge von allen Tabellen<br />
der Detail-View.<br />
5.5.5 Alle bevorstehenden Resultate anzeigen<br />
Vor dem Start hat man die Möglichkeit das Kontrollkästchen “Alle Ausgaben zeigen“<br />
zu aktivieren. Dies hat zur Folge, dass während der späteren Läufe die Ausgaben aller<br />
Algorithmenberechnungen sofort angezeigt werden und man nicht erst einmal die Resultate<br />
abspeichern muss um diese zu betrachten. Diese Option kann man allerdings auch<br />
noch nach dem Start, vor dem Ablauf aller Testläufe aktivieren.<br />
7 Als Experiment versteht man im Zusammenhang mit der CAEW einen Testlauf, den man zu einem<br />
späteren Zeitpunkt mit gleichen oder veränderten Werten wiederholt durchführen kann<br />
60
5.5.6 Resultat-Graph<br />
KAPITEL 5. BEDIENUNG DES WERKZEUGS<br />
Zusätzlich zu den Ausgabedokumenten lassen sich die Laufzeitdifferenzen zwischen den<br />
einzelnen Testläufen als Graph [Abbildung 5.11] darstellen. Dies hat den Vorteil, mögliche<br />
Unterschiede beim zeitlichen Ablauf der Testläufe einfacher erkennen zu können. Um<br />
diese Funktion zu aktivieren, wird das Kontrollkästchen “Resultat-Graph anzeigen“ vor<br />
dem Ablauf des letzten Testlaufs angeklickt.<br />
5.5.7 Testläufe starten<br />
Abbildung 5.11: Der Resultat-Graph<br />
Nachdem man die gewünschten Testläufe definiert hat, werden die Berechnungen mit<br />
Hilfe des Buttons “Start“ gestartet. In der Spalte “Status“ der Testlauf-Tabelle kann man<br />
beobachten welche Testläufe aktuell auf welchem Server berechnet werden. Nach dem<br />
Ablauf jedes Testlaufs kann man in dieser Spalte ablesen, ob dieser korrekt durchlaufen<br />
wurde oder fehlgeschlagen ist. Ist ein Testlauf fehlgeschlagen, wird dies in der “Status“-<br />
Spalte durch den Ausdruck “FAILED“ angezeigt. Durch ein Rechtsklick auf dieses Feld<br />
kann man sich die Fehlerausgabe anzeigen lassen, falls eine vom Algorithmus erzeugt<br />
wurde. Es besteht jederzeit die Möglichkeit, die Testläufe durch Betätigen des Buttons<br />
“Abbrechen“ vorzeitig zu beenden.<br />
61
5.5.8 Testläufe speichern<br />
KAPITEL 5. BEDIENUNG DES WERKZEUGS<br />
Nach Beendigung aller Testläufe besteht die Option, diese als Experimente zu speichern.<br />
Hierzu bestätigt man den erscheinenden Abfrage-Dialog mit “Ja“. Es erscheint<br />
ein neuer Dialog, der dem Benutzer die Möglichkeit bietet, diverse Einstellungen vor<br />
dem Speichern vorzunehmen. Zuallererst selektiert man die Testläufe, die als Experimente<br />
gespeichert werden sollen, wobei nur die korrekt berechneten zur Auswahl stehen.<br />
Hat man einen oder mehrere Testläufe selektiert, können sich die daraus ergebenden<br />
Experimente zu einer Experiment-Sequenz zusammenfassen lassen um diese zusätzlich<br />
gruppiert abzuspeichern. Dieser Sequenz wird automatisch ein Standard-Name zugewiesen,<br />
der jedoch vom Benutzer im unteren Textfeld geändert werden kann. Nach dem<br />
Betätigen des “Speichern“-Buttons werden alle selektierten Testläufe als Experimente<br />
und ggf. die Experiment-Sequenz in das System übernommen.<br />
62
5.6 Experimente<br />
KAPITEL 5. BEDIENUNG DES WERKZEUGS<br />
Unter einem Experiment versteht man, im Zusammenhang mit der CAEW, einen Testlauf,<br />
den man zu einem späteren Zeitpunkt, mit gleichen oder veränderten Werten, erneut<br />
durchführen kann.<br />
5.6.1 Einzel-Experimente<br />
Übersicht<br />
Beabsichtigt man ein gespeichertes Experiment aufzurufen, öffnet man in der Table-<br />
View die Sektion Experimente und selektiert das gewünschte Experiment, wobei zu<br />
beachten ist, dass der untere Reiter “Einzel-Experimente“ gewählt sein muss. Hat man<br />
ein Experiment selektiert, erscheint dessen detaillierte Beschreibung in der Detail-View<br />
[Abbildung 5.12]. Diese Ansicht ist in vier Bereiche unterteilt:<br />
• Name des Experiments und Informationen zu seiner Generierung<br />
• Komponenten, die für den Testlauf verwendet wurden: Oben wird der Name des<br />
Algorithmus angezeigt. Alle Eingabe-Dokumente (Eingabedateien, Konfigurationen<br />
und Stylesheets) werden in den entsprechenden Tabellen dargestellt.<br />
• Kontext, der die Testlaufbedingungen dokumentiert: Es werden das Betriebssystem,<br />
der Prozessortyp, der Gesamtspeicher und der Name des Servers angezeigt,<br />
auf dem der Testlauf dieses Experiments durchgeführt wurde. Zudem wird die Zeit<br />
angezeigt, die der Algorithmus gebraucht hat um die Berechnungen durchzuführen.<br />
• Kommentar, der das jeweilige Experiment näher beschreibt.<br />
Namen ändern<br />
Den Namen eines Experiments ändert man, indem man mit der rechten Maustaste<br />
auf den entsprechenden Eintrag der Table-View-Tabelle klickt und somit das Popup-<br />
Menü öffnet. Aus diesem Menü wählt man den Punkt “Name ändern“ und gibt anschließend,<br />
in dem erscheinenden Dialog, den neuen Namen ein.<br />
Kommentar verfassen bzw. ändern<br />
Wird im Textfeld “Kommentar“ ein neuer Kommentar verfasst oder ein bestehender<br />
verändert, muss die Eingabe mit dem Button “Änderungen übernehmen“ bestätigt werden.<br />
63
Ins Archiv verschieben<br />
KAPITEL 5. BEDIENUNG DES WERKZEUGS<br />
Abbildung 5.12: Die Details eines Experimentes<br />
Durch Anklicken des Menüpunktes “Ins Archiv“ des Popup-Menüs eines Dokumentes in<br />
der Tabelle der Table-View, wird dieses ins Archiv verschoben und aus dem Arbeitsbereich<br />
entfernt.<br />
Zur Tabelle der Testläufe hinzufügen<br />
Hat man sich dafür entschieden, ein bestehendes Experiment einem wiederholten Testlauf<br />
zu unterziehen, selektiert man dieses in der Table-View, sodass es in der Detail-View<br />
erscheint. Nun betätigt man den Button “Zur Testlauftabelle hinzufügen“, woraufhin das<br />
Experiment zu der besagten Tabelle hinzugefügt wird und die Detail-View zur Ansicht<br />
der Testläufe wechselt. Das Verändern der Attribute des Testlaufs und das Starten der<br />
Berechnung wurde ausführlich im Kapitel “Testläufe“ beschrieben.<br />
Löschen<br />
Um ein Experiment zu löschen, öffnet man, wie schon zuvor beschrieben, das Popup-<br />
Menü des zu löschenden Eintrags und wählt die Option “Löschen“. Nachdem man die<br />
Sicherheitsanfrage bestätigt hat, wird das Experiment endgültig aus dem System entfernt.<br />
64
Ausgabe<br />
KAPITEL 5. BEDIENUNG DES WERKZEUGS<br />
Übersicht Bei jedem korrekt berechneten Testlauf wird auch eine Ausgabe erzeugt, die<br />
die Resultate anzeigt. Diese Ausgabe wird ebenfalls beim Speichern eines Experiments<br />
in der Datenbank abgelegt. Um die Ausgebe eines selektierten Experiments zu betrachten<br />
[Abbildung 5.13], wählt man den Reiter “Ausgabe-Datei“ in der Detail-View des<br />
Experiments.<br />
Abbildung 5.13: Ansicht einer gespeicherten Ausgabe-Datei<br />
In dem nun erscheinenden Texteditor sieht man den Inhalt der Ausgabe-Datei, während<br />
weiter unten die Standard-Ausgabe des Testlaufs als grau unterlegtes Textfeld zu sehen<br />
ist.<br />
Kommentar verfassen bzw. ändern Es besteht die Möglichkeit ebenfalls die Ausgabe-<br />
Datei, im “Kommentar“-Textfeld, mit einem Kommentar zu versehen. Jede Abänderung<br />
des Kommentars muss mit dem “Änderungen übernehmen“-Button bestätigt werden.<br />
Exportieren Das Programm bietet die Option, die Ausgabedatei als eine Datei beliebigen<br />
Formats auf den Datenträger zu exportieren. Hierzu betätigt man, bei selektiertem<br />
Experiment und gewählter “Ausgabedatei“-Ansicht, den Button “Exportieren“. Es<br />
erscheint ein Dateizugriffsdialog in dem man den Namen der neuen Datei und das Speicherziel<br />
wählen kann. Gibt man beim Dateinamen keine Endung an, so wird automatisch<br />
die Endung “.xml“ vergeben.<br />
65
5.6.2 Experimentsequenzen<br />
KAPITEL 5. BEDIENUNG DES WERKZEUGS<br />
Eine Erweiterung der Experimente stellt die Experiment-Sequenz dar. Eine Experimentsequenz<br />
ist eine Ansammlung mehrerer Experimente. Diese eignet sich sehr gut dazu,<br />
ganze Testlauf-Serien wiederholt berechnen zu lassen.<br />
Übersicht<br />
Um eine Experiment-Sequenz zu selektieren, muss bei der Table-View der Bereich<br />
“Experimente“ ausgewählt und der “Experiment-Sequenzen“-Reiter dieser Ansicht aktiviert<br />
sein. Klickt man auf einen Eintrag der Tabelle, erscheint in der Detail-View eine<br />
detaillierte Ansicht dieser Sequenz [Abbildung 5.14]. Diese Ansicht zeigt eine Tabelle mit<br />
allen Experimenten, die von dieser Sequenz referenziert werden.<br />
Namen ändern<br />
Abbildung 5.14: Detail-Ansicht einer Experiment-Sequenz<br />
Durch einen Klick auf den Punkt “Name ändern“ des Popup-Menüs eines Sequenz-<br />
Eintrags in der Table-View, ist es möglich die jeweilige Sequenz umzubenennen.<br />
Kommentar verfassen bzw. ändern<br />
Auch bei der Experimentsequenz besteht die Möglichkeit individuelle Kommentare zu<br />
verfassen. Diese gibt man im Textfeld “Kommentare“ der Detail-View ein und bestätigt<br />
deren Änderung mit dem Button “Änderungen übernehmen“.<br />
66
Ins Archiv verschieben<br />
KAPITEL 5. BEDIENUNG DES WERKZEUGS<br />
Analog zu Einzelexperimenten, lassen sich Experimentsequenzen ebenfalls durch ein<br />
Klick auf den Popup-Menü-Eintrag “Ins Archiv“ ins Archiv auslagern.<br />
Zur Tabelle der Testläufe hinzufügen<br />
Die referenzierten Experimente einer Experimentsequenz fügt man mit dem “Zur Testlauftabelle<br />
hinzufügen“-Button in der Detailansicht der Sequenz zur Testlauftabelle hinzu.<br />
Die Detailansicht wechselt anschließend automatisch zur Ansicht der Testläufe. Das<br />
Starten und Abändern dieser Testläufe wurde im Kapitel “Testläufe“ detailliert beschrieben.<br />
Löschen<br />
Das Löschen einer Experimentsequenz erfolgt indem man den Punkt “Löschen“ im<br />
Popup-Menü des entsprechenden Eintrags in der Table-View anwählt.<br />
67
5.7 Archiv<br />
KAPITEL 5. BEDIENUNG DES WERKZEUGS<br />
Das Archiv bietet die Möglichkeit Dokumente, die man zwar aktuell nicht benötigt, die<br />
man aber nicht endgültig aus dem System entfernen möchte, aus dem Arbeitsbereich<br />
zu entfernen. Dies bietet einen besseren Überblick beim Experimentieren mit aktuellen<br />
Algorithmen. Sollte man die archivierten Dokumente wieder benötigen, ist es jederzeit<br />
möglich, diese aus dem Archiv in den Arbeitsbereich zurück zu verschieben.<br />
5.7.1 Die Archivansicht<br />
Um die Archivansicht [Abbildung 5.15] zu öffnen, klappt man das Untermenü “Work“<br />
des Hauptmenüs auf und wählt den Punkt “Archiv öffnen“. Es erscheint die Archivansicht<br />
mit Archivbereichen für jeden im Programm verwendeten Dokumenttyp. Wie<br />
Dokumente archiviert werden, wurde in den vorangehenden Kapiteln genau beschrieben.<br />
Um zu einem Archivbereich eines bestimmten Dokumenttyps zu wechseln, klickt man<br />
auf den jeweiligen Reiter. Die Dokumente selbst werden, wie auch in der Table-View des<br />
Arbeitsbereiches, durch Einträge in einer Tabelle dargestellt.<br />
Abbildung 5.15: Die Archivansicht mit selektiertem Archivbereich “Algorithmus“<br />
68
KAPITEL 5. BEDIENUNG DES WERKZEUGS<br />
5.7.2 Datei zum Arbeitsbereich verschieben oder löschen<br />
Um eine Datei wieder zum Arbeitsbereich zu verschieben, hat man die Möglichkeit, diese<br />
zunächst mittels des eingebauten Filters zu suchen. Hat man das entsprechende Dokument<br />
gefunden, klickt man in dieser Zeile der Archivtabelle auf den Button “Zurück“,<br />
worauf dieses sofort wieder zum Arbeitsbereich zurück verschoben wird.<br />
Um eine Datei direkt aus dem Archiv heraus zu löschen, betätigt man den “Löschen“-<br />
Button des jeweiligen Tabelleneintrages, worauf eine Sicherheitsabfrage bestätigt werden<br />
muss. Anschließend wird dieses Dokument endgültig aus dem System entfernt.<br />
5.8 Darstellung, Log und Beendigung des Programms<br />
5.8.1 Darstellung<br />
Der Benutzer hat die Möglichkeit, zwischen drei verschiedenen Erscheinungsbildern der<br />
graphischen Oberfläche zu wählen:<br />
• Metal-Look<br />
• Motif-Look<br />
• Windows-Look<br />
Um das Aussehen der graphischen Oberfläche zu ändern, öffnet man im Hauptmenü das<br />
Untermenü “Einstellungen“ und wählt den entsprechenden Menüpunkt. Zu beachten ist,<br />
dass die Option “Windows-Look“ aus rechtlichen Gründen nur Nutzern des Betriebssystems<br />
“Microsoft W INDOW S T M “ 8 vorbehalten ist.<br />
5.8.2 Log<br />
Die wichtigsten Aktionen, die der Benutzer durchführt, werden im unteren Log-Fenster<br />
festgehalten. Somit ist es möglich die Arbeitsschritte, die man getätigt hat, jederzeit<br />
nachzuvollziehen.<br />
5.8.3 Programm beenden<br />
Um das Programm zu beenden, öffnet man im Hauptmenü das Untermenü “System“<br />
und wählt den Punkt “Exit“. Die zweite Möglichkeit das Programm zu beenden besteht<br />
darin, das X-Zeichen des Hauptfensters zu betätigen.<br />
8 Windows ist ein eingetragenes Markenzeichen der Firma Microsoft Corporation<br />
69
6 Erweiterungsmöglichkeiten<br />
Das System verfügt über eine modulare Architektur, welche es erlaubt, neue Funktionalität<br />
ohne größeren Aufwand in das Programm zu integrieren. Im diesem Kapitel sollen<br />
zunächst die Schritte beschrieben werden, die zur Erstellung der funktionserweiternden<br />
Plugins benötigt werden. Anschließend wird der Vorgang der Integration neuer Sprachmodule<br />
detailliert vorgestellt.<br />
6.1 Erstellung und Integration eines Plugins<br />
Die einfachste Methode ein neues Plugin für die “CAEW“ zu Entwickeln, ist, dieses<br />
mit dem Entwicklungstool ’Eclipse“ zu erstellen. Hierfür muss zunächst der bei der Installation<br />
des Programms erstellte Ordner als Workspace von Eclipse definiert werden.<br />
Bei der Erstellung eines neuen Projektes für die Entwicklung des Plugins muss das<br />
“CAEW“-Projekt zum Klassenpfad hinzugefügt werden. Die Entwicklung von Plugins<br />
ohne den Einsatz von “Eclipse“ ist ebenfalls möglich, hierbei muss darauf geachtet werden,<br />
dass das Verzeichnis “bin“, das ein direkter Unterordner des Installationsordners ist,<br />
zum Klassenpfad des eingesetzten Entwicklungwerkzeugs hinzugefügt wird. Im Folgenden<br />
wird als Beispiel ein Plugin erstellt, welches keine relevante Funktion für das System<br />
mitbringt, es fügt lediglich die Worte “PLUGIN ERFOLGREICH HINZUGEFÜGT“ in<br />
die beiden Ansichtsfenster und in die Nachrichtenausgabe ein. Zudem ergänzt es das<br />
Hauptmenü des Systems um den Eintrag “NEUER MENÜPUNKT“. Bei der Entwicklung<br />
dieses Plugins wird auf die Strukturierung in ein Schichtenmodell verzichtet, es wird<br />
lediglich eine Klasse implementiert,die alle benötigten Methoden bereitstellt. Hierdurch<br />
soll der Aufwand der Erstellung des Beispielplugins so gering wie möglich gehalten werden.<br />
Dieses Beispiel kann selbstverständlich als Referenz für die Entwicklung weiterer<br />
Plugins verwendet werden.<br />
Zunächst müssen die oben beschriebenen Vorkehrungen getroffen werden.<br />
Anschließend wird die Klasse “MyPlugin“ erstellt. Diese muss als Hauptklasse des Pluins<br />
die Schnittstelle "de.usi.caew.system.Plugin" des “CAEW“-Projektes implementieren.<br />
Die Schnittstelle beschreibt die zwei Methoden<br />
"setMainSys(de.usi.caew.system.MainSys mainSys)" und<br />
"setMainFrame(de.usi.caew.gui.MFrame mainFrame)", die ebenfalls von der Klasse<br />
Implementiert werden müssen. Mit der Implementierung dieser Methoden beschafft man<br />
die Referenzen auf die Klassen "MainSys" und "MFrame" des “CAEW“-Hauptsystems.<br />
Zudem beherbergt die erstgenannte Methode den Aufruf der zunächst leeren Initialisierungsmethode<br />
start(). Das Listing des Quellcodes der bis hierhin erstellten Klasse<br />
sieht wie folgt aus:<br />
70
import de.usi.caew.system.*;<br />
import de.usi.caew.gui.*;<br />
import javax.swing.*;<br />
public class MyPlugin implements Plugin{<br />
private MainSys mainSys;<br />
private MFrame mainFrame;<br />
public void setMainSys(MainSys mainSys){<br />
this.mainSys = mainSys;<br />
start();<br />
}<br />
public void setMainFrame(MFrame mainFrame){<br />
this.mainFrame = mainFrame;<br />
}<br />
public void start(){<br />
}<br />
}<br />
KAPITEL 6. ERWEITERUNGSM ÖGLICHKEITEN<br />
Die folgende Funktionalität wird als Inhalt der "start"-Methode implementiert. Zunächst<br />
werden zwei "JPanel"-Objekte erstellt, denen wird jeweils ein "Label"-Objekt zugeordnet.<br />
Bei der Erstellung dieser "Label"-Objekte wird deren Konstruktoren der String<br />
"PLUGIN ERFOLGREICH HINZUGEFÜGT" übergeben. Die "JPanel"-Objekte werden mit<br />
Hilfe der Aufrufe der Methoden "getMainView()" und "getTreeView()" des Hauptfensters<br />
in dieses integriert. Anschließend wird mittels der Methode "updateLog(String text)"<br />
der "MainSys"-Klasse und der Methode "updateLog()" des Hauptfensters die Nachrichtenausgabe<br />
des Systems aktualisiert.<br />
JPanel pan1 = new JPanel();<br />
pan1.add(new JLabel("PLUGIN ERFOLGREICH HINZUGEFÜGT"));<br />
JPanel pan2 = new JPanel();<br />
pan2.add(new JLabel("PLUGIN ERFOLGREICH HINZUGEFÜGT"));<br />
mainFrame.getMainView().addTab("tab1", pan1);<br />
mainFrame.getTreeView().addTab("tab2", pan2);<br />
mainSys.updateLog("PLUGIN ERFOLGREICH HINZUGEFÜGT");<br />
mainFrame.updateLog();<br />
Als nächstes soll das Hauptmenü um den Eintrag “NEUER MENÜPUNKT“ erweitert<br />
werden, welcher im Untermenü “Work“ erscheint. Hierzu wird die Methode "getMenu()"<br />
des Hauptfensters verwendet, die ein Objekt des Typs "UsedMenu" zurückgibt. Die<br />
"UsedMenu"-Klasse ist eine Erweiterung der Swing-Klasse "JMenuBar", die einige Zusatzfunktionen<br />
bietet. Dem Hauptmenü, welches durch das "UsedMenu"-Objekt repräsentiert<br />
wird, wird ein neuer Menüpunkt in Form eines "JMenuItem"-Objektes übergeben.<br />
71
KAPITEL 6. ERWEITERUNGSM ÖGLICHKEITEN<br />
JMenuItem menuItem = new JMenuItem("NEUER MENÜPUNKT");<br />
UsedMenu mainMenu = mainFrame.getMenu();<br />
mainMenu.getImports().add(menuItem);<br />
Nach der Compilierung ist die Entwicklung dieses Plugins abgeschlossen. Dieses muss<br />
dem System jetzt zur Verfügung gestellt werden. Aus diesem Grund wird im Verzeichniss<br />
“Plugin“ des Installationsordners ein neuer Ordner mit dem Namen “TestPlugin“<br />
erstellt, in den die compilierte Klasse eingefügt wird. Als zweiter Schritt muss nun eine<br />
XML-Datei, welche nach den Regeln der im Abschnitt “Einbindung von Plugins“ des Kapitels<br />
3.9 gezeigten DTD aufgebaut ist, erstellt werden. Der Inhalt dieser Datei, die unter<br />
dem Namen plugin.xmlëbenalls im Ordner TestPlugin“begelegt wird, sieht wie folgt aus:<br />
<br />
<br />
<br />
In dieser Datei definiert man den Namen des Plugins, der in diesem Fall “Test Plugin“<br />
lautet und gibt mit dem Attribut “Classname“ die Hauptklasse des Plugins, die vom<br />
Hauptsystem geladen wird, an.<br />
Nach dem Start des Systems muss man mittels der Option “Plugins“, die sich im Untermenü<br />
“Admin“ des Hauptmenüs befindet, das erstellte Plugin aktivieren. Bei einem<br />
erneuten Start lädt das System das Plugin und übernimmt dessen Funktionalität. Das<br />
Programm bekommt durch das Plugin das folgende Erscheinungsbild, wobei die relevanten<br />
Stellen rot markiert wurden:<br />
Abbildung 6.1: Das Erscheinungsbild des Systems nach dem Einbinden des Testplugins<br />
72
6.2 Integration eines neuen Sprachpakets<br />
KAPITEL 6. ERWEITERUNGSM ÖGLICHKEITEN<br />
Die Eigenschaft der modularen Spracherweiterung des Systems erlaubt es dem Entwickler,<br />
die Unterstützung von zusätzlichen Sprachen in relativ einfacher Weise und ohne<br />
großen Aufwand in das System zu integrieren. Die Integration eines Pakets, welches das<br />
Programm um die Sprache Französisch erweitert, soll im Folgenden erläutert werden.<br />
Zunächst wird eine leere Textdatei erzeugt und unter dem Namen “Lang fr FR.properties“<br />
im Verzeichnis “Language“, welches ein Unterordner des Installationsordners ist, abgespeichert.<br />
In diese Datei werden nun alle vom Programm genutzten Zeichenketten<br />
mit der Zuweisung eines Schlüssels abgelegt. Dabei werden nur Schlüssel verwendet,<br />
die auch schon in der Datei “Lang en US.properties“ vorkamen. Diesen Schlüsseln wird<br />
die französische Übersetzung der in der Datei “Lang en US.properties“ vorkommenen<br />
Zeichenketten in geeigneter Weise zugeordnet. Ein kurzer Auszug der Datei soll im Folgenden<br />
gezeigt werden:<br />
1=Des filtres supprimer<br />
2=De retour<br />
3=Supprimer<br />
4=Serveur<br />
5=Nom servuer<br />
6=Application<br />
7=Nouveau servuer<br />
8=Nom:<br />
9=Ajouter<br />
.<br />
.<br />
.<br />
Es ist nicht zwingend notwendig allen Schlüsseln eine Übersetzung zuzuordnen. Zeichenketten,<br />
deren Schlüssel in der neuen Sprachdatei nicht vorkommen, werden im Programm<br />
ersatzweise in der englischen Sprache ausgegeben.<br />
Nach der Erstellung der Sprachdatei ist es notwendig, in der XML-Datei “Lang.xml“,<br />
welche sich ebenfalls im Ordner “Language“ befindet, im Tag ein neues<br />
XML-Element hinzuzufügen, mit deren Hilfe dem System Informationen über das neue<br />
Sprachpaket übergeben werden. Nach dem hinzufügen des neuen Elements hat die Datei<br />
folgende Form:<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
73
KAPITEL 6. ERWEITERUNGSM ÖGLICHKEITEN<br />
Nach dem Systemstart kann im erscheinenden Dialog, wie in Abbildung 6.2 dargestellt,<br />
die neu hinzugekommene Sprache aus dem Pull-Down-Menü ausgewählt werden.<br />
Die Ausgabe der Texte im Programm findet nun in der Sprache des neu hinzugefügten<br />
Sprachpakets statt.<br />
Abbildung 6.2: Wahl der neu hinzugekommenen Sprache<br />
74
7 Zusammenfassung und Ausblick<br />
Zusammenfassung<br />
In dieser Arbeit wurde die Entwicklung und die Bedienung eines Werkzeugs vorgestellt,<br />
welches zur Unterstützung rechnergestützter Experimente eingesetzt werden kann. Diese<br />
Experimente dienen dazu, Algorithmen diversen Testläufen zu unterziehen, bei denen<br />
verschiedene Eingaben und Konfigurationen eingesetzt werden um das Laufzeitverhalten<br />
dieser Algorithmen zu ermitteln. Die Verbesserung der Effizienz von Algorithmen kann<br />
oft nur durch wiederholtes Testen und Neukonfigurieren erreicht werden.<br />
Das Werkzeug unterstützt den Nutzer - wie gezeigt wurde - nicht nur bei der Verwaltung<br />
der benötigten Dokumente, die zur Ausführung solcher Experimente eingesetzt werden,<br />
sondern auch bei der Durchführung der Testläufe. Um den Nutzer bei der Berechnung<br />
von mehreren Testläufen zu unterstützen, bietet es die Möglichkeit, diese Berechnungen<br />
auf mehrere Server eines Netzwerkclusters zu verteilen und die einzelnen Testläufe<br />
parallel auszuwerten.<br />
Bevor in dieser Ausarbeitung auf den Entwurf des Werkzeugs und seiner einzelnen<br />
Komponenten eingegangen wurde, wurden vorab die an das System gestellten Anforderungen<br />
und Bedingungen vorgestellt.<br />
Bei der Dokumentation der Entwicklung des Systems wurde gezeigt, dass dessen Aufbau<br />
auf einer modularen Struktur beruht. Die einzelnen Module wiederum weisen eine<br />
Schichtenarchitektur auf, wie sie in dieser Ausarbeitung vorgestellt wurde.<br />
Es wurde gezeigt wie die Einbindung einer relationallen Datenbank mit Hilfe des Frameworks<br />
“Hibernate“ funktioniert und in das System integriert wurde. Hierbei wurden die<br />
verwendeten Datenstrukturen und deren Abbildung auf die eingesetzte Datenbankstruktur<br />
erklärt. Zudem wurde das Verfahren der individuellen Verteilung von eindeutigen<br />
Identifizierern, welche für die persistente Speicherung in einer relationalen Datenbank<br />
benötigt werden, detaillierter vorgestellt.<br />
Nachdem demonstriert wurde, wie das System Dokumente intern verwaltet, wurde auf<br />
die Fähigkeit der Integration neuer Funktionen in das System, mit Hilfe der Einbindung<br />
von Plugins, eingegangen. Anschließend wurde die Funktionalität des Programms<br />
erläutert, die es erlaubt, die Anzahl der unterstützten Sprachen in Form von Sprachpaketen<br />
zu erweitern. Zudem wurde gezeigt, in welcher Weise der Einsatz der graphischen<br />
Oberfläche die modulare Struktur des Systems unterstützt. Um die Funktionalität des<br />
Werkzeugs zu demonstrieren, wurde dessen Installation und Bedienung sehr detailliert<br />
beschrieben.<br />
Anschließend wurde die Entwicklung und Integration eines neuen Plugins sowie eines<br />
neuen Sprachpakets anhand von zwei praktischen Beispielen demonstriert.<br />
75
Ausblick<br />
KAPITEL 7. ZUSAMMENFASSUNG UND AUSBLICK<br />
Das hier entwickelte System stellt den ersten Schritt zur Realisierung eines Werkzeugs<br />
dar, mit dem kooperative und kompetitive algorithmenbasierte Experimentdurchführung<br />
verteilter Nutzer ermöglicht werden soll. Um diese Funktionalität bieten zu können, muss<br />
das System konzeptionell so erweitert werden, dass ein paralleles Arbeiten mehrerer Nutzer,<br />
aber auch ganzer Benutzergruppen, auf der Basis gemeinsamer Dokumentmappen<br />
möglich ist. Um dies zu garantieren, wären die folgenden konzeptionellen Erweiterungen<br />
denkbar:<br />
• Die Verwaltung von vielen Einzelnutzern und Benutzergruppen erfordert eine Funktion<br />
zur Vergabe und Prüfung von Rechten, die diesen Nutzern bzw. Gruppen<br />
zugeteilt werden müssen. Hierzu ist es notwendig, ein administratives System zu<br />
entwickeln, welches durch den Eingriff von als Administrator gekennzeichneten<br />
Nutzer, diese Aufgaben übernimmt. Die Administratoren sollten dabei nicht nur<br />
für den einwandfreien Ablauf des Systems verantwortlich sein, sondern auch die<br />
Aufgabe übernehmen, einzelne Nutzer in das Mehrbenutzersystem aufzunehmen<br />
bzw. diese aus dem System zu entfernen.<br />
• Da bei einem Mehrbenutzersystem viele Nutzer und Nutzergruppen mit dem System<br />
interagieren, ist es womöglich erforderlich - zwecks Identifikation und Kontaktierung<br />
- deren prsönlichen Daten aufzunehmen und zu verwalten. Aus Datenschutzgründen<br />
wäre hierbei ein besonderes Verschlüsselungsverfahren zu empfehlen.<br />
• Der Einsatz einer integrierten Datenbank ist in einem Mehrbenutzersystem nicht<br />
mehr von Interesse. Um die Möglichkeit des Zugriffs vieler Nutzer zu unterstützen,<br />
müsste die Anbindung an einen bestehenden Datenbankserver, wie beispielsweise<br />
MySQL, in das System integriert werden<br />
• Bei der Verwendung eines Datenbankservers müsste die Kommunikation und insbesondere<br />
die Datenübertragung zwischen Client und Server angepasst werden.<br />
Da hierbei davon auszugehen ist, dass die an das Netzwerkcluster angeschlossenen<br />
Server einen direkten Zugriff auf die Datenbank erhalten können, kann die Datenübertragung<br />
direkt zwischen diesen beiden Instanzen ablaufen und nicht mehr<br />
auf dem indirekten Wege über den Client stattfinden.<br />
• Die Übertragung von Daten zwischen Datenbank und Server könnte zudem minimiert<br />
werden. Dies könnte durch eine temporäre Speicherung der vom Server<br />
empfangenen Daten realisiert werden. Bei dem Versuch der Neuübertragung gleicher<br />
Daten könnte anhand einer Checksummenprüfung dies unterbunden werden<br />
um die auf dem Server temporär gespeicherten Daten für eine Berechnung zu nutzen.<br />
• Da einzelne Nutzer bzw. Nutzergruppen nicht unbedingt in einem lokalen Netzwerk<br />
arbeiten, wäre der Zugriff auf das Mehrbenutzersystem über das Internet<br />
76
KAPITEL 7. ZUSAMMENFASSUNG UND AUSBLICK<br />
wünschenswert. Hierzu müssten geeignete Methoden, welche die Datenübertragung<br />
im WWW ermöglichen, zur Verfügung gestellt werden.<br />
• Zur Unterstützung der Entwicklung von Softwareprojekten werden oft Medien,<br />
wie beispielsweise Repositories, eingesetzt. Es wäre in der Mehrbenutzerversion des<br />
Systems von Interesse, den Zugriff auf CVS- bzw SVN-Repositories zu ermöglichen.<br />
Dies stellt jedoch eine besondere Herausforderung dar, da in Repositories in der<br />
Regel Quelltexte der Programme abgelegt werden. Es müsste somit eine Funktion<br />
bereitgestellt werden, welche solche Quellcodes in geeigneter Weise compiliert.<br />
• Die Weiterverarbeiung von Resultaten sollte gefördert werden. Hierzu wäre es sinnvoll,<br />
ein einheitliches Format für diese Ausgabedokumente zu entwickeln. Somit<br />
wäre eine Unterstützung der Weiterverarbeitung mittels verschiedener Werkzeuge,<br />
wie etwa LaTex oder Matlab, relativ einfach zu realisieren.<br />
Die in dieser Ausarbeitung vorgestellte modulare Architektur, welche im Hinblick auf<br />
das Mehrbenutzersystem entwickelt wurde, erlaubt es, eine solche Funktionalität mit<br />
relativ geringem Aufwand in das System zu integrieren. Die Entwicklung der Mehrbenutzerfunktionalität<br />
soll als Nachfolgeprojekt Gegenstand einer weiteren Diplomarbeit<br />
sein.<br />
77
8 Anhang<br />
Anhang A<br />
Der Aufbau aller persistent zu speichernden Daten des Systems:<br />
78
Anhang B<br />
KAPITEL 8. ANHANG<br />
In diesem Anhang sind alle für die Nutzung von “Hibernate“ verwendeten Konfigurationsund<br />
Mappingdateien aufgelistet.<br />
SessionFactory-Konfigurationsdatei (“hibernate.cfg.xml“)<br />
<br />
<br />
<br />
<br />
<br />
org.apache.derby.jdbc.EmbeddedDriver<br />
<br />
<br />
jdbc:derby:derbyDB/db; create=true<br />
<br />
sa<br />
<br />
org.hibernate.dialect.HSQLDialect<br />
false<br />
<br />
org.hibernate.transaction.JDBCTransactionFactory<br />
<br />
<br />
org.hibernate.cache.HashtableCacheProvider<br />
<br />
create<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
79
Mapping-XML-Datei für das Mapping von Algorithm-Objekten<br />
(“Algorithm.hbm.xml“)<br />
KAPITEL 8. ANHANG<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
80
KAPITEL 8. ANHANG<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Mapping-XML-Datei für das Mapping von InputData-Objekten<br />
(“InputData.hbm.xml“)<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Mapping-XML-Datei für das Mapping von Config-Objekten (“Config.hbm.xml“)<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
81
KAPITEL 8. ANHANG<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Mapping-XML-Datei für das Mapping von User-Objekten (“User.hbm.xml“)<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Mapping-XML-Datei für das Mapping von User-Objekten (“User.hbm.xml“)<br />
Mapping-XML-Datei für das Mapping von RessourcePart-Objekten<br />
(“RessourcePart.hbm.xml“)<br />
<br />
<br />
<br />
82
KAPITEL 8. ANHANG<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Mapping-XML-Datei für das Mapping von Context-Objekten (“Context.hbm.xml“)<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Mapping-XML-Datei für das Mapping von OutputData-Objekten<br />
(“OutputData.hbm.xml“)<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
83
KAPITEL 8. ANHANG<br />
<br />
<br />
<br />
<br />
Mapping-XML-Datei für das Mapping von Experiment-Objekten<br />
(“Experiment.hbm.xml“)<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Mapping-XML-Datei für das Mapping von ExpSequence-Objekten<br />
(“ExpSequence.hbm.xml“)<br />
<br />
KAPITEL 8. ANHANG<br />
’-//Hibernate/Hibernate Mapping DTD 3.0//EN’<br />
’http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd’><br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Mapping-XML-Datei für das Mapping von Schema-Objekten (“Schema.hbm.xml“)<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Mapping-XML-Datei für das Mapping von IDContainer-Objekten<br />
(“IDContainer.hbm.xml“)<br />
<br />
<br />
<br />
85
KAPITEL 8. ANHANG<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
86
Literaturverzeichnis<br />
[Merz04] Vorlesung: Algorithmen, W.Merzenich, Uni-<strong>Siegen</strong> 2004<br />
[Kel1] Software-Architekturen, Vorlesung Softwaretechnik II, Udo Kelter; 2003<br />
[Kel2] Vorlesung Datenbanken, Udo Kelter; 2007<br />
[Kel3] Vorlesung Datenbanken II, Udo Kelter; 2007<br />
[Sun99] Java Look and Feel Design Guidelines, Inc. Sun Microsystems 1999<br />
[Ba07] Java 6 Anwendungen programmieren. Von der GUI-Programmierung bis<br />
zur Datenbank-Anbindung, Helmut Balzert, W3l 2007<br />
[ZiBa05] Apache Derby - Off to the Races, Paul C. Zikopoulos, George Baklarz und<br />
Dan Scott 2005<br />
[BaKi05] Java persistance with hibernate, Christian Bauer und Gavin King, Manning<br />
Publications Co. 2005<br />
[BeHa07] Hibernate, Robert F. Beeger, Arno Haase, Stefan Roock, Dpunkt Verlag<br />
2007<br />
[HiKe07] Hibernate und die Java Persistence API, Robert Hien, Markus Kehle, Entwickler.Press<br />
Verlag 2006<br />
[SaSa03] Datenbanken und Java, Gunter Saake und Kai-Uwe Sattler, Dpunkt Verlag<br />
2003<br />
[SaSa01] JDBC in der Praxis. Datenbankanwendungen in Intranet und Internet, Rainer<br />
Klute , Addison Wesley Verlag; 2001<br />
[GoWe01] Java als erste Programmiersprache,<br />
Joachim Goll, Cornelia Weiß und Frank Müller, Teubner Verlag 2001<br />
[Ho00] Datenbanken programmieren mit JDBC in 21 Tagen,<br />
Ashton Hobbs, Pearson Education 2000<br />
[Be02] Verteilte Systeme. Client-Server-Computing für Studenten und Praktiker,<br />
Günther Bengel, Vieweg Verlag 2002<br />
[DeCz01] Netzwerkprogrammierung unter LINUX und UNIX,<br />
Andrew Deitsch, David Czarnecki, O’Reilly Media 2001<br />
87
Literaturverzeichnis<br />
[FiMü02] Java Internationalization,<br />
Stefan Fischer, Walter Müller, Hanser Fachbuch 1998 Java Internationalization<br />
[He03] Grundlegende Algorithmen,<br />
Folker Heun, Vieweg Verlag 2003<br />
[Sch01] Algorithmik,<br />
Uwe Schöning, Spektrum Akademischer Verlag 2001<br />
88
Erklärung<br />
Literaturverzeichnis<br />
Ich versichere, dass ich meine Arbeit selbständig verfasst und keine anderen<br />
als die angegebenen Quellen und Hilfsmittel benutzt sowie alle Stellen, die<br />
wörtlich oder sinngemäß aus Veröffentlichungen entnommen worden sind, als<br />
solche kenntlich gemacht habe.<br />
<strong>Siegen</strong>, Juli 2007<br />
89