Web-Framework für Medien-Mix

Apache Cocoon bietet eine flexible Möglichkeit, Inhalte für die verschiedensten Medien vom Browser bis zum PDF aufzubereiten.

Artikel erschienen in Swiss IT Magazine 2007/11

     

Apache Cocoon ist ein Projekt, das etwas zwischen den Stühlen sitzt. Prinzipiell man kann es als Web-Framework bezeichnen, doch unterscheidet es sich konzeptionell recht stark von anderen Apache Web-Frameworks wie myFaces, Struts oder Tapestry. Denn Apache Cocoon kann nicht nur fürs Web, sondern auch für Cross-Publishing-Problemlösungen sowie für die Integration von Systemen über XML-Protokolle eingesetzt werden.
Cocoon ist eine Java-Servlet-Anwendung. Das heisst, es wird ein Servlet-Container wie Tomcat oder Jetty benötigt, um Cocoon als Server laufen zu lassen. Cocoon kümmert sich «nur» um die Verarbeitung von Anfragen an den Server sowie die Bereitstellung einer Antwort, die dann vom Server gesendet wird. Dieser Request-Response-Zyklus wird über eine sogenannte Sitemap abgearbeitet.


Die Cocoon-Sitemap

Die Cocoon-Sitemap ist die zentrale Steuereinheit einer Cocoon-Anwendung – egal, ob es sich «nur» um ein Publishing-Projekt oder eine ausgewachsene Webapplikation handelt. In der Sitemap werden Requests entsprechend der URL auf sogenannte Pipelines abgebildet. Eine Pipeline ist ein Sitemap-Abschnitt, der sich um einen bestimmten Request-Response-Zyklus kümmert.


Die Abbildung der URLs auf die Pipelines erfolgt mit Mustern, die ähnlich wie reguläre Ausdrücke mit Wildcards versehen werden können, um mehrere URLs auf eine einzige Pipeline abzubilden.
Innerhalb einer Pipeline wird dann mit der Hilfe von Pipeline-Komponenten bestimmt, wie der Request konkret behandelt werden soll. Wie dies genau geht, zeigt folgendes Beispiel, bei dem Anfragen auf den Pfad /dokumente/artikel1234.pdf behandelt werden:













<map:match pattern="dokumente/artikel*.html">
<map:generate type="file" src="artikel-{1}.xml"/>
<map:transform type="xslt" src="artikel.xsl"/>
<map:serialize type="html"/>
</map:match>








In dieser einfachen Pipeline sehen wir neben dem Muster («Pattern») drei weitere Kern-Komponenten: den Generator, den Transformator und den Serializer. Sie dienen dazu, die Anfrage abzuhandeln. Der Generator liest dabei die Daten ein (in diesem Fall die Datei artikel-1234.xml), schickt sie in Form eines XML-Streams an den Transformator, der sie in das gewünschte Format umwandelt (XHTML), bevor sie dann zum Serializer kommen, der aus dem XHTML einen HTML-Stream erzeugt und an den Client sendet.


Zum Aufbau hierarchischer Strukturen können Matcher ohne weiteres verschachtelt werden. Dies kann einerseits Performance-Vorteile bringen, weil weniger Matcher geprüft werden müssen, um bestimmte Fälle ausschliessen zu können. Andererseits können so auch ganze Kategorien von Matchern mit Hilfe sogenannter Actions gemeinsame Logik ausführen, beispielsweise Zugriffsschutz für bestimmte Ressourcen/URLs.




Konferenz-Registrierungs-Formular: Ablaufsteuerung mit Cocoon Flow


Cross Publishing

Hat man dieses relativ einfache Beispiel verstanden, so lassen sich damit schon einfachere Cross-Publishing-Projekte angehen. Unter Cross Publishing versteht man die Erzeugung von Ausgaben in verschiedenen Formaten, Stilen oder für verschiedene Geräte aus einer bestimmten Datenquelle. Um auf das obige Beispiel zurückzugreifen, könnte man die Artikel-Stammdaten als XML-Dokumente am Server vorhalten. Diese könnten dann mit Hilfe von Cocoon – wie oben gezeigt – recht einfach in HTML verwandelt werden. Verwendet man aber ein anderes Stylesheet und einen anderen Serializer, könnte man statt HTML auch ein PDF oder (SVG-)Grafiken dynamisch erstellen lassen. Oder man könnte Ausgaben für Mobiltelefone oder Browser von Spielkonsolen oder Newsfeeds in RSS massgeschneidert erstellen.


Weiter wäre es denkbar, dass man unterschiedliche Pipelines für das Intranet und das Internet verwendet. So könnten die internen Arbeitsplätze mehr Informationen angezeigt bekommen (wie Einkaufspreis, Lagerstand, Lieferant etc.) als die externen Kunden.
Derartige Problemstellungen lassen sich mit Cocoon sehr einfach umsetzen. Da Cocoon auf XML aufbaut, sind allerdings gute Kenntnisse in XML-Technologien wie XSLT, XSL:FO sowie XPath erforderlich.






Verschachtelung von Pipelines für Cross Publishing mittels Zwischenformat


Mehr Sitemap-Komponenten

Cocoon bietet eine Menge an verschiedenen Komponenten in den Kategorien Generator, Transformator und Serializer an. Es existieren beispielsweise Generatoren, die auf MP3-Dateien oder Bilder spezialisiert sind. Von ihnen erhält man dann etwa einen XML-Stream zurück, der Daten aller Bilder oder MP3 mit entsprechenden Meta-Information wie Name, Dateigrösse, Bildgrösse oder Bit-Rate beinhaltet. Mit Hilfe dieser Generatoren kann man auf sehr einfache Weise Listen von bestimmten Dateitypen erstellen.


Weiter können diese Generatoren und insbesondere Transformatoren wie CInclude und XInclude verwendet werden, um Dokumente mit einer bestimmten Logik zu aggregieren. Ein weiterer, für einfache Datenbankzugriffe sehr nützlicher Transformator ist der SQL-Transformer. Mit diesem kann auf eine JDBC-Datenquelle zugegriffen werden; die entsprechenden Ergebnisse werden wieder als XML-Stream an die nächste Komponente weiterge­reicht. Die nächste Komponente könnte in diesem Fall wieder ein Transformator sein. Dieses Mal aber ein XSLT-Transformator, der das Ergebnis in HTML oder XSL:FO für die PDF-Erstellung aufbereitet. Ein entsprechender HTML- oder PDF-Serializer sendet dann das Ergebnis zurück an den Client.



In der Cocoon-Dokumentation findet man eine Übersicht über eine grosse Anzahl an Komponenten, mit denen man viele Probleme ad hoc lösen kann. Dazu gehören auch das dynamische Erstellen von ZIP-Archiven, die Internationalisierung von Texten, Erstellen von Directory-Listen oder der Zugriff auf GET- und POST-Parameter.
Reichen die vorhandenen Komponenten nicht aus, kann man relativ einfach eigene Komponenten schreiben.


Performance

Eine Frage, die im Zusammenhang mit den beschriebenen Mechanismen oft gestellt wird, ist, ob denn mit diesen auf XML aufbauenden Prinzipien überhaupt performante Anwendungen möglich sind. Cocoon verfügt über verschiedene Strategien, um einerseits die Flexibilität von XML voll ausschöpfen zu können und andererseits aber die Performance wenig leiden zu lassen. Beispielsweise kommunizieren die Komponenten innerhalb der Sitemap über SAX-Streams und nicht über DOM-Objektbäume oder gar XML-Dokumente. Auch verfügt Cocoon über leistungsfähige
Caching-Mechanismen auf verschiedenen Ebenen, die beispielsweise «teure» Operationen wie XSLT-Transformationen nur dann durchführen, wenn dies tatsächlich notwendig ist. Das Thema Caching ist im Detail aber relativ komplex. Daher muss an dieser Stelle auf die entsprechende Dokumentation verwiesen werden.


Webapplikationen

Die bisher beschriebenen Mechanismen lassen noch kaum Interaktion mit dem Benutzer zu, wie dies bei Webapplikationen natürlich notwendig ist. Auch benötigen Webapplikationen typischerweise komplexere Logik, die man gern in Java-Backends schreibt und nicht in die Sitemap packt.


Cocoon verfügt daher auch über leistungsfähige Technologien, um komplexe Webapplikationen realisieren zu können. Es existiert beispielsweise ein Formular-Framework (Cocoon Forms), das einen sehr generischen Ansatz verfolgt. Es basiert auf einem Satz von (erweiterbaren) Widgets, bei diesen handelt es sich im wesentlichen um logische Formularkomponenten wie Texteingabefelder oder Kalenderkomponenten, die man in eigenen Formularen verwenden kann. Diese Widgets definieren noch kein bestimmtes Aussehen (wie HTML-Code), sondern erlauben Dinge wie Typ-Prüfungen, Validierungen und Event Handling.



Werden die Formulare auf diese Weise aufgebaut, werden sie in der Pipeline dann gerendert. Dabei ist man nicht nur auf HTML als Ausgabeformat beschränkt. Prinzipiell hat man die Möglichkeit, beliebige eigene Rendering-Mechanismen zu verwenden.
Weiter besteht die Möglichkeit, Objekte an Formulare zu binden, um somit die Werteübergabe zwischen den Java-Backend-Komponenten und den Formularkomponenten zu erleichtern.


Mit Cocoon Flow lassen sich Abläufe, die in einer Webanwendung auftreten können, steuern. Es können beispielsweise mehrseitige Formulare realisiert werden, bei denen je nach Eingabewerten in den vorhergehenden Formularen entschieden wird, welche weiteren Formulare präsentiert werden. Solche Abläufe lassen sich mit traditionellen Web-Frameworks oft schwer abbilden. In Cocoon Flow kann man aber eigene serverseitige Flow-Scripts in JavaScript oder Java schreiben, die die Kontroll-Logik für den Seitenablauf mit Hilfe der Sitemap abbilden. Änderungen im Flow lassen sich dann sehr einfach an einer Stelle machen.


Tools

Cocoon versteht sich auch mit anderen Werkzeugen aus der Java-Welt, wobei mit der bereits in den Startlöchern stehenden Version 2.2 (aktuell ist 2.1) einige Neuerungen einhergehen werden. So wird Cocoon künftig auf Maven 2 als Build-System setzen, das wir bereits in InfoWeek 12/2006 vorgestellt haben. Es erleichtert den Build-Vorgang, bietet aber auch andere Vorteile. So wird es einen Maven-Archetyp geben, der rudimentäre Cocoon-Applikationen erstellt, was die initiale Konfiguration erleichtert. Auch die Einbindung in Eclipse ist möglich.


Modularisierung

Bis zu Version 2.1 wurde hauptsächlich mit Hilfe der Sitemap modularisiert. Das heisst, es gab eine Haupt-Sitemap und Unter-Sitemaps, die eingebunden wurden. Das hat sich in der Praxis als recht unbequem herausgestellt. Mit der neuen Version wird es deshalb sogenannte Blocks geben. Mit denen kann man seine Applikationen aufspalten, was die Konfiguration und Distribution erleichtert. Eine Kommunikation zwischen Blöcken ist ebenfalls möglich. Weiter, und dies ist ebenfalls eine zentrale Neuerung, wurde das zugrundeliegende Komponenten-Framework ausgetauscht. War Version 2.1 noch auf Avalon-Komponenten aufgebaut, basiert die neue Version auf dem Spring-Framework. Dies ist nicht nur das modernere Framework, es erlaubt auch eine einfachere Konfiguration und das Einbinden beliebiger Spring-Komponenten, die ja heute das vorherrschende Komponenten-Modell darstellen.


Projekte mit Cocoon

Da Cocoon ein sehr leistungsfähiges Basis-Framework für Publishing und Webanwendungen darstellt, gibt es auch einige Projekte, die auf Cocoon aufbauen. Nennenswert ist beispielsweise Apache Forrest. Es ermöglicht die Umsetzung statischer und dynamischer Dokumentationsprojekte mit recht geringem Aufwand (einige Apache-Projekte verwenden Forrest zur Generierung der eignen Webseiten). Lenya und vor allem Daisy sind leistungsfähige Content-Management-Systeme, die ebenfalls auf Cocoon aufsetzen.


Nicht ganz einfach

Wie man sieht, ist Cocoon ein sehr leistungsfähiges XML-Framework, das als Servlet in einem Servlet-Container läuft und sowohl für verschiedene Publishing-Zwecke als auch für komplexe Webapplikationen gut einsetzbar ist. Mit Hilfe von Cocoon kann man auch sehr elegant verschiedenste Systeme integrieren. Die neue Version 2.2 wird demnächst erscheinen, und damit wird Cocoon einen erheblichen Schritt vorwärts machen, vor allem was die Modularisierung, die Verwendung von Spring und die Konfiguration betrifft.
Gleichzeitig muss aber auch klar sein, dass man für die Einarbeitung in Cocoon (wie in die meisten komplexen Web-Frameworks) doch einige Zeit veranschlagen muss, zumal es etliche Technologien und Komponenten zu verstehen gilt. Mittlerweile gibt es aber auch Sekundärliteratur. Zur Version 2.2 wird mit «Apache Cocoon» auch ein Buch (ISBN 978-3-89864-299-6) erscheinen, mit dessen Hilfe sich der Einstieg in die Welt von Cocoon einfacher gestalten dürfte.


Der Autor

Alexander Schatten (alexander@schatten.info) ist Assistent am Institut für Softwaretechnik und interaktive Systeme der Technischen Universität Wien.




Artikel kommentieren
Kommentare werden vor der Freischaltung durch die Redaktion geprüft.

Anti-Spam-Frage: Wieviele Zwerge traf Schneewittchen im Wald?
GOLD SPONSOREN
SPONSOREN & PARTNER