i INSTITUT FÜR INFORMATIK DER LUDWIG-MAXIMILIANS-UNIVERSITÄT MÜNCHEN Diplomarbeit Jan-Friedrich Mutter Entwicklung einer Intranet-basierten Unterstützung einer Musterklassifikation Aufgabensteller: Betreuer: Prof. Dr. Martin Wirsing Dr. María Victoria Cengarle, Dr. Peter Brössler Abgabedatum: 7. Oktober 1999 Ich versichere, daß ich diese Diplomarbeit selbständig verfaßt und nur die angegebenen Quellen und Hilfsmittel verwendet habe. München, 7. Oktober 1999 Jan-Friedrich Mutter Inhalt 1 Einleitung______________________________________________________________ 1 2 Vorgehensweise _________________________________________________________ 4 2.1 Kommunikation im Web ___________________________________________________ 4 2.1.1 2.1.2 2.1.3 2.2 Interviews _______________________________________________________________ 7 2.2.1 2.2.2 2.3 Struktur der Klassifikation ______________________________________________________ 8 Patlet-Struktur _______________________________________________________________ 11 Analyse _______________________________________________________________ 14 3.1 Anforderungen __________________________________________________________ 14 3.1.1 3.1.2 3.2 3.3 Die Muster __________________________________________________________________ 14 Anwendungsfälle _____________________________________________________________ 14 Aktivitäten ______________________________________________________________ 15 3.2.1 3.2.2 3.2.3 3.2.4 3.2.5 3.2.6 3.2.7 3.2.8 4 Fragebogen und Zusammenfassung _______________________________________________ 7 Schlußfolgerungen ____________________________________________________________ 8 Schnittstellen der beiden kooperierenden Diplomarbeiten ________________________ 8 2.3.1 2.3.2 3 WWWBoard _________________________________________________________________ 4 Sammeln von Mustern im Web ___________________________________________________ 5 Fazit ________________________________________________________________________ 6 Suche ______________________________________________________________________ Ansicht eines Patlets __________________________________________________________ Kommentare zu einem Muster __________________________________________________ Abhängigkeiten abfragen ______________________________________________________ Patlet importieren ____________________________________________________________ Patlet importieren (Administration) ______________________________________________ Patlet exportieren ____________________________________________________________ Klassifikation anlegen (Administration) ___________________________________________ 16 17 17 18 20 20 21 21 Datenstruktur ___________________________________________________________ 23 Entwurf ______________________________________________________________ 24 4.1 Wahl der Technologie _____________________________________________________ 24 4.1.1 4.1.2 4.1.3 Java _______________________________________________________________________ 24 Relationale Datenbank ________________________________________________________ 25 Framework SUMATRA _______________________________________________________ 25 4.2 Überblick des Gesamtsystems ______________________________________________ 26 4.3 Schichten _______________________________________________________________ 27 4.4 Aufruf__________________________________________________________________ 29 4.5 Standard Dialog _________________________________________________________ 30 4.6 Kommunikation mit dem Server ____________________________________________ 31 4.7 Daten Management _______________________________________________________ 34 4.8 Suche __________________________________________________________________ 42 4.9 Ansicht eines Patlets ______________________________________________________ 44 4.10 Kommentare anlegen _____________________________________________________ 44 4.11 Patlet importieren ________________________________________________________ 45 4.12 Patlet exportieren ________________________________________________________ 46 4.13 Beziehungen zwischen Patlets ______________________________________________ 47 4.14 Klassifikation anlegen_____________________________________________________ 48 4.15 Menüverwaltung _________________________________________________________ 49 4.16 Meldungen an den Benutzer _______________________________________________ 51 5 Implementierung _______________________________________________________ 52 5.1 Erweiterungen von JFC ___________________________________________________ 52 5.2 Erweiterungen von SUMATRA_____________________________________________ 56 6 Bedienungsanleitung ____________________________________________________ 60 6.1 Das Suchwerkzeug _______________________________________________________ 60 6.2 Das Administrationswerkzeug ______________________________________________ 64 7 Installation ____________________________________________________________ 67 7.1 Arbeitsumgebung ________________________________________________________ 67 7.2 Installationsschritte ______________________________________________________ 68 7.3 Das Makefile ____________________________________________________________ 71 7.4 Konfigurationsdatei von SUMATRA ________________________________________ 72 7.5 HTML Dateien __________________________________________________________ 72 7.6 Verzeichnisstruktur der CDROM ___________________________________________ 73 7.7 Anmerkungen ___________________________________________________________ 75 8 Zusammenfassung und Ausblick __________________________________________ 76 9 Personen und Organisationen ____________________________________________ 77 10 Danksagungen _______________________________________________________ 78 Glossar __________________________________________________________________ 79 Literatur _________________________________________________________________ 81 Abbildungen ______________________________________________________________ 84 Stichwortverzeichnis________________________________________________________ 85 1 1 Einleitung Muster (engl. Patterns) sind erprobte Lösungen für immer wiederkehrende Probleme in der Softwareentwicklung. Daß diese Lösungen funktionieren garantiert, die Tatsache, daß Muster nicht erfunden werden, sondern bereits erfolgreich in verschiedenen Projekten angewandt wurden. Es handelt sich also um die niedergeschriebenen und leicht verfügbaren Erfahrungen von Experten. Damit eröffnet sich dem Softwareentwickler die Möglichkeit, aus dem Wissen anderer zu lernen. Grund genug also, sich mit Mustern ausführlich auseinanderzusetzen. Das gemeinsame Ziel dieser Diplomarbeit und der Diplomarbeit von Gianmarco Niedermeyr ([NIE99]) war es, ein Klassifikationssystem für Muster zu erstellen und gleichzeitig ein Werkzeug zu entwickeln, daß diese Klassifikation geeignet repräsentiert. Das Werkzeug soll dem Benutzer die Möglichkeit bieten, über das System ein oder mehrere Muster zu finden, die er für seine Zwecke einsetzen könnte. Eine weitere Anforderung war, das Werkzeug im Intranet jedem zur Verfügung stellen zu können. Der Vorschlag für dieses Thema kam von der Firma sd&m München, die in Zusammenarbeit mit dem Institut für Informatik der Universität München beide Diplomarbeiten unterstützten. Während es die Aufgabe von [NIE99] war, das Klassifikationssystem zu entwickeln und es mit geeigneten Daten zu füllen, wurde mit dieser Diplomarbeit die Umsetzung des Werkzeuges realisiert. Diese Diplomarbeit beschäftigt sich in erster Linie nicht mit dem Inhalt von Mustern, sondern vielmehr mit dessen Verfügbarkeit. Das Wissen anderer nützt nur dann, wenn man es in vertretbarer Zeit finden kann. Der schnelle Zugriff ist ein Teil dessen, was die Nützlichkeit eines Musters ausmacht. Buschmann et. al. [POSA98, S, 20] schreiben: „Ein Muster muß einen Namen haben – am besten einen sprechenden Namen –, wenn wir es anderen mitteilen und es mit ihnen diskutieren wollen. Ein solcher Name sollte den Kern des Musters widerspiegeln. ...“. Bei der Flut der existierenden Muster ist es jedoch, auch bei sorgfältig ausgewählten Namen, schwer, den Überblick zu behalten. In [POSA98, S. 362] heißt es dazu: „Wenn Softwareentwickler jedes Muster analysieren und genau verstehen müssen, um dasjenige herauszufinden, welches sie gerade brauchen, ist das Mustersystem als Ganzes nutzlos, auch wenn seine einzelnen Muster brauchbar sind. Um die Gesamtheit aller Muster in einem Mustersystem bequem überblicken zu können, ist es hilfreich, die Muster in Gruppen verwandter Muster einzuteilen.“. Buschmann bezieht sich hier auf ein Mustersystem [POSA98, S. 359] [NIE99, S. 22]. Man könnte aber diese Aussage durchaus auf alle weltweit verfügbaren Muster ausweiten. Bereits in dem Buch „Design Patterns, Elements of Reusable Object-Oriented Software“ von E. Gamma, R. Helm, R. Johnson und J. Vlissides [GOF95] 1 werden die dort veröffentlichten Muster in zweck-basierte Kategorien gruppiert: creational, structural und behavioural. Buschmann et. al [POSA98] gehen einen Schritt weiter und unterteilen die Muster in ein zweidimensionales Klassifikationsschema. Das eine Klassifikationskriterium sind Musterkategorien. Es unterscheidet zwischen ‚Architekturmuster‘, ‚Entwurfsmuster‘ und ‚Idiome‘. Das andere Kriterium beschreibt eine problemorientierte Sicht auf das Mustersystem. Jedes Muster löst ein bestimmtes Problem, das sich während der Entwicklung eines Software-Systems stellen kann. Das Abstrahieren von speziellen Problemen führt zu Problemkategorien, die verschiedene verwandte Probleme umfassen. Sie beinhalten unter anderem ‚Verteilte Systeme‘, ‚Interaktive Systeme‘, ‚Zugriffskontrolle‘, usw. In [POSA98] werden nicht nur die dort vorgestellten Muster in das Klassifikationsschema eingefügt. Es finden auch die Muster aus [GOF95] ihren Platz. Das Schema ist erweiterbar, indem neue Musterund Problemkategorien hinzugefügt werden, um Muster zu klassifizieren, die keinen bisher existierenden Kategorien zugeordnet werden können. Interessanterweise baut das gerade besprochene Klassifikationsschema auf dem in [BM94] vorgeschlagenen System auf. Dieses System ist jedoch dreidimensional, wobei die ersten beiden Dimensionen den oben beschriebenen entsprechen. Die dritte Dimension „Strukturelle Prinzipien“, bezeichnet die technischen Prinzipien, die der Lösung des jeweiligen Musters unterliegen [POSA, S. 367]. Die Autoren von [POSA98] sind der Meinung, daß die diese Dimension zu wenig Aussagekraft hat, weshalb sie von ihnen einfach weggelassen wurde. Das zusammen mit [NIE99] entwickelte Klassifikationsschema geht einen Schritt weiter. Hier werden beliebig viele Dimensionen zugelassen. Eine genaue Beschreibung ist in Kapitel 2.3.1 zu finden. Nicht Die vier Autoren werden oft als die „Gang of Four“ bezeichnet (so benannt nach der „Gang of Four“ in der chinesischen Politik [POSA98, S. XIV]) 1 Einleitung 2 nur der Inhalt der Kategorien kann erweitert werden, es können auch beliebig viele neue Kategorien hinzukommen, falls die bisher vorhandenen Kategorien nicht ausreichen, um das Muster zu beschreiben. Offensichtlich besteht durch diese Erweiterung die Gefahr, daß das Klassifikationssystem sehr bald unübersichtlich wird. Auf einem Blatt Papier ist ein mehrdimensionales Schema kaum noch darstellbar. Ein Programm, das das Klassifikationsschema übersichtlich darstellen kann und die Prinzipien des Schemas widerspiegelt, wäre wünschenswert. Die folgenden Kapiteln werden sich mit der Realisierung eines solchen Programmes beschäftigen. Im Internet gibt es eine Vielzahl von Seiten rund um das Thema Muster. Viele Seiten bieten eine textbasierte Suche, jedoch gibt es eine Suchmaschine, die mit Hilfe einer Klassifikation eine Auswahl von Mustern findet, bisher nicht. Die Suchmaschine auf Ward Cunningham’s WikiWiki Web [Wiki] beispielsweise durchsucht die auf dem Server befindlichen Artikel. Sie beschreiben teilweise Muster in Kurzform oder enthalten Informationen über den Umgang mit Mustern. Eine Suchmaschine, die sich nur auf Muster beschränkt, findet sich auf ‚The DA VINCI Initiative‘ [DaVinci]. Dort kann man nach Name und Intention des Musters suchen. Es befinden sich in der darunter liegenden Datenbank nur wenige Muster. Das Projekt scheint leider nicht weitergeführt zu werden. Hat man eine Auswahl von Mustern gefunden, die die Klassifikationskriterien widerspiegeln, so muß in der Regel geprüft werden, ob das Muster als Lösung für das vorgegebene Problem geeignet ist. Um dies möglichst schnell festzustellen, sollte die Kernaussage des Musters sofort erkennbar sein. Die Form der existierenden Muster ist jedoch nicht normiert, was die Arbeit des Suchenden, der sich einen schnellen Überblick schaffen will, erschwert. Es gibt viele Vorschläge in der Literatur, wie ein Muster aussehen könnte. [GOF95] und [POSA98] sind die bekanntesten davon. Jedoch gibt es keinen allgemein anerkannten Standard. Fowler sieht eine vorgeschriebene Form für Muster kritisch [Fow97, S. 6 f]. Er bemängelt, daß eine Darstellung von mehreren Problemlösungen für ein vorgegebenes Problem bei Beibehaltung einer vorgeschriebenen Form nicht möglich ist, da für jede Lösung ein eigenes Muster erstellt werden müßte [NIE99, S. 13]. Die Suche nach einem passenden Muster wird durch die uneinheitliche Form sicherlich erschwert. Die in [Cop92] präsentierten Muster beispielsweise sind nur schwer aus dem Text des Buches zu extrahieren, ohne das Buch im gesamten durchzulesen [NIE99, S. 13]. Ein einheitliches Schema würde den Zugriff auf Muster sicher beschleunigen und eine bessere Übersicht gewährleisten. In dieser Arbeit wurde ein Musterarchiv aufgebaut, das Muster aus verschiedenen Quellen enthält. Um dem Benutzer des Archivs eine bessere Übersicht zu geben, werden alle darin enthaltenen Muster als sogenannte Patlets repräsentiert. Bereits 1996 wurden von der Hillside Group [Hill] mehr als hundertfünfzig Patlets geschrieben, die leider bisher nicht veröffentlicht wurden [NIE99, S. 38 f]. Die Gruppe verstand sie als Kurzfassung von Mustern, die den Namen des Musters, eine kurze Problembeschreibung, das Grundprinzip seiner Lösung und eine Referenz auf die vollständige Beschreibung enthalten sollen [POSA98, S. 418]. Patlets, die im Rahmen der Diplomarbeit von [NIE99] entstanden sind, sind eine Schnittstelle zwischen dem Softwarearchitekten, der nach Lösungen sucht, und den Mustern. Durch sie kann eine einheitliche Form geschaffen werden, ohne daß das eigentliche Muster verändert werden muß. Durch die Zusammenfassung eines Musters durch ein Patlet kann man auf einen Blick erkennen, ob es sich lohnt, sich weiter mit dem eigentlichen Muster auseinanderzusetzen. Da Muster im allgemeinen aus seitenlangen Beschreibungen bestehen, ist dieser Prozeß sehr zeitaufwendig. Selbstverständlich bleibt dem Architekten diese Arbeit nicht erspart, sofern er sich einmal für die Umsetzung der in einem Muster beschriebenen Lösung entschieden hat. Der Nutzen des in den Diplomarbeiten zu entwickelnden Systems, war es, eine möglichst kleine Menge von Mustern zu ermitteln und diese geeignet zu präsentieren, um dem Softwarearchitekten schnell eine Übersicht zu geben. Patlets beschreiben neben einer Zusammenfassung des Inhalts auch ihre Beziehungen zu anderen Mustern. Muster müssen oft im Zusammenhang mit anderen Mustern gesehen werden. Sie können zusammen einen Musterkatalog, ein Mustersystem oder sogar eine Mustersprache bilden [NIE99, S. 16]. Sie können lose zusammenhängen, sich gegenseitig ergänzen oder aufeinander Einleitung 3 aufbauen. Das Wissen über solche Beziehungen ist sehr wichtig. „Die Vorteile einer Menge verwandter Muster ist mehr als die Summe aller Vorteile jedes einzelnen Musters in dieser Menge.“ [POSA98, S. 380]. Die Beziehungen der in [GOF95] vorgestellten Muster werden dort mit einer Graphik dargestellt, während [POSA98] sogar ein Mustersystem präsentiert, in dem die Muster als zusammenhängendes Ganzes gesehen werden können. Sie sind stark miteinander verwoben und aufeinander abgestimmt [NIE99, S. 16]. In dem zu entwickelnden System wird die Darstellung der Zusammenhänge von Mustern mit Hilfe von HTML Verweisen realisiert, wie man es auch bereits beim Wiki Wiki Web [Wiki] zu finden ist. In dem folgenden Kapitel 2 werden die Vorarbeiten beschrieben, die geleistet wurden, um eine gemeinsame Grundlage für diese Diplomarbeit und [NIE99] zu schaffen. In den beiden darauffolgenden Kapiteln 3 und 4 geht es um die Planung, die zu einem lauffähigen System führen sollen. Kapitel 5 beschreibt die Umsetzung. Das Kapitel 6 beschreibt den Umgang mit dem fertigen System während das Kapitel 7 die Instandsetzung des Systems und seine Konfigurationsmöglichkeiten diskutiert. Eine Zusammenfassung und Ausblick bietet das Kapitel 8. Eine Liste aller an dieser Diplomarbeit Beteiligten und eine anschließende Danksagung ist in Kapitel 9 und 10 zu finden. Zur besseren Übersicht wird die Diplomarbeit mit einem Glossar, der grundlegende Begriffe klärt, einem Abbildungsverzeichnis und einem Inhaltsverzeichnis abgeschlossen. 4 2 Vorgehensweise Vor der Entwicklung eines Softwareprogramms wurde einige Vorarbeit geleistet. Das betraf vor allem die Zusammenarbeit mit Gianmarco Niedermeyr. Es wurden zunächst gemeinsam Informationen gesammelt, wie in Abschnitt 2.1 und 2.2 beschrieben. Abschnitt 2.3 definiert die gemeinsamen Schnittstellen von dieser Arbeit und [NIE99]. 2.1 Kommunikation im Web Wie schon erwähnt, waren viele Parteien an dieser Diplomarbeit beteiligt 2. Diese Tatsache ließ es sinnvoll erscheinen, eine Plattform zu schaffen, auf der man leicht Informationen austauschen konnte, die alle Beteiligten erreichen konnten. Zu diesem Zweck wurde eine, per WWW erreichbare, Diplomarbeit Homepage erstellt, die zwei Dienste anbot. Sie werden in den beiden folgenden Abschnitten näher beschrieben. 2.1.1 WWWBoard Das WWWBoard sollte als eine Art Newsgroup im WWW fungieren. Jeder Beteiligte konnte dort Nachrichten hinterlassen und auf bestimmte Nachrichten antworten. Es wurde als CGI realisiert und in der Programmiersprache Perl [Perl] geschrieben. Der Quellcode ist von ‚Matt’s Script Archive‘ [Matts] und wurde nur der bestehenden UNIX Umgebung angepaßt. Abbildung 1: Oberfläche des WWWBoards 2 Zu diesen gehörten das Institut für Informatik der LMU, die Firma sd&m, Gianmarco Niedermeyr und der Autor dieser Diplomarbeit. Eine ausführliche Liste aller Personen und Organisationen ist in Kapitel 9 zu finden. Vorgehensweise 5 Jeder der beteiligten Personen konnte Nachrichten hinterlassen. So wie es auch bei den Newsgroups im Internet üblich ist, konnte man seinen Namen, seine Emailadresse, den Titel der Nachricht und den Inhalt der Nachricht selbst dort ablegen. Jeder der Beteiligten konnte dann auf diese Nachricht antworten. Wie auf Abbildung 1 zu sehen ist, wurde diese Einrichtung auch tatsächlich genutzt. 2.1.2 Sammeln von Mustern im Web Um einen Überblick über die Muster zu bekommen, die weltweit zur Verfügung stehen, ist das WWW sicherlich ein wichtiges Hilfsmittel. Neben einer separaten Literaturrecherche muß man dem Internet als Informationsquelle einen großen Stellenwert einräumen. Das gilt vor allem bei Themen aus der Informatik. Es liegt also nahe, einen Teil der Recherche auch im Internet durchzuführen und alle URLs zu sammeln, die auf Muster im WWW verweisen. Zu diesem Zweck wurde ein CGI in Perl [Perl] implementiert, mit dem man diese Links sammeln konnte. Jeder Link mußte einer bestimmten Kategorie zugeordnet werden: Konkrete Patterns Implementierungen Frameworks Beschreibungen und Erklärungen Verschiedenes Idiome Pattern Languages Diese Unterteilungen sollten nur erste Anhaltspunkte sein und der später entstandenen Klassifikation nicht vorgreifen. Zu jedem neu eingefügten Link mußte ein Titel angegeben werden. Optional konnte man auch eine kurze Beschreibung und sogar bereits möglich Attribute beifügen. Abbildung 2: Linksammlung im Internet Vorgehensweise 6 Abbildung 2 zeigt die Eingabemaske, mit der Links hinzugefügt werden konnten. Bei Eingabe eines Stichwortes am linken Rand wurden alle Information über die Links durchsucht und das Ergebnis neu dargestellt. Diese Suchmöglichkeit wurde als einfache Textsuche implementiert. Ebenfalls auf der linken Seite befindet sich eine Navigationsleiste, um dem Benutzer eine Übersicht über das Angebot zu geben. Alle Seiten der Homepage, bis auf das WWW Board, hatten diese Leiste. Um möglichst alle Verweise aufzunehmen, wurde sehr systematisch vorgegangen: Von den bekanntesten Seiten im Internet, die sehr viele Informationen über Muster enthalten, wurden Links rekursiv verfolgt und gesammelt. Es wurden dabei folgende Seiten durchsucht: Auf der „Patterns Home Page“ (http://hillside.net/patterns/patterns.html) die Seite "Patterns and Pattern Languages" (http://hillside.net/patterns/EgPatterns.html) Auf „Cetus Links - Object-Orientation“ die Seite „Architecture and Design: Patterns“ (http://www.cetus-links.org/oo_patterns.html) Auf diese Weise wurden 339 Links gesammelt. Der Fortschritt wurde jeweils im WWWBoard dokumentiert. Um doppelte Einträge zu vermeiden, wurde eine URL, die schon eingefügt war, vom CGI nicht akzeptiert. Die Linksammlung konnte auch administriert werden. Um einen oder mehrere Einträge in der Sammlung zu löschen, waren ein Login und ein Paßwort erforderlich, die nur den Beteiligten bekannt war. Abbildung 3 zeigt die zugehörige Oberfläche. Hier konnten beliebig viele Links selektiert und gelöscht werden. Abbildung 3: Administration der Linksammlung 2.1.3 Fazit Über den Erfolg dieser Vorgehensweise läßt sich streiten. Die Kommunikation auf dem WWWBoard wurde im Laufe dieser Diplomarbeit eingestellt und wurde durch die Email ersetzt. Fest steht jedoch, 7 Vorgehensweise daß sich das WWWBoard durch das Protokollieren der eingefügten Links in der Linksammlung als nützlich erwies. Die Sammlung aller Muster im WWW gibt einen groben Überblick über die Anzahl der vorhandenen Muster. Es wurden 339 Verweise auf Muster oder auf verwandte Themen gesammelt. Die Sammlung wurde nicht näher analysiert, so daß sicher auch Verweise auf Dokumente zu finden sind, die dem Wesen eines Musters nicht entsprechen [NIE99], [GOF95]. Eine genaue Analyse hätte den Rahmen der beiden Diplomarbeiten gesprengt. Die vielversprechendsten Verweise wurden jedoch von Gianmarco http://www.pst.informatik.uni-muenchen.de/DA/niederme zusammengefaßt. 2.2 Niedermeyr auf Interviews Um einen besseren Eindruck von der Vorgehensweise bei Projekten bei sd&m zu bekommen, wurden gemeinsam mit Gianmarco Niedermeyr einige Interviews bei sd&m Mitarbeitern durchgeführt. Das Ziel war es zum einen, dadurch eine Struktur erkennen zu können, die wir in der zu erstellenden Klassifikation einbringen konnten. Zum anderen sollte auch erkundet werden, welche Muster für das Unternehmen relevant sind. 2.2.1 Fragebogen und Zusammenfassung Von Gianmarco Niedermeyr wurde ein Fragebogen erstellt, den wir dann mit vier Mitarbeiter des Unternehmens vorgelegt haben. Die Fragen sollten klären, welche Muster den Mitarbeitern von sd&m in ihren Projekten helfen könnten. Dies erforderte eine Übersicht über die Art der Projekte, die Vorgehensweise, wie Projekte bearbeitet werden, und den Umgang mit Mustern. Fragebogen und Antworten werden hier zusammengefaßt dargestellt: Frage: Was macht sd&m an Projekten ? Antworten: Betriebliche Informationssysteme Datenbankanwendungen Beratungen Kaum eine Einschränkung bei den verwendeten Technologien Frage: Was wird bei sd&m nicht gemacht ? Antworten: Steuerung / Kontrolle (z.B. embedded systems, Fahrzeugsteuerung, Kontrolle Waschmaschinen, Fernsehen, ...); Ausnahme: Softwareoberfläche für Fotoentwicklung. Aufträge für militärische Zwecke. f. Frage: Werden Design Patterns von Ihnen bereits eingesetzt ? Antworten: Ja, aber unbewußt. Viele Patterns ergeben sich aus Erfahrung. Einige Patterns sind z.B. schon aus der Smalltalk Bibliothek bekannt. Fachliche Patterns aus [Fow97] Viele Patterns aus [GOF95] Frage: Welche Anforderungen würden Sie an ein Such Tool für Design Patterns haben, um Design Patterns auch ohne Erfahrung auf diesem Gebiet effizient nutzen zu können ? Vorgehensweise 8 Antworten: "Pattern weaving" (dt. Musterverflechtung) 3 Problembezogene Suche Frage: Wie werden bei sd&m Softwareprojekte zur Bearbeitung durch die Mitarbeiter in Teilprojekte aufgeteilt? Antwort: 2-dimensionale Trennung: Schichten (UI, Kern, DB), Fachlichkeiten (Verwaltung von Kunde, Antragsformular, usw.). 2.2.2 Schlußfolgerungen Die Projekte, die bei sd&m durchgeführt werden, erfassen ein sehr weites Spektrum. Deshalb kann es kaum eine Einschränkung bei der Auswahl der Muster geben, die in das Archiv einbezogen werden können. Durch die Flexibilität des entstandenen Klassifikationssystems und die Erweiterungsmöglichkeiten des Archivs stehen dafür, daß es kaum Einschränkungen geben kann. Die Umfrage bestätigte, daß die am populärsten geltenden Muster der „Gang of Four“ [GOF95] und Buschmann et. al. [POSA98] auch in der Firma ein Begriff sind. In einem Musterarchiv dürfen sie also nicht fehlen. Daß Muster oft in Beziehung zueinander stehen, wurde bereits in der Einleitung angesprochen. Die Einschätzung der Mitarbeiter, daß es wichtig ist, solche Abhängigkeiten zu erkennen und zu nutzen, deckt sich mit den Aussagen in der Literaur [POSA98, S. 380]. Dem Wunsch, mehr über die Verflechtungen zu erfahren, wurde beim Aufbau des Archivs Folge geleistet. Jedes Patlet enthält Informationen darüber, wie es mit anderen in Verbindung steht. Die wichtigsten Schlußfolgerungen, die aus diesen Interviews gezogen werden konnten, sind auch tatsächlich in das entstandene Archiv eingegangen. 2.3 Schnittstellen der beiden kooperierenden Diplomarbeiten Um mit der Bearbeitung an der eigentlichen Aufgabenstellung dieser Diplomarbeit beginnen zu können, mußte die Struktur der Klassifikation und die Datenstruktur eines Patlets definiert werden. Sie werden in den beiden folgenden Kapiteln 2.3.1 und 2.3.2 beschrieben. 2.3.1 Struktur der Klassifikation Die Form der Klassifikation wird im folgenden detailliert beschrieben. Sie wurde nicht komplett neu entworfen, sondern baut auf den Erkenntnissen, die im Bereich der Indexierung gemacht wurden, auf. Anhand von Beispielen wird die Anwendbarkeit und der Umgang mit der Klassifikation verdeutlicht. Die Wahl fiel auf die Facettenklassifikation mit gewissen Erweiterungen und Einschränkungen, die hier erklärt werden. Eine Facettenklassifikation dient in der Praxis zur Indizierung von Dokumenten zur Wiederverwendung. Das Klassifikationssystem wird aus den inhaltlichen Aussagen ausgewählter Dokumente aufgebaut. Dazu werden die inhaltlichen Aussagen nur in Einfachklassen zerlegt. Die Einfachklassen werden dann in Facetten gruppiert. Eine Facettenklassifikation für Software kann etwa die Einfachklassen sort, compress und append in eine Facette FUNCTION gruppieren. Einfachklassen wie arrays, strings und trees können in die Facette OBJECT gruppiert werden. Sowohl Einfachklassen als auch Facetten können hierarchisch angeordnet werden. Will man nun ein Dokument mit diesem System repräsentieren, so muß man eine Verbundklasse aus den Einfachklassen von verschiedenen Facetten zusammensetzen. Diese Verbundklasse wird dann dem Dokument zugewiesen. Möchte man beispielsweise Quellcode von Programmen indexieren, so ist die von Pietro-Díaz [PRI89] entwickelte Facettenklassifikation geeignet (Tabelle 1). 3 Das Zusammenspiel von Mustern 9 Vorgehensweise FUNCTION OBJECTS MEDIUM SYSTEMTYPE FUNCTIONAL- SETTING AREA add arguments array assembler accountpayable advertising append integers buffer code auditing aircraft compare arrays card file-handler bookkeeping association ... ... ... ... ... ... Tabelle 1: Auszug aus der Facettenklassifikation von [PRI89] zur Repräsentierung von Programmen Die Repräsentation eines gegebenen Programmstücks ProgA, entsprechend der vorgestellten Facettenklassifikation, erfolgt dadurch, daß für jede Facette eine Einfachklasse ausgewählt wird, wobei die festgelegte Reihenfolge der Facetten eingehalten werden muß. ProgA kann dann folgendermaßen repräsentiert werden [ZEN97]: <add, integers, array file-handler, bookkeeping, association> Es fällt auf, daß bei diesem System jedem Dokument genau ein n-Tupel zugeordnet ist. Für die hier eingeführte Klassifikation wäre es wünschenswert, diese Einschränkung aufzuheben. Viele Muster sind so allgemein gehalten, daß ihre Lösungen in vielen verschiedenen Bereichen eingesetzt werden können. Wie sich später bei der Klassifikation der Muster herausstellte, wurden vielen Mustern in [NIE99] Einfachklassen mehrfach zugewiesen. Das CORBA Muster ‚Agent‘ [MM97, S. 202] beispielsweise wird unter anderem durch die Klassen ‚Zugriffskontrolle‘, ‚Parallelität‘, ‚Verteilte Systeme‘, ‚Middleware‘ repräsentiert, die alle zu derselben Facette gehören. Es könnten dann beliebig viele n-Tupel einem Dokument zugeordnet werden. Zum Beispiel kann ProgA nun wie folgt repräsentiert werden: <add, integers, array, file-handler, bookkeeping, association>, <append, integers, buffer, file-handler, bookkeeping, association> Dieses Repräsentationsschema ist fehleranfällig, da teilweise die gleiche Information in beiden Tupeln vorhanden und damit redundant ist. Deshalb wurde eine andere Beschränkung aufgehoben. Anstatt eine Stelle im Tupel mit nur genau einer Einfachklasse zu besetzen, können nun beliebig viele Einfachklassen aus einer Facette der Stelle zugeordnet werden. Bildet man nun obige Repräsentation mit Hilfe der neuen Regel ab, so ergibt sich folgendes: <{add, append}, integers, {array, buffer}, file-handler, bookkeeping, association> Die Abbildung ist nicht injektiv. Die umgekehrte Abbildung würde nämlich vier Tupel ergeben: <add, integers, array, file-handler, bookkeeping, association>, <add, integers, buffer, file-handler, bookkeeping, association>, <append, integers, array, file-handler, bookkeeping, association>, <append, integers, buffer, file-handler, bookkeeping, association> Die neu eingeführte Repräsentation ist also weniger aussagekräftig. Auf der Suche nach Dokumenten, die etwa <append, integers, array, file-handler, bookkeeping, association> zugeordnet sind, wäre auch ProgA in der Trefferliste, was ursprünglich nicht zutrifft. In Hinblick auf die Wartung und der geringen Anzahl der Dokumente ist dieser Nachteil akzeptabel. Wenn sich alle Einfachklassen in einer bestimmten Facette widersprechen, macht es keinen Sinn, mehrere davon auswählen zu können. Deshalb muß für jede Facette festgelegt werden, ob mehrere Einfachklassen aus der Facette aufgelistet werden dürfen oder nur eines davon ausgewählt werden darf. In der Klassifikation werden die Facetten dann entsprechend mit ‚Liste‘ oder ‚Auswahl‘ gekennzeichnet. Eine Klassifikation, in der alle Facetten mit ‚Auswahl‘ gekennzeichnet sind, entspricht der klassischen Facettenklassifikation. Falls sich nur bestimmte Klassen in einer Facette widersprechen, muß von Fall zu Fall entschieden werden, ob die Facette nun eine ‚Liste‘ oder eine ‚Auswahl‘ darstellen soll. Eine besondere Kennzeichnung sich widersprechender Klassen ist nicht vorgesehen. Vorgehensweise 10 Bei der speziellen Art der Dokumente, nämlich bei Entwurfsmustern, ist es durchaus möglich, daß es keine Einfachklasse in einer Facette gibt, die ein Muster repräsentieren könnte. Die GoF-Muster4 beispielsweise sind in der Regel so allgemein gehalten, daß sie nicht allein einer spezifischen Schicht innerhalb einer 3-Schichten-Architektur zuzuordnen sind [NIE99]. Die Schichten sind einer der in [NIE99] definierten Facetten. Die neu eingeführte Repräsentation läßt deshalb zu, daß Felder in einem Tupel frei gelassen werden dürfen bzw. an dieser Stelle undefiniert sind. Im folgenden werden diese Stellen mit einem ‚*‘ gekennzeichnet. Ein ProgB kann nun so repräsentiert werden: <append, integers, array, file-handler, bookkeeping, *> Die Kennzeichnung mit ‚*‘ bedeutet, daß an dieser Stelle jede beliebige Ausprägung der Facette angenommen werden darf. Auf der Suche nach Dokumenten, die etwa <append, integers, array, filehandler, bookkeeping, association> zugeordnet sind, wäre auch ProgB in der Trefferliste. Diese Erweiterung des Wertebereiches einer Facette macht es außerdem möglich, das neue Klassifikationssystem um beliebig viele Facetten zu erweitern, was bei der klassischen Facettenklassifikation nicht möglich ist. Wenn der Verwalter des Systems erkennt, daß die vorhandenen Facetten nicht ausreichen, um neu hinzukommende Dokumente zu beschreiben, so kann eine neue Facette hinzugefügt werden. Die Klassifikation der alten Dokumente muß jedoch nicht aufwendig angepaßt werden. Es genügt n-Tupel des alten Systems nun als n+1-Tupel zu betrachten, wobei die neu hinzugekommene Stelle ein ‚*‘ enthält. Anders ausgedrückt, könnte man auch sagen, daß Dokumente, die durch einen ‚*‘ in der Facette repräsentiert werden, überhaupt nicht in dieser Facette repräsentiert werden, wobei festgelegt ist, daß so ein Dokument immer den Anforderungen an die Klassen in der Facette genügen soll. In [NIE99] sind etliche Muster entstanden, die durch keine Einfachklasse in einer bestimmten Facette repräsentiert werden. Während den Besprechungen hat sich für diese Art von Mustern der Begriff „don’t care“ Muster oder „don’t care“ Patlet eingebürgert, Muster also, um die man sich nicht kümmern muß, wenn man nach Mustern sucht, die durch bestimmte Einfachklassen in dieser Facette repräsentiert werden, denn sie erfüllen immer die Anforderungen. In der neu eingeführten Klassifikation wird keine hierarchische Unterteilung der Einfachklassen zugelassen. Sie wird für eine Indexierung von Mustern, wie sich Laufe der Arbeit von [NIE99] zeigte, nicht benötigt. Diese Einschränkung erleichtert zudem die Notation, die für ein Patlet festgelegt wird, erheblich. Die Tiefe der Facetten-Hierarchie ist genau zwei. Auch diese Beschränkung ist an die Anforderungen angepaßt, die das neue Klassifikationssystem stellt. Im folgenden werden die Facetten der ersten Ebene als „Bereich“ bezeichnet. Die Facetten der zweiten Ebene werden einfach als „die Facetten“ identifiziert. Durch die definierte Struktur der Klassifikation ergibt sich ein Baum der Höhe vier, wobei die Bereiche direkte Söhne der Wurzel sind, die Facetten Sohnknoten eines Bereichs und die Einfachklassen Söhne der Facetten und zugleich die Blätter des Baumes darstellen. Die inhaltliche Bedeutung der Facetten und Einfachklassen ist für die Implementierung eines Werkzeuges, das das Klassifikationsschema unterstützt, zweitrangig. Deshalb wird an dieser Stelle nur kurz darauf eingegangen. Weiterführende Information kann man bei [NIE99] finden. Zur Verdeutlichung sei in Tabelle 2 die in [NIE99] entstandene Klassifikation dargestellt. Sie ist nach den oben beschriebenen Regeln erweiterbar. 4 GoF = „Gang of Four“, wobei die Autoren von [GOF95] gemeint sind. 11 Vorgehensweise Software Granularität Problemkat Scope Purpose sdm-Schichten (Auswahl) (Liste) (Liste) (Auswahl) (Liste) Entwurfsmuster Adaptierbare Systeme Object Structural Fehlerbehandlung Architekturmuster Adaption Class Creational Benutzerschnittstelle Idiom Erweiterung der Dienstleistung Behavioral Datenverwaltung Erzeugung Anwendungskern Fehlerbehandlung Interaktive Systeme Kommunikation Management Middleware Organisation Arbeit von Parallelität PerformanceSteigerung RessourcenVerwaltung Strukturelle Zerlegung Variation Diensten von Verteilte Systeme Vom Chaos Struktur zur Zugriffskontrolle Tabelle 2: Klassifikationssystem aus Gianmarco Niedermeyrs Diplomarbeit [NIE99] 2.3.2 Patlet-Struktur Die Grammatik eines Patlets wurde in Zusammenarbeit mit Gianmarco Niedermeyr entwickelt. Ein Patlet sollte folgende Informationen enthalten: Eine Kurzbeschreibung des Inhaltes des zugehörigen Musters. Die wichtigsten Informationen über Zusammenhänge zu anderen Mustern. Referenzen auf die vollständige Beschreibung des Musters oder auf die weiterführende Literatur über das Muster. Eine Repräsentation im oben erläuterten Klassifikationsschema. Ein Patlet sollte in seiner Form so gestaltet sein, daß es für den Menschen leicht lesbar ist. Jeder, der das Schema des Patlets kennt, sollte in der Lage sein, eigene Patlets zu erstellen. Vorgehensweise 12 Diesen Anforderungen entsprechend wurde eine Patletvorlage (engl. Template) entwickelt. Jedes Patlet ist eine einfache ASCII Datei sein. Es enthält bestimmte Schlüsselwörter, denen in den darauffolgenden Zeilen ein oder mehrere Werte zugeordnet sind. Die Werte sind durch Kommata getrennt. Bestimmte Werte sind in Anführungszeichen eingeschlossen, um sie als ein Wert zu kennzeichnen. Die genauen Regeln werden anhand der vorkommenden Schlüsselwörter in der Vorlage erklärt: NAME: (Genau ein Wert)5 Angabe des Musternamens. ALT: (Optional)6 Alternativnamen. DOMAIN: (Genau ein Wert) entspricht der ersten Hierarchiestufe der Facetten (dem Bereich). ATTRIBUTES: (Ein oder mehrere Facetten und Einfachklassen) Angabe der Facetten der zweiten Hierarchiestufe und Einfachklassen der dem vorliegenden Muster zugeordneten Klassifikation: Zunächst Angabe der Facette gefolgt von einem Doppelpunkt, dem sich die Liste der Einfachklassen (mit Komma voneinander getrennt) anschließt. Nach dem Doppelpunkt können Leerzeichen oder Tabulatoren zum Einrücken der Liste von Klassen verwendet werden, um so die Übersicht zu erhöhen. Jede Beschreibung einer Facette schließt mit einem Zeilenvorschub ab. INTENTION: (Genau ein Wert) Kurzbeschreibung des Musters in der Art, daß entschieden werden kann, ob dieses Muster für die Lösung eines vorliegenden Problems relevant ist. Dazu wird in der Regel vor allem das Problem und der Kontext in ein bis zwei Sätzen erläutert und ggf. ein Hinweis auf die Art der Lösung gegeben. CONTAINS: (Optional, Liste)7 Sollte es sich bei dem Muster um eine Mustersprache handeln, so werden hier sämtliche darin enthaltene Muster aufgelistet. Falls das aufgelistete Muster im Archiv enthalten ist, soll lediglich sein Name ohne Anführungszeichen erscheinen. Ansonsten soll es mit Anführungszeichen versehen werden. RELATIONS: (Optional, Liste) Auflistung der Muster, die oft in Verbindung mit diesem Muster verwendet werden und in irgendeiner Beziehung zu diesem Muster stehen. Ausnahme sind die Mustersprachen, die das vorliegende Muster enthalten, denn diese Form der Beziehung wird bereits durch das Attribut “CONTAINS” erfaßt. Die Art der Beziehung wurde ansonsten nicht erfaßt, da in den meisten Fällen keine Bezeichnung existiert, die diese Beziehung charakterisieren könnte, das Muster arbeitet in der Regel einfach “im Kontext” der anderen Muster. Falls das aufgelistete Muster im Archiv enthalten ist, soll lediglich sein Name ohne Anführungszeichen erscheinen. Ansonsten soll es mit Anführungszeichen versehen werden. VARIATIONS: (Optional, Liste) Verweise auf Quellen, die Variationen des Musters beschreiben. Falls das aufgelistete Muster im Archiv enthalten ist, soll lediglich sein Name ohne Anführungszeichen erscheinen. Ansonsten soll es mit Anführungszeichen versehen werden. SAMPLE IMPLEMENTATIONS: (Optional, Liste) Verweise auf Quellen, welche Implementierungen des Musters in konkreten Programmiersprachen zeigen. Jeder Wert ist mit Anführungszeichen versehen. USES: (Optional, Liste) „Genau ein Wert“ bedeutet, daß dem Schlüsselwort genau ein Wert zugeordnet werden muß. „Optional“ heißt, daß dem Schlüsselwort ein Wert zugewiesen werden kann aber nicht muß. 7 „Liste“ heißt, daß mehrere Werte möglich sind. 5 6 13 Vorgehensweise Verweise auf sd&m-Projekte, in welchen das Muster erfolgreich eingesetzt worden ist. Diese Werte müssen im Laufe der Anwendung des Muster Archivs bei sd&m von den Projektverantwortlichen hinzugefügt werden. Jeder Wert ist in Anführungszeichen versehen. LINK: (mindestens ein Wert, Liste) Verweise auf vollständige Beschreibungen des Musters in Literatur, Internet und im sd&m-eigenen Intranet (“sww”). Jeder Wert ist mit Anführungszeichen versehen. Eine EBNF Beschreibung ist in [NIE99] zu finden. Zur Verdeutlichung der Syntax ist in Abbildung 4 ein Patlet vorgestellt, das für das Archiv erstellt wurde. NAME: <Muster-Name> ALT: <Alternativnamen> DOMAIN: Software ATTRIBUTES: Granularität: Problemkat: Scope: Purpose: sdm-Schichten: Architekturmuster | Entwurfsmuster | Idiom | ... Vom Chaos zur Struktur | Verteilte Systeme | ... Class | Object Creational | Structural | Behavioral Benutzerschnittstelle | Anwendungskern | ... // Kommentare zur Klassifikation INTENTION: <Beschreibung von Problem, Kontext und evtl. Lösung in Kurzform> CONTAINS: <Liste von Musternamen> RELATIONS: <Liste von Musternamen> VARIATIONS: "<erster Verweis>”, "<zweiter Verweis>”, ... SAMPLE IMPLEMENTATIONS: "<erster Verweis>”, "<zweiter Verweis>”, ... USES: "<erster Verweis>”, "<zweiter Verweis>”, ... LINK: "<erster Verweis>”, "<zweiter Verweis>”, ... Abbildung 4: Patlet Struktur 14 3 Analyse Mit Analyse werden alle Aktivitäten im Rahmen des Softwareentwicklungsprozesses bezeichnet, die der Ermittlung, Klärung und Beschreibung der Anforderungen an das System dienen [Oest98, S. 340]. Die Anforderungen an das zu entwickelnde System, in Kapitel 3.1 beschrieben, wurden in gemeinsamen Besprechungen, an denen alle vier Parteien beteiligt waren 8, ermittelt. Das Kapitel 3.2 beschreibt was das System im einzelnen leisten soll und welche Interaktionen dabei auftreten. Auch sie wurden in gemeinsamen Besprechungen erörtert. Ein zu diesem Zeitpunkt bereits existierender Prototyp half, die zu bewältigenden Aufgaben besser zu verstehen. Die auftauchenden Datenstrukturen werden in Kapitel 3.3 erörtert. 3.1 Anforderungen Die benötigten Schritte, die zum Aufbau des Musterarchivs gemacht werden müssen, lassen sich in zwei Gebiete aufteilen. Der eine Teil ist die Sammlung und Zubereitung der Daten, die in das Archiv aufgenommen werden sollen. Der zweite Teil baut auf dem ersten auf. Er ist dafür verantwortlich, dem Benutzer die Daten des Archivs auf geeignete Weise zugänglich zu machen. Der erste Teil, in Absatz 3.1.1 beschrieben, war vor allem die Aufgabe von [NIE99], während sich diese Diplomarbeit mit den Aufgaben des zweiten Teils, Absatz 3.1.2, beschäftigt. 3.1.1 Die Muster Folgende Anforderungen mußten an die, für das Archiv zu erstellenden, Daten gemacht werden: Auswahl Die Anzahl der weltweit verfügbaren Muster ist sehr groß. Wie viele es tatsächlich sind, kann nur annähernd bestimmt werden. Die Anzahl von Verweisen auf Muster, wie in Kapitel 2.1.2 erwähnt, kann nur eine grobe Vorstellung über die Menge aller Muster geben. Muster gibt es für die unterschiedlichsten Bereiche. Nicht alle Bereiche sind für sd&m von Interesse. Deshalb muß eine Auswahl stattfinden, in der entschieden wird, welche Muster in das Archiv aufgenommen werden sollen. Klassifikation Um den Mitarbeitern einen schnellen Zugriff auf ein, seinem Problem entsprechendem, Muster zu gewährleisten, müssen die Muster in einer geeigneten Klassifikation sortiert werden. Zusammenfassung Die meisten Muster enthalten eine sehr ausführliche Beschreibung über Problem und Lösung, die sich oft über viele Seiten erstreckt. Wie bereits in Kapitel 1 angesprochen, ist dieses Format nicht geeignet, um leicht und schnell feststellen zu können, ob ein Muster bei einem bestimmten Problem zur Hilfe beitragen kann. Die Muster sollten zu Patlets zusammengefaßt werden. 3.1.2 Anwendungsfälle Das zu entwickelnde System soll die neu entstandene Klassifikation unterstützen und die Patlets verwalten. Im Rahmen der Voruntersuchungen haben sich folgende Anwendungsfälle (engl. Use Cases) herauskristallisiert: Klassifikation verwalten Der Administrator kann die Klassifikation anlegen, Kategorien darin erstellen, verändern und löschen. Patlet importieren Der Benutzer und der Administrator kann neue Patlets in das Archiv aufnehmen. Das Musterarchiv ordnet automatisch diese entsprechend ihrer Klassifikation ein. 8 Alle mitwirkenden Personen sind in Kapitel 9 aufgelistet. Analyse 15 Patlet exportieren Jederzeit ist es möglich, die Informationen eines Patlets, das in das Archiv importiert wurde, wieder zu extrahieren und als Textdatei abzuspeichern. Patlets löschen Dem Administrator des Archivs kann veraltete Patlets aus dem Archiv entfernen. Suche nach Mustern Der Benutzer kann durch die erstellte Klassifikation navigieren. Je detaillierter er dabei seine Anforderungen spezifiziert, desto mehr soll sich die Ergebnisliste, nämlich eine Auswahl von Mustern, einschränken. Die Suche geschieht in Echtzeit. Patlet betrachten Der Inhalt eines Patlets kann betrachtet werden. Dies beinhaltet auch ein leichtes Navigieren zu dem vollständigen Muster, sofern es im Internet verfügbar ist, und zu anderen Mustern, die in diesem Archiv enthalten sind. Kommentare In eine Art Diskussionsplattform können Anwender ihre Erfahrungen mit einem bestimmten Muster mit anderen teilen, d.h. zu jedem Muster kann der Benutzer Kommentare schreiben und auf die Kommentare anderer antworten. Ein Teil der Aufgaben beschränkt sich nur auf das Suchen von Mustern. Sie stellen Interaktionen mit dem normalen Benutzer des Archivs dar. Ein anderer Teil beschäftigt sich nur mit der Verwaltung des Archivs. Abbildung 5: Anwendungsfälle für das Musterarchiv 3.2 Aktivitäten Ausgehend von den Anwendungsfällen sind folgende Aktivitäten ausmachbar, die von dem System unterstützt werden sollen. 16 Analyse Die Eigenschaften und Fähigkeiten des Programms werden mit Hilfe von Aktivitätsdiagrammen beschrieben. Aktivitätsdiagramme sind Teil der UML [UML]. Ihnen fehlen einige wichtige Konstrukte. Bernd Oestereich hat die Syntax und Semantik von Aktivitäten erweitert. Die in seinem Buch beschriebene ‚Oder-Synchronisation‘ [Oest98, S. 297] wird an einigen Stellen verwendet. 3.2.1 Suche Ziel der Suche ist es, dem Benutzer eine Menge von Mustern zu präsentieren, die den Anforderungen des Benutzers genügen. Um diese Anforderungen beschreiben zu können, muß er eine Auswahl von Eigenschaften in der gegebenen Klassifikation bestimmen. Diese Auswahl führt dann zu einer Ergebnismenge, die diesen Anforderungen entsprechen. Der Benutzer kann außerdem wählen, ob die Einfachklassen innerhalb einer Facette mit dem logischen UND oder mit ODER verknüpft werden sollen. ‚UND‘ bedeutet, daß jede ausgewählte Einfachklasse jedem Muster, das in der Ergebnismenge enthalten sein soll, zugeordnet ist. ‚ODER‘ heißt, daß ein oder mehrere der Einfachklassen jedem gefundenen Muster zugeordnet sind. Das endgültige Ergebnis entsteht dann durch die Verknüpfung der innerhalb einer Facette gefundenen Mustermengen. Ob die Mengen mit UND oder mit ODER verknüpft werden, soll der Benutzer entscheiden dürfen. {Or} Einfachklasse(n) auswählen Ergebnismenge wird angezeigt Logische UND/ODER Verknüpfung innerhalb der Facette bestimmen Logische UND/ODER Verknüpfung zwischen den Facetten bestimmen Menge von Mustern [enthält alle Muster, die den ausgewählten Klassen zugeordnet und entsprechend logisch verknüpft worden sind] Abbildung 6: Suche Um den Vorgang der Suche genauer beschreiben zu können, muß also vorausgesetzt werden, daß das Programm die Struktur und den Inhalt der gesamten Klassifikation widerspiegelt. Wie oben erwähnt, gibt es Auswahlmöglichkeiten für die logische Verknüpfung innerhalb und zwischen den Facetten. 17 Analyse Ablauf (Abbildung 6): Der Benutzer kann beliebig viele Einfachklassen aus der gegebenen Klassifikation auswählen. Jede Auswahl bewirkt eine sofortige Berechnung und Darstellung der neuen Ergebnismenge unter Berücksichtigung der logischen Verknüpfungen innerhalb und zwischen den Facetten. Auch die Änderung einer logischen Verknüpfung bewirkt eine sofortige Neuberechnung des Ergebnisses. Der Vorgang kann beliebig oft wiederholt werden. 3.2.2 Ansicht eines Patlets Um mehr über ein Muster aus der Ergebnismenge zu erfahren, kann der Benutzer es auswählen woraufhin die im Archiv gespeicherten Informationen angezeigt werden. Der Vorgang kann beliebig oft wiederholt werden. Er ist in Abbildung 7 dargestellt. Muster aus der Ergebnismenge auswählen Inhalt des Patlets wird angezeigt Abbildung 7: Patlet anzeigen 3.2.3 Kommentare zu einem Muster Es besteht die Möglichkeit, zu jedem Muster Kommentare zu verfassen oder andere Kommentare zu lesen. Ablauf (Abbildung 8): Der Benutzer wählt ein Muster aus. Daraufhin löst er über das Menü einen Befehl aus, der ihn zu einer Übersicht über die bisher geschriebenen Kommentare führt. Der Benutzer kann danach einen Kommentar auswählen und lesen und auf diesen antworten. Oder er kann einen neuen Kommentar schreiben. Nach Vollendung wird der neue Kommentar im Archiv abgespeichert. Der Benutzer kann zu jedem Zeitpunkt den Ablauf unterbrechen. So kann er nur die Übersicht betrachten oder sich die Kommentare anzeigen lassen und danach abbrechen. Selbst einen neu geschriebenen Kommentar kann er verwerfen, anstatt ihn abzuschicken. Um die Übersichtlichkeit zu wahren, wurden die Abbruchmöglichkeiten im Aktivitätsdiagramm (Abbildung 8) nicht dargestellt. 18 Analyse Muster auswählen [„Kommentare“] Übersicht aller Kommentare zu Muster anzeigen [„antworten“] [„lesen“] [„neu“] Kommentar anzeigen {Or} Kommentar schreiben [„antworten“] [„abschicken“] Im Archiv abspeichern Abbildung 8: Kommentare 3.2.4 Abhängigkeiten abfragen Die Einfachklassen im Klassifikationssystem sind mit den Mustern verknüpft. Sie bilden also einen Graph. Für den Anwender ist nicht offensichtlich, welche Klassen bestimmten Mustern zugeordnet sind, da eine Darstellung des Archivs als Graph nicht vorgesehen ist. Um trotzdem Zusammenhänge erkennen zu können, soll für jede Klasse die Möglichkeit bestehen, die durch sie repräsentierten Muster abzufragen. Umgekehrt soll es möglich sein, für jedes Muster die Klassen abzufragen, die es repräsentieren. 19 Analyse Ablauf: Der Benutzer wählt eine Einfachklasse aus. Daraufhin löst er über das Menü den Befehl „Alle Muster anzeigen“ aus. Alle Muster, die durch die Klasse repräsentiert sind, werden angezeigt. Abbildung 9 stellt das zugehörige Aktivitätsdiagramm dar. Der Benutzer wählt ein Muster in der Ergebnismenge aus. Daraufhin löst er über das Menü den Befehl „Alle Einfachklassen anzeigen“ aus. Alle Einfachklassen, die das Muster repräsentieren, werden angezeigt. Abbildung 10 stellt das zugehörige Aktivitätsdiagramm dar. Einfachklasse auswählen [„Muster anzeigen“] Alle Muster, die einer Einfachklasse zugeordnet sind, anzeigen Abbildung 9: Abhängigkeiten. Alle Muster, die einer Einfachklasse zugeordnet sind. Einfachklasse auswählen [„Einfachklassen anzeigen“] Alle Klassen, die dem Muster zugeordnet sind, anzeigen Abbildung 10: Abhängigkeiten. Alle Einfachklassen, die einem Muster zugeordnet sind. 20 Analyse 3.2.5 Patlet importieren Die einzige Möglichkeit, ein Patlet dem Archiv hinzuzufügen, besteht darin, es als Textdatei zu importieren. Die Form des Patlets muß dabei der oben beschriebenen Patletvorlage genügen. Ablauf (Abbildung 11): Der Benutzer wählt die zu importierende Datei aus, woraufhin deren Inhalt geparst wird. Es wird dann geprüft, ob alle Schlüsselwörter darin vorkommen. Sowohl der angegebene Bereich als auch die Facetten und Einfachklassen müssen bereits in der Klassifikation enthalten sein. Außerdem wird überprüft, ob eine Facette als ‚Auswahl‘ oder als ‚Liste‘, so wie in der Klassifikationsstruktur beschrieben, spezifiziert ist. Sollten dem Patlet mehrere Einfachklassen aus einer Auswahl zugewiesen worden sein, kann das Patlet nicht akzeptiert werden. Nur wenn das Patlet alle Bedingungen erfüllt, kann es aufgenommen werden. Sollte bereits ein Patlet mit gleichem Namen im Archiv existieren, wird es durch das neue ersetzt. Dateinamen auswählen [„Klassifikation genügt Anforderungen nicht“] Patlet parsen und analysieren. Patlet ablehnen und Vorgang abbrechen [„Klassifikation genügt Anforderungen“] Patlet importieren Archiv Objekt Patlet Abbildung 11: Patlet importieren 3.2.6 Patlet importieren (Administration) Der Administrator darf beliebig viele Patlets auf einmal importieren. Der Ablauf ist ähnlich dem oben beschriebenen. Falls der Bereich, eine Facette oder eine Einfachklasse, die dem Patlet zugeordnet ist, noch nicht im Archiv existiert, kann diese auf Wunsch automatisch in das Archiv aufgenommen werden, so daß das Patlet in das bestehende Klassifikationssystem eingebettet werden kann. Abbildung 12 zeigt den Ablauf als Aktivitätsdiagramm. 21 Analyse [Bereiche, Facetten oder Einfachklassen existieren noch nicht im Klassifikationsschema] Dateinamen auswählen [Klassifikation genügt Anforderungen] Klassifikation erweitern Patlet importieren Datenbank Objekt Patlet Abbildung 12: Patlet importieren (Administration) 3.2.7 Patlet exportieren Die gesamten Informationen eines Patlets befinden sich im Archiv. Sie können, wie bereits oben angesprochen, auch in einem bestimmten Format als Textdatei abgespeichert werden. Ablauf (Abbildung 13) Der Benutzer wählt ein Muster aus. Daraufhin löst er über das Menü den Befehl „Abspeichern“ aus. Die entsprechenden Informationen werden aus dem Archiv geladen und mit Hilfe der Patletvorlage (s. Kapitel 2.3.2) formatiert. Nachdem er den Namen der neuen Datei gewählt hat, wird das Patlet lokal auf seiner Festplatte gespeichert. 3.2.8 Klassifikation anlegen (Administration) Nur der Administrator kann das Klassifikationssystem anlegen und verändern. Die Struktur der Klassifikation entspricht einem Baum der Höhe vier (s. Kapitel 2.3.1). Dementsprechend soll der Administrator einen Baum anlegen dürfen. Stufe eins entspricht dann dem ‚Bereich‘, Stufe zwei den ‚Facetten‘ und Stufe drei den ‚Einfachklassen‘. Die Namen der Knoten dürfen verändert werden. Ein Löschen der Knoten ist möglich. Jede Veränderung wird sofort im Archiv umgesetzt. Neues Element hinzufügen: Der Benutzer selektiert einen Knoten im Baum. In der Hierarchie der Klassifikation steht der ‚Bereich‘ unter der Wurzel, die ‚Facette‘ unter dem ‚Bereich‘ und die ‚Einfachklasse‘ unter der ‚Facette‘. Einfachklassen stellen die letzte Stufe in der Hierarchie dar. Für die Wurzel, den Bereichsknoten oder Facettenknoten kann der Benutzer einen Sohnknoten erstellen. Er stellt dann ein neues Element in der Hierarchie dar. Das Archiv wird um das neue Element erweitert. Es ergibt sich dadurch ein Baum der Höhe vier wie zuvor in Kapitel 2.3.1 spezifiziert. 22 Analyse Exemplarischer Ablauf beim Anlegen einer Facette: Voraussetzung ist, daß bereits mindestens ein Bereich im Archiv existiert. Wird dieser ausgewählt, so kann als Sohnknoten eine neue Facette im Klassifikationsbaum angelegt werden. Dem Benutzer wird die Möglichkeit gegeben, den Namen der Facette anzugeben. Daraufhin wird das Archiv aktualisiert. Element entfernen: Der Benutzer kann ein Element aus der Klassifikation auswählen und den Befehl zum Löschen geben. Falls das Element Abhängigkeiten hat, so kann es nicht gelöscht werden. Ein Knoten im Klassifikationsbaum hat Abhängigkeiten, genau dann wenn er einen Sohn besitzt. Ein Blatt (eine Einfachklasse) hat Abhängigkeiten, genau dann wenn es ein Muster im Archiv gibt, das durch die Einfachklasse repräsentiert wird. Muster auswählen [„Exportieren“] Dateinamen auswählen Informationen aus DB laden Als Patlet abspeichern Abbildung 13: Patlet exportieren Textdatei gemäß der Patletvorlage 23 Analyse 3.3 Datenstruktur Die Struktur des Klassifkationssystems entspricht einem Baum der Höhe vier. Durch die Repräsentation eines Musters durch das System entsteht ein Graph. In Abbildung 14 ist beispielhaft ein Auszug aus der Klassifikation abgebildet, wie sie in [NIE99] entstanden ist. Klassifikation Bereiche Facetten Muster Einfachklassen Wurzel Software Granularität Architekturmuster Entwurfsmuster Problemkat Adaptierbare Systeme Physical View Organisation von Arbeit Verteilte Systeme Mediator Adaption Sdm-Schichten Datenverwaltung Purpose Behavioral Structural Scope Object Abbildung 14: Auszug aus der Klassifikation Microkernel 24 4 Entwurf Mit Entwurf (engl. Design) werden alle Aktivitäten im Rahmen des Softwareentwicklungsprozesses bezeichnet, mit denen ein Modell logisch und physisch strukturiert wird und die dazu dienen zu beschreiben, wie das System die in der Analyse beschriebenen Anforderungen erfüllt [Oest98, S. 344]. Dieses Kapitel beschäftigt sich mit der Art und Weise, mit der die Anforderungen in Kapitel 3 erfüllt werden sollen. Hier werden die Klassen des Systems und ihre Bedeutung spezifiziert. 4.1 Wahl der Technologie „Nur in Ausnahmefällen entsteht das neu zu entwickelnde System auf der grünen Wiese. In der Regel wird es in einen bestehenden Anwendungsbereich integriert [...]“ [Oest98, S. 78]. So auch in dieser Arbeit. Das hier entstandene Archiv wurde nicht völlig neu implementiert, sondern setzt auf dem von sd&m entwickelten Framework SUMATRA auf. Es unterstützt die Kommunikation mit Datenbanken. So ist es sinnvoll, sich bereits zu Anfang der Entwurfsphase über die zu verwendenden Technologien im Klaren zu sein, da die neu zu entwickelnden Komponenten auf einem bestehenden System aufbauen werden. Die Entscheidung über Implementierungssprache (Kapitel 4.1.1) und Art der Speicherung des Archivs (Kapitel 4.1.2) sind die Voraussetzung für die Verwendung von SUMATRA. Es wird in Kapitel 4.1.3 beschreiben. 4.1.1 Java Für die Implementierung wurde die Programmiersprache Java gewählt. Sie bietet als recht neue und moderne Sprache einige Vorzüge: Java ist objektorientiert. Java bietet keinen direkten Zugriff auf den Hauptspeicher. Im Gegensatz zu C/C++ kann man in Java den Speicher nicht selbst verwalten. So ist es z.B. überhaupt nicht möglich versehentlich den auszuführenden Code im Speicher zu überschreiben. Dies ist eine sehr häufige Fehlerursache bei C++. Die Laufzeitfehler treten erfahrungsgemäß selten an der Stelle auf, an der sie verursacht wurden. Oft sind sie nicht einmal reproduzierbar, da sie vom Dateninput und der Umgebung abhängen. Deshalb ist die Fehlersuche meist sehr mühsam und zeitaufwendig. Ein weiteres Problem können Speicherlecks darstellen. Sie entstehen oft durch die Eigenverwaltung des Speichers. Durch die Einführung eines Garbage Collectors nimmt Java dem Programmierer diese Aufgabe ab. Java ist plattformunabhängig. Sun Microsystems [Sun] bietet eine eigene Laufzeitumgebung an, die Java Programme interpretieren kann. Die Laufzeitumgebung wird Virtual Machine (VM) genannt. Eine VM ist für fast alle Plattformen verfügbar. Java ist netzwerkfähig. Das zu erstellende Archiv soll im Intranet oder sogar im Internet zur Verfügung gestellt werden. Es macht daher Sinn auf Techniken zurückzugreifen, die die Kommunikation im Netzwerk unterstützen. Ein Java Programm kann als sogenanntes Applet implementiert werden. Ein Applet hat den Vorzug, daß es auf einem Server zur Verfügung gestellt werden kann. Mittels HTTP kann ein Client das Applet vom Server laden und lokal bei sich ausführen. Der dabei verwendete Browser muß Java unterstützen. Viele moderne Browser tun dies, entweder durch eine eingebaute VM oder durch die von Sun veröffentlichten Plug-ins [Plug-in11], [Plug-in12]. Dadurch ist die Verbreitung des Programms über das Intranet und Internet sehr leicht. Bei Versionsänderungen des Programms muß es nicht neu verteilt werden, sondern wird vom Browser, bei erneutem Aufruf, automatisch neu geladen. Entwurf 25 Es wurde entschieden, das Suchwerkzeug und Administrationswerkzeug als Applet zu implementieren. Java bietet außerdem das RMI [RMIGuide] Konzept an, so daß es mit anderen Programmen im Netzwerk kommunizieren kann. Java bietet eine standardisierte Schnittstelle zu relationalen Datenbanken. Mit den Klassen aus der sogenannten JDBC [JDBC] ist es möglich, Befehle an eine relationale Datenbank zu schicken und die Ergebnisse abzufragen. Benötigt wird zusätzlich ein JDBCTreiber, der speziell für eine Datenbank geschrieben ist. Solche Treiber sind für fast alle Datenbanken erhältlich [JDBC-Drivers]. Die Plattformunabhängigkeit ist trotzdem weiterhin gegeben. Java hat aber auch Nachteile. Es ist eine sehr junge Sprache und immer noch in der Entwicklung. Deshalb sind Fehler in den Klassenbibliotheken nicht selten. Auch die Geschwindigkeit des ausführbaren Codes kann sich mit einem, für ein Betriebssystem kompilierten, Programm noch nicht messen. 4.1.2 Relationale Datenbank Auch wenn die Patlets bereits in Textdateien existieren, macht es keinen Sinn, diese zentral abzulegen und zu verwalten. Es gäbe keine geeignete Methode zu prüfen, ob die Einfachklassen, durch die ein Patlet klassifziert wird, auch tatsächlich im Klassifikationssystem enthalten sind, denn eine referenzielle Integrität bietet nur eine Datenbank. Sie kann für Datenkonsistenz garantieren. Da objektorientierte und objektrelationale Datenbanken immer noch den Ruf haben, fehleranfällig und langsam zu sein, wurde für die Speicherung der Daten im Archiv eine relationale Datenbank gewählt. 4.1.3 Framework SUMATRA SUMATRA ist ein in Java implementiertes Framework, das von sd&m entwickelt wurde. Es besteht aus einer Server Applikation, die über JDBC mit einer relationalen Datenbank kommunizieren kann und einem Applet, das mit Hilfe von RMI [RMIGuide] Informationen mit dem Server austauscht. Das Framework ist also eine Middleware, die zwischen Applet und Datenbank vermittelt. Es ist so konzipiert, daß auf einfache Art und Weise die Funktionalität und das Aussehen des Applets verändert werden kann, indem Klassen, die vom Framework aufgerufen werden, durch eine eigene Implementationen überschrieben werden. Man kann also eine eigene Benutzeroberfläche gestalten und gleichzeitig die Vorzüge von SUMATRA nutzen. Der Einsatz des Frameworks bietet einige Vorteile, die im folgenden beschrieben werden. Dazu seien zunächst die Probleme genannt, die durch die Verwendung von SUMATRA automatisch gelöst werden: Wenn ein Applet über einen Browser mit HTTP geladen wurde, wird es laut Spezifikation [JVM-Spec] in einer sogenannten Sandbox ausgeführt. Sie sorgt dafür, daß ein Applet nicht alle Aktionen ausführen darf, die ein normales Programm ausführen dürfte. Die Beschränkungen dienen zum Schutz des Benutzer. Eine typische Einschränkung ist beispielsweise die Verweigerung, auf das lokale Dateisystem zugreifen zu dürfen. Außerdem darf ein Applet mit keinem anderen Rechner kommunizieren als mit demjenigen, auf dem der Webserver das Applet zur Verfügung gestellt hat. Möchte das Applet nun mit einer Datenbank im Netzwerk mittels eines JDBC-Treibers vom Typ 49 [JDBC-Drivers] Verbindung aufnehmen, so müßte die Datenbank auf demselben Rechner wie der Webserver liegen. Das ist nicht wünschenswert, da solche Rechner beliebte Angriffsziele von Hackern im Internet sind. Zudem können so die Lasten nicht auf unterschiedliche Rechner verteilt werden. Die Lösung ist, eine Middleware zu benutzen. Sie läuft als eigenständiger Server auf dem Webserver und vermittelt zwischen Datenbank und Applet. JDBC-Treiber des Typs 3 sind als Middleware spezifiziert. Sie übersetzen JDBC API Aufrufe in ein DBMS unabhängiges Netzprotokoll, was dann durch einen Server in ein DBMS Protokoll übersetzt wird. 9 Ein JDBC-Treiber vom Typ 4 nimmt direkte Verbindung zur Datenbank auf. 26 Entwurf Wenn aber ein extra Server benötigt wird, um mit einer Datenbank Verbindung aufzunehmen, so wäre es sinnvoll, den Programmteil, der die JDBC API benutzt, bereits auf dem Server zu kapseln und den Client (das Applet) davon zu befreien. Wie bereits oben beschrieben, verfolgt SUMATRA genau diesen Ansatz. Ein weiteres Problem ist, daß trotz der Standardisierung von SQL es Unterschiede zwischen den verschiedenen SQL-Dialekten gibt. So unterscheiden sich beispielsweise die Anweisungen bei JOINS für Oracle und MSSQL Server. Über eine Konfigurationsdatei kann man SUMATRA auf die entsprechende Datenbank einstellen. Im Laufe der Diplomarbeit wurde das System mit Oracle 8 und MSSQL Server 6.5 getestet. Neben den genannten Vorteilen, ist das Frameworks zusätzlich in der Lage, von der Struktur der Datenbank zu abstrahieren indem es die Daten aus den Datenbanktabellen in sogenannte fachliche Objekte umwandelt. Sie können als Datenbank View verstanden werden, der von einer Haupttabelle ausgeht und weitere Attribute aus Fremdtabellen hinzu nimmt. Die fachlichen Objekte werden in einer speziellen Syntax beschrieben und als Metadaten bezeichnet [SUMATRA]. Der Server des Frameworks hat Zugang zu den Metadaten und interpretiert diese entsprechend. Die Metadaten legen für das fachliche Objekt insbesondere folgendes fest: Eine Liste von Attributen des fachlichen Objekts. Für diese Attribute wird festgelegt: Der Name. Der Basistyp. Ob es sich um ein Schlüsselattribut handelt. Das Darstellungsformat. Das Speicherformat. Datenbanktabellen und Spaltennamen. Die Beschreibung von hierarchisch untergeordneten Objekten, die durch eine 1:n-Beziehung in dem fachlichen Objekt enthalten sind. Diese Objekte sind durch eigene Metadaten beschrieben und unterscheiden sich dadurch von den oben genannten Attributen, die jeweils von einem Basistyp sind. Es wird festgelegt, wie sich diese Objekte für eine bestimmte Instanz des fachlichen Objekts bestimmen. Hierzu wird eine Regel aufgestellt, wie mit Hilfe der aktuellen Werte der Attribute die möglichen Schlüssel der Unterobjekte eingegrenzt werden. Für weitere Informationen sei die Dokumentation von SUMATRA verwiesen [SUMATRA]. 4.2 Überblick des Gesamtsystems Das hier entwickelte System besteht aus vier Komponenten. Die erste Komponente ist eine relationalen Datenbank in der das Archiv in abgespeichert ist. Der SUMATRA Server, die zweite Komponente, der auf die Datenbank Zugriff hat, läuft auf demselben Rechner, auf dem auch ein Webserver installiert ist. Von diesem Webserver aus können zwei unterschiedliche Applets geladen werden. Eines stellt das Suchwerkzeug dar, das andere dient zur Administration des Archivs. Den Applets ist die Adresse des Servers bekannt, der ständig auf Anfragen der Applets horcht. SUMATRA stellt einen fertigen Server und ein vorgefertigtes Applet zu Verfügung. Das Applet ist so konzipiert, daß man leicht diejenigen Klassen, die für die Kontrolle und Darstellung des Applets zuständig sind, erweitern kann. Anstelle der Originalklassen werden dann diese Erweiterungen verwendet. Dies ist eine übliche Vorgehensweise bei der Verwendung von Frameworks. Wie der Aufrufmechanismus in SUMATRA funktioniert, wird in Kapitel 4.4 beschrieben. Die Kommunikation zwischen Datenbank und Server ist in SUMATRA über JDBC realisiert. Die Kommunikation zwischen Applet und Server funktioniert über RMI [RMIGuide]. Mit den Java Foundation Classes (JFC, auch bekannt als Swing Klassen) ist es möglich, ein Programm zu erschaffen, das dem Look and Feel moderner Programme entspricht. Die Klassen verfügen über eine Vielzahl von nützlichen Komponenten, wie die Darstellung von Bäumen oder Tabellen. Die Klassenstruktur entspricht größtenteils dem Architekturmuster ‚Model View Controller‘ (MVC) bzw. dem ‚modified MVC‘ [ModMVC]. 27 Entwurf Die Version von SUMATRA, die für diese Diplomarbeit bereitgestellt wurde, ist jedoch mit den herkömmlichen AWT Klassen von Java implementiert. Das Mischen von Swing Klassen und AWT Klassen ist problematisch und teilweise sogar unmöglich [Mixing]. Dem Programmierer wird beim Umgang mit den Swing Klassen viel mehr Arbeit abgenommen als bei den AWT Klassen. Zudem lassen die graphischen Komponenten die Oberfläche einer mit JFC programmierten Applikation schöner aussehen. Das Standard-Applet in SUMATRA verfügt über eine sehr einfache Oberfläche. Für jedes Attribut eines fachlichen Objektes wird eine Textzeile dargestellt, in der man Suchparameter angeben kann. Anschließend wird die Ergebnismenge in einer Tabelle dargestellt. Komplexere Strukturen wie Bäume oder Graphen werden nicht unterstützt. Angesichts der Baumstruktur des Klassifikationssystems und der Graphenstruktur, die sich durch die Klassifizierung der Muster ergibt, wird die Oberfläche komplett neu mit den Swing Klassen implementiert. Um das zu realisieren, muß schon sehr früh in das Framework eingegriffen und die entsprechenden Controller selbst implementiert werden. 4.3 Schichten Die Applets sind in ihrer Struktur der „Drei Schichten Architektur“ (engl. Three Layer Architecture) nachempfunden. Das Architekturmuster ist eine gängige Vorgehensweise, um Informationssysteme, wie dieses eines ist, zu planen. Die Firma sd&m verwendet das Muster in Datenbankprojekten. Während der Suche nach verwendeten Mustern innerhalb von Firmenprojekten (engl. Pattern Mining) wurde es entdeckt und dokumentiert. Die Beschreibung ist in [BDRS97, S. 63 ff] nachzulesen. Eine allgemeinere Definition des Schichtenmodells (engl. Layers) findet man in [POSA98, S. 32 ff]. Die drei Schichten bauen sich üblicherweise aus der Präsentationsschicht, der Anwendungslogik und der Datenbankschicht auf. Die unterste Schicht übernimmt die Kommunikation mit der Datenbank. Da diese Aufgabe bereits durch den Server von SUMATRA bewältigt wird, muß diese Schicht nicht mehr implementiert werden. Sie wird durch die Kommunikation mit dem Server von SUMATRA ersetzt. Die obere Präsentationsschicht enthält alle Komponenten der Bedienungsoberfläche und die Kommunikation mit dem Benutzer. In der mittleren Anwendungsschicht werden interne Vorgänge implementiert. Abbildung 15 zeigt die Unterteilung der packages in einzelne Schichten. Mit der Verwendung von packages (dt. Pakete) ist es möglich, in Java Klassen, die eine ähnliche Funktionalität haben oder die eng zusammenarbeiten, in einzelne Bereiche zu unterteilen. Sie verschaffen einen besseren Überblick über die Struktur des Programmes. Eine Beschreibung der einzelnen Klassen und deren Zusammenspiel folgt in den späteren Kapiteln. Die Schichten sind miteinander vermischt. So sind einige packages sowohl der Präsentationsschicht als auch der Anwendungslogik zuzuordnen. 28 Entwurf Beinhaltet die graphischen Oberflächen parchie.gui parchie.comment.composer parchie.util.dubh.ui Klassen für den Kommentar Editor Klassen für die Generierung von Menüs, Popupmenüs und Toolbars Allgemeine Erweiterungen der Swingklassen. parchie.swing Klassen für Darstellung und Verwaltung der Kommentare. Präsentationsschicht parchie.comment.dialog parchie.control.search parchie.control.admin parchie.control Anwendungsschicht Dialog mit dem Benutzer des Administrationswerkzeuges Allgemeine Dialoge mit dem Benutzer parchie.util.dubh.misc Nützliche Klassen parchie.environment Bereitstellung und Definition sämtlicher Strings und Menüs. parchie.objects parchie.util parchie.comment.nntp „Datenbankschicht“ (Kommunikation mit SUMATRA) Dialog mit dem Benutzer im Suchwerkzeug. Objekte, wie sie im Applet gehalten werden. Enthält Informationen über Klassifikation und Patlets Nützliche Funktionen wie Dateioperationen und rekursive Ausgabe von Arrays. parchie.applmeta parchie.persist Schnittstelle zwischen Datenbank und Kommentaren. Schnittstelle zwischen den fachlichen Objekten von SUMATRA und den Objekten aus parchie.objects Datenbank Kommandos als Objekte, so daß leicht jede beliebige Datenbankoperation an den Server geschickt werden kann. Abbildung 15: Schichtenmodell und Packages des Programms 29 Entwurf 4.4 Aufruf Die Klasse DialogApplet (sumatra.control)10 ist der Einstiegspunkt des Applets. Bei Aufruf des Applets wird zunächst die Methode init() in DialogApplet aufgerufen. Von dort aus wird eine Instanz der Implementation des Interfaces DialogManager (sumatra.control) erzeugt. Welche Implementation verwendet wird, entscheidet sich erst zur Laufzeit. Der Name der Klasse ist in der Variablen ClassDialogManager in der Klasse Environment (sumatra.environment) abgelegt. Bei Aufruf der Methode createDialogManager() wird ein Objekt der Klasse mit Hilfe des Reflection Mechanismus [ReflectDoc] erzeugt. Für dieses Applet ist es eine Instanz der Klasse PA_DialogManager (parchie.control). Dort wird ein Fenster kreiert, in dem später die Bedienungsoberfläche eingebettet wird. Von dort aus wird ein Objekt der Klasse DialogImpl (sumatra.control) erzeugt, daß wiederum eine Implementierung des Interfaces PA_DialogController (parchie.control) instanziiert und die Methode useFrame() aufruft. Damit ist die Kontrolle an PA_DialogController übergeben. Von dort aus wird das Applet gesteuert. Die Oberfläche und Funktionalität der Suchmaschine und des Administrationswerkzeuges sind voneinander getrennt. Da jedoch beide große Teile des Quellcodes gemeinsam nutzen können, sind sie in einem Applet vereint. Die Unterscheidung findet durch einen übergebenen Parameter in PA_DialogManager statt. Je nachdem wird dann die Kontrolle parchie.control.admin.DialogController oder parchie.control.search.DialogController übergeben. Alle Fenster, die während der Laufzeit entstehen, werden beim WindowManager (sumatra.control) registriert. Es ist somit sichergestellt, daß alle Fenster bei Beendigung des Applets geschlossen werden. Die Aufrufmechanismen, so wie sie eben beschrieben worden sind, sind von SUMATRA vorgegeben. Abbildung 16 zeigt das Zusammenspiel der Klassen. Abbildung 16: Aufruf 10 In der Klammer steht das package, in dem die Klasse angesiedelt ist. 30 Entwurf 4.5 Standard Dialog Die Klassen parchie.control.admin.DialogController bzw. parchie.control.search.DialogController sind das eigentliche Herzstück des Applets. Von hier aus wird das Menü erstellt. Sie instanziieren außerdem die entsprechenden Listener für die sichtbaren Komponenten. Im Suchwerkzeug werden die sichtbaren Komponenten in der Klasse SearchPanel (parchie.gui) erzeugt. Für jeden Bereich, wie er in Kapitel 2.3.1 definiert ist, wird ein eigenes SearchPanel angelegt und in einem eigenen Reiter (engl. Tab Panel) dargestellt. Das SearchPanel enthält eine Darstellung der Facetten und deren Einfachklassen. Sie wird mit Hilfe der Klasse JTable (javax.swing) realisiert. Die Darstellung der Ergebnismenge der gefundenen Muster übernimmt eine JList (java.swing). An jede Tabelle ist eine eigene SearchAction (sumatra.control.search) gekoppelt. Sie reagiert sofort, sobald der Benutzer eine Zelle in der Tabelle selektiert oder die Suchkriterien (UND/ODER Verknüpfung) ändert. Es wird dann die Ergebnismenge neu berechnet und in der JList dargestellt. PatletListAction ist ein Listener für die JList. Sobald der Benutzer ein Muster selektiert, wird der HTML Browser, der das Applet geladen hat, dazu aufgefordert, das zugehörige Patlet darzustellen. Für jedes importierte Patlet ist eine HTML Datei generiert worden, die auf der Serverseite abgespeichert ist (Kapitel 4.11). Der MenuController (parchie.control.search) generiert das Menü und reagiert entsprechend auf die Benutzerbefehle. In diesem Zusammenhang werden Klassen aus der externen Bibliothek ‚Dubh Utils‘ verwendet [DubhUtils]. Kapitel 4.15 beschreibt das dahinterstehende Prinzip. In Abbildung 17 sind die Zusammenhänge als Klassendiagramm zusammengefaßt. Abbildung 17: Dialog für das Suchwerkzeug Für das Administrationswerkzeug wurde eine eigene Oberfläche geschaffen. Auch die Funktionalität unterscheidet sich von dem Suchwerkzeug. Die sichtbaren Komponenten werden in der Klasse AdminPanel (parchie.gui) erzeugt. Dort wird die gesamte Klassifikation mit Hilfe von JTree (javax.swing) als Baum dargestellt. Die Gesamtheit aller Patlets wird in einer JList (javax.swing) dargestellt. 31 Entwurf Der MenuController (parchie.control.admin) generiert das Menü und reagiert entsprechend auf die Benutzerbefehle. Von dort aus kann ein Patlet importiert oder gelöscht und Einträge in der Klassifikation verändert werden. Jede Veränderung hat einen entsprechenden Aufruf in der „Datenbankschicht“ zur Folge. Zur ihr gehören die drei Klassen PatletObject, DomainCatalogObject und AttributeObject (parchie.applmeta). Sie werden in Kapitel 4.6 beschrieben. Abbildung 18 zeigt die Zusammenarbeit der Klassen. Abbildung 18: Dialog für das Administrationswerkzeug 4.6 Kommunikation mit dem Server Für die Kommunikation zwischen Client und Server wird die Middleware RMI [RMIGuide] benutzt. Definierte Schnittstellen (sumatra.comm.DialogConnection, sumatra.comm. ServerProxy und sumatra.comm.ViewFactoryClient) verbergen die Implementierungsdetails vor den Aufrufern. Es sei an dieser Stelle auf die Dokumentation von SUMATRA verwiesen [SUMATRA]. Dieses Kapitel beschäftigt sich mit dem Entwurfsmuster ‚ViewFactory‘. Es ist ein Teil des Framework Pattern ‚Relational Database Access Layer‘ [BDRS97. S. 142]. Die Klasse ViewFactory (sumatra.persist.ViewFactory) ist die Schnittstelle der Zugriffsschicht und als Singleton [GOF95, S. 127] realisiert, welches bei Aufruf der Methode getInstance() auf Client- und Server-Seite unterschiedliche Implementierungen liefert. Bei einem Datenbankzugriff läßt sich der Aufrufer von der Umgebung (sumatra.environment.Environment) über die Methode getViewFactory() eine Instanz der ViewFactory geben. Der Aufrufer ruft dann beispielsweise die Methode insert() der Klasse ViewFactoryClient (sumatra.comm.ViewFactoryClient) auf. Der Befehl wird dann an das zum Client gehörenden Remote Objekt KService (sumatra.comm.Kservice) weitergeleitet. Hier findet der Übergang zum Server statt. Letztendlich wird die Methode in ViewFactoryServer (sumatra.persist.ViewFactoryServer) aufgerufen. Abbildung 19 zeigt als Klassendiagramm, wie SUMATRA das Muster einsetzt. Entwurf 32 Abbildung 19: View Factory Muster in SUMATRA Die Implementierung des ViewFactory Musters in SUMATRA hat den Nachteil, daß es sehr mühsam ist, Methoden hinzuzufügen. Dazu muß man jeweils sechs Klassen modifizieren, und sie um die entsprechende zu Methode erweitern. Die Datenbanktransaktionen sind in SUMATRA durch das Interface Transaction (sumatra.persist) gekapselt. Mit den Methoden commit() bzw. abort() wird die Transaktion beendet und die Ressourcen werden wieder freigegeben. Die Implementierung des Interfaces ist nicht serialisierbar, was zur Folge hat, daß es nicht über die RMI Schnittstelle geschickt werden kann [RMITut]. Dadurch ist es nicht möglich mehrere Datenbankbefehle auf der Clientseite in eine einzige Transaktion zu packen. Es muß jede Datenbank Transaktion, die auf der Clientseite entsteht, sofort an den Server geschickt und dort ausgeführt werden. Dies schränkt die Flexibilität des Frameworks ein und ist, unabhängig vom View Factory Muster, ein weiterer Nachteil. Abhilfe schafft das Command Muster [GOF95, S. 233] das beide Probleme löst. Anstelle von Methoden werden Befehlsobjekte übertragen. Alle Objekte erben von der Klasse DatabaseCommand (parchie.persist) mit der Methode execute(). Für jede Datenbankoperation gibt es eine eigene Implementierung. So gibt es für die Standardoperationen ‚insert‘, ‚delete‘ und ‚update‘ jeweils eine eigenen Klasse InsertCommand, DeleteCommand und UpdateCommand (im package parchie.persist). Für die speziellen Kommandos ‚insertWithReferences‘ und ‚deleteWithReferences‘ (s. Kapitel 5.2 Abschnitt a)) kommen die beiden Klassen InsertWithReferencesCommand und DeleteWithReferencesCommand (package parchie.persist) hinzu. Die Objekte sind im Gegensatz zu TransAction serialisierbar und können deshalb über die RMI Schnittstelle zum Server übertragen werden. Auf der Serverseite wird dann die Methode execute() ausgeführt, die je nach Implementierung das Gewünschte tut. Abbildung 20 zeigt die Zusammenhänge der beteiligten Klassen. Entwurf Abbildung 20: Command Muster Abbildung 21: Kombination aus Command und View Factory Muster 33 34 Entwurf Wegen der teilweise speziellen Struktur der Daten werden für die fachlichen Objekte spezielle Klassen eingeführt. Sie dienen als Schnittstelle zwischen den von SUMATRA angelegten fachlichen Objekten und den im Archiv verwendeten Objekten. Die Klasse AttributeObject (parchie.applmeta) repräsentiert dabei die Einfachklassen, DomainCatalogObject (parchie.applmeta) repräsentiert den Bereich und die Facetten und parchie.applmeta.PatletObject ein Patlet. Die Klasse CommentObject (parchie.applmeta) repräsentiert die Kommentare, die der Anwender zu einem Muster schreiben kann. Alle Klassen enthalten nicht die eigentlichen Daten, sondern dienen nur als Schnittstelle. Sie enthalten unter anderem die Methoden insert(), delete() und update(). Wird nun beispielsweise insert() von AttributeObject aufgerufen, so wird der Aufruf an die Klasse ViewFactoryParchie (parchie.persist) weitergeleitet, die alle Datenbankbefehle kapselt. Dabei wird eine bereits vorhandene Liste von Datenbankbefehlen übergeben. Dort wird dann InsertCommand instanziiert und der Liste hinzugefügt. Die so gesammelten Datenbankbefehle werden dann mit ViewFactoryParchie.executeCommands() an den Server weitergeleitet und dort, wie bereits oben beschrieben, ausgeführt. Alle in diesem Zusammenhang benötigten Klassen sind noch einmal in Abbildung 21 dargestellt. 4.7 Daten Management Eine Anforderung an das System ist, die Suche in Echtzeit zu implementieren, d.h., daß das System sofort auf Aktionen des Benutzers ohne merkliche Verzögerung reagieren sollte. Jede Anfrage an eine Datenbank benötigt mindestens zwei Sekunden [Hal]. Für eine Suche in Echtzeit ist das zu lang. Es bleibt deshalb keine andere Möglichkeit, alle für die Suche benötigten Daten bei Start des Programms zu laden und sie selbst zu verwalten. Zu den benötigten Daten gehören alle Informationen, die das Klassifikationssystem enthalten und die wie die Muster durch das System repräsentiert werden. Um die Daten zu verwalten und eine effektive Suche durchzuführen, muß eine geeignete Datenstruktur gefunden werden. Zudem müssen die Daten entsprechend indexiert werden, um einen schnellen Zugriff zu gewährleisten. Dieses Kapitel wird sich mit der Umsetzung dieser Punkte beschäftigen. Offensichtlich birgt dieser Ansatz Nachteile: Die Daten sind doppelt vorhanden. Zum einen sind sie in der Datenbank, zum anderen noch einmal im Programm gespeichert. Um Inkonsistenten zu vermeiden, bedarf es einer hohen Disziplin des Programmierers. Ein weiterer Nachteil ist der möglicherweise hohe Bedarf an Speicherplatz im Hauptspeicher. Der Platzbedarf, der durch die in [NIE99] erstellten Daten benötigt wird, ist sehr gering. Bei zahlreichen Tests, die mit diesen Daten durchgeführt wurden, stellte der Speicherplatz kein Problem dar. Da das System beliebig erweiterbar ist, muß jedoch die Frage gestellt werden, ob nicht der Fall eintreten kann, daß zu viele Daten auf einmal geladen werden müssen. Dieser Punkt wird in Abschnitt d) diskutiert. a) Datenbankstruktur SUMATRA übersetzt die Daten aus der Datenbank in sogenannte fachliche Objekte, wie sie in Kapitel 4.1.3 eingeführt wurden. Dieser Vorgang wird in Abschnitt b) beschrieben und ist mit der Datenbankstruktur eng verbunden. Es ist deshalb sinnvoll, sie bereits jetzt vorzustellen. In der Datenbank wird das Klassifikationssystem abgespeichert. Zudem sind alle Informationen über Patlets, wie sie in Kapitel 2.3.2 vorgestellt wurden, enthalten. Auch die Kommentare, die ein Benutzer zu jedem Muster schreiben kann, sind hier enthalten. Die Namen der im folgenden beschriebenen Tabellen, fachlichen Objekte und Klassen stimmen nicht mit den in Kapitel 2.3.1 eingeführten Begriffen überein. Zu Anfang wurde die Facette als Katalog und die Einfachklasse als Attribut bezeichnet. Der Begriff Bereich wurde beibehalten. Die endgültigen Bezeichnungen entstanden erst im Laufe dieser Diplomarbeit. Sie wurden im Quellcode nicht mehr geändert, haben aber die gleiche Bedeutung. Die Datenbank muß so angelegt sein, daß beliebig Bereiche, Facetten und Einfachklassen hinzugefügt, gelöscht und verändert werden können. Bereiche und Facetten werden in der Datenbanktabelle Catalog festgehalten. Sie enthält den Namen des Bereiches domain, den Namen der Facette name. Zusätzlich wird durch choice festgelegt, ob die 35 Entwurf Facette eine Auswahl oder Liste ist. Jede Ausprägung besitzt eine ‚ID‘. Somit ist es möglich, eine Facette zu referenzieren. Selbst bei Änderung des Namens der Facette oder des Bereiches bleibt die Referenz gültig. Die Einfachklassen selbst werden in einer separaten Tabelle Attributes abgespeichert. Hier wird der Name der Klasse in name festgehalten. Sie verfügt ebenfalls über eine ‚ID‘, um wiederum referenziert werden zu können. Attributes steht in einer 1:n Beziehung zu Catalog. Die Tabelle Patlet enthält den Namen des Patlet (name), die schriftliche Zusammenfassung content und den Alternativnamen alternativeName. Alle Schlüsselwörter, wie sie in Kapitel 2.3.2 festgelegt wurden finden sich in der Datenbankstruktur wieder. Das Attribut name entspricht dabei dem Schlüsselwort NAME, content entspricht INTENTION, und alternativeName entspricht ALT. Alle anderen Schlüsselwörter lassen mehrere Werte zu. Sie sind deshalb in eigene Tabellen ausgelagert: Die Tabelle ContainsPatlets entspricht CONTAINS, Variations VARIATIONS, Relations RELATIONS, Uses USES, Samples SAMPLE IMPLEMENTATIONS und Literature LINK. Jede dieser Tabellen steht in einer 1:n Beziehung zu der Tabelle Patlet. Sie enthalten alle das Attribut pat_name, mit dem sie auf die Haupttabelle Patlet referenzieren. Die Tabellen ContainsPatlets, Variations und Relations enthalten das Attribut pat_names. Dort können entweder Namen anderer Patlets stehen oder ein Literaturhinweis auf ein Muster. Die Tabellen Uses, Literature und Samples enthalten das Attribut source. Dort werden Literaturhinweise gespeichert. In der Tabelle Comments werden die Kommentare zu den einzelnen Mustern gespeichert. Darin enthalten sind: Der Titel (title), der Kommentar selbst (content), der Name des Autors (author), eine Referenz auf einen anderen Kommentar, falls auf diesen geantwortet wurde (refers_to) und das Datum, zu dem der Kommentar verfaßt worden ist (send_date). Die Repräsentation der Patlets durch das Klassifikationssystem wird mit einer n:m Beziehung (hasAttributes) zwischen der Tabelle Attributes und der Tabelle Patlet realisiert. Abbildung 22 zeigt das Entity Relationship Diagramm, das die Datenbankstruktur widerspiegelt. Literature ID I source TXT Uses ID I source TXT pat_name pat_name usedIn foundAt Samples ID I source TXT pat_name isAt name name name Patlet Attributes ID I name VA255 pat_name name content alternativeName ID_ATT hasAttributes VA255 TXT VA255 name pat_name has Comments ID I title VA255 content TXT author VA255 refers_to I send_date VA60 ID_CAT containsAttr Catalog ID I name VA255 onlyChoice BL domain VA255 name name ID ContainsPatlets ID I pat_names TXT pat_name name variationsRef relationsRef containsRef pat_name pat_name Relations ID I pat_names TXT Variations ID I pat_names TXT Abbildung 22: ER-Diagramm der Datenbank Für die unterschiedlichen Datenbanken können geringfügig unterschiedliche Datenbankschemata entstehen. Sie unterscheiden sich lediglich in den Typen der Attribute. In Abbildung 23 wird beispielhaft das Datenbankschema für den Microsoft SQL Server 6.5 beschrieben. Für die n:m Beziehung zwischen Attributes und Patlet wurde eine neue Tabelle hasAttributes eingeführt. Sie referenziert die Ausprägungen in Attributes über deren ID’s (ATT_ID), in 36 Entwurf Patlets über den Namen (pat_name). Damit ist gewährleistet, daß auch bei nachträglichen Änderungen der Namen von Einfachklassen die Beziehungen gültig bleiben. Samples ID pat_name source ID pat_name source Attributes ID name CAT_ID int varchar(255) int Uses int varchar(255) text name = pat_name ID = ATT_ID name = pat_name name = pat_name Literature ID int pat_name varchar(255) source text Comments ID int pat_name varchar(255) title text content text author varchar(255) refers_to int send_date datetime Patlet hasAttributes pat_name ATT_ID int varchar(255) text varchar(255) int name = pat_name name content alternativeName varchar(255) text varchar(255) name = pat_name ID = CAT_ID ContainsPatlets ID pat_name pat_names int varchar(255) text Catalog ID name domain onlyChoice Relations name = pat_name name = pat_name name = pat_name ID pat_name pat_names int varchar(255) text Variations ID int pat_name varchar(255) pat_names text int varchar(255) varchar(255) bit Abbildung 23: Datenbankschema für den MS SQL Server 6.x Das in Abbildung 24 abgebildete Datenbankschema wurde für die Oracle 8 Datenbank erstellt. Es unterscheidet sich lediglich in den Typbezeichnungen der Attribute. ID pat_name source ID pat_name source Uses INTEGER VARCHAR2(255) LONG Literature INTEGER VARCHAR2(255) LONG VARCHAR name = pat_name name = pat_name name = pat_name ID pat_name source Samples INTEGER VARCHAR2(255) LONG VARCHAR Comments Attributes ID INTEGER name VARCHAR2(255) CAT_ID INTEGER ID = ATT_ID hasAttributes pat_name VARCHAR2(255) ATT_ID INTEGER name = pat_name Patlet name VARCHAR2(255) content LONG VARCHAR alternativeName VARCHAR2(255) ID = CAT_ID ID name domain onlyChoice Catalog INTEGER VARCHAR2(255) VARCHAR2(255) NUMBER(1) ID pat_name title name = pat_name content author refers_to send_date INTEGER VARCHAR2(255) VARCHAR2(255) LONG VARCHAR VARCHAR2(255) INTEGER VARCHAR2(60) name = pat_name ContainsPatlets ID INTEGER pat_name VARCHAR2(255) pat_names LONG name = pat_name name = pat_name Relations ID INTEGER pat_name VARCHAR2(255) pat_names LONG Variations ID INTEGER pat_name VARCHAR2(255) pat_names LONG Abbildung 24: Datenbankschema für die Oracle 8 Datenbank b) Metadaten SUMATRA übersetzt Datenbankobjekte in fachliche Objekte mit Hilfe von Metadaten, die übergeordnete Informationen über die Datenbankobjekte enthalten. Für jedes fachliche Objekt existieren zwei Textdateien, die zusammen die benötigten Informationen enthalten. Die Metadaten beschreiben die Attribute einer Datenbanktabelle (Haupttabelle). Zusätzlich können Attribute aus Tabellen, die in Beziehung zur Haupttabelle stehen (Fremdtabellen), integriert werden. Dadurch kann ein View über mehrere Tabellen entstehen. Die Beziehungen werden nicht direkt Entwurf 37 zwischen den Datenbanktabellen, sondern zwischen den zugehörigen fachlichen Objekten (Metadatenbeschreibungen) ausgedrückt. Es kann festgelegt werden, welchen Typ das Attribut besitzt, ob es ein Schlüsselattribut oder Fremdattribut ist und ob es möglich ist, den Wert einer Ausprägung zu verändern. Zudem können die Attribute in Gruppen aufgeteilt werden. Jedem Attribut wird ein Name zugewiesen, so daß man leicht auf das Attribut zugreifen kann. Metadaten können zusätzlich Regeln enthalten. Mit der Regel ‚CHANGE_TO‘ können beispielsweise 1:n Beziehungen zwischen fachlichen Objekten beschrieben werden. Die Metadaten sind auf der Serverseite verfügbar und werden dort eingelesen. Für jedes fachliche Objekt werden auf dem Server die Informationen abgelegt. Somit kann auch auf der Clientseite darauf zugegriffen werden. Für eine eingehende Beschreibung der Metadaten und die zu verwendende Syntax verweise ich auf die beiliegende Dokumentation von SUMATRA [SUMATRA]. Im folgenden werden die für die Datenbank entstandenen Metadaten beschrieben. Es wurden folgende fachliche Objekte generiert: ALLPATLETS_OBJ (Attributes) ATTR_OBJ (Attributes) CATALOG_OBJ (Catalog) HASATTR_OBJ (hasAttributes) PATLET_OBJ (Patlet) CONTAINS_OBJ (ContainsPatlets) VARIATIONS_OBJ (Variations) RELATIONS_OBJ (Relations) USES_OBJ (Uses) LITERATURE_OBJ (Literature) SAMPLES_OBJ (Samples) COMMENT_OBJ (Comments) Hinter den fachlichen Objekten steht zur Verdeutlichung der Name der Haupttabelle in Klammern. Nicht alle fachlichen Objekte werden vom Programm direkt genutzt. Einige davon dienen nur dazu, auf sie verweisen zu können und dadurch Fremdattribute entstehen zu lassen. Lediglich ALLPATLETS_OBJ, ATTR_OBJ, CATALOG_OBJ, PATLET_OBJ und COMMENT_OBJ werden vom Programm direkt genutzt. Sie werden im folgenden näher beschrieben. Um das Klassifikationssystem und die Repräsentation der Muster kapseln zu können, wurde ALLPATLETS_OBJ erstellt. Das Objekt nimmt als Ausgangspunkt die Tabelle Attributes. Neben der Beschreibung der eigenen Attribute nutzt es auch die beiden fachlichen Objekte CATALOG_OBJ und HASATTR_OBJ. Es entsteht so ein View mit folgenden Attributen: ID (aus Attributes), name (aus Attributes), ID (aus Catalog), name (aus Catalog), choice (aus Catalog), domain (aus Catalog), pat_name (aus hasAttributes). Das fachliche Objekt ATTR_OBJ kapselt die Einfachklassen und die Information darüber, wie sie im Klassifikationssystem eingeordnet sind. Dafür benötigt es noch Fremdattribute aus CATALOG_OBJ. Es entsteht folgender View: ID (aus Attributes), name (aus Attributes), ID (aus Catalog), name (aus Catalog), domain (aus Catalog). Im Objekt CATALOG_OBJ ist die Information über Facetten und Bereiche enthalten. Es enthält nur Attribute aus der Tabelle Catalog: Entwurf 38 ID (aus Catalog), name (aus Catalog), choice (aus Catalog), domain (aus Catalog). In PATLET_OBJ sind sämtliche Informationen enthalten, die ein Patlet, so wie es in Kapitel 2.3.2 definiert ist, haben kann. Darin enthalten sind: Name (aus Patlet), content (aus Patlet), alternativeName (aus Patlet), source (aus Literature), source (aus Samples), source (aus Uses), pat_names (ContainsPatlet), pat_names (aus Variations), pat_names (aus Relations), pat_name (aus hasAttributes). Jedes dieser Attribute entspricht einem Schlüsselwort wie es für das Patlet in schriftlicher Form definiert wurde. Es wurde bereits in Abschnitt a) darauf eingegangen. In den Metadaten ist diese Beziehung festgehalten. Dort kann zu jedem Attribut der zugehörige Schlüsselwort-Name abgefragt werden. Wie schon erwähnt, ist es möglich einem fachlichen Objekt Regeln zuzuordnen. Für das Objekt PATLET_OBJ wurde das getan. Die Regel „CHANGE_TO“ schlüsselt die Beziehung zu den abhängigen Fremdtabellen auf. Konkret wurden die Beziehungen zu den Fremdtabellen ContainsPatlet, Relations, Variations, Uses, Samples, Literature und hasAttributes aufgeschlüsselt. Sie geben an, daß das Attribut pat_name der Fremdtabellen auf das Attribut name in Patlet referenziert. Dadurch ist es möglich, ein Patlet in der Datenbank zu löschen, ohne Kenntnis von den abhängigen Einträgen in den Fremdtabellen zu haben. Die praktische Umsetzung des generischen Löschens wird in Kapitel 5.2 Abschnitt a) beschrieben. Das Objekt COMMENT_OBJ speichert die Kommentare, die zu jedem Patlet verfaßt werden können. Es enthält nur Attribute aus der Tabelle Comments: ID (aus Comments), pat_name (aus Comments), title (aus Comments), author (aus Comments), content (aus Comments), refers_to (aus Comments), sent_date (aus Comments). c) Laden der Daten Wie bereits in Kapitel 2.3.1 erläutert, entspricht die Struktur des Klassifikationssystems der eines Baumes der Höhe vier. Durch die Repräsentation eines Musters durch das System entsteht ein Graph. Diese komplexen Strukturen werden durch SUMATRA nicht unterstützt. Es kann nur eine Liste von Objekten liefern, die in den Metadaten zusätzliche Informationen enthalten. Der Nutzen von Metadaten wird in Abschnitt b) näher erläutert. Aus diesem Grunde ist es notwendig, eine Schnittstelle zwischen SUMATRA und dem hier erstellten Programm zu schaffen. Dieser Teil kann nicht generisch gehalten werden. Er erfordert eine genaue Kenntnis über die fachlichen Objekte, wie sie von SUMATRA mit Hilfe der Metadaten generiert werden. Das gesamte Klassifikationssystem und die damit verbundenen Muster werden beim Start des Programms geladen. Die hierfür benötigten Informationen kapselt das fachliche Objekt ALLPATLETS_OBJ (Abschnitt b) ). Fachliche Objekte sind in SUMATRA über den Typ View (sumatra.container.View) verfügbar. Jeder View enthält den Namen des fachlichen Objekts. Über die den Attributen zugewiesenen Namen kann auf deren Werte zugegriffen werden. SUMATRA bietet einen Mechanismus, mit dem abstrakt Selektionskriterien ausgedrückt werden können. Dieser Mechanismus ist in der Klasse SelectData (sumatra.container.SelectData) gekapselt. Es lassen sich damit Selektionsanfragen konstruieren, die einer SQL select Anweisung für eine relationale Datenbank entspricht. Die Anfrage wird auf Serverseite in den entsprechenden SQL Dialekt der verwendeten Datenbank übersetzt. Als Ergebnis liefert SUMATRA ein ViewSet (sumatra.container.ViewSet), der die den Suchkriterien entsprechenden Views enthält. Der Inhalt eines Views entspricht einer Zeile eines Anfrageergebnisses, wie man es bei Datenbank ‚select‘ Anweisungen gewohnt ist. Um die gesamten Informationen über das Klassifikationssystem und die Repräsentation der Muster zu erhalten, wird eine Suchanfrage an den View ALLPATLETS_OBJ gestartet, die einem ‚select *‘ entspricht, wobei das Ergebnis in dieser Reihenfolge nach Bereich, Facette, Einfachklasse und Musternamen geordnet ist. In Tabelle 3 wird veranschaulicht, wie SUMATRA die angeforderten Daten liefert. Es ist ein Auszug aus den in [NIE99] entstandenen Daten. 39 Entwurf Bereich Facette Einfachklasse Muster Software Aufgabe Creational Builder Software Aufgabe Creational Factory Method Software Aufgabe Creational Independent Objects Aufgabe Structural Abstract Event Software Granularität Entwurfsmuster Abstract Event Software Granularität Entwurfsmuster Abstract Factory Software Granularität Architekturmuster Abstract Interface Software Granularität Architekturmuster Architecture Enforcement ... Software ... ... ... Tabelle 3: Form der von SUMATRA gelieferten Daten Abbildung 25: Objekte (im package parchie.objects) Aus der flachen Datenstruktur wird iterativ ein Baum generiert. Gleichzeitig entsteht auch ein Graph, der wiedergibt, wie die Muster repräsentiert werden. Für Bereich, Facette, Einfachklasse und Patlet wurden jeweils eine eigene Klasse geschaffen, um die speziellen Eigenschaften jeder dieser Typen festzuhalten. Es sind die Klassen Catalog (parchie.objects), Attribute (parchie.objects) und Patlet (parchie.objects). Catalog enthält den Bereich, den Namen der Facette und eine Menge von Patlets. In dieser Menge werden diejenigen Patlets gesammelt, die durch keine Einfachklasse in der Entwurf 40 betreffenden Facette repräsentiert werden. Anders ausgedrückt handelt es sich um die Patlets die in der Facette durch einen ‚*‘ repräsentiert werden (s. Kapitel 2.3.1). Attribute enthält den Namen der Einfachklasse und die Menge von Patlets, die durch diese Einfachklasse repräsentiert werden. Ein Patlet enthält seinen Namen und eine Liste von Attributen, die das Patlet repräsentieren. Abbildung 25 veranschaulicht die Zusammenhänge. Die Menge patlets in der Klasse Attribute enthält Zeiger auf Instanzen der Klasse Patlet. Umgekehrt enthält die Liste attributes in der Klasse Patlet Zeiger auf Instanzen der Klasse Attribute. Es existieren also keine mehrfachen Instanzen, sondern nur Verweise auf Objekte. Die Menge patlets ist eine invertierte Liste [Index, S. 36], mit deren Hilfe die Suche über das Klassifikationssystem realisiert wird. Für die Implementierung der Suche ist umgekehrt die Liste attributes in Patlet nicht nötig. Sie existiert lediglich, um dem Benutzer die Möglichkeit zu geben, abzufragen, durch welche Einfachklassen das Patlet repräsentiert wird. Um die Konsistenz der gegenseitigen Verzeigerung von Attributen (Einfachklassen) und Patlets zu garantieren, übernimmt nur jeweils eine Methode das Anlegen oder Löschen der Zeiger. In der Klasse Patlet wird beim Aufruf von addAttribute() auch gleichzeitig das entsprechende Attribute aktualisiert. Beim Aufruf der Methode deteachAllAttributes() werden alle Zeiger auf die entsprechenden Attribute gelöscht. Gleichzeitig werden die entsprechenden Attribute aktualisiert. Abbildung 25 zeigt die Details. Die Menge der patlets wird durch die Klasse ExtTreeSet (parchie.util) implementiert. Sie benutzt intern die vom JDK 1.2 zur Verfügung gestellte Klasse TreeSet (java.util). Die Implementation garantiert, daß die Kosten bei den Basisoperationen (Hinzufügen, Löschen und Abfrage der Existenz in der Menge) der Ordnung log(n) sind [TreeSet]. Der Aufbau der Baumstruktur wird in der Klasse ObjectBuilder realisiert (parchie.applmeta.AllObjects$ ObjectBuilder)11. Die darin implementierte Methode makeTree() generiert iterativ die Struktur. Sie erhält als Eingabe alle benötigten Daten, wie sie beispielhaft in Tabelle 3 dargestellt sind. Die Methode durchläuft die Daten zeilenweise. Jedesmal, wenn sich der Name des Bereiches, der Facette oder der Einfachklasse ändert, muß ein neuer Knoten in den Baum eingefügt werden. In Abbildung 26 ist der verwendete Algorithmus dargestellt. makeTree() { root = new Node(„Root“); foreach (Zeile) { if (Einfachklasse changes) { knode = new Node(Einfachklasse); if (Facette changes) { fnode = new Node(Facette); if (Domain changes) { dnode = new Node(Domain); root.addSon(dnode); } dnode.addSon(fnode); } fnode.addSon(knode); } } Abbildung 26: Pseudocode für die Generierung der Baumstruktur Gleichzeitig werden die zugehörigen Patlets erfaßt. Zum einen wird jedes Patlet in eine Menge eingefügt, die am Ende die gesamten Patlets enthält, zum anderen werden den Einfachklassen (Attribute) diejenigen Patlets zugewiesen, die durch sie repräsentiert sind. Weiterhin werden auch den Mit der Bezeichnung ‚class1$class2‘ wird die Klasse class2 als ‚inner class‘ von class1 spezifiziert. Die Bedeutung von inner classes kann in [icGuide] nachgelesen werden. 11 Entwurf 41 Facetten (Catalog) diejenigen Patlets zugewiesen, die durch keine Einfachklasse in dieser Facette repräsentiert werden (bzw. durch einen ‚*‘, wie er in Kapitel 2.3.1 eingeführt worden ist, repräsentiert werden). Dazu ist anzumerken, daß es kein Sonderzeichen geben soll, das diese Patlets kennzeichnet. Es wäre ja vorstellbar, daß ein Patlet, für die Facette beispielsweise den, in der Datenbank reservierten, Wert ‚UNDEF‘ erhält. Dies würde zwar das Suchen nach solchen Patlets erleichtern, hätte aber einen erhöhten Verwaltungsaufwand zur Folge, da es sich um eine überflüssige Information handelt: Ein Patlet, das in einer Facette undefiniert ist, wird in dieser Facette durch keinen Wert repräsentiert. Die Klassenbibliothek des JFC (Java Foundation Classes) stellt eine Baumstruktur zu Verfügung (javax.swing.tree.DefaultTreeModel). Sie wurde für den Aufbau des Baumes verwendet. d) Speicherplatz Selbstverständlich muß man sich darüber Gedanken machen, ob der Speicherplatz auf dem Rechner ausreicht, um alle Daten des Archivs auf einmal zu halten. Dazu wird im folgenden der benötigte Speicherplatz für die Objekte Attribute, Catalog und Patlet und die voraussichtliche Anzahl der Objekte berechnet. Das Objekt Attribute enthält einen String (den Namen) und einen TreeSet. TreeSet ist eine Menge von Zeigern auf andere Objekte. Er enthält alle Zeiger (engl. Pointer) auf Patlets, die durch das Attribut repräsentiert werden. 73 Muster, die im Laufe der Arbeit von [NIE99] entstanden sind, sind durch die Einfachklasse ‚Object‘ repräsentiert. Bei allen anderen Klassen sind es weniger Muster. Bei der Annahme, daß der Name des Attributs nicht länger als 256 Zeichen lang ist und daß maximal 500 Patlets durch dieses Attribut repräsentiert werden, errechnet sich der Speicherbedarf eines Attribute Objekts wie folgt, wobei davon ausgegangen wird, daß ein Zeiger 32 bit im Hauptspeicher belegt: 256 byte + 500 * 32 bit = 2265 byte Die Anzahl der Einfachklassen, die in der Arbeit von [NIE99] entstanden sind, beträgt 31. Das System ist zwar erweiterbar, es ist jedoch anzunehmen, daß die Anzahl der Einfachklassen auch im Laufe der Zeit überschaubar bleibt, um die Übersicht zu wahren. Es wird im folgenden angenommen, daß nicht mehr als 500 Einfachklassen in das System integriert werden. Damit ergibt sich für den insgesamt benötigten Speicherplatz der Attribute Objekte folgender Maximalwert: 500 * 2265 byte 1100 KB Das Objekt Catalog enthält zwei Strings und einen TreeSet. Der TreeSet enthält Zeiger auf alle „don’t care“ Patlets in diesem Catalog (Facette). In der in [NIE99] eingeführten Facette „sdm-Schichten“ gibt es 78 „don’t care“ Patlets. Bei den anderen Facetten sind es sogar weniger Muster. Bei der Annahme, daß die beiden Strings nicht länger als 256 Zeichen lang sind und daß maximal 500 Zeiger in TreeSet sind, errechnet sich der Speicherbedarf eines Catalogs wie folgt: 2* 256 byte + 500 * 32 bit 3 KB Die Anzahl der Facetten, die in [NIE99] entstanden sind, beträgt 5. Bei der Annahme, daß während der Lebensdauer des Systems nicht mehr als 20 Facetten in das Archiv integriert werden, ergibt sich für den insgesamt benötigten Speicherplatz für alle Cataloge folgender Wert: 20 * 3 KB = 60 KB Das Objekt Patlet enthält einen String (den Namen des Patlets) und eine Liste von Zeigern auf Attribute, die das Patlet repräsentieren. In [NIE99] wird das Muster ‚Independent Objects‘ durch 8 Einfachklassen repräsentiert. Alle anderen Muster werden durch weniger Klassen repräsentiert. Bei der Annahme, daß der String nicht länger als 256 Zeichen lang ist und daß maximal 30 Zeiger in der Liste sind, errechnet sich der Speicherbedarf eines Patlet Objekts wie folgt: 256 byte + 30 * 32 bit = 376 byte 42 Entwurf Es sind in [NIE99] 124 Patlets erstellt worden. Die Anzahl der weltweit verfügbaren Muster ist unüberschaubar. Einen Anhaltspunkt über die Gesamtzahl gibt die Linksammlung auf Muster, die im Laufe dieser Diplomarbeit erstellt wurde (s. Kapitel 2.1.2). Dort wurden 339 Verweise eingetragen. Geht man davon aus, daß nicht mehr als 3000 Muster während der Lebensdauer des Systems in das Archiv eingefügt werden, so errechnet sich der maximal benötigte Speicherplatz für alle Muster wie folgt: 3000 * 356 byte 1043 KB Die Summe des Speicherplatzes aller Objekte ist dann: 1100 KB + 60 KB + 1043 KB 2,1 MB Der zu allokierende Hauptspeicher für das Halten der Objekte ist also sehr gering. Selbst wenn das Applet auf einem, heutzutage als veraltet geltenden, Rechner mit nur 16 MB Hauptspeicher ausgeführt werden würde, stünde genügend Speicher zu Verfügung, um die gesamten Objekte der Klassifikation zu laden. 4.8 Suche Mit Hilfe der Klassifikation soll der Softwarearchitekt eine Menge von Mustern finden, die möglicherweise sein Problem lösen. Zu diesem Zweck kann er die Eigenschaften, die das Problem ausmachen, spezifizieren. Um dies zu tun, steht ihm eine Ansicht der Klassifikation zur Verfügung. Auf dieser Oberfläche sind die Einfachklassen in Facetten gruppiert, so wie es die Struktur der Klassifikation vorschreibt (Kapitel 2.3.1). Der Benutzer kann auf dieser Oberfläche Einfachklassen selektieren bzw. deselektieren. Durch jede weitere Selektion werden die Eigenschaften näher bestimmt, die die Muster haben sollen. Die Suchparameter stellen also die Einfachklassen dar, während die Ergebnismenge aus Mustern besteht, die durch diese Einfachklassen repräsentiert werden. Dem Benutzer wird die Möglichkeit gegeben, die logische Verknüpfung zwischen den Einfachklassen selbst zu wählen. Dabei kann er entscheiden, ob die Einfachklassen innerhalb einer Facette mit UND bzw. mit ODER verknüpft werden sollen. Dies ist nur möglich, wenn die Facette eine Liste ist, wie in Kapitel 2.3.1 beschrieben. Wenn die Facette eine Auswahl ist, kann nur höchstens eine Einfachklasse aus dieser Facette ausgewählt werden. Eine Verknüpfung ist dann also gar nicht möglich. Das bedeutet konkret: Sollen die Einfachklassen innerhalb einer Facette mit UND verknüpft werden, so heißt das, daß das zu findende Muster durch jedes der Einfachklassen repräsentiert sein soll. Wenn sie mit ODER verknüpft werden sollen, reicht es aus, wenn sie durch eine der ausgewählten Klassen repräsentiert werden. Dazu ein Beispiel: Das Muster ‚Architecture Enforcement‘ wird für den Bereich ‚Software‘ in [NIE99] folgendermaßen repräsentiert: <Architekturmuster, {Zugriffskontrolle, Verteilte Systeme, Middleware}, *, Structural, * >, wobei Granularität, Problemkat, Bereich, Aufgabe, sdm-Schichten die in dieser Reihenfolge zugörigen Facetten sind. Die hier verwendete Syntax kann in Kapitel 2.3.1 nachgelesen werden. Angenommen, der Benutzer wählt aus der Facette Problemkat die beiden Einfachklassen Zugriffskontrolle und Parallelität aus. Das Muster wird unter anderem durch Zugriffskontrolle klassifiziert, nicht jedoch durch Parallelität. Sollen nun die Einfachklassen innerhalb der Facette Problemkat mit ODER verknüpft werden, so genügt das Muster ‚Architecture Enforcement‘ den Anforderungen, weil eine Einfachklasse in der Repräsentation enthalten ist. Sollen die Einfachklassen innerhalb der Facette mit UND verknüpft werden, genügt das Muster nicht den Anforderungen, weil alle Muster gesucht werden, die sowohl durch Zugriffskontrolle als auch durch Parallelität repräsentiert werden. Wie werden aber die Bedingungen aus den einzelnen Facetten vereint ? Auch hier soll es dem Benutzer frei stehen, zwischen der logischen UND- oder ODER- Verknüpfung zu wählen. Ist die UND-Verknüpfung gewählt, so müssen alle Bedingungen aus den einzelnen 43 Entwurf Facetten erfüllt sein. Bei ODER genügt nur eine der Bedingungen. Die Verknüpfung innerhalb der Facette hat Priorität vor der Verknüpfung zwischen den Facetten. Dazu ein Beispiel: Seien A1, A2, ... Einfachklassen aus der Facette A und B1, B2, ... Einfachklassen aus der Facette B. Seien weiterhin M1, M2 Muster, die durch diese Facetten folgendermaßen repräsentiert sind: M1 = < A1, { B1, B2} > M2 = < {A1, A2}, B1 > Über die Benutzeroberfläche seien nun die Einfachklassen A1, B1 und B2 ausgewählt. Je nach Verknüpfung kommt man zu folgenden Mustern: A1 ( B1 B2 ) : M1 A1 ( B1 B2 ) : M1, M2 A1 ( B1 B2 ) : M1, M2 A1 ( B1 B2 ) : M1, M2 In den bisherigen Erläuterungen wurde das in Kapitel 2.3.1 eingeführte Element ‚*‘ außer Acht gelassen. Es steht für eine beliebige Einfachklasse in einer Facette. Das bedeutet, ein Muster, das durch ein ‚*‘ innerhalb einer Facette repräsentiert wird, gehört immer zur Ergebnismenge innerhalb dieser Facette. Dazu noch einmal das obige Beispiel: Die Repräsentation des Musters ‚Architecture Enforcement‘: <Architekturmuster, {Zugriffskontrolle, Verteilte Systeme, Middleware}, *, Structural, * >, wobei Granularität, Problemkat, Bereich, Aufgabe, sdm-Schichten die in dieser Reihenfolge zugehörigen Facetten sind. Angenommen, der Benutzer wählt aus der Facette sdm-Schichten die beiden Einfachklassen Fehlerbehandlung und Benutzerschnittstelle aus. Das Muster erfüllt auf jeden Fall die Bedingungen in dieser Facette, weil es durch ‚*‘ repräsentiert wird. Dabei spielt es keine Rolle, ob die Bedingungen mit UND oder mit ODER verknüpft werden sollen. Intern wird die Suche mit invertierten Listen [Index, S. 36] verwirklicht. Wie in Kapitel 4.7 beschrieben, sind bereits alle nötigen Informationen über das Archiv auf der Clientseite geladen. Die Informationen sind bereits so aufbereitet, daß für jede Facette eine Menge von Mustern ermittelt wurde, die in dieser Facette mit ‚*‘ repräsentiert werden. Außerdem ist jeder Einfachklasse eine Menge von Mustern zugeordnet. Die Menge enthält alle Muster, die durch diese Einfachklasse repräsentiert werden. Je nachdem, ob die UND- oder ODER-Verknüpfung gewählt ist, werden die Mengen vereinigt oder geschnitten. Seien Pat(Kij) alle Muster, die durch die Einfachklasse Ki in der j-ten Facette repräsentiert werden, mit i < mj, j < n und m, n . Und sei Facj die Menge aller Muster, die in der j-ten Facette durch einen ‚*‘ repräsentiert werden. Sollen die Bedingungen innerhalb der j-ten Facette mit UND verknüpft werden, ergibt sich folgendes: Dj = Pat( K ) Fac ij j i Bei einer ODER Verknüpfung: Dj = Pat( K ) Fac ij j i Sollen alle Bedingungen zutreffen, die Facetten also mit UND verknüpft werden, so ergibt sich D . j j Sind die Facetten mit ODER verknüpft, ist D j j die Ergebnismenge. 44 Entwurf 4.9 Ansicht eines Patlets Der Inhalt eines Patlets wird durch eine HTML Seite dargestellt. Die HTML Dateien werden bereits zum Zeitpunkt des Imports und nicht dynamisch zu dem Zeitpunkt, an dem sie angefordert werden, generiert. Durch diese Entwurfsentscheidung ist es dem Administrator des Webservers (engl. Webmaster) möglich, zusätzlich neben dem Suchwerkzeug auch eine HTML Seite anzubieten, die die Gesamtheit aller Patlets in HTML Form präsentiert und dem Anwender die Möglichkeit gibt, sich nur mit Hilfe eines Browsers eine Übersicht zu verschaffen. Der Anwender des Suchwerkzeuges hat die Möglichkeit, ein Patlet aus der Ergebnismenge anzusehen. Bei Selektion eines Patlets wird die entsprechende HTML Datei im Browser geladen, durch den das Suchapplet aufgerufen wurde. 4.10 Kommentare anlegen Die Funktionalität, die benötigt wird, um Kommentare verfassen und ansehen zu können, ähnelt sehr der Funktionalität, die ein Newsclient verwendet, um mit Newsgroups im Usenet kommunizieren zu können, so wie es das in Java geschriebene Programm ‚Newsagent‘ [NewsAgent] tut. Es unter der Gnu Public License [GPL] veröffentlicht. Teile des Codes wurden dem Programm entnommen und modifiziert und dazu genutzt, eine Oberfläche zu gestalten, die der einer Newsgroup entspricht und einen einfachen Editor bereit zu stellen, um Kommentare zu schreiben. Möchte der Benutzer zu einem bestimmten Patlet einen Kommentar schreiben oder andere Kommentare abrufen, so wird ein neues Fenster CommentFrame (parchie.comment.dialog) geöffnet. In diesem wird der ThreadTree (parchie.comment.dialog) und der MsgDisplayPanel (parchie.comment.dialog) dargestellt. ThreadTree gibt eine Übersicht über alle Kommentare die bisher zu dem Patlet geschrieben worden sind. Die Übersicht enthält den Titel, den Autor und das Datum jedes Kommentars, die im folgenden Kopfdaten genannt werden. Im MsgDisplayPanel soll der jeweilige Inhalt des im ThreadTree selektierten Kommentars angezeigt werden. Die Methode init() in CommentFrame initialisiert beim Start die Komponenten. Zunächst werden die Kopfdaten mit Hilfe von CommentProvider (parchie.comment.nntp) abgerufen. CommentProvider verfügt über Methoden, mit denen man Kommentare abrufen und speichern kann. Nun wird ThreadTree mit den Kopfdaten gefüllt. Gleichzeitig wird an ThreadTree der Listener ThreadTreeSelectionListener (parchie.comment.dialog. ThreadTree$ThreadTreeSelectionListener)12 gekoppelt. Er reagiert, wenn im ThreadTree ein neuer Kommentar selektiert wird. Er ruft dann mit Hilfe der Methode getBody() in der Klasse CommentProvider den Inhalt des Kommentars und stellt ihn im MsgDisplayPanel dar. Möchte der Anwender einen neuen Kommentar schreiben, so wird ein neues Fenster CommentComposer (parchie.comment.composer) geöffnet. Es enthält einen Editor, mit dem man seinen Kommentar verfassen kann. Zudem kann der Name des Autors und der Titel des Kommentars angegeben werden. Nach Beendigung werden die Informationen mit Hilfe der Methode postMessage() an den CommentProvider weitergeleitet, der seinerseits den Kommentar abspeichert. Der Editor kann ‚Kopieren‘, ‚Ausschneiden‘ und ‚Einfügen‘, wie man es von herkömmlichen Editoren kennt. Er besitzt außerdem eine ‚Undo‘ und ‚Redo‘ Funktion, die in der Klasse UndoHandler (parchie.comment.composer) gekapselt ist. All diese Aufgaben werden von der Java API unterstützt. In Abbildung 27 ist das zugehörige Klassendiagramm abgebildet. Statt mit einem Newsserver zu kommunizieren, kommuniziert CommentProvider mit dem SUMATRA Server. Es verwendet hierzu die Klasse CommentObject (parchie.applmeta), die als Schnittstelle zwischen dem Applet und dem Server fungiert. Mit der Bezeichnung ‚class1$class2‘ wird die Klasse class2 als ‚inner class‘ von class1 spezifiziert. Die Bedeutung von inner classes kann in [icGuide] nachgelesen werden. 12 Entwurf 45 Abbildung 27: Kommentare anlegen und abrufen 4.11 Patlet importieren Sowohl der Benutzer des Suchwerkzeuges als auch der Administrator hat die Möglichkeit, Patlets in Textform zu importieren. Dieser Text muß intern geparst werden, um mit den darin enthaltenen Informationenen entsprechend umgehen zu können. Er wurde mit Hilfe von Regulären Ausdrücken (engl. Regular Expressions) geparst. Regular Expressions sind nicht Bestandteil der JDK API (Application Interface). Es wurde die externe Bibliothek RegEx verwendet [JavaRegEx], die diese Funktionalität bietet. Das Importieren wird durch den Benutzer im Menü angestoßen. Ein Objekt der Klasse MenuController (parchie.control.admin, parchie.control.search) reagiert auf diesen Aufruf und ruft seinerseits die Methode importPatlet() in der Klasse ImportPatlet (parchie.control.admin, parchie.control.search) auf. Es existieren für das Suchwerkzeug und das Administrationsprogramm unterschiedliche Implementationen der Klassen MenuController und ImportPatlet. Da für den Administrator und den normalen Benutzer unterschiedliche Aktionen angeboten werden, ist es offensichtlich, daß auch das Menü Management unterschiedlich realisiert werden muß. Die Implementationen von ImportPatlet unterscheiden sich kaum: Während des Importierens wird geprüft, ob Bereich, Facetten und Einfachklassen, die das betreffende Patlet repräsentieren sollen, auch tatsächlich vorhanden sind. Fehlt entweder der Bereich, eine Facette oder eine Einfachklasse im Klassifikationssystem, so wird dem Administrator angeboten, diese sofort anzulegen. Tut er das, so kann das Importieren fortgesetzt werden. Ansonsten wird das Patlet als ungültig abgelehnt. Dem Benutzer des Suchwerkzeuges wird diese Option nicht gegeben. Kann das zu importierende Patlet nicht durch das momentan vorhandene System klassifiziert werden, so muß sich der Benutzer Entwurf 46 an den Administrator wenden, damit dieser dann das System entsprechend erweitert. Das Patlet wird nicht importiert. Die Methode parsePatlet() in PatletParser (parchie.applmeta.PatletParser) erhält als Eingabe den zu parsenden Text. Der Rückgabewert ist eine Hashtable, deren Schlüssel die jeweiligen Schlüsselwörter sind, die bei der Definition des Patlets festgelegt worden sind. Die Werte in der Hashtable entsprechen den Werten, die dem zu importierenden Patlet zugewiesen worden sind. Anschließend werden die Informationen in der Datenbank abgespeichert. Dazu wird die Methode insertWithReferences() in der Klasse PatletObject (parchie.applmeta.PatletObject) verwendet. Die Methode fügt die Werte der Schlüsselwörter des Patlets in Textform in die Haupttabelle von dem fachlichen Objekt PATLET_OBJ und alle ihre Fremdtabellen auf einmal ein. Zusätzlich wird eine HTML Datei angelegt, die den Inhalt des Patlets repräsentiert. Zu diesem Zweck wurde von Gianmarco Niedermeyr eine HTML Vorlage geschaffen, mit der das Layout der HTML Seite festgelegt wurde. Sie enthält selbst definierte Tags. Jeder dieser Tags entspricht einem PatletSchlüsselwort. In der Methode convertToHtml() in der Klasse PatletParser (parchie.applmeta.PatletParser) werden die Tags der Vorlage durch die Werte des geparsten Inhalts ersetzt. Zudem werden HTML Verweise auf andere Patlets innerhalb des Systems generiert, sofern eine Beziehung zu diesen Patlets angegeben ist. Einige Werte können auch externe HTML Verweise enthalten, das heißt Verweise, die auf eine HTML Seite außerhalb des Systems verweisen. Sie können bereits in der entsprechenden HTML Syntax als solche gekennzeichnet sein. In diesem Fall müssen sie nicht verändert werden. Es ist jedoch auch zulässig, lediglich die Adresse einer HTML Seite anzugeben. Die Adresse wird dann automatisch in einen Link umgewandelt. Abbildung 28 zeigt die beteiligten Klassen. Abbildung 28: Patlet importieren 4.12 Patlet exportieren Für die Suche und die Verwaltung des Archivs ist das Laden der gesamten Informationen der Patlets nicht erforderlich. Sowohl bei der Administration als auch bei dem Suchwerkzeug werden nur die Namen und die Repräsentation der Patlets geladen, da ja die eigentliche Ansicht des Patlets in einer HTML Seite betrachtet werden kann. Entwurf 47 Möchte der Anwender (des Such- oder Administrationswerkzeuges) alle Informationen des Patlets in einer Textdatei gespeichert haben, so müssen diese nachträglich aus der Datenbank ausgelesen werden. Danach werden sie entsprechend der Patletvorlage (s. Kapitel 2.3.2) in Textform umgewandelt. Nachdem der Anwender über den Filechooser den Namen der Patlet Textdatei ausgewählt hat, wird das Patlet gespeichert. Der lineare Vorgang ist in der Klasse SavePatlet (parchie.control) gekapselt. Von dort aus wird durch den Aufruf von getPatlet() in der Klasse PatletObject (parchie.applmeta) die Daten geladen. Diese werden dann in der Klasse PatletParser durch die Methode convertToText() konvertiert. Daraufhin wird der Anwender nach Namen und Pfad der zu speichernden Datei gefragt. Die geschieht durch den FileChooser (parchie.swing). Letztendlich wird diese durch die Methode write() in der Klasse FileUtils (parchie.utils) gespeichert. Die beteiligten Klassen sind noch einmal in Abbildung 29 festgehalten. Abbildung 29: Abspeichern eines Patlets in Textform 4.13 Beziehungen zwischen Patlets Die Definition eines Patlets erlaubt, Beziehungen zu anderen Patlets haben zu dürfen. Über die Schlüsselwörter CONTAINS und RELATIONS können solche Beziehungen ausgedrückt werden. Die gegenseitigen Verweise bilden einen Graphen. Im Programm selbst werden diese Beziehungen nicht visualisiert. Es ist auch keine Überprüfung der Konsistenz vorgesehen. So besteht die Gefahr, daß ein Patlet auf ein anderes verweist, dieses jedoch nicht in der Datenbank existiert. Der Administrator ist angehalten, diese Abhängigkeiten selbst zu prüfen. Durch die statische Erzeugung der HTML Dateien (s. Kapitel 4.9) können ungültige Referenzen entstehen, da die Beziehungen zwischen den Patlets durch HTML Verweise auf andere Patlets innerhalb des Archivs realisiert werden. Verweist ein Patlet auf ein anderes Patlet, das nicht existiert, so ist die Referenz nicht gültig. Es ist jedoch beim Importieren eines Patlets noch nicht bekannt, ob ein anderes Patlet, zu dem das importierte Patlet in Beziehung steht, zu einem späteren Zeitpunkt in das Archiv eingefügt werden wird, weshalb sich dieses Problem nicht vermeiden läßt. Die möglichen Inkonsistenzen haben ansonsten keine Auswirkung auf den Ablauf im Programm. Entwurf 48 4.14 Klassifikation anlegen Der Administrator kann die als Baum dargestellte Klassifikation anlegen und verändern. Konkret bedeutet dies, daß er Knoten im Baum anlegen kann bzw. bereits vorhandene Knoten löschen oder umbenennen kann. Für die Ansicht des Baumes wurde die Klasse ObjTree (parchie.gui) verwendet, die eine Erweiterung der Swing Klasse JTree (javax.swing) ist. Die eigentlichen Daten sind von der Ansicht getrennt in DefaultTreeModel (javax.swing.tree) abgelegt, wie es der Philosophie von MVC entspricht. Je nach Höhe des Knotens haben die oben beschriebenen Aktionen eine unterschiedliche Bedeutung. In Knoten der Ebene zwei sind die Bereiche gespeichert und werden lediglich als String (java.lang) repräsentiert. In den Knoten der Höhe drei befinden sich die Facetten. In ihnen werden die Objekte der Klasse Catalog (parchie.objects) gehalten. In Ebene vier sind die Einfachklassen gespeichert, die durch Attribute (parchie.object) repräsentiert werden. Die Ebene eins, in der nur der Vaterknoten vorhanden ist, hat keine Bedeutung und kann auch nicht interaktiv verändert werden. Je nachdem, welcher Knoten im Klassifikationsbaum markiert ist, werden nur bestimmte Aktionen zugelassen. Ist die Wurzel selektiert, so kann nur ein neuer ‚Bereichsknoten‘ erstellt werden. Möchte der Anwender dies tun, so erscheint ein Fenster, in das er den Namen des neuen Bereiches eingeben kann. Daraufhin wird ein neuer Bereich als Sohnknoten der Wurzel angelegt. Wenn ein Knoten der Höhe zwei selektiert ist (Bereich), so wird dem Anwender das Anlegen einer neuen Facette in dem Bereich angeboten. Wie beim Anlegen eines neuen Bereiches erscheint ein Fenster, in das der Anwender den Namen der Facette eingeben kann. Daraufhin wird ein Sohnknoten des selektierten Bereichs angelegt, der nun eine neue Facette in diesem Bereich darstellt. Gleichzeitig wird mit Hilfe der Klasse DomainCatalogObject (parchie.applmeta) Bereich und Facette in der Datenbank abgespeichert. Als weitere Option darf der Anwender den ‚Bereichsknoten‘ löschen, sofern dieser keine Söhne besitzt. Ein dritter Menüpunkt gestattet dem Anwender den Bereichsknoten zu editieren und ihm einen neuen Namen zu geben. Die Änderung wird sofort in der Datenbank mit Hilfe von DomainCatalogObject aktualisiert. Ist ein ‚Facettenknoten‘ markiert, kann der Anwender ebenfalls einen neuen Sohnknoten anlegen, den markierten Knoten löschen oder ihn umbenennen. Wenn die Facette gelöscht oder umbenannt wird, wird auch die Datenbank mit Hilfe von DomainCatalogObject sofort aktualisiert. Die Facette kann nur gelöscht werden, wenn sie keinen Sohnknoten bestitz. Mit dem Anlegen eines Sohnknotens entsteht eine neue Einfachklasse in der Facette. Mittels AttributeObject (parchie.applmeta) wird die Einfachklasse neu eingefügt. Als letzte Option kann der Anwender mittels einer Checkbox entscheiden, ob die markierte Facette eine ‚Auswahl‘ oder eine ‚Liste‘ (s. Kapitel 2.3.1) ist. Auch hier wird die Datenbank sofort aktualisiert. Einen Knoten, in dem eine Einfachklasse gehalten wird, kann man nur umbenennen oder löschen. Beides wird sofort mittels AttributeObject in der Datenbank dokumentiert. Das Löschen einer Einfachklasse ist nur dann möglich, wenn nicht ein Patlet durch sie repräsentiert wird. Da jedes Attribute die Menge von denjenigen Patlets hält, die durch sie repräsentiert werden, ist das leicht feststellbar. Zusammenfassend kann man sagen, daß jede Änderung in der Klassifikation zugleich eine Änderung des Datenmodells des Baumes (DefaultTreeModel) und der Datenbank nach sich ziehen, während sich die Ansicht des Baumes (JTree) selbständig aktualisiert. Das für den Anwender sichtbare Menü ändert sich je nachdem, welcher Knoten im Baum markiert ist. Der Listener TreeListener (parchie.control.admin.MenuController$TreeListener) 13 ist an die Ansicht des Baumes gekoppelt und generiert das dementsprechende Kontextmenü, sobald sich die Selektion ändert. Ein anderer Listener EditTreeAction (parchie.control.admin.MenuController$EditTreeAction) reagiert, wenn über das Menü ein Befehl ausgelöst wurde und führt dementsprechend die oben beschriebenen Aktionen aus. In Abbildung 30 findet man das zugehörige Klassendiagramm. Es enthält Pseudocode, der die Vorgänge verdeutlichen soll. Mit der Bezeichnung ‚class1$class2‘ wird die Klasse class2 als ‚inner class‘ von class1 spezifiziert. Die Bedeutung von inner classes kann in [icGuide] nachgelesen werden. 13 Entwurf 49 Abbildung 30: Klassifikation anlegen 4.15 Menüverwaltung Für die Menüverwaltung wurden Teile der externen Java Bibliothek Dubh Utils 1.0.1 genutzt [DubhUtils]. Es wird im folgenden erklärt, wie diese Bibliothek zu nutzen ist und wie sie funktioniert. Das Menü wird aus einer Ressourcen Datei konstruiert. Die Datei ist als Property, wie sie Java verwendet, abgespeichert und enthält Zuweisungen der Art ‚key = value‘. Das Format der Ressource wird im folgenden erklärt. Um etwa die Menüleiste des Kommentar Editors CommentComposer (parchie.comment.composer) zu definieren, steht folgendes in der Ressourcen Datei: mbComposer=file edit Wobei ‚file‘ und ‚edit‘ die Identifikatoren der Menüs sind. Sie werden dann genauer spezifiziert. Es werden die Identifikatoren der Menüpunkte, der Name des Menüs (text) und die Tastenkombination (mnemonic), mit der das Menü erreichbar ist (hier: Alt+B), bestimmt: edit=compCut compCopy compPaste - compUndo edit.text=Bearbeiten edit.mnemonic=B Letztendlich werden die einzelnen Menüpunkte selbst definiert: compCopy.text=Kopieren compCopy.toolTip=Kopieren compCopy.icon=images/copy.gif compCopy.mnemonic=o compCopy.accelerator=Ctrl+C Hier ist der Name (text), der Text des Tooltips (toolTip), der Pfad des Bildes, das in der Werkzeugleiste (engl. Toolbar) erscheinen soll (icon), der mnemonic (mnemonic) und die direkte Tastenkombination (accelerator) angegeben. Entwurf 50 Zusätzlich kann, wie schon erwähnt, eine Werkzeugleiste mit ausgewählten Menüpunkten definiert werden: toolbar=copy paste Sämtliche Menüs der Applets werden so in der Ressource Menus.properties im Unterverzeichnis parchie/environment festgelegt. Die Implementation der Aktionen der Menüpunkte übernehmen Methoden einer bestimmten Klasse. So übernimmt etwa CommentComposer die Ausführung sämtlicher Menüpunkte des Kommentareditors. Die Methoden müssen den gleichen Namen haben wie die Identifikatoren der Menüpunkte. Es sind dort also die Methoden compCut(), compCopy(), compPaste() und compUndo() implementiert. Abbildung 31: Menüverwaltung Üblicherweise werden Listener an die einzelnen Menüpunkte gebunden, die dann bei Aktivierung des Menüpunktes aufgerufen werden. Die Kopplung der Listener wird durch die Bibliothek Dubh Utils verborgen, obwohl intern Objekte instanziiert werden, die an die einzelnen Menüpunkte angebunden sind. Die dahintersteckende Vorgehensweise wird im folgenden erklärt: Mit Hilfe der Klasse JMenuBarResource (parchie.utils.dubh.ui) wird aus der Ressourcen Datei das Menü automatisch generiert. Bei Instanziierung wird die Klasse, die durch Methoden, die die Menüpunkte implementiert, als Parameter übergeben. Nun wird jedem Menüpunkt eine Instanz des Listeners DubhAction (parchie.utils.dubh.ui) zugewiesen. Dort wird mit Hilfe des Reflection Mechanismus festgestellt, ob die Methode, die bei Aktivierung des Menüpunktes aufgerufen werden soll, tatsächlich implementiert ist. Ist sie es nicht, so wird der betreffende Menüpunkt deaktiviert (engl. disabled), ansonsten wird die Methode an die Instanz von DubhAction gekoppelt. Wird der Listener während der Laufzeit durch die Aktivierung eines Menüpunktes aufgerufen, leitet er den Aufruf an diese Methode weiter. 51 Entwurf In Abbildung 31 sind die Zusammenhänge der beschriebenen Klassen dargestellt. Für die Menüs in den Fenstern des Suchapplets, der Kommentarübersicht und des Kommentareditors wurde dieses Prinzip verwendet. Die Methoden für die Menüpunkte sind jeweils in den Klassen MenuController (parchie.control.search.MenuController), CommentFrame (parchie.comment.dialog) und CommentComposer (parchie.comment.composer) definiert. Da sich beim Administrationsapplet das Menü dynamisch ändert, konnte die Bibliothek Dubh Utils hier nicht angewendet werden. Es wurden mit der herkömmlichen Methode Listener direkt an die Menüpunkte gekoppelt (s. Kapitel 4.14). Auch hier werden aber die Namen der Menüpunkte aus der Ressourcen Datei ausgelesen. 4.16 Meldungen an den Benutzer Alle Texte, die für den Benutzer sichtbar sind, werden als externe Ressourcen ausgelagert. Somit sind die Benutzermeldungen und Menüpunkte mit dem Programm nicht fest verdrahtet. Alle Texte sind mit einem Namen identifiziert. Mit Hilfe dieser Identifikation ist es möglich, auf den Text zuzugreifen und darzustellen. Die Java API unterstützt diesen Vorgang [i18nTut]. Die externen Ressourcen werden Properties genannt und haben nach Java Konvention die Endung ‚.properties‘. Sie sind im package parchie.environment abgelegt. Die Klasse PA_Environment (parchie.environment.PA_Environment) stellt die statischen Methoden getResString(), getMenuText() und getImage() zur Verfügung. Mit deren Hilfe können Benutzermeldungen, Menüpunkte und die Lage der Bilder abgefragt werden, die zur Laufzeit in dem Programm dargestellt werden sollen. Die Klasse PA_Environment kapselt alle Java API spezifischen Vorgänge, die benötigt werden, um die Informationen aus den Properties zu erhalten. Die Java API bietet die Möglichkeit, die Texte der Properties zu parametrisieren. Dies eröffnet die Möglichkeit, Texte erst zur Laufzeit zu vervollständigen. Beispielsweise wird so aus der Property countPatlets = Es wurden {0} Patlets gefunden die Benutzermeldung „Es wurden 12 Patlets gefunden“ zur Laufzeit generiert. Nach Java Konvention bezeichnet ‚{0}‘ einen Platzhalter in einer Property. Der Weg, das Programm in eine andere Sprache zu übersetzen, ist damit geebnet. Es müssen lediglich die entsprechenden Property Dateien übersetzt werden. Die Unterscheidung nach Sprache funktioniert über die Namenskonvention der Property Dateien. Eine Datei mit deutschem Inhalt etwa sollte den Namen ‚name_de_DE.properties‘ haben, eine Datei mit englischem Inhalt den Namen ‚name_en_EN.properties‘, wobei ‚name‘ der Name der Property ist. Im Laufe der Entwicklung des Archivprogramms sind die drei Properties Strings_de_DE.properties, Menus_de_DE.properties und Images_de_DE.properties entstanden, die die Benutzermeldungen, Menüpunkte und die Lage der, vom Programm genutzten, Bilder beinhalten. 52 5 Implementierung Während der Realisierung des Systems ist Quellcode entstanden, der auch außerhalb dieses Systems in anderen Programmen wiederverwendet werden könnte. Das folgende Kapitel 5.1 beschreibt ‚Java-Tricks‘, während Kapitel 5.2 Erweiterungen des SUMATRA Frameworks erläutert. 5.1 Erweiterungen von JFC Bei der Entwicklung des Programms wurden einige Begrenzungen der Klassenbibliothek JFC offenbar. Mit gewissen Erweiterungen an den entsprechenden Klassen konnten sie umgangen werden. Es entstanden dadurch allgemeingültige ‚Java-Tricks‘, die im folgenden beschrieben werden. Diese Codefragmente können auch für andere Projekte von Nutzen sein. Es wurden deshalb zwei Artikel auf [CodeGuru] veröffentlicht, die den Code und eine kurze englische Beschreibung beinhalten. a) Beliebige Selektion in einer Tabelle Die Facetten und deren Einfachklassen sollten mit Hilfe einer Tabelle dargestellt werden, da damit eine gute Übersicht gewährleistet ist. Dabei stellen die Spalten die jeweiligen Facetten dar und die Zellen in einer Spalte die zugehörigen Klassen. Wie in der Analyse in Kapitel 3.2.1 festgelegt, soll der Benutzer durch Auswählen der Klassen die Eigenschaften der gesuchten Muster festlegen. Er muß also in der Lage sein, beliebig viele voneinander unabhängige Zellen selektieren zu können. JFC bietet bereits eine Klasse JTable an. Sie übernimmt die Darstellung einer Tabelle. Auch ein Selektionsmechanismus ist bereits implementiert. Informationen über die aktuelle Selektion werden in zwei ListSelectionModels (javax.swing) gespeichert. Das eine, in der Dokumentation als ‚rowSelection‘ bezeichnete, Modell wird in der Klasse JTable selbst gehalten, das andere Modell, als ‚columnSelection‘ bezeichnet, befindet sich in der Klasse DefaultTableColumnModel (javax.swing.table). Das ListSelectionModel dient ursprünglich dazu, die Selektion einer Liste zu speichern. Das ‚Row Selection Model‘ deckt die Selektion aller Zeilen ab. Das ‚Column Selection Model‘ kann die Selection auf bestimmte Spalten einschränken oder ausweiten. Dieses Konzept macht es unmöglich, die Selektion beliebig vieler voneinander unabhängiger Zellen zu behalten. Es war daher nötig ein eigenes Selektions Modell zu implementieren, das dazu in der Lage ist. Das Selektions Modell TableSelectionModel (parchie.swing) hält für jede Spalte in der Tabelle ein eigenes ListSelectionModel. Es ist dadurch garantiert, daß alle Selektionen gespeichert und wiedergegeben werden können. Um das TableSelectionModel aktuell zu halten, wurde die Klasse BasicTableUI (javax.swing.plaf.basic) mit der Klasse ExtTableUI (parchie.swing) überschrieben. In der Methode createMouseInputListener() legt die Klasse BasicTableUI fest, welche Klasse als Listener auf Mausklicks des Benutzers reagieren soll. Sie wurde überschrieben, um einen eigenen Listener ExtMouseInputHandler (parchie.swing.ExtTableUI$ExtMouseInputHandler) zu instanziieren, der das TableSelectionModel entsprechend aktualisiert. Bei der Implementierung wurden die JFC API Konventionen eingehalten. In der JFC ist es üblich, für jedes Modell auch einen entsprechenden Listener zu Verfügung zu stellen, der benachrichtigt wird, wenn sich das Modell ändert. Eine Nachricht ist in Java immer in Events verpackt die sich alle von der Klasse EventObject (java.util.EventObject) ableiten. Deshalb wurde eigens für das TableSelectionModel ein TableSelectionListener (parchie.swing.TableSelectionModel) und ein TableSelectionEvent (parchie.swing.TableSelectionEvent) implementiert. Letztlich mußte auch die standard JTable mit der Klasse ExtJTable (parchie.swing.ExtJTable) überschrieben werden. Sie sorgt dafür, daß ExtTableUI nun die UI der Tabelle ist. Zudem generiert sie eine Instanz von TableSelectionModel und interpretiert die darin enthaltenen Informationen entsprechend. Abbildung 32 zeigt die Zusammenhänge der Klassen. Einige technische Details sollen im folgenden ausgeführt werden: Um die Klassen in ein anderes Projekt einzubauen, wäre es nicht nötig, Kenntnis von diesen Details zu haben. Sie sollen trotzdem nicht verborgen bleiben: Die Klasse TableSelectionModel implementiert die drei Interfaces PropertyChangeListener (java.beans), TableModelListener (javax.swing.event) und ListSelectionListener (javax.swing.event). Implementierung 53 TableSelectionModel ist an die Klasse ExtJTable als PropertyChangeListener gebunden, um benachrichtigt zu werden, wenn ExtJTable ein neues TableModel bekommt. Dies ist nötig, weil TableSelectionModel genauso viele ListSelectionModels halten muß, wie es Spalten in der Tabelle gibt. Falls das TableModel für die Tabelle wechselt, könnte auch die Anzahl der Spalten wechseln. TableSelectionModel paßt die Anzahl seiner ListSelectionModels an die Anzahl der Spalten an. Sie ist weiterhin als TableModelListener an das aktuelle TableModel gebunden, um benachrichtigt zu werden, wenn sich das aktuelle TableModel verändert hat. Sollte sich die Anzahl der Spalten des TableModel geändert haben, so paßt sich TableSelectionModel an. Als ListSelectionListener ist die Klasse TableSelectionModel an seine eigenen ListSelectionModels gebunden. Sie wird also selbst benachrichtigt, wenn sie durch ihre eigenen Methoden addSelection(), clearSelection(), usw. die Selektion an den ListSelectionModels selbst verändert. Sobald das TableSelectionModel ein solches Ereignis (ListSelectionEvent) empfangen hat, feuert es selbst ein TableSelectionEvent. Dabei werden die Informationen des ListSelectionEvents in das TableSelectionEvent übertragen. Durch diesen Ansatz erspart man sich die Mühe die Informationen, die durch das ListSelectionEvent geliefert werden, selbst zu errechnen. Zudem ist garantiert, daß bei jeder Veränderung der Selektion auch ein TableSelectionEvent an die Listener gefeuert wird. Der Quellcode wurde auf [TableSel99] veröffentlicht. Er enthält einen Verweis auf die Lehr- und Forschungseinheit für Programmierung und Softwaretechnik der Ludwig-Maximilians-Universität München und die Firma sd&m. Abbildung 32: Klassendiagramm im package parchie.swing b) Checkbox in der Titelleiste einer Tabelle Bei der Suche nach Mustern kann der Benutzer entscheiden, ob die selektierten Einfachklassen innerhalb einer Facette mit dem logischen UND oder ODER verknüpft werden sollen, sofern die Facette eine Mehrfachauswahl von Klassen zuläßt (Kapitel ‚Struktur der Klassifikation‘). Für so eine Auswahl eignen sich Checkboxen, die der Benutzer selektieren bzw. deselektieren kann. Für jede Facette (sofern die Mehrfachauswahl in ihr erlaubt ist) muß genau eine Checkbox existieren. Implementierung 54 Die Darstellung der Facetten und deren Einfachklassen ist mit Hilfe einer Tabelle realisiert. Jede Spalte stellt eine Facette dar. Im Titel der Spalte steht der Name der Facette. In den Zellen der jeweiligen Spalte sind die zugehörigen Klassen angesiedelt. Wo könnte die Checkbox besser angesiedelt sein als in der Titelleiste der jeweiligen Spalte ? Leider ist es nicht ohne weiteres möglich, eine Checkbox in die Titelleiste einzubauen. Zwar gibt es die Möglichkeit, jede beliebige Komponente der Titelleiste zuzuweisen; es werden jedoch standardmäßig keine Ereignisse an die Komponente weitergeleitet. Insbesondere empfängt also die entsprechende Komponente auch keine Mausereignisse. Eine Checkbox, die zwar in der Titelleiste sichtbar ist, ihren Zustand aber bei einem Mausklick nicht ändert, wäre sinnlos. Die Lösung des Problems besteht darin, einen Listener an die Titelleiste zu binden. Sobald dieser ein Ereignis empfängt, ändert er den Zustand der Checkbox. Zu diesem Zweck wurde ein eigener TableCellRenderer (javax.swing.table) implementiert. Java stellt dieses Interface dem Programmierer zu Verfügung, um das Aussehen und das Verhalten der Titelleiste selbst gestalten zu können. Mit der Methode setHeaderRenderer() der Klasse TableColumn kann dann dem Titel der jeweiligen Spalte ein solcher Renderer zugewiesen werden. Der hier implementierte Renderer HeaderCellRenderer (parchie.gui) leitet sich von JCheckBox (javax.swing) ab und implementiert gleichzeitig einen MouseListener (java.awt.event). Weil er eine Checkbox ist, kann von außen ein ItemListener (java.awt.event) an ihn gebunden werden, der benachrichtigt wird, wenn sich der Zustand der Checkbox ändert. Intern empfängt der HeaderCellRenderer Mausereignisse und ändert entsprechend den Zustand der Checkbox. Der Auszug des Quellcodes in Abbildung 33 vermittelt die wichtigsten Prinzipien. public class CheckBoxHeader extends JCheckBox implements TableCellRenderer, MouseListener { //implementiert TableCellRenderer public Component getTableCellRendererComponent(...) { ... JTableHeader header = table.getTableHeader(); //‘this‘ ist MouseListener header.addMouseListener(this); return this; } //implementiert MouseListener public void mouseClicked(MouseEvent e) { ... //JCheckBox Methode: doClick(); } } Abbildung 33: Auszug aus dem Quellcode der Klasse CheckBoxHeader Der Quellcode wurde auf [TableHea99] veröffentlicht. Er enthält einen Verweis auf die Lehr- und Forschungseinheit für Programmierung und Softwaretechnik der Ludwig-Maximilians-Universität München und die Firma sd&m. c) Erweiterung des JFileChoosers Dem Benutzer ist die Möglichkeit gegeben, Patlets in Form von Textdateien in das Archiv zu importieren. Die Lage der Textdatei zu bestimmen, sollte dem Benutzer so leicht wie möglich gemacht werden. Es ist üblich, über einen Filechooser die Dateien auszuwählen zu lassen, die das Programm verarbeiten soll. Die Klassenbibliothek des JFC bietet den JFileChooser (javax.swing) an, mit dem man bequem Dateien auswählen kann. In [NIE99] sind 124 Patlets in Form von Textdateien entstanden. Möchte der Administrator das Archiv neu aufbauen und alle Patlets importieren, so wäre es wünschenswert, dies in einem Schritt zu tun und alle Textdateien auf einmal auswählen zu können. Laut Dokumentation von Java sollte man mit der Methode getSelectedFiles() in der Klasse JFileChooser einfach die ausgewählten Dateien abfragen können. In der aktuellen Version des JDK 1.2.2 gibt diese Methode leider nur den Namen der ersten Datei, anstatt die Namen aller Implementierung 55 ausgewählten Dateien, zurück. Die Dokumentation [JavaTut] behauptet, die Methode sei nicht implementiert. Um trotzdem diese wichtige Funktionalität nutzen zu können, wurden die betreffenden Klassen erweitert. Ein Einblick in den Quellcode von JFileChooser ergab, daß die Methode getSelectedFiles() sehr wohl implementiert ist. Jedoch ist intern eine Variable nicht gesetzt, die die ausgewählten Dateien enthalten sollte. Mit der Methode setSelectedFiles() im JFileChooser kann man diese Variable belegen. Die Methode muß also aufgerufen werden, sobald der Benutzer eine oder mehrere Dateien auswählt. Ähnlich wie in Abschnitt a) wurde zu diesem Zweck die UI des JFileChoosers erweitert. Die Klasse MetalFileChooserUI_ (parchie.swing) erweitert die ursprüngliche MetalFileChooserUI (javax.swing. plaf.metal) und installiert den Listener FileSelectionListener (parchie.swing. MetalFileChooserUI_$ FileSelectionListener). Dieser reagiert, wenn eine Datei selektiert wird und ruft setSelectedFiles() auf. Um dem JFileChooser die neue UI zuzuweisen, wurde die Methode getUIClassID() überschrieben. Es wird dort intern dem UIManager (javax.swing.UIManager) mitgeteilt, daß diese Klasse seine eigene UI verwendet. Es sei an dieser Stelle auf die Artikel „A Swing Architecture Overview“ [SwingArch], „The process of installing a UI delegate“ [Uidelegate] und „The 'LookandFeel' Class Reference“ [LAFCR] verwiesen, die sich eingehend mit dem komplizierten Thema des ‚Pluggable Look and Feel‘ beschäftigen. Abbildung 34 zeigt das Klassendiagramm der beteiligten Klassen. Abbildung 34: Erweiterung des JFileChoosers im package parchie.swing Es soll nicht verschwiegen werden, daß durch diesen Ansatz die Möglichkeit verloren geht, das ‚Look and Feel‘ zur Laufzeit zu ändern, wie das in der Klassenbibliothek des JFC vorgesehen ist. Der FileChooser ist nun fest an das ‚Metal Look and Feel‘ (bezeichnet als ‚Java L&F‘ [JavaLAF]) gebunden. Da das hier implementierte Archivprogramm fest auf das ‚Java L&F‘ eingestellt ist, kann das Problem in diesem Kontext vernachlässigt werden. d) Mehrzeiliger Tooltip Manche Tooltips können sehr viel Text beinhalten, so daß es wünschenswert wäre, wenn der Tooltip über mehrere Zeilen dargestellt werden könnte. Diese Funktionalität ist jedoch in JFC nicht vorgesehen. Für das Zeichnen des Tooltips ist die korrespondierende UI verantwortlich. Um einen mehrzeiligen Tooltip darzustellen, muß also eine eigene erweiterte UI an die Klasse JToolTip (javax.swing) gebunden werden. Die Klasse JMultiLineToolTip (parchie.swing) erbt von JToolTip. Sie installiert die neue UI MultiLineToolTipUI (parchie.swing). MultiLineToolTipUI überschreibt die Methode paint(), um einen eigenen Tooltip zeichnen zu können. Der Quellcode von JMultiLineToolTip und MultiLineToolTipUI wurde von [MultTT] übernommen. Er enthält lediglich geringe Modifikationen in der Methode getPreferredSize() der Klasse MultiLineToolTipUI. Sie bewirken, daß der für den Tooltip bestimmten Text automatisch formatiert Implementierung 56 wird, so daß Zeilenumbrüche selbst vorgenommen werden. Dazu wurde eine JTextArea (javax.swing) verwendet, die als Unterlage für den Tooltip dient. Wenn der Text des Tooltips eine bestimmte Länge überschreitet, wird der automatische Zeilenumbruch des JTextArea eingeschaltet. In Abbildung 35 zeigen sich die Zusammenhänge der Klassen. Abbildung 35: JMultiLineToolTip im package parchie.swing 5.2 Erweiterungen von SUMATRA Um bestimmte Funktionalitäten zu erlangen, die bisher in SUMATRA noch nicht implementiert waren, mußte der Quellcode von SUMATRA an einigen Stellen modifiziert werden. Die wichtigsten Änderungen werden im folgenden beschrieben. a) Generisches Löschen Mit Hilfe der Metadaten können in SUMATRA fachliche Objekte aus den Attributen von Datenbanktabellen zusammengesetzt werden. Mit diesen kann dann auf der Server und Client Seite gearbeitet werden. SUMATRA unterstützt dabei die Abfrage und Darstellung der Inhalte. Es wäre auch wünschenswert, die fachlichen Objekte als Ganzes einfügen oder löschen zu können, was jedoch von SUMATRA nicht direkt unterstützt wird. Ein fachliches Objekt setzt sich aus den Attributen einer Haupttabelle und aus Attributen von Fremdtabellen zusammen. Die Fremdattribute sind in der Regel von den Einträgen in der Haupttabelle referenziell abhängig. Das bedeutet, solange eine Ausprägung in einer Fremdtabelle auf einen Eintrag in der Haupttabelle referenziert, kann der Eintrag in der Haupttabelle nicht gelöscht werden. Umgekehrt kann man nicht eine neue Ausprägung in einer Fremdtabelle, die auf einen Eintrag in der Haupttabelle referenziert, anlegen, solange der Eintrag in der Haupttabelle nicht existiert. Bei der Beschreibung der Metadaten ist es möglich, derartige Abhängigkeiten wiederzugeben. Sie werden mit Hilfe der Regel CHANGE_TO beschrieben. Die Regel wurde konkret für das fachliche Objekt PATLET_OBJ eingesetzt. Es wurde bereits in Kapitel 4.7, Abschnitt b), besprochen. Das Löschen eines fachlichen Objektes als Ganzes kann durch diese Regel realisiert werden. Es wurde in der Methode deleteWithReferences() in der Klasse DialogObject (parchie.applmeta) implementiert. Die Methode erhält als Eingabe die Schlüsselattribute der Haupttabelle. Mit Hilfe der Regel CHANGE_TO können die Einträge der Fremdtabellen festgegestellt werden. Dieser Vorgang wird rekursiv wiederholt, bis keine Abhängigkeiten mehr vorhanden sind. Dann wird der entsprechende Eintrag gelöscht. Auf diese Weise, werden alle relevanten Einträge in den Fremdtabellen gelöscht, bevor die Einträge in der Haupttabelle gelöscht werden. Implementierung 57 Abbildung 36 zeigt das Prinzip des Algorithmus. Obwohl der dort abgebildete Code der Java Syntax nachempfunden ist, handelt es sich doch nur um Pseudocode, der zum Verständnis des Algorithmus beitragen soll. Der dort verwendete Typ View (sumatra.container) ist ein von SUMATRA verwendeter Behälter für die Inhalte von fachlichen Objekten. Mit der von SUMATRA zur Verfügung gestellten Methode getChangeDefaults() in der Klasse DialogImpl (sumatra.control) ist es möglich, die durch die Regel CHANGE_TO spezifizierten Attribute zu ermitteln. Das generische Löschen funktioniert bei jedem fachlichen Objekt. Wird die Datenbankstruktur verändert und die Metadaten entsprechend modifiziert, so muß der Quellcode im Programm nicht geändert werden. deleteWithReferences(View view) { //Attribute im View, die abhängig von diesem View sind, //werden über die Regel CHANGE_TO ermittelt changeDefaults = getChangeDefaults(view); for all (changeDefaults) c { //abhängige Einträge in den Fremdtabellen View foreignView = getViewSet(c); //rekursiver Aufruf deleteWithReferences(foreignView); } //tatsächliches Löschen delete(view); } Abbildung 36: Algorithmus für das Löschen eines fachliches Objektes b) Auto-Insert von Ids Manche Datenbanken machen es zur Bedingung, daß eine Tabelle einen numerischen Wert als Primärschlüssel besitzt, sofern für diese ein Index erstellt werden soll. Dies ist auch der Grund, weshalb fast alle Tabellen in der vorliegenden Arbeit einen numerischen Primärschlüssel besitzen. Die meisten von ihnen haben sonst keine Bedeutung. Es macht daher Sinn, diese Zahlen beim Einfügen eines Datensatzes automatisch generieren zu lassen. SUMATRA selbst bietet diese Funktionalität nicht an. Deshalb wurde sie für die vorliegende Arbeit implementiert. Es wurden zu diesem Zweck die Klassen der Datenbankschicht von SUMATRA erweitert und teilweise modifiziert. Es handelt sich um die Klassen ViewFactoryServer (sumatra.persist), QueryBroker (sumatra.persist), QueryBrokerImpl (sumatra.persist) und SQLBuilder (sumatra.persist). In ViewFactoryServer wurde die Methode insert() modifiziert. Anstatt den übergebenen View sofort an die Datenbank zu schicken, wird zunächst jedes Attribut geprüft, ob es ein numerisches Schlüsselattribut ist und ob diesem noch kein Wert zugewiesen worden ist. Ist dies der Fall, so bekommt das Attribut einen noch nicht belegten Wert. Für die Berechnung des Wertes wird die Methode selectMaxPlus1() aufgerufen, die wiederum selectMax() verwendet. Die Methode selectMax() läßt zunächst einen SQL String von der Methode buildSQLmaxValue() in SQLBuilder generieren, der den Maximalwert aller für dieses Attribut eingefügten Werte ermitteln soll. Dieser wird dann ausgeführt und das Ergebnis abgefragt. Es wird dann letztendlich an die Methode insert() weitergeleietet. Die Aufteilung der unterschiedlichen Aufgabengebiete entspricht den Konventionen von SUMATRA.. Das Klassendiagramm in Abbildung 37 zeigt die Zusammenhänge der beteiligten Klassen. Implementierung 58 Abbildung 37: Klassendiagramm aus dem package sumatra.persist c) Escape Zeichen für SQL Strings Strings, die in eine Datenbank eingefügt werden sollen und die einfache Anführungsstriche (‘) beinhalten, müssen vorher modifziert werden. Der Datenbank muß durch ein spezielles Zeichen vermittelt werden, daß die Anführungsstriche zu dem einzufügenden String dazu gehören und nicht den Anfang oder das Ende eines Strings kennzeichnen. Man nennt dieses spezielle Zeichen ‚Escape Zeichen‘. Es wird vor den Anführungsstrich gesetzt. In der Klasse SQLBuilder (sumatra.persist), in der die SQL Strings, wie sie letztendlich an die Datenbank geschickt werden, generiert werden, geschieht eine solche Erweiterung der Strings nicht. Die Klasse wurde daher um die Methode convert2DBString(), erweitert um diese Aufgabe zu übernehmen. Sie wurde an allen Stellen im SQLBuilder, an denen ein Anführungsstrich auftauchen könnte, eingesetzt. d) Umleitung der Fehlerausgabe SUMATRA bietet in der Klasse Log (sumatra.util) Methoden zur formatierten Ausgabe von Fehlermeldungen an. Die Ausgabe erfolgt nach StdErr (Datenstrom ‚Standard Error‘). Durch die hinzugekommene Methode redirect() kann der Strom optional auch in eine Protokolldatei erfolgen. Der Name der Datei kann in der Konfigurationsdatei von SUMATRA benannt werden (s. Kapitel 7.4). Alle Ausgaben im Quellcode, die nach StdOut (Datenstrom ‚Standard Out‘) oder StdErr gingen, wurden durch die entsprechenden Methoden aus der Klasse Log ersetzt. e) Fehlerbehebung von SUMATRA Die für diese Diplomarbeit übergebene SUMATRA Version (Version 990122) war nicht von Anfang an lauffähig. Es mußten einige Veränderungen vorgenommen werden. Sie sind im folgenden stichpunktartig aufgeführt: In der Methode getDataManagement() der Klasse sumatra.environment.ServerEnvironment wurde die Zeile obj = new DataManagementImpl(qualifier); durch obj = new DataManagementDefaultImpl(qualifier); Implementierung 59 ersetzt. Der ursprüngliche Code führte zu einem Laufzeitfehler. In der Methode getViewFactory() der Klasse sumatra.applmeta.Table wurde versucht, eine neue Instanz von sumatra.environment.ViewFactoryServerDefaultImpl herzustellen. Dies mißlang, da nur innerhalb des Packages auf diese Klasse zugriffen werden durfte. Die Klasse sumatra.environment. ViewFactoryServerDefaultImpl und deren Konstruktor wurde deshalb mit ‚public‘ deklariert. In der Klasse sumatra.environment.Environment gibt es eine String Variable ‚ClassDialogManager‘, in der der Name der Klasse steht, die das Interface sumatra.control.DialogManager implementiert. Die Idee dabei war es, erst zur Laufzeit den Namen dieser Klasse zu lesen und auf Anforderung eine Instanz der Klasse zu generieren. Die Methode createDialogManager() sollte dies übernehmen, was sie nicht tat. Mit Hilfe des Reflection Mechanismus von Java (java.lang.reflect) wurde dies nachgeholt. In der Klasse sumatra.container.ViewSetImpl wurde die Methode elementAt() verändert: in der ‚for‘ Schleife wurde die Zeile if (viewData[i] == null) viewData[i] = ""; hinzugefügt, da sonst in der darauffolgenden Zeile eine NullpointerException geworfen wird, wenn die Variable viewData[i] immer noch den Wert ‚null‘ hat. f) Geringfügige Änderungen An vielen Stellen im Code wurden kleine Modifikationen vorgenommen, die meistens der Fehlersuche dienten. So ist beispielsweise die Methode toString() in der Klasse SelectData, WhereData, WhereDataEntry und ViewSetImpl (sumatra.container) hinzugekommen die lediglich für eine formatierte Textausgabe der Inhalte der Objekte sorgen. Weiterhin wurden Ausgaben nach STDERR hinzugefügt, die sich jedoch durch eine boolean Variable ausschalten lassen. Alle Änderungen wurden direkt im Quellcode mit dem Kommentar ‚//MODIFIED !‘ dokumentiert. 60 6 Bedienungsanleitung 6.1 Das Suchwerkzeug Das Suchwerkzeug verfügt über eine Vielzahl von Interaktionsmöglichkeiten. Sie werden im folgenden beschrieben. Das Menü: 1. ‚Dialog‘ 1. ‚Aktualisieren‘ Lädt den aktuellen Stand der Datenbank und stellt ihn dar. 2. ‚Beenden‘ beendet das Applet. 2. ‚Aktionen‘ 1. ‚Zeige zugehörige Muster‘ Die dem zuletzt selektierten Attribut zugehörigen Muster werden angezeigt. Dies geschieht durch Selektion der entsprechenden Muster in der Musterliste. Dabei ist zu beachten, daß durch die Auswahl im Katalog möglicherweise nicht alle Muster angezeigt werden. Es können somit nur diejenigen Muster selektiert werden, die sich zu diesem Zeitpunkt in der Liste befinden. 2. ‚Alle zugehörigen Muster zeigen...‘ Die dem zuletzt selektierten Attribut zugehörigen Muster werden angezeigt. Dies geschieht durch ein eigenes Fenster, in dem die Muster aufgelistet werden. 3. ‚Alle zugehörigen Attribute zeigen‘ Die dem zuletzt selektierten Muster zugehörigen Attribute werden angezeigt. Dies geschieht durch ein eigenes Fenster, in dem die Attribute aufgelistet werden. 4. ‚Kommentare...‘ Öffnet ein neues Fenster, in dem die Möglichkeit besteht, Kommentare zu dem zuletzt selektierten Muster zu schreiben. 5. ‚Patlet abspeichern...‘ Öffnet einen Filedialog, mit dem man auswählen kann, wo und unter welchem Namen das zuletzt selektierte Muster abgespeichert werden soll. 6. ‚Patlet importieren...‘ Öffnet einen Filedialog mit dem man auswählen kann, welche Patlet Datei importiert werden soll. Die Rechte für das Importieren im Such Applet sind eingeschränkt. Falls das Patlet Attribute enthält, die sich nicht im Katalog befinden, so kann das Patlet nicht importiert werden. Änderungen am Katalog kann nur der Administrator vornehmen. Ansicht der Klassifikation: Die Klassifikation entspricht der Struktur eines Baumes der Tiefe 4. Die Darstellung der Klassifikation spiegelt diese Struktur wieder, obwohl sie nicht direkt einen Baum darstellt. Die imaginäre Wurzel des Baumes ist unwichtig und wird nicht dargestellt. Die Ebene 1 des Kataloges entspricht dem Bereich, dem ein Muster zugeordnet werden kann, z.B. ‚Software‘. Diese Ebene wird als Reiter dargestellt. Die zweite Ebene entspricht den Facetten, die in dieser Klassifikation enthalten sind. Die Ebene 3 entspricht den in den Facetten enthaltenen Einfachklassen. Ebene 2 und 3 werden als Tabelle dargestellt. Die Spalten in der Tabelle stellen die Facetten dar. Jede Zelle in der Tabelle stellt eine Einfachklasse dar. Folgende Optionen werden dem Benutzer angeboten: 1. Wechseln zwischen den Bereichen: Durch einen Mausklick auf den entsprechenden Reiter wechselt man zu dem gewünschten Bereich. 2. Suche über die Einfachklassen: Durch die Auswahl einer oder mehrerer Einfachklassen bestimmt der Benutzer seine Suche. Das Ergebnis dieser Suche ist eine Liste von Mustern, die sich bei der Auswahl sofort aktualisiert. Zudem kann die Auswahl der logischen Verknüpfungen innerhalb einer Facette bestimmt werden: Bedienungsanleitung 61 Durch Klicken auf den Kopf einer Spalte kann ausgewählt werden, ob die Einfachklassen mit dem logischen UND oder ODER verknüpft werden sollen. Eine Änderung bewirkt eine Neuberechnung der Ergebnismenge. Eine Unterscheidung zwischen UND und ODER ist nur möglich, wenn die entsprechende Facette eine ‚Liste‘ ist (siehe Kapitel 2.3.1). Auch die Auswahl der logischen Verknüpfung zwischen den Facetten kann geändert werden. Durch Auswahl einer Checkbox kann bestimmt werden, ob bei der Suche die Facetten mit dem logischen UND oder ODER verknüpft werden sollen. Eine Änderung bewirkt eine Neuberechnung der Ergebnismenge. 3. Durch einen ‚Rechts Klick‘ auf eine Zelle öffnet sich ein Popupmenü, das die Punkte ‚Zeige zugehörige Patlets‘ und ‚Alle zugehörigen Patlets zeigen...‘ enthält. Die beiden Punkte wurden bereits besprochen. Liste der Muster: Sie stellt das Ergebnis der Suche dar, die sich durch die Auswahl der Einfachklassen ergeben hat. Folgende Optionen werden dem Benutzer angeboten: 1. Ansicht des Patlets: Durch Selektion eines Musters wird im Browserfenster das entsprechende Patlet geladen. Abbildung 38 zeigt beispielhaft die Darstellung des Patlets ‚Action Object‘. 2. Untermenü: Durch einen ‚Rechts Klick‘ auf einen Listeneintrag öffnet sich ein Untermenü, das die Menüpunkte ‚Alle zugehörigen Patlets zeigen...‘, ‚Kommentare...‘ und ‚Patlet abspeichern...‘ enthält. Die Punkte sind bereits weiter oben besprochen worden. Abbildung 38: Screenshot eines Patlets in HTML Form Die Statusbar: Sie stellt einige nützliche Informationen für den Benutzer bereit: Bedienungsanleitung 62 1. Die Statuszeile informiert den Benutzer darüber, welche Aktion gerade ausgeführt wird. 2. Eine weitere Anzeige informiert über die momentane Anzahl der Muster in der Liste. Abbildung 39 zeigt einen Screenshot des Suchwerkzeugs. Sie zeigt zudem die beiden Fenster, die die gegenseitigen Abhängigkeiten von Einfachklassen und Mustern darstellen. Abbildung 39: Screenshot des Suchwerkzeugs Die Kommentare zu einem Muster werden in einem eigenen Fenster verwaltet. Es gibt, ähnlich wie in einem Newsgroup Client, in der oberen Hälfte eine Übersicht über alle geschriebenen Kommentare. Durch Selektion eines Kommentars wird der Inhalt abgerufen und in der unteren Hälfte des Fensters dargestellt. Im Menü sind folgende Punkte verfügbar: 1. ‚Dialog‘ Enthält nur den Menüpunkt ‚Schließen‘. 2. ‚Kommentare...‘ Dieses Menü enthält folgenden Menüpunkte: 1. ‚Aktualisieren‘ Lädt alle Kommentare neu. 2. ‚neuer Kommentar...‘ Ein Editor Fenster öffnet sich, in dem man einen neuen Kommentar anlegen kann. 3. ‚auf Kommentar antworten...‘ Ein Editor Fenster öffnet sich, in dem man auf den selektierten Kommentar antworten kann. Abbildung 40 zeigt einen Screenshot der Kommentarübersicht. Bedienungsanleitung 63 Abbildung 40: Übersicht der Kommentare zu dem Muster "Agent" In einem eigenen Editor kann ein neuer Kommentar verfaßt werden. In dem Feld ‚From‘ kann der Name des Autors angegeben werden. Das Feld ‚Subject‘ gibt dem Kommentar einen Titel. Der größte Teil des Editors ist ein Textfeld, in dem der Kommentar geschrieben werden kann. Im Menü sind folgende Punkte verfügbar: 1. ‚Kommentar‘ Er enthält folgende Menüpunkte: 1. ‚Abschicken‘ Speichert den neu geschriebenen Kommentar. 2. ‚Abbrechen‘ Schließt den Editor. Der Kommentar wurde verworfen. 2. ‚Bearbeiten‘ Dieses Menü enthält die klassische Editorfunkttionalität: 1. ‚Ausschneiden‘ Verschiebt den selektierten Text in die Zwischenablage. 2. ‚Kopieren‘ Kopiert den selektierten Text in die Zwischenablage. 3. ‚Einfügen‘ Kopiert den Inhalt der Zwischenablage an die Stelle, an der sich der Textcursor befindet. 4. ‚Undo action‘ Macht die letzte Aktion action rückgängig. 5. ‚Redo action‘ Wiederholt die durch ‚Redo‘ rückgängig gemachte Aktion action. Abbildung 41 zeigt einen Screenshot des Editors. Bedienungsanleitung 64 Abbildung 41: Editor für Kommentare 6.2 Das Administrationswerkzeug Auch das Administrationswerkzeug gibt seinem Benutzer verschiedene Interaktionsmöglichkeiten, die alle über das Menü verfügbar gemacht wurden: 1. ‚Dialog‘ 1. ‚Aktualisieren‘ Lädt den aktuellen Stand der Datenbank und stellt ihn dar. 2. ‚Beenden‘ beendet das Applet 2. ‚Administration‘ 1. Untermenü ‚Klassifikation editieren‘ Dieses Untermenü ist kontextabhängig und hängt von dem momentan selektierten Knoten im Klassifikationsbaum ab. 1. Ist die Wurzel selektiert, so ist ein Unterpunkt anwählbar: ‚Neuer Bereich‘ Es öffnet ein Fenster, in dem man den Namen des neuen Bereiches eintragen kann. 2. Ist ein Bereich selektiert, so sind folgende Unterpunkte anwählbar: ‚Neue Facette‘ Es öffnet sich ein Fenster, in dem man den Namen der neuen Facette eintragen kann. Die neue Facette ist dem selektierten Bereich zugeordnet. ‚Bereich editieren‘ Es wird dem Benutzer die Möglichkeit gegeben, den Namen des Bereiches zu ändern. ‚Bereich löschen‘ Der Bereich wird gelöscht, sofern das möglich ist. Ein Bereich kann nur gelöscht werden, wenn er keine Facetten enthält. 3. Ist eine Facette selektiert, so sind folgende Unterpunkte anwählbar: ‚Neue Einfachklasse‘ Es öffnet sich ein Fenster, in dem man den Namen der neuen Einfachklasse eintragen kann. Die neue Einfachklasse ist der selektierten Facette zugeordnet. Bedienungsanleitung 65 ‚Facette editieren‘ Es wird dem Benutzer die Möglichkeit gegeben, den Namen der Facette zu ändern. ‚Facette löschen‘ Die Facette wird gelöscht, sofern das möglich ist. Eine Facette kann nur gelöscht werden, wenn sie keine Einfachklasse enthält. ‚Auswahl‘ Hier kann mittels einer Checkbox entschieden werden, ob die Facette eine ‚Auswahl‘ oder eine ‚Liste‘ ist. Die beiden Begriffe sind in Kapitel 2.3.1 eingeführt worden. Ist die Checkbox angewählt, so ist die Facette eine Liste. 4. Ist eine Einfachklasse selektiert, so sind folgende Unterpunkte anwählbar: ‚Einfachklasse editieren‘ Es wird dem Benutzer die Möglichkeit gegeben, den Namen der Einfachklasse zu ändern. ‚ Einfachklasse löschen‘ Die Einfachklasse wird gelöscht, sofern das möglich ist. Eine Einfachklasse kann nur gelöscht werden, wenn sie keinen Muster zugewiesen ist. ‚Zeige zugehörige Muster‘ Alle Muster in der Liste der Muster werden selektiert, sofern das Attribut den jeweiligen Muster zugeordnet ist. 5. Untermenü ‚Muster editieren‘ ‚Patlet importieren...‘ Öffnet einen Filedialog, mit dem man auswählen kann, welche Patlet Datei importiert werden soll. Es können auch mehrere Patlets auf einmal importiert werden. Während des Importvorgangs wird geprüft, ob das Patlet dem spezifizierten Format entspricht. Sollte das nicht der Fall sein, so kann das Patlet nicht importiert werden. Der Administrator erhält eine Fehlermeldung. Sollte entweder ein Bereich, eine Facette oder eine Einfachklasse in der Klassifikation des Patlets vorkommen, die noch nicht in der Datenbank ist, so wird der Administrator gefragt, ob der entsprechende Eintrag in der Datenbank ergänzt werden soll. Bestätigt er die Ergänzung, so kann der Import fortgesetzt werden, andernfalls wird das Patlet nicht aktzeptiert. ‚Patlet exportieren...‘ Öffnet einen Filedialog mit dem man auswählen kann, wo und unter welchem Namen das zuletzt selektierte Muster abgespeichert werden soll. ‚Patlet löschen...‘ Entfernt alle selektierten Patlets in der Datenbank. ‚Zeige zugehörige Einfachklassen‘ Alle Einfachklassen im Klassifikationsbaum, die dem Patlet zugeordnet sind, werden selektiert. Der Klassifikationsbaum: Darstellung der Klassifikation der Muster als Baum. Bei ‚Rechts Klick‘ auf einen Knoten öffnet sich ein Untermenü, das jeweils dem oben besprochenen Kontextmenü entspricht. Liste der Patlets: Auflistung aller Muster in der Datenbank. Bei ‚Rechts Klick‘ auf einen Listeneintrag öffnet sich ein Untermenü, das dem oben besprochenen Menüpunkt ‚Muster editieren‘ entspricht. Statusbar: Die Statusbar wurde bereits beim Suchwerkzeug besprochen. Bedienungsanleitung In Abbildung 42 ist ein Screenshot des Applets abgebildet. Abbildung 42: Screenshot des Administrationswerkzeugs 66 67 7 Installation Das Archivprogramm wurde mit JDK 1.2.2 entwickelt und unter Windows NT 4.0, Service Pack 3 getestet. Die Arbeit umfaßt eine Applikation (engl. application) und zwei Applets. Ein Applet ist das Suchwerkzeug, das dem Benutzer bei der Suche nach nützlichen Mustern helfen soll. Das andere Applet dient zur Administration des Archivs. Um die Applets im Browser ausführen zu können, wird das von Sun Microsystems zu Verfügung gestellte Plug-in benötigt. 7.1 Arbeitsumgebung Um die geeignete Umgebung, die zur Installation und Ausführung der Programme benötigt wird, zu erschaffen, werden folgende externe Programme benötigt: Java 2 SDK v1.2.2 Windows 95/98/NT Production Release (im folgenden als JDK bezeichnet) Homepage: http://java.sun.com/ Download: http://java.sun.com/products/jdk/1.2/download-windows.html Die Lizenz Bestimmungen von Sun Microsystems [JDK12Lic] lassen es nicht zu, das Programm auf CDROM mitzuliefern. Java 2 Runtime Environment Windows 95/98/NT Production Release (im folgenden als JRE bezeichnet) Homepage: http://java.sun.com/ Download: http://java.sun.com/products/jdk/1.2/jre/download-windows.html CDROM: tools\jre1_2_2-win.exe Während der Installation des JRE wird auch das Plug-in 1.2.2 installiert. Cygwin 32 (GNU Utilities für Windows 95/98/NT 4.0) Homepage: http://sourceware.cygnus.com/cygwin/ Download: ftp://ftp.franken.de/pub/win32/develop/gnuwin32/cygwin/mirrors/cygnus/cygwinb20/full.exe CDROM: tools\cygwin32-20.1.exe falls die Installation unter Win 32 erfolgen soll. Für UNIX Systeme ist es nicht nötig. ActivePerl Build 519 Homepage: http://www.activestate.com/ Download: http://www.activestate.com/ActivePerl/download.htm#complete CDROM: tools\APi519e.exe JavaCC (Java Compiler Compiler) Homepage: http://www.metamata.com/ Download: http://www.metamata.com/javacc/ CDROM: tools\JavaCC1_1.class JavaTM Plug-in 1.2 HTML Converter Homepage: http://java.sun.com/ Download: http://java.sun.com/products/plugin/1.2/converter.html CDROM: tools\htmlconv12.zip Webserver Der verwendete Webserver ist beliebig. Das Archiv wurde mit dem Internet Information Server (IIS) und dem Apache Webserver (http://www.apache.org/) unter Windows NT 4.0, Service Pack 3 getestet. Datenbank SUMATRA unterstützt eine Vielzahl von relationalen Datenbanken. Darunter sind MS Access, DB2, AdabasD, Oracle 8 und MSSQL Server 6.5. Getestet wurde das Archiv mit dem MSSQL Server 6.5 und Oracle 8. JDBC-Treiber Ein JDBC-Treiber für die installierte Datenbank wird benötigt. Auf der CDROM befindet sich aus lizenzrechtlichen Gründen kein Treiber für den MSSQL Server 6.5, es ist jedoch eine Liste von JDBC-Treibern ist auf http://java.sun.com/products/jdbc/drivers.html zu finden. Der MSSQL Server wurde mit dem JDBC-Treiber von der Firma i-net software getestet. Er steht auf http://www.inetsoftware.de/ zum Download bereit. Für Oracle 8 wird der „JDBC-Thin driver for use with JDK 1.2“ benötigt. Installation 68 download: http://technet.oracle.com/software/utilities.htm CDROM: src\Resources\classes\classes111.zip 7.2 Installationsschritte Die Beschreibung der Installation umfaßt alle Schritte, die getan werden müssen, um ein lauffähiges System zu erhalten. Es werden dabei nicht alle Konfigurationsmöglichkeiten besprochen, sondern nur diejenigen die unbedingt nötig sind. Eine vollständige Beschreibung der Einstellungsmöglichkeiten erfolgt in den darauffolgenden Abschnitten. Folgende Schritte müssen ausgeführt werden. Sie beschreiben die Installation unter Windows NT 4.0. 1. JDK installieren jdk1_2_2-win.exe‘ (JDK) aufrufen. Zur Unterstützung der Installation erscheint eine Oberfläche, die den Benutzer durch die einzelnen Installationsschritte führt. Es wird angenommen, daß das JDK in das Verzeichnis D:\Programme\jdk-1.2.2 installiert wurde. 2. GNU Utilities installieren ‚cygwin32-20.1.exe‘ (tools\cygwin32-20.1.exe) aufrufen. Zur Unterstützung der Installation erscheint eine Oberfläche, die den Benutzer durch die einzelnen Installationsschritte führt. Es wird angenommen, daß das Programm in das Verzeichnis D:\Programme\cygnus installiert wurde. Nach der Installation muß die nun installierte Shell ‚bash‘ aufgerufen werden. Dies geschieht über die Startleiste: ‚Start\Programme\Cygnus Solutions\Cygwin B20‘. Ein Fenster mit Kommandozeile erscheint. Dort müssen folgende Kommandos ausgeführt werden: 1. 2. 3. cd / mkdir /tmp mount D:\\Temp /tmp (es wird angenommen, daß D:\Temp bereits existiert und zur Zwischenspeicherung von temporären Dateien dient) 4. mkdir /bin 5. mount D:\\Programme\\cygnus\\cygwin-b20\\H-i586-cygwin32\\bin /bin 6. exit (mit diesem Kommando verläßt man die Shell) 3. Perl installieren ‚APi519e.exe‘ (tools\APi519e.exe) aufrufen. Zur Unterstützung der Installation erscheint eine Oberfläche, die den Benutzer durch die einzelnen Installationsschritte führt. Es wird im folgenden angenommen, daß perl.exe im Suchpfad des Betriebssystems eingebunden ist (was durch die Installation geschehen sein sollte). 4. Webserver installieren Die Wahl des Webservers ist beliebig. Während der Entwicklung wurde das System mit dem IIS (Internet Information Server) und Apache Webserver getestet. Es ist keine spezielle Konfiguration nötig. Im folgenden wird angenommen, daß das Wurzelverzeichnis des Servers in D:\InetPub\wwwroot liegt, wie es der Standard des IIS vorschlägt. Das Unterverzeichnis D:\InetPub\wwwroot\PatternsArchive sollte eingerichtet werden, in das später das Archivprogramm kopiert wird. Der Name des Rechners soll www.webserver.de lauten. 5. Datenbank Management System installieren Das Archiv wurde mit den beiden Datenbank Management Systemen (DBMS) Oracle 8 für Windows NT und dem MSSQL Server 6.5 für Windows NT getestet. Die Installation kann auf einem beliebigen Rechner stattfinden. Er sollte innerhalb des Intranets von dem Rechner, auf dem der Webserver installiert ist, über das Netzwerk Protokoll TCP/IP erreichbar sein. Zudem muß das DBMS TCP/IP unterstützen. Im folgenden wird angenommen, daß das DBMS auf dem Rechner database.de (192.168.0.1) installiert wurde und auf dem Port 1521 erreichbar ist. Adresse und Port entsprechen dem bei der Firma sd&m bereits eingerichteten DBMS Oracle 8. 6. Datenbank einrichten Installation 69 Nach erfolgreicher Installation des DBMS sollten eine neue Datenbank und ein neuer Benutzer angelegt werden. Im folgenden wird angenommen, daß für Oracle ein Benutzer mit dem Namen scott und dem Paßwort tiger eingerichtet ist und für diesen Platz in der Datenbank angelegt wurde. Für den MSSQL Server soll angenommen werden, daß der Benutzer Sa mit leerem Paßwort angelegt und zudem eine Datenbank mit dem Namen Parchie eingerichtet ist. Das Anlegen der Tabellen übernehmen die in SQL verfaßten Skripte ‚Parchie-SumatraMSSQL6x.sql‘ (src\Resources\data\Parchie-Sumatra-MSSQL6x.sql) und ‚Parchie-SumatraOracle8.sql‘ (src\Resources\data\Parchie-Sumatra-Oracle8.sql). Achtung: Alle neu anzulegenden Tabellen werden dabei gelöscht, falls diese bereits existieren. 7. Plug-in Das Java Plug-in 1.2.2 ist im JRE (tools\jre1_2_2-win.exe) integriert. Es sollte über den Webserver erreichbar sein. Es wird empfohlen, ein neues Verzeichnis D:\InetPub\wwwroot\Plugin\ anzulegen und die Datei ‚jre1_2_2-win.exe‘ dorthin zu kopieren. Es muß außerdem eine HTML Datei existieren, die mit einem Hyperlink auf die Datei verweist. Es wird empfohlen, die Datei ‚.\Resources\HtmlFiles\plugin12-install.html‘ (CDROM: src\Resources\HtmlFiles\plugin12install.html) in das gleiche Verzeichnis zu kopieren. Das JRE muß nicht installiert werden. Mit den Schritten 1-7 wurden die Voraussetzungen für die Laufzeitumgebung geschaffen. Im folgenden wird auf die Konfigurationsmöglichkeiten eingegangen. Dazu wird angenommen, daß das Quellverzeichnis (src) nach D:\proj\PatternsArchive\src\ kopiert wurde. Alle Verzeichnisangaben sind relativ zu diesem neu angelegten Verzeichnis zu sehen, sofern es sich nicht um einen absoluten Pfad handelt. 8. JDBC-Treiber kopieren Im folgenden wird davon ausgegangen, daß sich ein JDBC-Treiber für die installierte Datenbank mit dem Namen classes111.zip in ‚.\Resources\classes\‘ befindet. Sollte die installierte Datenbank Oracle 8 sein, so befindet sich der Treiber bereits an seinem Platz. 9. HTML Converter konfigurieren Die Datei ‚.\bin\htmlconv12\converter.props‘ editieren. Dort wird festgelegt, unter welcher Adresse das Plug-in zu erreichen ist. Zwei Einträge müssen geändert werden: converter.plugin.loc=http\://www.webserver.de/Plugin/plugin12-install.html und converter.cab.file.loc=http\://www.webserver.de/Plugin/jre1_2_2-win.exe\#Version\=1,2,2,0 10. Konfigurationsdatei von SUMATRA Die Konfigurationsdatei des Servers von SUMATRA muß der Umgebung angepaßt werden. Hierzu die Datei ‚.\Resources\default.conf‘ editieren. Die Datei enthält etliche Parameter. Die meisten davon müssen nicht geändert werden. Allgemein müssen folgende Werte angepaßt werden: ACCESSFILE=http://www.webserver.de/PatternsArchive/Rescources/access/access.html SERVER_URL=http://www.webserver.de/PatternsArchive/ Für Oracle 8 und den MSSQL Server ergeben sich unterschiedliche Werte, die hier beide besprochen werden. Jeder Parameter muß in einer einzigen Zeile definiert sein. Die beiden Parameter DBDRIVER und DBURL hängen vom verwendeten JDBC-Treiber ab. Die jeweilige Syntax muß in der Dokumentation des Treibers nachgelesen werden. 1. Oracle 8: DBNAME=Adabas DBDRIVER=oracle.jdbc.driver.OracleDriver DBURL=jdbc:oracle:thin:scott/tiger@(description=(address_list=(address=(protocol=tcp)(host =192.168.0.1)(port=1521))(address=(protocol=tcp)(host=192.168.0.1)(port=1522)))(source_r oute=yes)(connect_data=(sid=orc1))) DBUSER=scott DBPASSWD=tiger 2. MSSQL Server 6.5: DBNAME=Default DBDRIVER=com.inet.tds.TdsDriver Installation 70 DBURL=jdbc:inetdae:database.de:1522?database=Parchie DBUSER=Sa DBPASSWD= 11. Applet Parameter In der Datei ‚.\Resources\AppletParameters.txt‘ muß die URL des SUMATRA Servers angepaßt werden: <PARAM NAME = "ServerUrlExternal" VALUE="http://www.webserver.de:1999/Parchie"> <PARAM NAME = "ServerUrlInternal" VALUE="http://www.webserver.de:1999/Parchie"> 12. Applet Sicherheit In der Datei ‚.\ Resources\Security\.java.policy‘ muß der Name des Webservers angepaßt werden: grant codeBase "http://www.webserver.de/PatternsArchive/Parchie.jar" { und grant codeBase "http://www.webserver.de/PatternsArchive/" { 13. Startskript Die Datei ‚.\Resources\RootFiles\_startServer122.bat‘ editieren. Es muß der Pfad des JDK angepaßt werden: set JHOME=D:\Programme\jdk1.2.2\ Zusätzlich muß der Pfad geändert werden, in dem sich der Server befinden wird: cd D:\InetPub\wwwroot\PatternsArchive Sollte der Name des JDBC-Treibers nicht, wie oben angenommen, classes111.zip sein, so muß auch dies angepaßt werden: set JDBC=.\Resources\classes\dateiNamedesTreibers.zip 14. Übersetzen Für die Übersetzung des Quell Codes wurde ein Makefile entwickelt, das diesen Vorgang automatisiert. Es übernimmt zudem die Generierung aller zusätzlich benötigten Dateien. Bevor das Makefile benutzt wird, muß noch der Pfad des JDK angepaßt werden. Hierzu ist die Datei ‚.\MAKEFILE‘ zu editieren und folgende Zeilen verändern: JAVA_HOME12=D:\\Programme\\jdk1.2.2 Zudem muß das Verzeichnis ..\bin (D:\proj\PatternsArchive\bin) angelegt werden. Danach in der Kommandozeile der bash (siehe Schritt 2) folgenden Befehle ausführen: 1. cd D:\\proj\\PatternsArchive\\src 2. make everything 15. Server starten Nach der Übersetzung sind die ausführbaren Dateien nun in D:\proj\PatternsArchive\bin. Von dort aus sollten sie in das Verzeichnis D:\InetPub\wwwroot\PatternsArchive kopiert werden. Der Aufruf von ‚_startServer12-jar.bat‘ startet den Server. 16. Applets starten Die beiden Applets sind nun auf ‚http://www.webserver.de/PatternsArchive/Parchie-jar-plugin.html‘ (Suche) und ‚http://www.webserver.de/PatternsArchive/Parchie-Admin-jar-plugin.html‘ (Administration) erreichbar. Die Willkommensseite ‚http://www.webserver.de/PatternsArchive/index.html‘ verweist auf die beiden Dokumente. Jeder Benutzer, der Zugang zu dem Webserver hat und den Netscape 4.5 oder höher oder den Internet Explorer 4 oder höher verwendet, kann das Archiv nun nutzen. Sollte das Java Plug-in 1.2.2 noch nicht auf dem Rechner des Benutzers installiert sein, so wird der Benutzer beim ersten Aufruf der Applets automatisch dazu aufgefordert, dies nachzuholen und auf die URL des Plug-ins verwiesen. Nach dem Herunterladen und Installieren des Plug-ins können die Applets ausgeführt werden. Bei jedem weiteren Aufruf der Applets schaltet sich dann das Plug-in automatisch ein. Um die Applets fehlerfrei ausführen zu können, muß der Benutzer vor dem Laden die unter ‚http://www.webserver.de/Resoucres/Security/.java.policy‘ erreichbare Datei in sein Homeverzeichnis kopieren. Unter Windows 95/98 ist das Homeverzeichnis üblicherweise ‚C:\Windows‘, unter Windows NT ist es ‚C:\WINNT\Profiles\USERNAME‘, wobei USERNAME für den Login Installation 71 Namen des Benutzers steht. Unter UNIX Systemen ist das Homeverzeichnis üblicherweise unter /home/USERNAME zu finden. 7.3 Das Makefile Für die Automatisierung bestimmter Vorgänge wurde ein Makefile entwickelt. Es entspricht der GNU make Syntax und wurde unter Cygnus GNU Win32 entwickelt und getestet. GNU Win32 ist eine Umgebung für Windows NT/95/98, das einige GNU Utilities enthält. Unter anderem ‚make‘, ‚find‘ und ‚bash‘. Um ein Kommando über das Makefile auszulösen, muß folgender Befehl an die Kommandozeile übergeben werden: make kommando_name oder make –f Makefile kommando_name Das Makefile befindet sich in der obersten Ebene des Quellverzeichnisses. Alle hier im folgenden erwähnten Verzeichnisse sind relativ zu der Lage des Makefiles zu sehen. Im Zielverzeichnis soll ein lauffähiges System entstehen. Es befindet sich standardmäßig in ‚..\bin‘. Intern ist es durch die Variable $CLASSDIR festgelegt. Das Makefile enthält folgende Kommandonamen: compile Es wird das gesamte Projekt übersetzt. Zudem werden die für die Kommunkation über RMI benötigten Stubs und Skeletons automatisch generiert und außerdem Java Code durch den Java Compiler Compiler erzeugt. Zusätzlich entsteht aus den Properties Java Code. copy Kopiert die Dateien aus dem Verzeichnis Resources in das Zielverzeichnis. Dabei wird die Verzeichnisstruktur beibehalten. plugin Durch den Einsatz des Java Plug-ins ändert sich die Syntax der HTML Dateien, die ein Applet beinhalten [PluginDoc]. Der HTML Converter ist in der Lage, HTML Dateien in die neue Syntax zu übersetzen. Dieses Programm wird intern verwendet. Durch die Übersetzung entsteht in der HTML Datei redundante Information: Die Applet Parameter sind nach der Übersetzung mehrfach vorhanden. Deshalb wurden die Parameter in eine eigene Datei .\Resources\AppletParameters.txt gespeichert und werden vor der Übersetzung in die HTML Dateien eingesetzt. Die HTML Vorlagen, die übersetzt werden sollen, befinden sich in ‚.\Resources\RootFiles\PlugIn‘. Nach der Übersetzung werden sie in das Zielverzeichnis kopiert. rootfiles Alle Dateien, die sich in dem Verzeichnis ‚.\Resources\RootFiles‘ befinden, werden in das Zielverzeichnis kopiert. clientjar Es wird eine .jar Datei generiert. Sie enthält alle Klassen, die für die Ausführung des Applets benötigt werden. Die Datei wird direkt im Zielverzeichnis erzeugt. Anmerkung: Jede Klasse, die im Applet benötigt wird, enthält im Quellcode den Kommentar: ‚//\#client-class\#‘ serverjar Es wird eine .jar Datei generiert, die sämtliche Klassen enthält, die für den Server benötigt werden. Die Datei wird direkt im Zielverzeichnis erzeugt. backup Alle Quell Dateien werden gesammelt und gepackt. Dabei entsteht eine Datei der Form ‚ ParchieSrc-yymmdd.tgz‘ im Quellverzeichnis, wobei yymmdd für das aktuelle Datum steht (yy=Jahr, mm=Monat, dd=Tag). Das verwendete Packprogramm ist das GNU tar. Das Backup kann mit dem Befehl ‚tar –xzf Parchie-Src-yymmdd.tgz‘ entpackt werden. Installation 72 doc Generiert eine HTML Dokumentation aus dem Quellcode. Intern wird das dem JDK beiligenden javadoc verwendet. Standardmäßig werden die Dateien in dem Verzeichnis ‚..\javadoc‘ erzeugt. properties Aus den .properties Dateien werden .java Klassen generiert. Sie werden im demselben Verzeichnis abgespeichert, in dem auch die Properties liegen. jj Übersetzt den Parser Code in den Dateien mit der Endung .jj in Java Code. Intern wird das Programm JavaCC verwendet. jjclean Die bei der Ausführung von ‚make jj‘ entstandenen Dateien werden gelöscht. Die folgenden Kommandos fassen einige Vorgänge zusammen: everything Erstellt ein komplett lauffähiges System im Zielverzeichnis. Es werden alle benötigten Kommandos zusammengefaßt. Der Vorgang benötigt auf einem Pentium 200, MMX, 64 MB RAM circa 15 Minuten. (Das Kommando umfaßt: compile, install, clientjar, serverjar) all Erstellt ein komplettes lauffähiges System im Zielverzeichnis. Es werden jedoch keine .jar Dateien generiert. (Das Kommando umfaßt: compile, install) install Kopiert bzw. generiert alle Ressourcen, die für das Archiv benötigt werden. Es findet keine Übersetzung des Java Quellcodes statt. (Das Kommando umfaßt: copy, plugin, rootfiles) Am Anfang des Makefiles sind Variablen definiert, die die Lage der Hilfsprogramme, die innerhalb des Makefiles verwendet werden, bestimmen. Sie können leicht an eine andere Laufzeitumgebung angepaßt werden. Alle Variablen sind innerhalb des Makefiles ausführlich dokumentiert. 7.4 Konfigurationsdatei von SUMATRA Der Server von SUMATRA kann mit Hilfe einer Textdatei konfiguriert werden. Sie befindet sich standardmäßig in ‚.\Resources\default.conf‘. Beim Start wird dem Server der Name der Konfigurationsdatei als zweiter Parameter übergeben, so daß Lage und Name der Datei keiner Einschränkung unterliegt. In der Konfigurationsdatei wird jedem Schlüssel ein Wert zugewiesen. Das geschieht nach folgender Syntax: KEYNAME=VALUEOFKEY Kommentare beginnen mit dem reservierten Zeichen ‚#‘. Alle zugelassen Schlüsselwörter sind direkt in der Datei ‚.\Resources\default.conf‘ erklärt. Da die Konfigurationsdatei Login und Paßwort der Datenbank enthält, sollte sie über den Webserver nicht verfügbar sein. 7.5 HTML Dateien Der Aufruf eines Applets geschieht immer mit Hilfe einer HTML Datei. Sie beinhaltet die Informationen über die Lage des Applets, die Lage der zusätzlich benötigten Bibliotheken und Parameter, mit denen das Applet konfiguriert werden kann. Installation 73 Für die vorliegende Arbeit sind zwei Applets entstanden, eines für die Suche und eines zur Administration. Beim Start eines Applets werden die übersetzten Klassen vom Webserver aus einzeln zum Browser bzw. zum Java Plug-in übertragen. Alle zu übertragenden Klassen können aber auch in eine Jar Datei gepackt und als ein Paket übertragen werden. Welche Art der Übertragung gewählt wird, hängt mit dem Aufruf des Applets innerhalb der HTML Datei zusammen. Es werden bei der vorliegenden Arbeit beide Arten des Aufrufes angeboten. Demzufolge sind vier HTML Seiten entstanden, deren Parameterwerte fast alle gleich sind. Da das Applet über das Java Plug-in interpretiert wird, ändert sich die üblicherweise verwendete Syntax innerhalb der HTML Seiten. Mehrere Browser unterstützen das Plug-in. Die Syntax um ein Plug-in zu aktivieren ist allerdings bei allen Browsern unterschiedlich. Im Rahmen dieser Arbeit wurden die HTML Dateien für den Netscape 4.5 oder höher und den Internet Explorer 4 oder höher konfiguriert. Die Syntax beider Browser wurde in jeweils eine HTML Seite integriert, was zur Folge hat, daß zwei Aufrufmechanismen und alle dazugehörigen Informationen in einer HTML Seite untergebracht sind. Soll nachträglich ein Applet Parameter in den HTML Dateien geändert werden, so muß diese Änderung an acht Stellen durchgeführt werden. Dies macht eine Wartung sehr schwer. Zur Lösung des Problems wurden lediglich HTML Vorlagen erzeugt. Sie rufen ein Applet in der herkömmlichen Syntax auf und enthalten nur die nötigsten Informationen über die Aufrufart (die Klassen direkt laden oder als Jar Datei) und ob es sich um das Suchwerkzeug oder das Administrationswerkzeug handelt. Alle anderen Parameter sind in eine externe Datei ausgelagert. Um nun die tatsächlichen HTML Dateien zu erzeugen, wird ein Automatismus in Gang gesetzt, der zunächst die externen Parameter in die Vorlagen einsetzt und diese danach, mit Hilfe des Programms ‚HTML Converter‘, übersetzt, so daß das Plug-in beim Laden aktiviert wird. Durch den Aufruf von ‚make plugin‘ werden die HTML Dateien erzeugt. Die Vorlagen befinden sich in ‚.\Resources\RootFiles\PlugIn‘. Sie müssen alle die Endung -PLUG-INTEMPLATE.html haben. Die ausgelagerten Parameter befinden sich in der Datei ‚.\Resources\AppletParameters.txt‘. Folgende Parameter sind ausgelagert und werden von den Applets genutzt: ServerUrlExternal URL des SUMATRA Servers ServerUrlInternal Alternative URL des SUMATRA Servers PicDir relative Lage der zu ladenden Bilder TemplDir relative Lage der HTML Patletvorlage WelcomePage Seite, die während des Ladens des Applets angezeigt wird StartedPage Informationsseite, die angezeigt wird, sobald das Applet geladen ist FrameIcon Name des Icons, daß im Applet Fenster angezeigt werden soll HTML_DEST_DIR relative Lage der Patlets in HTML Form TEXT_DEST_DIR relative Lage der Patlets in Textform Nur der Parameter „Admin„ ist innerhalb der HTML Vorlagen zu finden. Durch ihn wird unterschieden, ob das Such- oder das Administrationswerkzeug geladen werden soll. Seine zulässigen Werte sind ‚true‘ oder ‚false‘. 7.6 Verzeichnisstruktur der CDROM src Enthält das Makefile (Kapitel 7.3). Installation 74 src\Resources AppletParameters.txt enthält die ausgelagerten Applet Parameter wie in Kapitel 7.5 beschrieben. default.conf Konfigurationsdatei von SUMATRA wie in Kapitel 7.4 beschrieben. src\Resources\access Enthält die Datei ‚access.html‘, die dazu verwendet werden kann, die Rechte für die Administration zu vergeben. src\Resources\classes classes111.zip Thin ODBC Driver für die Oracle 8 Datenbank. Netscape-Full.jar Klassenbibliothek, die vom Browser Netscpape 4.5 unter Windows 32 verwendet werden. Sie wurden aus dem Verzeichnis ‚...\Netscape\Communicator\Program\java\classes‘ entnommen und werden bei der Übersetzung der SUMATRA Quell Dateien benötigt. Netscape-Security.jar Eine Untermenge von Klassen von Netscape-Full.jar. Sie werden zur Ausführung der Applets benötigt. patbin132-small.jar Die Zusammenfassung der benötigten Klassen, die es zulassen, Reguläre Ausdrücke parsen zu können. src\Resources\data *.mdd Metadaten für die fachlichen Objekte. Sie enthalten eine Aufzählung der Attribute und Regeln. *.mdo Metadaten für die fachlichen Objekte. Sie beschreiben die einzelnen Attribute. Parchie-Sumatra-MSSQL6x.sql SQL Skript, das die benötigten Datenbanktabellen für den MSSQL Server 6.x erstellt. Parchie-Sumatra-Oracle8.sql SQL Skript, das die benötigten Datenbanktabellen für Oracle 8 erstellt. src\Resources\HtmlFiles patlettemplate.html HTML Vorlage für die Erstellung von Patlets. plugin12-install.html Verweist auf die Lage des Plug-ins. welcome.html Wird angezeigt, während das Applet geladen wird. src\Resources\Pictures Enthält Bilder für die Werkzeugleiste und Logos. src\Resources\RootFiles Enthält diejenigen Dateien, die via ‚make‘ in die oberste Ebene des Zielverzeichnisses kopiert werden sollen. _startServer12.bat Startet den SUMATRA Server. Dabei werden die Klassen aus den Verzeichnissen ‚parchie‘ und ‚sumatra‘ verwendet. _startServer12-jar.bat Startet den SUMATRA Server. Dabei wird das Jar verwendet. _stop_server.bat Beendet den Server. index.html Begrüßungsseite. src\Resources\RootFiles\PlugIn Enthält HTML Vorlagen, wie sie in Kapitel 7.5 beschrieben werden. 75 Installation src\Resources\Security .java.policy Vergibt bestimmte Rechte für die Applets. Jeder Benutzer der Applets muß diese Datei in sein Homeverzeichnis kopieren, wie es in Kaptitel 7.2 Schritt 16 beschrieben ist. src\bin find.exe Gehört zu den GNU Utilities und wird von ‚insertParams.pl‘ genutzt. getInnerclasses.pl In dieser Arbeit entstandenes Perl Skript. Es wird vom Makefile intern genutzt. insertParams.pl In dieser Arbeit entstandenes Perl Skript. Es wird vom Makefile intern genutzt. make_i18n_class.pl In dieser Arbeit entstandenes Perl Skript. Es erzeugt aus Property Dateien (.properties) Java Code. Es wird vom Makefile intern genutzt. src\bin\javacc Enthält das Programm ‚Java Compiler Compiler‘. Es wird vom Makefile intern genutzt. src\bin\htmlconv12 Enthält das Programm ‚HTML Converter‘. Es wird vom Makefile intern genutzt wie in Kapitel 7.3 beschrieben. src\parchie Die in dieser Diplomarbeit entstanden Java Quellen. src\sumatra Der modifizierte Quellcode des Framework SUMATRA. 7.7 Anmerkungen Der Quellcode ist in „100% Pure Java“ geschrieben worden und sollte somit plattformunabhängig sein. Er wurde jedoch nicht auf anderen System getestet. Im Zusammenhang mit den von JavaCC generierten Klassen kam es zu Laufzeitfehlern. Dies scheint ein gängiges Problem zu sein. In den Newsgroups wird empfohlen, den ‚Just In Time Compiler‘ (JIT) des Java Interpreter auszuschalten. Die Batch Datei ‚_startServer.bat‘ (src\Resources\RootFiles) startet den Server, ohne den JIT zu verwenden: java -Djava.compiler=NONE ... Der komplette Aufruf des Servers lautet: java -Djava.compiler=NONE -classpath %cpath% parchie.comm.KHauptServerImpl Parchie .\Resources\default.conf Mit dem Parameter ‚-classpath‘ wird der Java Virtual Machine (JVM) die Lage der externen Bibliotheken übergeben. Sie sind in der Variablen %cpath% gespeichert, die zuvor definiert wurde. ‚ parchie.comm.KHauptServerImpl‘ ist die aufzurufende Klasse. ‚Parchie‘ ist der erste Parameter, der dem Server übergeben wird. Er spezifiziert den Namen des Servers. Der zweite Server Parameter ‚.\Resources\default.conf‘ bestimmt die Lage der Konfigurationsdatei (siehe Kapitel 7.4). Weiterhin ist zu bemerken, daß die Jar Dateien der Applets nur dann über das Plug-In geladen werden, wenn sich die ungepackten .class Dateien nicht in demselben Verzeichnis befinden. Ansonsten werden die Klassen direkt geladen, während die Jar Datei ignoriert wird. Abhilfe schafft das Löschen der .class Dateien oder das Umbenennen der Verzeichnisse (z.B. ‚parchie‘ nach ‚parchie_‘ und ‚sumatra‘ nach ‚sumatra_‘). Es sollte darauf geachtet werden, daß die Konfigurationsdatei nicht über HTTP zugänglich ist, da sie Login und Paßwort des Datenbankbenutzers enthält. 76 8 Zusammenfassung und Ausblick Das Ziel dieser Arbeit war es, eine technische Unterstützung für ein Muster-Klassifikationssystem zu entwickeln, mit deren Hilfe eine Suche nach Mustern über die Klassifikation und eine Administration für das System möglich war. Sowohl das Suchwerkzeug als auch das Administrationswerkzeug sollten innerhalb des Intranets von sd&m erreichbar sein. Zu diesem Zweck wurden zwei Java Applets implementiert, die diese Aufgaben übernehmen. Die Daten der Klassifikation werden in einer relationalen Datenbank gespeichert. Um ein stabiles System zu erhalten, daß den Anforderungen des Auftraggebers entspricht, wurde das es mit den üblichen Methoden der Softwareentwicklung geplant. So gab es eine Analyse-, Entwurfsund Implementierungs-Phase, die in dieser Arbeit ausführlich besprochen wurden. Selbstverständlich können die Phasen nicht so strikt eingehalten werden, wie sie in dieser Arbeit beschrieben wurden. Es handelt sich vielmehr um einen iterativen Prozeß, bei dem man immer wieder zu einer Stelle der drei Phasen zurückkehrt um Verbesserungen vorzunehmen. Kevlin Henney bezeichnet die Entwicklung eines Softwaresystems sogar als ‚blackboard process‘, bei dem Entwurfsfragmente mit ersten Erfahrungen aus der Implementierungsphase zusammenkommen um ein lebensfähiges System zu erschaffen [Hen98, S. 12]. Zahlreiche Besprechungen mit Gianmarco Niedermeyr und den Mitarbeitern von sd&m halfen, die zu lösenden Probleme besser zu verstehen. Es entstand dadurch ein Musterarchiv, daß die Flexibilität der in [NIE99] und Kapitel 2.3.1 vorgestellten Klassifikation widerspiegelt. So können beliebig Einträge in der Klassifikation neu hinzukommen oder gelöscht und das Archiv um beliebig viele Muster erweitert werden. Im Hinblick darauf, daß Mustern in der Softwareentwicklung ein immer größerer Stellenwert eingeräumt wird, ist ein möglichst flexibles System sinnvoll, da durch die große Beachtung, die Mustern geschenkt wird, sehr viele neue Muster entstehen14. Durch die Hinzunahme von neuen Mustern in das Archiv, ist anzunehmen, daß irgendwann die Themenbereiche in der Klassifikation nicht mehr ausreichen. Das Klassifikationssystem sollte genügend variabel sein, um diese neuen Bereiche abzudecken. Ob es diese Eigenschaft besitzt, wird sich erst bei der praktischen Anwendung des Systems zeigen. Für die Implementierung des Systems wurde das von sd&m entwickelte Framework SUMATRA verwendet, das den Datenbankzugriff, von einem Applet aus, erleichtert. Es erwies sich als nützlich und sinnvoll darauf zurückzugreifen, da das Framework unterschiedliche Datenbanken unterstützt, eine Abstraktion der Datenbanktabellen liefert und die Trennung von Datenbank und Webserver ermöglichte. Die Ansicht der Beziehungen zwischen den Mustern wird in dem hier entwickelten System durch HTML Verweise verwirklicht. Die Informationen über die Beziehungen sind in der Datenbank gespeichert und könnten auch als Graph dargestellt werden um so einen besseren Überblick über die Musterveflechtungen zu bekommen. Ob der Ansatz, Muster über eine Klassifikation mit Hilfe einer Suchmaschine zu suchen, in der Praxis bestehen kann, wird sich zeigen, wenn das System im Intranet von sd&m freigegeben ist. 14 Es ist beispielsweise bereits eine Fortsetzung des populären Buches [POSA98] angekündigt. Eine Voransicht der als ‚POSA2‘ bezeichneten Veröffentlichung ist auf http://www.cs.wustl.edu/~schmidt/patterns/patterns.html zu finden. 77 9 Personen und Organisationen Univ. Prof. Dr. Martin Wirsing, Ordinarius Lehr- und Forschungseinheit für Programmierung und Softwaretechnik der Ludwig-Maximilians-Universität München [email protected] http://www.pst.informatik.uni-muenchen.de/personen/wirsing Dr. María Victoria Cengarle Lehr- und Forschungseinheit für Programmierung und Softwaretechnik der Ludwig-Maximilians-Universität München [email protected] http://www.pst.informatik.uni-muenchen.de/personen/cengarle Dr. Peter Brössler Leiter Technologiemanagement sd&m AG München [email protected] http://www.sdm.de/ Institut für Informatik Lehr- und Forschungseinheit für Programmierung und Softwaretechnik der Ludwig-Maximilians-Universität München Oettingenstraße 67 D-80538 München http://www.pst.informatik.uni-muenchen.de sd&m software design & management AG Thomas-Dehler-Straße 27 81737 München Telefon 089 / 6 38 12 - 0 http://www.sdm.de 78 10 Danksagungen Neben meinen beiden Betreuern Dr. Peter Brössler und Dr. María Victoria Cengarle, die mir mit Rat und Tat beiseite standen, ist es mir ein Anliegen auch folgende Personen zu danken: Dr. Harald Haller sd&m AG München [email protected] Bernhard Sporkmann sd&m AG München [email protected] Dr. Klaus Mayr sd&m AG München [email protected] Sie unterstützten mich bei der Verwendung von SUMATRA. Diana Heggemann sd&m AG München [email protected] Sie half bei allen technischen Problemen, die bei der Installation des Systems in der Firma sd&m auftauchten. Ganz allgemein möchte ich mich bei der „Internetgemeinschaft“ bedanken. Diskussionen über spezielle technische Probleme in der Newsgroup de.comp.lang.java und den Diskussionsforen auf http://forum.java.sun.com/, http://www.codeguru.com/ und http://www.experts-exchange.com trugen zur schnellen Lösung vieler Implementierungsfragen bei. Nicht zuletzt danke ich Gianmarco Niedermeyr für die konstruktive Zusammenarbeit. 79 Glossar API: (Application Programming Interface, dt. Anwendungsprogrammierschnittstelle) Die extern sichtbare Schnittestelle einer Softwareplattform, z.B. eines Betriebsystems, die von Systemen oder Anwendungen verwendet werden, die auf der Plattform aufsetzen [POSA98, Anhang B]. Architekturmuster: (engl. Architectural Patterns) Spezielle Muster, welche grundsätzliche Strukturierungsprinzipien für Software-Systeme behandeln. Ihr Einsatz erfolgt in der Regel zu Beginn des Grobentwurfs. CGI: (Common Gateway Interface) Definiert den Standard um externe Programme von einem Webserver ausführen zu können. Das CGI spezifiziert, wie Argumente an das Programm über eine HTTP Anfrage übergeben werden können. Das Programm generiert dynamisch HTML Code und schickt ihn an den Browser zurück. Ein CGI Programm kann in jeder beliebigen Sprache geschrieben sein solange es Kommandozeilen Parameter interpretieren kann. Es ist oft in Perl [Perl] implementiert. Entwurfsmuster: (engl. Design Patterns) Eigentlich Bezeichnung für spezielle Muster, die eine gegebene Grundstruktur eines SoftwareSystems durch Beschreibung der Komponenten und Subsysteme und ihrer Beziehungen untereinander verfeinern und in der Entwurfsphase einzusetzen sind. Die Bezeichnung wird jedoch oft synonym für Muster in der Software-Entwicklung gebraucht. Framework: (dt. Rahmenwerk) Halbfertiges Software-System, das dem Software-Entwickler eine Rahmenarchitektur vorgibt und von noch instantiiert werden muß. Zur Erstellung von Frameworks werden meist Muster herangezogen. Idiome: (engl. Idioms) Spezielle Art von Mustern auf einer niedrigen Abstraktionsebene, welche implementierungsspezifische Probleme in einer konkreten Programmiersprache behandeln. Look & Feel: Das Erscheinungsbild und die Funktionalität der Bedienungsoberfläche eines Programms. Das Look & Feel übernimmt etwa die Darstellung von Icons um bestimmt Funktionen zu repräsentieren wie z.B. das Öffnen und Schließen von Dateien, das Ändern der Fenstergröße oder das Positionieren von Fenstern. Glossar 80 Middleware: Eine Software, die zwischen einer Applikation und dem Netzwerk vermittelt. Es organisiert die Interaktionen zwischen ungleichen Applikationenen in einem heterogenen Netzwerk. Der Object Request Broker (ORB), eine Software, die die Kommunikation zwischen Objekten organisiert, ist ein Beispiel für eine Middleware [Foldoc]. Muster: (engl. Patterns) Beschreibung von wiederverwendbaren Expertenerfahrungen, welche mit einem aussagekräftigen Namen versehen ist und zu einem wiederkehrenden Problem in einem bestimmten Kontext unter Berücksichtigung bestimmter Randbedingungen das Wesen einer erprobten Lösung erläutert. Mustersystem: (engl. Pattern System) Möglichst vollständige Sammlung von Mustern, um einen Themenkreis so weit wie möglich abzudecken, zusammen mit Richtlinien für die Implementierung, Kombination und praktische Verwendung der Muster. Beispiel: [POSA98]. Patlet: Kurzform eines Musters, welches für den Software-Entwickler ausreichende Informationen enthält, um zu entscheiden, ob das dazugehörige Muster auf die konkrete Problemsituation anwendbar ist. RMI: (Remote Method Invocation) Teil der Programmiersprache Java, mit der es einem Java Programm, das auf einem bestimmten Rechner läuft, möglich ist, Objekte und Methoden eines anderen Java Programms, das auf einem anderen Rechner gestartet worden ist, zu erreichen. Usenet: Ein verteiltes System, ähnlich einem schwarzen Brett, auf dem meist Artikel versendet und gelesen werden können. Die Newsgroups sind ein Teil des Usenets. Nicht alle Internet Hosts unterstützen das Usenet und nicht alle Usenet Hosts unterstützen das Internet. 81 Literatur [BDRS97] Manfred Broy, Ernst Denert, Klaus Renzel, Monika Schmidt: Software Architectures and Design Patterns in Business Applications, Technische Universität München, TUM-I9746, November 97; http://www.sdm.de/g/arcus. [BM94] Frank Buschmann, Regine Meunier: A System of Patterns; Proceedings of PLoP’94 in: J.O. Coplien, D.C. Schmidt (Eds.): Pattern Languages of Program Design, Addison-Wesley, 1995, S. 325-343. [CodeGuru] The CodeGuru homepage, http://www.codeguru.com/ [Cop92] James O. Coplien: Advanced C++ - Programming Styles and Idioms; AddisonWesley, Reading, Massachusetts, 1992; ISBN 0-201-54855-0. [DaVinci] The DA VINCI Initiative: http://ganesh.mit.edu [DubhUtils] Brian Duff: Dubh Utils 1.0.1 build 5 build environment, http://wired.st-and.ac.uk/~briand/newsagent/download/index.html [Foldoc] FOLDOC, Free On-Line Dictionary of Computing, http://foldoc.doc.ic.ac.uk/foldoc/index.html [Fow97] Martin Fowler: Analysis Patterns - Reusable Object Models; Addison-Wesley, 1997, ISBN 0-201-89542. [GOF95] Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides: Design Patterns – Elements of Reusable Object-Oriented Software; Addison-Wesley, 1995. [GPL] Free Software Foundation: GNU General Public License, http://www.gnu.org/copyleft/gpl.html [Hal] Dr. Harald Haller (sd&m Mitarbeiter, er wirkte am SUMATRA Projekt mit): Private Kommunikation [Hen98] Kevlin Henney: Introduction to Patterns; Object Management Group: Patterns ’98 Conference Notes, Manchester, UK, Okt. 1998. [Hill] Hillside Group: The Patterns Homepage; http://hillside.net/patterns/patterns.html. [i18nTut] Dale Green: The JavaTM Tutorial, http://java.sun.com/docs/books/tutorial/i18n/index.html [icGuide] JDKTM 1.1.8 Documentation, Guide to New Features, Inner Classes, http://java.sun.com/products/jdk/1.1/docs/guide/innerclasses/ [Index] Prof. Dr. Hans-Peter Kriegel: Index- und Speicherungsstrukturen für Datenbanksysteme, Skript unter Mitarbeit von Thomas Brinkhoff, 1994 [JavaAPI] JavaTM 2 Platform, Standard Edition, v1.2.2, API Specification, http://java.sun.com/products/jdk/1.2/docs/api/overview-summary.html [JavaCC] The Java Parser Generator, http://www.metamata.com/javacc/ [JavaLAF] Michael Albers, Chris Ryan: The Java Look and Feel, Swing's Cross-Platform L&F Design, http://java.sun.com/products/jfc/tsc/plaf_papers/java_lf/java_lf.html [JavaRegEx] Regular Expressions in Java, http://javaregex.com/ 82 Literatur [JavaTut] How to Use File Choosers, http://java.sun.com/docs/books/tutorial/uiswing/components/filechooser.html [JDBC] JDBCTM API , http://java.sun.com/products/jdk/1.2/docs/guide/jdbc/index.html [JDBC-Drivers] JDBCTM technology drivers, http://java.sun.com/products/jdbc/drivers.html [JDK12Lic] Sun Microsystems, Inc. Binary Code License Agreement, http://java.sun.com/products/jdk/1.2/LICENSE [JVM-Spec] THE JAVATM VIRTUAL MACHINE SPECIFICATION, http://java.sun.com/docs/books/vmspec/index.html [LAFCR] Steve Wilson: The 'LookandFeel' Class Reference, A PLAF Lookup Guide for Swing Programmers, http://java.sun.com/products/jfc/tsc/plaf_papers/lookandfeel_reference/lookandfeel_re ference.html [Matts] Matt’s Script Archive Inc., http://www.worldwidemart.com/scripts/ [Mixing] Amy Fowler: Mixing heavy and light components, http://java.sun.com/products/jfc/tsc/archive/tech_topics_arch/mixing/mixing.html [MM97] Thomas J. Mowbray, Raphael C. Malveau: CORBA Design Patterns; John Wiley & Sons, 1997, ISBN 0-471-15882-8. [ModMVC] Amy Fowler: A Swing Architecture Overview, The Inside Story on JFC Component Design, http://java.sun.com/products/jfc/tsc/archive/what_is_arch/swing-arch/swingarch.html [MultiPlex] Will Walker: The Multiplexing Look & Feel, Creating and Using Auxiliary L&Fs in Swing, http://java.sun.com/products/jfc/tsc/archive/plaf_papers_arch/multi_update/multi_upd ate.html [MultTT] Zafir Anjum: Multi-line ToolTip, http://www.codeguru.com/java/articles/122.shtml, 1998 [NewsAgent] Brian Duff: NewsAgent, http://st-and.compsoc.org.uk/~briand/newsagent [NIE99] Gianmarco Niedermeyr: "Klassifikation von Mustern zum Aufbau eines Patlet-Archivs ”, Diplomarbeit, Institut für Informatik der Ludwig-Maximilians-Universität München, Lehr- und Forschungseinheit für Programmierung und Softwaretechnik, http://www.pst.informatik.uni-muenchen.de/DA/niederme. [NTService] Rick Furnival: Apps at Your Service, http://www.winmag.com/library/1998/0801/how0071.htm, 1998 [Oest98] Bernd Oestereich: Objektorientierte Softwareentwicklung, Analyse und Design mit der Unified Modeling Language; R.Oldenbourg Verlag München Wien, 4. Auflage 1998, ISBN 3-486-24787-5. [Perl] Perl Mongers – The Perl advocacy people, http://www.perl.org/ [Plug-in11] Java Plug-in 1.1.3, http://java.sun.com/products/plugin/1.1.3/index-1.1.3.html [Plug-in12] JAVATM PLUG-IN PRODUCT, http://java.sun.com/products/plugin/index.html [PluginDoc] Java Plug-in 1.2.2 Documentation, http://java.sun.com/products/plugin/1.2/docs/index.docs.html 83 Literatur [POSA98] [PRI89] Frank Buschmann, Regine Meunier, Hans Rohnert, Peter Sommerlad, Michael Stal: Pattern-orientierte Software-Entwicklung; Addison-Wesley, 1998, ISBN 3-8273-12825. Rubén Prieto-Díaz: Classification of reusable modules; in: Ted J. Biggertstaff, Alan J. Perlis (Eds): Software Reusability; ACM Press frontier series, Addison-Wesley, 1989, ISBN 0-201-08017-6, S. 99-123. [ReflectDoc] Guide to Features - Java Platform, Reflection, http://java.sun.com/products/jdk/1.2/docs/guide/reflection/index.html [RMIGuide] JavaTM Remote Method Invocation (RMI), http://java.sun.com/products/jdk/1.2/docs/guide/rmi/index.html [RMITut] Ann Wollrath, Jim Waldo: The RMI trail of The JavaTM Tutorial, http://java.sun.com/docs/books/tutorial/rmi/index.html [SUMATRA] Das Framework SUMATRA, auf der beiligenden CDROM: doc\SUMATRA-html.zip, SUMATRA-doku.ps und SUMATRA-folien.ppt [Sun] Sun Microsystems, Inc., 901 San Antonio Road, Palo Alto, CA 94303 USA, http://www.sun.com/ [SwingArch] Amy Fowler: A Swing Architecture Overview, The Inside Story on JFC Component Design, http://java.sun.com/products/jfc/tsc/archive/what_is_arch/swing-arch/swingarch.html [TableHea99] Jan-Friedrich Mutter: CheckBox in a TableHeader, http://www.codeguru.com/java/articles/664.shtml, 1999 [TableSel99] Jan-Friedrich Mutter: Selection of any Cell in a JTable, http://www.codeguru.com/java/articles/663.shtml, 1999 [TreeSet] JavaTM 2 Platform, Standard Edition, v1.2.2 API Specification, Class TreeSet, http://java.sun.com/products/jdk/1.2/docs/api/java/util/TreeSet.html [Uidelegate] The process of installing a UI delegate, http://java.sun.com/products/jfc/tsc/archive/what_is_arch/ui_install/ui_install.html [UML] Unified Modeling Language RESOURCE CENTER, http://www.rational.com/uml/index.jtmpl [Wiki] Portland Pattern Repository, WikiWikiWeb: http://c2.com/wiki?WelcomeVisitors [Zen97] Andreas Zendler: Konzepte, Erfahrungen und Werkzeuge zur SoftwareWiederverwendung, Tectum Verlag, 1997. 84 Abbildungen ABBILDUNG 1: OBERFLÄCHE DES WWWBOARDS ................................................................................................... 4 ABBILDUNG 2: LINKSAMMLUNG IM INTERNET......................................................................................................... 5 ABBILDUNG 3: ADMINISTRATION DER LINKSAMMLUNG .......................................................................................... 6 ABBILDUNG 4: PATLET STRUKTUR ........................................................................................................................ 13 ABBILDUNG 5: ANWENDUNGSFÄLLE FÜR DAS MUSTERARCHIV............................................................................. 15 ABBILDUNG 6: SUCHE............................................................................................................................................ 16 ABBILDUNG 7: PATLET ANZEIGEN ......................................................................................................................... 17 ABBILDUNG 8: KOMMENTARE ............................................................................................................................... 18 ABBILDUNG 9: ABHÄNGIGKEITEN. ALLE MUSTER, DIE EINER EINFACHKLASSE ZUGEORDNET SIND. ..................... 19 ABBILDUNG 10: ABHÄNGIGKEITEN. ALLE EINFACHKLASSEN, DIE EINEM MUSTER ZUGEORDNET SIND. ................ 19 ABBILDUNG 11: PATLET IMPORTIEREN ................................................................................................................. 20 ABBILDUNG 12: PATLET IMPORTIEREN (ADMINISTRATION)................................................................................... 21 ABBILDUNG 13: PATLET EXPORTIEREN .................................................................................................................. 22 ABBILDUNG 14: AUSZUG AUS DER KLASSIFIKATION ............................................................................................. 23 ABBILDUNG 15: SCHICHTENMODELL UND PACKAGES DES PROGRAMMS .............................................................. 28 ABBILDUNG 16: AUFRUF ....................................................................................................................................... 29 ABBILDUNG 17: DIALOG FÜR DAS SUCHWERKZEUG .............................................................................................. 30 ABBILDUNG 18: DIALOG FÜR DAS ADMINISTRATIONSWERKZEUG ......................................................................... 31 ABBILDUNG 19: VIEW FACTORY MUSTER IN SUMATRA ..................................................................................... 32 ABBILDUNG 20: COMMAND MUSTER..................................................................................................................... 33 ABBILDUNG 21: KOMBINATION AUS COMMAND UND VIEW FACTORY MUSTER .................................................... 33 ABBILDUNG 22: ER-DIAGRAMM DER DATENBANK ............................................................................................... 35 ABBILDUNG 23: DATENBANKSCHEMA FÜR DEN MS SQL SERVER 6.X .................................................................. 36 ABBILDUNG 24: DATENBANKSCHEMA FÜR DIE ORACLE 8 DATENBANK ................................................................ 36 ABBILDUNG 25: OBJEKTE (IM PACKAGE PARCHIE.OBJECTS) .................................................................................. 39 ABBILDUNG 26: PSEUDOCODE FÜR DIE GENERIERUNG DER BAUMSTRUKTUR ....................................................... 40 ABBILDUNG 27: KOMMENTARE ANLEGEN UND ABRUFEN ...................................................................................... 45 ABBILDUNG 28: PATLET IMPORTIEREN .................................................................................................................. 46 ABBILDUNG 29: ABSPEICHERN EINES PATLETS IN TEXTFORM ............................................................................... 47 ABBILDUNG 30: KLASSIFIKATION ANLEGEN .......................................................................................................... 49 ABBILDUNG 31: MENÜVERWALTUNG .................................................................................................................... 50 ABBILDUNG 32: KLASSENDIAGRAMM IM PACKAGE PARCHIE.SWING ..................................................................... 53 ABBILDUNG 33: AUSZUG AUS DEM QUELLCODE DER KLASSE CHECKBOXHEADER .............................................. 54 ABBILDUNG 34: ERWEITERUNG DES JFILECHOOSERS IM PACKAGE PARCHIE.SWING ............................................. 55 ABBILDUNG 35: JMULTILINETOOLTIP IM PACKAGE PARCHIE.SWING .................................................................... 56 ABBILDUNG 36: ALGORITHMUS FÜR DAS LÖSCHEN EINES FACHLICHES OBJEKTES ................................................ 57 ABBILDUNG 37: KLASSENDIAGRAMM AUS DEM PACKAGE SUMATRA.PERSIST ....................................................... 58 ABBILDUNG 38: SCREENSHOT EINES PATLETS IN HTML FORM............................................................................. 61 ABBILDUNG 39: SCREENSHOT DES SUCHWERKZEUGS ........................................................................................... 62 ABBILDUNG 40: ÜBERSICHT DER KOMMENTARE ZU DEM MUSTER "AGENT" ........................................................ 63 ABBILDUNG 41: EDITOR FÜR KOMMENTARE ......................................................................................................... 64 ABBILDUNG 42: SCREENSHOT DES ADMINISTRATIONSWERKZEUGS....................................................................... 66 85 Stichwortverzeichnis Aktivitätsdiagramm .............................................. 16 Anwendungsfälle ................................................. 14 Muster ................................................. 1, 2, 5, 11, 80 Command Muster ........................................32, 33 View Factory Muster ..................................32, 34 Mustersystem ................................................... 1, 80 C O CGI................................................................... 4, 79 Command Muster ................................ Siehe Muster Oracle ...................................... 26, 36, 67, 68, 69, 74 A F P Facettenklassifikation ............................................. 8 fachliches Objekt................................ 26, 34, 36, 56 Patlet ............................................... 2, 10, 11, 35, 80 „don’t care“ Patlet .......................................10, 41 Perl ..............................................................4, 67, 68 I R Indexierung ............................................................ 8 relationale Datenbank ......................... 25, 38, 67, 68 RMI ............................................... 25, 26, 31, 71, 80 J Java .......................................................... 24, 52, 67 JDBC .................................................................... 25 JDBC-Treiber ........................................... 25, 67, 69 JFC ................................................................. 26, 52 S Schichten ...............................................8, 10, 11, 27 SUMATRA ................................... 24, 25, 26, 72, 76 Swing ................................................................... 26 K U Klassifikation ............ 1, 8, 12, 14, 21, 48, 60, 64, 65 Use Cases ............................ Siehe Anwendungsfälle M V Middleware .............................................. 25, 31, 80 MSSQL Server ................................... 26, 67, 68, 69 View Factory Muster ........................... Siehe Muster