[Xplate] ist ein nahe an den XML-Standards implementierter XML-Prozessor. Hauptzweck ist das Verarbeiten von Web-Requests und Generieren von dynamischen Web-Inhalten, wobei [Xplate] nicht darauf eingeschränkt ist.

!!!Inhalt
[{TableOfContents numbered=true}]

!!!Hintergrund
!!Aktueller Stand der Technik
Es gibt eine Vielzahl von Frameworks für den Aufbau von Web-Seiten, selbst wenn man nur Java-basierte Systeme betrachtet. Allen gemeinsam ist, dass ein neues System erfunden wurde, das sehr spezielles und tiefes Know-How verlangt. Dabei unterscheiden sich die Frameworks untereinander so stark, das ein Umstieg fast einem Neueinstieg gleicht.

Das historisch erste XML-basierte System war wohl XSLT, das heute nur noch in speziellen Fällen eine Rolle spielt. Die Anwendung für Web-Seiten und HTML hat bis fast vollständig an Bedeutung verloren. Es wurde hauptsächlich durch JSP und deren Nachfolgersysteme, sowie rein Java-basierte Systeme verdrängt.

Diese Frameworks weisen inzwischen eine enorme Komplexität auf und sind selbst für langjährige Experten schwerlich einsehbar. Die Systeme sind gewachsen, mit der Anforderung auf Abwärtskompatibilität. Einige Teile, wie zum Beispiel die Tag-Unit ist in JSF derart tief verbaut, das auf dieser Ebene der Eingriff so gut wie nicht mehr möglich ist.

Das Verständnis, wann ein Tag aufgebaut wird, in welchen Phasen welche Variablen zur Verfügung stehen, wie weit andere Tags instantiiert sind, ist kaum mehr nachvollziehbar. Ein Effekt ist, dass das Verhalten von <c:forEach>, <ui:repeat> oder anderen dynamischen Elementen gerade in komplizierten Situationen nicht verstanden wird. Kleine Änderungen können ein unvoraussagbares Verhalten der Anwendung bewirken.

Auch andere Neuerungen, die vom Ansatz her eigentlich sehr nützlich sind, gestalten sich in der praktischen Anwendung als seht kompliziert. Als Beispiel seien hier Behaviors erwähnt, die nur bei speziellen Attributen wirken und explizit unterstützt werden müssen. Wenn dann auch noch sogenannte Composite Components im Spiel sind, bekommen selbst Hersteller großer Komponentenbibliotheken Probleme.

Auch das Einsatzgebiet ist stark eingeschränkt. Factories und viele statische Elemente sind so mit dem Web-Request verbunden, dass selbst das einfache Laden oder Rendern einer XHTML-Datei außerhalb des vorgesehenen Servlets zum Verhängnis wird.

Der Umgang mit EL-Expressions ist momentan eine Herausforderung für die wirklichen Profis. Die Kontexte sind mit der Tag-Erzeugung (Facelet-Context), Include-Anweisungen und Composite-Tags verbunden. Wobei Composite-Tags höchst ineffizient sind, da viele Tags durch den Speicher- und CPU-Intensiven Tag-Mechanismus geleitet werden müssen.

Der Umgang mit sogenannten View-States ist ein überladenes Thema, da die Komponentenbäume unmittelbar mit den gespeicherten Daten verbunden sind. Dadurch muss bei jedem Request der komplette Komponentenbaum rekonstruiert werden, auch wenn beispielsweise nur ein einziges Häkchen geändert wird.

!!Idee
XML ist eine recht ausgereifte Sprache, die sowohl von Computer und Maschine gut verstanden wird. Vor allem gibt es für XML-Dateien die Möglichkeit ein Schema zu definieren (oder mehrere), die beschreiben, welche Tags auftauchen können und welche Attribute diese enthalten können. Diese Schema-Dateien haben die Endung .xsd und werden direkt von den XML-Editoren der Entwicklungsumgebungen unterstützt, wie zum Beispiel von Eclipse.

Für eine Tag-Library inklusive Content-Assist und Hilfe-Texte ist nichts weiter nötig, als eine XSD-Datei zu generieren. Die Frameworks zum Einlesen von XML-Dateien liegen auch bereits lange vor, diese prüfen sogar auf Verstöße gegen diese Schema-Dateien.

Entsprechende Java-Klassen können anhand des XML-Namespace gefunden werden, dies können durch Konfiguration oder Annotationen zur Verfügung gestellt werden. Für das Abwickeln von Web-Requests ist dann nur noch ein kleines System erforderlich, das einen Kontext bereit hält, mit dem eine derart gestaltete XHTML-Seite abgearbeitet und das Ergebnis ausgegeben werden kann.

Die Komponentenbäume werden zustandsfrei gespeichert, der aktuelle Zustand in einfachen Kontekten gespeichert. Die Komponentenbäume können daher Request-, Session- und Applikationsübergreifend wiederverwerdet werden. Es fällt keinerlei Berechnungsaufwand für das Erzeugen, Serialisieren und Wiederherstellen an. Der Zustand wird durche den XplateContext transportiert und braucht sehr wenig Speicher.

!!Design-Criterien
Die Liste ist im Moment noch etwas unsortiert:

* Keine gehideten Methoden, Private Constructors und Package Classes, die volle Funktionalität von Xplate ist nutzbar.
* Einfacher straight-forward Ansatz. Die Aufrufe gehen alle durch die gleichen Methoden, alle Attribute und Elemente werden gleich behandelt. Im Zweifelsfall wird eine Exception geworfen, der Entwickler kann den Fehler beheben.
* Tags werden zu einem statischen Komponenten-Baum compiliert. Es gibt keine komplizierten Restore State oder State Saving.
* EL-Expressions werden statisch compiliert, die Werte werden ausschließlich durch Resolver ermittelt. Es gibt keine komplizierten dynamischen Kontexte für verschiedene Arten von Komponenten.
* EL-Expressions werden beim Abrufen durch den Tag erzeugt und auch am Tag gespeichert. Es gibt keinen komplizierten Evaluation-Mechanismus für Attribute auswerten.
* XML-Tags, für die keine Java-Klasse vorhanden ist, wird 1:1 in den Response Stream kopiert. Es wird keine komplizierte Interpretation jedes HTML-Attributs vorgenommen, noch die Auswahl möglicher Tags eingeschränkt. [Xplate] beschränkt sich auf Tags, für die eine Definition in Form einer @XmlNamespace annotierter Java-Klasse vorliegt.

!!Geplanter Umfang
Folgende Features sind geplant, dass sie in [Xplate] eingebaut werden:

* __Java-Tags:__ Die Möglichkeit, Tags auf einfache Weise in Java zu implementieren.
* __XML-Tags:__ Die Möglichkeit Tags ohne Java-Code zu implementieren. Statt dessen werden andere Tags zu einem neuen Tag kombiniert.
* __XML-Text:__ Text und Whitespace wird As-Is in den Output Stream kopiert um die Kontrolle über das Ergebnis zu maximieren. Es ist an jeder Stelle möglich, dieses Verhalten beliebig durch Tags zu ändern.
* __Statischer Pages:__ Pages, und damit auch Composite Tags, sind XML- bzw. XHTML-Dokumente, die aus hierarchisch angeordneten Tags bestehen. Dieser Tree wird nur einmal eingelesen und bleibt dann erhalten. Die Dynamik der Seiten erfolgt ausschließlich durch den Kontext (Xplate-Context), unter dem ein Tag oder eine ganze Page aufgerufen wird.
* __AJAX:__ In [Xplate] wird es Tags und eine Java-API geben, mit der vom Browser Teile einer Web-Seite abgeschickt und neu gerendert werden können.
* __EL-Expressions:__ Die Sprache für Expressions in [Xplate] sind EL-Expressions, wie diese von JSP, JSF und anderen Frameworks bekannt sind. Wie bei den Tags und Pages selbst, werden Expressions statisch compiliert. Das Auswerten erfolgt über den Xplate-Context.
* __EL-Methods:__ Method Expressions können genauso übergeben werden wie Value Expressions. Composite Tags und Native Tags können Value- und Method-Expressions gleichermaßen als Parameter entgegennehmen, unabhängig wo diese übergeben wurden, ohne extra Code.
* __XML-Schema:__ [Xplate] kommt mit XML-Schema (auch XSD genannt) aus, um die Tags zu beschreiben. Es sind keine besonderen Taglibs erforderlich, da Tags einfach mit dem entsprechenden XML-Namespace annotiert werden. Zum Unterstützen des Content-Assist von Entwicklungsumgebungen wird aus den Tags ein XML-Schema generiert.
* __Redirect:__ Seitenwechsel werden ausschließlich mit Redirect durchgeführt. Forwards bei denen der URL nicht mit der angezeigten Seite übereinstimmen sollen erst gar nicht eingeführt werden.

!!Aktueller Stand
[Xplate] ist lauffähig, befindet sich jedoch noch stark in der Entwicklung. Eine einsatzfähiger Stand ist bis zum Q3/2014 zu erwarten.

!!Performance
Da [Xplate] auf Effizienz getrimmt ist, werden die Seiten sehr schnell verarbeitet. Sicher kommt es nicht nur auf die View-Schicht an, wenn es um die Performance einer Anwendung geht. Umgekehrt leidet die Performance einer sonst gut aufgebauten Application durch eine ineffiziente View-Schicht.

[Xplate] läd die Seiten beim ersten Zugriff. Und weil die Seiten statisch sind, werden sie für konsequente Aufrufe gecacht:

{{{
INFO 2014-04-20 16:46:40,373 com.intersult.xplate.servlet.XplateServlet processing of '/index.xhtml' took 1110 ms 
INFO 2014-04-20 19:12:37,290 com.intersult.xplate.servlet.XplateServlet processing of '/index.xhtml' took 11 ms 
INFO 2014-04-20 19:12:39,209 com.intersult.xplate.servlet.XplateServlet processing of '/index.xhtml' took 10 ms 
INFO 2014-04-20 19:12:40,105 com.intersult.xplate.servlet.XplateServlet processing of '/index.xhtml' took 17 ms 
INFO 2014-04-20 19:12:41,074 com.intersult.xplate.servlet.XplateServlet processing of '/index.xhtml' took 17 ms 
INFO 2014-04-20 19:12:41,887 com.intersult.xplate.servlet.XplateServlet processing of '/index.xhtml' took 12 ms 
INFO 2014-04-20 19:12:42,677 com.intersult.xplate.servlet.XplateServlet processing of '/index.xhtml' took 8 ms 
INFO 2014-04-20 19:12:43,368 com.intersult.xplate.servlet.XplateServlet processing of '/index.xhtml' took 8 ms 
INFO 2014-04-20 19:12:44,036 com.intersult.xplate.servlet.XplateServlet processing of '/index.xhtml' took 8 ms 
INFO 2014-04-20 19:12:44,662 com.intersult.xplate.servlet.XplateServlet processing of '/index.xhtml' took 7 ms 
}}}

!!!Dokumentation
Hier wird API, Tags, Konfiguration und Hinweise zu [Xplate] dokumentuiert:

!!Configuration
[Xplate] kann durch eine Datei konfiguriert werden. Diese hat den Namen xplate-config.xml und befindet sich entweder in WEB-INF/xplate-config.xml oder META-INF/xplate-config.xml. Die Variante WEB-INF ist natürlich möglich, wenn Xplate über das XplateServlet in einem Servlet-Container gestartet wurde.

Die Konfiguration enthält unter anderem auch eine [XmlConfig|Abraxas#XMLKonfiguration], die über das XML-Element xmlConfig erreichbar ist.

!Beispiel
Die Konfiguration kann so aussehen:

{{{
<?xml version="1.0" encoding="UTF-8"?>
<xplate-config>
	<xmlConfig>
		<pretty>false</pretty>
	</xmlConfig>
	
	<resolver>com.intersult.xplate.spring.SpringBeanElResolver</resolver>
</xplate-config>
}}}

!!Meta Tags
Meta-Tags sind Bestandteil von [Xplate] und unter dem XML-Namespace http://intersult.com/xplate/meta und haben das Prefix meta.

!Include Tag
Mit dem Include-Tag kann ein Fragment in eine bestehende Page eingebunden werden:

{{{
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
		xmlns:meta="http://intersult.com/xplate/meta"
	<meta:include viewId="/fragment.xhtml"/>
</html>
}}}

Ein derartiges Fragment kann so aussehen:

{{{
<?xml version="1.0" encoding="UTF-8"?>
<meta:tag xmlns="http://www.w3.org/1999/xhtml"
		xmlns:meta="http://intersult.com/xplate/meta"
		xmlns:flow="http://intersult.com/xplate/flow"
		xmlns:h="http://intersult.com/xplate/html">
	<p>
		<h:text value="Included Tag"/>
	</p>
</meta:tag>
}}}

__Hinweis:__ der Tag <meta:tag> stellt zum einen die Möglichkeit zur Verfügung, Namespaces anzugeben (xmlns:...), zum anderen sorgt er für ein einheitliches Interface.

!Attribute Tag
Attribute Tags sind eine erweiterte Möglichkeit, Werte für ein Attribut des Parent Tags zu erzeugen:

{{{
<h:text>
    <meta:attribute name="value" value="Attribute value"/>
</h:text>
}}}

__Hinweis:__ Attribut Tags sind generisch, das heißt sie können ohne extra Code oder Aufwand überall verwendet werden.

!!Allgemeine Tags (HTML)
[Xplate] behandelt Tags einheitlich. Alle Tags unterstützen EL-Expressions, Meta Tags etc. [Xplate] liefert daher nicht für jeden HTML-Tag einen eigenen Tag mit. Es reicht völlig aus, den Namespace in der Page anzugeben und enthaltene Tags in die Page zu schreiben:

{{{
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
	<head>
		<meta http-equiv="X-UA-Compatible" content="IE=9; IE=8"/>
		<title>test</title>
	</head>
	<body>
		<h1>Hello World</h1>
	</body>
</html>
}}}

!!Spezielle HTML Tags
Es gibt spezielle Tags, für die eine erweiterte Unterstützung von [Xplate] angeboten wird. Diese werden unter dem Namespace http://intersult.com/xplate/html mit dem Prefix h.

!Der Text Tag
Mit diesem Tag ist das Ausgeben von Text möglich. Generell kann auch Text zwischen die Tags geschrieben werden, wie es bei XML gemeinhin üblich ist. Allerdings unterstützt der Text-Tag das dynamische Gestalten der Seite:

{{{
<h:text value="#{testBean.text}"/>
}}}

__Hinweis:__ Wenn XML-Text inline geschrieben wird, entsteht intern ein Tag vom Typ <h:text>.

!!Flow Tags
Flow-Tags stehen unter dem Namespace http://intersult.com/xplate/flow und dem Prefix flow zur Verfügung.

!If Tag
Mit dem If Tag ist ein bedingtes Abarbeiten der untergeordneten Tags möglich:

{{{
<flow:if test="#{true}">
	<h1>Hello World!</h1>
</flow:if>
}}}

!!Composite Tags
In [Xplate] können Composite Tags gebaut werden. Diese können dann wir andere Tags in einer Page verwendet werden. Composite Tags werden angesprochen, indem der Namespace mit http://intersult.com/xplate/tag/<prefix>/ beginnt. Die entsprechenden XHTML-Dateien werden dann unter <base-path>/tag/<prefix>/ zugegriffen.

{{{
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
		xmlns:meta="http://intersult.com/xplate/meta"
		xmlns:flow="http://intersult.com/xplate/flow"
		xmlns:h="http://intersult.com/xplate/html"
		xmlns:app="http://intersult.com/xplate/tag/app">
	...
	<app:composite/>
	...
</html>
}}}

Der Composite Tag befindet sich dann unter /tag/app/composite.xhtml:

{{{
<?xml version="1.0" encoding="UTF-8"?>
<meta:tag xmlns="http://www.w3.org/1999/xhtml"
		xmlns:meta="http://intersult.com/xplate/meta"
		xmlns:flow="http://intersult.com/xplate/flow"
		xmlns:h="http://intersult.com/xplate/html">
	<p>
		<h:text value="Composite Tag"/>
	</p>
</meta:tag>
}}}