Erzeugung von Maskenschnittstellen aus mehrrelationalen Datenbankschemata Studienarbeit Christian Stahlhut Matr.-Nr. 1937473 Betreuung: Prof. Dr. Udo Lipeck Dipl.-Math. Thomas Esser Institut für Informatik, Abteilung B: Datenbanken und Informationssysteme Universität Hannover Hannover, den 16. Oktober 2001 Zusammenfassung Im Rahmen dieser Studienarbeit soll ein Programmpaket zur Erzeugung von Maskenschnittstellen aus mehrrelationalen Datenbankschemata erstellt werden. Eine Maske soll den Benutzern die Selektion, sowie das Einfügen, Ändern und Löschen von Tupeln der zugehörigen Relation ermöglichen. Hierbei sind entsprechende Schnittstellen zur Ein- und Ausgabe vorzusehen. Außerdem ist eine Listensicht zu implementieren, die eine Übersicht des jeweiligen Anfrageergebnisses liefert. Um inhaltlich zusammenhängende Daten aus verschiedenen Relationen gemeinsam bearbeiten zu können, sollen zugehörige Masken untereinander über Verbundbedingungen zu einem Maskensystem verknüpft werden können. Der Einsatzbereich der Masken ist möglichst weit zu fassen; daher bietet sich an das Programmpaket in Java zu implementieren. Das zugrundeliegende Datenbanksystem ist Oracle 8i. Eine Anpassung an andere Systeme soll jedoch mit möglichst wenig Aufwand möglich sein. Dies legt die Nutzung von JDBC (Java Database Connectivity) nahe. Inhaltsverzeichnis 1 Allgemeine Konzepte 1.1 Aufgabenstellung . . . . . . . . . . . . . . . . . . . . 1.2 Grundanforderungen an eine Maske . . . . . . . . . . 1.2.1 Grundlegende Funktionalität . . . . . . . . . . 1.2.2 Navigation, Listen- und Tupelsicht . . . . . . 1.2.3 Ein- und Ausgabeschnittstellen . . . . . . . . 1.2.4 Maskensysteme und Untermasken . . . . . . . 1.2.5 Mehrbenutzerbetrieb . . . . . . . . . . . . . . 1.3 Konzepte und Lösungsansätze . . . . . . . . . . . . . 1.3.1 Ein- und Ausgabeschnittstellen - UI-Elemente 1.3.2 Untermasken . . . . . . . . . . . . . . . . . . 1.3.3 Datenbankanbindung . . . . . . . . . . . . . . 1.3.4 Datenbankoperationen . . . . . . . . . . . . . 1.4 Vergleich zu anderen Arbeiten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 3 3 3 4 4 5 5 6 6 7 8 8 8 2 Benutzerhandbuch für Masken 2.1 Allgemeines . . . . . . . . . . . . . . . . . . . . . . . . 2.2 Installation . . . . . . . . . . . . . . . . . . . . . . . . 2.2.1 Voraussetzungen . . . . . . . . . . . . . . . . . 2.2.2 Starten einer Maske . . . . . . . . . . . . . . . . 2.2.3 Abhängigkeiten (Komponenten, Java-Classpath) 2.3 Aufbau einer Maske . . . . . . . . . . . . . . . . . . . . 2.4 Programmstart . . . . . . . . . . . . . . . . . . . . . . 2.5 Basisfunktionen . . . . . . . . . . . . . . . . . . . . . . 2.5.1 Navigation . . . . . . . . . . . . . . . . . . . . . 2.5.2 Einstellungen . . . . . . . . . . . . . . . . . . . 2.5.3 Suchen (Selektion, Auswahl, Anfrage) . . . . . . 2.5.4 Einfügen neuer Datensätze . . . . . . . . . . . . 2.5.5 Eingabefelder leeren . . . . . . . . . . . . . . . 2.5.6 Ändern von Datensätzen . . . . . . . . . . . . . 2.5.7 Löschen von Datensätzen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 10 10 10 10 11 11 11 13 14 16 16 17 17 17 17 1 2.5.8 2.5.9 2.5.10 2.5.11 2.5.12 Alle Änderungen übernehmen oder verwerfen Felder zurücksetzen (Undo) . . . . . . . . . . Untermasken . . . . . . . . . . . . . . . . . . Sichten ein- und ausschalten . . . . . . . . . . Maske schließen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 18 18 20 20 3 Benutzerhandbuch des Editors 3.1 Allgemeines . . . . . . . . . . . . . . . . . . . . . . . . 3.2 Installation . . . . . . . . . . . . . . . . . . . . . . . . 3.2.1 Voraussetzungen . . . . . . . . . . . . . . . . . 3.2.2 Starten des Editors . . . . . . . . . . . . . . . . 3.2.3 Abhängigkeiten (Komponenten, Java-Classpath) 3.3 Programmstart . . . . . . . . . . . . . . . . . . . . . . 3.4 Erstellen einer neuen Maske . . . . . . . . . . . . . . . 3.4.1 Konfiguration der Maskenelemente . . . . . . . 3.4.2 Allgemeine Parameter der Maske . . . . . . . . 3.4.3 Eine Maske testen . . . . . . . . . . . . . . . . 3.4.4 Eine Maske speichern . . . . . . . . . . . . . . . 3.4.5 Eine Maske laden . . . . . . . . . . . . . . . . . 3.5 Ändern von Masken . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 21 21 21 21 22 22 24 24 32 32 34 34 35 . . . . . . . . . 36 36 36 38 39 43 43 45 45 45 4 Implementation 4.1 Struktur . . . . . . . . . . . . . . . . . . . . . . 4.1.1 Der Editor . . . . . . . . . . . . . . . . . 4.1.2 Der Maskeninterpreter . . . . . . . . . . 4.1.3 Die UI-Elemente . . . . . . . . . . . . . 4.1.4 Die Datenbankkomponenten . . . . . . . 4.1.5 diverse Resourcen . . . . . . . . . . . . . 4.2 Anpassung und Erweiterbarkeit . . . . . . . . . 4.2.1 Hinzufügen von UI-Elementen . . . . . . 4.2.2 Anpassung an andere Datenbanksysteme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 Ausblick 47 A Format von Parameterdateien 48 2 Kapitel 1 Allgemeine Konzepte 1.1 Aufgabenstellung Gefordert ist ein Programmpaket zur Erzeugung von Maskenschnittstellen (oder kurz Masken) aus mehrrelationalen Datenbankschemata. Die so zu einer Relation erzeugten Masken sollen den Benutzern die Selektion, sowie das Einfügen, Ändern und Löschen von Tupeln der zugehörigen Relation ermöglichen. Hierbei sind entsprechende Schnittstellen zur Ein- und Ausgabe vorzusehen. Außerdem ist eine Listensicht zu implementieren, die eine Übersicht des jeweiligen Anfrageergebnisses liefert. Um inhaltlich zusammenhängende Daten aus verschiedenen Relationen gemeinsam bearbeiten zu können, sollen zugehörige Masken untereinander über Verbundbedingungen zu einem Maskensystem verknüpft werden können. Die Masken sollen möglichst unabhängig vom verwendeten Betriebssystem einsetzbar sein. Daher bietet es sich an das Programmpaket in Java (Version 1.3 oder höher) zu implementieren. Das zugrundeliegende Datenbanksystem ist Oracle 8i. Eine Anpassung an andere Systeme soll jedoch mit möglichst wenig Aufwand möglich sein. 1.2 1.2.1 Grundanforderungen an eine Maske Grundlegende Funktionalität Eine Maske soll dem Benutzer die grundlegenden Operationen zur Bearbeitung ermöglichen: die Auswahl (= Selektion, Anfrage, Suche), sowie das Einfügen, Ändern und Löschen von Tupeln der zugehörigen Relation. 3 1.2.2 Navigation, Listen- und Tupelsicht Selbstverständlich muß im jeweiligen Anfrageergebnis auch navigiert werden können. Um dies zu unterstützen, soll eine Maske eine Listensicht“ bieten, ” die dem Benutzer ausgewählte Attributwerte eines Großteils der angefragten Tupel auflistet. Zunächst muß es jedoch möglich sein Kriterien zur Auswahl von Tupeln eingeben zu können; dies geschieht in einer Tupelsicht“. Die” se ist mit der Listensicht gekoppelt und zeigt das dort gewählte Tupel an. Umgekehrt ist auch in der Tupelsicht eine rudimentäre Navigation möglich: Das ausgewählte Tupel in der Listensicht wechselt entsprechend, wenn man in der Tupelsicht zum vorigen oder nächsten Tupel blättert“. ” Weiterhin können in der Tupelsicht die Operationen zur Bearbeitung der Tupel gewählt und Untermasken aufgerufen werden (siehe 1.2.4). 1.2.3 Ein- und Ausgabeschnittstellen Grundsätzlich ist es bei der Erstellung des geforderten Programmpakets nicht möglich für alle potentiell in einer Datenbank benutzbaren Datentypen eine Schnittstelle zu implementieren. Zum Beispiel können spezielle Datentypen erst im Nachhinein in das Datenbanksystem eingebracht werden. Auch kann die gewünschte Ein- und Ausgabedarstellung abhängig vom Kontext der Relation verschieden sein. Deshalb müssen die Ein- und Ausgabeschnittstellen einer Maske möglichst modular entworfen werden. Dies soll gewährleisten, daß zu jedem Datentyp und jeder gewünschten Darstellung passende Schnittstellen implementiert werden können - auch im Nachhinein. Beispiele: • Bei Eingaben kann es wünschenswert sein den Wertevorrat des zugehörigen Attributs anzeigen zu lassen und dann einen Wert zu wählen. Dies kann in einer dynamischen Variante (die Werte werden aus der Datenbank gelesen) oder einer statischen Variante (die Werte stehen beim Erstellen der Maske fest) vorliegen. Die dargebotene Auswahlliste sollte hierbei auch aus decodierten Werten bestehen können: Statt zum Beispiel das (kryptische) Kürzel eines Mitarbeiters zu wählen, wählt man stattdessen den vollen Namen aus. • Für manche Datentypen ist eine Spezialisierung nützlich. So kann zum Beispiel ein Preis den Datentyp Zahl“ haben. In diesem Fall soll ” jedoch ein Währungssymbol ausgegeben werden oder gar eine automatische Umrechnung stattfinden. Beispiel: Eingabe: 5 DM, automatische Umrechnung, Ausgabe: 2.56 (in der Standardwährung Euro) 4 • Bei der Kriterieneingabe macht es manchmal Sinn (zum Beispiel bei Zeichenketten) keine exakte Übereinstimmung des eingegebenen Werts mit dem Attributwert des Tupels zu fordern, sondern nur eine partielle. Zum Beispiel sollte eine Anfrage mit dem Wert ’Hans’ beim Attribut ’Vorname’ alle Personen(tupel) mit dem Vornamen ’Hans’ liefern - auch ’Hans Peter’. 1.2.4 Maskensysteme und Untermasken Um inhaltlich zusammenhängende Daten aus verschiedenen Relationen gemeinsam bearbeiten zu können, sollen zugehörige Masken untereinander über Verbundbedingungen zu einem Maskensystem verknüpft werden können. Die Verbundbedingungen setzen die Attribute einer Partnerrelation mit den Attributwerten des aktuell in der Maske angezeigten Tupels in Beziehung. Aus der Maske heraus kann dann auch eine neue Maske zu der Partnerrelation mit den Verbundbedingungen geöffnet werden. (Solch eine Maske sei mit Un” termaske“, die Maske aus der die Untermaske aufgerufen wird mit Haupt” maske“ bezeichnet.) Existiert eine Fremdschlüsselbeziehung zwischen zwei Relationen, zeigt dies eine mögliche Hauptmaske/Untermaske Situation an. Wie bei Listen- und Tupelsicht sind auch Haupt- und Untermaske gekoppelt: Da die in der Untermaske angezeigte Ergebnismenge von dem in der Hauptmaske ausgewählten Tupel abhängt, ändert sich bei einer anderen Auswahl auch die Ergebnismenge in der Untermaske. Als Beispiel sei zu einer Filmdatenbank eine Maske gegeben, die in der Tupelsicht Informationen zu einem bestimmten Film anzeigt. Durch einen Knopf mit der Aufschrift Schauspieler“ wird eine Untermaske geöffnet, die ” in einer Listensicht alle an dem Film beteiligten Schauspieler auflistet. Wählt man dann in der Hauptmaske einen anderen Film aus, so ändert sich automatisch auch die Liste der beteiligten Schauspieler. Untermasken sollen selbst wieder als Hauptmasken agieren können, also selbst wieder Untermasken enthalten können. Die Unterscheidung zwischen Unter- und Hauptmaske ist jedoch bei dem hier vorgestellten Konzept (siehe 1.3) rein inhaltlich: Zugelassen sind mehrere Masken zu einer Relation, die beliebig als Unter- oder Hauptmaske benutzbar sind. Der Benutzer kann damit im Prinzip den Einstiegspunkt in das Maskensystem (aus den vorhandenen Masken) selbst bestimmen. 1.2.5 Mehrbenutzerbetrieb Die Maske soll von mehreren Benutzern gleichzeitig benutzt werden können. 5 Abbildung 1.1: Die Struktur des Programmpakets Wollen mehrere Benutzer zur gleichen Zeit das gleiche Tupel bearbeiten, sollte dies nur dem Benutzer erlaubt werden, der die erste Eingabe macht. Für andere Benutzer ist das Tupel zu sperren bis die Änderungen abgeschlossen und die neuen Daten angefragt wurden. 1.3 Konzepte und Lösungsansätze Zunächst wird eine Applikation benötigt, mit der aus einem gegebenen Datenbankschema Masken generiert werden können. Diese Applikation sei mit Editor“ bezeichnet. ” Bei dem hier gewählten Ansatz erzeugt der Editor aus einem Datenbankschema und Spezifikationen des Benutzers eine Datei. Diese Datei ( Para” meterdatei“) enthält alle Parameter für die zu erstellende Maske. Um nun daraus eine Maske zu generieren, existiert eine weitere Applikation, die Parameterdateien auswerten kann und mit dieser Information dem Benutzer eine entsprechende Maske darbietet. Diese Applikation sein mit Maskeninterpreter“ bezeichnet. ” Beide Programme sind in Java implementiert um eine möglichst große Plattformunabhängigkeit zu erreichen. 1.3.1 Ein- und Ausgabeschnittstellen - UI-Elemente Da die Ein- und Ausgabeschnittstellen für Attributwerte in Masken möglichst modular sein müssen (siehe 1.2.3), ist eine erweiterbare Bibliothek von Klas6 sen zu implementieren, die diese Schnittstellenfunktionen übernehmen. Die für eine bestimmte Maske benötigten Klassennamen stehen in der Parameterdatei und werden nach dem Start des Maskeninterpreters geladen. Durch dieses dynamische Laden ist es möglich der Bibliothek weitere Klassen hinzuzufügen, ohne den Maskeninterpreter ändern zu müssen. Da der Editor die Parameterdatei erzeugt, müssen ihm bereits die Klassennamen bekannt sein. Auch muß festgestellt werden, ob eine bestimmte Klasse ein Attribut überhaupt darstellen kann. Weiterhin muß es möglich sein den Klassen verschiedene Parameter zu übermitteln, wie zum Beispiel einen statischen Wertevorrat oder eine Spezialisierung von Zahl auf Preis (siehe 1.2.3). Dies macht es notwendig zu jeder Klasse der Bibliothek für die Ein- und Ausgabe in Masken eine Klasse für den Editor zu schreiben, die eben diese Aufgaben übernimmt. Solch ein Paar von Klassen sei mit UI” Element“ bezeichnet, die Klasse für die Maske mit Maskenteil“ und die ” für den Editor mit Editorteil“. ” Der Masken- und Editorteil eines UI-Elements erbt jeweils von einer abstrakten Oberklasse, die die Schnittstelle zum jeweiligen Programmteil spezifiziert. Die bereits im Programmpaket enthaltenen UI-Elemente weisen eine detaillierter Strukturierung auf: Gleichartige Schnittstellen (z.B. Eingabefelder) werden zunächst abstrakt definiert und dann in konkreten Klassen für verschiedene Datentypen genutzt (siehe Implementation). 1.3.2 Untermasken Für die Realisierung von Untermasken wird von der Hauptmaske aus eine weitere Instanz des Maskeninterpreters mit der Parameterdatei für die Untermaske und den jeweiligen Verbundbedingungen aufgerufen. Wird in der Hauptmaske ein anderes Tupel ausgewählt, so werden die neuen Verbundbedingungen an die Instanz des Maskeninterpreters für die Untermaske weitergegeben. Das Anfrageergebnis der Untermaske wird daraufhin aktualisiert. Stellt man in der Untermaske eine neue Anfrage, so unterliegt die Ergebnismenge stets den von der Hauptmaske übernommenen Verbundbedingungen. Wird in zwei verschiedenen Instanzen des Maskeninterpreters (also z.B. Haupt- und Untermaske) das gleiche Tupel angezeigt, so wird die Bearbeitung nur für genau eine Instanz erlaubt, für andere Instanzen wird das Tupel gesperrt. Wurden die Änderungen mit der Datenbank abgeglichen oder die sperrende Instanz geschlossen, werden die Sperren wieder freigegeben. Diese Verfahrensweise ist analog zur Mehrbenutzerregelung (siehe 1.2.5). 7 1.3.3 Datenbankanbindung Die Gewährleistung einer Anpassungsmöglichkeit an andere Datenbanksysteme als Oracle 8i wird durch die Kapselung der Datenbankzugriffe in eigene Klassen erreicht. Zusätzlich wird in diesen Klassen weitgehend JDBC 2.0 eingesetzt. Ob jedoch ein anderes Datenbanksystem alle benötigten JDBCFunktionen implementiert, oder ob JDBC überhaupt unterstützt wird, kann nicht garantiert werden. Editor und Maskeninterpreter greifen nur durch die gekapselten Klassen auf das Datenbanksystem zu. Bei einem Wechsel sind daher auch nur diese Klassen anzupassen. 1.3.4 Datenbankoperationen Teil der Klassen zur Kapselung des Datenbankzugriffs ist eine Klasse, die ein Anfrageergebnis kapselt. Diese Klasse erlaubt neben der Anfrage selbst, auch die grundlegenden Operationen zur Bearbeitung: Ändern, Einfügen und Löschen von Tupeln. Ein durch diese Operationen modifiziertes Anfrageergebnis wird erst auf Wunsch des Benutzers für die Datenbank freigegeben ( committed“). Davor ” kann der Benutzer einige oder alle dieser Modifikationen rückgängig machen. Beginnt der Benutzer ein bestehendes Tupel zu ändern, wird dieses Tupel für alle anderen Benutzer gesperrt. Diese Sperre wird erst wieder freigegeben, wenn der Benutzer alle seine Änderungen verworfen oder mit der Datenbank abgeglichen hat ( committed“ hat). Dies sichert die Anforderungen für einen ” Mehrbenutzerbetrieb. 1.4 Vergleich zu anderen Arbeiten Beeinflußt wurde diese Studienarbeit durch andere Arbeiten zum Thema Erzeugung von Maskenschnittstellen“ die am Institut für Informatik entstan” den sind: Dies sind Metamask“ [1] beziehungsweise das zugrundeliegende ” Flit“ sowie JForms“ [2]. ” ” JForms“ ist ein Teil der Diplomarbeit Arnim von Helmolts, in der auf ” die Problematik einer allgemeinen automatischen Maskengeneration für Relationen und Sichten eingegangen wird. Die dort angesprochenen Lösungen zu Problemen von Masken auf allgemeine Sichten wurden hier nicht berücksichtigt. Masken auf Sichten sind mit dem hier vorgestellten Programmpaket nur möglich wenn die Aktionen select, update, insert und delete ohne Konflikte (wie bei normalen Relationen) durchführbar sind. Die exemplarische Maskengenerator Applikation (siehe [2], Kapitel 4) diente jedoch als 8 Anregung für das Schema des Editors. Besonders die Konzepte der Benutzeroberfläche und der Modularität der Ein- und Ausgabeschnittstellen lassen sich in diesem Programmpaket wiederfinden. An den von Metamask“ erzeugten Masken ist größtenteils die Handha” bung der hier vorgestellten Masken orientiert. Die Funktionalität wurde jedoch an manchen Stellen verändert und ergänzt: • Mit Metamask ist es nicht möglich Maskensysteme zu erstellen. Mit dem vorliegenden Programmpaket ist die Verknüpfung von Masken möglich (vgl. 1.2.4). • Die Metamask-Masken sind entweder im Startzustand der Kriterieneingabe für eine neue Suche, oder im Zustand der Neueingabe für neue Daten. Da sich das Umschalten zwischen diesen Zuständen in der Praxis als unkomfortabel erwiesen hat, sind diese beiden Zustände hier verschmolzen: Der Benutzer kann zunächst Daten eingeben und dann entscheiden, was mit den Eingabedaten geschehen soll. • Die Listenansicht von Flit besteht lediglich aus einem Text, in dem bestimmte Attribute der Ergebnistupel aufgelistet sind. Hier ist eine Listensicht vorhanden, die mit der Tupelsicht interagiert und somit als Navigationshilfe dient. • Metamask erzeugt für eine Maske eine komplette Java-Applikation und diverse Parameterdateien. Der Editor im hier vorgestellten Programmpaket erzeugt eine einzige Datei, die alle Daten enthält um die konstruierte Maske darzustellen. • Die Konzepte zur Ein- und Ausgabeschnittstellen wurden modular erweitert. So ist es möglich komfortablere Schnittstellen in den Masken einzusetzen und sogar im Nachhinein speziell angepaßte Schnittstellen in das System zu integrieren. • Durch die Benutzung der JDBC 2 Funktionen des Oracle-JDBC-Treibers ist es nun nicht mehr nötig das Anfrageergebnis im Hintergrund einzulesen. Außerdem muß die Applikation keine Kopie der Ergebnismenge im Speicher halten. Dies ermöglicht die Erstellung von Masken zu umfangreicheren Relationen. • Für die Benutzeroberfläche der Java-Applikation wird Swing statt AWT benutzt. 9 Kapitel 2 Benutzerhandbuch für Masken 2.1 Allgemeines Eine Maske zu einer bestehenden Tabelle wird durch den Maskeninter” preter“ erzeugt. Dies ist eine Applikation, die die Spezifikation der Maske aus einer Datei ( Parameterdatei“) liest und die Maske dann entsprechend ” anzeigt. 2.2 2.2.1 Installation Voraussetzungen Der Maskeninterpreter ist eine Java-Applikation und benötigt eine Java Virtual Machine Version 1.3 oder höher, sowie ein System auf dem JavaApplikation (in annehmbarer Geschwindigkeit) ausführbar sind. Das standardmäßig zugrundeliegende Datenbanksystem ist Oracle 8i. Für andere Systeme muß das Programmpaket entsprechend angepaßt werden (siehe Dokumentation der Implementation). 2.2.2 Starten einer Maske Um eine den Maskeninterpreter mit einer Maske unter einer Linux/Unix Umgebung zu starten kann das dem Programmpaket beiliegende Skript maske“ ” benutzt werden. Als einziger Parameter ist der Name der zur Maske gehörigen Parameterdatei zu übergeben: also zum Beispiel maske meineMaske.mask“. ” Um den Maskeninterpreter unter anderen Umgebungen zu starten und bei eigenen Änderungen der Verzeichnisstruktur des Programmpakets sind folgende Abhängigkeiten zu beachten: 10 2.2.3 Abhängigkeiten (Komponenten, Java-Classpath) Das Programmpaket umfasst die Verzeichnisse code“, welches den eigentli” chen Maskeninterpreter enthält und shared“, in dem vom Paket unabhängi” ge Komponenten enthalten sind. Eine Maske mit zugehöriger Parameterdatei meineMaske.mask“ läßt sich ” mit java code.mask.Mask meineMaske.mask“ starten, sofern alle benötig” ten Verzeichnisse im Java-Classpath eingetragen sind. Folgende Verzeichnisse werden benötigt: • code/mask: der Maskeninterpreter • code/db: Datenbankanbindung • code/ui: Ein- und Ausgabeschnittstellen • code/res: Konfigurationsdateien und diverse Resourcen • shared, Datei dbis.jar: Klassen zur Datenbankansteuerung des Instituts für Informatik, Abteilung B Datenbanken und Informationssy” steme“ • shared JDBC-Datenbanktreiber (zum Beispiel classes111.zip für Oracle 8i) 2.3 Aufbau einer Maske Eine Maske bietet grundsätzlich zwei mögliche Ansichten auf die Einträge einer Tabelle (Relation). Die einfache ist die Listensicht, in der ausgewählte Spalten (Attribute) mehrerer Zeilen (Tupel) der Tabelle angezeigt werden. Dies dient der Übersicht; Änderungen können hier nicht vorgenommen werden. Um einzelne Tupel der Relation bearbeiten zu können existiert eine Tupelsicht, in der alle (notwendigen) Attributwerte des Tupels zu sehen sind. 2.4 Programmstart Nach dem Programmstart des Maskeninterpreters wird zunächst vom Benutzer verlangt sich mit Benutzernamen und Passwort in die Datenbank einzuloggen (Abb. 2.1). Ist der Login erfolgreich, wird je nach Inhalt der Parameterdatei die Listensicht (Abb. 2.2), die Tupelsicht (Abb. 2.3) oder beide geöffnet. 11 Abbildung 2.1: Login für eine Maske Abbildung 2.2: Eine Listensicht nach dem Start der Maske 12 Abbildung 2.3: Eine Tupelsicht nach dem Start der Maske Die anfängliche Auswahl enthält alle Tupel der Relation. Das bedeutet, daß in der Listensicht eine Übersicht aller Tupel zu sehen ist. Jedoch ist noch kein Tupel in der Liste ausgewählt. Dementsprechend erscheint in der Tupelsicht zunächst ein leeres Eingabefeld (wie 2.5.5). Eine Navigation in der Tupelauswahl ist von hier aus möglich (siehe 2.5.1). 2.5 Basisfunktionen Generell ist das Bearbeiten von Tupeln nur in der Tupelsicht möglich, da die Listensicht nur als Übersicht dient. Damit sind die Funktionen Suchen“, ” Einfügen“, Löschen“, Ändern“, Änderungen übernehmen/verwerfen“ und ” ” ” ” Änderung zurücknehmen“ nur dort verfügbar. Knöpfe zur Aktivierung sind ” am rechten Rand der Tupelsicht zu finden (Abb. 2.4). Untermasken (siehe 2.5.10) können aus Tupel- und Listensicht heraus geöffnet werden. Eine Eingabe, etwa Kriterieneingabe für die Suche oder die Eingabe von Attributwerten von Tupeln zum Ändern oder Einfügen, geschieht immer in der Tupelsicht. Die dort vorhandenen Eingabeschnittstellen (meist Textfelder) sind unabhängig vom Maskeninterpreter implementiert. Daher lassen sich hier nicht alle möglichen Eingabemethoden dokumentieren. 13 Abbildung 2.4: In der Tupelsicht verfügbare Funktionen Standardmäßige Funktionen der Eingabeschnittstellen sind zum Beispiel: • Einfache Ein- und Ausgabe des Wertes in ein Textfeld • Auswählbare statische Werte (Abb. 2.5) • Auswählbare (dynamische) Werte aus der Datenbank (Abb. 2.6) • Bei der Kriterieneingabe: Übernahme eines Tupels in die Ergebnismenge, auch bei partieller Übereinstimmung mit der Eingabe. (Zum Beispiel sollte eine Anfrage mit dem Wert ’Hans’ beim Attribut ’Vorname’ alle Personen(tupel) mit dem Vornamen ’Hans’ liefern - auch ’Hans Peter’.) Für die sinnvolle Zusammenstellung aller angebotenen Schnittstellen ist der Erzeuger der Maske zuständig. 2.5.1 Navigation Um im Datenbestand navigieren zu können, ist es in der Listensicht möglich ein dort angezeigtes Tupel mit der Maus auszuwählen. Daraufhin wird dieses in der Tupelsicht dargestellt und kann dort bearbeitet werden. 14 Abbildung 2.5: Auswahl aus einem statischen Wertevorrat Abbildung 2.6: Auswahl aus einem statischen Wertevorrat 15 Abbildung 2.7: Der Einstellungen-Dialog Umgekehrt ist auch in der Tupelsicht eine rudimentäre Navigation möglich: mit dem ’<’-Knopf gelangt man zum vorigen Tupel, mit dem ’>’-Knopf zum nächsten (Abb. 2.4). Dies ändert wiederum die Auswahl in der Listensicht entsprechend. In der Listensicht sind Knöpfe mit der Beschriftung ’vorige Seite’ und ’nächste Seite’ vorhanden (Abb. 2.2). Da in der Listensicht nur eine bestimmte Anzahl von Tupeln dargestellt wird (= 1 Seite), die möglicherweise kleiner ist, als die Gesamtzahl der Tupel im aktuellen Anfrageergebnis, kann der Benutzer sich so trotzdem alle Tupel anzeigen lassen. Die maximale Anzahl der Tupel pro Seite kann vom Benutzer eingestellt werden (siehe 2.5.2). Weil eine Liste mit mehr Tupeln auch mehr Systemresourcen benötigt, kann der Benutzer damit die Listensicht gemäß seinem System anpassen. Weiterhin kann es bei einer schlechten Anbindung an die Datenbank und einer großen Anzahl darzustellender Tupel pro Seite auch einfach zu lange dauern, bis die Listensicht gefüllt ist. 2.5.2 Einstellungen Die Einstellungen sind über die obere Menüleiste erreichbar (Menüpunkt Maske/Einstellungen). Hier können die Anzahl der Tupel pro Seite in der Listensicht und die Sortierreihenfolge der Tupel und angegeben werden (Abb. 2.7). Vorgegebene Sortierungen können über die Auswahlliste ausgewählt und (falls gewünscht) verändert werden. Hierbei ist die Sortierung wie eine SQL Order-By-Klausel (ohne das order by“) in der Form [Spaltenname] ” asc/desc anzugeben, wobei asc für aufsteigende und desc für absteigende Sortierung steht. 2.5.3 Suchen (Selektion, Auswahl, Anfrage) Um eine Auswahl von Tupeln aus einer Relation zu treffen, werden die Werte (oder Wertemuster, wie ’%...%’ bei Strings) der Attribute eingegeben, die 16 allen Tupeln der Ergebnismenge gemein sein sollen. Nach einer Betätigung des ’Suchen’-Knopfes wird die neue Ergebnismenge mit der Maske verknüpft und somit in Tupel- und Listensicht angezeigt. Gibt es noch Änderungen in der alten Ergebnismenge, die noch nicht übernommen wurden, wird der Benutzer vorher darauf hingewiesen. Der Knopf ’letzte Kriterien’ läßt bei Betätigung die bei der letzten Suche benutzten Kriterien in der Tupelsicht erscheinen. 2.5.4 Einfügen neuer Datensätze Um ein neues Tupel der Relation hinzuzufügen, müssen zunächst alle Attributwerte des neuen Tupels in die Tupelsicht eingegeben werden. Dann kann der ’Einfügen’-Knopf gedrückt werden, womit dann das neue Tupel eingefügt wird. Die neuen Daten werden nach dem Druck auf den ’Änderungen übernehmen’-Knopf (2.5.8) in die Datenbank übernommen. 2.5.5 Eingabefelder leeren Für die Kriterieneingabe zur Suche oder beim Einfügen eines neuen Datensatzes kann es sinnvoll sein alle Attributwerte der Tupelsicht zu leeren. Dies geschieht nach der Aktivierung des ’Eingabefeld leeren’-Knopfs. Durch diese Aktion wird das vorher angezeigte Tupel nicht verändert oder gar gelöscht. Die Navigation ist weiterhin möglich; wird jedoch ein Tupel ausgewählt, sind die Eingaben im leeren“ Eingabefeld verloren. ” 2.5.6 Ändern von Datensätzen Um bestimmte Attributwerte eines Tupels zu ändern, können diese Änderungen in der Tupelsicht eingegeben werden. Alle Änderungen werden nach dem Druck auf den ’Änderungen übernehmen’-Knopf (2.5.8) für die Datenbank freigegeben. 2.5.7 Löschen von Datensätzen Soll ein Tupel der Relation gelöscht werden, kann dies über den ’Löschen’Knopf geschehen. Solange die Änderungen nicht übernommen wurden (siehe 2.5.8), wird das Tupel immer noch angezeigt. Jedoch ist es nicht mehr möglich in der Tupelsicht zu diesem Tupel Eingaben zu machen (Abb. 2.8); in der Listensicht ist die Zeile des Tupels leer. 17 Abbildung 2.8: Ein gelöschtes Tupel 2.5.8 Alle Änderungen übernehmen oder verwerfen Änderungen schließen hier das Einfügen, Ändern und Löschen von Tupeln ein. ’Änderungen übernehmen’ gibt alle gemachten Änderungen für die Datenbank frei, ’Änderungen verwerfen’ verwirft sie. 2.5.9 Felder zurücksetzen (Undo) Hierbei werden alle Änderungen am ausgewählten Tupel zurückgenommen: Änderungen an den Attributwerten des Tupels werden verworfen, neue Tupel werden gelöscht und ein gelöschtes wieder hergestellt. Diese Operation hat keine Auswirkungen auf die Datenbank. 2.5.10 Untermasken Eine Untermaske ist eine Maske, die von einer anderen Maske ( Hauptmaske“) ” aus geöffnet wird. Die in der Untermaske angezeigten Tupel sind hierbei gewissen Bedingungen unterworfen, die von den Attributwerten des in der Hauptmaske ausgewählten Tupels abhängen. So könnte zum Beispiel zu einem Film(tupel) alle mitwirkenden Schauspieler(tupel) durch eine Untermaske abrufbar sein. Untermasken sind als Knöpfe in der Tupelsicht realisiert: 18 Abbildung 2.9: Die Liste der Schauspieler zum ausgewählten Film Klickt man auf solch einen Knopf, öffnet sich die Untermaske (Abb. 2.9). Die Untermaske ist mit der Hauptmaske gekoppelt. Das heißt wählt man in der Hauptmaske ein anderes Tupel aus, so ändert sich die Bedingung der Untermaske und auch die in der Untermaske angezeigten Tupel. (Im Beispiel: Wählt man einen anderen Film, werden nun in der Untermaske die Schauspieler zu diesem Film angezeigt.) Wird in zwei verschiedenen Masken (also z.B. Haupt- und Untermaske) das gleiche Tupel angezeigt, so wird die Bearbeitung nur für genau eine Maske erlaubt, für andere wird das Tupel gesperrt. Wurden die Änderungen mit der Datenbank abgeglichen (vgl. 2.5.8) oder die sperrende Maske geschlossen, werden die Sperren wieder freigegeben. (Diese Verfahrensweise ist analog zur Regelung beim Mehrbenutzerbetrieb.) Untermasken können geschlossen werden (siehe 2.5.12) ohne das die Hauptmaske geschlossen wird. Das Schließen der Hauptmaske hat jedoch das Beenden der Applikation und somit das Schließen aller Untermasken zur Folge. 19 2.5.11 Sichten ein- und ausschalten Mittels ’Listensicht EIN/AUS’ beziehungsweise ’Tupelsicht EIN/AUS’ können die entsprechenden Sichten ein- und wieder ausgeschaltet werden. Dies ist in jeder Sicht möglich. Wird die letzte Sicht der Hauptmaske geschlossen, so entspricht dies dem Maske schließen“-Befehl (2.5.12). ” 2.5.12 Maske schließen Um die Maskenapplikation zu beenden, kann in der Listen- und Tupelsicht der Menüpunkt Maske/Maske schließen gewählt werden. Tupel- und Listensicht sowie alle Untermasken werden damit geschlossen. Gibt es noch Änderungen, die noch nicht übernommen wurden (siehe 2.5.8), wird der Benutzer vorher darauf hingewiesen. 20 Kapitel 3 Benutzerhandbuch des Editors 3.1 Allgemeines Der Editor ist eine Java-Applikation mit der anhand von Metadaten aus einer Datenbank und Benutzereingaben Dateien ( Parameterdateien“) erzeugt ” werden können. Eine solche Datei enthält alle relevanten Parameter zur Erzeugung einer Maske. Eine andere Java-Applikation (der Maskeninterpre” ter“, siehe Benutzerhandbuch für Masken) stellt anhand dieser Parameter ein entsprechendes Maskenformular dar. 3.2 3.2.1 Installation Voraussetzungen Der Editor ist eine Java-Applikation und benötigt eine Java 2 Virtual Machine Version 1.3 oder höher, sowie ein System auf dem Java-Applikation (in annehmbarer Geschwindigkeit) ausführbar sind. Das standardmäßig zugrundeliegende Datenbanksystem ist Oracle 8i. Für andere Systeme muß das Programmpaket entsprechend angepaßt werden (siehe Dokumentation der Implementation). 3.2.2 Starten des Editors Um eine den Editor unter einer Linux/Unix Umgebung zu starten kann das dem Programmpaket beiliegende Skript editor“ benutzt werden. Als einzi” ges Argument kann beim Start der Dateiname einer Parameterdatei übergeben werden. Dies entspricht einem normalen Programmstart bei dem sofort die angegebene Datei geladen wird (siehe 3.3 und 3.4.5). 21 Um den Maskeninterpreter unter anderen Umgebungen zu starten und bei eigenen Änderungen der Verzeichnisstruktur des Programmpakets sind folgende Abhängigkeiten zu beachten: 3.2.3 Abhängigkeiten (Komponenten, Java-Classpath) Das Programmpaket umfasst die Verzeichnisse code“, welches den eigentli” chen Editor enthält und shared“, in dem vom Paket unabhängige Kompo” nenten enthalten sind. Der Editor läßt sich mit java code.editor.Editor“ starten, sofern alle ” benötigten Verzeichnisse im Java-Classpath eingetragen sind. Folgende Verzeichnisse müssen im Java-Classpath eingetragen sein: • code/editor: der Editor • code/mask: der Maskeninterpreter zum Testen einer Maske • code/db: Datenbankanbindung • code/ui: Ein- und Ausgabeschnittstellen • code/res: Konfigurationsdateien und diverse Resourcen • shared, Datei dbis.jar: Klassen zur Datenbankansteuerung des Instituts für Informatik, Abteilung B Datenbanken und Informationssy” steme“ • shared JDBC-Datenbanktreiber (zum Beispiel classes111.zip für Oracle 8i) Damit der Editor die UI-Elemente (siehe unten) dynamisch laden kann, muß in der Datei config.conf im Verzeichnis code/res unter ui path der Pfad zu den UI-Elementen angegeben sein (also zum Beispiel code/ui/editor). 3.3 Programmstart Während des Programmstarts wird zunächst versucht die UI-Elemente für den Editorteil zu laden. Danach wird die Benutzeroberfläche gestartet (Abb. 3.1). Im oberen Teil des Editors befinden sich zwei vertikal angeordnete Listen. Die linke mit Auswahl überschriebene Liste enthält alle Elemente, die der Benutzer noch in die Maske einbringen kann (wie Spalten oder Untermasken). Die rechte Liste (überschrieben mit Maske) enthält die bereits in die Maske 22 Abbildung 3.1: Der Editor nach dem Start 23 übernommenen Elemente. Nach dem Start des Programms sind diese Listen leer (Abb. 3.1). Im unteren Teil sind mehrere Reiter angebracht: • Information: Hier erscheinen Informationen zur Spalte oder Untermaske des zuletzt angewählten Elements. • Konfiguration: Hier kann das in der rechten Liste ausgewählte Maskenelement konfiguriert werden. • Allgemein: Hier werden allgemeine Parameter der Maske konfiguriert. 3.4 Erstellen einer neuen Maske Um eine neue Maske zu erstellen, ist zunächst in der Menüleiste der Punkt Datei/neue Maske zu wählen (Abb. 3.2). Daraufhin erscheint ein Dialog um die Verbindung zu einer Datenbankinstanz herzustellen. Hier muß der Benutzername, das Paßwort und die URL der gewünschten Datenbankinstanz eingetragen werden (Abb. 3.3). Ist die Datenbankverbindung hergestellt, wird eine Liste der Tabellen angezeigt (Abb. 3.4). Dies sind alle Tabellen der Datenbankinstanz auf die der angemeldete Benutzer Leserechte hat. Hier kann nun die Tabelle ausgewählt werden, für die eine Maske erstellt werden soll. (Sichten werden nicht aufgelistet und müssen eigenhändig in das Eingabefeld eingetragen werden.) Wurde eine Tabelle ausgewählt, werden die Metainformationen zu dieser Tabelle aus der Datenbank gelesen. Alle Spalten der Tabelle werden in die Maske übernommen (erscheinen also in der rechten Liste). Potentielle Untermasken (also Fremdschlüsselbeziehungen zwischen der gewählten und anderen Tabellen) werden ebenfalls übernommen. Sie stehen jedoch auch zur Auswahl in der linken Liste, falls eine Untermaske nochmals mit anderen Verbundbedingungen hinzugefügt werden soll. Außerdem ist es über den Eintrag [neue Untermaske] möglich Untermasken zu beliebigen Tabellen einzufügen (Abb. 3.5). 3.4.1 Konfiguration der Maskenelemente Die in der rechten, mit Maske überschriebenen Liste stehenden Elemente ( Maskenelemente“) machen die Maske aus: Ein Element, das eine Tabel” lenspalte beschreibt ( Spaltenelement“) wird in der From ’Beschreibung ” (Spaltenname)’ angezeigt, eine Untermaske in der Form ’Beschreibung 24 Abbildung 3.2: Eine neue Maske erstellen Abbildung 3.3: Login an eine wählbare Datenbankinstanz Abbildung 3.4: Liste der verfügbaren Tabellen 25 Abbildung 3.5: Parameter einer neuen Maske 26 Abbildung 3.6: Die erstellte Maske mit unveränderten Parametern (Tabellenname)’. Zusätzlich enthält jede Darstellung am Ende eine Positionsangabe der Form ’[Zeile, Spalte]’ (Abb. 3.5). Daraus läßt sich schließen, daß in der Maske zunächst in jeder Zeile genau 1 Element steht - was sich durch einen Druck auf den ’Maske testen’-Knopf bestätigt (Abb. 3.6, siehe 3.4.3). Detailliertere Informationen zum zuletzt ausgewählten Element sind unter dem Reiter Information zu finden. Unter dem Reiter Konfiguration können die Elemente in der rechten Liste konfiguriert werden. Spaltenelemente Um ein Spaltenelement zu konfigurieren, muß dies in der rechten Liste ausgewählt, also in die Maske übernommen worden sein. Dann können unter dem Reiter Konfiguration diverse Einstellungen vorgenommen werden (Abb. 3.7): • Position: Das Element kann in der Maske um eine Spalte höher oder tiefer verschoben werden. Außerdem veranlaßt der Knopf ’neue Zeile/Zeilen verbinden’ die Verbindung oder Trennung der Zeile des Elements mit der nächsten Zeile. 27 • Spalte: Hier ist nochmals der Spaltenname des Elements aufgeführt. • Beschreibung: Die Beschreibung des Eingabefeldes in der Maske ist hier einzutragen. • in der Listensicht anzeigen: Ist dieses Feld aktiviert, so wird diese Spalte auch in der Listenansicht der Maske angezeigt; standardmäßig sind dies nur die Primärschlüssel. • UI-Element: Hier kann die Ein- und Ausgabeschnittstelle spezifiziert werden. Diese Schnittstellen können dem System auch im Nachhinein hinzugefügt werden und können deshalb hier nicht umfassend erläutert werden. Standardmäßige Schnittstellen sind einfache Eingabefelder, sowie statische und dynamische Auswahlmöglichkeiten. • UI-Parameter: Die schnittstellenspezifischen Parameter können hier eingestellt werden: – einfache Eingabefelder: Hier kann die Länge des Eingabefeldes in Zeichen eingestellt werden. Die Schnittstelle zu einem Datum läßt auch die Eingabe einer Formatierungsvorschrift zu. – Beim ’Zahlfeld mit Einheit’ ist es möglich eine Standardeinheit und mehrere weitere Einheiten samt Umrechnungsfaktor anzugeben (Abb. 3.8). Wird dann in der Maske ein Wert in einer anderen als der Standardeinheit angegeben, wird er sofort in diese umgerechnet. – Eine statische Auswahl läßt dem Benutzer nur die Wahl zwischen vorher angegebenen Werten, die im Parameterdialog angegeben werden können. Hierbei kann der in die Beschreibung und der in der Datenbank verwendete Wert verschieden sein (zum Beispiel ’Ja’ statt 1, ’Nein’ statt 0) (Abb. 3.9). – Eine dynamische Auswahl bietet dem Benutzer eine Liste mit den aktuell in der Datenbank vorhandenen Werten in der Spalte. Im Parameterdialog (Abb. 3.10) kann die dazu nötige Anfrage spezifiziert werden. Weiterhin ist es möglich die eigentlichen Werte zu verstecken: Für die Auswahl von Mitarbeiterkürzeln kann eine Anfrage nach Kürzel, Vorname und Name angegeben werden. Dann wird ’erste Spalte darstellen’ deaktiviert. Damit sieht der Benutzer den vollen Namen der Mitarbeiter und erhält nach der Auswahl trotzdem das gewünschte Kürzel (die erste Spalte im Anfrageergebnis). 28 Die Auswahl wird in einem einfachen Eingabefeld angezeigt und kann verändert werden. Untermasken Wie bei Spaltenelementen, muß zur Konfiguration das Untermaskenelement in die Maske übernommen worden sein. Untermasken sind als Knopf in der Maske realisiert, auf dessen Betätigung eine neue Instanz des Maskeninterpreters mit den anzugebenden Parametern erzeugt wird. Unter dem Reiter Konfiguration stehen folgende Konfigurationsmöglichkeiten zur Auswahl (Abb. 3.11): • Position: Wie bei den Spaltenelementen kann die Position der Untermaske verändert werden. • Die Auswahllisten ’Tabelle der Untermaske’ und ’Spalten’ geben eine Übersicht über die in der Datenbank vorhandenen Tabellen und ihren Spalten. Diese Listen dienen lediglich zur Information um kompliziertere Verbundbedingungen einfacher formulieren zu können. • Beschreibung: die Beschreibung des Knopfs für die Untermaske • Start der Untermaske als: Hier kann angegeben werden, ob die Untermaske in der Tupelsicht, Listensicht oder beidem starten soll. • Maskendatei: Hier ist der Dateiname der Parameterdatei der Untermaske einzutragen. Ist die Untermaske noch nicht konstruiert, kann hier (falls bekannt) trotzdem der Dateiname eingetragen werden - das Öffnen der Untermaske scheitert dann natürlich. • Bedingung: Die Bedingung, die für die Ergebnismenge der Untermaske in Abhängigkeit vom in der Hauptmaske angezeigten Tupel gelten soll muß hier eingegeben werden. Die Bedingung ähnelt einer SQL-Query ohne den select“-Teil: Zunächst muß die from“-Klausel angegeben ” ” werden, wobei zumindest die Tabelle der Untermaske enthalten sein muß. Dann kann die where“-Bedingung spezifiziert werden, die die ” eigentliche Verbundbedingung enthält. Ausdrücke die mit ’::’ beginnen und denen ein gültiger Spaltenname der Tabelle der Hauptmaske folgt, werden durch den entsprechenden Wert aus der Hauptmaske ersetzt. Wurde eine Untermaske aus der Auswahl in die Maske übernommen, ist stets eine vorformulierte Bedingung vorhanden. 29 Abbildung 3.7: Konfiguration eines Spaltenelements 30 Abbildung 3.8: Konfiguration eines Zahlfeldes mit Einheit Abbildung 3.9: Konfiguration einer statische Auswahlliste 31 Abbildung 3.10: Konfiguration einer dynamischen Auswahlliste 3.4.2 Allgemeine Parameter der Maske Unter dem Reiter Allgemein können allgemeine Einstellungen zur Maske gemacht werden (Abb. 3.12): • Überschrift: Hier kann die Überschrift der Maske eingegeben werden. • Die Maske startet als: Der Startmodus der Maske (Tupelsicht, Listensicht oder beides) kann hier eingestellt werden. Wird die Maske als Untermaske genutzt, so gelten die bei der Konfiguration der Untermaske gemachten Angaben. • Zeilenanzahl in der Tupelsicht: Hier kann die vorgegebene Anzahl von Tupeln pro Seite in der Listensicht der Maske eingestellt werden. • Unter ’Sortierreihenfolgen’ können verschiedene Sortierungen für die Ergebnismenge einer Anfrage angegeben werden. Diese sind in der Form einer SQL Order-By-Klausel (ohne das order by“) anzugeben, also ” zum Beispiel year desc, title asc“ oder nachname, vorname“. ” ” 3.4.3 Eine Maske testen Zur Überprüfung der gemachten Einstellungen kann die Maske aus dem Editor heraus getestet werden (Menüpunkt Datei/Maske testen oder der entsprechende Knopf unten rechts). Dies führt zum Start einer Instanz des Maskeninterpreters“ (siehe Benutzerhandbuch für Masken) mit einer Pa” rameterdatei, die die aktuellen Einstellungen enthält. Die Testmaske ist voll funktionsfähig und entspricht vollkommen einer herkömmlich gestarteten 32 Abbildung 3.11: Konfiguration einer Untermaske 33 Abbildung 3.12: Allgemeine Parameter der Maske Maske. Während die Testmaske geöffnet ist, kann mit dem Editor weitergearbeitet werden. Zwischenzeitliche Änderungen werden jedoch nicht sofort auf die Testmaske übertragen; um eine neue Testmaske zu erhalten kann wieder Maske testen“ aufgerufen werden. Es ist nicht nötig die alte Test” maske vorher zu schließen, dies sollte jedoch aus Performancegründen und der Übersichtlichkeit halber trotzdem geschehen. 3.4.4 Eine Maske speichern Um eine Maske (oder genauer die sie beschreibende Parameterdatei) zu speichern, ist in der Menüleiste der Punkt Datei/Parameterdatei speichern beziehungsweise Datei/Parameterdatei speichern unter zu wählen. spei” chern unter“ speichert die Parameterdatei zur aktuellen Maske unter einem vom Benutzer einzugebenden Dateinamen ab. speichern“ speichert die aktu” elle Maske unter dem aktuellen Dateiname; ist noch kein aktueller Dateiname mit speichern unter“ spezifiziert worden, wird speichern unter“ ausgeführt. ” ” Alle Parameterdateien haben stets die Endung .mask“. Diese muß bei ” der Eingabe der Dateinamen nicht mit angegeben werden. 3.4.5 Eine Maske laden Um eine Maske (oder genauer die sie beschreibende Parameterdatei) zu laden, ist in der Menüleiste der Punkt Datei/Parameterdatei laden zu wählen. Der Benutzer wird aufgefordert den Dateinamen der Parameterdatei 34 anzugeben und sich anschließend bei der entsprechenden Datenbankinstanz anzumelden. Daraufhin werden die Maskenelemente geladen und dargestellt. Ist ein Untermasken- oder Spaltenelement nicht in der Datenbank vorhanden erhält der Benutzer eine Warnmeldung. 3.5 Ändern von Masken Eine bestehende Maske kann verändert werden, indem zunächst die zugehörige Parameterdatei geladen wird (siehe 3.4.5). Dann können wie bei der Erstellung der Maske alle nötigen Einstellungen gemacht werden. Die veränderte Parameterdatei ist dann zu speichern. 35 Kapitel 4 Implementation 4.1 Struktur Die grundlegenden Bestandteile des Programmpakets sind der Editor und der Maskeninterpreter (siehe Allgemeine Konzepte). Der Editor erzeugt anhand von Metadaten aus der Datenbank und Benutzereingaben eine Datei ( Pa” rameterdatei“) die alle relevanten Parameter zur Erzeugung einer Maske enthält. Der Maskeninterpreter wertet eine Parameterdatei aus und stellt anhand dieser Information eine entsprechende Maske dar (Abb. 4.1). Das gesamte Programmpaket wurde in Java 1.3 realisiert. Das zugrundeliegende Datenbanksystem ist Oracle 8i. Eine genauere Spezifikation ist den jeweiligen Benutzerhandbüchern zu entnehmen (Benutzerhandbuch für Masken bzw Benutzerhandbuch des Editors). Das Komponentendiagramm (4.2) zeigt die Gliederung, sowie das Zugriffsverhalten (Pfeile) der Klassen des Systems. Im folgenden werden die Komponenten einzeln erläutert. Die detailliertere Programmierschnittstelle ist im HTML-Format als JAVA-DOC vorhanden. 4.1.1 Der Editor Der Editor erzeugt anhand von Metadaten aus der Datenbank und Benutzereingaben eine Datei ( Parameterdatei“) die alle relevanten Parameter ” zur Erzeugung einer Maske enthält. Die Editor-Komponente (Package code.editor) enthält viele Klassen zur grafischen Benutzeroberfläche (GUI mit splitPane und tabbedPane sowie TableChooserDialog) sowie einige Klassen zur logischen Abstraktion der Maskenkonfiguration. Speziell dienen die Klassen ColumnElement und SubmaskElement mit MaskElement als Oberklasse zur Kapselung der Pa36 Abbildung 4.1: Die Struktur des Programmsystems Abbildung 4.2: Komponentendiagramm des Programmpakets 37 Abbildung 4.3: Klassendiagramm der Editor-Komponente rameter von Spalten- und Untermaskenrepräsentationen in der Maske. Die Klasse MaskElements dient hierbei als Container für solche Objekte; der Inhalt wird in der rechten Liste (überschrieben mit Maske) des Editors dargestellt. Damit enthält die rechte Liste alle in die Maske übernommenen Elemente. Die linke mit Auswahl überschriebene Liste enthält alle Elemente, die der Benutzer noch in die Maske einbringen kann. Sie wird aus der Klasse MaskOptions gespeist, die die von den Datenbankkomponenten zurückgelieferten Informationen über Spalten und Fremdschlüsselinformationen aufnimmt. Die Hauptklasse schließlich ist die Klasse Editor selbst, da sie den größten Teil der Logik enthält und aufzurufen ist, um den Editor zu starten (Abb. 4.3). 4.1.2 Der Maskeninterpreter Der Maskeninterpreter (Package code.mask) wertet eine Parameterdatei aus und stellt anhand dieser Information eine entsprechende Maske dar. Größtenteils enthält diese Komponente Klassen für die grafischen Benutzeroberfläche: einerseits für die Tupelsicht (TupelGUI, MainPanel und CommandPanel) und andererseits für die Listensicht (zum Beispiel ListGUI und ListTableModel). Hierbei stellt MainPanel die grafischen Bestandtei38 Abbildung 4.4: Klassendiagramm der Maskeninterpreter-Komponente le der UI-Elemente dar und übernimmt die Anordnung dieser. Als Container und übergeordnete Schnittstelle dient die Klasse UIElementHandler. Die Klasse um den Maskeninterpreter zu starten ist die Klasse Mask (Abb. 4.4). Sie enthält die Logik zur Verwaltung der Benutzerschnittstelle und kommuniziert mit der UIElementHandler-Klasse, sowie mit den Datenbankkomponenten (Abb. 4.5). 4.1.3 Die UI-Elemente Die UI-Elemente sind Klassen für Ein- und Ausgabeschnittstellen (siehe Allgemeine Konzepte). Die für eine bestimmte Maske benötigten Klassennamen der UI-Elemente stehen in der Parameterdatei und werden nach dem Start des Maskeninterpreters geladen. Durch dieses dynamische Laden ist es möglich weitere Klassen hinzuzufügen, ohne den Maskeninterpreter ändern zu müssen. Da der Editor die Parameterdatei erzeugt, müssen ihm bereits die Klassennamen bekannt sein. Auch muß festgestellt werden, ob eine bestimmte Klasse einen Datentyp überhaupt darstellen kann. Weiterhin muß es möglich 39 Abbildung 4.5: Interaktion zwischen Maske, Benutzer und Datenbank sein den Klassen verschiedene Parameter zu übermitteln, wie zum Beispiel einen statischen Wertevorrat. Dies macht es notwendig zu jeder Klasse für die Ein- und Ausgabe in Masken eine Klasse für den Editor zu schreiben, die eben diese Aufgaben übernimmt. Solch ein Paar von Klassen ist mit UI” Element“ bezeichnet, die Klasse für die Maske mit Maskenteil“ und die ” für den Editor mit Editorteil“. ” Der Maskenteil (Package code.ui.mask) macht hierbei die Ein- und Ausgabeschnittstelle in der Maske selbst aus (etwa ein Eingabefeld mit Beschriftung). Der Editorteil (Package code.ui.editor) ist selbst ein Dialog, der durch den ’UI-Parameter’-Knopf im Editor aufgerufen wird. Das Klassendiagramm für die standardmäßig vorhandenen UI-Elemente des Masken- bzw Editorteils ist in Abbildung 4.6 bzw 4.7 dargestellt. Unterschiede liegen notwendigerweise in den abstrakten Oberklassen: Die Klassen des Maskenteils erben alle von der abstrakten Oberklasse UIElement, die des Editorteils von ParamDlg. Außerdem sind für den Editorteil der UI-Klasse für die statische Auswahl zwei verschiedene Klassen implementiert um Zeichenketten und Zahlen gesondert zu behandeln. Bei Zahlen wird die korrekte Eingabe eines Zahlwertes überprüft. Die standardmäßig vorhandenen UI-Elemente sind folgende: • TextField: Abstrakte Oberklasse aller UI-Elemente, die aus einem einfachen Eingabefeld mit Beschriftung (Label) bestehen. Im zugehörigen Parameterdialog kann die Länge des Eingabefeldes bestimmt werden. • StringField: Einfaches Eingabefeld zur Eingabe von Zeichenketten. 40 Abbildung 4.6: Klassendiagramm der standardmäßig vorhandenen UIElemente (Maskenteil) Abbildung 4.7: Klassendiagramm der standardmäßig vorhandenen UIElemente (Editorteil) 41 Im Parameterdialog können neben der Länge des Eingabefeldes auch Groß- und Kleinschreibung beachten“ und Exakte Übereinstimmung ” ” bei Suche“ an- oder abgestellt werden. • DateField: Einfaches Eingabefeld zur Eingabe eines Datums. Im Parameterdialog können neben der Länge des Eingabefeldes kann auch die Formatierung des Datums angegeben werden. • NumberField: Einfaches Eingabefeld zur Eingabe von Zahlen. • UnitNumberField: Einfaches Eingabefeld zur Eingabe von Zahlen mit Einheit. Im Parameterdialog kann eine Standardeinheit spezifiziert werden. Bei allen anderen Einheiten ist ein Umrechnungsfaktor zur Standardeinheit anzugeben. Die Angabe einer Abkürzung oder eines Symbols ist möglich. • StaticChooser (im Editorteil abstrakt): Auswahlliste (ComboBox) mit einer festgelegten (statischen) Wertemenge. Im Parameterdialog kann die Beschreibung und der in der Datenbank benutzte Wert eines Auswahlpunktes angegeben werden. • StaticStringChooser (nur im Editorteil): Spezialisierung des Parameterdialogs des StaticChoosers auf Zeichenketten. • StaticNumberChooser (nur im Editorteil): Spezialisierung des Parameterdialogs des StaticChoosers auf Zahlen. Nur Zahlenwerte werden bei der Eingabe zugelassen. • DynamicChooser: Abstrakte Oberklasse für Dynamische Auswahllisten mit Eingabefeld. In der Maske kann durch den Benutzer eine neues Listenfenster mit den aktuell in der Datenbank vorhandenen Werten angezeigt werden. Nach der Auswahl steht der entsprechende Wert im Eingabefeld. Im Parameterdialog kann die dazu nötige Anfrage spezifiziert werden. Weiterhin ist es möglich die eigentlichen Werte zu verstecken: Für die Auswahl von Mitarbeiterkürzeln kann beispielsweise eine Anfrage nach Vorname, Name und Kürzel angegeben werden. Dann wird die letzte Spalte (also Nummer 3 - Kürzel) als Ergebnisspalte angegeben und ’letzte Spalte darstellen’ wird deaktiviert. Damit sieht der Benutzer den vollen Namen der Mitarbeiter und erhält nach der Auswahl trotzdem das gewünschte Kürzel. • DynamicNumberChooser: Spezialisierung des DynamicChoosers auf Zahlen. 42 • DynamicStringChooser: Spezialisierung des DynamicChoosers auf Zeichenketten. Außerdem sind im Parameterdialog die geichen Optionen wie beim StringField vorhanden. 4.1.4 Die Datenbankkomponenten Die Gewährleistung einer Anpassungsmöglichkeit an andere Datenbanksysteme als Oracle 8i wird durch die Kapselung der Datenbankzugriffe in eigene Klassen erreicht. Zusätzlich wird in diesen Klassen weitgehend JDBC eingesetzt. Ob jedoch ein anderes Datenbanksystem alle benötigten JDBCFunktionen implementiert, oder ob JDBC überhaupt unterstützt wird, kann nicht garantiert werden. Die Datenbankkomponente (Package code.db) des Programmsystems setzt sich aus folgenden Klassen zusammen: • DBAL ( DataBase Abstraction Layer“): liefert Informationen über die ” Datenbank • DBResultHandler: kapselt ein Anfrageergebnis – in der Ergebnismenge kann beliebig navigiert werden – Tupel können verändert, eingefügt oder gelöscht werden – alle gemachten Änderungen können in die Datenbank übernommen, oder verworfen werden • DBColumn: kapselt Informationen über eine Spalte einer Tabelle • RefTable: kapselt Informationen zu Fremdschlüsselbeziehungen • DBCriteria: kapselt Anfragekriterien • DBDataMapper: stellt ein Java-Objekt als SQL-String dar • DBException: für die Fehlerbehandlung bei Datenbankzugriffen 4.1.5 diverse Resourcen Zusätzlich zu den Hauptkomponenten des Programmpakets werden Konfigurationsdateien, globale Konstantendeklarationen und diverse nützliche“, ” allgemeine Funktionen benötigt (Package code.res): • Resources: Klasse die globale Variablen (z.B. die Versionsnummer) und nützliche“, allgemeine Funktionen enthält ” 43 • PropertyHandler: Klasse für die Handhabung von Konfigurationsdateien (Property-Dateien) • ErrorDialog: Dialog zur Anzeige eines Fehlers • JLoginDialog: Dialog zum Login an eine Datenbankinstanz • SingleExtensionFileFilter: Implementierung von javax.swing.filechooser.FileFilter um Dateien mit bestimmten Endungen zu filtern • mask.language (Konfigurationsdatei): von der Maske zur Ausgabe genutzte Zeichenketten • editor.language (Konfigurationsdatei): vom Editor zur Ausgabe genutzte Zeichenketten • db.language (Konfigurationsdatei): von den Datenbankkomponenten zur Ausgabe genutzte Zeichenketten • config.conf (Konfigurationsdatei): enthält Parameter über UI-Elemente. – ui path: Pfad in dem der Editor beim Start nach UI-Elementen sucht – paramDlgs start with: Jede .class-Datei in ui path muß den Prefix paramDlgs start with haben um vom Editor geladen zu werden. – paramDlgs end with: Jede .class-Datei in ui path muß den Suffix paramDlgs end with haben um vom Editor geladen zu werden. – paramDlgs package: Name des Packages der Editorteile der UIElemente – uiElements package: Name des Packages der Maskenteile der UIElemente • dbis.jar (nicht im Programmpaket enthalten): am Institut für Informatik - Datenbanken und Informationssysteme entwickelte Klassen zur Handhabung von Datenbankverbindungen • JDBC-Datenbanktreiber (nicht im Programmpaket enthalten): zum Beispiel classes 111.zip für Oracle 8i Weiteren Details der Programmierschnittstelle (Package-Struktur, einzelne Methoden der Klassen, ...) sind im HTML-Format als JAVA-DOC vorhanden. 44 4.2 Anpassung und Erweiterbarkeit Um das Programmsystem auf kommende Gegebenheiten einstellen zu können, wurde bei der Implementation versucht die kritischen Komponenten möglichst modular zu entwerfen. Die folgenden Erläuterungen geben zu den wichtigsten Punkten Aufschluß. 4.2.1 Hinzufügen von UI-Elementen Um dem Programmsystem ein neues UI-Element hinzuzufügen, muß eine Klasse für den Maskenteil und eine für den Editorteil geschrieben werden (siehe 4.1.3). Der Maskenteil wird abgeleitet von der abstrakten Oberklasse UIElement, der Editorteil von ParamDlg, wobei die abstrakt deklarierten Methoden implementiert werden müssen. Soll die neue Schnittstelle nur aus einem Eingabefeld mit Beschriftung bestehen, kann auch TextField als Oberklasse dienen. Für genauere Informationen zur Schnittstelle und den zu implementierenden Methoden sei hier auf die JAVA-DOC API Dokumentation verwiesen. Schließlich müssen die übersetzten Klassen in die für den Maskenbzw Editorteil vorgesehenen Verzeichnisse (bzw JAR-Archive) kopiert werden (standardmäßig ui/mask für den Maskenteil und ui/editor für den Editorteil). Der Editor versucht beim Programmstart die in der Konfigurationsdatei config.conf (siehe 4.1.5) Klassen der Editorteile der UI-Elemente zu laden. Die Klassennamen der vom Maskeninterpreter zu ladenden Klassen stehen in der Parameterdatei. 4.2.2 Anpassung an andere Datenbanksysteme Die nötigen Veränderungen für eine Anpassung an andere Datenbanksysteme sind schwer vorauszusehen, da der Funktionsumfang und die Treiberunterstützung sehr unterschiedlich ausfallen können. Um das Datenbanksystem unter Java ansprechen zu können, wird zunächst ein JDBC-Treiber (am besten Version 2 oder höher) benötigt. Generell sollte es dann jedoch ausreichen die Datenbankkomponenten (siehe 4.1.4) zu ändern. Bei speziellen Klassen gibt es besondere Details zu beachten: • DBAL: Diese Klasse liefert die grundlegenden Metainformationen über die Datenbank liefert. Manche Anfragen beziehen sich dabei auf das Data Dictionary der Datenbank ( select TABLE NAME, OWNER from ” ALL TABLES“). Diese Anfragen sind gegebenenfalls zu modifizieren. • DBResultHandler: Diese Klasse kapselt ein Anfrageergebnis. Hierbei wird ein Statement mit dem Parameter TYPE SCROLL INSENSITIVE be45 nutzt, d.h. im ResultSet kann vor- und zurück geblättert werden. Außerdem werden die Daten gecached (Statement.setFetchSize). Ist eins dieser Merkmale beim neuen Datenbanksystem nicht vorhanden, muß ein eigenes Caching implementiert werden! • DBColumn: kapselt Informationen über eine Spalte einer Tabelle, diese werden aus ResultSetMetaData ausgelesen • DBCriteria: kapselt Anfragekriterien; bei Vergleichen auf ’null’ wird ’=’ durch ’is’ ersetzt • DBDataMapper: stellt ein Java-Objekt als SQL-String dar; bei java.util.Date (oder abgeleiteten Klassen) könnte die korrekte Übersetzung in einen SQL-String vom Datenbanksystem abhängen 46 Kapitel 5 Ausblick Durch die Trennung von Editor und Maskenteil ist es möglich jeden Teil einzeln zu ersetzen. Der Editor könnte durch eine komfortablere Version ausgetauscht oder ganz automatisiert werden. Denkbar ist auch die vom Editor erzeugte Parameterdatei mit einem anderen Interpreter auszuwerten, als mit dem Maskeninterpreter. So könnte eine andere Applikation beispielsweise eine Webschnittstelle auf PHP-Basis aus der Parameterdatei generieren. Diese kann dann die Benutzung des Maskensystems im Internet ermöglichen. 47 Anhang A Format von Parameterdateien Die Art und Reihenfolge der in der Parameterdatei gespeicherten Objekte ist hier wiedergegeben: • java.lang.String: Name der Datenbankinstanz (z.B. ’PRODUCTION’ oder ’DBIS’) • java.lang.String: Tabellenname (z.B. ’PERSONEN’ oder ’ADR’) • java.lang.String: Besitzer“ der Tabelle, in Java auch Schema“ ” ” (z.B. ’WWWADM’ oder ’DBIS’) • int: Art des Starts der Maske (Tupelsicht, Listensicht, beides); Koodierung siehe Klasse Resources im JAVA-DOC • java.lang.String: Überschrift der Tabelle • java.util.Vector: Vector mit den im Editor eingegebenen OrderByKlauseln als java.lang.String (vergleiche Benutzerhandbuch des Editors • int: vorgegebene Zeilenanzahl in der Tupelsicht • int: Anzahl der Maskenelemente • java.lang.String: Beschreibung des Elements • boolean: eine neuen Zeile beginnt hinter diesem Element • int: Art des Maskenelements (Spalte - ColumnElement oder Untermaske - SubmaskElement); Koodierung siehe Klasse Resources im JAVA-DOC • Falls das Maskenelement eine Spalte beschreibt: 48 – code.db.DBColumn: Informationen über die Spalte – java.lang.String: Name der Klasse des Editorteils des UIElements – java.lang.String: Name der Klasse des Maskenteils des UIElements – boolean: diese Spalte wird in der Listensicht angezeigt – [spezielle Parameter des UI-Elements] • Falls das Maskenelement eine Untermaske beschreibt: – code.db.RefTable: Informationen über die Fremdschlüsselbeziehung – java.lang.String: Bedingung an die Untermaske (wie im Editor eingegeben) – java.lang.String: Pfad und Dateiname der Parameterdatei der Untermaske – int: Art des Starts der Untermaske (Tupelsicht, Listensicht, beides); – [spezielle Parameter des UI-Elements] Ein Beispiel (test.mask) ist dem abgegebenen Programmcode beigefügt. 49 Literaturverzeichnis [1] Eric Schellhammer: Implementation und Generation von Datenbankmasken in Java, Studienarbeit am Institut für Informatik, 1999 [2] Arnim von Helmolt: Automatische Generierung von Update-Masken aus Datenbanksichten, Diplomarbeit am Institut für Informatik, 1999 [3] Java API: http://java.sun.com/j2se1.3/docs/api/index.html offizielle Java 1.3 API-Dokumentation von Sun [4] lokale Version der Dokumentation zur Oracle Datenbank: info/system/databases/oracle/oracle infos.html (lokal unter http://www-b.informatik.uni-hannover.de) 50