Dokumentation zur betrieblichen Projektarbeit Fionn Ziegler - Fachinformatiker Fachrichtung Anwendungsentwicklung Modul-Entwicklung auf der NetBeans Rich-Client Plattform Entwicklung eines dynamisch ladbaren Moduls zur Verwaltung der Zugangsdaten für verschiedene Vergabeplattformen © 2008 Administration Intelligence AG, Würzburg Administration Intelligence AG Seite 2 von 37 Inhaltsverzeichnis 1 Vorwort 5 2 Einführung 6 2.1 Projektdefinition 6 2.2 Entscheidung für die NetBeans RCP 6 3 Grundbegriffe 8 3.1 NetBeans Rich-Client Plattform 8 3.2 System Filesystem 8 3.3 Package 9 3.4 Modul 9 3.5 Extension Points / Erweiterungspunkte 10 4 Projektkonzept / Zielsetzung 11 4.1 Projektziel 11 4.2 Konzeptphase 11 4.2.1 Modulkonzept 11 4.2.2 GUI-Konzept 12 4.2.2.1 Plattform-Übersichtstabelle 12 4.2.2.2 Plattform-Einstellungen 12 4.3 Persistenz 12 4.3.1 Java-DB 13 4.3.2 Hibernate und Java Persistence API 13 5 Implementierung 5.1 Datenbank 14 14 5.1.1 Peristenz NetBeans Modul 14 5.1.2 Datenmodell 14 5.2 Registrierung der TopComponent 14 5.3 GUI 16 5.4 Darstellung der Vergabeplattformen 16 5.4.1 PlatformTable 17 5.4.1.1 PlatformTableModel 17 5.4.1.2 PlatformTableCellRenderer 18 5.4.1.3 Mögliche Benutzer-Aktionen zum Öffnen des Plattform-Fensters 18 Administration Intelligence AG Seite 3 von 37 5.5 Auffinden der Modulimplementation 22 5.6 Webservice 24 5.6.1 Implementation serverseitig 24 5.6.2 Implementation clientseitig 25 5.7 Plattform Modul 25 5.7.1 Grafische Oberfläche (GUI) 26 5.7.2 Persistenz 26 6 Test 27 6.1 Modul-Auffindung 27 6.2 Persistenz-Test mit JUnit 27 7 Projektresumé 29 7.1 Soll-Ist-Vergleich 29 8 Literaturverzeichnis 30 9 Abbildungsverzeichnis 31 A. Glossar 32 B. Anhang 34 a) Skizzen 34 I. Übersichtstabelle 34 II. Plattform-Fenster 34 b) Klassendiagramm - PlatformOverview 36 c) Aktivitätsdiagramm 37 C. Erklärung 38 Administration Intelligence AG Seite 4 von 37 1 Vorwort 1 Vorwort In der EU werden jährlich ca. 1,5 Billionen Euro für öffentliche Aufträge ausgegeben, das entspricht etwa 15 % des Bruttoinlandsprodukts. Dadurch ist die elektronische Vergabe (Ausschreibung) eines der wichtigsten Themen für Unternehmen im öffentlichen Sektor, die Produkte und Dienstleistungen zur Ausschreibung anbieten. Potentielle Auftragsnehmer haben mit elektronischen Vergaben eine Reihe von Möglichkeiten, komplexe Prozesse zu optimieren und damit Zeit und Kosten zu sparen. 1 Das Problem ist jedoch, dass zur Zeit eine Vielzahl von unterschiedlichen Vergabeplattformen existieren und es pro Plattform auch nur eine spezielle Bietermanagement-Lösung gibt. Dadurch ergeben sich mehrere Probleme. Eine effektive Recherche über mehrere Vergabeplattformen ist daher schwierig bis unmöglich. Mitarbeiter der Unternehmen müssen mit unterschiedlichen Softwarelösungen und inhomogenen Angebotsformaten arbeiten. Diese Nachteile sind sicherlich ein Grund dafür, dass sich viele Unternehmen noch von dem Thema elektronische Vergabe fernhalten. Die Firma Administration Intelligence AG (AI-AG) will deshalb durch eine modulare Softwareanwendung Abhilfe schaffen. Anfang des Jahres hat die Planung und Entwicklung des Angebotsassistenten angefangen, die es einem Ausschreibungsteilnehmer (Bieter) ermöglichen soll, mit verschiedenen Vergabeplattformen zu kommunizieren und innerhalb eines elektronischen Vergabeprozesses digitale Angebote abzugeben. 1 Eine Vergabeplattform ist eine Webseite, auf der Bieter bzw. Interessenten Vergabe-Informationen erhalten können. Administration Intelligence AG Seite 5 von 37 2 Einführung 2 Einführung Rich Clients sind meist Frameworks, die durch Module und Plug-ins erweiterbar sind und auf denen die eigentliche Verarbeitung der Daten auf dem Client vollzogen wird. Rich Client Plattformen bieten die Möglichkeit, immer wiederkehrende Funktionen, insbesondere im Bezug der grafischen Benutzeroberfläche, zu vereinfachen. Eine der bekanntesten Plattformen ist die auf Java basierende NetBeans Platform (Rich Client Anwendungen werden im nächsten Kapitel näher erläutert).[Wiki08a] 2.1 Projektdefinition Ziel meines Abschlussprojektes ist es, auf Basis der NetBeans Platform eine Art Kontenverwaltung für die verschiedenen Vergabeplattformen zu entwickeln. Der Benutzer bekommt eine Übersicht über die verschiedenen Vergabeplattformen sowie die Möglichkeit, die Zugangsdaten und Verbindungsinformationen der Vergabeplattformen zu konfigurieren. Das Projekt gliedert sich in ein zentrales Core Modul, sowie mehrere Plattform-Module. Weiterhin können die Vergabeplattformen über einen Webservice abgerufen werden. Die Organisation der Vergabeplattformen sowie das Vorhalten gemeinsamer Schnittstellen, wird vom Core-Modul übernommen. Die Konfiguration der einzelnen Plattformen und dessen Zugangsdaten, sowie das Editieren und Speichern der jeweiligen Kommunikationsdaten muss jedoch in den einzelnen PlattformModulen geschehen, da diese sehr plattformspezifisch sein können. Weiterhin wird durch die strenge Modularisierung gewährleistet, dass Plattform-Module für neue Vergabeplattformen ohne weiteres implementiert werden können und somit die Funktionalität der Anwendung leicht erweitert werden kann. Das Projekt beinhaltet die Implementierung des Plattform-Moduls für die firmeninterne Vergabeplattform (im folgendem „AIPlatform“ oder „Plattform-Modul“ genannt). Die Entwicklung weiterer Plattform-Module würde den Zeitrahmen des Projektes sprengen. 2.2 Entscheidung für die NetBeans RCP Ein wichtiger Punkt am Anfang der Planungs-Phase war die Wahl des passenden Frameworks, das unseren Anforderungen entspricht. Bisher wurde in der AI-AG in der Entwicklungsumgebung Eclipse programmiert. Auch der neue Angebotsassistent sollte anfangs in Eclipse, mit eigenem modularem Framework (OSGI) und Rich Client Plattform (Eclipse-RCP), entwickelt werden. Einige Gründe sprachen jedoch gegen den Einsatz dieser Kombination, unter anderem eine aufwändige Konfiguration des modularen OSGI-Frameworks und außerdem die grafische Oberfläche SWT(Standard Widget 2 Toolkit) der Eclipse Rich Client Platform. Da alle firmeninternen Komponenten mit Swing entwickelt 3 wurden und diese nur über größere Umwege (über SWT-Swing bridge ) in die Rich Client Plattform von Eclipse einzubinden sind, fiel die Entscheidung gegen OSGI & Eclipse. 2 Swing ist eine Hilfsbibliothek von SUN zur Erstellung von grafischen Oberflächen. 3 Eine Brücke, um Swing-Oberflächen in einer SWT-Applikation anzeigen zu können. Benötigt viel Rechenleistung und Ressourcen. Administration Intelligence AG Seite 6 von 37 2 Einführung Die NetBeans Plattform hingegen bietet alle relevanten Merkmale, welche entscheidend für die Wahl der NetBeans Plattform waren: ● Verkürzung der Entwicklungszeit Durch zahlreiche NetBeans APIs für grafische Oberflächen, Persistenz und andere StandardsoftwareFunktionalitäten, kann sich der Entwickler vollständig auf die Geschäftslogik der Anwendung konzentrieren. ● Modularität / Wiederverwendbarkeit Die Anwendung kann durch spätere Anforderungen/Kundenwünsche mittels PlugIns bzw. Module erweitert werden, ohne Änderungen an der ganzen Software vorzunehmen. Module können mit einer Zip-Datei (*.nbm 'NetBeans module') installiert werden, entweder lokal oder über das Netzwerk. Außerdem kann die Software wie nach dem Baukasten-Prinzip, je nach Kundenwunsch bzw. Finanzmodell, aus Modulen zusammen gebaut werden. ● Flexible grafische Oberfläche Die NetBeans Rich-Client-Plattform erlaubt es, über eine XML-Datei (sog. Layer.xml) z.B. Menüs zu bearbeiten oder das Look-and-Feel anzupassen. Außerdem bietet NetBeans die Möglichkeit, die Oberflächen konsistent zu halten, wenn also ein User seine Komponenten innerhalb der Anwendung verschiebt oder die Größe des Fensters anpasst, werden diese Informationen gespeichert und beim nächsten Start der Anwendung wiederhergestellt. ● Swing Im Gegensatz zu der RCP von Eclipse (OSGI), welche SWT als grafische Oberfläche benutzt, basiert die NetBeans RCP auf Swing, genau wie unsere firmeninternen Bibliotheken. ● Plattform-Unabhängigkeit 4 Die NetBeans-Plattform kann auf allen Systemen benutzt werden, auf der eine JRE vorhanden ist. 4 Eine plattformspezifische Java Runtime Environment / Java Laufzeitumgebung beinhaltet eine Java Virtual Machine, die den Java-Bytecode in Maschinencode übersetzt und dann ausführt. Administration Intelligence AG Seite 7 von 37 3 Grundbegriffe 3 Grundbegriffe Dieses Kapitel erklärt einige Begriffe, die Grundlage für das Verständnis der NetBeans Rich-Client Plattform und insbesondere meines Projektes sind. 3.1 NetBeans Rich-Client Plattform „The NetBeans Platform allows applications to be developed from a set of modular software components called modules.“[Wiki08c] Auf Basis der NetBeans Rich-Client Platform können Desktop-Anwendungen erstellt werden. Die grundlegenden Anforderungen an eine Softwareanwendung wie z.B. Menüs, Toolbars, Datenverwaltung, Hilfesystem, Einstellungen etc. können mit Hilfe der RCP vereinfacht implementiert werden. Einer der wohl wichtigsten Aspekte der Rich-Client Plattform ist das Auffinden und Verwalten bestimmter Modul-Implementierungen. Abbildung 1 zeigt eine Anwendung, in der nur die Core-Module der NetBeans Platform geladen sind. Es kann durch eigenen Module erweitert werden, wodurch später eine separat installierbare Anwendung entsteht. Abbildung 1: RCP-Applikation ohne zusätzlich geladene Module 3.2 System Filesystem Die Konfiguration der RCP-Anwendung erfolgt über ein virtuelles Dateisystem, das durch XMLDateien namens layer.xml beschrieben wird. Dies ist ein zentraler Speicher für die NetBeans Konfiguration. Administration Intelligence AG Seite 8 von 37 3 Grundbegriffe Abbildung 2: Aufbau des System Filesystem Alle aktivierten/installierten Module melden ihre layer.xml im Konfigurations-System von NetBeans ('System Filesystem') an (siehe Abbildung 2). Aus allen „Layern“ ensteht dadurch eine XML-Datei, die für die Konfiguration der RCP-Anwendung benutzt wird. Im 'System Filesystem' werden beispielsweise die Toolbars aufgebaut, Menüpunkte erstellt und Actions definiert. In meinem Projekt habe ich mittels der layer.xml ein Menü 'Einstellungen' mit Unterpunkt 'Plattformen' erstellt. Außerdem wird definiert, welche Standard-Menüs und Toolbar-Icons (siehe Abbildung 1) nicht sichtbar sein sollen. 3.3 Package Ein Package ist ein Mechanismus, um Klassen in Namensräume zu organisieren. Klassen mit ähnlicher Funktionalität oder der gleichen Kategorie werden oft in einem Namensraum zusammengefügt. [Wiki08d] Außerdem erlaubt die Organisation in Packages, Sichtbarkeit von Klassen und Methoden einzuschränken. Ein Package repräsentiert ein Verzeichnis im Dateisystem. Eine Klasse im selben Package muss stets eindeutig sein, das bedeutet, dass Klassen auch den gleichen Namen haben können, solange sie sich in verschiedenen Namensräumen (Packages) befinden. Abbildung 3: Package 3.4 Modul Im Gegensatz zu nicht-modularer Software, werden Funktionen einer modularen Applikation in verschiedene Einheiten, repräsentiert durch Module, aufgeteilt. Dadurch können komplexe Programme in relativ eigenständige Einheiten (Module) gegliedert werden. Ziel der modularen Entwicklung ist es unter anderem, dem Prinzip der Abstraktion zu folgen. Eine Abstraktion beschreibt z.B. eine Funktionalität, blendet jedoch die Details der Implementierung aus. Mit der Abstraktion können verschiedene Problemstellungen, die in bestimmten Punkten gleich sind, zusammengefasst werden. Bei der Betrachtung eines Moduls, bzw. eines „Clusters“ (Sammlung von Modulen), ist es wichtig, dass einzelne Module bestimmte Funktionen eines Gesamtproblems übernehmen können. Also eine Art Aggregation: Ein Modul ist Teil eines Ganzen, kann aber auch ohne das Ganze existieren. Dabei kann ein Modul wiederum von anderen Modulen abhängig sein. Ziel ist es, Wiederverwendbarkeit und Erweiterbarkeit auch bei komplexen Applikationen auf längere Zeit zu gewährleisten.[Gal02] Administration Intelligence AG Seite 9 von 37 3 Grundbegriffe Manchmal ist es sinnvoll, Packages nach außen hin sichtbar zu machen, damit andere Module auf diese Klassen zugreifen können. Jedoch sollte vorsichtig damit umgegangen werden, weil es leicht unübersichtlich werden kann, wenn zu viele direkte Abhängigkeiten zwischen Modulen bestehen. In Java werden Module in Form von JAR-Bibliotheken dargestellt und bestehen gewöhnlich aus folgenden Teilen: ● Manifest-Datei (manifest.mf) ● Layer-Datei (layer.xml) (NetBeans spezifisch) ● Java-Klassen ● Ressources (Icons, Properties, Bundles etc.) In der NetBeans Terminologie gibt es keine fachlichen Unterschiede zwischen PlugIns und Modulen: Sie werden beide eingesetzt, um eine Software dynamisch um bestimmte Features bzw. Dienste zu erweitern. [Gal] „As an aside: in NetBeans terminology, "plug-in" is an adjective while "module" is a noun. There is no semantic difference between them„ [NBP] 3.5 Extension Points / Erweiterungspunkte Extension Points sind dann sinnvoll, wenn ein Algorithmus, bzw. eine Funktionalität dynamisch ausgetauscht oder erweitert werden soll. In meinem Projekt verwende ich Extension Points, um den Vergabeplattform-spezifischen Quellcode ansprechen zu können. Dies ist sinnvoll, da spätere Änderungen einer Plattform-Schnittstelle sich nicht auf den Angebotsassistenten auswirken, sondern nur auf das spezifische Plattform-Modul. Administration Intelligence AG Seite 10 von 37 4 Projektkonzept / Zielsetzung 4 Projektkonzept / Zielsetzung 4.1 Projektziel Das Ziel meines Projektes ist es, die Möglichkeit zu schaffen, Vergabeplattformen bzw. deren Zugangsund Verbindungsdaten, dynamisch zu verwalten und anderen Modulen zugänglich zu machen. Konkret sollen dem Bieter die Möglichkeiten geboten werden, verfügbare Vergabeplattformen in einem Übersichts-Fenster einzusehen, die Liste verfügbarer Plattformen von einem Server via Webservice zu synchronisieren und einzelne Plattformen zu konfigurieren. Als komplex erweist sich dabei die Konfiguration unterschiedlicher Vergabeplattformen, denn jede Plattform benötigt komplett unterschiedliche Verbindungsinformationen. Um das Programm dynamisch erweiterbar zu halten, kommt das Modul-Konzept von NetBeans zum Einsatz. Dieses Konzept ist auch für die Preisgestaltung der Software wichtig, denn der Bieter soll nur mit Vergabeplattformen kommunizieren können, wenn er das entsprechende Modul erworben hat. 4.2 Konzeptphase 4.2.1 Modulkonzept Es wurde ein Haupt-Modul (Core) angelegt, in dem Projekte, Angebote und Benutzer verwaltet werden können. Dieses Modul wird benutzt, um eine Übersichtstabelle der verfügbaren Plattformen, die von einem Webservice bereitgestellt werden, darzustellen. Jede Plattform hat einen bestimmten Typ, z.B. 'AIPlatform' oder 'eVergabe'. Durch diese ID wird der Plattform eine bestimmte ModulImplementierung zugeordnet. Für einen Vergabeplattform-Typ kann es mehrere Vergabeplattformen geben. Beispielsweise gibt es die AI-Vergabeplattform – Hessen, oder die AI-Vergabeplattform – EZB. Abbildung 4: Plattform-Module implementieren das Platform Interface Administration Intelligence AG Seite 11 von 37 4 Projektkonzept / Zielsetzung 5 Konkret funktioniert es folgendermaßen: Klickt der Benutzer auf eine Plattform im Core-Modul , wird über eine Hilfsklasse das entsprechende Modul gesucht und die Implementierung des PlattformInterfaces zurückgegeben. Ein Aktivitätsdiagramm zu diesem Vorgang befindet sich im Anhang (siehe Abbildung 16). 4.2.2 GUI-Konzept 4.2.2.1 Plattform-Übersichtstabelle Innerhalb der NetBeans Plattform ist es möglich, sogenannte TopComponents zu erstellen. TopComponents sind Fenster (Inkl. Position, Größe usw.), welche von der Plattform verwaltet werden. Der Aufbau wird in drei Bereiche getrennt: Im oberen Bereich ein Info Panel, im mittleren Bereich die Tabelle mit den Plattformen und im unteren Bereich ein Panel für die Buttons. Der rote Bereich hat eine statische Größe und ist immer sichtbar. Der grüne Bereich (Tabelle der Vergabeplattformen) ist in einer Scrollpane und somit dynamisch. Als Info-Panel gibt es schon eine vorgefertigte Komponente der Firma, die verwendet werden kann. Diese stellt einen gewünschten Infotext mit passendem Icon und Layout dar. Die Tabelle inkl. eigenem TableModel und TableCellRenderer (werden jeweils im nächsten Kapitel erläutert) werden selbst Abbildung 5: Top-Komponenten entwickelt. Genauso wie das Button-Panel mit den Layout ActionListenern usw. 4.2.2.2 Plattform-Einstellungen Wird in der Tabelle eine Plattform ausgewählt, öffnet sich ein Fenster, um die Plattform zu bearbeiten. In diesem Fenster sollen Daten wie z. B. Username, Passwort, Host, Port, Protokoll usw. eingegeben werden. Das Konfigurations-Panel soll in zwei Tabs - „Allgemein“ und „Erweitert“ unterteilt werden. Dies soll dazu führen, dass unerfahrene Benutzer nicht überfordert werden und trotzdem eine flexible Konfiguration gewährleistet wird. Konzeptskizzen beider GUI-Komponenten befinden sich im Anhang. 4.3 Persistenz „The Java Persistence API provides a POJO persistence model for object-relational mapping.“ [JPA08] Die Persistenz wird mit der Java-DB realisiert. Um eine Abbildung der Objekte auf Entitäten der Datenbank zu bekommen, wird JPA (Java Persistence API) verwendet, welches ein leichtgewichtiges Persistenz-Framework ist. Außerdem wird die Hibernate Implementierung der JPA verwendet. Mit Hilfe von Annotationen in den POJO (Plain Old Java Object) Klassen und der JPQL (Java Persistence Query Language) werden die entsprechenden Objekte mit kleinstmöglichem Aufwand persistiert. Die Einbindung der Java-DB in unserer Software erfolgt mittels Hibernate und JPA. Ein großer Vorteil der Java-DB ist es, dass sie nicht explizit installiert werden muss, sondern embedded in der Java5 Kernmodul des Angebotsassistenten. Administration Intelligence AG Seite 12 von 37 4 Projektkonzept / Zielsetzung 6 Runtime ausgeführt wird. Dies ist ein großer Vorteil gegenüber herkömmlichen DBMS , denn der Endbenutzer hat keinen administrativen Aufwand. [Unk02] Ziel dieser Kombination ist es, dem Entwickler eine objektorientierte Sicht auf Tabellen und Beziehungen in einer relationalen Datenbank zu bieten. 4.3.1 Java-DB Hinter Java DB verbirgt sich das relationale Datenbank-Managementsystem (RDBMS) Derby. Derby wird von SUN entwickelt und ist zu 100% in Java implementiert. Es funktioniert ganz nach dem Motto „Write Once Run Anywhere“ auf jedem Betriebssystem, für das es eine JRE gibt. Außerdem ist die Java DB sehr klein und schlank. Für die Embedded-Version, die im Projekt verwendet wird, ist keine Installation der Datenbank notwendig, da diese beim ersten Aufruf der Datenbank automatisch initialisiert wird. 4.3.2 Hibernate und Java Persistence API JPA wurde mit dem Ziel entwickelt, die besten Eigenschaften aus verschiedenen PersistenzFrameworks zusammenfliessen zu lassen. Die JPA ist eine Schnittstelle von der Anwendung zum eigentlichen Persistenz Framework (z.B. Hibernate). Der Anwendung ist es also egal, welches Persistenz-Framework sich hinter der JPA verbirgt. Durch Leichtgewichtigkeit und Schlankheit ist es besonders für Einzelplatzanwendungen geeignet. [Gal03] Java-Annotationen in den POJO's vereinfachen es dem Entwickler, Objektrelationen abzubilden. Durch JPQL (Java Persistence Query Language) muss auch kein Standard-SQL mehr angewandt werden. In dem Plattform-POJO (PlatformData.java) verwende ich beispielsweise Annotationen, damit die entsprechende Plattform-Tabelle nicht den Namen der Klasse hat, sondern den annotierten Namen: @Entity(name = "Platform") public class PlatformData { @Id @GeneratedValue private long iID; private String name; Die Annotation @ID besagt, dass die Klassen-Attribute 'iID' der PrimaryKey der Tabelle ist. Durch @GeneratedValue wird automatisch ein zufälliger, eindeutiger Wert erzeugt. Die JPQL-Abfrage, um alle Plattform Objekte von der Datenbank zu holen, ist dadurch folgende: select p from Platform p Es wird also nicht mehr mit den Relationen gearbeitet, sonder mit den Objekten. In der JPQL-Abfrage könnte man beispielsweise auch auf Felder des Objektes zurückgreifen (z.B.: „WHERE p.name='AI' “). 6 Datenbankmanagementsystem Administration Intelligence AG Seite 13 von 37 5 Implementierung 5 Implementierung 5.1 Datenbank 5.1.1 Peristenz NetBeans Modul Um den Zugriff zur Datenbank zentral zu halten, gibt es ein zentrales Modul, das den Zugriff zur Datenbank bereitstellt. Der Zugriff aus einem Modul erfolgt über die so genannte DAO-Schicht (Data 7 Access Objects Schicht). Diese kapselt den Zugriff auf die Datenbank. Aus dieser Schicht erfolgen die JPQL-Anweisungen an den Entity-Manager von JPA. 5.1.2 Datenmodell Aus der Plattformverwaltung (inkl. des AI-Plattform-Moduls) bildet sich folgendes Datenmodell: Abbildung 6: ER-Modell Tabellen Definition: Platform (Core-Modul) z.B.:Vergabeplattform Frankfurt am Main vom Typ 'AIPlatform' ● AIPlatformConnection (Plattform-Modul) Verbindungsdaten wie Port, Protokoll (http,https etc.) und Host zu einer Vergabeplattform. Pro Plattform kann es auch immer nur eine Connection geben. ● Login (Plattform-Modul) Beinhaltet Logindaten für eine Vergabeplattform. ● ● User (User-Modul) User aus der lokalen Anwendung; ein User kann auf verschiedenen Plattformen jeweils ein Login haben. 5.2 Registrierung der TopComponent „...TopComponent is a JComponent subclass which knows how to work with the NetBeans window system. If you want to add components to the main window, typically you will subclass TopComponent, using it the same way you would a JPanel“ Um eigene Fenster in NetBeans zu entwickeln, stellt die Windows System API die Klasse 8 TopComponent zur Verfügung. Top-Komponenten können in verschiedenen 'Modes' installiert werden und werden automatisch vom Window-Manager verwaltet. Der Window-Manager merkt sich jegliche Anpassungen an der GUI und stellt sie bei jedem Start wieder her. 7 Trennung der Geschäftslogik von der Datenschicht. 8 Definiert die Position des Fensters. Administration Intelligence AG Seite 14 von 37 5 Implementierung Meine Klasse PlatformOverviewTopComponent ist von org.openide.windows.TopComponent abgeleitet. Dabei können einige Methoden überschrieben werden, z.B. getName(), um dem Fenster einen Titel zu geben oder componentOpened(), um eine bestimmte Aktion beim Öffnen des Fensters auszuführen. Ansonsten verhält sich das Fenster wie gewohnt, da die Klasse TopComponent wiederum von JComponent abgeleitet ist. Damit das Fenster erfolgreich geladen wird, kommt das 'System Filesystem' und die layer.xml zum Einsatz. In der Layer-Datei wird die Komponente im Window-Manager angemeldet: <folder name="Windows2"> <folder name="Components"> <file name="PlatformOverviewTopComponent.settings" url="PlatformOverviewTopComponentSettings.xml"/> </folder> <folder name="Modes"> <folder name="explorer"> <file name="PlatformOverviewTopComponent.wstcref" url="PlatformOverviewTopComponentWstcref.xml"/> </folder> </folder> </folder> Das XML-Element „File“ repräsentiert ein Fenster, wovon es selbstverständlich auch mehrere geben kann. Im Folder „Components“ wird festgelegt, um welchen Typ es sich bei der Komponente handelt. Im Folder „Modes“ wird festgelegt, an welcher Position sich das Fenster befinden soll. Im Folder „explorer“ wird die Komponente links an den Rand eingestellt. Außerdem gibt es noch zahlreiche andere Modes wie z.B. „editor“, wenn das Fenster im „Hauptfenster“ angezeigt werden soll. Um eine Top-Komponente zu erstellen, hilft die NetBeans IDE mit einem Wizard, der folgende Dateien automatisch erstellt: Datei Zweck PlatformOverviewAction.java Eine Action, die das Fenster öffnet, wird automatisch der layer.xml im Folder „Menu“ hinzugefügt. Dadurch wird ein Menüpunkt angezeigt. Bei einem Klick darauf, wird die Action-Klasse aufgerufen. PlatformOverviewTopComponent.java Ist eine Sub-Klasse von der TopComponent und soll das Plattformübersichts-Fenster beinhalten. • • Diese beiden Dateien sind dafür da, um die TopKomponente richtig zu instanziieren und zu laden. Sie werden in der layer.xml registriert. PlatformOverviewTopComponentSettings.xml PlatformOverviewTopComponentWstcref.xml [Unk06] Administration Intelligence AG Seite 15 von 37 5 Implementierung 5.3 GUI Die Benutzeroberfläche wurde bewusst einfach, flexibel und intuitiv gehalten, um dem Benutzer die Einarbeitungszeit zu verkürzen. Außerdem wurden alle Buttons mit dynamisch konfigurierbaren Mnemonics (Tastenkürzel) versehen. Des Weiteren sind Informationen, die im Programm angezeigt 9 werden, in Properties-Dateien lokalisiert . 5.4 Darstellung der Vergabeplattformen Das Übersichtsfenster (PlatformOverviewTopComponent.java) setzt sich aus folgenden Bestandteilen zusammen: Typ-Beschreibung (siehe Abbildung 7): ● ContentPane : JPanel Ein Container für die drei anderen GUIElemente. Als Layout-Manager habe ich das BorderLayout gewählt, weil es für die Anforderungen aus der Analyse-Phase am besten geeignet ist. ● InfoPanel : JPanel Firmeninterne Klasse zum Anzeigen von Infopanels. Position: BorderLayout.NORTH ● OverviewPanel : JScrollPane Die PlatformTable wird in eine ScrollPane gelegt, damit es möglich ist zu scrollen, falls der Platz nicht ausreicht. Position: BorderLayout.CENTER ● ButtonPanel : JPanel Container für die Buttons der Übersichtstabelle. Position: BorderLayout.SOUTH Abbildung 7: Screenshot (Plattformübersicht) der TopComponent 9 Locales sind einzelne Sätze oder Wörter, die in der Software in irgendeiner Weise angezeigt werden. Diese werden ausgelagert, damit die Software auch mehrsprachig ausgeliefert werden kann. Administration Intelligence AG Seite 16 von 37 5 Implementierung 5.4.1 PlatformTable Die PlatformTable ist eine abgeleitete Klasse von XTable (firmeninterne Klasse mit einigen Hilfsfunktionen), diese erbt wiederum von der Swing-Klasse JTable10. 5.4.1.1 PlatformTableModel Die JTable benötigt ein Datenmodell, um die gewünschten Daten in der Tabelle anzuzeigen. Die eigene Klasse PlatformTableModel erbt von der abstrakten Klasse AbstractTableModel. Beispielsweise kann die Methode getColumnName(aColumn) mit der eigenen überschrieben werden. Dadurch können die Spaltenüberschriften definiert werden: (1)@Override (2)public String getColumnName(int aColumn){ (3) switch (aColumn){ (4) case 0: //icon (5) return " "; (6) case 1: //Platformname (7) return NbBundle.getMessage(PlatformTableModel.class, "Platform"); (8) default: (9) return ""; (10) } (11) } Zeile Aktion 1-2 Annotation und Methodenkopf mit Spalte als Übergabeparameter 3 Switch-Case Anweisung zur Unterscheidung der Spalten. 4-5 Case 0 ist die erste Spalte mit dem Icon. Es wird ein Leerstring zurückgegeben, da keine Überschrift nötig ist. 6-7 Case 1 soll die Überschrift der Vergabeplattform-Spalte besitzen. Der lokalisierte Wert für den Key "Platform" wird zuzrückgegeben. 8-9 Dieser Fall sollte nicht auftreten, da es nur 2 Spalten gibt. Außerdem werden weitere Methoden überschrieben: Überschriebene Methode / Definition getRowCount - Liefert die Zeilenanzahl. Beschreibung Dynamischer Wert: Es wird die Anzahl der vorhandenen PlatformData Objekte zurückgegeben. return iPlatformDataList.size(); getColumnCount - Liefert die Spaltenanzahl. Statischer Wert: zurückgegeben. Anzahl der vorhandenen Spalten wird 10 JTable ist eine Komponente von der Swing-Bibliothek, zur Darstellung von Tabellen. Administration Intelligence AG Seite 17 von 37 5 Implementierung return 2; getValueAt(int columnIndex) rowIndex, int In dieser Methode wird wieder eine Fallunterscheidung der Spalten (columnIndex) gemacht. Danach wird das PlatformData Objekt an der Position der Zeile(rowIndex) geholt, und ein Wert - Liefert den Wert einer Zelle. zurückgegeben. case 0: return case 1: return 5.4.1.2 //Spalte 1, icon iPlatforms.get(rowIndex).getURL(); //Spalte 2, name iPlatforms.get(rowIndex).getName(); PlatformTableCellRenderer Ein TableCellRenderer wird benötigt, um auch andere Elemente (Icons, Textbox etc.) als nur reinen Text in einer Tabelle darzustellen. Die erste Spalte in der Plattform-Tabelle soll das Icon der jeweiligen Plattform beinhalten. Im TableModel wird den Zellen der ersten Spalte eine URL des Bildes zugewiesen. Damit nicht die URL angezeigt wird sondern das Icon, wird folgende Methode von der Super-Klasse DefaultTableCellRenderer überschrieben: getTableCellRendererComponent(JTable table, Object value, boolean aIsSelected, boolean hasFocus, int row, int column) In der Super Methode wird der Zelle value.toString() zugewiesen, also die URL. Dies soll durch das Überschreiben der Methode im eigenem CellRenderer verhindert werden. Damit das Icon angezeigt wird, wird ein JLabel mit dem Icon zurückgegeben: ... ImageIcon imageIcon = new ImageIcon(new URL(value.toString())); tLabel.setIcon(imageIcon); return tLabel; 5.4.1.3 Mögliche Benutzer-Aktionen zum Öffnen des Plattform-Fensters 11 Damit es der User im Bezug auf Usability so einfach wie möglich hat und evtl. auch die vom Benutzer gewohnten Vorgänge zu ermöglichen, gibt es drei Möglichkeiten, um die Einstellungen der Vergabeplattform zu öffnen. Als Hilfe zeigt folgendes Klassendiagramm (siehe Abbildung 8) den Aufbau der Klassen und Interfaces der Tabelle, im Zusammenhang mit den jeweiligen Benutzerinteraktionen. (siehe auch Abbildung 15: Klassendiagramm - PlatformOverview im Anhang). 11 Usability: Benutzerfreundlichkeit der Software. Administration Intelligence AG Seite 18 von 37 5 Implementierung Abbildung 8: Klassendiagramm PlatformTable 1. Möglichkeit PopUp-Menü (TablePopupMenuProvider) Die Klasse PlatformTable implementiert das Interface TablePopupMenuProvider . Das Interface deklariert diese Methode: JPopupMenu getPopupMenu ( int aRow, int aColumn ); Die Implementation wird beim Initialisieren der Tabelle zugewiesen. setTablePopupMenuProvider(this); 12 Bei einem Klick mit dem PopupTrigger weiß die Tabelle, an welche Klasse sie das Event delegieren soll. Da die PlatformTable das Interface implementiert und der Tabelle mit setTabePopupMenuProvider das aktuelle Objekt zugewiesen wird, wird das Event an die PlatformTable weitergeleitet, in der es folgendermaßen behandelt wird: 12 Betriebssystem-spezifisches Maus-Event zum Öffnen des Kontextmenüs (Popup) Administration Intelligence AG Seite 19 von 37 5 Implementierung (1) public JPopupMenu getPopupMenu(final int aRow, int aColumn){ (2) JPopupMenu tPopupMenu = new JPopupMenu(); (3) JMenuItem tMenuItem= new JmenuItem( NbBundle.getMessage(PlatformTable.class , "Details"), (4) XButton.getDefaultButtonIcon(XButton.BUTTON_DETAILS)); (5) tMenuItem.addActionListener(new AbstractAction() (6) { (7) public void actionPerformed(ActionEvent e) (8) { (9) openPlatformDetails(iPlatforms.get(aRow)); (10) } (11) }); (12) tPopupMenu.add(tMenuItem); (13) return tPopupMenu; (14) } Zeile Aktion 1 Methodenkopf Deklaration mit Übergabeparametern(Zeile und Spalte der Tabelle). 2 Ein neues Kontextmenü wird erzeugt. 3-4 Ein Menüitem wird erzeugt und mit einem Locale als Beschriftung und einem Icon versehen. Die statische Methode Xbutton.getDefaultButtonIcon(XButton.BUTTON_DETAILS) liefert das firmeninterne gängige Icon für einen Details-Button. 5-11 Dem Item wird eine Aktion hinzugefügt, welche die Methode openPlatformDetails mit der gewählten Plattform als Parameter aufruft. Diese Aktion ist in Form einer anonymen inneren Klasse implementiert. Dies bedeutet, dass eine Sub-Klasse von AbstractAction erzeugt wird und durch die Methode actionPerformed erweitert wird. Diese wird aufgerufen, wenn der Benutzer auf das Popup-Menü-Item klickt. 12-13 Das Item tMenuItem wird dem Kontextmenü zurückgegeben. tPopupMenu hinzugefügt und 2. Möglichkeit Doppelklick (MouseListener) Außerdem besteht die Möglichkeit, den Dialog mit Doppelklick auf die gewünschte Vergabeplattform zu öffnen. Dafür implementiert die Klasse PlatformTable das Interface MouseListener. Bei jeglichem Klick auf die Tabelle wird die Methode mouseClicked aufgerufen. Administration Intelligence AG Seite 20 von 37 5 Implementierung (1) public void mouseClicked(MouseEvent aMouseEvent){ (2) if (aMouseEvent.getButton() == MouseEvent.BUTTON1 && aMouseEvent.getClickCount() >= 2){ (3) int tClickedIndex = super.rowAtPoint(aMouseEvent.getPoint()); (4) if (tClickedIndex != -1){ (5) openPlatformDetails(iPlatforms.get(tClickedIndex)); (6) }}} Zeile Aktion 1 Methodenkopf Deklaration mit dem Maus-Event als Parameter. 2 Auf Doppelklick prüfen 3 Die Methode rowAtPoint von der Super-Klasse JTable liefert die Zeilennummer, auf die geklickt wurde. 4 Prüfe ob Zeile gefunden (liefert -1 wenn keine Zeile gewählt wurde). 5 Methode openPlatformDetails mit der gewählten Plattform als Parameter wird aufgerufen. 3. Möglichkeit Buttonpanel (ActionListener) Der Dialog kann auch über das ButtonPanel geöffnet werden. Deswegen implementiert die Klasse PlatformOverviewTopComponent das Interface ActionListener. Dem Button im Panel wird der ActionCommand „details“ zugewiesen. Des Weiteren muss dem Button der ActionListener hinzugefügt werden, damit er weiß, wem er das Event schicken soll. In diesem Fall ist das die gleiche Klasse (this). Folgender Codeabschnitt zeigt die Behandlung des Events. (1) public void actionPerformed(ActionEvent e){ (2) String tActionCommand = e.getActionCommand(); (3) if ("refresh".equalsIgnoreCase(tActionCommand)) (4) {...} (5) else if ("details".equalsIgnoreCase(tActionCommand)){ (6) iTable.openPlatformDetails(iTable.getPlatforms().get(iTable.getSel ectedRow())); (7) } Zeile Aktion 1 Methodenkopf Deklaration mit dem Action-Event als Parameter. 2 Variable tActionCommand mit dem als Parameter gegebenen ActionCommand definieren. Dieser wird beim erstellen des Buttons definiert. 3-5 Abfrage auf verschiedene ActionCommands. 6 Methode openPlatformDetails mit der selektierten Plattform als Parameter wird aufgerufen. Administration Intelligence AG Seite 21 von 37 5 Implementierung 5.5 Auffinden der Modulimplementation Die Methode openPlatformDetails(PlatformData aPlatformData) in PlatformTable soll das passende 13 Plattformmodul finden und den Dialog dazu öffnen. Dazu war es nötig, eine Singleton Klasse zu entwickeln, die die Modulimplementation der passenden Plattform liefert. Wie es in Kapitel 4.2.1 auf der Abbildung 4 ersichtlich ist, implementiert eine Klasse aus dem Plattformmodul das Interface im Core-Modul. Das Interface Platform deklariert die Methoden, die jedes Plattform-Modul implementieren muss. Durch diese Abstraktion ist sichergestellt, dass sich die vorhandenen Plattformen an die Schnittstellen halten und damit das Core-Modul Funktionen der einzelnen Module verwenden kann, ohne die Implementierung der einzelnen Module kennen zu müssen. Damit ist eine unabhängige Implementierung der Plattform-Module möglich. Abbildung 9: Klassendiagramm Platform-Interface Mit der Lookup API stellt NetBeans einen Mechanismus bereit, mit dem Anbieter Dienste registrieren können und Konsumenten diese Dienste wieder finden können. [Jue08] In diesem Fall ist es notwendig, dass verschiedene Anbieter (z.B AIPlatformImpl) einen Dienst (vom Platform Interface) anbieten. Dadurch ist es gegeben, dass es für eine Schnittstelle mehrere Implementationen gibt. Details bzw. die Implementation selbst, bleiben dem Konsumenten (CoreModule) jedoch verborgen. Das Interface Platform im Core-Modul stellt somit ein Extension-Point dar, an dem sich beliebig viele Module registrieren können. Die Service-Provider bzw. die Anbieter (in dem Fall die Plattform-Module) müssen sich registrieren, damit sie vom Lookup gefunden werden. Dazu wird im Plattform-Modul ein Ordner 'METAINF/services' angelegt, mit einer Datei, die den kompletten Namen des Interfaces 13 Singleton bedeutet, dass die Klasse seine eigene Instanz hält und mit einer statischen Methode bereitstellt. Der Konstruktor ist private um sicherzustellen, dass keine externe Klasse eine Instanz erzeugt. Dadurch gibt es während der Laufzeit immer nur eine Instanz der Singleton-Klasse. Administration Intelligence AG Seite 22 von 37 5 Implementierung (de.sepp.offerassistant.core.api.Platform) hat. Der Inhalt der Datei hat den kompletten Namen der Implementation (de.sepp.offerassistant.aiplatform.AIPlatformImpl). [Gal03] Die Singleton-Klasse PlatformModuleFactory stellt die Methode findPlatformInstanceByImplID bereit. Sie soll die Implementation von einem gegebenen Plattform-Typ zurückgeben. Praktisch heißt das: Klickt der User auf eine Vergabeplattform, wird der Typ der Plattform (z.B.: „AIPlatform“) mitgegeben und mit folgendem Algorithmus wird die Implementation gesucht: (1)public Platform findPlatformInstanceByImplID(String aPlatformTypeID){ (2) Lookup.Template<Platform> tTmpl = new Lookup.Template<Platform> (Platform.class); (3) Collection<? extends Item<Platform>> allItems = Lookup.getDefault().lookup(tTmpl).allItems(); (4) for (Iterator<? extends Item<Platform>> tIterator = allItems.iterator(); tIterator.hasNext();) (5) { (6) Item<Platform> tItem = tIterator.next(); (7) if (tItem.getId().endsWith(aPlatformTypeID + "Impl") || (8) tItem.getId().endsWith(aPlatformTypeID)) (9) { (10) return tItem.getInstance(); (11) }} (12)return null;} Zeile Aktion 1 Methodenkopf mit dem Plattformtyp als String-Parameter(z.B. „AIPlatform“). 2 Es wird ein Template erstellt, welches besagt, dass das gesuchte Objekt das PlatformInterface implementiert. 3 In dieser Zeile wird nach den Implementationen gesucht und eine Collection14 mit allen registrierten Plattformen erstellt. Der Teil „<? extends Item<Platform>>“ besagt, dass die Collection nur Items vom Typ PlatformData beinhalten kann. 4 Iteration über alle Items in der Collection. 6 Das aktuelle Item der Collection wird in die temporäre Variable tItem geladen. 7-8 Zuerst wurde die Instanz von tItem geholt und dann über eine Methode der Instanz mit dem gegebenem Wert verglichen. Das war jedoch sehr unperformant, weil von jeder Plattform eine Instanz erzeugt wurde. Deswegen wird jetzt die ID der Implementation mit dem Typ verglichen, das heißt, die Impl-Klasse muss wie der Plattformtyp heißen bzw. mit „Impl“ am Ende. Beispiel: Parameter: „AIPlatform“, Modul-Implementation: „AIPLatformImpl“. 10 Die gesuchte Implementation wird zurückgegeben. 12 Wenn kein Plattform-Modul vom gegebenem Typ gefunden wurde, wird Null zurückgegeben. 14 Eine Collection ist ein Interface, welches von Klassen wie z.B. Arraylist, Vector usw. implementiert wird. Es ist ein Objekt, welches eine Anzahl von anderen Elementen hält. Administration Intelligence AG Seite 23 von 37 5 Implementierung Mit dem zurückgegebenem Objekt vom Typ Platform kann jetzt der Plattform-spezifische Dialog mit der Methode showConnectionDetails(...) aufgerufen werden (siehe Kapitel 5.7). 5.6 Webservice Die Kommunikation zwischen dem Angebotsassistenten und einem zentralem Server der Administration Intelligence AG erfolgt via Webservice. Als Gründe dafür zählen beispielsweise die zentrale Datenhaltung allgemeiner Informationen und die Bereitstellung verschiedener Funktionalitäten, wie das Suchen nach Vergaben/Auschreibungen auf mehreren Vergabeplattformen. Dadurch ist die Möglichkeit geschaffen, bessere Finanzmodelle einzubringen. Beispielsweise kann der Benutzer alle Vergabeplattformen synchronisieren. Um diese jedoch benutzen zu können, benötigt er das passende Plattform-Modul, welches er dann erwerben kann. Durch die Anforderung des Projektes wurde der Webservice um die Methode 'getAllPlatforms' erweitert, sie liefert alle Vergabeplattformen (PlatformData) und dessen Verbindungsinformationen (ConnectionData) als XML. Da die Synchronisation im Core-Modul stattfindet, können die PlatformData Objekte einfach in der Datenbank persistiert werden. Die ConnectionData Objekte, die beim Abruf vom Webservice noch aus reinem XML bestehen, werden an die installierten Plattform-Module weitergegeben. Nur diese wissen, wie der XML-Content ausgewertet werden kann. Das bedeutet, dass das Core-Modul den XML-Content einfach an die Plattform-Module weitergibt, ohne sie zu verändern bzw. zu verarbeiten. Im Plattform15 Modul wird der XML-Content dann deserialisiert und persistiert. 5.6.1 Implementation serverseitig Die Vergabeplattformen werden von der Administration Intelligence AG gepflegt und befinden sich in der Datenbank auf dem Server. Um an die PlatformData Objekte (repräsentieren jeweils eine Vergabeplattform) zu kommen, wurde in der DAO-Schicht eine weitere finder-Methode benötigt: (1) public List<PlatformData> findAllPlatforms() throws DAOFinderException{ (2) try (3) { (4) Query tQ = getEntityManager().createQuery("select p from PlatformData p"); (5) List<PlatformData> tPlatforms = tQ.getResultList(); (6) return tPlatforms; (7) } (8) catch (Exception aException) (9) { (10) String tMessage = "Error in Platform.findAll()..."; (11) throw new DAOFinderException(tMessage, aException); (12) }} Sie ähnelt sehr der Methode der Klasse PlatformDAO im Core-Modul. Die Funktionalität ist auch identisch, nur die Datenschicht ist eine andere. 15 Umwandlung von z.B. XML in ein Objekt. Administration Intelligence AG Seite 24 von 37 5 Implementierung Die Methode in der Webservice-Implementations-Klasse verwendet die Annotion @WebMethod, um die Methode als eine Webservice-Methode zu kennzeichnen. Diese ruft einfach die DAO-Methode auf und gibt das Ergebnis zurück: (1)@WebMethod (2)public List<PlatformData> getAllPlatforms() throws DAOFinderException (3){ (4) return iDAO.findAllPlatforms(); (5)} 5.6.2 Implementation clientseitig 16 Durch hilfreiche Tools wie wsdl2java wird es mit Java sehr einfach gemacht, Clients für SOAP-JAXWebservices zu erstellen. Dementsprechend war auch die Implementation des Clients kein großer Aufwand, da durch wsdl2java automatisch Hilfsklassen für den Webservice-Zugriff erstellt werden. In der Klasse AIWebServiceInformationReceiver werden folgende vier Code-Zeilen ausgeführt, um alle Vergabeplattformen vom Webservice abzurufen. Des Weiteren werden diese über die DAO-Schicht persistiert. (1)... (2) PlatformServiceServiceLocator tLoc = new PlatformService ServiceLocator(); (3) PlatformService tServ = tLoc.getPlatformServicePort(); (4) PlatformData[] tList = tServ.getPlatforms(); (5) getPlatformDAO().persistAll(tList); (6)... 5.7 Plattform Modul Aus dem Core-Modul wird nach dem Suchen des entsprechenden Plattform-Moduls die Methode showConnectionDetails mit dem Parameter 'PlatformID' aufgerufen. Diese Methode ist in der Klasse AIPlatformImpl implementiert. Die Funktionalität der Methode besteht darin, dass nach einem vorhandenem persistiertem Datensatz anhand der 'PlatformID' gesucht wird und falls einer vorhanden ist, wird er an die GUI weitergegeben. Die einzelnen Plattform Module sind komplett unabhängig voneinander, das bedeutet, dass es möglich ist, dynamisch zur Laufzeit weitere Plattform-Module zu installieren. 16 Generiert aus einem WSDl-Dokument (XML) Java-Sourcecode Klassen. Administration Intelligence AG Seite 25 von 37 5 Implementierung 5.7.1 Grafische Oberfläche (GUI) Das Fenster, in dem die Plattform-Konfiguration angezeigt wird, basiert auf Swing. Der Aufbau bildet sich wie folgt: Typ-Beschreibung (siehe Abbildung 10): ● ContentPane : JPanel Layout: BorderLayout ● InfoPanel : JPanel Firmeninterne Klasse zum Anzeigen von Infopanels. Position: BorderLayout.NORTH ● ConfigurationPane : JTabbedPane Ist ein Container für verschiedene Seiten mit mehreren Tabs. Position: BorderLayout.CENTER ● TabContentPane : JPanel Panel für den Inhalt der einzelnen Tabs. Abbildung 10: Plattform-Fenster ● ButtonPane : JPanel Panel für die Buttons. Layout: BoxLayout (Vertikal) Position: BorderLayout.SOUTH Unter dem Tab 'Erweitert' (siehe Abbildung 11) befinden sich Informationen über die Kommunikation mit der Vergabeplattform (Host, Port, Protokoll etc.). Abbildung 11: Reiter 'Erweitert' 5.7.2 Persistenz Die beiden Tabs 'Allgemein' und 'Erweitert' repräsentieren die GUI-Schicht der Java-Objekte 'LoginData' und 'AIPlatformConnectionData'. Diese beiden POJO's werden nach dem Klick auf „OK“ über die DAO-Methode perist(POJO) peristiert. Da die Verbindungsdaten auch editierbar sind, aber auch wiederherstellbar sein sollen, werden die Verbindungsdaten redundant gespeichert. Einmal in der Tabelle 'Platform' des Core-Module als XMLString und einmal im Plattform-Modul als AIConnectionData Objekt. Dadurch kann der User, falls er die entsprechenden Rechte besitzt, die Verbindungsinformationen 'AIConnectionData' bearbeiten. Löscht der User versehentlich Daten, können die originalen Daten durch einen Standard-Button aus dem Core-Modul wiederhergestellt werden. Administration Intelligence AG Seite 26 von 37 6 Test 6 Test 6.1 Modul-Auffindung Wenn das Produkt einmal produktiv wird, kann es bis zu 10 verschiedene Plattform-Module (und bis zu 40 Vergabeplattformen je Modul-Typ) geben, daher habe ich eine zweite „Dummy-Plattform“ erstellt. Dadurch konnte die Modul-Auffindung usw. getestet werden. Außerdem habe ich das dynamische Laden von Plattform-Modulen getestet, wodurch ich feststellen konnte, dass eine entsprechende Fehlermeldung erscheint, wenn ein gesuchtes Modul nicht aktiviert/installiert ist. 6.2 Persistenz-Test mit JUnit Die Speicherung der PlatformData Objekte vom Webservice soll ein JUnit-Test automatisch testen. Dabei werden die JUnit-Klassen und Dateien explizit von dem ausgelieferten Source-Code getrennt. „»Once«, said Mock Object at last, with a deep sigh, »I was a real object».“17 Die einzelnen Tests sollen so isoliert wie möglich ablaufen. Um dies zu gewährleisten, werden für die 18 Ausführung der zu testenden Klassen benötigten Infrastruktur-Objekte durch Mock-Objekte (auch Platzhalter- oder 'Dummy'-Objekte genannt) simuliert. Beim Unit-Test der Persistenz wird die Webserviceanbindung des Programmes durch solch ein Platzhalterobjekt ersetzt, da ein laufender Webserver, eine Internetverbindung, sowie korrekte Daten nicht garantiert werden können. Innerhalb der Tests sollen Objekte, die von dem Platzhalterobjekt kommen, gespeichert und wieder geladen werden. Sind die Ergebnisse gleich, kann davon ausgegangen werden, dass die Persistenzschicht korrekt funktioniert. Einzelne Tests werden in der Test-Klasse TestPlatformPersistence, die von junit.framework.TestCase abgeleitet ist, implementiert. 17 Zitat aus http://www.dpunkt.de/leseproben/3-89864-325-5/Kapitel_6.pdf 18 Diese werden normalerweise, während der Ausführung der Softwareanwendung, automatisch erstellt. Administration Intelligence AG Seite 27 von 37 6 Test (1)/** (2) * Test persistence (3) */ (4) @Test (5) public void testGetPlatformDataList() { (6) System.out.println("persistence test with Platform objects"); (7) PlatformDAO.deletePlatformData(); (8) List<PlatformData> expResult = AIWebServiceInformationReceiver.getInstance().getPlatforms(); (9) PlatformDAO.insertPlatformData(expResult); (10) List<PlatformData> result = PlatformDAO.getPlatformDataList(); (11) assertEquals(expResult, result); (12)} Zeile Aktion / Beschreibung 1-3 Java-Dokumentation der Methode(Javadoc). 4 JUnit-Annotation, damit die Methoden als Test-Methode deklariert wird. 5 Methodenkopf (<<Sichtbarkeit>> <<Rückgabetyp>> <<Name>>) 7 Alle Plattformen aus der Datenbank löschen. 8 Liste von Platform-POJO's wird vom Webservice geholt und in der temporären Variable expResult (engl.: expected result) zwischengespeichert. 9 Speichern der PlatformData Objekten in der Datenbank. 10 In dieser Zeile werden die Plattform-Objekte wieder aus der Datenbank geholt und in der Variable result gespeichert. 11 Mit der Methode assertEquals wird geprüft, ob das Ergebnis (result) dem erwarteten Ergebnis (expResult) entspricht. Durch ein gute Einbindung des JUnit-Frameworks in NetBeans können Unit-Tests sehr komfortabel geschrieben und ausgewertet werden. Weiterhin werden die bestehenden Tests in Test-Suites organisiert, wodurch die komplette Anwendung in regelmäßigen Abständen automatisch getestet werden kann. Abbildung 12: JUnit Testergebnis Administration Intelligence AG Seite 28 von 37 7 Projektresumé 7 Projektresumé 7.1 Soll-Ist-Vergleich Zeit Projektphasen Aufgaben Analysephase ● ● ● ● ● Implementierungsphase ● ● ● ● ● ● Testphase Soll Ist Durchführung einer Soll-Analyse und Besprechung 8 der Schnittstellen Plug-in Details Anforderung an die GUI Datenpersistenz Analyse der NetBeans Platform 11 Plug-in Gerüst anlegen/entwickeln Allgemeine Programmlogik Eingabemasken erstellen Webservice serverseitig Webservice clientseitig Persistenz 44 41 5 5 13 13 70 70 Testen des separaten Moduls Persistenz-Test ● Webservice-Test ● Testen im Angebotsassistent (White-Box-Test) ● ● Dokumentation ● Erstellen der Projektdokumentation Grund für die Abweichungen der zeitlichen Faktoren in der Analysephase, ist die etwas aufwändige Einarbeitung in die NetBeans Plattform sowie die teilweise schlecht dokumentierte API. Durch die relativ einfache Einbindung und Entwicklung des Webservices hat die Implementierungsphase 3 Std. weniger gedauert. Administration Intelligence AG Seite 29 von 37 8 Literaturverzeichnis 8 Literaturverzeichnis • [Wiki08a] Unknown, Fat Client, http://de.wikipedia.org/wiki/Rich-Client • [Wiki08c] Unknown, NetBeans, „The NetBeans Platform allows applications to be developed from a set of modular software components called modules.“ • [Wiki08d] Wikipedia, Java package, http://en.wikipedia.org/wiki/Java_package • [Gal02] Kathrin Hilz, Analyse der Netbeans Rich Client Plattform • [Gal] Bernhard Lahres, Gregor Raýman, Praxisbuch Objektorientierung, http://www.galileocomputing.de/openbook/oo/oo_06_moduleundarchitektur_000.htm • [NBP] Unknown, NetBeans feedreader_background.html • [JPA08] http://platform.netbeans.org/tutorials/60/nbm- Unknown, Java Persistence API, http://java.sun.com/javaee/technologies/persistence.jsp • [Unk02] Unknown, JavaDB it.ch/java/javadb_grundlagen.html • [Gal03] Platform, / Derby Grundlagen, http://scherer- Heiko Böck, NetBeans Platform 6 • [Unk06] Unknown, http://wiki.netbeans.org/DeveloperDocumentation DeveloperDocumentation, • [Jue08] Jürgen Petri, NetBeans RCP - Das Entwicklerheft • [Wap08] Wapedia, Annotation (Java), http://wapedia.mobi/de/Annotation_(Java) • [wiki08] Wikipedia® , JAX-WS, http://de.wikipedia.org/wiki/JAX-WS • [Wiki08b] Unknown, OSGI, http://de.wikipedia.org/wiki/OSGi • [Tor05] Torsten Horn, SOAP, http://www.torsten-horn.de/techdocs/soap.htm Administration Intelligence AG Seite 30 von 37 9 Abbildungsverzeichnis 9 Abbildungsverzeichnis Abbildung 1: RCP-Applikation ohne zusätzlich geladene Module...........................................................8 Abbildung 2: Aufbau des System Filesystem...........................................................................................9 Abbildung 3: Package...............................................................................................................................9 Abbildung 4: Plattform-Module implementieren das Platform Interface................................................11 Abbildung 5: Top-Komponenten Layout................................................................................................12 Abbildung 6: ER-Modell........................................................................................................................14 Abbildung 7: Screenshot der TopComponent (Plattformübersicht)........................................................16 Abbildung 8: Klassendiagramm PlatformTable......................................................................................19 Abbildung 9: Klassendiagramm Platform-Interface...............................................................................22 Abbildung 10: Plattform-Fenster............................................................................................................26 Abbildung 11: Reiter 'Erweitert'.............................................................................................................26 Abbildung 12: JUnit Testergebnis..........................................................................................................28 Abbildung 13: Skizze: Plattformübersichts-Dialog................................................................................34 Abbildung 14: Skizze Plattform-Dialog.................................................................................................35 Abbildung 15: Klassendiagramm - PlatformOverview...........................................................................36 Abbildung 16: Aktivitätsdiagramm - Plattform-Fenster anzeigen..........................................................37 Administration Intelligence AG Seite 31 von 37 9 Abbildungsverzeichnis A. Glossar Abstraktion Abstraktion bedeutet die Reduktion eines Problems auf relevante Informationen und das Weglassen unwichtiger Details. API(Application Programming Interface) Eine Programmierschnittstelle zu anderen Bibliotheken. Annotationen Ein Annotation-Processor ist ein Compiler-Plugin, das Annotationen (Metainformationen) beim Compilieren auswerten kann, um damit Warnungen und Fehlermeldungen zu unterdrücken oder weiteren Quellcode bzw. andere Dateien zu generieren. [Wap08] BorderLayout Das BorderLayout ist ein Layoutmanager, welcher dazu dient Komponenten wie Buttons, Eingabefelder, Panels usw. in einer bestimmten Art und Weise anzuordnen. Mit diesem Layoutmanager ist es möglich, die Komponenten nach Himmelsrichtungen, wie SOUTH, WEST, EAST usw., anzuordnen. Entität Als Entität bezeichnet man in der Informatik ein eindeutig bestimmbares Objekt. Im Bezug auf Datenbanken repräsentiert dieses Objekt einen Datensatz, der meist einmalig ist. GUI Graphical User Interface = grafische Benutzeroberfläche Interface Ein Interface zu Deutsch: Schnittstelle, definiert Methoden (Name, Rückgabetyp, Parameter usw.), die aber von anderen Java-Objekten implementiert werden. JAX-WS „JAX-WS (Java API for XML - Web Services) wurde in der Java Platform Enterprise Edition 5 eingeführt und ist eine Java API zum Erstellen von Web Services. Wie andere Java EE APIs benutzt auch JAX-WS Annotationen, um die Entwicklung und das Deployment von Web Service Clients und Service Endpunkten zu vereinfachen.“[wiki08] JUnit JUnit ist ein Framework, mit dem es möglich ist, Tests von Programmeinheiten (Module) zu entwicklen und durchzuführen. Es wird ein Test mit vordefinierten Werten gestartet, welches ein bestimmtes Ergebnis erwartet. Administration Intelligence AG Seite 32 von 37 9 Abbildungsverzeichnis Look & Feel Das Look & Feel (kurz: L&F) bestimmt das Aussehen der Komponenten wie Fenster, Buttons usw. Standardmäßig wird das Look & Feel des vom Benutzer eingestellten Themas des Betriebssystems genutzt. So schaut die gleiche Applikation beispielsweise auf einem Mac Rechner anders aus, als auf einem Rechner mit einem Windows Betriebsystem. Allerdings ist es auch möglich, mit einem eigens erstellten L&F eine komplett andere Darstellung von Komponenten zu erzeugen. OSGI „Die OSGi Alliance (früher "Open Services Gateway initiative") spezifiziert eine hardwareunabhängige dynamische Softwareplattform, die es erleichtert, Anwendungen und ihre Dienste per Komponentenmodell ("Bundle"/"Service") zu modularisieren und zu verwalten ("Service Registry"). Die OSGi-Plattform setzt eine Java Virtual Machine (JVM) voraus und bietet darauf aufbauend das OSGiFramework.“ [Wiki08b] Persistenz Dauerhafte Speicherung von Daten. POJO Plain Old Java Object = ein einfaches Java-Objekt meist im Bezug auf Datenhaltung → ein POJO repräsentiert ein Datensatz. SOAP Simple Object Access Protocol ist ein Protokollstandard des W3C und ist unabhängig von Betriebssystemen, Programmiersprachen und Objektmodellen, kann verschiedene Plattformen verbinden (z.B. .NET und Java).[Tor05] Swing Ist eine Sammlung von Java-Bibliotheken, die für die Erstellung von grafischen Oberflächen verwendet werden kann. WSDL Web Services Description Language beschreibt einen Webservice und seine Methoden, Parameter, Datentypen usw. XML Extensible Markup Language definiert, wie Daten strukturiert in Textdateien gespeichert werden. Ähnlich wie HTML nur wesentlich dynamischer. Administration Intelligence AG Seite 33 von 37 9 Abbildungsverzeichnis B. Anhang a) Skizzen I. Übersichtstabelle Abbildung 13: Skizze: Plattformübersichts-Dialog II. Plattform-Fenster Abbildung 14: Skizze Plattform-Dialog Administration Intelligence AG Seite 34 von 37 9 Abbildungsverzeichnis b) Klassendiagramm - PlatformOverview Abbildung 15: Klassendiagramm - PlatformOverview Administration Intelligence AG Seite 35 von 37 9 Abbildungsverzeichnis c) Aktivitätsdiagramm Abbildung 16: Aktivitätsdiagramm - Plattform-Fenster anzeigen Administration Intelligence AG Seite 36 von 37 9 Abbildungsverzeichnis C. Erklärung Hiermit erkläre ich, dass ich diese Dokumentation selbständig verfasst und keine anderen als die angegebenen Quellen oder Hilfsmittel benutzt habe. Würzburg, den 15.06.2008 Administration Intelligence AG Fionn Ziegler Seite 37 von 37