Softwaredokumentation
Transcription
Softwaredokumentation
Software-Projekt: Java2Prolog Softwaredokumentation Malte Cornelius, Jan Gellermann, Benjamin Heuer, Ki-Hyoun Kim, Reinhard Klaus Losse Stand: 5. Februar 2008 Inhaltsverzeichnis 1 Einleitung 1.1 Java-Benutzeroberäche . . . . . . . . . . . . . . . . 1.1.1 Beschreibung der Funktionen des Programms 1.1.2 Design der Entwicklungsumgebung . . . . . . 1.2 Webservice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 3 3 3 5 2 Installation und Bedienungsanweisung 2.1 Voraussetzungen . . . . . . . . . . . . . . . . . . . . . . 2.2 Installation . . . . . . . . . . . . . . . . . . . . . . . . . 2.3 Bedienungsanweisung . . . . . . . . . . . . . . . . . . . . 2.3.1 Erstellen eines neuen Prolog-Projektes . . . . . . 2.3.2 Erstellen eines neuen Prolog-Quelltextes . . . . . 2.3.3 Auswahl einer Prolog-Engine . . . . . . . . . . . 2.3.4 Absenden einer Anfrage . . . . . . . . . . . . . . 2.3.5 Abbrechen einer Anfrage . . . . . . . . . . . . . 2.3.6 Anzeigen von Debug-Output der Prolog-Engines 2.3.7 Kongurieren des Plugins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 5 5 6 6 6 6 7 7 7 8 3 Architektur 3.1 Überblick . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.2 Grobe UML-Darstellung der Architektur . . . . . . . . . . . . . . . . . . . . . 9 9 9 . . . . 4 Die Packagestruktur 10 5 Dokumentation der Klassen und Interfaces des Projektes 5.1 Erweiterte UML-Darstellung der Klassenstruktur . . . 5.2 Die Interfaces . . . . . . . . . . . . . . . . . . . . . . . 5.2.1 PrologEngine und PrologEngineMarshable . . . 5.2.2 PrologOutput und J2pOutputListener . . . . . 5.3 Aufbau des Eclipse-Plugins . . . . . . . . . . . . . . . 5.4 Der Kongurationsdialog . . . . . . . . . . . . . . . . . 5.4.1 PreferenceDialog . . . . . . . . . . . . . . . . . 5.4.2 PreferencePage . . . . . . . . . . . . . . . . . . 5.4.3 PreferenceContent . . . . . . . . . . . . . . . . 5.5 Die Prolog-Engines und die PrologEngineFactory . . . 5.6 Die Konguratorklasse Conf . . . . . . . . . . . . . . . 5.7 Die Klasse XMLConverter . . . . . . . . . . . . . . . . 5.8 Die Klasse Strings . . . . . . . . . . . . . . . . . . . . 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 11 12 12 12 13 14 14 14 14 15 16 16 16 6 Der 6.1 6.2 6.3 6.4 Webservice Einleitung . . . . . . . . . . . . . . . . . Der Webservice-Server . . . . . . . . . . Der Webservice-Client . . . . . . . . . . Verwenden des Webservice-Servers . . . 6.4.1 Voraussetzungen . . . . . . . . . 6.4.2 Starten des Webservice-Servers . 6.4.3 Stoppen des Webservice-Servers . 7 Die Kongurationsdatei cong.xml . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 17 17 17 18 18 18 18 19 2 1 Einleitung Die vorliegenden Programme sind das Ergebnis des Softwareprojektes 'Java2Prolog' an der Leibniz Universität Hannover im WS 2007/2008. Sie wurden durch die auf dem Deckblatt angegebenen Studenten in Gruppenarbeit entwickelt und dokumentiert. Das Projekt besteht aus zwei Teilprojekten, einer graschen Entwicklungsumgebung in Java für Prolog sowie ein Webservice, der Prologanfragen verarbeiten kann. Im folgenden ndet sich ein Überblick über die entwicklten Programme. 1.1 Java-Benutzeroberäche 1.1.1 Beschreibung der Funktionen des Programms Es wurde eine grasche Benutzeroberäche in Java entwickeln, die es erlaubt, in einem Texteditor Prolog-Programme zu schreiben, editieren, laden und speichern. Diese PrologProgramme sowie Prolog-Anfragen an diese sollen an verschiedene auswählbare PrologImplementierungen übergeben werden. Die Oberäche ist als Plug-in für die bekannte OpenSource-Entwicklungsumgebung 'Eclipse' realisiert. Mit Hilfe der Entwicklungsumgebung ist es möglich, die Implementierungen von tuProlog, JLog-Prolog, SWI-Prolog und XSB-Prolog anzusprechen. Dies funktioniert sowohl auf linuxals auch auf windowsbasierten Umgebungen. Der Editor unterstützt den Benutzer bei der Eingabe der Programme durch Funktionen wie Syntax-Hervorhebung oder Verbergen (Einfalten) des Quellcodes einzelner Methoden. 1.1.2 Design der Entwicklungsumgebung Das Design der Oberäche zeigt Abbildung 1. In der Mitte bendet sich ein Editor (1) mit mehreren Fenstern, der die Wissensdatenbank beinhaltet. Der Editor unterstützt SyntaxHervorherbung und das verbergen einzelner Methoden durch Klicken auf ein kleines MinusSymbol am Kopf der Methode. Per Mausklick können unterschiedliche Prolog-Engines (2) ausgewählt werden. Anfragen an die Wissensdatenbank können in ein Eingabefeld (3) eingegeben und mit dem Start-Knopf (4) abgeschickt werden. Vorherige Anfragen können über eine Kombinationsbox aufgerufen werden. Das Ergebnis der Anfagen in in der Konsole (5) am unteren Bildschirmrand sichtbar. Am linken Rand gibt es einen Projektexplorer (6), der schnellen Zugri auf mehrere Dateien des aktuellen sowie anderer Projekte bietet. Hier lassen sich mehrere Projekte anlegen und gleichzeitig verwalten. Durch Assistenten ist es möglich, neue Dateien dem Projekt hinzuzufügen. 3 Abbildung 1: Gesamtansicht der Benutzeroberäche 4 1.2 Webservice Der zu entwickelte Webservice erhält per XML ein Prolog-Programm sowie Anfragen an dieses und sendet die von einer Prolog-Implementation zurückgegebenen Antworten ebenfalls per XML zurück. Der Webservice kann hierzu auf die oben genannten Prolog-Implementierungen zugreifen, um die Anfragen zu beantworten. 2 Installation und Bedienungsanweisung 2.1 Voraussetzungen Das Java2Prolog-Plugin setzt ein installiertes Eclipse sowie eine laufende Java-Umgebung voraus. Es wurde erfolgreich getestet mit Eclipse Version Version: 3.2.1, Build id: M200609210945 und Java JRE 1.6.0. Möglicherweise arbeitet es auch mit früheren Versionen zusammen; dies kann jedoch nicht garantiert werden. Zur Verwendung von XSB- und SWI-Prolog müssen diese Implemetierungen ebenfalls lauähig auf dem System installiert sein. tuProlog und JLog-Prolog werden mit dem Plugin mitgeliefert. Das Plugin sowie tuProlog, JLog-Prolog, SWI-Prolog und XSB-Prolog wurden erfolgreich unter Windows XP Professional sowie Linux getestet. 2.2 Installation Zur Installation genügt es, die Java2Prolog.jar in das Unterverzeichnis 'plugins' im EclipseVerzeichnis zu kopieren. Anschlieÿend muss im Menü von Eclipse unter 'Window->Open Perspective->Other...' die Perspektive 'Prolog' geladen werden. Auÿerdem müssen im Menü 'Window->Show View>Other...' im Ordner 'Prolog' die Views 'Prolog Engines' und 'Querys' geönet werden. Sofern noch keine Konsole angezeigt wird, so kann diese im gleichen menü im Ordner 'General' ausgewählt werden. 5 2.3 Bedienungsanweisung 2.3.1 Erstellen eines neuen Prolog-Projektes Klicken Sie im Navigator-Fenster mit der rechten Maustaste und wählen Sie 'New->Project...'. In dem nun erscheinenden Assistenten wählen Sie im Ordner 'General' 'Project' aus und klicken auf 'Next >'. Geben Sie nun unter 'Project Name' einen Namen für das Projekt ein und klicken Sie auf 'Finish'. 2.3.2 Erstellen eines neuen Prolog-Quelltextes Um einen Prolog-Quelltext erstellen zu können, muss zunächst ein Projekt erstellt werden, in das der Quelltext eingefügt werden kann. Klicken Sie mit der rechten Maustaste auf das gewünschte Projekt und wählen Sie 'New>Other...'. In dem nun erscheinenden Assistenten wählen Sie im Ordner 'PrologWizards' 'Prolog File' aus und klicken auf 'Next >'. Geben Sie nun unter 'Dateiname' einen Namen für die Datei ein und klicken Sie auf 'Finish'. Abbildung 2: Assistent zur Erstellung eines Prolog-Quelltextes 2.3.3 Auswahl einer Prolog-Engine Klicken Sie im Prolog-Engines-View eine Prolog-Engine Ihrer Wahl doppelt an. Wenn diese erfolgreich aktiviert werden konnte, so wird der Pfeil dieser Engine gelb eingefärbt. Alle Anfragen gehen nun an diese Engine. 6 2.3.4 Absenden einer Anfrage Geben Sie eine Prolog-Anfrage an das Prolog-Programm in die Eingabezeile des Query-Views ein. Ein abschlieÿender Punkt ist nicht erforderlich. Die Anfrage können Sie entweder durch Betätigen der Enter-Taste oder durch einen Klick auf den Start-Knopf (Gelber Pfeil oben rechts im View) absenden. Bereits zuvor gestellte Anfragen können Sie erneut absenden, indem Sie auf den kleinen Pfeil am rechten Rand des Eingabefeldes klicken und in der dann erscheinenden Auswahl (Query-History) die gewünschte Anfrage auswählen. Abbildung 3: Absenden einer Anfrage und Query-History 2.3.5 Abbrechen einer Anfrage Dauert die Berechnung einer Anfrage zu lange oder ist eine Endlosschleife aufgetreten, können Sie diese Anfrage durch einen erneuten Klick auf den Start-Knopf beenden. Dass die Anfrage noch ausgeführt wird, erkennen Sie daran, dass der Start-Knopf während der Berechnung der Anfrage ein rotes 'X' darstellt statt des gelben Pfeils. Abbildung 4: Abrechen einer Anfrage 2.3.6 Anzeigen von Debug-Output der Prolog-Engines Einige Engines erzeugen neben den Ausgabe zu den Anfragen weitere Ausgaben wie etwa Informationen über Kompilierzeiten an. Auÿerdem ist es möglich, mittels 'write()' oder je nach Engine ähnlichen Anweisungen Debug-Ausgaben zu erzeugen. Diese Aufgabe werden in einer zusätzlichen Konsole ausgegeben. Sie können durch einen Klick auf den Knopf 'Display Selected Console' (2) zwischen beiden Konsolen hin- und herschalten. Durch einen Klick auf 'Clear Console' (1) wird der Inhalt der Konsole gelöscht. Die Antworten auf die Anfragen werden in der Konsole 'Prolog Result', die Debug-Ausgaben in der Konsole 'Prolog Output' ausgegeben. Dies ist erst möglich, nachdem mindestens eine Anfrage gestellt wurde. Durch einen Klick auf den Pfeil rechts neben dem 'Open Console'-Knopf (3) können Sie 'New Console View' auswählen. Dadurch wird eine weitere Konsole geönet. Sie können beide Konsolen nebeneinander anordnen, um stets beide Ausgaben zu erhalten. Abbildung 5: Konsolenfunktionen und Anzeigen von Debug-Output 7 2.3.7 Kongurieren des Plugins Üebr das Menü 'Window->Preferences...->Java2Prolog' oder durch einen Klick auf 'Eigenschaften' im Prolog-Engines-View gelangen Sie zum Kongurationsdialog. Im Bereich 'Verwendete Menüsprache' können Sie die Sprache auswählen, die von den Menüs und Fehlermeldungen des Plugins sowie von den Prolog-Engines verwendet wird, angeben. Deutsch und Englisch sind bereits implementiert. Diese Änderung wird erst nach einem Neustart von Eclipse wirksam. Unter 'Installierte Prolog-Implementierungen' können Sie auswählen, welche Prolog-Implementierungen durch das Plugin verwendet werden sollen. Es werden nur die Engines verwendet, vor deren Eintrag ein Haken steht. Auÿerdem müssen Sie hier die Pfade Binärdateien von XSB- und SWI-Prolog denieren. Wenn Sie den Webservice verwenden möchten, müssen Sie an dieser Stelle die komplette URL eingeben. Der Eintrag 'Standard-Engine' deniert die Engine, die beim Start des Plugins ausgewählt wird. Hinweis: Diese Funktion ist noch nicht implementiert. Abbildung 6: Kongurieren des Plugins 8 3 Architektur 3.1 Überblick Kern der Architektur bildet das Interface PrologEngine. Für jede der Prolog-Implementierungen sowie den Webservice existiert eine Implementierung dieses Interfaces. Über die Klasse PrologEngineFactory erzeugt die GUI eine Instanz einer Engine und lädt PrologProgramme sowie Anfragen an diese. Die GUI beinhaltet als zentrales Element die Klasse PrologEditor, die unter anderem die Methode query() besitzt. Über diese Methode werden die Anfragen gestellt. Der PrologEditor ermittelt dabei zunächst aus der Klasse PrologEngines die aktuell ausgewählte Engine und erzeugt dann mittels der PrologEngineFactory eine Instanz derselben, um dann mit der Methode query() das aktuell im Editor stehende Programm sowie die im QueryView eingebene Anfrage an die Engine abzusenden. 3.2 Grobe UML-Darstellung der Architektur Abbildung 7: Überblick über die Architektur des Projektes 9 4 Die Packagestruktur Der Quellcode des gesamten Projekts (Verzeichnis src) liegt im Package de.l3s.j2p.*. In diesem Package gibt es folgende Unterverzeichnisse: • cong enthält den Kongurator, der die XML-Datei liest und schreibt • engines enthält die Engines der einzelnen Prolog-Implementierungen und des Webser- vice-Clienten. • engines.factory enthält die Engine-Factory. Prolog-Implementierungen • interfaces enthält das primäre Interface PrologEngine, das zugehörige interface für den Webservice PrologEngineMarshable und zwei Interfaces, die zur Ausgabe der Prologausgaben auÿerhalb der Anfagen-Ergebnisse dienen. • plugin enthält alle für die GUI notwendigen Klassen: editors enthält den zentralen Editor der GUI. perspective hier wird die Prolog-Perspektive von Eclipse deniert. prference enthält alle Klassen, die zur Darstellung des Kongurationsdialogs nötig sind. views enthält die Klassen der Fenster (views) der GUI. wizards hier stehen die Assistenten zum Anlegen eines neuen Projekts bzw. zum Hinzufügen einer neuen Quelldatei. • server enthält den Server des Webservices. • test enthält die Testklassen. • util enthält die Klasse Strings zur Internationalisierung des Projektes sowie eine XML- Konverter für den Webservice. Im lib-Verzeichnis liegen die erforderlichen Java-Bibliotheken für das Eclipse- und Apache CFX-Framework sowie sie Bibliotheken der Java-basierenden Prolog-Implementationen und die von Interprolog. Das resource-Verzeichnis enthält Graken (Icons) der GUI. Die Datei plugin.xml auf Hauptebene im Verzeichnis deniert alle wesentlichen Elemente und Zusammenhänge des Eclipse-Plugins. Im testdata-Verzeichnis liegen einige Dateien mit Prolog-Programmen und Beispielanfragen, die von den Tests verwendet werden. In der Hauptebene des Projektes sind auÿerdem folgende Dateien abgelegt: • .classpath, .project, .texlipse Kongurationsdateien von Eclipse. • build.xml, build.properties Dateien zur Erstellung der einzelnen Perojektteile. • plugin.xml Zentrale Denitionsdatei des Plugins. • startup.sh, shutdown.sh Skripte zum Starten bzw. Stoppen des Webservice • java2prolog_de.properties, java2prolog_en.properties Internationalisierte Strings des Projektes Auÿerdem legt das Plugin bei seinem ersten Start im Workspace von Eclipse die Kongurationsdatei cong.xml an. In dieser Datei werden lokale Kongurationen gespeichert wie etwa die Pfade zu den Binärdateien der Prolog-Implementationen und die Adresse des Webservice. Der Zugri auf diese Datei erfolgt ausschlieÿlich durch die Klasse Conf. 10 5 Dokumentation der Klassen und Interfaces des Projektes 5.1 Erweiterte UML-Darstellung der Klassenstruktur Abbildung 8: Klassendiagramm von Java2Prolog 11 5.2 Die Interfaces 5.2.1 PrologEngine und PrologEngineMarshable Zentraler Bestandteil des Projektes ist das Interface PrologEngine, das von allen Engines implementiert wird. Es enthält folgende Methoden: public void load() (überladen) Die Methode load() lädt eine Wissensbasis in die Prolog-Implementation. public boolean execute() Die Methode execute() führt eine Anfrage einmal aus und gibt nur true oder false zurück. public ActionResult queryOnce() (überladen) Die Methode queryOnce() führt eine Anfrage einmal aus und gibt das erste Ergebnis im ActionResult zurück. public ActionResult queryAll() (überladen) Die Methode queryAll() führt eine Anfrage solange aus, bis alle Ergebnisse ausgegeben sind. Sie werden im ActionResult zurück gegeben. public void AssertRule() Die Methode AssertRule() fügt eine Regel zur Wissensdatenbank hinzu. public ActionResult retractOnce() (überladen) Die Methode retractOnce() entfernt eine angegebene Regel aus der Wissensdatenbank. public ActionResult retractAll() (überladen) Die Methode retractAll() entfernt alle mit der angegebenen übereinstimmenden Regeln aus der Wissensdatenbank. Auÿerdem existiert ein Interface PrologEngineMarshable. Die hier angegebenen Methoden sind die "Marshable"pendants zu den im PrologEngine Interface denierten Methoden, welche ohne m_ beginnen. Der Rückgabetyp der hier angegebenen Methoden ist ein String im XML Format. 5.2.2 PrologOutput und J2pOutputListener Die Prolog-Implementierungen geben auÿer den eigentlichen Antworten auf Anfragen weitere Meldungen (z.B. Debug-Ausgaben von write() oder Meldungen über das Kompilieren von Prolog-dateien) aus. Diese werden durch das vorgegebene Interface PrologEngine jedoch nicht erfasst und können daher auf diesem Wege auch nicht ausgegeben werden. Die Interfaces PrologOutput und J2pOutputListener dienen dazu, eben diese Ausgaben dem Eclipse-Plugin zur Ausgabe zur Verfügung zu stellen. Das Interface PrologOutput stellt eine Methode addOutputListener(J2pOutputListener l) zur Verfügung. Es wird von allen Engines implementiert. Mit dessen Hilfe können sich interessierte Objekte für den Output 'anmelden'. Dies wird vom Plugin in der Klasse de.l3s.j2p. plugin.editors.PrologEditor in der Methode query genutzt. Das Interface J2pOutputListener besitzt eine Methode processOutput(String output). Klassen, die diesen Output nutzen wollen, müssen dieses Interface implementieren. Dies geschieht ebenfalls in der Klasse PrologEditor. Dort gibt die processOutput()-Methode den Output in einer Eclipse Konsole aus. Es ist Aufgabe der einzelnen Engines, die Methode processOutput in passender Weise aufzurufen, so dass der ganze Output im Plugin ankommt. Dies geschieht in jeder Engine leicht unterschiedlich. Alle Engines haben jetzt eine LinkedList namens listeners, in der sich die angemeldeten Objekte benden. Die Methode addOutputListener() fügt neue Objekte in die Liste ein. Interprolog stellt ein Interface PrologOutputListener mit einer Methode print() zur Verfügung. Im Konstruktor melden sich die XSB- und SWI-Engines für diesen Listener an. In der print() Methode wird der Output einfach an alle Objekte in der Liste listeners weitergegeben. 12 Bei TU Prolog funktioniert dies genauso wie bei Interprolog, nur heiÿt das Interface OutputListener und die Methode onOutput(). Der output von JLog-Prolog wird in eine temporäre Datei geschrieben. Es existiert eine Methode sendOutput(), die in allen Methoden, die Output erzeugen können, aufgerufen wird und eventuell neu in der Datei hinzugekommenen Output an die angemeldeten Objekte weitergibt. 5.3 Aufbau des Eclipse-Plugins Zum Eclipse-Plugin-Teil gehören folgende Klassen: • de.l3s.j2p.plugin.Activator • de.l3s.j2p.plugin.editors.PrologEditor • de.l3s.j2p.plugin.editors.ReconcilingStrategy • de.l3s.j2p.plugin.perspective.PrologPerspective • de.l3s.j2p.plugin.preference.PreferenceContent • de.l3s.j2p.plugin.preference.PreferenceDialog • de.l3s.j2p.plugin.preference.PreferencePage • de.l3s.j2p.plugin.views.PrologEngines • de.l3s.j2p.plugin.views.QueryView • de.l3s.j2p.plugin.wizards.PrologWizard • de.l3s.j2p.plugin.wizards.PrologWizardPage Das Eclipse-Plugin enthält als Startklasse die Klasse Aktivator. Diese wird beim Start des Plugins aufgerufen und übernimmt egrundlegende Verwaltungsaufgaben. Die Oberäche des Plugins wird durch eine Perspektive (Layout) deniert. Diese ist in der Klasse PrologPerspective deniert. Hier werden die zur Perspektive zugehörigen Assistenten und Views (Fenster) angegeben. Innerhalb der Perspektive existieren mehrer Views (Fenster) mit speziellen Aufgaben, der Editor sowie eine oder mehrere Konsolen. Die Konsolen dienen der Ausgabe der Ergebnisse der Prolog-Anfragen sowie der sonstigen Ausgaben der einzelnen Prolog-Implementierungen. Die Klasse PrologEngines deniert das Fenster (View), in dem die aktiven PrologEngines ausgewählt werden können. In der Klasse QueryView wird das Fenster mit der Eingabezeile für Anfragen deniert. Diese Klasse verwaltet auch eine Liste mit vorherigen Anfragen, um diese ggf nochmals stellen zu können (Query-History). Auÿerdem ist hier ein Thread implementiert, in dem die Berechnung der Ergebnisse der Anfragen an ein Prolog-Programm durchgeführt wird. Der Thread kann durch einen Stopp-Button abgebrochen werden. Somit wird die programmstabilität im Falle einer Endlosschleife im Prolog-Programm oder einer zu komplexen Berechnung sichergestellt. Die Klasse PrologEditor enthält sämtlichen Code, der zur Darstellung des PrologQuelltextes relevant ist. Der Editor enthält zwei Unterklassen Conguration und Scanner. Diese sind für die Syntaxhervorhebung zuständig. Zusätzlich benden sich hier die Methoden zur Faltung der Methodenrümpfe. Ebenfalls für die Faltung wird die Klasse ReconcilingStrategy benötigt. Auÿerdem ndet sich in der PrologEditor-Klasse die Methode query(), die das PrologProgramm und im QueryView eingegebene Anfragen an die jeweils selektierte PrologEngine weitergibt. Die Klassen PreferenceContent, PreferenceDialog und PreferencePage enthalten den Code für die Darstellung des Kongurationsdialoges und für die Interaktion mit der 13 Kongurationsdatei. Dies geschieht über die Klasse Conf. Der Kongurationsdialog kann entweder als eigenständigen Fenster angezeigt werden (durch einen Klick auf 'Eigenschaften' im PrologEngines-View) oder als integrierte Kongurationsseite im Eclipse-Menü unter Window->Preferences...->Java2Prolog. Diese drei Klassen sind im folgenden Abschnitt beschrieben. Die Klasse PrologWizard deniert einen Assistenten, der eine neue Prolog-Datei dem jeweiligen Prolog-Prjekt hinzufügt. Der Aufbau des Assistenten ist in der Klasse PrologWizardPage deniert. Die Aktionen, die nach dem Sammeln der nötigen Informationen (Dateiname, Projekt) durch PrologWizardPage vorgenommen werden, stehen in der Methode doFinish() in der Klasse PrologWizard. 5.4 Der Kongurationsdialog Der Kongurationsdialog für das Plug-in besteht aus den drei Klassen PreferenceDialog, PreferencePage und PreferenceContent. 5.4.1 PreferenceDialog Die Klasse PreferenceDialog zeigt dem Benutzer nach einem Klick auf den Button Eigenschaften im PrologEngines-View einen Kongurationsdialog an. Sie enthält den Konstruktor PreferenceDialog(), der den Dialog önet. public Control createMessageArea(Composite parent) Diese Methode erstellt den Inhalt des Dialogs. protected void buttonPressed(int buttonId) Diese Methode überprüft, ob der OK-Button und nicht der Cancel-Button gedrückt wurde. Falls der OK-Button gedrückt wurde, wird die Cong-Datei aktualisiert und der Dialog geschlossen. 5.4.2 PreferencePage Die Klasse PreferencePage zeigt den Kongurationsdialog als Seite im Eintrag Preferences des Menüs Window an. protected Control createContents(Composite arg0) Diese Methode erstellt den Inhalt des Dialogs und entfernt den Default- und Apply-Button. Die Methode performOk() aktualisiert die Cong-Datei nach dem Drücken des OK-Buttons und schliesst den Dialog. 5.4.3 PreferenceContent Die Klasse PreferenceContent kapselt den Inhalt des Kongurationsdialogs und wird von den beiden anderen Klassen intern verwendet. Diese Hilfsmethode createContents() erstellt für jede Prologengine im zweiten Bereich des Kongurationsdialogs innerhalb einer Zeile die notwendigen Widgets, um die Engine kongurieren zu können. Dabei werden auch Selectionlistener hinzugefügt, die dem Benutzer die Angabe eines Pfads über einen Datei-Önen-Dialog ermöglichen und die verhindern, dass eine bereits deaktivierte Engine als Startengine ausgewählt wird. Die Hilfsmethode createPrologsGroups() setzt die Anzahl der Spalten und das Layout für den oberen, mittleren und unteren Teil des zweiten Bereichs des Kongurationsdialogs. Der Inhalt des Dialogs wird durch die Methode createContents() erzeugt. Die Hilfsmethode nameStrings() bestimmt am Anfang und nach dem Aktivieren und dem Deaktivieren einer Prologengine, welche Engines aktiv sind und daher in die Liste aller Einträge der Combo-Box, mit der man eine Startengine auswählen kann, aufgenommen werden können. Rückgabewert: Ein String-Array zum Setzen der Einträge der Combo-Box. Innerhalb der Cong-Datei setzt die Methode setProperties() eine Engine auf aktiv oder inaktiv und ihren Pfad oder ihre URL. 14 5.5 Die Prolog-Engines und die PrologEngineFactory Als Schnitstelle zwischen dem Eclipse-Plugin bzw. des Webservices und den einzelnen PrologImplementierungen existiert für jede Prolog-Implemenmtierung eine sogenannte PrologEngine. Hierzu gehören folgende Klassen: • de.l3s.j2p.engines.JLogPrologEngine: Engine für JLog-Prolog • de.l3s.j2p.engines.TUPrologEngine: Engine für tuProlog • de.l3s.j2p.engines.SWIPrologEngine: Engine für SWI-Prolog • de.l3s.j2p.engines.XSBPrologEngine: Engine für XSB-Prolog • de.l3s.j2p.engines.InterPrologAdapter: Abstakte Klasse als Schnittstelle mit In- terprolog. • de.l3s.j2p.engines.PrologEngineClient: Webservice-Client • de.l3s.j2p.engines.PrologEngineServer: Webservice-Server • de.l3s.j2p.engines.factory.PrologEngineFactory: Factory, die eine Instanz einer Engine erzeugt und diese zurückgibt • de.l3s.j2p.engines.PrologEngineException: Exception-Klasse für PrologEngine- spezische Exceptions Der Zugri auf die beiden direkt in Java programmierten Prolog-Engines tuProlog und JLogProlog erfolgt direkt durch die entsprechenden Engines. Diese waren zu Beginn des Projektes berits gegeben und wurden modiziert, um die Ausgabe von Rückgaben neben den eigentlichen Ergebnissen der Prolog-Anfragen zu ermöglichen. Auf die beiden C++-basierenden Implementationen von Prolog, XSB- und SWI-Prolog wird nicht direkt, sondern über die Software 'Interprolog' zugegrien. Dazu existiert als Engine eine abstrakte Klasse InterPrologAdapter, die mit Interprolog kommuniziert. Die Engines für XSB-Prolog und SWI-Prolog erben jeweils von dieser Klasse und erweitern diese um implementationsspezische Details. Da XSB Prolog-Programme nur aus Dateien laden und nicht als Strings übergeben bekommen kann, werden diese in eine temporäre Datei gespeichert und dann von XSB geladen. Existierende Dateien werden ebenfalls in eine temporäre Datei kopiert, da XSB unter unterschiedlichen Betriebssystemen nur bestimmte Dateiendungen verarbeitet. In den Engines für XSB- und SWI-Prolog existiert eine Methode parseVariables(), die die Variablen in Anfragen parst. Dadurch wird überprüft, ob in den Methoden des PrologEngineInterfaces, in denen Variablen von Interesse angegeben werden können, die angegeben Variablen überhaupt in der Anfrage vorkommen. Der Zugri auf den Webservice erfolgt über die Engine PrologEngineClient. Sie wird genau wie die übrigen Engines verwendet. Auf der Serverseite steht die Engine PrologEngineServer zur Verfügung. Diese implementiert nicht das Interface PrologEngine, sondern PrologEngineMarshable, das von PrologEngine abgeleitet ist um webservice-spezische Details erweitert wurde. Die Methoden, welche mit einem m_ beginnen, sind in dem Interface PrologEngineMarshable vordeniert. Da der Rückgabetyp 'ActionResult' des PrologEngine Interface aber nicht ohne weiteres über das Internet versandt werden kann, wird hier auf die Hilfsmethoden m_ zurückgegrien. Diese wandeln das ActionResult in einen XMLString um, so dass das ActionResult als XML-String über das Internet versandt werden kann. Instanzen einer Prolog-Engine werden mithilfe der Klasse PrologEngineFactory erzeugt. Diese stellt hierzu die Methode public static PrologEngine getEngine(Conf. PrologEngines engine) bereit. Sie liefert als Rückgabe eine Engine vom Typ PrologEngine zurück. 15 5.6 Die Konguratorklasse Conf Die Klasse Conf enthält alle notwendigen Methoden zum Zugri auf die Kongurationsdatei cong.xml. Diese wird zur Laufzeit dynamisch im Workspace-Verzeichnis von Eclipse erzeugt. Der interne Aufbau dieser Datei ist in Abschnitt 7 erläutert. Die Klasse Conf stellt folgende Methoden bereit: • public static String getProperty(int prop) liest eine Einstellung aus der Kongu- rationsdatei. Der Schlüssel wird als numerische Konstante übergeben. Die Konstanten sind ebenfalls in der Klasse Conf deniert. • public static void setProperty(int prop, String value) schreibt eine Einstellung in die Kongurationsdatei. Der Schlüssel wird als numerische Konstante übergeben. Soll ein Schlüssel gelesen werden, der nicht in der Kongurationsdatei deniert ist, wird stattdessen ein Standardwert zurückgegeben. Soll ein nicht existierender Schlüssel geschrieben werden, so wird dieser neu angelegt. 5.7 Die Klasse XMLConverter Die Klasse XMLConverter dient dazu, nicht-primitive Datentypen in das XML-Format und zurück zu konvertieren, um sie über den Webservice versenden zu können. • public static String actionResultToXML(ActionResult ar) wandelt ein über- gebenes ActionResult in eine XML-Struktur um und gibt diese als String zurück. • public static ActionResult XMLtoActionResult(String xml) wandelt den über- gebenen String wieder in ein Objekt vom Typ ActionResult um. 5.8 Die Klasse Strings Die statische Klasse Strings wird von allen Klassen importiert, die Meldungen in einer bestimmten Landessprache ausgeben. die Methode public static String get(String id) liefert dann einen String in der aktuell in der Konguratuion eingestellten Sprache zurück. 16 6 Der Webservice 6.1 Einleitung Der Webservice bietet die Möglichkeit, Prolog-Programme und -Anfragen über das Internet an einen entfernten Server zu senden. Dieser berechnet die Antwort auf die Anfrage und sendet diese an den Clienten zurück. Zur Übertragung über das Internet werden hierbei alle Datentypen in Strings umgewandelt und in einer XML-Struktur übertragen. Als Framework wurde bei der Implementierung des Webservices auf das Apache-CFX zurückgegrien, welches die Implementierung vereinfacht. Der eigentliche Webservice besteht lediglich aus der Serverklasse de.l3s.j2p.engines.PrologEngineServer. Dieser benötigt zusätzlich noch die Hilfsklasse de.l3s.j2p.util.XMLConverter. Zusätzlich benötigt der Server die XSB-Prolog-Engine. Der Client ist in der Klasse de.l3s.j2p.engines.PrologEngineClient implementiert, die ebenfalls den XMLConverter verwendet. Darüberhinaus greift der Webservice-Client auch auf die Konguratorklasse Conf und darüber auf die Kongurationsdatei cong.xml zu. Abbildung 9: Einbindung des Webservice in das Projekt 6.2 Der Webservice-Server Eine Instanz des PrologEngine Webservice wird erzeugt, indem man einen PrologEngineServer erzeugt. Wie auch bei der Erzeugung der anderen PrologEngines wird hier auf den Congurator und die Factory zurückgegrien. Als wichtigste Instanzvariable besitzt der PrologEngineServer eine Instanz einer PrologEngine 'p'. Diese wird im Konstruktor des Servers erzeugt. Voraussetzung für die Erzeugung des Servers ist eine laufende Prolog-Laufzeit Umgebung. Die Anfragen werden von der Instanzvariable 'p', welche eine PrologEngine Instanz ist, verarbeitet. Handelt es sich bei dem Ergebnis nicht um einen primitiven Datentyp, sondern um ein ActionResult, so wird dieses mit dem XMLConverter aus dem Package 'de.l3s.j2p.util' in einen XML String verwandelt und über das Internet an den Client zurückgesendet. 6.3 Der Webservice-Client Die Klasse PrologEngineClient implementiert das Interface PrologEngine. Jedoch werden im Gegensatz zu den anderen PrologEngine-Implementierungen die Anfragen nicht an lokale Prolog-Laufzeit-Umgebungen, sondern über das Internet an einen Webservice gesendet. Dies geschieht mithilfe der Instanzvariable im PrologEngineClient 'server'. Diese ist eine Instanz 17 von PrologEngineMarshable. Das Interface PrologEngineMarshable ist direkt vom Interface PrologEngine abgeleitet, bietet aber zudem noch einige Methoden, die bei der Übertragung über HTTP benötigt werden. Die Methoden des PrologEngine Interface, welche einen primitiven Datentypen (z.B. Integer, String oder Boolean) als Rückgabewert haben, können diesen direkt über http versenden, da das Apache-CFX Framework das Marshallen bereits übernimmt. Das Marshallen des Rückgabetyps 'ActionResult' übernimmt das Apache-CFX Framework nicht automatisch. Methoden, welche diesen Rückgabewert haben, besitzen daher ein Pendant im Interface PrologEngineMarshable, welche mit einem 'm_' gekennzeichnet sind. Diese haben als Rückgabetyp immer einen String. Sobald eine Methode mit dem Rückgabetyp 'ActionResult' vom PrologEngineClient aufgerufen wird, wird innerhalb der Methode das Pendant aufgerufen. Dieses sendet die Anfrage an den Webservice und bekommt das ActionResult (Ergebnis der Anfrage) als XML String zurückgeliefert. Dieser String wird mit dem XMLConverter aus dem de.l3s.j2p.util-Package in ein ActionResult zurückgewandelt und zurückgegeben. 6.4 Verwenden des Webservice-Servers 6.4.1 Voraussetzungen Der Webservice setzt eine laufende Java-Umgebung voraus. Er wurde erfolgreich mit der Java-Version JRE 1.6.0. unter Linux getestet. Möglicherweise arbeitet er auch mit früheren Versionen zusammen; dies kann jedoch nicht garantiert werden. Auÿerdem muss XSB-Prolog lauähig auf dem System installiert sein. Zum Betrieb werden weiterhin die Bibliothek j2pwebservice.jar sowie die Shellskripte startup.sh und shutdown.sh benötigt. 6.4.2 Starten des Webservice-Servers Der Webservice wird auf einem Linux-System über das mitgelieferte Shellskript 'startup.sh' im Hintergrund gestartet. Optional kann als Argument der Host und Port uebergeben werden, unter dem der Webservice gestartet werden soll. Der Default ist localhost und Port 9000. Auÿerdem muss im Shellskript der Pfad zur Binärdatei von XSB-Prolog angegeben werden. Nach dem Starten des Webservice wird die PID des Prozesses in die temporäre Datei 'j2p-webservice.pid' gespeichert. 6.4.3 Stoppen des Webservice-Servers Durch Aufruf des Shellskriptes shutdown.sh wird der Webservice-Server gestoppt. Dies geschieht, indem die PID des Servers aud der temporären Datei 'j2p-webservice.pid' ausgelesen wird und der Prozess anschlieÿend terminiert wird. Zum Schluss wird die temporäre Datei gelöscht. 18 7 Die Kongurationsdatei cong.xml Die Kongurationsdatei ist wie folgt aufgebaut: <?xml v e r s i o n ="1.0" encoding="UTF−8"?> <!DOCTYPE c o n f i g u r a t i o n > <c o n f i g u r a t i o n > <x s b p r o l o g e n g i n e > <punkt>f a l s e </punkt> <aktiv >true </aktiv > <name>XSB−Prolog </name> <pfad>D: \ xsb \ c o n f i g \x86−pc−windows\ bin \ xsb . exe </pfad> </x s b p r o l o g e n g i n e > <webservice > <punkt>f a l s e </punkt> <aktiv >true </aktiv > <name>Webservice </name> <url >http : / / l o c a l h o s t : 9 0 0 0 / prologEngine </url > </webservice > <sprache>de</sprache> <a k t i v e e n g i n e >TU−Prolog </a k t i v e e n g i n e > </ c o n f i g u r a t i o n > Jede Engine hat ihren eigenen Eintrag; hier ist nur der Eintrag für XSB-Prolog dargestellt. Für die anderen Engines heiÿt der Eintrag entsprechend. Die Einträge haben folgende Bedeutungen: • punkt (true/false) gibt an, ob die Engine am Ende einer Anfrage einen Punkt erwartet oder nicht. • aktiv (true/false) gibt an, ob die Engine zur Zeit verwendet werden kann, d.h. auf diesem System verfügbar ist. • name ist die Bezeichnung der Engine, wie sie im Plugin angezeigt wird. • pfad gibt den Pfad zur Binärdatei der Implementierung im lokalen Dateisystem an. Bei den Java-basierenden Prolog-Implementierungen entfallen die <pfad>-Einträge. Eim Webservice ist der Eintrag ähnlich, auÿer dass statt <path> <url> verwendet wird. Hier wird die komplette Adresse incl. Port des Webservice wie im obeigen Beispeil angegeben. Der Eintrag <sprache> gibt die verwendete Sprache der Menüs und Meldungen des Projektes an; hier sind Deutsch ('de') und Englisch ('en') implementiert. Über den Eintrag <aktiveengine> wird die bei Start des Plugins ausgewählte Engine ausgewählt. 19