entwurf und implementierung einer modular erweiterbaren ... · entwurf und implementierung einer...
TRANSCRIPT
University of Zurich Department of Informatics
Entwurf und Implementierung einer modular erweiterbaren Anwendung
für Eingabe und Import von heterogenen Daten
Diplomarbeit in Informatik vorgelegt von
Claude Humard Aarau, Schweiz
Matrikelnummer: 01-719-483
Betreuer: Boris Glavic, Prof. Dr. Klaus R. Dittrich
Datum der Abgabe: 02. Mai 2007 University of Zurich Department of Informatics (IFI) Binzmühlestrasse 14, CH-8050 Zürich, Switzerland
DIP
LOM
AR
BE
IT
- D
atab
ase
Tec
hnol
ogy
Res
earc
h G
roup
, Pro
f. D
r. K
laus
R. D
ittric
h
Diploma Thesis Database Technology Research Group Department of Informatics (IFI) University of Zurich Binzmühlestrasse 14, CH-8050 Zürich, Switzerland URL: http://www.ifi.unizh.ch/dbtg
Zusammenfassung
III
Zusammenfassung
Im Rahmen des Nationalen Forschungsschwerpunktes (NFS) Sesam wird eine Applikation
für die Validierung und Speicherung der Messdaten inklusive deren Metadaten benötigt.
Die Besonderheit dieser Messdaten liegt in deren Heterogenität: dies können Barcodes,
Fragebögen und sogar Videodaten sein. Die Herausforderung besteht in der Entwicklung
einer Architektur, die sich flexibel um neue Datenformate erweitern lässt. Das Ziel der
vorliegenden Arbeit ist der Entwurf und die Implementierung einer modular aufgebauten
Anwendung in Java, die diesen Anforderungen gerecht wird. Dabei werden auch die
verwendeten Konzepte, Design-Patterns und Frameworks beschrieben. Ausserdem soll ein
vertieftes Verständnis für die entwickelte Architektur vermittelt werden, um zukünftige
Weiterentwicklungen der Applikation zu unterstützen.
Diplomarbeit
IV
Abstract
V
Abstract
In the context of the national main research Sesam, an application is required to validate
and store the results of research activities including their metadata. The measured data is
very heterogeneous as it contains barcodes, questionnaires or even video files. The main
challenge of this thesis is the development of an architecture, which can be easily extended
to support new data formats. The aim of this diploma thesis is to develop a draft and an
implementation of a modular application written in Java, which covers the requirements
mentioned above. Additionally, the used concepts, design patterns and frameworks are
described in detail. Furthermore, in-depth presentation of the developed architecture is
included to support further enhancements of the application.
Diplomarbeit
VI
Inhaltsverzeichnis
1 EINLEITUNG ........................................................................................................................................1
1.1 SESAM-STUDIE ................................................................................................................................1
1.1.1 Hintergrund................................................................................................................................1
1.1.2 Nutzen.........................................................................................................................................2
1.1.3 Rolle der Datenbankgruppe der Universität Zürich...................................................................3
1.2 AUFGABENSTELLUNG......................................................................................................................3
1.3 PROBLEME.......................................................................................................................................4
1.4 MOTIVATION ...................................................................................................................................5
2 RELATED WORK.................................................................................................................................6
2.1 DATENHETEROGENITÄT...................................................................................................................6
2.1.1 Einleitung ...................................................................................................................................6
2.1.2 Technische Heterogenität...........................................................................................................7
2.1.3 Syntaktische Heterogenität.........................................................................................................7
2.1.4 Datenmodellheterogenität..........................................................................................................7
2.1.5 Strukturelle Heterogenität..........................................................................................................8
2.1.6 Schematische Heterogenität .......................................................................................................9
2.1.7 Semantische Heterogenität.........................................................................................................9
2.1.8 Zusammenfassung ....................................................................................................................10
2.2 DATA PROVENANCE......................................................................................................................10
2.2.1 Ansätze zur Rückverfolgung von Datenänderungen.................................................................11
2.2.2 Ansätze zur Speicherung der Provenance ................................................................................12
2.2.3 Daten- vs. Prozessorientierte Provenance ...............................................................................12
2.2.4 Der Provenance Ansatz von Sesam..........................................................................................13
2.3 XML..............................................................................................................................................13
2.3.1 XML Schema ............................................................................................................................15
2.4 OBJEKT-RELATIONALES-MAPPING................................................................................................15
2.4.1 Mapping Grundkonzepte ..........................................................................................................16
Inhaltsverzeichnis
VII
2.4.2 Mapping von Vererbungen ...................................................................................................... 16
2.4.3 Mapping von Beziehungen....................................................................................................... 20
2.4.4 Zusammenfassung.................................................................................................................... 22
3 VORGEHEN ........................................................................................................................................ 23
4 SPEZIFIKATION................................................................................................................................ 24
4.1 PROZESS DER DATENERHEBUNG................................................................................................... 24
4.2 DATENMODELL ............................................................................................................................. 25
4.3 USE CASES.................................................................................................................................... 28
4.4 HETEROGENE DATEN .................................................................................................................... 29
4.5 MODULARE ERWEITERBARKEIT.................................................................................................... 30
4.6 WEITERE ANFORDERUNGEN......................................................................................................... 31
4.7 ZUSAMMENFASSUNG..................................................................................................................... 32
5 ARCHITEKTUR ................................................................................................................................. 34
5.1 DAS ENTITÄTEN-RELATIONEN-MODELL....................................................................................... 34
5.1.1 ERM-Schema Experiments, Processes and Measurements ..................................................... 35
5.2 ÜBERSICHT................................................................................................................................... 37
5.2.1 Einführung Architektur............................................................................................................ 37
5.2.2 Importprozess .......................................................................................................................... 39
5.2.3 Eingabeverarbeitung ............................................................................................................... 40
5.2.4 Validierung.............................................................................................................................. 41
5.2.5 Speicherung ............................................................................................................................. 42
5.2.6 Fehlerbehandlung.................................................................................................................... 43
5.2.7 Verantwortlichkeiten ............................................................................................................... 44
5.3 XML-OBJEKT-MAPPING............................................................................................................... 44
5.4 VALIDIERUNG ............................................................................................................................... 45
5.5 OBJEKT-RELATIONEN-MAPPING................................................................................................... 46
5.6 DATENBANKANBINDUNG .............................................................................................................. 47
6 DETAILENTWURF............................................................................................................................ 49
6.1 DATENMODELLE ........................................................................................................................... 49
6.1.1 Eingabemodell ......................................................................................................................... 50
Diplomarbeit
VIII
6.1.2 Metamodell...............................................................................................................................52
6.2 TRANSAKTIONEN ...........................................................................................................................54
7 IMPLEMENTIERUNG.......................................................................................................................57
7.1 EINGABEVERARBEITUNG ...............................................................................................................57
7.1.1 Anforderung .............................................................................................................................57
7.1.2 Umsetzung................................................................................................................................58
7.1.3 Pendenzenliste..........................................................................................................................60
7.1.4 Vergleich zweier XML-Java-Binding-Frameworks..................................................................62
7.2 VALIDIERUNG ................................................................................................................................65
7.2.1 Anforderung .............................................................................................................................65
7.2.2 Problematik eines generischen Ansatzes..................................................................................66
7.2.3 Umsetzung................................................................................................................................66
7.2.4 Einsatz von Threads .................................................................................................................70
7.3 SPEICHERUNG................................................................................................................................72
7.3.1 Anforderung .............................................................................................................................72
7.3.2 Umsetzung................................................................................................................................73
7.3.3 Vergleich von Objekt-Relationalen-Mapping-Frameworks .....................................................77
7.3.4 Umgang mit der Vererbungshierarchie der Prozesse ..............................................................78
7.3.5 Historisierung der Daten .........................................................................................................80
7.4 ZUSAMMENFASSUNG.....................................................................................................................81
8 TESTEN ................................................................................................................................................83
8.1 JUNIT.............................................................................................................................................83
8.2 TEST-AUFBAU ...............................................................................................................................84
8.3 ZUSAMMENFASSUNG.....................................................................................................................85
9 ZUSAMMENFASSUNG......................................................................................................................86
10 WEITERFÜHRENDE ARBEITEN....................................................................................................88
10.1 DATA ITEMHANDLER .....................................................................................................................88
10.2 TESTDATEN ...................................................................................................................................88
10.3 BENUTZERTESTS............................................................................................................................88
10.4 VERBESSERUNG DER GRAFISCHEN BENUTZEROBERFLÄCHE..........................................................89
Inhaltsverzeichnis
IX
10.5 UPDATEMÖGLICHKEITEN .............................................................................................................. 89
10.6 ZUSÄTZLICHE INPUTPLUGINS ....................................................................................................... 89
11 LITERATURVERZEICHNIS............................................................................................................ 91
12 ABBILDUNGSVERZEICHNIS ......................................................................................................... 94
13 ANHANG.............................................................................................................................................. 96
13.1 XML IMPORT-SCHEMA I (EXPERIMENT)....................................................................................... 97
13.2 XML IMPORT SCHEMA II (PROZESS) ............................................................................................ 98
1. Einleitung
1
1 Einleitung
Diese Einleitung soll eine kurze Einführung über den Nationalen Forschungsschwerpunkt
(NFS) namens Sesam geben sowie die Rolle der Universität Zürich darlegen.
Anschliessend wird die Aufgabenstellung für diese Diplomarbeit und die Motivation
erläutert.
Kapitel 1.1 lehnt sich mehrheitlich an die Projektbeschreibung von der offiziellen Sesam-
Homepage [Sesam] an.
1.1 Sesam-Studie
Sesam ist die Abkürzung für „Swiss Etiological Study of Adjustment and Mental Health“,
was übersetzt soviel bedeutet wie „Schweizerische ätiologische Studie zur psychischen
Gesundheit“. Sesam ist ein Nationaler Forschungsschwerpunkt mit dem Ziel, die
komplexen Ursachen aufzudecken, die zu einer gesunden psychischen Entwicklung über
die Lebensspanne führen. Sesam will dazu beitragen, menschliche Entwicklung und
seelische Gesundheit besser zu verstehen. Dazu begleitet die interdisziplinäre Studie 3000
Kinder und ihre Familien über 20 Jahre, beginnend ab Frühling 2007. An Sesam sind ein
Netzwerk von Wissenschaftlern aus dem In- und Ausland sowie Spitäler in der ganzen
Schweiz beteiligt. Die Heiminstitution dieses NFS ist die Universität Basel.
1.1.1 Hintergrund
Gesundheit ist für die meisten Menschen das höchste Gut. Weltweit leiden jedoch immer
mehr Menschen unter psychischen Störungen. Das Ausmass und die Folgen, besonders in
den Industrienationen, sind besorgniserregend.
Nach Aussage der Weltgesundheitsorganisation (WHO) wird in den kommenden
Jahrzehnten die psychische Gesundheit wesentlich über das Wohlergehen des Einzelnen
und der Gesellschaft entscheiden. Im Jahr 2020 werden Depressionen die zweithäufigste
Ursache schwerer gesundheitlicher Beeinträchtigungen und vorzeitiger Sterblichkeit sein.
In den Industriestaaten sind psychische Erkrankungen – vorweg Depressionen – die viert
häufigste Ursache von schwerwiegenden Beeinträchtigungen: Im Jahre 2002 standen in der
Schweiz 543 Verkehrstoten (Strasse und Schiene) 1546 Suizide gegenüber. Psychische
Diplomarbeit
2
Erkrankungen gehören damit auch in der Schweiz zu den grössten Herausforderungen des
Gesundheitswesens. Die durchschnittliche Wahrscheinlichkeit, im Laufe des Lebens an
einer psychischen Störung zu erkranken, liegt derzeit bei über 40%.
1.1.2 Nutzen
Was sind die Ursachen und Auslöser von psychischen Störungen wie Depressionen oder
belastenden Ängsten? Welche Risikofaktoren begünstigen ihren Ausbruch, welche
Schutzfaktoren wirken ihnen entgegen? Die Forschung kann diese Fragen heute noch nicht
zufrieden stellend beantworten. Obwohl viele Einflussfaktoren bekannt sind, fehlen
wissenschaftlich fundierte Befunde über deren genaue Wirkung und vor allem ihr
gegenseitiges Zusammenwirken. Ohne solches Wissen können im Bereich psychischer
Erkrankungen und psychischer Gesundheit nicht genügend wirkungsvolle – vorweg auch
präventive – Strategien entwickelt werden.
Was Sesam erreichen möchte:
• Gesundheitsfördernde und schützende Faktoren identifizieren.
• Konstellationen im Lebenskontext verstehen, die einer gesunden psychischen
Entwicklung entgegenstehen.
• Grundlagen für die Entwicklung wirksamer Prävention, Behandlung und
Bewältigungsstrategien bei psychischen Krankheiten und Lebenskrisen entwickeln.
Die Tatsache, dass die Forschung die Ursachen und Wirkungsfaktoren von psychischen
Erkrankungen noch nicht hinreichend erklären kann, ist, angesichts von Erkrankungsraten
von weit über 40%, beunruhigend.
Sesam erforscht die komplexen Ursachen, die zu einer gesunden psychischen Entwicklung
vom Kindes- bis ins Erwachsenenalter führen. Es geht dabei um eine grundlegende
Erforschung der gesundheitserhaltenden und krankmachenden Faktoren bei der
psychischen Entwicklung von Menschen.
Empfehlungen und konkrete Ratschläge zur Verbesserung der psychischen Gesundheit der
Bevölkerung können nur dann gesichert abgegeben werden, wenn umfassendes
disziplinenübergreifendes Wissen zur menschlichen Entwicklung über die gesamte
Lebensspanne vorliegt. Dieses Wissen steht uns heute noch nicht in ausreichendem
Umfang zur Verfügung.
1. Einleitung
3
Die Häufigkeit und die alarmierende Zunahme psychischer Erkrankungen führen
unweigerlich zu gesundheitsökonomischen Herausforderungen. Selbst in der „reichen“
Schweiz befinden sich die Gesundheits- und Sozialausgaben in einer Höhe, die viele
Menschen, insbesondere Familien und Alleinerziehende, vor finanzielle Probleme stellt.
Ein besseres Verständnis der psychischen Gesundheit ist daher für die Gesundheits- und
Sozialpolitik wie auch für die Volkswirtschaft von Bedeutung.
1.1.3 Rolle der Datenbankgruppe der Universität Zür ich
Die Sesam-Studie wird eine grosse Menge an Daten wie Fragebögen, biologische
Analysen, genetische Daten, Multimedia-Inhalte und Ablaufdaten generieren. Die
Datenbankgruppe der Universität Zürich übernimmt die Aufgabe der Datenspeicherung im
Rahmen des Projekts sesamDB. Das Ziel von sesamDB ist die Entwicklung und
Implementierung einer Datenbank mit entsprechenden Anwender-Programmen, um
verschiedene Arten von Daten und Metadaten zu bewältigen. Neben Speicherung und
Management der Informationen, wird sesamDB benutzt, um den Workflow des Sesam-
Projekts zu unterstützen. Da die meisten der gesammelten Daten persönliche
Informationen enthalten, hat das Sesam-Projekt höchste Ansprüche was die Sicherheit der
verwalteten Daten betrifft.
Aus der Sicht des Informatik-Forschers eröffnet das Sesam-Projekt die Möglichkeit, ein
breites Feld von Datenbank-Techniken und –Konzepten in einer Real-Welt-Anwendung
einzusetzen. Die eingesetzten Konzepte und Techniken umfassen die Gebiete des
Workflow-Managements, Datenhistorisierung und –versionisierung, Qualitätsmanagement,
Datensicherheit und Verwaltung von Multimedia- und Ablaufdaten.
1.2 Aufgabenstellung
Die im Rahmen des sesamDB-Projekts zu entwickelnde Datenbank (sesamDB) dient dazu,
die unterschiedlichen Daten, die im Rahmen des Forschungsprojektes anfallen, zu
verwalten. Dazu gehören einerseits diverse administrative Daten, wie zum Beispiel die
Personendaten von Probanden und Mitarbeitern. Andererseits entstehen aus den
Untersuchungen und Messungen der jeweiligen Studien eine Vielzahl von
wissenschaftlichen Daten, die sehr unterschiedlich in ihrer Struktur und ihrem Inhalt sein
können. Der Fokus dieser Arbeit liegt auf diesen äusserst heterogenen, wissenschaftlichen
Daten. Es wird eine Anwendung benötigt, die es ermöglicht, diese Daten in sesamDB zu
Diplomarbeit
4
importieren. Im Hinblick auf die zeitlich langfristige Ausrichtung der Studie soll die
Anwendung modular aufgebaut und einfach erweiterbar sein, um sie an zukünftige
Anforderungen anpassen zu können.
Diese Arbeit umfasst den Entwurf eines Konzeptes für eine flexibel erweiterbare
Anwendung für Dateneingabe und –import. Gleichzeitig soll das entwickelte Konzept
umgesetzt und mit einer entsprechenden Benutzeroberfläche implementiert werden. Als
Ergebnis soll eine dokumentierte, voll funktionstüchtige und getestete Clientanwendung
vorliegen, welche die oben genannten Aufgaben erfüllt. Dazu gehören auch Installations-
und Konfigurationsanleitungen, um die Software leicht und zuverlässig in Betrieb zu
nehmen.
Der zeitliche Rahmen für diese Arbeit ist auf 6 Monate beschränkt.
1.3 Probleme
Bereits bei der ersten Betrachtung der Aufgabenstellung zeichnen sich eine Reihe
vielfältiger Probleme und Schwierigkeiten ab. Angesichts des sehr umfangreichen und
nicht trivialen Datenbank-Schemas der sesamDB könnte das Mapping von Objekten auf
die jeweiligen Relationen der Datenbank und umgekehrt zu einer Herausforderung werden,
insbesondere auch was die Performance der Applikation betrifft.
Eine Anforderung an die Anwendung ist das Handling von heterogenen Daten. Obwohl ein
Grossteil der Eingaben in Form von XML-Dateien erfolgen wird, fallen auch multimediale
Daten an, wie zum Beispiel Videoaufzeichnungen von Interviews. Hier drängt sich unter
Umständen eine spezielle Lösung auf, da solche umfangreiche Multimedia-Dateien
möglicherweise zu einem Speicherplatz-Problem führen könnten.
Die Form und Struktur der Datenimporte orientiert sich grösstenteils am relationalen
Schema der sesamDB. Es wird eine besondere Herausforderung sein, anhand des Inhalts
der Dateneingabe die entsprechende Struktur aus der Datenbank zu extrahieren um
anschliessend die Eingabe gegen dieses Schema zu validieren.
Auf konzeptioneller Ebene besteht die Schwierigkeit darin, die Architektur der
Anwendung so zu wählen, dass letztere modular aufgebaut und flexibel erweiterbar ist.
Hier ist es wichtig, die Lösungsansätze vor Beginn der Implementierung aufzuzeichnen, da
ein späteres Redesign zu aufwändig wäre. Dieser Punkt deutet auf den kritischen Faktor
1. Einleitung
5
Zeit hin. Die Entwicklungszeit der Anwendung ist auf sechs Personenmonate limitiert, so
dass bei der Umsetzung stets die zeitliche Machbarkeit im Auge behalten werden muss.
1.4 Motivation
Die Motivation für diese Diplomarbeit lässt sich aus unterschiedlichen Aspekten ableiten.
Zum einen besteht sicher ein Anreiz darin, mit dieser Arbeit zumindest indirekt einen
Beitrag an ein nationales Forschungsprojekt wie Sesam zu leisten, das selbst in den
Tagesmedien präsent ist (siehe [Mašek07] und [Sieber07]). Die Aussicht, dass die zu
entwickelnde Anwendung für das Projekt benötigt und über längere Zeit verwendet wird,
erhöht den Ansporn, ein einwandfreies Produkt abzuliefern.
Sehr interessant sind auch die vielseitigen Anforderungen an die Applikation. Einerseits ist
Verständnis in der Datenbanktechnik gefragt, um einen sinnvollen Umgang mit der
komplexen und umfangreichen sesamDB zu finden. Andererseits spielen auch Aspekte der
Sicherheit und Verschlüsselung eine nicht unwesentliche Rolle, wenn es zum Beispiel
darum geht, die Dateneingaben auf sicherem Weg zur Datenbank zu übertragen. Die
Vielfältigkeit der Aufgabenstellung wird ergänzt mit der konzeptionellen Herausforderung,
eine modulare und erweiterbare Anwendung zu entwerfen. Spannend bei dieser Arbeit ist
auch der umfangreiche Einsatz von XML, eine Sprache die aus der Informatikwelt nicht
mehr wegzudenken ist.
Ein wichtiger Motivationsfaktor besteht für mich darin, dass diese Arbeit sowohl
konzeptionelle wie auch praktische Aspekte abdeckt. Ich kann nachvollziehen, wie
Informatik-Ansätze aus Wissenschaft und Forschung in eine gebrauchsfähige
Implementierung einfliessen. Zudem sind meine wichtigsten Studienschwerpunkte von
dieser Diplomarbeit abgedeckt.
Diplomarbeit
6
2 Related Work
2.1 Datenheterogenität
Dieses Kapitel befasst sich mit der Heterogenität bei der Datenintegration. Darunter
versteht man das Zusammenführen von Daten aus unterschiedlichen, meist verteilten
Quellen. Nachfolgend werden die verschiedenen Arten von Heterogenität beleuchtet, die
dabei auftreten können. Gleichzeitig wird jeweils Bezug auf das Sesam-Projekt und die zu
entwickelnde Anwendung genommen.
2.1.1 Einleitung
Man bezeichnet zwei Datenobjekte als heterogen, wenn sie über unterschiedliche Modelle
oder Strukturen verfügen, oder in unterschiedlichen Formaten gespeichert sind. Daraus
wird bereits deutlich, dass Heterogenität verschiedene Facetten hat. Die Form und
Darstellung von Daten hängt ab von ihrem Kontext, den eingesetzten Anwendungen, den
Vorlieben des Programmierers, den Anforderungen, den technischen Gegebenheiten etc.
Das Sesam-Projekt ist in 12 Teilstudien aufgeteilt, die ganz unterschiedliche
Forschungsgebiete abdecken, beispielsweise Genetik, Familienprozesse oder Befinden in
der Schwangerschaft. Dies führt auch zu ganz unterschiedlichen Datenmodellen und –
strukturen, die in der sesamDB auf ein relationales Modell (bzw. auf eine relationale
Datenbank) abgebildet und gespeichert werden müssen.
Naumann und Leser ([LN07]) unterscheiden zwischen folgenden Arten von Heterogenität:
• Technische Heterogenität
• Syntaktische Heterogenität
• Datenmodellheterogenität
• Strukturelle Heterogenität
• Schematische Heterogenität
• Semantische Heterogenität
Diese werden nachfolgend erläutert und mit dem Sesam-Projekt in einen Zusammenhang
gebracht.
2. Related Work
7
2.1.2 Technische Heterogenität
Bei technischer Heterogenität stehen nicht direkt die Daten selber im Vordergrund,
sondern die Art und Weise, wie auf diese zugegriffen werden kann. Tabelle 1 zeigt eine
Übersicht wichtiger Konzepte und einige beispielhafte Ausprägungen davon.
Tabelle 1: Ebenen der technischen Heterogenität (Quelle: [LN07])
Ebene Mögliche Ausprägungen
Anfragemöglichkeit Anfragesprache, parametrisierte Funktionen, Formulare
Anfragesprache SQL, XQuery, Volltextsuche
Austauschformat Binärdaten, XML, HTML, tabellarisch
Kommunikationsprotokoll HTTP, JDBC, SOAP
Im Zusammenhang mit Sesam und der zu entwickelnden Anwendung ist vor allem das
Austauschformat von Relevanz. Die Daten werden nicht über eine Netzwerkverbindung
oder ähnliches abgefragt, sondern mittels einfachen Datenaustauschs übermittelt (siehe
dazu später Kapitel 4.1 Prozess der Datenerhebung). Das Datenformat kann dabei ganz
unterschiedlich ausfallen, abhängig von der Art der Information und der Anwendung, die
das Datenobjekt erstellt.
2.1.3 Syntaktische Heterogenität
Mit syntaktischer Heterogenität sind die technischen Unterschiede bei der Darstellung
gleicher Informationen gemeint. Wird beispielsweise derselbe Text einmal in ASCII-
Format und einmal im Unicode-Format gespeichert, so sind die resultierenden Textdateien
syntaktisch heterogen. Ein weiteres Beispiel ist die Speicherung eines Bytes. Dieses kann
als Zahlenwert gespeichert werden oder aber mittels des Base64-Kodierverfahrens (RFC
4648) durch ASCII-Zeichen ausgedrückt werden. In beiden Fällen wird die exakt gleiche
Information auf unterschiedliche Weise dargestellt.
Syntaktische Heterogenität kann in der Regel einfach behoben werden: Zahlenformate
lassen sich umrechnen und Zeichendarstellung ineinander transformieren. Deshalb soll an
dieser Stelle nicht weiter darauf eingegangen werden.
2.1.4 Datenmodellheterogenität
In der Softwareentwicklung wird man ständig mit Datenmodellheterogenität konfrontiert.
So wird beispielsweise für die Datenmodellierung UML als Modell eingesetzt, für die
Diplomarbeit
8
Verwaltung der Daten wird eine Datenbank basierend auf dem relationalen Modell
verwendet und für den Datenaustausch kommt XML zum Einsatz.
Datenmodellheterogenität liegt vor, wenn zwei Datenobjekte unterschiedliche
Datenmodelle verwenden. Dies führt gleichzeitig fast immer zu semantischer
Heterogenität, da die jeweiligen Datenmodelle bereits über eine gewisse Semantik
verfügen. Darauf soll in Abschnitt 2.1.7 näher eingegangen werden.
Die Überbrückung der Datenmodellheterogenität ist eine der Hauptaufgaben der zu
entwickelnden Applikation. Mit sesamDB ist das relationale Modell als Zielmodell
vorgegeben. Ein Grossteil der zu importierenden Daten wird im XML-Format eintreffen,
jedoch können, je nach verwendeten Anwendungen, auch andere Datenmodelle zum
Einsatz kommen.
2.1.5 Strukturelle Heterogenität
Auch wenn ein bestimmtes Datenmodell festgelegt wurde, so bestehen immer noch viele
Möglichkeiten, einen Anwendungsbereich durch ein Schema zu beschreiben. Gemäss
Naumann und Leser [LN07] liegt strukturelle Heterogenität vor, wenn zwei Schemata
unterschiedlich sind, obwohl sie den gleichen Ausschnitt aus der realen Welt erfassen.
Die Ursachen dafür können ganz unterschiedlich sein, abhängig von den jeweiligen
Anforderungen, dem benötigten Ausschnitt der realen Welt und den technischen
Gegebenheiten und Möglichkeiten.
Eine häufige Ursache für strukturelle Heterogenität ist die grosse Anzahl von Variationen,
wie ein konzeptionelles Modell in ein logisches übersetzt werden kann. Ein Beispiel dafür
ist das Konzept der Vererbung. Dieses lässt sich in einem Gegenstands-Beziehungs-Modell
(engl. entity-relationship-model), das häufig als Grundlage für die Implementierung von
Datenbanken verwendet wird, ohne weiteres darstellen. Das relationale Modell, auf dem
eine grosse Zahl von Datenbanken beruht, kennt aber keine Vererbung1. Es gibt aber eine
Reihe von Möglichkeiten, wie eine Vererbung in einer relationalen Datenbank abgebildet
werden kann (vgl. Abschnitt 2.4.2).
1 Tatsächlich gibt es aber diverse Datenbankmanagementsysteme (DBMS), die das Konzept der Vererbung
implementieren (beispielsweise PostgreSQL). Dabei handelt es sich aber meist um eine DBMS-spezifische
Erweiterung, die losgelöst ist vom relationalen Modell.
2. Related Work
9
Ein weiterer Grund besteht darin, dass ein Schema für bestimmte Anfragen optimiert
werden muss. Wird beispielsweise eine Vererbungshierarchie im relationalen Modell so
implementiert, dass jede Klasse auf eine eigene Relation abgebildet wird (vgl. Abschnitt
2.4.2.3), so werden in der Regel mehr Joins benötigt, um wieder an die Daten zu gelangen.
Dies kann unter Umständen negative Auswirkungen auf die Geschwindigkeit der Anfrage
haben, da Joins kostenintensive Operationen sind.
Eine dritte Ursache liegt in der Freiheit, die Attribute von Ausschnitten der realen Welt
beliebig festzulegen und zu unterteilen. So kann beispielsweise eine Adresse als einzelnes
Attribut gespeichert oder in Strasse, Nummer, PLZ und Ort aufgeteilt werden. Die
Semantik ist dabei dieselbe.
Strukturelle Heterogenität ist auch im sesamDB-Projekt zu erwarten. Es kann nämlich
vorkommen, dass die Daten einer Anwendung zwar in einer relationalen Datenbank
gespeichert sind, aber nicht direkt auf das Schema von sesamDB abgebildet werden
können. In diesen Fällen müssen die Daten von der zu entwickelnden oder einer dritten
Applikation in die entsprechende Zielrelation übertragen werden. In der Regel kann aber
die strukturelle Heterogenität im Sesam-Projekt leichter überwunden werden als in anderen
Datenintegrationsprojekten. Denn einerseits sind die jeweiligen Schemata genau bekannt
und anderseits kann die Struktur der zu integrierenden Daten teilweise beeinflusst werden.
2.1.6 Schematische Heterogenität
Schematische Heterogenität ist ein Spezialfall der strukturellen Heterogenität und liegt
dann vor, wenn unterschiedliche Elemente eines Datenmodells für die Darstellung
desselben Sachverhalts verwendet werden.
So können beispielsweise in XML Informationen als Elemente, als Attribute oder als Wert
modelliert werden. Dasselbe gilt in objektorientierten Modellen, wo ein Datenobjekt als
Klasse, als Variable oder als Wert dargestellt werden kann. In relationalen Modellen
können Relationen, Attribute und Werte verwendet werden um eine Information zu
modellieren.
2.1.7 Semantische Heterogenität
Werte haben für sich genommen keine Bedeutung. So ist beispielsweise nicht klar, was die
Zahl „1998“ ausdrückt: Es kann der Preis eines Fernsehers, die Einwohnerzahl eines
Dorfes oder eine Jahreszahl sein. Erst durch ihre Interpretation erhalten Werte eine
bestimmte Semantik. Um sie jedoch interpretieren zu können, wird ein Kontext benötigt.
Diplomarbeit
10
Dieser ist primär durch das Schema und dessen Elemente, bzw. durch die Namen der
Elemente gegeben. Ist die oben genannte Zahl „1998“ der Wert des Elements „Preis“, so
wird klar, dass es sich nicht um eine Jahreszahl, sondern um eine Preisangabe handelt.
Hingegen ist noch nicht eindeutig festgelegt, um welche Währung es sich genau handelt,
ob um Schweizer Franken oder Euro.
Ein Grossteil des Kontexts ist meist nicht explizit modelliert, sondern in Form von Wissen
über die Applikation und das Anwendungsgebiet vorhanden. Weitere Quellen von
Kontextinformationen können beispielsweise eine Programmdokumentation oder eine
Menge von Beispieldaten sein, mit denen die Semantik eines Datenobjekts klar wird. Ist im
erwähnten Beispiel bekannt, dass es sich um eine Preisangabe in einem Katalog eines
Schweizer Versandhauses handelt, so kann davon ausgegangen werden, dass es sich um
Schweizer Franken handelt.
Semantische Heterogenität liegt also dann vor, wenn zwei gleichnamige Elemente mit
demselben Wertebereich unterschiedliche Bedeutung haben. Ein klassisches Beispiel dafür
ist auch das deutsche Wort „Bank“, das sowohl ein Finanzinstitut als auch eine
Sitzgelegenheit bezeichnet.
Im Sesam-Projekt sollten semantische Missinterpretationen bei der Speicherung der Daten
in sesamDB unbedingt vermieden werden, um ein Verfälschen von Messdaten zu
verhindern. Dies kann unter anderem durch eindeutige Schema-Bezeichnungen und
ausführliche Dokumentationen sichergestellt werden.
2.1.8 Zusammenfassung
Dieses Kapitel gab einen kurzen Überblick über die verschiedenen Arten von
Datenheterogenität nach [LN07]. Gleichzeitig wurde aufgezeigt, welche Auswirkungen
allenfalls für die zu entwickelnde Applikation zu erwarten sind. Insbesondere in Kapitel
2.4 wird ausführlicher auf die Datenmodellheterogenität im Zusammenhang mit Objekt-
Relationalem Mapping eingegangen.
2.2 Data Provenance
Das Forschungsprojekt Sesam stellt eine enorme Herausforderung für die Organisation der
Datenverwaltung dar. Wie bei den meisten empirischen Studien steht und fällt das Projekt
mit der Qualität der erhobenen Daten. Werden diese durch bestimmte Experimente
verändert und unter Umständen als Ausgangsprodukt für weitere Untersuchungen
2. Related Work
11
verwendet, so sollten die daran beteiligten Prozesse festgehalten und dokumentiert werden.
Damit sollen folgende drei Aspekte abgedeckt werden: Mittels einer ausführlichen
Dokumentation der Abläufe können einerseits Drittpersonen ein Experiment wiederholen
und das Resultat verifizieren. Andererseits kann so überprüft werden, ob die Ausführung
und Abfolge der Prozesse semantisch sinnvoll und korrekt ist. Drittens lassen sich
genauere Aussagen über ein Ergebnis machen, wenn dessen Ursprungsdaten bekannt sind
und deren Qualität beurteilt werden kann. Idealerweise wird auch festgehalten, welche
Personen ein Experiment durchgeführt haben und wer dafür verantwortlich ist, um
allfällige Rückfragen stellen zu können.
Diese Problematik wird in der Forschung unter dem Begriff Provenance oder Data
Provenance behandelt. Eine ausführliche Übersicht über verschiedene Provenance Systeme
kann in [SPG05] gefunden werden. An dieser Stelle sollen einige Aspekte von Data
Provenance kurz erläutert und anschliessend die für die sesamDB gewählte Umsetzung
beschrieben werden.
2.2.1 Ansätze zur Rückverfolgung von Datenänderunge n
Die bestehenden Techniken zur Rückverfolgung von Datenänderungen lassen sich nach
[Tan04] in zwei grobe Ansätze unterteilen: den „lazy approach“ und den „eager approach“.
Der „lazy approach“ (träge Ansatz) berechnet die Provenance eines Datenobjekts erst bei
Bedarf. Dabei wird davon ausgegangen, dass jeweils der aktuellste Stand der Daten sowie
alle darauf angewendeten Transformationen bekannt sind. Um die Ursprungsdaten wieder
herzustellen, muss für jede Transformation eine Umkehrfunktion berechnet werden, die
dann nacheinander auf die aktuellen Daten ausgeführt werden. Dieser Ansatz zeichnet sich
durch einen sehr geringen Speicherbedarf aus. Jedoch kann die Herleitung der Provenance
rechenaufwändig sein, wenn eine grosse Zahl von Änderungen vorliegt. Ausserdem muss
die Möglichkeit bestehen, für jede Transformation eine Umkehrfunktion berechnen zu
können.
Unter dem „eager approach“ oder fleissigen Ansatz versteht [Tan04] das Berechnen der
Provenance während der Änderung von Daten. Dabei sind die Herkunftsinformationen
eines Datenobjekts direkt mit diesem verbunden und stets bekannt, unabhängig davon, ob
diese auch wirklich benötigt werden. Der zusätzliche Overhead bei Datenänderungen, der
durch das Berechnen und Speichern der Provenance entsteht, wirkt sich natürlich
nachteilig auf die Performance einer Anwendung aus.
Diplomarbeit
12
2.2.2 Ansätze zur Speicherung der Provenance
[Tan04] unterscheidet auch hier zwischen zwei verschiedenen Ansätzen zur Speicherung
der Daten-Provenance. Den ersten nennt sie den „sequence-of-delta approach“. Ausgehend
von einer Grundversion eines Datenobjekts werden jeweils inkrementell die
Veränderungen zur Vorversion gespeichert. Idealerweise ist jedes Delta der
kleinstmögliche Unterschied zwischen zwei Versionen. Beim zweiten Ansatz, dem so
genannten „timestamping approach“ oder Zeitstempelverfahren, werden die Änderungen
zwischen zwei Versionen eines Datenobjekts markiert und gleichzeitig mit einem
Zeitstempel versehen. Bei einer naiven Implementierung dieses Vorgehens wird jeweils
eine Version vollständig gespeichert. Dies kann im Vergleich zum vorhergehenden
Verfahren zu einem enormen Speicherbedarf führen. Es gibt jedoch auch Ansätze, die das
Datenobjekt so strukturieren, dass innerhalb einer Datei mehrere Versionen gehalten
werden können (vgl. [BKTT04]). Dabei werden jeweils nur die geänderten Elemente
innerhalb der Datei dupliziert und mit einem Timestamp versehen. Das Problem bei den
erwähnten Varianten besteht grundsätzlich darin, dass die semantische Bedeutung einer
Änderung nicht erfasst werden kann.
Neben diesen beiden Verfahren gibt es noch diverse andere Möglichkeiten, Provenance
Daten zu speichern. Beispielhaft sei an dieser Stelle der Ansatz von PASOA [PASOA]
erwähnt, bei dem in einer Service orientierten Architektur sämtliche Web-Service-Aufrufe
und -Antworten aufgezeichnet werden. Ein weiteres Beispiel ist DBNotes [DBNotes], ein
relationales Datenbanksystem, in dem jedes Tupel über zusätzliche Attribute verfügt, in
denen Provenance Informationen abgelegt sind. Diese Informationen werden automatisch
bei Datenmanipulationen durch eine Anfrage weitergereicht, so dass beispielsweise bei
einem neuen Tupel vermerkt ist, aus welchen Ursprungstupeln dieses entstanden ist.
2.2.3 Daten- vs. Prozessorientierte Provenance
Provenance kann über verschiedene Ressourcen in einem Datenverarbeitungsablauf und in
unterschiedlichen Detailgraden erhoben werden. So kann beispielsweise die Provenance
explizit von Datenobjekten gesammelt werden. Oder es werden Informationen über die
beteiligten Prozesse aufgezeichnet, aus denen sich implizit Rückschlüsse auf die
beteiligten Daten ziehen lassen. Man spricht bei ersterem von datenorientierter bzw. bei
letzterem von prozessorienterter Provenance (vgl. [SPG05]). Bei der expliziten,
datenorientierten Variante sind die Provanance Informationen Metadaten eines
Datenobjekts. Dessen Vorgänger können über diese Metadaten direkt ermittelt werden.
2. Related Work
13
Anders beim impliziten, prozessorientierten Ansatz, wo primär die Prozesse im
Vordergrund der Provenance Erhebung stehen. Um die Herkunft eines Datenobjekts zu
ermitteln, müssen die aufgezeichneten Inputs und Outputs der Prozesse analysiert werden.
2.2.4 Der Provenance Ansatz von Sesam
Für das Sesam-Projekt wählte man einen rein prozessorientierten Ansatz zur Provenance
Erhebung. Im Fokus stehen die Prozesse, aus denen ein Datenobjekt entstanden ist. Zu
beiden Entitäten werden Metainformationen gespeichert, über welche die Prozesse mit den
Datenobjekten verknüpft sind. Daraus kann ermittelt werden, aus welchen Prozessen ein
Datenobjekt entstanden ist, um welchen Prozess es sich genau handelt und, falls
vorhanden, welches die Eingabe-Daten des Prozesses waren. Um verschiedenen Versionen
eines Datenobjekts Rechnung zu tragen, implementiert die sesamDB einen
Historisierungsansatz, der im Abschnitt 7.3.5 genauer erläutert wird.
2.3 XML
Wenn es um den Austausch von semi-strukturierten Daten zwischen unterschiedlichen
Applikationen geht, so hat sich XML als Austauschformat zu grossen Teilen etabliert.
XML steht für Extensible Markup Language und wurde 1996 von der XML Working
Group unter der Federführung des W3C2 entwickelt [XML].
Die Vorteile von XML sind folgende:
• XML-Dokumente sind für den Menschen wie auch für Maschinen lesbar: XML
Dokumente sind in der Regel Textdokumente, die nach einer bestimmten Struktur
und Syntax aufgebaut sind. Obwohl dies nur in Ausnahmefällen vorkommen sollte,
kann ein Dokument auch von Menschen gelesen und verstanden werden. Mittels so
genannten Tags, wie man sie aus HTML-Dokumenten kennt, werden jeweils der
Anfang und das Ende eines Elementes markiert. Diese klar definierte Syntax macht
es für Maschinen einfach, ein Dokument einzulesen und mindestens syntaktisch zu
validieren.
• XML ist unabhängig von der physischen Struktur der Speicherung: In XML-
Dokumenten wird in der Regel das verwendete Verfahren zur Zeichencodierung
2 http://www.w3c.org
Diplomarbeit
14
ausgewiesen, so dass verarbeitende Programme genau wissen, wie bestimmte
Zeichen interpretiert werden müssen. In XML wird die Struktur durch Tags
definiert; Zeilenumbrüche, Tabulatoren und Leerschläge, die zur besseren
Lesbarkeit eingefügt werden, haben keinen Einfluss auf die Struktur des
Dokumentes.
• XML ist unabhängig vom Betriebssystem und der jeweiligen Hardware: XML-
Dokumente sind meist als einfache Textdateien gehalten und verwenden keine
Features bestimmter Betriebssysteme.
• XML-Dokumente lassen sich leicht erstellen: XML-Dokumente sind einfache
Textdateien, die mit jedem beliebigen Texteditor manuell erzeugt werden können,
ähnlich wie man dies von HTML kennt.
• XML ist als Sprache relativ einfach zu erlernen: Die Sprachdefinition von XML
umfasst nur eine Teilmenge der um ein Vielfaches komplexeren Standard
Generalized Markup Language (SGML).
• XML ist erweiterbar: es lassen sich beliebige Tags definieren, im Gegensatz
beispielsweise zu HTML, wo diese fest vorgegeben sind.
• Die XML-Tags dienen nicht nur zur Strukturierung von Informationen, sie
vermitteln auch eine gewisse Semantik. Vorausgesetzt man kennt die semantische
Bedeutung eines Tags, so kann man bereits Aussagen über seinen Inhalt machen,
bevor man diesen überhaupt gesehen hat.
• Dank der starken Verbreitung von XML gibt es unzählige Dialekte und
Sprachdefinitionen, die bestimmte Themengebiete beschreiben und wieder
verwendet werden können. Beispiele dafür sind SVG (Scalable Vector Graphics)
zur Beschreibung von zweidimensionalen Vektorgrafiken oder WSDL (Web
Services Description Language) zur Beschreibung von Netzwerkdiensten zum
Austausch von Nachrichten.
Mit wenig Aufwand können XML Schema-Definitionen (siehe nachfolgenden Abschnitt
2.3.1) erstellt werden, welche die Struktur eines XML-Dokumentes beschreiben und diese
auf die eigenen Bedürfnisse zuschneiden. Ausserdem gibt es eine breite Auswahl von
Werkzeugen und Programmierschnittstellen, welche die Verarbeitung von XML-
Dokumenten unterstützen und automatisieren. Damit entfällt die aufwändige Entwicklung
entsprechender Parser. Dies geht gar soweit, dass mit bestehenden Frameworks mit
2. Related Work
15
wenigen Zeilen Code ein XML-Dokument direkt auf Java-Objekte abgebildet werden kann
(beispielsweise mit XMLBeans [XMLBeans]).
2.3.1 XML Schema
XML Schema [XMLSchema] ist ein Standard des W3C zur Definition der Struktur von
Elementen und Attributen in XML-Dokumenten. Ein XML Schema, oder auch XML
Schema Definition (XSD) genannt, ist selber wiederum ein XML-Dokument und soll die
DTDs (Document Type Definition) ablösen. Ein XSD definiert die Elemente und
Attribute, die in einem XML-Dokument auftreten können, sowie deren Wertebereiche,
Reihenfolge und Anordnung. Im Gegensatz zu den älteren DTDs sind XML Schema
erweiterbar für zukünftige Änderungen, ermöglichen das Festlegen von Datentypen und
bieten die Möglichkeit von Namensräumen. Letzteres dient vor allem dazu, die
Wiederverwendung von Definitionen in anderen Schemas zu ermöglichen.
Ein XML Schema unterscheidet grundsätzlich zwischen einfachen und komplexen
Datentypen. Unter einem einfachen Datentyp wird ein atomares Element verstanden, das
keine weiteren Kindelemente noch Attribute enthält. In XML Schema sind bereits eine
Vielzahl von einfachen Datentypen definiert, die aus den gängigsten Programmiersprachen
bekannt sind. Dazu gehören beispielsweise string, decimal, integer, float, boolean und date.
Eigene Datentypen können relativ einfach definiert werden, indem diese aus den
vordefinierten einfachen Datentypen abgeleitet und beispielsweise deren Wertbereiche
eingeschränkt werden.
Ein komplexer Datentyp definiert im Gegensatz zum einfachen Datentyp eine Menge von
Kindelementen, Elementreferenzen und Attributen. Dabei kann beispielsweise festgelegt
werden, ob ein Element angegeben werden muss und wie häufig es sich wiederholen darf.
Neben der Definition einer XML Struktur, kann ein XML Schema verwendet werden, um
ein XML Dokument vor dem Einlesen maschinell auf seine Gültigkeit hin zu überprüfen.
Damit kann unter anderem kontrolliert werden, ob alle benötigten Elemente vorhanden
sind und ob die gesetzten Werte den Wertebereichen entsprechen.
2.4 Objekt-Relationales-Mapping
Dieses Kapitel beschäftigt sich mit einigen ausgewählten Schwierigkeiten von Objekt-
Relationalen Mappings. Darunter versteht man das Abbilden von Objekten auf Relationen
in einer relationalen Datenbank. Obwohl es inzwischen auch rein objektorientierte
Diplomarbeit
16
Datenbanken (beispielsweise [db4o]) gibt, wird aufgrund der grossen Verbreitung von
Relationalen Datenbank diese Problematik noch längere Zeit aktuell bleiben.
Mit einem Objekt-Relationalen Mapping sollen zwei konzeptuell verschiedene Welten
verbunden werden: die objektorientierte Sichtweise, bei der die zu beschreibende Welt in
Objekte mit Eigenschaften und Operationen aufgeteilt wird, und das relationale Modell,
dem die mengentheoretische und mathematisch wohldefinierte Relation zugrunde liegt.
Die Verknüpfung dieser beiden Konzepte ist zwar nicht trivial, aber durchaus machbar.
Nachfolgend werden zuerst einige grundsätzliche Abbildungseigenschaften erläutert, um
anschliessend die möglichen Strategien zum Mapping von Vererbungen und Beziehungen
zu erläutern.
2.4.1 Mapping Grundkonzepte
Der einfachste Fall ist das Abbilden eines Objekt-Attributs auf eine einzelne Spalte in der
Datenbank mit zueinander kompatiblen Datentypen, wie beispielsweise String und
VARCHAR oder Integer und INT4. Ein Objekt als „Behälter“ von Attributen entspricht
dabei der Relation. Häufig haben wir jedoch Objekt-Eigenschaften, die nicht gespeichert
werden sollen, beispielsweise Werte, die aus zwei anderen Attributen berechnet werden.
Auf Seite der Datenbank benötigen wir zudem meist zusätzliche Felder, zum Beispiel
einen Primärschlüssel zur eindeutigen Identifizierung und Unterscheidung zweier Tupel.
Diese zusätzlichen Angaben auf Seite der Datenbank werden als Schatteninformation
(engl. shadow information) bezeichnet. Häufig werden ausser der ID noch weitere
Informationen benötigt, wie beispielsweise Timestamps, um Konkurrenzsteuerungen zu
realisieren, oder Indexe, um geordnete Objekt- oder Werte-Listen wiederzugeben.
Insbesondere im Zusammenhang mit der Abbildung von Vererbungshierarchien wird eine
Reihe von solchen Schatteninformationen benötigt.
Die Zuordnung von Objekt-Eigenschaften zu Attributen in Relationen muss in irgendeiner
Form festgehalten werden. Diese Angaben werden als Meta-Daten bezeichnet. Dabei
können auf Seite der Objekte sowohl Attribute wie auch Operationen auf entsprechende
Felder in einer Relation abgebildet werden.
2.4.2 Mapping von Vererbungen
Ambler [Ambler06] beschreibt vier Möglichkeiten zum Abbilden von
Vererbungshierarchien auf Relationen:
2. Related Work
17
• Abbilden der gesamten Klassenhierarchie auf eine einzelne Tabelle
• Abbilden jeder konkreten Klasse auf eine eigene Tabelle
• Abbilden jeder Klasse auf eine eigene Tabelle
• Abbilden der Klassen in eine generische Tabellen-Struktur
Nachfolgend werden diese vier Ansätze kurz erläutert. Als Beispiel wird die in Abbildung
1 dargestellte einfache Klassenhierarchie benutzt. Zur Administration der Personen an
einer Universität werden von der abstrakten Klasse Person einerseits die Klasse Student
und anderseits die Klasse Angestellter abgeleitet. Beide abgeleiteten Klassen erben das
Attribut Name von Person. Während Student zusätzlich Matrikel-Nr. erhält, besitzt
Angestellter ein Attribut Lohn.
Abbildung 1: Einfache Klassenhierarchie
2.4.2.1 Abbilden der gesamten Klassenhierarchie auf eine einzelne Tabelle
Bei dieser Strategie werden sämtliche Instanzen einer Klassenhierarchie in ein und
derselben Relation gehalten. Dazu werden sämtliche Attribute aller beteiligten Klasse in
einer Tabelle zusammengefasst. Abbildung 2 zeigt das Resultat dieser Umsetzung auf
unser Beispiel angewandt. Hinzu kommen noch zwei Felder mit Schatteninformationen:
den Primärschlüssel PersonOID und PersonType. Das OID in PersonOID steht für Objekt
Identifikator und ist eine künstliche ID zur eindeutigen Kennzeichnung von Personen-
Objekten. Mit PersonType wird angegeben, welche konkrete Klasse ein Tupel beschreibt.
Diese Angabe wird benötigt, um daraus wieder die richtige Objekt-Instanz zu erzeugen.
Wird beispielsweise ein Angestellter erfasst, so wird MatrikelNr auf NULL gesetzt und in
PersonType wird eine entsprechende Typ-Kennzeichnung gespeichert.
Bei einer umfangreichen Klassenhierarchie kann diese einzelne Tabelle schnell sehr viele
Attribute umfassen, was unübersichtlich werden kann.
Diplomarbeit
18
Abbildung 2: Mapping auf eine einzelne Tabelle
2.4.2.2 Abbilden jeder konkreten Klasse auf eine eigene Tabelle
Der zweite Ansatz bildet jede konkrete Klasse auf eine eigene Tabelle ab. Jede dieser
Tabellen enthält dabei die Attribute von abstrakten Superklassen. Abstrakte Klassen
werden nicht abgebildet. In unserem Beispiel entstehen also zwei Relationen, die jeweils
neben ihrem eigenen Attribut noch das Feld Name von Person besitzen (vgl. Abbildung 3).
Hier ist anhand der Relation, in der ein Tupel abgelegt ist, die Klasse eindeutig gegeben,
womit PersonType überflüssig ist. Wiederum wurde aber jeweils eine künstliche ID
hinzugefügt.
Falls die Möglichkeit besteht, dass eine Person gleichzeitig Student und Angestellter sein
kann (beispielsweise ein Tutor), dann muss diese eine Person in beiden Relationen
gespeichert werden, wodurch unnötige Redundanzen entstehen.
Abbildung 3: Mapping konkreter Klassen auf eigene Tabellen
2.4.2.3 Abbilden jeder Klasse auf eine eigene Tabelle
Die dritte Strategie ordnet jeder Klasse (konkreten wie auch abstrakten) eine eigene
Tabelle zu. Eine Instanz einer Klasse muss dabei jeweils auch in die Relationen sämtlicher
Superklassen eingefügt und mit einem eindeutigen Primärschlüssel verknüpft werden.
Abbildung 4 zeigt die Auswirkungen auf unser Beispiel. Im Gegensatz zum
vorhergehenden Ansatz verwenden die Relation Student und Angestellter ebenfalls die
PersonOID als Primärschlüssel. Gleichzeitig ist dies auch der Fremdschlüssel auf ein
Tupel in der Relation Person. Um einen Studenten abzuspeichern, wird erst in der Relation
Person ein Tupel angelegt und die PersonOID generiert. Danach wird ein Tupel in der
Tabelle Student erzeugt und die eben generierte PersonOID als Primärschlüssel verwendet.
2. Related Work
19
Über diese PersonOID können beim Auslesen mit einem Join über die Relationen Student
und Person wieder alle Attribute zusammengefügt werden.
Mit dieser Variante entstehen bei Instanz-Objekten, die sowohl Student wie auch
Angestellter sind, keine Redundanzen. Dies wird aber mit zusätzlichem Aufwand beim
Datenzugriff erkauft, da mehrere Anfragen benötigt werden.
Abbildung 4: Mapping jeder Klasse auf eigene Tabelle
2.4.2.4 Abbilden der Klassen in eine generische Tabellen-Struktur
Bei den vorangegangenen Mapping-Strategien müssen bei jeder Erweiterung der
Klassenhierarchie Relationen angepasst oder hinzugefügt werden. Die vierte Strategie
verwendet einen generischen Ansatz zum Abbilden von Klassen, Attributen und
Vererbungshierarchien. Abbildung 5 zeigt ein mögliches Datenschema, das jedoch nicht
vollständig ist, da damit beispielsweise keine Assoziationen abgebildet werden können.
Soll eine Klasse mit 10 Attributen abgebildet werden, so wird in der Relation Klasse ein
Tupel angelegt, das von 10 Tupeln aus der Relation Attribut referenziert wird. Für unsere
Beispiel-Hierarchie wird in der Relation Klasse für jede Klasse ein Eintrag angelegt. Über
die Tabelle Vererbung wird die Vererbungshierarchie modelliert. Um eine Instanz von
Student zu persistieren, werden in der Relation Wert zwei Tupel gespeichert: eines mit dem
Namen und eines mit der Matrikel-Nummer.
Dieser generische Ansatz erlaubt das Abbilden beliebiger Klassen und
Vererbungshierarchien, ohne dass dazu zusätzliche Relationen angelegt werden müssen.
Der Nachteil liegt in der erhöhten Komplexität und der Reduktion der Performance, da zur
Wiederherstellung eines Objekts eine Vielzahl von Anfragen notwendig ist. Ferner kann
Diplomarbeit
20
auf diese Weise die referentielle Integrität3 zwischen den Objekten nicht mehr von der
Datenbank überprüft werden. Dies muss die Applikation selber sicherstellen, was
zusätzlichen Aufwand für die Programmierung bedeutet.
Abbildung 5: Generisches Datenschema zur Objekt-Speicherung (Quelle: [Ambler06])
2.4.3 Mapping von Beziehungen
Abhängig von der Kardinalität einer Beziehung, bieten sich unterschiedliche Mapping-
Strategien an. Grundsätzlich wird unterschieden zwischen one-to-one, one-to-many und
many-to-many Beziehungen. Nachfolgend wird für jeden Beziehungstyp der geeignete
Ansatz erläutert. Dabei kann eine one-to-one Beziehung auch mit der Strategie der one-to-
many oder many-to-many Beziehung umgesetzt werden, jedoch nicht umgekehrt.
2.4.3.1 One-to-one
Dies ist der einfachste Beziehungstyp. Abbildung 6 zeigt die UML-Notation dieser
Beziehung an einem Beispiel. Ein Angestellter belegt genau eine Position, und eine
Position wird von genau einem Angestellten besetzt (oder ist in Ausnahmefällen vakant).
In diesen Fällen wird bei einer der beiden Relationen ein Fremdschlüssel eingefügt, der
sich auf den Primärschlüssel der anderen Relation bezieht. Im Beispiel bietet sich an, dass
die Tabelle Angestellter den Primärschlüssel von Position als Fremdschlüssel erhält.
Gerade so gut könnte aber Position den Primärschlüssel von Angestellter als
Fremdschlüssel enthalten. Beide Varianten sind grundsätzlich gleich effizient.
3 Referentielle Integrität befasst sich mit der Korrektheit von Attributen zwischen Relationen. Eine Regel zur
Sicherstellung der referentiellen Integrität könnte beispielsweise lauten, dass ein Tupel nicht gelöscht werden
darf, solange ein zweites Tupel über seinen Fremdschlüssel auf den Primärschlüssel des ersten Tupels
verweist.
2. Related Work
21
Abbildung 6: One-to-one Beziehung
2.4.3.2 One-to-many
Dieser Beziehungstyp drückt aus, dass ein Objekt vom Typ A mehrere Objekte vom Typ B
referenziert. Ein Objekt vom Typ B wird aber nur von genau einem Objekt von Typ A
referenziert. Auf unser Beispiel angewandt bedeutet dies, dass ein Angestellter genau einer
Abteilung angehört, eine Abteilung aber null oder mehrere Angestellte haben kann. Diese
Beziehung wird im relationalen Modell so umgesetzt, dass Angestellter den
Primärschlüssel von Abteilung als Fremdschlüssel erhält. Im Vergleich zur one-to-one
Beziehung macht der umgekehrte Fall wenig Sinn.
Abbildung 7: One-to-many Beziehung
2.4.3.3 Many-to-many
Beim dritten Beziehungstyp hält ein Objekt vom Typ A mehrere Referenzen auf Objekte
von Typ B. Objekte von Typ B können zudem gleichzeitig von mehreren Objekten von
Typ A referenziert werden. Abbildung 8 veranschaulicht dies an einem Beispiel. Einem
Angestellten können mehrere Aufgaben zugewiesen sein und eine Aufgabe kann von
mehreren Angestellten gleichzeitig wahrgenommen werden. Dieser Beziehungs-Typ wird
in der Datenbank mittels einer Verbindungsrelation abgebildet, die nur aus den
Primärschlüsseln der beteiligten Relationen besteht.
Abbildung 8: Many-to-many Beziehung
In Abbildung 9 ist Umsetzung des Beispiels in der Datenbank dargestellt. So wurden dem
Angestellten Cäsar drei Aufgaben zugewiesen. Die Aufgabe Spülen wiederum wird von
drei Angestellten erledigt. Wie bereits erwähnt, lassen sich mit dieser Verbindungsrelation
auch one-to-one und one-to-many Beziehungen realisieren. Dazu kann in der
Verbindungsrelation das entsprechende Fremdschlüsselfeld mit einer UNIQUE-
Beschränkungen versehen werden, um doppelte Werte zu verhindern. Soll in unserem
Beispiel einem Angestellten jeweils nur eine Aufgabe zugewiesen werden, so könnte man
Diplomarbeit
22
in der Verbindungsrelation doppelte Werte in der Spalte AngestellterOID verbieten.
Dadurch kann eine Aufgabe noch von mehreren Personen wahrgenommen werden, die
OID eines Angestellten darf jedoch nur einmal darin vorkommen.
Abbildung 9: Beispiel einer many-to-many Verbindungsrelation
2.4.4 Zusammenfassung
Dieses Kapitel gab eine kurze Einführung in die Thematik von Objekt-Relationalen
Mappings. Anhand von Vererbung und Beziehungen wurden zwei ausgewählte Probleme
dargestellt und deren Lösungsansätze anhand von Beispielen erläutert.
3. Vorgehen
23
3 Vorgehen
Dieses Kapitel gibt eine kurze Übersicht über die angewandte Vorgehensweise zur
Entwicklung der Applikation.
Im Vorfeld wurden die genauen Anforderungen an die Anwendung erfasst. Dazu musste
ein umfassendes Verständnis über den Erhebungs- und Importierungsablauf sowie über
den Aufbau der sesamDB erarbeitet werden. Der Entwicklungsprozess selber wurde an das
Wachstumsmodell (siehe [Glinz01], Abschnitt 3.2.3) angelehnt. Nach einer kurzen
Analyse- und Spezifikationsphase wurde schnell eine erste Teillieferung angestrebt,
welche die Basisfunktionalität enthielt. Damit sollte einerseits die Machbarkeit des
gewählten Ansatzes aufgezeigt und andererseits die Grundlage geschaffen werden, um
darauf aufbauend die Funktionalität iterativ auszuweiten. In regelmässigen Gesprächen mit
dem Betreuer wurden jeweils Verbesserungen diskutiert und die nächsten
Implementierungsschritte geplant. Mit dieser evolutionären Vorgehensweise konnte
verhindert werden, dass am Abgabetermin ein nicht funktionsfähiges System vorhanden
ist, weil beispielsweise gewisse (möglicherweise weniger wichtige) Funktionen zu viel
Zeit in Anspruch nahmen oder weil sich erst gegen Ende gewisse Features als nicht
machbar herausstellten.
Mit dem gewählten Entwicklungsmodell war die Grundfunktionalität bereits zu einem
frühen Zeitpunkt vorhanden, die danach schrittweise erweitert werden konnte. Dieses
Vorgehen unterstützte die Entwicklung einer modularen Architektur. Aufbauend auf dem
Kern der Anwendung wurden nach und nach modulartig die Detail-Implementierungen
hinzugefügt. Gleichzeitig entstand auch die Testumgebung. Anstatt am Ende der
Entwicklung eine grosse Zahl von Testklassen zu schreiben, wurde jeweils mit der
Fertigstellung eines Applikations-Teils die entsprechenden Tests entwickelt und
durchgeführt. Damit konnte auch die Qualität der Anwendung stetig sichergestellt werden
und das Programm musste nicht bei Projektende mit viel Aufwand von Fehlern befreit
werden. Ausserdem konnte so das Risiko minimiert werden, dass ein erst am Schluss
entdeckter Fehler eine zeitintensive Anpassung der Architektur bewirkt.
Diplomarbeit
24
4 Spezifikation
In diesem Abschnitt sollen die genauen Anforderungen an die zu entwickelnde Applikation
dokumentiert werden. Aus der Aufgabenstellung alleine lässt sich nur ein erstes grobes
Bild ableiten. Die detaillierten Spezifikationen entstanden in mehreren ausführlichen
Gesprächen mit dem Betreuer und teilweise durch Rückfragen an die potentiellen
Anwender an der Universität Basel. Im Folgenden werden zuerst der Prozess der
Datenerhebung und das Datenmodell erläutert, wie sie bereits festgelegt wurden.
Anschliessend werden die daraus abgeleiteten Anwendungsfälle der Applikation
beschrieben und die zwei wichtigsten Anforderungen genauer ausgeführt. Abschliessend
werden sämtliche Anforderungen aufgelistet und zusammengefasst.
4.1 Prozess der Datenerhebung
Der Prozess von der Erhebung bis zur Speicherung der Daten ist in Abbildung 10
dargestellt. An den jeweiligen Erhebungsorten werden die Daten erhoben und
pseudonymisiert. Anschliessend werden diese mit einem asymmetrischen
Verschlüsselungsverfahren4 vor unberechtigtem Zugriff geschützt. Via
Datenträgeraustausch gelangen die Daten zur Zentralstelle von Sesam. Eine elektronische
Übermittlung der Daten anstelle des Datenträgeraustauschs ist nicht möglich, da die
Zentralstelle aus sicherheitstechnischen Überlegungen an kein externes Netzwerk, wie zum
Beispiel das Internet, angeschlossen ist, noch über sonst irgendeine externe Verbindung
verfügt. Die Arbeitsstationen der Zentralstelle sind somit über ein vollständig isoliertes
Intranet mit der sesamDB verbunden. Diese zusätzliche Sicherheit erkauft man sich mit
längeren Transportzeiten der Daten von den Erhebungsorten, die in der ganzen Schweiz
verteilt sind, zur Zentralstelle. Im Falle von Sesam ist es aber irrelevant, wenn die Daten
4 Beim asymmetrischen Verschlüsselungsverfahren wird vorgängig ein Schlüsselpaar bestehend aus einem
öffentlichen und einem privaten Schlüssel generiert. Während der öffentliche Schlüssel (public key) frei
verfügbar und allen Beteiligten bekannt ist, wird der private Schlüssel (private key) geheim gehalten und ist
nur dem Schlüsselinhaber bekannt. Der öffentliche Schlüssel kann nur zur Verschlüsselung der Daten
verwendet werden. Diese können wiederum nur mit dem privaten Schlüssel entschlüsselt werden. Damit
kann sichergestellt werden, dass nur der Inhaber des privaten Schlüssels diese lesen kann (vgl. [FRR00]).
4. Spezifikation
25
für den Transport ein paar Tage benötigen. Im Gegensatz dazu hat die Datensicherheit
höchste Priorität. Alternativ wäre es denkbar, in der Zentralstelle einen separierten Server
aufzustellen, der zwar ans Internet angebunden ist, jedoch nicht an das Intranet der
Zentralstelle und somit auch nicht an die sesamDB. Man müsste dann zwar immer noch
die Daten manuell von diesem separierten Server zu einer ans Intranet angebundenen
Arbeitsstation bringen, beispielsweise mittels eines austauschbaren Speichermediums. So
könnte aber einiges an Transportkosten und –zeit eingespart und erst noch das Risiko
minimiert werden, dass ein Speichermedium auf dem Transport verloren geht oder
beschädigt wird.
Sind die eingelieferten Daten auf einer an die sesamDB angeschlossenen Arbeitsstation,
werden diese mithilfe der zu entwickelnden Anwendung mit dem in sesamDB
gespeicherten, privaten Schlüssel entschlüsselt und einem Validierungsprozess unterzogen.
Damit soll sichergestellt werden, dass die Daten in struktureller und syntaktischer Hinsicht
korrekt sind. Abschliessend werden diese in der sesamDB abgespeichert.
Abbildung 10: Der Speicherungsprozess der Erhebungsdaten
4.2 Datenmodell
Ausgangspunkt für sämtliche Überlegungen bezüglich der Daten und deren Struktur ist das
von der Datenbankgruppe der Universität Zürich ausgearbeitete Datenmodell. Dabei sind
für die zu entwickelnde Anwendung nur bestimmte Ausschnitte relevant, die nachfolgend
erläutert werden.
Bei den zu importierenden Daten handelt es sich im Wesentlichen um Experimente,
Prozesse und Datenobjekte:
Diplomarbeit
26
• Experiment: Ein Experiment beschreibt die Ausführung einer Untersuchung
bestehend aus einem oder mehreren Prozessen, zu einem bestimmten Zeitpunkt und
an einem bestimmten Ort.
• Prozess: Ein Prozess stellt einen Vorgang zur Erzeugung oder Veränderung
bestimmter Datenobjekte dar. Dieser Vorgang kann von Sesam-Mitarbeitern unter
Einbezug bestimmter Hilfsmittel oder Testpersonen ausgeführt werden.
• Datenobjekt (DataItem): Bei den Datenobjekten handelt es sich um heterogene
Daten, die konkrete Resultate oder Werte repräsentieren, die aus bestimmten
Prozessen entstanden sind. DataItems können beispielsweise Antworten aus
Interviews, Auswertungen von Fragebögen, Blut- oder DNS-Proben oder gar
Videoaufzeichnungen von Gesprächen mit Probanden sein.
Ein Experiment besteht aus einem oder mehreren Prozessen, die wiederum ein oder
mehrere DataItems als Ein- und/oder als Ausgabeobjekt haben. Die Prozesse innerhalb
eines Experiments können unabhängig voneinander oder aber so aneinander gekoppelt
sein, dass beispielsweise das Ausgabeobjekt eines ersten Prozesses als Eingabeobjekt eines
zweiten Prozesses agiert. Diese Informationen werden als Provenance Daten bezeichnet
(siehe Kapitel 2.2).
Das Datenmodell ist so aufgebaut, dass für jedes konkrete Objekt, wie eben beispielsweise
ein Experiment oder Prozess, jeweils ein Metaobjekt besteht, welches das konkrete Objekt
genauer beschreibt und die Beziehungen zu anderen Objekten festhält. Diese Metaobjekten
werden als „Klassen“ bezeichnet. So wird beispielsweise der Umstand, dass ein
Experiment ein oder mehrere Prozesse enthalten kann, in den Metaobjekten oder eben den
Klassen der beiden genannten Objekte beschrieben.
4. Spezifikation
27
Abbildung 11: Darstellung der Objekt-Beziehungen im Datenmodell
In Abbildung 11 sind die Zusammenhänge und Beziehungen zwischen den einzelnen
Begriffen und Objekten grafisch dargestellt. Die Metadaten im InputFile beschreiben die
Art und Herkunft der DataItems. In den Metadaten wird beispielsweise dokumentiert, aus
welchem Experiment und aus welchen Prozessen ein Datenobjekt stammt. Zudem wird
jedes Element (Experiment, Prozess, DataItem) einer bestimmten Klasse zugeordnet.
Damit kann beispielsweise mithilfe des Metamodells aus der sesamDB überprüft werden,
ob alle benötigten Angaben zu einem Experiment erfasst wurden oder ob alle
dazugehörigen Prozesse enthalten sind.
Das folgende Beispiel soll die Zusammenhänge und Begriffe veranschaulichen (vgl.
Abbildung 12):
Ein Experiment heisst „Bestimmung der Blutgruppe“ und besteht aus zwei Prozessen: (1)
Blutentnahme und (2) Blutgruppenbestimmung. In Prozess 1 entnimmt ein Sesam-
Mitarbeiter einem Probanden Blut, gibt dieses in ein Reagenzglas und versieht dieses mit
einem Barcode. Diese Blutprobe als Output von Prozess 1 stellt DataItem 1 dar.
Anschliessend bestimmt in Prozess 2 ein Sesam-Mitarbeiter mithilfe eines Analysegerätes
die Blutgruppe der Probe aus Prozess 1. Das Resultat bzw. der Output ist die Bezeichnung
der Blutgruppe und wird als DataItem 2 erfasst. Wir haben also ein Experiment bestehend
aus zwei Prozessen. Der erste Prozess benötigt einen Mitarbeiter und einen Probanden und
Diplomarbeit
28
hat die Blutprobe bzw. DataItem 1 als Output. Der zweite Prozess benötigt einen
Mitarbeiter, ein Analysegerät und als Input eine Blutprobe, was in diesem Fall wiederum
DataItem 1 ist. Als Output hat Prozess 2 die Bezeichnung der Blutgruppe bzw. DataItem 2.
Abbildung 12: Beispiel-Experiment "Bestimmung der Blutgruppe"
4.3 Use Cases
In Abbildung 13 ist das UML Use Case Diagramm der zu erstellenden Anwendung
dargestellt. Die Applikation deckt im Wesentlichen einen Anwendungsfall ab: den Import
von Datenobjekten (DataItems) mit den zugehörigen Metadaten, die in einer Eingabedatei
(InputFile) zusammengefasst sind, in die sesamDB. Dabei sollen die Metadaten vorgängig
gegen das Metamodell aus der sesamDB validiert werden.
Abbildung 13: UML Use Case Diagramm
Dieser Hauptanwendungsfall kann in die folgenden fünf Einzelschritte aufgeteilt werden
(vgl. Abbildung 13):
4. Spezifikation
29
1. Struktur von InputFile überprüfen: In einem ersten Schritt soll die Eingabe-Datei
mit den Metadaten daraufhin überprüft werden, ob ihre Struktur syntaktisch
korrekt ist. Im Falle einer XML-Datei kann die Überprüfung gegen eine XML
Schema Definition (XSD) geschehen.
2. Metadaten aus InputFile validieren: Anschliessend sollen die darin enthaltenen
Metadaten gegen die Vorgaben (sprich gegen das Metamodell der Metadaten) aus
der sesamDB validiert werden. In der sesamDB sind sämtliche Arten von
Experimenten, Prozesse, Datenobjekten usw. gespeichert. Es gilt also zu
überprüfen, ob die in der Eingabedatei erfassten Metaangaben richtig und
vollständig sind, beispielsweise ob ein bestimmtes Experiment tatsächlich auch in
der sesamDB existiert und ob alle dazugehörigen Prozesse vorhanden sind etc.
3. Metadaten aus InputFile in sesamDB übertragen: In einem nächsten Schritt sollen
die validierten Metadaten in der sesamDB gespeichert werden. Dies soll über eine
mittels Verschlüsselung gesicherte Verbindung zur sesamDB geschehen.
Allenfalls soll auch die Eingabedatei mit den Metadaten archiviert werden.
4. DataItems in sesamDB speichern: Neben den Metadaten sollen auch die jeweiligen
Datenobjekte in der sesamDB gespeichert werden. Unter Umständen kann dies
auch ein alternativer Ablagespeicher sein. So kann es beispielsweise bei grossen
Videodateien Sinn machen, diese nicht als Binärdaten in die Datenbank direkt
einzuspeisen, sondern separat auf einen FTP-Server abzulegen.
5. Validierungsfehler speichern: Metadaten von Experimenten, die unvollständig
oder fehlerhaft sind, dürfen nicht in die sesamDB gelangen. Ebenso werden die
dazugehörigen Datenobjekte nicht übertragen. Stattdessen sollen dem Benutzer die
aufgetretenen Fehler dargestellt werden, so dass er die Möglichkeit hat, den
Ursprung manuell zu lokalisieren. Die Fehlerliste soll vom Benutzer für spätere
Zugriffe gespeichert werden können.
4.4 Heterogene Daten
Eine Anforderungen an die Applikation leitet sich aus dem Anwendungsfall „DataItems in
sesamDB übertragen“ ab: Das Programm soll in der Lage sein, jegliche Datenobjekte
mindestens auf ihr Vorhandensein zu überprüfen und in die sesamDB zu übertragen bzw.
am entsprechenden Speicherort abzulegen. Das jeweilige Vorgehen soll dabei auf den
Diplomarbeit
30
jeweiligen Datentyp abgestimmt sein. Während strukturierte Datenobjekte eingelesen und
möglicherweise syntaktisch validiert werden könnten, ist bei binären Dateien wie
Videoaufzeichnungen beispielsweise ein Prüfsummenvergleich oder eine Überprüfung des
Videoformats anhand des Dateiheaders denkbar. Unterschiedlich können auch die
Vorgehensweisen zur Archivierung ausfallen. Strukturierte XML-Daten können auf
Relationen in der sesamDB oder einer Zweitdatenbank abgebildet werden. Binärdaten
werden möglicherweise auf einen separaten FTP-Server ausgelagert oder als BLOBs5 in
eine Datenbank eingefügt.
Bei der Implementierung muss unbedingt darauf geachtet werden, dass die Applikation mit
relativ wenig Aufwand so erweitert werden kann, dass sie in der Lage ist, neue Datentypen
zu verarbeiten. Dies führt zu der unter Punkt 4.5 aufgeführten Anforderung.
Im Rahmen dieser Arbeit soll die zu entwickelnde Applikation mindestens zwei
unterschiedliche Datenformate verarbeiten können, vorzugsweise Textdateien (bspw.
Interviews) und strukturierte Daten im XML-Format (bspw. Fragebogenauswertungen).
4.5 Modulare Erweiterbarkeit
Neben den erwähnten Anwendungsfällen und dem Umgang mit heterogenen Daten besteht
für die Applikation eine weitere Anforderung, die sich im Wesentlichen in der Architektur
und der Art der Programmierung niederschlägt und keinerlei direkte funktionale
Auswirkungen hat. Dabei handelt es sich um die modulare Erweiterbarkeit der
Anwendung. Die Applikation wird über eine längere Zeitspanne im Einsatz sein und es ist
damit zu rechnen, dass Anforderungen im Laufe der Zeit ändern oder neu hinzukommen.
Änderungen sind vor allem bezüglich des Metamodells in der sesamDB zu erwarten. Dabei
können zwei Arten von Modifikationen am Metamodell unterschieden werden:
• Änderungen am logischen Metamodell ohne physische Auswirkungen auf das
Datenbankschema. Beispielsweise können neue Experiment- und Prozessklassen
definiert werden, indem ein neues Tupel in der entsprechenden Relation eingefügt
wird. Das Datenbankschema ändert sich dabei nicht.
5 Binary Large Objects sind grosse binäre und für die Datenbank nicht weiter strukturierte Objekte
beziehungsweise Felddaten.
4. Spezifikation
31
• Änderungen am Metamodell mit physischen Auswirkungen auf das
Datenbankschema. Soll beispielsweise eine neue Art von Datenobjekten unterstütz
werden, so muss in der Datenbank eine entsprechende Relation erstellt werden,
welche das neue DataItem repräsentiert. Dadurch ändert sich das
Datenbankschema.
Solche und andere Anpassungen sollten mit möglichst geringem Aufwand möglich sein.
Programmteile, die aller Voraussicht nach einmal ausgetauscht oder verändert werden,
sollten möglichst lose mit den restlichen Komponenten der Applikation gekoppelt sein.
Allgemein sollten voraussehbare Änderungen der Anforderungen nur lokal und punktuell
nötig sein und keine kettenartigen Auswirkungen nach sich ziehen. Dies kann durch eine
konsequente objektorientierte Programmierung und den Einsatz von Design-Patterns (siehe
[Gamma04]) erreicht werden. Von grossem Vorteil kann in diesem Zusammenhang die
Implementierung einer Plugin-Struktur sein. Hierbei kann zusätzliche Funktionalität
einfach angehängt werden, indem eine neue Klasse oder ein neues Paket implementiert und
nur durch eine simple Änderung in einer Konfigurationsdatei in die bestehende
Applikation eingebunden wird, ohne dass bestehender Programmcode geändert werden
muss. Dies kann unter anderem durch den Einsatz von Reflexion6-Techniken realisiert
werden.
4.6 Weitere Anforderungen
Weitere informale Anforderungen an die Applikation sind nachfolgend aufgeführt:
1. Bei den zu bearbeitenden Daten handelt es sich meist um sensible, persönliche
Informationen, die es so gut wie möglich vor fremden Zugriffen zu schützen gilt.
Um die Vertraulichkeit bei der Übertragung vom Erhebungsort in die sesamDB zu
gewährleisten, werden sämtliche Daten verschlüsselt und erst in der sesamDB-
Zentrale für die Validierung und Übertragung in die Datenbank entschlüsselt. Dazu
soll ein asymmetrisches Verschlüsselungsverfahren eingesetzt werden. Am
Erhebungsort werden die Daten mit dem öffentlichen Schlüssel verschlüsselt, der
zum privaten, in der sesamDB gespeicherten Schlüssel passt. Vor dem Beginn der
6 In der Programmierung bedeutet Reflexion (engl. reflection) bzw. Introspektion, dass ein Programm
Erkenntnisse über seine eigene Struktur gewinnen kann. (Quelle:
http://de.wikipedia.org/wiki/Reflexion_(Programmierung) [Stand: 21.02.2007])
Diplomarbeit
32
eigentlichen Datenübertragung in der Zentrale wird aus der sesamDB der private
Schlüssel des Datenbankservers ausgelesen, um die Daten zu entschlüsseln und die
Validierung vorzunehmen.
2. Es kann durchaus vorkommen, dass die Metadaten eines Experiments in der
Sesam-Zentrale eintreffen, die dazugehörigen, externen DataItems aber noch
aufbereitet oder ausgewertet werden müssen, bevor sie zur Zentrale übermittelt
werden. Die Applikation soll entsprechende Möglichkeiten anbieten, um die
Metadaten zu einem Experiment zu speichern und zu einem späteren Zeitpunkt,
wenn die DataItems verfügbar sind, zu wiederholen.
3. Die Bedienung des Programms soll einfach und leicht erlernbar über eine grafische
Benutzeroberfläche (GUI) geschehen. Wo immer möglich sollten dem Benutzer
Programmhilfen zur Verfügung stehen. Zudem ist eine Programm-Dokumentation
zu erstellen, die dem Benutzer die Bedienung und Funktionsweise der Applikation
nahe bringt.
4. Aus der Aufgabenstellung geht hervor, dass die Installation und Inbetriebnahme der
Anwendung möglichst einfach zu gestalten ist. Nachträgliche
Konfigurationsanpassungen sollten möglichst einfach über ein entsprechendes GUI
getätigt werden können.
4.7 Zusammenfassung
Nachfolgend werden sämtliche Anforderungen an die im Rahmen dieser Arbeit zu
entwickelnde Anwendung aufgelistet und nochmals kurz zusammengefasst:
[1] Datenentschlüsselung Entschlüsselung der Daten mit dem privaten in der sesamDB
gespeicherten Schlüssel.
[2] Validierung Syntaktische und strukturelle Validierung der Metadaten
gegen das Metamodell in der sesamDB.
[3] Datenspeicherung Speicherung von Datenobjekten mit heterogenen
Datenformaten.
[4] Neue Eingabeformate Leicht erweiterbar um zusätzliche Eingabeformate von
Metadaten zu unterstützen.
4. Spezifikation
33
[5] Neue Datenobjekte Leicht erweiterbar um zusätzliche Datenobjektformate zu
unterstützen.
[6a] Änderungsresistent Änderungen am Datenbankmodell der sesamDB
(Hinzufügen/Ändern/Löschen von Relationen) sollen
möglichst wenige Änderungen an der Applikation nach sich
ziehen.
[6b] Änderungsresistent Änderungen an den Metadaten in der sesamDB
(Hinzufügen/Ändern/Löschen von Tupeln) sollen ohne
Änderungen an der Applikation möglich sein.
[7] Zwischenspeicher Zwischenspeichern von Metadaten bei fehlenden DataItems
und Möglichkeit zur Validierung und Speicherung zu einem
späteren Zeitpunkt.
[8] GUI Benutzerinterface zur einfachen Bedienung.
[9] Testen Ausführliches Testen der Applikation.
[10] Installation Einfache Installation der Anwendung.
[11] Dokumentation Ausführliche Dokumentation im Code.
Diplomarbeit
34
5 Architektur
In diesem Kapitel wird die Architektur der Applikation dokumentiert. Ausgangspunkt ist
das ERM-Schema der sesamDB, das im ersten Unterkapitel betrachtet wird. Danach wird
in einer ersten Übersicht der grundlegende Aufbau dargestellt und erläutert. Anschliessend
werden die wichtigsten Architekturschwerpunkte in eigenen Abschnitten ausführlicher
diskutiert. Dabei wird jeweils Bezug genommen auf die in Abschnitt 4 dargestellten
Anwendungsfälle und Anforderungen.
5.1 Das Entitäten-Relationen-Modell
Das Entitäten-Relationen-Modell (kurz ERM) ist der Ausgangspunkt für die meisten in der
zu entwickelnden Anwendung verwendeten Datenmodelle und Validierungsverfahren. Das
Modell wurde bereits im Vorfeld dieser Arbeit von der Datenbankgruppe der Universität
Zürich in enger Zusammenarbeit mit Beteiligten des Sesam-Projekts an der Universität
Basel erarbeitet. Es sind darin sämtliche Daten abgebildet, die für das Sesam-Projekt von
Relevanz sind und gespeichert werden sollen.
Das ERM ist zu Gunsten der Übersichtlichkeit in 6 Kategorien aufgeteilt, die jeweils eine
bestimmte Thematik abdecken:
• Tasks and Appointments: Das Schema beschreibt die Daten zur Administration von
Aufgaben und Terminen.
• Equipment and Storage: Definition der Daten zur Erfassung und Verwaltung von
Messgeräten, Aufbewahrungsbehälter (beispielsweise Kühlschränke für biologische
Proben) und deren Standorte.
• Locations, Studies and Organisations: Umfasst die Daten zur Beschreibung der
einzelnen Studien sowie der Orte und Organisationen, die an den Studien
teilnehmen und an denen Daten erhoben werden, bzw. die Messungen durchführen.
Dies können beispielsweise Spitäler, Geburtshäuser oder Universitätszentren sein.
• Persons, Study Subjects and Employees: In diesem Schema sind sämtliche
personenbezogenen Daten modelliert. Dazu gehören einerseits die Probanden und
5. Architektur
35
Studienteilnehmer sowie deren Familien. Andererseits sind darin auch die
Angestellten erfasst, welche die jeweiligen Untersuchen und Messungen ausführen.
• Scientific Data and Instruments: In diesem Teil des ERM sind die
wissenschaftlichen Daten aufgeführt, die während der Studie bei Messungen und
Befragungen anfallen. Diese können ganz unterschiedliche Formen annehmen. Im
einfachsten Fall handelt es sich um einen Barcode, der eine bestimmte Blutprobe
identifiziert, die in einer Untersuchung entnommen wurde. Eine andere
Möglichkeit wäre, dass es sich bei diesen wissenschaftlichen Daten um die
digitalisierte Form eines kompletten Fragebogens handelt.
• Experiments, Processes and Measurements: Dieser Teil des ERM hat in Bezug auf
die zu entwickelnde Applikation die grösste Bedeutung. Er beschreibt die
Zusammenhänge zwischen Experimenten, Prozessen und Datenein- und ausgaben.
Da dieses Schema den zentralen Ausgangspunkt für diese Arbeit darstellt, soll es
im nachfolgenden Unterkapitel genauer betrachtet werden.
5.1.1 ERM-Schema Experiments, Processes and Measure ments
Wie bereits erwähnt, sind die in diesem Teil des Schemas beschriebenen Entitäten von
zentraler Bedeutung für die Applikation bzw. für deren Verarbeitungslogik. Abbildung 14
zeigt einen stark vereinfachten und reduzierten Ausschnitt des Schemas. Dieses beschreibt
die Relationen, in denen die Metadaten der jeweiligen Erhebungsverfahren abgelegt
werden. So wird beispielsweise erfasst, welche unterschiedlichen Arten von Experimenten
es gibt, welche Prozesse diese enthalten, an welchen Standorten diese durchgeführt werden
können und welche Personen daran teilnehmen müssen. Die Metadaten der Prozesse
enthalten beispielsweise Angaben darüber, welche Geräte und Angestellte zur Ausführung
benötigt werden. Jeder Prozess erzeugt mindestens ein Datenobjekt als Ausgabe und kann
kein bis mehrere Datenobjekte als Eingabeparameter verlangen. Des Weiteren können
innerhalb eines Experimentes mehrere Prozesse aneinandergereiht werden. Dabei kann das
Ausgabeobjekt des ersten Prozesses gleichzeitig das Eingabeobjekt eines zweiten
Prozesses sein. All diese Eigenschaften und Verknüpfungen werden als Metadaten in den
von diesem Teil des ERM beschriebenen Relationen abgelegt. Relationen, die solche
Metadaten enthalten, sind im Allgemeinen, aber nicht ausschliesslich, daran zu erkennen,
dass sie die Bezeichnung „class“ im Namen enthalten, beispielsweise „experiment_class“
oder „process_class“.
Diplomarbeit
36
Das Schema „Experiments, Processes and Measurements“ umfasst aber nicht nur die
Metadaten, sondern auch die konkreten Ausprägungen der ausgeführten Experimente und
Prozesse. Von jedem ausgeführten Experiment wird ein entsprechendes Tupel erzeugt, das
in der Regel Informationen darüber enthält, von welchem Typ dieses Experiment ist,
welche Personen daran teilgenommen haben und welche konkreten Prozesse dazu gehören.
Dasselbe gilt auch für jeden Prozess. Es wird vermerkt, von welcher Klasse ein Prozess ist
und welche konkreten Datenobjekte die Ein- und Ausgabeparameter sind.
Diese komplexe Datensammlung ermöglicht es, für jedes Datenobjekt nachzuvollziehen,
von welcher Art es ist, in welchen Prozessen und Experimenten es entstanden ist, und
welche Personen das Experiment mit welchen Geräten ausgeführt haben.
Manche Beziehungen zwischen den Entitäten sind recht komplex und lassen sich teilweise
mit dem ER-Modell nur ungenügend ausdrücken. Und nicht alle Arten von Beziehungen
können datenbankseitig abgebildet werden, beispielsweise mit Fremdschlüssel, Constraints
und Triggers. Um dennoch sicherzustellen, dass die erfassten Experimente, Prozesse und
Datenobjekten dem Metamodell entsprechen, wird eine Applikation benötigt, die genau
diese Kontroll-Aufgabe übernimmt.
Abbildung 14: Stark vereinfachter und reduzierter Ausschnitt aus dem ERM-Schema „Experiments,
Processes and Measurements“
5. Architektur
37
5.2 Übersicht
Dieser Abschnitt gibt einen Überblick über die Architektur der Anwendung. Zuerst wird
die entwickelte Architektur kurz erläutert und mit denkbaren Alternativen verglichen.
Anschliessend wird der Prozess des Datenimports erklärt, bevor dann die einzelnen
Komponenten der Architektur genauer erläutert werden.
5.2.1 Einführung Architektur
In Abbildung 15 ist die Architektur der zu entwickelnden Applikation abgebildet.
Kernstück dabei ist die Workflow-Steuerung zusammen mit den vier Hauptkomponenten
Eingabeverarbeitung, Validierung, Speicherung und Fehlerbehandlung. Diese
Komponenten entsprechen den vier Prozessschritten, die beim Import nacheinander
ausgeführt werden. Die Workflow-Steuerung orchestriert den Ablauf und dient als Single-
Entry-Point des Import-Prozesses. Gemeinsam bilden sie den Controller-Teil der
Applikation. Darüber befindet sich die grafische Benutzeroberfläche, die einerseits den
Workflow anstösst und andererseits über wohldefinierte Schnittstellen Informationen aus
den Komponenten Speicherung und Fehlerbehandlung abrufen kann (durch gestrichelte
Pfeile angedeutet). Dies kann beispielsweise eine Auflistung der Validierungsfehler sein
oder eine Liste mit zu speichernden Experimenten. Die Schicht unter den vier
Kernkomponenten enthält die eigentliche Implementierung der Verarbeitungslogik. Das
InputPlugin wird abhängig von der Art des InputFiles geladen. Bei der Validierung und
Speicherung werden die Handler-Klassen rekursiv aufgerufen, wobei jeder Handler einem
Objekt im Eingabemodell (siehe Kapitel 6.1.1) zugeordnet ist. Während die Speicher-
Handler direkt mit der Datenbank kommunizieren, verwenden die Validierungshandler
eine MetaModelReader-Klasse, welche generische Zugriffsfunktionen sowie einen
Objektbuffer zur Minimierung der Datenbankanfragen bereitstellt.
In dieser Architektur werden die vier Kernprozesse von der Workflow-Komponente
gesteuert. Ein alternatives Konzept könnte so aussehen, dass die vier Komponenten sich
jeweils gegenseitig aufrufen, wenn sie ihre Aufgaben abgearbeitet haben. Damit würde die
Workflow-Steuerung wegfallen und die Eingabeverarbeitung wäre der Einstiegspunkt für
den Import-Prozess. Obwohl dadurch eine Komponente wegfällt, wird die Komplexität
nicht reduziert, sondern lediglich die Steuerlogik auf die vier Kernkomponenten aufgeteilt.
Jede dieser Komponenten muss nun den nachfolgenden Prozess kennen und diesen
entsprechend aufrufen. Dies hat zur Folge, dass die Komponenten stärker aneinander
Diplomarbeit
38
gekoppelt werden. Der gewichtigste Nachteil besteht aber darin, dass die Kernprozesse
nicht einzeln aufgerufen werden können. In der aktuellen Architektur kann jeder Prozess
prinzipiell für sich alleine ausgeführt werden. So kann beispielsweise eine Eingabedatei
nur eingelesen und validiert werden, ohne etwas zu speichern. Die Speicherung kann zu
einem späteren Zeitpunkt vom Benutzer ausgelöst werden. Ein wichtiger Aspekt betrifft
auch das Testen. Dank der Möglichkeit, die Komponenten einzeln auszuführen, können
diese isoliert voneinander getestet werden.
Ebenfalls denkbar wäre die Integration der Implementierungsklassen in die jeweilige
Kernkomponente und ein iteratives Abarbeiten der Aufgaben anstelle eines rekursiven
Vorgehens. Dadurch könnte allenfalls die Performance etwas verbessert werden, was aber
gemäss den Anforderungen kein Kriterium ist. Hingegen wäre mit dieser Änderung die
Gefahr verbunden, dass grosse, unübersichtliche Klassen entstehen, die spätere
Anpassungen erschweren, was nicht im Sinne der Anforderungen [4] Neue
Eingabeformate und [5] Neue Datenobjekte wäre. In der gewählten Architektur wurden die
Kern-Komponenten bewusst von den Implementierungsklassen getrennt. Die
Kernkomponenten (in der Abbildung 15 blau eingefärbt) enthalten die eigentliche
Kontroll-Logik und sind grundsätzlich sehr generisch gehalten und nicht an das konkrete
Daten- bzw. Metamodell gebunden, im Gegensatz zu den Implementierungsklassen (in der
Abbildung 15 gelb eingefärbt), die jeweils auf ein bestimmtes Datenobjekt ausgerichtet
sind. Durch die Aufteilung der Funktionalität in einzelne Klassen entsteht wiederum die
Möglichkeit, diese jeweils einzeln und isoliert zu Testen, was der Anforderung [9] Testen
entgegenkommt.
5. Architektur
39
Abbildung 15: Architekturübersicht
5.2.2 Importprozess
Ausgangspunkt des Importprozesses (vgl. Abbildung 16) ist eine einzelne Eingabe-Datei
(InputFile), welche die Metadaten über die zu importierenden Datenobjekte (DataItems)
enthält. Die DataItems selber sind entweder in strukturierter Form im InputFile selber
enthalten (wenn es sich beispielsweise nur um einzelne Zahlenwerte handelt) oder aber,
was häufiger der Fall sein wird, in externen Dateien ausgelagert, die für die Anwendung
erreichbar sein müssen (idealerweise am selben Ort wie das InputFile). Über ein
entsprechendes GUI kann der Benutzer der Applikation die Eingabe-Datei mitgeben und
damit den Importprozess starten. Anschliessend wird das InputFile syntaktisch validiert
und eingelesen. Danach wird für jede Import-Einheit (was beispielsweise ein Experiment
oder Prozess sein kann) ein Eintrag in einer Pendenzenliste in der sesamDB erzeugt. In
dieser Liste sind sämtliche Import-Einheiten aufgeführt, die einer Validierung unterzogen
wurden, und zwar unabhängig davon, ob die Validierung erfolgreich war oder nicht.
Gleichzeitig wird jeweils vermerkt, ob die jeweilige Import-Einheit bereits gespeichert
wurde. Eine genauere Beschreibung der Funktionsweise dieser Pendenzenliste ist in
Abschnitt 7.1.3 zu finden. Im Anschluss findet die eigentliche Validierung gegen das
Diplomarbeit
40
Metamodell aus der sesamDB statt. Sind keine Fehler vorhanden, werden die Metadaten
sowie die dazugehörigen DataItems in der sesamDB gespeichert, und der entsprechende
Eintrag in der Pendenzenliste als gespeichert markiert. Sind jedoch bei der Validierung
Unstimmigkeiten entdeckt worden, so werden keine Daten in die sesamDB übertragen.
Stattdessen werden die Fehlermeldungen in eine Log-Datei ausgegeben.
Die Koordination dieses Prozesses wird von der Workflow-Steuerung übernommen. Diese
stösst die jeweiligen Verarbeitungsschritte an, die nachfolgend genauer erläutert werden.
Abbildung 16: Importierungsprozess
5.2.3 Eingabeverarbeitung
Je nach Typ der Eingabedatei oder gemäss Benutzerauswahl wird das entsprechende
InputPlugin geladen, welches das InputFile einliest und syntaktisch validiert. Vorgängig
kann vom InputPlugin eine Entschlüsselung der Eingabedatei, wie in Anforderung [1]
Datenentschlüsselung formuliert, vorgenommen werden. Im Falle einer XML-Datei kann
die Validierung beispielsweise gegen eine XML Schema Definition (XSD) geschehen.
Damit liegt die Verantwortlichkeit zur Erfüllung des ersten Teils der Anforderung [2]
Validierung ebenfalls beim InputPlugin. Danach wird der Inhalt geparst und in eine Java
Daten Objekt (JDO) Struktur umgewandelt. Diese Struktur soll so aufgebaut sein, dass sie
sich als gerichteten, azyklischen Graphen darstellen lässt. Das Ergebnis ist eine Objekt-
Struktur, welche die Meta-Daten aus der Eingabe-Datei enthält.
Für diese Komponente wurde die Plug-In-Architektur gewählt, um der Anforderung [4]
Neue Eingabeformate gerecht zu werden. Alternativ hätte man die Syntaxvalidierung und
das Parsing in separate Komponenten aufteilen können. Da aber beide Prozessschritte
abhängig vom Format der Eingabedatei sind, ist es sinnvoller, diese in einem einzelnen
Plug-In zu kapseln. Dadurch bleiben diese Schritte transparent für den Rest der
Applikation.
5. Architektur
41
Eine Plug-In-Klasse unterscheidet sich nur geringfügig von einer normalen Klasse. Im
Wesentlichen implementiert eine Plug-In-Klasse ein bestimmtes Interface. Zusätzlich muss
aber die Klasse der Anwendung ihre Existenz mittels einer eigenen Konfigurationsdatei
oder einem Eintrag in der Konfiguration der Anwendung mitteilen. Darin muss mindestens
der Name der Input-Klasse vermerkt sein. Während bei einer normalen Klasse bereits zur
Entwurfs- bzw. Kompilierungszeit festgelegt wird, ob und wann eine Instanz dieser Klasse
generiert wird, entscheidet dies bei einer Plug-In-Klasse die Anwendung zur Laufzeit. Dies
geschieht in der Regel durch die Überprüfung einer bestimmten Bedingung (beispielsweise
ob ein bestimmter Konfigurationseintrag gesetzt ist). Mittels Reflexion-Techniken kann die
Anwendung zur Laufzeit den Konstruktor der Klasse ermitteln und neue Instanzen
erzeugen. Dadurch können neue Plug-In-Klassen ohne Änderungen an bestehendem Code
mittels eines entsprechenden Konfigurationseintrages eingebunden werden. Dies hat den
Vorteil, dass nicht die gesamte Applikation neu kompiliert werden muss, sondern nur die
neu einzubindende Klasse. Ausserdem entfällt auf diese Weise eine Neuinstallation der
Applikation.
5.2.4 Validierung
In der Validierung wird die JDO-Struktur Objekt für Objekt rekursiv durchlaufen und
gegen ein Meta-Modell aus der sesamDB, das die Meta-Daten beschreibt, validiert. Damit
ist diese Komponente für die Umsetzung des zweiten Teils der Anforderung [2]
Validierung verantwortlich. Je nach Typ des betrachteten Objekts wird der entsprechende
ValidationHandler geladen. Dieser kann über einen MetaModelReader auf das Meta-
Modell aus der sesamDB zugreifen, um dagegen seine Vergleiche durchzuführen. Der
MetaModelReader bietet dazu diverse Zugriffsfunktionen an, die entsprechende Java-
Objekte zurückliefern, welche diese Meta-Informationen repräsentieren.
An dieser Stelle wird jedem zu prüfenden Objekt ein eigener Handler zugeordnet. Das
Wissen über die interne Struktur und Semantik eines Objekts ist so in einer einzigen Klasse
gekapselt. Damit wird der Anforderung [6a] Änderungsresistent Rechnung getragen, da so
bei einer allfälligen Modelländerung die betroffene Stelle leichter lokalisiert und der
Aufwand verringert werden kann.
Natürlich wäre an dieser Stelle wiederum eine Plug-In-Architektur denkbar. Da aber von
jedem ValidationHandler höchstens eine Implementierung benötigt wird, ergäbe sich
daraus kein zusätzlicher Nutzen. Zudem würden sich allfällige Änderungen dahingehend
auswirken, dass bestehender Code angepasst werden müsste und nicht durch eine komplett
Diplomarbeit
42
neue Klasse ersetzt würde, wie dies bei der Eingabeverarbeitung der Fall sein kann.
Dennoch lassen sich für zusätzliche Datenobjekte ohne grossen Aufwand weitere
ValidationHandler hinzufügen, wie dies von [5] Neue Datenobjekte gefordert wird. Gerade
bei den DataItems werden nachträglich zusätzliche Handler zu implementieren sein, da
zum Zeitpunkt dieser Arbeit die Spezifikation erst eines DataItems bekannt war. Geplant
ist aber eine Vielzahl von Datenobjekten, die nach und nach eingebaut werden müssen.
Mit dem MetaModelReader sollen primär die ValidationHandler von der darunter
liegenden Datenbankschicht entkoppelt werden (entspricht Anforderung [6a]
Änderungsresistent). Der MetaModelReader nimmt dabei mehrere Aufgaben gleichzeitig
wahr: Einerseits bietet er komfortable Zugriffsfunktionen auf die persistenten Metaobjekte
an. Andererseits entsteht so die Möglichkeit, Bufferfunktionen einzubauen, um die Zahl
der Datenbankzugriffe zu minimieren. Natürlich könnten solche Buffer auch in den
jeweiligen ValidationHandler eingebaut werden. Durch die Auslagerung in den
MetaModelReader können diese Buffer aber zentral verwaltet werden und die Entstehung
von Code-Duplikaten wird verringert.
5.2.5 Speicherung
Die validierten und korrekten Meta-Daten aus dem InputFile werden anschliessend in die
sesamDB übertragen. Gleichzeitig werden die von den Meta-Daten beschriebenen Daten-
Objekte (DataItems) archiviert. Damit ist diese Komponente für die Erfüllung der
Anforderung [3] Datenspeicherung verantwortlich. Auch hier wird wieder eine Handler-
Architektur eingesetzt. Für jedes Metadaten-Objekt und jedes DataItem ist ein
entsprechender StoreHandler implementiert, der für die Speicherung des jeweiligen
Objekts zuständig ist. Wiederum werden diese Handler rekursiv aufgerufen, dass heisst,
jeder Handler ruft jeweils die StoreHandler für die Unterobjekte seines Objekts auf. Alle
Metadaten werden dabei in einer einzigen Datenbanktransaktion zusammengefasst. Schlägt
die Speicherung eines Objektes fehl, findet ein Rollback statt und sämtliche Änderungen
der Datenbank durch diese Transaktion werden rückgängig gemacht. Damit wird
sichergestellt, dass die Datenbank keine inkonsistenten Daten enthält.
Bei den DataItems besteht für jeden Typ ein entsprechender DataItemHandler. Von dessen
Implementierung hängt es denn auch ab, ob ein DataItem direkt in die sesamDB übertragen
wird, oder ob es an einer anderen Stelle gespeichert wird (beispielsweise auf einem
separaten Datei-Server). Unabhängig davon werden die Meta-Daten eines DataItems in
jedem Fall in der sesamDB abgelegt.
5. Architektur
43
Wie bei der Validierung stehen auch hier bei der Kapselung der Speicherlogik eines
Objekts in eine eigene Klasse die Anforderungen [5] Neue Datenobjekte und [6a]
Änderungsresistent im Vordergrund. Die Plug-In-Architektur ist an dieser Stelle wenig
sinnvoll, da die einzelnen Speicherprozeduren bei Modelländerungen angepasst und nicht
ausgetauscht werden. Um die Speicherung von zusätzlichen DataItems zu unterstützen,
muss lediglich ein entsprechender Handler implementiert und in der Factory-Klasse dem
DataItem-Typ zugeordnet werden. Bestehende Handler sind davon nicht betroffen.
5.2.6 Fehlerbehandlung
Fehler, die während der Validierung auftreten, werden von der Fehlerbehandlungs-Routine
gesammelt und dem Benutzer strukturiert über das GUI dargestellt. Zusätzlich besteht die
Möglichkeit, die detaillierte Fehlerliste in einer Datei abzuspeichern.
Bei der Ausarbeitung der Architektur kam die Idee zur Diskussion, eine Fehlerbehebung
einzubauen. Diese hätte bei einem Validierungsfehler eine entsprechende Eingabemaske
angezeigt, worin der Benutzer die fehlerhaften Werte hätte korrigieren können. Dieser
Ansatz wurde aber schnell verworfen, da der Benutzer, der den Datenimport vornimmt, in
der Regel nicht für die Erfassung der Daten verantwortlich ist und deshalb wohl auch nicht
berechtigt, diese zu verändern. Viel entscheidender war jedoch der Punkt, dass er zum
Zeitpunkt des Imports keine Informationen darüber hat, was bei einem Fehler die richtige
Angabe wäre. Er hat beispielsweise keine Möglichkeit, einen Probanden nochmals zu
befragen oder nachzuschauen, was die korrekte ID eines Gerätes X im Labor Y ist, wenn
diese falsch erfasst worden ist. Das Vorgehen in dieser Situation wird vermutlich so
aussehen, dass die Import-Daten am jeweiligen Erhebungsort nochmals überprüft werden
müssen.
Die Fehlerbehandlung beschränkt sich deshalb darauf, die fehlenden oder falschen
Elemente anzuzeigen und mit möglichst aussagekräftigen und präzisen Ortsangaben zu
versehen. Diese Ortsangabe besteht aus einer Pfad-ähnlichen Angabe des fehlerhaften
Elements. Sie bezieht sich auf die interne JDO-Struktur, wie sie von der
Eingabeverarbeitung generiert wird und nicht auf die Struktur in der ursprünglichen
Eingabe-Datei. Dennoch sollte mindestens eine manuelle Lokalisierung der Fehlerquelle in
der Eingabe-Datei möglich sein.
Diplomarbeit
44
5.2.7 Verantwortlichkeiten
In der Architektur wurde versucht, die einzelnen Verarbeitungsschritte klar voneinander zu
trennen. Ausgetauscht werden nur Java Objekte und keine XML-Elemente oder Ergebnis-
Listen von Datenbankanfragen. Die Verantwortlichkeiten der einzelnen Plug-Ins und
Handler lassen sich wie folgt zusammenfassen:
Tabelle 2: Verantwortlichkeiten von Plug-Ins und Handler
Komponente Eingabe Ausgabe Verantwortlichkeit
InputPlugin Datei mit Meta-Daten über DataItems
JDO-Struktur der Meta-Daten
Einlesen und parsen einer Eingabedatei in einem bestimmten Format und erzeugen der Meta-Daten-Objekt-Struktur
ValidationHandler Meta-Daten-Objekt und JDO-Struktur des Meta-Meta-Modells
Validierungsfehler Validieren des Meta-Daten-Objekts gegen die Vorgaben aus dem Meta-Meta-Modell und erstellen von Validierungsfehler-Meldungen
StoreHandler Meta-Daten-Objekt sesamDB Speicherung des Meta-Daten-Objekts in der sesamDB
DataItemHandler DataItem sesamDB / File-Server
Speicherung der Meta-Daten eines bestimmten DataItems in der sesamDB sowie Archivierung der DataItem-Werte bzw. des externen DataItem-Objekts in der sesamDB oder auf einem File-Server
MetaModelReader sesamDB JDO-Struktur des Meta-Meta-Modells
Liest die Meta-Meta-Modell-Struktur aus der sesamDB ein und liefert die gewünschten Objekte an die ValidationHandler
Nachfolgend sollen einzelne Aspekte aus den erwähnten Verarbeitungsschritten vertieft
betrachtet werden.
5.3 XML-Objekt-Mapping
Zum Zeitpunkt der Implementierung soll die Applikation Eingabe-Dateien (InputFiles) im
XML-Format verarbeiten können. Für die Eingabeverarbeitung soll deshalb ein
InputPlugin zur Handhabung von XML-Dateien entwickelt werden. Wie in Tabelle 2
aufgeführt, besteht die Verantwortlichkeit des InputPlugins darin, aus der Eingabe-Datei
eine Java-Daten-Objekt-Struktur zu erzeugen. Dieser Vorgang wird als XML-Objekt-
5. Architektur
45
Binding oder XML-Objekt–Mapping bezeichnet. Die Implementierung der Abbildung der
jeweiligen XML-Daten auf die Java-Objekte wäre an dieser Stelle sehr aufwändig und
äusserst ungeeignet. Hier bietet es sich an, auf eines der diversen Frameworks von
Drittanbietern zurückzugreifen. Diese haben den Vorteil, dass sie schon mehrfach in der
Praxis eingesetzt und ausführlich getestet wurden, was der Anforderung [9] Testen
entgegenkommt. Zu den bekanntesten Frameworks in diesem Bereich zählen sicherlich
JAXB von Sun [JAXB], Castor (The Castor Project) [Castor] und Apache XMLBeans
[XMLBeans]. Um die Vereinfachung zu verdeutlichen, welche diese Tools bieten, sei hier
beispielhaft XMLBeans erwähnt, dass direkt aus einem XSD die dazu passenden Java
Daten Objekte generiert. Bei einer Änderung des Schemas können die Objekte schnell
angepasst werden, indem dieser Generierungsprozess einfach wiederholt wird. Ein
detaillierter Vergleich zwischen den verschiedenen Frameworks wird später
vorgenommen.
5.4 Validierung
Die Validierung der Meta-Daten aus der Eingabe-Datei gegen das Meta-(Meta-)Modell aus
der sesamDB ist bewusst so angelegt, dass sie auf Java-Daten-Objekten operiert. Denkbar
wäre die XML-Elemente direkt gegen das Meta-Modell zu prüfen, ohne den Umweg über
die Java-Daten-Objekte zu gehen. Dies bringt aber drei wesentliche Nachteile mit sich:
1. Die Validierung würde direkt an das Format der Eingabe-Datei gekoppelt. Wird die
Struktur dieser Eingabe-Datei verändert (ohne die Semantik zu ändern), müsste die
Komponente für die Validierung angepasst werden. Dies würde der Anforderung
[4] Neue Eingabeformate widersprechen.
2. Würde die Validierung auf diese Weise direkt an die Eingabe-Datei gekoppelt, so
wird es schwierig, mehrere verschiedene Eingabe-Formate zu unterstützen. Es
müssten dazu für jedes Format eine eigene Validierungskomponente geschrieben
werden. Auch in diesem Punkt ist die in Anforderung [4] Neue Eingabeformate
postulierte leichte Erweiterbarkeit nicht mehr gegeben. Mit der Entkoppelung
mittels den JDOs kann der Validierungsteil wieder verwendet werden.
3. Spätestens im dritten Prozessschritt, der Speicherung, sollte die Abbildung der
Eingabe-Daten auf Java-Objekte vorgenommen werden. Im Falle von XML als
Eingabe-Format ist ein direktes Mapping auf eine relationale Sicht durchaus
möglich, würde aber wiederum dazu führen, dass die Speicherung an das Eingabe-
Diplomarbeit
46
Format gebunden ist. Damit würde der ganze Prozess an das Eingabe-Format sowie
an die Datenbank gebunden, was der Anforderung [4] Neue Eingabeformate
widerspricht.
Die Validierung erhält die JDOs, die aus der Eingabe-Datei generiert wurden und die
Meta-Daten der zu importierenden DataItems enthalten. Diese müssen mit dem Meta-
Modell, das die Meta-Daten beschreibt, verglichen werden. Dieses Meta-Modell ist in der
sesamDB abgelegt und kann über den MetaModelReader in Form von JDOs abgerufen
werden.
Um bei der Validierung die Wiederverwendbarkeit möglichst hoch zu halten, wurde ein
rekursiver Ansatz gewählt. Dies ist möglich, da die Struktur der Eingabe-Daten einem
azyklischen Graphen entspricht. Für jedes Daten-Objekt wird ein eigener
ValidationHandler implementiert. Dieser prüft das entsprechende Objekt und allenfalls
Anzahl und Identitäten von seinen Kind-Objekten. Danach übergibt er jedes Kind-Objekt
seinem ValidationHandler. Dieses Objekt wird wieder überprüft und allfällige Kind-
Objekte werden wiederum ihrem ValidationHandler übergeben und so weiter. Mit diesem
Ansatz kann relativ einfach ein zusätzlicher ValidationHandler eingefügt werden, falls
neue Datenobjekte hinzukommen. Damit wird den Anforderungen [5] Neue Datenobjekte
und [6a] Änderungsresistent Rechnung getragen.
Eine Frage, die sich bei der Validierung stellt, ist, wie Validierungsfehler gesammelt
werden. Eine mögliche Variante ist der Einsatz von Exceptions, was in diesem rekursiven
Ansatz durchaus machbar wäre. Doch dadurch wird eine Validierung beim ersten Fehler
unterbrochen und die Kontrolle wird recht schwierig und unflexibel. Eine elegantere
Lösung bietet sich mit dem Observer-Pattern (siehe [Gamma04]) an. Dabei registriert sich
die Fehlerbehandlungskomponente als Observer bei den jeweiligen ValidationHandler.
Validierungsfehler werden über eine entsprechende notify-Methode an die
Fehlerbehandlung gesendet. Dies ermöglicht es auch, während der Überprüfung
auftretende Fehler dem Benutzer sofort anzuzeigen. Dazu muss die Fehlerbehandlung
lediglich über eine entsprechende Schnittstelle zur grafischen Benutzeroberfläche (GUI)
verfügen.
5.5 Objekt-Relationen-Mapping
Am Ende des Importprozesses erfolgt die Speicherung der überprüften und korrekten
Metadaten in der sesamDB. Hier ergibt sich ein weiteres Schnittstellen-Problem: die
5. Architektur
47
Abbildung der Java Daten Objekte in eine für die Datenbank geeignete Darstellung. Im
Falle einer relationalen Datenbank wird hier ein Objekt-Relationen-Mapping benötigt. In
der Abbildung 15 wird dies durch die Komponente „Speicherung“ dargestellt. Tatsächlich
besteht diese Komponente aber aus zwei Schichten: eine Schicht enthält die
Applikationslogik, die auf den Java Daten Objekten arbeitet und diese nacheinander der
zweiten Schicht übergibt. Diese enthält das eigentliche Objekt-Relationen-Mapping und
die datenbank-spezifischen SQL-Befehle zur Speicherung der Objekte. Während die erste
Schicht auf die Applikation zugeschnitten ist und deshalb selber implementiert werden
muss, gibt es für die zweite Schicht bereits diverse Open-Source-Lösungen. Diese haben
meist noch den Vorteil, dass sich die darunter liegende Datenbank leicht austauschen lässt,
und man somit nicht an ein spezielles Datenbank-Produkt gebunden ist. Ein solches
Framework, und sicherlich eines der bekanntesten und am meist verbreiteten in der Java
Programmierung, ist Hibernate. Ein Produktvergleich wird in Kapitel 7.3.3 vorgenommen.
Diese Frameworks übernehmen nicht nur die Abbildung von Java Objekten auf Relationen
und von Java-Datentypen auf SQL-Datentypen. Sie tragen auch dazu bei, durch Kapselung
die Anwendung frei von hersteller-spezifischem SQL-Code zu halten. Meistens ist es aber
auch möglich das Framework zu umgehen und SQL-Befehle direkt auf die Datenbank
anzuwenden. So lassen sich auch sehr spezifische Kommandos umsetzen, die von den
Frameworks nicht abgedeckt werden. Dies hat natürlich den unerwünschten Nebeneffekt,
dass der Code stärker an die jeweilige Datenbank gekoppelt wird.
Aber gerade diese Möglichkeit, auch direkte SQL-Befehle abzusetzen, ist im Rahmen
dieser Applikation von grosser Bedeutung. Die Anwendung ist insgesamt sehr stark an die
sesamDB gebunden, und es wird bei der Implementierung Fälle geben, bei denen eine
direkte Speicherung von Objekten unter Umgehung des Frameworks einfacher und
effizienter ist. Dies spricht aber keineswegs gegen den Einsatz eines solchen Frameworks,
da damit in der Regel rund 80% der persistenzbezogenen Programmieraufgaben abgedeckt
werden können.
5.6 Datenbankanbindung
Das Einsatzszenario der Applikation sieht vor, dass die Anwendung auf einem Client läuft,
während die sesamDB auf einem zentralen Server betrieben wird. Der Datenbankzugriff
findet über ein internes Netzwerk (Intranet) statt. Dieses Intranet ist vollständig von aussen
abgekoppelt, verfügt also weder über einen Internetanschluss noch über sonst eine
Diplomarbeit
48
Netzwerkanbindung. Dabei bietet es sich an, die Kommunikation zwischen Client und
Datenbankserver mit einem gängigen Verschlüsselungsverfahren wie SSL (Secure Socket
Layer Protocol, siehe [FRR00]) vor internen Abhörversuchen zu schützen. Abbildung 17
stellt den geschilderten Aufbau grafisch dar.
Abbildung 17: Einsatzumgebung
Die unter 5.5 erwähnten Datenbank-Frameworks übernehmen meist auch die Handhabung
der Datenbankverbindungen. So kann die Verbindung mittels entsprechender
Konfiguration eingerichtet und für die Applikation transparent genutzt werden.
6. Detailentwurf
49
6 Detailentwurf
Im vorausgehenden Kapitel wurde die Architektur der zu implementierenden Anwendung
festgehalten und ausgeführt. Die erwähnten Konzepte und Designentscheidungen wurden
bis anhin bewusst auf einer sehr abstrakten Ebene gehalten. In diesem Kapitel geht es nun
darum, die erwähnte Architektur zu verfeinern und Details auszuarbeiten oder bereits
konkret darzustellen. Bei diversen Problembereichen bieten sich meist mehrere
Lösungsansätze an. Diese sollen jeweils erläutert und die Entscheidung für eine bestimmte
Variante begründet werden.
6.1 Datenmodelle
Dieser Abschnitt befasst sich mit dem Datenmodell der Applikation. Ausgangspunkt
sämtlicher Überlegungen ist dabei das Entitäten-Relationen-Modell (ERM) der sesamDB,
das bereits vorgängig von der Datenbankgruppe der Universität Zürich entwickelt wurde.
Dieses beschreibt einerseits die Zusammensetzung sämtlicher Metadaten und die
Beziehungen unter den Objekten wie auch die zu speichernden konkreten Forschungs-
Daten (siehe Kapitel 5.1). Das ERM ist grundsätzlich so aufgebaut, dass jedes konkrete
Objekt (z.B. eine Person, ein Forschungs-Instrument, ein Messergebnis etc.) eine Referenz
auf mindestens eine Metarelation besitzt, welche das Objekt genauer beschreibt und
allenfalls Beziehungen zu anderen Objekten dokumentiert. Im Rahmen der zu
implementierenden Anwendung ist dabei nicht das gesamte ERM der sesamDB relevant,
sondern nur spezifische Ausschnitte. Dazu gehören im Wesentlichen Informationen über
Experimente und Prozesse (siehe Kapitel 5.1.1) sowie über daran beteiligte Personen,
Messinstrumente und –daten.
Während die Metadaten bereits in der sesamDB vorhanden sind, werden die konkreten
Daten mit der zu entwickelnden Applikation in die Datenbank importiert. Dazu findet
vorgängig eine Validierung dieser Eingabedaten gegen das vorgegebene Metamodell statt.
Nachfolgend werden das Modell der Eingabedaten (InputModel) und das Modell der
Metadaten (MetaModel) beschrieben.
Diplomarbeit
50
6.1.1 Eingabemodell
In Abbildung 18 ist das Klassendiagramm des Eingabemodells (InputModel) abgebildet,
welches die Struktur der Eingabedaten beschreibt. Während des Importprozesses liest das
InputPlugin die Daten aus einer Eingabedatei ein und bildet diese auf die Objekte des
Eingabemodells ab. Die Struktur des Eingabemodells lehnt sich dabei stark an das
Entitäten-Relationen-Modell an, das in Kapitel 5.1 beschrieben wird. Sämtliche Objekt-
Kollektionen sind in eigene Objekte ausgelagert. So enthält Experiment nicht eine Liste
mit Prozessen, sondern eine Referenz auf ein Processes-Objekt, das dann eine Kollektion
von Prozessen beinhaltet. Diese Java-Klassen-Struktur wird von XMLBeans aus dem
XML Schema „importManager.xsd“ automatisch generiert. Was auf den ersten Blick ein
wenig umständlich aussieht, zeigt sich beispielsweise bei der Validierung als sehr hilfreich,
da so nämlich den jeweiligen Kollektions-Klassen eigene Validation- und StoreHandler
zugewiesen werden können.
Nachfolgend werden die Bedeutungen der einzelnen Klassen (mit Ausnahme der eben
erwähnten Kollektions-Klassen) kurz beschrieben.
• Experiment: Das Wurzelelement des InputModels bildet ein Objekt der Klasse
Experiment, das anhand der classId einer Experimentklasse zugeordnet ist. Da eine
Eingabedatei mehrere Experimente der gleichen Klasse enthalten kann, erhält jedes
Experiment eine elementId, die innerhalb der Eingabedatei eindeutig sein muss. Mit
date wird das Datum vermerkt, an dem dieses Experiment ausgeführt wurde. Über
die locationId kann der Ort identifiziert werden, an dem dieses Experiment
stattfand. Jedes Experiment besteht aus mindestens einem Prozess und mindestens
einem StudySubject.
• StudySubject: Identifiziert eine Person, die als Proband am Experiment teilnahm.
Es kann sein, dass diese Person selber Auskunft gab, oder dass über diese Person
Informationen gesammelt wurden. Die sid ist der Identifikations-Code. Die roleId
identifiziert eine bestimmte Rolle, welche die betreffende Person zum Zeitpunkt
des Experiments einnahm. Mögliche Rollen sind beispielsweise Kind, Mutter,
Vater, Grossvater mütterlicherseits etc. Über die pathId kann der Proband eindeutig
dem Prozess zugeordnet werden, an dem er teilnahm.
• Process: Ein Prozess wird über die classId eindeutig einer Prozessklasse
zugeordnet. Die workflowNodeId dient zur Bestimmung des Workflow-Knotens im
6. Detailentwurf
51
MetaModell. Dieser Knoten bringt die jeweiligen Prozesse in eine Reihenfolge,
weist ihnen die Probanden (StudySubjects) zu und zeigt an, welches die In- und
Outputs eines Prozesses sind.
• Equipment: Unter Equipment sind die Arbeitsgeräte aufgeführt, die zur Ausführung
eines bestimmten Prozesses verwendet wurden. Sämtliche Geräte müssen in der
sesamDB erfasst werden und erhalten eine eindeutige id.
• Employee: Das Employee-Objekt repräsentiert einen sesam-Mitarbeiter, der einen
bestimmten Prozess ausgeführt hat. Ein Angestellter kann mehrere Job-Rollen
einnehmen, auch innerhalb desselben Prozesses.
• Extrafields: Je nach Prozess werden zur Speicherung zusätzliche Angaben benötigt.
Jede Prozess-Art wird in der Datenbank über eine eigene Relation definiert, die in
einer hierarchischen Struktur angeordnet sind. Jede Prozessrelation erbt dabei alle
Attribute der Eltern-Relation und kann selber zusätzliche Attribute definieren.
Damit nicht für jede Prozess-Art eine eigene Java-Klasse mit den passenden
Attributen erstellt werden muss, werden diese in der Liste extrafields
zusammengefasst. Dabei entspricht jedes zusätzliche Prozess-Attribut einem Data-
Objekt in der Liste. Damit eine eindeutige Zuordnung der Werte zu ihren
Attributen möglich ist, wird neben dem Wert des Attributs (value) auch dessen
Name (name) benötigt, wie er in der Datenbankrelation definiert ist.
• Inputs / Outputs: Jeder Prozess hat mindestens einen Output und kann optional
einen oder mehrere Inputs haben. Da sowohl die Inputs als auch die Outputs
dieselbe Objektstruktur haben, halten beide eine Liste mit Artefact-Objekten.
• Artefact: Diese Klasse stellt wie erwähnt entweder einen In- oder Output eines
Prozesses dar. Mit number kann das Artefact eindeutig in der Prozesskette
innerhalb eines Experimentes zugeordnet werden.
• DataItem: Jedes Artefact-Objekt enthält genau ein DataItem, das ein bestimmtes
Datenobjekt beschreibt. Die classId identifiziert die Klasse des Datenobjekts. Ein
Datenobjekt kann aus einem oder mehreren Datenfelder bestehen (Schlüssel-Wert-
Paar) und/oder auf ein oder mehrere externe Dateien verweisen, die durch das File-
Objekt repräsentiert werden.
• Data: Das Data-Objekt enthält ein simples Schlüssel-Wert-Paar. name kennzeichnet
den Namen des Attributs, value stellt den Wert dar, den dieses Attribut einnimmt.
Diplomarbeit
52
• File: Repräsentiert eine bestimmte externe Datei. Diese ist gekennzeichnet durch
den Dateinamen filename, und einen Pfad path. Der Pfad sollte in der Regel relativ
zur Eingabedatei angegeben sein.
Abbildung 18: Klassendiagramm des Eingabemodells (InputModel)
6.1.2 Metamodell
Das Metamodell ist, wie das Eingabemodell, stark an das in Kapitel 5.1 erwähnte
Entitäten-Relationen-Modell angelehnt. Es wurde teilweise insofern vereinfacht, als dass
nicht jede Entität als Objekt abgebildet wird und nicht alle Attribute einer Entität in einem
Objekt enthalten sind. Der Grund dafür ist, dass nicht alle Attribute oder Objekte für die
Validierung benötigt werden. Häufig wird bei der Validierung nur das ID-Attribut eines
Objekts verglichen. So besteht ein Equipment-Element im Eingabemodell nur aus einem
ID-Attribut. Der Wert dieser ID wird bei der Validierung mit den ID-Werten der
Equipments einer bestimmten Prozessklasse verglichen. Viele Meta-Objekte halten auch
nicht sämtliche referenzierten Entitäten als Objekt-Assoziation, sondern häufig nur als
einfache Liste mit ID-Werten. Dieses Vorgehen vereinfacht das Objekt-Relationen-
Mapping und vermeidet unnötige Rechenoperationen.
In Abbildung 19 ist das Klassendiagramm des verwendeten Meta-Modells abgebildet.
Nachfolgend werden die einzelnen Klassen kurz erläutert:
6. Detailentwurf
53
• ExperimentClass: Beschreibt eine Experiment-Klasse, die durch id eindeutig
identifiziert werden kann.
• MeasurementPoint: Identifiziert einen MeasurementPoint oder genauer eine
SiteRole, also eine Typbeschreibung des Standorts, an dem ein Experiment einer
bestimmten Klassen ausgeführt werden kann.
• ExperimentTypeWorkflowNode: Verknüpft ein Experiment mit einer Prozess-
Klasse und gibt für jeden benötigten Informanten und Probanden die StudySubject-
Pfade an, die durch StudySubjects abgedeckt werden müssen. Das heisst, für jede
Prozess-Klasse ist die Zahl der Personen und deren benötigten Rollen definiert.
• ProcessClass: Repräsentiert eine Prozess-Klasse. processDataRelname enthält den
Namen der Relation des konkreten Prozesses, den diese Klasse beschreibt. Da die
Prozesse in einer Vererbungshierarchie angeordnet sind (siehe Aufzählungspunkt
„Extrafields“ im vorhergehenden Kapitel 6.1.1), muss über dieses Attribut definiert
werden, in welche konkrete Relation in der Hierarchie ein Prozess abgelegt werden
muss, der einer bestimmten Prozess-Klasse angehört. Ausserdem sind die
benötigten Job-Rollen zur Ausführung dieses Prozesses als ID-Liste gespeichert.
Die Klassen der dabei einzusetzenden Geräte sind ebenfalls als ID-Liste abgelegt,
wobei die jeweilige Anzahl auf die Geräte-Klasse-ID abgebildet ist. Schliesslich
enthält das ProcessClass-Objekt je eine Liste mit ProcessClassInput- und
ProcessClassOutput-Objekten.
• ProcessClassInput: Definiert einen Input einer bestimmten Prozess-Klasse. Da eine
Prozess-Klasse mehrere Inputs des gleichen Typs haben kann, dient die
inputNumber zur Unterscheidung. Ein Input muss ein Datenobjekt einer
bestimmten DataItemClass enthalten.
• ProcessClassOutput: ProcessClassOuput ist gleich aufgebaut wie
ProcessClassInput. Die outputNumber dient zur eindeutigen Unterscheidung
möglicherweise gleichartiger Outputs in derselben Prozess-Klasse. Auch ein
Output muss ein Datenobjekt einer bestimmten DataItemClass enthalten.
• DataItemClass: Beschreibt die Klasse eines Datenobjekts. Da auch hier ähnlich wie
bei den Prozessen die DataItems in einer Vererbungshierarchie angeordnet sind,
wird das Attribut dataRelationName dazu verwendet, um den Relationen-Namen
Diplomarbeit
54
anzugeben, in dem ein konkretes Datenobjekt von dieser DataItemClass abgelegt
wird.
Wie bereits erwähnt, werden vielerorts nur die ID-Werte der Unterobjekte als Liste
gehalten, da bei der Validierung nur diese Attribute benötigt werden und die restlichen
Eigenschaften wie name, description, abbreviation etc. für die Validierung nicht
verwendet werden.
Abbildung 19: Klassendiagramm des Meta-Modells (MetaModel)
6.2 Transaktionen
Ein wichtiger Aspekt bei Datenbanktransaktionen ist die Einhaltung der ACID-
Eigenschaften. ACID steht für:
• Atomarität (Atomicity: Eine Datenbanktransaktion wird entweder komplett oder
gar nicht ausgeführt. Sie bildet also eine unteilbare, atomare Operation.
6. Detailentwurf
55
• Konsistenz (Consistency): Eine Datenbank befindet sich vor und nach einer
Transaktion stets in einem konsistenten Zustand. Das heisst, sämtliche Daten sind
widerspruchsfrei und gültig.
• Isolation (Isolation): Bei gleichzeitiger Ausführung von Transaktionen dürfen sich
diese gegenseitig nicht beeinflussen.
• Dauerhaftigkeit (Durability): Die Änderungen einer abgeschlossenen Transaktion
bleiben dauerhaft gültig. Dies bedeutet, dass die Änderungen auch nach einem
Programmabsturz oder Ausfall eines Speichermediums bestehen bleiben.
Speziell die erste Eigenschaft, die Atomarität von Transaktionen, ist für den Datenimport
von Bedeutung. Hier stellt sich die Frage, was als atomare Transaktion angesehen werden
soll. Ein (Meta-)Datenobjekt darf nur in die sesamDB gelangen, nachdem es ohne Fehler
validiert werden konnte. Da sich aber jedes Objekt in einer Struktur von (Meta-)Daten
befindet, kann der Fall eintreten, dass ein Objekt zwar in Ordnung ist, eines seiner Eltern-
oder Kindobjekte jedoch Fehler aufweist. Es gilt also festzulegen, welche Objekte
zusammen eine Einheit bilden sollen. Betrachtet man das Eingabemodell in Abbildung 18,
so erkennt man, dass nur die Speicherung des Modells als Ganzes sinnvoll ist. Ein
Datenobjekt, zu dem sämtliche Metadaten fehlen, kann nicht sinnvoll verwendet werden,
da sein Ursprung oder der Kontext der Erhebung nicht bekannt sind. Andererseits nützt ein
Experiment-Eintrag nichts, wenn die Prozessinformationen und Messresultate nicht
vorhanden sind. Damit bietet sich das Experiment-Objekt als Wurzelelement des
Eingabemodells als sinnvolle Transaktionseinheit an. Mit anderen Worten, das
Experiment-Objekt und die darin enthaltenen Unterobjekte bilden zusammen eine Import-
Einheit. Das heisst, diese Objekte werden gemeinsam in einer Datenbank-Transaktion in
die sesamDB übertragen. Gleichzeitig bedeutet dies, dass ein Fehler bei der Validierung
irgendeines dieser Objekte dazu führt, dass kein Objekt dieser Import-Einheit gespeichert
wird.
Die meisten Datenbanken und Objekt-Relationalen Frameworks bieten dem
Programmierer die Möglichkeit, Transaktionseinheiten festzulegen. Durch spezielle
Sprachkonstrukte können mehrere Datenbankoperationen in einer Transaktion
zusammengefasst werden. Schlägt eine dieser Operationen bei der Ausführung fehl, so
findet eine automatische Rückabwicklung (engl. rollback) statt, das heisst, sämtliche bisher
ausgeführten Operationen innerhalb der Transaktion werden rückgängig gemacht.
Diplomarbeit
56
Besondere Beachtung muss hierbei der Übertragung von Datenobjekten geschenkt werden.
Denn wenn diese beispielsweise via File-Transfer-Protokoll (FTP) auf einen separaten
Dateiserver übertragen werden, findet diese Operation ausserhalb der eben erwähnten
Datenbanktransaktion statt, womit sie auch von einer automatischen Rückabwicklung
ausgeschlossen ist. Hier muss die Applikation, bzw. der entsprechende DataItemHandler,
sicherstellen, dass die Datenbanktransaktion abgebrochen wird, wenn der Dateitransfer
fehlschlägt. Wünschenswert wäre auch der umgekehrte Fall, bei dem der Dateitransfer
rückgängig gemacht wird (bzw. das bereits übertragene Datenobjekt auf dem Dateiserver
gelöscht wird), wenn die Datenbanktransaktion der Metadaten fehlschlägt. Aufgrund des
gewählten Ansatzes, der für diese Applikation bei der Speicherung gewählt wurde, ist dies
aber nicht ohne weiteres möglich. Auf dieses Problem wird in Kapitel 7.3 eingegangen.
7. Implementierung
57
7 Implementierung
Dieses Kapitel beschäftigt sich mit ausgewählten Problemen und Lösungsansätzen, die
sich auf die konkrete Implementierung beziehen. Dabei wird auch hier versucht, mehrere
Möglichkeiten zur Bewältigung eines Problems aufzuzeigen und den für diese Arbeit
gewählten Weg zu begründen. Das Kapitel ist thematisch grob in die drei Kernprozesse (1)
Eingabeverarbeitung, (2) Validierung und (3) Speicherung aufgeteilt.
7.1 Eingabeverarbeitung
Die Architektur der Eingabeverarbeitung ist in Abschnitt 5.2.3 dokumentiert. In diesem
Kapitel sollen diese Anforderungen detailliert ausgeführt und anschliessend die konkrete
Umsetzung beschrieben werden. Hinzu kommt ein kurzer Vergleich zweier XML-Java-
Binding-Frameworks, von denen das eine im InputPlugin eingesetzt wurde.
7.1.1 Anforderung
Ausgangspunkt des Eingabeverarbeitungs-Prozesses ist eine externe Datenquelle, welche
Metadaten über bestimmte Datenobjekte enthält. Optional kann das Datenobjekt selber
auch enthalten sein. Prinzipiell ist jede Art von Datenquelle denkbar: von einer simplen
Textdatei, über ein XML-Dokument bis hin zu Datenbanken. Das Ziel der
Eingabeverarbeitung besteht in der Erzeugung einer Struktur aus Java-Daten-Objekten als
Repräsentationsform dieser Metadaten. Diese JDO-Struktur wird anschliessend an die
Validierungskomponente weitergegeben. Es ist also die Aufgabe der Eingabeverarbeitung,
aus der externen Datenquelle die eben genannte Objekt-Struktur zu erzeugen (siehe
Abbildung 20). Dies soll völlig transparent für den Rest der Applikation geschehen, das
heisst, für die nachfolgenden Komponenten ist es vollkommen irrelevant, aus welchen
konkreten Datenquellen diese Metadaten eingelesen wurden. Es findet an dieser Stelle also
eine Entkoppelung von der konkreten Eingabequelle statt. Die Implementierung der
Eingabe-Komponente sollte so angelegt sein, dass mit wenig Programmieraufwand
beliebige zusätzliche Eingabeformate unterstützt werden können. Abhängig von der
jeweiligen Quelle soll zur Laufzeit die entsprechende Verarbeitungslogik ausgeführt
werden.
Diplomarbeit
58
Abbildung 20: Schematische Darstellung des Eingabeverarbeitungsprozesses
7.1.2 Umsetzung
Wie in Kapitel 5.2.3 bereits ausgeführt, wird für die Eingabeverarbeitung eine Plug-In-
Architektur eingesetzt. Dazu wird eine Factory-Klasse (siehe [Gamma04]) verwendet, die
je nach Typ der Eingabequelle die entsprechende Klasse zur Eingabeverarbeitung lädt und
aufruft. Diese Klassen werden im Rahmen dieser Arbeit als InputPlugins bezeichnet. Ein
InputPlugin implementiert das InputPlugin-Interface und wird in der Konfigurationsdatei
der Applikation einer bestimmten Datei-Endung zugeordnet. Zur Laufzeit kann über die
Benutzeroberfläche eine Datei ausgewählt werden und die Applikation lädt anhand der
Datei-Endung das entsprechende InputPlugin. Diese gegenwärtige Implementierung
impliziert zwei Einschränkungen: einerseits können als Eingabequellen nur Dateien
ausgewählt werden (und beispielsweise keine Datenbanken) und andererseits müssen sich
unterschiedliche Eingabe-Formate in der Datei-Endung unterscheiden. Der Grund für diese
Beschränkungen liegt darin, dass ursprünglich nur der Import aus Dateien angedacht war.
Ausserdem kann so die grafische Benutzeroberfläche wesentlich vereinfacht werden.
Ansonsten müsste für jedes InputPlugin zusätzlich noch jeweils eine eigene Eingabe-
Maske zur Definition der Eingabequelle realisiert werden. Dies kann aber nachträglich
eingebaut werden, denn wie bereits erwähnt, ist die darunter liegenden Business-Logik
durchaus in der Lage, dies zu unterstützen.
Im Rahmen dieser Arbeit wurde ein InputPlugin zum Einlesen von XML-Dateien
verwirklicht. Dieses benutzt im Wesentlichen die Funktionalität von XMLBeans, einem so
genannten XML-Java-Binding-Framework. Neben XMLBeans gibt es noch diverse andere
solche Frameworks. Eine entsprechende Evaluation und Begründung für die Wahl von
XMLBeans wird in Abschnitt 7.1.4 geliefert.
Als Erstes wurde eine entsprechende XML-Schema-Definition (XSD) erstellt, welche die
Struktur einer XML-Eingabedatei beschreibt. Mithilfe des XML-Java-Binding-
7. Implementierung
59
Frameworks namens XMLBeans konnten aus dieser XSD die Java-Klassen generiert
werden, welche zur Repräsentation der Metadaten dienen. Auf diesen Java-Objekten findet
anschliessend auch die Validierung statt. Die Vorteile, die sich aus diesem Vorgehen
ergeben, sind folgende:
• Mit XMLBeans als Binding-Framework können die Daten aus der Eingabedatei
automatisch in die Java-Data-Objects abgefüllt werden. Ein umständliches,
manuelles Mapping und Abfüllen entfällt.
• Wurde am XSD eine Änderung vorgenommen, so kann der oben genannte Prozess
zur Generierung der Java-Klassen einfach wiederholt werden, um so das Java-
Modell anzupassen. Dazu wurde ein entsprechender Ant7-Task erstellt, mit dem
diese Generierung per Knopfdruck ausgeführt werden kann.
• XMLBeans kann zudem dazu verwendet werden, um beispielsweise die
Eingabedatei zu validieren oder um aus den JDOs wieder XML-Code zu erzeugen.
Andererseits entstehen durch den Einsatz von XMLBeans auch gewisse Nachteile:
• Zwar können die generierten JDOs mit zusätzlicher Funktionalität erweitert
werden, aber diese Änderungen würden bei der nächsten Neugenerierung wieder
verloren gehen. Somit sollten die JDOs nicht verändert werden und wenn, dann nur
indirekt über Anpassungen in der XSD und einer anschliessenden Neugenerierung
durch XMLBeans. Dies ist auch der Grund, weshalb diese JDOs in einer eigenen
JAR-Datei vom Rest der Applikation getrennt werden. Damit soll verdeutlicht
werden, dass diese Klassen nicht verändert werden sollten.
• Das geschilderte Vorgehen kann nur für dieses eine InputPlugin gewählt werden.
Weitere InputPlugins müssen auf diese generierten JDOs zurückgreifen und dürfen
daran weder Änderungen vornehmen noch um weitere Klassen erweitern. Der
Grund ist der, dass die anschliessende Validierung sowie die Speicherung auf
7 Ant (Another Neat Tool, http://ant.apache.org) ist ein in Java geschriebenes Open-Source-Werkzeug, das
ursprünglich zur automatischen Kompilierung von Quellcode entwickelt wurde. Mittels einer XML-Datei
können Targets (Ziele) definiert werden, die wiederum Tasks (Aufgaben) enthalten, die in einer bestimmten
Reihenfolge automatisch abgearbeitet werden. Ant verfügt über eine offene Schnittstelle, über die es mit
beliebigen, zusätzlichen Tasks erweitert werden kann. Damit wird Ant längst nicht mehr nur für
Kompilierungsaufgaben verwendet, sondern für jegliche Arten von Stapelverarbeitungsprozessen.
Diplomarbeit
60
diesen Objekten aufbauen. Modifikationen an den JDOs würden Inkompatibilitäten
mit den Validierungs- und Speicherkomponenten einerseits und mit dem
bestehenden XML-InputPlugin andererseits hervorrufen.
Trotz den erwähnten Nachteilen hat sich der Einsatz von XMLBeans an dieser Stelle als
sehr nützlich erwiesen. Durch das automatische XML-Java-Mapping konnte eine Menge
Programmierarbeit eingespart werden. Gerade in der Entwicklungsphase gab es immer
wieder Änderungen am XML Schema. Dank XMLBeans konnten diese aber schnell und
einfach auf die Objekte abgebildet werden.
Die von XMLBeans generierten Java-Objekte besitzen zudem Methoden, um sich selber
wieder als XML-Text darzustellen. Diese Funktion wurde zur Realisierung einer
Pendenzenliste eingesetzt. Diese soll im nachfolgenden Abschnitt erläutert werden.
7.1.3 Pendenzenliste
Die Pendenzenliste in der zu entwickelnden Applikation deckt drei Aspekte ab:
• Sie soll verhindern, dass bereits erfolgreich gespeicherte Experimente ein zweites
Mal importiert werden können und es dadurch zu Duplikaten in der sesamDB
kommt.
• Sie bietet die Möglichkeit, Experimente, die aufgrund von Fehlern bei der
Validierung nicht gespeichert werden konnten, zu einem späteren Zeitpunkt einzeln
nochmals zu validieren, ohne dabei das ursprüngliche InputFile nochmals angeben
zu müssen. Dies kann beispielsweise der Fall sein, wenn zwar ein Experiment und
dessen Prozesse bereits erfasst und bereit für den Import sind, aber die
dazugehörigen DataItems noch nachgeliefert werden müssen. Sind die DataItems
dann vorhanden, kann die Validierung nochmals ausgelöst werden. Damit wird
vollumfänglich Anforderung [7] Zwischenspeicher abgedeckt.
• Die Pendenzenliste kann auch als Archivierungsliste benutzt werden. Sämtliche
importierten Experimente sind darin aufgeführt.
Jede Import-Einheit (beispielsweise ein Experiment) ist eindeutig identifiziert durch zwei
Attribute: der InputFileId und der ElementId. Ersteres ist eine eindeutige Kennzeichnung
der ursprünglichen Eingabedatei. Letzteres ist die Nummer des Elements innerhalb eben
dieser Eingabedatei. Diese Identifikatoren werden verwendet, um einen entsprechenden
Eintrag in der Pendenzenliste zu erstellen. Dieser enthält unter anderem auch die XML-
7. Implementierung
61
Text-Repräsentation der jeweiligen Import-Einheit. Dieser XML-Text wird vom XML-
InputPlugin bzw. vom XMLBeans-Framework erzeugt. Im Grunde entspricht dieser XML-
Text einer normalen XML-Eingabedatei, die aus nur einem Experiment besteht.
Abbildung 21: Historisierungsprozess
Die Historisierung findet kurz vor der Validierung statt. Abbildung 21 stellt den
entsprechenden Workflow dar. Zu Beginn wird überprüft, ob das Element bereits in der
Pendenzenliste vorhanden ist. Dazu wird ein Eintrag gesucht, der dieselbe Identifikation
(InputFileId und ElementId) aufweist wie das vorliegende Element. Bleibt die Suche
ergebnislos, wird ein neuer Eintrag erstellt und das Element wird zur Validierung
weitergegeben. Falls die Suche ein Ergebnis liefert, wird überprüft, ob der Eintrag als
bereits gespeichert markiert ist. Dies würde bedeuten, das Element wurde bereits
erfolgreich validiert und in die sesamDB übertragen. Ist dies der Fall, so wird eine
entsprechende Meldung ausgegeben und es findet keine Validierung statt. Ist der Eintrag
aber noch nicht als gespeichert markiert und somit pendent, wird angefragt, ob der
pendente Eintrag überschrieben oder beibehalten werden soll. Es kann sein, dass der
vorhandene Eintrag inhaltliche Fehler aufweist und deshalb nach der Validierung nicht
gespeichert werden konnte. In diesem Fall möchte der Benutzer diesen pendenten,
fehlerhaften Eintrag durch eine korrigierte Version ersetzen, die zwar die genau gleichen
Identifikations-Attribute aufweist, aber einen anderen XML-Text enthält. Dann wird der
entsprechende Eintrag in der Pendenzenliste aktualisiert und das Element wird zur
Diplomarbeit
62
Validierung weitergeleitet. Andernfalls kann der Benutzer ein Aktualisieren ablehnen und
so die Validierung sowie die Speicherung verhindern.
Wird ein Element nach der Validierung erfolgreich gespeichert, so wird der entsprechende
Eintrag in der Pendenzenliste als gespeichert markiert, womit ein nachträgliches Speichern
oder Überschreiben nicht mehr möglich ist.
7.1.4 Vergleich zweier XML-Java-Binding-Frameworks
Im Web lassen sich eine Vielzahl von so genannten XML-Java-Binding-Produkten finden.
Die funktionalen Unterschiede liegen oftmals im Detail. Ein ausführlicher Vergleich
zwischen diesen Produkten wäre an dieser Stelle zu aufwändig. Deshalb beschränkt sich
diese Evaluation auf zwei Produkte und auf eine Auswahl von Funktionen, die im
Zusammenhang mit der zu entwickelnden Applikation sinnvoll erscheinen.
Die Anforderungen der Applikation an ein entsprechendes Framework sind relativ simpel:
• Aus einer XML-Datei sollen die passenden Java-Objekte erzeugt werden
(unmarshalling).
• Die XML-Datei soll gegen ein XML Schema validiert werden können.
• Die Java-Objekte sollten wieder zurück in XML-Text umgewandelt werden
können (marshalling).
• Optional soll aus einem XML Schema die passende Java-Objekt-Struktur generiert
werden können.
Manche Frameworks haben Einschränkungen was die Zahl der unterstützten XML
Schema-Elemente betrifft. Da aber die im vorliegenden XML Schema verwendeten
Elemente eher einfacher Natur sind, sollte dies in keinem Fall ein Problem sein.
Idealerweise sollten aber möglichst alle Arten von Elementen abgedeckt sein, um
Probleme bei zukünftigen Erweiterungen des Schemas zu vermeiden. Nachfolgend werden
zwei ausgewählte Frameworks kurz vorgestellt und deren besonderen Eigenschaften
beschrieben. Anschliessend werden diese bezüglich den gestellten Anforderungen
verglichen und die Wahl in einem Fazit zusammengefasst.
7.1.4.1 JAXB
JAXB [JAXB] steht für „Java Architecture for XML Binding“ und ist einerseits eine
Spezifikation und andererseits eine Referenzimplementierung dieser Spezifikation von Sun
7. Implementierung
63
Microsystems8. Abbildung 22 stellt diese Architektur schematisch dar. Aus einem XML
Schema wird mit einem so genannten Binding Compiler die passenden Klassen und
Interfaces generiert. Diese können dann in die Applikation eingebunden werden. Mit der
von JAXB zur Verfügung gestellten Programmierschnittstelle können mit wenigen Zeilen
Code aus einem XML Dokument die Objekte erzeugt werden (unmarshalling) und
umgekehrt, aus den Objekten wieder XML-Text generiert werden (marshalling). Zudem
besteht die Möglichkeit, beim Unmarshalling einen Handler zu registrieren, um
Validierungsfehler aufzufangen.
Abbildung 22: Schematische Darstellung der Architektur von JAXB (Quelle: [OM03])
Einige XML Schema Komponenten werden von JAXB nicht direkt unterstützt, dass heisst,
für diese Elemente muss ein eigenes Mapping definiert werden. Dazu gehören unter
anderem Identitätseinschränkungen wie xs:key, xs:keyref und xs:unique.
Im Artikel von [Kawa03] wird zudem darauf hingewiesen, dass sich das Marshalling von
JAXB nur mangelhaft konfigurieren lässt. Das bedeutet, auf die physische Darstellung und
Formatierung des erzeugten XML-Textes kann wenig bis gar kein Einfluss genommen
werden.
7.1.4.2 XMLBeans
XMLBeans [XMLBeans] ist Teil des Apache XML Projects und ein Open-Source
Framework zum Einlesen und Bearbeiten von XML-Dokumenten, indem diese auf Java
Objekte abgebildet werden. Die Funktionsweise ist dabei ähnlich wie bei JAXB. Aus
einem XML Schema werden mit einem Binding Compiler die dazu passenden Java
8 http://www.sun.com
Diplomarbeit
64
Klassen generiert, die jeweils über entsprechende Getter- und Setter-Methoden für den
Zugriff auf die Daten verfügen. Mithilfe der XMLBeans-API können in der Applikation
XML-Dokumente auf Objekt-Instanzen der generierten Java Klassen abgebildet werden.
Natürlich kann auch umgekehrt aus den XMLBeans-Objekten wieder XML-Code erzeugt
werden. Zwei wesentliche Merkmale unterscheiden XMLBeans von anderen XML-Java-
Binding-Frameworks: [XMLBeans/overview]
• Komplette XML Schema Unterstützung. XMLBeans unterstützt alle Eigenschaften
von XML Schema gemäss der W3C Spezifikation9. Dies ist insbesondere dann
hilfreich, wenn man selber keine Kontrolle über das zu bearbeitende Schema hat,
weil dies beispielsweise von einer externen Instanz vorgegeben wird. Zudem ist
man so nicht gezwungen, sich auf eine Teilmenge von XML Schema zu
beschränken.
• Vollständige Informationen über das XML-Dokument. Wenn ein XML-Dokument
auf Java-Objekte abgebildet wird, gehen zwangsläufig Informationen verloren, die
sich nicht ohne weiteres auf diese Objekte abbilden lassen. Dazu gehören
beispielsweise Kommentar-Elemente und die Reihenfolge von Elementen.
XMLBeans bietet dem Entwickler die Möglichkeit, diese Informationen bei Bedarf
abzurufen.
XMLBeans wurde ausserdem stets mit Rücksicht auf die Performance entwickelt. Gemäss
Shah [Shah04] wird dies erreicht, indem Marshalling oder Unmarshalling erst dann
stattfindet, wenn dies auch wirklich benötigt wird. Ausserdem bietet XMLBeans die
Möglichkeit an, auf Datentypen, die von XML Schema vordefiniert sind (so genannte
built-in data types) über effizientere Getter-Methoden zuzugreifen.
7.1.4.3 Vergleich
Grundsätzlich decken beide vorgestellten, sowie wahrscheinlich noch viele andere XML-
Java-Binding-Frameworks, die gestellten Anforderungen ab. Da jeweils nur ein XML-
Dokument verarbeitet wird und dieses in der Regel vollständig eingelesen werden muss,
fallen die von XMLBeans umgesetzten Performance Optimierungen nicht ins Gewicht,
zumal Geschwindigkeit sowieso kein Kriterium für die zu erstellende Applikation darstellt.
Auch in der Einfachheit der Verwendung unterscheiden sich die beiden Frameworks nur
9 http://www.w3c.org/xml/schema/
7. Implementierung
65
geringfügig. Was bleibt, sind kleine Unterschiede im Detail. So hat XMLBeans durch die
vollständige Abdeckung aller XML Schema Komponenten einen kleinen Vorsprung auf
JAXB, das gewisse Elemente nicht direkt unterstützt. Dies betrifft beispielsweise das
xs:unique-Element, das im Schema verwendet wurde, um eine eindeutige elementId
innerhalb des XML-Dokumentes zu erzwingen. Ausserdem möchte man für zukünftige
Schema-Änderungen möglichst wenige Einschränkungen einbauen.
7.1.4.4 Fazit
Die Anforderungen, die von der Applikation an ein XML-Java-Binding-Framework
gestellt werden, beschreiben im Prinzip die Grundanforderungen eines solchen
Frameworks und werden deshalb von den meisten auch erfüllt. Somit ergeben sich keine
signifikanten Gründe, die für die Wahl eines bestimmten Produkts sprechen. XMLBeans
wurde im vorliegenden Fall wegen seiner vollständigen XML Schema Unterstützung
bevorzugt. Aufgrund der einfachen Anforderungen ist eine ausführlichere Evaluation der
unterschiedlichen Frameworks nicht gerechtfertigt.
7.2 Validierung
Dieses Kapitel befasst sich mit den Implementierungsdetails der Validierungskomponente.
Dazu werden nachfolgend die Anforderungen nochmals detailliert dargestellt und auf die
Problematik eines generischen Ansatzes eingegangen. Anschliessend wird die konkrete
Umsetzung beleuchtet und zum Abschluss noch der Einsatz von Threads diskutiert.
7.2.1 Anforderung
Die Validierungskomponente hat die Aufgabe, die semantische Korrektheit des
Eingabemodells zu überprüfen. Dabei sollen die Daten mit den Angaben im Metamodell
der sesamDB verglichen werden. Die Struktur des Eingabemodells wurde bereits in der
Eingabeverarbeitung überprüft, beispielsweise mit einer Validierung gegen ein XML
Schema.
Um dem Benutzer die Korrektur allfälliger Fehler zu ermöglichen, müssen diese einerseits
von der Validierungskomponente gesammelt und angezeigt werden und andererseits muss
jede Fehlerbeschreibung eine möglichst genaue Angabe der Fehlerquelle liefern. Zu
beachten ist, dass sich diese Ortsangabe eines Fehlers nur auf die Struktur des
Eingabemodells beziehen kann, denn die Validierungskomponente hat keinerlei
Informationen über die interne Struktur der ursprünglichen Eingabedatei.
Diplomarbeit
66
Wie in den Spezifikationen und in Anforderung [5] Neue Datenobjekte bereits
festgehalten, sollte die Architektur so gewählt sein, dass zusätzliche Datenobjekte ohne
grossen Aufwand hinzugefügt werden können.
7.2.2 Problematik eines generischen Ansatzes
Das Problem bei der semantischen Überprüfung besteht darin, dass sich dieser Prozess
nicht vollständig generisch umsetzen lässt. Dies würde einen Algorithmus voraussetzen,
mit dem sich jedes Objekt unabhängig von seinem konkreten Typ validieren lässt. Das
wiederum bedingt, dass sich sämtliche Beziehungen, Bedingungen und Einschränkungen
in irgendeiner maschinell verarbeitbarer Form erfassen lassen. Zwar sind in der sesamDB
gewisse Beziehungen und Einschränkungen durch Fremdschlüsselbeziehungen und andere
Attributbedingungen im Datenmodell hinterlegt, jedoch können damit längst nicht alle
Sachverhalte abgebildet werden.
Angesichts der relativ geringen und konstanten Zahl von zu prüfenden Objekten, ist das
manuelle Ausprogrammieren der jeweiligen semantischen Prüfregeln vollkommen
gerechtfertigt.
7.2.3 Umsetzung
Aus dem vorhergehenden Abschnitt 7.2.2 geht bereits hervor, dass ein generischer Ansatz
im vorliegenden Fall zu aufwändig wäre. Konkret handelt es sich um ungefähr 20
Prüfregeln, die bei einer Validierung angewendet werden.
7.2.3.1 Regelzentrierter vs. objektzentrierter Ansatz
Grundsätzlich bieten sich nun zwei Varianten an, den Validierungsprozess zu
strukturieren: ein regelzentrierter Ansatz und ein objektzentrierter Ansatz. Bei ersterem
stehen die Regeln im Vordergrund. Dabei wird eine Menge von Regeln sequentiell auf das
Eingabemodell angewandt. Dies lässt sich mit einer Art Checkliste vergleichen. Der zweite
Ansatz fokussiert sich auf die einzelnen Objekte. Für jedes Objekt wird ein Satz von
Regeln definiert und ausgeführt. Der Unterschied liegt darin, dass im zweiten Fall dem
Prüfalgorithmus nur das jeweilige Objekt bekannt sein muss, während beim
regelzentrierten Ansatz der Prüfalgorithmus die benötigten Objekte selber aus dem
Eingabemodell heraussuchen und dazu dessen gesamte Struktur kennen muss. Letzteres
wirkt sich insbesondere bei einer Änderung der Struktur des Eingabemodells negativ aus.
Denn dadurch muss bei sämtlichen Regeln die Zugriffsmethode auf ein Objekt im
7. Implementierung
67
Eingabemodell an die neue Struktur angepasst werden. Im objektzentrierten Ansatz
müssen höchstens die Kindobjekt-Beziehungen in den betroffenen Objekten angepasst
werden. Anhand dieser Überlegungen zeigt sich der objektzentrierte Ansatz allgemein als
resistenter gegen Veränderungen als der regelzentrierte Ansatz, womit ersterer geeigneter
für die zu entwickelnde Anwendung ist.
7.2.3.2 Umsetzung des rekursiven, objektzentrierten Ansatzes
Die Umsetzung der gewählten Variante ist in Abbildung 23 dargestellt. Für jedes Objekt
wurde ein so genannter ValidationHandler implementiert, der die jeweiligen Prüfregeln auf
das Objekt anwendet. In der Abbildung sind beispielhaft drei ValidationHandler
aufgeführt, die jeweils für die Prüfung eines Objekts von Typ A, B oder C zuständig sind.
Aufgerufen werden die ValidationHandlers in einer Art Rekursion. Jeder Handler kennt die
Kindobjekte seines Objektes und gibt diese an die ValidationHandlerFactory weiter. Im
Beispiel enthält das Objekt vom Typ A die Kindobjekte B und C. Jedes dieser Kindobjekte
übergibt der ValidationHandler A in einem Methodenaufruf an die
ValidationHandlerFactory. Diese verwaltet eine Zuordnung der Objekte zu den
ValidationHandlern. Mittels Reflexion wird der Typ eines Objektes identifiziert, der dafür
zuständige Handler geladen und die Validierung gestartet, indem eine entsprechende
Methode im ValidationHandler aufgerufen und das Objekt mitgegeben wird.
Abbildung 23: Ablaufschema der Validierung
7.2.3.3 PropertyMap als gemeinsamer Variablenpool
Manchmal besteht die Notwendigkeit, zwischen den Handler bestimmte Informationen
auszutauschen. So benötigen beispielsweise manche Validierungsregeln das Datum, an
Diplomarbeit
68
dem ein Experiment statt gefunden hat. Da aber die Handler nur ihr jeweiliges Objekt
kennen, können sie nicht auf die Daten eines anderen Objekts zugreifen. Deshalb haben
alle Handler Zugriff auf eine gemeinsame Sammlung von Attributen, eine so genannte
PropertyMap (siehe Abbildung 24). So kann beispielsweise der ValidationHandler des
Experiment-Objektes das Datum einlesen und in der PropertyMap abspeichern. Diese
PropertyMap wird dann jeweils von Handler zu Handler weitergereicht. Später kann ein
zweiter ValidationHandler dieses Datum wieder aus der PropertyMap auslesen und
verwenden, ohne dass er Zugriff auf das Experiment-Objekt benötigt.
Abbildung 24: PropertyMap als gemeinsamer Zwischenspeicher
7.2.3.4 Fehlerhandling
Ein wichtiger Punkt bei der Validierung liegt in der Art und Weise, wie Fehler gesammelt
werden sollen. Ein erster Entwurf sah vor, dies über die in Java üblichen Exceptions zu
lösen. Findet ein ValidationHandler einen Fehler, so erzeugt er eine Exception und wirft
diese. Durch den rekursiven Ansatz, der im vorangegangenen Abschnitt beschrieben
wurde, könnte diese vom aufrufenden ValidationHandler aufgefangen, allenfalls mit
eigenen Fehlern ergänzt und wiederum an den nächst höheren Handler weitergeworfen
werden. Dieser Lösungsansatz hatte aber diverse Schwächen. Die Handhabung der
Exceptions erwies sich als sehr unflexibel und umständlich in der Implementierung. Der
Code würde übersät mit Try-Catch-Anweisungsblöcken, um die Fehlermeldungen
innerhalb der Klasse sowie diejenigen der ValidationHandler der Kindobjekte aufzufangen
und zu verarbeiten. Ausserdem erzwingt das Werfen einer Exception immer auch den
Abbruch der aktuellen Funktion. In Fällen, wo der Fehler nicht kritisch ist, möchte man
aber eine vollständige Validierung, um möglichst alle Fehler zu erfassen. Ein weiterer
Punkt, der gegen die Exception-Variante spricht, ist dass eine Auswertung der Fehler erst
nach Abschluss der Validierung statt finden kann. Hierbei müssen die geschachtelten
7. Implementierung
69
Exceptions iterativ oder rekursiv durchlaufen werden, um schliesslich eine Liste von
Fehlermeldungen zu erhalten. Diese Nachteile führten zur Verwerfung dieser Variante und
zur Entwicklung eines alternativen Ansatzes, der nachfolgend beschrieben wird.
Der zweite Ansatz ist in der Implementierung wesentlich einfacher und kann flexibler
eingesetzt werden. Es handelt sich dabei um eine einfache Anwendung des Beobachter-
Entwurfsmuster (engl. observer pattern) nach [Gamma04]. Dazu werden zwei
Schnittstellen definiert (vgl. Abbildung 25): eine für die Observer-Klassen (also die
Konsumenten der Validierungsfehler) und eine für die Observable-Klassen (also für die
Produzenten von Validierungsfehlern, sprich die ValidationHandler). Eine an den Fehlern
interessierte Klasse kann nun das Observer-Interface implementieren und sich bei der
ValidationHandlerFactory anmelden. Diese registriert den Observer wiederum bei den
ValidationHandlern, sobald diese aufgerufen werden. Die ValidationHandler
implementieren ihrerseits eine öffentliche Methode10, mit der sich Observer-Objekte
registrieren können und verpflichten sich, sämtliche Validierungsfehler an diese
weiterzuleiten.
Abbildung 25: Validation-Observer-Pattern
Dieser Ansatz bietet drei wesentliche Vorteile: einerseits können Fehlermeldungen
jederzeit losgelöst von der Laufzeit einer Validierungsmethode erzeugt werden.
10 Die konkrete Implementation sieht so aus, dass die ValidationHandler von einer abstrakten
ValidationHandler-Klasse abgeleitet sind, die wiederum das Observable-Interface implementiert.
Gleichzeitig übernimmt die abstrakte Klasse die Verwaltung der registrierten Observer-Objekte, so dass sich
die konkreten ValidationHandler nur noch um die Erzeugung der Validierungsfehler kümmern müssen.
Diplomarbeit
70
Andererseits können die erstellten Fehlermeldungen während der Laufzeit der Validierung
gesammelt und angezeigt werden. Der dritte Vorteil besteht darin, dass jede beliebige
Klasse die Fehlermeldungen empfangen kann, die das erwähnte Observer-Interface
implementiert und sich bei der ValidationHandlerFactory registriert. Im Gegensatz zum
ersten Ansatz muss sie sich nicht im Aufruf-Stapel der ValidationHandler befinden, um die
Exceptions zu erhalten.
7.2.3.5 Beschreibung der Fehlerquelle
Neben einer aussagekräftigen Fehlernachricht sollte ein Validierungsfehler ausserdem
Informationen enthalten, welche die Ortung des fehlerhaften Elements in der
ursprünglichen Eingabedatei ermöglichen. Der Anwendungsfall sieht dabei so aus, dass der
Benutzer mithilfe der Angaben in der Fehlermeldung die Lokalisierung der Fehlerquelle
manuell vornimmt. Im Falle eines XML-Dokumentes würde sich dafür XPath11
hervorragend eignen. Das Eingabemodell kann jedoch auch aus einer anderen Quelle als
einem XML-Dokument stammen. Ausserdem hat die Validierungskomponente
grundsätzlich keinerlei Informationen über das verwendete InputPlugin bzw. das Format
der Quelle. Deshalb muss die Lokalisierungs-Angabe des fehlerhaften Elementes in einer
allgemeinen Form gehalten sein, die für den Benutzer leicht zu verstehen ist und eine
möglichst eindeutige Identifizierung zulässt. Zu diesem Zweck wird eine einfache Notation
verwendet, welche den Pfad zur Fehlerquelle ausgehend vom Wurzelelement beschreibt.
Bei jedem Element werden ausserdem der Name und der Wert eines eindeutig
identifizierenden Attributs notiert. So können in einer Sequenz von gleichnamigen
Elementen diese voneinander unterschieden werden.
7.2.4 Einsatz von Threads
Zu Beginn der Implementierung wurde der Import-Prozess zu Testzwecken jeweils nur
über die Konsole ausgeführt und sämtliche Ausgabeinformationen wurden auf diese
ausgegeben. Mit dem Hinzufügen der grafischen Benutzeroberfläche entstand ein neues
Problem: Dadurch, dass ursprünglich sowohl das GUI wie auch der Import-Prozess im
selben Thread ausgeführt wurden, war die Benutzeroberfläche während der Laufzeit des
Import-Prozesses vollständig blockiert und konnte erst wieder nach dessen Beendigung
11 Die XML Path Language (XPath) ist eine vom W3C-Konsortium entwickelte Anfragesprache, um Teile
eines XML-Dokumentes zu adressieren. (Quelle: http://de.wikipedia.org/wiki/XPATH [Stand: 16.04.2007])
7. Implementierung
71
Befehle entgegen nehmen. Dieses Verhalten sollte vermieden werden, zumal der Import-
Prozess je nach Anzahl der Elemente in der Eingabedatei einige Sekunden bis Minuten in
Anspruch nimmt. Während dieser Zeit hat der Benutzer keinerlei Feedback über den
Fortschritt der Aktion. Das könnte dazu führen, dass er einen Programm-Absturz vermutet
und die Anwendung während des laufenden Prozesses vorzeitig beendet.
Aus diesen beiden Gründen (Verhinderung der GUI-Blockierung und Feedback über
Prozessverlauf) wurden die drei rechenintensiven Kernprozesse Eingabeverarbeitung,
Validierung und Speicherung so angepasst, dass sie jeweils in einem eigenen Thread
ausgeführt werden. Dadurch konnte nebenbei die Möglichkeit geschaffen werden, diese
Prozesse über einen bestimmten Funktionsaufruf kontrolliert zu unterbrechen. Im Falle der
Validierung und der Speicherung wird der Prozess jeweils nach der vollständigen
Abarbeitung einer Import-Einheit beendet, um die in Kapitel 6.2 erwähnten ACID-
Eigenschaften nicht zu verletzen und um inkonsistente Zustände zu vermeiden.
Die jeweiligen Prozessfortschritte werden in eigens dafür angelegten Datenobjekten
festgehalten und von den Prozessen laufend aktualisiert. Diese Datenobjekte
implementieren das Observer-Pattern nach [Gamma04]. Objekte, die deren Informationen
benötigen, können sich registrieren und werden jeweils informiert, wenn eine Änderung
statt gefunden hat. So können Fortschrittsbalken ins GUI eingebaut werden, die den
Prozessfortschritt visualisieren.
Durch den Einsatz von separaten Threads konnten zwar die eingangs erwähnten Probleme
behoben werden, doch entstanden daraus zwei neue Schwierigkeiten. Einerseits war es nun
möglich, den gleichen Prozess mehrmals hintereinander zu starten. Dies konnte verhindert
werden, indem die Workflow-Steuerung den Zustand jedes Prozesses überwacht und eine
erneute Ausführung nur erlaubt, wenn der vorhergehende Prozess beendet wurde.
Anderseits war die Anbindung ans GUI, das mit SWT [SWT] umgesetzt wurde, nicht mehr
ohne weiteres möglich, da SWT-Objekte den Zugriff von Objekten aus anderen Threads
verbieten. Diese Zugriffsfunktionen müssen in separate Klassen ausgelagert werden, die
das java.lang.Runnable-Interface implementieren. Anschliessend muss ein Objekt dieser
Runnable-Klassen instanziert und der syncExec bzw. asyncExec-Methode der aktuellen
SWT-Display-Instanz übergeben werden.
Bei rechenintensiven Prozessen sind Threads die einzige Lösung um unerwünschte
Nebeneffekte wie GUI-Blockierung zu vermeiden. Durch den Einsatz von Threads steigen
jedoch die Komplexität der Applikation und die Zahl der möglichen Fehlerquellen. Die
Diplomarbeit
72
parallele Ausführung von Methoden führt zu unerwünschten Nebeneffekten, die schwer
aufzuspüren und zu kontrollieren sind. Obwohl die Zugriffsverweigerung von fremden
Threads bei SWT oftmals als störend empfunden wird, hilft dieses Verhalten,
Nebeneffekte und damit verbundene Fehlerquellen auszuschalten.
7.3 Speicherung
Dieses Kapitel beschreibt die Umsetzung der Komponente „Speicherung“. Dazu werden
anschliessend die Anforderungen nochmals detailliert ausgeführt und danach die konkrete
Umsetzung beleuchtet. Nachfolgend werden einige ausgewählte Aspekte näher betrachtet.
Dazu gehören der Schwachpunkt der implementierten Speicherung, ein kurzer Vergleich
von Objekt-Relationalen-Mapping-Frameworks, eine Erläuterung der Besonderheiten im
Umgang mit Vererbung bei Relationen und zum Abschluss eine Betrachtung des
Historisierungsansatzes in der sesamDB.
7.3.1 Anforderung
Gemäss Anforderung [3] Datenspeicherung hat die Speicher-Komponente die Aufgabe,
einerseits die korrekt validierten Objekte mit den Metadaten in die sesamDB zu übertragen
und anderseits die konkreten Datenobjekte (DataItems) zu archivieren. Letztere haben die
Besonderheit, dass sie nicht in einer einheitlichen, sondern in einer heterogenen Form
vorhanden sind. Die Daten dieser DataItems können direkt in der Eingabedatei mit den
Metadaten enthalten sein, beispielsweise wenn es sich nur um einzelne Werte wie einen
Barcode handelt. Es ist jedoch zu erwarten, dass die Datenobjekte in einer eigenen Datei
gespeichert sind, die aber in der Eingabedatei referenziert und für die Applikation
erreichbar sein muss. Abhängig von der Art des DataItems ist auch dessen Ort der
Speicherung. Ein Grossteil wird direkt in der sesamDB in entsprechenden Relationen
abgelegt. Es kann aber Fälle geben, wo eine Archivierung des Datenobjektes ausserhalb
der sesamDB erwünscht ist. Denkbar wäre dies beispielsweise bei Videodaten, die auf
einem separaten Dateiserver gespeichert werden.
Wichtig bei der Speicherung ist die Einhaltung der ACID-Eigenschaften (siehe Abschnitt
6.2). Es darf keinesfalls zu inkonsistenten Daten kommen, beispielsweise aufgrund von
Fehlern oder Programmabstürzen während des Speichervorgangs. In der Regel sind solche
Mechanismen bereits in den Datenbankmanagementsystemen (DBMS) implementiert, so
dass es sich anbietet, diese äusserst komplexe Aufgabe wann immer möglich an das DBMS
7. Implementierung
73
zu delegieren. Dadurch lässt sich einerseits der Aufwand für die Implementierung
vermeiden und anderseits kann davon ausgegangen werden, dass diese Mechanismen
intensiv getestet wurden und sicher funktionieren.
7.3.2 Umsetzung
In Kapitel 5.2.5 wurde bereits die Architektur der Speicherungs-Komponente erläutert.
Analog zur Abbildung 23 bzw. zur Validierungs-Komponente werden auch hier einzelne
StoreHandler implementiert, wobei jeder Handler für die Speicherung der Objekte einer
bestimmten Klasse verantwortlich ist. Die Zuordnung der Klassen zu den StoreHandlern
geschieht wiederum in einer Factory, der so genannten StoreHandlerFactory. Mittels
Reflexions-Mechanismen wird der Klassenname des aktuellen Objekts ermittelt und
anschliessend der entsprechende Handler geladen. Wie bei der Validierung wird auch hier
ein quasi-rekursiver Ansatz angewendet. Die StoreHandler leiten jedes Kindobjekt ihrer
Objekte an die StoreHandlerFactory weiter, die dieses dann dem entsprechenden Handler
übergibt.
7.3.2.1 PropertyMap
Alle StoreHandler haben Zugriff auf die PropertyMap (siehe Abbildung 24), um
untereinander Werte auszutauschen. Tatsächlich ist dies dieselbe PropertyMap-Instanz, die
bereits bei der Validierung verwendet wurde. Das heisst, die StoreHandler haben die
Möglichkeit auf Attribute zuzugreifen, die von ValidationHandlers bzw. vom InputPlugin
gesetzt wurden. In der Regel wird die PropertyMap in der Speicherung dazu eingesetzt, um
anderen StoreHandler die von der Datenbank generierte ID eines gespeicherten Objekts
mitzuteilen, die häufig für gegenseitige Referenzen benötigt wird.
7.3.2.2 Transaktions-Handling
Eine Besonderheit der Speicherung im Vergleich zur Validierung ist das Transaktions-
Handling. Um die in Kapitel 6.2 formulierten ACID-Eigenschaften einzuhalten, darf eine
Import-Einheit nur entweder vollständig oder gar nicht gespeichert werden. Auf jeden Fall
muss verhindert werden, dass durch einen Fehler während der Speicherung einzelne
Objekte bereits in die sesamDB übertragen wurden und andere noch nicht. In so einem Fall
muss sichergestellt werden, dass die vor dem Auftreten eines Fehlers bereits ausgeführten
Speicheranweisungen rückgängig gemacht werden und der vorherige Stand der Daten in
der Datenbank wiederhergestellt wird. Diese komplexe Aufgabe wird von den meisten
Diplomarbeit
74
Datenbankmanagementsystemen übernommen, was im Falle von sesamDB PostgreSQL
ist. So kann die Handhabung der Transaktionen an das DBMS delegiert werden.
An dieser Stelle werden jedoch nicht direkt die Funktionen von PostgreSQL verwendet,
sondern es wird mit Hibernate eine Objekt-Relationale-Schicht dazwischen geschaltet.
Diese bringt zwei Vorteile: Erstens wird so die Kopplung der Applikation an PostgreSQL
minimiert, um damit die Möglichkeit offen zu lassen, zu einem späteren Zeitpunkt die
Datenbank ohne grossen Aufwand auszutauschen. Zweitens bietet Hibernate eine
komfortable Java-API für den Umgang mit Transaktionen, was die Programmierung
wesentlich erleichtert, da Transaktionen über einfache Methodenaufrufe kontrolliert
werden können.
Um sicherzustellen, dass sämtliche Speicher-Anweisungen der StoreHandler innerhalb
einer gemeinsamen Transaktion stattfinden, wird diese von der Kontroll-Klasse der
Speicherung initialisiert. Jeder StoreHandler erhält nun zusätzlich eine Referenz auf das
Transaktions-Objekt, um dieses für seine Speicherbefehle an die Datenbank zu verwenden.
Wenn alle StoreHandler durchlaufen sind und ihre Befehle eingebracht haben, wird von
der Kontroll-Klasse der Befehl zum endgültigen Ausführung der Transaktion gegeben.
Entstand jedoch bei einem StoreHandler ein Fehler, so wird die Anweisung zur
Rückabwicklung derjenigen Datenbankbefehle gegeben, die innerhalb der aktuellen
Transaktion bereits getätigt wurden. Die entsprechenden SQL-Befehle werden dabei von
Hibernate abgesetzt, während das Datenbankmanagementsystem die eigentliche
Transaktionsverwaltung erledigt.
Ein Schwachpunkt dieser Implementierung wird im Abschnitt 7.3.2.4 erläutert.
7.3.2.3 DataItemHandler
In der realisierten Implementierung werden die DataItemHandler von den übrigen
StoreHandler separiert, indem erstere ein eigenes Interface und eine eigene Factory
besitzen. Die grundsätzliche Funktionsweise ist aber bei beiden Handlern die gleiche. Ein
DataItemHandler ist aber nicht einer Java-Klasse zugeordnet, sondern dem Namen einer
Relation, in welche die Daten des entsprechenden DataItems abgelegt werden. Jedes
DataItem aus dem InputModel ist über die classId einer bestimmten DataItemClass
zugeordnet. Diese wiederum enthält ein Attribut, in dem der Name derjenigen Relation
gespeichert ist, die den konkreten DataItems dieser Klasse zugeordnet ist. Dabei hängt es
ganz von der Art des DataItems ab, ob in dieser Relation sämtliche Daten abgespeichert
7. Implementierung
75
werden, oder diese an einem externen Ort archiviert werden. Aus diesem Grund muss für
jede DataItem-Art ein eigener Handler zur Speicherung implementiert werden, der den
entsprechenden Algorithmus ausführt.
Jeder DataItemHandler ist somit über den Relationennamen genau einer Klasse von
DataItems zugeordnet und kennt die Beschaffenheit des Datenobjekts. Er ist dafür
zuständig, dass das DataItem korrekt abgespeichert wird. Dabei sind die folgenden
Szenarien denkbar:
• Sämtliche Daten des DataItems sind in der Eingabedatei enthalten. Diese werden in
sesamDB gespeichert.
• Sämtliche Daten des DataItems sind in der Eingabedatei enthalten. Diese werden
teilweise in sesamDB sowie an einem weiteren Speicherort gespeichert.
• Das DataItem in der Eingabedatei referenziert eine oder mehrere externe Dateien.
Die Daten werden in sesamDB gespeichert.
• Das DataItem in der Eingabedatei referenziert auf eine oder mehrere externe
Dateien. Die Daten werden teilweise in sesamDB sowie an einem weiteren
Speicherort gespeichert.
Für jedes DataItem muss in sesamDB ein minimaler Eintrag erzeugt werden, der
beispielsweise aus einer ID und einer Referenzangabe auf den externen Speicherort
besteht. Es ist auch möglich, dass die Relation des DataItems in sesamDB mit weiteren
Relationen verbunden ist, um so komplexere Inhalte abzubilden.
Muss ein DataItemHandler Daten an einen externen Speicherort übertragen, so muss er
sicherstellen, dass im Falle einer fehlgeschlagenen Übertragung eine Rückabwicklung der
in sesamDB getätigten Speicheranweisungen stattfindet. Dazu genügt in der Regel das
Werfen einer StoreException, die dann von der Kontroll-Klasse aufgefangen wird. Diese
leitet automatisch eine Rückabwicklung (engl. rollback) ein. Das folgende Beispiel soll
diesen Fall verdeutlichen:
Das Eingabemodell enthält ein DataItem, das auf eine separate Datei referenziert. Der
DataItemHandler erzeugt zuerst einen Eintrag in der sesamDB in der Relation, die der
Klasse dieses DataItems zugewiesen ist. Danach liest er die externe Datei ein und überträgt
sie via File Transfer Protocol (FTP) auf einen separaten Server. Aus unbekannten Gründen
schlägt nun diese Übertragung fehl. Der DataItemHandler erkennt diesen Fehler und wirft
eine entsprechende StoreException. Diese wird von der Kontroll-Klasse der Speicher-
Diplomarbeit
76
Komponente aufgefangen und eine Rückabwicklung der aktuellen Transaktion veranlasst.
Damit wird der vom DataItemHandler erstellte DataItem-Eintrag in der sesamDB wieder
entfernt. So wird verhindert, dass sich ein DataItem in der sesamDB befindet, das über eine
ungültige Referenz verfügt bzw. dessen Daten gar nicht gespeichert wurden.
Der nachfolgende Abschnitt 7.3.2.4 behandelt diesbezüglich einen Schwachpunkt der
Architektur.
7.3.2.4 Schwachpunkt
Die realisierte Implementierung enthält einen Schwachpunkt bezüglich der Transaktions-
Sicherheit der DataItemHandler, der nachfolgend erläutert werden soll.
In der Regel können die Metadaten der DataItems sowie externe DataItem-Objekte, die in
der sesamDB abgespeichert werden, ebenfalls innerhalb der Datenbanktransaktion
abgewickelt werden, die von der Kontroll-Klasse der Speicherung zur Verfügung gestellt
wird. Damit werden diese bei einem allfälligen Rollback automatisch miteinbezogen.
Etwas anders verhält es sich bei externen DataItems, die nicht in der sesamDB, sondern auf
einen anderen Speicher-Server übertragen werden. Deren Übertragung müsste bei einem
Rollback ebenfalls rückgängig gemacht werden. Da für diese DataItems aber unter
Umständen ein anderes Übermittlungsverfahren verwendt wird (beispielsweise FTP), ist
eine Rückabwicklung nicht so ohne weiteres möglich. Dadurch kann es sein, dass diese
DataItems auf einem Speicher-Server liegen bleiben, obwohl keine Metadaten dazu in der
sesamDB vorhanden sind. Das kann als Schwachpunkt der gegenwärtigen
Implementierung gesehen werden, der aber vernachlässigt werden kann, zumal dieses
Verhalten keine negativen Auswirkungen auf den Betrieb hat. Denn der Fall, in dem die
Übertragung der externen DataItems fehlschlägt, löst korrekterweise einen Rollback der
Metadaten-Speicherung aus. Das bedeutet, dass bei einem Rollback, bei dem bereits eine
Übertragung der DataItems auf einen externen Speicherort stattgefunden hat,
schlimmstenfalls DataItems auf dem Speicherserver abgelegt sind, die von keinem
Datensatz in der sesamDB referenziert werden. Somit besteht der Nachteil nur im
unnötigen Belegen von Speicherplatz durch das irrtümlich übertragene Datenobjekt. Sollte
dies wider Erwarten tatsächlich zu einem Problem werden, so wäre eine entsprechende
Prozedur denkbar einfach zu implementieren, die auf dem externen Speicherserver nach
Datenobjekten sucht, die von keinem Eintrag in der sesamDB referenziert werden, und
diese entfernt.
7. Implementierung
77
7.3.3 Vergleich von Objekt-Relationalen-Mapping-Fra meworks
In diesem Abschnitt werden drei Frameworks für Objekt-Relationales Mapping kurz
vorgestellt. Ferner werden diese einander gegenübergestellt und die getroffene Wahl
begründet.
7.3.3.1 Apache Cayenne
Apache Cayenne [Cayenne] ist ein Open-Source Projekt und ist unter der Apache Lizenz
verfügbar. Cayenne ist auf eine einfache Bedienung ausgelegt, ohne auf Flexibilität zu
verzichten. Eine Besonderheit ist der dazugehörige Cayenne/Modeler, über dessen
grafische Benutzeroberfläche einfach und ohne XML- oder SQL-Kenntnisse Java-Klassen
auf ein Datenbankschema abgebildet werden können. Umgekehrt besteht auch die
Möglichkeit, aus einem Datenbankschema die dazu passenden Java-Klassen zu generieren.
Die Mappings werden XML-basiert abgespeichert und können auch manuell bearbeitet
werden. Apache Cayenne verfügt über Caching-Funktionen zur Reduktion der Anzahl
Datenbankanfragen. Ferner lässt sich Cayenne mit beinahe jeder JDBC Datenbank
verwenden. Positiv ist auch die aktive Weiterentwicklung von Cayenne, aktuell wird an der
Version 3.0 gearbeitet.
7.3.3.2 Apache iBATIS
iBATIS [iBATIS] ist ein weiteres Daten-Mapping-Framework der Apache Software
Foundation12. Im Gegensatz zu Cayenne werden die Objekte mittels Gespeicherten
Prozeduren13 und SQL-Statements auf die Datenbank-Relationen abgebildet. Diese
Mappings werden ebenfalls in XML gespeichert und müssen vom Benutzer selber erstellt
werden, womit dieser über entsprechende XML- und SQL-Kenntnisse verfügen muss. Ein
Vorteil von iBATIS ist die schlanke und einfach zu verwendende Architektur. Ferner kann
der Daten-Mapper sehr gut auf jede Art von Applikationsdesign angepasst werden.
12 http://www.apache.org
13 Gespeicherte Prozedur (engl. stored procedure) bezeichnet eine Funktion in
Datenbankmanagementsystemen, in der ganze Befehls-Abläufe unter einem Namen gespeichert werden
können. Diese stehen dann auf dem Datenbankserver zur Verfügung und können dort aufgerufen und
ausgeführt werden. (Quelle: http://de.wikipedia.org/wiki/stored_procedure [Stand: 24.04.2007])
Diplomarbeit
78
7.3.3.3 Hibernate
Hibernate [Hibernate] ist ein sehr mächtiges Framework zur Speicherung von Objekten in
relationalen Datenbanken. Es werden dabei zahlreiche objektorientierte Konzepte
unterstützt wie Assoziationen, Vererbung, Polymorphismus, Kompositionen und
Kollektionen. Gleichzeitig können nach wie vor eigene Anfragen in der Hibernate Query
Language (HQL) oder auch in nativem SQL formuliert werden. Hibernate besteht schon
seit über 5 Jahren und wird von einer grossen und aktiven Gemeinschaft von Entwicklern
unterstützt und weiterentwickelt.
7.3.3.4 Vergleich
Die beiden Apache-Frameworks können im direkten Vergleich nicht mit Hibernate
mithalten. Cayenne ist zwar sehr einfach und ohne SQL-Kenntnisse anwendbar, Hibernate
dagegen bietet schlichtweg mehr Möglichkeiten und Freiheiten beim Abbilden von
Objekten auf Datenbanken. Durch die grosse Verbreitung von Hibernate finden sich im
Internet unzählige Support-Foren und Tutorials, die dessen Anwendung dokumentieren
und bei Problemen weiterhelfen. Ferner ist durch die grosse Entwickler-Gemeinde die
Weiterentwicklung und Unterstützung von Hibernate auf absehbare Zeit gesichert, was
angesichts der langen Einsatzzeit der Applikation nicht ganz unbedeutend ist.
7.3.4 Umgang mit der Vererbungshierarchie der Proze sse
Grundsätzlich wurde in der zu entwickelnden Anwendung versucht, für Datenbankzugriffe
das Hibernate-Framework zu verwenden. Dieses sieht vor, dass Java-Klassen über ein
entsprechendes Mapping auf die Datenbankrelationen abgebildet werden. Die Speicherung
kann anschliessend bequem über die von Hibernate zur Verfügung gestellte API
vorgenommen werden.
In einem speziellen Fall wurde aber von diesem Grundsatz bewusst abgewichen, und zwar
bei der Speicherung von Prozessen. Diese sind in der sesamDB in einer
Vererbungshierarchie angelegt. Dabei gibt es eine Wurzelrelation namens „Process“, der
alle anderen Prozess-Relationen untergeordnet sind. Das bedeutet, jede Prozess-Art erhält
eine eigene Relation. Diese ist entweder von „Process“ selber oder von einer anderen
Prozess-Relation abgeleitet. Die so angelegten Relationen erben einerseits sämtliche
Attribute der Eltern-Relation und können anderseits zusätzliche, eigene Attribute
definieren.
7. Implementierung
79
Um den eingangs erwähnten Grundsatz anzuwenden, müssten für jede Prozessart eine
eigene Java-Klasse erstellt werden, die wiederum über ein eigenes Mapping auf ihre
Relation abgebildet wird. Im Zusammenhang mit den gewählten Architektur-Ansätzen
würde das schliesslich bedeuten, dass für jede Prozess-Art ein eigener Validation- und
StoreHandler implementiert werden müsste. Diese würden sich nur in der Überprüfung
bzw. Speicherung der zusätzlichen Attribute unterscheiden. In [6a] Änderungsresistent
und [6b] Änderungsresistent wurden die Anforderungen gestellt, dass Änderungen sowohl
am logischen wie auch am physischen Datenbankmodell möglichst wenige Anpassungen
an der Applikation nach sich ziehen. Das Hinzufügen einer neuen Prozess-Klasse würde
diverse Modifikationen notwendig machen:
• Erstellen einer neuen Java-Prozess-Klasse.
• Erstellen eines entsprechenden Hibernate-Mappings.
• Implementierung eines neuen ValidationHandlers.
• Implementierung eines neuen StoreHandlers.
Aufgrund dieser zahlreichen Anpassungen, die für eine neue Prozessklasse benötigt
würden, wurde an dieser Stelle ein anderer Ansatz gewählt.
Dabei wird ähnlich vorgegangen wie bei den DataItems. Jeder Prozess ist über die classId
eindeutig einer Prozess-Klasse zugeordnet. Diese besitzt ein Attribut mit dem Namen der
Relation aus der oben erwähnten Vererbungshierarchie, in der die Prozesse dieser Klasse
gespeichert werden. Mittels speziellen SQL-Befehlen können in PostgreSQL
Informationen über eine Relation und deren Attribute abgefragt werden. Auf diese Weise
können für einen beliebigen Prozess abhängig von seiner Klasse die zusätzlich benötigten
Attribute sowie deren Datentyp bestimmt werden. Im Eingabemodell können dem Prozess-
Element bzw. –Objekt unter extrafields eine Liste von zusätzlichen Attributen definiert
werden. Dabei muss der Name des Attributs mit demjenigen in der Prozess-Relation
übereinstimmten.
Bei der Validierung wird nun überprüft, ob alle benötigten Attribute angegeben wurden,
und ob die Werte mit dem verlangten Datentyp kompatibel sind. Etwas umständlicher ist
die Speicherung. Hier muss für jede Prozess-Klasse ein entsprechendes SQL-Insert-
Statement definiert werden. Diese sind in einem Hibernate-XML-Dokument abgelegt.
Es ist an dieser Stelle nicht gelungen, einen vollständig generischen Ansatz zu
implementieren. Stattdessen konnte aber die Zahl der benötigten Eingriffe beim
Diplomarbeit
80
Hinzufügen einer neuen Prozess-Klasse auf ein Minimum reduziert werden. Konkret muss
lediglich in einem XML-Dokument der SQL-Insert-Befehl definiert werden. Da kein Java-
Code betroffen ist, entfällt auch das erneute Kompilieren der Anwendung.
7.3.5 Historisierung der Daten
Auf Ebene der Datenbank und transparent für die Applikation wurde in der sesamDB ein
Mechanismus zur Historisierung sämtlicher Daten erstellt. Die Gründe dafür sind die
folgenden: Durch die lange Laufzeit von Sesam ist zwingend damit zu rechnen, dass
Datenfehler entstehen und nachträglich korrigiert werden müssen. Dabei muss auch der
Fall berücksichtigt werden, dass korrekte Daten ungewollt verfälscht werden. Dies verlangt
nach einer Möglichkeit, sämtliche Änderungen am Datenbestand zurückverfolgen zu
können. Es sollte ersichtlich sein, zu welchem Zeitpunkt eine Modifikation vorgenommen
wurde und was der vorhergehende Stand war. Idealerweise sollte auch die verantwortliche
Person bekannt sein, um allfällige Rückfragen stellen zu können.
Änderungen von bestehenden Daten werden meist nur zur Korrektur von fehlerhaften
Informationen notwendig sein und nicht auf einer regelmässigen, alltäglichen Basis
stattfinden. Einmal erfasste Messdaten bleiben in der Regel unverändert. Was sich ändern
kann sind beispielsweise die Beschreibung eines Experimentes oder die Job-Rolle eines
Mitarbeiters. Insgesamt betrachtet ist die Menge von Mutationen eher gering bis
vernachlässigbar.
Wie bereits erwähnt wurde die Historisierung in der sesamDB auf Stufe der Datenbank
mithilfe von so genannten Trigger-Funktionen umgesetzt. Für jede Relation wird eine
zweite Relation angelegt, die zur Historisierung dient. Das heisst, jedes Tupel, das geändert
oder gelöscht wird, wird in diese zweite Archivierungsrelation verschoben und nur das
aktuell gültige Tupel in der Hauptrelation gehalten. Jedes Tupel erhält zudem zwei
zusätzliche Attribute, die jeweils einen Zeitstempel beinhalten. Der erste Zeitstempel gibt
an, ab wann ein Tupel gültig war (beispielsweise der Zeitpunkt der Erstellung oder der
Änderung). Der zweite Zeitstempel hingegen hält den Zeitpunkt fest, bis zu dem ein Tupel
gültig war (dies kann das Datum sein, an dem es beispielsweise geändert oder gelöscht
wurde).
Mit diesem Ansatz kann jede Änderung sowohl zeitlich als auch inhaltlich nachvollzogen
und rekonstruiert werden. Durch die Umsetzung mittels Trigger-Funktionen wird
gewährleistet, dass dies für Applikationen möglichst transparent geschieht und nicht
7. Implementierung
81
versehentlich Tupel gelöscht oder geändert werden, ohne einen Historisierungseintrag zu
erzeugen. Aufgrund der sehr geringen Zahl von Änderungen ist der zusätzliche Overhead
und Speicherbedarf angesichts der dadurch gewonnenen Sicherheit und Datenqualität
durchaus gerechtfertigt.
7.4 Zusammenfassung
Die gesamte Applikation ist sowohl in der Architektur als auch in der Implementierung
vollständig darauf ausgerichtet, dass voraussehbare oder bereits geplante Veränderungen
mit einem Minimum an Programmieraufwand vorgenommen werden können. Das bedeutet
einerseits, die antizipierbaren Änderungspunkte sollten so angelegt sein, dass für
Anpassungen möglichst nur ein geringes Verständnis der Architektur benötigt wird bzw.
die Architektur an diesen Punkten leicht zu verstehen ist. Anderseits sollte der neu zu
schreibende bzw. anzupassende Code auf ein Minimum beschränkt werden. Hierbei
handelt es sich grundsätzlich um einen Zielkonflikt. Denn je flexibler die Applikation sein
soll, umso generischer und deshalb komplexer wird die Architektur. Hier galt es, ein
gesundes Mittelmass zu finden. Durch den Einsatz von Handler-Klassen sowohl in der
Validierung wie auch in der Speicherung sind Änderungen im Normalfall auf zwei Klassen
beschränkt (einen ValidationHandler und eine StoreHandler). Ausserdem ist das
Funktionsprinzip in der Validierung und der Speicherung zu grossen Teilen gleich oder
zumindest sehr ähnlich. In beiden Komponenten wird je ein Handler einem Objekt des
Eingabemodells zugeordnet und werden diese Handler in einer Art Rekursion ausführt. Die
Handler können je nach Bedarf sehr einfach oder sehr komplex ausfallen. Die Architektur
setzt kaum irgendwelche Einschränkungen. Dies sei nachfolgend am Beispiel der
DataItemHandler in der Speicher-Komponente gezeigt.
Im einfachsten Fall besteht ein DataItem aus ein paar wenigen Attributen, beispielsweise
aus einem Barcode, der eine bestimmte Blutprobe identifiziert. Hierbei fällt der
DataItemHandler sehr einfach aus und umfasst nur wenige Zeilen Code, in denen ein neues
DataItem-Tupel in der sesamDB angelegt und darin der Barcode gespeichert wird.
In einem anderen Fall handelt es sich bei dem DataItem um die Antworten aus einem
Fragebogen. Diese Antworten sind in einem externen XML-Dokument gespeichert. Dabei
hat der DataItemHandler die Aufgabe, das XML-Dokument einzulesen, gegen ein XML
Schema zu validieren und anschliessend die Daten auf die entsprechenden Relationen in
der sesamDB abzubilden. In dem Fall fällt der Handler wesentlich komplexer aus als in
Diplomarbeit
82
vorangegangenen Beispiel. Hier steht grundsätzlich frei, ob die Funktionalität direkt in die
Handler-Klasse eingebaut wird oder ob diese in mehrere Klassen aufgeteilt wird.
Ausserdem wäre es denkbar, dass sich der DataItemHandler einer weiteren Applikation
oder einer externen Komponente bedient.
Diese Beispiele sollen aufzeigen, dass die gewählte Architektur äusserst flexibel
erweiterbar ist und grundsätzlich jede Art von Datenobjekten eingebunden werden kann,
wie dies von den Anforderungen [5] Neue Datenobjekte, [6a] Änderungsresistent und [6b]
Änderungsresistent gefordert wird. Dabei müssen lediglich ein entsprechender Validation-
und StoreHandler implementiert werden. Die übrigen Teile der Applikation bzw. des
Frameworks bleiben unangetastet.
8. Testen
83
8 Testen
Die zu entwickelnde Applikation hat im Datenerhebungsprozess von Sesam eine zentrale
Rolle: sämtliche Metadaten sowie ein Grossteil der Resultate von Untersuchungen und
Messungen werden von dieser Anwendung verarbeitet und in der sesamDB gespeichert.
Das bedeutet, es muss sichergestellt werden, dass die Verarbeitungsvorgänge zuverlässig
und voll funktionstüchtig sind und keine fehlerhaften oder unerwünschten Veränderungen
an den Daten vornehmen. Bleiben solche fehlerhafte Modifikationen unentdeckt, können
sie Auswertungen und Forschungen verfälschen. Eine Massnahme zur Sicherstellung der
Qualität dieser Applikation ist der Aufbau einer gut ausgebauten Testbasis. Insbesondere
Komponenten und Klassen, die ein Datenobjekt verändern oder in eine andere Form
überführen, müssen intensiv getestet werden, da Fehler an diesen Stellen direkte
Auswirkungen auf die Gültigkeit der Daten haben. Dazu gehören namentlich die
Komponenten Eingabeverarbeitung (Überführung der Eingabedaten in Java-Objekte bzw.
in das InputModel) und Speicherung (Überführung der Java-Objekte bzw. des InputModels
in relationale Tupel in der Datenbank).
Als Test-Framework kam JUnit14 zum Einsatz, das nachfolgend kurz eingeführt wird.
Anschliessend wird der Aufbau der Tests und die Test-Strategie erläutert.
8.1 JUnit
JUnit ist ein Testframework zum automatisierten Testen von beliebigen Code-Einheiten
(engl. units), was in der Regel Klassen oder Methoden sind. Ein Unit-Test kennt zwei
Ergebnisse: entweder der Test war erfolgreich oder er schlug fehl. Die Gründe für einen
Fehler können ein falsches Resultat oder eine unerwartete Exception sein. JUnit-Tests
lassen sich auf Knopfdruck automatisch ausführen und beliebig wiederholen. Die Tests
sollen insbesondere sicherstellen, dass durch Änderungen am Code keine neuen Fehler
eingebaut werden. Dabei soll der Entwickler vor dem Verändern von Programmteilen die
Unit-Tests ausführen um sich zu vergewissern, dass der Code vor seinen Änderungen
fehlerfrei ist. Nachdem er seine Modifikationen durchgeführt hat, ruft er die Tests erneut
14 http://www.junit.org [Stand: 23.04.2007]
Diplomarbeit
84
auf. Misslingen diese, so weiss der Entwickler, dass er selbst einen Fehler verursacht hat.
Dabei wird ihm vom JUnit-Framework angezeigt, welche konkreten Tests fehlerhaft
waren. Dies hilft ihm bei der Lokalisierung der Fehlerquelle. Nachdem er die
entsprechende Stelle korrigiert hat, ruft er die Tests nochmals auf, um die Korrektur zu
verifizieren. Dieser Prozess wird so oft wiederholt, bis alle Tests wieder erfolgreich sind.
8.2 Test-Aufbau
Die modulare Architektur der entwickelten Applikation macht sich auch für den Aufbau
von Tests bezahlt. Dadurch, dass die jeweiligen Komponenten einzeln und isoliert
ausgeführt werden können, lassen sich diese auch unabhängig vom Rest der Anwendung
testen. Insbesondere die Validation- und StoreHandler können jeder für sich getestet
werden.
Dabei wurden die Tests so aufgebaut, dass zuerst die Handler derjenigen Objekte
implementiert werden, welche die Blätter im InputModel darstellen, das heisst, die keine
weiteren Kindobjekte enthalten. Von diesen ausgehend werden anschliessend die Tests der
Eltern-Objekte geschrieben. Dabei ist zu beachten, dass die Handler solcher Eltern-Objekte
jeweils die Handler der Kindobjekte aufrufen. Um die erzeugten Fehlermeldungen
aufzufangen und zu überprüfen, wird bei den Handlern jeweils ein spezieller Test-Listener
registriert. Dabei können Fehler, die von den Handlern der Kindobjekte erstellt wurden,
ignoriert werden, wenn diese für das jeweilige Test-Objekt keine Relevanz haben.
Um eine Kontroll-Klasse, wie zum Beispiel die Validierung, komplett zu testen, wird ein
vollständiges Eingabemodell mit Testobjekten benötigt. Um letztere zu erzeugen, wird das
ObjectMother-Pattern [SP01] verwendet. Dieses beschreibt den Einsatz eines Mutter-
Objekts, das für die Erzeugung, Veränderung und das Löschen von Testobjekten zuständig
ist. Dadurch wird die Erstellung von Test-Objekten vereinfacht und standardisiert. Indem
nur eine Klasse oder eine klar definierte Gruppe von Klassen bei Änderungen angepasst
werden muss, wird der Wartungsaufwand deutlich verringert. Ferner sorgt das Mutter-
Objekt nach dem Testen für das automatische Löschen der Testdaten.
Insbesondere bei der Validierung, aber auch für die Speicherung, wird in der sesamDB ein
Metamodell benötigt, das mit den Testdaten übereinstimmt und gegen das validiert werden
kann bzw. aus dem Metadaten abgerufen werden können. Die Elemente in der
Eingabedatei referenzieren die Objekte aus dem Metamodell ausschliesslich über deren ID-
Werte. Diese ID-Attribute werden beim Einfügen der Tupel aus einer Sequenz-Funktion
8. Testen
85
der Datenbank erzeugt. Deren Resultat ist davon abhängig, wie viele Tupel vorher bereits
eingefügt wurden. Um zu gewährleisten, dass die ID-Werte der Metaobjekte in der
Datenbank mit denjenigen in der Eingabedatei oder den Testobjekten übereinstimmen,
bieten sich zwei Ansätze an:
• Erstens, die Metaobjekte werden zuerst in die Datenbank eingefügt und
anschliessend wird die Eingabedatei bzw. die Testobjekte anhand der generierten
ID-Werte erstellt.
• Zweitens, es wird eine separate Test-Datenbank verwendet, so dass die
Metaobjekte kontrolliert eingefügt werden können und damit sichergestellt ist, dass
diese immer dieselben ID-Werte erhalten.
Während der erste Ansatz mehr Stabilität bei Veränderungen gewährleistet, ist er ungleich
aufwändiger zu implementieren als der zweite. Angesichts dessen, dass Tests immer in
einer separaten Datenbank stattfinden sollten, fiel die Wahl auf die zweite Variante. Mittels
eines SQL-Skripts lässt sich einfach eine separate Testdatenbank mit allen Relationen und
Testdaten erstellen, auf der dann die Tests ausgeführt werden.
8.3 Zusammenfassung
In diesem Kapitel wurde die Bedeutung der Tests für die zu entwickelnde Applikation
erklärt. Nach einer kurzen Einführung zum eingesetzten Test-Framework JUnit, wurde der
verwendete Aufbau der Tests erläutert. Ausserdem wurden die zwei verwendeten Ansätze
zur Erzeugung von Testdaten beschrieben.
Diplomarbeit
86
9 Zusammenfassung
Das Resultat der vorliegenden Arbeit ist eine Architektur, bestehend aus vier
Kernprozessen, die sich zu einem Workflow zusammensetzen lassen, der zum Import von
Daten in die sesamDB dient. Diese vier Prozess-Komponenten sind weitestgehend
unabhängig vom konkreten Datenmodell. Mit dem entsprechenden InputPlugin kann
grundsätzlich jede Art von Datenquelle angesprochen werden. Eingeschränkt wird diese
Eigenschaft lediglich durch die aktuelle Implementierung der Benutzeroberfläche, die nur
zur Auswahl von Dateien ausgelegt ist. Die eigentliche Programmlogik zur Validierung
und Speicherung ist in so genannte Handler-Klassen ausgelagert, wobei jedem Objekt des
Eingabemodells jeweils ein Validation- und ein StoreHandler zugewiesen sind. Damit ist
die Verantwortlichkeit eines solchen Handlers klar geregelt, was die Lokalisation von
Änderungspunkten erleichtert.
Während der Entwicklung der Applikation hat sich gezeigt, dass die Umsetzung von neuen
Anforderungen bezüglich dem Datenmodell ohne grossen Aufwand möglich ist.
Beispielsweise waren zu Beginn der Implementierung nur Experimente als Wurzelelement
des Eingabemodells vorgesehen. Nachträglich enstand die Forderung, dass auch Prozesse
als Wurzelelemente möglich sein sollen. Mittels wenigen Anpassungen am InputPlugin
und dem Prozess-ValidationHandler konnte dieser Anspruch erfüllt werden, ohne dass
Änderungen an der Architektur notwendig waren.
Das entwickelte Framework berücksichtigt bei der Speicherung von Daten in der sesamDB
das ACID-Prinzip und garantiert damit unter anderem die Wahrung der Daten-Konsistenz.
Abschliessend seien nachfolgend die weiteren Eigenschaften der Applikation aufgeführt:
• Änderungen am logischen Metamodell, die keine Modifikationen von
Datenbankrelationen nach sich ziehen, sind jederzeit möglich. Dazu gehören
beispielsweise das Hinzufügen neuer Experiment- und Prozess-Klassen.
• Um eine neue Prozess-Art zu unterstützen, die eine neue Datenbank-Relation
verwenden, muss nur ein entsprechendes SQL-Insert-Statement in einer XML-
Datei erstellt werden.
• Import-Einheiten (beispielsweise ein Experiment) werden vor der Validierung
automatisch historisiert und können jederzeit erneut validiert werden. Damit kann
9. Zusammenfassung
87
eine fehlgeschlagene Validierung zu einem späteren Zeitpunkt wiederholt werden
(beispielsweise wenn die dazugehörigen Datenobjekte erst später verfügbar sind).
• Mittels der Historisierung wird sichergestellt, dass eine Import-Einheit jeweils nur
einmal gespeichert werden kann, um Duplikate zu vermeiden.
• Zusätzliche InputPlugins zur Unterstützung alternativer Dateiformate können
jederzeit hinzugefügt werden, ohne dass die Anwendung neu kompiliert oder
installiert werden muss. Es genügt, die kompilierte Class-Datei des InputPlugins zu
verteilen und die Konfigurationsdatei anzupassen.
• Die Applikation kann ohne Änderungen an der Architektur so erweitert werden,
dass beliebige Datenobjekte (DataItems) unterstützt werden können. Je nach Bedarf
kann der DataItemHandler sehr einfach ausfallen (beispielsweise Validierung und
Speicherung weniger, atomarer Werte) oder aber komplexe
Verarbeitungsfunktionen übernehmen (beispielsweise Einlesen und Validieren
einer kompletten XML-Datei und Abbilden der darin enthaltenen Entitäten auf die
entsprechenden Relationen in der Datenbank).
• Die Benutzeroberfläche ist grundsätzlich mehrsprachenfähig. Weitere Sprachen
können einfach über eine zusätzliche Sprachkonfiguration eingebunden werden.
Verbesserungsmöglichkeiten ergeben sich vor allem im Bereich der Benutzeroberfläche.
Wie weiter oben bereits erwähnt, wird die Möglichkeit zur Unterstützung alternativer
Eingabequellen einerseits durch das GUI und anderseits durch die Art und Weise, wie die
InputPlugins der Eingabequellen zugeordnet werden, beschränkt. Diese Einschränkung
betrifft zwar nicht direkt die an diese Anwendung gestellten Anforderungen, engt aber die
Ausbaufähigkeit in diesem Bereich ein.
Abschliessend lässt sich festhalten, dass mit dieser Arbeit eine Applikation entwickelt
werden konnte, die in der Lage ist, heterogene Daten zu verarbeiten. Dank dem modularen
Aufbau kann der Funktionsumfang sowie die Zahl der unterstützten Datenobjekte ohne
grossen Aufwand flexibel erweitert werden. Damit ist es gelungen, dem Sesam-Projekt ein
Werkzeug zur Verfügung zu stellen, mit dem die Messdaten und deren Metainformationen
sowohl validiert wie auch archiviert werden können.
Diplomarbeit
88
10 Weiterführende Arbeiten
Mit der vorliegenden Arbeit wurde ein Framework entwickelt, das sich weiter ausbauen
lässt und auch ausgebaut wird, um neuen Anforderungen des Sesam-Projekts gerecht zu
werden. In diesem Kapitel sollen die Ansätze und Möglichkeiten für weiterführende
Arbeiten aufgezeigt werden.
10.1 DataItemHandler
Als erstes muss die Applikation um weitere DataItemHandler erweitert werden, um
zusätzliche Datenobjekte zu unterstützen. Zum Zeitpunkt der Fertigstellung dieser Arbeit
war erst eine DataItem-Art vollständig definiert. Immerhin konnte damit zumindest eine
Referenz-Implementierung eines DataItemHandlers vorgenommen werden.
10.2 Testdaten
Ein Schwachpunkt der vorliegenden Anwendung ist die geringe Basis an Testdaten, die
während der Entwicklung verwendet wurde. Der Grund dafür ist der hohe Aufwand, der
nötig ist, um ein Metamodell manuell aufzubauen, gegen das Eingabedaten validiert
werden können. Dies birgt die Gefahr, dass spezielle Daten-Konstellationen nicht getestet
wurden und möglicherweise nicht wie gewünscht validiert bzw. gespeichert werden. Aus
diesem Grund sollten zusätzliche Testdaten erzeugt werden, um eine grössere Vielfalt an
Testfällen zu ermöglichen. Um die Generierung solcher Daten zu vereinfachen, wäre eine
Anwendung wünschenswert, mit der sich einfach und schnell neue Metamodelle erstellen
oder generieren lassen.
10.3 Benutzertests
Mithilfe zusätzlicher Testdaten können neben zusätzlichen automatischen Tests auch
ausführliche Benutzertests geplant und durchgeführt werden. Mit diesen sollen die
verschiedenen Einsatzszenarien in realen Umgebungen durchgespielt werden. Der Fokus
wird dabei sicherlich in der Verbesserung der Bedienung und der grafischen
Benutzeroberfläche liegen. Dies führt gleich zum nächsten Punkt.
10. Weiterführende Arbeiten
89
10.4 Verbesserung der grafischen Benutzeroberfläche
Der Schwerpunkt der vorliegenden Arbeit lag primär in der Entwicklung eines
Frameworks für den Datenimport. Die Benutzeroberfläche ist deshalb relativ einfach
gehalten, verfügt aber über alle notwendigen Elemente, um den Import zu steuern und
allfällige Fehler zu analysieren. Folgende Verbesserungen sind denkbar und
wünschenswert:
• Ausführliche, aus dem Programm aufrufbare Hilfe-Datei, wenn möglich in Deutsch
und Englisch.
• Selbsterklärende Tooltipps für Buttons und Textfelder.
• Verdeutlichung von Informationstexten, Status- und Fehlerangaben mit grafischen
Icons.
• Dynamische Eingabemaske zur Angabe von Datenquellen, die abhängig vom
gewählten InputPlugin angezeigt wird. Damit kann die Möglichkeit geschaffen
werden, ausser Dateien noch andere Eingabequellen zu unterstützen (beispielsweise
Datenbanken).
10.5 Updatemöglichkeiten
Die Anwendung wird während ihrer Einsatzzeit mehrfach geändert. Abhängig von der
Häufigkeit kann es sich lohnen, entsprechende Mechanismen zu implementieren, die ein
einfaches Update der Applikation ermöglichen. Denkbar wäre eine Möglichkeit, bei der
sich das Programm zu einem zentralen Server verbindet um dort selbstständig nach neuen
Versionen zu suchen und diese gegebenenfalls automatisch installiert. Idealerweise sollte
solch ein Update-Mechanismus für sämtliche Sesam-Applikationen verwendbar sein.
10.6 Zusätzliche InputPlugins
Es ist auf absehbare Zeit eher unwahrscheinlich, dass XML nicht mehr als Eingabeformat
verwendet werden kann. Wahrscheinlicher ist aber der Fall, dass das entwickelte XML
Schema (XSD) nicht mehr den Bedürfnissen gerecht wird oder mit dem Metamodell nicht
mehr konform ist. Denkbar wäre beispielsweise, dass neben Experimenten und Prozessen
noch andere Objekte als Wurzelelemente gewünscht sind. Hier könnte es sich lohnen, statt
das bestehende InputPlugin ständig auszubauen und zu vergrössern, die neuen
Diplomarbeit
90
Anforderungen in einem eigenen Plugin umzusetzen. Dies hat zwei Vorteile: Erstens, die
jeweiligen Plugin-Klassen bleiben übersichtlich und sind so leichter zu testen. Zweitens,
auf diese Weise können InputPlugins, deren Funktionalität nicht mehr benötigt wird,
einfach entfernt werden, ohne dass Code angepasst werden muss.
11. Literaturverzeichnis
91
11 Literaturverzeichnis
[Ambler06] Ambler, Scott W.: Mapping Objects to Relational Databases: O/R Mapping
In Detail, http://www.agiledata.org/essays/mappingObjects.html [Stand:
24.04.2007], 2006.
[BKTT04] Buneman, Peter; Khanna, Sanjeev; Tajima, Keishi; Tan, Wang-Chiew:
Archiving Scientific Data, ACM Transactions on Database Systems, Volume
29, Nr. 1, S. 2-42, 2004.
[Castor] Castor: The Castor Project, http://www.castor.org/ [Stand: 20.04.2007].
[Cayenne] Apache Cayenne: Object Relational Mapping, Persistence and Caching for
Java, http://cayenne.apache.org/ [Stand: 24.04.2007].
[db4o] db4objects: Opensource Objektdatenbank, http://www.db4o.com/ [Stand:
24.04.2007].
[DBNotes] DBNotes: Database Annotation Management System,
http://www.cs.ucsc.edu/~laura/dbnotes/ [Stand: 19.04.2007].
[FRR00] Fischer, Stephan; Rensing, Christoph; Rödig, Utz: Open Internet Security:
von den Grundlagen zu den Anwendungen, Springer, 2000.
[Gamma04] Gamma, Erich [et al.]: Entwurfsmuster: Elemente wiederverwendbarer
objektorientierter Software, Addison-Wesley, München, 2004.
[Glinz01] Glinz, Martin: Software Engineering I, Vorlesungsskript, Zürich, 2001.
[Hibernate] Hibernate: Relational Persistence for Java and .NET,
http://www.hibernate.org/ [Stand: 24.04.2007].
[iBATIS] Apache iBATIS: Data Mapper Framework, http://ibatis.apache.org/ [Stand:
24.04.2007].
[JAXB] JAXB Reference Implementation Project, https://jaxb.dev.java.net/ [Stand:
15.04.2007].
[Kawa03] Kawaguchi, Kohsuke: The JAXB API, Article, XML.com,
http://www.xml.com/pub/a/2003/01/08/jaxb-api.html [Stand: 15.04.2007],
2003.
Diplomarbeit
92
[LN07] Leser, Ulf; Naumann, Felix: Informationsintegration, dpunkt.verlag GmbH,
Heidelberg, 2007.
[Mašek07] Mašek, Andrea: Entscheid: „Sesam“ darf sich öffnen, Artikel in: Aargauer
Zeitung, Nr. 66 vom 20.03.2007, S. 5.
[OM03] Ort, Ed; Mehta, Bhakti: Java Architecture for XML Binding (JAXB), Article,
Sun Developer Network (SDN),
http://java.sun.com/developer/technicalArticles/WebServices/jaxb/ [Stand:
15.04.2007], 2003.
[PASOA] PASOA: Provenance Aware Service Oriented Architecture,
http://www.pasoa.org [Stand: 19.04.2007].
[Sesam] Sesam: Swiss Etiological Study of Adjustment And Mental Health,
Nationaler Forschungsschwerpunkt, http://www.sesamswiss.ch [Stand:
15.04.2007].
[Shah04] Shah, Hetal C.: XML-Java Data Binding Using XMLBeans, Article,
ONJava.com,
http://www.onjava.com/pub/a/onjava/2004/07/28/XMLBeans.html [Stand:
15.04.2007], 2004.
[Sieber07] Sieber, David: Sesam-Studie: „Wir wollen Gutes tun“, Artikel in: Aargauer
Zeitung, Nr. 71 vom 26.03.2007, S. 4.
[SP01] Schuh, Peter; Punke, Stephanie: ObjectMother – Easing Test Object Creation
in XP, XP Universe Conference, 2001.
[SPG05] Simmhan, Yogesh L.; Plale, Beth; Gannon, Dennis: A Survey of Data
Provenance Techniques, Technical Report 612, Computer Science
Department, Indiana University, 2005.
[SWT] SWT: The Standard Widget Toolkit, http://www.eclipse.org/swt/ [Stand:
20.04.2007].
[Tan04] Tan, Wang-Chiew: Research Problems in Data Provenance, IEEE Data
Engineering Bulletin, Volume 27, Nr. 4, S. 45-52, 2004.
[XML] Extensible Markup Language (XML) 1.1, W3C Recommendation,
http://www.w3.org/TR/xml11 [Stand: 19.04.2007].
11. Literaturverzeichnis
93
[XMLSchema] W3C Recommendation: “XML Schema Part 0: Primer Second Edition”,
http://www.w3.org/TR/xmlschema-0/ [Stand: 15.04.2007].
[XMLBeans] The Apache XML Project: “Welcome to XMLBeans”,
http://xmlbeans.apache.org/ [Stand: 15.04.2007].
[XMLBeans/overview] The Apache XML Project: “XMLBeans Overview”,
http://xmlbeans.apache.org/overview.html [Stand: 15.04.2007].
Diplomarbeit
94
12 Abbildungsverzeichnis
Abbildung 1: Einfache Klassenhierarchie........................................................................... 17
Abbildung 2: Mapping auf eine einzelne Tabelle ............................................................... 18
Abbildung 3: Mapping konkreter Klassen auf eigene Tabellen.......................................... 18
Abbildung 4: Mapping jeder Klasse auf eigene Tabelle ..................................................... 19
Abbildung 5: Generisches Datenschema zur Objekt-Speicherung (Quelle: [Ambler06]) .. 20
Abbildung 6: One-to-one Beziehung .................................................................................. 21
Abbildung 7: One-to-many Beziehung ............................................................................... 21
Abbildung 8: Many-to-many Beziehung............................................................................. 21
Abbildung 9: Beispiel einer many-to-many Verbindungsrelation ...................................... 22
Abbildung 10: Der Speicherungsprozess der Erhebungsdaten ........................................... 25
Abbildung 11: Darstellung der Objekt-Beziehungen im Datenmodell ............................... 27
Abbildung 12: Beispiel-Experiment "Bestimmung der Blutgruppe".................................. 28
Abbildung 13: UML Use Case Diagramm.......................................................................... 28
Abbildung 14: Stark vereinfachter und reduzierter Ausschnitt aus dem ERM-Schema
„Experiments, Processes and Measurements“ ............................................................ 36
Abbildung 15: Architekturübersicht.................................................................................... 39
Abbildung 16: Importierungsprozess.................................................................................. 40
Abbildung 17: Einsatzumgebung........................................................................................ 48
Abbildung 18: Klassendiagramm des Eingabemodells (InputModel) ................................ 52
Abbildung 19: Klassendiagramm des Meta-Modells (MetaModel) ................................... 54
Abbildung 20: Schematische Darstellung des Eingabeverarbeitungsprozesses ................. 58
Abbildung 21: Historisierungsprozess ................................................................................ 61
Abbildung 22: Schematische Darstellung der Architektur von JAXB (Quelle: [OM03]).. 63
Abbildung 23: Ablaufschema der Validierung ................................................................... 67
12. Abbildungsverzeichnis
95
Abbildung 24: PropertyMap als gemeinsamer Zwischenspeicher ...................................... 68
Abbildung 25: Validation-Observer-Pattern ....................................................................... 69
Diplomarbeit
96
13 Anhang
13. Anhang
97
13.1 XML Import-Schema I (Experiment)
Diplomarbeit
98
13.2 XML Import Schema II (Prozess)