Realisierung eines Web-basierten Dokument-Druckdienstes Studienarbeit Alexander Steinert [email protected] Betreuung: Prof. Dr. Florian Matthes Arbeitsbereich Software-Systeme Technische Universität Hamburg-Harburg Januar 2002 Copyright © 2002 von Alexander Steinert Als Beispiel für ingenieursmäßige Softwareentwicklung ist ein System für die Web-basierte Verwaltung (insb. Erfassung) von studienunterstützenden Dokumenten in druckbarer Form und die Web-basierte Beauftragung des Dokumentdrucks zu erstellen. Auftragsgeber ist der Fachschaftsrat ET/IT der TUHH. Inhaltsverzeichnis 1 Analyse.............................................................................................................................................. 1 1.1 Lastenheft .............................................................................................................................. 1 1.2 Pflichtenheft .......................................................................................................................... 2 1.2.1 Zielbestimmung ........................................................................................................ 2 1.2.1.1 Musskriterien ............................................................................................... 2 1.2.1.2 Wunschkriterien ........................................................................................... 2 1.2.1.3 Abgrenzungskriterien................................................................................... 2 1.2.2 Einsatz ...................................................................................................................... 2 1.2.3 Umgebung ................................................................................................................ 2 1.2.4 Funktionen ................................................................................................................ 3 1.2.4.1 Anwendungsfallkatalog ............................................................................... 4 1.2.4.1.1 Ändere Dokument ........................................................................... 4 1.2.4.1.2 Ändere Dokumenttypen .................................................................. 5 1.2.4.1.3 Ändere Gruppen .............................................................................. 5 1.2.4.1.4 Ändere Konstanten .......................................................................... 5 1.2.4.1.5 Ändere Personendaten ..................................................................... 5 1.2.4.1.6 Ändere Sprachen ............................................................................. 5 1.2.4.1.7 Ändere Studiengänge ...................................................................... 6 1.2.4.1.8 Erfasse neues Dokument ................................................................. 6 1.2.4.1.9 Führe Auftrag aus............................................................................ 6 1.2.4.1.10 Gib Auftrag ab............................................................................... 6 1.2.4.1.11 Gib Teilauftrag ab.......................................................................... 6 1.2.4.1.12 Lösche Dokument ......................................................................... 7 1.2.4.1.13 Lösche Personendaten ................................................................... 7 1.2.4.1.14 Registriere neue Person ................................................................. 7 1.2.4.1.15 Storniere Auftrag........................................................................... 7 1.2.4.1.16 Suche Dokumente ......................................................................... 8 1.2.4.1.17 Suche Person ................................................................................. 8 1.2.4.1.18 Verbuche Abholung ....................................................................... 8 1.2.4.1.19 Verbuche Zahlung.......................................................................... 8 1.2.4.1.20 Versende Erinnerungsmails ........................................................... 9 1.2.4.1.21 Zeige Änderungen an .................................................................... 9 1.2.4.1.22 Zeige Auftrag an............................................................................ 9 1.2.4.1.23 Zeige Auftragsliste an ................................................................... 9 1.2.4.1.24 Zeige Dokumentdaten an .............................................................. 9 1.2.4.1.25 Zeige Kundendaten an................................................................... 9 1.2.4.1.26 Zeige Personendaten an................................................................. 9 1.2.4.1.27 Zeige Übersicht an ...................................................................... 10 1.2.5 Daten....................................................................................................................... 10 1.2.6 Leistungen .............................................................................................................. 12 1.2.7 Benutzerschnittstelle............................................................................................... 12 1.2.8 Entwicklungsumgebung ......................................................................................... 12 1.2.9 Ergänzungen ........................................................................................................... 12 1.2.10 Glossar .................................................................................................................. 13 2 Entwurf........................................................................................................................................... 17 2.1 Ähnliche Softwareprodukte ................................................................................................ 17 i 2.1.1 Document Manager ................................................................................................ 17 2.1.2 FreeDMS ................................................................................................................ 17 2.1.3 SDMS ..................................................................................................................... 17 2.2 ArsDigita Community System ............................................................................................ 18 2.3 Programmiersprache ........................................................................................................... 18 2.4 Persistenz ............................................................................................................................ 19 2.5 Benutzerschnittstelle ........................................................................................................... 20 2.6 Verteilung ............................................................................................................................ 20 2.7 N-Schicht-Architektur......................................................................................................... 21 2.7.1 Persistenz-Schicht................................................................................................... 22 2.7.1.1 Transaction ......................................................................................... 23 2.7.1.2 Class_map .............................................................................................. 23 2.7.1.3 Attribute_map .................................................................................... 23 2.7.1.4 Persistent_object........................................................................... 23 2.7.2 Geschäftsschicht ..................................................................................................... 24 2.7.2.1 Monthly_sum ......................................................................................... 24 2.7.2.2 Session................................................................................................... 24 2.7.2.3 Query........................................................................................................ 24 2.7.2.4 Observed_object................................................................................ 24 2.7.3 Präsentationsschicht ............................................................................................... 24 2.7.3.1 Dictionary............................................................................................ 25 2.7.3.2 Request................................................................................................... 25 2.7.3.3 Argument_record................................................................................ 25 2.7.3.4 Page .......................................................................................................... 25 3 Implementierung............................................................................................................................ 27 3.1 Persistenz-Schicht ............................................................................................................... 27 3.1.1 Transaktionen ......................................................................................................... 27 3.1.2 Persistente Objekte ................................................................................................. 28 3.1.2.1 OR-Mapping .............................................................................................. 28 3.1.2.2 Werteinschränkung .................................................................................... 29 3.1.3 Dokument-Behandlung........................................................................................... 30 3.2 Geschäftsschicht.................................................................................................................. 31 3.3 Präsentationsschicht ............................................................................................................ 32 3.3.1 Klassen ................................................................................................................... 32 3.3.1.1 Dictionary............................................................................................ 32 3.3.1.2 Request................................................................................................... 33 3.3.1.3 Argument_record................................................................................ 33 3.3.2 Sitzungsverwaltung ................................................................................................ 34 4 Zusammenfassung ......................................................................................................................... 35 A Übersetzungen............................................................................................................................... 37 Literaturverzeichnis ......................................................................................................................... 41 ii Kapitel 1 Analyse 1.1 Lastenheft Mit der Zusammenfassung der Basisanforderungen an das zu realisierende Produkt dient dieses Lastenheft als Einstieg in die Thematik und als Überblick über die Wünsche des Auftraggebers. 1. Zielbestimmung Der Fachschaftsrat Elektrotechnik und Informationstechnik soll durch das Produkt in die Lage versetzt werden, rechnergestützt sowohl die von ihm beschafften studienunterstützenden Dokumente zu verwalten als auch von Studierenden abgegebene Druckaufträge zu bearbeiten. 2. Produkteinsatz Das Produkt dient zur Dokument- und Kundenverwaltung sowie zur Abgabe und Bearbeitung von Druckaufträgen. Zielgruppen sind die Mitarbeiter des Fachschaftsrates und Studierende der TUHH. 3. Produktfunktionen /LF10/ Erfassung, Änderung, Löschung von Personen. /LF20/ Erfassung, Änderung, Löschung von Dokumenten. /LF30/ Änderung der Grundeinstellung (Studiengänge, Sprachen, Dokumenttypen). /LF40/ Änderung der Gruppenzugehörigkeiten und Konstanten. /LF50/ Abgabe, Stornierung und Bearbeitung von Druckaufträgen und Verbuchung der Bezahlung. /LF60/ Benachrichtigung der Kunden über Fertigstellung eines Auftrags und Erinnerung an Abholung bzw. Bezahlung. /LF70/ Ansicht der Änderungen am Datenbestand. /LF80/ Ansicht einer Übersicht über den Datenbestand. 4. Produktdaten /LD10/ Es sind relevante Daten über Kunden zu speichern. /LD20/ Es sind Daten über Dokumente, Dokumenttypen, Sprachen und Studiengänge zu speichern. /LD30/ Es sind Daten über Druckaufträge und Zahlungen zu speichern. /LD40/ Es sind Daten über Gruppenzugehörigkeiten und Konstanten zu speichern. 5. Produktleistungen /LL10/ Es müssen mindestens 4000 Personen, Dokumente mit insgesamt mindestens 20000 Seiten und Aufträge mit insgesamt mindestens 600000 Positionen verwaltet werden können. 1 Kapitel 1 Analyse /LL20/ Die Dokumentverwaltung muss parallel von mindestens drei Arbeitsplatzrechnern aus möglich sein. 1.2 Pflichtenheft Dieses Pflichtenheft dient zur präzisen Definition der fachlichen Anforderungen an das Produkt. Allerdings wurde zwischen dem Autor dieser Arbeit und dem Auftraggeber kein juristischer Vertrag abgeschlossen, so dass die folgenden Abschnitte lediglich den relevanten Teilen eines Musterpflichtenhefts entsprechen. 1.2.1 Zielbestimmung Der Fachschaftsrat Elektrotechnik und Informationstechnik der Technischen Universität HamburgHarburg soll durch das Produkt in die Lage versetzt werden, seine Sammlung studienunterstützender Dokumente rechnergestützt zu verwalten und zum Druck anzubieten. 1.2.1.1 Musskriterien Das Produkt muss die Verwaltung von Personen, Dokumenten, Druckaufträgen und derer Bezahlung ermöglichen. Die Dokumentbeschaffung muss insbesondere per Scanner möglich sein. 1.2.1.2 Wunschkriterien Die Kundenverwaltung soll so gestaltet sein, dass möglichst wenig Betreuungsaufwand erforderlich ist. Dies gilt insbesondere für vergessene Passwörter. 1.2.1.3 Abgrenzungskriterien Das Produkt soll nicht Dokumente zum “Download” zur Verfügung stellen. Insbesondere soll die Ansicht oder Änderung des eigentlichen Dokumentinhaltes außer zur Korrektur von Fehlern nicht möglich sein. 1.2.2 Einsatz Das Produkt wird für die Mitarbeiter1 des Fachschaftsrates ET/IT als Verwalter der Dokument- und Personendaten sowie als Anbieter des Dokumentdrucks realisiert. Die zweite Zielgruppe sind Studierende der TUHH. Die Studierenden sind “Kundschaft” des Fachschaftsrates im Sinne einer Personengruppe mit Nachfrage an studienunterstützenden Dokumenten. Das Produkt soll auf die Verwendung durch weitere Fachschaftsräte der TUHH sowie weiterer Hochschulen ausgelegt sein. Das Produkt muss unterbrechungsfrei betreibbar sein. 1 2 Mit den in diesem Dokument verwendeten männlichen Personenbezeichnungen sind auch weibliche Personen gemeint. Kapitel 1 Analyse 1.2.3 Umgebung Zielumgebung des Produkts ist die vorhandene Umgebung des Fachschaftsratsbüros einschließlich externer Anbindungen. Sie umfasst • einen Server mit 500MHz AMD-K6 Prozessor und 128MB RAM, der mit Debian GNU/Linux 2.2r3 betrieben und auch von lokalen Benutzern verwendet wird, • einen Kyocera FS-3750 Laserdrucker mit Duplexeinheit und zwei Papierschächten, • einen Umax Astra 2400S Scanner mit Einzelblatteinzug, • zwei PCs unter Windows 2000, die für Bürotätigkeiten genutzt werden, • die Anbindung aller Maschinen an das Hochschulnetz und damit an das Internet, • einen Apache-Webserver, der das bisherige WWW-Angebot des FSRs ermöglicht, • einen CUPS-Druckserver, der die Warteschlange des Druckers verwaltet, • einen Mailserver und • SSL-fähige Webbrowser auf allen Maschinen. 1.2.4 Funktionen Abbildung 1-1 und Abbildung 1-2 zeigen die Funktionalität des Systems aus externer Perspektive. Die darin auftretenden Aktoren werden in Abschnitt 1.2.10 beschrieben. Ändere Gruppen Ändere Konstanten Ändere Sprachen Ändere Studiengänge Administrator Ändere Dokumenttypen Zeige Änderungen an Erfasse neues Dokument Ändere Dokument Dokumentar Lösche Dokument «include» «include» Suche Dokumente «include» Zeige Dokumentdaten an Zeige Übersicht an Abbildung 1-1 Anwendungsfalldiagramm Administrator und Dokumentar 3 Kapitel 1 Analyse Zeige Übersicht an Registriere neue Person Zeige Änderungen an «include» Verbuche Abholung «include» Verbuche Zahlung Zeige Personendaten an Suche Person Verkäufer «include» Lösche Personendaten Ändere Personendaten «include» «include» Storniere Auftrag Versende Erinnerungsmails «include» «include» Zeige Auftragsliste an Zeige Auftrag an Gib Teilauftrag ab «include» Suche Dokumente Kunde Zeige Dokumentdaten an Gib Auftrag ab «include» Zeige Kundendaten an Führe Auftrag aus Abbildung 1-2 Anwendungsfalldiagramm Verkäufer und Kunde 1.2.4.1 Anwendungsfallkatalog Für alle Anwendungsfälle, in denen das System die Ungültigkeit von Werten feststellt, kehrt es zum Punkt vor der Prüfung zurück, wobei eine Fehlermeldung eingefügt wird, alle Werte erhalten bleiben und ungültige Werte hervorgehoben sind. Prüft das System die Durchführbarkeit von Schreiboperationen, so muss die Prüfung zusammen mit der Durchführung als Transaktion ausgeführt werden. Für alle Anwendungsfälle außer den in Abschnitt 1.2.4.1.16 und Abschnitt 1.2.4.1.24 beschriebenen muss die Authentizität des Aktors gewährleistet sein. Die Art und Weise, wie dies erreicht wird, muss dem Benutzer bei der Authentifikation mitgeteilt werden. Es darf vorausgesetzt werden, dass jede agierende Person einen Shell-Account auf einem im Hochschulnetz der TUHH erreichbaren UnixRechner hat. Vom System an Kunden versandte Emails enthalten einen Link auf die aktuellen Öffnungszeiten des FSR-Büros. 4 Kapitel 1 Analyse 1.2.4.1.1 Ändere Dokument 1. Der Dokumentar sucht das gewünschte Dokument mit Hilfe der Dokumentsuchmaske und wählt es aus. 2. Das System präsentiert ein mit den bisherigen Daten vorausgefülltes Formular. 3. Der Dokumentar ändert die gewünschten Felder und kann die Seitenreihenfolge verändern, einzelne Seiten löschen oder neu zu beschaffende Seiten einfügen. 4. Das System prüft die Gültigkeit der Werte. 5. Das System stellt alte und neue Daten gegenüber, wobei geänderte Werte hervorgehoben werden, und zeigt Konsequenzen für betroffene wartende Aufträge. Der Dokumentar kann den Vorgang hier abbrechen. 6. Die Änderungen werden unwiderruflich übernommen. 1.2.4.1.2 Ändere Dokumenttypen 1. Das System präsentiert ein mit den bisherigen Dokumenttypen vorausgefülltes Formular. 2. Der Dokumentar ändert die gewünschten Felder. 3. Das System prüft die Gültigkeit der Werte. 4. Das System stellt alte und neue Daten gegenüber, wobei geänderte Werte hervorgehoben werden. Der Dokumentar kann den Vorgang hier abbrechen. 5. Die Änderungen werden unwiderruflich übernommen. 1.2.4.1.3 Ändere Gruppen Dieser Anwendungsfall verläuft analog zu Abschnitt 1.2.4.1.2, jedoch mit dem Administrator als Aktor. 1.2.4.1.4 Ändere Konstanten Dieser Anwendungsfall verläuft analog zu Abschnitt 1.2.4.1.2, jedoch mit dem Administrator als Aktor. 1.2.4.1.5 Ändere Personendaten 1. Der Verkäufer sucht die gewünschte Person mit Hilfe der Personensuchmaske und wählt sie aus. 2. Das System präsentiert ein mit den bisherigen Daten vorausgefülltes Formular. 3. Der Verkäufer ändert die gewünschten Felder. 4. Das System prüft die Gültigkeit der Werte. 5. Das System stellt alte und neue Daten gegenüber, wobei geänderte Werte hervorgehoben werden. Der Verkäufer kann den Vorgang hier abbrechen. 6. Die Änderungen werden unwiderruflich übernommen. 5 Kapitel 1 Analyse 1.2.4.1.6 Ändere Sprachen Dieser Anwendungsfall verläuft analog zu Abschnitt 1.2.4.1.2. 1.2.4.1.7 Ändere Studiengänge Dieser Anwendungsfall verläuft analog zu Abschnitt 1.2.4.1.2. 1.2.4.1.8 Erfasse neues Dokument 1. Der Dokumentar gibt die Dokumentquelle an: Entweder eine PS- oder PDF-Datei per URL oder den Scanner mit Optionen für die Seitenzusammenstellung. 2. Bei Angabe einer URL holt das System die Dokumentdatei, wandelt sie ggf. ins interne Format und prüft dann das Format auf Gültigkeit. Bei Angabe des Scanners gibt das System dem Dokumentar präzise Anweisungen zur Seitenzufuhr, scannt die Dokumentseiten und stellt die Seiten im internen Format zusammen. 3. Das System präsentiert ein Daten-Formular. 4. Der Dokumentar gibt die gewünschten Daten ein oder bricht den Vorgang ab. 5. Das System prüft die Gültigkeit der Werte. 6. Das Dokument wird ins System übernommen. 1.2.4.1.9 Führe Auftrag aus 1. Wann immer der Drucker verfügbar ist, wählt das System aus den druckbaren wartenden Aufträgen einen aus2. 2. Der entgültige Auftragspreis wird auf dem Konto des Kunden verbucht3 und das Druckerzeugnis hergestellt. 3. Der Kunde wird per Email über die Fertigstellung des Druckauftrags benachrichtigt. 1.2.4.1.10 Gib Auftrag ab 1. Das System präsentiert dem Kunden eine Übersicht mit allen Positionen des aktuellen nicht abgegebenen Auftrags. 2. Der Kunde kann die Optionen der Auftragspositionen (z.B. Anzahl der Exemplare) ändern oder den Vorgang hier abbrechen. 3. Das System zeigt dann den zu zahlenden Preis an. Er wird auf Zehntel Euro (bzw. DM) gerundet. Falls die Abbuchung dieses Preises beim aktuellen Kontostand und Kreditlimit des Kunden nicht möglich wäre, weist das System den Kunden darauf hin, dass der Auftrag zwar angenommen würde, der Kontostand für den Druck z.Z. allerdings nicht ausreicht. 4. Der Kunde bestätigt den Auftrag oder bricht den Vorgang hier ab. 5. Der Auftrag ist nun wartend, kann aber noch storniert werden. 2 Die Auswahlstrategie muss gewährleisten, das Aufträge geringeren Volumens und höherer Wartezeit bevorzugt werden. 3 Falls ein Teil der zu druckenden Dokumente zwischenzeitlich geändert wurde, werden die aktuellen Versionen gedruckt. Der entgültige Auftragspreis kann sich hierdurch ebensowenig erhöhen wie durch eine zwischenzeitliche Druckpreiserhöhung. 6 Kapitel 1 Analyse 1.2.4.1.11 Gib Teilauftrag ab 1. Der Kunde führt eine Dokumentsuche durch. 2. Der Kunde gibt für die gewünschen Dokumente eine Exemplarzahl sowie evtl. weitere Druckoptionen an oder bricht den Vorgang hier ab. 3. Das System prüft die Gültigkeit aller Werte. Sollten gewählte Dokumente zwischenzeitlich gelöscht worden sein, kehrt das System zu Punkt 2 zurück wobei die Löschungen hervorgehoben sind. 4. Falls dem Kunden momentan kein nicht abgegebener Auftrag zugeordnet ist, werden die gewählten Positionen in einen neu zu erzeugenden übernommen. Sonst werden sie in den vorhandenen nicht abgegebenen Auftrag übernommen, wobei ggf. Optionen bereits bestehender Positionen überschrieben werden. In jedem Fall hat die Angabe einer Exemplarzahl von Null das Nicht-Einfügen bzw. Löschen der Position zur Folge. 1.2.4.1.12 Lösche Dokument 1. Der Dokumentar sucht das gewünschte Dokument mit Hilfe der Dokumentsuchmaske und wählt es aus. 2. Das System zeigt die Dokumentdaten inkl. Verweise auf assoziierte Dokumente an. Hier kann der Dokumentar den Vorgang abbrechen. 3. Das System prüft, ob das Dokument keiner Auftragsposition zugeordnet ist. 4. Das Dokument einschließlich seiner Assoziationen zu anderen Dokumenten wird unwiderruflich gelöscht. 5. Falls der Titel des Dokuments jetzt keinem Dokument mehr zugeordnet ist, wird auch er unwiderruflich gelöscht. 1.2.4.1.13 Lösche Personendaten 1. Der Verkäufer sucht die gewünschte Person mit Hilfe der Personensuchmaske und wählt sie aus. 2. Das System präsentiert die Personendaten. Der Vorgang kann hier abgebrochen werden. 3. Das System prüft, ob kein Dokument mit der Person assoziiert ist, ob sie nicht das einzige Mitglied einer Gruppe ist, ob sie für keinen Datensatz Verantwortlicher ist, ob ihr kein im Druck befindlicher oder gedruckter Auftrag zugeordnet ist und ob ihr Kontostand gleich Null ist. 4. Alle gespeicherten der Person zugeordneten Buchungen und Aufträge einschließlich der Auftragspostionen werden gelöscht. 5. Die Personendaten werden unwiderruflich gelöscht. 1.2.4.1.14 Registriere neue Person 1. Das System präsentiert eine Eingabemaske. 2. Der Verkäufer trägt die Werte ein oder bricht den Vorgang hier ab. 3. Das System prüft die Gültigkeit der Werte. 4. Die Person wird unwiderruflich im System registriert. 7 Kapitel 1 Analyse 1.2.4.1.15 Storniere Auftrag 1. Der Kunde wählt mit Hilfe der Auftragsliste, der Verkäufer mit Hilfe der Anzeige der Personendaten, den gewünschten wartenden Auftrag aus. 2. Das System zeigt den Auftrag wie in Abschnitt 1.2.4.1.22 an. Der Kunde oder Verkäufer kann den Vorgang hier abbrechen. 3. Das System prüft, ob der Auftrag storniert werden kann. 4. Der Auftrag wird storniert. 1.2.4.1.16 Suche Dokumente 1. Das System präsentiert eine Maske für die Eingabe der Suchkriterien. Es können alle Dokumentdatenfelder sowie mit dem Dokument assoziierte Datenfelder als Suchkriterium gelten und Wildcards verwendet werden. 2. Das System führt die Suche durch. 3. Das System präsentiert das Ergebnis als Liste inkl. Verweisen auf die Anzeige der Dokumentdaten. 1.2.4.1.17 Suche Person 1. Das System präsentiert eine Maske für die Eingabe der Suchkriterien. Es kann auch nach Personen, die lange inaktiv waren und/oder deren Daten löschbar sind (siehe Abschnitt 1.2.4.1.13), gesucht werden. 2. Das System führt die Suche durch. 3. Das System präsentiert das Ergebnis als Liste mit Verweisen auf die Anzeige der Personendaten. 1.2.4.1.18 Verbuche Abholung 1. Der Verkäufer wählt mit Hilfe der Personensuchmaske den relevanten Kunden. 2. Das System zeigt alle Daten des Kunden wie in Abschnitt 1.2.4.1.26 an. 3. Der Verkäufer wählt die gedruckten Aufträge, die abgeholt wurden, oder bricht den Vorgang hier ab. 4. Das System versetzt die gewählten Aufträge unwiderruflich in den Zustand “abgeholt”. 1.2.4.1.19 Verbuche Zahlung 1. Der Verkäufer wählt mit Hilfe der Personensuchmaske den relevanten Kunden. 2. Das System zeigt alle Daten des Kunden wie in Abschnitt 1.2.4.1.26 an. 3. Der Verkäufer gibt den (eingezahlten oder ausgezahlten) Betrag ein oder bricht den Vorgang hier ab. 4. Das System prüft die Gültigkeit der Werte. 5. Das System verbucht die Zahlung unwiderruflich auf dem Konto des Kunden. 8 Kapitel 1 Analyse 1.2.4.1.20 Versende Erinnerungsmails 1. Das System versendet in einstellbaren, regelmäßigen Abständen Emails an Kunden, um sie an gedruckte, nicht abgeholte Aufträge sowie an für den Ausgleich des Kontos notwendige Zahlungen zu erinnern. 1.2.4.1.21 Zeige Änderungen an 1. Der Verkäufer oder Dokumentar gibt einen Datumsbereich an. 2. Das System präsentiert als Liste alle innerhalb des Datumsbereichs geänderten oder neuen Dokumenttypen (Kürzel und Beschreibung), Dokumente (Titel und Datum mit Verweis auf die Anzeige der Dokumentdaten), Gruppen (Name sowie Vor- und Nachnamen der Mitglieder), Konstanten (Name und Wert), Sprachen (Kürzel und Name) und Studiengänge (Kürzel und Name). Außerdem gehört zu jedem Listeneintrag das Änderungsdatum und der für die Änderung Verantwortliche (Vor- und Nachname). 1.2.4.1.22 Zeige Auftrag an 1. Der Kunde wählt mit Hilfe der Auftragsliste den gewünschten Auftrag aus. 2. Das System zeigt den Auftrag inkl. aller Positionen an. Falls der Auftragsstatus “nicht abgegeben“ ist, befindet sich der Kunde in Punkt 2 von Abschnitt 1.2.4.1.11. Falls nicht, bietet ihm das System an, dorthin zu gelangen, so dass der angezeigte Auftrag zur Vorlage für einen neuen wird. 1.2.4.1.23 Zeige Auftragsliste an 1. Das System zeigt alle gespeicherten Aufträge des Kunden mit Auftragsstatus, Preis, Seiten- und Blattzahl und ggf. Zeit der Abgabe sowie der Fertigstellung als Liste an. Jeder Eintrag enthält einen Verweis auf die Anzeige der Auftragspositionen. 1.2.4.1.24 Zeige Dokumentdaten an 1. Der Kunde oder Dokumentar sucht das gewünschte Dokument mit Hilfe der Dokumentsuchmaske und wählt das gewünschte aus. 2. Das System zeigt alle Daten des Dokuments an, wobei es auch Verweise auf assoziierte Dokumente anbietet. 1.2.4.1.25 Zeige Kundendaten an 1. Das System zeigt alle Daten des Kunden wie in Abschnitt 1.2.4.1.26 an. 1.2.4.1.26 Zeige Personendaten an 1. Der Verkäufer sucht die gewünschte Person mit Hilfe der Personensuchmaske und wählt sie aus. 9 Kapitel 1 Analyse 2. Das System zeigt die Daten der Person, die Buchungen auf ihrem Konto, ihren Kontostand, alle wartenden oder gedruckten Aufträge dieser Person sowie die Anzahl der ihr zugeordneten Dokumente gruppiert nach Dokumenttypen an. 1.2.4.1.27 Zeige Übersicht an 1. Das System gibt einen Überblick über die gespeicherten Daten: Anzahl der Personen, Summe der Kontostände, Anzahl der Dokumente (gesamt und gruppiert nach Dokumenttypen), Anzahl der Aufträge gruppiert nach Status, Anzahl der Aufträge, der bedruckten Blätter und Seiten und die Einnahmen dafür (gesamt, gruppiert nach Monaten und gruppiert nach Semestern). 1.2.5 Daten Abbildung 1-3 und Abbildung 1-4 zeigen die statische Sicht auf die Konzepte des Problembereichs. Die auftretenden Begriffe werden im folgenden erläutert, sofern dies nicht im Abschnitt 1.2.10 geschieht oder sie nicht selbsterklärend sind. Dokument.datum Bei Dokumenten, die sich auf schriftliche oder mündliche Prüfungen beziehen, ist dies nicht das Datum der letzten Änderung durch den Verfasser sondern das Prüfungsdatum. Person.kreditlimit Falls der aktuelle Kontostand des Kunden minus den Preis für einen seiner wartenden Aufträge größer gleich seinem negativen Kreditlimit ist, so ist dieser Auftrag druckbar, d.h. er darf die Zuteilung des Druckers erhalten. Auftrag.abgabe Zeitpunkt des Zustandsübergangs eines Auftrags von “nicht abgegeben” zu “wartend”. Auftrag.fertigstellung Zeitpunkt des Zustandsübergangs eines Auftrags von “im Druck” zu “gedruckt”. Auftragsposition.duplex Dieser Wert legt fest, ob das zugehörige Dokument beidseitig gedruckt wird oder nicht. Auftragsposition.nup Dieser Wert legt fest, wie viele logische Seiten des zugehörigen Dokuments auf einer physischen Seite des Ausdrucks erscheinen sollen. 10 Kapitel 1 Analyse Dokumenttyp {name != ""} -kuerzel: String 0..* -beschreibung: String -aenderung: Timestamp = now() {Alle Werte != ""} {seitenzahl >= 1} 1..* 0..* Studiengang Aufgaben 0..* Lösungen 0..* Dokument -kuerzel: String -name: String 0..* -aenderung: Timestamp = now() {Alle Werte != ""} 0..* Sprache Titel -name: String -notiz: String -inhalt: Printable 0..* -datum: Date 0..* -anzahl_seiten: Integer 0..* -notiz: String -anzahl_drucke: Integer = 0 -aenderung: Timestamp = now() 0..* 0..* -kuerzel: String -name: String 0..* -aenderung: Timestamp = now() {Zwei-Buchstaben-Kürzel} {name != ""} Prüfer/Verfasser 0..* Verantwortlicher Person Verantwortlicher Verantwortlicher Verantwortlicher Abbildung 1-3 Konzeptuelles Klassendiagramm Dokument {name in {"Blattpreis", "Seitenpreis", "Öffnungszeiten-URL", "Mail-Turnus"}} Konstante -name: String -beschreibung: String -wert: String -aenderung: Timestamp = now() 0..* {name in {"Administratoren", "Dokumentare", "Verkäufer"}} Gruppe 0..* -name: String -aenderung: Timestamp = now() 0..* Verantwortlicher Verantwortlicher Verantwortlicher Person Mitglied -vorname: String 1..* -nachname: String {nachname != ""} -email: String -kreditlimit: Number = 10 Kontoinhaber {0 <= kreditlimit <= 99} Prüfer/Verfasser 0..* 0..* 0..* Dokument Verkäufer 0..1 0..* 0..* Auftrag 0..* Buchung -zeitpunkt: Timestamp = now() -betrag: Number 0..1 {exemplare >= 1} {nup in {1,2,4,8}} -nummer: Integer -status: State -abgabe: Timestamp -preis: Number -anzahl_blaetter: Integer -anzahl_seiten: Integer -fertigstellung: Timestamp 0..1 Auftragsposition 1..* -exemplare: Integer = 1 -duplex: Boolean = true 0..* -nup: Integer = 1 Abbildung 1-4 Konzeptuelles Klassendiagramm Auftrag Die verschiedenen Stati4 eines Auftrags zeigt Abbildung 1-5. 4 Der entgültige Auftragspreis wird nicht erst am Ende sondern bereits mit Beginn des Druck verbucht, um so die einfache Erweiterbarkeit des Systems auf mehr als einen Drucker zu gewährleisten. 11 Kapitel 1 Analyse Abgabe des ersten Teilauftrags nicht abgegeben Abgabe des Auftrags wartend Storno storniert Zuteilung des Druckers / verbuche Preis im Druck Druck abgeschlossen gedruckt Druckerzeugnis abgeholt abgeholt Abbildung 1-5 Zustandsdiagramm Auftrag Abgeholte oder stornierte Aufträge werden 80 Tage lang gespeichert. 1.2.6 Leistungen Das Produkt muss die Verwaltung von mindestens 4000 Personen ermöglichen. Außerdem müssen Dokumente mit insgesamt mindestens 20000 Seiten und Aufträge mit insgesamt mindestens 600000 Positionen verwaltet werden können. Die Dokumentverwaltung muss parallel von mindestens drei Arbeitsplatzrechnern aus möglich sein, ohne die Konsistenz der Daten zu gefährden. 1.2.7 Benutzerschnittstelle Als Benutzerschnittstelle für alle menschlichen Aktoren dienen Web-Interfaces, die mit einem SSLfähigen Web-Browser auf einem beliebigen Betriebssystem bedienbar sind. 1.2.8 Entwicklungsumgebung Der Fachschaftsrat stellt die Zielumgebung als Entwicklungsumgebung zur Verfügung. 1.2.9 Ergänzungen Alle monetären Daten werden bis zum 28.2.2002 sowohl Euro als auch DM und ab dem 1.3.2002 ausschließlich in Euro angezeigt. Die Speicherung dieser Daten erfolgt ausschließlich in Euro. Der Quellcode sowie die gesamte Dokumentation des Produkts müssen öffentlich zugänglich sein. Erstens soll anhand des Codes und der Dokumentation für andere Personen als den Auftragnehmer eine möglichst schnelle Einarbeitung in das Produkt insbesondere zum Zwecke korrektiver und progressiver Tätigkeiten möglich sein. Zweitens soll eine potentielle Nutzung/Integration durch/in andere Systeme durch offene Schnittstellen erleichtert werden. 12 Kapitel 1 Analyse Es dürfen keine Lizenzierungskosten anfallen. Die Lizenz des Produktes muss es erlauben, das niemandem die Benutzung, Veränderung oder Weiterverbreitung des Produkts oder Teilen davon untersagt wird. 1.2.10 Glossar Administrator Er darf Konstanten (insb. Preise) ändern und die Zugehörigkeit von Personen zu den Gruppen der Verkäufer, Dokumentare und Administratoren festlegen. Aufgaben Rolle eines Dokuments, welches die Aufgaben zu einem assoziierten Dokument mit Lösungen enthält. Auftrag Eine Sammlung von Auftragspositionen, die einem Kunden zugeordnet ist. Auftragsposition Zusammen mit Druckoptionen (z.B. Anzahl der Exemplare) repräsentiert sie einen Teil eines Auftrags, der sich auf genau ein Dokument bezieht, das gedruckt werden soll. Auftragsstatus Bezeichnung für den aktuellen Zustand eines Auftrags. Siehe auch Abbildung 1-5. Blattpreis Für jedes gedruckte Dokumentexemplar werden als Maß für den Papierverbrauch die bedruckten Blätter in Rechnung gestellt. Buchung Durch eine Buchung wird entweder die Herstellung eines Druckerzeugnisses in Rechnung gestellt oder eine Barzahlung zwischen Kunde und Verkäufer festgehalten. Die Buchungen eines Kunden ergeben sein Konto. Deckblatt Zu jedem Druckerzeugnis gehört ein Deckblatt, das Auftragsdaten, Kontostand und einen doppelten Quittungsvordruck für den Ausgleich des Kontostandes (änderbar auf einen individuellen Betrag) enthält. Es wird auf Papier aus einem auschließlich hierfür bestimmten Schacht gedruckt. 13 Kapitel 1 Analyse Dokument Für DIN A4 druckbar formatierter Dokumentinhalt zusammen mit den zugehörigen Daten, wie bspw. Datum oder Seitenzahl. Dokumentar Diese Person erfasst und verwaltet die Dokumente und ist in der Lage, dafür relevante Grundeinstellungen (z.B. Dokumenttypen) zu ändern. Dokumenttyp Jedes Dokument wird durch seinen Typ eindeutig klassifiziert. Druckerzeugnis Der ausgeführte Auftrag inkl. Deckblatt. Jede Druckseite enthält den laufenden Titel, den Namen des Kunden und die Auftragsnummer. Druckvorbereitung Die Erstellung des Deckblatts und das Formatieren der Druckseiten für ein Druckerzeugnis. Gruppe Eine Menge von Personen, die zu bestimmten Aktionen berechtigt sind. Konto Das Konto eines Kunden enthält die diesem Kunden zugeordneten finanziellen Buchungen, aus denen sich ein Kontostand ergibt. Kunde Ein Kunde ist eine Person, die über das Web-Interface im Bestand der Dokumente recherchieren sowie Druckaufträge abgeben kann. Lösungen Rolle eines Dokuments, welches die Lösungen zu einem assoziierten Dokument mit Aufgaben enthält. 14 Kapitel 1 Analyse Mail-Turnus Abstand in Tagen zwischen der Fertigstellung eines Auftrags bzw. der letzten Erinnerungsmail und der neuen Erinnerungsmail. Person Administrator, Dokumentar, Kunde, Prüfer/Verfasser und/oder Verkäufer. Prüfer Einer der zugehörigen Prüfer bei Dokumenten, die sich auf eine bestimmte schriftliche oder mündliche Prüfung beziehen. Seitenpreis Für jedes gedruckte Dokumentexemplar werden als Maß für den Tonerverbrauch die bedruckten Seiten in Rechnung gestellt. Sprache Jedes Dokument kann in einer oder mehreren Sprachen verfasst sein. Studiengang Studiengänge werden Dokumenten zugeordnet, um den Studierenden die potentielle Relavanz für sie zu zeigen. Oft handelt es sich um Studiengänge, für die eine Prüfung gestellt wurde. Titel Der Titel des Dokuments bzw. der Veranstaltung, auf die sich das Dokument bezieht. Verantwortlicher Diejenige Person, welche die Neuerfassung oder letzte Änderung eines Datensatzes vorgenommen hat. Verfasser Verfasser eines Dokuments, insb. bei Skripten. 15 Kapitel 1 Analyse Verkäufer Er gibt Druckerzeugnisse aus, nimmt Bezahlungen entgegen und verbucht sie, erklärt dem Kunden ggf., wie das ganze System funktioniert. Außerdem ist er in der Lage, Personendaten zu verwalten. 16 Kapitel 2 Entwurf 2.1 Ähnliche Softwareprodukte Um überhaupt Untersuchungen anstellen zu können, wurde der Bergriff “ähnlich” sehr weit gefasst. Viele Kandidaten entfallen für die nähere Betrachtung, weil der Quellcode nicht zugänglich bzw. die Dokumentation sehr oberflächlich ist, oder für die Verwendung, da Lizenzkosten auftreten würden. Keines der in diesem Abschnitt aufgeführten Produkte kommt für die Verwendung als Grundlage für das zu realisierende System in Frage, da alle nur einen Bruchteil der gewünschten Anwendungsfälle (dem Namen nach) bieten. Deshalb werden die Produkte lediglich kurz vorgestellt und ggf. relevante Teilaspekte, deren Implementation Modell sein könnte, näher beleuchtet. 2.1.1 Document Manager Document Manager [Pavl01] ist ein Web-basiertes Sytem zur Dokumentverwaltung, welches das Einfügen von Dateien (“Dokumenten”) in eine veränderbare Ordnerhierarchie per Upload (“Ceck-in”) ermöglicht. Die Dokumente können durch Download (“Ceck-out”) mit der Absicht der Änderung und anschließendem Check-in bezogen werden. Das System basiert auf dem Webseiten-Verwaltungssystem AnyPortal(php) [Wies00]. Die Dokumente werden im Dateisystem des Servers gespeichert, wobei die fünf letzten Versionen eines Dokuments erhalten werden. Beim Check-out wird ein Lockfile angelegt, welches weitere Check-outs verhindert und beim erneuten Check-in gelöscht wird. Die Authentifizierung eines Benutzers geschieht entweder mit Hilfe eines POP3-Accounts (EmailPostfach) auf einem beliebigen Server oder mit Hilfe von Datensätzen in einer PostgreSQL-, MySQL, Oracle- oder per ODBC (Open Database Connectivity) erreichbaren Datenbank. 2.1.2 FreeDMS Bei FreeDMS [Ente01] handelt es sich ebenso um ein Web-basiertes Dokumentverwaltungssystem mit der Möglichkeit, Dokumente in einer hierarchischen Ordnerstruktur abzulegen. Neben Upload gibt es hier Versand per Email oder Pseudo-Druck über Samba1 als Möglichkeiten der Dokumenterfassung. Dokumente können angezeigt, heruntergeladen oder mit individuellen Rechten versehen werden. Eine Volltext-Suchfunktion steht zur Verfügung. FreeDMS ist über Samba hinaus abhängig vom Webserver Apache, dem Datenbankverwaltungssystem MySQL, der Scriptsprache Perl und einem Mailserver. Die Dokumente werden als BLOBs (Binary Large Objects) in der Datenbank abgelegt. Für die Authentifizierung der Benutzer sind in der Datenbank Login-Namen und die zugehörigen Passwörter gespeichert. 2.1.3 SDMS Ein sehr einfaches Web-basiertes Dokumentverwaltungssystem stellt SDMS [Cafu01] dar. Außer Upload von Dokumenten in eine veränderliche Ornerhierarchie, individueller Rechtevergabe und Download bietet es keine weiteren Funktion. 1 Samba ist ein weit verbreiter Datei- und Druckserver, der v.a. auf Unix-Maschinen in heterogen Netzwerken eingesetzt wird. 17 Kapitel 2 Entwurf SDMS basiert auf MySQL und der Webseiten-Scriptsprache PHP. Die Benutzerauthentifizierung verläuft analog zu FreeDMS mit dem Unterschied, dass die Passwörter verschlüsselt gespeichert werden. 2.2 ArsDigita Community System Als Musterbeispiel für anpassbare Softwareprodukte wird in diesem Abschnitt das ArsDigita Community System [ArsD01] betrachtet. Es ist ein komplexes Application Framework u.a. für die Realisierung von Content Management Systemen (Redaktionssystemen für Web-Inhalt) und ECommerceAnwendungen, das die typisch benötigten Kernfunktionen z.B. der Benutzer- und Gruppenverwaltung, der Authentifizierung und Zugriffskontrolle oder auch der Produktkatalog- und Bestellungsverwaltung zur Verfügung stellt. Zur Zeit ist ACS im wesentlichen abhängig von dem Datenbankverwaltungssystem Oracle 8.1.6 Enterprise Edition [Orac00] und der Java 2 SDK Standard Edition [Java01]. Im Hinblick auf die Zielumgebung (siehe Abschnitt 1.2.3), speziell den Server, der seine Funktion als Web-, Mail- und Druckserver des Auftraggebers weiterhin wahrnehmen soll, machen allein schon die Hardwareanforderungen des Oracle-Systems die Verwendung von ACS für die Realisierung des Produkts ungeeignet. Architektonisch ist ACS strikt in Persistenz-, Geschäfts- und Präsentationslogik geschichtet. Um die konzeptuellen Klassen zu realisieren, muss sowohl SQL-Code für die Initialisierung der Datenbank als auch sogenannter PDL-Code (Persistance Definition Language), welcher die Persistenzabstraktion gewährleistet, geschrieben werden. Das ACS bietet dem Programmierer eine sehr umfangreiche Klassenbibliothek an und erscheint als viel geeigneter für sehr große Projekte als für kleine. Angesichts der Forderung nach einer schnellen ein Einarbeitungszeit in den Quellcode des zu realisierenden Systems (siehe Abschnitt 1.2.9) erscheint eine komplexe Bibliothek wenig zuträglich. Die Authentifizierung eines Benutzers erfolgt mit Hilfe des Konzeptes der Sitzung und eines in der Persistenzschicht zu speichernden Benutzerdatensatzes über das Passwort. Transaktionen, wie sie in Abschnitt 1.2.4.1 gefordert werden, können explizit über die angebotene Schnittstelle zur Persistenzschicht realisiert werden. 2.3 Programmiersprache Zunächst sei eine Vorbemerkung zur verwendeten natürlichen Sprache erlaubt. Das Produkt soll laut Pflichtenheft unter eine Open-Source-Lizenz gestellt werden. Hinzu kommt die Ansicht, dass es stilistisch schlecht ist, nicht-englische Kommentare oder gar Variablennamen in Programmquelltext zu verwenden, von dem obendrein gute Lesbarkeit erwartet wird. Wir gehen also beim Verlassen der konzeptionellen Sicht auf englische Bezeichnungen über, die nun auch in den UML-Diagrammen auftauchen. Anhang A enthält die gewählten Übersetzungen. Über die großenteils subjektiv empfundenen Vor- und Nachteile spezieller Programmiersprachen ließe sich sehr ausführlich diskutieren. Diese Arbeit konzentriert sich allerdings auf die folgenden bei der Realisierung des Projekts wichtigen Punkte: 18 • Der Funktionsumfang des zu realisierenden Systems ist überschaubar. • In Anbetracht der Ausstattung das Servers und der Tatsache, dass er weiterhin als Web-, Mail- und Druckserver des Auftraggebers dient, sind seine Ressourcen knapp. Kapitel 2 Entwurf • Das Produkt soll auf die Verwendung durch weitere Fachschaftsräte der TUHH sowie weiterer Hochschulen ausgelegt sein. • U.a. anhand des Quellcodes soll für andere Personen als den Auftragnehmer eine möglichst schnelle Einarbeitung in das Produkt insbesondere zum Zwecke korrektiver und progressiver Tätigkeiten möglich sein. Daraus lassen sich die Anforderungen an die zu verwendende Programmiersprache ableiten: • Die Sprache braucht nicht auf sehr große Systeme skalierbar zu sein. • Die Ausführung des Codes darf keine großen Hardwareressourcen erfordern. • Der resultiernde Code sollte auf hohem Abstraktionsniveau, leicht zu lesen und kurz sein. • Es sollte möglichst für Persistenz-, Verhaltens- und Präsentationslogik dieselbe Sprache verwendet werden. • Da für keine existierende Programmiersprache angenommen werden darf, dass zukünftige mit der Wartung und Pflege des Systems betraute Personen sie beherrschen, muss die hier zu verwendende Sprache leicht zu lernen sein. Die für das zu realisierende System am besten geeignete Sprache scheint Python [VanR00] zu sein. Ein detallierter Vergleich zu anderen weit verbreiteten Sprachen wie Java, C, C++, Perl oder auch PHP ist im Rahmen dieser Studienarbeit nicht möglich. Python entspricht der Anforderung nach leichter Erlernbarkeit besonders gut; bei den anderen Sprachen muss eine Aussage über die Erlernbarkeit immer unter Berücksichtigung des beim Lernenden vorhanden Vorwissens getroffen werden. Quellcode in Python besticht wie gefordert durch seine Lesbarkeit (insb. gegenüber Perl) und Kürze (v.a. gegenüber Java, C und C++). 2.4 Persistenz Aufgrund der zahlreichen Verknüpfungen zwischen den konzeptuellen Klassen des Problembereichs und vielen notwendigen Abfragen (z.B. “Alle von Person X verfassten Dokumente sortiert nach dem Datum”) sind Datenbankverwaltungssysteme (DBMS) prädestiniert, die Persistenz der Daten zu gewährleisten. Unter den frei erhältlichen Datenbankverwaltungssystemen werden MySQL [MySQ00] und PostgreSQL [Post00] sehr häufig genannt und verwendet. In dieser Arbeit beschränkt sich die Betrachtung auf diese beiden Kandidaten. Laut Abschnitt 1.2.6 darf die parallel von mehreren Rechnern aus durchgeführte Dokumentverwaltung nicht die Datenkonsistenz gefährden. Der Auftraggeber fordert sogar explizit Transaktionen für die Prüfung und Durchführung einiger Aktionen (siehe Abschnitt 1.2.4.1). Diese Forderung wird von PostgreSQL durch Transaktionen mit ACID-Eigenschaften [Ston98] erfüllt. Bis vor kurzem bot MySQL lediglich Tabellen-Locks und und sogennante “atomare Operationen”. Durch die neu hinzugekommenen Tabellen-Typen BDB und InnoDB kann MySQL nun auch ACID-Eigenschaften gewährleisten. Die Relevanz der über Transaktionen hinausgenden Funktionsvielfalt eines DBMS wird wahrscheinlich erst bei der Implementierung im Detail sichtbar, so dass im Rahmen dieser Arbeit keine Aussage darüber getroffen wird. Da auch keinem Kandidaten eine (bei Verwendung von Transaktionen) wesentlich bessere Performanz als dem anderen nachgewiesen werden kann, gibt die Tatsache, dass ACID-Transaktionen bei MySQL ein relativ neues Merkmal sind, während sie bei PostgreSQL schon sehr lange fester Bestandteil sind, den Ausschlag für die Entscheidung, PostgreSQL zu verwenden. 19 Kapitel 2 Entwurf Für den Zugriff auf PostgreSQL aus Python-Programmen gibt es im wesentlichen drei Implementationen der Python DB API 2.0 [DBAP01], welche die Schnittstelle zu Datenbanken verschiedener Hersteller vereinheitlichen soll. Das Modul psycopg [DiGr01] ist das einzige, welches einen Pool von Verbindungen zur Datenbank pflegt. Dadurch wird es möglich, für jede neue Transaktion eine schon vorhandene aber nicht mehr gebrauchte Verbindung zu verwenden. Bei Benutzung eines der beiden anderen Datenbank-Module würde für jede Transaktion eine neue Verbindung aufgebaut, was einen Geschwindigkeitsnachteil darstellt. Also findet psycopg Verwendung. 2.5 Benutzerschnittstelle Um mit Hilfe von Python und Apache dynamisch Webseiten zu erzeugen, existieren verschiedene Ansätze, von denen einer das klassische, auch in der Python-Standardbibliothek realisierte Common Gateway Interface (CGI) ist. Für jede Anfrage wird der Python-Interpreter gestartet, um das zuständige Script auszuführen, welches die Anfrageparameter über Umgebungsvariablen des Interpreterprozesses erhält. Eine weitere Möglichkeit besteht in “aktiven” Webseiten, die in ihren HTML-Code eingebetteten Python-Code enthalten. Dafür gibt es verschiedene Imlpementationen [Bodd01]. Schließlich existiert noch das Apache-Modul mod_python [Trub01], welches den Interpreter in den Webserver einbettet. Diese Methode hat den Vorteil, dass Instanzen des Interpreters statt bei jeder Anfrage nur beim Start des Webservers entstehen. Weil dies im Vergleich zu CGI einen erheblichen Geschwindigkeitszuwachs bringt und HTML- und Python-Code sauber getrennt werden können statt vermischt werden zu müssen, ist dies der Ansatz der Wahl. Die Verwendung von JavaScript oder ähnlichem auf der Client-Seite verbietet das Pflichtenheft implizit durch die Beschränkung auf SSL-fähige Browser, was als eine Maximalanforderung an die Benutzermaschinen darstellt. 2.6 Verteilung Der Auftraggebers fordert die Bedienbarkeit des Systems mit Hilfe von Web-Browsern auf beliebigen Betriebssystemen und diktiert hierdurch eine "Thin Client"-Architektur, bei der abgesehen von der Benutzerschnittstelle die gesamte Funktionalität in dem einen dafür zur Verfügung stehenden Server realisiert wird. Die im wesentlichen beteiligten Prozesse zeigt Abbildung 2-1. “postmaster” ist der Name des Datenbank-Backends. SSL-Browser apache FS Abbildung 2-1 Thin Client-Architektur 20 postmaster DB Kapitel 2 Entwurf 2.7 N-Schicht-Architektur Um eine gute Übersichtlichkeit und Robustheit zu erreichen, ist es sinnvoll, die Software nach der N-Schicht-Architektur aufzubauen, wie sie in Abbildung 2-2 (siehe auch [Ambl00]) dargestellt ist. Jede Schicht verbirgt ihre Implementation vor abhängigen, höher liegenden Schichten, indem ausschließlich über eine fest definierte Schnittstelle auf ihre Bestandteile zugegriffen werden kann. Weil dies möglichst wenig Verflechtung bzw. Kopplung zwischen den Klassen bedeutet, entsteht robuster Code, bei dem der Entwickler die Folgen einer Änderung besser absehen kann [Shaw96]. Präsentationsklassen Kontroll-Klassen SystemKlassen Geschäftsklassen Persistenz-Klassen Speicher Abbildung 2-2 N-Schicht-Architektur Die Persistenz-Klassen als unterste Schicht sollen die Schnittstelle zum Persistenzmechanismus (in unserem Fall einem DBMS) nutzen und dabei Persistenzabstraktion bieten: Langlebige Objekte der darüberliegenden Schicht müssen sich nicht mit den Details auseinandersetzen, auf welche Art und Weise sie sich persistent machen. 21 Kapitel 2 Entwurf Die Geschäftsschicht muss alle im Pflichtenheft aufgeführten Daten und Regeln der konzeptuellen Klassen des Problembereichs umsetzen. Dazu gehören auch Hilfsklassen, die nicht explizit gefordert werden aber nötig sind, um bestimmte gewünschte Funktionen realisieren zu können. Kontroll-Klassen sollen als übergeordnete Instanz auf Geschäftsklassen zugreifen, wenn nicht interaktive Hintergrundaufgaben zu erledigen sind oder ein bestimmter Anwendungsfall die Zusammenarbeit mehrerer Klassen der Geschäftsschicht erfordert. Die auf jeder Ebene nutzbaren System-Klassen kapseln den Zugriff auf benötigte BetriebssystemFunktionen wie Drucken oder Mailen. Schließlich werden in der Präsentationsschicht alle für die Produktbenutzung durch menschliche Aktoren notwendigen Klassen zusammengefasst. Dabei können durchaus verschiedene Arten von Benutzerschnittstellen zu Untergruppierungen führen. Es ist anzumerken, dass diese Architektur besonders gut für die vorliegende Aufgabenstellung geeignet ist. Die Implementation der Persistenzschicht ist austauschbar und die oberste Schicht kann um andere Benutzerschnittstellen erweitert werden. So könnte beispielsweise MySQL statt PostgreSQL mit der Datenspeicherung beauftragt oder die Verwendung eines auf den Clients zu installierenden Programms für eine komfortablere Oberfläche ermöglicht werden. Außerdem wirkt sich die geringe Kopplung zwischen den Systemkomponenten günstig auf die geforderte leichte Erlernbarkeit für potentielle Entwickler aus. Abbildung 2-3 zeigt, wie versucht wurde, die dargelegte Architektur umzusetzten. Nicht aufgeführte Klassen sind durch Auslassungszeichen angedeutet. Es handelt sich dabei allerdings ausschließlich um den Entwurf für konzeptuelle Klassen des Problembereichs und solche, welche diese ergänzen, um das Systemverhalten vollständig zu ermöglichen (siehe Abschnitt 2.7.2.1 und Abschnitt 2.7.2.2). Im folgenden werden die neuen Klassen kurz vorgestellt. wdps ui Dictionary web Request Argument_record Page business Person Document Order Observed_object . . . Query persistence Persistent_object Class_map Abbildung 2-3 Paketdiagramm 22 Attribute_map Transaction Kapitel 2 Entwurf 2.7.1 Persistenz-Schicht Die für Python verfügbaren Persistenz-Abstraktionsmodule sind dadurch gekennzeichnet, dass sie sehr oft als wichtiger Bestandteil größer Projekte realisiert wurden. Ein naheliegender, jedoch dicht am relationalen Modell orientierter Kandidat ist dbObj [Remp00]. Ein Modul, das sowohl einen ausreichend hohen Abstraktionsgrad als auch ein den Anforderungen entsprechend geringen Umfang hat, konnte nicht gefunden werden und soll deshalb selbst entworfen und inplementiert werden. Als Grundlage des Entwurfs dient [Ambl00], wobei allerdings nur die wichtigsten Konzepte übernommen werden. Eine Einführung in die Klassen des Pakets liefern die folgenden Abschnitte, während Hinweise zur Implementation und Nutzung in Abschnitt 3.1 zu finden sind. Um das Paket schlank und den Implementationsaufwand annehmbar zu halten, wird darauf verzichtet, objektorientierte Hilfsmittel für die Operation auf vielen Objekten einer oder gar mehrerer Klassen persistenter Objekte zu erstellen. Solche Operationen sollen der Einfachheit halber in der Geschäftsschicht durch die Verwendung der Query-Klasse (Abschnitt 2.7.2.3) realisiert werden. 2.7.1.1 Transaction Transaction-Objekte dienen der Kapselung von Datenbank-Transaktionen und bieten neben den üblichen commit- und rollback-Methoden die Möglichkeit, Aktionen zu registrieren, die erst dann ausgeführt werden, wenn die Transaktion garantiert erfolgreich abgeschlossen wurde. Ein Beispiel hierfür ist, mit der Benachrichtigungsmail an neu registrierte Personen so lange zu warten, bis die Personendaten garantiert persistent sind. Jede Operation auf langlebigen Objekten findet innerhalb einer Transaktion statt. 2.7.1.2 Class_map Für die Abbildung auf den Speicher des Persistenzmechanismus verwenden Klassen Class_mapInstanzen. Diese enthalten jeweils u.a. Informationen über Tabellennamen und Primärschlüssel und eine Sammlung von Attribute_map-Instanzen. Jeder Klasse persistenter Objekte wird genau eine Tabelle der Dantenbank zugeordnet. 2.7.1.3 Attribute_map Da die Namensgebung der Objektattribute nicht immer mit den Spaltennamen der Datenbank übereinstimmen kann oder muss, ist es sinnvoll, eine Abbildung der Namen definieren zu können. Darüberhinaus enthalten Attribute_map-Instanzen Informationen über den Attributtyp, die Eindeutigkeit, usw. Objekt-Assoziationen werden durch spezielle Attributtypen gekennzeichnet, so dass jede Assoziation über ein eigenes Attribut zugänglich ist. 2.7.1.4 Persistent_object Jede Klasse persistenter Objekte erbt von Persistent_object die für die Persistenz notwendigen Methoden und stellt seine Abbildung auf die Datenbank in einem Class_map-Objekt bereit. Für die konsequente Einhaltung der N-Schicht-Architektur müsste die Einschränkung von Attributwerten eigentlich komplett in der Geschäftsschicht abgewickelt werden, weil die Regeln dafür von den konzeptuellen Klassen herrühren. Dies gilt ebenso für die Assoziationen. Da jedoch gerade relationale DBMS auf die Integritätsbewahrung vieler Objekte spezialisiert sind, sollen hier alle notwendigen Prüfungen der Eindeutigkeit und der referentiellen Integrität vom DBMS durchgeführt werden. 23 Kapitel 2 Entwurf 2.7.2 Geschäftsschicht In diesem Abschnitt werden diejenigen Klassen aufgeführt, die über den Umfang der im Pflichtenheft aufgeführten konzeptuellen Klassen hinausgehen. Anmerkungen zur Implementation befinden sich in Abschnitt 3.2. 2.7.2.1 Monthly_sum In Abschnitt 1.2.4.1.27 werden zusammenfassende, historische Informationen über den Datenbestand verlangt. Es ist daher nötig, diese Informationen in Einheiten der kleinsten geforderten zeitlichen Granularität (Monat) aufzubewahren. 2.7.2.2 Session Für die meisten Anwendungsfälle muss die Authentizität des Aktors gewährleistet sein. Eine Passwörter nutzende Methode wird im Pflichtenheft angeregt. Weil es dem Anwender sehr entgegenkommt, nicht für jede Aktion sein Passwort eingeben zu müssen, bemühen wir uns des Konzepts der Sitzung. Jede Session-Instanz ist mit einer eindeutigen, sehr schwer zu erratenden Kennung (Session-ID) versehen, die der Benutzer erhält, nachdem er sich erfolgreich über den Passwort-Mechanismus authentifizieren konnte. Danach wird sein Wissen um die Sitzungskennung als ausreichend für seine Authentizität erachtet. Das Ende einer Sitzung wird entweder nach Ablauf einer bestimmten Zeitspanne der Inaktivität oder explizit durch den Benutzer herbeigeführt, damit es sich bei der Sitzungskennung im Gegensatz zum Passwort um ein temporäres Geheimnis handelt, das für Angreifer wertlos wird. 2.7.2.3 Query Das grundlegende Problem bei der Anbindung objektorientierter Programmiersprachen an relationale Datenbankverwaltungssysteme wird als “Impedance Missmatch” bezeichnet [Härd99]: Die Datenstrukturen der beiden Seiten passen nicht gut zusammen; während bspw. das DBMS mit Hilfe seiner Abfragesprache prinzipiell viele Datensätze liefert, werden mit objektorientierten Sprachen einzelne Objekte manipuliert. Wie in Abschnitt 2.7.1 erwähnt bietet die Persistenzschicht aus Gründen der Einfachheit keine Möglichkeit, auf Mengen von langlebigen Objekten zu operieren. Wo immer so eine Operation benötigt wird, soll eine Subklasse von Query diese Funktionalität ermöglichen, indem unter intensiver Nutzung der Class_map-Instanzen Datenbankabfragen explizit gestellt werden. Dazu vererbt die Query-Klasse die Zugriffsmöglichkeiten auf Transaction-Instanzen. Als Ergebnis ihrer result-Methode liefert jede Query-Instanz i.d.R. ein oder mehr persistente Objekte, eine Menge von Objekt-Kennungen oder einen den Erfolg der Operation signalisierenden Wahrheitswert zurück. 2.7.2.4 Observed_object In Anbetracht dessen, dass einige konzeptuelle Klassen den Zeitpunkt der letzten Änderung als Attribut und eine Assoziation mit der für diese Änderung verantwortlichen Person aufweisen, ist es ratsam, dieses Muster in einer Spezialisierung von Persistent_object zu berücksichtigen. Alle Klassen, deren Instanzen auf diese Weise verfolgt werden, erben also von Observed_object statt von Persistent_object. 24 Kapitel 2 Entwurf 2.7.3 Präsentationsschicht Die in diesem Abschnitt vorgestellten Klassen haben die Aufgabe, die Erzeugung der Benutzerschnittstelle zu ermöglichen. 2.7.3.1 Dictionary Um eine möglichst saubere Trennung zwischen Python-Code und HTML-Code zu gewährleisten, wird mit HTML-Vorlagesegmenten gearbeitet, die Ersetzungsmarken enthalten können, welche zur Laufzeit mit beliebigen Strings oder weiteren HTML-Segmenten ausgefüllt werden. Alle Vorlagesegmente werden unter einem eindeutigen Namen in Dictionaries abgelegt. Obwohl es vom Auftraggeber nicht vorgegeben wurde, so ist an einer Universität mit hohem Anteil an ausländischen Studierenden doch zu erwarten, dass der Wunsch nach einer mehrsprachigen Benutzeroberfläche aufkeimen wird. Es sollte also eine Implementation gewählt werden, die einfach auf weitere Benutzersprachen erweitert werden kann. 2.7.3.2 Request Request-Instanzen werden von mod_python zur Verfügung gestellt und entsprechen je einem HTTPRequest. Sie enthalten alle für das HTTP-Protokoll relevanten Informationen, insbesondere über die Anfrageargumente. 2.7.3.3 Argument_record Damit der Entwickler einen objektorientierten Zugriff auch auf die von Anfrage zu Anfrage weitergereichten Argumente erhält, wird bei der Verarbeitung jeder Anfrage die Argument_record-Klasse instantiiert. 2.7.3.4 Page Ein Page-Objekt stellt die Antwort auf Anfragen dar und enthält alle dafür notwendigen Informationen, v.a. Vorlagensegmente. Bei der Instantiierung soll — sofern nötig — die Authentizität geprüft und abhängig von der Gruppenzugehörigkeit des Benutzers der Navigations- und Titelbereich der zurückzugebenden HTML-Seite vorbereitet werden. 25 Kapitel 2 Entwurf 26 Kapitel 3 Implementierung In diesem Abschnitt beschäftigen wir uns mit der Umsetzung der Vorgaben des Pflichtenheftes im Rahmen der getroffenen Entwurfsentscheidungen. Es werden insbesondere Fragen zur Einfachheit, Änderbarkeit und Robustheit behandelt und die dabei auftretenden Probleme aus Entwicklersicht angesprochen. Darüber hinaus soll Autoren, die sich mit Fehlersuche, Änderung oder Erweiturung des Systems beschäftigen möchten, ein möglicher Weg zur Benutzung der Schnittstellen und zum Verständnis der Systemrealisierung aufgezeigt werden, ohne direkt in den Quelltext einsteigen zu müssen. Es liegt nahe, die in Abschnitt 2.7 gewählte Reihenfolge der Vorgensweise zu übernehmen. 3.1 Persistenz-Schicht An dieser Stelle die wollen wir die Gesichtspunkte beleuchten, die bei der Implementation der in Abschnitt 2.7.1 vorgezeichneten Klassen interessant erscheinen. Übersichtshalber liefert Abbildung 3-1 das zugehörige Klassendiagramm. Persistent_object class_map: Class_map __init__(transaction:Transaction,id:Integer=None,values:Keyword_args) __setattr__(name:String,value:Object) save() delete() get_transaction() Class_map Attribute_map table_name: String id_column_name: String attribute_maps: Dict update_only: Boolean sql: SQL type: Type default_value: Object none_forbidden: Boolean unique: Boolean read_only: Boolean Transaction commit() rollback() register_commit_action(action:Function) Abbildung 3-1 Persistenz-Klassen 3.1.1 Transaktionen Die Nutzung von Transaktionen soll u.a. die Konsistenz der Daten und die Isolation der Benutzer voneinander gewährleisten. Tritt z.B. vor Ende einer Anfragebearbeitung zwischen zwei ObjektÄnderungen eine erwartete oder auch unerwartete Ausnahme ein, so werden alle Änderungen bis zurück zum Transaktionsbeginn rückgängig gemacht. Eine Transaktion dauert nicht länger als die Bearbeitung einerAnfrage an den Webserver, da sonst Benutzer bliebig viele Datensätze beliebig lange blockieren könnten. Somit können Werte von Daten (z.B. Auftragsstatus: “wartend”; notwendig für die Stornierung des Auftrags) nicht bis zu einer folgenden Anfrage (z.B. “Ich möchte wirklich stornieren“) gewährleistet werden. Die im Pflichtenheft geforderte Bündelung von Durchführbarkeitprüfung und Durchführung beschränkt sich also auf eine Anfrage. Mit anderen Worten: Obwohl der Benutzer eine Aktion bestätigt, kann es trotzdem sein, dass sie nicht durchgeführt wird. 27 Kapitel 3 Implementierung Ein Caching von Objekten zwischen Persistenz- und Geschäftslogik ist zunächst nicht vorgesehen. Da sich die in Python implementierten Handler verschiedener Apache-Prozesse zu sich überschneidenden Zeiten dasselbe Objekt aus der Datenbank holen können, kann es sein, dass mehrfache Kopien in den Namensräumen der Interpreter existieren. Der Transaktionsmechanismus gewährleistet jedoch, dass nicht mehr als eine davon geändert in die Datenbank zurückgeschrieben werden kann. Bei der Implementation trat das Problem auf, dass nach Ende einer Transaktion trotz der Löschung des zugehörigen Transaction-Objekts die zugehörige Datenbankverbindung nicht wieder freigegeben wurde, um als Bestandteil des Verbindungspools (siehe Abschnitt 2.4) wiederverwendet zu werden. Offensichtlich wurde der Fehler erst, als bei der 65. Anfrage in Folge das Datenbank-Backend jede weitere Verbindung verweigerte. Der Fehler konnte in der Definition des Transaction-Konstruktors lokalisiert werden. Die Referenzierung einer Instanzmethode durch ein Instanzattribut bereitet dem Garbage-collector offensichtlich Probleme, der Grund hierfür bleibt verborgen. Möglicherweise handelt es sich um einen Fehler im Interpreter. class Transaction: """Wrapper for a PostgreSQL transaction.""" def __init__(self): """Begin a new database transaction. Return a Transaction instance.""" self._cursor = _connection.cursor() self._commit_actions = [] if DEBUG: self._execute = self._execute_debugging else: self._execute = self._execute_non_debugging def _execute_debugging(self, operation, parameters): """Execute an SQL statement and log it.""" expanded_operation = operation % parameters log_message("Executing >>%s<< (quoting might differ)." % expanded_operation) self._execute_non_debugging(operation, parameters) def _execute_non_debugging(self, operation, parameters): ... 3.1.2 Persistente Objekte 3.1.2.1 OR-Mapping In Abschnitt 2.7.1.2 und Abschnitt 2.7.1.3 wurde bereits erwähnt, dass die Klassen Class_map und Attribute_map der Abbildung von Objekten der Programmiersprache auf Objekte des DBMS dienen. Auf die letztere Klasse und ihre Verwendung innerhalb von Methoden der abstrakten Klasse Persistent_object soll hier näher eingegangen werden. Jede Attribute_map-Instanz enthält den Attributtyp. Erlaubt sind String, Integer, Float, DateTime, Association1 und AssociationN, was zur Laufzeit überprüft wird. Erlaubte Werte für Assoziationsattribute sind Integer-Zahlen, die den Fremdschlüsseln in der Datenbank entsprechen, bzw. Listen davon. Der zweite Parameter des Attribute_map-Konstruktors enthält den Spaltennamen in der zugehörigen Datenbanktabelle oder bei einer Assoziation mit mehreren Objekten sämtliche Informationen über die Assoziationstabelle. Darüber hinaus kann noch ein Standardwert festgelegt werden, ob “Unbekannt” ein gültiger Wert ist und ob der Wert nur gelesen werden darf. 28 Kapitel 3 Implementierung Wie das folgende Code-Beispiel zeigt, wird Vererbung in Python definiert, indem der Name der Superklasse in Klammern auf den Namen der Subklasse folgt. Das Klassenattribut class_map weist auf die zugehörige Class_map-Instanz, bei deren Initiierung alle notwendigen SQL-Strings festgelegt werden. Die Speicherung des Klassennamens "Order" und der Abbildung constraint_info von SQL-Constraint-Namen auf Objekt-Attributnamen dient dazu, erst im DBMS abgefangene Integritätsverletzungen eindeutig identifizieren zu können, um eine aussagekräftige Fehlermeldung an den Benutzer zu veranlassen. from wdps.persistence import Persistent_object, Class_map, Attribute_map, \ StringType, IntType, DateTimeType, Association1Type, AssociationNType class Order(Persistent_object): """Represents an order of a customer.""" Am = Attribute_map # Overrides inherited attribute. class_map = Class_map( "Order", "orders", "id", {"status": Am(StringType, "status", "N", none_forbidden=1), "submission_time": Am(DateTimeType, "submission_time"), "price": Am(IntType, "price"), "number_of_sheets": Am(IntType, "number_of_sheets"), "number_of_pages": Am(IntType, "number_of_pages"), "completion_time": Am(DateTimeType, "completion_time"), "customer_id": Am(Association1Type, "customer_id", none_forbidden=1), "posting_id": Am(Association1Type, "posting_id"), "order_item_ids": Am(AssociationNType, ("order_items", "order_id", "id"), read_only=1)}, constraint_info={"or.customer_id.pe": "customer_id", "or.posting_id": "posting_id", "or.posting_id.po": "posting_id"}) def submit(self): """If order isn’t submitted submit it, return 1, else return 0.""" if self.status != "N": return 0 ... 3.1.2.2 Werteinschränkung Um die im Pflechtenheft festgelegten Regeln der Datenintegrität zu befolgen, werden alle Einschränkungen außer denen der Eindeutigkeit und der referentiellen Integrität (siehe Abschnitt 2.7.1.4) programmatisch in der Geschäftsschicht geprüft. Python unterstützt Datenkapselung nur mäßig; mit dem erforderlichen Wissen kann ein Entwickler im Prinzip auf alles zugreifen. Die ausschließliche Nutzung vorgesehener Schnittstellen basiert immer auf Konvention. Bei strikter Objektorientierung ist es üblich, für alle Attribute getter- und setter-Methoden zu definieren, was nicht nur stereotypen Code bei uneingeschränkten Attributen zur Folge hat, sondern auch den Code, der von außen auf Attribute zugreift, aufbläht. Die vorliegende Implementation nutzt stattdessen die in Python vorgesehene Möglichkeit, die __setattr__-Methode einer Klasse zu definieren, welche dann bei jeder Zuweisung an ein Attribut implizit aufgerufen wird, um die o.a. Einschränkungen zu gewährleisten. Wie groß der negative Einfluss auf die Performance ist, müsste durch Test ermittelt werden. Außerdem erlaubt die Persistent_object-Klasse von ihr abgeleiteten Klassen Methoden namens _is_valid_aaa zu definieren, wobei aaa für den Attributnamen steht. Existiert eine solche Methode, wird sie ebenfalls bei jeder Zuweisung objekt.aaa = wert implizit aufgerufen, damit im Falle eines ungültigen Wertes ein ValueError erzeugt wird. 29 Kapitel 3 Implementierung Im folgenden Code-Beispiel ist die Umsetzung einiger Geschäftsregeln der Person-Klasse zu sehen. Der Nachname darf nicht leer sein, Authentifizierungs-Account und Email-Adresse müssen speziellen Mustern genügen, und das Kreditlimit darf weder negativ noch größer als 9900 Cent sein. from wdps.persistence import Persistent_object import re class Person(Persistent_object): ... _auth_account_rexp = re.compile(r"^[-a-zA-Z0-9._]+@[-a-zA-Z0-9.]+$") _email_rexp = re.compile(r"^[-a-zA-Z0-9._]+@[-a-zA-Z0-9.]+$") def _is_valid_surname(self, value): """Return the result of the value validation.""" return value != "" def _is_valid_auth_account(self, value): """Return the result of the value validation.""" return value == "" or Person._auth_account_rexp.search(value) def _is_valid_email(self, value): """Return the result of the value validation.""" return value == "" or Person._email_rexp.search(value) def _is_valid_credit_limit(self, value): """Return the result of the value validation.""" return 0 <= value <= 9900 ... Ein aufgetretenes Problem ist die unzureichende Kapselung von AssociationN-Attributen, die als Python-Standarddatentyp Liste implementiert sind: Das direkte Setzen auf einen ungültigen Wert durch Zuweisung kann zwar abgefangen werden, das Nutzen der Python-Methoden für Listenobjekte jedoch nicht, da der Listentyp in der vorliegenden Python-Version noch keine ableitbare Klasse ist, deren Methoden wie bspw. remove man überschreiben oder erweitern könnte. 3.1.3 Dokument-Behandlung Die Frage, wie die Dokumente zu behandeln sind, teilt sich in zwei Teile auf. Zum einen muss geklärt werden, in welchem Format Dokumente vorliegen sollen. Wichtige Gesichtspunkte sind dabei Druckvorbereitungsdauer, Druckdauer und Speicherbedarf. Es muss bedacht werden, dass ein großer Teil der Dokumente über den Scanner erfasst werden soll. Darüber hinaus besteht die Notwendigkeit, Seiten vor dem Ausdrck mit einem dynamisch erzeugten Informationstext versehen zu können. Es liegt nahe, Dokumente in PostScript, der “Muttersprache” des vorgegebenen Druckers zu speichern. Eine entgültige Entscheidung konnte allerding noch nicht getroffen werden. Nicht weniger wichtig ist die Frage, ob ein Dokument wie gewohnt im Dateisystem (des Servers) oder besser direkt in der Datenbank gespeichert werden sollte. Die Speicherung als Datei bietet eine bessere Skalierbarkeit. Falls dass System an die Grenze von Partitionsplatz stößt, ist die Mitverwendung neuer Partitionen sehr einfach zu realisieren. Außerdem besteht eine größere Flexibilität, was die später mögliche Erweiterung des Systems z.B. um eine Download-Funkion angeht. In Bezug auf das Pflichtenheft erscheint allerdings die zweite Variante eher angebracht. Die Dokumente wären wie der Rest der Daten dem Transaktionsmechanismus des DBMS unterworfen, was die Konsistenz der Daten auch bei parallelem Zugriff durch mehere Benutzer oder nach einem Systemausfall sicherstellte. Auch müssten für die Zeit während eines System-Backups keine besonderen Vorkehrungen getroffen werden. 30 Kapitel 3 Implementierung Erste Tests bescheinigten dem theoretisch vorzuziehenden Ansatz der Speicherung in der Datenbank allerding eine verheerende Laufzeit. Schon das Einfügen von Datenmengen mittleren Umfangs beanspruchte die Zielmaschine jeweils mehrere zehn Sekunden, während denen sie ihre anderen Aufgaben nur sehr eingeschränkt wahrnehmen konnte. PostgreSQL hat sich dahingehend bewegt, das Abspeichern großer Objekte direkt in Tabellenspalten zu ermöglichen und von der früher speziell vorgesehen Klasse “Large Object” Abstand zu nehmen. Gegenwärtig existieren aber leider keine speziellen Operationen, um große Daten stückweise in Tabellenspalten einzufügen, so dass das gesamte Datum als ein Stück den SQL-Parser passieren muss. Aufgrund dieses Flaschenhalses fällt die Entscheidung also fürs Erste auf die Speicherung im Dateisystem. Wir halten grundsätzlich fest, dass getroffene Annahmen frühzeitig überprüft werden müssen, weil das Ergebnis der Überprüfung durchaus Entwurfsentscheidungen beeinflussen kann. 3.2 Geschäftsschicht Eine Monthly_sum-Instanz erfasst die für die Datenbestandsübersicht relevanten Zahlen eines Monats. Während die Anzahl an Dokumenten, Titeln und Personen nur einmal im Monat beim aktuellen Stand festgehalten werden muss, gehen die restlichen Zahlen aus den Aufträgen hervor und werden immer dann aktualisisiert, wenn ein Auftrag fertiggestellt oder storniert wird. Bei der Erstellung der Übersicht müssen laufende Aufträge, die warten oder in Produktion sind, mit berücksichtigt werden. Aussagen bezüglich der Nutzung der Session-Klasse sind in Abschnitt 3.3.2 zu finden, während die Observed_object-Klasse in Abschnitt 2.7.2.4 ausreichend behandelt wurde. Die Klassen Constant, Document, Document_type, Group, Language und Study_program erben von Observed_object. Abbildung 3-2 gibt einen Überblick über die Klassenhierarchie. Persistent_object Monthly_sum Person . . . Observed_object class_map: Class_map modification_time: DateTime = now() resposible_id: Integer save() Document . . . Session id: String 0..1 user_id: Integer user_groups: String last_request_time: DateTime = now() __init__(transaction:Transaction,id:String=None,user_id:Integer=None) delete() Abbildung 3-2 Klassenhierarchie Die Entscheidung, aus Gründen der Einfachheit in der Persistenzschicht auf objektorientierte Hilfsmittel für Operationen auf vielen Objekten zu verzichten, erweist sich bei der Implementation als wenig hilfreich. Diese Art der Operation kommt sehr häufig vor und sollte dem entsprechend gut unterstützt werden. Wünschenswert ist ein Framework, um alle Abfragen unabhängig vom SQL- 31 Kapitel 3 Implementierung Dialekt gut lesbar in Python formulieren zu können. Während die Implementierung eines solchen Frameworks erheblichen Programmieraufwand mit sich bringt, wäre der erzielte Abstraktionsgrad auf höheren Schichten von großem Wert. Das folgende Code-Beispiel zeigt die stereotypische Formulierung, Ausführung und Auswertung einer Datenbankabfrage. In diesem Fall soll eine Liste aller abgelaufenen Sitzungen zurückgegeben werden. from wdps.business import Session class Old_sessions(Query): def result(self): """Return a list of all sessions which can be deleted.""" from wdps.constants import SESSION_TIMEOUT class_map = Session.class_map tn = class_map.table_name idcn = class_map.id_column_name lrtcn = class_map.attribute_maps["last_request_time"].column_name cond = ( "now() - %(lrtcn)s > ’%(SESSION_TIMEOUT)s minutes’" % vars()) operation = "select %(idcn)s from %(tn)s where %(cond)s" % vars() self._execute(operation, vars()) if self._cursor.rowcount: # Flatten the list of 1-tuples returned by fetchall(). ids = map(max, self._cursor.fetchall()) return map(Session, [self._transaction] * len(ids), ids) else: return [] Bei der Frage wo zusätzliche Konfigurationsparameter festzulegen sind, ist die Tatsache wichtig, dass es zwei verschiedene Sichten auf die Systemkonfiguration gibt: die des Software-Administrators und die des Druckdienst-Administrators. Dem wurde durch die Verwendung einer Konfigurationsdatei namens /etc/wdps.conf, in der vornehmlich Pfade definiert werden, Rechnung getragen. Um die korrekte Implementierung sämtlicher Geschäftsklassen inklusive ihrer Regeln zu kontrollieren existiert das Python-Script business_test.py. 3.3 Präsentationsschicht 3.3.1 Klassen Die folgenden Abschnitte sind den Präsentationsklassen gewidmet. Jedoch findet die Page-Klasse keine Erwähnung, weil den Aussagen in Abschnitt 2.7.3.4 nichts hinzuzufügen ist. 3.3.1.1 Dictionary Im realisierten System gibt es keine echte Klasse Dictionary sondern das Modul dictionaries, von dem Schnittstellenimplementierungen die Abbildung languages von Sprachkürzeln auf Sprachnamen und Vorlagen-Verzeichnisse importieren können. Diese in Abschnitt 2.7.3.1 skizzierten Verzeichnisse sind als vom Python-Sprachkern angebotene Dictionaries realisiert, was die Verwendung besonders vereinfacht und die Eignungsprüfung zahlreicher existierender Vorlagenmodule [Bodd01] obsolet macht. Desweiteren exportiert dictionaries ein Verzeichnis von noch nicht auf die gewählte Sprache lokalisierten HTML-Segmenten, damit der Entwickler aus Gründen der Lesbarkeit wählen kann, ob 32 Kapitel 3 Implementierung er Segmente, die reich an HTML-Auszeichnungscode sind und wenig konstantem Text enthalten (z.B. Formulare), lieber dort definiert. Um der Mehrsprachlichkeit möglicher Folgeversionen gänzlich den Weg zu bereiten, werden dynamisch erzeugte Inhalte von Emails und Ausdrucken gleichfalls als Bestandteil einer Benutzerschnittstelle angesehen und entsprechend in der vorhandenen Abbildung für die deutsche Sprache abgelegt. Für eine konsistente Objekt-Orientierung ist es ratsam, die gewählte Implementierung der VorlagenVerzeichnisse noch einmal zu überdenken. 3.3.1.2 Request Um die Zuordnung von Anfragen auf den für die durchzuführende Aktion zuständigen Python-Code einfach zu gestalten, findet der von mod_python mitgelieferte “PublisherHandler” Verwendung. Wenn dieser Handler für das Web-Verzeichnis ddd aktiviert wird, “landen” Anfragen der Form https://host/ddd/quit/session?session_id=... in einer Datei quit.py in der Funktion session, die als Parameter mindestens die Referenz auf das aktuelle Request-Objekt nimmt. from wdps.ui.web.page import Page from wdps.business import Session, Person def session(req): page = Page(req) if page.caption: return page.get(page.caption) arg = page.arg session = Session(page.transaction, arg.session_id) user = Person(page.transaction, page.user_id) user.last_session_time = session.last_request_time user.save() session.delete() page.transaction.commit() del arg.session_id # Recreate navigation segment without using session ID. page.set_navigation_segment() return page.get("Session quit") 3.3.1.3 Argument_record Von mod_python wird auch die Klasse FieldStorage für die übermittelten Anfrageargumente bereitgestellt. Auf FieldStorage-Instanzen kann man wie auf ein Python-Dictionary zugreifen; allerdings können wie bei HTTP üblich für einen Argumentnamen durchaus mehrere Werte vorliegen, die dann als Liste von Strings repräsentiert werden. Um die Überprüfung dieses Sonderfalls an sehr vielen Stellen des Quellcodes einzusparen, werden Anfrageargumente bewusst rigoros auf skalare Werte eingeschränkt. HTTP wird oft als ein “zustandsloses Protokoll” bezeichnet: Es ist nicht möglich, aus einer Anfrage Informationen über die Anfrage-Historie zu erlangen. Die im Pflichtenheft geforderte Prüfung von Werten zusammen mit der Möglichkeit Aktionen abzubrechen impliziert jedoch genau dies. Für POST-Anfragen wird dies durch ein verborgenes Formularelement realisiert, in dessen Wert alle zur nächsten Anfrage zu propoagierenden Argumente enthalten sind. Darüber hinaus soll es möglich sein Anfrageargumente während der Verarbeitung hinzuzufügen bzw. zu löschen. Ein gutes Beispiel dafür ist, das session_id-Argument, das bei Sitzungsstart bzw. -ende hinzuzufügt bzw. gelöscht werden muss, um die korrekte Weiterverarbeitung zu gewährleisten. 33 Kapitel 3 Implementierung Die Umsetzung all dieser Vorgaben wird durch die Verwendung einer Argument_record-Instanz ermöglicht. Die Objektattribute entsprechen den Anfrageargumenten zusammen mit den propoagierten Argumenten. 3.3.2 Sitzungsverwaltung Die implementierte Sitzungsverwaltung dient ausschließlich dazu, die Authentizität des Benutzers auf eine für ihn angenehme Art zu gewährleisten, damit er entsprechend seiner Gruppenzugehörigkeit nur bestimmte Anwendungsfälle durchführen kann. Aktionen zu bündeln oder zu protokollieren ist nicht Aufgabe der vorliegenden Sitzungsverwaltung. Ein Benutzer authentifiziert sich unter Verwendung des HTTPS-Protokolls mit einem Benutzernamen und einem Passwort. Ersterem ist im System ein “Authentifizierungs-Account” (z.B. ein Account beim Rechenzentrum der TUHH) zugeordnet, der genutzt wird, um per SSH die Korrektheit des Passworts zu prüfen. Auf diese Weise muss sich der Benutzer für einen u.U. selten genutzten Dienst kein zusätzliches Passwort merken, und der Auftraggeber ist nicht für die Passwortverwaltung verantwortlich. Nach erfolgreichem Sitzungsbeginn wird eine 40-stellige Kennung jeder auszuliefernden HTMLSeite in den URLs und einem verborgenen Formularfeld (notwendig für Anfragen nach der POSTMethode) beigefügt, so dass spätere Anfragen über die Sitzungskennung eindeutig und sicher einem Benutzer zugeordnet werden können. Diese Vorgehensweise ist der Verwendung von Cookies vorzuziehen, da es für den Benutzer bequemer ist, Cookies nicht aktivieren zu müssen. Der Nachteil dieser Methode ist jedoch, dass die explizite Behandlung der Sitzungskennung umständlich ist und ausgelieferte Seiten mit vielen Referenzen redundant aufgebläht werden. Das HTMLbase-Tag könnte einen Ansatzpunkt liefern, diesen Nachteil durch Intergration der Kennung in den Pfadanteil der URL zu umgehen. 34 Kapitel 4 Zusammenfassung Es wurde ein System zur Web-basierten Behandlung von Personen, Dokumenten und Druckaufträgen großenteils geschaffen. Für diverse Anwendungsfälle existiert noch keine vollständige Benutzerschnittstelle. Desweiteren ist die Hervorhebung ungültiger Werte noch nicht realisiert. Da der Auftraggeber die Leistung nicht finanziell vergütet und nur eine lose Vereinbarung mit dem Auftragnehmer besteht, ist es angebracht, die Unterschiede zu einem Projekt mit einem juristischen Vertrag und einem Softewareunternehmen als Auftragnehmer aufzuzählen. Aufgrund der mangelnden juristische Grundlage bzw. Bezahlung wurde keine Frist für Fertigstellung oder Inbetriebnahme gesetzt. Somit mussten keine Methoden zur Kosten- und Terminschätzung, wie z.B. die Function Point-Methode, angewendet werden. Ebenso entfallen Abnahmetest und -protokoll. Die Systemimplementation und -dokumentation ist unter eine Lizenz zu stellen, welche die typischen Merkmale einer Open Source-Lizenz aufweist. Daraus resultiert in der Regel, dass keinerlei Gewährleistung für das Produkt gegeben wird. Durch die Verwendung im Umfeld der studentischen Selbstverwaltung und die Auslegung auf Anwendung durch andere Fachschaftsräte musste besonderes Augenmerk auf den leichten Einstieg und die gute Verstehbarkeit des Codes für nachfolgende Entwickler gelegt werden. Es kann festgestellt werden, dass vollständige Analyse, Entwurf und Implementierung eines Systems diesen Umfangs nach ingenieursmäßigen Gesichtspunkten im Rahmen einer Studienarbeit nicht möglich sind. Dabei ist allerdings zu beachten, dass der Änderungsfreudigkeit unbedingt Grenzen gesetzt werden müssen, damit die Optimierung der Lesbarkeit und Verstehbarkeit nicht auf Kosten der Vollständigkeit stattfindet. 35 Kapitel 4 Zusammenfassung 36 Anhang A Übersetzungen Englisch Deutsch account balance Kontostand account holder Kontoinhaber administrator Administrator amount Betrag auth Abk. für Authentifizierung(s-) authenticity Authentizität background tasks Hintergrund-Aufgaben business Verhalten cancel stornieren change ändern check prüfen complete fertigstellen constant Konstante content Inhalt cover sheet Deckblatt credit limit Kreditlimit current derzeitig customer Kunde date Datum debug fehlersuchen delete löschen description Beschreibung dictionary Wörterbuch document Dokument documentalist Dokumentar enter verbuchen examiner Prüfer exception Ausnahme execute ausführen forename Vorname group Gruppe import importieren income Einkommen language Sprache logger Protokollierer member Mitglied mnemonic Kürzel month Monat monthly sum Monatssumme 37 Anhang A Übersetzungen 38 Englisch Deutsch name Name note Notiz number Anzahl object Objekt observe beobachten order item Auftragsposition order Auftrag overview Übersicht page Seite path Pfad payment Zahlung persistent langlebig person Person pick up abholen posting Buchung price Preis printout Ausdruck problem Aufgabe publisher Herausgeber query Abfrage quit beenden register registrieren / erfassen reminder Erinnerung retrieve abrufen save speichern send schicken session Sitzung sheet Blatt show zeigen solution Lösung start beginnen status Status study program Studiengang submission Abgabe surname Nachname time Zeitpunkt title Titel type Typ UI Benutzerschnittstelle update aktualisieren valid gültig value Wert Anhang A Übersetzungen Englisch Deutsch vendor Verkäufer welcome willkommen heißen year Jahr 39 Anhang A Übersetzungen 40 Literaturverzeichnis [Ambl00] The Design of a Robust Persistence Layer for Relational Databases1, Scott W. Ambler, 2000. [ArsD01] ACS 4.6 2, 2001. [Balz96] Lehrbuch der Software-Technik: Software-Entwicklung, Helmut Balzert, 1996, Spektrum Akademischer Verlag GmbH. [Bodd01] Python Web modules3, Paul Boddie, 2001. [Cafu01] SDMS 1.1.44, Cafuego, 2000, 2001. [DBAP01] Python Database API Specification 2.05, 2001. [DiGr01] psycopg6, Federico Di Gregorio, 2001. [Ente01] FreeDMS 0.807, Jochen Entenmann und Thomas Müller, 2001. [Fowl97] UML Distilled: Applying the Standard Object Modeling Language, Martin Fowler und Kendall Scott, 1997, Addison-Wesley Longman, Inc.. [Härd99] Datenbanksysteme: Konzepte und Techniken der Implementierung, Theo Härder und Erhard Rahm, 1999, Springer-Verlag. [Java01] Java 2 SDK Standard Edition 1.3.18, 1995, 1996, 1997, 1998, 1999, 2000, 2001. [Matt00] Software Engineering 9, Florian Matthes und Holm Wegner, 2000. [MySQ00] MySQL 3.23.42 Reference Manual10, 2001. [Orac00] Oracle8i Release 2 (8.1.6) for Linux Intel11, 2000. [Pavl01] Document Manager 1.6 12, Dobrica Pavlinusic, 2001. [Post00] PostgreSQL 7.1 Documentation 13, 2001. [Remp00] Database Objects14, Boudewijn Rempt, 2000. [Shaw96] Software architecture: Perspectives on an emerging discipline, Mary Shaw und David Garlan, 1996, Prentice Hall. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 http://www.ambysoft.com/persistenceLayer.pdf http://developer.arsdigita.com/acs-java/doc/ http://www.infector.com/Paul/Python/web_modules.html http://sdms.cafuego.net http://www.python.org/topics/database/DatabaseAPI-2.0.html http://www.zope.org/Members/fog/psycopg http://freedms.sourceforge.net http://java.sun.com/j2se/1.3/docs http://www.sts.tu-harburg.de/teaching/ss-01/SoftEng/entry.html http://www.cwi.nl/ftp/farhad/mysql-3.23.42-sgi-irix6.5-mips/manual_toc.html http://technet.oracle.com/doc/oracle8i_816/linux_816/unixdoc/a82848/index.htm http://www.rot13.org/~dpavlin/docman.html http://www.de.postgresql.org/users-lounge/docs/ http://www.xs4all.nl/~bsarempt/python/dbobj.html 41 [Ston98] Readings in database systems, Herausgegeben von Michael Stonebraker Herausgegeben von und Joseph M. Hellerstein, 3, 1998, Morgan Kaufmann Publishers. [Trub01] Mod_python Manual15, Gregory Trubetskoy, 2001. [VanR00] Python 1.5.2 Documentation 16, Guido van Rossum und Fred L. Drake, Jr., 2000. [Wies00] AnyPortal(php) 17, Stefan Wiesendanger, 2000. 15 http://www.modpython.org/live/mod_python-2.7.6/doc-html/ 16 http://www.python.org/doc/1.5.2p2/ 17 http://nger.org/anyportal 42