FacesTales

Das "Baukasten"-Prinzip

Lars Röwekamp und Matthias Weßendorf

Neben etlichen Verbesserungen und Korrekturen gegenüber der Vorgängerversion JSF 1.2, wartet die aktuelle Spezifikation 2.0, dank der direkten Integration von Facelets, vor allem mit zwei neuen Highlights auf: Templating und Composite Components. In Kombination genutzt, ist so das Erstellen von JSF-Komponenten ohne Java-Code und XML-Konfiguration möglich – eine neue Grenzerfahrung für jeden JSF-Entwickler.

Keep simple Things simple!

Was waren das noch für Zeiten, als es echter Männer (und Frauen) bedurfte, um selbst die einfachsten JSF-Komponenten zu implementieren. Für die hohe Schule der Komponentenentwicklung benötigte man mindestens ein abgeschlossenes Studium der Informatik sowie eine vierjährige Zusatzausbildung in „Advanced Component Design & Development“. Entsprechend stolz konnte man am Ende sein, zu dem erlesenen Kreis der Auserwählten zu gehören. Aber mal im Ernst: Die enorme Komplexität der Entwicklung von JSF-Komponenten war seit jeher ein berechtigter Kritikpunkt an der Spezifikation. Java-Code, XML-Konfiguration(en), Resource-Handling, gute Kenntnisse des JSF Lifecycles und vieles mehr war notwendig, um eine einigermaßen sinnvolle und universal einsetzbare JSF-Komponente zu bauen. Kein Wunder, dass der Komponentenmarkt bis dato von wenigen, professionellen Herstellern beherrscht wird. Mit JSF 2.0 findet ein kompletter Umbruch statt. Neben den bisher bekannten Standardkomponenten – die es auch weiterhin geben wird – halten zusätzlich so genannte Composite Components Einzug. Diese zeichnen sich dadurch aus, dass sie keine (XML-)Konfiguration benötigen und ohne Java-Code auskommen. Das Schreiben und Deployen einer Composite Component ist entsprechend einfach. Möglich geworden ist das durch Facelets Templating, JSF 2 Resource Handling und eine einfache Namenskonvention.

Konvention und Komposition

Und so funktioniert das mit der Namenskonvention: Innerhalb der verwendenden Seite wird zunächst ein Namespace deklariert, der aktuell immer mit dem Präfix http://java.sun.com/jsf/composite beginnt und zusätzlich die Verzeichnisstruktur, ausgehend vom Basisverzeichnis resource, widerspiegelt, unter der die Komponente abgelegt wurde. Es gibt übrigens bereits konkrete Pläne für die Spezifikation 2.1, das Namespace-Präfix noch einmal deutlich zu verschlanken. Die Komponente selbst wird dann via Namespace und Dateinamen referenziert. Folgendes Beispiel zeigt die Verwendung einer Composite Component namens imgButton.xhtml, die im Verzeichnis resources/components/buttons/ abgelegt ist:

   ...
   
   ...

So weit so gut, aber wie sieht nun eine solche Komponente aus? Die Implementierung einer Composite Component geschieht, wie es der Name schon sagt, durch die Komposition von anderen Komponenten – und Ressourcen – unter Verwendung von XHTML. Dabei verfügt eine Composite Component mindestens über zwei Abschnitte: composite:interface und composite:implementation. Der erste Abschnitt (composite:interface) beschreibt die Schnittstelle der Komponente und somit u. a die Attribute, die durch den Anwender gesetzt werden können. Der zweite Abschnitt (composite:implementation) definiert die Ausgabe und das Verhalten der Komponente unter Berücksichtigung der übergebenen Attribute, via #{cc.attrs.ATTR_NAME}, und referenzierten Ressourcen. Listing 1 zeigt eine einfache Komponente imgButton.xhtml, die als Image-Button verwendet werden soll. Neben den darzustellenden icon sowie der abzuarbeitenden action-Methode kann zusätzlich eine spezielle styleClass als Attribut des Tags angegeben werden.


  

  

Eine mögliche Anwendung der Komponente könnte wie folgt aussehen:

Mithilfe der beiden im Rahmen der JSF-2-Spezifikation neu eingeführten composite-Bereiche – interface und implementation – sollen die typischen Probleme der Facelet-Vergangenheit, wie Typos bei der Angabe von Attributen umgangen werden. Ein positiver Nebeneffekt: Das Generieren von Dokumentation für eine Composite Component auf Basis der Interfaceinformation ist mithilfe eines selbstgeschriebenen XML-Parsers ein Kinderspiel.

Bereits dieses einfache Beispiel zeigt deutlich die Vorteile der Composite Components. Zum einen können dank Komposition von Facelet-Fragmenten auf einfachste Art und Weise widerverwendbare und individuell anpassbare Komponenten entstehen. Zum anderen bedarf es dank Namens- und Ressourcenkonventionen keinerlei Konfigurationsaufwand.

Keep complex Things possible?

Einfache Komponenten scheinen kein Problem darzustellen. Wie aber sieht es mit komplexeren Szenarien aus? Sind auch diese durch Composite Components abzudecken? Die Antwort darauf ist ein klares JEIN. Die Möglichkeiten der Composite Components gehen deutlich über das bisher Gezeigte und im Rahmen dieser Kolumne Darstellbare hinaus. So ist z. B. die Verschachtelung von Komponenten inkl. Zugriff auf die Parent-Attribute, so wie das Verwenden von Validatoren und/oder Konvertern, kein Rocket-Science. Beispiele hierzu findet man sowohl in der offiziellen JSF-2-Spezifikation als auch in der JSF-2-Dokumentation. Auch das Einbinden und Verwenden von JavaScript-Bibliotheken ist mit wenigen Zeilen Code möglich, wie u. a. das Projekt facesgoodies in Form eines jQuery basierten Sliders zeigt. Dank weiterer composite-Schnittstellentags wie facet, valueHolder, editableValueHolder oder actionSource können ganze Dialoge, Tabellen oder Menüs problemlos als Composite Component realisiert werden.

Wie weit die Möglichkeiten der Composite Components tatsächlich gehen, wird die Zukunft zeigen. Da durch Ansatz der Komposition nicht nur vollwertige Komponenten, sondern auch Facets realisiert werden können, wird es wohl demnächst die eine oder andere positive Überraschung aus dem JSF-Component-Library-Umfeld geben. Interessant dürften zukünftig vor allem auch die Komponenten werden, die die Composite Components lediglich als „JSF Wrapper“ für jQuery und Co. verwenden. Bestehende Funktionalität ließe sich so mit wenig Aufwand transparent in die JSF-Welt einbinden.

Fazit

Dank Composite Components ist es in JSF 2 auch für „Normalsterbliche“ möglich, eine eigene, umfangreiche Komponentenbibliothek zu implementieren. Die Grundlage hierfür bilden Facelets, JSF 2 Resource Handling sowie eine neu eingeführte Namenskonvention. Die Möglichkeiten gehen dabei dank der Option zur Einbindung anderer Komponenten und Scripting-Bibliotheken deutlich über „Hello World“-Komponenten hinaus. Ob es Grenzen für diesen neuen Ansatz gibt oder die bisherigen JSF-Standardkomponenten auf Dauer obsolet werden, wird die Zukunft zeigen. Bisher werden die Standardkomponenten durch die Spezifikation bewusst auch weiterhin unterstützt – Pläne, das zu ändern, existieren bis dato nicht. Ein interessantes Projekt wäre es übrigens, die klassischen <h:… >-Komponenten auf Basis von Composite Components neu zu implementieren. Freiwillige vor!

Lars Röwekamp ist Geschäftsführer der OpenKnowledge GmbH und berät seit mehr als zehn Jahren Kunden in internationalen Projekten rund um das Thema Enterprise Computing (Twitter: @mobileLarson).

Matthias Weßendorf arbeitet für Oracle an einer Server-side-Push-Lösung für ADF Faces. Er ist PMC Chair von Apache MyFaces. Matthias bloggt regelmäßig auf http://matthiaswessendorf.wordpress.com (Twitter: @mwessendorf).

Geschrieben von
Lars Röwekamp und Matthias Weßendorf
Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.