Leopold-Franzens-Universität Innsbruck Institut für Informatik Datenbanken und Informationssysteme Dynamisches RIA Informationssystem Bachelor-Arbeit Philip Krauss betreut von Michael Borovicka Innsbruck, 16. März 2012 Zusammenfassung Datenbankanwendungen sind aus dem Alltag nicht mehr wegzudenken. Die Entwicklung benötigt viel Aufwand sowie fundierte Kenntnisse der verfügbaren Technologien. Die Wiederverwendbarkeit einer Datenbankanwendungen ist minimal. Durch den Einsatz von unterschiedlichen Konzepten wird hier eine Basis geschaffen, welche durch Konfiguration komplexe Datenbankanwendungen abbilden kann. Diese Basis adaptiert sich dynamisch an den Schemas der Datenbank. Folglich kümmert die Basis sich um den dynamischen Aufsatz, sprich die Datenbankabbildung. Das impliziert dass man Datenbankanwendung durch triviale Konfigurationen entwickeln kann. Abstract Database applications are part of our day to day use. The development of such applications requires a large amount of time as well as proficient understanding of the related technologies. The application logic is similar and yet not reusable due the database schemes. The deployment of a variety of concepts builds a foundation, which can produce complex database application by configuration. The foundation adapts itself dynamic according to the logic of the scheme. Thus takes the foundation care of it’s dynamic attachment, the database visualization. This implies that database applications can be developed with trivial configurations. Inhaltsverzeichnis Abbildungsverzeichnis VIII Tabellenverzeichnis IX Quellcodeverzeichnis XI 1 Einleitung 1.1 Generik . . . . . . . . . . 1.2 Basis-Aufsatz System . . 1.3 Bestehender Prototyp . . 1.4 Rich Internet Application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 Analyse 2.1 Bestehender Prototyp . . . . . . . . . . . . 2.2 Technologien in Webapplikationen . . . . . 2.2.1 HyperText Markup Language . . . . 2.2.2 Cascading Style Sheets . . . . . . . . 2.2.3 Extensible Markup Language . . . . 2.2.4 JavaScript Object Notation . . . . . 2.2.5 Web Services . . . . . . . . . . . . . 2.2.6 JavaScript . . . . . . . . . . . . . . . 2.2.7 Asynchronous JavaScript and XML 2.2.8 Representational State Transfer . . . 2.3 Programmiersprachen . . . . . . . . . . . . 2.3.1 Java . . . . . . . . . . . . . . . . . . 2.3.2 PHP . . . . . . . . . . . . . . . . . . 2.3.3 Ruby On Rails . . . . . . . . . . . . 2.4 Model View Controller Frameworks . . . . . 2.5 Datenbanken . . . . . . . . . . . . . . . . . 2.5.1 Relationale Datenbanksysteme . . . 2.5.2 Schemafreie Datenbanksysteme . . . III . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1 1 2 4 . . . . . . . . . . . . . . . . . . 5 5 6 6 7 7 8 9 9 9 10 10 10 11 11 12 12 12 13 INHALTSVERZEICHNIS 3 Eingesetzte Technologien 3.1 Eingesetzte Technologien in Webapplikationen . 3.1.1 Asynchronous JavaScript and XML . . 3.1.2 Web Services . . . . . . . . . . . . . . . 3.1.3 REST Schnittstellen . . . . . . . . . . . 3.2 JavaScript . . . . . . . . . . . . . . . . . . . . . 3.2.1 Datenaustauschformat . . . . . . . . . . 3.3 Die Programmiersprache Java . . . . . . . . . . 3.3.1 Java API for RESTful Web Services . . 3.3.2 Apache Tomcat . . . . . . . . . . . . . . 3.3.3 Apache Maven . . . . . . . . . . . . . . 3.3.4 Hibernate . . . . . . . . . . . . . . . . . 3.4 Datenbanken . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 15 15 15 16 16 17 17 18 19 19 20 20 4 Architektur 4.1 Abbildung der Generik . . . . . 4.2 Entity Relationship Diagramm 4.3 Softwarearchitektur . . . . . . . 4.3.1 Komponenten . . . . . . 4.3.2 Persistenzschicht . . . . 4.3.3 Kontrollerschicht . . . . 4.3.4 Präsentationsschicht . . 4.4 Client-Server Architektur . . . 4.5 Web Service Schnittstellen . . . 4.6 Projektarchitektur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 23 24 24 25 25 25 25 26 26 26 5 Implementierung 5.1 Persistenzschicht . . . . . . . . . . . . . . . . . . 5.1.1 Systemkomponenten . . . . . . . . . . . . 5.1.2 Generik allgemein . . . . . . . . . . . . . 5.1.3 Metamodell . . . . . . . . . . . . . . . . . 5.1.4 Lesen der Generik . . . . . . . . . . . . . 5.1.5 Schreiben der Generik . . . . . . . . . . . 5.1.6 Löschen der Generik . . . . . . . . . . . . 5.2 Kontrollerschicht . . . . . . . . . . . . . . . . . . 5.2.1 Der Basiskontroller . . . . . . . . . . . . . 5.2.2 Die Systemkomponentenkontroller . . . . 5.2.3 Der generische Kontroller . . . . . . . . . 5.2.4 Konventionen der Kontrollerschnittstellen 5.3 Präsentationsschicht . . . . . . . . . . . . . . . . 5.3.1 Java Server Pages . . . . . . . . . . . . . 5.3.2 ExtJs . . . . . . . . . . . . . . . . . . . . 5.4 Metamodell . . . . . . . . . . . . . . . . . . . . . 5.4.1 Beispiel eines JSON Metamodell’s . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 27 28 28 29 29 30 30 30 32 32 32 32 33 33 34 35 35 IV . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Philip Krauss INHALTSVERZEICHNIS 5.5 Visuelle Darstellung der Generik . . . . . . . 5.5.1 Phase Eins: Bildung des Metamodells 5.5.2 Phase Zwei: Datendarstellung . . . . . 5.5.3 Flussdiagramm . . . . . . . . . . . . . 5.6 Assoziationen . . . . . . . . . . . . . . . . . . 5.6.1 Darstellung von assozierten Werten . . 5.6.2 Cachen von assozierten Werten . . . . 5.7 Helpers . . . . . . . . . . . . . . . . . . . . . 5.7.1 DatabaseHelper . . . . . . . . . . . . . 5.7.2 SyntaxBuilder . . . . . . . . . . . . . 5.8 XML Annotations . . . . . . . . . . . . . . . 5.9 JSON Konvertierung . . . . . . . . . . . . . . 5.10 Editoren . . . . . . . . . . . . . . . . . . . . . 5.10.1 Xtype . . . . . . . . . . . . . . . . . . 5.10.2 Text . . . . . . . . . . . . . . . . . . . 5.10.3 Zahlen . . . . . . . . . . . . . . . . . . 5.10.4 Datum . . . . . . . . . . . . . . . . . . 5.10.5 Binär . . . . . . . . . . . . . . . . . . 5.10.6 Listen . . . . . . . . . . . . . . . . . . 5.11 Transferklassen . . . . . . . . . . . . . . . . . 5.11.1 Datentransferklasse . . . . . . . . . . . 5.11.2 Statustransferklasse . . . . . . . . . . 5.12 Erweiterungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 Handbuch 6.1 Desktop . . . . . . . . . . . . . . . . . . . . . . . . 6.1.1 Desktop Icons . . . . . . . . . . . . . . . . . 6.1.2 Systemkomponenten . . . . . . . . . . . . . 6.2 Ansichten . . . . . . . . . . . . . . . . . . . . . . . 6.2.1 Datenfeld-Ansicht . . . . . . . . . . . . . . 6.2.2 Listfeld-Ansicht . . . . . . . . . . . . . . . . 6.2.3 Formular-Ansicht . . . . . . . . . . . . . . . 6.2.4 Personalisiern der Spalten im Live Betrieb . 6.3 Tabellen . . . . . . . . . . . . . . . . . . . . . . . . 6.4 Attribute . . . . . . . . . . . . . . . . . . . . . . . 6.5 Assoziationen . . . . . . . . . . . . . . . . . . . . . 6.6 Formulare . . . . . . . . . . . . . . . . . . . . . . . 6.6.1 Erstellen von eignen Formularen . . . . . . 6.7 Editoren . . . . . . . . . . . . . . . . . . . . . . . . 6.7.1 Texteditoren . . . . . . . . . . . . . . . . . 6.7.2 Binäreditor . . . . . . . . . . . . . . . . . . 6.7.3 Zahleneditoren . . . . . . . . . . . . . . . . 6.7.4 Datumseditoren . . . . . . . . . . . . . . . . 6.7.5 Listeneditoren . . . . . . . . . . . . . . . . Philip Krauss . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 37 37 38 38 38 39 40 40 40 40 42 42 43 43 43 43 43 43 45 46 47 47 . . . . . . . . . . . . . . . . . . . 49 49 50 50 52 52 52 53 54 55 55 55 55 56 57 57 57 57 57 58 V INHALTSVERZEICHNIS 6.8 Applikation mit Maven kompilieren . . . . . . . . . . . . . 58 7 Diskussion 7.1 Softwareentwurf . . . . . . . . . . . . . . 7.1.1 Benützung von Interfaces . . . . 7.1.2 Datentyp long . . . . . . . . . . 7.1.3 Bidirektionale Referenzen . . . . 7.2 Konvertierung von JSON . . . . . . . . 7.3 JavaScript . . . . . . . . . . . . . . . . . 7.3.1 Der Punktoperator . . . . . . . . 7.3.2 Der Gültigkeitsbereich . . . . . . 7.4 Metamodell Varianten . . . . . . . . . . 7.5 Assoziationen und Datenbanksysteme . 7.6 Erweiterungen und Änderungen . . . . . 7.6.1 Das Konzept des Metamodells . 7.6.2 SQL Anfragen . . . . . . . . . . 7.6.3 Schemaänderungen zur Laufzeit . 7.6.4 Editoren . . . . . . . . . . . . . . 7.6.5 Durchsatz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 61 61 61 62 62 63 63 63 64 64 64 65 65 65 66 66 8 Zusammenfassung und Ausblick 67 8.1 Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . 67 8.2 Ausblick . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 Appendix A.1 Quellcodelistings . . . . . . . . . . . . . A.1.1 JAX-RS Annotierte Klasse . . . A.1.2 XML annotierte Model Klasse . A.1.3 Instanzierung des GridMetaPanel A.1.4 IBaseEntity Interface . . . . . . . A.2 Klassendiagramme . . . . . . . . . . . . A.2.1 BaseDAO . . . . . . . . . . . . . A.2.2 SyntaxBuilder . . . . . . . . . . A.2.3 Basiskontroller . . . . . . . . . . A.2.4 MetaModel . . . . . . . . . . . . A.2.5 JSON Klasse . . . . . . . . . . . A.2.6 Editoren . . . . . . . . . . . . . . A.3 Java Packetdiagramme . . . . . . . . . . Literaturverzeichnis VI . . . . . . . . . . . . . . . . . . Objektes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 69 69 70 71 72 73 73 73 74 74 75 75 76 78 Philip Krauss Abbildungsverzeichnis 1.1 1.2 1.3 1.4 Basis-Aufsatz System . . . . . . . . . . . . . . Hauptmenü im Access Prototyp . . . . . . . . . Listfeld-Ansicht der Datenstämme (Entitäten) . Datenfeld-Ansicht der Entität Datenstämme . . . . . . . . . . . . . . . . . . . . . . . . . . 2 3 3 4 2.1 Vergleich von klassischem - und Ajax Modell . . . . . . . 10 3.1 3.2 Web Services und Ajax . . . . . . . . . . . . . . . . . . . . 16 ExtJS Grid und Inline Editor [Sena] . . . . . . . . . . . . 17 4.1 4.2 ER Diagramm der des Datenbankschemas . . . . . . . . . 24 Komponentendiagramm . . . . . . . . . . . . . . . . . . . 25 5.1 5.2 . 29 Modell Transitivität für Generikbildung . . . . . . . . . Datenaustausch zwischen Präsentations- und Kontrollerschicht . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.3 Rolle der Kontrollerschicht . . . . . . . . . . . . . . . . . 5.4 Kontroller für generische Anfragen . . . . . . . . . . . . 5.5 Ext.ux.MetaGridPanel der Queries Entität . . . . . . . . 5.6 Beispiel eines Ajax Request mit JSON Datensatz . . . . 5.7 Flussdiagramm zur Darstellung der Generik . . . . . . . 5.8 Assoziationsbaum . . . . . . . . . . . . . . . . . . . . . . 5.9 befüllter Assoziations Cache . . . . . . . . . . . . . . . . 5.10 Parsen von nichtverschachteltem JSON [jso] . . . . . . . 5.11 Datentransferklasse . . . . . . . . . . . . . . . . . . . . . 5.12 Statustransferklasse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 31 32 34 35 38 38 39 42 46 47 6.1 6.2 6.3 6.4 6.5 6.6 6.7 . . . . . . . 49 50 51 52 52 53 54 Der Desktop . . . . . . . . . . . Top Toolbar . . . . . . . . . . . Systemkomponenten Toolbar . Datenfeld-Ansicht . . . . . . . Listfeld-Ansicht . . . . . . . . . Generische Formular-Ansicht . Spalten einer Ansicht anpassen VII . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ABBILDUNGSVERZEICHNIS 6.8 Datumseditor mit Eingabe-Interface . . . . . . . . . . . . 58 7.1 7.2 Zyklen durch Bidirektionale Referenzen . . . . . . . . . . 62 Flussdiagramm einer Schemaänderung zur Laufzeit . . . . 66 1 2 3 4 5 6 7 8 BaseDAO . . . . . . . . . . . . Interface SyntaxBuilder . . . . Basiskontroller . . . . . . . . . MetaModel . . . . . . . . . . . JSON Klasse . . . . . . . . . . Klassendiagramm der Editoren Controller Package Diagram . . Models Package Diagram . . . VIII . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73 73 74 74 75 75 76 76 Philip Krauss Tabellenverzeichnis 5.1 5.2 5.3 5.4 Konventionen der Kontroller Schnittstellen . . . . . Kaskadierungsoptionen für Assoziationen . . . . . . Tabellarische Darstellung vom JSON aus Listing 5.9 Typen der Transferklassen . . . . . . . . . . . . . . . 6.1 6.2 6.3 Desktop-Icons . . . . . . . . . . . . . . . . . . . . . . . . . 50 Toolbar -Icons . . . . . . . . . . . . . . . . . . . . . . . . . 51 Maven Befehlsargumente . . . . . . . . . . . . . . . . . . . 59 IX . . . . . . . . . . . . 33 38 42 45 Listings 2.1 2.2 2.3 2.4 5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.8 5.9 5.10 5.11 6.1 6.2 6.3 7.1 1 2 3 4 HTTP POST Nachricht . . . . . . . . . . . . . . . . . . . HTTP GET Nachricht . . . . . . . . . . . . . . . . . . . . XML Beispielausgabe . . . . . . . . . . . . . . . . . . . . JSON Beispielausgabe . . . . . . . . . . . . . . . . . . . . Spalten auslesen aus JPA ResultSet . . . . . . . . . . . . Definition der Schnittstellen zu den Eigenschaftenschlüssel Definition der Spaltenindizes im Metamodell . . . . . . . Definition des Spaltenmodels im Metamodell . . . . . . . Datenstruktur des Caches . . . . . . . . . . . . . . . . . . Erläuterung zu Zugriffsmethoden/Getter und Setter . . . Beispiel: Java Model . . . . . . . . . . . . . . . . . . . . . Beispiel: Ausgabe in JSON von Java Model . . . . . . . . Beispiel JSON String für Konvertierung . . . . . . . . . . JSON Ausgabe nach Produktion von Query Resultat . . . Datenstruktur zur Abbildung einer Tabelle . . . . . . . . Auslesen von übergebenen Daten . . . . . . . . . . . . . . Wert von name auslesen . . . . . . . . . . . . . . . . . . . Sicherer Schlüsselzugriff auf JSON Werte . . . . . . . . . Zugriff auf JavaScript Cache Objekt . . . . . . . . . . . . JAX-RS Annotierte Klasse . . . . . . . . . . . . . . . . . XML annotierte Model Klasse . . . . . . . . . . . . . . . . Instanzierung des GridMetaPanel Objektes . . . . . . . . Interface für alles POJO’s . . . . . . . . . . . . . . . . . . XI 6 7 8 8 29 36 36 36 39 40 41 41 42 45 46 56 56 57 63 69 70 71 72 Kapitel 1 Einleitung Dieses Kapitel erklärt die grundlegenden Konzepte, wie die der Generik, des Basis-Aufsatz Systems und erläutert Begriffe wie Rich Internet Application. Zusätzlich wird ein erster Blick auf den bestehenden Prototyp geworfen. 1.1 Generik Der Begriff Generik steht im Kontext dieser Arbeit für eine generische Entität. Die Generik beschreibt eine generische Entität die zur Laufzeit der Anwendung nicht bekannt ist. Die generische Entität existiert nur in der Persistenz. Implizierend aus der Generik muss ein Mechanismus gefunden werden um die generischen Entiäten zu charakterisieren. Ein Konzept welches solch einen Mechanismus abbildet ist das Basis-Aufsatz System, welches im folgenden Abschnitt 1.2 genauer beschrieben wird. Wird eine generische Entität benötigt, greift die Anwendung auf die Persistenz zu und bildet die Entität anhand dessen Charakteristika. 1.2 Basis-Aufsatz System Das Basis-Aufsatz System beschreibt das Konzept der Teilung der Entitäten. Dabei gibt es systemabhängige Entitäten und generische Entitäten. Systemabhängige Entitäten dienen der Charakterisierung der generischen Entitäten. Beide Entitätstypen behandeln also einen Teil des Ganzen. Die systemabhängigen Entitäten sind essentiell und bilden die Basis. Die generischen Entitäten beschreiben den Aufsatz. Die Abbildung 1.1 illustriert das Konzept des Basis-Aufsatz Systems. 1 KAPITEL 1. EINLEITUNG Abbildung 1.1: Basis-Aufsatz System Das Paradigma der Generik wird ebenso auf die Basis angewandt, so kann man eine einheitliche Schnittstelle zu den Entitäten definieren und die Charakteristiken der Generik noch erweitern. Folglich ist die Basis rekursiv zu sich selbst, indem die Basis ebenfalls Wissen über ihre Charakteristik hat. 1.3 Bestehender Prototyp Es extistiert bereits ein Prototyp welcher im MS Access geschrieben wurde. Die Applikation greift über ODBC 1 auf eine MySQL Datenbank zu. Der Prototyp setzt das aus dem vorigen Abschnitt 1.2 beschriebene Basis-Ausatz System um. Weitere Features sind eine Benutzer- sowie Benutzergruppenverwaltung mit Vergabe von Zugriffsrechten auf die Entitäten. Der Prototyp verfügt über drei Arten von Ansichten zur Visualisierung der Daten. Die Datenfeld-Ansicht erzeugt eine tabellarische Ausgabe einer Entität. Die Listfeld-Ansicht, ermöglicht grosse Datenmengen schnell zu filtern und die Daten komfortabel anzuzeigen. Die Formular-Ansicht ist ein weiteres Werkzeug zur Dateneingabe bzw. Datenmanipulation. Der Prototyp beherscht die Benutzerverwaltung, wobei Benutzer zu einer oder mehreren Benutzergruppen gehören. Aus den Benutzergruppen leitet sich die Rechtevergabe ab. Weiters können Profile für Benutzergruppen angelegt werden um schnelleren Zugriff auf Funktionalitäten zu haben. 1 Mehr zu Open Database Connectivity ist unter http://de.wikipedia.org/wiki/ Open_Database_Connectivity zu finden 2 Philip Krauss KAPITEL 1. EINLEITUNG Der Einstiegspunkt nach der Anmeldung des Benutzers im bestehenden Prototyp ist das Hauptmenü. Von hier aus kann man auf die Generik zugreifen und/oder diese verändern. Die Abbildung 1.2 zeigt das Hauptmenü aus Sicht des Administrators. Abbildung 1.2: Hauptmenü im Access Prototyp Die Abbildung 1.3 zeigt die Listfeld-Ansicht der Datenstämme (Entitäten). Auf der rechten Seite erkennt man die Filter, mit den man die Menge der dargestellten Daten schnell reduzieren kann. ListfeldAnsichten bieten keine Manipulationsoperationen an und dienen rein dem Zweck Daten schnell zu finden. Abbildung 1.3: Listfeld-Ansicht der Datenstämme (Entitäten) Philip Krauss 3 KAPITEL 1. EINLEITUNG Bei der Datenfeld-Ansicht (Abbildung 1.4) handelt es sich um eine tabellarische Darstellung aller Datensätze einer Entität. Es existiert keine Filterungsmöglichkeiten. Diese Ansicht erlaubt die Modifikation eines Datensatzes. Abbildung 1.4: Datenfeld-Ansicht der Entität Datenstämme 1.4 Rich Internet Application Eine Rich Internet Application, kurz RIA beschreibt eine Anwendung welche in einem Webbrowser ausgeführt wird. Eine RIA verfolgt das Ziel die Funktionalität von grafischen Benutzerschnittstellen einer DesktopAnwendung für Webapplikationen zu ermöglichen. Deshalb werden Technologien wie Ajax eingestetzt um dem Benutzer asynchrone Interaktion zu ermöglichen, d.h. das eine Interaktion zu einem unbekannten Zeitpunkt ausgeführt wird. Durch den Einsatz von Ajax sinkt das Transfervolumen, da nur die Daten ausgetauscht werden und nicht bei jeder Interaktion erneut die Seite neu geladen wird. Der Begriff Rich Internet Application ist kein standardisierter Begriff, sondern eine Namensgebung aus der Folge der neuen Technologien der Internetentwicklergemeinde. 4 Philip Krauss Kapitel 2 Analyse Webapplikationen tragen eine hohe Anzahl an de facto Standards und unterschiedlichen Technologien in sich. Es gilt diese im Bezug zu der Aufgabenstellung, sowie den Ist-Zustand des Prototyps zu analysieren. Dabei sind die Konzepte der unterschiedlichen Technologien relevant und gegebenenfalls wiederverwendbar. Besondere Aufmerksamkeit gelten den Programmiersprachen und den Datenbanksystemen. 2.1 Bestehender Prototyp Wie bereits erwähnt wurde der Prototyp in Microsoft Access entwickelt. Microsoft Access bietet ein komplettes Framework das dem Entwickler viele out of the box Fähigkeiten zur Verfügung stellt und wenig programmiertechnischen Fähigkeiten verlangt aber bietet es auch eine vollständige objektorientierte Entwicklungsumgebung. Grafische Benutzerschnittstellen lassen sich via Drag and Drop erstellen bzw. werden autonom durch die Definition des Tabellenschemas gerendert. Dadurch erhält man automatisch zwei Arten von Ansichten, eine DatenfeldAnsicht einer Tabelle und eine Formular-Ansicht eines Datensatzes. Access bietet die Möglichkeit seine Applikation in einer offenen Variante und einer geschlossenen Variante abzuspeichern wo der Benutzer keine Einblick in den Code bekommt. Die Programmiersprache für Access Anwendungen ist Visual Basic for Applications (VBA). Verständlicherweise sind diese Fähigkeiten so nativ in keinem Webframework bzw. keiner Webapplikation zu finden, da Access ein in sich selbst abgeschlossenes System ist und Webapplikationen aus multiplen zusammengesetzen Technologien bestehen. Access bietet keine Portierung zu einer Webapplikation an. Obwohl das Microsoft Office Packet für mehrere Plattformen angeboten wird, ist Access nur in der Windows Variante verfügbar. 5 KAPITEL 2. ANALYSE Bei der Weiterentwicklung einer Access Applikation muss man jedem Benutzer die aktuelle Version physikalisch übergeben, hingegen zu Webappliktionen wo, die Anwendung im Webbrowser ausgeführt wird und der Benutzer im auf die aktuelle Version zugreift. Das beschreibt die Idee von Software as a Service (SaaS) aus dem Bereich des Cloudcomputings. 2.2 Technologien in Webapplikationen Webapplikationen sind immer bidirektionale Client-Server Anwendungen, wobei n Clients auf einem Server 1 zugreifen. Dabei gibt es verschiedene Kommunikationswege bzw. Medien. HyperText Markup Language (HTML), Extensible Markup Language (XML), JavaScript Object Notation (JSON) und weitere. XML und JSON sind beliebte Technologien im Einsatz mit Web Services. Dort werden die Daten in dem entsprechenden Format ausgetauscht sprich vom Server produziert und konsumiert. Um Komplikationen vorzubeugen sind nur Technologien bzw. Standards relevant welche vom World Wide Web Consortium (W3C) [W3C] oder von der Internet Engineering Task Force (IETF) [IET] anerkannt sind. 2.2.1 HyperText Markup Language HTML ist das Urgestein der Webseiten. Es wurde entwickelt um den Besuchern Interaktionen mit einer Webseite zu ermöglichen. Beispielweise Hyperlinks, Verweise auf andere HTML Seiten. Die Kommunikation zwischen Client und Server, erfolgt über die Anfrage einer Seite durch die Angabe einer URI2 . Der Server antwortet mit einer HTML Seite welche vom Browser des Clients geparset und gerendert wird. Um eine Nachricht vom Client zum Server zu senden gibt es mehrere HTTP Methoden, in diesem Kontext sind nur POST und GET relevant. POST und GET sind Anfrage Methoden des Hypertext Transfer Protocol und sind Teil des RFC2068 HTTP Standards [BLFM+ 99]. Bei POST wird innerhalb der Nachricht ein Körper mitgeführt in welchem die Daten stehen. Das eignet sich gut für die Übertragung von Dateien, ein Beispiel einer POST Nachricht wird im Quellcode Listing 2.1 gezeigt. 1 2 3 4 POST /demo . html HTTP/ 1 . 1 H o s t : www. b e i s p i e l . abc Content−t y p e : a p p l i c a t i o n /x−www−form−u r l e n c o d e d Content−L e n g t h : 62 5 6 I c h b i n e i n Textdokument und s t e h e n im ’ Body ’ d e r N a c h r i c h t . . . Listing 2.1: HTTP POST Nachricht 1 2 6 Die Serveranzahl von eins entspricht einer niedrig skalierten Webapplikation URI: Uniform Resource Identifier Philip Krauss KAPITEL 2. ANALYSE Bei GET werden die Daten als Query Paramater über die URI übertragen, siehe Quellcode Listing 2.2. Als Beispiel will der Client die Werte 12 und hallo für die Argumente a und b an den Server mit der URI http://www.beispiel.abc/demo.html übertragen. 1 2 GET /demo . html ? a=12&b=h a l l o HTTP/ 1 . 1 H o s t : www. b e i s p i e l . abc Listing 2.2: HTTP GET Nachricht 2.2.2 Cascading Style Sheets Cascading Style Sheets, kurz CSS ist eine Technologie für die Formatierung von HTML Objekten/Tags. CSS kann via Datei im Header eines HTML Dokumentes geladen werden oder inline über das binäre link Tag. Der Vorteil von CSS ist das die definierten Klassen immer wiederverwendbar sind und so eine einheitliche grafische Benutzerschnittstelle möglich ist. Das Paradigma der Objektorientierten Programmierung wird folglich auf grafische logiklose HTML Objekte/Tags angewendet. Die Idee von CSS besteht darin den HTML Code rein strukturell zu entwerfen und durch CSS die Darstellung zu erweitern. Dadurch entsteht eine Trennung zwischen dem Code und dem Design bzw. Layout. Die Einführung von CSS führte zu einem positiven Effekt für die Bandbreite der Benutzer. Moderne Webbrowser laden die CSS Dateien beim Sitzungsstart und cachen diese für eine bestimmte Zeit. Mittlerweile ist CSS in der dritten Version angekommen und ist der de facto Standard für grafische Elemente in Webapplikationen. 2.2.3 Extensible Markup Language Das Prinzip von XML ist, dass Dokumente von Maschinen lesbar sind, sowie einfach, generisch und nutzbar über ein Rechnernetz sind. Dadurch das es nur wenige Regeln zur Bildung solcher Dateien gibt, ist das Parsen von Dokumenten auch sehr einfach und effektiv. XML ist ein beliebtes Medium im Einsatz mit Web Services und gewinnt durch den Boom des Cloud Computings mit dem Konzept Software as a Service immer mehr an Präsenz. Jedoch erhält man durch die wiederholte Beschreibung der Knoten einen Overhead bzw. Redundanz wie in im Quellcodelisting 2.3 gezeigt wird. Philip Krauss 7 KAPITEL 2. ANALYSE 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 <?xml version=” 1 . 0 ” e n c o d i n g=”UTF−8” standalone=” y e s ” ?> <p e r s o n> <i d>76423</ i d> <name>Mustermann</name> <vorname>Max</ vorname> <f i r m e n> <f i r m a i d=” 76423−1 ”> <i d>76423−1</ i d> <name>Mustermann AG</name> <www>www. mustermannag . a t</www> <s t a n d o r t e> <s t a n d o r t>I n n s b r u c k</ s t a n d o r t> <s t a n d o r t>Wien</ s t a n d o r t> <s t a n d o r t>S a l b u r g</ s t a n d o r t> </ s t a n d o r t e> </ f i r m a> <f i r m a i d=” 76423−2 ”> <i d>76423−2</ i d> <name>Max AG</name> <www></www> <s t a n d o r t e> <s t a n d o r t>I n n s b r u c k</ s t a n d o r t> </ s t a n d o r t e> </ f i r m a> </ f i r m e n> </ p e r s o n> Listing 2.3: XML Beispielausgabe 2.2.4 JavaScript Object Notation JavaScript Object Notation, kurz JSON ist genau wie XML ein maschinenlesbares Datenformat, doch es ist schlanker. Es existieren Syntaxregeln zur Bildung von JSON Objekten. Das Format wurde anfänglich eingeführt als Medium zwischen unterschiedlichen Programmiersprachen. Mittlerweile besitzen alle gängigen Programmiersprachen einen JSON Parser. JSON ist unter RFC4627 standardisiert [Cro06]. 1 { ” i d ” : ” 76423−1 ” , ”Name” : ”Mustermann” , ”Vorname” : ”Max” , ” Firmen ” : [ { ” i d ” : ” 76423−1 ” , ”Name” : ”Mustermann AG” , ”www” : ”www. mustermannag . a t ” , ” s t a n d o r t e ” : [ ” I n n s b r u c k ” , ”Wien” , ” S a l z b u r g ” ] }, { ” i d ” : ” 76423−2 ” , ”Name” : ”Max AG” , ”www” : ” ” , ” standorte ” : [ ” Innsbruck ” ] }] 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 } Listing 2.4: JSON Beispielausgabe 8 Philip Krauss KAPITEL 2. ANALYSE Das Quellcodelisting 2.4 zeigt die Ausgabe des JSONs und es ist leicht zu erkennen das JSON wesentlich schlanker ist als das XML Pendant aus dem Quellcodelisting 2.3. Die Daten werden via Key Value in Objekten abgelegt. Wie das Beispiel (Quellcodelisting 2.4) veranschaulicht ist die Notation simpel und intuitiv. Alle Syntaxregeln sowie weitere Informationen sind auf der JSON Projektseite http://www.json.org zu finden. 2.2.5 Web Services Ein Web Service beschreibt das Konzept der Lastenübertragung. Daten werden von einem Web Service konsumiert und die entsprechende Aktion wird ausgefürt oder Daten werden angefragt wobei der Web Service diese produziert. Ein Client empfängt nur die Daten bzw. sendet die Daten zum Web Service und lässt diesen für sich arbeiten. Web Services kommunizieren über Medientypen, wie z.B. XML und JSON3 . 2.2.6 JavaScript JavaScript ist eine Skriptsprache für Webapplikationen. Der Code wird auf der Client Seite direkt im Browser ausgeführt und verringert dadurch die Serverlast. JavaScript kann man nicht in Konkurenz zu einer Programmiersprache setzen da diese nur eine Gültigkeit innerhalb des ausführenden Dokumentes hat. Das liegt an dem Document Object Model (DOM) was die Gültigkeit begrenzt. Das bedeutet dass man andere Programmiersprachen nutzen muss für Datenbankoperationen. Allerdings kann man mittels JavaScript live HTML ändern bzw. erstellen via DOM, was keine andere Programmiersprache beherrscht. JavaScript ist eine objektorientierte Sprache, doch gibt es keine Klassen sondern nur Objektinstanzen. Frameworks wie jQuery und ExtJS bieten eine Vielsatz an Objekten für Ajax, Effekte, Formulare usw. 2.2.7 Asynchronous JavaScript and XML Asynchronous JavaScript and XML wird immer mit dessen Akronym Ajax angesprochen. Wie der Name schon sagt kann man mittels Ajax asynchron Daten zwischen dem Server und dem Client austauschen. Senden und Empfangen wird über die XMLHttpRequest (kurz XHR) Klasse abgewickelt. Die XHR Instanz bildet die Schnittstelle zum HTTP Protokoll. Ajax wurde erstmals 2005 von Jesse James Garrett in dessen Aufsatz Ajax: A New Approach to Web Applications vorgestellt [Gar05]. Diverse Konzepte wurden zusammengeführt und mit dem Begriff XMLHttpRequest beschrieben. Den Unterschied zwischen einer klassischen 3 Es gibt noch weitere wie z.B. HTML, plain text Philip Krauss 9 KAPITEL 2. ANALYSE Anfrage an einen Webserver und eine Ajax Anfrage zeigt die Abbildung 2.1. Abbildung 2.1: Vergleich von klassischem - und Ajax Modell Aus historischen Gründen steht das X in Ajax für XML. Dies liegt daran dass ursprünglich Ajax rein auf den Transfer von XML optimiert war. Mittlerweile gibt es diese Einschränkung nicht mehr und die Spezifikation schreibt kein Datenformat mehr vor. 2.2.8 Representational State Transfer Im Jahre 2000 wurde von Roy Fielding in dessen Dissertation das Representational State Transfer Konzept, kurz REST eingeführt [Fie00]. Mittels REST kann man eindeutige URI Schnittstellen für Web Services definieren über welche die entsprechenden Daten konsumiert und produziert werden. Die Konsumation wie auch die Produktion erfolgt über einen definierten Medientyp wie JSON, XML, usw. REST ist per se nicht protokollgebunden. Doch ist es geläufig das HTTP Protokoll im Kontext zu REST zu setzten. Durch den Erfolg von REST erlebte das HTTP Protokoll ebenfalls wieder einen Aufschwung nachdem es seit längerem als veraltet galt. In der Literatur wird von der Wiedergeburt des HTTP Protokolls geredet. 2.3 Programmiersprachen Mittlerweile gibt es eine unüberschaubare Anzahl an Programmiersprachen welche Entwicklern die Möglichkeit bieten Webapplikationen zu 10 Philip Krauss KAPITEL 2. ANALYSE erstellen. Vielen Spachen sind nur in kleinen Entwicklergemeinden vertreten oder sind am aussterben. Allerdings kristallisieren sich Java, PHP und Ruby On Rails aus der breiten Masse heraus. 2.3.1 Java Java ist eine plattformunabhänige Sprache und wurde 1995 von Sun Microsystem vorgestellt. Eine Java Anwendung wird zu Bytecode kompiliert und dann von der Java Virtual Machine, kurz JVM interpretiert. Java übernimmt für den Programmierer sämtliche Zeigeroperationen und ist komplett objektorientiert. Allerdings macht dieses Konzept des Bytecodes Java langsamer. Die Java Version 2.3 führt Java Servlets ein. Mittels Servlets kann man Java Webapplikationen entwickeln. Die Grundidee ist es vorhandene Java Programme ans Internet anzubinden. Die Servlet Klasse ist im Packet javax.servlet enthalten, welches Teil der Java Enterprise Edition ist. Ein grosse Anzahl kompilierter Bibliotheken, Java Archive kurz jar sind frei verfügbar. Unter anderem Schnittstellen zu allen gängigen Datenbanksystemen, Handhabung von XML Dokumenten, JSON und REST Schnittstellen. Weiters ist Java in der akademischen Welt stark vertreten. 2.3.2 PHP PHP wurde 1995 von Rasmus Lerdorf vorgestellt und ist heute die meist genutzte Technologie für Webseiten. Der Webserver interpretiert den PHP Code serverseitig und sendet nur das Resultat an den Client zurück. So lässt sich dynamisch ein Dokument eines beliebigen Medientyp erstellen. Der Code wird über einen Parser generiert. Der Einstieg in PHP ist recht einfach, die Syntax ist stark an C orientiert und hat eine schwache dynamische Typisierung. PHP ist eine prozedurale Sprache, kennt aber seit Version 4 das Konzept der Objektorientierung. 2.3.3 Ruby On Rails Die Sprache Ruby wurde genau wie Java und PHP im Jahre 1995 publiziert. Ruby konnte sich nie gegen andere Programmiersprachen durchsetzen. Der Durchbruch erfolgte als David Heinermeier Hanson in 2004 Ruby On Rails veröffentlichte. Dabei handelt es sich um ein Model View Controller 4 Framework für die Entwicklung agiler Software. Das Problem jedoch ist dass die Syntax anfänglich sehr kompliziert ist, da 4 kurz MVC, beschreibt ein Software Entwurfsmuster Philip Krauss 11 KAPITEL 2. ANALYSE sehr viel Wert auf syntatic sugar gelegt wird. Weiters sind die Hostingmöglichkeiten begrenzt und somit ist die Servermiete oft das dreibis vierfache von einem klassischen Apache Server mit PHP Modul. Das Angenehme des Frameworks ist das man durch das Scaffolding 5 schon einen Grossteil der Applikation erstellen kann und durch das DRY Konzept6 werden einem viele Tasks abgenommen wie z.B. das Validierenden von Formularfeldern. Der/die Entwickler kümmern sich rein um die Kernaktivitäten7 der Applikation. Die bekannteste Ruby On Rails Webapplikation ist Twitter 8 . Man kann keinen direkten Vergleich zwischen Ruby On Rails und PHP bzw. Java ziehen da Ruby On Rails ein Framework ist und nicht wie die anderen nur eine Sprache. 2.4 Model View Controller Frameworks Es gibt sehr mächtige Model View Controller Frameworks in allen vorgestellten Programmiersprachen. Solche Frameworks erleichtern die Projektumsetzung ungemein, da diese von Haus aus sich um die Transaktionen der Datenbank kümmern, Formularfelder auf Korrektheit kontrollieren und weitere Helferlein zur Verfügung stellen. Dadurch entsteht allerdings auch ein Overhead, da viele Objekte geladen werden, ohne diese zu nutzen. Der Begriff Model stellt die objektorientierte Abbildung eines Tabellenschemas einer Datenbank dar. Anhand des Model s kennt das Framework die Charakteristiken des Schemas und kann folgedessen Operationen auf der Tabelle ausfürhen. 2.5 Datenbanken Genau wie die Programmiersprachen gibt es etliche Datenbanksysteme. Diese unterscheiden in den angewandten Konzepten, den relationalen Datenbanksystemen und den schemafreien Datenbanksystemen. 2.5.1 Relationale Datenbanksysteme Die relationalen Datenbanksysteme entstanden aus dem relationalen Datenbankmodel von Edgar Codd [Cod70]. Die Relationen beruhen auf mathematischen Konzepten, der relationalen Algebra. Eine Relation beschreibt eine Beziehung zwischen zwei Mengen. Eine Menge entspricht einer Tabelle, somit sind Beziehungen zwischen Tabellen (Relationen). 5 Mittels Scaffolding kann man GUI Prototypen für eine Applikation erzeugen DRY: Don’t Repeat Yourself 7 Geschäftsproess Logik 8 http://www.twitter.com 6 12 Philip Krauss KAPITEL 2. ANALYSE Eine Tabelle kann mehrere Relationen besitzen. Tabellen sind nach einem Schema definiert, welches die Struktur eines Datensatzes festlegt. Das Schema beschreibt sämtliche Spalten innerhalb der Tabelle. Eine Spalte ergibt sich aus einem Namen, Datentyp und weiteren optionalen Parameter. Das Schema bestimmt folglich die Struktur der Daten. Die Sprache zur Abfrage bzw. der Manipulation der Daten ist die Structured Query Language, kurz SQL. Abhängig vom Anbieter kann die SQL Syntax variieren, dann wird diese Variation als Dialekt bezeichnet. Das ACID 9 Konzept beschreibt die elementaren Anforderungen eines Datenbanksystems. Das Akronym gibt vier Eigenschaften an, die Überstezung resultiert in AKID Die Atomarität der Operationen. Zu jedem Zeitpunkt ist die Datenbank konsistent. Isolation der Daten wärend einer Operation, also Schutz vor nebenläufigen parallelen Datenmanipulationen. Der Begriff Dauerhaftigkeit gibt an das die Daten immer persistent gespeichert sind auch wenn Systemausfälle auftreten. 2.5.2 Schemafreie Datenbanksysteme Der Begriff schemafreie Datenbank kann als Obermenge des Paradigmas verschiedener Datenbank Konzepte betrachtet werden. Das Grundkonzept ist NoSQL und verfolgt das Ziel sich von dem fixen Schema einer Tabelle zu trennen, wobei NoSQL für Not only SQL steht. Daraus folgt dass es die Struktur eines Datensatzes nicht mehr gibt, sprich eine variable Struktur entsteht. Diese Art von Datenbanksystem skaliert horizontal. Relationale Datenbanksysteme können diese Leistung nicht erbringen, da dort mehrere Transaktionen von nöten sind, so z.B. bei einem Schreibzugriff, die Kontrolle ob die Daten dem Schema entsprechen, ob die Referenzen nicht verletzt werden, usw. Die Untermengen der schemafreien Datenbanksysteme sind die dokumentenorientierten Datenbanken, Graphendatenbanken und Objektdatenbanken. Dokumentenorientierte Datenbanken haben einen hohen Durchsatz. Dabei wird ein Datensatz als einzelne Datei abgespeichert. Genauer gesagt ist der Inhalt einer Datei eine Serialisierung eines Objektes. Daraus folgt eine Zugriffszeit von O(1) für Lese- und Schreiboperationen. Bekannte Vertreter dieser Gattung sind MongoDB10 und CouchDB11 . Der Einsatz findet sich zum Grossteil in Webapplikationen. Deshalb sind viele dokumentenorientierte Datenbanken über eine REST API12 erreichbar. Der Datentransfer funktioniert über JSON. 9 Atomicity, Consistency, Isolation und Durability http://www.mongodb.org/ 11 http://www.couchdb.org 12 Application Programming Interface bzw. Programmierschnittstelle 10 Philip Krauss 13 Kapitel 3 Eingesetzte Technologien Das Kapitel der Analyse stellte diverse Technologien in Detail vor, die für die Weiterentwicklung in Frage kommen. Diese werden nun evaluiert. 3.1 Eingesetzte Technologien in Webapplikationen Eine Webapplikation kann als Menge W betrachtet werden, wobei jede Technologie T eine Teilmenge der Menge W darstellt (∀T ⊂ W ). Erst durch alle Teilmengen kann eine vollständige Webapplikation gebildet werden. Um weiterhin die Konvention der Mengen zu behalten können die Technologien HTML und CSS als Grundmengen jeder Webanwendung definiert werden. Ohne HTML kann man keine Interaktionen mit dem Benutzer erstellen, fernerhin keine von Menschen lesbare sinnvolle grafische Representation von Daten. 3.1.1 Asynchronous JavaScript and XML Um einer Webanwendung ein äquivalentes look and feel einer DesktopAnwendung zu verleihen muss die Webanwendung eine Rich Internet Application, kurz RIA sein. Aus einer RIA folgt immer der Einsatz von Ajax. Ein weiterer Vorteil von Ajax ist die Reduzierung des Datentransfers, dadurch dass nur benötigte Daten ausgetauscht werden. Die redundanten Daten wie HTML und CSS für das Layout werden nur einmal übertragen. 3.1.2 Web Services Web Services und Ajax sind eine gute Kombination. Ajax ermöglicht den Datenaustausch zwischen Client und Server. Über Web Services 15 KAPITEL 3. EINGESETZTE TECHNOLOGIEN kann man die Datenaustauschschnittstellen des Servers definieren. Dabei werden die Daten1 des Servers über die Web Service Schnittstelle konsumiert und/oder produziert und dann via Ajax weiter zur Client gesendet. Dies funktioniert vice versa, da der Client ebenfalls Daten produzieren und konsumieren kann. Abbildung 3.1: Web Services und Ajax Die in der Abbildung 3.1 veranschaulichten Anfragen sind alle Ajax Anfragen und werden folglich asynchron zu einem unbekannt Zeitpunkt x konkurrent ausgeführt. 3.1.3 REST Schnittstellen Representational State Transfer ermöglicht die Definition eindeutiger Schnittstellen zu den Web Services. Weiters kann man mittels den HTTP Methoden die gewünschte Operationen festlegen, so wurde es auch von Roy Fielding in dessen Spezifikation konkretisiert [Fie00]. Durch REST kann man die Struktur einer Webapplikation verschleiern dadurch dass nur die URI bekannt ist. Beispielsweise sehe eine Anfrage auf einen PHP Web Service wie folgt aus http : //host : port/context/webservice.php oder das Java Pendant http : //host : port/context/W ebServiceServlet. Bei PHP wird direkt auf das Skript zugegriffen und bei Java auf das Servlet. Infolgedessen hätten potenziellen Angreifern bereits Angriffspunkte. 1 16 Formatunabhänig Philip Krauss KAPITEL 3. EINGESETZTE TECHNOLOGIEN 3.2 JavaScript Aus dem Einsatz von Ajax folgt der Einsatz von JavaScript, denn nur via JavaScript ist es möglich Ajax Anfragen zu starten. Dadurch dass die Applikation in einem Webbrowser darsgestellt wird ist die Verwendung eines Framework ratsam. Frameworks wie jQuery oder ExtJS enthalten Ajax Objekte die interoperabel mit allen gängigen Browsern sind. Dabei kristallisiert sich ExtJS heraus. Im Vergleich zum Prototyp, kann ExtJS die meiste Funktionalität abbilden. Mit der Komponente GridPanel kann man Tabellen abbilden sowie Sortierfunktionen und hat den Accesstypischen Inline Editor. Die Abbildung 3.2 zeigt ein Beispiel des Inline Editor und einer tabellarischen Darstellung. Abbildung 3.2: ExtJS Grid und Inline Editor [Sena] Die bis dato eingesetzten Technologien wie REST, Web Services und Ajax werden alle vom ExtJS Framework abgedeckt. Sprich das Framework kann Ajaxanfragen an REST Schnittellen senden und ist fähig XML und JSON als Datenaustauschformat einzusetzen. Das Framework ist für nicht kommerzielle Nutzung kostenlos. Viele Objekte sind bereits sofort benutzbar und zu massgeschneiderten Zwecken erweiterbar. ExtJS benutzt das Konzept eines xtype’s um dem Programmierer die Instanzierung von Objekten zu erleichtern. So erstellt ExtJS eigenständig die Instanzen über die Kenntniss des xtype’s. ExtJS bietet nützliche Funktionen an wie die automatische Anbindung von EventListeners an Elemente bietet. Mehr Informationen zu ExtJS findet man sich [Sena]. 3.2.1 Datenaustauschformat Letzlich bleibt noch zu klären wie die Daten der Ajaxanfragen übermittelt werden. Prinzipiell sollen die JSON und XML Formate anwendbar sein. Das ist möglich da ExtJS beide Formate parsen kann. Das Datenaustauschformat ist also frei wählbar. Philip Krauss 17 KAPITEL 3. EINGESETZTE TECHNOLOGIEN 3.3 Die Programmiersprache Java Nachdem die verschiedenen Webtechnologien ermittelt sind, gilt es eine Programmiersprache zu finden welche die erforderten Eigenschaften erfüllt. Nach der Analyse ist Ruby On Rails bereits ausgeschieden. Grund dafür ist das MVC Framework, siehe Abschnitt 2.4. Durch dessen Starrheit der Modelle der Datenbanktabellen ist es schwierig die Generik abzubilden. Ebenfalls ist ein Framework immer mit einem Overhead versehen und verschlechtert den Durchsatz. Ferner bleiben nur noch PHP und Java. Nach der Spezifikation ist der Einsatz von PHP nicht mehr gegeben, obwohl Klassen existieren die REST URIs auf Objekten abbilden können und JSON bzw. XML Parser in der nativen PHP Bibliothek enthalten sind. Das Problem liegt in der Implementierung eines Services mittels PHP. SOAP2 Klassen sowie eine Vielzahl an XML Konfigurationen müssen geladen werden, daraus folgt ein Overhead. Die Konfigurationen enthalten das Web Services Description Language, kurz WSDL. WSDL beschreibt die Service Schnittstelle. Java besitzt die grösste Stabilität und Praxiserprobheit. Weiters können alle gänigen Datenbanksysteme angesprochen werden. Allerdings ist das grösste Plus die Java API for RESTful Web Services (JAX-RS) Spezifikation, welche unteranderem von Roy Fielding entwickelt wurde. 3.3.1 Java API for RESTful Web Services JAX-RS ist ein Framework mit dem man Ressourcen innerhalb eines Servlets mittels Annotations auf eine REST URI binden/mappen kann [Bur09]. Die JAX-RS Schnittstellen sind Teil der Java Platform Enterprise Edition. JAX-RS wird unter dem Projektnamen Java Jersey3 entwickelt. Das JAX-RS Framework ist frei verfügbar und nicht auf properitäre Webserver limitiert. Es gibt noch weitere REST Frameworks, doch sind die meisten wie z.B. dass von JBoss auf properitäre Webserver optimiert oder stehen unter kostenpflichtigen Lizenzen. Über die Annotations kann das JAX-RS Framework mittels der Reflection API, Schlüsse über die URI ziehen bzw. diese mappen. Den Pfad zu einer Ressource, HTTP Methode und den Medientyp wie JSON und/oder XML kann man per Annotations konfigurieren. Dabei kann man eine globale Konfiguration auf eine Klasse applizieren und die Klassenmethode dann erweitern bzw. verfeinern. Die Klassenmethoden können 2 3 18 Simple Object Access Protocol Projekt Seite von Java Jersey: http://jersey.java.net/ Philip Krauss KAPITEL 3. EINGESETZTE TECHNOLOGIEN Parameter besitzen welche autonom aus der URI des Pfades gesetzt werden. Ein Beispiel einer mit JAX-RS annotierten Klasse ist im Appendix A.1.1 zu finden. Das Marshalling, sprich das Umwandeln zu dem gewünschten Medientyp übernimmt das Framework. Man kann die Marshaller überschreiben bzw. eigene unter Verwendung der obligatorsichen Schnittstelle Marshaller entwicklen. Damit der Marshaller weiss wie eine zu marshallende Klasse aussieht sind diese mit XML Annotations der JAX-WS Spezifikation annotiert. JAX-WS steht für Java API for XML Web Services und ist ein Framework welches Fähigkeiten wie z.B. Objekt in XML umwandeln und vice versa beherscht. Eine JAX-WS annotierte Klasse findet man im Appendix A.1.2. Beide Spezifikationen zusammen bezeichnet man mit Java API for RESTful XML Web Services bzw. JAX-RS-WS. 3.3.2 Apache Tomcat Webapplikationen müssen von einem Webserver ausgeführt werden. Durch die Wahl von Java lag der Schritt zu dem Apache Tomcat Server nahe. Die Apache Software Foundation 4 ist eine ehrenamtliche Organisation welche die Apache Produkte entwickelt. Alle Apache Produkte laufen unter der beliebten Apache Lizenz5 und sind frei verfügbar. Darunter fällt auch der Tomcat Server. Der Tomcat Server ist eine Umgebung zur Ausführung von Java Code auf einem Webserver. Dabei werden die Servlets ausgeführt. Zusätzlich gibt es einen JSP Kompiler, welcher die Java Server Pages übersetzt. JSP sind HTML Seiten welche Java Code enthalten können, dementsprechend dynamische HTML Seiten sind. Mehr zum Apache Tomcat Projekt findet man auf dessen Projektseite [Foub]. 3.3.3 Apache Maven Maven ist ein Build Management Tool basierend auf Java. Genau wie der Tomcat Server ist es ein Produkt von der Apache Software Foundation. Der Zweck von Maven ist es dem Entwickler bei dem Zyklus der Softwareerstellung zu helfen. So kann man sich ein neues Projekt via Maven erstellen und es wird die von der Architektur abhängigen Verzeichnissstruktur erstellt mitsamt der gegebenenfalls benötigten Konfigurationsdateien. Weiters kümmert Maven sich um die Abhängigkeiten innerhalb des Projektes und lädt diese automatisch aus den Repositories 4 5 http://www.apache.org http://www.apache.org/licenses/LICENSE-2.0 Philip Krauss 19 KAPITEL 3. EINGESETZTE TECHNOLOGIEN der Drittanbieter in ein lokales Repository. Maven deckt den Lebenszyklus der Softwareentwicklung ab in dem man seine Ziele angibt und diese dann produziert werden, z.B. dass die Applikation als erstes kompiliert wird folgedessen die Tests ausgeführt werden und anschliessend die fertig gepackte Webapplikation zum Server deployed wird. Wie erwähnt kann man seine Applikation sofort via Maven zum Server deployen. Das ist möglich in dem der Apache Tomcat Server in der Maven XML Konfiguarationsdatei pom.xml 6 registriert wird und über die URI des Tomcat Managers die Applikation als war -Datei7 übergeben wird. Fast alle Java-Bibliotheken Anbieter haben ihre Dateien im zentralen Maven Repository oder gar in deren eignen Repository gehostet. Die Konfiguration der Abhängigkeiten soll dem Programmierer die Zusammenstellung der Bibliotheken ersparen und dies Maven überlassen, welches autonom die Einbettung übernimmt. Diese Eigenschaft folgt dem Softwareentwicklungsparadigma Convention over Configuration, welches das Ziel hat mit einem Minimum an Konfiguration ein Maximum autonom zu Erstellen. Hibernate, das gesamte JAX-RS-WS Framework werden mittels Maven geladen. Weiter Informationen zu dem Maven Projekt findet man auf dessen Projektseite [Foua]. 3.3.4 Hibernate Hibernate ist ein ORM8 Framework. Mittels Hibernate kann man eine Tabelle eines relationalen Datenbanksystemes durch ein Java Objekt abbilden. Diese Objekte werden auch als Plain Old Java Object (POJO) bezeichnet, da es simple Objekte mit wenig bis gar keine Logik sind. Ein Datensatz der Tabelle entspricht dann einer Instanz des Objektes. Ausserdem können Relationen zwischen Tabellen über Annotations dargestellt werden. Dabei kann man zwischen den Annotations des Open Source Frameworks Java Persistence API und den des Hibernate Frameworks wählen. Hibernate bildet die SQL Abfragen anhand der Annotations und bildet einen Datensatz mit samt seiner in Relation stehenden Datensätzen in einem Objekt ab. Eine weitere Methode zur Charakterisierung von Tabellen auf Objekte sind XML Mapping Dateien, wo die Attribute und Relationen der Tabelle mittels XML ausgedrückt werden. Durch das Basis-Aufsatz System, siehe Abschnitt 1.2, kann man die Entitäten der Basis mittels Hibernate darstellen, da deren Definition immer bekannt ist. Dadurch erleichtert sich das Finden von Datensätzen und deren Relationen und der Programmierer arbeitet nur mit Objekten. Das grosse Plus des Hibernate Frameworks ist das es mehrere SQL Dialekte 6 Project Object Model Web Application Archive 8 Object Relational Mapping 7 20 Philip Krauss KAPITEL 3. EINGESETZTE TECHNOLOGIEN kennt, folglich ist der Wechsel zu einem anderen relationalen Datenbanksystem durch eines Parameters der Konfigurationsdatei9 möglich. 3.4 Datenbanken Die Generik beschreibt ein universales Objekt. Allerdings müssen Objektschnittstellen existieren, damit die Charakteristika der generischen Entität ermittelbar sind. Wobei die Charakteristika der Entität die Struktur bzw. Definition der Entität ist. Daraus folgt eine Komplexität in der Anwendung eines schemalosen Datenbanksystems. Hingegen zu relationalen Datenbanksystemen folgen Datensätzen in schemalosen Datenbanksystemen keiner fix Struktur bzw. Definition, diese sind wie der Name es bereits sagt Schemalos. Die Komplexität entsteht durch die Validierung der Daten. Neue bzw. modifizierte Datensätze können nicht in ein fixes Schema gepresst werden und somit müssten diese auf Programmiererebene kontrolliert werden. Der pragmatische Ansatz ist das Datenbanksystem für sich arbeiten zu lassen, diese Rolle erfüllen relational Datenbanksysteme. Weiters wäre es auch unnötig ein schemaloses Datenbanksystem zu verwenden wenn die Datensätze alle strikt einem Schema folgen müssen. Ein relationales Datenbanksystem wurde also gewählt. Das Schema einer Tabelle wird benötigt um einem Datensatz eine Struktur abzuverlangen. Weiters kann man aufgrund des Basis-Aufsatz Systems die Daten elegant kapseln und die Datensätze der Basis so in mehreren Tabellen aufteilen. Aus der Masse der Systeme wie PostgreSQL, Oracle, DB2, usw. sticht MySQL10 im Einsatz mit Webapplikationen hervor. MySQL ist ein Open Source Projekt das ursprünglich von Oracle gegründet wurde und wurde in C/C++ geschrieben. MySQL ist auf allen gängigen Plattformen verfügbar und wurde speziell für den Einsatz von Webapplikationen entwickelt. Fast alle Programmiersprachen haben MySQL Treiber und dessen Schnittstellen. Das System hat sich mittlerweile seinen Rang innerhalb der relationalen Datenbanksysteme erkämpft. So benutzt z.B. Facebook die MySQL Cluster Variante für die Speicherung der Daten. 9 10 hibernate.cfg.xml http://www.mysql.com/ Philip Krauss 21 Kapitel 4 Architektur Dieses Kapitel beschäftigt sich mit der Kombination der unterschiedlichen Technologien und den vorgestellten Konzepten. Dies bezieht sich auf die Abbildung der Generik, dem Entwurf der Datenbankmodelle und sowie die Softwarearchitektur mit einer Aufteilung der Aufgabenbereiche. Dabei gilt es die Applikation flexibel bzw. lose zu entwerfen dass der Austausch von Komponenten möglich ist. 4.1 Abbildung der Generik Die Generik wird abgebildet in dem die Charakteristika einer generischen Entität in den Basis Entitäten abgelegt werden. Somit teilt sich die generische Entität in dessen Bestandteile auf. Der Tabellenname wird in der Tabelle tablenames, dessen Spalten werden in der Tabelle attributes gespeichert, usw. Die Tabellendefinition sprich die Charakteristika und die physikalische Tabelle wird in der Datenbank abgelegt. Dadurch entsteht eine gewollte Redundanz, da die Definitionen einer Tabelle in der Datenbank liegen sowohl als auch die definierte Tabelle. Anhand der Definitionen kann man dynamische Schlüsse über die generische Entität ziehen. Es wäre möglich die Spaltendefinitionen einer Tabelle nicht abzuspeichern. Bei Gebrauch könnten man diese über das SQL Statement DESCRIBE ‘tabellen name‘; ermitteln. Dementsprechend wäre die Redundanz nicht nötig, doch dann wäre es nicht mehr möglich Spalten zu typisieren. Dabei ist nicht der Datentyp gemeint sondern für grafische Ausgaben der Spalte wie z.B. ein Alias. Weiters entsteht ein komplexes Geflecht für die Abbildung der Abhängigkeit zwischen den einzelnen Entitäten. Mit der Redundanz kann man sich auf den Primärschlüssel der Spalten-Tabelle verlassen. Ohne Redundanz müsste man die Spaltennamen expliziert abspeichern. Resultat wären Trigger die bei jedem 23 KAPITEL 4. ARCHITEKTUR Schreibvorgang der Spalten-Tabelle, die Konsistenz zwischen den Tabellen kontrollieren müssten und gegebenenfalls ausbessern. 4.2 Entity Relationship Diagramm Die Abbildung 4.1 enthält das Entity Relationship Diagramm und zeigt die Basisentitäten der Datenbank. Folgende Entitäten sind Teil der Basis. Abbildung 4.1: ER Diagramm der des Datenbankschemas 4.3 Softwarearchitektur Nach der Analyse hat sich herausgestellt dass fertige MVC Frameworks nicht gegeignet sind, siehe Abschnitt 2.4. Das Model View Controller Pattern hat sich in der Praxis bewiesen und ist ein beliebtes Softwarearchitekturparadigma in Webapplikationen als auch in Desktopapplikationen [FF04]. Folglich wurde das MVC Pattern in diesem Projekt eingesetzt. Die Software wurde also in ihre einzelnen Komponenten der Zuständigkeitsbereiche bzw. in Schichten aufgeteilt. 24 Philip Krauss KAPITEL 4. ARCHITEKTUR 4.3.1 Komponenten Das Komponentendiagramm in Abbildung 4.2 zeigt die einzelnen Schichten der Softwarearchitektur. Die Aufteilung erfolgt nach dem Model View Controller Prinzip. Eine Schicht enthält mehrere Komponenten, welche austauschbar sind. Abbildung 4.2: Komponentendiagramm Die durchgezogenen Linien beschreiben eine direkte Verbindung zwischen den Schichten. Das heisst die Schichten können direkt miteinander kommunizieren. Die gestrichelte Linie zeigt eine transitive Beziehung zwischen der Präsentationsschicht und der Presistenzschicht dar. Die beiden Schichten stehen über die Kontrollerschicht in Beziehung. 4.3.2 Persistenzschicht Die Persistenzschicht bildet die Schnittstelle zur Datenbank. Dabei bilden die Modelle, die Tabellen ab. Sämtliche Anfragen bzw. Operationen auf der Datenbank werden auf dieser Schicht ausgeführt. Die anderen Schichten kennen nur die konkreten Modelle welche zurückgegeben werden. Für Datenzugriffe wird das Data Access Object Pattern eingesetzt. Um einen einfachen Wechsel der Datenbank zu ermöglichen, sind alle Datenbanksystem spezifischen Klassen über Schnittstellen implementiert. Die Klassen sind lose gekoppelt. 4.3.3 Kontrollerschicht Die Kontrollerschicht stellt den Mediator zwischen der Persistenz- und der Präsentationsschicht dar. Eine public Methode innerhalb eines Kontrollers ist eine Web Service Schnittstelle. Die Kontroller übernehmen die Umwandlungen der Daten und leiten diese dann zwischen den Schichten weiter. Philip Krauss 25 KAPITEL 4. ARCHITEKTUR 4.3.4 Präsentationsschicht Die Präsentationsschicht ist wie erwähnt lose mit der Kontrollerschicht gekoppelt. Dadurch ist diese leicht austauschbar bzw. erweiterbar. Diese Schicht kennt nur die Schnittstellen der Web Services. Daten werden konsumiert, produziert und Geschäftsprozesse werden angestossen. 4.4 Client-Server Architektur Die Client-Server Architektur befindet sich zwischen der Präsentationsund der Kontrollerschicht. Die Präsentationsschicht stellt den Client dar welcher Daten zum Server, der Kontrollerschicht, sendet bzw. empfängt. Jede Webapplikation setzt die Client-Server Architektur um. 4.5 Web Service Schnittstellen Representational State Transfer ist ein Architekturstil für Web Services und deren Hypermedien für Webapplikationen. Die REST Schnittstellen ermöglichen eine lose Koppelung zwischen der Präsentationsschicht und der Kontrollerschicht. Kontrollerschicht und Präsentationsschicht besitzen kein Wissen übereinander. Anfragen auf REST Schnittstelle können der Präsentationsschicht kommen oder z.B. von dem Command Line Programm curl 1 kommen [Bur09]. Der Web Service agiert als Server. 4.6 Projektarchitektur Webapplikationen in Java benötigen eine bestimmte Verzeichnissarchitektur damit die Servlets von einem Webserver interpretiert werden. Vor der Interpretation muss natürlich das Projekt als erstes in den Bytecode kompilliert werden. Für Erstellung der Verzeichnissarchitektur bietet Maven (siehe Abschnitt 3.3.3) Abhilfe. Bei der Erstellung eines neuen Maven Projektes gibt man den Architekturtyp an, in diesem Fall Webapplication und anschliessend wird die passende Verzeichnisstruktur generiert. 1 26 http://curl.haxx.se/ Philip Krauss Kapitel 5 Implementierung Die Implementierung setzt die im Kapitel 4 vorgestellten Architekturmuster und die im Kapitel 3 eingesetzten Technologien um. Es werden die drei Schichten des MVC1 Frameworks erklärt sowie die Implementierung der Generik. 5.1 Persistenzschicht In der Persistenzschicht sind sämtliche von der Datenbank abhängige Komponenten implementiert. Das Ziel war es den Entwurf so flexibel wie möglich zu halten und einen einfachen Datenbankwechsel zu ermöglichen. Deswegen wurde das Data Access Object Entwurfsmuster, kurz DAO implementiert. Die Idee des DAO Entwurfsmusters besteht darin eine Zeile einer Datenbanktabelle auf ein Objekt abzubilden. Folglich sind die Spalten eines Tabelleschemas, die Attribute (Variablen) eines Objektes. Ein DAO ist also ein simples Objekt, in der Literatur und in der Hibernate Dokumentation[JBo] werden solche Objekte als Plain Old Java Object, kurz POJO bezeichnet. Im Einsatz mit Hibernate kann man über das DAO Entwurfsmuster auf seine DAO’s zu greifen ohne Kenntniss über das Datenbanksystem zu besitzen. Hibernate beherrscht die unterschiedlichen SQL Dialekte für die Anfragen auf das Datenbanksystem und übernimmt das Konvertieren des SQL Resultats in einem DAO. Das Datenbanksystem kann man in der Hibernatekonfiguartionsdatei2 ändern. 1 2 Model View Controller hibernate.cfg.xml 27 KAPITEL 5. IMPLEMENTIERUNG 5.1.1 Systemkomponenten Die Entitäten der Basis, sprich die Systemkomponenten, sind alle über das DAO Entwurfsmuster implementiert. Generische Entitäten sind zur Laufzeit nicht bekannt, sie liegen in der Persistenz. Deshalb wurde ein generisches DAO entwickelt, sodass man eine generische Entität auf ein DAO abbilden kann, die Klasse BaseDAO, siehe Appendix A.2.1. Falls nötig kann man von dieser Klasse abstrahieren und weitere Funktionalität einspielen. Die POJO’s implementieren alle das Interface IBaseEntity A.1.4. IBaseEntity verlangt die Implementierung von drei Methoden, eine Getter -Methode zum Auslesen der Id eines Datensatzes und zwei Setter -Methoden zum setzen des Modifizierungs- bzw. Erstellungsdatums. Die POJO sind alle mit den JPA3 Annotations annotiert. Die Annotations erlauben es Beziehungen zwischen den Modellen (hier die DAO’s) zu definieren. Diese Beziehungen bilden die Beziehungen im Datenbanksystemen ab, sprich die 1:1, 1:n oder m:n Beziehungen. Vorteilhaft ist, dass man über diese Beziehungen Transitivität erhält, da Hibernate automatisch die in Beziehung stehenden Datensätze in das Resultat einbindet. In diesem Projekt beschränkt sich die Verwendung von Hibernate nur auf Lesezugriffe. Schreib- sowie Löschzugriffe werden mittels der generischen Logik ausgeführt. Die Entitäten der Systemkomponenten sind ident wie die generischen Entitäten in der Datenbank abgelegt. Sie sind rekursiv zu sich selbst. Die Benützung der generischen Logik liegt daran das Systemkomponenten auch Assoziationen besitzen und damit die gleiche Logik benötigt wird. 5.1.2 Generik allgemein Eine generische Entität ist normalerweise zur Laufzeit als Modell per se nicht bekannt. Deshalb werden dessen Charakteristika bzw. Schema benötigt. Hier kommt wie im vorrigen Abschnitt Hibernate und dessen Transitivität zum Einsatz. Damit man ein generisches Modell erstellen kann, benötigt man die Id der Entität. Von dem Punkt aus muss man diese über Hibernate suchen um erhält einen Charakteristikabaum. Baum ist nicht der korrekte Ausdruck, aber hierarschich betrachtet ist die Entität die Wurzel und die folgenden Entitäten (Charakteristiken) welche die Knoten bzw. Blätter eines Baums darstellen. Mittels des Charakteristikabaums kann man das Metamodell erstellen. Das Metamodell ist eine einheitliche Beschreibung einer Entität und wird noch genauer im folgenden Abschnitt 5.1.3 beschrieben. Eine visuelle Darstellung der Transistivität bzw. des Charakteristikabaums zeigt die Abbildung 5.1. 3 28 Java Persistence API: Java Framework für Persistenzzugriffe Philip Krauss KAPITEL 5. IMPLEMENTIERUNG Abbildung 5.1: Modell Transitivität für Generikbildung Die Lese- und Schreiboperationen werden über das JPA Framework abgewickelt. Die Verbindung zur Datenbank wird über Hibernate aufgebaut und an JPA übergeben. Damit ein einfacher Wechsel der Datenbank möglich ist wurde ein Broker Interface entwickelt. Alle datenbankspezifischen Operationen werden in einer vom Broker Interface implementierten Klasse gekapselt. Ein Persistenzzugriff erfolgt nur über die Methoden dieses Interfaces. 5.1.3 Metamodell Das Metamodell ist eine Beschreibung einer Entität, dabei kann es sich um eine generische sowie eine bekannte Entität handeln. Lese- sowie Schreiboperationen können anhand des Modells erstellt werden. Die Implementierung des Metamodells ist genauer im Abschnitt 5.4 beschrieben. 5.1.4 Lesen der Generik Bei Leseoperationen auf generischen Datenstämmen wird die Methode findAll(table, attributes) aufegrufen. Innerhalb der Methode wird mittels des Metamodells der Tabelle das entsprechende SQL Statement erstellt. Im nächsten Schritt wird die Verbindung zur Datenbank geöffnet und folgedessen wird das Statement ausgeführt. Das Resultat wird als java.sql.ResultSet zurückgegeben. Abschliessend wird das Resultat in Philip Krauss 29 KAPITEL 5. IMPLEMENTIERUNG ein Datentransferobjekt (siehe Abschnitt 5.11) konvertiert. Die Konvertierung des java.sql.ResultSet erfolgt durch iteratives Abarbeiten jeder Spalte. Das Auslesen einer Spalte erfolgt über den Spaltennamen. Da man in generischen Entitäten diese nicht kennt aufgrund der Laufzeitdynamik, werden die Spalten einer Tabelle der Methode übergeben. 1 2 /∗ r s = j a v a . s q l . R e s u l t S e t ∗/ f i n a l Object value = r s . getObject ( ’ spalten name ’ ) ; Listing 5.1: Spalten auslesen aus JPA ResultSet Daraus entsteht eine verschachtelte Schleife, wobei die äussere Schleife die Iteration des ResultSets ist und die innere Schleife die Abtastung der Spaltennamen. Als Laufzeit benötigt die Methode O(n ∗ m ∗ a), mit n =| Spalten − des − ResultSets |, m =| Datensaetze − des − ResultSets | und a =| Spalten − der − T abelle |. 5.1.5 Schreiben der Generik Das Schreiben einer generischen Entität verfolgt den gleichen Ansatz wie das Lesen. Durch die Erstellung des Metamodells ist das Schema bekannt und ein SQL Statement kann erstellt werden. Dies gilt für die Insert- sowie Update Statements. In dem ersten Abschnitt des Vorgangs, werden die Spaltenwerte von modified und gegebenenfalls created auf das aktuelle Datum im generischen Entitätsobjekt4 gesetzt. Anschliessend wird das SQL Statement gebildet. Dies erfolgt mittels der Klasse SyntaxBuilder, siehe Appendix 5.7.2. Eine Kontrolle der Eingabe findet auf dieser Ebene nicht statt. Eingaben werden vorab durch die Editoren auf der Präsentationsschicht geprüft, mehr zu Editoren im Abschnitt 5.10. Ein zweite Stufe der Kontrolle übernimmt das Datenbanksystem. Bei falschen Eingaben, z.B. einen String Wert in eine Integer Spalte zu schreiben gibt das System den Fehler aus. 5.1.6 Löschen der Generik Um einen generischen Datensatz zu löschen wird im ersten Schritt dessen Assoziationen geprüft und gegebenenfalls die referenzierten Datensätze rekursiv gelöscht bzw. wird der Löschvorgang beendet wenn das Kaskadierungsflag STOP gefunden wird. Assoziationen sind näher im Abschnitt 5.6 beschrieben. Falls keine Assoziationen gesetzt sind oder die referenzierten Datensätze alle erfolgreich gelöscht wurden wird der Datensatz gelöscht. Hier kommt wieder die Klasse SyntaxBuilder (siehe 4 30 Die Klasse des generischen Entitätsobjekt findet man im Appendix 5.9 Philip Krauss KAPITEL 5. IMPLEMENTIERUNG Appendix 5.7.2) ins Spiel, die das SQL Statement bildet. Um einen Datensatz zu löschen benötigt man nur dessen Id und den Tabellenamen. 5.2 Kontrollerschicht Eine Kontrollerklasse bzw. ein Controller ist ein Servlet das über REST URI gemappt wird. Die Methoden des Controllers entsprechen den Web Services, wobei jeder Web Service über dessen REST URI angesprochen wird. Ein Controller dient nur zur Konsumation bzw. Produktion der gesendeten bzw. angeforderten Daten, siehe Abbildung 5.2. Controller sind mit Annotations aus dem JAX-RS-WS Frameworks annotiert. Die Annotations geben die URI des Web Services an, sowie dessen HTTP Methode und den Medientyp für Konsumation und/oder Produktion. Eine Beispielimplementierung eines Kontrollers mit den Annotations findet man im Appendix A.1.1 Der Vorteil von Web Services ist dass die Schnittstellen nur für die Präsentationsschicht sichtbar sind. Daraus resultiert eine lose Koppelung zwischen den Schichten. Abbildung 5.2: Datenaustausch zwischen Präsentations- und Kontrollerschicht Die Kontrollerschicht agiert als Vermittler zwischen der Präsentationsund der Persistenzschicht, siehe Abbildung 5.3. Dessen Aufgabebereich ist die Konsumation bzw. Produktion von JSON Daten, das Ausführen der Geschäftsprozesslogik und das Weiterleitung der Daten an die Schichten. Philip Krauss 31 KAPITEL 5. IMPLEMENTIERUNG Abbildung 5.3: Rolle der Kontrollerschicht 5.2.1 Der Basiskontroller Der Basiskontroller beinhaltet die gesamten benötigten Kontrollflussmethoden und generische Create Read Update Delete Methoden. Das Klassendiagramm des Basiskontrollers ist Appendix A.2.3 zu finden. 5.2.2 Die Systemkomponentenkontroller Für die einzelnen Systemkomponenten wurde jeweils ein eigner Kontroller entwickelt. Grund dafür ist das diverse Routinen komplexer sind. Beispielsweise ist es beim Hinzufügen eines Attributs einer Tabelle nötig als erstes das Attribut im Modell zu persistieren. Bei Erfolg, wird nun die physikalische Tabelle mit dem Attribut erweitert. Falls eine der Transaktionen fehlschlägt wird eine Rollback Routine eingeleitet. Dieses Verhalten ist generisch nicht abbildbar. Dementsprechend war es einfacher einzelne Kontroller einzuführen. Zusätzlich ist die Erweiterung einer Systemkomponente wesentlich einfacher da diese nun modularer abgelegt sind. 5.2.3 Der generische Kontroller Für die Generik wurde ein eigener Kontroller implementiert. Aufgrund der Dynamik der Generik kann man keinen konkreten Kontroller für jede generischen Entität implementieren. Dies wäre natürlich möglich, doch müsste das System dann jedes mal anhalten, den Kontroller entwickeln, neu komplierien und wieder deployen. So ein manueller Vorgang ist mit hohen Entwicklungskosten verbunden und birgt Fehlerquellen. 32 Philip Krauss KAPITEL 5. IMPLEMENTIERUNG Für alle generischen Entitäten gehen die Anfragen wie folgt auf einen Kontroller. Damit dieser Kontroller auch weiss, wer was von ihm verlangt benötigt er die Id der Entität. Abbildung 5.4: Kontroller für generische Anfragen Wie auf der Abbildung 5.4 erkennbar ist das Prefix der Web Service Schnittstelle /app/data/. Folgend wird die Aktion angegeben, dann die Id des Datenstammes und gegebenenfalls die Id des Datensatzes. 5.2.4 Konventionen der Kontrollerschnittstellen Eine Schnittstelle zu einem Kontroller bzw. Web Service besteht immer aus einer URI5 . Die URI ist intern auf eine Methode innerhalb eines Kontrollers gemappt 6 . Mittels der HTTP GET Methode kann man weitere Parameter zu einer URI übertragen und werden als Query Parameter bezeichnet. Diese sind via ? -Zeichen von der URI getrennt. Der gesamte Ausdruck hinter dem ? -Zeichen wird als Query String bezeichnet. Die URI http://host:port/context/app/editors?id=123 macht eine Anfrage an die Persistenz um alle Editoren zu erhalten, durch den Query Parameter id=123 wird die Suche eingegrenzt auf den Datensatz mit der Spalte Id und dem Wert 123. Das Schnittstellendesign ist den gängigen Konventionen angepasst und respektiert die RFC3986 Norm [BLFM05]. Die Konventionen entsprechen einer CRUD Abbildung. Die Schlüsselwörter in der Tabelle 5.1 wie controller bzw. id sind Platzhalter für die effektiven Kontrollernamen bzw. die Id Werte. Die mit * gekennzeichnete Zeile ist die Schnittstelle zur Ausgabe aller Datensätze. Weiters zeigt sich das http://host:port/context/app/controller ?id=123 und http://host:port/context/app/controller /read/123 Synonyme sind. 5 6 Uniform Resource Identifier Beispiel eines Kontrollers A.1.1 Philip Krauss 33 KAPITEL 5. IMPLEMENTIERUNG * 1 2 3 4 Create Read Update Delete http://host:port/context/app/controller http://host:port/context/app/controller /create http://host:port/context/app/controller /read/id http://host:port/context/app/controller /update/id http://host:port/context/app/controller /delete/id Tabelle 5.1: Konventionen der Kontroller Schnittstellen 5.3 Präsentationsschicht Die Präsentationsschicht benutzt die Technologien der Java Server Pages (kurz JSP ) und des ExtJS Frameworks zur Darstellung der visuellen Objekte. 5.3.1 Java Server Pages Es wurde die erste Version von den JSP benützt. JSP ermöglicht es dem Entwickler Java Code in der View auszuführen. Diese Fähigkeit kann sich auch schnell zum Nachteil entwickeln wenn man zuviel Logik anderer Schichten dort ablagert. JSP instanziierte Umgebungsobjekte vor dem Rendering einer Seite. Umgebungsobjekte sind beispielsweise Objekte mit Datenflussmethoden oder Objekte mit Informationen über die Sitzung und der Umgebung. In diesem Projekt werden JSP Seiten nur als Behälter für die ExtJs Objekte benützt. 5.3.2 ExtJs Das Ext.ux.MetaGridPanel 7 Objekt bildet den zentralen Punkt die tabellarische Darstellung. Für die Population der Tabelle ist eine Index Map notwendig. Diese beschreibt den dataIndex damit nach dem Datenempfang die Daten auch zuweisbar sind. Ist das Objekt instanziiert wird ein Ajax Request zu der REST URI ausgeführt wo die Daten produziert werden und zurückgeliefert werden. Die empfangenen Daten werden in einem Store abgelegt. Ein Store ist ein zwei-dimensionales assoziatives Array, wo die Spalten mit ihrem dataIndex ähnlich einer HashMap abgelegt werden. Die Datensätze sind über den RowEditor oder über ein generisches- bzw. selbst geschnitztes Formular editierbar. Der RowEditor ist ein ExtJsPlugin. Das Objekt muss instanziiert und konfigURIert werden. Die Konfiguration beinhaltet das Binden der Callbacks wenn ein Datensatz editiert bzw. erstellt wurde. Bei Callbacks wird ein Zeiger auf eine Speicherroutine umgeleitet. So kann man Code einspielen. Die ge7 34 Beispiel einer Instanzierung im Appendix, A.1.3 Philip Krauss KAPITEL 5. IMPLEMENTIERUNG nerischen Formulare werden aus dem Metamodell gebildet welches dem Ext.ux.MetaGridPanel (Abbildung 5.5) Objekt übergeben wird. Folglich muss man keine neue Anfrage für das Metamodell stellen und man behält die Konsistenz. Abbildung 5.5: Ext.ux.MetaGridPanel der Queries Entität Über das Flag inputEnable kann man den Modifikationsmechanismus abschalten. Wird das Flag nicht gesetzt und der Modifikationsmechanismus ist aktiviert muss man die URI’s zur Datenmanipulation setzen. Wurde ein Datensatz modifiziert bzw. erstellt wird der Datensatz in ein JSON Objekt geparst und zur der definierten REST URI gesendet wo dann der entsprechende Geschäftsprozess des Kontrollers eingeleitet wird. Nach dem Abschluss der Routine wird eine Antwortet an das Senderobjekt geleitet um dieses über den Transaktionstatus zu informieren. Die Konvertierung zu JSON übernimmt das ExtJs Framework. Die Abbildung 5.6 zeigt die ganze Routine. Philip Krauss 35 KAPITEL 5. IMPLEMENTIERUNG Abbildung 5.6: Beispiel eines Ajax Request mit JSON Datensatz Eine Beispielimplementierung findet man im Appendix A.1.3. 5.4 Metamodell Das Metamodell beschreibt das Schema der Entität, dessen Attribute und dessen Assoziationen. Der Zweck des Metamodells ist es, nur mit einer Klasse alle Entitäten abzubilden und so die Generik zu charakterisieren. Der Präsentationsschicht ist nichts über die Entität bekannt und behandelt diese wie in ihrem Metamodell beschrieben. Die Präsentationsschicht muss nur die Schnittstellen des JSON Objektes kennen. Minimum benötigt man ein Statusflag, einen Zähler der Datensätze und das Datenobjekt innerhalb des JSON Objektes zum Lesen der Datensätze, siehe Quellcodelisting 5.2 auf Seite 36. Der Vorteil von JSON ist dass es nur eine Spezifikation der Syntax gibt und man von dem Punkt aus frei ist seine JSON Objekte zu erstellen, [III08]. 5.4.1 Beispiel eines JSON Metamodell’s Das folgende Quellcodelisting 5.2 zeigt die Schnittstellen zu den Eigenschaftenschlüssel, diese werden im Metamodell übertragen. Diese dienen zu Identifizierung der Schlüssel für den Zugriff auf die Daten (dataRoot), den Transaktionszustand (success) und die Anzahl der Einträge (totalProperty). 36 Philip Krauss KAPITEL 5. IMPLEMENTIERUNG 1 { ” totalProperty ” : ” total ” , ” success ” : ” success ” , ” dataRoot ” : ” data ” , ... 2 3 4 5 6 } Listing 5.2: Definition der Schnittstellen zu den Eigenschaftenschlüssel Das nächste Quellcodelisting 5.3 zeigt die Definition der Felder und deren Datentypen für das Indexieren der Daten. 1 2 3 4 5 6 7 8 9 10 11 ”fields” :[ { ”name” : ” type ” : }, { ”name” : ” type ” : }, ... ] ” id ” , ” int ” ”name” , ” string ” Listing 5.3: Definition der Spaltenindizes im Metamodell Im Quellcodelisting 5.4 werden die Definitionen der Felder zur grafischen Representation gezeigt und das Binden der Ausgabe an die folgenden Daten über den dataIndex. Die Eigenschaft editor beschreibt die Representation des Editors welcher an dieses Felder gebunden wird und somit die Schnittstelle zwischen Benutzereingaben und der Speicherung der Daten steht. Editoren sind zwingend nötig für ein Feld. Besitzt ein Feld keinen Editor so wird es nicht editierbar sein. Editoren werden genauer im Abschnitt 5.10 erklärt. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ” columnModel ” : [ { ” dataIndex ” : ” id ” , ” h e a d e r ” : ”ID” , ” width ” : 5 0 }, { ” d a t a I n d e x ” : ”name” , ” h e a d e r ” : ”NAME” , ” width ” : 5 0 , ” editor ” :{ ” xtype ” : ” t e x t f i e l d ” , ” allowBlank ” : true , ” blankText ” : ” t h i s f i e l d } }, ... ] i s mandatory ” Listing 5.4: Definition des Spaltenmodels im Metamodell Philip Krauss 37 KAPITEL 5. IMPLEMENTIERUNG 5.5 Visuelle Darstellung der Generik Die Darstellung von generischen Entitäten durchläuft zwei Phasen. Wobei erst nach einem erfolgreichen Abschluss der ersten Phase die zweiten Phase angestossen wird. Die Abbildung 5.7 zeigt das Flussdiagramm der zwei Phasen. 5.5.1 Phase Eins: Bildung des Metamodells Ist die HTML Seite fertig gerendert startet das ExtJS Objekt eine Ajax Anfrage zum Web Service welche die Informationen zu dem Metamodell der Entität besitzt. Der Web Service greift auf die Persistenzschicht zu und holt das Metamodell. Nun wird das Metamodell gebildet in dem die Attribute bzw. Spalten mit dessen Editoren (siehe Abschnitt 5.10) und die Assoziationen der Entität gesucht werden. Das Resultat der Anfrage auf die Persistenz wird folgedessen an den Kontroller weitergeleitet und dort im MetaData Kontainerobjekt gepackt. Das MetaData Objekt sprich das Java Objekt des Metamodells wird nun über den Kontroller zurück zur Präsentationsschicht geleitet wo es als JSON empfangen wird. Das Marshalling zum JSON Objekt wird vom im JAX-RS Framework inkludierten Jackson Framework übernommen. Das Resultat der Operation wird der Präsentationsschicht durch das Status Flag success mit geteilt. Mehr zum Metamodell JSON Objekt ist in Abschnitt 5.4 zu finden. 5.5.2 Phase Zwei: Datendarstellung Das Metamodell ist nun an die Präsentationsschicht gebunden und folgedessen können nun die Datensätze dargestellt werden. Nun wird eine Ajax Anfrage zur Datenschnittstelle gestartet wo dann die Datensätze gelesen werden. Dies erfolgt in dem der an die Schnittstelle gebundene Kontroller die Anfrage an die Persistenz stellt und die Datesätze in einem Transferobjekt erhält. Das Resultat der Anfrage wird wiederum in ein JSON Objekt umgewandelt und an die Präsentationsschicht zurückgeleitet wo es dargestellt wird. 38 Philip Krauss KAPITEL 5. IMPLEMENTIERUNG 5.5.3 Flussdiagramm Das Flussdiagramm in Abbildung 5.7 zeigt nochmals grafisch die Schritte zur visuellen Darstellung einer generischen Entität. Abbildung 5.7: Flussdiagramm zur Darstellung der Generik 5.6 Assoziationen Die Assoziationen werden rekursiv gelöscht. Es wird ein Baum (Abbildung 5.8) erstellt aus den Datensätzen welche jeweils in Beziehung stehen. Wenn alle Datensätze mit den Kaskadierungsbedingungen (Tabelle 5.2) löschbar sind wird das erste Blatt im Baum gelöscht und so sich weiter den Baum nach oben gearbeitet. Damit der Baum mit dessen Knoten gebildet wird, steht das zu löschende Element an der Wurzel. Anhand der Assoziationen wird dann überprüft ob es referenzierende Datensätze gibt. Diese Datensätze bilden dann die momentanen Blätter und führen Philip Krauss 39 KAPITEL 5. IMPLEMENTIERUNG die Rekursion weiter auf sich selbst aus. So entsteht eine weitere Ebene bis es keine Assoziationen oder keine referenzierbaren Datensätze mehr gibt. Abbildung 5.8: Assoziationsbaum STOP ASK DELETE CLEAR Wenn Datensätze existieren, breche den Vorgang ab Fragt nach erneuter Bestätigung Lösche alle Datensätze Setze die Fremdschlüssel auf NULL Tabelle 5.2: Kaskadierungsoptionen für Assoziationen 40 Philip Krauss KAPITEL 5. IMPLEMENTIERUNG 5.6.1 Darstellung von assozierten Werten Beim Bilden eines generischen Entitätsobjektes ensteht das Problem das eine Spalte, zwei Werte besitzen muss wenn diese assoziert ist. D.h. der Wert der Referenz und den Wert der referenzierten Spalte im entsprechenden Datensatz. Z.B.: Attribute sind assoziert auf die Tabellen, somit besitzen die Attribute eine Spalte table id. Bei der Ausgabe soll allerdings nur der Tabellenname ausgegeben werden. Nun entsteht das Problem das man zwei Werte für eine Spalte benötigt. Durch einen Trick ist dies möglich. Mittels HTML und CSS kann man den effektiven Wert maskieren, also den Wert von table id. So werden beide Werte an die Präsentationsschicht übergeben doch nur ein Wert durch Ausnutzen der CSS Eigenschaften angezeigt. 5.6.2 Cachen von assozierten Werten Das Bilden eines generischen Entitätsobjekts mit mehreren Assoziatonen kann sehr langsam werden, da die Assoziationen aufgelöst werden. Um den Vorgang zu beschleunigen wurde ein Cache eingeführt welcher die Assoziationswerte zwischenspeichert. Das Cacheparadigma ist gleich dem eines Level 1 CPU Caches. Bei einem Cache Miss werden die Daten von der externen Datenquellen geholt, in diesem Fall die Persistenz. Bei einem Cache Hit liegt die Zugriffszeit bei O(1). Die Datensturktur des Caches (Siehe Quellcodelisting 5.5) ist eine zwei dimensionale Referenztabelle mit einem Referenzschlüssel und einer Referenz auf eine weitere zwei dimensionale Datentabelle. 1 2 H a s h t ab l e <Long , H a s h t a b l e <S t r i n g , S t r i n g >> c a c h e = new H a s h t ab l e <Long , H a s h t a b l e <S t r i n g , S t r i n g > >(); Listing 5.5: Datenstruktur des Caches Die Abbildung 5.9 zeigt den befüllten Zustand des Caches zur Laufzeit. Wobei die linke Tabelle die Referenztabelle darstellt und die Tabellen auf der rechten Seite jeweils die referenzierten Werte. Philip Krauss 41 KAPITEL 5. IMPLEMENTIERUNG Abbildung 5.9: befüllter Assoziations Cache 5.7 Helpers Helper wurden eingesetzt um Klassen zu entwickeln welche über mehrere Schichten verwendbar sind, bzw. um Wiederverwendbarkeit zu erreichen. In einem Helper ist nur eine bestimmte Funktionalität implementiert. 5.7.1 DatabaseHelper Der DatabaseHelper ist der zentrale Punkt um Logik zu kapseln für Datenbankoperationen. Er übernimmt Funktionalitäten wie die Bildung von Spaltennamen wo gegebenenfalls ein Alias möglich ist und besitzt Fabrikmethoden8 für weitere Helper, z.B. dem SyntaxBuilder (Abschnitt 5.7.2), zur Erstellung von SQL Syntax. 5.7.2 SyntaxBuilder SQL Syntax unterscheidet sich innerhalb der unterschiedlichen Datenbanksysteme. Deshalb ist der SyntaxBuilder über ein Interface definiert. Dies ist der empfohlene Weg um einen flexiblen Entwurf zu erhalten [Haf09]. Die Kommunikation mit der Klasse läuft nur über dessen Fabrikklasse, dem DatabaseHelper (Abschnitt 5.7.1) wobei dieser nur das 8 42 Entwurfsmuster: http://de.wikipedia.org/wiki/Fabrikmethode Philip Krauss KAPITEL 5. IMPLEMENTIERUNG Interface QuerySyntaxBuilder kennt. Das Klassendiagramm vom Interface QuerySyntaxBuilder ist im Appendix A.2.2. 5.8 XML Annotations Die XML Annotations liegen im Package javax.xml.bind.annotation. Sie werden benötigt für das Marshalling sprich die Konvertierung von Java Objekten zu JSON Objekten. Wichtig ist das man die Wurzel des Elementes angibt, mit @XmlRootElement(name = ”data”). Als Konvention für den Namen des Wurzelelements wurde immer data gewählt. Der Name des Wurzelelements ist wichtig für die Bildung des Metamodells, Siehe Abschnitt 5.4. Wird der Zugriffstyp @XmlAccessorType nicht auf XmlAccessType.FIELD gesetzt, versucht der JSON/XML Marshaller über die Getter der Variablen den Wert auszulesen. Dies führt zu Problemen mit assozierten Daten9 und ist lansamer da für jede Variable eine Annahme zu dessen Zugriffsmethode (Getter ) getroffen wird. Das Quellcodelisting 5.6 erklärt anhand einer Klasse was Getter und Setter sind. 1 2 3 4 5 6 7 8 9 10 11 12 public c l a s s Foo { /∗ P r i v a t e K l a s s e n v a r i a b l e ∗/ private S t r i n g name = ‘ ‘ f o o ’ ’ ; /∗ Z u g r i f f s m e t h o d e / G e t t e r f u e r d i e V a r i a b l e ’ name ’ ∗/ public S t r i n g getName ( ) { return t h i s . name ; } /∗ S c h r e i b m e t h o d e / S e t t e r f u e r d i e V a r i a b l e ’ name ’ ∗/ public void setName ( S t r i n g name ) { t h i s . name = name ; } } Listing 5.6: Erläuterung zu Zugriffsmethoden/Getter und Setter Ausserdem ist es übersichtlicher für den Programmier, da man nicht explizit ein @XmlTransient setzen muss wenn man eine Variable aus dem XML Scope entfernen will. Folgedessen müssen nur die Variablen annotiert werden. Dies passiert über @XmlElement 10 . Das folgende Quellcodelisting 5.7 zeigt eine Klasse welche konvertierbar zu JSON bzw. XML ist. 1 2 3 4 @XmlRootElement ( name = ” data ” ) @XmlAccessorType ( XmlAccessType . FIELD ) public c l a s s Bean implements S e r i a l i z a b l e { private s t a t i c f i n a l long s e r i a l V e r s i o n U I D = 4 7 7 1 4 5 6 2 6 0 4 8 1 9 5 4 0 8L ; 9 Erläuterung im Abschnitt 7.1.3 XmlElement API: http://docs.oracle.com/javase/6/docs/api/javax/xml/ bind/annotation/XmlElement.html 10 Philip Krauss 43 KAPITEL 5. IMPLEMENTIERUNG 5 @XmlElement private long i d = 1 2 3 ; 6 7 8 @XmlElement ( name = ” someBetterName ” ) private long a n u g l y l o n g v a r i a b l e n a m e = 6 1 5 4 ; 9 10 11 @XmlElement private S t r i n g name = ” i ’m a name” ; 12 13 14 } Listing 5.7: Beispiel: Java Model Aus der vorigen Java Klasse aus dem Quellcodelisting 5.7 würde folgendes JSON produziert werden, illustriert im Listing 5.8. 1 { ” data ” : [ { ” i d ” : ” 123 ” , ” someBetterName ” : ” 6154 ” , ”name” : ” i ’m a name” } ] 2 3 4 5 6 7 8 9 } Listing 5.8: Beispiel: Ausgabe in JSON von Java Model Um sich an die Javakonventionen zu halten, sind die Klassenvariabeln privat. Folglich besitzt jede mit XML Annotations annotierte Klasse auch passende Getter und Setter. 5.9 JSON Konvertierung Die Kontrollerschicht erhält den Datensatz als String in der JSON Notation. Für die Konvertierung in ein Java Objekt musste ein eigner Konverter geschrieben werden welche den String parst und in einem brauchbaren Format ablegt. Der Grund für die Vermeidung der native Konverter ist im Abschnitt 7.2 genauer erklärt. Da die ankommenden JSON Strings nicht verschachtelt sind, kann man die Tokens einzeln durchlaufen, wobei das erste Token den Schlüssel angibt und das folgende Token den Wert, siehe Abbildung 5.10. Auch als Key Value Paar bekannt. Abbildung 5.10: Parsen von nichtverschachteltem JSON [jso] 44 Philip Krauss KAPITEL 5. IMPLEMENTIERUNG Die Container Klasse speichert den Schlüssel und dessen Wert in einer Liste ab. So würde das JSON aus dem Quellcodelisting 5.9 nach der Konvertierung wie in der Tabelle 5.3 aussehen. 1 { ” i d ” : ” 730 ” , ”name” : ” i ’m a name” , ” d e s c r i p t i o n ” : ” none ” , 2 3 4 5 } Listing 5.9: Beispiel JSON String für Konvertierung Schlüssel id name description Wert 730 i’m a name none Tabelle 5.3: Tabellarische Darstellung vom JSON aus Listing 5.9 5.10 Editoren Editoren stellen eine grafische Schnittstelle zur Datenmanipulation dar. Ein Editor kann auch als Steuerelement betitelt werden. Sie können auch Logik besitzen, wie z.B. das ein Steuerelement nicht leer sein darf oder das nur Zahlen zulässige Eingaben sind. Editoren werden durch das ExtJs Framework unterstützt und werden automatisch instanziiert wenn in dem Feldobjekt die Eigenschaft editor gesetzt ist. Editoren können direkt über ein Formularobjekt gebildet werden oder über die Eigenschaft xtype. 5.10.1 Xtype Der xtype gibt die Variante des Editors an und instanziiert das mit dem übergebenen Eigenschaften die des xtypes entsprechde Formobjekt. Da man in ExtJs neue Klassen erstellen kann und bestehende Klassen erweitern, kann man auch seinen eignen xtype definieren bzw. im Namespace registrieren. 5.10.2 Text Texteditoren sind wie im Beispiel in Abschnitt 5.4.1 zu sehen mit dem xtype textfield definiert. Die folgenden Eigenschaften sind nicht obligatorisch, doch kann man über allowBlank eine Benutzereingabe erzwingen bevor das Formular abgeschickt wird. Weiters kann man mit der Philip Krauss 45 KAPITEL 5. IMPLEMENTIERUNG Eigenschaft blankText die Standard Fehlermeldung für den Benutzer überschreiben. 5.10.3 Zahlen Zahleneditoren sind mit dem Xtype numberfield gekenzeichnet. Man kann einen Editoren auf eine selbst definierte Range konfigURIeren. ExtJs übernimmt dann die Prüfung der Eingabe. 5.10.4 Datum Datumseditoren sind mit dem xtype datefield gekennzeichnet. Der Datumseditor ist ein Textfeld mit einer Schaltfläche die nach Betätigung einen Kalender Dialog anzeigt wo der Benutzer sich das Datum auswählen kann. 5.10.5 Binär Ein Binäreditor liefert ein Checkbox objekt zurück welches aktiv oder inaktiv sein kann. Die Binäreditoren haben den xtype checkbox. 5.10.6 Listen Listeneditoren oder auch Drop Down-Listen sind Steuerelemente welche dem Benutzer eine Auswahl der Elemente bieten. Eine Anwendung für Listen ist die Ausgabe von assozierten Daten. Der Benutzer sieht nur die Elemente in der Liste welche aber intern über den Fremdschlüssel abgespeichert werden. Ein Listeneditor ist live. Das heisst wenn man die Liste betrachten will bzw. ein Element auswählen wird die Liste neu populiert. Die Population findet also asynchron statt. Events welche von dem Benutzer auf dem Editorobjekt ausgelöst werden, stossen das Objekt selbst an nach den Daten über eine REST URI nachzufragen und den Store des Listenobjekts zu füllen. Der Vorteil ist das Änderungen der Daten sofort verfügbar sind und nicht wie üblich in Webapplikation die Seite neu geladen werden muss. Der Store eines Listen Editors wird über das Resultat einer Query befüllt. Das Resultat wird als JSON zurück an den Editor gesendet. Somit muss die Id der auszuführenden Query dem Objekt bekannt sein, z.B. ist das Objekt nun auf die Query mit der Id 16 gebunden, wird wenn der Benutzer ein Event zum Anzeigen der Liste die URI http://host:port/context/app/queries/run/16 aufgerufen. Die REST URI produziert nun die zur Id 16 passende Ressource, wandelt diese in JSON um und sendet das Resultat zurück zum aufrufendem Objekt. Ein solches JSON wird im folgenden Quellcodelisting 5.10 auf der Seite 45 gezeigt. Das Klassendiagramm ist im Appendix unter A.2.6 zu finden. 46 Philip Krauss KAPITEL 5. IMPLEMENTIERUNG 1 { ” s u c c e s s ” : true , ” t o t a l ” : 16 , ” message ” : ”Found : 16 r e c o r d ( s ) ! ” , ” dbMessage ” : ” no message . . . ” , ” data ” : [ { ” t a b l e n a m e s −name” : ” a s s o c i a t i o n s ” , ” t a b l e n a m e s −i d ” : ” 2 ” }, { ” t a b l e n a m e s −name” : ” a t t r i b u t e s ” , ” t a b l e n a m e s −i d ” : ” 3 ” }, ... } ] 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 } Listing 5.10: JSON Ausgabe nach Produktion von Query Resultat 5.11 Transferklassen Transferklassen bilden das Nachrichtensystem zwischen den Schichten. Beim Zugriff auf eine Schicht antwortet diese mit einer Instanz einer Transferklasse, einem Transferobjekt. Die Art des Transferobjektes ist abhängig von dem Anfragentyp. Deshalb wurden die Anfragen in zwei Kategorien unterteilt. Typ Lesen Status Beschreibung Finde die Daten und reiche Sie weiter. Benachrichtige über Fehler Ermittle den Status der Transaktion Tabelle 5.4: Typen der Transferklassen Beide Kategorien besitzen zum Teil idente Eigenschaften. Eine wichtige Eigenschaft ist das Success Flag. Dieses erlaubt es den Status einer Transaktion zu ermitteln. Ausserdem wird immer eine Nachricht message weitergereicht welche den Status bzw. Fehlermeldungen textuell mitführt. Bei Datenbankfehlern wird das Feld dbMessage genutzt, um im Fehlerfall die Meldung weiterzuleiten. Philip Krauss 47 KAPITEL 5. IMPLEMENTIERUNG 5.11.1 Datentransferklasse Die Datentransferklasse wird immer im Bezug zu der Persistenz benutzt. Das Lesen von Daten wird angefordert und die Persistenz liest die Daten ein, packt Sie in das Transferobjekt und übergibt Sie der anfragenden Klasse. Um die Struktur eines Datensatzes zu behalten und noch immer Klassen zu benutzen welche in JSON konvertierbar sind, wurden native Java Klassen benutzt. Die Abbildung eines Datensatzes ist über eine java.util.HashMap möglich. Dabei bildet der HashKey den Spaltennamen und der HashValue gibt den Inhalt an. Damit man nun mehrere Datensätze in der Klasse ablegen kann benötigt man die java.util.ArrayList. Die Datentyp der java.util.ArrayList ist die java.util.HashMap wie im Quellcodelisting 5.11 gezeigt wird. 1 2 private A r r a y L i s t <HashMap<S t r i n g , S t r i n g >> data = new A r r a y L i s t <HashMap<S t r i n g , S t r i n g > >(); Listing 5.11: Datenstruktur zur Abbildung einer Tabelle Eleganter wäre die Benützung der Interfaces doch sind diese nicht in JSON oder XML konvertierbar. Eine ausführliche Erklärung dazu findet sich im Abschnitt 7.1.1. Die Abbildung 5.11 zeigt das Klassendiagramm der Datentransferklasse. Abbildung 5.11: Datentransferklasse 48 Philip Krauss KAPITEL 5. IMPLEMENTIERUNG 5.11.2 Statustransferklasse Statustransferklassen geben den Status zurück. Eine weitere Eigenschaft ist das wenn eine Schreiboperation auf der Persistenz ausgeführt wird, liefert das Rückgabeobjekte die Id des Datensatzes mit. Dies erfolgt nur unter der Permisse dass die Schreibtransaktion keine Modifikation eines bestehenden Datensatzes sondern die Erstellung eines neuen Datensatzes war. Die folgende Abbildung 5.12 zeigt das Klassendiagramm. Abbildung 5.12: Statustransferklasse 5.12 Erweiterungen Erweiterungen sind über ein reserviertes Servlet einspielbar. Das Servlet hat den Namen ExtensionController 11 und ist von der Klasse Controller abgeleitet wo generische CRUD Operationen und Flusskontrollmethoden implementiert sind und folgedessen dem Entwickler zur Verfügung stehen. Methoden können rein als Web Service implementiert werden um Daten zu produzieren bzw. mit den konsumierten Daten bestimmte Operationen auszuführen. Erweiterungen können allerdings aus Formulare und/oder Ansichten (Views) bestehen, wobei man eine neue Java Server Page kurz JSP erstellen muss mit dem gewünschten Inhalt. Auf diese JSP wird dann über den Controller mit der render() Methode referenziert und das entsprechende JSP wird angezeigt. 11 Der ExtensionController at.ac.uibk.controllers.extensions Philip Krauss befindet sich im Java Package: 49 Kapitel 6 Handbuch Das Handbuch dient der Erklärung im Umgang mit der Software. Die grafischen Elemente wie Icons werden gezeigt und dessen Bedeutung. 6.1 Desktop Der Desktop (Abbildung 6.1) ist der Startschirm und weiters der Zentrale Punkt der Webapplikation. Von hier aus sind alle Elemente zu erreichen. Wenn der Desktop bis geladen ist benötigt dieser nicht mehr neu geladen zu werden, ausser es würden neue sichtbare Elemente hinzugefügt werden. Abbildung 6.1: Der Desktop 51 KAPITEL 6. HANDBUCH 6.1.1 Desktop Icons Die Desktop Icons ermöglichen den Zugang zu den unterschiedlichen Elementen der Generik. Öffnen einer Ansicht/View Öffnen einer Listfeld-Ansicht Datenfeld-Ansicht einer Entität Ausführen einer Abfrage/Query und visuelle Darstellung Tabelle 6.1: Desktop-Icons 6.1.2 Systemkomponenten Systemkomponenten sind jene die für die Verwaltung der Generik vorgesehen sind. Da diese nicht immer benötigt werden sind sie ’versteckt’. Die Anzeige erfolg wenn man in der Top Toolbar (Abbildung 6.2) auf die beiden Schraubenschlüssel klickt. Abbildung 6.2: Top Toolbar 52 Philip Krauss KAPITEL 6. HANDBUCH Dann zeigt sich die Toolbar mit den Systemkomponenten wie in die Abbildung 6.3 zeigt. Abbildung 6.3: Systemkomponenten Toolbar Die Icons der Systemkomponenten bilden das gleiche Paradigma wie die der Desktop-Icons ab. Sie dienen den Zugang zu den entsprechenden Operationen. Tabellen Tabellenattribute Entitäten Abfragen/Queries Assoziationen Ansichten/Views Listfeld-Ansichten Formulare Editoren Parameter Erweiterungen Tabelle 6.2: Toolbar -Icons Philip Krauss 53 KAPITEL 6. HANDBUCH 6.2 Ansichten Eine Ansicht entspricht der Darstellung von Daten einer Entität. Dabei wird zwsichen drei verschiedene Ansichtstypen unterschieden, der Datenfeld-Ansicht, der Formular-Ansicht und der Listfeld-Ansicht. 6.2.1 Datenfeld-Ansicht Die Datenfeld-Ansicht ist eine tabellarische Darstellung einer Entität. Über diese Ansicht ist es möglich auf einer Entität zu arbeiten, sprich sämtlich CRUD-Methoden1 auf der gewählten Entität auszuführen. Ein Beispiel der Datenfeld-Ansicht zeigt die Abbildung 6.4. Abbildung 6.4: Datenfeld-Ansicht Die untere Schaltfläche ermöglicht die Datenmanipulation, sowie die Live Anpassung der Ansicht (Siehe Abschnitt 6.2.4), das Neuladen der Fensterinstanz, das Aktivieren des Inline Editors, die Ausgabe des Loggers und das Schliessen des Fensters. Durch das Klicken in eine Zeile wird der Inline Editor aktiv. Dieser erlaubt es die Werte des ausgewählten Datensatzes direkt innerhalb der Zeile zu manipulieren. Ist der Inline Editor in der Schaltfläche aktiviert wird beim Erstellen eines neuen Datensatzes der Inline Editor verwendet, anderfalls wird die Formular-Ansicht aufgerufen. Die Formular-Ansicht wird im Abschnitt 6.2.3 beschrieben. 1 54 CRUD: Create Read Update Delete Philip Krauss KAPITEL 6. HANDBUCH 6.2.2 Listfeld-Ansicht Listfeld-Ansichten dienen dem schnellen Finden von Daten. Sie basieren auf Queries und können deshalb nicht editiert werden. Um das schnelle Finden zu erleichtern kann man das Resulat eingrenzen mit Hilfe der Filtrierungsoptionen, wie die Abbildung 6.5 auf Seite 52 zeigt. Abbildung 6.5: Listfeld-Ansicht 6.2.3 Formular-Ansicht Formulare können von generischer Natur oder selbst definiert sein. Selbst definierte Formulare und wie man diese mit einer Ansicht bindet wird genauer im Abschnitt 6.6 beschrieben. Falls kein selbst definiertes Formular an die Ansicht gebunden ist wird ein generische Formular generiert, siehe Abbildung 6.6. Die Formularfelder sind identisch mit den Spalten der Datenfeld-Ansicht. Falls eine neuer Datensatz erstellt wird, sind die Eingabefelder unpopuliert und im Falle einer Änderung eines Datensatzes sind die Werte bereits gesetzt. Philip Krauss 55 KAPITEL 6. HANDBUCH Abbildung 6.6: Generische Formular-Ansicht 6.2.4 Personalisiern der Spalten im Live Betrieb Die Spalten einer Ansicht können direkt in der Verwaltung der Views angepasst werden oder im Live Betrieb einer offnen Fensterinstanz. Um die Ansicht zwecks dessen Spalten anzupassen muss man auf den Button View Config in klicken. Dann öffnet sich ein Fenster, wie in Abbildung 6.7 zu sehen ist, in welchem man das Anzeigen einer Spalte aktivier bzw. abschalten kann. Abbildung 6.7: Spalten einer Ansicht anpassen 56 Philip Krauss KAPITEL 6. HANDBUCH 6.3 Tabellen Die Verwaltung einer Tabelle ist in der Toolbar der Systemkomponenten zu finden (siehe Abschnitt 6.1.2). Die verwendete Ansicht ist die Datenfeld-Ansicht, welche im Abschnitt 6.2.1 beschrieben wird. Um eine neue Tabelle zu Erstellen, benützt man den Add Button in der Schaltfläche der Datenfeld-Ansicht. Die Modifikation bzw. Erstellung einer Tabelle impliziert eine weitere Routine welche die Änderungen auf der physikalischen Tabelle durchführen. Sprich wird der Tabellenname im Datensatz geändert wird auch der Tabellenname der physikalischen Tabelle geändert. 6.4 Attribute Attribute verhalten sich wie die Tabellen und implizieren eine Routine welche die Änderungen am Datensatz sowie am Tabellenschema durchführen. Ein Attribute ist abhängig von einer Tabelle, somit muss man aus der Auswahlliste die Tabelle auswählen. Ebenso gilt dies für den Datentyp un dessen Grösse. Diese Werte sind essentiel für das Tabellenschema. Weiters kann man angeben ob das Attribute nullable ist, dessen Reihenfolge für die visuelle Darstellung, einen Defaultwert, die Spaltenbreite für die Darstellung und einen Alias für die Spaltenüberschrift. Ein Editor ist ebenfalls hier konfigURIerbar. Wenn der Wert nicht geändert wird, bleibt der Standardeditor gesetzt. Mehr zu Editoren findet im Abschnitt 6.7. 6.5 Assoziationen Assoziationen werden über 1:n Relationen gebildet. Will man m:n Relationen abbilden muss man zwei Assoziationen transitiv anlegen. Beispielsweise stehen die Entitäten A und B in einer m:n Relation, mit der Relationstabelle Z. Daraus folgt A → Z → B. Die Definition geht von der assozierten Entität aus, d.h. die Entität mit dem Fremdschlüssel. Diese definiert das der Fremdschlüssel auf ein bestimmtes Attribut einer bestimmten Tabelle referenziert. Für die Darstellung bzw. der Verschleierung der Felddaten muss ein Value Attribute angegeben werden. Dieses ist das Attribut, wessen Wert anstelle des Fremdschlüsselwertes angezeigt wird. 6.6 Formulare Mittels der Entitätformulare kann der Benutzer eigne Formulare erstellen. Wichtig ist das Formular mit der Id 1 und dem Namen Generic Philip Krauss 57 KAPITEL 6. HANDBUCH Form. Das Formular darf nicht gelöscht werden. Wie man erkennt besitzt das Formular keine Datei welche gerendert wird beim Aufruf des Formulars. Dies ist ein Platzhalter für die Konfiguration eines generischen Formulars. Andernfalls muss für jede Ansicht ein entsprechendes Formular entwickelt werden. Ein Formular ist durch seinen Namen, einer Beschreibung und dem Dateinamen gekennzeichnet. Der Dateiname gibt den Pfad zur Datei an welche das selbstdefinierte Formular enthält. 6.6.1 Erstellen von eignen Formularen Ein eigenes Formular ist in einer JSP Datei abgelegt. Die Datei trägt den gleichen Namen, wie der des Dateinamens innerhalb des Datensatzes. Die Datei wird im Verzeichnis, src/main/webapp/views/forms/ abgelegt. Das neue Formular muss deployed werden damit es in der Applikation präsent ist. Das Deployen und Kompilieren von der Applikation wird im Abschnitt 6.8 beschrieben. Um Fehler zu vermeiden gibt es eine Model Datei blank.jsp. Das Einfachste ist diese Datei zu kopieren und in den entsprechenden Namen umzuändern. In der kopierten Datei existieren schon vorkonfigURIerte Optionen und die Einbindung von übermittelten Daten. Beim Rendering der Datei wird automatisch der Datensatz als JSON Objekt übergeben. Dies natürlich nur unter der Prämisse dass eine Modifikationsanfrage ausgeführt wird, da beim Erstellen von einem Datensatz, keine Daten existieren. In der Datei kann man dann mit dem JSON Objekt arbeiten wenn man es wie folgt einbindet. 1 <% f i n a l JSONObject r e c o r d = ( JSONObject ) pageContext . f i n d A t t r i b u t e ( ” i t ” ) ; 2 3 4 %> Listing 6.1: Auslesen von übergebenen Daten Um nun Daten aus dem JSON Objekt zu erhalten benutzt man die get( java.lang.String key ) Methode. Die Methode get( String ) gibt in dieser Benützung immer ein Objekt der Klasse java.lang.Object zurück. Man kann allerdings auch typisierte Getter benützen. Will man beispielsweise den Wert von dem Schlüssel name wissen, so würde man die Methode wie folgt aufrufen. 1 <%= r e c o r d . g e t ( ”name” ) %> Listing 6.2: Wert von name auslesen Weiters ist die isNull( java.lang.String key ) Methode sehr nützlich. Sie hilft dabei abzufragen ob dieser Schlüssel überhaupt existiert. So kann man über eine simple If Kontrollstruktur auf dem JSONObject Objekt arbeiten. Sonst müsste man try-except Kontrollstrukturen benützen. 58 Philip Krauss KAPITEL 6. HANDBUCH 1 2 3 <% i f ( ! i s N u l l ( ”name” ) { %> H a l l o , <%= r e c o r d . g e t ( ”name” ) %>! <% } %> Listing 6.3: Sicherer Schlüsselzugriff auf JSON Werte Die Klasse JSONObject ist wesentlich mächtiger als die hier gezeigten Beispiele. Die API der Klasse JSONObject findet sich unter http:// www.json.org/javadoc/org/json/JSONObject.html. 6.7 Editoren Editoren unterscheiden sich in deren Darstellung und Funktionalität. Die Darstellung wird durch den xtype bestimmt, siehe Abschnitt 5.10 für eine Erklärung der verschiedenen xtypes. Der Standardeditor hat die Id 1. Dieser Editor wird automatisch gemappt falls keine andere Konfiguration für ein Attribute vorgesehen ist. 6.7.1 Texteditoren Ein Texteditor wird mittels des xtypes textfield instanziiert und behandelt alphanumerische Zeichenketten. Die einzige Konfigurationsmöglichkeit ist das Überschreiben der Fehlermeldung. 6.7.2 Binäreditor Eine Binäreditor ist mit dem xtype checkbox versehen und besitzt keine Konfigurationen. Man kann bedenkenlos den bereits definierte benützen. Sämtliche binäre Logik ist bereits in diesem Editor gekapselt. 6.7.3 Zahleneditoren Ein Zahleneditor ist mit numberfield als xtype gekennzeichnet. Zahleneditoren können wie der Name es schon nur mit Zahlen umgehen, sprich erlauben nur numerische Eingaben. Man kann einem Zahleneditor auch eine Range zuordnen, dabei gibt man den minimal Wert und/oder den maximal Wert an. 6.7.4 Datumseditoren Datumseditoren sind mit dem xtype datefield markiert. Diese Editoren erlauben eine händischen Eingabe eines Datums oder man benutzt das Eingabe-Interface wie in Abbildung 6.8. Bei einer händischen Eingabe muss allerdings der Benutzer Kenntniss über das gewünschte Format haben. Das Standardformat ist Tag-Monat-Jahr, d-m-Y. Philip Krauss 59 KAPITEL 6. HANDBUCH Abbildung 6.8: Datumseditor mit Eingabe-Interface 6.7.5 Listeneditoren Listeneditoren werden auch als Combobox bezeichnet und tragen den xtype combo. Ein Listeneditor basiert auf einer Abfrage/Query. Somit muss bevor ein Listeneditor erstellt wird, die passende Abfrage erstellt werden. Zur Erstellung eines Listeneditors wählt man die Abfrage aus und zwei Attribute. Diese Attribute sind zunächst das Value-Attribute, sprich das Attribute dessen Wert benutzt wird und das Display-Attribute, welches das Attribut ist dessen Wert angezeigt wird. Eine typische Anwendung ist bei den Assoziationen, wo das Value-Attribut die Id ist und das Display-Attribut z.B. der Name. Weiters kann man einen Listeneditor auf eine Entität binden. Dann taucht hinter dessen Darstellung ein Knopf auf, überwelchen man die Entität öffnen kann. 6.8 Applikation mit Maven kompilieren Um die Applikation zu kompilieren wird Maven benutzt. Prinzipiell ist es nicht nötig die Applikation neu zu kompilieren ausser Erweiterungen bzw. neue Formulare sollen in den Live Betrieb eingespielt werden. Maven wird hier nur auf der Kommandozeile benützt, da sich die Applikation auf einem virtuellen Webserver befindet und der Zugang nur über SSH 2 möglich ist. Um Maven bedienen zu können benötigt es Befehlsargumenten, welche in der Tabelle gezeigt werden. Natürlich ist Maven wesentlich reicher an Befehlsargumenten als die hier aufgelisteten, doch würde sich rein auf die benötigten beschränkt. 2 60 SSH : Secure Shell, http://de.wikipedia.org/wiki/Secure_Shell Philip Krauss KAPITEL 6. HANDBUCH clean package tomcat:deploy Target Folder leeren. Beim Kompilieren werden die .class Dateien mit den webspezifischen Dateien wie z.B. CSS und JavaScript in diesem Verzeichnis abgelegt. Das dient dem Zweck des Deployens. Ansicht ist das Verzeichnis die fertige Webapplikation, die dekomprimierte war Datei. Die Applikation wird abhängig von dessen Architektur in eine war oder jar Datei gepackt. Die Applikation in den Einsatz schicken, sprich dem Tomcat Server die Applikation übergeben und starten. Tabelle 6.3: Maven Befehlsargumente Es ist noch zu Erwähnen das man die Webapplikation redeployed wird, falls diese schon deployed wurde. D.h. der korrekte Befehl wäre eigentlich tomcat:redeploy. Dies ist natürlich möglich doch nicht nötig wegen einer Maven Konfiguration welche das Updaten einer laufenden Webapplikation erlaubt. Allerdings ist das deploy besser geeignet, weil es die Applikation zuerst komplett entfernt und dann eine neue Applikation startet. Damit wird auch der Applikationscache geleert. Will man die Applikation nach Änderungen deployen, benutzt man den Maven Befehl mvn. Als erstes wechselt man in das Wurzelverzeichniss der Applikation, z.B. /home/workspace/bachelorthesis und gibt dann die Befehlsparameter in der gewünschten Reihenfolge nach dem Maven Befehl an. So z.B. will man als erstes die Applikation säubern, dann kompilieren und als letztes, diese in den Einsatz schicken. [root@dmis-w6690 ~]# mvn clean package tomcat:deploy Der Befehlsparameter package ist nicht zwingend nötig da dieser autonom ausgeführt wird wenn der Parameter tomcat:deploy getroffen wird und keine kompilierte Version zur Verfügung steht. Falls die Applikation auf einen neuen Server verlegt wird, wird das erste Ausführen des Befehls ein paar Minuten dauern, da als erstes sämtliche Dependencies aufgelöst und die Bibliotheken (jar -Dateien) in einem lokalen Repository abgelegt werden. Mehr zu dem Apache Maven Projekt findet sich unter http://maven.apache.org/, [Spi09]. Philip Krauss 61 Kapitel 7 Diskussion Dieses Kapitel beschäftigt sich mit Komplikationen die während des Entwurfsprozesses als auch des Entwicklungsprozesses aufgetreten sind. Weiters werden die Erweiterungen und Änderungen im Bezug zu dem vorgestellten Prototype erklärt. Das Kapitel beschreibt zu erst die Komplikationen und stellt in einem zweiten Teil die Änderungen vor. 7.1 Softwareentwurf Bei dem Softwareentwurf musste manchmal eine Alternative gefunden werden um die vollständige Unterstützung des JAX-RS-WS und Hibernate Frameworks zu erhalten. 7.1.1 Benützung von Interfaces Aufgrund der Konvertierung zu JSON oder XML konnten keine Interfaces für Klassen benützt werden welche zwischen Kontroller- und Präsentationsschicht ausgetauscht werden. Dabei handelt es sich um die Transferklassen, welche im Abschnitt 5.11 erklärt werden. Das Problem liegt daran das ein Interface ein Objekt nicht vollständig beschreiben kann wie ein Klasse bzw. Objektinstanz. Schlussfolgerend ist ein flexibler Entwurf nicht immer möglich. Als Beispiel wären die ExtJs Editoren zu nennen wo eine polymorphe Klasse definiert wird anstelle eines Interfaces. 7.1.2 Datentyp long Primitive Datentypen mussten gegebenenfalls auf deren Klasse umgewandelt werden. Verschiedene Attribute können null sein. Der primitive Datentyp long kennt null nicht und wirft dementsprechend eine Excep63 KAPITEL 7. DISKUSSION tion 1 . Durch die Benützung der Klasse Long kann man das Problem lösen, da im Fall eines Null wertes ein leere Objektinstanz entsteht. 7.1.3 Bidirektionale Referenzen Die Mächtigkeit von Hibernate kann leider nicht komplett ausgenutzt werden. Durch Bidirektionale Referenzen entstehen Zyklen bei der Konvertierung zu JSON bzw. XML. Als Beispiel könnte man als POJO die Entität und die Tabelle nehmen. Dabei refrerenziert der Datenstamm auf die Tabelle mit 1:n und die Tabelle mit n:1. Dadurch entsteht eine Bidirektionale Referenz, eine Endlosschleife. Abbildung 7.1: Zyklen durch Bidirektionale Referenzen Bei der Konvertierung der Entität erkennt der Konverter das eine Variable Tabelle vorhanden ist und folgt dem Pfad zu der Klasse Tabelle. Logischerweise referenziert die Tabelle dann wiederum auf die Entität und der Kreislauf wiederholt sich. Eine Endlosschleife wäre das Resultat. Der Konverter erkennt das er diesen Pfad schon überquert hat, beendet den Vorgang und wirft eine Exception. Dadurch konnten nur einseitige Referenzen gebildet werden. 7.2 Konvertierung von JSON Die nativen Konvertierungsroutinen des JAX-RS-WS Frameworks verlangen eine konkrete Klasse für die Konvertierung. Zum Einsatz kommt die Klasse javax.xml.bind.JAXBElement<T>, wobei T ein generischer Typ ist wo die Klassendefinition verlangt ist. Das Paradigma ist ähnlich dessen der POJOs in Hibernate. Das Objekt wird populiert als dem JSON- bzw. XML String. Allerdings trifft der Faktor der Generik mit 1 Es wird eine NullPointerException geworfen, http://docs.oracle.com/javase/ 1.4.2/docs/api/java/lang/NullPointerException.html 64 Philip Krauss KAPITEL 7. DISKUSSION dessen Laufzeitdynamik zu. Somit gibt es keine konkrete Klasse als Typisierungsreferenz. Ein JSON Konverter wurde entwickelt für die Abtastung flacher JSON Strings und generischer Konvertierung (Siehe Appendix A.2.5). Zusätzlich ist der Standard Java zu JSON bzw. XML Konvertierer nicht in der Lage anhand der XML Annotations Klassen zu konvertieren. Deshalb wird beim Booten des Servers die Umwandlungsroutine überschrieben und das Framework mit der Fähigkeit versehen. 7.3 JavaScript Alle Programmiersprachen sind unterschiedlich, ob nun im Bezug auf deren Syntax oder Datentypisierung oder ob diese kompiliert bzw. interpretiert werden. Im Zusammenspiel verschiedener Sprachen müssen Brücken die Kommunikation dazu bilden. Eine solche Brücke stellt hier JSON dar. 7.3.1 Der Punktoperator Genau wie Java benutzt auch JavaScript den Punkt (’.’) als Objektoperatorzeichen. Der Unterschied ist das Java kompiliert und JavaScript interpretiert wird. Also muss man vor der Übergabe eines JSONs, der Präsentationsschicht alle Punktzeichen durch ein anderes Zeichen ersetzen. Sonst betrachtet JavaScript den String als Objekt und versucht dessen Methode auf zu rufen. Wird z.B. als JSON {0 a.b0 :0 keinObjekt!0 } übergeben, wird JavaScript versuchen die Methode b von Objekt a aufzurufen. Allerdings ist dies nur ein Problem wenn man Indizese zur Datenpopulation setzen will, wie z.B. im MetaGridPanel. Dieses Verhalten kann man auch ausnutzen, wie es mit den Editoren gemacht wird. Durch den Punktoperator instanziiert JavaScript automatisch das neue Objekt. Mehrere Informationen dazu findet man im Abschnitt 5.10. 7.3.2 Der Gültigkeitsbereich Bei der objektorientierten Programmierung von JavaScript gibt es einen Gültigkeitsbereich (engl. Scope). Dies kann problematisch sein für die Entwicklung der Handler Routinen welche auf die Ereignisse wie Klicks reagieren. Innerhalb der Handler Routine sind nur die vom Ereignis als Parameter übergebenen Variablen bekannt, sprich innerhalb des Scopes. Benötigt man nun Wissen über andere Objekte innerhalb des Document Object Model s (kurz DOM) muss man diese über dessen Id ansprechen. Damit eine Id bekannt sind kann man einen implementierten Cache ansprechen welcher die wichtigsten Id Werte speichert und Philip Krauss 65 KAPITEL 7. DISKUSSION über einen String Schlüssel verfügbar macht. Dieser Cache ist in der erwähnten Handler Routine nicht bekannt. Somit wird dieser über eine fixe/konstante Id instanziiert und bleibt dadurch immer ansprechbar. Um nun Daten aus dem Cache auszulesen bzw. zu setzen muss diesen mittels seiner fixen Id über das DOM adressieren. 1 2 // Cache a n s p r e c h e n und i n V a r i a b l e s e t z e n v a r c a c h e = document . getElementById ( ’ c a c h e ’ ) ; 3 4 5 // Wert i n Cache s c h r e i b e n c a c h e . s e t ( ’ wert ’ , 123 ) ; 6 7 8 // Wert aus Cache a u s l e s e n v a r v = c a c h e . g e t ( ’ wert ’ ) ; Listing 7.1: Zugriff auf JavaScript Cache Objekt Die Handler Routinen von Ereignissen werden auch als Callbacks bezeichnet. 7.4 Metamodell Varianten Das Metamodell wäre auch erstellbar durch das live abfragen der Tabellendefinition. Dieser Ansatz ist in vielen Frameworks zu finden wie z.B. Ruby On Rails oder CakePHP und wird als scaffolding 2 bezeichnet. Die Idee ist es schnell einen Prototyp zu erhalten um so leichter mit dem Kunden die Oberfläche zu gestalten. Das Konzept stammt aus der agilen Softwareentwicklung. Doch würde dieses scaffolding diverse Probleme mit sich bringen, etwa dass es sehr komplex wäre die Editoren an die bestimmten Attribute zu hängen. So könnte man diese nur anhand dessen Datentypen ermitteln. Oder im Falle von Änderung der Tabellendefinition die assozierten Tabellen mit zu ändern. Das in diesem Projekt größte Problem wäre das man wieder eine Schritt näher zur Datenbank gehen müsste. Nicht jedes Datenbanksystem kann ein DESCRIBE TABLE ’xyz’; ausführen. Anders kann man mit den Basis SQL Statements das gleiche Verhalten produzieren. 7.5 Assoziationen und Datenbanksysteme Ein Weg Assoziationen zu verwalten wäre der pragmatische, etwa das Datenbanksystem für sich arbeiten zu lassen. Die meisten Datenbanksysteme können intern selbst die Organisation der Assoziationen übernehemen. 2 66 http://en.wikipedia.org/wiki/Scaffold_(programming) Philip Krauss KAPITEL 7. DISKUSSION Aber genau da liegt das Problem. Nicht alle Datenbanksysteme beherrschen diese Referenzverwaltung. Weiters wäre dies wieder ein Schritt näher zur Datenbank. Folglich werden Assoziationen nur über Basis SQL Statements verwaltet. 7.6 Erweiterungen und Änderungen Dieser Abschnitt beschreibt die konzeptionellen Änderungen im Bezug zum Prototyp. Die offensichtlichsten Änderungen ist wohl die Portierung einer Desktop-Anwendung zu einer Webapplikation. Dabei musste die Programmiersprache gewechselt, Java und JavaScript ersetzen nun Microsoft Visual Basic. 7.6.1 Das Konzept des Metamodells Das Metamodell ist ein neues Konzept das keine Anwendung im Prototyp fand. Im Prototyp war dies auch nicht nötig aufgrund der ClientServer Architektur. Der Prototyp bildet eine Client-Server Architektur zwischen dem Datenbanksystem und der Anwendung ab. Allerdings bildet eine Webapplikation eine Client-Server Architektur zwischen dem Webserver und dem Datenbanksystem und eine weitere zwischen dem Webserver und dem Benutzer. Sprich zwischen dem Benutzer und dem Datenbanksystem besteht eine transitive Client-Server Architektur. 7.6.2 SQL Anfragen Im Prototyp sind die SQL Anfragen hartkodierte MySQL Statements, welche in einer Tabelle abgelegt sind. Folglich ist ein Wechsel zu einem anderen Datenbanksystem mit hohen Entwicklungskosten verbunden. Deshalb wurde das Java Interface, Broker eingeführt und eine lose Koppelung erworben. Die SQL Anfragen werden anhand des SyntaxBuilders (Siehe Appendix A.2.2) für das entsprechende Datenbanksystem generiert. Nun werden die Spalten einer Entität und dessen referenzierten Entitäten einer Abfrage zugewiesen. Dabei können Aliase für die Spaltenname sowie die Tabellennamen gesetzt werden. Weiters kann man ebenfalls Funktion wie COUNT benutzen. Die Abfragen sind Basis verschiedener Komponenten wie der Listfeld-Ansicht und den Listeneditoren. Abfragen können bei der Erstellung sofort auf deren Korrektheit überprüft werden und liefern gegebenenfalls eine Fehlermeldung zurück. Philip Krauss 67 KAPITEL 7. DISKUSSION 7.6.3 Schemaänderungen zur Laufzeit Der Prototyp ist nicht in der Lage bei einer Änderung einer Entität dessen Schema direkt anzupassen. So muss das neue Schema als SQL Statement generiert werden und in das Datenbanksystem eingespielt werden. Diese Software kann die Schemaänderungen wärend der Laufzeit anpassen. Bei Änderungen werden die Operationen in zwei Phasen ausgeführt. Das Flussdiagramm zeigt die Phasen, siehe Abbildung 7.2. Als erstes wird der entsprechende Datensatz modifiziert bzw. erstellt, dann wird der Schemamodifikationsbefehl ausgeführt. Abbildung 7.2: Flussdiagramm einer Schemaänderung zur Laufzeit Beide Phasen sind mit Rollback s versehen, um im Fehlerfall um die Datenintegrität nicht zu verletzen. 7.6.4 Editoren Editoren können zur Laufzeit erstellt werden und Spalten zugewiesen werden. Ebenfalls können eigens definierte SQL Abfragen einem Listeneditor zugewiesen werden. Ein Listeneditor wird zum Großteil benutzt um die Fremdschlüssel zu verstecken und Benutzerfreundlichkeit zu erhöhen. Folglich muss ein Listeneditor zwei Werte kennen, den Wert des Fremdschlüssels und den des darzustellenden Wertes. 68 Philip Krauss KAPITEL 7. DISKUSSION 7.6.5 Durchsatz Der Prototyp behandelt Entitäten mit dessen Referenzen als eine Menge, folglich entstehen dabei keine Durchsatzeinbußen. Da allerdings ein Paradigmawechsel der SQL Abfragen erfolgte wobei eine Entität linear durchlaufen wird und die Referenzen beim Durchlaufen des Resultats gemappt werden, ensteht ein Flaschenhalseffekt. Alle Referenzen müssen wieder via SQL Abfrage ermittelt werden. Da dies zu Zeitaufwendig ist kommt der interne Cache zu Einsatz, dabei werden die Werte der Referenzen zwischengespeichert. Der Cache wird genauer im Abschnitt 5.6.2 beschrieben. Philip Krauss 69 Kapitel 8 Zusammenfassung und Ausblick Dieses Kapitel fast das Projekt mit dessem Eckpunkten sowie Beobachtungen während der Umsetzung zusammen. Abschliessend wird noch ein Blick auf noch fehlende Funktionalität geworfen. 8.1 Zusammenfassung Das Kriterium der Portierung, einer Desktop-Anwendung zu einer Webapplikation wurde erfüllt, sowie die Erstellung einer Rich Internet Applikation. Die Portierung ergab diverse Problembereiche, wo neue Konzepte zum Einsatz kamen. Dabei ist besonders das Konzept des Metamodells (Siehe Abschnitt 7.6.1) zu erwähnen, welches ein Beschreibungsobjekt für generische Entitäten ist. Bewährte Paradigmen wie das BasisAufsatz System wurden übernommen. Auf Grund der grossen Anzahl an Technologien im Bereich der Webentwicklung, den Datenbanksystemen und den Programmiersprachen wurden diese evaluiert. Dabei wurde ein Blick in die unterschiedlichen Richtungen der verfügbaren Technologien geworfen. Das Endresultat ist dass die neuen Konzepte der Software auch neue Funktionalitäten ermöglichten. Doch war es nicht vollständig möglich den vollen Funktionsumfang des Prototyps zu reproduzieren. Die unterschiedlichen Plattformen ergaben komplexe Implementierungen. Im Prototyp ist die Programmierung der Benutzeroberfläche recht leicht mit fertigen Objekten und Dialogen. Hingegen war die Entwicklung der Benutzeroberfläche, der neuen Software wesentlich komplexer, mit dem Hauptfokus auf der Darstellung der Generik. Ebenfalls mussten alle persistenzrelevanten Klassen selbst entwickelt werden mit dem Ausblick auf einen einfachen Austausch des Datenbanksystems. 71 KAPITEL 8. ZUSAMMENFASSUNG UND AUSBLICK 8.2 Ausblick Momentan ist jeder Benutzer der Webapplikation berechtigt alles zu tun. Oft ist das nicht wünschenswert. Die Einteilung Benutzer in Benutzergruppen mit Rechtevergabe ist die Konsequenz. Jeder Benutzer erhält sein eignes Benutzerkonto und wird einer oder mehreren Benutzergruppen zugeteilt. Benutzergruppen wären mit Rechten versehen und würden die Zugriffe auf etwaige Ressourcen erlauben bzw. einschränken oder gar verbieten. Weiters wäre es angenehm, Profile an Benutzerkonte zu hängen. Ein Profil ist ein fertiges Layout für die Benutzergruppe und/oder für einen Benutzer. Ziel wäre es, visuelle Objekte wie z.B. Abfragen schneller zugänglich zu machen. 72 Philip Krauss Appendix A.1 Quellcodelistings Die Quellcodelistings zeigen Beispielimplementationen. Durch die Beispiele soll der Einstieg in die Weiterentwicklung sowie die Erstellung von Erweiterungen erleichtert werden. A.1.1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 JAX-RS Annotierte Klasse @Path ( ” / a u t o s ” ) @Consumes ( { MediaType . APPLICATION JSON , MediaType . APPLICATION XML} ) @Produces ( { MediaType . APPLICATION JSON , MediaType . APPLICATION XML} ) public c l a s s A u t o s C o n t r o l l e r { /∗ ∗ ∗ Finde a l l e s Autos ∗ @return L i s t ∗/ @Path ( ” / z e i g e n /{ i d } ” ) @GET public L i s t <Auto> f i n d e A l l e A u t o s ( ) { /∗ Finde a l l e Autos ∗/ f i n a l L i s t <Auto> a u t o s = P e r s i s t e n z . AutoDAO . f i n d e A l l e ( ) ; return a u t o s ; // L i s t e mit Autos a u s g e b e n } 16 /∗ ∗ ∗ Finde das Auto mit d e r I d ∗ @return Auto ∗/ @Path ( ” / z e i g e n /{ i d } ” ) @GET public Auto z e i g e A u t o ( @PathParam ( ” i d ” ) f i n a l long i d ) { /∗ Finde das Auto ∗/ f i n a l Auto auto = P e r s i s t e n z . AutoDAO . f i n d e M i t I d ( i d ) ; return auto ; // K o n k r e t e s Auto a u s g e b e n } 17 18 19 20 21 22 23 24 25 26 27 28 } Listing 1: JAX-RS Annotierte Klasse Die @Path Annotation gibt die URI an über welche die Ressource verfügbar ist. @Path Annotation sind nicht zwingend über dem Klassennamen anzugeben doch ist dies good practice um eventuelle Fehlerquellen zu vermeiden und einen globalen Namen für die Ressource zu definieren. 73 APPENDIX A.1. QUELLCODELISTINGS Damit man wie im Beispiel eine bestimmte Ressource erhalten kann, ist es möglich den Pfad zur Ressource mit Parameter zu vesehen, z.B. @Path( ”/zeigen/{id}”). Hier kann man eine Id als obligatorischen URI Parameter übergeben. Um den Wert des Parameters zu erhalten muss man in der Methodensignatur @PathParam( ı̈d”) final long id den Wert an eine Variable binden. Nun ist der Wert im Scope der Methode verfügbar. Mit @Consumes( { MediaType.APPLICATION JSON, MediaType.APPLICATION XML ) } kann man einen fixen Medientyp für die Datenkonsumation bzw. mit @Produces( ... ) für die Datenproduktion festlegen. Wie hier gezeigt ist es möglich mehrere Medientypen anzulegen wobei diese durch deren Prezedenz innerhalb des Array’s gestaffelt sind. Als HTTP Methoden wird im Beispiel nur @GET verwendet. Prinzipiel ist die explizite Definition von @GET überflüssig da ohne Methodenangabe automatisch die @GET Methode voraussetzt. A.1.2 1 2 3 XML annotierte Model Klasse @XmlRootElement ( name = ” data ” ) @XmlAccessorType ( XmlAccessType . FIELD ) public c l a s s View { 4 @XmlElement private long i d ; 5 6 7 @XmlElement private S t r i n g name ; 8 9 10 @XmlElement private S t r i n g h e r s t e l l e r ; 11 12 13 14 } Listing 2: XML annotierte Model Klasse 74 Philip Krauss APPENDIX A.1. QUELLCODELISTINGS A.1.3 Instanzierung des GridMetaPanel Objektes Hier würde das Objekt erstellt werden und auf dem div gerendert werden. Man könnte das Objekt auch auf dem Dokument selbst rendern doch ist dies bad practise und benötigt mehr Speicher. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 // E n t i t y I d = 42 v a r lookUpUrl = ’<%= r e q u e s t . g e t C o n t e x t P a t h ( ) %>/app / data / ’ + ’ metadata/<%= e n t i t y . g e t I d ( ) %> ’ ; // lookUpUrl = ’ / gdbms/ app / data / metadata / 4 2 ’ Ext . Ajax . r e q u e s t ( { u r l : lookUpUrl , method : ’GET ’ , disableCaching : false , /∗ ∗ ∗ S u c c e s s : B u i l d Grid ∗/ success : function ( result , request ) { v a r g r i d = new Ext . ux . MetaGridPanel ( { id : id , c o n t e x t P a t h : ’<%= r e q u e s t . g e t C o n t e x t P a t h ( ) %> ’ , url : ’ / app / data / r e a d/<%= e n t i t y . g e t I d ( ) %> ’ , metaData : Ext . u t i l . JSON . d ec od e ( r e s u l t . r e s p o n s e T e x t ) , inputEnable : false , renderTo : ’ grid ’ }); }, /∗ ∗ ∗ AJAX Request F a i l u r e ∗/ f a i l u r e : function ( result , request ) { App . s e t A l e r t ( App . STATUS EXCEPTION, ” F a i l e d t o l o a d t h e Meta Model ! ” ) ; } }); 30 31 <d i v i d=” g r i d ”><!−− P o p u l a t e d by ExtJs −−></div> Listing 3: Instanzierung des GridMetaPanel Objektes Philip Krauss 75 APPENDIX A.1. QUELLCODELISTINGS A.1.4 IBaseEntity Interface Das Interface IBaseEntity beschreibt die obligatorischen Schnittstellen eines Model Objektes für den Einsatz mit Hibernate. 1 2 3 4 5 6 7 8 /∗ ∗ ∗ Base I n t e r f a c e f o r a l l E n t i t i e s ∗ ∗ E n s u r e s t h a t a l l E n t i t i e s implement Methods ∗ − to get the Id o f the Entity ∗ − t o s e t t h e ’ m o d i f i e d ’ and ’ c r e a t e d ’ Timestamps ∗/ package a t . ac . u i b k . d a t a b a s e . p o j o s . i n t e r f a c e s ; 9 10 import j a v a . u t i l . Date ; 11 12 public i n t e r f a c e I B a s e E n t i t y { 13 /∗ ∗ ∗ Returns t h e E n t i t y ’ s I d ∗ ∗ @return { @ l i n k Long} ∗/ public long g e t I d ( ) ; 14 15 16 17 18 19 20 /∗ ∗ ∗ Set ’ s the Entity ’ s modified Variable ∗ ∗ @param m o d i f i e d ∗/ public void s e t M o d i f i e d ( Date m o d i f i e d ) ; 21 22 23 24 25 26 27 /∗ ∗ ∗ Set ’ s the Entity ’ s created Variable ∗ ∗ @param c r e a t e d ∗/ public void s e t C r e a t e d ( Date c r e a t e d ) ; 28 29 30 31 32 33 34 } Listing 4: Interface für alles POJO’s 76 Philip Krauss APPENDIX A.2. KLASSENDIAGRAMME A.2 Klassendiagramme In diesem Abschnitt werden all relevanten Klassendiagramme aufgelistet. Dabei handelt es sich um einzelne Klasse als auch Klassen und deren abgeleiteten Klassen bzw. in relationsstehenden Klassen. A.2.1 BaseDAO Abbildung 1: BaseDAO A.2.2 SyntaxBuilder Abbildung 2: Interface SyntaxBuilder Philip Krauss 77 APPENDIX A.2. KLASSENDIAGRAMME A.2.3 Basiskontroller Abbildung 3: Basiskontroller A.2.4 MetaModel Abbildung 4: MetaModel 78 Philip Krauss APPENDIX A.2. KLASSENDIAGRAMME A.2.5 JSON Klasse Abbildung 5: JSON Klasse A.2.6 Editoren Abbildung 6: Klassendiagramm der Editoren Philip Krauss 79 APPENDIX A.3. JAVA PACKETDIAGRAMME A.3 Java Packetdiagramme Abbildung 7: Controller Package Diagram Abbildung 8: Models Package Diagram 80 Philip Krauss Literaturverzeichnis [BLFM+ 99] T. Berners-Lee, R. Fielding, L. Masinter, J. Gettys, J. Mogul, H. Frystyk and P. Leach: Hypertext Transfer Protocol – HTTP/1.1, RFC2616, 1999, URL http://tools.ietf. org/html/rfc2616. [BLFM05] T. Berners-Lee, R. Fielding and L. Masinter: Uniform Resource Identifier (URI): Generic Syntax, RFC3986, 2005, URL http://www.ietf.org/rfc/rfc3986.txt. [Bur09] B. Burke: RESTful Java with JAX-RS, O’Reilly Media, 2009. [Cod70] E. F. Codd: A Relational Model of Data for Large Shared Data Banks, Technical report, IBM Research Laboratory, 1970, http://www.seas.upenn.edu/~zives/03f/ cis550/codd.pdf. [Cro06] D. Crockford: The application/json Media Type for JavaScript Object Notation (JSON), RFC4627, 2006, URL http://tools.ietf.org/html/rfc4627. [FF04] E. Freeman and E. Freeman: Head First Design Patterns, Operations Research, 2004. [Fie00] R. T. Fielding: Architectural Styles and the Design of Network-based Software Architectures, Ph.D. thesis, University of California, Irvine, 2000. [Foua] A. S. Foundation: Apache Maven Projektseite, http:// maven.apache.org/. [Foub] A. S. Foundation: Apache Tomcat Projektseite, http:// tomcat.apache.org/. [Gar05] J. J. Garrett: Ajax: A New Approach to Web Applications, Technical report, Adaptive Path, 2005, http://www.adaptivepath.com/ideas/ ajax-new-approach-web-applications. 81 APPENDIX LITERATURVERZEICHNIS [Haf09] M. Hafner: Design of Softwaresystems - Lecture, University of Innsbruck, Computer Science faculty, 2009. [IET] IETF: Internet Engineering Task Force, http://www. ietf.org/. [III08] A. T. H. III: Ajax: The Definitive Guide, O’Reilly Media, 2008. [JBo] JBoss: Hibernate hibernate.org/docs. [jso] json.org: http://json.org/. [Sena] Sencha: http://www.sencha.com. [Senb] Sencha: ExtJS 3.3.1 API, http://dev.sencha.com/ deploy/ext-3.3.1/docs/. [Spi09] M. Spiller: Maven 2: Konfigurationsmanagement mit Java, mitp, 2009. [Ull11] C. Ullenboom: Java ist auch eine Insel, volume 9, Galileo Computing, 2011. [W3C] W3C: World Wide Web Consortium, http://www.w3. org/. 82 Dokumentation, http://www. Philip Krauss