"
 
 1 Einführung in JavaServer Faces
"
 
 2 Die Konzepte von JavaServer Faces
"
 
 3 Standard-JSF-Komponenten
"
 
 4 Advanced JSF
"
 
 5 Verwaltung von Ressourcen
"
 
 6 Die eigene JSF-Komponente
"
 
 7 Ajax und JSF
"
 
 8 JSF und HTML5
"
 
 9 JSF und CDI
"
 
 10 PrimeFaces -- JSF und mehr
"
 
 11 Faces-Flows
"
 
 12 MyGourmet Fullstack -- JSF, CDI und JPA mit CODI kombiniert
"
 
 13 JSF und Spring
"
 
 14 MyGourmet Fullstack Spring -- JSF, Spring, Orchestra und JPA kombiniert
"
 
 15 Tobago -- JSF und mehr
"
 
 16 Eine kurze Einführung in Maven
"
 
 17 Eclipse
"
 
 18 Autoren
"
 
 19 Änderungshistorie

5 Verwaltung von Ressourcen

In JSF handelt es sich bei Ressourcen um Artefakte wie Bilder, Skripte oder Stylesheets, die eine Komponente benötigt, um vollständig am Client angezeigt zu werden.
Die Verwaltung von Ressourcen ist eine Anforderung, die in der einen oder anderen Form für jede Anwendung relevant ist. Besonders für Komponentenbibliotheken ist es wichtig, die Abhängigkeiten zwischen Komponenten und Ressourcen wie Skripten oder Stylesheets zu definieren. Außerdem müssen diese Ressourcen für den Anwendungsentwickler transparent zur Verfügung gestellt werden. Vor JSF 2.0 hat es dafür keinen standardisierten Weg gegeben. Viele Anbieter haben daher eigenständige Lösungen entwickelt, die allerdings in den wenigsten Fällen miteinander kompatibel sind.
Ab JSF 2.0 gibt es einen standardisierten Weg, Ressourcen zu verwalten und flexibel in der Ansicht zu positionieren. Davon profitieren nicht nur Komponentenbibliotheken, sondern alle Anwendungen mit eigenen Bildern, Stylesheets oder Skripten. Die Abschnitte [Sektion:  Identifikation von Ressourcen -- Teil 1] bis [Sektion:  Ressourcen in MyGourmet 12] zeigen ausführlich, wie die Verwaltung von Ressourcen funktioniert.
JSF 2.2 bietet mit den sogenannten Resource-Library-Contracts eine Möglichkeit zur Definition austauschbarer Templates und Ressourcen, wie Abschnitt [Sektion:  Resource-Library-Contracts] zeigt.

5.1 Identifikation von Ressourcen -- Teil 1

Ressourcen werden in JSF im einfachsten Fall durch ihren Namen identifiziert. Sehen wir uns das am besten anhand eines Beispiels an. Folgender Code fügt das Bild image.png in eine Ansicht ein:
<h:graphicImage name="image.png"/>
Erfahrene JSF-Entwickler werden sofort bemerkt haben, dass in JSF~1.2 noch kein Attribut name für das h:graphicImage -Tag definiert ist. Der Wert dieses Attributs ist der Name der Ressource, die als Bild ausgegeben werden soll. Es handelt sich dabei nicht um eine Pfadangabe im klassischen Sinn, sondern um einen Bezeichner, der intern in den tatsächlichen Pfad der Ressource aufgelöst wird.
JSF sucht Ressourcen an den folgenden Stellen einer Anwendung (in der angegebenen Reihenfolge):
  1. Im Wurzelverzeichnis der Webapplikation unter /resources
  2. In /META-INF/resources und somit auch in allen Jar-Dateien im Classpath
In unserem Fall versucht JSF die Bezeichnung image.png an einem der oben genannten Orte aufzulösen. Daher legen wir folgende Datei an:
/resources/image.png
Das oben angeführte Beispiel zeigt den einfachen Fall einer Ressource, die über ihren Namen referenziert wird. JSF bietet aber darüber hinaus eine Einteilung in Bibliotheken, eine Versionierung und die Lokalisierung von Ressourcen.
Bibliotheken sind eine Möglichkeit, Ressourcen unter einem gemeinsamen Namen zu gruppieren. Der Bibliotheksname wird dann gemeinsam mit dem Ressourcennamen zur Identifikation der Ressource verwendet. Wir erweitern unser Beispiel um eine Bibliothek images , in der alle Bilder abgelegt sind. Die Codezeile von oben ändert sich wie folgt ab:
<h:graphicImage library="images" name="image.png"/>
JSF interpretiert die Bibliothek beim Auflösen der Ressource als zusätzliches Verzeichnis. Der Pfad der Bilddatei sieht folgendermaßen aus:
/resources/images/image.png
Doch damit noch nicht genug - Ressourcen und Bibliotheken können in mehreren Versionen existieren und lokalisiert werden. Die Funktionsweise zeigt Abschnitt [Sektion:  Identifikation von Ressourcen -- Teil 2] .
JSF 2.2: In Versionen vor 2.2 sucht JSF Ressourcen in der Webanwendung immer im Verzeichnis /resources . Dieser Pfad hat aber den Nachteil, dass er ohne zusätzliche Absicherungen nach außen verfügbar ist. Das ist insbesondere für Kompositkomponenten nicht immer das gewünschte Verhalten. Ab JSF 2.2 lässt sich dieses Verzeichnis daher über den Kontextparameter javax.faces.WEBAPP_RESOURCES_DIRECTORY in der web.xml anpassen. Im Beispiel in Listing Konfiguration des Verzeichnisses für Ressourcen liegt das Verzeichnis innerhalb von /WEB-INF , wodurch es von außen nicht zugänglich ist.
<context-param>
  <param-name>
    javax.faces.WEBAPP_RESOURCES_DIRECTORY
  </param-name>
  <param-value>/WEB-INF/resources</param-value>
</context-param>
Nachdem die Ressourcen nur intern von JSF aus diesem Verzeichnis gelesen werden und nach außen unter einer anderen URL zur Verfügung stehen, ist das kein Problem für die Applikation. Der Pfad für das Beispiel mit der Bibliothek von oben sieht dann folgendermaßen aus:
/WEB-INF/resources/images/image.png
Das Auflösen der Ressourcen und das Ausliefern der Daten an den Client übernimmt die Klasse Resource-Handler . Wie viele andere Teile von JSF kann auch der Resource-Handler über die faces-config.xml mit einer eigenen Implementierung dekoriert werden. Denkbar wären Implementierungen, die Ressourcen aus einer Datenbank holen oder dynamisch erzeugen - der Fantasie sind keine Grenzen gesetzt.

5.2 Ressourcen im Einsatz

Es gibt mehrere Wege, ab JSF 2.0 Ressourcen in die Seite einzubinden. Folgende Standardkomponenten verfügen über die Attribute name und library , um direkt die auszugebende Ressource zu referenzieren:
Ressourcen können auch direkt über einen EL-Ausdruck im Attribut value der entsprechenden Komponente referenziert werden - das implizite Objekt resource dient diesem Zweck. Eigenschaften dieses Objekts werden beim Auswerten des Ausdrucks als Ressourcenbezeichner interpretiert. Dieser Bezeichner kann der Name der Ressource oder der Name der Bibliothek gefolgt vom Namen der Ressource mit einem Doppelpunkt als Trennzeichen sein.
Hier nochmals das Beispiel aus dem letzten Abschnitt, diesmal allerdings über einen EL-Ausdruck realisiert:
<h:graphicImage value="#{resource['images:image.png']}"/>
Kommt als Seitendeklarationssprache Facelets zum Einsatz, kann dieser EL-Ausdruck sogar direkt im HTML-Code verwendet werden:
<img src="#{resource['images:image.png']}"/>
Die dritte Methode zum Einbinden von Ressourcen erfolgt im Java-Code und ist vor allem für Entwickler von Komponenten interessant. Mit den beiden Annotationen @ResourceDependency und @ResourceDependencies können Abhängigkeiten zu Ressourcen bereits in der Komponenten- beziehungsweise Rendererklasse definiert werden. Folgender Code verknüpft zum Beispiel eine Komponente mit der Ressource script.js aus der Bibliothek scripts :
@ResourceDependency(name="script.js", library="scripts")
public class MyComponent extends UIComponentBase {
...
}
Diese Methode wird hier nur der Vollständigkeit halber erwähnt. Weiterführende Informationen zum Thema Komponentenentwicklung und Ressourcen finden Sie in Abschnitt Sektion:  Rendererklasse schreiben .

5.3 Positionierung von Ressourcen

Einen wichtigen Aspekt des Ressourcenmanagements von JSF haben wir bis jetzt noch nicht erwähnt. Stellen Sie sich vor, Sie benutzen eine Komponente aus einer Komponentenbibliothek, die ein spezielles Skript oder Stylesheet verwendet. Wie kommt diese Ressource dann in die Ansicht? Als Anwender der Bibliothek wollen wir uns nicht darum kümmern. Bei einigen Ressourcen wie Stylesheets und manchen Skripten kommt noch hinzu, dass sie an speziellen Stellen der Ansicht ausgegeben werden müssen, damit beim Benutzer die Seite richtig funktioniert. Wie die Verbindung zwischen Komponente und Ressource modelliert wird, haben wir bereits im letzten Abschnitt gezeigt. Das erklärt aber noch nicht, wie ein Link auf die Ressource in die Ansicht übernommen wird.
JSF erlaubt die Positionierung einzelner Ressourcen in definierten Bereichen der Ansicht wie dem Head oder dem Body. Damit JSF diese Bereiche richtig identifizieren kann, gibt es folgende neue Komponenten in der HTML-Tag-Library :
Beim Einbinden einer Ressource kann einer dieser Bereiche direkt adressiert werden. Dafür existiert in @ResourceDependency das Element target und in h:outputScript ein gleichnamiges Attribut. Die erlaubten Werte sind head , body und form , wobei Stylesheets allerdings unabhängig von der Angabe immer im Head ausgegeben werden (gemäß HTML-Standard müssen Stylesheets im Head-Bereich verlinkt werden, damit der Quelltext der Seite gültiges HTML bleibt).
Damit das Positionieren von Ressourcen funktioniert, ist es unbedingt nötig, h:head und h:body in allen Ansichten einzusetzen. Mit Facelets können Sie das in einem Template zentral für alle Seiten erledigen. Wie das funktioniert, erfahren Sie in Abschnitt Sektion:  Templating .
Sehen wir uns anhand eines Beispiels an, wie das Positionieren von Ressourcen in der Praxis aussieht. Das folgende Dokument enthält im Body-Bereich ein Stylesheet ohne Positionsangabe und ein Skript mit der Position head :
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://xmlns.jcp.org/jsf/html">
<h:head>
  <title>Ressourcen-Test</title>
</h:head>
<h:body>
  <h:outputStylesheet name="style.css"/>
  <h:outputScript name="test.js" target="head"/>
  <h:outputText value="Test"/>
</h:body>
</html>
Hier der gerenderte HTML-Code:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <title>Ressourcen-Test</title>
  <link type="text/css" rel="stylesheet"
      href="/app/javax.faces.resource/style.css.jsf"/>
  <script type="text/javascript"
      src="/app/javax.faces.resource/test.js.jsf">
  </script>
</head>
<body>
  Test
</body>
</html>
Der Code zeigt, dass beide Ressourcen, das Skript und das Stylesheet, im Head-Bereich der Seite gerendert wurden. Mit Komponenten aus einer Bibliothek funktioniert das genauso - vorausgesetzt, der Entwickler hat die Komponente mit @ResourceDependency annotiert und das target -Attribut auf den Wert head gesetzt. Wenn Sie dann h:head und h:body auf der Seite einsetzen, erledigt JSF den Rest.

5.4 Identifikation von Ressourcen -- Teil 2

In Abschnitt [Sektion:  Identifikation von Ressourcen -- Teil 1] haben wir kurz darauf hingewiesen, dass JSF bei Ressourcen und Bibliotheken Versionierung und Lokalisierung unterstützt.
Versionsnummern sind bei Bibliotheken und Ressourcen mit durch Unterstrich ( _ ) getrennte Zahlen wie 1_0 oder 1_0_1 angegeben. Sie werden, getrennt durch einen Schrägstrich ( / ), an den Namen der Ressource oder der Bibliothek angehängt. Bei Ressourcennamen kann die Version zusätzlich eine Dateierweiterung wie .png oder .css aufweisen. Warum das so ist, sehen wir gleich. Hier unser Beispiel mit Versionsnummern für die Bibliothek und die Ressource:
<h:graphicImage library="images/1_0"
    name="image.png/1_1.png"/>
JSF interpretiert Bibliotheksversionen beim Auflösen als ein weiteres Verzeichnis im Pfad der Ressource. Ressourcenversionen werden dahingegen etwas anders behandelt. Existiert eine Ressource in mehreren Versionen, wird der Name der Ressource zu einem Verzeichnis, und die einzelnen Versionen sind die eigentlichen Ressourcendateien. Der neue Pfad der Bilddatei lautet dann folgendermaßen:
/resources/images/1_0/image.png/1_1.png
In den meisten Fällen ist es aber nicht nötig, die Versionsnummern beim Einsatz von Ressourcen zu definieren. Wenn keine expliziten Versionen angegeben sind, verwendet JSF automatisch die Ressource mit der höchsten Versionsnummer.
Um die verschiedenen Kombinationen von Ressourcennamen, Bib-liotheksnamen und Versionsnummern zu veranschaulichen, wollen wir unser Beispiel erweitern. Abbildung Beispiele von Ressourcen zeigt das Ressourcenverzeichnis der Anwendung mit einer Bibliothek und den zwei Ressourcen image.png und new.png . Links neben dem Namen der Bilddatei ist jeweils das Bild selbst dargestellt.
Abbildung:Beispiele von Ressourcen
Basierend auf dem Verzeichnisbaum aus Abbildung Beispiele von Ressourcen wollen wir nun verschiedene Ressourcen auflösen und uns das Ergebnis ansehen. Tabelle tab:resource-resolution zeigt für eine Reihe von Kombinationen aus Bibliotheks- und Ressourcenname, welches Bild dadurch angezeigt wird. Beachten Sie bitte vor allem Namen ohne Versionsangaben und wie diese immer zur höchsten Version aufgelöst werden.
BibliothekRessource
images image.png
file=grafiken/resources-2_1.eps
images image.png/2 _ 1.png
file=grafiken/resources-2_1.eps
images/2 _ 0 image.png
file=grafiken/resources-2_1.eps
images/2 _ 0 image.png/2 _ 1.png
file=grafiken/resources-2_1.eps
images image.png/2 _ 0.png
file=grafiken/resources-2_0.eps
images/1 _ 0 image.png/1 _ 0.png
file=grafiken/resources-1_0.eps
images/1 _ 0 image.png
file=grafiken/resources-1_1.eps
images new.png
file=grafiken/resources-new.eps
Zum Schluss wollen wir noch die Lokalisierung von Ressourcen besprechen. JSF sucht beim Auflösen von Ressourcen nach folgendem Eintrag im Application-Message-Bundle :
javax.faces.resource.localePrefix=<Wert>
Falls dieser Eintrag für das aktuelle Locale gesetzt ist, wird dessen Wert als Teil des Pfads der Ressourcendatei interpretiert. Ist der Wert im deutschen Resource-Bundle beispielsweise auf de gesetzt, sieht der Pfad zu unserem Bild wie folgt aus:
/resources/de/images/image.png
Weiterführende Informationen zur Internationalisierung und zum Application-Message-Bundle finden sich in Abschnitt Sektion:  Internationalisierung .

5.5 Ressourcen in MyGourmet 12

Die Umstellung von MyGourmet auf Ressourcen ist im momentanen Stand der Entwicklung trivial - wir erstellen dafür kein neues Beispiel.
Die wichtigste Änderung ist die Umstellung des Haupttemplates template.xhtml auf die Elemente h:head und h:body . Dafür müssen aber nur die entsprechenden HTML-Elemente ersetzt werden. Sobald das geschehen ist, können auch das Stylesheet und das Logo ins Verzeichnis /resources verschoben und als Ressourcen verwendet werden.
Die Ressourcenverwaltung wird erst ab dem nächsten Beispiel MyGourmet 13 interessant, wenn sich alles um die in JSF 2.0 eingeführten Kompositkomponenten dreht. Mehr dazu erfahren Sie in Abschnitt Sektion:  Kompositkomponenten .

5.6 Resource-Library-Contracts

JSF 2.2: Die Pläne für JSF 2.2 sahen ursprünglich ein "Multi-Templating" genanntes System zur Unterstützung von Themes vor. Dieses System hat es aber nicht bis in die finale Version der Spezifikation geschafft. Übrig geblieben sind die sogenannten Resource-Library-Contracts, eine Notlösung mit grundlegenden Features zur Unterstützung austauschbarer Templates und mit Potenzial für künftige Erweiterungen.
Resource-Library-Contracts gruppieren Templates und Ressourcen zu einer austauschbaren Einheit. Ein Contract besteht aus einem oder mehreren Facelets-Templates, deren mit ui:insert definierten ersetzbaren Bereichen und einer beliebigen Anzahl von Ressourcen. Die Templates, deren ersetzbare Bereiche und die Ressourcen bilden somit eine (informelle) Schnittstelle, aus der hervorgeht, wie ein Resource-Library-Contract eingesetzt werden kann. Alle Resource-Library-Contracts mit derselben Schnittstelle können gegeneinander ausgetauscht werden.

5.6.1 Ein erstes Beispiel

Ein Resource-Library-Contract ist im Grunde genommen ein Container für Templates und Ressourcen, der in einem speziellen Verzeichnis abgelegt wird. JSF sucht Resource-Library-Contracts standardmäßig an folgenden Stellen einer Anwendung (in der angegebenen Reihenfolge):
  1. Im Wurzelverzeichnis der Webapplikation unter /contracts
  2. In /META-INF/contracts und somit auch in allen Jar-Dateien im Classpath
Abbildung Resource-Library-Contract in der Applikation zeigt den Inhalt des Contracts mit dem Namen contract1 im Verzeichnis /contracts der Webapplikation.
Abbildung:Resource-Library-Contract in der Applikation
Dieser Resource-Library-Contract beinhaltet das Template tem-plate.xhtml , das Stylesheet style.css und das Bild image.png . Das Template definiert die ersetzbaren Bereiche header und content und bindet das Stylesheet als JSF-Ressource ein, wie Listing Template für Resource-Library-Contract zeigt.
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
      xmlns:h="http://xmlns.jcp.org/jsf/html">
<h:head><title>Contract Template</title></h:head>
<h:body>
  <h:outputStylesheet name="style.css"/>
  <div class="header">
    <ui:insert name="header"/>
  </div>
  <div class="content">
    <ui:insert name="content"/>
  </div>
</h:body>
</html>
Die Schnittstelle dieses Contracts besteht somit aus dem Template template.xhtml und dessen ersetzbaren Bereichen header und content . Das Stylesheet und das Bild beachten wir momentan nicht weiter (mehr dazu in Abschnitt [Sektion:  Ressourcen aus Resource-Library-Contracts] ). Mit diesem Wissen können wir das Template aus dem Contract bereits in einer Facelets-Seite einsetzen, wie Listing Template-Client für Resource-Library-Contract zeigt.
<ui:composition template="/template.xhtml">
  <ui:define name="header">
    <h1>Überschrift</h1>
  </ui:define>
  <ui:define name="content">
    <p>Beliebiger Inhalt</p>
  </ui:define>
</ui:composition>
Das Template aus dem Resource-Library-Contract wird nur über seinen Namen referenziert. Dabei stellt sich die Frage, wie es aus dem Contract in die Seite kommt. Dazu müssen wir zwei neue Aspekte von JSF 2.2 berücksichtigen. Zum einen stellt JSF standardmäßig alle Resource-Library-Contracts, die beim Starten der Applikation gefunden werden, allen Seiten zur Verfügung. Nachdem es in unserem Beispiel nur einen Contract gibt, ist das genau das gewünschte Verhalten. Zum anderen versucht JSF ab Version 2.2, XHTML-Dateien und Ressourcen immer zuerst aus den der Seite zugeordneten Contracts zu laden.
JSF sucht also in unserem Fall das Template template.xhtml wie gewünscht zuerst im Contract contract1 . Selbst wenn im Wurzelverzeichnis der Applikation auch ein Template mit dem Namen template.xhtml existiert, kommt zuerst jenes aus dem Contract zum Zug.
Der Einsatz von Resource-Library-Contracts wird erst richtig interessant, wenn mehrere Contracts mit derselben Schnittstelle in einer Applikation zur Verfügung stehen. Damit lassen sich zum Beispiel Templates mit unterschiedlichem Styling für verschiedene Bereiche der Anwendung realisieren. In diesem Fall muss natürlich gewährleistet sein, dass es eine eindeutige Zuordnung von Contracts zu Seiten gibt. Abschnitt [Sektion:  Zuordnung von Resource-Library-Contracts] zeigt, wie das funktioniert.
Packt man Resource-Library-Contracts in Jar-Dateien, ergeben sich weitere interessante Anwendungsfälle. Contracts lassen sich dadurch sehr einfach durch das Ersetzen einer Jar-Datei austauschen oder in mehreren Applikationen einsetzen. Abschnitt [Sektion:  Resource-Library-Contracts in Jar-Dateien] zeigt, was Sie dabei beachten müssen.

5.6.1.1 Konfiguration des Contracts-Verzeichnisses

Wie bereits erwähnt sucht JSF Resource-Library-Contracts in der Webanwendung standardmäßig im Verzeichnis /contracts . Dieser Pfad kann aber in der web.xml über den Kontextparameter javax.faces.WEBAPP_CONTRACTS_DIRECTORY angepasst werden. Im Beispiel in Listing Konfiguration des Verzeichnisses für Contracts liegt das Verzeichnis innerhalb von /WEB-INF , wodurch es auch nicht mehr von außen zugänglich ist.
<context-param>
  <param-name>
    javax.faces.WEBAPP_CONTRACTS_DIRECTORY
  </param-name>
  <param-value>/WEB-INF/contracts</param-value>
</context-param>

5.6.2 Ressourcen aus Resource-Library-Contracts

Neben Templates können Resource-Library-Contracts auch eine beliebige Anzahl von Ressourcen enthalten. Der Resource-Library-Contract aus Abschnitt [Sektion:  Ein erstes Beispiel] beinhaltet zum Beispiel neben dem Template auch noch die Ressourcen style.css und image.png . Diese Ressourcen können über ihren Namen in eine Seite eingebunden werden. Das Stylesheet wird ja bereits mit h:outputStylesheet im Template verwendet, wie Listing Template für Resource-Library-Contract zeigt.
Das Einbinden von Ressourcen aus einem Contract funktioniert aber nicht nur innerhalb des Contracts. Wie schon bei den Tem-plates versucht JSF ab Version 2.2, auch Ressourcen immer zuerst aus den einer Seite zugeordneten Contracts zu laden. Listing Template-Client für Resource-Library-Contract mit Ressource zeigt nochmals den Template-Client aus Listing Template-Client für Resource-Library-Contract - diesmal allerdings zusätzlich mit dem Bild image.png .
<ui:composition template="/template.xhtml">
  <ui:define name="header">
    <h1>Überschrift</h1>
  </ui:define>
  <ui:define name="content">
    <p>Beliebiger Inhalt</p>
    <h:graphicImage name="image.png"/>
  </ui:define>
</ui:composition>

5.6.3 Zuordnung von Resource-Library-Contracts

Existieren mehrere Contracts mit derselben Schnittstelle in einer Applikation, muss die Zuordnung von Contracts zu Seiten angepasst werden. Andernfalls stellt JSF wiederum alle Contracts in allen Seiten zur Verfügung, was zu unvorhersehbaren Ergebnissen führen kann.
JSF baut beim Starten der Applikation eine Liste aller verfügbaren Resource-Library-Contracts auf. Diese Liste hat allerdings keine eindeutig definierte Ordnung. Nachdem JSF aber beim Laden von XHTML-Dateien und Ressourcen die Liste der für die Seite verfügbaren Contracts durchgeht und einfach den ersten Treffer verwendet, bleibt es also in gewissem Maß dem Zufall überlassen, welcher Contract zum Einsatz kommt.
Die Zuordnung von Resource-Library-Contracts zu Seiten der Applikation lässt sich auf zwei Arten definieren. Es kann eine grundlegende Zuordnung für einzelne Seiten oder für ganze Seitenbereiche in der faces-config.xml gemacht werden. Für einzelne Seiten kann die Zuordnung mit f:view zudem gezielt definiert werden.
Die Zuordnung von Contracts zu Seiten in der faces-config.xml basiert auf URL-Mustern. Mögliche Werte für die Muster umfassen einzelne Seiten wie /page1.xhtml , Seitenbereiche wie /customer/* oder die gesamte Applikation mit * . Pro Muster wird eine Liste aller anzuwendenden Contract-Namen angegeben. Bei der Auswertung berücksichtigt JSF zuerst immer exakte Übereinstimmungen für konkrete Seiten und ansonsten das längste zutreffende Muster.
Die Konfiguration erfolgt im Element resource-library-contracts innerhalb application . Dort wird für jede Kombination von URL-Muster und Contract-Namen ein contract-mapping -Element eingefügt. Das URL-Muster kommt dabei ins Element url-pattern und die kommaseparierte Liste von Contract-Namen ins Element contracts . Mit der in Listing Zuordnung von Resource-Library-Contracts in der faces-config.xml gezeigten Konfiguration wird allen Seiten, deren View-ID mit /special/ beginnt, der Contract layout-special und alle anderen Seiten der Contract layout zugeordnet.
<application>
  <resource-library-contracts>
    <contract-mapping>
      <url-pattern>/special/*</url-pattern>
      <contracts>layout-special</contracts>
    </contract-mapping>
    <contract-mapping>
      <url-pattern>*</url-pattern>
      <contracts>layout</contracts>
    </contract-mapping>
  </resource-library-contracts>
</application>
Die Zuordnung von Resource-Library-Contracts kann für einzelne Seiten gezielt überschrieben werden. Dazu gibt es im Tag f:view das neue Attribut contracts , in dem eine kommaseparierte Liste von Contract-Namen angegeben werden kann. Listing Zuordnung von Resource-Library-Contracts mit f:view zeigt ein Beispiel.
<f:view contracts="contract1">
  <ui:composition template="/template.xhtml">
    ...
  </ui:composition>
</f:view>
Im Attribut contracts kann auch eine Value-Expression angegeben werden, wie das folgende Beispiel zeigt:
<f:view contracts="#{bean.contracts}">
  ...
</f:view>
Die referenzierte Bean-Eigenschaft muss die Liste der Contract-Namen in Form einer Zeichenkette zurückliefern. Damit besteht die Möglichkeit, die einer Seite zugeordneten Contracts dynamisch zu ändern.
Wenn Sie jetzt auf die Idee kommen, das global in einem Template zu definieren, müssen wir Sie leider enttäuschen. JSF erlaubt die Definition der Contracts über f:view explizit nur in der ersten Datei, die beim Aufbau der Seite verarbeitet wird (also im Template-Client).

5.6.4 Resource-Library-Contracts in Jar-Dateien

Resource-Library-Contracts in Jar-Dateien bieten einige Vorteile. Sie können einerseits in mehreren Applikationen eingesetzt werden und lassen sich andererseits beim Bauen der Applikation einfach austauschen. Dabei sollten Sie allerdings darauf achten, dass der neue Contract dieselbe Schnittstelle definiert.
Jar-Dateien mit Resource-Library-Contracts sind schnell erstellt. Dazu müssen die Contracts nur in das Verzeichis /META-INF/contracts kopiert werden. Für den aus Abschnitt [Sektion:  Ein erstes Beispiel] bekannten Contract contract1 sieht die Verzeichnisstruktur dann wie in Abbildung Resource-Library-Contract in Jar-Datei aus.
Abbildung:Resource-Library-Contract in Jar-Datei
JSF berücksichtigt Resource-Library-Contracts aus Jar-Dateien nur dann, wenn sie eine Datei mit dem Namen javax.faces.contract.xml beinhalten. In JSF 2.2 kann diese Datei noch leer sein, was aber in zukünftigen Versionen von JSF nicht so bleiben muss.

5.6.5 MyGourmet 12 mit Resource-Library-Contracts

In diesem Abschnitt präsentieren wir eine Variante von MyGourmet 12 , bei der das Basis-Template der Applikation mithilfe von Resource-Library-Contracts verwaltet wird. Das erlaubt uns die Definition von zwei Contracts mit unterschiedlichem Design für den Kundenbereich und den Anbieterbereich der Applikation.
Die beiden Designs werden jeweils als Contract realisiert: base-color für das bereits bekannte Design und base-gray für eine in Grau gehaltene Variante. Beide Contracts beinhalten folgende Ressourcen:
Abbildung Resource-Library-Contracts in15mmMyGourmet 12 zeigt die Resource-Library-Contracts base-color und base-gray in der Verzeichnisstruktur der Applikation.
Abbildung:Resource-Library-Contracts in15mmMyGourmet 12
Um die Zuordnung von Contracts zu Seiten einfacher zu machen, haben wir die Seiten im Kundenbereich nach /views/customer und die Seiten im Anbieterbereich nach /views/provider verschoben. Damit können wir den Kundenseiten den Contract base-color und den Anbieterseiten den Contract base-gray zuordnen. Listing Konfiguration in MyGourmet 12 zeigt die entsprechende Konfiguration in der faces-config.xml .
<resource-library-contracts>
  <contract-mapping>
    <url-pattern>/views/customer/*</url-pattern>
    <contracts>base-color</contracts>
  </contract-mapping>
  <contract-mapping>
    <url-pattern>/views/provider/*</url-pattern>
    <contracts>base-gray</contracts>
  </contract-mapping>
</resource-library-contracts>
Die Seiten der Applikation benutzen weiterhin das Template customerTemplate.xhtml . Dort müssen wir noch den Pfad des Basis-Templates auf den Wert /template.xhtml ändern - dieses Template kommt jetzt wie das Stylesheet aus dem Contract. Das Logo wird als Ressource mit dem Namen logo.png ebenfalls aus dem Contract eingebunden.