Version: GSB 7ViewDispatcher
Das vorliegende Dokument richtet sich an Entwickler und ist somit ein rein technisches Konzept.
Das GSB Content Modell ist eine objekt-orientierte Datenstruktur, die unter anderem stark vom Vererbungskonzept Gebrauch macht. Ebenso wie Datentypen können auch die Darstellungstemplates, die einem Dokumenttyp zugeordnet sind, entlang der Vererbungshierarchie der Dokumenttyp vererbt werden. In einen abgeleiteten Dokumenttyp können vererbte Darstellungstemplates überschrieben werden. Wenn ein Dokument mithilfe eines Darstellungstemplates durch den CoreMedia Generator beispielsweise als HTML-Seite dargestellt werden soll, so muss zunächst die Implemation des Darstellungstemplates (d.h. die JSP) bestimmt werden, die aus dem CoreMedia Dokument den gewünschten HTML-Code erzeugt. Diese Aufgabe wird durch einen sogenannten Template Finder übernommen.
Ein ViewDispatcher ist ein spezieller Template Finder, der die Vererbungshierachie von Dokumenttypen besonders berücksichtigt. Der Standard ViewDispatcher von CoreMedia bietet allerdings keine Möglichkeit, mandantenspezifische JSP Templates zu verwalten. Dies ist aber zwingend erforderlich, damit verschiedene Mandanten auf einer Active Delivery Server Instanz betrieben werden und diese auch verschiedene Layouts (=Templates) haben können.
Es ist erforderlich, gemeinsame Templates für alle Mandanten zu haben, die aber nach bestimmten Regeln überschrieben bzw. ergänzt werden können.
Aus diesem Grund wurde für den GSB ein eigener TemplateFinder entwickelt, der auf dem Standard CoreMedia ViewDispatcher basiert und als Dispatcher für weitere "Unter"-ViewDispatcher dient (für jeden Mandanten einen). Dadurch können verschiedene Templates-Sets getrennt konfiguriert und verwaltet werden.
Ergänzend zu diesem Dokument ist in jedem Fall die „GSB_BasiskonfigurationMandant.doc“ zu sehen. Hier wird die Konfiguration der ViewDisapatcher beschrieben.
Technische Umsetzung
Der Einstiegspunkt für die technische Umsetzungsbetrachtung ist die Klasse
- de.bundonline.basis.web.viewdispatcher.
MultiCustomerViewDispatcher.
Sie dient als „der“ am Generator angemeldete TemplateFinder und bekommt die initialen Anfragen für das Auffinden eines Templates zu einer ResourceUri (siehe JavaDoc zu hox.corem.servlets.TemplateFinder#findTemplate (Generator generator, ResourceUri uri).
An einer (bzw. „der“) Instanz dieser Klasse können weitere Mandanten angemeldet werden, die intern über das Instanzieren eines jeweils eigenen von de.bundonline.basis.web.viewdispatcher.CustomerViewDispatcher abgeleiteten TemplateFinders abgebildet werden.
Derzeit gibt es 2 Implementierungen von CustomerViewDispatcher:
- de.bundonline.basis.web.viewdispatcher.
DefaultCustomerViewDispatcher
- de.bundonline.basis.web.viewdispatcher.
IndependentCustomerViewDispatcher
Wird vom Generator eine Anfrage zum Auffinden eines Templates an den MultiCustomerViewDispatcher weitergeleitet, so benutzt dieser die konfigurierte CustomerDeterminationRule. Implementierungen dieses Interfaces dienen dazu, zu einer gegebenen URI einen Identifier (=String) zurückzuliefern, der den Mandanten identifiziert.
Eine Implementierung ist zum Beispiel
- de.bundonline.basis.web.viewdispatcher.
PathViewCustomerDeterminationRule.
Diese Klasse gibt den Namen des 2. Ordners zurück, in dem die Resource aus der gegebenen URI liegt.
Beispiel:
Bei der URI = "/mandant/Content/meinArtikel.html" liefert PathViewCustomerDeterminationRule.getCustomerName() -> "mandant" als Ergebnis
Inhaltsverzeichnis
- 1 DefaultCustomerViewDispatcher
- 2 IndependentCustomerViewDispatcher
- 3 Property-Templates
- 4 ViewVarianten
- 5 UML Diagramme & UpdateViews
DefaultCustomerViewDispatcher
Der erste von beiden (DefaultCustomerViewDispatcher) bildet das sogenannte "Z" Vererbungsmuster ab. Die Implementierung sieht die Templates aus dem Mandanten-Template-Ordner dabei als Sichten/Views von virtuellen Dokumenttypen, die quasi in die reale Dokumenttypen-Vererbung eingeklinkt werden. Jeder reale Dokumenttyp erbt nun nicht mehr von seinem realen Parent-Dokumenttyp, sondern ist ein Kind von dem mandantenspezifischen (=virtuellen) Parent-Dokumenttyp.
Ein mandantenspezifischer Dokumenttyp wiederum erbt von dem realen Dokumenttyp gleichen Namens.
Beispiel:
Beim Einlesen der JSPs (Views) werden nun die Views auf reale und virtuelle Dokumenttypen abgebildet. Der ViewDispatcher benutzt dazu die Methode getDocTypeFromFilenname(String name), um den Namen des Dokumenttyps aus dem Pfad einer JSP zu ermitteln. Der DefaultCustomerViewDispatcher überschreibt diese Methode, benutzt die Super-Methode und ergänzt den dort gefundenen Dokumenttypnamen ggf. um ein Trennzeichen ("$") und den Namen des Mandanten, wenn die JSP unterhalb des mandantenspezifischen Template Verzeichnis liegt
- (templates/customers/{MANDANTENNAME}).
Beispiel:
getDocTypeFromFile-name("templates/customers/test/Article/render.jsp")
-> Article$test
getDocTypeFromFile-
name ("templates/Article/render.jsp")
-> Article
Der ViewDispatcher merkt sich diese gefunden View/Dokumenttyp-Paare in einer Map zum späteren Lookup beim Auffinden von Templates.
Wird nun ein Anfrage für eine bestimmte Resource an diesen ViewDispatcher weitergeleitet (vom MultiCustomerViewDispatcher, siehe oben), so versucht dieser zunächst den Dokumenttyp aus der URI zu ermitteln. Diese Methode des ViewDispatchers ist im DefaultCustomerViewDispatcher überschrieben und ergänzt den von der Superklasse gefundenen Dokumenttypennamen einfach um den Zusatz des Mandanten und erzeugt somit die Zuordnung zu dem mandantenspezifischen Dokumenttyp.
Beispiel:
Für den Mandanten "test" liefert getDocTypeFromUri(uri) für eine URI auf den Dokumenttyp "Article" das Ergebnis "Article$test".
Der jetzige Suchmechanismus nach dem passenden Template ist wiederum Teil des CoreMedia Standard ViewDispatcher, von dem wir ja erben. Er benutzt die zuvor eingelesene Map mit den realen und virtuellen Dokumenttyp-/View-Kombinationen, die auf JSPs verweisen. Wird kein Template für genau diesen Dokumenttyp gefunden, so ruft der ViewDispatcher die Methode superType(String type) auf, um den Parent-Dokumenttyp zu ermitteln. Auch diese Methode ist im DefaultCustomerViewDispatcher überschrieben und liefert, je nachdem ob der angefragte Typ bereits ein mandantenabhängiger Typ ist oder nicht, entweder einen realen oder einen virtuellen Dokumenttypnamen zurück.
Beispiel:
superType("Article") -> "Document$test"
superType("Article$test") -> "Article"
Hinweis:
Diese virtuellen Dokumenttypen existieren *nur* in dem DefaultCustomerViewDispatcher, keiner anderen Klasse ist dies bekannt (ansonsten würde es Fehler geben, wenn auf einen solchen Dokumenttyp referenziert würde)
IndependentCustomerViewDispatcher
Neben dem zuvor beschriebenen "Z"-Vererbungsmuster gibt es auch eine Konfiguration, bei der ein Mandant gar keine oder nur im Ausnahmefall Defaulttemplates benutzt. Bei einer Anfrage an den IndependentCustomerViewDispatcher, wird zunächst nur der Template-Zweig in dem mandantenabhängigen Teil berücksichtigt. Wird dort kein entsprechendes Template gefunden und ist der IndependentCustomerViewDispatcher so konfiguriert, dass er auch die Default-Templates nutzen darf (Konstruktor-Parameter useDefaultTemplates = true), so sucht der MultiCustomerViewDispatcher anschliessend in den default Templates. Anderenfalls bricht der Suchvorgang ab, bzw. es wird die doesNotUnderstand.jsp zurückgeliefert.
Beispiel Suchreihenfolge (mit Defaulttemplates):
Article$mandant ->
Document$mandant ->
Resource$mandant ->
Article ->
Document ->
Resource
Property-Templates
Property-Templates funktionieren natürlich analog. Diese werden intern vom ViewDispatcher ähnlich unseren oben beschriebenen virtuellen Dokumenttypen abgebildet, werden also aus Dokumenttypnamen, Trennzeichen, Propertytyp und ggf. weiterer Einschränkungen (MIME Type) gebildet. Wir ergänzen dann evtl. noch den Mandanten-Postfix und der restliche Lookup ist genau gleich, wie bei den Resource-Templates.
ViewVarianten
View Varianten sind ebenfalls möglich, jedoch ist die Suchreihenfolge beim DefaultCustomerViewDispatcher zu beachten. Wird ein Template plus ViewVariante gesucht, so wird zunächst versucht ein Template mit der ViewVariante im Mandanten-Template-Zweig zu finden. Gelingt dies nicht, so wird versucht das Template ohne Variante im Mandanten-Template-Zweig zu finden. Erst wenn dies auch nicht möglich ist, so wird auf den Default-Zweig übergegangen und dort zunächst wieder die Variante gesucht.
Beispiel Suchreihenfolge
Article$mandant.render[variante] ->
Article$mandant.render ->
Article.render[variante] ->
Article.render ->
Document$mandant.render[variante] ->
Document$mandant.render ->
Document.render[variante] ->
Document.render ->
Resource$mandant.render[variante] ->
Resource$mandant.render ->
Resource.render[variante] ->
Resource.render
Bei mehreren gleichzeitigen Varianten geht der ViewDispatcher so vor, dass er zunächst nach einer JSP mit allen Varianten sucht und danach immer die letzte Variante streicht.
render[varianteA, varianteB, varianteC] ->
render[varianteA, varianteB]
-> render[varianteA] -> render
UML Diagramme & UpdateViews
Die Anzeigen in den Generator Developseiten wurden entsprechend angepasst, so dass diese auch gezielt auf einen Mandanten angewendet werden können. Das gilt für die UpdateViews Aufrufe und die Darstellung des Dokumenttypmodells inklusive der gefundenen Views.