+ All Categories
Home > Documents > Webservices als Komponenten: Entwicklung eines neuartigen ... · Webservices als Komponenten:...

Webservices als Komponenten: Entwicklung eines neuartigen ... · Webservices als Komponenten:...

Date post: 29-Mar-2019
Category:
Upload: vokiet
View: 219 times
Download: 0 times
Share this document with a friend
147
Webservices als Komponenten: Entwicklung eines neuartigen, komponentenbasierten Ajax-Frameworks für Web 2.0-Systeme Diplomarbeit zur Erlangung des Grades Diplom-Informatiker (FH) an der Hochschule Heilbronn Studiengang Software Engineering vorgelegt von: Benedikt Schwinkendorf Matr.-Nr.: 159980 8. Semester aus: Am Baumgarten 13 74199 Unterheinriet Tel.: 07130 401433 [email protected] Referent / Koreferent: Prof. Dr. Dominikus Herzberg / Prof. Dr. Jörg Winckler Heilbronn, 31.01.2007
Transcript

Webservices als Komponenten: Entwicklung einesneuartigen, komponentenbasierten Ajax-Frameworks

für Web 2.0-Systeme

Diplomarbeit

zur Erlangung des Grades Diplom-Informatiker (FH)

an derHochschule Heilbronn

Studiengang Software Engineering

vorgelegt von: Benedikt SchwinkendorfMatr.-Nr.: 1599808. Semester

aus: Am Baumgarten 1374199 UnterheinrietTel.: 07130 [email protected]

Referent / Koreferent: Prof. Dr. Dominikus Herzberg / Prof. Dr. Jörg Winckler

Heilbronn, 31.01.2007

Inhaltsverzeichnis I

Inhaltsverzeichnis

Abbildungsverzeichnis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . IVAbkürzungsverzeichnis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . V

1 Einleitung 1

2 Vom HyperText über Ajax zum Web 2.0 32.1 Die Grundlage des Webs: Das HyperText Transfer Protokoll . . . . . . . 3

2.1.1 Das Client/Server-Modell . . . . . . . . . . . . . . . . . . . . . . 32.1.2 Kommunikation via Request und Response . . . . . . . . . . . . . 42.1.3 Die Grenzen dieses Ansatzes . . . . . . . . . . . . . . . . . . . . . 4

2.2 Die Erweiterung: Einsatz von Ajax als Agententechnologie . . . . . . . . 52.2.1 Altbekanntes neu entdeckt: Ajax . . . . . . . . . . . . . . . . . . 52.2.2 Eröffnung neuer Möglichkeiten durch clientseitige Agenten . . . . 7

2.3 Entdecke die Möglichkeiten: Ajax und das Web 2.0 . . . . . . . . . . . . 82.3.1 Neue Webanwendungen entstehen: Beispiel GMail, Flickr und Pe-

diaX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82.3.2 Teildienste anbieten und verknüpfen: Beispiel Feeds und Mashups 102.3.3 Das Web 2.0: “Die soziale Komponente des Webs“ . . . . . . . . . 112.3.4 Der Web-Browser als Desktop-Ersatz . . . . . . . . . . . . . . . . 12

3 Die Idee: Ajax-Framework mit Webservices als Komponenten 133.1 Das Problem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

3.1.1 Heutige Webapplikationen sind als Software zu komplex . . . . . . 133.1.2 Unzählige Ajax-Frameworks verfügbar mit vielfältigen Zielsetzungen 14

3.2 Der Ansatz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153.2.1 Radikale Service-Orientierung: Alles ist ein Service . . . . . . . . 153.2.2 Einfache und klare Strukturen durch Komponenten-Orientierung . 153.2.3 So viel Ajax-Einsatz wie möglich: Webservice-Agenten . . . . . . 16

3.3 Was ein komponentenbasiertes Framework leisten muss . . . . . . . . . . 173.3.1 Komponenten und Komponenten-Komposition . . . . . . . . . . . 173.3.2 Komponenten-Verbindungen zur Kommunikation . . . . . . . . . 19

3.4 Grundaufbau eines clientseitigen, komponenten-orientierten Ajax-Frame-works . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193.4.1 Strikte Service-Orientierung: Auch Komponenten-Ansatz als Dienst! 193.4.2 Namespaces als Basis für clientseitigen Komponentenanteil . . . . 203.4.3 Clientseitige Komponenten-Verbindungen per Subscriber-Modell . 213.4.4 Client/Server-Kommunikation durch Kommunikationsdienst . . . 22

3.5 Absicherung: Was, wenn ein Client kein Ajax unterstützt? . . . . . . . . 233.5.1 Webanwendungen ohne Ajax-Abhängigkeit realisieren . . . . . . . 233.5.2 Aufbau einer Webanwendung mit serverseitiger Client-Simulation 23

Diplomarbeit von Benedikt Schwinkendorf

Inhaltsverzeichnis II

4 Die Umsetzung: Aufbau und Anwendung des Frameworks 264.1 Überblick über den den Aufbau und die Services des Frameworks . . . . 26

4.1.1 Der Init-Service als Funktionsgrundlage . . . . . . . . . . . . . . . 274.1.2 Beschreibung der Framework-Services und ihrer Funktionen . . . 28

4.2 Eine Webanwendung aus Teildiensten erstellen und konfigurieren . . . . . 304.2.1 Die Startseite als permanentes Layout-Grundgerüst . . . . . . . . 304.2.2 Anlegen und initialisieren von Anwendungs-Services: “Hello World“ 314.2.3 Anpassen der Server-Konfiguration . . . . . . . . . . . . . . . . . 334.2.4 Interaktive Webservice-Agenten durch Ajax-Kommunikation . . . 35

4.3 HTML-Clients unterstützen . . . . . . . . . . . . . . . . . . . . . . . . . 364.3.1 Serverseitige Client-Simulation mit Framework-Funktionalität . . 374.3.2 Teildienste erweitern für den Einsatz ohne Javascript . . . . . . . 38

4.4 Eine Beispielanwendung: “Student sucht Job . de“ . . . . . . . . . . . . . 39

5 Abgrenzung zu alternativen Ajax-Frameworks 455.1 Prototype aus dem “Ruby-on-Rails“-Projekt . . . . . . . . . . . . . . . . 455.2 Die Open Source Javascript-Bibliothek Rico . . . . . . . . . . . . . . . . 465.3 Scriptaculous: Neue DHTML-Anwendungen durch Ajax-Einsatz . . . . . 475.4 MochiKit: Eine leichtgewichtige Javascript-Bibliothek . . . . . . . . . . . 485.5 Das auf XML basierende Ajax-Framework Spry . . . . . . . . . . . . . . 495.6 Diskussion: Ein Vergleich, Vor- und Nachteile . . . . . . . . . . . . . . . 50

6 Zusammenfassung und Ausblick 526.1 Resultate der Arbeit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 526.2 Perspektiven . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54

Literatur 55

A Verzeichnisstruktur des Quellcodes 56

B Quellcode 59B.1 client.html . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59B.2 client.php . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59B.3 empty.html . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61B.4 init_service.js . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61B.5 init_service.php . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70B.6 general.css . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76B.7 configuration_manager.php . . . . . . . . . . . . . . . . . . . . . . . . . 80B.8 interface_server.php . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88B.9 server.php . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89B.10 interface_application_services.php . . . . . . . . . . . . . . . . . . . . . 92B.11 interface_framework_services.php . . . . . . . . . . . . . . . . . . . . . . 93

Diplomarbeit von Benedikt Schwinkendorf

Inhaltsverzeichnis III

B.12 application_service.php . . . . . . . . . . . . . . . . . . . . . . . . . . . 95B.13 hello_world_service.php . . . . . . . . . . . . . . . . . . . . . . . . . . . 98B.14 hello_world_service.js . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100B.15 /lib/hello_world_service.php . . . . . . . . . . . . . . . . . . . . . . . . 100B.16 hello_world_service.css . . . . . . . . . . . . . . . . . . . . . . . . . . . 101B.17 framework_service.php . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101B.18 communication_service.php . . . . . . . . . . . . . . . . . . . . . . . . . 103B.19 composition_service.php . . . . . . . . . . . . . . . . . . . . . . . . . . . 104B.20 configuration_service.php . . . . . . . . . . . . . . . . . . . . . . . . . . 104B.21 monitoring_service.php . . . . . . . . . . . . . . . . . . . . . . . . . . . 105B.22 subscriber_service.php . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105B.23 update_service.php . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106B.24 communication_service.js . . . . . . . . . . . . . . . . . . . . . . . . . . 106B.25 composition_service.js . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111B.26 configuration_service.js . . . . . . . . . . . . . . . . . . . . . . . . . . . 124B.27 monitoring_service.js . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126B.28 subscriber_service.js . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130B.29 update_service.js . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133

Diplomarbeit von Benedikt Schwinkendorf

Abbildungsverzeichnis IV

Abbildungsverzeichnis

2.1 Ablauf einer HTTP-Kommunikation . . . . . . . . . . . . . . . . . . . . . 42.2 Klassisches Modell und Ajax Modell einer Webanwendung im Vergleich

[Gar05] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72.3 Die Benutzeroberfläche von Google-Mail . . . . . . . . . . . . . . . . . . 93.1 Einfache Komponenten und Schnittstellen . . . . . . . . . . . . . . . . . 183.2 Komponenten-Komposition und Schnittstellen . . . . . . . . . . . . . . . 183.3 Aufbau einer Konfiguration mit Komponenten-Komposition, Schnittstel-

len und Komponenten-Verbindungen . . . . . . . . . . . . . . . . . . . . 193.4 Namespace als clientseitige Komponenten-Komposition . . . . . . . . . . 213.5 Komponenten-Verbindung mittels Subscriber . . . . . . . . . . . . . . . . 223.6 Modell einer Webanwendung bei Anwendung des Frameworks mit und

ohne Javascript im Vergleich . . . . . . . . . . . . . . . . . . . . . . . . . 244.1 Das optionale Menü einer Namespace-Komponente . . . . . . . . . . . . 284.2 Die Teildienste der Startseite beim ersten Aufruf der Beispielanwendung 404.3 Die Konfigurations-Ansicht des Update-Service bei aktiver Kommunikations-

Verbindung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 414.4 Die Startseite der Webanwendung nach erfolgreicher Benutzeranmeldung 434.5 Aufgezeichnete Ereignisse des Monitoring-Service . . . . . . . . . . . . . 44

Diplomarbeit von Benedikt Schwinkendorf

Abkürzungsverzeichnis V

Abkürzungsverzeichnis

AJAX . . . . . . . . . . . . . . . . . . . . . . . Asynchronous Javascript And XmlAPI . . . . . . . . . . . . . . . . . . . . . . . . . Application Programming InterfaceASP.NET . . . . . . . . . . . . . . . . . . . Active Server Pages .NETCGI . . . . . . . . . . . . . . . . . . . . . . . . . Common Gateway InterfaceCMS . . . . . . . . . . . . . . . . . . . . . . . . Content Management SystemCSS . . . . . . . . . . . . . . . . . . . . . . . . . Cascading Style SheetsHTML . . . . . . . . . . . . . . . . . . . . . . HyperText Markup LanguageHTTP . . . . . . . . . . . . . . . . . . . . . . . HyperText Transfer ProtokollIP . . . . . . . . . . . . . . . . . . . . . . . . . . . Internet ProtocolJSON . . . . . . . . . . . . . . . . . . . . . . . JavaScript Object NotationJSP . . . . . . . . . . . . . . . . . . . . . . . . . JavaServer PagesPC . . . . . . . . . . . . . . . . . . . . . . . . . . Personal ComputerPHP . . . . . . . . . . . . . . . . . . . . . . . . PHP: Hypertext PreprocessorRSS . . . . . . . . . . . . . . . . . . . . . . . . . Really Simple SyndicationTCP . . . . . . . . . . . . . . . . . . . . . . . . Transmission Control ProtocolURI . . . . . . . . . . . . . . . . . . . . . . . . . Uniform Resource IdentifierURL . . . . . . . . . . . . . . . . . . . . . . . . Uniform Resource LocatorW3C . . . . . . . . . . . . . . . . . . . . . . . . World Wide Web ConsortiumWWW . . . . . . . . . . . . . . . . . . . . . . World Wide WebXHTML . . . . . . . . . . . . . . . . . . . . . EXtensible HyperText Markup LanguageXML . . . . . . . . . . . . . . . . . . . . . . . . EXtensible Markup LanguageXSL . . . . . . . . . . . . . . . . . . . . . . . . . EXtensible Stylesheet LanguageXSLT . . . . . . . . . . . . . . . . . . . . . . . EXtensible Stylesheet Language Transformations

Diplomarbeit von Benedikt Schwinkendorf

1 Einleitung 1

1 Einleitung

Wer die Entwicklung des World Wide Web in den letzten Jahren beobachtet hat, weisdass das Web längst nicht mehr nur ein HyperText-System darstellt. Die statischenWebseiten vergangener Tage sind dynamischen, datenbank-getriebenen Webanwendun-gen gewichen. Dadurch sind neue Webanwendungen wie online-Banking, eCommerce,oder Community-Foren möglich geworden. Die nächste Stufe der Evolution des Webssteht nun in ihren Anfängen und macht sich bereits durch eine neue Art von Webanwen-dungen bemerkbar. Bisher werden Webseiten nach dem “Klicken und Warten“-Prinzipgesteuert. Ein Mausklick auf bestimmte Bereiche einer Webseite sorgt dafür, dass ange-forderte Inhalte in Form einer neuen Seite dargestellt werden. Nach dem klicken mussder Benutzer jedoch warten, bis die Inhalte in seinem Web-Browser dargestellt werden.Eine Webanwendungen der neuen Generation lässt sich hingegen so bedienen, dass einBenutzer das “Gefühl“ hat, es handle sich dabei um eine Anwendung auf dem Desktop.

Die Technik hinter diesen Applikationen erlangt zur Zeit unter dem Schlagwort “Ajax“[Gar05] mehr und mehr Bekanntheit. Sie ermöglicht es clientseitige Logik im Web-Browser eines Benutzers auszuführen und im Hintergrund einer Webanwendung mit derServerseite zu kommunizieren. Dabei werden lediglich benötigte Daten für bestimmteTeile einer Webanwendung vom Server abgerufen und direkt im Web-Browser darge-stellt. Konsequent weiter gedacht wird durch Ajax eine neue Herangehensweise an denAufbau von Webanwendungen möglich. Eine Webseite kann in Komponenten zerlegtwerden, die jeweils eigenständig im Web-Browser des Clients laufen und untereinanderkommunizieren. Jede Komponente ist dabei Teildienst der Webseite und liefert einen be-stimmten Funktionsumfang. Eine vollständige Webanwendung wird nach diesem Prinzipaus mehreren Teildiensten zusammen gesetzt. Sie “komponiert“ die Funktionsumfängeder verschiedenen Komponenten zu einer zusammenhängenden Anwendung.

Diese Arbeit beschreibt die Ideen und die Umsetzung eines neuartigen, komponentenba-sierten Frameworks, das den Aufbau von Webanwendungen auf Basis von Komponentenund Teildiensten unterstützt. In Kapitel zwei werden die technischen Grundlagen desWebs und deren Erweiterungen durch Ajax-Technologie beschrieben. Zu Beginn wirddas Client/Server-Modell und die Kommunikation via Request und Response erläutert.Des Weiteren wird beschrieben welche Grenzen und Probleme dieser Kommunikations-Ansatz bei normalen Webanwendungen mit sich bringt und mit welchen Mitteln versuchtwird diese zu umgehen. Dies führt zur Erläuterung der Ajax-Technologie und deren Mög-lichkeit clientseitige Agenten zu schaffen. Es werden neue Möglichkeiten aufgezeigt, dieder Einsatz von Ajax für Webanwendungen und Web 2.0-Systeme bietet. Der letzte Ab-schnitt dieses Kapitels geht darauf ein in welchen Bereichen die Ajax-Technologie bereitsheute eingesetzt wird. Dazu werden drei neuartige Webanwendungen vorgestellt und wiediese sich durch den Einsatz von Ajax von bisherigen Webanwendungen abheben. AmBeispiel von Feeds und Mashup-Seiten wird beschrieben, wie mehrere Teildienste zu einer

Diplomarbeit von Benedikt Schwinkendorf

1 Einleitung 2

einheitlichen Anwendung verbunden werden können. Darauf folgend beschäftigt sich dieArbeit mit der Bedeutung von Web 2.0-Systemen in technischer Hinsicht sowie mit dersozialen Komponente, die diese Systeme mit sich bringen. Abschließend wird erläutert,welche neuen Einsatzgebiete für Webanwendungen mit Ajax-Technologie weiter denkbarwären und inwieweit es sinnvoll ist Kommunikation über Ajax-Technologie zu lösen.

Kapitel drei beschreibt zu Anfang, welche Probleme heutige Webanwendungen habenund wie aktuelle Frameworks versuchen den Aufbau von Anwendungen zu unterstützen.Die Ideen der neuen Herangehensweise an den Aufbau von Webanwendungen in Formvon Teildiensten und der Aufbau von Teildiensten als Webservices werden im Anschlussdaran beschrieben. Der nächste Abschnitt zeigt auf was ein Framework leisten mussum komponenten-orientiert arbeiten zu können. Dann werden der Grundaufbau undder angedachte Funktionsumfang des Frameworks im Detail erläutert. Zum Schluss desKapitels wird auf die Problematik der Javascript-Abhängigkeit von Ajax-Frameworkseingegangen und wie diese durch eine serverseitige Client-Simulation aufgelöst werdenkann.

Das vierte Kapitel stellt den Aufbau und die Anwendung des Frameworks beginnend miteiner Übersicht der angebotenen Framework-Funktionalität vor. Es wird beschrieben, wieneue Teildienste über einfache Framework-Funktionen eingeladen und verwendet werdenund warum JSON als Daten-Format zum Datenaustausch zwischen Client und Servergewählt wurde. Weiter wird anhand eines “Hello World“-Beispiels erläutert, wie eigeneTeildienste auf einem Web-Server bereitgestellt werden, so dass diese als Komponen-ten im Browser des Clients verwendbar sind. Der anschlieáende Abschnitt erläutert, wieclientseitige Komponenten-Verbindungen zur Kommunikation zwischen Teildiensten rea-lisiert werden. Durch eine ausführliche Beispielanwendung wird die konkrete Anwendungdes Frameworks und dessen Funktionen aufgezeigt. Abschließend behandelt das Kapiteldie Umsetzung der serverseitigen Client-Simulation, die es ermöglicht das Frameworkauch mit einem Web-Browser zu verwenden, welcher keine Javascript-Unterstützungbietet.

Im fünften Kapitel werden zunächst die Zielsetzung und der Funktionsumfang von fünfder bekanntesten Ajax-Frameworks vorgestellt. Es werden die verschiedenen Vor- undNachteile der Rahmenwerke sowie wesentliche Unterschiede beschrieben. Im letzten Ab-schnitt des Kapitels werden die Arbeiten mit dem hier vorgestellten Framework vergli-chen.

Eine abschließende Zusammenfassung beschreibt die Ergebnisse der vorliegenden Arbeit,welcher praktische Nutzen gezogen werden kann sowie auftretende Kritikpunkte. Zudemwerden Erfahrungen berichtet, die beim Entwickeln einer aus Komponenten zusammengesetzten Webanwendung und mit der Verwendung des Frameworks gemacht werdenkonnten. Die Perspektiven des Frameworks in Form von gegebenen Anwendungsmög-lichkeiten sowie denkbaren Erweiterungen auf der Client- und Serverseite werden imletzten Abschnitt der Arbeit dargestellt.

Diplomarbeit von Benedikt Schwinkendorf

2 Vom HyperText über Ajax zum Web 2.0 3

2 Vom HyperText über Ajax zum Web 2.0

2.1 Die Grundlage des Webs: Das HyperText TransferProtokoll

Das Web basiert auf einem einfachen Grundkonzept: verschiedene Anbieter stellen Web-seiten zur Verfügung, die ein Nutzer mit einem Web-Browser betrachten kann. DieWebseiten sind dabei in der Regel mit Seitenbeschreibungssprache HTML (HyperTextMarkup Language) verfasst. Mittels HTML wird die Darstellung von Inhalten wie Tex-ten, Bildern und Hyperlinks in Dokumenten wie Webseiten beschrieben. HTML wurdein seiner heutigen Form vom World Wide Web Consortium1 (W3C) standardisiert undliegt aktuell in der Version 4.01 [RHJ99] vor. So genannte Hyperlinks können Teil ei-ner solchen Webseiten-Beschreibung sein. Jeder Hyperlink stellt dabei einen Verweis aufeine andere Webseite dar. Es wird somit möglich von einer Webseite über einen Hyper-link auf eine andere Webseite zu verweisen. Durch die Darstellung von Hyperlinks imWeb-Browser eines Clients haben Benutzer, durch den Klick auf einen Link, die Mög-lichkeit das Anfordern einer neuen Webseite anzustoßen. Mehrere Webseiten können sichdurch Hyperlinks so gegenseitig Verweisen und eine zusammengehörige Webanwendungbilden.

2.1.1 Das Client/Server-Modell

Eine Webseite ist in der Regel auf einem Web-Server gespeichert, der über das WorldWide Web (WWW) erreichbar ist. Ein Web-Server erlaubt es die auf ihm gespeicher-ten Webseiten über das WWW abzurufen. Dazu kommunizieren der Web-Browser desClient und der Web-Server über das HyperText Transfer Protokoll (HTTP) [FGM+99]miteinander. Der Browser sendet eine HTTP-Anfrage (request) an den Web-Server, wel-cher darauf eine Antwort (response), in den meisten Fällen in Form einer HTML-Seite,über HTTP an den Web-Browser zurück sendet. HTTP-Anfragen werden immer vonder Clientseite angestoßen. Der Web-Server bleibt stets passiv und antwortet lediglichauf eingehende Anfragen.

HTTP verwendet als Übertragungsprotokoll TCP/IP (Transmission Control Protocol/ Internet Protocol) [KC81]. Ein Web-Server kann daher über eine IP-Adresse genauidentifiziert werden. IP-Adressen können im WWW auch mit einer so genannten Domainverknüpft werden. Dies sind einfache Namen, welche anstelle der IP-Adresse verwendetwerden können um die Webseiten eines Web-Servers anzufragen. Über so genannte URLs(Uniform Resource Locator) können die gespeicherten Webseiten eines Web-Servers

1http://www.w3.org/

Diplomarbeit von Benedikt Schwinkendorf

2 Vom HyperText über Ajax zum Web 2.0 4

lokalisiert werden. Eine URL setzt sich meist aus dem Namen des Web-Servers sowie derPosition der Webseite in der Verzeichnisstruktur des Servers zusammen.

2.1.2 Kommunikation via Request und Response

Die HTTP-Kommunikation ermöglicht den Transport von beliebigen Daten über dasWWW, die auch als Nachrichten bezeichnet werden. Ein von einem Web-Browser abge-setzter HTTP-Request enthält als Request-Nachricht z.B. die URL der anzuforderndenWebseite. Der angesprochene Web-Server sendet darauf in seinem HTTP-Response dieentsprechende HTML-Beschreibung der Webseite als Response-Nachricht an den Web-Browser zurück. Weitere Bestandteile eines HTTP-Request sind die HTTP-Header, wel-che Meta-Informationen wie etwa den vom Client verwendeten Zeichensatz enthaltenkönnen. Der Ablauf einer HTTP-Kommunikation via Request und Response wird inAbbildung 2.1 dargestellt.

Abbildung 2.1: Ablauf einer HTTP-Kommunikation

Über einen HTTP-Request kann immer nur eine einzige Anfrage gesendet werden. Meh-rere Anfragen z.B. von verschiedenen Webseiten zugleich werden nicht unterstützt. Fürjede anzufordernde Webseite wird demnach ein separater HTTP-Request benötigt, dermit einem entsprechendem HTTP-Response beantwortet wird. Das HTTP-Protokollkennt keine Zustände, da die vom Protokoll erstellte Verbindung nach dem übertragenvon Request und Response wieder getrennt wird.

2.1.3 Die Grenzen dieses Ansatzes

Eine Webanwendung, die aus mehreren Webseiten besteht, verwendet in der Regel eineNavigation aus mehreren Hyperlinks, welche auf alle Webseiten der Anwendung verwei-sen. Um von jeder Webseite der Anwendung alle anderen Seiten erreichen zu können,muss diese Navigation auf allen Webseiten eingebunden werden. Sie wird also Teil derSeitenbeschreibung aller Webseiten der Webanwendung. Auch Inhalt der seitenübergrei-fend angezeigt werden soll, z.B. ein Kalender, der unabhängig von der aktuellen Webseiteimmer im rechten oberen Bereich der Webanwendung steht, muss dafür auf jeder Web-seite der Anwendung integriert sein. Dies hat bei statischen Webseiten den Nachteil,dass Quellcode redundant vorhanden ist. Ändert sich z.B. der Verweis einer Seite oder

Diplomarbeit von Benedikt Schwinkendorf

2 Vom HyperText über Ajax zum Web 2.0 5

neue Inhalte kommen hinzu, so muss die Navigation auf allen Webseiten der Anwen-dung entsprechend angepasst werden. Moderne Webseiten werden dynamisch erstelltund lösen dieses Problem durch Auslagerung des entsprechenden Quellcodes. Ausgela-gerte Code-Stücke können dann an beliebiger Stelle einer Webseite eingebunden werden.Dies verhindert jedoch nicht, dass in der Seitenbeschreibung der einzelnen Webseitenimmer alle darzustellenden Inhalte vorhanden sein müssen.

Dies hat zu Folge, das der Web-Browser des Clients bei jedem Aufruf einer Websei-te viele Inhalte empfangen muss, die ihm bereits zuvor bekannt waren. Je nach Artund Aufbau einer Webanwendung können diese Inhalte sogar den Großteil der über-tragenen Daten ausmachen. Werden Webseiten auf dem Server dynamisch generiert,so muss zudem der Generations-Prozess einer Seite für jeden Request neu durchlaufenwerden. Auch eventuelle Datenbankabfragen werden wiederholt ausgeführt und fordernentsprechenden Rechenaufwand. Die Grenze der Belastbarkeit eines Web-Servers wirddurch diese Abläufe somit schnell erreicht. Dabei wäre es überhaupt nicht nötig, bereitsdargestellte Inhalte mit jeder Webseite erneut zu empfangen. Theoretisch würde es aus-reichen nur die Inhalte zu empfangen, die tatsächlich neu sind. Da Webseiten bereitsdurch die gegebene Beschreibungssprache HTML hierarchisch und modularisiert geglie-dert sind, wäre es denkbar diese in Modul-Einheiten zu unterteilen z.B. Kalender-Moduloder Navigations-Modul und Content-Modul, um dann bei folgenden Aktualisierungennur noch geänderte Module zu empfangen. Durch reine HTTP-Requests ist dies aller-dings nicht möglich, da Web-Browser den gesamten Inhalt einer dargestellten Webseiteverwerfen, sobald ein neuer Request abgesetzt wurde.

2.2 Die Erweiterung: Einsatz von Ajax als Agententechnologie

Um die oben beschriebenen Grenzen des bisherigen Ansatzes zu überschreiten, soll eineneue Vorgehensweise zum Tragen kommen, die die Nachteile der “alten“ Technik ver-meidet. Die Idee dabei ist, den Funktionsumfang einer Webanwendung nach Möglichkeitauf die Clientseite zu verlagern. Zudem sollen die Inhalte einer Webseite nicht mehr alsGanzes, sondern in Form von Modulen vom Web-Server einer Anwendung zu empfangensein.

2.2.1 Altbekanntes neu entdeckt: Ajax

Unter dem Namen Ajax (Asynchrones Javascript und XML) wurde im letzten Jahr eineneue Technologie bekannt, die den bisherigen Aufbau von Webanwendungen um neueMöglichkeiten erweitert. Geprägt wurde der Begriff Ajax von Jesse James Garrett, der inseinem Essay “Ajax: A new approach to web applications“ [Gar05] die Ajax-TechnologieAnfang 2005 erstmals genauer beschreibt.

Diplomarbeit von Benedikt Schwinkendorf

2 Vom HyperText über Ajax zum Web 2.0 6

Ajax vereint mehrere bekannte Technologien mit dem Ziel, Daten asynchron im Hinter-grund einer Webanwendung empfangen zu können und entsprechende Inhalte bei Bedarfdirekt im Web-Browser des Clients anzuzeigen.

• XHTML und CSS zur standard-basierten Darstellung

• DOM-Manipulation für Interaktion und dynamisches Einbinden von Inhalten

• Datenaustausch und -manipulation durch XML und XSLT

• Asynchroner Datenempfang durch XMLHttpRequest

• Javascript zur Kombination der Technologien

Klassische Webanwendungen funktionieren nach dem oben beschriebenen Prinzip. Be-nutzer stoßen z.B. durch Mausklick auf einen Hyperlink das Ausführen eines HTTP-Request an, dieser wird über WWW an den entsprechenden Web-Server geleitet. DerServer wertet die übergebene Nachricht des Request aus und generiert neue Inhalte,welche er dann als neue Webseite an den Web-Browser des Clients zurück sendet. DasAbsetzen eines Request, dessen Verarbeitung auf dem Server und der Empfang einerneuen Webseite nimmt einige Zeit in Anspruch. Beim klassischen Modell muss der Be-nutzer diese Zeit mit Warten verbringen. Meist werden dabei nach einem Request alleInhalte des Browsers verworfen, so dass der Benutzer bis zum Eintreffen der Antwortnur eine weiße Seite sieht.

Ajax-Anwendungen verhindern dieses Start-Stopp-Prinzip der Interaktion mit Weban-wendungen durch das Einbinden einer zusätzlichen clientseitigen Schicht. Garret be-schreibt diese Schicht in seinem Essay als “Ajax engine“. Alle Interaktionen des Benutzerswerden nun nicht mehr direkt an den Web-Server geleitet, sondern gehen an diese neueSchicht. Hierbei handelt es sich um ein Javascript-Programm, welches das Anstoßen vonHTTP-Request an den Web-Server für den Benutzer übernimmt. Die Kommunikationmit dem Web-Server erfolgt dabei asynchron, d.h. sie ist unabhängig von den Interak-tionen des Benutzers. Dabei werden keine vollständigen Webseiten angefragt, sondernnur bestimmte Daten oder Inhalte in Form von XML. Diese werden vom Ajax engine inentsprechendes HTML gewandelt und direkt auf der Webseite eingebunden. Die War-tezeiten des Benutzers werden durch dieses Modell stark verkürzt, zudem werden hierbestehende Inhalte durch den Web-Browser nicht mehr verworfen. Abbildung 2.2 stelltdas Modell einer klassischen Webanwendung und einer Ajax-Anwendung im Vergleichdar.

Ajax schafft also die Möglichkeit, Daten und Inhalte nur für bestimmte Teile einerWebseite zu aktualisieren. Durch den Einsatz der oben erwähnten Modul-Einheiten(Kalender-Module, Navigations-Modul), die man auch als Teildienste einer Webseiteverstehen kann, können somit auch gezielt bestimmte Teildienste einer Webseite aktua-lisiert werden. Logisch und konsequent wäre es nun auch die Serverseite aus solchenTeildiensten aufzubauen. Ein Web-Server würde dadurch zu einer Art Service-Lieferant

Diplomarbeit von Benedikt Schwinkendorf

2 Vom HyperText über Ajax zum Web 2.0 7

dessen Dienste von der Clientseite nach Belieben genutzt werden können. Dieses Vorge-hen bereitet den Weg zu einer strikten Service-Orientierung.

Abbildung 2.2: Klassisches Modell und Ajax Modell einer Webanwendung im Vergleich[Gar05]

2.2.2 Eröffnung neuer Möglichkeiten durch clientseitige Agenten

Webanwendungen können sich durch den Einsatz von Ajax-Technologie im Grunde wieDesktop-Anwendungen verhalten. Das clientseitige Javascript-Programm übernimmt da-

Diplomarbeit von Benedikt Schwinkendorf

2 Vom HyperText über Ajax zum Web 2.0 8

bei die Aufgaben des Datenempfangs und des direkten Einbinden neuer Inhalte. Prin-zipiell kann Ajax auch als Agenten-Technologie verstanden werden. Aufgaben werdenan einen Agenten (ein Javascript-Programm) delegiert und von diesem ausgeführt. DerAgent erledigt seine Arbeit dabei still im Hintergrund der Webseite. Er kann HTTP-Requests ausführen und z.B. beim Web-Server nachfragen, ob neue Termine für eineneingebundenen Kalender vorhanden sind. Dies kann der Agent auch, wenn der Benutzerdies nicht direkt z.B. durch Mausklick auf eine Hyperlink veranlasst hat. Jedes möglicheJavascript-Event kann vom einem Agenten genutzt werden um neue Abläufe auszufüh-ren.

Ein solcher Ajax-Agent hat die Möglichkeit über DOM-Manipulation den gesamten Auf-bau einer Webseite zu beeinflussen. Meist nutzt er diese Technik um an bestimmten Po-sitionen neue Inhalte einzubinden, zu aktualisieren oder zu entfernen. Die Fähigkeit, alleEvents der Clientseite mit einem Agenten abzufangen, darauf neue Inhalte vom Web-Server zu empfangen und diese schließlich direkt in eine Webseite einbinden zu können,ermöglicht einen völlig neuen Design-Ansatz für Webanwendungen. Theoretisch wäredurch diesen Ansatz sogar eine Webanwendung als Desktop-Ersatz denkbar. So reichtheute die Spannweite dessen, was mit Ajax realisiert wird, vom kleinen Service-Scriptbis hin zur vollständigen clientseitigen Application, bei der der Web-Server zum reinenDatenspeicher “degradiert“wird.

Einige Webanwendungen erlauben es ihren Benutzern, durch den Einsatz eines Agentenim Hintergrund, aktiv dargestellte Inhalte zu beeinflussen. Dies wird zum einen durchdas dynamische Einbinden von Teildiensten und zum anderen durch das individuelleund personalisierte Anpassen grafischer Layoutelemente möglich. Drei der bekanntestenWebanwendungen in diesem Bereich werden im weiteren Verlauf des nächsten Abschnittsvorgestellt.

2.3 Entdecke die Möglichkeiten: Ajax und das Web 2.0

2.3.1 Neue Webanwendungen entstehen: Beispiel GMail, Flickr und PediaX

GMail oder auch “Google Mail“ ist ein Freemail-Dienst der Google Inc.2. Er kann miteinem Web-Browser über eine Oberfläche im Stil der Desktop-Anwendungen OutlookExpress und Thunderbird bedient werden. Mittels Ajax-Technologie wurde die Weban-wendung um verschiedene Features erweitert. So wird beispielsweise der Onlinestatusbekannter Kontakte “live“ angezeigt und bei Änderungen aktualisiert. Es ist möglichverfasste E-Mails in verschiedenen Sprachen auf Rechtschreibung überprüfen zu lassenoder per Chat mit bekannten GMail-Anwendern direkt in Kontakt zu treten. Zudemwird man beim Eintreffen neuer E-Mails automatisch benachrichtigt.

2http://mail.google.com/

Diplomarbeit von Benedikt Schwinkendorf

2 Vom HyperText über Ajax zum Web 2.0 9

Abbildung 2.3: Die Benutzeroberfläche von Google-Mail

Flickr3 ist eine Web 2.0 Anwendung die es angemeldeten Benutzern erlaubt eigene Bilderauf einem Web-Server zu speichern und somit Online-Fotoalben zu erstellen. Es bestehtdie Möglichkeit die Bilder per Tagging zu kategorisieren, damit diese von anderen Be-nutzern einfacher gefunden werden können. Flickr setzt beim Aufbau seiner Webseitenauf Ajax-Technologie um Bilder einer Webseite im Hintergrund nachzuladen. Es wirdso möglich, den Benutzern beim Aufrufen neuer Webseiten umgehend einzelne Teile derSeite anzuzeigen und die restlichen Inhalte nach und nach einzublenden. Die Benutzergewinnen so, trotz großer Mengen zu übertragender Daten, den Eindruck einer schnellenWebanwendung.

PediaX4 ist eine erweiterte Version der bekannten Internet-Enzyklopädie Wikipedia5. Siebietet verschiedene Funktionen an, die mittels Ajax-Technologie umgesetzt werden. Beider Suche nach einem Wikipedia Artikel wird beispielsweise bereits bei der Eingabe nachpassenden Treffern gesucht. Diese werden in einer Liste direkt unter dem Eingabefeldeingeblendet. Des Weiteren wird beim Überfahren von Wikipedia-Links eine Kurzzu-

3http://www.flickr.com/4http://www.pediax.de/5http://www.wikipedia.de/

Diplomarbeit von Benedikt Schwinkendorf

2 Vom HyperText über Ajax zum Web 2.0 10

sammenfassung des verwiesenen Artikels geladen und angezeigt. Schließlich wird beimÜberfahren eines Vorschaubilds dessen Großansicht automatisch vom Server angefordertund eingeblendet.

2.3.2 Teildienste anbieten und verknüpfen: Beispiel Feeds und Mashups

Immer häufiger machen Webanwendungen wie Flickr Teile ihrer Dienste über eine Pro-grammschnittstelle zugänglich. Durch diese wird es Webmastern möglich gemacht, Funk-tionalitäten und Inhalte fremder Webanwendungen auf ihren eigenen Webseiten zu inte-grieren. Nach dem Baukasten-Prinzip lassen sich so auch vollständige Webanwendungenaus verschiedenen Teildiensten zusammensetzen. Inzwischen hat sich für dieses Vorgehender Begriff “Mashup“ durchgesetzt, der für das Re-Kombinieren verschiedener Inhalte zueiner gesamten Webanwendung steht.

Feeds sind XML-basierte Beschreibungsformate, z.B. RSS [Boa06] oder Atom [NS05],über die verschiedene Inhalte angeboten werden können. Sie werden in der Regel fürNachrichten- und Blogwebseiten verwendet, können aber auch zum verteilen andererdigitaler Inhalte wie Bilder oder Videos verwendet werden. Außerdem können überFeeds Audiodaten, meist im MP3-Format übertragen und mit einem Computer oderMP3-Player abgespielt werden. Dies wird auch als Podcasting bezeichnet. Gängige Web-Browser unterstützen das Aufrufen von Feeds bereits direkt und bieten die Option, einenFeed zu abonnieren. In diesem Fall aktualisiert ein Web-Browser die Inhalte des Feedsin einem vom Benutzer vorgegebenen Intervall automatisch. Ein Beispiel für einen be-kannten Nachrichten-Feed ist der Heise-Newsticker6.

Eine Programmschnittstelle oder auch API (Application Programming Interface)ist inder Regel über eine URL erreichbar, was das direkte Ansprechen über das WWW sowiedie Übergabe von Parametern ermöglicht. Einige APIs erlauben es auch, die Daten vonTeildiensten mit zusätzlichen Informationen zu verknüpfen um somit einen neuen Infor-mationsgehalt zu schaffen. Eine oft und vielseitig verwendete API bietet Google für seineWebanwendung “Google Maps“7 an. Mit dieser wird es möglich, das über Google Mapserreichbare Kartenmaterial an bestimmten Geopositionen um zusätzliche Informationenzu erweitern. Verschiedene Webseiten nutzen dieses Feature um gespeicherte Informa-tionen gezielt auf einen relevanten Kartenabschnitt zu projizieren. So verknüpft z.B.Chicagocrime.org8 den Stadtplan von Chicago mit den auftretenden kriminellen Hand-lungen der amerikanischen Großstadt, wodurch direkt erkannt werden kann, in welchenStadtteilen die Kriminalitätsrate besonders hoch oder niedrig liegt. Andere Webseitenverbinden Bilder aus Flickr mit Geopositionen berühmter Bauwerke, die dann, beim

6http://www.heise.de/newsticker/7http://www.google.de/apis/maps/8http://www.chicagocrime.org/

Diplomarbeit von Benedikt Schwinkendorf

2 Vom HyperText über Ajax zum Web 2.0 11

Überfahren der entsprechenden Stellen mit dem Mauszeiger direkt in der Karte ange-zeigt werden. Dies sind nur wenige Beispiele, doch diese lassen bereits die Flexibilitätder angebotenen Schnittstellen und die gegebenen Möglichkeiten verschiedenste Inhaltemiteinander zu kombinieren erahnen.

2.3.3 Das Web 2.0: “Die soziale Komponente des Webs“

Web 2.0 ist der Begriff, der Internet Nutzern im letzten Jahr das Aufkommen eines neuenWorld Wide Web suggeriert hat. Geschaffen wurde der Begriff von Tim O’Reilly, der imJahre 2004 erstmals eine Veranstaltung9 seines O’Reilly-Verlages nach diesem benannte.Technisch gesehen handelt es sich beim Web 2.0 aber keineswegs um eine Neuheit odergar eine neue Version des World Wide Web. Neu hingegen ist die Art und Weise, wieInhalte in Web 2.0-Systemen geschaffen werden: “User-generated Content“, also Inhaltedie von Nutzern für Nutzer erstellt werden, ist das Schlagwort welches Web 2.0-Systemewie MySpace10, Flickr, YouTube11 oder Wikipedia von Grund auf prägt. In diesem Sinnekönnte man aber schon altbekannte Webanwendungen wie Foren oder Community-Seitenals Web 2.0-System verstehen. Was steckt also hinter dem Phänomen Web 2.0? Die untenstehende Tabelle (Tabelle 2.1) zeigt eine Auswahl bekannter Webanwendungen, die nachO’Reilly [O’R05] als Web 2.0-Systeme verstanden werden können.

Anwendungstyp Web 1.0 Web 2.0Fotoalben Ofoto FlickrInhalte/Daten verbreiten Akamai BitTorrentMusik online erwerben MP3.com NapsterEnzyklopädien Britannica Online Wikipediapersönlicher Webauftritt persönliche Webseiten WebblogsInhaltsverbreitung veröffentlichen teilnehmen

Tabelle 2.1: Web 2.0-Systeme nach O’Reilly [O’R05]

Anders als bei den klassischen Massenmedien wie Fernsehen, Zeitung oder auch Web1.0 Anwendungen, bei denen wenige Verantwortliche für ein breites Publikum Inhalteveröffentlichen, können die Benutzer am Web 2.0 aktiv teilnehmen. Ajax und weite-re Techniken wie Tagging, Streaming oder Flash machen es den Benutzern einfach,interessante Inhalte zu finden und anzusehen. Zudem bieten sie unkomplizierte We-ge, eigene Inhalte zu veröffentlichen und einem breiten Publikum zugänglich zu ma-chen. Benutzer werden somit zugleich Empfänger und Produzent von neuen Inhalten,

9http://www.web2con.com/10http://www.myspace.com/11http://www.youtube.com/

Diplomarbeit von Benedikt Schwinkendorf

2 Vom HyperText über Ajax zum Web 2.0 12

was das bisherige Verständnis des Webs als reines Informationssystem zum interaktivenPartizipations-Medium verändert. Die Gemeinschaft der Benutzer sorgt dabei kontinu-ierlich für neue Inhalte. Das dieses Gemeinschafts-Prinzip funktioniert, kann man z.B.an Web 2.0-Systemen wie der Video-Plattform YouTube sehen, die täglich um ca. 65000neue Beiträge [Goo06] erweitert wird.

2.3.4 Der Web-Browser als Desktop-Ersatz

Betrachtet man die Entwicklung neuer Webanwendungen mit Ajax-Technologie, so äh-neln diese im Auftreten der Benutzeroberflächen sowie ihrer Funktionalität und Bedien-barkeit immer deutlicher herkömmlichen Desktop-Anwendungen. Einige native Desktop-Anwendungen werden bereits als Ajax-Anwendung angeboten und können mittels Brow-ser ausgeführt werden. So bietet z.B. Microsoft auf seiner “Windows Live“ Webseite12 be-reits verschiedene Beta-Versionen solcher Ajax-Anwendungen. Darunter auch eine Text-verarbeitung sowie ein an Outlook Express anlehnendes E-Mail Programm. Auch Googlewartet auf der Seite “Google Docs & Spreadsheets“13 mit den browserfähigen Versioneneiner Textverarbeitung sowie einer Tabellenkalkulation auf.

12http://ideas.live.com/13http://docs.google.com/

Diplomarbeit von Benedikt Schwinkendorf

3 Die Idee: Ajax-Framework mit Webservices als Komponenten 13

3 Die Idee: Ajax-Framework mit Webservices alsKomponenten

Die Idee der vorliegenden Arbeit ist, die oben beschriebene Agenten-Technologie (Ajax)zu nutzen, um eine Webanwendung in Form von Service-Orientierten Teildiensten aufzu-bauen. Durch strikte Service-Orientierung werden dabei klare Strukturen auf der Client-und der Serverseite geschaffen. So werden Web-Server als Service-Lieferanten genutztund die Clientseite, meist in Form eines Web-Browsers, wird zum Service-Empfängerverschiedener Teildienste.

3.1 Das Problem

3.1.1 Heutige Webapplikationen sind als Software zu komplex

Heutige Webanwendungen setzen sich in der Regel aus vielen verschiedenen Teilanwen-dungen zusammen. So zählt z.B. “Content-Management“ zum verwalten der verschiede-nen Inhalte einer Webanwendung sowie eine entsprechende Benutzerverwaltung schonzu den Standard-Anforderungen neuer Web-Projekte. Hinzu kommen oft weitere Pro-grammteile, die je nach Anwendungsbereich (z.B. Home-Banking oder Suchmaschine)der Seite mehr oder weniger komplex sein können. Darüber steht in der Regel eine Da-tenbank oder ein ähnliches Persistenz-System um Inhalte dauerhaft speichern und beiBedarf abrufen zu können.

Ein Framework, das die Umsetzung einer solchen Webanwendungen ermöglichen soll,darf deren Komplexität nicht weiter steigern. Ein Framework sollte dabei helfen, gegebe-ne Komplexität möglichst einfach und verständlich umsetzen zu können. Einige bekannteRahmenwerke erfüllen diesen Vorsatz jedoch nicht. So muss z.B. ein Anwender des Web-CMS Plone14 erst viel Zeit investieren um dessen Funktionsweise zu verstehen, bevor erseine eigentliche Anwendung damit umsetzen kann. Mitgelieferte Dienste wie Authenti-fizierung oder Session-Management sind in Plone fest integriert. Eigene Erweiterungenoder Änderungen von Diensten dieser Art, können nur schwer realisiert werden und sindmit zusätzlichem Aufwand verbunden. Dadurch ist ein Anwender beim realisieren einerWebanwendung oft gezwungen, diese an die Eigenheiten des verwendeten Frameworksanzupassen, wobei die Zielsetzung eines Frameworks viel eher der umgekehrte Fall seinsollte. Viele Rahmenwerke setzen zudem einen Großteil ihrer Funktionalität serverseitigum. Eine stark frequentierte Webseite wird aber bei serverlastigen Anwendungen mitjedem neuen Benutzer zunehmend langsamer. Das Potential der Client-Rechner wirdnur von wenigen Frameworks optimal genutzt, dabei lassen sich viele Funktionen, wie

14http://www.plone.org/

Diplomarbeit von Benedikt Schwinkendorf

3 Die Idee: Ajax-Framework mit Webservices als Komponenten 14

z.B. das Sortieren einer Tabelle, auch ressourcen-sparend auf die verwendenden Clientsauslagern.

Ein Framework sollte es im Idealfall ermöglichen, die Komplexität einer Webanwendungvon deren Umsetzung mit dem Framework zu trennen. Jede Art von Anwendung soll-te mit einem Framework daher so zu realisieren sein, dass der Funktionsumfang derAnwendung vom Framework getrennt umgesetzt werden kann und nur bei Bedarf übervorgesehene Schnittstellen mit dem Framework kommuniziert wird. Die Anwendung undderen Anwender dürfen durch den Einsatz des Frameworks nicht eingeschränkt werden,sondern sollten durch eine bessere Handhabung der Komplexität davon profitieren. Zu-dem sollte ein Framework die Möglichkeit besitzen, Funktionalitäten auf die Seite desClients zu verlagern. Durch diese Maßnahmen kann ein Framework dazu beitragen, auchschwierige Sachverhalte verständlich und nachvollziehbar darzustellen.

3.1.2 Unzählige Ajax-Frameworks verfügbar mit vielfältigen Zielsetzungen

Seit der Einführung des Begriffs Ajax zu Anfang des Jahres 2005, steigt das allgemei-ne Interesse an dieser Technik. Vorhandene Webanwendungen werden um Ajax-Featureserweitert und viele neue Applikationen (Abschnitt 2.3.1 - Neue Webanwendungen entste-hen: Beispiel GMail, Flickr und PediaX) wären ohne Ajax-Technologie in der bekanntenForm nicht realisierbar. Mit der steigenden Zahl veröffentlichter und in Entwicklung be-findlicher Ajax-Anwendungen, erhöht sich auch die Nachfrage für geeignete Tools undFrameworks, die Entwicklern den Umgang mit der neuen Technik erleichtern sollen. EineVielzahl solcher Anwendungen lassen sich auf dem Ajax-Portal “Ajax Patterns“15 finden.Aktuell werden dort über 150 “Frameworks“ in 21 verschiedenen Kategorien gelistet. Wo-bei hier der Begriff des Frameworks lediglich als Oberbegriff angewendet werden sollte,da es sich oftmals nur um kleinere Tools oder Bibliotheken handelt.

Die Zielsetzung der angebotenen Frameworks läuft in viele verschiedene Richtungen. Sogibt es z.B. spezielle Frameworks um visuelle Effekte zu erzielen (Effects Frameworks),Log-Einträge zu erstellen (Logging Frameworks), “drag-and-drop“ Anwendungen zu rea-lisieren oder Widgets einzubinden (Specialised Frameworks). Entwickler sehen sich somitbei der Auswahl eines passenden Ajax-Frameworks für ein anstehendes Projekt vor eineschwere Aufgabe gestellt. Einige Rahmenwerke heben sich jedoch von der großen Mas-se ab und finden regen Zuspruch. Fünf der bekanntesten Frameworks werden daher inAbschnitt 5 - Abgrenzung zu alternativen Ajax-Frameworks detaillierter vorgestellt undmit der vorliegenden Arbeit verglichen.

15http://www.ajaxpatterns.org/

Diplomarbeit von Benedikt Schwinkendorf

3 Die Idee: Ajax-Framework mit Webservices als Komponenten 15

3.2 Der Ansatz

Strikte Service-Orientierung, Komponenten-Orientierung und Ajax-Einsatz bilden dieGrundlage des hier vorgestellten Frameworks. Was hinter diesen Gedanken steckt, wirdin den folgenden Abschnitten genauer erläutert.

3.2.1 Radikale Service-Orientierung: Alles ist ein Service

Das Prinzip, eine Webanwendung aus vielen verschiedenen Teildiensten zusammen zusetzen, soll logisch und konsequent angewendet werden, in dem alle Teildienste in Formvon Services von einem Web-Server angeboten werden. Jeder Service kann mit Hilfe desFrameworks auf der Clientseite eingebunden und verwendet werden. Prinzipiell wird esdadurch möglich, eine Webanwendung nach Belieben aus den verschiedenen angebotenenServices zusammen zu stellen.

Services werden vom Framework dabei in Ajax-Manier asynchron und im Hintergrundeiner Webanwendung nachgeladen. Über eine Konfiguration kann festgelegt werden, wel-che Services eine Webanwendung zu Beginn benötigt. Beim ersten Aufruf der Weban-wendung ist außer dieser Konfiguration und dem Framework an sich also kein weitererInhalt nötig. Erst durch das Nachladen der angegebenen Services wird die Webanwen-dung nach und nach zusammengesetzt. Ein einfache Applikation könnte so z.B. nachihrem Start einen Navigations-Service zum Aufrufen der Inhalte, einen Kalender-Serviceals Seitenübergreifender Dienst und einen Content-Service zum Anzeigen der Inhalteeinbinden. Eine Webanwendung auf diese Weise aus verschiedenen Teildiensten zusam-men zu setzen, sorgt schon bei der Konzeption der Anwendung für eine klare Trennungder unterschiedlichen Funktionalitäten. Services können so möglichst unabhängig von-einander entwickelt werden, was deren Wiederverwendbarkeit für andere Anwendungenerheblich steigern kann.

Auch die Funktionen des Frameworks selbst werden als separate Services angeboten.Eine Webanwendung kann aus diesem Service-Angebot den Funktionsumfang wählen,den sie wirklich verwenden möchte. Es muss also nicht immer das gesamte Frameworkeingeladen werden, eine Webanwendung bindet lediglich die Dienste ein, die sie für ihreUmsetzung benötigt und ausführen will.

3.2.2 Einfache und klare Strukturen durch Komponenten-Orientierung

In der Regel sind Webseiten als statisches HTML-Dokument auf einem Web-Server ge-speichert oder werden von diesem unter Einsatz einer Datenquelle dynamisch generiert.

Diplomarbeit von Benedikt Schwinkendorf

3 Die Idee: Ajax-Framework mit Webservices als Komponenten 16

So aufgebaute HTML-Dokumente enthalten alle dargestellten Teildienste als zusammen-hängenden Block und erlauben keine direkte Unterscheidung der Dienste auf der Cli-entseite. Auch Mashups (Abschnitt 2.3.2 - Teildienste anbieten und verknüpfen: BeispielFeeds und Mashups), also Webanwendungen die aus verschiedenen Teildiensten kombi-niert werden, verfahren hier nicht anders. Deren Inhalt wird auf den entsprechendenWeb-Servern durch einbeziehen fremder Datenquellen generiert und als zusammenhän-gendes HTML-Dokument an die Clientseite übertragen. Selbst der Einsatz von Ajax-Technologie ist noch kein Garant für übersichtliche Strukturen. In der Regel werdenüber Ajax-Kommunikation empfangene Inhalte mittels DOM-Manipulation auf vorbe-stimmten Platzhaltern eingefügt. Strukturell gesehen macht dies aber keinen Unterschiedzu Seiten, die vollständig auf einem Web-Server generiert wurden.

Verwenden die eingebundenen Dienste einer Webanwendung zusätzliche CSS-Styles fürindividuelles Layout oder Javascript-Programme für clientseitige Funktionalität, so müs-sen die entsprechenden Daten zusätzlich eingebunden werden. Dies geschieht meist glo-bal, im Head-Bereich einer Webseite, so dass die eingebundenen Funktionen und Stylesfür alle Dienste der Webseite Gültigkeit haben. Das dieses Verfahren bei größeren We-banwendungen aus vielen verschiedenen Teildiensten schnell unübersichtlich wird, liegtauf der Hand. Entwickler müssen daher genau beachten, dass verwendete Styles undFunktionen eines Dienstes nicht im Namens-Konflikt mit den Styles und Funktionenanderer Dienste stehen, da diese sich sonst gegenseitig beeinflussen würden.

Den Lösungsansatz für die oben genannte Probleme sieht die vorliegende Arbeit in derKomponenten-Orientierung. Da die Serverseite bereits durch das Anbieten verschiedenerTeildienste als Services eine klare Trennung des vorhandenen Funktionsumfangs vorsieht,liegt es nahe, diese Trennung auch auf der Clientseite beizubehalten. Die Komponenten-Orientierung bildet die Basis für dieses Vorhaben, da sie es erlaubt verschiedene Servicesund ihren Funktionsumfang in separaten Komponenten zu kapseln. Durch das Kap-seln in Komponenten entsteht zum einen eine klar unterteilte Struktur der Clientseiteund zum anderen werden mögliche Namens-Konflikte zwischen Layout-Definitionen oderJavascript-Programmen verhindert.

3.2.3 So viel Ajax-Einsatz wie möglich: Webservice-Agenten

Durch clientseitige Agenten (Abschnitt 2.2.2 - Eröffnung neuer Möglichkeiten durch cli-entseitige Agenten) soll das Potential der Ajax-Technologie möglichst effektiv genutztwerden. Jeder angebotene Service des Web-Servers stellt daher einen so genanntenWebservice-Agenten bereit, der einen Service auf der Clientseite repräsentiert und dieKommunikation mit der Serverseite via Ajax-Kommunikation übernimmt.

Alle Webservice-Agenten werden, wie oben beschrieben, auf der Clientseite unter Ein-satz des Frameworks in separaten Komponenten gekapselt. Innerhalb einer Komponen-

Diplomarbeit von Benedikt Schwinkendorf

3 Die Idee: Ajax-Framework mit Webservices als Komponenten 17

te kann ein Webservice-Agent seine Funktion unabhängig von anderen eingebundenenKomponente erfüllen. Benutzer- oder programmgesteuerte Javascript-Events, die inner-halb einer Komponente auftreten, können also direkt vom entsprechenden Webservice-Agenten abgefangen werden. Dieser kann darauf über Ajax-Kommunikation Daten vonder Serverseite empfangen oder dieser eigene Daten zusenden. Durch dieses Vorgehenkann jede Komponente und somit jeder Teildienst, der in dieser gekapselt wurde, se-parat verwendet werden. Die gesamte Kommunikation und der Programmablauf allerTeildienste einer Webanwendung können auf diesem Weg, über Webservice-Agenten undAjax-Kommunikation, im Hintergrund der Anwendung abgewickelt werden.

3.3 Was ein komponentenbasiertes Framework leisten muss

3.3.1 Komponenten und Komponenten-Komposition

Unter einer Komponente wird in dieser Arbeit die Kapselung eines bestimmten Dienstesoder einer Funktionalität in einem abgeschlossenen Bereich verstanden. Mittels Schnitt-stellen wird angegeben, über welche Funktionsaufrufe eine Komponente und ihr enthal-tener Dienst nach außen hin verwendbar ist und welche Ein- und Ausgabedaten diesebenötigen bzw. zurückgeben. Eine Komponente kann neben diesen “angebotenen Schnitt-stellen“ auch Schnittstellen angeben die sie benötigt, um ihren eigenen Dienst erfüllenzu können. So genannte “verwendete Schnittstellen“. Folgend ein kurzes Beispiel das zweiKomponenten verwendet. Komponente K die einen Kalender-Service kapselt und ihrenDienst über die Schnittstelle K.S1 zur Verfügung stellt und Komponente D, die überihre Schnittstelle D.S1 einen Datenbank-Service anbietet. Komponente K möchte nunneue Termine aus der Datenbank abfragen und verwendet dazu die Schnittstelle D.S1der Komponente D. Abbildung 3.1 stellt diesen Aufbau grafisch dar. Zur Unterschei-dung der beiden Schnittstellen-Arten werden “verwendete Schnittstellen“ innerhalb derverwendenden Komponente und “angebotene Schnittstellen“ außerhalb der anbietendenKomponente gezeichnet. Damit Schnittstellen-Abhängigkeiten von Komponenten auchin größeren Architekturdarstellungen besser sichtbar bleiben, werden die verschiedenenSchnittstellen mit eindeutigen Hintergrundmustern versehen.

Komponenten können auch andere Komponenten enthalten, d.h. mehrere einzelne Kom-ponenten zusammengefasst können eine neue, größere Komponente bilden. Solche zusam-mengesetzten Komponenten nennt man Komponenten-Komposition. Ein Komponenten-Komposition verbirgt ihre inneren Komponenten vor anderen Nutzern. Sie wirkt nachaußen hin wie eine normale Komponente die, wie oben beschrieben, eine oder mehrereSchnittstellen anbieten und verwenden kann. Andere Komponenten, die diese Schnitt-stellen nutzen oder anbieten sehen also nicht, was im Inneren der Komponenten-Kompo-sition geschieht oder wie diese aufgebaut ist. Auf das vorangehende Beispiel angewendet,ist es möglich aus Komponente K und Komponente D eine neue Komponente KD zu

Diplomarbeit von Benedikt Schwinkendorf

3 Die Idee: Ajax-Framework mit Webservices als Komponenten 18

Abbildung 3.1: Einfache Komponenten und Schnittstellen

komponieren. Die Komponente KD bietet lediglich die Schnittstelle K.S1 an und ist vonaußen über diese verwendbar. KD stellt also einen Kalender-Service dar, der das Ausle-sen gespeicherter Termine im Inneren selbst behandelt. Andere Komponenten kümmertes nicht, wie sich die Komponente KD im Inneren zusammen setzt und das es sichin Wirklichkeit um eine Komponenten-Komposition handelt. Sie sehen und verwendenlediglich die Schnittstelle K.S1 der Komponente KD. Dadurch wird es möglich, auchkomplexere Funktionalität, die sich über mehrere Komponenten widerspiegelt, in einerKomponenten-Komposition zu kapseln, die nach außen über einfache Schnittstellen ver-wendbar bleibt. Abbildung 3.2 zeit den Aufbau der Komponeten-Komposition KD undeine Komponente A, welche die Schnittstelle K.S1 von KD verwendet.

Abbildung 3.2: Komponenten-Komposition und Schnittstellen

Diplomarbeit von Benedikt Schwinkendorf

3 Die Idee: Ajax-Framework mit Webservices als Komponenten 19

3.3.2 Komponenten-Verbindungen zur Kommunikation

Das einfache Spezifizieren angebotener und verwendeter Schnittstellen von Komponentenreich noch nicht aus, um diese aktiv kommunizieren zu lassen. Daher werden Komponen-ten-Verbindungen benötigt, die zur Laufzeit einer Anwendung zwischen Schnittstellenverschiedener Komponenten hergestellt werden müssen. Diese leiten die Anfragen ei-ner Komponente an eine ihrer verwendeten Schnittstellen, an die passende Komponente,die diese Schnittstelle zur Verwendung anbietet, weiter. Das Erstellen von Komponenten,Schnittstellen sowie deren Komponenten-Verbindungen zur Laufzeit wird auch als Konfi-guration bezeichnet. Die Konfiguration einer Anwendung kann auch noch im Nachhineingeändert oder erweitert werden. Abbildung 3.3 zeigt den Aufbau einer Konfiguration fürdas oben beschriebene Beispiel.

Abbildung 3.3: Aufbau einer Konfiguration mit Komponenten-Komposition, Schnittstel-len und Komponenten-Verbindungen

3.4 Grundaufbau eines clientseitigen, komponenten-orientiertenAjax-Frameworks

3.4.1 Strikte Service-Orientierung: Auch Komponenten-Ansatz als Dienst!

Wie in Abschnitt 3.2.1 - Radikale Service-Orientierung: Alles ist ein Service beschrieben,ist ein Grundgedanke des Frameworks die strikte Service-Orientierung. Das Frameworkunterscheidet hierbei zwischen zwei wesentlichen Service-Arten. Zum einen den “Fra-mework-Services“ die verschiedene Funktionalitäten des Frameworks bereitstellen. Zumanderen den “Anwendungs-Services“, die als Teildienste einer Webanwendung verschie-dene Funktionalitäten anbieten.

Diplomarbeit von Benedikt Schwinkendorf

3 Die Idee: Ajax-Framework mit Webservices als Komponenten 20

Framework-Services werden z.B. eingesetzt, um Ajax-Kommunikation mit dem Ser-ver zu betreiben oder die im vorangehenden Abschnitt beschriebenen Komponenten-Verbindungen herzustellen. Framework-Services können von anderen Framework-Servicesabhängig sein und deren Dienste zum realisieren von eigenen Funktionen verwenden. Al-le Abhängigkeiten werden beim einbinden eines Framework-Service geprüft und fehlendeFramework-Services automatisch nachgeladen. Anwendungs-Services werden nicht voll-ständig auf den Client übertragen, sondern stellen für ihre clientseitige Repräsentationeinen Webservice-Agenten bereit. Dieser wird auf dem Client, in einer separaten Kom-ponente gekapselt, eingebunden.

Jeder Webservice-Agent kann beliebige Framework-Services verwenden. Diese werdennach Bedarf als weitere Komponenten hinzugefügt. Somit entsteht eine Komponenten-Komposition, die sich aus der Komponente des Webservice-Agenten und einer oder meh-reren Framework-Service-Komponenten zusammen setzt. Jeder verwendete Service, obAnwendungs- oder Framework-bezogen, wird also auf der Clientseite als Komponenteangesehen und eingebunden.

3.4.2 Namespaces als Basis für clientseitigen Komponentenanteil

Die zuvor beschriebene Komponenten-Komposition, wird auf der Clientseite mit Hilfe desFrameworks in Form eines Namespace eingebunden. Prinzipiell kann jede Komponenten-Komposition daher auch als Namespace angesehen werden, der wiederum von andereneingebundenen Namespaces als einfache Komponente betrachtet wird. Jede Namespace-Komponente stellt auf der Clientseite einen vollständigen Teildienst einer Webanwen-dung dar. Nach außen hin ist nicht ersichtlich aus wie vielen Komponenten der Name-space im Inneren besteht oder wie angebotene Schnittstellen im Inneren verarbeitet wer-den. Viele Namespace-Komponenten bilden gemeinsam die eigentliche Webanwendung.Die Planung einer Webanwendung kann daher auf Basis der Namespace-Komponentenin Form einer Komponenten-Architektur erstellt werden. Abbildung 3.4 zeigt den Aufbaueiner Namespace-Komponente als Komponenten-Komposition. Durch den geschachtel-ten Aufbau des DOM-Modells einer Webseite, können Komponenten und Komponenten-Kompositionen einfach in diesem abgebildet werden. Durch DOM-Manipulation wird esmöglich, den Aufbau einer Webanwendung auch noch zur Laufzeit beliebig zu verändernund dadurch Komponenten hinzuzufügen, zu ändern oder zu entfernen.

Eine Namespace-Komponente stellt seinen eingebundenen Komponenten eine eigeneLaufzeitumgebung zur Verfügung. Dies hat den Vorteil, dass verwendete Styles undJavascript-Programme nur innerhalb dieser Umgebung gültig sind. Namens-Konflikte indiesen Bereichen müssen demnach nur noch für einen Namespace und dessen Teildienstvorgenommen werden, was die Entwicklung einer Webanwendung auch bei Verwendungvieler verschiedener Dienste übersichtlich gestaltet. Durch die separaten Laufzeitumge-bungen kann jeder Teildienst einer Webanwendung eigenständig verwendet werden, ohne

Diplomarbeit von Benedikt Schwinkendorf

3 Die Idee: Ajax-Framework mit Webservices als Komponenten 21

Abbildung 3.4: Namespace als clientseitige Komponenten-Komposition

dabei andere Teildienste zu beeinflussen. Akzeptiert der verwendete Web-Server zudemmehrere HTTP-Requests von einem Client zu einer Zeit, so werden durch die unab-hängigen Laufzeitumgebungen sogar parallele Anfragen einer Webanwendung möglich.Ansonsten laufen ausstehende HTTP-Requests sequentiell in Reihenfolge des Anfrage-zeitpunktes ab.

3.4.3 Clientseitige Komponenten-Verbindungen per Subscriber-Modell

Eine Webanwendung setzt sich, wie in Abschnitt 3.4.2 - Namespaces als Basis für cli-entseitigen Komponentenanteil beschrieben, aus mehreren Namespace-Komponenten zu-sammen. Diese verhalten sich nach außen hin wie eine einfache Komponente und könnenSchnittstellen anbieten und anfordern. Um Komponenten-Verbindungen zwischen die-sen Schnittstellen und deren Namespace-Komponenten herstellen zu können, stellt dasFramework ein Subscriber-Modell zur Verfügung.

Namespace-Komponenten bzw. die darin enthaltenen Webservice-Agenten können einoder mehrere Funktionen zum “subscriben“ anbieten. Andere Komponenten können sichauf diese angebotenen Funktionen einschreiben. Sie werden dadurch “Subscriber“ einerFunktion. Dieser Vorgang kann mit einem Abonnement verglichen werden. Der Sub-scriber wird, solange er eingeschrieben ist, bei jedem Aufruf der Funktion durch dieanbietenden Komponente automatisch aufgerufen. Durch das Einschreiben des Subscri-bers auf die Funktion wurde eine Komponenten-Verbindung zwischen der abonnierendenKomponente und der anbietenden Komponente hergestellt. Abbildung 3.5 stellt dieseKomponenten-Verbindung dar. Der Funktionsaufruf der anbietenden Komponente wird

Diplomarbeit von Benedikt Schwinkendorf

3 Die Idee: Ajax-Framework mit Webservices als Komponenten 22

direkt an den betreffenden Subscriber geleitet, welcher darauf seine eigene Implementie-rung der Funktion durchlaufen kann. Eventuelle Parameter können dabei ohne Änderungvom Subscriber empfangen werden.

Abbildung 3.5: Komponenten-Verbindung mittels Subscriber

3.4.4 Client/Server-Kommunikation durch Kommunikationsdienst

Das Framework bietet einen separaten Service für die Kommunikation der Clientseitemit dem Server an. Jeder Namespace bzw. die darin enthaltenen Services können diesenKommunikations-Service nutzen und eigenständig mit dem Server kommunizieren. DerKommunikationsdienst nutzt Ajax-Technologie, um die Kommunikation mit der Server-seite asynchron im Hintergrund der Webanwendung zu realisieren.

Die Serverseite bietet für die Kommunikation mit dem Client eine definierte Schnitt-stelle, die vom Kommunikations-Service verwendet wird. Funktionsaufrufe über dieseSchnittstelle werden vom Server automatisch an die betreffenden Services der Serversei-te weitergeleitet. Dadurch können über den Kommunikations-Service alle Dienste einerWebanwendung auf dem Server angesprochen werden.

Diplomarbeit von Benedikt Schwinkendorf

3 Die Idee: Ajax-Framework mit Webservices als Komponenten 23

3.5 Absicherung: Was, wenn ein Client kein Ajax unterstützt?

3.5.1 Webanwendungen ohne Ajax-Abhängigkeit realisieren

Die Verwendung des Frameworks wie bisher beschrieben, erfordert vom Web-Browser desBenutzers die Unterstützung, der bei der Ajax-Kommunikation verwendeten Techniken.Doch nicht alle Web-Browser unterstützten asynchrone HTTP-Requests oder das Aus-führen von clientseitigen Javascript-Programmen. Auch aus Sicherheitsgründen, kannJavascript z.B. in größeren Firmennetzwerken von vornherein deaktiviert sein. Wer alsodie Nutzung einer Webanwendungen bestimmten Nutzerkreisen nicht vorenthalten will,muss eine entsprechende Alternative zur Absicherung bereitstellen.

Eine Webanwendung ohne Ajax-Abhängigkeit zu realisieren, erfordert prinzipiell einejavascript-freie Version der Webanwendung und all ihrer Teildienste. Ohne den Einsatzvon Javascript, ist es jedoch nicht mehr möglich die bisher beschriebenen clientseitigenFunktionen wie z.B. das Nachladen von Services zu realisieren. Die Clientseite kannsomit keine Ajax-Kommunikation mehr betreiben oder Webservice-Agenten ausführen.Auch der Austausch von clientseitigen Nachrichten zwischen Namespace-Komponentenist ohne Javascript nicht mehr umzusetzen.

Der Web-Browser des Clients übernimmt in diesem Fall nur noch die eigentliche Darstel-lung deiner Webseiten. Die gesamte Programmlogik einer Webanwendung muss wiederauf der Serverseite realisiert werden. Eine Webanwendung ist somit auf die in Kapi-tel 2 beschriebenen Grundlagen der Web-Technologie angewiesen und empfängt neueWebseiten, durch Klicken des Benutzers auf einen entsprechenden Hyperlink, immer alsvollständiges HTML-Dokument.

3.5.2 Aufbau einer Webanwendung mit serverseitiger Client-Simulation

Was also tun, um nicht alle Vorteile, die durch den Aufbau von Webanwendungen aufBasis von Teildiensten und durch den Einsatz des Ajax-Frameworks entstehen, in derjavascript-freien Version einer Webanwendung zu verlieren? Die Idee der vorliegendenArbeit ist es hier, auf der Serverseite einen Client zu simulieren, der den Aufbau einer We-banwendung aus verschiedenen Teildiensten beibehalten kann. Dieser simulierte Clientwird dabei auf der Serverseite vor der eigentlichen Server-Anwendung platziert. Der Web-Browser eines Clients kommuniziert nun nicht mehr direkt mit der Server-Anwendung,sondern mit dem simulierten Client, welcher dem Web-Browser immer vollständige Web-seiten zurück liefert. Das Modell einer Webanwendung bei Anwendung des Frameworksmit und ohne Javascript wird in Abbildung 3.6 dargestellt.

Der simulierte Client setzt eine Webanwendung ebenfalls aus verschiedenen Teildienstenzusammen, die er beim Server separat anfordern kann.

Diplomarbeit von Benedikt Schwinkendorf

3 Die Idee: Ajax-Framework mit Webservices als Komponenten 24

Abbildung 3.6: Modell einer Webanwendung bei Anwendung des Frameworks mit undohne Javascript im Vergleich

Der simulierte Client generiert das HTML-Dokument der aktuell darzustellenden Web-seite aus den jeweiligen Zuständen der einzelnen Teildienste. Je nach Zustand, liefert

Diplomarbeit von Benedikt Schwinkendorf

3 Die Idee: Ajax-Framework mit Webservices als Komponenten 25

ein Teildienst unterschiedliche HTML-Daten für seine Darstellung zurück. Diese werdenauf dem simulierten Client gespeichert, so dass dieser nicht bei jeder neu empfangenenHTTP-Anfrage alle Services erneut von der Server-Anwendung empfangen muss.

Wie bereits ein Webservice-Agent der Clientseite, sendet der simulierte Client nur neueAnfragen an die Server-Anwendung, wenn er mit einem bestimmten Service kommu-nizieren will. Entweder um dem Service neue Daten zu senden oder um selbst neueInhalte zu empfangen. Für die Kommunikation mit der Server-Anwendung und denAufbau der Webanwendung aus Teildiensten, verwendet der simulierte Client eine ei-gene, javascript-freie Version des Ajax-Frameworks auf Basis von PHP. Dieses PHP-Framework stellt ebenfalls einen Kommunikations-Service zur Verfügung, der diesel-be Schnittstelle zum Ansprechen der Services auf der Serverseite verwendet, wie derKommunikations-Service des Ajax-Frameworks. Angeforderte Anwendungs-Services derServerseite werden also ebenfalls in Form eines Webservice-Agenten empfangen und ein-gebunden. Auch alle weiteren Framework-Services des Ajax-Frameworks existieren inPHP-Versionen, die ähnliche oder gleiche Dienste anbieten und überwiegend über die-selben Schnittstellen verwendbar sind. Durch diesen Aufbau wird es, wie im folgendenKapitel genauer erläutert, mit wenig Aufwand möglich, einen serverseitigen Teildienstauch auf einem javascript-freien Client lauffähig zu machen.

Diplomarbeit von Benedikt Schwinkendorf

4 Die Umsetzung: Aufbau und Anwendung des Frameworks 26

4 Die Umsetzung: Aufbau und Anwendung desFrameworks

4.1 Überblick über den den Aufbau und die Services desFrameworks

Das Framework verwendet auf der Serverseite den Apache-Webserver16 mit MySQL-Anbindung17 und die Skriptsprache PHP18. Dies stellt die im WWW am häufigsten ein-gesetzte Kombination aus Web-Server, Datenbank und serverseitiger Skriptsprache darund ist auch unter der Bezeichnung LAMP bzw. WAMP (für Linux bzw. Windows,Apache, MySQL und PHP) bekannt. Die Server-Anwendung und die dort enthaltenenTeildienste wurden über Komponenten und Schnittstellen realisiert. Dadurch ist genaufestgelegt, welche Ein- und Ausgabedaten die jeweiligen Server-Komponenten verwen-den oder anbieten. Es wird somit einfach möglich, die Server-Anwendung auch auf ande-rer technischer Grundlage aufzubauen und z.B. andere serverseitige Skriptsprachen wieASP.NET oder JSP oder eine andere Datenbank zu verwenden.

Als Daten-Format für den Nachrichtenaustausch mit der Server-Anwendung kommt dasJSON-Format19 zum Einsatz. JSON ist ein kompaktes Datenaustausch-Format, das vonMenschen und Computern gleichermaßen gelesen werden kann. Es existieren JSON-Implementierungen für alle gängigen Programmiersprachen. Die Clientseite einer We-banwendung kann somit ohne zusätzliche Änderungen auch mit einer Server-Anwendungkommunizieren, die nicht auf Basis der Skriptsprache PHP erstellt wurde. Zudem könnenübertragene JSON-Daten in Javascript über die eval-Funktion direkt in ein Javascript-Objekt umgesetzt und weiterverarbeitet werden.

Das Framework bietet neben dem Init-Service, der im folgenden Abschnitt erläutert wird,sechs weitere Framework-Services mit unterschiedlicher Funktionalität. Die Funktions-namen und Variablennamen der einzelnen Framework-Services wurden mit einem Präfixversehen. Dieses besteht zum einen aus einem Kürzel, das den definierenden Framework-Service angibt und zum anderen aus einem Kategorie-Buchstaben, der die vorgeseheneBenutzung einer Funktion oder Variable kennzeichnet. Es gibt drei verschiedene Kate-gorien, die in der folgenden Auflistung erläutert werden.

1. Kategorie “x“Kennzeichnet private Funktionen und Variablen des Frameworks. Diese dürfen nurvom Framework selbst verwendet werden.

16http://httpd.apache.org/17http://www.mysql.de/18http://www.php.net/19http://www.json.org/

Diplomarbeit von Benedikt Schwinkendorf

4 Die Umsetzung: Aufbau und Anwendung des Frameworks 27

2. Kategorie “p“Kennzeichnet öffentliche Funktionen und Variablen eines Frameworks. ÖffentlicheFunktionen dürfen ohne Einschränkung von allen Teilen einer Webanwendung ver-wendet werden.

3. Kategorie “u“Kennzeichnet Funktionen und Variablen, die vom Entwickler einer Webanwendungzu editieren sind. Sie enthalten Konfigurations-Einstellungen, die für die Verwen-dung des Frameworks angegeben werden müssen.

Das Kürzel des Framework-Service und die Kennzeichnung der Kategorie sind jeweilsdurch Unterstriche voneinander getrennt, wobei am Anfang eines Funktions- oder Varia-blennamen zwei Unterstriche gesetzt werden. Ein Beispiel für eine öffentliche Funktiondes Kommunikations-Service wäre somit: “__CS_p_doRequest“ gefolgt von entsprechen-den Parametern.

4.1.1 Der Init-Service als Funktionsgrundlage

Das Framework stellt als Funktionsgrundlage einen Init-Service bereit. Dieser wird ein-gesetzt um weitere Framework-Services nachzuladen. Die Startseite einer Webanwen-dung muss diesen Init-Service in Form einer Javascript-Datei direkt einbinden, damitdas Framework verwendet werden kann. Der Init-Service verfügt über die Startfunktion__IS_p_initialize(). Diese muss im im Body-Tag der Webanwendung über das Javas-cript-Event “onload“ aufgerufen werden, damit der Init-Service das Nachladen benötigterFramework-Services veranlassen kann.

Über die Variable __IS_u_FRAMEWORK_SERVICE_ARRAY wird angegeben welche Framework-Services zu Beginn der Webanwendung benötigt werden. Es handelt sich hierbei um einString-Array, in dem die Service-Namen der entsprechenden Framework-Services direkteingetragen werden können.

var __IS_u_FRAMEWORK_SERVICE_ARRAY =new Array (

'composition_service' ,'subscriber_service' ,'configuration_service'

) ;

In der Initialize-Funktion des Init-Service wird dieses Array ausgewertet und das Nach-laden und Einbinden der entsprechenden Framework-Services automatisch veranlasst.Durch das Einbinden des Konfigurations-Service, wie im obigen Beispiel, können schonbeim Start der Webanwendung beliebige Anwendung-Services bzw. deren Webservice-

Diplomarbeit von Benedikt Schwinkendorf

4 Die Umsetzung: Aufbau und Anwendung des Frameworks 28

Agenten angefordert und direkt eingebunden werden. Die genaue Vorgehensweise hier-für wird anhand einer Beispielanwendung in Abschnitt 4.2.3 - Anpassen der Server-Konfiguration erläutert.

4.1.2 Beschreibung der Framework-Services und ihrer Funktionen

Der Kompositions-ServiceDer Kompositions-Service bietet einer Webanwendung die Möglichkeit neue Anwen-dungs-Services bzw. den entsprechenden Webservice-Agenten nachzuladen und als Kom-ponente einzubinden. Der Service erstellt eine Namespace-Komponenten und bindet denWebservice-Agenten dort als Teil der Komposition ein. Jeder Webservice-Agent besitztebenfalls einen Init-Service der, wie oben beschrieben, die angegebenen Framework-Services für diesen Teildienst nachladen kann. Die entsprechende Initialize-Funktion wirdnach dem Einbinden des Webservice-Agenten automatisch aufgerufen.

Abbildung 4.1: Das optionale Menü einer Namespace-Komponente

Eine Namespace-Komponente kann mit einem einfachen Menü versehen werden. Dieseszeigt zunächst den Namen des verwendeten Anwendungs-Service und einen Schließen-Button an, über den die Namespace-Komponente und somit der gesamte Teildienst, derdarin enthalten ist, entfernt werden kann. Werden über den Init-Service des enthaltenenWebservice-Agenten die Framework-Services für Update und Monitoring eingebunden,so fügen diese Dienste dem Menü weitere Buttons hinzu. Für das Hinzufügen einesneuen Buttons, stellt der Kompositions-Service eine öffentliche Funktion bereit, so dasdas Menü auch individuell erweitert werden kann. Abbildung 4.1 zeigt das Menü mit denzusätzlichen Buttons vom Update- und Monitoring-Service.

Der Kommunikations-ServiceDer Kommunikations-Service kann für die Kommunikation mit der Serverseite verwendetwerden. Er setzt, wie in Abschnitt 3.4.4 - Client/Server-Kommunikation durch Kommu-nikationsdienst beschrieben, Ajax-Technologie zur asynchronen Kommunikation ein undspricht dabei die dafür angebotene Schnittstelle der Server-Anwendung an.

Der Kommunikations-Service besitzt zur öffentlichen Nutzung lediglich die doRequest-Funktion. Diese erlaubt es, neue Anfragen an einen beliebigen Anwendungs-Service zustellen. Die Funktion erwartet als Parameter den Service-Namen des anzusprechendenAnwendungs-Service, den Namen einer dort aufzurufenden Funktion, eine beliebige An-zahl an entsprechenden Funktionsparametern und den Namen einer Empfänger-Funktion

Diplomarbeit von Benedikt Schwinkendorf

4 Die Umsetzung: Aufbau und Anwendung des Frameworks 29

auf der Clientseite. Der Aufruf wird auf dem Server automatisch an den entsprechen-den Anwendungs-Service weitergeleitet, welche die Auswertung der übergebenen Datenübernimmt und die angegebene serverseitige Funktion ausführt. Die Empfänger-Funk-tion wird, mit den Rückgabewerten der Funktion aufgerufen, sobald die Daten als ent-sprechende Antwort vom Server empfangen wurden.

Der Konfigurations-ServiceDurch das Einbinden des Konfigurations-Service kann das Nachladen mehrerer Webser-vice-Agenten ausgelöst werden. Dieser Dienst kann eingesetzt werden, um z.B. beimStart einer Webanwendung mehrere Teildienste einzubinden. Der Konfigurations-Ser-vice lädt bei seinem serverseitigen Gegenstück die aktuelle Konfiguration, diese enthälteine Liste, mit Namen, Position und Menü-Einstellung aller nachzuladenden Webservice-Agenten. Der Konfigurations-Service durchläuft diese Liste und bindet die angegebenenWebservice-Agenten mit Hilfe des Kompositions-Service ein.

Wird die Serverseite des Konfigurations-Service z.B. mit einer Benutzerverwaltung ge-koppelt so können, dem Status des aktuellen Benutzers entsprechend, unterschiedlicheKonfigurationen liefern. So würde ein angemeldeter Benutzer beispielsweise mehr oderandere Webservice-Agenten geliefert bekommen als ein unbekannter Benutzer.

Der Monitoring-ServiceDer Monitoring-Service stellt verschiedene Funktionen zur Verfügung, die es erlaubenbestimmte Ereignisse als Nachricht in einer Historie abzulegen und alle bisher gespei-cherten Nachrichten wieder auszulesen.

Wurde der Monitoring-Service als Teil einer Namespace-Komponente eingebunden dieüber ein Menü verfügt, so erstellt der Dienst automatisch einen Button in diesem Menü.Über den Button kann die Nachrichten-Ansicht ein- und ausgeblendet werden. Abbildung4.5 stellt das Menü und eine geöffnete Historie dar.

Der Subscriber-ServiceWie in Abschnitt 3.4.3 - Clientseitige Komponenten-Verbindungen per Subscriber-Modellbeschrieben, stellt das Framework ein Subscriber-Modell für die clientseitige Kommu-nikation zwischen Namespace-Komponenten bereit. Verwendet ein Webservice-Agentdiesen Dienst, so kann er eine Komponenten-Verbindung zwischen seiner Namespace-Komponente und der Namespace-Komponente eines anderen Agenten erstellen. Übereine Komponenten-Verbindung wird der Aufruf der betreffenden Funktion, mitsamt denentsprechenden Parametern, an die Namespace-Komponente übergeben, die als Subscri-ber eingetragen ist.

Die anbietende Namespace-Komponente kann über eine Standard-Implementierung derangebotenen Funktion verfügen. Diese Implementierung wird aufgerufen, wenn kein Sub-scriber für die Funktion eingetragen ist oder der betreffende Subscriber nicht mehr er-reichbar ist. Dies kann z.B. der Fall sein, wenn eine subscribende Namespace-Komponenteüber den Schließen-Button ihres Menüs entfernt wurde.

Diplomarbeit von Benedikt Schwinkendorf

4 Die Umsetzung: Aufbau und Anwendung des Frameworks 30

Der Update-ServiceDer Update-Service wird verwendet, um einen Anwendungs-Service automatisch auf neueInhalte zu prüfen. Erkennt der Dienst neue Inhalte, so löst er über den Kommunikations-Service das erneute Nachladen des entsprechenden Webservice-Agenten aus. Über denKompositions-Service wird der vorhandene Webservice-Agent dann mit den Daten desneu empfangenen Agenten aktualisiert.

Das automatische Überprüfen auf neue Inhalte wird mittels Polling in einem vorgegebe-nen Intervall ausgelöst. Verfügt die betreffende Namespace-Komponente über ein Menü,so kann die regelmäßige Überprüfung auch vom Benutzer aktiviert und deaktiviert wer-den. Zudem kann dieser über ein Konfigurations-Panel das Update-Intervall verändern.Als weitere Option kann der Benutzer dort wählen, ob das Nachladen des Webservice-Agenten automatisch geschehen oder er dies vorher bestätigen soll. Über eine weite-re Update-Funktion kann das Aktualisieren eines Webservice-Agenten zudem manuellausgelöst werden.

4.2 Eine Webanwendung aus Teildiensten erstellen undkonfigurieren

4.2.1 Die Startseite als permanentes Layout-Grundgerüst

Die Startseite einer Webanwendung ist ein einfaches HTML-Dokument im Hauptver-zeichnis der Webanwendung. Die Seite muss die im für den Einsatz des Init-Servicebeschriebenen notwendigen Punkte erfüllen, damit das Framework verwendet werdenkann. Als Startseite für das im nächsten Abschnitt folgende Beispiel kann der untenstehende Quellcode verwendet werden.

<html><head><l ink rel=" Sty l e sh e e t " type=" text / c s s "href=" l i b / c s s / gene ra l . c s s " /><script =" JavaScr ipt " type=" text / j a v a s c r i p t "src=" l i b / i n i t_ s e r v i c e . j s "></ script></head><body onload="__IS_p_init ia l ize ( ) ">

<span id=" content " style=" po s i t i o n : abso lu t e ;top : 10px ; l e f t : 10px">

</span></body></html>

Diplomarbeit von Benedikt Schwinkendorf

4 Die Umsetzung: Aufbau und Anwendung des Frameworks 31

Um dabei die genaue Position einzubindender Webservice-Agenten bestimmen zu kön-nen, werden auf der Startseite Platzhalter erstellt. Diese werden als Span- oder Div-Elemente erstellt und über CSS-Styles auf der Startseite positioniert. Jeder Platzhal-ter wird dabei mit einer eindeutigen ID versehen. Diese ID muss beim Nachladen einesWebservice-Agenten angegeben werden, damit dieser richtig positioniert werden kann.Hierbei besteht auch die Möglichkeit mehrere Webservice-Agenten mit derselben ID zuversehen. Die entsprechende Namespace-Komponente wird dann unterhalb der auf dieserPosition bereits bestehenden Namespaces eingebunden.

Durch Angabe verschiedener Platzhalter wird die Layout-Grundlage einer Webanwen-dung geschaffen. Da durch das Einbinden oder das Entfernen von Namespace-Komponentendie Platzhalter an sich nicht verändert werden, bleibt diese Layout-Grundlage für eineWebanwendung permanent erhalten. Die Startseite einer Webanwendung kann nebenden Platzhaltern auch beliebig mit “normalen“ HTML-Elementen gefüllt werden. Ei-ne Webanwendung kann somit auch zugleich aus statischen Inhalten und einem odermehreren Teildiensten aufgebaut sein.

4.2.2 Anlegen und initialisieren von Anwendungs-Services: “Hello World“

Das Anlegen sowie das Initialisieren eines Anwendungs-Service, wird in den folgendenAbschnitten anhand eines “Hello World“-Beispiels erläutert. Um den entsprechenden “hel-lo_world_service“ zu erstellen, muss zunächst ein gleichnamiges Verzeichnis unter demPfad /server/services/application/ erstellt werden. In diesem Ordner erstellt mananschließend die PHP-Datei “hello_world_service.php“ und darin eine ebenso bezeichne-te Klasse. Die Service-Klasse muss, um später über die Schnittstelle “interface_applica-tion_service“ erreichbar zu sein, die Klasse “application_service“ erweitern, welche dieseSchnittstelle implementiert. Zudem kann dadurch einfach auf einige Helfer-Funktionender “application_service“-Klasse zugegriffen werden. Die PHP-Klasse des “Hello World“-Service beginnt somit mit folgender Zeile:

class he l lo_wor ld_serv ice extends app l i c a t i on_se rv i c e { . . .

Im nächsten Schritt wird der Konstruktor der PHP-Klasse erstellt. Hier kann der Da-teiname einer eventuell vorhandenen Javascript-Datei und einer CSS-Datei angegebenwerden. Das Javascript-Programm und die CSS-Styles werden bei späteren Anfragenals Teil des Webservice-Agenten übergeben und vom Framework automatisch so einge-bunden. Dies geschieht so, dass Javascript-Funktionen und CSS-Styles im Quellcode desWebservice-Agenten normal verwendet werden können. Die CSS-Datei und die Javas-cript-Datei werden dabei im Unterordner /css/ bzw. /lib/ des Anwendungs-Servicegespeichert. Dem Konstruktor wird als Parameter der Titel des Anwendungs-Service

Diplomarbeit von Benedikt Schwinkendorf

4 Die Umsetzung: Aufbau und Anwendung des Frameworks 32

übergeben. Dieser Titel wird in der Klassenvariable title abgelegt. In der letzten Co-dezeile des Konstruktors wird schließlich der Konstruktor der Eltern-Klasse “applicati-on_service“ aufgerufen. Der vollständige Konstruktor für das laufende Beispiel könntesomit so aussehen:

function he l lo_wor ld_serv ice ( $ t i t l e ) {$th i s−>l ib_f i l ename = 'hello_world_service' ;$ th i s−>css_f i l ename = 'hello_world_service' ;$ th i s−>t i t l e = $ t i t l e ;$ th i s−>app l i c a t i on_se rv i c e ( ) ;

}

Nun kann die Funktion getWebserviceAgent() implementiert werden. Diese entspricht,der in der Schnittstelle “interface_application_service“ angegebenen Funktion und über-schreibt dadurch deren Implementierung innerhalb der Eltern-Klasse “application_service“.Wie der Name der Funktion bereits vermuten lässt, gibt diese den Webservice-Agenteneines Anwendungs-Service zurück. Der eigentliche HTML-Code eines Webservice-Agentenkann hier individuell erstellt werden. Der definierte Quellcode wird dazu in der Klassen-variable html abgelegt. Für den “Hello World“-Service soll hier ein Hyperlink definiertwerden, der beim klicken eine Javascript-Funktion aufruft. Das Layout des Hyperlinkswird zudem über ein einfaches CSS-Style bestimmt.

function getWebserviceAgent ( ) {$th i s−>html = '<a class="pagelink" href="#"onclick="helloWorld(\'Hallo\'); return false;">Hallo

Welt!</a>' ;return $th i s−>createWebserviceAgent ( ) ;

}

Durch den abschließenden Aufruf der Funktion createWebserviceAgent(), die von der“application_service“-Klasse bereit gestellt wird, kann der Webservice-Agent erstellt unddirekt zurückgegeben werden.

Jeder Anwendung-Service muss seinem Webservice-Agenten einen eigenen Init-Service(Abschnitt 4.1.1 - Der Init-Service als Funktionsgrundlage) bereitstellen. In diesem wirdangegeben, welche Framework-Services ein Webservice-Agent benötigt um seinen Diensterfüllen zu können. Als Vorlage kann die Datei “init_service_.js“ aus dem Ordner/lib/ des Hauptverzeichnis verwendet werden. Diese wird in den Ordner /server/ser-vices/hello_world_service/lib/ kopiert und die benötigten Framework-Services imArray __IS_u_FRAMEWORK_SERVICE_ARRAY eingetragen.

Bevor das Erstellen des “Hello World“-Service durch das Anpassen der Server-Konfigura-tion abgeschlossen wird, müssen noch die beiden im Konstruktor angegebenen Dateienfür Javascript und CSS erstellt werden. Die Javascript-Datei “hello_world_service.js“

Diplomarbeit von Benedikt Schwinkendorf

4 Die Umsetzung: Aufbau und Anwendung des Frameworks 33

wird also im Unterordner /lib/ des Anwendungs-Service mit der Funktion helloWorld()erstellt. Diese soll für das Beispiel ein einfaches Popup-Fenster aufrufen.

/∗ he l lo_wor ld_serv ice . j s ∗/function hel loWorld ( t ext ) { alert ('Welt: ' + text ) ; }

Schließlich wird die CSS-Datei “hello_world_service.css“ im Unterordner /css/ an-gelegt. Diese soll das Layout des Hyperlinks durch das Definieren der Style-Klassepagelink bestimmen.

/∗ he l lo_wor ld_serv ice . c s s ∗/a . page l ink {

font−family : Verdana , Geneva , Ar ia l , He lve t i c a ;font−s ize : 13px ;text−decoration : none ;color : #333399;

}a . page l ink : hover {

font−family : Verdana , Geneva , Ar ia l , He lve t i c a ;font−s ize : 15px ;text−decoration : none ;color : #666666;

}

4.2.3 Anpassen der Server-Konfiguration

Nachdem alle Vorbereitungen für das Erstellen eines neuen Anwendungs-Service wieoben beschrieben getätigt wurden, kann der Server für den Einsatz des betreffendenAnwendungs-Service konfiguriert werden.

Dies geschieht zunächst in der PHP-Klasse “configuration_manager“, welche im Ordner/server/ zu finden ist. Diese Klasse stellt den Konfigurations-Manager des Servers darund übernimmt die Komponenten-Konfiguration der Serverseite. PHP-bedingt muss hierdie Datei des erstellten Anwendungs-Service über die PHP-Funktion include() einge-bunden werden, bevor ein Objekt der darin enthaltenen Klasse erstellt werden kann.

include ( " s e r v i c e s / app l i c a t i o n / he l lo_wor ld_serv ice /he l lo_wor ld_serv ice . php" ) ;

Die Funktion __CM_u_setApplicationServices() dient der Konfiguration von Anwen-dungs-Services. Hier wird ein neuer Service wie folgt eingebunden.

Diplomarbeit von Benedikt Schwinkendorf

4 Die Umsetzung: Aufbau und Anwendung des Frameworks 34

/∗ I n s t a n t i a t e HelloWorld−Se rv i c e ∗/$he l lo_wor ld_serv ice

= new he l lo_wor ld_serv ice ("Hallo Welt!" ) ;/∗ I n s t a n t i a t e HelloWorld−Se rv i c e i n t e r f a c e ∗/$ inte r face_he l l o_wor ld_serv i c e

= new i n t e r f a c e_app l i c a t i o n_s e r v i c e s ( ) ;/∗ Bind HelloWorld−Se rv i c e implementation ∗/$ inte r face_he l lo_wor ld_serv i ce−>

$BIND_IMPLEMENTATION(&$he l lo_wor ld_serv ice ) ;/∗ Bind Server Component used i n t e r f a c e ∗/$th i s−>server_component−>

$BIND_USED_INTERFACE("interface_hello_world_service" ,&$ inte r face_he l l o_wor ld_serv i c e

) ;

Dieser Code stellt die Grundkonfiguration eines Anwendungs-Services dar und enthältalle Angaben die serverseitig nötig sind, um einen Anwendungs-Service clientseitig an-sprechen zu können. Zuerst wird ein Objekt der neuen Service-Klasse erstellt, dabei wirdder gewünschte Titel als Parameter übergeben. Als nächstes wird die Schnittstelle desAnwendungs-Service erstellt. Hierfür wird die allgemeine Schnittstelle interface_app-lication_service verwendet. Dadurch werden alle Anwendungs-Services über diesel-be Schnittstelle verwendbar. Im folgenden Schritt wird die Implementierung des An-wendungs-Service, also das zuvor erstelle Objekt der Service-Klasse, an die Schnitt-stelle übergeben. Diese verwendet das Objekt bzw. die entsprechende Klasse nun alsSchnittstellen-Implementierung. Ab diesem Zeitpunkt werden alle Funktionsaufrufe, dieüber diese Schnittstelle getätigt werden, automatisch an die Implementierung des “HelloWorld“-Service weiter geleitet. Abschließend wird die Schnittstelle an die Server-Kom-ponente übergeben. Die Server-Komponente empfängt alle Anfragen der Clientseite undruft den betreffenden Anwendungs-Service über die hier übergebene Schnittstelle auf.

Um einen Anwendungs-Service direkt beim Start der Webanwendung einzuladen, wirddieser in der Startkonfiguration eingetragen. Die Startkonfiguration ist Teil des Konfigu-rations-Service, der als Framework-Service bereit gestellt wird. Um neue Einträge in dieStartkonfiguration vorzunehmen, wird die Funktion __CM_u_setStartConfiguration()des Konfigurations-Managers verwendet. Der Eintrag für den “Hello World“-Service kannwie folgt vorgenommen werden.

$ th i s−>in t e r f a c e_con f i gu ra t i on_se rv i c e−>act i on (array ( "action" => "setStartConfiguration" ,

"service_name" => "hello_world_service" ,"insertplace" => "content" ,"add_menu" => true , "type" => "public" ) ) ;

Diplomarbeit von Benedikt Schwinkendorf

4 Die Umsetzung: Aufbau und Anwendung des Frameworks 35

Dem assoziativen Array wird unter action der Name der aufzurufenden Funktion desKonfigurations-Service übergeben. Dieser Name ist für alle Einträge der Startkonfigu-ration gleich. Im Eintrag service_name wird der Name des zu ladenden Anwendungs-Service übergeben. Der Eintrag insertplace beinhaltet den Platzhalter, an dem derWebservice-Agent auf der Startseite angezeigt werden soll. Mittels add_menu wird übereinen boolschen Wert bestimmt, ob die Namespace-Komponente des Webservice-Agen-ten mit einem Menü versehen werden soll. Für das “Hello World“-Beispiel soll dies derFall sein. Der letzte Wert des Arrays gibt an, um welchen Service-Typen es sich beimangegebenen Anwendungs-Service handelt. Der Service-Typ kann dazu verwendet wer-den, verschiedene Konfigurationen zu unterscheiden. So wird es z.B. in Verbindung miteiner Benutzerverwaltung möglich, angemeldete Benutzer mit einer anderen Startkonfi-guration zu versorgen als unbekannte Benutzer. Für diesen Zweck liefert die Serverseitebereits eine einfache Benutzer-Komponente mit, welche lediglich zwischen unbekanntenund angemeldeten Benutzern unterscheidet. Wird als Wert beim type-Eintrag “public“eingetragen, so wird der entsprechende Anwendungs-Service allen Benutzern angezeigt.Der Wert “private“ behält einen Anwendungs-Service angemeldeten Benutzern vor. Dasbis zu diesem Punkt vorgestellte Beispiel ist nun, mit einem ajaxfähigen Web-Browser,vollständig lauffähig und lädt beim Aufruf der Startseite den “Hello World“-Service au-tomatisch am Platzhalter content ein.

4.2.4 Interaktive Webservice-Agenten durch Ajax-Kommunikation

Damit ein Webservice-Agent auf individuelle Benutzereingaben reagieren kann, ist esdiesem möglich, mit seinem Gegenstück auf der Serverseite zu kommunizieren. Der ent-sprechende Anwendungs-Service auf dem Server kann übertragene Daten auswerten undgegebenenfalls neue Inhalte an den Webservice-Agenten schicken, welche dieser danndem im Web-Browser des Clients direkt anzeigen kann. Der Kommunikations-Servicedes Frameworks erlaubt die Kommunikation mit der Serverseite über einen einfachenFunktionsaufruf der Funktion __CS_p_doRequest().

function __CS_p_doRequest( service_name , act ion , r e c e i v e r ){ . . .

Der erste Parameter bestimmt den Namen des anzusprechenden Anwendungs-Service.Der Parameter action enthält den Funktionsnamen der aufzuführenden Funktion die-ses Services. Dem Funktionsnamen können beliebig viele Parameter folgen, die in derForm name=wert angegeben und durch &-Zeichen getrennt werden. Unter receiver wirdangegeben, welche Javascript-Funktion die Antwort der Serverseite auf der Clientseiteverarbeiten soll. Für das “Hello World“-Beispiel wird die Funktion helloWorld() wieunten angegeben neu definiert, um den Service beim Klick auf dem Hyperlink mit derServerseite kommunizieren zu lassen.

Diplomarbeit von Benedikt Schwinkendorf

4 Die Umsetzung: Aufbau und Anwendung des Frameworks 36

/∗ he l lo_wor ld_serv ice . j s ∗/function hel loWorld ( t ext ) {

__CS_p_doRequest( "hello_world_service" ,"getHelloWorldData&repeat=8&text=" + text ,"__CPS_p_refreshWebserviceAgent" ) ; }

Die Antwort des Server wird im Beispiel direkt an die Funktion __CPS_p_refreshWeb-serviceAgent des Kompositions-Service übergeben. Der Service aktualisiert darauf dieDarstellung des Webservice-Agenten mit den erhaltenen Daten.

Damit die Anfrage überhaupt vom “Hello World“-Service entgegengenommen werdenkann, muss dieser die Funktion action implementieren. Diese wird in der PHP-Klassehello_world_service erstellt und überschreibt wiederum die Standard-Implementie-rung ihrer Eltern-Klasse application_service. Alle Angaben, die beim Aufruf derFunktion __CS_p_doRequest() unter Parameter action angegeben wurden, werden derFunktion action() in Form des Array $values übergeben.

function ac t i on ( $va lues ) {i f ( $va lues [ "action" ] == "getHelloWorldData" ) {

$repeat = $va lues [ "repeat" ] ;$ t e s t = $va lues [ "text" ] ;$ th i s−>html = . . .return $th i s−>createWebserviceAgent ( ) ;

}}

Der “Hello World“-Service überprüft im Beispiel zunächst ob eine bekannte Aktion aus-geführt werden soll. Ist dies der Fall, so liest er die erwarteten Parameter aus demübergebenen Array aus und erstellt anschließend die neue HTML-Beschreibung für denWebservice-Agenten. Die neue aktualisierte Version des Agenten wird wiederum durchAufruf der Funktion createWebserviceAgent() zurückgegeben.

4.3 HTML-Clients unterstützen

Wie in Abschnitt 3.5 - Absicherung: Was, wenn ein Client kein Ajax unterstützt? be-schrieben, gibt es verschieden Gründe warum eine Webanwendung auch ohne Javascriptlauffähig sein sollte. Daher ist es für ein umfangreiches Framework wichtig hierfür ge-eignete Alternativen bereitzustellen. Wie eine Webanwendung, mit dem Framework dervorliegenden Arbeit, auch ohne Ajax-Einsatz aus Teildiensten zusammengesetzt werdenkann erläutern die nächsten Abschnitte.

Diplomarbeit von Benedikt Schwinkendorf

4 Die Umsetzung: Aufbau und Anwendung des Frameworks 37

4.3.1 Serverseitige Client-Simulation mit Framework-Funktionalität

Eine Webanwendung kann, ohne den Einsatz von Javascript, auf der Clientseite nichtdurch das Nachladen von Teildiensten zusammengesetzt werden. Das Framework verfügtdaher über eine serverseitige Client-Simulation, die diese Aufgabe für den Web-Browserdes Clients übernimmt. Die Server-Anwendung bleibt somit auch weiterhin über ihregewohnte Schnittstelle verwendbar und kann ihren Aufbau als Service-Lieferant beibe-halten.

Der simulierte Client, im weiteren Verlauf PHP-Client genannt, kann die aktuelle Dar-stellung einer Webanwendung auf Basis von Teildiensten zusammen setzen. Prinzipiellverhält der PHP-Client sich dabei wie ein normaler Web-Server, der die Anfragen derClientseite entgegen nimmt und die Inhalte der angeforderten Webseite, den überge-benen Parametern entsprechend, generiert. Im Unterschied zu einem normalen Web-Server generiert der PHP-Client sein Inhalte aber nicht selbst, sondern empfängt dieseals Teildienste von der Server-Anwendung. Aus den verschiedenen Teildiensten setztder PHP-Client wiederum eine vollständige Webseite zusammen. Der Web-Browser derClientseite ruft also nicht mehr die in Abschnitt 4.2.1 - Die Startseite als permanen-tes Layout-Grundgerüst beschriebene Startseite auf, sondern kommuniziert nur mit demPHP-Client, um dessen generierte Webseiten direkt zu empfangen.

Damit der PHP-Client die Teildienste des Servers empfangen und verarbeiten kann, setztdieser ebenfalls die vom Framework angebotenen Framework-Services ein. Da serverseitigdie Verwendung von Javascript nicht möglich ist, stellt der Server für diesen Zweckalle Framework-Services als entsprechende PHP-Variante bereit. Aus dem clientseitigenAjax-Framework, wird auf diese Weise ein serverseitiges PHP-Framework, welches aufähnliche Art und Weise nutzbar ist. Der PHP-Client verwendet als Grundlage für dasGenerieren einer Webseite ein HTML-Grundgerüst. Dieses Grundgerüst entspricht mitwenigen Ausnahmen, der normalen Startseite einer Webanwendung. Die Positionen dereingefügten Platzhalter, bestimmen hier genauso die möglichen Bereiche, die für dasEinladen neuer Webservice-Agenten verwendet werden können.

Um nicht bei jeder Anfrage der Clientseite alle Teildienste der Webanwendung erneutvom Server laden zu müssen, verfügt der PHP-Client über einen Zwischenspeicher, derdie Daten aller eingebundenen Services enthält. Der PHP-Client muss dadurch bei jederAnfrage nur noch neue Inhalte beim Server abfragen und diese in den Zwischenspeichereinbinden. Über die im folgenden Beispiel unter dem Platzhalter content angegebeneFunktion __IS_p_showInsertplacecontent() können die HTML-Darstellung der ge-speicherten Services für einen bestimmten Platzhalter aufgerufen werden.

<html><head></head><body>

Diplomarbeit von Benedikt Schwinkendorf

4 Die Umsetzung: Aufbau und Anwendung des Frameworks 38

<span id=" content " style=" po s i t i o n : abso lu t e ;top : 10px ; l e f t : 10px">

<?php/∗ show content f o r t h i s i n s e r t p l a c e ∗/__IS_p_showInsertplaceContent ("content" ) ;

?>

</span></body></html>

Beim Generieren der Webseite werden dadurch alle eingebundenen Services an ihrementsprechenden Platzhalter angezeigt.

4.3.2 Teildienste erweitern für den Einsatz ohne Javascript

Der PHP-Client verfügt, wie oben beschrieben, über dieselben Framework-Services wieeine ajaxfähige Clientseite. Daher können die Framework-Services auch vom PHP-Clientüber ähnliche Schnittstellen- bzw. Funktionsaufrufe angesprochen werden. Möchte dieClientseite nun eine solche Funktion ausführen, so wird diese nicht mehr direkt ausge-führt, sondern zunächst, über einen einfachen HTTP-Request, an den PHP-Client aufder Serverseite gesendet. Der PHP-Client wertet den Request und die darin übergebe-nen Parameter aus und ruft die PHP-Variante der entsprechenden Funktion auf. Umdieses Vorgehen zu unterstützen, muss ein Webservice-Agent so erweitert werden, dassein Funktionsaufruf per HTTP-Request an den PHP-Client gesendet wird, sobald dieentsprechende Funktion nicht über Javascript ausgeführt werden kann. Als Beispiel sollhier wieder der bereits bekannte “Hello World“-Service dienen.

function getWebserviceAgent ( ) {$th i s−>html = '<a class="pagelink"

href="client.php?function=helloWorld&text=Hallo"onclick="helloWorld(\'Hallo\'); return false;">Hallo Welt!</a>' ;

return $th i s−>createWebserviceAgent ( ) ;}

Der Webservice-Agent wird also lediglich beim Attribut href des Hyperlinks erweitert.Über dieses Attribut können alle für einen Funktionsaufruf notwendigen Daten an denPHP-Client übergeben werden. Mehrere Parameter werden dabei über name=wert Zu-weisungen und durch &-Zeichen getrennt angegeben. Unter dem Parameter functionwird festgelegt, welche Service-Funktion der Webanwendung aufgerufen werden soll.

Diplomarbeit von Benedikt Schwinkendorf

4 Die Umsetzung: Aufbau und Anwendung des Frameworks 39

Ist der Webservice-Agent in einem ajaxfähigen Web-Browser eingebunden, so wird zuerstdas angegebene Javascript ausgeführt. Dieses verhindert durch die Angabe von “returnfalse“, dass die Anfrage unter dem Attribut href an den PHP-Client ausgeführt wird.Auf einem Web-Browser der kein Javascript unterstützt, werden die Angaben unter demAttribut onclick hingegen ignoriert und nur der HTTP-Request auf die unter hrefangegebene URL ausgeführt. Somit ist es möglich, einen Webservice-Agenten zugleichfür beide Laufzeit-Umgebungen zu konfigurieren, ohne dass dabei Konflikte auftreten.

Für jede aufzurufende Funktion benötigt der PHP-Client eine entsprechende Imple-mentierung. Die Implementierungen der Framework-Services werden dem PHP-Clientautomatisch bereit gestellt. Individuelle Funktionen der Anwendungs-Services müssenvon diesen selbst implementiert und bereitgestellt werden. Dazu kann ein Anwendungs-Service auf der Serverseite in seinem /lib/-Ordner eine PHP-Datei anbieten, die die Im-plementierung der individuellen Funktionen enthält. Bei Verwendung eines Anwendungs-Service im PHP-Client, wird diese PHP-Datei und die entsprechenden Funktionen au-tomatisch als Teil des jeweiligen Webservice-Agenten eingebunden. Der folgende Quell-code zeigt die PHP-Variante der bereits bekannten Funktion helloWorld() des “HelloWorld“-Service.

/∗ he l lo_wor ld_serv ice . php ∗/function hel loWorld ( $va lues ) {

__CS_p_doRequest( "hello_world_service" ,"getHelloWorldData&repeat=8&text=" . $va lues [ "text" ] ,"__CPS_p_refreshWebserviceAgent" ) ; }

Mehrere Parameter werden, einer über HTTP-Request aufgerufenen Funktion, im asso-ziativen Array $values übergeben. Erwartete Parameter können so über ihren Varia-blennamen aus diesem Array gelesen werden.

4.4 Eine Beispielanwendung: “Student sucht Job . de“

Wie Teildienste einer Webanwendung unter Einsatz des Frameworks prinzipiell erstelltwerden können, wurde in den vorangehenden Abschnitten bereits vorgestellt. Die in die-sem Abschnitt beschriebene Beispielanwendung soll anschaulich darstellen, wie die kon-krete Umsetzung einer Webanwendung mit Hilfe des Framework realisiert werden kann.Als Szenario dient der Anwendung eine Job-Plattform, die das Ausschreiben von Neben-jobs, Praktikas und Angeboten zur Festeinstellungen ermöglicht. Sie bietet Studentendie Möglichkeit offene Stellen zu finden und die entsprechenden Firmen zu kontaktieren.Die Plattform verfügt über eine Benutzerverwaltung, die das Anmelden verschiedenerBenutzer ermöglicht. Angemeldete Benutzer dürfen neue Jobeinträge erstellen und dieDetailansicht einer ausgeschrieben Stelle öffnen.

Diplomarbeit von Benedikt Schwinkendorf

4 Die Umsetzung: Aufbau und Anwendung des Frameworks 40

Für die Startseite der Webanwendung wurden vier Teildienste erstellt, die über denKonfigurations-Service beim Aufruf der Plattform direkt nachgeladen und angezeigtwerden. Ein einfaches Navigationsmenü, eine Schnellsuche, die Ansicht der fünf zuletzteingetragenen Stellen und eine Möglichkeit zur Benutzeranmeldung. Die Startseite ent-hält neben den entsprechenden Platzhaltern das Logo der Job-Plattform als permanentenstatischen Inhalt. Abbildung 4.2 zeigt die Teildienste der Startseite beim ersten Aufrufder Beispielanwendung.

Abbildung 4.2: Die Teildienste der Startseite beim ersten Aufruf der Beispielanwendung

Nur der Teildienst, der die fünf aktuellsten Stellen darstellt (im Folgenden Stellen-Service genannt), verwendet das vom Framework angebotene Menü. Alle anderen Ser-vices wurden so konfiguriert, dass Sie lediglich die Inhalte ihres Webservice-Agentenanzeigen. Beim betrachten des Menüs kann man erkennen, dass der Stellen-Service dieFramework-Services für automatische Updates (Update-Service) und automatisches Log-ging (Monitoring-Service) verwendet. Diese binden jeweils einen eigenen Button und eineeigene Service-Ansicht über den Kompositions-Service in das Menü und die entsprechen-de Namespace-Komponente ein.

Durch Klicken auf das Uhr-Icon, welches den Button des Update-Service visualisiert,kann die Konfigurations-Ansicht des Update-Service geöffnet werden. Dort hat ein Be-nutzer die Möglichkeit das automatische Updaten des Webservice-Agenten zu aktivieren.Die Standardeinstellung des Update-Intervalls beträgt 10 Sekunden. Dieser Wert kannüber das dargestellte Textfeld beliebig verändert werden. Ein Klick auf das Uhr-Iconneben dem Textfeld startet das automatische Updaten. Besteht im Hintergrund eine

Diplomarbeit von Benedikt Schwinkendorf

4 Die Umsetzung: Aufbau und Anwendung des Frameworks 41

aktive Kommunikations-Verbindung mit dem Server, so erscheint im Menü des Stellen-Service zusätzlich das Lade-Icon. Abbildung 4.3 zeigt die Konfigurations-Ansicht desUpdate-Service bei aktiver Kommunikations-Verbindung.

Abbildung 4.3: Die Konfigurations-Ansicht des Update-Service bei aktiverKommunikations-Verbindung

Der Login-Service im rechten oberen Bereich der Startseite bietet die Möglichkeit, einenBenutzer über Name und entsprechendes Passwort bei der Webanwendung anzumel-den. Dazu sendet der Webservice-Agent eingegebene Benutzerdaten über die Funkti-on __CS_p_doRequest() des Kommunikations-Service an seinen Anwendungs-Serviceauf der Serverseite. Das Drücken des Login-Buttons löst dabei zunächst die FunktionstartLogin() aus, welche die Überprüfung der Eingabedaten bereits auf der Clientsei-te durchführt. Bei fehlenden Eingaben wird die Funktion __CS_p_doRequest() nichtausgeführt, sondern ein entsprechendes Hinweis-Fenster eingeblendet. Beim Aufruf derFunktion __CS_p_doRequest() wird, als clientseitiger Empfänger der Rückgabedaten,die Funktion checkLoginData() angegeben. Diese überprüft ob die Anmeldung desBenutzers erfolgreich war. Ist dies der Fall, so wird die Startkonfiguration für den be-treffenden Benutzer geladen.

/∗ l o g i n_se rv i c e . j s ∗/function s t a r tLog in ( ) {

i f ( document . login_form . login_name . va lue == "" ) {alert ("Geben Sie bitte Ihren Loginamen ein" ) ;document . login_form . login_name . f o cu s ( ) ;return f a l s e ;

}i f ( document . login_form . login_password . va lue == "" ) {

alert ("Geben Sie bitte Ihr Passwort ein" ) ;document . login_form . login_password . f o cu s ( ) ;return f a l s e ;

}/∗ Cal l app l i c a t i on−s e r v i c e ∗/__CS_p_doRequest(

Diplomarbeit von Benedikt Schwinkendorf

4 Die Umsetzung: Aufbau und Anwendung des Frameworks 42

'login_service' ,'startLogin&user=' +

document . login_form . login_name . va lue +'&password=' +

document . login_form . login_password . value ,'checkLoginData'

) ;}function checkLoginData ( webservice_agent ) {

/∗ Check l o g i n su c c e s s ∗/i f ( webservice_agent . l og in_succe s s == true ) {

/∗ Load s t a r t c on f i g u r a t i on f o r the user ∗/__SCS_p_loadStartConfiguration ( ) ;

}else {

/∗ Refresh Webservice−Agent ∗/__CPS_p_refreshWebserviceAgent ( webservice_agent ) ;

}}

Nach dem erfolgreichem Login verändert sich die Webanwendung automatisch an ver-schiedenen Stellen, da der Benutzer nun über erweiterte Rechte verfügt und dessen er-weiterte Startkonfiguration geladen wird. Zum einen wird die Navigation um zusätzlichePunkte erweitert. Hier kann nun über den Link “Die 5 neuesten Jobs“ der Stellen-Serviceaufgerufen bzw. aktualisiert werden. Der Login-Service zeigt nicht mehr die Felder zurEingabe der Benutzerdaten an, sondern den Namen des angemeldeten Benutzers. DerStellen-Service verfügt nun über Hyperlinks mit der Bezeichnung “Details“ hinter je-dem Eintrag. Über diese kann der Benutzer die Detailansicht einer Stelle aufrufen. Aufder rechten Seite der Webanwendung wurde eine weiterer Navigations-Service sowie einKalender-Service eingefügt. Die neue Navigation ermöglicht über den Link “Neuen Jobeintragen“ den Aufruf einer Eingabemaske, die es erlaubt neue Stellen anzulegen. Abbil-dung 4.4 zeigt alle hinzugefügten Services mit der Job-Detailansicht und der Eingabe-maske für neue Stellen.

Der Subscriber-Service des Frameworks wird in der Beispielanwendung unter anderembeim Erstellen neuer Job-Einträge verwendet. Der Eintrags-Service, der durch die Ein-gabemaske dargestellt wird, verfügt über die Funktion newEntryNotifier(). Die Stan-dard-Implementierung der Funktion, blendet ein Hinweis-Fenster mit einer Erfolgsnach-richt ein. Der Eintrags-Service ruft newEntryNotifier() auf, sobald er vom Server dieNachricht bekommen hat das ein zum Speichern übergebener Job-Eintrag erfolgreichangelegt wurde. Der Stellen-Service soll über das Speichern neuer Einträge informiertwerden und ist deshalb als Subscriber auf diese Funktion eingetragen.

Diplomarbeit von Benedikt Schwinkendorf

4 Die Umsetzung: Aufbau und Anwendung des Frameworks 43

Abbildung 4.4: Die Startseite der Webanwendung nach erfolgreicher Benutzeranmeldung

Da jede Namespace-Komponente nur die Komponenten kennt, die sie selbst enthält,wissen Eintrags-Service und der Stellen-Service nichts von ihrer gegenseitigen Existenzinnerhalb der Webanwendung. Das Subscriben muss daher von einem Namespace erle-digt werden der beide zu verbindenden Komponenten kennt. In diesem Fall trifft dasauf die Startseite der Webanwendung zu, die das Subscriben innerhalb ihres Init-Servicein der Funktion __IS_u_userConfig() übernimmt. Das Subscriben auf eine Funktionwird über den Aufruf von __IS_p_subscribeFunction() realisiert. Diesem werden alsEingabeparameter zuerst der Namespace des anbietenden Services, dann der Funktions-name inklusive eventueller Parameter der zu subscribenden Funktion und schließlich derNamespace des Subscribers übergeben.

function __IS_u_userConfig ( ) {/∗ Subscr ibe f unc t i on s ∗/__IS_p_subscribeFunction (

'http://.../services/application/new_job_service' ,'newEntryNotifier()' ,'http://.../services/application/

latest_jobs_service') ;

}

Diplomarbeit von Benedikt Schwinkendorf

4 Die Umsetzung: Aufbau und Anwendung des Frameworks 44

Der Stellen-Service muss als Subscriber über eine eigene Version der Funktion newEntry-Notifier() verfügen. Diese wird durch das Subscriben vom Eintrags-Service anstelle derStandard-Implementierung aufgerufen. Dadurch wird es dem Stellen-Service möglich,sich nach dem Speichern direkt über den Update-Service zu aktualisieren.

Abbildung 4.5: Aufgezeichnete Ereignisse des Monitoring-Service

Der Monitoring-Service wird über jede Aktualisierung automatisch benachrichtigt. Überdie Ereignis-Ansicht (Abbildung 4.5) können alle an diesen Framework-Service gesende-ten Benachrichtigungen eingeblendet werden.

Diplomarbeit von Benedikt Schwinkendorf

5 Abgrenzung zu alternativen Ajax-Frameworks 45

5 Abgrenzung zu alternativen Ajax-Frameworks

In diesem Kapitel werden fünf der bekanntesten clientseitigen Ajax-Frameworks vorge-stellt. Sie zeigen auf, wie groß die Unterschiede in Zielsetzung und Funktionsumfang derverschiedenen Javascript-Bibliotheken sein können. Neben der clientseitigen Ausführungder Frameworks, galt als weiteres Auswahlkriterium deren kostenlose Nutzung, da auchdie vorliegende Arbeit in diesen Bereich als Open-Source-Software (Framework 2.020)angeboten wird.

5.1 Prototype aus dem “Ruby-on-Rails“-Projekt

Prototype21 stammt aus dem “Ruby-on-Rails“-Projekt und stellt eine objektorientierteZusammenstellung von Javascript-Bibliotheken dar. Diese sind zum Zwecke der einfachenNutzung in einer Javascript-Datei (prototype.js) zusammengefasst. Prototype wird ineinigen anderen Ajax-Frameworks als Basis für den Einsatz von Ajax-Kommunikationverwendet. Darunter auch die im weiteren Verlauf des Kapitels vorgestellten FrameworksScriptaculous und Rico.

Prototype stellt ein Ajax-Objekt zur Verfügung, das auf verschiedenen Javascript-Erwei-terungen basiert. Darunter z.B. Erweiterungen für die Javascript-Kernklassen Number,String und Array, eine Enumerable-Klasse sowie ein Hash-Objekt. Zusätzlich gibt es dieObjekte Form und Field die zur Manipulation von Formularen und Feldern genutzt wer-den können. Das Framework führt, neben weiteren Funktionen zur DOM-Manipulation,für den Aufruf der DOM-Funktion von document.getElementById() die Kurzfassung$() ein. Schließlich erlaubt es über Funktionsobjekte das Binden von Funktionen an einObjekt.

Das mittels Prototype generierte Ajax-Objekt stellt fünf verschiedene Klassen bereit,die zum Absetzen und Verarbeiten von HTTP-Requests verwendet werden können.

• Ajax.Base

• Ajax.Request

• Ajax.Updater

• Ajax.PeriodicalUpdater

• Ajax.Responders

20https://sourceforge.net/projects/framework20/21http://www.prototypejs.org/

Diplomarbeit von Benedikt Schwinkendorf

5 Abgrenzung zu alternativen Ajax-Frameworks 46

Ajax.Base wird dabei als Basis von den anderen Klassen des Ajax-Objekts verwen-det. In Ajax.Request und Ajax.Updater kapselt die Prototype-Bibliothek ihre gesamteAufruf-Logik, einschließlich der browser-abhängigen Komponenten eines Requests. Mit-tels Ajax.PeriodicalUpdater können in bestimmten Intervallen Ajax.Updater -Request ab-gesetzt werden. Über Ajax.Responders können globale Event-Handler registriert werden,die verschiedene Ajax-spezifische Ereignisse, wie z.B. onComplete abfangen können.

Ajax.Request wird in allen Klassen verwendet, die tatsächlichen Ajax-Funktionsumfangnutzen. Dem Konstruktor werden als Parameter zuerst eine URL und als zweites einoptions-Objekt übergeben. Dieses Objekt muss einer vorgegebenen Syntax entsprechenund kann verschiedene Werte wie z.B. method, postBody, onSuccess, onFailure oderonException enthalten. Die Übergabe des options-Objekt ist dabei optional, da es füralle möglichen Werte bereits Default-Einstellungen gibt. Diese werden mit der Angabedes options-Objekt entsprechend überschrieben. Unter onSuccess kann eine individuelleFunktion angegeben werden, die sich um die Antwort des Request kümmert.

Ajax.Updater kann dazu verwendet werden, bestimmte Bereiche einer Webanwendungdirekt zu aktualisieren. Dafür wird der Updater-Klasse im Konstruktor, neben der URLund dem optionalen options-Objekt zusätzlich ein Container übergeben. Dies kann ent-weder die ID eines vorhandenen HTML-Elements oder das DOM-Objekt des entspre-chenden HTML-Elements selbst sein. Der Wert der Option postBody, in dem das erwar-tete Format des Response angegeben werden kann, wird dazu auf mimeType=text/htmlgesetzt. Nach erfolgreichem Empfang des HTML-Codes, wird der vorhandene HTML-Code des angegebenen Containers automatisch mit dem neuen Quellcode ersetzt.

5.2 Die Open Source Javascript-Bibliothek Rico

Rico ist laut Aussage der eigenen Webseite22, eine Javascript-Bibliothek um reichhalti-ge Webanwendungen zu erstellen. Weiter wird volle Ajax-Unterstützung sowie die Drag& Drop-Management und eine “Cinematic Effect“-Bibliothek angepriesen. Der genannteFunktionsumfang des Frameworks lässt bereits vermuten, dass ein Großteil der Funktio-nen keine Ajax-Technologie verwendet.

Wie im vorausgehenden Abschnitt erwähnt setzt Rico das Prototype-Framework alsBasis für seine Ajax-Kommunikation ein. Hier stellt sich nun die Frage wo die Unter-schiede im Vergleich zu Prototype bei der Handhabung von Ajax-Requests liegen. Ricokapselt sein Ajax-Funktionen in dem Objekt ajaxEngine. Dieses steht beim verwen-den der Bibliothek in einer Webseite automatisch zur Verfügung. Über die FunktionregisterRequest() werden vorab alle URIs mit einer zugehörigen ID registriert, anwelche im weiteren Verlauf ein Request gesendet werden soll. Über die angegeben IDkönnen die entsprechenden Requests dann mit der Funktion sendRequest() ausgelöst

22http://www.openrico.org/

Diplomarbeit von Benedikt Schwinkendorf

5 Abgrenzung zu alternativen Ajax-Frameworks 47

werden. Diese kann neben der beim registrieren angegebenen ID, im zweiten Parame-ter optionale Werte empfangen, welche dem HTTP-Request dann als CGI-Parameterangehängt werden.

Rico erwartet vom Response eines Webservices ein spezielles Datenformat in XML-Syntax. Das Wurzel-Element der Antwort muss den Tag-Namen ajax-response enthal-ten. Darunter können sich mehrere mit response bezeichnete Elemente befinden. Dieseenthalten wiederum zwei Attribute, type und id. Innerhalb eines Response-Elements kannbeliebiger, aber wohlgeformter XHTML-Code enthalten sein. Wurde im Type-Attributder Wert element übergeben, so ersetzt Rico den HTML-Code eines HTML-Elementsdirekt mit dem HTML-Code der Antwort. Die ID des betreffenden Elements, wird un-ter dem Attribut id angegebenen. Zuvor muss das Element aber, unter Angabe derID, mit der Funktion registerAjaxElement() registriert werden, damit Rico desseninnerHTML-Eigenschaft modifizieren kann.

Als Alternative kann anstelle des Typs element auch der Typ object im Attribut einesResponse-Elements angegeben werden. Rico übernimmt die Auswertung der Response-Nachricht dann nicht mehr selbst, sondern ruft die Funktion ajaxUpdate() auf demdurch die angegebene ID identifizierten Objekt auf. Die Response-Nachricht darf dabeikeinen HTML-Code mehr enthalten sondern besteht aus reinen XML-Inhalten. Diesekann dann in Verantwortung des Programmierers über die jeweilige Objekt-FunktionajaxUpdate() ausgewertet und entsprechend auf die Webseite eingebunden werden. Ricoerlaubt es auch, mehrere Response-Elemente mit unterschiedlichen Typenangaben ineiner Ajax-Response zu verarbeiten.

5.3 Scriptaculous: Neue DHTML-Anwendungen durchAjax-Einsatz

Scriptaculous23 verwendet ebenfalls das Prototype-Framework für seinen Ajax-Funkti-onsumfang. Die Zielsetzung dieses Frameworks liegt aber in der Umsetzung clientsei-tiger Funktionalität, wie DHTML-Effekte, -Widgets und -Controls. Scriptaculous bie-tet mehrere interessante Funktionen dieser Art, die aber in der Regel ohne Ajax-Ein-satz auskommen. Anders ist dies beim den bereitgestellten Klassen Ajax.Autocompleter,Ajax.InPlaceEditor sowie Ajax.InPlaceCollectionEditor.

Wie bereits der Name vermuten lässt, kann Ajax.Autocompleter dazu verwendet werden,Eingaben in Textfeldern zu vervollständigen. Die entsprechenden Wortlisten für eineVervollständigung bezieht Scriptaculous per Ajax-Kommunikation direkt bei der Einga-be. Der Server wird dabei erst nach der Eingabe einer bestimmten Anzahl an Zeichenangesprochen, damit die übertragenen Wortlisten einen entsprechend geringen Umfang

23http://script.aculo.us/

Diplomarbeit von Benedikt Schwinkendorf

5 Abgrenzung zu alternativen Ajax-Frameworks 48

besitzen. Die beiden Editor -Klassen bieten die Möglichkeit, Elemente einer Webseite zueditieren und getätigte Änderungen an einen Webservice zu senden. Die Verarbeitung derentsprechenden Daten liegt dabei beim Entwickler des angesprochenen Webservices.

Scriptaculous kann daher nicht zwingend als Ajax-Framework bezeichnet werden. Viel-mehr abstrahiert es von der direkten Ajax-Nutzung. Es stellt neue Anwendungen fürdie Webentwicklung bereit, die Ajax-Technologie (hier realisiert durch Prototype) imHintergrund verwenden. Dies geschieht für einen Anwender des Frameworks versteckt ineiner tieferen Ebene der angebotenen Komponenten.

5.4 MochiKit: Eine leichtgewichtige Javascript-Bibliothek

MochiKit wird auf der Webseite24 als leichtgewichtige Javascript-Bibliothek beschrieben.Die Bibliothek besitzt unter anderem verschiedene Klassen für visuelle Effekte, DOM-Manipulation, Drag & Drop, Event-Handling sowie CSS-Manipulation.

Zur asynchronen Kommunikation stellt das Framework die Klasse MochiKit.Async zurVerfügung. Deren Funktionsumfang ist von der Python-Bibliothek mit dem Namen“Twistet“ inspiriert. Dabei wird die Klasse Deffered (zu deutsch “verzögert“) als Ba-sis der asynchronen Kommunikation verwendet. Ein Objekt dieser Klasse kann entwederdirekt erzeugt und verwendet werden oder ist Rückgabewert beim Aufruf der FunktiondoSimpleXMLHttpRequest(). Der Funktion werden dabei zwei Parameter übergeben.Die URI des Webservice und ein options-Objekt. Welche Funktion die Verarbeitung desResponse übernehmen soll, kann über das Deffered -Objekt festgelegt werden. Dies kannüber die Zuweisung einer Callback-Funktion, durch den Aufruf von addCallback(), auchnachträglich geschehen. Eine Funktion, die im Fehlerfall aufgerufen wird, kann ebenfallsnachträglich über addErrback() bestimmt werden.

Durch zuweisen mehrerer Callback-Funktionen auf ein Deffered-Objekt, bietet MochiKitdie Möglichkeit Callback-Chains zu verarbeiten. So kann die Response eines Webser-vice von mehreren verschiedenen Funktionen verarbeitet werden. Hierbei können durchRückgabe eines weiteren Deffered-Objektes als Response eines Webservices auch tiefereVerkettungen abgearbeitet werden. So können z.B. Requests abgesetzt werden die inAbhängigkeit von weiteren Request stehen.

24http://www.mochikit.com/

Diplomarbeit von Benedikt Schwinkendorf

5 Abgrenzung zu alternativen Ajax-Frameworks 49

5.5 Das auf XML basierende Ajax-Framework Spry

Das letzte Ajax-Framework, das hier vorgestellt werden soll ist Spry von Adobe25. Diesesverwendet als Grundlage Googles Javascript-Implementierung von XPath26.

Den Kern von Sprys Ajax-Funktionsumfang bilden XML Data Sets und Dynamic Regi-ons. Wobei das XMLDataSet-Objekt verwendet wird um die auf dem Server verfügbarenXML-Daten zu handhaben. Dabei wandelt Spry die XML-Daten in Zeilen und Spalten,so dass diese auf einer Ebene ohne Verschachtelung verarbeitet werden können. DerKonstruktor des XMLDataSet-Objekts erwartet die Übergabe von zwei Parametern.Die URL des Webservice und den XPath als Verweis auf die benötigten Daten. Optionalkönnen im dritten Parameter weitere Einstellungen für den HTTP-Requests festgelegtwerden.

Mit der Angabe des XPath wird festgelegt, welche Teile einer XML-Datei angefordertwerden sollen. Dabei werden als Response alle Inhalte zurückgeliefert die auf dieses Kri-terium zutreffen. Wird z.B. als XPath /root/element angegeben so enthält die Antwortalle Elemente, die Kind-Element von root sind und den Namen element tragen. Gibt esdrei solcher Elemente, enthält das entsprechende Data Set drei Zeilen und eine Spalte.Als Spaltenbezeichnung wird dabei der entsprechende Element-Name verwendet. Enthältein angefragtes Element zudem weitere Attribute, so werden diese als weitere Spaltenhinzugefügt. Als Bezeichnung der Spalte wird hierbei der Attributname mit vorange-stellten @-Zeichen verwendet. Tabelle 5.1 zeigt den Aufbau des XML Data Set für eindreimal vorhandenes XML-Element mit einem Attribut.

elementname @attributZeile 1 Elementinhalt AttributwertZeile 2 Elementinhalt AttributwertZeile 3 Elementinhalt Attributwert

Tabelle 5.1: Beispielhafter Aufbau eines XML Data Set in Spry

Um empfangene Inhalte im DOM-Modell der Webseite darzustellen werden die Dyna-mic Regions benötigt. Diese geben an, an welchen Stellen der Webseite nachgelade-ne Inhalte eingefügt werden sollen. Dafür verwendet Spry spezielle Spry-Attribute, diein den HTML-Code einer Webseite eingetragen werden. So wird z.B. über den Ein-trag spry:region=“regionName“ in einem Div -Element eine neue Dynamic Region er-stellt.

25http://labs.adobe.com/technologies/spry/26http://www.w3.org/TR/xpath20/

Diplomarbeit von Benedikt Schwinkendorf

5 Abgrenzung zu alternativen Ajax-Frameworks 50

5.6 Diskussion: Ein Vergleich, Vor- und Nachteile

Prototype stellt sich als ausgereifte und stabile Javascript-Bibliothek heraus, die nichtzuletzt daher auch von anderen Frameworks als die Basis für Ajax-Kommunikationverwendet wird. Auch durch seine verschiedenen Erweiterungen, die die Handhabungfür das Absenden und Verarbeiten von asynchronen HTTP-Requests erleichtern undbrowser-unabhängig abbilden, kann das Framework vielseitig genutzt werden. Im direk-ten Vergleich zur vorliegenden Arbeit lassen sich einige Gemeinsamkeiten feststellen. Sobieten beide Frameworks das Handling von Ajax-Requests im Hintergrund über einfachanzuwendende Funktionen an. Es stehen in beiden Arbeiten Funktionen für einfachesUpdate oder automatische, in bestimmten Abständen ablaufende Aktualisierungen zurVerfügung. Wobei das Framework dieser Arbeit vor einem Update zunächst ermittelt, obüberhaupt neue Daten zur Darstellung vorhanden sind und somit das Nachladen bereitsbekannter Inhalte verhindert.

Rico erleichtert die bereits einfache Handhabung des Prototype-Frameworks noch wei-ter. Durch die globale Anwesenheit der ajaxEngine können jederzeit asynchrone HTTP-Request abgesetzt werden, ohne zuvor ein entsprechendes Objekt erstellen zu müssen. Indiesem Punkt gleicht es auch dem in diese Arbeit vorgestellten Framework. Alle dort ent-haltenen Framework-Dienste können permanent und direkt angewendet werden. Auchdie Formate der Antwortnachrichten werden bei beiden Anwendungen in einem speziellenFormat erwartet. Während Rico auf ein vorgegebenes XML-Format setzt, erwartet dasAjax-Framework dieser Arbeit einen Webservice-Agenten als assoziatives Array, welchesim JSON-Format übertragen wird. Über den Kommunikations-Service der vorliegendenArbeit ist es zudem möglich, beliebige Daten im JSON-Format zu empfangen, solangediese über die Javascript-Funktion eval() in ein Javascript-Objekt gewandelt werdenkönnen.

Die von Scriptaculous angebotenen Anwendungen in Form von DHML-Effekten, -Controlsund -Widgets, sind in ähnlicher Weise auch über die in Abschnitt 2.3.2 - Teildienste an-bieten und verknüpfen: Beispiel Feeds und Mashups vorgestellten Teildienste möglich.Ein Anwendungs-Service des Servers kann prinzipiell jede beliebige Funktionalität er-füllen und ist durch den komponenten-orientierten Aufbau der Serverseite für andereWebanwendungen mit geringem Konfigurationsaufwand wiederverwendbar.

Das MochiKit kann mit interessanten Funktionen aufwarten, wovon die attraktivstewohl das Ausführen verketteter Anfragen über Callback-Chains darstellt. Kein anderes,der in diesem Kapitel vorgestellten Frameworks, kann mit einem vergleichbaren Featureaufwarten. Über einfache Funktionen können wie bei der Kommunikation mit Proto-type asynchrone HTTP-Requests ausgelöst werden. Über die Funktion addErrback()und addCallback() können eigene Funktionen ausgewählt werden, die das Abarbeiteneiner Response-Nachricht übernehmen. Hier gleicht das Framework wiederum der vor-liegenden Arbeit, die es ermöglicht beliebige Empfänger für einen abgesetzten Response

Diplomarbeit von Benedikt Schwinkendorf

5 Abgrenzung zu alternativen Ajax-Frameworks 51

festzulegen. Ein Nachteil des MochiKit liegt darin, dass mit der aktuellen Version derJavascript-Datei MochiKit.js alle 14 vorhandenen Bibliotheken eingebunden werden, ob-wohl in der Regel nur ein Bruchteil dieser von einer Webanwendung aktiv verwendetwird.

Als letzter Vertreter der vorgestellten Frameworks setzt Spry und deren Entwickler vonAdobe auf eine Lösung, die sich durch den Einsatz von XPath, XML Data Sets sowieDynamic Regions stark von den anderen Frameworks unterscheidet. Durch die Um-wandlung der empfangenen XML-Daten in eine zweidimensionale Schicht wird es demSpry-Framework möglich, jeden Webservice zu nutzen der XML ausliefert. Zudem bietetSpry eine umfangreiche Widget- und Effekte-Bibliothek. Ob sich dieser eher ungewohnteAnsatz der Webentwicklung allerdings in der Breite durchsetzen wird, bleibt abzuwar-ten. Zu vermuten ist jedoch, dass es verschiedenen Anwendungen geben wird, die auf diespeziellen Möglichkeiten des Frameworks, wie z.B. ein xsl:choose-ähnliches Konstrukt,Oberserver für Regionen sowie die Behandlung von abhängigen Daten (Master/Detail)bevorzugt zurückgreifen werden.

Diplomarbeit von Benedikt Schwinkendorf

6 Zusammenfassung und Ausblick 52

6 Zusammenfassung und Ausblick

6.1 Resultate der Arbeit

Das Ziel ein clientseitiges Ajax-Framework zu schaffen, welches die Möglichkeit bieteteine Webseite auf Basis von Teildiensten zu erstellen, wurde erreicht. Teildienste kön-nen mit Hilfe des Frameworks in Form von Webservice-Agenten von der Serverseiteempfangen werden. Im nächsten Schritt ist es möglich, empfangene Webservice-Agentenkomponenten-orientiert auf der entsprechenden Webseite einzubinden. Dabei wird jederWebservice-Agent Teilkomponente einer individuellen Komponenten-Komposition dieals Namespace fungiert. Namespaces (Abschnitt 3.4.2 - Namespaces als Basis für client-seitigen Komponentenanteil) sind dabei voneinander unabhängige, abgeschlossene Um-gebungen einer Webseite, in denen der jeweils eingebundene Webservice-Agent ungestörtseinen Funktionsumfang bereitstellen kann. Dies hat den Vorteil, dass jeder Webservice-Agent inklusive der verwendeten Javascript-Programme und CSS-Styles nur innerhalbseines individuellen Namespace existiert, ohne dabei andere Teildienste einer Webseitezu beeinflussen. Zudem wird es durch die Namespaces möglich, Teildienste mit nur wenigAufwand auch auf fremden Webanwendungen einzubinden. Durch ein Subscriber-Modell(Abschnitt 3.4.3 - Clientseitige Komponenten-Verbindungen per Subscriber-Modell) undden entsprechenden Framework-Service wird es möglich, unabhängige Namespaces unddie darin enthaltenen Teildienste miteinander kommunizieren zu lassen. So kann z.B.die Nachricht über das erfolgreiche Speichern eines Datensatzes von einem Teildienst aneinen anderen Teildienst kommuniziert werden und dort das Ausführen einer entspre-chenden Datenverarbeitung auslösen.

Das Framework bietet seine Framework-Services ebenfalls in Form von Teildiensten an.Diese können bei Bedarf separat in einen Namespace eingebunden werden. Framework-Services können auf diese Weise auch nachträglich von einem Webservice-Agenten ange-fordert werden, wenn sich der entsprechende Bedarf z.B. erst im Laufe der Anwendungoder durch bestimmte Benutzereingaben ergibt. Jeder Namespace verwendet dadurchimmer nur so viele Framework-Services wie nötig sind, um die angebotenen Dienstedes enthaltenen Webservice-Agenten erfüllen zu können. Ein eingebundener Framework-Service ist immer direkt verfügbar, so dass dessen Funktionen unmittelbar aufgerufenwerden können, ohne zuvor bestimmte Service-Objekte erstellen zu müssen.

Im Vergleich mit bekannten alternativen Ajax-Frameworks, kann das Framework meistmit ähnlichen und teilweise umfangreicheren Features aufwarten. So können beispielswei-se browser-unabhängig asynchrone HTTP-Requests abgesetzt werden, deren Response-Nachrichten von beliebigen Funktion abgearbeitet werden können. Als Datenformat fürdie Kommunikation mit einem Webservice wird JSON verwendet. Dies hat den Vorteil,dass empfangene Daten automatisch in Javascript native Objekte wie Array, String oderNumber gewandelt und sofort weiterverarbeitet werden können. Der Update-Service des

Diplomarbeit von Benedikt Schwinkendorf

6 Zusammenfassung und Ausblick 53

Frameworks ermöglicht es einen Teildienst direkt zu aktualisieren. Zudem kann dieserFramework-Service genutzt werden, um die automatische Aktualisierung eines Teildiens-tes in bestimmten Intervallen auszulösen. Wird das optionale Menü für einen Teildienstverwendet, kann die automatische Aktualisierung auch direkt vom Benutzer konfiguriert,gestartet und beendet werden.

Ein weiterer interessanter Punkt, der von den vorgestellten alternativen Frameworksaußer Acht gelassen wurde, ist die Lauffähigkeit einer Webanwendung, wenn der Web-Browser eines Benutzer keine Javascript-Unterstützung bietet. Das Framework der vor-liegenden Arbeit bietet eine relativ einfache Möglichkeit, eine Webanwendung auch ohneJavascript zu realisieren und dabei deren Aufbau aus verschiedenen Teildiensten beizu-behalten. Möglich wird dies durch eine serverseitige Client-Simulation, welche die imNormalfall auf dem Client stattfindenden Vorgänge auf der Serverseite abbildet.

Als Kritikpunkt kann angebracht werden, dass es bei den direkten und automatischenAktualisierungen des Update-Service nicht möglich ist, Inhalte nur an bestimmten Platz-haltern einzufügen. Das Framework sieht hingegen vor, immer den gesamten Inhaltder entsprechenden Teildienste zu aktualisieren. Dies kann gegebenenfalls dazu führen,dass clientseitige Zustände wie z.B. Eingaben in Textfeldern oder die Auswahl einerDropDown-Box durch die Aktualisierung verloren gehen. Um diesen Effekt zu verhin-dern, hat ein Programmierer über das Framework jedoch die Möglichkeit, empfangeneDaten in einer von ihm bestimmten Empfänger-Funktion selbst zu verarbeiten. In die-ser können DOM-Aktualisierungen manuell und ohne die Beeinflussung clientseitigerZustände vorgenommen werden.

Webanwendungen auf Basis von Teildiensten zu erstellen, erweist sich bei der eigentli-chen Programmierung als hilfreich. Eine Webanwendung bekommt durch diesen Ansatzbereits beim Entwurf klare Strukturen. Es wird überlegt welche Funktionen einer We-banwendung zusammengehörig sind und wo die Grenzen verschiedener Funktionsberei-che liegen. Jeder Funktionsbereich wird dabei zu einem Teildienst der Webanwendung,welcher nahezu unabhängig von anderen Teildiensten entwickelt werden kann. Darausresultieren mehrere Vorteile. Zum Beispiel kann sich ein Programmierer bei der Ent-wicklung voll auf die Umsetzung eines einzigen Teildienstes konzentrieren, ohne dabeiKenntnis der gesamten Webanwendung besitzen zu müssen. Bei der Realisierung größe-rer Projekte können Aufgaben in Form von Teildiensten an verschiedene Programmiererübergeben werden, was z.B. verteilte Entwicklung vereinfacht. Darüber hinaus werdenTeildienste automatisch so unabhängig entwickelt, dass diese einfach für neue Projektewiederverwendet werden können.

Diplomarbeit von Benedikt Schwinkendorf

6 Zusammenfassung und Ausblick 54

6.2 Perspektiven

Das Framework der vorliegenden Arbeit kann auf viele verschiedene Weisen zum Einsatzkommen. Es ermöglicht z.B. das Erstellen vollständiger Webanwendungen auf Basis vonTeildiensten oder das Einbinden neuer Teildienste in eine bereits bestehende Webanwen-dung. Weitere Applikationen können es als Basis für Ajax-Kommunikation verwendenoder andere Features des Frameworks wie z.B. den Monitoring-Service einsetzen. Durchdas einfache Einbinden vorhandener Teildienste auf fremden Webseiten, wäre auch einEinsatz als Widget-Bibliothek denkbar, die eine Vielzahl verschiedener Dienste bereit-stellt.

Um die individuelle Aktualisierung bestimmter Elemente einer Webanwendung oder ei-nes Webservice-Agenten besser zu unterstützen, wäre die Erweiterung des Frameworksim Bereich Update-Service um zusätzliche Helfer-Funktionen denkbar, die die Manipu-lation des DOM-Modells erleichtern. Der Kommunikations-Service könnte um die ausdem MochiKit bekannten Callback-Chains erweitert werden. So wird es möglich dieResponse-Nachricht eines Services von mehreren Funktionen nacheinander abarbeitenzu lassen. Dadurch könnten Response-Nachrichten auch mit Daten für mehrere Teil-dienste ausgestattet werden um z.B. die Anzahl der auszuführenden HTTP-Requestszu verringern. Zudem könnte diese Technik mit einer Polling-Funktion verbunden wer-den, die in bestimmten Intervallen regelmäßig neue Nachrichten empfängt. Dann wärees möglich über diese “dauerhafte Verbindung“ vom Server simulierte Ereignissteuerungzu betreiben, die sich auf einen oder mehrere eingebundene Teildienste beziehen kann.

Prinzipiell eröffnen sich durch den Einsatz von Ajax-Technologie völlig neue Wege undFreiheiten beim gestalten und programmieren vom Webanwendungen. Das Frameworkbietet hierfür eine solide Grundlage die es, durch die Anwendung von Komponenten-Ori-entierung, erlaubt Webanwendungen einfach und strukturiert umzusetzen. Der Einsatzvon Webservice-Agenten unterstützt darüber hinaus die Möglichkeit beliebige clientsei-tige Funktionalitäten umzusetzen.

Diplomarbeit von Benedikt Schwinkendorf

Literatur 55

Literatur

[Boa06] RSS Advisory Board. RSS 2.0 Specification, August 2006.http://www.rssboard.org/rss-specification [2007-01-30].

[FGM+99] R. Fielding, J. Gettys, J. Mogul, H. Frystyk, L. Masinter, P. Leach, andT. Berners-Lee. RFC 2616: Hypertext Transfer Protocol – HTTP/1.1, Juni1999. http://tools.ietf.org/html/rfc2616 [2007-01-30].

[Gar05] J. J. Garrett. Ajax: A New Approach to Web Applications, Februar 18, 2005.http://www.adaptivepath.com/publications/essays/archives/000385.php[2007-01-30].

[Goo06] Google Inc. Google To Acquire YouTube for $1.65 Billion in Stock, Oktober2006. http://www.google.com/press/pressrel/google_youtube.html [2007-01-30].

[KC81] Robert E. Kahn and Vinton G. Cerf. TRANSMISSION CONTROL PROTO-COL - DARPA INTERNET PROGRAM PROTOCOL SPECIFICATION,1981. http://tools.ietf.org/html/rfc793 [2007-01-30].

[NS05] M. Nottingham and R. Sayre. The Atom Syndication Format, Dezember2005. http://www.ietf.org/rfc/rfc4287 [2007-01-30].

[O’R05] Tim O’Reilly. What Is Web 2.0 - Design Patterns and Busi-ness Models for the Next Generation of Software, September 2005.http://www.oreillynet.com/pub/a/oreilly/tim/news/2005/09/30/what-is-web-20.html [2007-01-30].

[RHJ99] Dave Raggett, Arnaud Le Hors, and Ian Jacobs. HTML 4.01 Specification,Dezember 1999. http://www.w3.org/TR/html4/ [2007-01-30].

Diplomarbeit von Benedikt Schwinkendorf

A Verzeichnisstruktur des Quellcodes 56

A Verzeichnisstruktur des Quellcodes

./

c l i e n t . htmlc l i e n t . phpempty . html

./lib/

i n i t_ s e r v i c e . j si n i t_ s e r v i c e . phpc s s / gene ra l . c s s

./server/

i n t e r f a c e_s e r v e r . phps e r v e r . phpconf igurat ion_manager . php

database_component/database_component . phpdatabase_component/ interface_database_component . php

json_component/ interface_json_component . phpjson_component/ json_component . php

user_component/ interface_user_component . phpuser_component/user_component . php

./server/services/

i n t e r f a c e_app l i c a t i o n_s e r v i c e s . phpinter face_framework_serv ices . php

./server/services/application/

app l i c a t i on_se rv i c e . php

ca l endar_se rv i c e /admin_mail . i ncca l endar_se rv i c e / ca l endar_se rv i c e . phpca l endar_se rv i c e / operate . php3ca l endar_se rv i c e /welcome . php3ca l endar_se rv i c e / d i sp l ay . php3ca l endar_se rv i c e / c s s / ca l endar_se rv i c e . c s sca l endar_se rv i c e / l i b / ca l endar_se rv i c e . j s

Diplomarbeit von Benedikt Schwinkendorf

A Verzeichnisstruktur des Quellcodes 57

ca l endar_se rv i c e / l i b / ca l endar_se rv i c e . phpca l endar_se rv i c e / l i b / i n i t_ s e r v i c e . j s

he l lo_wor ld_serv ice / he l lo_wor ld_serv ice . phphe l lo_wor ld_serv ice / c s s / he l lo_wor ld_serv ice . c s she l lo_wor ld_serv ice / l i b / i n i t_ s e r v i c e . j she l lo_wor ld_serv ice / l i b / he l lo_wor ld_serv ice . j she l lo_wor ld_serv ice / l i b / he l lo_wor ld_serv ice . php

job_deta i l_se rv i c e / j ob_deta i l_se rv i c e . phpjob_deta i l_se rv i c e / c s s / j ob_deta i l_se rv i c e . c s sj ob_deta i l_se rv i c e / l i b / i n i t_ s e r v i c e . j sj ob_deta i l_se rv i c e / l i b / job_deta i l_se rv i c e . j sj ob_deta i l_se rv i c e / l i b / job_deta i l_se rv i c e . php

l a t e s t_ job s_se rv i c e / l a t e s t_ job s_se rv i c e . phpl a t e s t_ job s_se rv i c e / c s s / l a t e s t_ job s_se rv i c e . c s sl a t e s t_ job s_se rv i c e / l i b / i n i t_ s e r v i c e . j sl a t e s t_ job s_se rv i c e / l i b / l a t e s t_ job s_se rv i c e . j sl a t e s t_ job s_se rv i c e / l i b / l a t e s t_ job s_se rv i c e . php

l o g i n_se rv i c e / l o g i n_se rv i c e . phpl o g i n_se rv i c e / c s s / l o g i n_se rv i c e . c s sl o g i n_se rv i c e / l i b / i n i t_ s e r v i c e . j sl o g i n_se rv i c e / l i b / l o g i n_se rv i c e . j sl o g i n_se rv i c e / l i b / l o g i n_se rv i c e . php

new_job_service /new_job_service . phpnew_job_service / c s s /new_job_service . c s snew_job_service / l i b / i n i t_ s e r v i c e . j snew_job_service / l i b /new_job_service . j snew_job_service / l i b /new_job_service . php

per sona l_nav igat ion_serv i ce / per sona l_nav igat ion_serv i ce . phpper sona l_nav igat ion_serv i ce / c s s / per sona l_nav igat ion_serv i ce . c s sper sona l_nav igat ion_serv i ce / l i b / i n i t_ s e r v i c e . j sper sona l_nav igat ion_serv i ce / l i b / per sona l_nav igat ion_serv i ce . j sper sona l_nav igat ion_serv i ce / l i b / per sona l_nav igat ion_serv i ce . php

sea rch_se rv i c e / sea r ch_se rv i c e . phpsea rch_se rv i c e / c s s / s ea rch_se rv i c e . c s ss ea r ch_se rv i c e / l i b / i n i t_ s e r v i c e . j s

Diplomarbeit von Benedikt Schwinkendorf

A Verzeichnisstruktur des Quellcodes 58

sea rch_se rv i c e / l i b / s ea rch_se rv i c e . j s

s tandard_navigat ion_serv ice / standard_navigat ion_serv ice . phpstandard_navigat ion_serv ice / c s s / standard_navigat ion_serv ice . c s ss tandard_navigat ion_serv ice / l i b / i n i t_ s e r v i c e . j ss tandard_navigat ion_serv ice / l i b / standard_navigat ion_serv ice . j s

./server/services/framework/

f ramework_service . php

communication_service / communication_service . phpcommunication_service / l i b / communication_service . j scommunication_service / l i b / communication_service . php

compos i t ion_serv i ce / compos i t ion_serv i ce . phpcompos i t ion_serv i ce / l i b / compos i t ion_serv i ce . j scompos i t ion_serv i ce / l i b / compos i t ion_serv i ce . php

con f i gu r a t i on_se rv i c e / con f i gu r a t i on_se rv i c e . phpcon f i gu r a t i on_se rv i c e / l i b / con f i gu r a t i on_s e rv i c e . j sc on f i gu r a t i on_se rv i c e / l i b / con f i gu r a t i on_s e rv i c e . php

moni tor ing_serv ice / moni tor ing_serv ice . phpmoni tor ing_serv ice / l i b / monitor ing_serv ice . j smoni tor ing_serv ice / l i b / monitor ing_serv ice . php

sub s c r i b e r_s e rv i c e / sub s c r i b e r_s e rv i c e . phpsub s c r i b e r_s e rv i c e / l i b / sub s c r i b e r_s e rv i c e . j ss ub s c r i b e r_s e rv i c e / l i b / sub s c r i b e r_s e rv i c e . php

update_service / update_service . phpupdate_service / l i b / update_service . j supdate_service / l i b / update_service . php

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 59

B Quellcode

B.1 client.html

<!DOCTYPEHTML PUBLIC "−//W3C//DTD HTML 4.01 Tran s i t i ona l //EN"><html><head><l ink rel=" Sty l e sh e e t " type=" text / c s s " href=" l i b / c s s / gene ra l .

c s s " /><script =" JavaScr ipt " type=" text / j a v a s c r i p t " src=" l i b /

i n i t_ s e r v i c e . j s "></ script></head><body onload="__IS_p_init ia l ize ( ) "><span id=" content " style=" po s i t i o n : abso lu t e ; top : 10px ; l e f t :

10px"></span></body></html>

B.2 client.php

<?php/∗∗∗ c l i e n t . php i s part o f the "Framework 2.0"−Program∗∗ Copyright (C) 2006 Benedikt Schwinkendorf∗∗ https : // s ou r c e f o r g e . net / p r o j e c t s / framework20∗∗ This program i s f r e e so f tware ; you can r e d i s t r i b u t e i t and/ or∗ modify i t under the terms o f the GNU General Publ ic L i cense∗ as publ i shed by the Free Software Foundation ; e i t h e r v e r s i on

2∗ o f the License , or ( at your opt ion ) any l a t e r v e r s i on .∗∗ This program i s d i s t r i b u t e d in the hope that i t w i l l be

us e fu l ,∗ but WITHOUT ANY WARRANTY; without even the impl i ed warranty

o f∗ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the∗ GNU General Publ ic L i cense f o r more d e t a i l s .

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 60

∗∗ You should have r e c e i v ed a copy o f the GNU General Publ ic

L i cense∗ along with t h i s program ; i f not , wr i t e to the Free Software∗ Foundation , Inc . , 51 Frankl in Street , F i f th Floor , Boston , MA

02110−1301 , USA.∗∗/

/∗∗∗ Inc lude i n i t s e r v i c e∗/include ("lib/init_service.php" ) ;

/∗∗∗ Inc lude s e r v e r and s e r v e r i n t e r f a c e∗/include ("server/interface_server.php" ) ;include ("server/server.php" ) ;

class PHPClient {

/∗∗∗ Constructor∗/function PHPClient ( ) {

/∗ Create s e r v e r component ∗/$server_component = new server_component ( ) ;$ i n t e r f a c e_s e rv e r = new i n t e r f a c e_s e r v e r ( ) ;$ i n t e r f a c e_se rve r−>bindimpl(&$server_component ) ;$_SESSION [ "SERVER_COMPONENT" ] = $ i n t e r f a c e_s e rv e r ;

/∗ Create JSON component ∗/$json_component = new json_component (SERVICES_JSON_LOOSE_TYPE) ;$interface_json_component = new interface_json_component ( ) ;$interface_json_component−>bindimpl(&$json_component ) ;$_SESSION [ "JSON_COMPONENT" ] = $interface_json_component ;

/∗ I n i t i a l i z e i n i t s e r v i c e on f i r s t s t a r t ∗/__IS_p_init ia l ize ( ) ;}

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 61

}

/∗ Create c l i e n t on f i r s t v i s i t ∗/i f (empty ($_SESSION [ "php_client" ] ) ) {$_SESSION [ "php_client" ] =& new PHPClient ( ) ;}__IS_p_start ( ) ;?><html><head></head><body><span id="content" s t y l e="position: absolute;top: 10px; left: 10px"><?php/∗ show content f o r t h i s i n s e r t p l a c e ∗/__IS_p_showInsertplaceContent ("content" ) ;?></span></body></html>

B.3 empty.html

<html><head><t i t l e></ t i t l e></head><body></body></html>

B.4 init_service.js

/∗∗∗ i n i t_ s e r v i c e . j s i s part o f the "Framework 2.0"−Program∗ . . .∗/

/∗∗∗ Set a l l needed Framework−Se r v i c e s here as an array .

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 62

∗ <br>∗ e . g .∗ <br>∗ var __IS_u_FRAMEWORK_SERVICE_ARRAY = <br> new Array ( '

compos i t ion_serv i ce ' , ' sub s c r i b e r_s e rv i c e ' ) ;∗/var __IS_u_FRAMEWORK_SERVICE_ARRAY =new Array ('composition_service' ,'subscriber_service' ,'configuration_service' ) ;

/∗∗∗ Set the s e r v i c e width f o r each used i n s e r t p l a c e here∗ <br>∗ e . g .∗ <br>∗ var __IS_u_SERVICE_WIDTH = new Object ( ) ;∗ __IS_u_SERVICE_WIDTH[ 0 ] [ " content " ] = 500 ;∗/var __IS_u_SERVICE_WIDTH = new Object ( ) ;__IS_u_SERVICE_WIDTH[ "login" ] = 300 ;__IS_u_SERVICE_WIDTH[ "content" ] = 500 ;__IS_u_SERVICE_WIDTH[ "left_navigation" ] = 200 ;__IS_u_SERVICE_WIDTH[ "left_navigation_deeper" ] = 200 ;__IS_u_SERVICE_WIDTH[ "right_navigation" ] = 200 ;__IS_u_SERVICE_WIDTH[ "right_navigation_deeper" ] = 200 ;

/∗∗∗ Set the app l i c a t i o n based c on f i g u r a t i on here∗ <br>∗ e . g .∗ <br>∗ − Component−Bindings with s ub s c r i b e r s∗ <br>∗ __IS_p_subscribeFunction ( provider_namespace , funct ion ,

subscriber_namespace ) ;∗/function __IS_u_userConfig ( ) {

/∗ Subscr ibe f unc t i on s ∗/__IS_p_subscribeFunction ('http://localhost/ajax-diplomarbeit.de

/server/services/application/latest_jobs_service' , '

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 63

openJobDetails(job_id)' , 'http://localhost/ajax-diplomarbeit.de/server/services/application/job_detail_service' ) ;

__IS_p_subscribeFunction ('http://localhost/ajax-diplomarbeit.de/server/services/application/new_job_service' , 'newEntryNotifier()' , 'http://localhost/ajax-diplomarbeit.de/server/services/application/latest_jobs_service' ) ;

__IS_p_subscribeFunction ('http://localhost/ajax-diplomarbeit.de/server/services/application/login_service' , '__SCS_p_loadStartConfiguration()' , '' ) ;

__IS_p_subscribeFunction ('http://localhost/ajax-diplomarbeit.de/server/services/application/standard_navigation_service' ,'__CPS_p_addWebserviceAgent(service_name , insertplace ,add_menu)' , '' ) ;

__IS_p_subscribeFunction ('http://localhost/ajax-diplomarbeit.de/server/services/application/personal_navigation_service' ,'__CPS_p_addWebserviceAgent(service_name , insertplace ,add_menu)' , '' ) ;

}

/∗ Publ ic F i e l d s ∗/var __IS_p_SERVICE_NAMESPACE = '' ;

/∗ Pr ivate F i e l d s ∗/var __IS_x_SERVICE_TITLE = 'Student

sucht Job . de' ;var __IS_x_SERVICE_ARRAY = new Array ( ) ;var __IS_x_REPEAT_FUNCTION_ARRAY = new Array ( ) ;var __IS_x_SERVICE_NAME = '' ;var __IS_x_SERVICE_INSERTPLACE = '' ;var __IS_x_SERVICE_LOADED = f a l s e ;var __IS_x_SERVICE_ADD_MENU_FLAG = f a l s e ;

/∗∗∗ I n i t f unc t i on f o r t h i s namespace :∗ <br>∗ − Loads needed framework−s e r v i c e s∗/function __IS_p_init ia l ize ( ) {

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 64

/∗ I n i t f i e l d s ∗/__IS_x_SERVICE_ARRAY[ 0 ] = new Object ( ) ;__IS_x_REPEAT_FUNCTION_ARRAY[ 0 ] = new Object ( ) ;

/∗ Load needed framework−s e r v i c e s ∗/f o r ( service_name in __IS_u_FRAMEWORK_SERVICE_ARRAY) {__IS_p_loadService (__IS_u_FRAMEWORK_SERVICE_ARRAY[ service_name

] ) ;}

/∗ Run fu r t h e r l o g i c ∗/__IS_x_run( ) ;}

/∗∗∗ Loads a new framework−s e r v i c e from the s e r v e r∗ <p>∗ @param { St r ing } service_name − Se rv i c e name o f the framwork−

s e r v i c e to load∗/function __IS_p_loadService ( service_name ) {

/∗ Load only i f l oad ing i s t a l r eady on the run ∗/i f ( (__IS_x_SERVICE_ARRAY[ 0 ] [ service_name ] != f a l s e )&& (__IS_x_SERVICE_ARRAY[ 0 ] [ service_name ] != true ) ) {

/∗ Save s e r v i c e name to s e r v i c e array ∗/__IS_x_SERVICE_ARRAY[ 0 ] [ service_name ] = f a l s e ;/∗ Create http reque s t v a r i a b l e ∗/var http_request = __IS_x_createHTTPRequestObject ( ) ;/∗ Set r e c e i v e func t i on ∗/http_request . onreadystatechange = function ( ) {__IS_x_receiveService ( http_request , service_name ) ;} ;/∗ Do http reque s t ∗/http_request . open ('GET' , 'server/server.php?type=

framework_service&service_name=' +service_name , t rue ) ;http_request . send ( nu l l ) ;}}

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 65

/∗∗∗ Creates a component−binding between two namespaces∗ <p>∗ The prov ide r can c a l l the g iven func t i on " func " , the c a l l

w i l l be r e l ayed to the implementation∗ o f " func " on the sub s c r i b e r∗ <p>∗ @param { St r ing } provider_namespace − Namespace o f prov ide r∗ @param { St r ing } func − Function name in c l ud ing parameters − e

. g . s e t S t a r t ( s ta r t_id ) or g e tS ta r t ( )∗ @param { St r ing } subscriber_namespace − Namespace o f

s ub s c r i b e r∗/function __IS_p_subscribeFunction ( provider_namespace , func ,

subscriber_namespace ) {

/∗ Only sub s c r i b e i f a l l s e r v i c e s are loaded ∗/i f ( __IS_x_allServicesReady ( ) ) {

/∗ Get prov ide r window ∗/var provider_win = __CPS_x_getNamespaceWindow(

provider_namespace ) ;

/∗ Only sub s c r i b e i f p rov ide r window e x i s t s and prov ide rs e r v i c e i s f u l l y loaded ∗/

i f ( ( provider_win ) && ( provider_win .__IS_x_SERVICE_LOADED) &&( provider_win .__IS_x_SERVICE_LOADED == true ) ) {

/∗ Cal l addRelayFunction ∗/__SS_p_addRelayFunction ( provider_namespace , func ,

subscriber_namespace ) ;}else {/∗ Repead un t i l s u c c e s s ∗/__IS_x_repeatFunctionCall ('__IS_p_subscribeFunction(\'' +

provider_namespace + '\',\'' + func + '\',\'' +subscriber_namespace + '\')' , 1000 , −1) ;

}}else {/∗ Repead un t i l s u c c e s s ∗/

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 66

__IS_x_repeatFunctionCall ('__IS_p_subscribeFunction(\'' +provider_namespace + '\',\'' + func + '\',\'' +subscriber_namespace + '\')' , 1000 , −1) ;

}}

/∗∗∗ Checks i f a l l needed s e r v i c e s are loaded∗ <br>∗ − Sta r t s user c on f i g∗ <br>∗ − Sets s e r v i c e as f u l l y loaded∗/function __IS_x_run( ) {

/∗ Check i f a l l needed s e r v i c e s are loaded ∗/i f ( ! __IS_x_allServicesReady ( ) ) {/∗ Retry in 0 .2 seconds ∗/__IS_x_repeatFunctionCall ('__IS_x_run()' , 200 , 100) ;}else {/∗ Run user c on f i g ∗/__IS_u_userConfig ( ) ;/∗ Set t h i s s e r v i c e as f u l l y loaded ∗/__IS_x_SERVICE_LOADED = true ;}}

/∗∗∗ Checks i f a l l needed s e r v i c e s are f u l l y loaded∗ <br>∗ @return ( Boolean ) True i f a l l needed s e r v i c e s are loaded∗/function __IS_x_allServicesReady ( ) {

/∗ Create he lpe r var ∗/var a l l_loaded_f lag = true ;/∗ Walk through s e r v i c e array ∗/f o r ( var cur r en t_se rv i c e in __IS_x_SERVICE_ARRAY[ 0 ] ) {/∗ Get cur rent s e r v i c e loaded s t a tu s ∗/var loaded_status = __IS_x_SERVICE_ARRAY[ 0 ] [ cu r r en t_se rv i c e ] ;/∗ I f cur r ent s e r v i c e i s n ' t loaded yet −> stop check ing ∗/

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 67

i f ( loaded_status == f a l s e ) {return f a l s e ;}}return a l l_loaded_f lag ;}

/∗∗∗ Repeats the execut ion o f the g iven func t i on∗ in a g iven i n t e r v a l l time∗ <br>∗ − Saves the cur rent execut ion count in a g l oba l var∗ <br>∗ − Ale r t s i f the g iven maximum repeat count i s reached∗ <p>∗ @param { St r ing } func_name − The func t i on name o f the func t i on

to repeat∗ @param { In t eg e r } r epea t_ in t e rva l − Repeat i n t e r v a l l in

m i l l i s e c ond s∗ @param { In t eg e r } max_repeat_count − Maximal repeat count (−1

f o r un l imi ted )∗/function __IS_x_repeatFunctionCall ( function_name ,

repeat_inte rva l , max_repeat_count ) {

/∗ Check i f f unc t i on a l r eady e x i s t s in array ∗/var current_repeat_count = 0 ;i f (__IS_x_REPEAT_FUNCTION_ARRAY[ 0 ] [ function_name ] != nu l l ) {current_repeat_count = __IS_x_REPEAT_FUNCTION_ARRAY[ 0 ] [

function_name ] ;}

/∗ Check i f max repeat count i s reached ∗/i f ( current_repeat_count < max_repeat_count | | max_repeat_count

== −1) {/∗ I n c r e a s e current_repeat count and save i t to array ∗/current_repeat_count++;__IS_x_REPEAT_FUNCTION_ARRAY[ 0 ] [ function_name ] =

current_repeat_count ;/∗ Repeat func t i on c a l l ∗/window . setTimeout ("" + function_name + "" , r epea t_ in t e rva l ) ;}

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 68

else {/∗ Aler t max repeat count reached ∗/alert (__IS_x_SERVICE_TITLE + '\nreached max_repeat_count: ' +

max_repeat_count + ' for funcion: ' + function_name ) ;}}

/∗∗∗ Catches occur ing e r r o r s∗ <p>∗ @param { St r ing } message∗ @param { St r ing } f i l e∗ @param { St r ing } row∗/function __IS_x_catchErrors ( message , f i l e , row ) {

/∗ Generate e r r o r message ∗/e r r o r = __IS_x_SERVICE_TITLE + "\nFehlermeldung:\n" + message +

"\n" + f i l e + "\n" + row ;/∗ Aler t e r r o r ∗/alert ( e r r o r ) ;return t rue ;}

/∗∗∗ Creates a new http reque s t ob j e c t∗ <br>∗ − Should work with a l l Gecko−Engine Browsers and In t e rn e t

Explorer∗ <br>∗ − Testet with : FireFox 2 .0 and In t e rn e t Explorer 7∗/function __IS_x_createHTTPRequestObject ( ) {

/∗ The reque s t v a r i ab l e ∗/var http_request = f a l s e ;

/∗ Gecko−Engine ∗/i f (window . XMLHttpRequest ) {http_request = new XMLHttpRequest ( ) ;i f ( http_request . overrideMimeType ) {http_request . overrideMimeType ('text/xml' ) ;

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 69

}}/∗ I n t e rn e t Explorer ∗/else i f (window . ActiveXObject ) {t ry {http_request = new ActiveXObject ("Msxml2.XMLHTTP" ) ;} catch ( e ) {t ry {http_request = new ActiveXObject ("Microsoft.XMLHTTP" ) ;} catch ( e ) {}}}

/∗ Aler t e r r o r ∗/i f ( ! http_request ) {alert ('End :( Could not create XMLHTTP-instance' ) ;return f a l s e ;}

return http_request ;}

/∗∗∗ Checks load ing s t a tu s o f a running http reque s t∗ <p>∗ @param {Object } http_request − The http reque s t ob j e c t∗ @param { St r ing } service_name − The s e r v i c e name∗/function __IS_x_receiveService ( http_request , service_name ) {

/∗ Process data on readyState 4 = FINISHED ∗/i f ( http_request . readyState == 4) {

/∗ Check i f data was r e c e i v ed without problems ∗/i f ( http_request . s t a tu s == 200) {

/∗ Parse g iven JSON−St r ing to j a v a s c r i p t ∗/var data_array = eva l ('(' + http_request . responseText + ')' ) ;

/∗ Save g iven va lue s in to an s e r v i c e ob j e c t ∗/var s e r v i c e = new Object ( ) ;s e r v i c e [ "service_name" ] = service_name ;

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 70

s e r v i c e [ "lib" ] = data_array . l i b ;

/∗ Add s e r v i c e ∗/__IS_x_addService ( s e r v i c e ) ;}else {alert ('Problem during request occured!. Status: ' +

http_request . s t a tu s ) ;}}}

/∗∗∗ Adds a loaded framework_service to DOM∗ <p>∗ @param {Object } s e r v i c e∗/function __IS_x_addService ( s e r v i c e ) {

/∗ Create new s c r i p t element ∗/var j a vaSc r i p t = document . createElement ('script' ) ;j a vaSc r i p t . language = "JavaScript" ;j a vaSc r i p t . type = "text/javascript" ;j a vaSc r i p t . t ex t = s e r v i c e . l i b ;/∗ Add s c r i p t element to DOM ∗/document . getElementsByTagName ('head' ) [ 0 ] . appendChild ( j avaSc r i p t

) ;

/∗ Cal l i n i t f unc t i on o f the framework−s e r v i c e ∗/window [ s e r v i c e . service_name + "__initService" ] ( ) ;}

B.5 init_service.php

<?php/∗∗∗ i n i t_ s e r v i c e . php i s part o f the "Framework 2.0"−Program∗ . . .∗/

/∗∗∗ Set the app l i c a t i o n based c on f i g u r a t i on here

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 71

∗ <br>∗ e . g .∗ <br>∗ − Component−Bindings with s ub s c r i b e r s∗ <br>∗ __IS_p_subscribeFunction ( provider_namespace , funct ion ,

subscriber_namespace ) ;∗ <p>∗ − The s e r v i c e width f o r each used i n s e r t p l a c e∗ <br>∗ e . g .∗ <br>∗ $_SESSION["__IS_u_SERVICE_WIDTH" ] [ " content " ] = 500 ;∗/function __IS_u_userConfig ( ) {

$_SESSION [ "__IS_u_SERVICE_WIDTH" ] [ "login" ]= 300 ;

$_SESSION [ "__IS_u_SERVICE_WIDTH" ] [ "content" ]= 500 ;

$_SESSION [ "__IS_u_SERVICE_WIDTH" ] [ "left_navigation" ] =200 ;

$_SESSION [ "__IS_u_SERVICE_WIDTH" ] [ "left_navigation_deeper" ] =200 ;

$_SESSION [ "__IS_u_SERVICE_WIDTH" ] [ "right_navigation" ] =200 ;

$_SESSION [ "__IS_u_SERVICE_WIDTH" ] [ "right_navigation_deeper" ] =200 ;

/∗ Subscr ibe f unc t i on s ∗/__IS_p_subscribeFunction ('http://localhost/ajax-diplomarbeit.de

/server/services/application/latest_jobs_service' , 'openJobDetails($job_id)' , ´'http://localhost/ajax-diplomarbeit.de/server/services/application/job_detail_service' ) ;

__IS_p_subscribeFunction ('http://localhost/ajax-diplomarbeit.de/server/services/application/new_job_service' , 'newEntryNotifier' , 'http://localhost/ajax-diplomarbeit.de/server/services/application/latest_jobs_service' ) ;

}

/∗∗

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 72

∗ I n i t f unc t i on f o r t h i s namespace :∗ <br>∗ − Loads needed framework−s e r v i c e s∗/function __IS_p_init ia l ize ( ) {

/∗ I n i t s e s s i o n f i e l d s ∗/$_SESSION [ "SERVICE_DATA" ] = array ( ) ;$_SESSION [ "SERVICE_DATA" ] [ "function_paths" ] = array ( ) ;$_SESSION [ "INSERTPLACE_DATA" ] = array ( ) ;$_SESSION [ "__IS_u_SERVICE_WIDTH" ] = array ( ) ; ;

/∗ Load s e r v i c e s ∗/__IS_p_loadService ('communication_service' ) ;__IS_p_loadService ('composition_service' ) ;__IS_p_loadService ('subscriber_service' ) ;__IS_p_loadService ('monitoring_service' ) ;__IS_p_loadService ('update_service' ) ;

/∗ Run user setup ∗/__IS_u_userConfig ( ) ;

/∗ Load con f i g u r a t i on ∗/__IS_p_loadService ('configuration_service' ) ;}

/∗∗∗ Sets up the PHPClient∗ <p>∗ − Inc lude s needed func t i on s∗ <br>∗ − Handles func t i on c a l l i f a func t i on i s g iven∗ <br>∗ − Ca l l s update s e r v i c e to check namespace updates∗/function __IS_p_start ( ) {

/∗ Inc lude f unc t i on s from saved func t i on paths ∗/foreach ($_SESSION [ "SERVICE_DATA" ] [ "function_paths" ] as $key =>

$value ) {include_once ( $value ) ;}

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 73

/∗ Do func t i on c a l l i f a func t i on i s g iven ∗/i f ( ! empty($_REQUEST[ "function" ] ) ) {/∗ Ca l l s s ub s c r i b e r s e r v i c e to check i f f unc t i on i s subsc r ibed

∗/i f ( array_key_exists ("subscriber_service" , $_SESSION [ "

SERVICE_DATA" ] ) ) {/∗ Check i f f unc t i on was subsc r ibed ∗/__SS_p_callFunction ($_REQUEST[ "function" ] ) ;}else {/∗ Cal l normal func t i on ∗/call_user_func ( $function_name , $_REQUEST) ;}}

/∗ Ca l l s update s e r v i c e to check namespace updates ∗/i f ( array_key_exists ("update_service" , $_SESSION [ "SERVICE_DATA

" ] ) ) {__US_x_updateNamespaces ( ) ;}}

/∗∗∗ Reads a l l namespaces from the g iven i n s e r t p l a c e∗ <br>∗ − Echos the i n s e r t p l a c e data∗ <p>∗ @param { St r ing } i n s e r t p l a c e − The i n s e r t p l a c e which data

s h e l l be loaded∗/function __IS_p_showInsertplaceContent ( $ i n s e r t p l a c e ) {

/∗ Get data array f o r i n s e r t p l a c e ∗/i f ( ! empty ($_SESSION [ "INSERTPLACE_DATA" ] [ $ i n s e r t p l a c e ] ) ) {/∗ Get i n s e r t p l a c e data ∗/$ inse r tp lace_data = $_SESSION [ "INSERTPLACE_DATA" ] [ $ i n s e r t p l a c e

] ;/∗ Run through i n s e r t p l a c e data ∗/foreach ( $ inse r tp lace_data as $value ) {echo $value ;}

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 74

}}

/∗∗∗ Loads a new framework−s e r v i c e from the s e r v e r∗ <p>∗ @param { St r ing } service_name − Se rv i c e name o f the framwork−

s e r v i c e to load∗/function __IS_p_loadService ( $service_name ) {

/∗ Only load i f s e r v i c e i s not loaded yet ∗/i f ( empty($_SESSION [ "SERVICE_DATA" ] [ $service_name ] ) ) {/∗ Get s e r v i c e from s e rv e r ∗/$serv ice_data = $_SESSION [ "SERVER_COMPONENT"]−>

handleRequestPHPClient ("framework_service" , $service_name ,nu l l ) ;

/∗ Receive s e r v i c e data ∗/__IS_x_receiveService ( $service_data , $service_name ) ;}}

/∗∗∗ Creates a component−binding between two namespaces∗ <p>∗ @param { St r ing } provider_namespace − Namespace o f prov ide r∗ @param { St r ing } func − Function name in c l ud ing parameters − e

. g . s e t S t a r t ( s ta r t_id ) or g e tS ta r t ( )∗ @param { St r ing } subscriber_namespace − Namespace o f

s ub s c r i b e r∗/function __IS_p_subscribeFunction ( $provider , $ funct ion ,

$ sub s c r i b e r ) {/∗ Cal l addRelayFunction ∗/__SS_p_addRelayFunction ( $provider , $ funct ion , $ sub s c r i b e r ) ;}

/∗∗∗ Rece ives s e r v i c e data∗ <p>∗ @param {Object } serv ice_data − The s e r v i c e data ob j e c t∗ @param { St r ing } service_name − The s e r v i c e name

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 75

∗/function __IS_x_receiveService ( $service_data , $service_name ) {

/∗ Parse g iven JSON−St r ing to PHP ∗/$data_array = $_SESSION [ "JSON_COMPONENT"]−>decode ( $serv ice_data

) ;

/∗ Save g iven va lue s in to an s e r v i c e array ∗/$ s e r v i c e = array ( ) ;$ s e r v i c e [ "service_name" ] = $service_name ;$ s e r v i c e [ "include_path" ] = $data_array [ "include_path" ] ;

/∗ Add s e r v i c e ∗/__IS_x_addService ( $ s e r v i c e ) ;}

/∗∗∗ Adds a loaded framework_service to DOM∗ <p>∗ @param {Object } s e r v i c e∗/function __IS_x_addService ( $ s e r v i c e ) {

/∗ c r e a t e in c lude path ∗/$url_host = 'http://' . $_SERVER[ 'HTTP_HOST' ] . dirname (

$_SERVER[ 'SCRIPT_NAME' ] ) . "/" ;$ include_path = st r_rep la ce ( $url_host , '' , $ s e r v i c e [ "

include_path" ] ) ;

/∗ Check i f i n c lude path e x i s t s ∗/i f ( ! array_search ( $include_path , $_SESSION [ "SERVICE_DATA" ] [ "

function_paths" ] ) ) {/∗ add inc lude path to func t i on paths ∗/array_push($_SESSION [ "SERVICE_DATA" ] [ "function_paths" ] ,

$ include_path ) ;

/∗ Inc lude s e r v i c e ∗/include ( $include_path ) ;

/∗ Create i n i t f unc t i on name f o r the s e r v i c e ∗/$ in i t_ func t i on = $ s e r v i c e [ "service_name" ] . "__initService" ;

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 76

/∗ Cal l i n i t f unc t i on f o r the s e r v i c e ∗/call_user_func ( $ in i t_ func t i on ) ;}}?>

B.6 general.css

/∗∗∗ gene ra l . c s s i s part of the "Framework 2.0"−Program∗ . . .∗/

/∗ I n s e r t p l a c e p o s i t i o n s ∗/#logo {po s i t i o n : abso lu te ;l e f t : 22px ;top : 19px ;}#l o g i n {po s i t i o n : abso lu te ;top : 17px ;l e f t : 620px ;}#l e f t_nav i ga t i on {po s i t i o n : abso lu te ;l e f t : 22px ;top : 136px ;}#r ight_nav igat ion {po s i t i o n : abso lu te ;l e f t : 707px ;top : 136px ;}#le f t_nav igat ion_deeper {po s i t i o n : abso lu te ;l e f t : 22px ;top : 340px ;}#right_navigat ion_deeper {po s i t i o n : abso lu te ;l e f t : 707px ;

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 77

top : 340px ;}#content {po s i t i o n : abso lu te ;l e f t : 190px ;top : 136px ;}/∗ General layout ∗/body {margin : 0px ;padding : 0px ;}. normaltext {font−f ami ly : Verdana , Lucida , He lvet i ca , Ar ia l , sans−s e r i f ;font−s i z e : 10px ;

text−trans form : uppercase ;text−deco ra t i on : none ;font−weight : normal ;}. normaltext_bold {font−f ami ly : Verdana , Lucida , He lvet i ca , Ar ia l , sans−s e r i f ;font−s i z e : 10px ;

text−trans form : uppercase ;text−deco ra t i on : none ;font−weight : bold ;}. c o n t r o l s_ l e f t {font−f ami ly : Verdana , Lucida , He lvet i ca , Ar ia l , sans−s e r i f ;font−s i z e : 13px ;padding : 2px ;

text−trans form : uppercase ;text−deco ra t i on : none ;font−weight : normal ;

background−image : u r l ( . . / . . / images /bg_menu . jpg ) ;border− l e f t : s o l i d 1px #CCCCCC;border−top : s o l i d 1px #CCCCCC;border−bottom : s o l i d 1px #CCCCCC;}

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 78

. c on t ro l s_r i gh t {font−f ami ly : Verdana , Lucida , He lvet i ca , Ar ia l , sans−s e r i f ;font−s i z e : 13px ;padding : 1px ;

text−trans form : uppercase ;text−deco ra t i on : none ;font−weight : normal ;

background−image : u r l ( . . / . . / images /bg_menu . jpg ) ;border−r i g h t : s o l i d 1px #CCCCCC;border−top : s o l i d 1px #CCCCCC;border−bottom : s o l i d 1px #CCCCCC;}#top i c t e x t {font−f ami ly : Verdana , Lucida , He lvet i ca , Ar ia l , sans−s e r i f ;font−s i z e : 13px ;

text−trans form : uppercase ;text−deco ra t i on : none ;font−weight : normal ;

background−image : u r l ( . . / . . / images /bg_menu . jpg ) ;border : s o l i d 1px #CCCCCC;}#form_f ie ld {font−f ami ly : Verdana , Lucida , He lvet i ca , Ar ia l , sans−s e r i f ;font−s i z e : 13px ;font−weight : normal ;background−c o l o r : #FFFFFF;

border−top−s t y l e : s o l i d ;border−r i ght−s t y l e : s o l i d ;border−l e f t−s t y l e : s o l i d ;border−bottom−s t y l e : s o l i d ;

border−width : 1px ;border−c o l o r : #CCCCCC;

padding : 0px ;margin− l e f t : 0px ;

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 79

width : 140px ;he ight : 20px ;}#form_button {font−f ami ly : Verdana , Lucida , He lvet i ca , Ar ia l , sans−s e r i f ;font−s i z e : 13px ;font−weight : normal ;background−c o l o r : #FFFFFF;

border−top−s t y l e : ou t s e t ;border−r i ght−s t y l e : ou t s e t ;border−l e f t−s t y l e : ou t s e t ;border−bottom−s t y l e : ou t s e t ;

margin− l e f t : 0px ;

he ight : 22px ;width : 140px ;}a . page l ink {font−f ami ly : Verdana , Geneva , Ar ia l , He lvet i ca , sans−s e r i f ;

text−deco ra t i on : none ;

COLOR: #333399;}a . page l ink : v i s i t e d {font−f ami ly : Verdana , Geneva , Ar ia l , He lvet i ca , sans−s e r i f ;

text−deco ra t i on : none ;

COLOR: #333399;}a . page l ink : hover {font−f ami ly : Verdana , Geneva , Ar ia l , He lvet i ca , sans−s e r i f ;

text−deco ra t i on : none ;

COLOR: #666666;}

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 80

B.7 configuration_manager.php

<?php/∗∗∗ conf igurat ion_manager . php i s part o f the "Framework 2.0"−

Program∗ . . .∗/

/∗∗∗ Inc lude s e r v e r components∗//∗ Database component ∗/include ("database_component/database_component.php" ) ;/∗ Database i n t e r f a c e ∗/include ("database_component/interface_database_component.php" ) ;/∗ User component ∗/include ("user_component/user_component.php" ) ;/∗ User i n t e r f a c e ∗/include ("user_component/interface_user_component.php" ) ;/∗ Json component ∗/include ("json_component/json_component.php" ) ;/∗ Json i n t e r f a c e ∗/include ("json_component/interface_json_component.php" ) ;

/∗∗∗ Inc lude wrapper c l a s s e s and the Web Se rv i c e i n t e r f a c e∗//∗ Wrapper c l a s s f o r l o c a l Web Se r v i c e s ∗/include ("services/application/application_service.php" ) ;/∗ Common Web Se rv i c e i n t e r f a c e ∗/include ("services/interface_application_services.php" ) ;

/∗∗∗ Inc lude gene ra l Web Se r v i c e s and i n t e r f a c e s∗//∗ Wrapper c l a s s f o r Framework−Se r v i c e s ∗/include ("services/framework/framework_service.php" ) ;/∗ Common Framework−Se rv i c e i n t e r f a c e ∗/include ("services/interface_framework_services.php" ) ;/∗ Star t Conf igurat ion Se rv i c e c l a s s ∗/

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 81

include ("services/framework/configuration_service/configuration_service.php" ) ;

/∗ Communication Se rv i c e c l a s s ∗/include ("services/framework/communication_service/

communication_service.php" ) ;/∗ Composition Se rv i c e c l a s s ∗/include ("services/framework/composition_service/

composition_service.php" ) ;/∗ Subsc r ibe r S e rv i c e c l a s s ∗/include ("services/framework/subscriber_service/

subscriber_service.php" ) ;/∗ Monitoring Se rv i c e c l a s s ∗/include ("services/framework/monitoring_service/

monitoring_service.php" ) ;/∗ Update Se rv i c e c l a s s ∗/include ("services/framework/update_service/update_service.php" )

;

/∗∗∗ Inc lude l o c a l Web Se r v i c e s∗//∗ Login Web Se rv i c e ∗/include ("services/application/login_service/login_service.php" )

;/∗ Standard nav igat i on Web Se rv i c e ∗/include ("services/application/standard_navigation_service/

standard_navigation_service.php" ) ;/∗ Persona l nav igat i on Web Se rv i c e ∗/include ("services/application/personal_navigation_service/

personal_navigation_service.php" ) ;/∗ Search Web Se rv i c e ∗/include ("services/application/search_service/search_service.php

" ) ;/∗ Lates t j obs Web Se rv i c e ∗/include ("services/application/latest_jobs_service/

latest_jobs_service.php" ) ;/∗ Job d e t a i l Web Se rv i c e ∗/include ("services/application/job_detail_service/

job_detail_service.php" ) ;/∗ New job Web Se rv i c e ∗/include ("services/application/new_job_service/new_job_service.

php" ) ;

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 82

/∗ Calendar Web Se rv i c e ∗/include ("services/application/calendar_service/calendar_service

.php" ) ;

/∗∗∗ DESCRIPTION:∗∗ This c l a s s handles the main c on f i g u r a t i on .∗ <br>∗ I t i n s t a n t i a t e s new ob j e c t s o f each used c l a s s (

implementat ions and i n t e r f a c e s )∗ and c r e a t e s the cor re spond ing b ind ings∗ <br>∗ F ina l l y i t saves the whole c on f i g u r a t i on in to a the s e s s i o n∗/class conf igurat ion_manager {

/∗∗∗ Framework v a r i a b l e s∗//∗ Function name o f the common bind method f o r i n t e r f a c e s ∗/var $BIND_USED_INTERFACE = "bind" ;/∗ Function name o f the Common funt i on to bind i n t e r f a c e

implementat ions ∗/var $BIND_IMPLEMENTATION = "bindimpl" ;

/∗ I n t e r f a c e s f o r app l i c a t i o n s e r v i c e usage ∗/var $interface_database_component ;var $interface_user_component ;var $interface_json_component ;var $ inte r face_update_serv i ce ;var $ i n t e r f a c e_con f i gu r a t i on_s e rv i c e ;

/∗ Components f o r app l i c a t i o n s e r v i c e usage ∗/var $server_component ;

/∗∗∗ Constructor∗/function conf igurat ion_manager ( $server_component ) {

/∗ Set v a r i a b l e s f o r func t i on c a l l s ∗/

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 83

$BIND_IMPLEMENTATION = $th i s−>BIND_IMPLEMENTATION;$BIND_USED_INTERFACE = $th i s−>BIND_USED_INTERFACE;

/∗ Save s e r v e r component to l o c a l v a r i ab l e ∗/$th i s−>server_component =& $server_component ;

/∗ I n s t a n t i a t e database component ∗/$database_component_component = new database_component ( ) ;/∗ I n s t a n t i a t e database i n t e r f a c e ∗/$interface_database_component = new

interface_database_component ( ) ;/∗ Bind database implementation ∗/$interface_database_component−>$BIND_IMPLEMENTATION(&

$database_component_component ) ;/∗ Save database component i n t e r f a c e to l o c a l v a r i a b l e ∗/$th i s−>interface_database_component =&

$interface_database_component ;

/∗ I n s t a n t i a t e user component ∗/$user_component = new user_component ( ) ;/∗ I n s t a n t i a t e user i n t e r f a c e ∗/$interface_user_component = new interface_user_component ( ) ;/∗ Bind user implementation ∗/$interface_user_component−>$BIND_IMPLEMENTATION(&

$user_component ) ;/∗ Save user component i n t e r f a c e to l o c a l v a r i a b l e ∗/$th i s−>interface_user_component =& $interface_user_component ;

/∗ I n s t a n t i a t e JSON component ∗/$json_component = new json_component (SERVICES_JSON_LOOSE_TYPE) ;/∗ I n s t a n t i a t e JSON i n t e r f a c e ∗/$interface_json_component = new interface_json_component ( ) ;/∗ Create b ind ings o f JSON component ∗/$interface_json_component−>$BIND_IMPLEMENTATION(&

$json_component ) ;/∗ Save JSON component i n t e r f a c e to l o c a l v a r i a b l e ∗/$th i s−>interface_json_component =&

$interface_json_component ;

/∗∗∗ Create Framework−Se r v i c e s∗/

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 84

/∗ I n s t a n t i a t e Conf igurat ion Se rv i c e ∗/$ con f i gu r a t i on_se rv i c e = new c on f i gu r a t i on_se rv i c e ( ) ;/∗ I n s t a n t i a t e Conf igurat ion Se rv i c e i n t e r f a c e ∗/$ i n t e r f a c e_con f i gu r a t i on_s e rv i c e = new

in te r face_framework_serv ices ( ) ;/∗ Bind Conf igurat ion Se rv i c e implementation ∗/$ in t e r f a c e_con f i gu ra t i on_se rv i c e−>$BIND_IMPLEMENTATION(&

$con f i gu r a t i on_se rv i c e ) ;/∗ Bind Conf igurat ion Se rv i c e Used i n t e r f a c e s ∗/$con f i gu ra t i on_se rv i c e−>$BIND_USED_INTERFACE("

interface_database_component" , &$interface_database_component ) ;

$ con f i gu ra t i on_se rv i c e−>$BIND_USED_INTERFACE("interface_user_component" , &$interface_user_component ) ;

$ con f i gu ra t i on_se rv i c e−>$BIND_USED_INTERFACE("interface_json_component" , &$interface_json_component ) ;

/∗ Bind Server Component used i n t e r f a c e ∗/$server_component−>$BIND_USED_INTERFACE("

interface_configuration_service" , &$ i n t e r f a c e_con f i gu r a t i on_s e rv i c e ) ;

/∗ Set s t a r t c on f i g u r a t i on ∗/$th i s−>in t e r f a c e_con f i gu r a t i on_s e rv i c e =&

$ in t e r f a c e_con f i gu r a t i on_s e rv i c e ;$ th i s−>se tS ta r tCon f i gu r a t i on ( ) ;

/∗ I n s t a n t i a t e Communication Se rv i c e ∗/$communication_service = new communication_service ( ) ;/∗ I n s t a n t i a t e Communication Se rv i c e i n t e r f a c e ∗/$inter face_communicat ion_serv ice = new

in te r face_framework_serv ices ( ) ;/∗ Bind Communication Se rv i c e implementation ∗/$inter face_communicat ion_service−>$BIND_IMPLEMENTATION(&

$communication_service ) ;/∗ Bind Communication Se rv i c e Used i n t e r f a c e s ∗/$communication_service−>$BIND_USED_INTERFACE("

interface_json_component" , &$interface_json_component ) ;

/∗ Bind Server Component used i n t e r f a c e ∗/

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 85

$server_component−>$BIND_USED_INTERFACE("interface_communication_service" , &$inter face_communicat ion_serv ice ) ;

/∗ I n s t a n t i a t e Composition Se rv i c e ∗/$compos i t ion_serv ice = new compos i t ion_serv i ce ( ) ;/∗ I n s t a n t i a t e Composition Se rv i c e i n t e r f a c e ∗/$ in te r f ace_compos i t i on_serv i c e = new

in te r face_framework_serv ices ( ) ;/∗ Bind Composition Se rv i c e implementation ∗/$ inte r face_compos i t i on_serv i ce−>$BIND_IMPLEMENTATION(&

$compos i t ion_serv ice ) ;/∗ Bind Composition Se rv i c e Used i n t e r f a c e s ∗/$compos i t ion_serv ice−>$BIND_USED_INTERFACE("

interface_json_component" , &$interface_json_component ) ;

/∗ Bind Server Component used i n t e r f a c e ∗/$server_component−>$BIND_USED_INTERFACE("

interface_composition_service" , &$ inte r f ace_compos i t i on_se rv i c e ) ;

/∗ I n s t a n t i a t e Composition Se rv i c e ∗/$ sub s c r i b e r_se rv i c e = new sub s c r i b e r_s e rv i c e ( ) ;/∗ I n s t a n t i a t e Composition Se rv i c e i n t e r f a c e ∗/$ i n t e r f a c e_sub s c r i b e r_s e rv i c e = new

in te r face_framework_serv ices ( ) ;/∗ Bind Composition Se rv i c e implementation ∗/$ in t e r f a c e_subs c r i b e r_se rv i c e−>$BIND_IMPLEMENTATION(&

$subs c r i b e r_se rv i c e ) ;/∗ Bind Composition Se rv i c e Used i n t e r f a c e s ∗/$subsc r ibe r_se rv i c e−>$BIND_USED_INTERFACE("

interface_json_component" , &$interface_json_component ) ;/∗ Bind Server Component used i n t e r f a c e ∗/$server_component−>$BIND_USED_INTERFACE("

interface_subscriber_service" , &$ in t e r f a c e_sub s c r i b e r_s e rv i c e ) ;

/∗ I n s t a n t i a t e Monitoring Se rv i c e ∗/$monitor ing_serv ice = new monitor ing_serv ice ( ) ;/∗ I n s t a n t i a t e Monitoring Se rv i c e i n t e r f a c e ∗/$ inte r f ace_mon i to r ing_serv i c e = new

in te r face_framework_serv ices ( ) ;

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 86

/∗ Bind Monitoring Se rv i c e implementation ∗/$ inte r face_moni to r ing_serv i ce−>$BIND_IMPLEMENTATION(&

$monitor ing_serv ice ) ;/∗ Bind Monitoring Se rv i c e Used i n t e r f a c e s ∗/$monitor ing_serv ice−>$BIND_USED_INTERFACE("

interface_json_component" , &$interface_json_component ) ;/∗ Bind Server Component used i n t e r f a c e ∗/$server_component−>$BIND_USED_INTERFACE("

interface_monitoring_service" , &$ inte r f ace_mon i to r ing_serv i c e ) ;

/∗ I n s t a n t i a t e Update Se rv i c e ∗/$update_service = new update_service ( ) ;/∗ I n s t a n t i a t e Update Se rv i c e i n t e r f a c e ∗/$ inte r face_update_serv i ce = new in te r face_framework_serv ices ( ) ;/∗ Bind Update Se rv i c e implementation ∗/$ inter face_update_serv ice−>$BIND_IMPLEMENTATION(&

$update_service ) ;/∗ Bind Update Se rv i c e Used i n t e r f a c e s ∗/$update_service−>$BIND_USED_INTERFACE("

interface_database_component" , &$interface_database_component ) ;

$update_service−>$BIND_USED_INTERFACE("interface_json_component" , &$interface_json_component ) ;

/∗ Bind Server Component used i n t e r f a c e ∗/$server_component−>$BIND_USED_INTERFACE("

interface_update_service" , &$ inte r face_update_serv i ce ) ;/∗ Save update s e r v i c e to l o c a l v a r i ab l e ∗/$th i s−>inte r face_update_serv i ce =& $inte r face_update_serv i ce ;

/∗ I n s t a n t i a t e app l i c a t i o n s e r v i c e s ∗/$th i s−>se tApp l i c a t i o nS e r v i c e s ( ) ;

/∗ Save c on f i g u r a t i on in to Se s s i on ∗/$_SESSION [ "server_application" ] =& $server_component ;}

/∗∗∗ This func t i on conta in s the app l i c a t i o n s e r v i c e c on f i g u r a t i on∗/function s e tApp l i c a t i o nS e r v i c e s ( ) {

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 87

/∗ Set v a r i a b l e s f o r func t i on c a l l s ∗/$BIND_IMPLEMENTATION = $th i s−>BIND_IMPLEMENTATION;$BIND_USED_INTERFACE = $th i s−>BIND_USED_INTERFACE;

/∗∗∗ Create app l i c a t i o n s e r v i c e c on f i g u r a t i o n s below∗//∗ I n s t a n t i a t e HelloWorld−Se rv i c e ∗/$he l lo_wor ld_serv ice = new he l lo_wor ld_serv ice ("Hallo Welt!" ) ;/∗ I n s t a n t i a t e HelloWorld−Se rv i c e i n t e r f a c e ∗/$ inte r face_he l l o_wor ld_serv i c e = new

i n t e r f a c e_app l i c a t i o n_s e r v i c e s ( ) ;/∗ Bind HelloWorld−Se rv i c e implementation ∗/$ inte r face_he l lo_wor ld_serv i ce−>$BIND_IMPLEMENTATION(&

$he l lo_wor ld_serv ice ) ;/∗ Bind HelloWorld−Se rv i c e used i n t e r f a c e ∗/$hel lo_wor ld_serv ice−>$BIND_USED_INTERFACE("

interface_json_component" , &$th i s−>interface_json_component );

/∗ Bind Server Component used i n t e r f a c e ∗/$th i s−>server_component−>$BIND_USED_INTERFACE("

interface_hello_world_service" , &$ inte r face_he l l o_wor ld_serv i c e ) ;

}

/∗∗∗ This func t i on conta in s the s t a r t c on f i g u r a t i on∗/function s e tS t a r tCon f i gu r a t i on ( ) {

/∗ Setup Star t Conf igurat ion Se rv i c e ∗/$th i s−>in t e r f a c e_con f i gu ra t i on_se rv i c e−>act i on ( array ("action" => "setStartConfiguration" ,"service_name" => "hello_world_service" ,"insertplace" => "content" ,"add_menu" => true ,"type" => "public") ) ;}}?>

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 88

B.8 interface_server.php

<?php/∗∗∗ i n t e r f a c e_s e r v e r . php i s part o f the "Framework 2.0"−Program∗ . . .∗/

/∗∗∗ This i n t e r f a c e i s used by the PHP−Cl i en t in order to r e c e i v e

any s e r v e r data∗/class i n t e r f a c e_s e r v e r {

/∗∗∗ Holds the i n t e r f a c e implementation∗/var $impl ;

/∗∗∗ Common func t i on to bind i n t e r f a c e implementat ions∗/function bindimpl ( $impl ) {$th i s−>impl =& $impl ;}

/∗∗∗ Ca l l s the r e s p on s i b l e s e r v i c e f o r the g iven data∗ <p>∗ @param { St r ing } type − The s e r v i c e type ( framework_service or

app l i c a t i on_se rv i c e )∗ @param { St r ing } service_name − The s e r v i c e s service_name∗ @param {Array} va lue s − The data to proce s s by the c a l l e d s

s e r v i c e∗/function handleRequestPHPClient ( $type , $service_name , $va lues )

{return $th i s−>impl−>handleRequestPHPClient ( $type , $service_name

, $va lues ) ;}}?>

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 89

B.9 server.php

<?php/∗∗∗ s e r v e r . php i s part o f the "Framework 2.0"−Program∗ . . .∗/

/∗ Inc lude the c on f i g u r a t i on manager ∗/include ("configuration_manager.php" ) ;

/∗∗∗ DESCRIPTION:∗ <br>∗ This i s the main s e r v e r component − every s e r v i c e−r eque s t has

to be d i r e c t ed to t h i s component .∗ <br>∗ The server_component w i l l r e l a y upcoming reque s t to the

cor re spond ing s e r v i c e s∗/class server_component {

/∗ Used i n t e r f a c e s ∗/var $used_inte r f ace s = array ( ) ;

/∗∗∗ Common bind method − Only save a r e f e r e n c e −> maybe the

i n t e r f a c e implementation w i l l change l a t e r∗/function bind ( $interface_name , $impl ) {$th i s−>used_inte r f a c e s [ $interface_name ] =& $impl ;}

/∗∗∗ Constructor∗/function server_component ( ) {/∗ Create c on f i g u r a t i on ∗/$_SESSION [ "configuration_manager" ] =& new conf igurat ion_manager

(&$ th i s ) ;}

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 90

/∗∗∗ Handles a l l normal c l i e n t s r eque s t s∗/function handleRequests ( ) {

/∗ Catch ac t i on r eque s t s and c a l l cor re spond ing s e r v i c efunc t i on ∗/

i f ( ! empty($_REQUEST[ "action" ] ) ) {$ i n t e r f a c e = "interface_" . $_REQUEST[ "service_name" ] ;/∗ Check i f i n t e r f a c e e x i s t s ∗/i f ( array_key_exists ( $ i n t e r f a c e , $ th i s−>used_inte r f a c e s ) ) {$ inte r face_impl =& $th i s−>used_inte r f a c e s [ $ i n t e r f a c e ] ;return $ inter face_impl−>act i on ($_REQUEST) ;}}/∗ Catch framework−s e r v i c e r eque s t s and c a l l cor re spond ing

s e r v i c e func t i on ∗/else i f ( ! empty($_REQUEST[ "type" ] ) && $_REQUEST[ "type" ] == "

framework_service" ) {$ i n t e r f a c e = "interface_" . $_REQUEST[ "service_name" ] ;/∗ Check i f i n t e r f a c e e x i s t s ∗/i f ( array_key_exists ( $ i n t e r f a c e , $ th i s−>used_inte r f a c e s ) ) {$ inte r face_impl =& $th i s−>used_inte r f a c e s [ $ i n t e r f a c e ] ;$ inter face_impl−>setJSEnabled ( true ) ;return $ inter face_impl−>getFrameworkService ( ) ;}}/∗ Catch app l i c a t i on−s e r v i c e r eque s t s and c a l l cor re spond ing

s e r v i c e func t i on ∗/else i f ( ! empty($_REQUEST[ "type" ] ) && $_REQUEST[ "type" ] == "

application_service" ) {$ i n t e r f a c e = "interface_" . $_REQUEST[ "service_name" ] ;/∗ Check i f i n t e r f a c e e x i s t s ∗/i f ( array_key_exists ( $ i n t e r f a c e , $ th i s−>used_inte r f a c e s ) ) {$ inte r face_impl =& $th i s−>used_inte r f a c e s [ $ i n t e r f a c e ] ;$ inter face_impl−>setJSEnabled ( true ) ;return $ inter face_impl−>getWebserviceAgent ( ) ;}}

}

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 91

/∗∗∗ Handles a l l PHPClient r eque s t s∗/function handleRequestPHPClient ( $type , $service_name , $va lues )

{

/∗ Create i n t e r f a c e name ∗/$ i n t e r f a c e = "interface_" . $service_name ;

/∗ Catch ac t i on r eque s t s and c a l l cor re spond ing s e r v i c efunc t i on ∗/

i f ( ! empty( $va lues ) ) {/∗ Check i f i n t e r f a c e e x i s t s ∗/i f ( array_key_exists ( $ i n t e r f a c e , $ th i s−>used_inte r f a c e s ) ) {$ inte r face_impl =& $th i s−>used_inte r f a c e s [ $ i n t e r f a c e ] ;return $ inter face_impl−>act i on ( $va lues ) ;}}/∗ Catch framework−s e r v i c e r eque s t s and c a l l cor re spond ing

s e r v i c e func t i on ∗/else i f ( $type == "framework_service" ) {/∗ Check i f i n t e r f a c e e x i s t s ∗/i f ( array_key_exists ( $ i n t e r f a c e , $ th i s−>used_inte r f a c e s ) ) {$ inte r face_impl =& $th i s−>used_inte r f a c e s [ $ i n t e r f a c e ] ;$ inter face_impl−>setJSEnabled ( fa l se ) ;return $ inter face_impl−>getFrameworkService ( ) ;}}/∗ Catch app l i c a t i on−s e r v i c e r eque s t s and c a l l cor re spond ing

s e r v i c e func t i on ∗/else i f ( $type == "application_service" ) {/∗ Check i f i n t e r f a c e e x i s t s ∗/i f ( array_key_exists ( $ i n t e r f a c e , $ th i s−>used_inte r f a c e s ) ) {$ inte r face_impl =& $th i s−>used_inte r f a c e s [ $ i n t e r f a c e ] ;$ inter face_impl−>setJSEnabled ( fa l se ) ;return $ inter face_impl−>getWebserviceAgent ( ) ;}}}}

session_start ( ) ;

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 92

/∗ Create c on f i g u r a t i on on f i r s t v i s i t ∗/i f (empty ($_SESSION [ "server_application" ] ) ) {$_SESSION [ "server_application" ] =& new server_component ( ) ;}

/∗ Handle r eque s t s ∗/echo $_SESSION [ "server_application"]−>handleRequests ( ) ;?>

B.10 interface_application_services.php

<?php/∗∗∗ i n t e r f a c e_app l i c a t i o n_s e r v i c e s . php i s part o f the "Framework

2.0"−Program∗ . . .∗/

/∗∗∗ DESCRIPTION:∗ <br>∗ This I n t e r f a c e has to be implemented by each app l i c a t i on−

s e r v i c e .∗ <br>∗ I t ' s the main communication I n t e r f a c e f o r each app l i c a t i on−

s e r v i c e in order to communicate with∗ i t s conta in ing Webservice−Agent or other Web Se rv i c e s∗/class i n t e r f a c e_app l i c a t i o n_s e r v i c e s {

/∗∗∗ Holds the i n t e r f a c e implementation∗/var $impl ;

/∗∗∗ Common funt i on to bind i n t e r f a c e implementat ions∗/function bindimpl ( $impl ) {$th i s−>impl =& $impl ;}

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 93

/∗∗∗ Returns the Webservice−Agent o f the c a l l e d s e r v i c e∗ <p>∗ @param {JSON−St r ing } The Webservice−Agent o f the c a l l e d

func t i on − j son−encoded∗/function getWebserviceAgent ( ) {return $th i s−>impl−>getWebserviceAgent ( ) ;}

/∗∗∗ Cal l the s e r v i c e s ac t i on func t i on with a l l g iven data∗ <p>∗ @return {JSON−St r ing } The app l i c a t i on−s e r v i c e re sponse on the

ac t i on c a l l − j son−encoded∗/function ac t i on ( $va lues ) {return $th i s−>impl−>act i on ( $va lues ) ;}

/∗∗∗ Sets j a v a s c r i p t usage on or o f f∗ <p>∗ @param {Boolean} boolean − The value to s e t∗/function setJSEnabled ( $boolean ) {$th i s−>impl−>setJSEnabled ( $boolean ) ;}}?>

B.11 interface_framework_services.php

<?php/∗∗∗ in te r face_framework_serv ices . php i s part o f the "Framework

2.0"−Program∗ . . .∗/

/∗∗

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 94

∗ DESCRIPTION:∗ <br>∗ This I n t e r f a c e has to be implemented by each framework−

s e r v i c e .∗ <br>∗ I t ' s the main communication I n t e r f a c e f o r each framework−

s e r v i c e∗ in order to communicate with other Web Se rv i c e s∗/class in te r face_framework_serv ices {

/∗∗∗ Holds the i n t e r f a c e implementation∗/var $impl ;

/∗∗∗ Common funt i on to bind i n t e r f a c e implementat ions∗/function bindimpl ( $impl ) {$th i s−>impl =& $impl ;}

/∗∗∗ Returns the framework−s e r v i c e o f the c a l l e d s e r v i c e c l a s s∗ <p>∗ @return {JSON−St r ing } The framework−s e r v i c e array − j son−

encoded∗/function getFrameworkService ( ) {return $th i s−>impl−>getFrameworkService ( ) ;}

/∗∗∗ Cal l the s e r v i c e s ac t i on func t i on with a l l g iven data∗ <p>∗ @return {JSON−St r ing } The framework−s e r v i c e re sponse on the

ac t i on c a l l − j son−encoded∗/function ac t i on ( $va lues ) {return $th i s−>impl−>act i on ( $va lues ) ;}

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 95

/∗∗∗ Sets j a v a s c r i p t usage on or o f f∗ <p>∗ @param {Boolean} boolean − The value to s e t∗/function setJSEnabled ( $boolean ) {$th i s−>impl−>setJSEnabled ( $boolean ) ;}}?>

B.12 application_service.php

<?php/∗∗∗ app l i c a t i on_se rv i c e . php i s part o f the "Framework 2.0"−

Program∗ . . .∗/

class app l i c a t i on_se rv i c e {

/∗∗∗ General Used i n t e r f a c e s f o r app l i c a t i on−s e r v i c e s∗/var $interface_database_component ;var $ inte r face_update_serv i ce ;var $interface_user_component ;var $interface_json_component ;

/∗∗∗ Common bind method f o r i n t e r f a c e s∗/function bind ( $interfaceName , $impl ) {$th i s−>$interfaceName =& $impl ;}

/∗∗∗ General f i e l d s f o r app l i c a t i on−s e r v i c e s∗/var $ l ib_f i l ename ;

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 96

var $css_f i l ename ;var $ t i t l e ;var $html ;

var $service_namespace ;var $ l i b ;var $c s s ;var $ i n i t_ s e r v i c e ;

var $js_enabled ;

/∗∗∗ Constructor∗/function app l i c a t i on_se rv i c e ( ) {

/∗ Get main namespace f o r each app l i c a t i on−s e r v i c e ∗/$th i s−>service_namespace = 'http://' . $_SERVER[ 'HTTP_HOST' ] .

dirname ( $_SERVER[ 'SCRIPT_NAME' ] ) . '/services/application/' . get_class ( $ t h i s ) ;

/∗ Check i n i t s e r v i c e ∗/while ( f i le_exists ('services/application/' . get_class ( $ t h i s ) .

'/lib/init_service.js' ) && empty( $ th i s−>in i t_ s e r v i c e ) ) {/∗ Read i n i t s e r v i c e to s t r i n g ∗/$th i s−>in i t_ s e r v i c e = implode ("" , f i l e ('services/application/' .

get_class ( $ t h i s ) . '/lib/init_service.js' ) ) ;}

/∗ Check j a v a s c r i p t ∗/i f ( ( ! empty ( $ th i s−>l ib_f i l ename ) ) && f i le_exists ('services/

application/' . get_class ( $ t h i s ) . '/lib/' . $ th i s−>l ib_f i l ename . '.js' ) ) {

/∗ Read j a v a s c r i p t to s t r i n g ∗/while ( empty( $ th i s−>l i b ) ) {$th i s−>l i b = implode ("" , f i l e ('services/application/' .

get_class ( $ t h i s ) . '/lib/' . $ th i s−>l ib_f i l ename . '.js' ) ) ;}}

/∗ Set c s s path ∗/i f ( ! empty( $ th i s−>css_f i l ename ) ) {

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 97

$th i s−>cs s = $th i s−>service_namespace . '/css/' . $ th i s−>css_f i l ename . '.css' ;

}}

/∗∗∗ Returns the s e r v i c e s data encoded to JSON∗/function createWebserviceAgent ( ) {

/∗ Encode data f o r php usage ∗/i f ( ! $ th i s−>js_enabled ) {

/∗ Encode HTML to s p e c i a l c h a r s ∗/$th i s−>html = htmlspecialchars ( $ th i s−>html ) ;

/∗ Check i f a php l i b r a r y i s g iven ∗/$th i s−>l i b = '' ;i f ( f i le_exists ( 'server/services/application/' . get_class (

$ t h i s ) . '/lib/' . $ th i s−>l ib_f i l ename . '.php' ) ) {/∗ Create in c lude path ∗/$th i s−>l i b = 'server/services/application/' . get_class ( $ t h i s )

. '/lib/' . $ th i s−>l ib_f i l ename . '.php' ;}}

/∗ Create data array ∗/$data_array = array ('name' => get_class ( $ t h i s ) ,'title' => $th i s−>t i t l e ,'namespace' => $th i s−>service_namespace ,'css' => $th i s−>css ,'lib' => $th i s−>l ib ,'html' => $th i s−>html ,'init_service' => $th i s−>in i t_ s e r v i c e) ;

/∗ Encode data array to j son ∗/$encoded_data = $th i s−>interface_json_component−>encode (

$data_array ) ;

return $encoded_data ;

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 98

}

/∗∗∗ Implementation o f the i n t e r f a c e "

i n t e r f a c e_app l i c a t i o n_s e r v i c e s . php"∗/function getWebserviceAgent ( $js_enabled ) {/∗ This method has to be ove rwr i t t en by extending c l a s s e s ∗/return "getWebserviceAgent() - method not implemented" ;}

/∗∗∗ Implementation o f the i n t e r f a c e "

i n t e r f a c e_app l i c a t i o n_s e r v i c e s . php"∗/function ac t i on ( $va lues ) {/∗ This method has to be ove rwr i t t en by extending c l a s s e s ∗/return "action() - method not implemented" ;}

/∗∗∗ Implementation o f the i n t e r f a c e "

i n t e r f a c e_app l i c a t i o n_s e r v i c e s . php"∗/function setJSEnabled ( $boolean ) {$th i s−>js_enabled = $boolean ;}}?>

B.13 hello_world_service.php

<?php/∗∗∗ he l lo_wor ld_serv ice . php i s part o f the "Framework 2.0"−

Program∗ . . .∗/

class he l lo_wor ld_serv ice extends app l i c a t i on_se rv i c e {

/∗∗

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 99

∗ Constructor∗/function he l lo_wor ld_serv ice ( $ t i t l e ) {$th i s−>l ib_f i l ename = 'hello_world_service' ;$ th i s−>css_f i l ename = 'hello_world_service' ;$ th i s−>t i t l e = $ t i t l e ;$ th i s−>app l i c a t i on_se rv i c e ( ) ;}

/∗∗∗ Implementation o f the i n t e r f a c e "

i n t e r f a c e_app l i c a t i o n_s e r v i c e s . php"∗/function getWebserviceAgent ( ) {

/∗ Create HTML s t ru c tu r e ∗/$th i s−>html = '<a class="pagelink" href="client.php?function=

helloWorld&text=Hallo" onclick="helloWorld(\'Hallo\'); ' .'return false;">Hallo Welt!</a>' ;

/∗ Create and return Webservice−Agent ∗/return $th i s−>createWebserviceAgent ( ) ;

}

/∗∗∗ Implementation o f the i n t e r f a c e "

i n t e r f a c e_app l i c a t i o n_s e r v i c e s . php"∗/function ac t i on ( $va lues ) {

i f ( $va lues [ "action" ] == "getHelloWorldData" ) {$repeat = $va lues [ "repeat" ] ;$ t e s t = $va lues [ "text" ] ;

$ th i s−>html = "Hallo Welt Text: <br>" ;

$x = 0 ;while ( $x < $repeat ) {$th i s−>html .= $va lues [ "text" ] . "<br>" ;$x++;}

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 100

return $th i s−>createWebserviceAgent ( ) ;}}}?>

B.14 hello_world_service.js

/∗∗∗ he l lo_wor ld_serv ice . j s i s part o f the "Framework 2.0"−Program∗ . . .∗/

/∗ he l lo_wor ld_serv ice . j s ∗/function hel loWorld ( t ext ) {__CS_p_doRequest("hello_world_service" ,"getHelloWorldData&repeat=8&text=" + text ,"__CPS_p_refreshWebserviceAgent") ;}

B.15 /lib/hello_world_service.php

<?php/∗∗∗ he l lo_wor ld_serv ice . php i s part o f the "Framework 2.0"−

Program∗ . . .∗/

/∗ he l lo_wor ld_serv ice . php ∗/function hel loWorld ( $va lues ) {__CS_p_doRequest("hello_world_service" ,"getHelloWorldData&repeat=8&text=" .$va lues [ "text" ] ,"__CPS_p_refreshWebserviceAgent") ;}?>

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 101

B.16 hello_world_service.css

/∗∗∗ he l lo_wor ld_serv ice . c s s i s part o f the "Framework 2.0"−

Program∗ . . .∗/

/∗ he l lo_wor ld_serv ice . c s s ∗/a . page l ink {font−f ami ly : Verdana , Geneva , Ar ia l , He lve t i c a ;font−s i z e : 13px ;text−deco ra t i on : none ;c o l o r : #333399;}

a . page l ink : hover {font−f ami ly : Verdana , Geneva , Ar ia l , He lve t i c a ;font−s i z e : 15px ;text−deco ra t i on : none ;c o l o r : #666666;}

B.17 framework_service.php

<?php/∗∗∗ f ramework_service . php i s part o f the "Framework 2.0"−Program∗ . . .∗/

class f ramework_service {

/∗∗∗ Used i n t e r f a c e s f o r framework−s e r v i c e s∗/var $interface_database_component ;var $interface_user_component ;var $interface_json_component ;

/∗∗∗ Common bind method f o r i n t e r f a c e s

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 102

∗/function bind ( $interfaceName , $impl ) {$th i s−>$interfaceName =& $impl ;}

/∗∗∗ General f i e l d s f o r framework−s e r v i c e s∗/var $service_namespace ;var $c s s ;var $ l ib_f i l ename ;var $js_enabled ;

/∗∗∗ Constructor∗/function f ramework_service ( ) {/∗ Get main namespace f o r each framwork−s e r v i c e ∗/$th i s−>service_namespace = 'http://' . $_SERVER[ 'HTTP_HOST' ] .

dirname ( $_SERVER[ 'SCRIPT_NAME' ] ) . '/server/services/framework/' . get_class ( $ t h i s ) ;

}

/∗∗∗ Implementation o f the i n t e r f a c e " inter face_framework_serv ices

. php"∗/function getFrameworkService ( ) {

/∗ Encode data f o r php usage ∗/i f ( ! $ th i s−>js_enabled ) {/∗ Create in c lude path ∗/$include_path = $th i s−>service_namespace . '/lib/' . $ th i s−>

l ib_f i l ename . '.php' ;/∗ Create data array ∗/$data_array = array ('include_path' => $include_path ) ;}else {/∗ Get j a v a s c r i p t content ∗/while (empty( $ j a v a s c r i p t ) ) {/∗ Read j a v a s c r i p t to St r ing ∗/

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 103

$ j a v a s c r i p t = implode ("" , f i l e ('services/framework/' . get_class( $ t h i s ) . '/lib/' . $ th i s−>l ib_f i l ename . '.js' ) ) ;

}/∗ Create data array ∗/$data_array = array ('lib' => $ j a v a s c r i p t ) ;}

/∗ Encode data array to j son ∗/$encoded_data = $th i s−>interface_json_component−>encode (

$data_array ) ;

return $encoded_data ;}

/∗∗∗ Implementation o f the i n t e r f a c e " inter face_framework_serv ices

. php"∗/function setJSEnabled ( $boolean ) {$th i s−>js_enabled = $boolean ;}}?>

B.18 communication_service.php

<?php/∗∗∗ communication_service . php i s part o f the "Framework 2.0"−

Program∗ . . .∗/

class communication_service extends f ramework_service {

/∗∗∗ Constructor∗/function communication_service ( ) {$th i s−>framework_service ( ) ;$ th i s−>l ib_f i l ename = 'communication_service' ;}

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 104

}?>

B.19 composition_service.php

<?php/∗∗∗ compos i t ion_serv i ce . php i s part o f the "Framework 2.0"−

Program∗ . . .∗/

class compos i t ion_serv i ce extends f ramework_service {

/∗∗∗ Constructor∗/function compos i t ion_serv i ce ( ) {$th i s−>framework_service ( ) ;$ th i s−>l ib_f i l ename = 'composition_service' ;}}?>

B.20 configuration_service.php

<?php/∗∗∗ c on f i gu r a t i on_se rv i c e . php i s part o f the "Framework 2.0"−

Program∗ . . .∗/

class c on f i gu r a t i on_se rv i c e extends f ramework_service {

/∗∗∗ Constructor∗/function c on f i gu r a t i on_se rv i c e ( ) {$th i s−>framework_service ( ) ;$ th i s−>l ib_f i l ename = 'configuration_service' ;

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 105

}}?>

B.21 monitoring_service.php

<?php/∗∗∗ monitor ing_serv ice . php i s part o f the "Framework 2.0"−Program∗ . . .∗/

class monitor ing_serv ice extends f ramework_service {

/∗∗∗ Constructor∗/function monitor ing_serv ice ( ) {$th i s−>framework_service ( ) ;$ th i s−>l ib_f i l ename = 'monitoring_service' ;}}?>

B.22 subscriber_service.php

<?php/∗∗∗ sub s c r i b e r_s e rv i c e . php i s part o f the "Framework 2.0"−Program∗ . . .∗/

class sub s c r i b e r_s e rv i c e extends f ramework_service {

/∗∗∗ Constructor∗/function sub s c r i b e r_s e rv i c e ( ) {$th i s−>framework_service ( ) ;$ th i s−>l ib_f i l ename = 'subscriber_service' ;}

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 106

}?>

B.23 update_service.php

<?php/∗∗∗ update_service . php i s part o f the "Framework 2.0"−Program∗ . . .∗/

class update_service extends f ramework_service {

/∗∗∗ Constructor∗/function update_service ( ) {$th i s−>framework_service ( ) ;$ th i s−>l ib_f i l ename = 'update_service' ;}}?>

B.24 communication_service.js

/∗∗∗ communication_service . j s i s part o f the "Framework 2.0"−

Program∗ . . .∗/

/∗∗∗ I n i t communication s e r v i c e∗/function communicat ion_service__initService ( ) {/∗ Run fu r t h e r l o g i c ∗/__CS_x_run( ) ;}

/∗∗∗ Sta r t s a asynchronous HTTP−Request on the s e r v e r i n t e r f a c e

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 107

∗ <p>∗ @param { St r ing } service_name − The s e r v i c e name o f the

s e r v i c e to c a l l∗ @param { St r ing } ac t i on − Function name and parameters o f the

func t i on to c a l l∗ e . g . "

showTest&param_name=value " or "showTest"∗ @param { St r ing } r e c e i v e r − The func t i on which should r e c e i v e

the s e r v e r re sponse∗/function __CS_p_doRequest( service_name , act ion , r e c e i v e r ) {

/∗ Create communication s t a tu s i con ∗/var communication_status_icon = '<img id="img_loading_' +

__IS_p_SERVICE_NAMESPACE + '" src="images/loading.gif" title="LOADING DATA" width="17">' ;

i f (__IS_x_SERVICE_ADD_MENU_FLAG == 'true' ) {/∗ Adding communication i con ∗/__CPS_p_addControlButton( communication_status_icon , '

communication_icon' ) ;}else i f (__IS_p_SERVICE_NAMESPACE != '' ) {document . getElementsByTagName ('body' ) [ 0 ] . innerHTML =

communication_status_icon ;}

/∗ Create http reque s t v a r i a b l e ∗/var http_request = __IS_x_createHTTPRequestObject ( ) ;/∗ Set r e c e i v e func t i on ∗/http_request . onreadystatechange = function ( ) {__CS_x_receiveResponse ( http_request , r e c e i v e r ) ;} ;

/∗ Do http reque s t ∗/var requestURL = 'server/server.php?type=application_service&

service_name=' + service_name + '&action=' + act i on + '' ;http_request . open ('GET' , requestURL , t rue ) ;http_request . send ( nu l l ) ;}

/∗∗∗ Checks i f a l l needed s e r v i c e s are loaded

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 108

∗ <br>∗ − Sets s e r v i c e as f u l l y loaded∗/function __CS_x_run( ) {/∗ Set t h i s s e r v i c e as f u l l y loaded ∗/__IS_x_SERVICE_ARRAY[ 0 ] [ "communication_service" ] = true ;}

/∗∗∗ Checks load ing s t a tu s o f a running http reque s t∗ <p>∗ @param {Object } http_request − The http reque s t ob j e c t∗ @param { St r ing } r e c e i v e r − The func t i on to c a l l with the

s e r v e r s re sponse∗/function __CS_x_receiveResponse ( http_request , r e c e i v e r ) {

/∗ Process data on readyState 4 = FINISHED ∗/i f ( http_request . readyState == 4) {

/∗ Remove communication s t a tu s i con ∗/i f (__IS_x_SERVICE_ADD_MENU_FLAG == 'true' ) {/∗ Remove communication i con ∗/__CPS_p_removeControlButton ('communication_icon' ) ;}

/∗ Check i f data was r e c e i v ed without problems ∗/i f ( http_request . s t a tu s == 200) {

/∗ Cal l r e c e i v e r func t i on i f g iven ∗/i f ( r e c e i v e r != '' ) {/∗ Parse g iven JSON−St r ing to j a v a s c r i p t ∗/var decoded_obj = eva l ('(' + http_request . responseText + ')' ) ;window [ r e c e i v e r ] ( decoded_obj ) ;}}else {alert ('Problem during request occured!. Status: ' +

http_request . s t a tu s ) ;}}}

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 109

/∗∗∗ Loads a Webservice−Agent∗ <p>∗ @param { St r ing } service_name − The s e r v i c e name to c a l l∗ @param { St r ing } i n s e r t p l a c e − The i n s e r t p l a c e where to put

the Webservice−Agent∗ @param {Boolean} add_menu − The menu f l a g ( ' t rue ' i f menu

s h e l l be added )∗ @param { St r ing } r e c e i v e r − The func t i on to c a l l with the

Webservice−Agent data∗/function __CS_x_loadWebserviceAgentData ( service_name ,

i n s e r t p l a c e , add_menu , r e c e i v e r ) {

/∗ Create communication s t a tu s i con ∗/i f ( __CPS_x_getElementFromDOM( i n s e r t p l a c e ) && !

__CPS_x_getElementFromDOM('img_loading_' + in s e r t p l a c e ) ) {var load_span = document . createElement ('span' ) ;load_span . id = 'img_loading_' + in s e r t p l a c e ;load_span . innerHTML = '<img src="images/loading.gif" title="

LOADING DATA" width="17">' ;document . getElementById ( i n s e r t p l a c e ) . appendChild ( load_span ) ;}

/∗ Create http reque s t v a r i ab l e ∗/var http_request = __IS_x_createHTTPRequestObject ( ) ;/∗ Set r e c e i v e func t i on ∗/http_request . onreadystatechange = function ( ) {__CS_x_receiveWebserviceAgentData ( http_request , i n s e r t p l a c e ,

add_menu , r e c e i v e r ) ;} ;

/∗ Do http reque s t ∗/http_request . open ('GET' , 'server/server.php?type=

application_service&service_name=' + service_name , t rue ) ;http_request . send ( nu l l ) ;}

/∗∗∗ Rece ives s e r v e r r ep sonse s f o r Webservice−Agent r eque s t s∗ <p>

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 110

∗ @param {Object } http_request − The http reque s t ob j e c t∗ @param { St r ing } i n s e r t p l a c e − The i n s e r t p l a c e where to put

the Webservice−Agent∗ @param {Boolean} add_menu − The menu f l a g∗ @param { St r ing } r e c e i v e r − The func t i on to c a l l with the

Webservice−Agent data∗/function __CS_x_receiveWebserviceAgentData ( http_request ,

i n s e r t p l a c e , add_menu , r e c e i v e r ) {

/∗ Process data on readyState 4 = FINISHED ∗/i f ( http_request . readyState == 4) {

/∗ Create communication s t a tu s i con ∗/i f ( __CPS_x_getElementFromDOM('img_loading_' + in s e r t p l a c e ) )

{document . getElementById ( i n s e r t p l a c e ) . removeChild ( document .

getElementById ('img_loading_' + in s e r t p l a c e ) ) ;}

/∗ Check i f data was r e c e i v ed without problems ∗/i f ( http_request . s t a tu s == 200) {

/∗ Parse g iven JSON−St r ing to j a v a s c r i p t ∗/var data_array = eva l ('(' + http_request . responseText + ')' ) ;

/∗ Create Webservice−Agent ∗/var webservice_agent = new Object ( ) ;webservice_agent [ "css" ] = data_array .

c s s ;webservice_agent [ "lib" ] = data_array .

l i b ;webservice_agent [ "name" ] = data_array .

name ;webservice_agent [ "html" ] = data_array .

html ;webservice_agent [ "title" ] = data_array .

t i t l e ;webservice_agent [ "namespace" ] = encodeURI ( data_array .

namespace ) ;webservice_agent [ "init_service" ] = data_array .

i n i t_ s e r v i c e ;

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 111

/∗ Add given con f i g params ∗/webservice_agent [ "insertplace" ] = i n s e r t p l a c e ;webservice_agent [ "add_menu" ] = add_menu ;

/∗ Cal l g iven r e c e i v e r ∗/window [ r e c e i v e r ] ( webservice_agent ) ;}else {alert ('Problem during request occured!. Status: ' +

http_request . s t a tu s ) ;}}}

B.25 composition_service.js

/∗∗∗ compos i t ion_serv i ce . j s i s part o f the "Framework 2.0"−Program∗ . . .∗/

/∗ Pr ivate f i e l d s ∗/var __CPS_x_SERVICE_DATA = new Array ( ) ;

/∗∗∗ I n i t compos it ion s e r v i c e∗/function compos i t i on_serv i ce__in i tServ i ce ( ) {

/∗ Load needed s e r v i c e l a y e r s ∗/__IS_p_loadService ('communication_service' ) ;

/∗ I n i t f i e l d s ∗/__CPS_x_SERVICE_DATA[ 0 ] = new Object ( ) ;

/∗ Run fu r t h e r l o g i c ∗/__CPS_x_run( ) ;}

/∗∗∗ Adds a new Webservice−Agent

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 112

∗ <p>∗ @param { St r ing } service_name − The s e r v i c e name to c a l l∗ @param { St r ing } i n s e r t p l a c e − The i n s e r t p l a c e where to put

the Webservice−Agent∗ @param {Boolean} add_menu − The menu f l a g ( ' t rue ' i f menu

s h e l l be added )∗/function __CPS_p_addWebserviceAgent ( service_name , i n s e r t p l a c e ,

add_menu) {

/∗ Get Webservice−Agent data from s e rv e r and run__CPS_x_addWebserviceAgentToDOM func t i on ∗/

__CS_x_loadWebserviceAgentData ( service_name , i n s e r t p l a c e ,add_menu , '__CPS_x_addWebserviceAgentToDOM' ) ;

}

/∗∗∗ Removes an namespace from DOM∗ <p>∗ @param { St r ing } namespace − The namespace o f a s e r v i c e∗/function __CPS_p_removeNamespace( namespace ) {

/∗ Remove element i f e x i s t s ∗/i f ( __CPS_x_getElementFromDOM( namespace ) ) {

/∗ Get i n s e r t p l a c e ∗/var cu r r en t_ in s e r tp l a c e =__CPS_x_getNamespaceWindow( namespace ) .

__IS_x_SERVICE_INSERTPLACE;/∗ Remove Webservice−Agent from DOM ∗/__CPS_x_getElementFromDOM( cur r en t_ in s e r tp l a c e ) . removeChild (

__CPS_x_getElementFromDOM( namespace ) ) ;}}

/∗∗∗ Adds a new con t r o l button to namespace menu∗ <p>∗ @param { St r ing } html − The buttons HTML−Code∗ @param { St r ing } control_name − The buttons name∗/function __CPS_p_addControlButton( html , control_name ) {

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 113

/∗ Check i f c on t r o l s are enabled ∗/i f (__IS_x_SERVICE_ADD_MENU_FLAG == 'true' ) {/∗ Get con t r o l button document ∗/var control_button_document = __CPS_x_getNamespaceDocument('' ) ;/∗ Get con t r o l buttons span ∗/var control_buttons_span = control_button_document .

getElementById ("control_buttons_" + __IS_p_SERVICE_NAMESPACE) ;

/∗ Create c on t r o l button ∗/var control_button = control_button_document .

createElement ('span' ) ;control_button . id = "control_button_" +

control_name + "_" + __IS_p_SERVICE_NAMESPACE;control_button . innerHTML = html ;control_button . s e tAt t r i bu t e ("style" , "float: right; width: 18px

" ) ;

/∗ Add con t r o l button ∗/control_buttons_span . appendChild ( control_button ) ;

/∗ Set c on t r o l button s t y l e s ∗/var span = control_button_document . getElementById ("

control_button_" + control_name + "_" +__IS_p_SERVICE_NAMESPACE) ;

span . s t y l e . width = "18px" ;span . s t y l e . padding = "0px" ;span . s t y l e . margin = "0px" ;span . s t y l e . f l o a t = "right" ;}}

/∗∗∗ Removes an e x i s t i n g con t r o l button from namespace menu∗ <p>∗ @param { St r ing } control_name − The buttons name∗/function __CPS_p_removeControlButton ( control_name ) {

/∗ I f menu e x i s t s ∗/i f (__IS_x_SERVICE_ADD_MENU_FLAG == 'true' ) {

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 114

/∗ Get con t r o l button document ∗/var control_button_document = __CPS_x_getNamespaceDocument('' ) ;/∗ Get con t r o l buttons span ∗/var control_buttons_span = control_button_document .

getElementById ("control_buttons_" +__IS_p_SERVICE_NAMESPACE) ;

/∗ Get con t r o l button ∗/var control_button = control_button_document . getElementById ("

control_button_" + control_name + "_" +__IS_p_SERVICE_NAMESPACE) ;

/∗ Remove con t r o l button ∗/control_buttons_span . removeChild ( control_button ) ;}}

/∗∗∗ Add a new con t r o l panel to namespace∗ <p>∗ @param { St r ing } html − The pane l s HTML−Code∗ @param { St r ing } control_name − The pane l s name∗/function __CPS_p_addControlPanel ( html , control_name ) {

/∗ Check i f c on t r o l s are enabled ∗/i f (__IS_x_SERVICE_ADD_MENU_FLAG == 'true' ) {/∗ Get con t r o l button document ∗/var control_panel_document = __CPS_x_getNamespaceDocument('' ) ;/∗ Get con t r o l buttons span ∗/var control_panels_span = control_panel_document . getElementById

("control_panels_" + __IS_p_SERVICE_NAMESPACE) ;

/∗ Append con t r o l span ∗/var contro l_pane l = control_panel_document .

createElement ('span' ) ;contro l_pane l . id = control_name + "_" +

__IS_p_SERVICE_NAMESPACE;contro l_pane l . innerHTML = html ;control_panels_span . appendChild ( contro l_pane l ) ;

/∗ Set c on t r o l span s t y l e s ∗/

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 115

var span = control_panel_document . getElementById ( control_name +"_" + __IS_p_SERVICE_NAMESPACE) ;

span . s t y l e . d i sp l ay = "none" ;span . s t y l e . p o s i t i o n = "absolute" ;span . s t y l e . top = "30px" ;span . s t y l e . l e f t = "0px" ;span . s t y l e . border = "1px solid #000000" ;span . s t y l e . background = "#FFFFFF" ;}}

/∗∗∗ Shows or h ide s the panel with the g iven con t r o l name∗ <p>∗ @param { St r ing } panel_name − The pane l s name∗/function __CPS_p_showOrHidePanel ( panel_name ) {

/∗ Check i f panel e x i s t s ∗/i f ( document . getElementById ( panel_name ) ) {/∗ Get span o f panel by con t r o l name ∗/var span = document . getElementById ( panel_name ) ;/∗ Show or hide span ∗/i f ( span . s t y l e . d i sp l ay == "none" ) {span . s t y l e . d i sp l ay = "block" ;}else {span . s t y l e . d i sp l ay = "none" ;}}}

/∗∗∗ Ref re shs the g iven Webservice−Agent with new HTML−Code∗ <p>∗ @param {Object } webservice_agent − The Webservice−Agent to

r e f r e s h∗/function __CPS_p_refreshWebserviceAgent ( webservice_agent ) {

/∗ Refresh Webservice−Agent HTML with new data ∗/document . body . innerHTML = webservice_agent . html ;

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 116

/∗ Read new namespace he ight ∗/var new_height = document . body . s c r o l lH e i g h t ;

/∗ Set new namespace he ight to prevent s c r o l l i n g ∗/var my_iframe = __CPS_x_getNamespaceDocument('' ) . getElementById

("iframe_" + webservice_agent . namespace ) ;my_iframe . he ight = new_height ;}

/∗∗∗ Checks i f a l l needed s e r v i c e s are loaded∗ <br>∗ − Sets s e r v i c e as f u l l y loaded∗/function __CPS_x_run( ) {

/∗ Check i f a l l needed s e r v i c e s are loaded ∗/i f (__IS_x_SERVICE_ARRAY[ 0 ] [ "communication_service" ] != true ) {__IS_x_repeatFunctionCall ('__CPS_x_run()' , 200 , 100) ;}else {/∗ Set t h i s s e r v i c e as f u l l y loaded ∗/__IS_x_SERVICE_ARRAY[ 0 ] [ "composition_service" ] = true ;}}

/∗∗∗ Adds the g iven Webservice−Agent to the DOM∗ <br>∗ Creates a new namespace i f nece s sa ry∗ <p>∗ @param {Object } webservice_agent − The Webservice−Agent∗/function __CPS_x_addWebserviceAgentToDOM( webservice_agent ) {

/∗ Save Webservice−Agent to s e r v i c e data array ∗/__CPS_x_SERVICE_DATA[ 0 ] [ webservice_agent . namespace ] =

webservice_agent ;

/∗ Check i f namespace a l r eady e x i s t s ∗/

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 117

i f ( __CPS_x_getElementFromDOM( webservice_agent . namespace )) {

/∗ Get cur rent i n s e r t p l a c e ∗/var cu r r en t_ in s e r tp l a c e = __CPS_x_getNamespaceWindow(

webservice_agent . namespace ) .__IS_x_SERVICE_INSERTPLACE;/∗ Check i f namespace has to be moved ∗/i f ( cu r r en t_ in s e r tp l a c e != webservice_agent . i n s e r t p l a c e ) {/∗ Remove namespace from cur rent i n s e r t p l a c e ∗/var namespace = __CPS_x_getElementFromDOM( cur r en t_ in s e r tp l a c e

) . removeChild ( __CPS_x_getElementFromDOM( webservice_agent .namespace ) ) ;

/∗ Append namespace to new i n s e r t p l a c e ∗/__CPS_x_getElementFromDOM( webservice_agent . i n s e r t p l a c e ) .

appendChild ( namespace ) ;}

/∗ Refresh Webservice−Agent ∗/__CPS_x_getNamespaceWindow( webservice_agent . namespace ) .

__CPS_p_refreshWebserviceAgent ( webservice_agent ) ;}else {/∗ Create new namespace f o r Webservice−Agent ∗/__CPS_x_createNamespace ( webservice_agent ) ;}}

/∗∗∗ Creates a new namespace f o r the g iven Webservice−Agent∗ <p>∗ @param {Object } webservice_agent − The Webservice−Agent∗/function __CPS_x_createNamespace ( webservice_agent ) {

/∗ Get width o f i n s e r t p l a c e ∗/var serv ice_width = __CPS_x_getNamespaceWindow('' ) .

__IS_u_SERVICE_WIDTH[ webservice_agent . i n s e r t p l a c e ] ;

/∗ Create namespace ∗/var namespace = document . createElement ('span' ) ;/∗ Set namespace id ∗/namespace . id = webservice_agent . namespace ;

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 118

/∗ Create namespace HTML ∗/var html = '<span id="control_panels_' + webservice_agent .

namespace + '" style="position: relative; top: 0px; left: 0px"></span>' +

'<table width="' + service_width + '" cellspacing="0"cellpadding="0" border="0">' ;

/∗ Add con t r o l s i f nece s sa ry ∗/i f ( webservice_agent . add_menu == 'true' ) {html += '<tr>' +'<td class="controls_left">' + webservice_agent . t i t l e + '</td>'

+'<td class="controls_right" align="right">' +'<span id="control_buttons_' + webservice_agent . namespace + '">

' +'<span id="control_button_close" style="float: right; width: 18

px">' +' <img src="images/close_entity.gif" title="ANSICHT SCHLIESSEN"

alt="ANSICHT SCHLIESSEN" style="cursor: pointer"' +' onClick="__CPS_p_removeNamespace(\'' + webservice_agent .

namespace + '\');"></span>' +'</span>' +'</td>' +'</tr>' +'<tr>' +'<td><img src="images/spacer.gif" width="' + ( serv ice_width /

2) + '" height="0"></td>' +'<td><img src="images/spacer.gif" width="' + ( serv ice_width /

2) + '" height="0"></td>' +'</tr>' ;}

html += '<tr>' +'<td colspan="2">' +'<iframe width="' + service_width + '" height="20" frameborder

="no" scrolling="auto"' +' src="empty.html" onLoad="__CPS_x_initializeWebserviceAgent(\'

' + webservice_agent . namespace + '\');"' +' id="iframe_' + webservice_agent . namespace +'"></iframe>' +'</td>' +'</tr>' +'<tr>' +

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 119

'<td colspan="2"><img src="images/spacer.gif" height="10"></td>' +

'</tr>' +'</table>' ;

/∗ Set namespace HTML ∗/namespace . innerHTML = html ;

/∗ Append en t i t y to i n s e r t p l a c e ∗/i f ( __CPS_x_getElementFromDOM( webservice_agent . i n s e r t p l a c e )

) {__CPS_x_getElementFromDOM( webservice_agent . i n s e r t p l a c e ) .

appendChild ( namespace ) ;}else {alert ('Given insertplace doesn\'t exist: ' + webservice_agent .

i n s e r t p l a c e ) ;}}

/∗∗∗ I n i t i a l i z e s the Webservice−Agent f o r a g iven namespace∗ <br>∗ Adds CSS−Sty l e s , Java s c r i p t and HTML−Data to the

cor re spond ing DOM−Model∗ <br>∗ Runs __IS_p_initial ize−f unc t i on f o r the cor re spond ing

Webservice−Agent∗ <p>∗ @param { St r ing } namespace − The namespace o f a s e r v i c e∗/function __CPS_x_initializeWebserviceAgent ( namespace ) {

/∗ Read Webservice−Agent from data array ∗/var webservice_agent = __CPS_x_SERVICE_DATA[ 0 ] [ namespace ] ;

/∗ Get namespace document ∗/var namespace_document = __CPS_x_getNamespaceDocument(

namespace ) ;/∗ Get namespace window ∗/var iframe_window = __CPS_x_getNamespaceWindow( namespace ) ;

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 120

/∗ Add c s s s t y l e s h e e t ∗/var c s s_s ty l e = namespace_document . createElement ('link' ) ;c s s_s ty l e . r e l = "stylesheet" ;c s s_s ty l e . type = "text/css" ;c s s_s ty l e . h r e f = webservice_agent . c s s ;namespace_document . getElementsByTagName ('head' ) [ 0 ] . appendChild (

c s s_s ty l e ) ;

/∗ Add j a v a s c r i p t ∗/var j ava_scr ip t = namespace_document . createElement ('

script' ) ;j ava_scr ip t . language = "JavaScript" ;j ava_scr ip t . type = "text/javascript" ;j ava_scr ip t . t ex t = webservice_agent . l i b ;namespace_document . getElementsByTagName ('head' ) [ 0 ] . appendChild (

java_scr ip t ) ;

/∗ Add and In i t−Se rv i c e ∗/var i n i t_ s e r v i c e_s c r i p t = namespace_document . createElement

('script' ) ;i n i t_ s e r v i c e_s c r i p t . language = "JavaScript" ;i n i t_ s e r v i c e_s c r i p t . type = "text/javascript" ;i n i t_ s e r v i c e_s c r i p t . t ex t = webservice_agent . i n i t_ s e r v i c e ;namespace_document . getElementsByTagName ('head' ) [ 0 ] . appendChild (

i n i t_ s e r v i c e_s c r i p t ) ;

/∗ Set i f rame HTML ∗/namespace_document . body . innerHTML = webservice_agent . html ;

/∗ Read new namespace he ight ∗/var namespace_body = namespace_document . getElementsByTagName ('

body' ) [ 0 ] ;var new_height = namespace_body . s c r o l lH e i g h t ;

/∗ Set new namespace he ight to prevent s c r o l l i n g ∗/var my_iframe = document . getElementById ("iframe_" +

webservice_agent . namespace ) ;my_iframe . he ight = new_height ;

/∗ Set In i t−Se rv i c e f i e l d s ∗/iframe_window .__IS_p_SERVICE_NAMESPACE =

webservice_agent . namespace ;

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 121

iframe_window .__IS_x_SERVICE_NAME =webservice_agent . name ;

iframe_window .__IS_x_SERVICE_TITLE =webservice_agent . t i t l e ;

iframe_window .__IS_x_SERVICE_INSERTPLACE =webservice_agent . i n s e r t p l a c e ;

iframe_window .__IS_x_SERVICE_ADD_MENU_FLAG =webservice_agent . add_menu ;

/∗ I n i t i a l i z e s e r v i c e ∗/iframe_window [ "__IS_p_initialize" ] ( ) ;}

/∗∗∗ Returns the document o f a g iven namespace∗ <br>∗ − Should work with a l l Gecko−Engine Browsers and In t e rn e t

Explorer∗ <br>∗ − Testet with : FireFox 2 .0 and In t e rn e t Explorer 7∗ <p>∗ @param { St r ing } namespace − The namespace o f a s e r v i c e∗/function __CPS_x_getNamespaceDocument( namespace ) {

var IE = ( document . a l l ) ;var FF = ( ! document . a l l ) ;

/∗ Get document ∗/var objdoc ;i f ( IE ) {i f ( namespace == '' ) {objdoc = parent . document ;}else i f ( frames [ 'iframe_' + namespace ] ) {objdoc = frames [ 'iframe_' + namespace ] . document ;}}else i f (FF) {i f ( namespace == '' ) {objdoc = parent . document ;}

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 122

else i f ( document . getElementById ('iframe_' + namespace ) ) {objdoc = document . getElementById ('iframe_' + namespace ) .

contentDocument ;}}

return objdoc ;}

/∗∗∗ Returns the window o f a g iven namespace∗ <br>∗ − Should work with a l l Gecko−Engine Browsers and In t e rn e t

Explorer∗ <br>∗ − Testet with : FireFox 2 .0 and In t e rn e t Explorer 7∗ <p>∗ @param { St r ing } namespace − The namespace o f a s e r v i c e∗/function __CPS_x_getNamespaceWindow( namespace ) {

var IE = ( document . a l l ) ;var FF = ( ! document . a l l ) ;

/∗ Get document ∗/var objwin ;i f ( namespace == '' ) {objwin = parent ;}else {/∗ IE ∗/i f ( IE && parent . frames [ 'iframe_' + namespace ] ) {objwin = parent . frames [ 'iframe_' + namespace ] . document .

parentWindow ;}/∗ FF ∗/else i f ( FF && parent . document . getElementById ('iframe_' +

namespace ) ) {objwin = parent . document . getElementById ('iframe_' + namespace ) .

contentDocument . de faultView ;}}

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 123

return objwin ;}

/∗∗∗ Reads an ob j e c t from DOM by the g iven ID∗ <br>∗ − Should work with a l l Gecko−Engine Browsers and In t e rn e t

Explorer∗ <br>∗ − Testet with : FireFox 2 .0 and In t e rn e t Explorer 7∗ <p>∗ @param { St r ing } id − The elements id or name∗/function __CPS_x_getElementFromDOM( id ) {

var returnValue = nu l l ;

i f ( ! document ) {document = window . document ;}

i f ( id == 'body' ) {return document . body ;}

i f ( document . l a y e r s ) {f o r (var l = 0 ; l < document . l a y e r s . l ength ; l++) {i f ( document . l a y e r s [ l ] . id == id ) {return document . l a y e r s [ l ] ;}}

f o r (var l = 0 ; l < document . l a y e r s . l ength ; l++) {var r e s u l t = __CPS_x_getElementFromDOM( id , document . l a y e r s [ l ] .

document ) ;

i f ( r e s u l t ) {return r e s u l t ;}}return nu l l ;

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 124

}else i f ( document . a l l ) {return document . a l l [ id ] ;}else i f ( document . getElementById ) {

/∗ Try to get element by id ∗/returnValue = document . getElementById ( id ) ;

/∗ Try to get element by name ∗/i f ( returnValue == nu l l ) {returnValue = document . getElementsByName ( id ) [ 0 ] ;}

return returnValue ;}

return f a l s e ;}

B.26 configuration_service.js

/∗∗∗ c on f i gu r a t i on_se rv i c e . j s i s part o f the "Framework 2.0"−

Program∗ . . .∗/

/∗∗∗ I n i t c on f i g u r a t i on s e r v i c e∗/function con f i gu ra t i on_se rv i c e__in i tSe rv i c e ( ) {

/∗ load needed s e r v i c e l a y e r s ∗/__IS_p_loadService ('composition_service' ) ;__IS_p_loadService ('communication_service' ) ;

/∗ run f u r t h e r l o g i c ∗/__SCS_x_run( ) ;}

/∗∗

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 125

∗ Loads the s t a r t c on f i g u r a t i on from s e rv e r∗/function __SCS_p_loadStartConfiguration ( ) {/∗ Star t c on f i g u r a t i on load ing ∗/__CS_p_doRequest('configuration_service' , '

getStartConfiguration' , '__SCS_x_loadConfigurationServices' );

}

/∗∗∗ Checks i f a l l needed s e r v i c e s are loaded∗ <br>∗ − Sets s e r v i c e as f u l l y loaded∗/function __SCS_x_run( ) {

/∗ Check i f a l l needed s e r v i c e s are loaded ∗/i f (__IS_x_SERVICE_ARRAY[ 0 ] [ "composition_service" ] != true| | __IS_x_SERVICE_ARRAY[ 0 ] [ "communication_service" ] != true ) {__IS_x_repeatFunctionCall ('__SCS_x_run()' , 200 , 100) ;}else {/∗ Set t h i s s e r v i c e as f u l l y loaded ∗/__IS_x_SERVICE_ARRAY[ 0 ] [ "configuration_service" ] = true ;/∗ Load s t a r t c on f i g u r a t i on ∗/__SCS_p_loadStartConfiguration ( ) ;}}

/∗∗∗ Rece ives c on f i g u r a t i on data from s e rv e r and loads the g iven

Webservice−Agents∗ <p>∗ @param {Object } start_conf ig_data − The con f i g u r a t i on data∗/function __SCS_x_loadConfigurationServices ( start_conf ig_data ) {

/∗ Load given Webservice−Agents ∗/f o r (var arrayIndex in start_conf ig_data ) {window . setTimeout ("__CPS_p_addWebserviceAgent(\"" +

start_conf ig_data [ arrayIndex ] . service_name + "\",\"" +

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 126

start_conf ig_data [ arrayIndex ] . i n s e r t p l a c e + "\",\"" +start_conf ig_data [ arrayIndex ] . add_menu + "\")" , 20 ) ;

}}

B.27 monitoring_service.js

/∗∗∗ monitor ing_serv ice . j s i s part o f the "Framework 2.0"−Program∗ . . .∗/

/∗∗∗ Var iab le to save the event h i s t o r y∗/var __MS_x_EVENTS = '' ;

/∗∗∗ I n i t moni tor ing_serv ice∗/function monitor ing_serv i ce__in i tServ i ce ( ) {

/∗ Load needed s e r v i c e l a y e r s ∗/__IS_p_loadService ('composition_service' ) ;

/∗ Run fu r t h e r l o g i c ∗/__MS_x_run( ) ;}

/∗∗∗ Adds a new message to the event h i s t o r y∗ <br>∗ Creates a new l i n e with the format : timestamp (dd .mm. yyyy ) +

message∗ <p>∗ @param { St r ing } message − The event message to save∗/function __MS_p_addEvent( message ) {

/∗ Get timestamp ∗/var timestamp = __MS_x_getTimestamp( ) ;

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 127

/∗ Add event ∗/__MS_x_EVENTS += "<br>" + timestamp + " - "+ message ;/∗ Add event to view ∗/__CPS_x_getNamespaceDocument('' ) . getElementById ('

monitored_events_' + __IS_p_SERVICE_NAMESPACE) . innerHTML =__MS_x_EVENTS;

}

/∗∗∗ Returns the __MS_x_EVENTS∗/function __MS_p_getEvents ( ) {return __MS_x_EVENTS;}

/∗∗∗ Checks i f a l l needed s e r v i c e s are loaded∗ <br>∗ − Sets s e r v i c e as f u l l y loaded∗/function __MS_x_run( ) {

/∗ Check i f a l l needed s e r v i c e s are loaded ∗/i f (__IS_x_SERVICE_ARRAY[ 0 ] [ "composition_service" ] != true ) {/∗ Retry a f t e r 0 ,2 seconds ∗/__IS_x_repeatFunctionCall ('__MS_x_run()' , 200 , 100) ;}else {/∗ add update c on t r o l s ∗/__MS_x_addMonitoringControls ( ) ;

/∗ Set t h i s s e r v i c e as f u l l y loaded ∗/__IS_x_SERVICE_ARRAY[ 0 ] [ "monitoring_service" ] = true ;}}

/∗∗∗ Adds the monitoring−button and −panel to the view∗/function __MS_x_addMonitoringControls ( ) {

/∗ Create monitor ing button ∗/

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 128

var monitoring_control_button = '<img id="img_monitoring_' +__IS_p_SERVICE_NAMESPACE + '" style="cursor: pointer" src="images/history.gif" title="AUFGEZEICHNETE EREIGNISSEEINBLENDEN" alt="AUFGEZEICHNETE EREIGNISSE EINBLENDEN" width="17" onClick="__CPS_p_showOrHidePanel(\'monitoring_panel_'+ __IS_p_SERVICE_NAMESPACE + '\');">' ;

/∗ Create monitor ing panel ∗/var monitor ing_control_panel = '<table width="' + (

__CPS_x_getNamespaceWindow('' ) .__IS_u_SERVICE_WIDTH[__IS_x_SERVICE_INSERTPLACE] − 2) + '" cellpadding="2"cellspacing="0" border="0">' +

'<tr>' +'<td class="normaltext"><strong>AUFGEZEICHNETE EREIGNISSE </

strong></td>' +'<td align="right"><img src="images/close_entity.gif" style="

cursor: pointer" title="AUFGEZEICHNETE EREIGNISSE AUSBLENDEN" alt="AUFGEZEICHNETE EREIGNISSE AUSBLENDEN" onClick="__CPS_p_showOrHidePanel(\'monitoring_panel_' +__IS_p_SERVICE_NAMESPACE + '\');"></td>' +

'</tr>' +'<tr>' +'<td colspan="2" class="normaltext" valign="top">' +'<span id="monitored_events_' + __IS_p_SERVICE_NAMESPACE + '

"></span>' +'</td>' +'</tr>' +'</table>' ;

/∗ Add monitor ing button ∗/__CPS_p_addControlButton( monitoring_control_button , '

monitoring_button' ) ;/∗ Add monitor ing panel ∗/__CPS_p_addControlPanel ( monitoring_control_panel , '

monitoring_panel' )

}

/∗∗∗ Return the cur rent Timestamp∗/function __MS_x_getTimestamp( ) {

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 129

/∗ Get timestamp ∗/var myDate = new Date ( ) ;var day = '' + myDate . getDate ( ) ;var month = '' + (myDate . getMonth ( ) + 1) ;var year = '' + myDate . getFul lYear ( ) ;var hour = '' + myDate . getHours ( ) ;var minute = '' + myDate . getMinutes ( ) ;var second = '' + myDate . getSeconds ( ) ;

/∗ Add zero to day ∗/i f ( day . l ength < 2) {day = '0' + day ;}/∗ Add zero to month ∗/i f (month . l ength < 2) {month = '0' + month ;}/∗ Add zero to hour ∗/i f ( hour . l ength < 2) {hour = '0' + hour ;}/∗ Add zero to minute ∗/i f ( minute . l ength < 2) {minute = '0' + minute ;}/∗ Add zero to second ∗/i f ( second . l ength < 2) {second = '0' + second ;}

/∗ Concatenate timestamp ∗/var timestamp = day + '.' +month + '.' +year + ' ' +hour + ':' +minute + ':' +second ;

return timestamp ;}

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 130

B.28 subscriber_service.js

/∗∗∗ sub s c r i b e r_s e rv i c e . j s i s part o f the "Framework 2.0"−Program∗ . . .∗/

/∗ Pr ivate F i e l d s ∗/var __SS_x_RELAY_FUNCTIONS = new Array ( ) ;var __SS_x_SUBSCRIBED_FUNCTIONS = new Array ( ) ;

/∗∗∗ I n i t s ub s c r i b e r s e r v i c e∗/function subs c r i b e r_se rv i c e__in i tSe rv i c e ( ) {

/∗ Load needed s e r v i c e l a y e r s ∗/__IS_p_loadService ('composition_service' ) ;/∗ i n i t f i e l d s ∗/__SS_x_RELAY_FUNCTIONS[ 0 ] = new Object ( ) ;__SS_x_SUBSCRIBED_FUNCTIONS[ 0 ] = new Object ( ) ;/∗ Star t f u r t h e r l o g i c ∗/__SS_x_run( ) ;}

/∗∗∗ Creates a component−binding between two namespaces∗ <br>∗ The prov ide r can c a l l the g iven func t i on " func " , the c a l l

w i l l be r e l ayed to the implementation∗ o f " func " on the sub s c r i b e r∗ <p>∗ @param { St r ing } provider_namespace − Namespace o f prov ide r∗ @param { St r ing } func − Function name in c l ud ing parameters − e

. g . s e t S t a r t ( s ta r t_id ) or g e tS ta r t ( )∗ @param { St r ing } subscriber_namespace − Namespace o f

s ub s c r i b e r∗/function __SS_p_addRelayFunction ( provider_namespace , func ,

subscriber_namespace ) {

/∗ Save sub s c r i p t i o n ∗/

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 131

var s ub s c r i p t i o n = new Object ( ) ;s ub s c r i p t i o n [ "provider" ] = provider_namespace ;s ub s c r i p t i o n [ "func" ] = func ;s ub s c r i p t i o n [ "subscriber" ] = subscriber_namespace ;__SS_x_SUBSCRIBED_FUNCTIONS [ 0 ] [ provider_namespace + '|_|' +

func + '|_|' + subscriber_namespace ] = sub s c r i p t i o n ;

/∗ Create func t i on s c r i p t ∗/var s c r i p t = 'function ' + func + ' {\n' +'var win = __CPS_x_getNamespaceWindow(\'' +

subscriber_namespace + '\');\n' +'if (!win) {\n' +'var default_function = __SS_x_RELAY_FUNCTIONS[0][\'' + func +

'\'];\n' +'default_function' + __SS_x_getFunctionParemeters ( func ) + ';\n'

+'}\n' +'else {\n' +'win.' + func + ';\n' +'}\n' +'}' ;

/∗ Save d e f au l t func t i on ∗/var provider_window = __CPS_x_getNamespaceWindow(

provider_namespace ) ;var function_name = __SS_x_getFunctionName( func ) ;var de fau l t_funct i on = provider_window [ function_name ] ;

/∗ Create new ob j e c t f o r r e l a y func t i on s i f needed ∗/i f ( provider_window .__SS_x_RELAY_FUNCTIONS[ 0 ] == nu l l ) {provider_window .__SS_x_RELAY_FUNCTIONS[ 0 ] = new Object ( ) ;}/∗ Only save the r e a l d e f au l t func t i on ∗/i f ( provider_window .__SS_x_RELAY_FUNCTIONS[ 0 ] [ func ] == nu l l ) {provider_window .__SS_x_RELAY_FUNCTIONS[ 0 ] [ func ] =

de fau l t_funct i on ;}

/∗ Get producer document ∗/var provider_document = __CPS_x_getNamespaceDocument(

provider_namespace ) ;/∗ Add j s ∗/

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 132

var j a v a s c r i p t = provider_document . createElement ('script' ) ;

j a v a s c r i p t . language = "JavaScript" ;j a v a s c r i p t . type = "text/javascript" ;j a v a s c r i p t . t ex t = s c r i p t ;provider_document . getElementsByTagName ('head' ) [ 0 ] . appendChild (

j a v a s c r i p t ) ;}

/∗∗∗ Checks i f a l l needed s e r v i c e s are loaded∗ <br>∗ − Sets s e r v i c e as f u l l y loaded∗/function __SS_x_run( ) {

/∗ Check i f a l l needed s e r v i c e s are loaded ∗/i f (__IS_x_SERVICE_ARRAY[ 0 ] [ "composition_service" ] != true ) {/∗ Retry a f t e r 0 ,2 seconds ∗/__IS_x_repeatFunctionCall ('__SS_x_run()' , 200 , 100) ;}else {/∗ Set t h i s s e r v i c e as f u l l y loaded ∗/__IS_x_SERVICE_ARRAY[ 0 ] [ "subscriber_service" ] = true ;

/∗ Check f o r open sub s c r i p t i o n s ∗/i f (__CPS_x_getNamespaceWindow('' ) .__IS_x_SERVICE_ARRAY[ 0 ] [ "

subscriber_service" ] == true ) {__CPS_x_getNamespaceWindow('' ) . __SS_x_checkOpenSubscriptions(__IS_p_SERVICE_NAMESPACE) ;

}}}

/∗∗∗ Ensures that e x i s t i n g s ub s c r i p t i o n s w i l l be f un c t i o n a l∗ even i f the prov ide r namespace was d e l e t e t and added again∗ <p>∗ @param {Object } namespace∗/function __SS_x_checkOpenSubscriptions ( namespace ) {/∗ Run through kown sub s c r i p t i o n ∗/f o r ( i d e n t i f i e r in __SS_x_SUBSCRIBED_FUNCTIONS[ 0 ] ) {

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 133

var i d e n t i f i e r _ s p l i t = i d e n t i f i e r . s p l i t ("|_|" ) ;i f ( i d e n t i f i e r _ s p l i t [ 0 ] == namespace ) {var s ub s c r i p t i o n = __SS_x_SUBSCRIBED_FUNCTIONS [ 0 ] [ i d e n t i f i e r ] ;__SS_p_addRelayFunction ( s ub s c r i p t i o n [ "provider" ] , s ub s c r i p t i o n [ "

func" ] , s ub s c r i p t i o n [ "subscriber" ] ) ;}}}

/∗∗∗ Returns the func t i on name without bracket s and parameters∗ <p>∗ @param { St r ing } fu l l_ func t i on_s t r i ng − The func t i on St r ing −

e . g . getTest ( ) getTest (param)∗/function __SS_x_getFunctionName( fu l l_ func t i on_s t r i ng ) {

/∗ Sp l i t f unc t i on s t r i n g by opening bracket ∗/var funct ion_parts = fu l l_ func t i on_s t r i ng . s p l i t ("(" ) ;/∗ Return func t i on name ∗/return funct ion_parts [ 0 ] ;}

/∗∗∗ Returns the func t i on parameters with bracket s∗ <p>∗ @param { St r ing } fu l l_ func t i on_s t r i ng − The func t i on St r ing −

e . g . getTest ( ) getTest (param)∗/function __SS_x_getFunctionParemeters ( f u l l_ func t i on_s t r i ng ) {

/∗ Sp l i t f unc t i on s t r i n g by opening bracket ∗/var funct ion_parts = fu l l_ func t i on_s t r i ng . s p l i t ("(" ) ;/∗ Return func t i on parameters with bracket s ∗/return '(' + funct ion_parts [ 1 ] ;}

B.29 update_service.js

/∗∗∗ update_service . j s i s part o f the "Framework 2.0"−Program∗ . . .

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 134

∗/

/∗ Pr ivate F i e l d s ∗/var __US_x_UPDATE_RUNNING = f a l s e ;var __US_x_DO_UPDATE = f a l s e ;

/∗∗∗ I n i t update_service∗/function update_serv ice__in i tServ ice ( ) {

/∗ Load needed s e r v i c e l a y e r s ∗/__IS_p_loadService ('communication_service' ) ;__IS_p_loadService ('composition_service' ) ;__IS_p_loadService ('monitoring_service' ) ;

/∗ Star t f u r t h e r l o g i c ∗/__US_x_run( ) ;}

/∗∗∗ Sta r t s p o l l i n g events in the g iven i n t e r v a l l∗ <p>∗ @param { in t } i n t e r v a l l − the p o l l i n g i n t e r v a l l in seconds∗/function __US_p_startUpdatePolling ( i n t e r v a l l ) {

__US_x_DO_UPDATE = true ;

/∗ Set update s t a tu s images ∗/__CPS_x_getNamespaceWindow('' ) . __CPS_p_showOrHidePanel ('

img_stop_polling_' + __IS_p_SERVICE_NAMESPACE) ;__CPS_x_getNamespaceWindow('' ) . __CPS_p_showOrHidePanel ('

img_stop_polling_config_' + __IS_p_SERVICE_NAMESPACE) ;__CPS_x_getNamespaceWindow('' ) . __CPS_p_showOrHidePanel ('

img_start_polling_' + __IS_p_SERVICE_NAMESPACE) ;__CPS_x_getNamespaceWindow('' ) . __CPS_p_showOrHidePanel ('

img_start_polling_config_' + __IS_p_SERVICE_NAMESPACE) ;

/∗ Star t p o l l i n g ∗/__US_x_startUpdatePolling ( i n t e r v a l l ) ;}

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 135

/∗∗∗ Stops p o l l i n g events∗/function __US_p_stopUpdatePolling ( ) {

__US_x_DO_UPDATE = f a l s e ;

/∗ Set update s t a tu s images ∗/__CPS_x_getNamespaceWindow('' ) . __CPS_p_showOrHidePanel ('

img_stop_polling_' + __IS_p_SERVICE_NAMESPACE) ;__CPS_x_getNamespaceWindow('' ) . __CPS_p_showOrHidePanel ('

img_stop_polling_config_' + __IS_p_SERVICE_NAMESPACE) ;__CPS_x_getNamespaceWindow('' ) . __CPS_p_showOrHidePanel ('

img_start_polling_' + __IS_p_SERVICE_NAMESPACE) ;__CPS_x_getNamespaceWindow('' ) . __CPS_p_showOrHidePanel ('

img_start_polling_config_' + __IS_p_SERVICE_NAMESPACE) ;}

/∗∗∗ Writes a new monitor ing event and r e l o ad s the Webservice−

Agent∗/function __US_p_update ( ) {/∗ Write h i s t o r y entry ∗/__MS_p_addEvent('Update Service :: Updated: ' +

__IS_x_SERVICE_TITLE) ;/∗ Load Webservice−Agent data ∗/__CS_x_loadWebserviceAgentData (__IS_x_SERVICE_NAME,

__IS_x_SERVICE_INSERTPLACE, __IS_x_SERVICE_ADD_MENU_FLAG, '__CPS_p_refreshWebserviceAgent' ) ;

}

/∗∗∗ Checks i f a l l needed s e r v i c e s are loaded∗ <br>∗ − Sets s e r v i c e as f u l l y loaded∗/function __US_x_run( ) {

/∗ Check i f a l l needed s e r v i c e s are loaded ∗/i f (__IS_x_SERVICE_ARRAY[ 0 ] [ "communication_service" ] != true

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 136

| | __IS_x_SERVICE_ARRAY[ 0 ] [ "composition_service" ] != true| | __IS_x_SERVICE_ARRAY[ 0 ] [ "monitoring_service" ] != true ) {/∗ Retry a f t e r 0 ,2 seconds ∗/__IS_x_repeatFunctionCall ('__US_x_run()' , 200 , 100) ;}else {/∗ Add update c on t r o l s ∗/__US_x_addUpdateControls ( ) ;/∗ Set t h i s s e r v i c e as f u l l y loaded ∗/__IS_x_SERVICE_ARRAY[ 0 ] [ "update_service" ] = true ;}}

/∗∗∗ Sta r t s p o l l i n g events in the g iven i n t e r v a l l∗ <br>∗ Reinvokes a f t e r the g iven i n t e r v a l l∗ <p>∗ @param { in t } i n t e r v a l l − The po l l i n g i n t e r v a l l in seconds∗/function __US_x_startUpdatePolling ( i n t e r v a l l ) {

/∗ Just go on i f __US_x_DO_UPDATE i s s t i l l t rue ∗/i f (__US_x_DO_UPDATE) {/∗ Just r e c e i v e update data i f no other update r eque s t i s s t i l l

on the run ∗/i f (__US_x_UPDATE_RUNNING == f a l s e ) {/∗ Set update s t a tu s to running ∗/__US_x_setUpdateStatus ( t rue ) ;/∗ Get update data ∗/var http_request = __CS_p_doRequest('update_service' , '

getUpdates&namespace=' + __IS_p_SERVICE_NAMESPACE, '__US_x_receiveUpdateData' ) ;

}

/∗ Restart update ∗/window . setTimeout ("__US_x_startUpdatePolling(" + i n t e r v a l l + ")

" , i n t e r v a l l ∗ 1000) ;}}

/∗∗

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 137

∗ Adds the update c on t r o l s to the view∗/function __US_x_addUpdateControls ( ) {

/∗ Get p o l l i n g c on f i g ∗/var d i sp l ay_sta r t_po l l i ng = 'block' ;var di sp lay_stop_pol l ing = 'none' ;var standard_update_time = '10' ;

/∗ Create update button ∗/var update_control_button ='<img id="img_stop_polling_' +__IS_p_SERVICE_NAMESPACE +'" src="images/stop_polling.gif" title="UPDATE KONFIGURATION

EINBLENDEN" alt="UPDATE KONFIGURATION EINBLENDEN" width="17"style="display: ' +

disp lay_stop_pol l ing + '; cursor: pointer"onClick="__CPS_p_showOrHidePanel(\'update_panel_' +

__IS_p_SERVICE_NAMESPACE + '\');"><img src="images/start_polling.gif" id="img_start_polling_' +__IS_p_SERVICE_NAMESPACE +'" title="UPDATE KONFIGURATION EINBLENDEN" alt="UPDATE

KONFIGURATION EINBLENDEN" width="17"style="display: ' +di sp l ay_sta r t_po l l i ng +'; cursor: pointer" onClick="__CPS_p_showOrHidePanel(\'

update_panel_' +__IS_p_SERVICE_NAMESPACE +'\');">' ;

/∗ Create update panel ∗/var upate_control_panel ='<form name="update_controls_' +__IS_p_SERVICE_NAMESPACE + '"/>' +'<div>' +'<table width="' +(__CPS_x_getNamespaceWindow('' ) .__IS_u_SERVICE_WIDTH[

__IS_x_SERVICE_INSERTPLACE] − 2) + '" cellpadding="2"cellspacing="0" border="0">' +

'<tr>' +'<td class="normaltext"><strong>UPDATE KONFIGURATION </strong></

td>' +

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 138

'<td align="right"><img src="images/close_entity.gif" style="cursor: pointer" onClick="__CPS_p_showOrHidePanel(\'update_panel_' + __IS_p_SERVICE_NAMESPACE + '\');"></td>' +

'</tr>' +'<tr>' +'<td><img src="images/spacer.gif" height="5"></td>' +'<td><img src="images/spacer.gif" height="5" width="' + (

__CPS_x_getNamespaceWindow('' ) .__IS_u_SERVICE_WIDTH[__IS_x_SERVICE_INSERTPLACE] / 2) + '"></td>' +

'</tr>' +'<tr>' +'<td class="normaltext" valign="top">' +'Update-Intervall in Sekunden: <input id="form_field" type="

text" size="5" name="update_time" value="' +standard_update_time + '">' +

'</td>' +'<td align="left">' +'<img id="img_stop_polling_config_' + __IS_p_SERVICE_NAMESPACE

+ '" src="images/stop_polling.gif" title="AUTOMATISCHESUPDATE BEENDEN" alt="AUTOMATISCHES UPDATE BEENDEN" width="17" style="display: ' + disp lay_stop_pol l ing + '; cursor:pointer" onClick="__CPS_x_getNamespaceWindow(\'' +__IS_p_SERVICE_NAMESPACE + '\').__US_p_stopUpdatePolling();">' +

'<img id="img_start_polling_config_' + __IS_p_SERVICE_NAMESPACE+ '" src="images/start_polling.gif" title="AUTOMATISCHESUPDATE STARTEN" alt="AUTOMATISCHES UPDATE STARTEN" width="17" style="display: ' + di sp l ay_sta r t_po l l i ng + '; cursor:pointer" onClick="__CPS_x_getNamespaceWindow(\'' +

__IS_p_SERVICE_NAMESPACE + '\').__US_p_startUpdatePolling(document.getElementsByName(\'update_controls_' +__IS_p_SERVICE_NAMESPACE + '\')[0].update_time.value );">' +

'</td>' +'</tr>' +'<tr>' +'<td colspan="2" class="normaltext">' +'<input type="radio" name="update_type" value="ask">Vor dem

Aktualisieren nachfragen <br>' +'<input type="radio" name="update_type" value="quiet" checked>

Im Hintergrund aktualisieren' +'</td>' +'</tr>' +

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 139

'</table>' +'</div>' +'</form>' ;

/∗ Add update button ∗/__CPS_p_addControlButton( update_control_button , 'update_button'

) ;/∗ Add update panel ∗/__CPS_p_addControlPanel ( upate_control_panel , 'update_panel' )}

/∗∗∗ Sets the g l oba l v a r i a b l e __US_x_UPDATE_RUNNING to the g iven

value∗ <p>∗ @param {Boolean} running_boolean = True on update cu r r en t l y

running∗/function __US_x_setUpdateStatus ( running_boolean ) {__US_x_UPDATE_RUNNING = running_boolean ;}

/∗∗∗ Rece ives the ac tua l update date and checks i f a r e f r e s h i s

needed∗ <p>∗ @param {Object } update_data∗/function __US_x_receiveUpdateData ( update_data ) {

/∗ Just update i f new data i s a v a i l a b l e ∗/i f ( update_data . updated == true ) {

/∗ Create he lpe r var ∗/var update = true ;/∗ Ask user i f he wants to update − Only i f checked ∗/i f ( __CPS_x_getNamespaceDocument('' ) . getElementsByName ('

update_controls_' + __IS_p_SERVICE_NAMESPACE + '' ) [ 0 ] .update_type [ 0 ] . checked ) {

/∗ Ask i f namespace should be r e f r e s h ed ∗/update = conf i rm ('New data available for: ' +

__IS_x_SERVICE_TITLE + '\nDo you want to update?' ) ;

Diplomarbeit von Benedikt Schwinkendorf

B Quellcode 140

}

/∗ Update namespace i f wanted ∗/i f ( update == true ) {__US_p_update ( ) ;}}

/∗ Set update s t a tu s to pending ∗/__US_x_setUpdateStatus ( f a l s e ) ;}

Diplomarbeit von Benedikt Schwinkendorf

Eidesstattliche Erklärung 141

Eidesstattliche Erklärung

Hiermit versichere ich, die vorliegende Arbeit selbstständig und unter ausschließlicherVerwendung der angegebenen Literatur und Hilfsmittel erstellt zu haben.

Die Arbeit wurde bisher in gleicher oder ähnlicher Form keiner anderen Prüfungsbehördevorgelegt und auch nicht veröffentlicht.

Heilbronn, 31. Januar 2007Unterschrift

Diplomarbeit von Benedikt Schwinkendorf


Recommended