Technische Universität Ilmenau Fakultät für Informatik und Automatisierung Institut für Praktische Informatik und Medieninformatik Datenbanken und Informationssysteme Studienjahresarbeit Verarbeitung und Speicherung von XML Daten in Multiuser Client-Server Anwendungen Thomas Bärwinkel August 2006 - Februar 2007 Betreuer: Prof. Dr.-Ing. habil. Kai-Uwe Sattler Dipl.-Inf. Katja Hose Dipl.-Ing. Katrin Reichelt Inhaltsverzeichnis 1 Einleitung 1.1 Motivation . . . . 1.2 Bisheriger Stand 1.3 Ziel . . . . . . . . 1.4 Ausblick . . . . . . . . . 1 1 1 2 2 2 IOSONO 2.1 Grundlagen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2 Wellenfeldsynthese . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.3 Architektur von IOSONO . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 3 4 5 . . . . . . . . . . . . . . . . . . . . 3 Anwendungszenarien 3.1 Single-User-Betrieb . . . . 3.2 Multi-User-Betrieb . . . . 3.2.1 Workgroup-Betrieb 3.2.2 Workspace-Betrieb . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 Implementierung 4.1 MuXp Framework . . . . . . . . . . . . . . . . . . . 4.1.1 Utility Paket . . . . . . . . . . . . . . . . . 4.1.2 Ausnahmebehandlung (Exception Handling) 4.1.3 Server Paket . . . . . . . . . . . . . . . . . . 4.1.4 Workspace (Client) Paket . . . . . . . . . . 4.2 Spamix als Testapplikation . . . . . . . . . . . . . . 4.3 MuXp Tools . . . . . . . . . . . . . . . . . . . . . . 4.3.1 MuXpClient Kommandozeilen Applikation . 4.3.2 MuXpMonitor Tool . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 8 11 13 14 . . . . . . . . . 17 18 19 25 26 30 33 35 35 37 5 Grundlegende XML Technologien 39 5.1 Speicherung von XML Daten . . . . . . . . . . . . . . . . . . . . . . . . . 39 5.1.1 XML Datenbank . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 5.2 Übertragung von XML Daten . . . . . . . . . . . . . . . . . . . . . . . . . 42 5.2.1 Analyse verschiedener Technologien für die Netzwerkkommunikation 42 5.2.2 Vergleich der Technologien . . . . . . . . . . . . . . . . . . . . . . . 43 5.2.3 Detallierte Beschreibung der Internet Communications Engine (ICE) 44 5.3 Verarbeitung von XML Daten . . . . . . . . . . . . . . . . . . . . . . . . . 47 ii Inhaltsverzeichnis 5.3.1 5.3.2 XML Grundlagen . . . . . . . . . . . . . . . . . . . . . . . . . . . . Adressierung und Manipulation von XML Dokumenten . . . . . . . 47 48 6 Fazit und Ausblick 50 Literaturverzeichnis 52 Abkürzungsverzeichnis 54 Quellcodeverzeichnis 56 Tabellenverzeichnis 57 Abbildungsverzeichnis 58 Seite iii 1 Einleitung 1.1 Motivation Das Fraunhofer Institut für Digitale Medientechnologie IDMT in Ilmenau hat ein neues Soundsystem namens IOSONO entwickelt. Mit Hilfe der Wellenfeldsynthese besteht, im Gegensatz zu herkömmlichen kanalbasierten Audiotechnologien, die Möglichkeit einen kompletten Kinosaal mit optimalem Raumklang zu füllen. Dazu werden die Klangeigenschaften, wie beispielsweise Lautstärke, Zeit oder Ort, als Objekte definiert und in Form von Metadaten in einer XML Struktur gespeichert. Die XML Dokumente werden als Textdatei lokal auf dem Dateisystem abgelegt. Diese Art der Speicherung hat den Nachteil, dass man auf essentielle Features wie Versionierung, Suche und XML Anfragesprachen wie XPath und XQuery verzichten muss. Das Erstellen der Metadaten ist ein aufwendiger Arbeitsprozess und kann für große Projekte nicht von einer Person allein bewältigt werden. Aus diesem Grund ist es notwendig, dass mehrere Autoren gleichzeitig auf einer gemeinsamen, zentralen Datenbasis arbeiten. 1.2 Bisheriger Stand In der aktuellen Version speichert IOSONO die Metadaten in einer XML Struktur als Textdatei lokal auf dem Dateisystem. In der Diplomarbeit von Hendrik Rusch[23] wurde die Eignung einer XML Datenbank zur Datenverwaltung untersucht und implementiert. Für die komfortable und effektive Verwaltung der XML Daten wurden ein Versionierungssystem und Suchfunktionen entwickelt und in das IOSONO System integriert. Dadurch wurde eine Einzelplatzversion mit erweiterter Speicher- und Verwaltungsfunktionalität geschaffen. Nachteilig ist die lokale Speicherung der XML Dokumente, wodurch Autoren nicht die Möglichkeit haben, kooperativ an Audioszenen zu arbeiten oder auf Audioobjekte von Kollegen zuzugreifen. 1 1 Einleitung 1.3 Ziel In der Produktion von Kinofilmen spielt die Zeit eine sehr wichtige Rolle. Aus diesem Grund ist es unumgänglich, dass mehrere Autoren gleichzeitig an Audioszenen arbeiten. Das Ziel dieser Arbeit ist es, ein Framework zu entwickeln, was die Möglichkeit bietet XML Daten zentral zu speichern und zu verwalten. Das hat den Vorteil, dass mehrere Anwendungen kooperativ XML Dokumente auf einer zentralen Datenbasis lesen, schreiben und löschen können. Die Autoren sind nun in der Lage parallel Audiomaterial zu erstellen, was die Produktionszeit eines Kinofilmes erheblich reduziert. Dazu sollen geeignete Grundstrukturen und Schnittstellen für die Speicherung, Verwaltung und Übertragung der XML Daten analysiert und implementiert werden. Um die Machbarkeit unter realen Bedingungen zu testen und aufzuzeigen, wird das Framework in das IOSONO Autorenwerkzeug Spamix integriert. 1.4 Ausblick Das entwickelte Framework stellt zunächst nur eine Grundstruktur mit Schnittstellen und primitiver Funktionalität zur Verfügung und soll in zukünftigen Arbeiten durch Integration von Sperrververfahren, Versionierung und Änderungspropagierung sukzessive erweitert werden. Seite 2 2 IOSONO 2.1 Grundlagen Bei konventionellen Soundsystemen wird der Klang auf verschiedene Kanäle aufgeteilt. Bei Mono wird ein Kanal genutzt, bei Stereo 2 Kanäle und bei einem 5.1 System 6 Kanäle. Um eine Bewegung der Klangquelle zu simulieren, springt das Signal von einem Kanal zum anderen. Mit dieser Technik können sehr gute Ergebnisse erzielt werden. Jedoch konzentriert sich der Bereich für die optimale räumliche Audiowiedergabe nur in einer bestimmten Region, dem so genannten Sweetspot1 . Durch die Hinzunahme von weiteren Kanälen kann man den Sweetspot zwar vergrössern, aber für die räumliche Beschallung eines Theaters oder Kinos ist diese Vorgehensweise sehr aufwendig und kostspielig. Das IOSONO Soundsytem[13] hingegen verfolgt einen anderen Ansatz, welcher die Eigenschaften der Wellenfeldsynthese nutzt. Mit der Wellenfeldsynthese besteht die Möglichkeit, eine räumliche Audiowiedergabe im gesamten Raum zu erreichen. Um diese Effekte realisieren zu können, wird eine Vielzahl von Lautsprecherpanels, abhängig von der jeweiligen Raumgröße, rund um die zu beschallende Fläche installiert. Ein Lautsprecherpanel besteht aus jeweils acht Zweiwegelautsprechern sowie einem integrierten Leistungsverstärker. Bei herkömmlichen kanalbasierten Systemen wird für jeden Kanal das Audiomaterial vorher abgemischt und gespeichert. IOSONO hingegen verfolgt einen objektorientierten Ansatz, bei dem erst zur Wiedergabe das Audiomaterial in Echtzeit für jeden einzelnen Lautsprecher gerendert wird. Dadurch können Klangobjekte frei innerhalb und außerhalb des Raumes platziert werden. Darüber hinaus können die Audioobjekte mit beliebiger Geschwindigkeit frei im Raum bewegt werden. Ein einfaches Beispiel aus der praktischen Anwendung könnte sein, dass uns während eines Beatles-Songs John Lennon singend durch den Raum folgt, während Paul McCartney an der Bassgitarre genau in diesem Moment von links nach rechts auf der imaginären Bühne läuft. Die IOSONO Technologie ist abwärtskompatibel, dadurch kann auch bereits vorhandenes Audiomaterial in Mono, Stereo oder 5.1 Soundtechnologie mit einer wesentlich verbes1 Sweetspot - bezeichnet eine effektive Zone 3 2 IOSONO serten Klangqualität wiedergegeben werden. Um das gesamte Potential des Soundsystems ausschöpfen zu können, ist es erforderlich, das Audiomaterial speziell für die Wellenfeldsynthese zu produzieren. 2.2 Wellenfeldsynthese Die Wellenfeldsynthese[25] wurde erstmals 1988 an der Technischen Universität Delft entwickelt. Mit 160 Lautsprechern wurde dort auch das erste Demonstrationssystem realisiert. In einem europäischen Forschungsprojekt unter der Leitung des Fraunhofer-Instituts für Digitale Medientechnologie IDMT wurde die Wellenfeldsynthese zur Marktreife entwickelt und wird unter dem Namen IOSONO vertrieben. Abbildung 2.1: Das Huygenssche Prinzip Die Wellenfeldsynthese basiert auf dem Huygensschen Prinzip, welches in Abbildung 2.1 skizziert ist. Es besagt, dass jede Quelle, die von einer Wellenfront erzeugt wurde, als Summe von unendlich vielen Einzelquellen betrachtet werden kann. Durch die Interferenz der Elementarwellen entsteht eine neue Wellenfront, welche mit der ursprünglichen Welle identisch ist. In einem 3-dimensionalen Raum ist die Form dieser Welle kugelförmig. Das Huygenssche Prinzip wird mit dem Kirchhoff-Helmholtz-Integral mathematisch beschrieben. Seite 4 2 IOSONO 2.3 Architektur von IOSONO Abbildung 2.2: IOSONO Architektur Das IOSONO System besteht aus mehreren Softwaremodulen, welche für die Erstellung, Berechnung und die Wiedergabe von räumlichen Audioobjekten verantwortlich sind. Die Rechen- und Steuereinheiten bestehen vorwiegend aus herkömmlichen Standard PCKomponenten. Lediglich zur Übertragung von Audiodaten sind spezielle Soundkarten notwendig. In Abbildung 2.2 ist die Architektur des IOSONO Systems dargestellt. Die dick umrandeten Elemente können jeweils zu einer Einheit zusammengefasst werden und befinden sich auf unterschiedlichen Recheneinheiten. Die Übertragungskanäle von Audio-, Positionsund Steuerdaten sind als gerichtete Pfeile dargestellt. Audiodaten werden über eine ALSA2 Schnittstelle mit Hilfe von speziellen Soundkarten übermittelt. Für den Austausch der 2 ALSA - Advanced Linux Sound Architecture ist eine Soundarchitektur für das Betriebssystem LINUX Seite 5 2 IOSONO Positions- und Steuerdaten wird eine herkömmliche Netzwerkverbindung genutzt. Die in Abbildung 2.2 grafisch dargestellten Bestandteile sollen nun ausführlich erläutert werden. Spamix Spamix ist eine grafische Benutzeroberfläche zum Entwurf, zur Bearbeitung und Wiedergabe von spatiotemporalen Audioobjekten. Die Audioobjekte werden intern als Szenengraph in einer Baumstruktur gespeichert und können in Raum und Zeit frei auf der grafischen Oberfläche bewegt werden. In Abbildung 2.3 ist ein Beispiel dr Struktur des Baumes dargestellt. Bei der Wiedergabe werden Steuerdaten an den Renderer und den Audioserver gesendet. Mit einem speziellen Timecode Generator können die Prozesse zwischen Spamix und Audioserver synchronisiert werden. Der Renderer arbeitet ohne Timecode und verarbeitet die eingehenden Daten sofort. Audioserver Der Audioserver stellt ein Softwaremodul auf einem speziellen Rechner dar und ist für die Speicherung und Verwaltung der Audiodaten verantwortlich. Die Audiodaten werden in Form von WAV3 Dateien auf dem Dateisystem abgelegt. Beim Abspielvorgang liest der Audioserver die benötigten Audiodateien und überträgt sie mit Hilfe einer speziellen Soundkarte an den Renderer. Renderer Der Renderer bekommt als Eingabe die Audiodaten vom Audioserver und die Positionsdaten vom Spamix geliefert und ermittelt daraus die Geometrieberechnungen für die Wellenfeldsynthese. Anschließend werden die berechneten Audiosignale an die entsprechenden Lautsprecherpanels übertragen. Die Berechnung der Audiosignale erfolgt während der Wiedergabe in Echtzeit und ist somit ein sehr kritischer Prozess, der eine sehr hohe Priorität fordert. Controlunit Die Controlunit ist für die Initialisierung und Überwachung der einzelnen Softwarekomponenten verantwortlich. Sie startet und beendet die einzelnen Module und überwacht den Audioserver und Renderer. Fällt beispielsweise einer der beiden Rechner aus, wird eine Benachrichtigung an Spamix geschickt. 3 WAV Dateiformat - Containerformat zur digitalen Speicherung von Audiodaten Seite 6 2 IOSONO Abbildung 2.3: Szenengraph einer Beispielszene Seite 7 3 Anwendungszenarien In diesem Kapitel sollen mögliche Anwendungszenarien für die Verwaltung und Speicherung von XML-Daten betrachtet werden. Die elementarste Variante ist der Single-UserBetrieb, bei dem genau ein Benutzer auf genau einem Datensatz arbeitet. In den meisten Fällen ist es aber notwendig, dass mehrere Benutzer gleichzeitig im Team, kooperativ auf einer zentralen Datenbasis arbeiten müssen. Der so genannte Multi-User-Betrieb kann wiederum in die zwei Kategorien Workgroup- und Workspace-Betrieb unterteilt werden. Im Workgroup-Betrieb soll es möglich sein, jede Änderung schon während der Bearbeitung für alle anderen Benutzer sichtbar zu machen. Dadurch können Modifikationen unmittelbar in den Arbeitsprozess der Kollegen mit einfließen. Im Workspace-Betrieb arbeiten die Autoren entkoppelt auf lokalen Arbeitskopien und die Dokumente werden ähnlich wie bei einem Versionierungssystem verwaltet. Hierbei ist es wichtig, die Schnittstelle für den Benutzer transparent zu gestalten. Das heisst, der Benutzer soll nicht merken, ob er allein oder mit mehreren Benutzern gleichzeitig an einem Dokument arbeitet. 3.1 Single-User-Betrieb In diesem Abschnitt werden die grundlegenden Funktionen zur Speicherung und Verwaltung von XML Daten im Single-User-Betrieb detailliert erläutert. Die Workgroup- und Workspace-Versionen bauen auf diesen Grundfunktionen auf und stellen somit eine Erweiterung der Single-User-Version dar. Wie in Abbildung 3.1 ersichtlich, kommuniziert die Anwendung mit einem lokalen MuXp Client, der für die Verwaltung und Speicherung von Dokumenten verantwortlich ist und die XML Dokumente in einer Berkeley DB XML Datenbank speichert. MuXp ist eine Abkürzung und steht für Multiuser XML Processing. Schwerpunkt dieser Arbeit ist die Analyse und Erarbeitung einer Gesamtstruktur mit den benötigten Schnittstellen und Funktionalitäten, welche unter der Abkürzung MuXp Framework zusammengefasst werden. Die konkrete Implementierung wird in Kapitel 4 ausführlich behandelt. Für die sinnvolle Verwaltung und Verarbeitung von XML Dokumenten ist es erforderlich, für die Anwendung 8 3 Anwendungszenarien Anwendung MuXp Client BerkeleyDB XML Abbildung 3.1: Single-User-Betrieb eine Reihe von Schnittstellen zum Hinzufügen, Speichern, Zwischenspeichern, Löschen, Suchen und für die Versionierung zu definieren. Hinzufügen Legt ein neues XML Dokument in der Datenbank an und stellt es unter die Versionsverwaltung. Speichern Nachdem ein Dokument hinzugefügt wurde, kann die Anwendung XML Dokumente erstellen und in der Datenbank abspeichern. Zwischenspeichern Mit Hilfe dieser Schnittstelle können in kontinuierlichen Intervallen temporäre Sicherheitskopien der zu bearbeitenden XML Dokumente angelegt werden. Bei einem Programmabsturz besteht somit die Möglichkeit, die Daten bis zum letzten Speicherintervall wieder herzustellen. Wird die Anwendung normal beendet, werden die temporär gespeicherten Daten verworfen. Erst durch den Aufruf der Funktion Speichern werden die Daten dauerhaft als eine neue Version in der Datenbank abgelegt. Laden Beim Aufruf der Funktion Laden wird jeweils die neueste Version eines Dokumentes von der Datenbank zurückgegeben. Seite 9 3 Anwendungszenarien Zurücksetzen Mit Zurücksetzen wird nicht die aktuelle, sondern eine bestimmte Version aus der Datenbank geladen. Suchen Die Schnittstelle Suchen bietet die Möglichkeit, nach bestimmten XML Elementen, Attributen oder Daten zu suchen und liefert bei einem Treffer eine Referenz in Form von einem XPath Ausdruck auf das entsprechende Element oder Attribut zurück. Löschen Die Schnittstelle Löschen bietet die Möglichkeit, einzelne Versionen oder ein gesamtes Dokument aus der Datenbank zu löschen. Anwendung Load(Example) MuXp Client Anwendung Zwischenspeichern MuXp Client Anwendung store MuXp Client Store(Examle:2_1) Store(Example:3) Example:2_3 Example:2_2 Example:2_1 Example:2 Example:1 Example:3 Example:2_3 Example:2_2 Example:2_1 Example:2 Example:1 Load(Example:2) Example:2 Example:1 Bild 1 Bild 2 Bild 3 Abbildung 3.2: Typischer Anwendungsfall für den Single-User-Betrieb Typischer Anwendungsfall Anhand eines kleinen Beispiels soll im Folgenden ein typischer Anwendungsfall erläutert werden. Wie in Abbildung 3.2 Bild 1 ersichtlich, befinden sich 2 Versionen des Dokumentes Example (Example:1, Example:2) in der Datenbank. Die Versionsnummer ist jeweils Seite 10 3 Anwendungszenarien durch einen Doppelpunkt vom Dokumentnamen getrennt und temporären Versionsnummern durch einen Unterstrich. Durch den Aufruf der Funktion laden gibt der MuXp Client die neueste Version des Dokumentes, in unserem Fall die Version Example:2, zurück. Die Anwendung kann nun die XML Daten verarbeiten und es wird in regelmäßigen Intervallen automatisch die Methode Zwischenspeichern aufgerufen, welche die temporäre Versionen Example:2 1, Example:2 2, Example:2 3 des Dokumentes in der Datenbank anlegt (siehe Bild 2). Kommt es nun zu einem Absturz der Anwendung, kann bei einem Neustart die letzte temporäre Version Example:2 3 wieder hergestellt werden und die Anwendung kann mit der Verarbeitung der Daten an dieser Stelle fortfahren. In Bild 3 werden durch den Aufruf von Speichern“ die temporären Versionen Example:2 1, Example:2 2 und Example:2 3 ” verworfen und eine neue Hauptversion Example:3 in der Datenbank angelegt. 3.2 Multi-User-Betrieb Die Multi-User-Versionen bauen auf den grundlegenden Funktionen der Single-User-Version auf und stellen somit eine Erweiterung dar. In diesem Abschnitt sollen die Unterschiede zur Single-User-Version und die erweiterten Funktionen erläutert werden. Damit mehrere Anwendungen kooperativ auf gemeinsame Dokumente zugreifen können, müssen die Daten zentral in einer Datenbank verwaltet werden. Wie in Abbildung 3.3 zu sehen, gibt es dafür einen zentralen MuXp Server, der für die Verwaltung der Daten verantwortlich ist und diese in einer XML Datenbank abspeichert. Für die lokale Verarbeitung der Daten verwendet jede Anwendung ihren eigenen MuXp Client und eine lokale XML Datenbank. Will die Applikation nun ein bestimmtes Dokument Laden, stellt sie eine entsprechende Anfrage an den MuXp Client. Ist das Dokument nicht in der lokalen Datenbank vorhanden, wird die Anfrage an den zentralen Server weitergeleitet, welcher das angefragte Dokument an den lokalen MuXp Client zurückgibt. Der lokale MuXp Client legt eine Arbeitskopie in der lokalen Datenbank an und übergibt das Dokument zur weiteren Verarbeitung an die Anwendung. Alle in Abschnitt 3.1 beschriebenen Schnittstellen existieren auch in den Multi-User-Versionen und haben prinzipiell die gleiche Funktionalität wie im Single-User-Betrieb. Der ausschlaggebende Unterschied besteht darin, dass jede Anfrage, die vom Client nicht verarbeitet werden kann, an den Server weitergeleitet wird. Weiterhin werden zur Bearbeitung immer lokale Arbeitskopien in der Client Datenbank angelegt. Eine Ausnahme stellt die Funktionalität der Schnittstelle Zwischenspeichern dar. Wird ein XML Dokument im Seite 11 3 Anwendungszenarien ... Anwendung 1 Anwendung 2 MuXp Client 1 BerkeleyDB XML 1 MuXp Server zentrale Datenbasis Anwendung n MuXp Client 2 ... MuXp Client n BerkeleyDB XML 2 ... BerkeleyDB XML n BerkeleyDB XML Abbildung 3.3: Multi-User-Betrieb Workspace-Betrieb zwischengespeichert, hat das nur Auswirkungen auf die lokale Arbeitskopie der Client Seite. Für die Anwendung ist der Zugriff auf die Daten somit transparent, das heißt sie muss sich nicht darum kümmern, ob sie allein auf die Daten zugreift oder ob mehrere Applikationen gleichzeitig auf die Daten zugreifen. Diese Verwaltungsarbeit übernimmt der zentrale Server. Aufgrund der Tatsache, dass mehrere Benutzer kooperativ auf gemeinsamen Daten arbeiten, entstehen Konflikte beim gleichzeitigen Zugriff auf ein XML Dokument. Angenommen, Anwendung 1 und Anwendung 2 aus Abbildung 3.3 bearbeiten kooperativ ein XML Dokument. Anwendung 1 ruft die Funktion Speichern auf, wodurch eine neue Hauptversion in der zentralen Datenbank angelegt wird. Ruft nun Anwendung 2 ebenfalls die Funktion Speichern auf, wird wieder eine neue Hauptversion in der zentralen Datenbank angelegt, womit die Änderungen von Anwendung 1 verloren gehen. Für diese Problematik gibt es 2 verschiedene Lösungsansätze, einen pessimistischen mit Hilfe von Sperrverfahren und einen optimistischen Ansatz mit Hilfe eines Versionierungssystems. Seite 12 3 Anwendungszenarien 3.2.1 Workgroup-Betrieb Im Workgroup-Betrieb arbeiten mehrere Autoren in einer Arbeitsgruppe kooperativ an einem XML Dokument. Es besteht die Möglichkeit, schon während dem Bearbeitungsprozess die Änderungen der Teamkollegen direkt mitzuverfolgen. Das hat den Vorteil, dass die Modifikationen der Kollegen unmittelbar in den eigenen Bearbeitungsprozess mit einbezogen werden können. Will eine Anwendung die Änderungen für ein XML Element verfolgen, muss sie sich für das entsprechende XML Element auf dem Server registrieren. Führt eine andere Anwendung für das entsprechende XML Element eine Änderung durch, benachrichtigt der MuXp Server alle für das Element registrierten Anwendungen, welche dann umgehend auf die Änderung reagieren können. Diese Änderungen werden zunächst nur im Hauptspeicher verwaltet und erst nach einem commit dauerhaft in der Server XML Datenbank gespeichert. Beispiel Änderungspropagierung In Abbildung 3.5 repräsentieren die Baumknoten jeweils ein XML Element im XML Baum. Möchte nun Workspace 1 Änderungen für das XML Element 2 verfolgen, wird eine Registrierungsanfrage an den MuXp Server für das entsprechende Element 2 geschickt. Führt Workspace 2 nun eine Änderung auf den XML Elementen 2, 3 oder 4 aus, sendet der Server eine Benachrichtigung mit den geänderten Knoten an Workspace 1. Änderungen der XML Elemente 1 und 5 haben hingegen keine Auswirkungen auf die Benachrichtigung von Workspace 1, da nur die Kindknoten von Element 2 betroffen sind. Wenn Workspace 1 eine automatische Benachrichtigung nicht mehr benötigt, ist es notwendig, sich wieder vom Server abzumelden. Für die Änderungspropagierung werden der Anwendung Schnittstellen zum Registrieren, Abmelden und Bekanntmachen von Änderungen angeboten. Um den gleichzeitigen Zugriff auf ein XML Element zu verhindern, werden im WorkgroupBetrieb Sperrverfahren genutzt. Bei Sperrverfahren muss die Anwendung vor dem Bearbeiten eine Schreibsperre für das entsprechende XML Element setzen. Will nun eine andere Anwendung das gleiche Element bearbeiten, muss sie warten bis die Sperre wieder freigegeben ist. Das hat den Vorteil, dass 2 verschiedene Anwendungen kein Element gleichzeitig bearbeiten können und somit keine Änderungen verloren gehen. Auf der anderen Seite schränkt man damit die gleichzeitige Bearbeitung ein und die Anwendung muss vor dem Bearbeiten wissen, welche Elemente gesperrt werden sollen. Ein guter Kompromiss besteht darin, die Sperren sehr granular und nur für kurze Zeit zu setzen. Das Sperrverfahren soll nun an einem kleinen Beispiel erläutert werden. In Abbildung 3.4 Seite 13 3 Anwendungszenarien Workspace 1 Workspace 2 MuXp Server 1 2 3 5 4 Abbildung 3.4: Beispiel Sperrverfahren repräsentieren die Baumknoten jeweils ein XML Element im XML Baum. Um die Grafik übersichtlicher zu gestalten, wurde die lokale Anwendung mit dem MuXp Client und lokaler Datenbank als Workspace zusammengefasst. Angenommen, Workspace 1 möchte das XML Element 2 bearbeiten. Dazu muss vor der Bearbeitung eine Schreibsperre für den XML Knoten 2 gesetzt werden. Will nun Anwendung 2 ebenfalls das XML Element 2 bearbeiten, bekommt sie eine Benachrichtigung vom MuXp Server, dass das XML Element 2 derzeit von Workspace 1 gesperrt ist. Workspace 2 kann auf den XML Knoten erst schreibend zugreifen, wenn Workspace 1 die Sperre wieder freigegeben hat. Durch das Sperren von Knoten 2 werden implizit auch die beiden Kindknoten 3 und 4 gesperrt. Sie können somit auch nicht von Workspace 2 bearbeitet werden. Auf die Knoten 1 und 5 hingegen kann Workspace 2 problemlos schreibend zugreifen, da die Sperre von Workspace 1 nur Einfluss auf die Kindknoten von Element 2 hat. Für das Sperren von einzelnen XML Knoten werden für die Anwendung Schnittstellen zum Sperren und Entsperren definiert. 3.2.2 Workspace-Betrieb Im Workspace-Betrieb arbeiten mehrere Autoren entkoppelt auf lokalen Arbeitskopien. In unregelmässigen Abständen werden die Änderungen mit der zentralen Datenbank abgeglichen. Hierfür wird ein optimistisches Verfahren verwendet, welches ähnlich wie ein Versionierungssystem arbeitet. Die Autoren können unabhängig voneinander Änderungen am gleichen XML Dokument vornehmen. Erst beim Speichern detektiert der Server die Änderungen zur aktuellen Version auf dem Server und versucht die beiden Dokumente Seite 14 3 Anwendungszenarien miteinander zu verschmelzen. Kommt es dabei zu Konflikten, werden die betroffenen Anwendungen benachrichtigt und die Konflikte müssen manuell aufgelöst werden. Das hat den Vorteil, dass die kooperative Verarbeitung von Daten nicht eingeschränkt wird und die Anwendungen müssen nicht vorher wissen, welche Elemente sie ändern möchten. Der Nachteil besteht darin, dass die manuelle Auflösung der Konflikte sehr aufwendig ist und somit nur bei wenig zu erwartenden Konflikten sinnvoll einsetzbar ist. Workspace 1 Workspace 2 load Workspace 1 Workspace 2 store store MuXp Server MuXp Server load MuXp Server 1 2 3 1 5 4 Version 3 5 2 3 1 4 5 2 3 Version 4 4 Konflikt Abbildung 3.5: Beispiel Versionierung Die Versionierung soll nun mit Hilfe von Abbildung 3.5 an einem Beispiel erläutert werden. Zur besseren Übersicht wird jeweils immer nur die aktuelle Version grafisch als XML Baum dargestellt. Workspace 1 lädt die aktuelle Version 3 vom MuXp Server und bearbeitet Knoten 2. Workspace 2 lädt ebenfalls die aktuelle Version 3 und bearbeitet parallel zu Workspace 1, den XML Knoten 2. Workspace 1 hat die Bearbeitung abgeschlossen und das XML Dokument wird auf dem Server gespeichert. Der Server bildet nun die Differenz zwischen Version 3 und der geänderten Version vom Workspace 1. Da zwischenzeitlich keine andere Anwendung das Dokument auf dem Server verändert hat, werden keine Konflikte erkannt und das Dokument wird mit der Versionsnummer 4 in der Datenbank abgelegt. Nun speichert Workspace 2 ebenfalls das geänderte XML Dokument und der Server bildet wieder die Differenz zwischen der Serverversion 4 und dem XML Dokument von Workspace 2. Da sowohl Workspace 1 als auch Workspace 2 den XML Knoten 2 geändert haben kommt es an dieser Stelle zu einem Konflikt, der in Abbildung 3.5 rechtes Bild durch einen Blitz verdeutlicht wird. Dieser Konflikt muss nun manuell von beiden Anwendungen aufgelöst werden und es wird eine neue Version 5 in der Serverdatenbank angelegt. Würde Workspace 2 nur Änderungen an den Knoten 1 und 5 vornehmen, käme es zu keinen Konflikten. Seite 15 3 Anwendungszenarien Für die Benachrichtigung der Anwendungen über aufgetrene Konflikte, müssen in weiteren Arbeiten geeignete Datenstrukturen und Schnittstellen definiert und implementiert werden. Seite 16 4 Implementierung MuXp Framework Internet W orkspace Interface Application Spamix Server Interface Connection XmlVersionManager XmlTransactionManager Database XmlVersionManager Xml Update Manager Database Application Workspace Server Abbildung 4.1: Übersicht MuXp Framework In diesem Kapitel soll die konkrete Implementierung der entwickelten Konzepte aus Kapitel 3 für das MuXp Framework detailliert erläutert werden. MuXp ist eine Abkürzung und steht für Multiuser XML processing und besteht aus einer Sammlung von C++ Klassen und Tools, mit denen mehrere Anwendungen kooperativ XML Daten verarbeiten und speichern können. Beim Entwurf dieser Struktur wurde vor allem auf die Kapselung und Modularität Wert gelegt, was den Vorteil bringt, jedes einzelne Modul ohne Auswirkungen auf die Gesamtstruktur zu verbessern, erweitern und auszutauschen. Um beispielsweise die Berkeley DB XML Datenbank durch eine andere Datenbank zu ersetzen, muss lediglich die Klasse Database modifiziert werden. Alle anderen Klassen und Schnittstellen bleiben unverändert. Weiterhin wird durch die Kapselung eine bessere Übersicht der einzelnen Klassen erreicht. Bei der Wahl der Programmiersprache waren vor allem die Kompatibilität zur Testapplikation Spamix und das Vorhandensein von Bibliotheken zur Speicherung, Verarbeitung und 17 4 Implementierung Übertragung von XML Daten entscheidend. Weiterhin war es wichtig, die Anschaffungskosten für Software so gering wie möglich zu halten und ein plattformunabhängiges Framework zu entwickeln. Dadurch ist die Verwendung sowohl unter Linux als auch unter Windows möglich. Aufgrund dieser Anforderungen wurde für die Implementierung die Programmiersprache C++ gewählt, da die Testapplikation Spamix ebenfalls in C++ implementiert wurde. Ein weiterer Vorteil ist die weite Verbreitung von C++, wodurch bereits die Open Source XML Datenbank Berkeley DB XML zur Verarbeitung und Speicherung, sowie der XML Parser Xerces-C von Apache zum Parsen und Generieren von XML Daten zur Verfügung stehen. Für die Kommunikation und Übertragung von XML Dokumenten wird die Ice Bibliothek der Firma ZeroC verwendet, welche ebenfalls eine Schnittstelle für C++ bereitstellt und unter einer Open Source Lizenz vertrieben wird. Die Vor- und Nachteile der genutzten Third Party Software“ und die Gründe für die Verwendung werden in den folgenden ” Kapiteln noch ausführlich analysiert. In Abbildung 4.1 ist eine Übersicht der einzelnen Module schematisch dargestellt. Die Testapplikation Spamix greift direkt auf die Schnittstellen des MuXp Workspace zu. Kann eine Anfrage nicht im lokalen Workspace verarbeitet werden, wird sie über die Kommunikationsschnittstelle (in der Abbildung als Internet dargestellt) an den MuXp Server weitergeleitet. Das MuXp Framework ist in mehrere Pakete untergliedert, welche dann die eigentlichen Module beinhalten. Jedes einzelne Modul entspricht dabei einer Klasse in C++ und kapselt eine bestimmte Funktionalität. Die jeweiligen Module beziehungsweise Klassen werden in den folgenden Abschnitten noch detaillierter erläutert. 4.1 MuXp Framework MuXp Framework Utility Workspace Server Abbildung 4.2: Struktur MuXp Framwork In Abbildung 4.2 ist die Struktur des MuXp Framework abgebildet, welches in die drei Pakete Utility, Workspace und Server untergliedert ist. Klassen, die sowohl im Server als Seite 18 4 Implementierung auch im Workspace Verwendung finden, wie beispielsweise der XmlVersionManager oder die Database Klasse, werden im Paket Utility verwaltet und können somit von mehreren Modulen unabhängig voneinander verwendet werden. Alle Module, die ausschließlich für den Workspace oder Server genutzt werden, befinden sich in den entsprechenden Workspace oder Server Paketen. Ein weiterer wichtiger Aspekt ist die Ausnahmebehandlung zwischen den einzelnen internen Klassen, aber auch zwischen der Anwendung und dem MuXp Client. Die internen Klassen sind dafür verantwortlich, dass spezifische Exceptions von Third Party Bibliotheken in die selbst definierte MuXp Exception umgewandelt werden. Dadurch muss eine Anwendungen nur MuXp Exceptions vom Workspace abfangen, was die Integration in vorhandene Applikationen erheblich erleichtert. 4.1.1 Utility Paket In diesem Paket sind die Klassen Database, XmlVersionManager, XmlTransactionManager, XmlUpdateManager, Property, MuXpException und TypeDef enthalten. Sie können sowohl im Server, Workspace oder auch in anderen Programmen Verwendung finden. In diesem Abschnitt sollen diese Klassen mit ihren Methoden detailliert erläutert werden. TypeDef In der Klasse TypeDef werden die proprietären Datentypen xmlDokument, xmlName, dokumentId, xmlKnoten und txnId zentral definiert. Dadurch vermeidet man die Redefinition von Datentypen und Änderungen müssen nur an einer zentralen Stelle vorgenommen werden. Dadurch kann man auch später die Basisdatentypen ohne Probleme ändern. Benötigt eine Klasse einen proprietären Datentyp, muss sie lediglich die Klasse TypeDef einbinden. xmlDokument Speichert ein XML Dokument. Als Basistyp wird der C++ Datentyp String benutzt. xmlName Beinhaltet den Namen eines XML Dokumentes. Als Basistyp wird der C++ Datentyp String benutzt. dokumentId Jedes XML Dokument in der XML Datenbank kann eindeutig durch einen Dokumentnamen und einer Versionsnummer bestimmt werden. Diese beiden Informationen werden als C++ Struct Datentyp dokumentId gespeichert. Seite 19 4 Implementierung xmlKnoten Jeder XML Knoten kann mit Hilfe eines XPath Ausdruckes eindeutig adressiert werden. Dieser Ausdruck wird im Datentyp xmlKnoten abgelegt. Als Basistyp wird der C++ Datentyp String verwendet. txnId Transaktionen können durch Transaktions-Ids eindeutig spezifiziert werden. Der Datentyp txnId stellt eine Transaktions-Id dar. Als Basistyp wird der C++ Datentyp Integer verwendet. xmlUpdate Dieser Datentyp beinhaltet Änderungen eines XML Dokumentes. Die genaue Struktur muss noch analysiert und definiert werden. Property Die Property Klasse speichert, ändert und liest bestimmte Eigenschaften, die vom MuXp Framework benötigt werden. Eigenschaften können beispielsweise der Pfad zur Datenbank, die IP Adresse des MuXp Servers oder der zu verwendende Port sein. Die einzelnen Werte werden in einer einfachen XML Struktur gespeichert und mit Hilfe der XPath Bibliothek Pathan[9] geschrieben und ausgelesen. Der Attributname wird jeweils als XML Knoten und der Attributwert als XML Text gespeichert. Die Funktions- und Rückgabewerte attributWert und attributName sind vom C++ Typ String. Im Listing 4.1 ist ein Beispiel für eine Propertydatei abgebildet. In Zeile 2 wird beispielsweise der Pfad zur Datenbank gespeichert. Der Attributname DatabasePath“ beinhaltet den Attributwert /home/bae” ” r/spamix.bdbxml“. 1 2 3 4 5 <P r o p e r t y> <DatabasePath>/home/ b a e r / spamix . bdbxml</ DatabasePath> <S e r v e r I P A d d r e s s>1 9 2 . 1 6 8 . 0 . 1</ S e r v e r I P A d d r e s s> <S e r v e r P o r t>10000</ S e r v e r P o r t> </ P r o p e r t y> Listing 4.1: Beispiel Property Datei attributWert get(attributName) Gibt den Wert eines bestimmten Attributes zurück. bool set(attributName, attributwert) Speichert den Wert eines bestimmten Attributes. Seite 20 4 Implementierung Database Die Klasse Database ist für die Speicherung von XML Dokumenten verantwortlich und nutzt dafür die C++ Schnittstelle der Datenbank Berkeley DB XML, welche die Dokumente in so genannten Containern verwaltet. Für jeden Datensatz wird ein eindeutiger Dokumentenname vergeben, mit dem dann auf die XML Daten zugegriffen werden kann. Zusätzlich können weitere Informationen in Form von Metadaten im Container gespeichert werden. Für die Benutzung werden Funktionen zum Hinzufügen, Speichern und Löschen zur Verfügung gestellt. bool putDocument(dokumentName, xmlDokument) Speichert ein neues Dokument in der Datenbank. xmlDokument getDocumentByName(dokumentName) Gibt ein XML Dokument anhand des entsprechenden Namens zurück. bool deleteDocument(dokumentName) Löscht das Dokument aus der XML Datenbank. bool deleteAllDocuments() Löscht alle Dokumente aus der Datenbank. vector<xmlDokument> getAllDocumentNames() Gibt alle Dokumentennamen, die in der Datenbank gespeichert sind, als Vektor zurück. XmlVersionManager Der XmlVersionManager ist für die Versionierung von XML Dokumenten verantwortlich, was eine Archivierung verschiedener XML Dokumente ermöglicht. Da im Rahmen dieser Studienarbeit der Entwurf einer Struktur für das Gesamtsystem im Vordergrund steht, wurde zunächst einmal nur ein sehr einfaches Versionierungssystem implementiert. Für jede neue Version wird ein neues Dokument mit einer Versionsnummer, die mit 0 beginnt und bei jeder neuen Version um 1 inkrementiert wird, angelegt. Die Versionsnummer wird, getrennt durch einen Unterstrich, direkt an den Dokumentennamen angehangen. Eine Ausnahme stellt die aktuellste Version dar, bei der die Versionsnummer in den Metadaten des Dokumentes abgelegt wird. Das hat den Vorteil, dass auf die aktuellste Version direkt über den Dokumentennamen zugegriffen werden kann. Würde man bei der neuesten Version auch die Versionsnummer an den Dokumentnamen anhängen, müsste man erst das Maxi- Seite 21 4 Implementierung mum aller Versionsnummern für das Dokument ermitteln, was bei einer Anzahl von vielen Versionen einen hohen Berechnungsaufwand nach sich zieht. add store Meta Meta example 0 store example example_0 1 example example_1 example_0 Meta 2 Abbildung 4.3: Beispiel Versionierung Anhand von einem Beispiel soll die Versionierung des XML Dokumentes example in Abbildung 4.3 anschaulich erläutert werden. Zuerst wird das Dokument mit der Funktion add in die Datenbank eingefügt und die Versionsnummer 0 als Metawert gespeichert. Beim Aufruf der Funktion store, wird die Versionsnummer 0 aus den Metadaten an den Dokumentennamen angehangen (example 0). Das neue Dokument wird unter dem Namen example gespeichert und die Versionsnummer 1 als Metawert abgelegt. Analog dazu, wird im rechten Bild die Version 2 in der Datenbank abgespeichert. Diese Art der Versionierung ist sehr ineffizient, da für jede neue Version immer das gesamte Dokument gespeichert wird. In der Diplomarbeit [23] wurden mehrere Ansätze zur effizienten Versionierung von XML Dokumenten untersucht, welche zur weiteren Optimierung und Steigerung der Effizienz in den XmlVersionManager integriert werden sollen. Weiterhin wurde in die Berkeley DB XML seit der Version 2.3 auch eine Unterstützung für die Versionierung integriert, welche man vielleicht im Versionsmangaer mit nutzen könnte. Der XmlVersionManager stellt folgende öffentliche Methoden für die Benutzung bereit. bool add(dokumentName, xmlDokument) Ein neues XML Dokument wird unter die Versionsverwaltung gestellt und eine neue Grundversion in der Datenbank angelegt. Steht das Dokument bereits unter der Verwaltung des XMLVersionManagers, wird die Funktion abgebrochen und false an die Anwendung zurückgegeben. bool store(dokumentName, xmlDocument) Legt eine neue Version von einem Dokument an, weleches bereits in der Datenbank vorhanden ist. Falls keine Grundversion von dem Dokument vorhanden ist, wird als Fallback das XML Dokument mit der Methode add hinzugefügt. Seite 22 4 Implementierung xmlDokument load(dokumentName) Lädt die neueste Version von einem Dokument und wirft eine MuXp Exception falls kein entsprechendes Dokument in der Datenbank vorhanden ist. xmlDokument loadVersion(dokumentId) Lädt eine bestimmte Version von einem Dokument und wirft eine MuXp Exception, falls die entsprechende Version des Dokumentes nicht vorhanden ist. Das Dokument und die Version werden eindeutig durch den struct dokumentId bestimmt. vector<version> getAllVersions(dokumentName) Gibt alle Versionsnummern eines Dokumentes an die Anwendung als Vektor zurück. Ist das Dokument nicht vorhanden, wird ein Vektor der Größe Null zurückgegeben. vector<dokumentName> getAllDocuments() Gibt alle Namen der XML Dokumente, die in der Datenbank gespeichert sind, als Vektor zurück. xmlDokument revert(dokumentId) Lädt eine bestimmt Version von einem Dokument und speichert diese als die neueste Version. Ist das Dokument mit der entsprechenden Version nicht vorhanden, wird eine MuXp Exception geworfen. Das Dokument und die Version werden eindeutig durch den struct dokumentId bestimmt. bool erase(dokumentName) Löscht das Dokument und alle Versionen aus der Datenbank. Ist das Dokument nicht vorhanden, wird false an die Anwendung zurückgegeben. XmlTransactionManager Der XmlTransactionManager ist für die Verwaltung von Transaktionen verantwortlich, welche direkt von der Applikation gesteuert werden können. Zum Starten einer Transaktion ruft die Anwendung die Methode begin auf, welche eine eindeutige Transaktions-Id generiert und an die Anwendung zurückgibt. Für die Generierung wird ein Integer Wert von 0 beginnen inkrementiert. Wir der Integer Wertebereich überschritten, wird der Wert des Zählers wieder auf 0 gesetzt. Diese Transaktions-Id wird intern in einer so genannten Transaktionstabelle gespeichert und verwaltet. Bei jeder ausgeführten Operation wird geprüft, ob die Transaktions-Id gültig ist und einer Transaktion eindeutig zugeordnet werden kann. Ist eine Transaktions-Id ungültig, wird die entsprechende Operation abgebrochen und eine Seite 23 4 Implementierung Exception geworfen, die von der Anwendung behandelt werden muss. Wird eine Transaktion von der Anwendung abgebrochen, werden alle Änderungen bis zum Transaktionsbeginn rückgängig gemacht und die Transaktions-Id aus der Transaktionstabelle gelöscht. txnId begin() Beim Aufruf von begin wird eine neue Transaktions-Id generiert und an die Anwendung zurückgegeben. bool commit(txnId) Mit commit werden alle Änderungen dauerhaft in der Datenbank gespeichert und die Transaktions-Id wird aus der Transaktionstabelle gelöscht. bool abort(txnId) Bei einem abort werden alle Änderungen bis zum Transaktionsbeginn rückgängig gemacht. Weiterhin wird die Transaktions-Id aus der Transaktionstabelle gelöscht. XmlUpdateManager Für die Änderungspropagierung ist es erforderlich dem Workspace Methoden zum Registrieren und Abmelden von XML Knoten bereit zu stellen, damit die entsprechenden Anwendungen über eine Änderung benachrichtigt werden können. Um Benachrichtigungen empfangen zu können, muss die Anwendung einen so genannten Listener implementieren, der die Schnittstelle zwischen XmlUpdateManager und der Anwendung darstellt. Derzeitig sind nur die Methoden subscribe und unsubscribe implementiert. Die Benachrichtigung der Anwendungen muss noch erarbeitet werden. bool subscribe(clientId, xmlKnoten) Mit subscribe kann sich eine Anwendung für die Benachrichtigung einer Änderung für einen bestimmten XmlKnoten registrieren. bool unSubscribe(clientId, xmlKnoten) Wird eine Benachrichtigung für eine Änderung nicht mehr benötigt, kann sich die Anwendung mit Hilfe der Methode unSubscribe wieder von der Benachrichtigung abmelden. bool publish(xmlUpdate) Verschickt Änderungen eines XML Dokumentes an alle registrierten Clients. Diese Methode stellt zunächst nur eine Schnittstelle ohne Funktionalität dar und wird in späteren Arbeiten implementiert. Seite 24 4 Implementierung XmlLockManger Der XmlLockManager ist für die Verwaltung von Sperren auf XML Knoten zuständig. Er bietet die Möglichkeit, Sperren zu setzen, zu entfernen und deadlocks aufzulösen. Weiterhin können externe Klassen prüfen, ob ein bestimmter XML Knoten gesperrt ist oder nicht. Im Rahmen dieser Arbeit wurde zunächst nur eine Struktur geschaffen. Die Funktionalität wird in einer weiteren Studienarbeit erarbeitet, implementiert und später in das MuXp Framework integriert. bool lock(xmlKnoten) Versucht eine Sperre für einen bestimmten XML Knoten zu erwerben und liefert im Erfolgsfall true zurück. bool unLock(xmlKnoten) Entfernt eine Sperre für einen bestimmten XML Knoten. bool isLocked(xmlKnoten) Testet, ob für einen XML Knoten eine Sperre gesetzt ist. Diese Methode stellt eine Schnittstelle für andere Module zum Lockmanager dar. 4.1.2 Ausnahmebehandlung (Exception Handling) Durch die verteilte Struktur der einzelnen Komponenten ist es in vielen Fällen notwendig, dass Ausnahmen, die im Server geworfen werden, im Workspace oder auch in der Anwendung behandelt werden müssen. Wird beispielsweise eine Exception in der Database Klasse auf dem Server geworfen, fängt der Server die Ausnahme ab und versucht sie zu behandeln. Kann die Ausnahme nicht im Server behandelt werden, wird sie sie über die Kommunikationsschnittstelle an den Workspace weitergereicht, welcher ebenfalls versucht die Ausnahme zu behandeln. Kann auch der Workspace die Ausnahme nicht behandeln, wird sie an die Anwendung weitergeleitet, die dann letztendlich für die Ausnahmebehandlung verantwortlich ist. Um auch das Exceptionhandling modular und für die Anwendung transparent zu gestalten, werden beispielsweise spezifische Ausnahmen der Database Klasse in selbst definierte MuXp Exceptions umgewandelt. Das hat den Vorteil, dass die Anwendung nur noch MuXp Exceptions abfangen und behandeln muss. Die MuXp Exception Klasse stellt der Anwendung eine Reihe von Konstruktoren zur Initialisierung und folgende Methoden und Konstanten zur Verfügung. Seite 25 4 Implementierung ExceptionCode In dieser Aufzählung werden Fehlercodes als Konstanten gespeichert, welche von der Anwendung abgefragt werden können. In Abbildung 4.1 sind alle möglichen Exceptioncodes aufgelistet. Exception Code UNKNOWN EXCEPTION FILE NOT FOUND INVALID XML DOC INVALID XPATH NO CONNECTION DB ERROR DOCUMENT NOT FOUND Beschreibung unbekannte Exception Datei konnte nicht gefunden werden ungültiges XML Dokument ungültiger XPath Ausdruck keine Verbindung zum Server Datenbank Fehler Das Dokument konnte nicht gefunden werden Tabelle 4.1: Übersicht der möglichen Exceptioncodes exceptionCode getExceptionCode() Liefert den entsprechenden Fehlercode an die Anwendung zurück. String what() Diese Funktion beinhaltet eine ausführliche Beschreibung des aufgetretenen Fehlers. String getFile() Liefert den Dateinamen, der die Exception ausgelöst hat. Int getLine() Liefert die Zeile, in der die Exception aufgetreten ist. String getFunction() Liefert den Namen der Funktion, in der die Exception aufgetreten ist. 4.1.3 Server Paket In Abbildung 4.4 ist die logische Struktur des MuXp Servers schematisch dargestellt. Zum Aufbau der Struktur werden die Klassen Database, XmlVersionManager, XmlTransactionManager und XmlUpdateManager aus dem MuXp Utitlity Paket verwendet. Das Server Interface bietet eine Schnittstelle für alle Clients, die mit dem Server kommunizieren wollen. Die einzelnen Methoden, Konstanten und Ausnahmen der Schnittstelle werden mit Hilfe der Definitionssprache Slice [16, S. 73 ff.] festgelegt. Mit dem Tool slice2cpp wird aus Seite 26 4 Implementierung Server Interface XmlTransactionManager XmlVersionManager Xml Update Manager Database Abbildung 4.4: Struktur des MuXp Servers der Slice Definitionsdatei ServerDbI.ice automatisch eine C++ Schnittstelle ServerDbI.h erzeugt, welche von der Klasse ServerDb implementiert wird. Sowohl die Definitionssprache Slice als auch der Compiler slice2cpp werden von der Ice Bibliothek zur Verfügung gestellt. Die Klasse ServerDb stellt letztendlich das eigentliche Server Interface dar und bietet die folgenden Methoden zur Kommunikation mit dem Server. txnId begin() Durch den Aufruf von begin kann eine Transaktion vom Server gestartet werden. Dazu wird der XmlTransactionManager aufgerufen, welcher eine Transaktions-Id zurückgibt. bool commit(txnId, xmlDokument) Mit commit werden alle Änderungen dauerhaft in der Server Datenbank gespeichert. bool abort(txnId) Bei einem abort werden alle Änderungen bis zum Transaktionsbeginn rückgängig gemacht. xmlDokument load(dokumentId) Fordert das XML Dokument mit der entsprechenden dokumentId vom MuXp Server an. bool add(xmlDokument) Mit der Methode add kann ein neues XML Dokument in der MuXp Server Datenbank hinzugefügt werden. bool erase(dokumentId) Löscht das XML Dokument mit der entsprechenden dokumentId aus der Server Datenbank. searchResult search(searchExpression) Stellt eine Suchanfrage an den MuXp Server und liefert ein entsprechendes Suchergenis als searchResult. Die search Methode und die beiden Datentypen searchResult und searchExpression sind derzeit nur als Schnittstelle vorhanden und müssen in weiteren Arbeiten Seite 27 4 Implementierung definiert und implementiert werden. bool publish(xmlUpdate) Durch den Aufruf der Methode publish werden alle angemeldeten Clients über Änderungen benachrichtigt. bool subscribe(clientId, xmlKnoten) Mit subscribe kann sich eine Anwendung für die Benachrichtigung einer Änderung für einen bestimmten XmlKnoten registrieren. bool unSubscribe(clientId, xmlKnoten) Wird eine Benachrichtigung für eine Änderung nicht mehr benötigt, kann sich die Anwendung mit Hilfe der Methode unSubscribe wieder von der Benachrichtigung abmelden. xmlDokument revert(dokumentId) Lädt eine bestimmt Version von einem Dokument und speichert diese als die neueste Version. Ist das Dokument mit der entsprechenden Version nicht vorhanden, wird eine MuXp Exception geworfen. Das Dokument und die Version werden eindeutig durch den struct dokumentId bestimmt. bool setProperty(attributName, attributwert) Mit setProperty können bestimmte Einstellungen, wie beispielsweise der Pfad der XML Datenbank oder die IP Adresse des MuXP Servers, vorgenommen werden. attributWert getProperty(attributName) Mit getProperty können die gespeicherten Einstellungen wieder ausgelesen werden. bool lock(xmlKnoten) Versucht eine Sperre für einen bestimmten XML Knoten zu erwerben und liefert im Erfolgsfall true zurück. bool unLock(xmlKnoten) Entfernt eine Sperre für einen bestimmten XML Knoten. In Abbildung 4.5 ist noch einmal der Zusammenhang der einzelnen Klassen des MuXp Servers als Klassendiagramm detailliert dargestellt. Die Klasse ServerDb implementiert alle Methoden der Schnittstelle ServerDbI und greift auf die Klassen XmlTransactionManager und XmlUpdateManager zu. Es gibt grundsätzlich zwei verschiedene Kategorien Seite 28 4 Implementierung Utility::Database +put(in documentName : string, in xmlDocument : string) : bool +getDocumentByName (in documentName : string) : XmlDocument +getAllDocumentNames () : vector<string> +deleteDocument (in documentName : string) : bool +deleteAllDocuments () : bool Utility::XmlVersionManager +add(in documentName : string, in xmlDocument : string) : bool +store(in documentName : string, in xmlDocument :string) : bool +load(in documentName : string) : XmlDocument +loadVerstion (in documentId : DocId) : XmlDocument +getAllVersions (in documentName : string) : vector<string> +revert(in documentId : DocId) : XmlDocument +erase(in documentName : string) : bool «Schnittstelle» ServerDbI +begin() : TxnId +commit(in txnId : TxnId, in xmlDocument : XmlDocument ) : bool +abort(in txnId : TxnId) : bool +load(in documentId :DocId) : XmlDocument +add(in xmlDocument : XmlDocument ) : bool +erase(in xmlDocument : XmlDocument ) : bool +search(in expression : SearchExpression ) : SearchResult +publish (in update : XmlUpdate ) : bool +subscribe (in clientId : ClientId, in xPath : XMLString ) : bool +unSubscribe (in clientId : ClientId, in xPath : XMLString ) : bool +revert(in documentId : DocId) : XmlDocument +setProperty (in attributeName : string, in attributeValue : string) : bool +getProperty (in attributeValue : string) : string +lock(in xmlKnoten : string) : bool +unlock(in xmlKnoten : string) : bool «implements» Utility:: XmlTransactionManager Server:: ServerDb +begin() : TxnId +commit (in txnId : TxnId) : bool +abort(in txnId : TxnId) : bool Server :: XmlUpdateManager +subscribe (in clientId :ClientId ,in xmlElement : XmlElement ) : bool +unsubscribe (in clientId : ClientId, in xmlElement : XmlElement ) : bool +publish (in update :XmlUpdate ) : bool Abbildung 4.5: UML Klassendiagramm des MuXp Servers von Anfragen, die der Server entgegennehmen kann. Zum einen Anfragen zur Verwaltung von XML Dokumenten und zum anderen Anfragen, die für die Änderungspropagierung zuständig sind. Die Anfragen der Änderungspropagierung werden an den XmlUpdateManager weitergeleitet. Alle anderen Methodenaufrufe zur Verwaltung werden an den XmlTransaktionsManager übergeben. Dieser prüft zunächst, ob eine gültige Tranksaktionsid für den Methodenaufruf vorhanden ist und leitet im Erfolgsfall die Anfrage an den XmlVersionManager weiter. Der XmlVersionManager ist für die Versionsverwaltung der XML Dokumente auf dem Server verantwortlich. Für die Speicherung der Daten arbeitet der Versionsmanager direkt mit der Klasse Database zusammen, welche eine Schnittstelle zur Berkeley DB XML Datenbank bietet. Seite 29 4 Implementierung Workspace Interface Connection XmlVersionManager Database Abbildung 4.6: Struktur des MuXp Workspace 4.1.4 Workspace (Client) Paket In Abbildung 4.6 ist die logische Struktur des MuXp Workspace schematisch dargestellt. Über die Schnittstelle Workspace Interface kann eine Anwendung mit dem Workspace kommunizieren. Zur lokalen Speicherung und Verwaltung von XML Dokumenten werden die Module XmlVersionManager und Database aus dem MuXp Utility Paket verwendet. Die Connection Klasse stellt einen Proxy des MuXp Servers für den Client dar. Sie beinhaltet die gleichen Methoden wie die MuXp Server Schnittstelle und stellt eine Verbindung zum MuXp Server her. In Abbildung 4.7 werden diese Zusammenhänge noch einmal detalliert in Form eines Klassendiagrammes dargestellt. Die Klasse ClientDb implementiert die Schnittstelle ClientDbI. Alle Methodenaufrufe einer Anwendung werden zunächst an den XmlVersionManager weitergeleitet. Kann dieser die Anfrage nicht verarbeiten, übergibt er diese an die Connection Klasse, welche die Anfrage an den MuXp Server weiterleitet. Nur die Connection Klasse kommuniziert direkt mit dem MuXp Server. Sie besitzt die gleichen Methoden wie der MuXp Server und stellt einen Proxy für den Workspace dar. Damit eine Anwendung auf den lokalen Workspace zugreifen kann, stellt das Workspace Interface die folgenden Methoden zur Verfügung. txnId begin() Durch den Aufruf von begin kann die Anwendung eine Transaktion starten. Dazu bekommt sie eine Transaktions-Id zurückgegeben, die bei jeder Operation, die zur Transaktion gehört, mit übergeben werden muss. bool commit(txnId, xmlDokument) Mit commit werden alle Änderungen dauerhaft in der Datenbank gespeichert. bool abort(txnId) Bei einem abort werden alle Änderungen bis zum Transaktionsbeginn rückgängig gemacht. Seite 30 4 Implementierung «Schnittstelle» Connection +begin() : TxnId +commit (in txnId : TxnId, in xmlDocument : XmlDocument ) : bool +abort(in txnId :TxnId) : bool +load(in documentId : DocId) : XmlDocument +add(in xmlDocument : XmlDocument ) : bool +erase(in xmlDocument : XmlDocument ) : bool +search(in expression : SearchExpression ) : SearchResult +publish (in update : XmlUpdate ) : bool +subscribe (in clientId : ClientId, in xPath : XMLString ) : bool +unSubscribe (in clientId : ClientId, in xPath : XMLString ) : bool +revert(in documentId : DocId) : XmlDocument +setProperty (in attributeName : string, in attributeValue : string) : bool +getProperty (in attributeValue : string) : string +lock(in xmlKnoten : string) : bool +unlock(in xmlKnoten : string) : bool Workspace :: ClientDb «implements» Utility::XmlVersionManager +add(in documentName : string, in xmlDocument : string) : bool +store(in documentName : string, in xmlDocument : string) : bool +load(in documentName :string ) : XmlDocument +loadVerstion (in documentId : DocId) : XmlDocument +getAllVersions (in documentName : string) : vector<string> +revert(in documentId : DocId) : XmlDocument +erase(in documentName : string) : bool Utility::Database +put(in documentName : string, in xmlDocument : string) : bool +getDocumentByName (in documentName :string ) : XmlDocument +getAllDocumentNames () : vector<string> +deleteDocument (in documentName : string) : bool +deleteAllDocuments () : bool «Schnittstelle» ClientDbl +begin() : TxnId +commit(in txnId : TxnId, in xmlDocument : XmlDocument ) : bool +abort(in txnId : TxnId) : bool +savePoint (in xmlDocument :XmlDocument ) : bool +load(in documentId : DocId) : XmlDocument +add(in xmlDocument :XmlDocument ) : bool +erase(in documentId : DocId) : bool +dispose (in documentId : DocId) : bool +search(in expression : SearchExpression ) : SearchResult +publish (in update : XmlUpdate ) : bool +subscribe (in clientId : DocId, in xPath : XMLString ) : bool +unSubscribe (in clientId : DocId, in xPath : XMLString ) : bool +revert(in documentId : XmlDocument ) : XmlDocument +setProperty (in attributeName : string, in attributeValue : string) : bool +getProperty (in attributeName : string) : string +lock(in xmlKnoten : string) : bool +unLock(in xmlKnoten : string) : bool Abbildung 4.7: UML Klassendiagramm des Workspace bool savePoint(xmlDokument) Speichert eine temporäre Sicherheitskopie in der lokalen Workspace Datenbank. Diese Methode hat keinen Einfluss auf die MuXp Server Datenbank. xmlDokument load(dokumentId) Fordert das XML Dokument mit der entsprechenden dokumentId vom MuXp Workspace an. bool add(xmlDokument) Mit der Methode add kann ein neues XML Dokument in der MuXp Server Datenbank hinzugefügt werden. Seite 31 4 Implementierung bool erase(dokumentId) Löscht das XML Dokument mit der entsprechenden dokumentId aus der Datenbank. bool dispose(dokumentId) Gibt ein lokales XML Dokument mit der entsprechenden dokumentId frei. searchResult search(searchExpression) Stellt eine Suchanfrage an den lokalen Workspace. Wird lokal kein Ergebnis gefunden, wird die Anfrage an den MuXp Server weitergeleitet. bool publish(xmlUpdate) In bestimmten Zeitabständen werden die Änderungen der Anwendung mit Hilfe der Methode publish veröffentlicht. Diese Methode stellt zunächst nur eine Schnittstelle ohne Funktionaltiät dar und wird in späteren Arbeiten implementiert. bool subscribe(clientId, xmlKnoten) Mit subscribe kann sich eine Anwendung für die Benachrichtigung einer Änderung für einen bestimmten XmlKnoten registrieren. bool unSubscribe(clientId, xmlKnoten) Wird eine Benachrichtigung für eine Änderung nicht mehr benötigt, kann sich die Anwendung mit Hilfe der Methode unSubscribe wieder von der Benachrichtigung abmelden. xmlDokument revert(dokumentId) Lädt eine bestimmt Version von einem Dokument und speichert diese als die neueste Version. Ist das Dokument mit der entsprechenden Version nicht vorhanden, wird eine MuXp Exception geworfen. Das Dokument und die Version werden eindeutig durch den struct dokumentId bestimmt. bool setProperty(attributName, attributwert) Mit setProperty können bestimmte Einstellungen, wie beispielsweise der Pfad der XML Datenbank oder die IP Adresse des MuXP Servers, für den MuXp Workspace vorgenommen werden. attributWert getProperty(attributName) Mit getProperty können die gespeicherten Einstellungen wieder ausgelesen werden. Seite 32 4 Implementierung bool lock(xmlKnoten) Versucht eine Sperre für einen bestimmten XML Knoten zu erwerben und liefert im Erfolgsfall true zurück. bool unLock(xmlKnoten) Entfernt eine Sperre für einen bestimmten XML Knoten. 4.2 Spamix als Testapplikation Zum Testen der einzelnen Funktionen wird die Applikation Spamix, vom IDMT Fraunhofer Ilmenau verwendet. Spamix ist eine grafische Benutzeroberfläche für den Entwurf und die Bearbeitung von spatiotemporalen Audioobjekten. Die Audioobjekte werden intern in einer Baumstruktur gespeichert und können in Raum und Zeit frei auf der grafischen Oberfläche bewegt werden. Für die Verarbeitung nutzt es eine interne Baumstruktur, welche zum Exportieren und Speichern in eine XML Struktur umgewandelt wird. In Spamix wurden alle Funktionen des MuXp Framework integriert und getestet. Eine Übersicht, wie Spamix, der Workspace und der MuXp Server zusammenarbeiten, ist in Form eines UML Klassendiagrammes in Abbildung 4.8 dargestellt. Die Testapplikation Spamix greift auf die Schnittstelle ClientDb des Workspace zu. Jeder Anwendung ist genau ein Workspace zugeordnet, welcher für die Kommunikation mit dem Server verantwortlich ist. Eine direkte Verbindung zwischen Anwendung und Server ist nicht vorgesehen. Damit der Server angemeldete Anwendungen über Änderungen der XML Struktur informieren kann, muss die Anwendung Spamix einen Listener implementieren. Zur Benachrichtigung ruft der Server dann die entsprechende notify Methode im Spamix auf. Soll nun beispielsweise ein Audioobjekt aus der Datenbank geladen werden, ruft Spamix die entsprechende Methode load im Wokrspace auf und bekommt als Rückgabewert ein XML Dokument übergeben. Dieses XML Dokument wird anschließend in eine interne Baumstruktur umgewandelt und mit dem Autorenwerkzeug Spamix weiter verarbeitet. In Abbildung 4.9 wird anhand eines Sequenzdiagrammes das Laden von einem XML Dokument dargestellt. Die Applikaton Spamix ruft die Methode load des Workspace Interfaces ClientDb auf. Anschließend baut die Klasse Connection eine Verbindung mit dem MuXp Server auf und leitet die Anfrage an die load Methode der Server Schnittstelle ServerDb weiter. Der XmlVersionManager generiert aus dem Dokumentnamen und der Versionsnummer den eigentlichen Dokumentennamen unter dem das XML Dokument in der Datenbank gespeichert ist. Durch den Aufruf der Methode getDocumentByName wird das Dokument Seite 33 4 Implementierung Spamix «Schnittstelle» ListenerI +notify(in update :XmlUpdate ) : bool -client «Schnittstelle» ClientDbl +begin() : TxnId +commit(in txnId : TxnId,in xmlDocument : XmlDocument ) : bool +abort(in txnId : TxnId) : bool +savePoint (in xmlDocument :XmlDocument ) : bool +load(in documentId : DocId) : XmlDocument +add(in xmlDocument :XmlDocument ) : bool +erase(in documentId : DocId) : bool +dispose (in documentId : DocId) : bool +search(in expression : SearchExpression ) : SearchResult +publish (in update : XmlUpdate ) : bool +subscribe (in clientId : DocId, in xPath : XMLString ) : bool +unSubscribe (in clientId :DocId, in xPath :XMLString ) : bool +revert(in documentId :XmlDocument ) : XmlDocument +setProperty (in attributeName : string, in attributeValue : string) : bool +getProperty (in attributeName : string) : string +lock(in xmlKnoten : string) : bool +unLock(in xmlKnoten : string) : bool 1 1 «implements» Workspace :: ClientDb 0..* «Schnittstelle» ServerDbI +begin() : TxnId +commit (in txnId :TxnId, in xmlDocument : XmlDocument ) :bool +abort(in txnId :TxnId) : bool +load(in documentId : DocId) : XmlDocument +add(in xmlDocument : XmlDocument ) : bool +erase(in xmlDocument : XmlDocument ) : bool +search(in expression : SearchExpression ) : SearchResult +publish (in update : XmlUpdate ) : bool +subscribe (in clientId : ClientId, in xPath : XMLString ) : bool +unSubscribe (in clientId : ClientId, in xPath : XMLString ) : bool +revert(in documentId : DocId) : XmlDocument +setProperty (in attributeName : string, in attributeValue : string) : bool +getProperty (in attributeValue : string) : string +lock(in xmlKnoten : string) : bool +unlock(in xmlKnoten : string) : bool 1 «implements» -server Server :: ServerDb Abbildung 4.8: UML Klassendiagramm der Schnittstellen von Server und Workspace aus der Datenbank geholt und als Rückgabewert wieder bis zur Workspace Schnittstelle ClientDb zurückgegeben. Nun wird die store Methode im lokalen XmlVersionManager aufgerufen, welcher durch den Aufruf von putDocument das XML Dokument lokal in der Berkeley DB XML Datenbank abspeichert. Letztendlich gibt die Klasse ClientDb das XML Dokument zur weiteren Verarbeitung an die Anwendung Spamix zurück. Seite 34 4 Implementierung Spamix ClientDb load(documentId ) Connection ServerDb load(documentId ) XmlVersionManager load(documentId ) Database load(documentId ) getDocumentByName xmlDocument xmlDocument xmlDocument xmlDocument XmlVersionManager Database store(docName , xmlDocument ) putDocument (docName , xmlDocument ) true true xmlDocument Abbildung 4.9: Sequenzdiagramm Laden von einem XML Dokument 4.3 MuXp Tools 4.3.1 MuXpClient Kommandozeilen Applikation Spamix ist eine sehr komplexe Anwendung, was in vielen Fällen das Testen von einzelnen Funktionen und Schnittstellen sehr schwierig gestaltet. Weiterhin darf aus Gründen der Vertraulichkeit, der Quellcode das Frauenhofer Institut nicht verlassen, was das Testen und Vorführen in anderen Einrichtungen unmöglich macht. Aus diesen Gründen wurde eine MuXpClient Kommandozeilenapplikation entwickelt, welche alle Funktionen und Schnittstellen des MuXp Framework implementiert. Dadurch besteht die Möglichkeit, auch ohne die Applikation Spamix die Funktionalität und die Schnittstellen des MuXp Framework zu testen und zu präsentieren. Ein weiterer Vorteil besteht darin, dass ein Kommandozeilentool in Skripten aufgerufen werden kann, womit komplexe Anfragen automatisiert und simuliert werden können. Die einzelnen Schnittstellen werden durch die Übergabe von Kommandozeilenparametern angesteuert, welche immer von links nach rechts ausgewertet werden. Weiterhin besteht die Möglichkeit Parameter und XML Dokumente als Referenz Seite 35 4 Implementierung auf eine Datei zu übergeben. Damit der Kommandozeileninterpreter feststellen kann, ob es sich um eine Option handelt, wird vor jeden Parameter das Zeichen "--\ geschrieben. Durch den Aufruf von --help wird beispielsweise eine ausführliche Hilfe ausgegeben. Für die wichtigsten Optionen gibt es auch noch eine Kurzschreibweise, die durch ein "-\ gekennzeichnet ist. Für das Ausgeben der Hilfe schreibt man beispielsweise -h. In Listing 4.2 wird die Ausgabe der Hilfefunktion gezeigt. Für jede Option existiert eine kurze Beschreibung und es ist dokumentiert, welche Schnittstelle des MuXp Framework mit welchen Parametern aufgerufen wird. Die Übergabeparamter, wie beispielsweise --docName in Zeile 23, können ebenfalls als Optionen definiert werden und sind im unteren Teil der Hilfe beschrieben. In Zeile 2 ist die allgemeine Syntax für die Benutzung des MuXpClient angegeben. Die Option -f bewirkt, dass der Inhalt der Datei [FILENAME] geladen wird, welcher dann mit den folgenden Optionen weiter verarbeitet werden kann. 1 2 3 Print t h i s help . U s a g e : . / MuXpClient −f [ FILE ] [ OPTIONS ] MuXpClient Commandline A p p l i c a t i o n 4 5 −h , −−h e l p print t h i s help −l , −−l o a d −d , −−d i s p o s e −d e l , −−d e l e t e −add l o a d ( docName ) l o a d a document d i s p o s e ( docName ) a l o c a l document e r a s e ( d o c I d ) d e l e t e a s c e n e i n t h e s e r v e r DB add ( s c e n e ) add a s c e n e −c , −−commit −a , −−a b o r t −b , −−b e g i n −sp ,−− s a v e P o i n t −r , −−r e v e r t commit ( txnId , s c e n e ) commit a t r a n s a c t i o n abort ( txnId ) abort a transacton TxnId b e g i n ( ) b e g i n a t r a n s a c t i o n s a v e P o i n t ( s c e n e ) s t o r e a new s c e n e ( o n l y l o c a l ) r e v e r t ( d o c I d ) −−docName −−v e r s i o n r e v e r t a s c e n −s , −−s u b s c r i b e −u , −−u n s u b s c r i b e −p , −−p u b l i s h −f , −− f i l e −−docName −−xmlContent −−fXmlContent −−v e r s i o n −−xPath s u b s c r i b e ( xmlElement ) s u b s c r i b e f o r a xml eleme u n s u b s c r i b e ( xmlElement ) u n s u b s c r i b e f o r a xml e p u b l i s h ( update ) p u b l i s h an update s e t v a r : fileName s e t v a r s : docName , s c e n e . name , d o c I d . name s e t v a r s : xmlContent , s c e n e . xmlContent i n p u t from a f i l e , s e t v a r s : xmlContent , s c e n e . s e t v a r s : version , docId . v e r s i o n s e t v a r s : xPath , update . xPath xmlElement . xPath 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 Listing 4.2: Ausgabe der MuXpClient Hilfe Anhand von Listing 4.3 soll nun die Benutzung des MuXpClient verständlich erläutert werden. Damit der Client eine Verbindung mit dem MuXpServer aufbauen kann, muss dieser zuerst gestartet werden. In Zeile 1 wird mit der Option -b eine neue TransaktionsId vom MuXp Workspace angefordert. Anschließend wird in Zeile 2 mit --docName der Seite 36 4 Implementierung Name und mit --xmlContent der Inhalt des XML Dokumentes spezifiziert. Durch die Angabe des Parameters -add wird dann die entsprechende Schnittstelle im MuXp Framework aufgerufen, welche ein neues Dokument in der Datenbank anlegt. Es ist wichtig, dass der Parameter -add am Ende angegeben wird, weil ansonsten die Übergabeparameter docName und xmlContent nicht initialisiert sind, was zu einem undefinierten Zustand führt. Um eine neue Version zu speichern, wird in Zeile 3 die Option -c mit der von Zeile 1 generierte Transaktions-Id 0 aufgerufen. Das XML Dokument kann nun durch die Verwendung des Parameters -l wieder aus der Datenbank geladen werden und wird auf dem Standardoutput der Kommandozeile ausgegeben (Zeile 5). Mit der Optien -d und der Angabe von Dokumentname und der Version kann das Dokument anschließend wieder aus der Datenbank gelöscht werden(Zeile 6). Um zwischen den einzelnen Schritten nachvollziehen zu können, welche XML Dokumente in der Workspace- oder Serverdatenbank vorhanden sind, kann das MuXpMonitor Tool verwendet werden, welches im nächsten Abschnitt erklärt wird. 1 2 MuXpClient −b txnId: 0 3 4 5 MuXpClient −−docName ”newDocument” −−xmlContent ”<xml>Content </xml>” −add return: 1 6 7 8 MuXpClient −−docName ”newDocument” −−xmlContent ”<xml>changedContent </xml>” −c 0 commit t x n I d : 0 9 10 11 12 MuXpClient −−docName ”newDocument” − l docName: newDocument c o n t e n t : <xml>chan</xml> 13 14 MuXpClient −−docName ”newDocument” −−v e r s i o n ” 1 ” −d Listing 4.3: Beispielanwendung für den MuXpClient 4.3.2 MuXpMonitor Tool Zum Debuggen und Testen ist es unumgänglich den Zustand und Inhalt der Berkeley DB XML Datenbank abzufragen. Für diesen Zweck wurde das MuXp Monitor Tool entwickelt, welches ebenfalls als Kommandozeilenapplikation zur Verfügung steht. Die Verwendung des Tools ist ähnlich wie beim MuXpClient gestaltet, das heißt die Funktionalität kann mit Optionen spezifiziert werden. In Listing 4.4 ist die Ausgabe der Hilfefunktion dargestellt, welche alle Optionen, die verwendet werden können, erklärt. Die wichtigsten Parameter sind -n zur Ausgabe aller Dokumentnamen und -p zur Ausgabe aller XML Dokumente mit Namen und Metadaten. Die Benutzung der beiden Optionen ist den Zeilen 5 und 6 als Seite 37 4 Implementierung Beispiel dokumentiert. 1 2 3 print t h i s help U s a g e : . / mo ni to r −f [ FILE ] [ OPTIONS ] MuXpMonitor Commandline Tool 4 5 6 7 8 9 −h , −n , −p , −d , −f , −−h e l p −−name −−p r i n t −−d e l e t e −− f i l e print t h i s help p r i n t a l l document names p r i n t t h e c o n t e n t and metadata o f a l l documents d e l e t e a l l documents next input i s a f i l e 10 11 12 13 14 Examples: MuXpMonitor −n MuXpMonitor −p p r i n t a l l document names p r i n t t h e c o n t e n t and metadata o f a l l documents Listing 4.4: Ausgabe der MuXpMonitor Hilfe Seite 38 5 Grundlegende XML Technologien 5.1 Speicherung von XML Daten Für die verteilte Bearbeitung von XML Daten ist es wichtig eine effektive Lösung zur Speicherung und Verwaltung der Daten zu finden. Die einfachste Lösung besteht darin, die XML Dokumente auf dem Dateisystem des Betriebssystemes abzulegen. Diese Form der Speicherung wird von jedem System unterstützt und die Installation von zusätzlicher Software ist nicht erforderlich. Allerdings muss man auf viele essentielle Funktionalitäten, wie beispielsweise die Suche über mehrere XML Dokumente oder Update Operationen verzichten. Weiterhin bietet ein Dateisystem nicht die Möglichkeit, dass mehrere Benutzer gleichzeitig auf den gespeicherten Daten arbeiten können[17]. Eine weitere Möglichkeit ist es, die XML Daten in den zahlreich vorhandenen und sehr gut ausgereiften RDBMS (Relationales Datenbank Managementsystem) abzulegen[2]. Dadurch stehen die bereits bewährten Datenbanktechnologien wie Transaktionsmanagement, Logging, Recovery, Synchronisation und Integritätsregeln zur Verfügung und können ohne zusätzlichen Aufwand genutzt werden. Weiterhin kann die Anfragesprache SQL zum Manipulieren genutzt werden und ein gleichzeitiger Zugriff von mehreren Benutzern ist möglich. Es gibt 2 Möglichkeiten XML in einem RDBMS zu speichern. Eine sehr einfache Variante besteht darin, die Daten direkt als Clob (Character Large Object) oder Blob (Blob Binary Large Object) Feld abzuspeichern, was den Nachteil hat, dass die XML Struktur verloren geht. Weiterhin sind innerhalb dieser Felder keine Datenzugriffsoperationen wie INSERT, UPDATE, SELECT oder DELETE erlaubt, was die Anfrageverarbeitung sehr schwierig gestaltet. Bei der 2. Möglichkeit werden die XML Daten direkt in den Tabellen des RDBMS abgespeichert. Dazu muss die hierarchisch gestaltete XML Struktur in eine flache Tabellenstruktur transformiert werden. Dieses so genannte Mapping ist nicht eindeutig, wodurch zusätzliche Informationen von Hand erstellt werden müssen. Aus diesem Grund ist es nicht möglich, XML Dokumente beliebiger Struktur in den Tabellen eines RDBMS abzubilden. Bei einer Anfrage muss die Ergebnismenge wieder in eine XML 39 5 Grundlegende XML Technologien Struktur umgewandelt werden, wobei nicht sicher gestellt ist, dass die Reihenfolge einzelner Knoten mit dem Ursprungsdokument identisch sind. Weiterhin müssen Anfragen, die in einer XML Anfragesprache formuliert werden, ebenfalls Transformiert werden. 5.1.1 XML Datenbank Ist es erforderlich, XML Dokumente beliebiger Struktur effizient zu speichern und komplexere Suchoperationen darauf auszuführen, ist es sinnvoll eine native XML Datenbank zu verwenden[17]. Sie ist von vornherein für den Umgang mit XML konstruiert und eine Umwandlung in eine Tabellenstruktur ist somit nicht notwendig. Für Anfragen und Manipulationen von Daten werden die vom W3C (World Wide Web Consortium) entwickelten Anfragesprachen wie XPath, XQuery oder XUpdate zur Verfügung gestellt. Weiterhin ist es möglich die Wohlgeformtheit und Gültigkeit eines XML Dokumentes mit Hilfe einer Schema-Validierung beim Speichern zu prüfen. Ein großes Problem für den kommerziellen Einsatz von XML Datenbanken ist die fehlende Sicherstellung der referentiellen Integrität und die Tatsache, dass die Produkte und Standards noch relativ neu sind und sich zum jetzigen Zeitpunkt noch in einem Entwicklungsprozess befinden. 4suite Berkeley DB XML Xpath X X Xquery X Xupdate X DOM SAX C++ API X Transaktionen X X Indexe X X dbXML eXist X X X X X X X X X X X OZONE Xindice X X X X X (X) ? X Tabelle 5.1: Vergleich von nativen XML Datenbanken In der Diplomarbeit [23, S. 46 ff.] von Hendrik Rusch wurden die XML Datenbanken 4suite[1], Berkeley DB XML[19], dbXML[8], eXist[11], OZONE[20] und Xindice[3] untersucht und verglichen. Alle Datenbanken erlauben die native Speicherung von XML Dokumenten und die Verwendung von Transaktionen. Große Unterschiede finden sich in der Unterstützung von XPath, XQuery und den zur Verfügung stehenden APIs. In der Tabelle 5.1 werden die betrachteten Features übersichtlich gegenübergestellt. Berkeley DB XML und eXist erfüllen dabei am besten die benötigten Anforderungen. Letztendlich wurde Berkeley DB XML wegen der C++ API für die Verwaltung und Speicherung von XML Seite 40 5 Grundlegende XML Technologien Dokumenten sowohl im lokalen Workspace als auch im Server verwendet. Im nächsten Abschnitt werden die Einzelheiten von Berkeley DB XML genauer erläutert. Berkeley DB XML Berkeley DB XML[19] wurde von der Firma Sleepycat Software entwickelt und am 14. Februar 2006 von Oracle1 aufgekauft. Die Software wird unter einer dualen Lizenz vertrieben, welche für die kostenlose Nutzung eine Open-Source Version unter der GPL-ähnlichen Oracle Lizenz bereitstellt. Will man die Software kommerziell nutzen, ist es erforderlich, eine kostenpflichtige Oracle Lizenz zu erwerben. Berkeley DB XML ist eine eingebettete native XML Datenbank, welche direkt auf Berkeley DB aufsetzt und deren Funktionalität wie Transaktionen, Recovery, Caching, Logging erbt. Für die Unterstützung von XML wurden ein XML Parser, XML Indexer und eine XQuery Engine ergänzt. Berkeley DB XML unterstützt die Anfragesprachen XQuery 1.0, XPath 2.0 und es bietet die Möglichkeit einer Schema Validierung. Die XML Dokumente werden in logischen Containern als Schlüssel Wert Paare gespeichert. Für jeden Container kann festgelegt werden, ob das Dokument im ganzen oder nur einzelne Teilbäume gespeichert werden sollen. Zusätzlich zu den eigentlichen Daten können Metadaten für jedes Dokument angelegt werden. Berkeley DB XML ist eine Bibliothek, die direkt in die Anwendung eingebettet wird und APIs2 für die Programmiersprachen C++, Java, Tcl, Perl, Python und PHP anbietet. Dadurch erspart man sich die zusätzliche Installation, Konfiguration und Wartung eines separaten Datenbank Management Systems. Für die Implementierung des MuXp Framework wurde die Version 2.2.13 verwendet. 1 2 http://www.oracle.com Programmierschnittstelle - Application Programming Interface Seite 41 5 Grundlegende XML Technologien 5.2 Übertragung von XML Daten Das MuXp Framework ist eine API für ein Mehrbenutzersystem, welches mehreren Nutzern die Möglichkeit bietet, kooperativ XML Daten verarbeiten zu können. Mehrere MuXp Workspaces müssen mit einem zentralen Server kommunizieren. Aus diesem Grund ist es von großer Bedeutung, eine geeignete Kommunikationsschnittstelle zwischen Workspace und Server zu definieren. Bei der Wahl der Schnittstelle war es wichtig eine, möglichst kostengünstige, plattformunabhängige Alternative, mit einer API für C++ zu finden. Wenn möglich sollte die Installation von zusätzlicher Software vermieden werden und eine bidirektionale Kommunikation zwischen Server und Workspace möglich sein. 5.2.1 Analyse verschiedener Technologien für die Netzwerkkommunikation Die elementarste Variante für die Kommunikation zwischen zwei Instanzen sind so genannte Sockets[21], welche eine eine bidirektionale Schnittstelle zur Netzwerkkommunikation zur Verfügung stellen. Sie bilden eine standardisierte API zwischen der Netzwerkprotokollimplementierung des Betriebssystems und der eigentlichen Anwendungssoftware. Sockets sind direkt in C++ integriert und somit sehr einfach zu implementieren. Das hat den Vorteil, dass die Anwendung genau auf die erforderlichen Bedürfnisse angepasst werden kann und nur die wirklich benötigte Funktionalität implementiert werden muss. Nachteilig wirkt sich aus, dass Sockets nur eine Basis für die Netzwerkprogrammierung bilden und damit jede Funktionalität, wie beispielsweise Remote Procedure Calls, Serialisierung oder Exceptions von Hand programmiert werden müssen. Aus diesem Grund ist es mit sehr viel Aufwand verbunden, die für das MuXp Framework benötigten Funktionen und Typdefinietionen zu implementieren. Die Verwendung von bereits entwickelten und ausgereiften Third Party Bibliotheken sollte vorgezogen werden. Eine weitere Möglichkeit bietet das XML basierte Kommunikationsprotokoll SOAP[29]. SOAP stand ursprünglich für Simple Object Access Protocol, was aber seit Version 1.2 nicht mehr als Akronym gebraucht wird. Mit so genannten Remote Procedure Calls3 können zwei Anwendungen miteinander kommunizieren. SOAP nutzt die Dienste anderer Standards. XML zur Repräsentation der Daten und das HTTP (Hypertext Transfer Protocol) Protokoll zur Übertragung von Nachrichten. Die Struktur einer SOAP Nachricht setzt sich aus einem Head für Metainformationen und einem Body für die eigentlichen Daten zusammen. 3 entfernte Prozedur Aufrufe Seite 42 5 Grundlegende XML Technologien Ein großes Problem von SOAP besteht darin, dass es die Menge der zu übertragenden Daten erheblich aufbläht. Für eine Anfrage vergrößert sich die Datenmenge um das 25 fache und Antworten können sogar bis zu 100 mal größer sein als die eigentlichen Daten. Dies ist nicht nur ein Problem der beanspruchten Netzwerkbandbreite, auch das Generieren und Auswerten der Nachrichten erfordert sehr viel Rechenzeit. Die Verarbeitung der Daten ist somit sehr ineffizient und für Leistungskritische Anwendungen unbrauchbar. Für C/C++ existieren die Bibliotheken cSOAP[6] und gSOAP[12]. Auch für andere Programmiersprachen wie Java, .NET, PHP, Delphi, Perl, Python, Ruby, Tcl und Smalltalk sind Implementierungen verfügbar. Die Internet Communications Engine (ICE)[16] ist eine kommunikationsorientierte Middleware zur Vermittlung von Dienstleistungen zwischen Anwendungen in Netzwerken. Die Middleware wurde von der Firma ZeroC[16] entwickelt und ist eine moderne Alternative zu CORBA (Common Object Request Broker Architecture) oder DCOM (Distributed Component Object Model). Sie stellt eine API für die Programmiersprachen C++, C#, Java, Python, Ruby, PHP, und Visual Basic zur Verfügung und ist sowohl für Windows als auch LINUX Plattformen erhältlich. ICE ist sehr einfach zu erlernen und bietet eine ausgereifte Netzwerkinfrastruktur für anspruchsvolle technische Anwendungen. Die Software wird kostenlos als Open Source Software unter der GNU General Public License angeboten. Für closed source4 Software ist ebenfalls eine kommerzielle Lizenz vorhanden. 5.2.2 Vergleich der Technologien Grundsätzlich sind sowohl Sockets, SOAP als auch die Middleware ICE für die Kommunikation zwischen Workspace und Server für das MuXp Framework geeignet. Es gilt nun abzuwägen, welche Kriterien entscheidend für die Auswahl der richtigen Technologie sind. In Tabelle 5.2 sind die 3 betrachteten Technologien mit ihren Vor- und Nachteilen dargestellt. Mit Sockets kann man eine optimale Kommunikationsschnittstelle selber programmieren. Allerdings ist der Aufwand dafür sehr hoch und eine optimale Lösung nicht unbedingt notwendig. Die Benutzung vorhandener Bibliotheken ist daher für die Problemlösung vorzuziehen. Die SOAP Bibliotheken gSOAP und cSOAP bieten eine Open Source API für C++ und sind plattformunabhängig. Ein großer Nachteil ist jedoch die hohe Aufblähung der zu übertragenden Datenmenge, wodurch die Übertragung sehr ineffizient wird. Weiterhin ist die Installation zusätzlicher Software erforderlich. Aus diesem Grund ist die Entscheidung letztendlich auf die ICE Bibliothek gefallen, welche die Anforderungen am 4 Closed Source Software - der Quellcode der Software wird nicht offen gelegt Seite 43 5 Grundlegende XML Technologien besten erfüllt. ICE ist plattformunabhängig, bietet eine API für C++, kann direkt in die Anwendung eingebettet werden und ist kostenlos als Open Source Software erhältlich. Kosten Open Source kommerzielle Lizenz Windows Linux C++ API Overhead Installation zusätzlicher Software eingebettete Software Sockets keine x x x gering x gSOAP keine x x x x x hoch x - cSOAP ICE keine keine x x x x x s x x x hoch gering x x Tabelle 5.2: Vergleich Übertragungsmöglichkeiten von XML Daten 5.2.3 Detallierte Beschreibung der Internet Communications Engine (ICE) ICE Anwendungen können in einer heterogenen Umgebung entwickelt werden. Dadurch können Client und Server in verschiedenen Programmiersprachen implementiert und auf verschiedenen Plattformen betrieben werden. Zur Definition von Schnittstellen, Operationen und Datentypen stellt ICE die IDL (Interface Definition Language) Slice zur Verfügung. Slice erlaubt es, die Schnittstelle zwischen Client und Server unabhängig von einer bestimmten Programmiersprache zu definieren. Mit einem speziellen Slice Compiler wird automatisch eine API für eine bestimmte Programmiersprache erstellt, welche vom Client und Server implementiert werden muss. ICE bietet ein RPC (Remote Procedure Call) Protokoll, welches TCP/IP oder UDP als Transportschicht benutzt. Zusätzlich kann die Kommunikation zwischen Client und Server mit SLL (Secure Sockets Layer) verschlüsselt werden. Zur Minimierung der genutzten Bandbreite können die Daten komprimiert übertragen werden, was vor allem bei großen Datenmengen sehr nützlich ist. Abbildung 5.1 zeigt eine Übersicht der logischen internen Struktur von einem Ice Client in Verbindung mit einem Ice Server. Jeder Ice Server und Client besteht aus einem Anwendungsteil, dem ICE Core und einer Schnittstelle, die vom Slice Compiler automatisch generiert wird. ICE Core Der ICE Core beinhaltet die Laufzeitunterstützung für die Netzwerkkommunikation. Ein großer Anteil des Programmcodes enthält konkrete Implementierungen Seite 44 5 Grundlegende XML Technologien Abbildung 5.1: ICE Client und Server Struktur für die Netzwerk- und Threadunterstützung, die für die Anwendung verborgen bleiben sollen. Der ICE Core besteht aus einer Sammlung von Bibliotheken, welche zur Server oder Client Anwendung gelinkt werden. ICE API Auf den generischen Teil des ICE Core, wird mit Hilfe der ICE API zugegriffen. Die ICE API wird für administrative Zwecke, wie Initialisierung oder Beenden der ICE Laufzeitumgebung, genutzt. Die ICE API ist sowohl für den Server als auch für den Client identisch. Proxy Code Der Proxy Code wird automatisch vom Slice Compiler generiert und enthält Client spezifische Datentypen und Objekte, welche vorher in Slice definiert wurden. Ruft ein Client eine selbst definierte Funktion im Proxy auf, wird sie in Form eines RPC (Remote Procedure Call) an den Server weitergeleitet. Weiterhin hat er die Aufgabe, die zu übertragenden Objekte und Datentypen zu serialisieren. Skeleton Der Skeleton Code wird ebenfalls vom Slice Compiler generiert und enthält Server spezifische Datentypen und Objekte, welche vorher in Slice definiert wurden. Seine Aufgabe und Funktionalität ist äquivalent zum Proxy Code des Clients. Object Adapter Der Object Adapter ist ein Teil der ICE API und wird ausschliesslich Seite 45 5 Grundlegende XML Technologien von ICE Servern benuutzt. Er hat die Aufgabe, Client Anfragen einem bestimmten Dienst zuzuordnen. Seite 46 5 Grundlegende XML Technologien 5.3 Verarbeitung von XML Daten In diesem Kapitel sollen die Grundlagen der Extensible Markup Language, sowei Möglichkeiten zur Verarbeitung, Manipulation und Navigation erläutert werden. 5.3.1 XML Grundlagen XML[22, S. 33ff] ist eine Abkürzung für Extensible Markup Language und beschreibt einen Standard zur Erstellung von strukturierten Dokumenten in Form einer Baumstruktur. XML wurde als Untermenge von SGML (Standard Generalized Markup Language) vom World Wide Web Consortium[27] definiert und ist eine Metasprache, mit der man andere Sprachen wie beispielsweise HTML definieren kann. Mit so genannten Schemasprachen, wie beispielsweise DTD (Dokumenttypdefinition) oder XSD (XML Schema Definition), kann man die Struktur von XML Dokumenten beschreiben. Das Autorenformat XMTSAW für das IOSONO System, welches in der Diplomarbeit von Hendrik Rusch [18, S. 15 ff.] beschrieben ist, wurde mit Hilfe von XML definiert. XML Dokumente werden in die Klassen Gültigkeit und Wohlgeformtheit untergliedert. Ein XML Dokument ist wohlgeformt, wenn es alle Regeln des XML Standards befolgt. Entspricht das Dokument zusätzlich noch den Regeln einer Schemadefinition, wird es als gültig bezeichnet. Jedes gültige XML Dokument ist auch wohlgeformt. Der Umkehrschluss trifft jedoch nicht zu, da es wohlgemormte XML Dokumente geben kann, die nicht gültig sind. Somit sind die gültigen XML Dokumente eine Teilmenge der wohlgeformten XML Dokumente. Für die Verarbeitung von XML Dokumenten werden XML Parser verwendet, welche das gesamte XML Dokument auswerten und die enthaltenen Informationen an die Anwendung zurückgeben. XML Parser können in validierende und nicht validierende Parser unterteilt werden. Ein nicht validierender Parser prüft ein XML Dokument auf Wohlgeformtheit, das heisst, das Dokument muss die Regeln des XML Standards befolgen. Ein validierender Parser überprüft ein XML Dokument auf Gültigkeit, was bedeutet es muss wohlgeformt sein und die Regeln einer Schemadefinition einhalten. Das Validieren eines XML Dokumentes ist allerdings sehr aufwendig und sollte nur verwendet werden, wenn es unbedingt notwendig ist. Eine weitere Unterteilung der XML Parser wird anhand der Schnittstelle, mit der auf die Daten zugegriffen wird, vorgenommen. Es existieren die Spezifikation DOM (Document Object Model[26]) und die Schnittstelle SAX (Simple API for XML[15]). Seite 47 5 Grundlegende XML Technologien SAX - Simple API for XML Die Simple API for XML[22, S. 197-244] ist ein Pseudo Standard und wurde nicht wie andere Mitglieder der XML Familie vom W3C, sondern von David Megginson veröffentlicht. Ein SAX Parser arbeitet ereignisbasiert und interpretiert die XML-Dokumente als sequentiellen Datenstrom. Für definierte Ereignisse werden festgelegte Callback Funktionen5 aufgerufen. Damit die XML Daten ausgewertet werden können, muss die Anwendung die Funktionalität der Callback Funktionen implementieren. SAX ist besonders für die Verarbeitung beliebig großer Dokumente geeignet, weil nicht das gesamte XML Dokument in den Speicher geladen werden muss. Aus diesem Grund hat man auch keinen freien Zugriff auf beliebige Elemente eines Dokumentes. Ein weiterer Nachteil besteht darin, dass SAX nur auf lesende Zugriffe beschränkt ist. SAX ist unabhängig von einer Programmiersprache definiert und es existiert eine Vielzahl von Parsern für Java, C++, C, C# und PHP. DOM - Document Object Model Das Document Object Model (DOM)[22, S. 159-195] ist vom W3C definiert und bietet einen neutralen objektorientierten Mechanismus für die Bearbeitung von XML Dokumenten. Im Gegensatz zu SAX können der Inhalt, die Struktur und das Layout eines Dokuments verändert werden. Weiterhin kann die XML Struktur mit Hilfe von Standard Funktionen zur Navigation leicht durchsucht und Informationen extrahiert werden. DOM ist sehr speicherintensiv, weil immer das gesamte XML Dokument zur Verarbeitung in den Speicher geladen werden muss. Aus diesem Grund eignet es sich nicht für die Verarbeitung von großen XML Dateien. DOM ist unabhängig von einer Programmiersprache definiert und es existiert eine Vielzahl von Parsern für Java, C++, C, C# und PHP. Für das MuXp Framework wird der XML Parser Xerces-C[5] von Apache6 verwendet. Er bietet eine API für C++ und implementiert sowohl die DOM Spezifikation als auch SAX. Xerces-C ist kostenlos als Open Source Software unter der Apache Software License Version 2.0[4] verfügbar. 5.3.2 Adressierung und Manipulation von XML Dokumenten Für die Adressierung von einzelnen Teilen eines XML Dokumentes hat das W3C Konsortium die Anfragesprache XPath[22, S. 330ff] definiert. Das Akronym XPath steht für 5 6 Rückruffunktionen Apache Software Foundation - ehrenamtlich arbeitende Organisation zur Förderung der Apache Softwareprojekte http://www.apache.org Seite 48 5 Grundlegende XML Technologien XML Path Language[28]. Ein XPath Ausdruck setzt sich aus so genannten Location Steps zusammen, die durch einen / getrennt sind. Jeder Location Step besteht aus einer Achse zur Navigation, einem Knotentest zur Einschränkung von Elementen und aus optionalen Prädikaten zur weiteren Einschränkung der Ergebnismenge. Die Open Source Bibliothek Pathan[9] erweitert den Xerces-C Parser von Apache um die Verwendung von XPath Ausdrücken. Pathan wurde gemeinsam von DecisionSoft[10], Sleepycat Software7 , Stylus Studio[24] und Parthenon Computing[7] entwickelt. XQuery[14] steht für XML Query Language und bezeichnet eine vom W3C spezifizierte Abfragesprache für XML Datenbanken. XQuery ist semantisch identisch mit SQL (Structured Query Language) und wurde als Erweiterung von XPath entwickelt. Mit den so genannten FLWOR Ausdrücken können XML Dokumente manipuliert, gelesen und generiert werden. FLWOR ist eine Abkürzung für die Konstrukte for, let, where, order by und return, und kann als Analogie zu den (SELECT, FROM, WHERE) - Konstrukten in SQL betrachtet werden. In der in Kapitel 5.1.1 beschriebenen XML Datenbank Berkeley DB XML wurde XQuery 1.0 implementiert. 7 Sleepycat Software im Februar 2006 von Oracle[19] übernommen Seite 49 6 Fazit und Ausblick In dieser Studienarbeit wurde ein Framework für die Verarbeitung und Speicherung von XML Daten in Multiuser Client-Server Anwendungen geschaffen. Das entwickelte Framework stellt zunächst erst einmal eine Grundstruktur mit der erforderlichen Funktionalität dar. Es wurden die Andwendungsszenarien Single-User-Betrieb, Workgroup-Betrieb und Workspace-Betrieb erarbeitet und die benötigten Schnittstellen für den Workspace und Server analysiert, definiert und implementiert. Für die Speicherung und Verarbeitung der XML Dokumente wird die XML Datenbank Berkeley DB XML von Oracle verwendet, welche unter einer Open Source Lizenz verfügbar ist. Die Kommunikation zwischen Workspace und Server wurde mit der CORBA ähnlichen ICE Bibliothek der Firma ZeroC realisiert, welche ebenfalls unter einer Open Source Lizenz vertrieben wird. Um die Funktionalität des MuXp Framework anhand einer konkreten Anwendung zu testen, wurden die entwickelten Ergebnisse in die Testapplikation Spamix integriert. Damit wurde gezeigt, dass die kooperative Verabeitung und Speicherung von XML Daten in Multiuser Client-Server Anwendungen möglich ist. Um das gesamte Potential der entwickelten Ansätze nutzen zu können, ist es notwendig, das Framework um weitere Funktionen zu erweitern. Der implementierte Versionierungsmanager speichert für jede neue Version immer das gesamte XML Dokument. Diese Art der Versionierung ist sehr ineffizient und speicherintensiv. In weiteren Arbeiten sollen andere Ansätze untersucht und implementiert werden. Bei der täglichen Arbeit mit einer Vielzahl von Informationen ist es sehr nützlich, nach einzelnen Attributen oder Knoten suchen zu können. Dafür muss ein geeigneter Suchalgorithmus entworfen und in das MuXp Framework integriert werden. Für das kooperative Arbeiten an einem XML Dokument ist es erforderlich, für einzelne XML Knoten Sperren zu setzen. Dafür sind geeignete Sperrprotokolle zu untersuchen und in das vorhande Framework zu integrieren. Für die Änderungspropagierung wurde das Modul XmlUpdateManager entwickelt, welches zunächst nur Anwendungen, die einen XML Knoten verfolgen wollen, registrieren und abmelden kann. Es ist erforderlich, eine Datenstruktur für die Änderungspropagierung zu erarbeiten und Methoden für das Benachrichtigen der angemeldeten Applikationen zu implementieren. Weiterhin muss ein Listener in 50 6 Fazit und Ausblick die Testapplikation Spamix integriert werden, welcher die Anwendung über Änderungen benachrichtigt. Seite 51 Literaturverzeichnis [1] 4suite: XML Datenbank 4suite. – http://4suite.org/ [2] Akmal B. Chaudhri, Roberto Z.: XML data management. Addison-Wesley, 2003. – ISBN 0–201–84452–4 [3] Apache: About Apache Xindice. – http://xml.apache.org/xindice/ [4] Apache: Apache License, Version 2.0. – http://www.apache.org/licenses/LICENSE-2.0.html [5] Apache: Xerces-C++ Documentation. 2005. – http://xml.apache.org/xerces-c/pdf/xerces-c.pdf [6] Ayaz, Ferhat: cSOAP Client/Server SOAP library in pure C. – http://csoap.sourceforge.net/ [7] Computing, Parthenon: XML software solutions. – http://www.parthcomp.com/ [8] dbXML: XML Datenbank dbXML. – http://www.dbxml.com/product.html [9] Decisionsoft: Pathan. – http://software.decisionsoft.com/pathanIntro.html [10] DecisionSoft: XBRL and XML solutions. – http://software.decisionsoft.com [11] eXist: Open Source Native XML Database. – http://exist.sourceforge.net/ [12] Genivia: gSOAP: C/C++ Web Services and Clients. – http://gsoap2.sourceforge.net/ [13] IDMT, Fraunhofer: IOSONO. . – http://www.iosono-sound.com/ [14] Katz, Howard: XQuery from the Experts. Addison-Wesley, 2004. – ISBN 0–321–18060–7 [15] Megginson, David: SAX - Simple API for XML. – http://www.saxproject.org/ 52 Literaturverzeichnis [16] Michi Henning, Mark S.: Distributed Programming with Ice. ZeroC, 2006. – http://www.zeroc.com/ [17] Mittermeier, Ludwig: XML und Datenbanken Naiv nativ. In: iX (2000), August. – http://www.heise.de/ix/artikel/2003/08/042/ [18] Münnich, Katrin: Untersuchung und Implementierung von Speicher- und Übertragungsformaten für Mischwerkzeuge der Klangfeldsynthese, Technische Universität Ilmenau, Diplomarbeit, 2003 [19] Oracle: A Comparison of Oracle Berkeley DB and Relational Database Management Systems. 2006. – http://www.oracle.com/database/docs/Berkeley-DB-v-Relational.pdf [20] OZONE: Ozone Database Project. – http://www.ozone-db.org/ [21] Pollakowski, Martin: Grundkurs Socketprogrammierung mit C unter Linux. Vieweg, 2004. – ISBN 3–528–05884–6 [22] Richard Anderson, Michael Kay u.: XML Professionell. MITP Verlag, 2000. – ISBN 3–8266–0633–7 [23] Rusch, Hendrik: Verwaltung spatio-temporaler Daten für die wellenfeldsynthese, Technische Universität Ilmenau, Diplomarbeit, 2005 [24] Studio, Stylus: XML productivity through innovation. – http://www.stylusstudio.com [25] Verheijen, Edwin: Sound Reproduction by Wave Field Synthesis. 1997. – Dissertation, Delft University of Technology [26] W3C: DOM - Document Object Model. – http://www.w3.org/DOM/ [27] W3C: XML - Extensible Markup Language. – http://www.w3.org/XML/ [28] W3C: XPath - XML Path Language. – http://www.w3.org/TR/xpath [29] Weerawarana, Sanjiva: Web services platform architecture. Prentice Hall International, 2005. – ISBN 0–13–148874–0 Seite 53 Abkürzungsverzeichnis ALSA . . . . . . . . API . . . . . . . . . . Blob . . . . . . . . . . Clob . . . . . . . . . CORBA . . . . . . DCOM . . . . . . . DOM . . . . . . . . . DTD . . . . . . . . . FLWOR . . . . . . GNU . . . . . . . . . HTML . . . . . . . HTTP . . . . . . . . ICE . . . . . . . . . . IDL . . . . . . . . . . IDMT . . . . . . . . MuXp . . . . . . . . PHP . . . . . . . . . RDBMS . . . . . . SAX . . . . . . . . . SGML . . . . . . . . SOAP . . . . . . . . SQL . . . . . . . . . . UML . . . . . . . . . W3C . . . . . . . . . WAV . . . . . . . . . XML . . . . . . . . . XPath . . . . . . . . XQuery . . . . . . Advanced Linux Sound Architecture Application Programming Interface Binary Large Object Character Large Object Common Object Request Broker Architecture Distributed Component Object Model Document Object Model Dokumenttypdefinition For, Let, Where, Order By, Return rekursives Akronym für GNU is Not Unix Hypertext Markup Language Hypertext Transfer Protocol Internet Communications Engine Interface Definition Language Fraunhofer-Institut für Digitale Medientechnologie Multiuser XML Processing Hypertext Preprocessor Relationales Datenbank Managementsystem Simple API for XML Standard Generalized Markup Language Simple Object Access Protocol Structured Query Language Unified Modeling Language World Wide Web Consortium Containerformat zur digitalen Speicherung von Audiodaten Extensible Markup Language XML Path Language XML Query Language 54 Literaturverzeichnis XSD . . . . . . . . . XML Schema Definition XUpdate . . . . . XML Update Language Seite 55 Quellcodeverzeichnis 4.1 4.2 4.3 4.4 Beispiel Property Datei . . . . . . . . . . Ausgabe der MuXpClient Hilfe . . . . . Beispielanwendung für den MuXpClient Ausgabe der MuXpMonitor Hilfe . . . . 56 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 36 37 38 Tabellenverzeichnis 4.1 Übersicht der möglichen Exceptioncodes . . . . . . . . . . . . . . . . . . . 26 5.1 5.2 Vergleich von nativen XML Datenbanken . . . . . . . . . . . . . . . . . . . Vergleich Übertragungsmöglichkeiten von XML Daten . . . . . . . . . . . . 40 44 57 Abbildungsverzeichnis 2.1 2.2 2.3 Das Huygenssche Prinzip . . . . . . . . . . . . . . . . . . . . . . . . . . . . IOSONO Architektur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Szenengraph einer Beispielszene . . . . . . . . . . . . . . . . . . . . . . . . 3.1 3.2 3.3 3.4 3.5 Single-User-Betrieb . . . . . . . . Typischer Anwendungsfall für den Multi-User-Betrieb . . . . . . . . Beispiel Sperrverfahren . . . . . . Beispiel Versionierung . . . . . . 4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8 4.9 Übersicht MuXp Framework . . . . . . . . . . . . . . . . Struktur MuXp Framwork . . . . . . . . . . . . . . . . . Beispiel Versionierung . . . . . . . . . . . . . . . . . . . Struktur des MuXp Servers . . . . . . . . . . . . . . . . UML Klassendiagramm des MuXp Servers . . . . . . . . Struktur des MuXp Workspace . . . . . . . . . . . . . . UML Klassendiagramm des Workspace . . . . . . . . . . UML Klassendiagramm der Schnittstellen von Server und Sequenzdiagramm Laden von einem XML Dokument . . 5.1 . . . . . . . . . . . . Single-User-Betrieb . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 10 12 14 15 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Workspace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 18 22 27 29 30 31 34 35 ICE Client und Server Struktur . . . . . . . . . . . . . . . . . . . . . . . . 45 58 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 5 7