Cocoon Transformer
- Auslesung des Benutzermodells,
- Finden der ersten Logik,
- Eintreten in die einzelnen Logikknoten der Verzweigung
- Finden und Herauslösen der gefundenen Variante,
- nach erfolgter Umwandlung erneutes Auslesen des Gesamtbaumes
- function setup
Diese erhält die übergebenen Parameter aus der sitemap.xmap und bereitet diese für eine spätere Transformation auf
- function transformer
Hierüber wird das zu bearbeitende Dokument als org.w3c.Document übergeben, als Rückgabewert wird wiederum das geparste Dokument erwartet.
- Auslesung des Benutzermodells,
- Finden der ersten Logik,
- Eintreten in die einzelnen Logikknoten der Verzweigung
- Finden und Herauslösen der gefundenen Variante,
- nach erfolgter Umwandlung erneutes Auslesen des Gesamtbaumes
- function setup
Diese erhält die übergebenen Parameter aus der sitemap.xmap und bereitet diese für eine spätere Transformation auf
- function transformer
Hierüber wird das zu bearbeitende Dokument als org.w3c.Document übergeben, als Rückgabewert wird wiederum das geparste Dokument erwartet.
- Auslesung des Benutzermodells,
- Finden der ersten Logik,
- Eintreten in die einzelnen Logikknoten der Verzweigung
- Finden und Herauslösen der gefundenen Variante,
- nach erfolgter Umwandlung erneutes Auslesen des Gesamtbaumes
- function setup
Diese erhält die übergebenen Parameter aus der sitemap.xmap und bereitet diese für eine spätere Transformation auf
- function transformer
Hierüber wird das zu bearbeitende Dokument als org.w3c.Document übergeben, als Rückgabewert wird wiederum das geparste Dokument erwartet.
- Auslesung des Benutzermodells,
- Finden der ersten Logik,
- Eintreten in die einzelnen Logikknoten der Verzweigung
- Finden und Herauslösen der gefundenen Variante,
- nach erfolgter Umwandlung erneutes Auslesen des Gesamtbaumes
- function setup
Diese erhält die übergebenen Parameter aus der sitemap.xmap und bereitet diese für eine spätere Transformation auf
- function transformer
Hierüber wird das zu bearbeitende Dokument als org.w3c.Document übergeben, als Rückgabewert wird wiederum das geparste Dokument erwartet.
- Auslesung des Benutzermodells,
- Finden der ersten Logik,
- Eintreten in die einzelnen Logikknoten der Verzweigung
- Finden und Herauslösen der gefundenen Variante,
- nach erfolgter Umwandlung erneutes Auslesen des Gesamtbaumes
- function setup
Diese erhält die übergebenen Parameter aus der sitemap.xmap und bereitet diese für eine spätere Transformation auf
- function transformer
Hierüber wird das zu bearbeitende Dokument als org.w3c.Document übergeben, als Rückgabewert wird wiederum das geparste Dokument erwartet.
- Auslesung des Benutzermodells,
- Finden der ersten Logik,
- Eintreten in die einzelnen Logikknoten der Verzweigung
- Finden und Herauslösen der gefundenen Variante,
- nach erfolgter Umwandlung erneutes Auslesen des Gesamtbaumes
- function setup
Diese erhält die übergebenen Parameter aus der sitemap.xmap und bereitet diese für eine spätere Transformation auf
- function transformer
Hierüber wird das zu bearbeitende Dokument als org.w3c.Document übergeben, als Rückgabewert wird wiederum das geparste Dokument erwartet.
- Auslesung des Benutzermodells,
- Finden der ersten Logik,
- Eintreten in die einzelnen Logikknoten der Verzweigung
- Finden und Herauslösen der gefundenen Variante,
- nach erfolgter Umwandlung erneutes Auslesen des Gesamtbaumes
- function setup
Diese erhält die übergebenen Parameter aus der sitemap.xmap und bereitet diese für eine spätere Transformation auf
- function transformer
Hierüber wird das zu bearbeitende Dokument als org.w3c.Document übergeben, als Rückgabewert wird wiederum das geparste Dokument erwartet.
Cocoon Transformer
Cocoon Transformer
Cocoon Transformer
Cocoon Transformer
Cocoon Transformer
Cocoon Transformer
Die unter Kapitel 4.2 durchgeführte Testreihe hatte den auf XSL basierenden Adaptions-Transformator als den größten Flaschenhals der Amacont-Pipeline identifiziert. Seine Aufgabe besteht in der Anpassung der Datenquelle an nutzerspezifische Eigenschaften, wie Bildschirmauflösung, Bandbreite, Alter des Nutzers etc. (vergleiche Abb. 14). Er enthält zu diesem Zweck eine aufwendige und unter [Ama03] sowie [Ama04] ausführlich vorgestellte Logik.
Um die Belastungen dieser Logiken abzumindern, wird er aus der rekursiv arbeitenden XSLT-Form in die eines Java-Transformators überführt. Dadurch kommen die unter Kapitel 3.4.3.5 genannten Vorteile zum tragen und der in Kapitel 4.2 gezeigte und nachgewiesenen Performancegewinn stellt sich ein. Folgend soll nun der Aufbau und die Funktionsweise beleuchtet werden.
Bei der Auswahl der passenden Technik stellt sich die Wahl zwischen der Nutzung einer SAX-basierenden Darstellung oder der Verwendung eines Views auf das komplette “Document Object Model” (DOM). Während bei ersterem der Quellcode wie bei einem Walkthrough durchlaufen wird, bildet ein DOM das XML-Dokument als Baum komplett im Speicher ab.
Die Änderung der Adaptions-Eigenschaften ist eine komplexe Aufgabe. Zunächst werden die übergebenen Parameter aus dem an das eigentliche AmaKomponenten-Dokument angehangene NutzerModell ausgelesen und daraufhin das Dokument nach Vorkommen dieser Parameter in den vorhandenen Logiken durchsucht, vereinfacht bzw. aufgelöst, wobei Zwischenschritte für einen mehrmaligen Durchlauf gespeichert werden. Die jeweilige Varianten-Darstellung ersetzt die vorgegebene Logik und beendet somit den Adaptionsprozess.
Eine Umsetzung anhand eines Sax-Parsers ist möglich, wobei das Dokument für die folgenden Aufgaben durchlaufen werden mu
Eine weitere theoretische Möglichkeit ist die selbständige Erstellung großer XML-Bäume innerhalb des Sax-Transformators, was jedoch als nicht sinnvoll angesehen wird.
Daher fällt die Wahl auf die Nutzung eines DOM-Transformators. Zu dieser Technologie sind innerhalb des Amacont-Projektes gute Erfahrungen vorhanden, da der LinkTransformer
auf diese Weise erstellt wurde. Die Wartung und Erweiterung des DOM-Transformators benötigt daher einen geringen Einarbeitungsaufwand.
Für den zu erstellenden AbstractDOMTransformer
sind grundsätzlich folgende zwei Funktionen von Bedeutung:
Um die Überschaubarkeit des Quellcodes zu gewährleisten und Performanz- und Lasttests zu unterstützen, wurde der Transformator in 3 Klassen aufgeteilt: den eigentlichen EvalLogicTransformer
als Hauptklasse, den EvalLogicParameter
als die Parameter enthaltende Klasse, und den EvalLogicResolver
, welcher in der Logik enthaltene Terme gegeneinander auflöst.
Zunächst wird beim Start der Laufzeitumgebung die Transformatorenklasse EvalLogicTransformer
instantiiert und der entsprechende Konstruktor public EvalLogicTransformer()
aufgerufen. Cocoon hält diese Instanz bis zum Neustart des Servers.
Erreicht Cocoon nun innerhalb der Sitemap einen die Klasse betreffenden Transformator, so übergibt er mit Hilfe der setup
-Funktion neben Umgebungsvariablen die Parameter der Sitemap.
<map:transform type="evalLogic">
<map:parameter name="givParam" value="Format;Age;InnerSizeX"/>
<map:parameter name="debug" value="true"/>
<map:parameter name="Format" value="xHTML"/>
</map:transform>
Diese werden aus dem Parameter-Array ausgelesen und an die EvalLogicParameter
-Klasse weitergeleitet. Wie im obigen Beispiel ersichtlich ist, beinhaltet der Aufruf bereits einen fest kodierten Parameter. Dieser wird sofort an die Parameterklasse übergeben und ist resistent gegenüber etwaig folgenden Nutzermodell-Einträgen.
Hierbei besteht derzeit eine Fehlverarbeitung innerhalb des Cocoon- oder unterliegenden Avalon-Systems, da bei Nacheinanderausführung des Transformators mit unterschiedlichen Parametern diese hintereinander in den ersten Transformator übertragen werden und sich somit gegenseitig überschrieben. Bei Zwischenschaltung eines fremden Transformators trat dieses Problem nicht auf.
Folgend wird das zu bearbeitende Dokument als org.w3c.Document
-Klasse mit Hilfe der transform
-Funktion an die Klasseninstanz übergeben und durchläuft sequentiell die folgenden Schritte.
Für die Grammatik des Dokuments besitzt die Reihenfolge eine wichtige Bedeutung. Da bei der Dokumenterstellung oftmals Kommentare oder Leerzeichen eingefügt werden, entfernt cleanup(Node node, short nodeType, String name)
sämtliche derartige Knoten. Daraufhin wird das Nutzermodell vom Dokumentende ausgelesen und an die Parameterklasse übergeben, welche die XML-Daten mit den Parametern abgleicht und entsprechende Werte übernimmt.
Nun bildet der Transformator eine alle Logiken enthaltende Knotenliste und leitet diese je nach Typ (If
-, Switch
-, Trinary
-Logik) ab.
Hier wird am Beispiel eines If-Knotens ersichtlich, dass dieser den Logik-Teil <aada:Term> an die Klasse LogicResolver
weiterleitet, welche die Rekursivität der Logik auflöst. Kommen dabei Nutzerparameter der Art <aada:UserParam>
vor, wird versucht, diese mit Hilfe der Parameter-Klasse aufzulösen. Komplett aufgelöste Baumzweige werden durch <aada:Const>Wert</aada:Const>
ersetzt, so dass die sequentielle Ausführung mit verteilten Nutzerinformationen möglich ist.
Im letzten Schritt wird bei gesetztem "_end_
" - Parameter das Nutzermodell aus dem Dokument entfernt und somit die Weiterverarbeitung innerhalb der Cocoon-Pipeline sichergestellt.
svg - komplettes Sequenzdiagramm - Vergrössern
Die fertige Komponente wird, wie unter Kapitel 3.1 angesprochen, in zwei Abschnitten der Sitemap des Amacont-Projektes eingefügt. Innerhalb des Definitionsabschnittes gilt es, die Initialisierung vorzunehmen:
<map:components>
<map:transformer name="evalLogic" src="de.amacont.dom.transformation.EvalLogicTransformer"/></map:components>
Während der Pipeline-Abarbeitung folgt dann der verarbeitende Aufruf. Dieser kann mehrmals sequentiell mit unterschiedlichen Parametern erfolgen. Der folgende Codeabschnitt zeigt ein mögliches Beispiel.:
<map:pipeline>
<map:match pattern="testEval">
<map:generate src="web/videothek/testMe.xml"/>
<map:transform type="evalLogic">
<map:parameter name="givParam" value="Age"/>
<map:parameter name="debug" value="true"/>
</map:transform>
<map:transform type="evalLogic">
<map:parameter name="givParam" value="Format;_end_"/>
<map:parameter name="debug" value="true"/>
</map:transform>
</map:match pattern="testEval">
</map:pipeline>
Zu Erprobungszwecken können ebenfalls die dem Projekt beigelegten JUnit-Tests verwendet werden, welche gleichzeitig die Robustheit bei ausgewählten Extremsituationen nachweisen.
Die unter Kapitel 4.2 durchgeführte Testreihe hatte den auf XSL basierenden Adaptions-Transformator als den größten Flaschenhals der Amacont-Pipeline identifiziert. Seine Aufgabe besteht in der Anpassung der Datenquelle an nutzerspezifische Eigenschaften, wie Bildschirmauflösung, Bandbreite, Alter des Nutzers etc. (vergleiche Abb. 14). Er enthält zu diesem Zweck eine aufwendige und unter [Ama03] sowie [Ama04] ausführlich vorgestellte Logik.
Um die Belastungen dieser Logiken abzumindern, wird er aus der rekursiv arbeitenden XSLT-Form in die eines Java-Transformators überführt. Dadurch kommen die unter Kapitel 3.4.3.5 genannten Vorteile zum tragen und der in Kapitel 4.2 gezeigte und nachgewiesenen Performancegewinn stellt sich ein. Folgend soll nun der Aufbau und die Funktionsweise beleuchtet werden.
Auswahl der passenden Unterklasse
Bei der Auswahl der passenden Technik stellt sich die Wahl zwischen der Nutzung einer SAX-basierenden Darstellung oder der Verwendung eines Views auf das komplette “Document Object Model” (DOM). Während bei ersterem der Quellcode wie bei einem Walkthrough durchlaufen wird, bildet ein DOM das XML-Dokument als Baum komplett im Speicher ab.
Die Änderung der Adaptions-Eigenschaften ist eine komplexe Aufgabe. Zunächst werden die übergebenen Parameter aus dem an das eigentliche AmaKomponenten-Dokument angehangene NutzerModell ausgelesen und daraufhin das Dokument nach Vorkommen dieser Parameter in den vorhandenen Logiken durchsucht, vereinfacht bzw. aufgelöst, wobei Zwischenschritte für einen mehrmaligen Durchlauf gespeichert werden. Die jeweilige Varianten-Darstellung ersetzt die vorgegebene Logik und beendet somit den Adaptionsprozess.
Eine Umsetzung anhand eines Sax-Parsers ist möglich, wobei das Dokument für die folgenden Aufgaben durchlaufen werden mu
Eine weitere theoretische Möglichkeit ist die selbständige Erstellung großer XML-Bäume innerhalb des Sax-Transformators, was jedoch als nicht sinnvoll angesehen wird.
Daher fällt die Wahl auf die Nutzung eines DOM-Transformators. Zu dieser Technologie sind innerhalb des Amacont-Projektes gute Erfahrungen vorhanden, da der LinkTransformer
auf diese Weise erstellt wurde. Die Wartung und Erweiterung des DOM-Transformators benötigt daher einen geringen Einarbeitungsaufwand.
Grundaufbau
Für den zu erstellenden AbstractDOMTransformer
sind grundsätzlich folgende zwei Funktionen von Bedeutung:
Um die Überschaubarkeit des Quellcodes zu gewährleisten und Performanz- und Lasttests zu unterstützen, wurde der Transformator in 3 Klassen aufgeteilt: den eigentlichen EvalLogicTransformer
als Hauptklasse, den EvalLogicParameter
als die Parameter enthaltende Klasse, und den EvalLogicResolver
, welcher in der Logik enthaltene Terme gegeneinander auflöst.
Vorgehen innerhalb des Transformers
Zunächst wird beim Start der Laufzeitumgebung die Transformatorenklasse EvalLogicTransformer
instantiiert und der entsprechende Konstruktor public EvalLogicTransformer()
aufgerufen. Cocoon hält diese Instanz bis zum Neustart des Servers.
Erreicht Cocoon nun innerhalb der Sitemap einen die Klasse betreffenden Transformator, so übergibt er mit Hilfe der setup
-Funktion neben Umgebungsvariablen die Parameter der Sitemap.
<map:transform type="evalLogic">
<map:parameter name="givParam" value="Format;Age;InnerSizeX"/>
<map:parameter name="debug" value="true"/>
<map:parameter name="Format" value="xHTML"/>
</map:transform>
Diese werden aus dem Parameter-Array ausgelesen und an die EvalLogicParameter
-Klasse weitergeleitet. Wie im obigen Beispiel ersichtlich ist, beinhaltet der Aufruf bereits einen fest kodierten Parameter. Dieser wird sofort an die Parameterklasse übergeben und ist resistent gegenüber etwaig folgenden Nutzermodell-Einträgen.
Hierbei besteht derzeit eine Fehlverarbeitung innerhalb des Cocoon- oder unterliegenden Avalon-Systems, da bei Nacheinanderausführung des Transformators mit unterschiedlichen Parametern diese hintereinander in den ersten Transformator übertragen werden und sich somit gegenseitig überschrieben. Bei Zwischenschaltung eines fremden Transformators trat dieses Problem nicht auf.
Folgend wird das zu bearbeitende Dokument als org.w3c.Document
-Klasse mit Hilfe der transform
-Funktion an die Klasseninstanz übergeben und durchläuft sequentiell die folgenden Schritte.
Für die Grammatik des Dokuments besitzt die Reihenfolge eine wichtige Bedeutung. Da bei der Dokumenterstellung oftmals Kommentare oder Leerzeichen eingefügt werden, entfernt cleanup(Node node, short nodeType, String name)
sämtliche derartige Knoten. Daraufhin wird das Nutzermodell vom Dokumentende ausgelesen und an die Parameterklasse übergeben, welche die XML-Daten mit den Parametern abgleicht und entsprechende Werte übernimmt.
Nun bildet der Transformator eine alle Logiken enthaltende Knotenliste und leitet diese je nach Typ (If
-, Switch
-, Trinary
-Logik) ab.
Hier wird am Beispiel eines If-Knotens ersichtlich, dass dieser den Logik-Teil <aada:Term> an die Klasse LogicResolver
weiterleitet, welche die Rekursivität der Logik auflöst. Kommen dabei Nutzerparameter der Art <aada:UserParam>
vor, wird versucht, diese mit Hilfe der Parameter-Klasse aufzulösen. Komplett aufgelöste Baumzweige werden durch <aada:Const>Wert</aada:Const>
ersetzt, so dass die sequentielle Ausführung mit verteilten Nutzerinformationen möglich ist.
Im letzten Schritt wird bei gesetztem "_end_
" - Parameter das Nutzermodell aus dem Dokument entfernt und somit die Weiterverarbeitung innerhalb der Cocoon-Pipeline sichergestellt.
svg - komplettes Sequenzdiagramm - Vergrössern
Einbindung
Die fertige Komponente wird, wie unter Kapitel 3.1 angesprochen, in zwei Abschnitten der Sitemap des Amacont-Projektes eingefügt. Innerhalb des Definitionsabschnittes gilt es, die Initialisierung vorzunehmen:
<map:components>
<map:transformer name="evalLogic" src="de.amacont.dom.transformation.EvalLogicTransformer"/></map:components>
Während der Pipeline-Abarbeitung folgt dann der verarbeitende Aufruf. Dieser kann mehrmals sequentiell mit unterschiedlichen Parametern erfolgen. Der folgende Codeabschnitt zeigt ein mögliches Beispiel.:
<map:pipeline>
<map:match pattern="testEval">
<map:generate src="web/videothek/testMe.xml"/>
<map:transform type="evalLogic">
<map:parameter name="givParam" value="Age"/>
<map:parameter name="debug" value="true"/>
</map:transform>
<map:transform type="evalLogic">
<map:parameter name="givParam" value="Format;_end_"/>
<map:parameter name="debug" value="true"/>
</map:transform>
</map:match pattern="testEval">
</map:pipeline>
Zu Erprobungszwecken können ebenfalls die dem Projekt beigelegten JUnit-Tests verwendet werden, welche gleichzeitig die Robustheit bei ausgewählten Extremsituationen nachweisen.
Die unter Kapitel 4.2 durchgeführte Testreihe hatte den auf XSL basierenden Adaptions-Transformator als den größten Flaschenhals der Amacont-Pipeline identifiziert. Seine Aufgabe besteht in der Anpassung der Datenquelle an nutzerspezifische Eigenschaften, wie Bildschirmauflösung, Bandbreite, Alter des Nutzers etc. (vergleiche Abb. 14). Er enthält zu diesem Zweck eine aufwendige und unter [Ama03] sowie [Ama04] ausführlich vorgestellte Logik.
Um die Belastungen dieser Logiken abzumindern, wird er aus der rekursiv arbeitenden XSLT-Form in die eines Java-Transformators überführt. Dadurch kommen die unter Kapitel 3.4.3.5 genannten Vorteile zum tragen und der in Kapitel 4.2 gezeigte und nachgewiesenen Performancegewinn stellt sich ein. Folgend soll nun der Aufbau und die Funktionsweise beleuchtet werden.
Auswahl der passenden Unterklasse
Bei der Auswahl der passenden Technik stellt sich die Wahl zwischen der Nutzung einer SAX-basierenden Darstellung oder der Verwendung eines Views auf das komplette “Document Object Model” (DOM). Während bei ersterem der Quellcode wie bei einem Walkthrough durchlaufen wird, bildet ein DOM das XML-Dokument als Baum komplett im Speicher ab.
Die Änderung der Adaptions-Eigenschaften ist eine komplexe Aufgabe. Zunächst werden die übergebenen Parameter aus dem an das eigentliche AmaKomponenten-Dokument angehangene NutzerModell ausgelesen und daraufhin das Dokument nach Vorkommen dieser Parameter in den vorhandenen Logiken durchsucht, vereinfacht bzw. aufgelöst, wobei Zwischenschritte für einen mehrmaligen Durchlauf gespeichert werden. Die jeweilige Varianten-Darstellung ersetzt die vorgegebene Logik und beendet somit den Adaptionsprozess.
Eine Umsetzung anhand eines Sax-Parsers ist möglich, wobei das Dokument für die folgenden Aufgaben durchlaufen werden mu
Eine weitere theoretische Möglichkeit ist die selbständige Erstellung großer XML-Bäume innerhalb des Sax-Transformators, was jedoch als nicht sinnvoll angesehen wird.
Daher fällt die Wahl auf die Nutzung eines DOM-Transformators. Zu dieser Technologie sind innerhalb des Amacont-Projektes gute Erfahrungen vorhanden, da der LinkTransformer
auf diese Weise erstellt wurde. Die Wartung und Erweiterung des DOM-Transformators benötigt daher einen geringen Einarbeitungsaufwand.
Grundaufbau
Für den zu erstellenden AbstractDOMTransformer
sind grundsätzlich folgende zwei Funktionen von Bedeutung:
Um die Überschaubarkeit des Quellcodes zu gewährleisten und Performanz- und Lasttests zu unterstützen, wurde der Transformator in 3 Klassen aufgeteilt: den eigentlichen EvalLogicTransformer
als Hauptklasse, den EvalLogicParameter
als die Parameter enthaltende Klasse, und den EvalLogicResolver
, welcher in der Logik enthaltene Terme gegeneinander auflöst.
Vorgehen innerhalb des Transformers
Zunächst wird beim Start der Laufzeitumgebung die Transformatorenklasse EvalLogicTransformer
instantiiert und der entsprechende Konstruktor public EvalLogicTransformer()
aufgerufen. Cocoon hält diese Instanz bis zum Neustart des Servers.
Erreicht Cocoon nun innerhalb der Sitemap einen die Klasse betreffenden Transformator, so übergibt er mit Hilfe der setup
-Funktion neben Umgebungsvariablen die Parameter der Sitemap.
<map:transform type="evalLogic">
<map:parameter name="givParam" value="Format;Age;InnerSizeX"/>
<map:parameter name="debug" value="true"/>
<map:parameter name="Format" value="xHTML"/>
</map:transform>
Diese werden aus dem Parameter-Array ausgelesen und an die EvalLogicParameter
-Klasse weitergeleitet. Wie im obigen Beispiel ersichtlich ist, beinhaltet der Aufruf bereits einen fest kodierten Parameter. Dieser wird sofort an die Parameterklasse übergeben und ist resistent gegenüber etwaig folgenden Nutzermodell-Einträgen.
Hierbei besteht derzeit eine Fehlverarbeitung innerhalb des Cocoon- oder unterliegenden Avalon-Systems, da bei Nacheinanderausführung des Transformators mit unterschiedlichen Parametern diese hintereinander in den ersten Transformator übertragen werden und sich somit gegenseitig überschrieben. Bei Zwischenschaltung eines fremden Transformators trat dieses Problem nicht auf.
Folgend wird das zu bearbeitende Dokument als org.w3c.Document
-Klasse mit Hilfe der transform
-Funktion an die Klasseninstanz übergeben und durchläuft sequentiell die folgenden Schritte.
Für die Grammatik des Dokuments besitzt die Reihenfolge eine wichtige Bedeutung. Da bei der Dokumenterstellung oftmals Kommentare oder Leerzeichen eingefügt werden, entfernt cleanup(Node node, short nodeType, String name)
sämtliche derartige Knoten. Daraufhin wird das Nutzermodell vom Dokumentende ausgelesen und an die Parameterklasse übergeben, welche die XML-Daten mit den Parametern abgleicht und entsprechende Werte übernimmt.
Nun bildet der Transformator eine alle Logiken enthaltende Knotenliste und leitet diese je nach Typ (If
-, Switch
-, Trinary
-Logik) ab.
Hier wird am Beispiel eines If-Knotens ersichtlich, dass dieser den Logik-Teil <aada:Term> an die Klasse LogicResolver
weiterleitet, welche die Rekursivität der Logik auflöst. Kommen dabei Nutzerparameter der Art <aada:UserParam>
vor, wird versucht, diese mit Hilfe der Parameter-Klasse aufzulösen. Komplett aufgelöste Baumzweige werden durch <aada:Const>Wert</aada:Const>
ersetzt, so dass die sequentielle Ausführung mit verteilten Nutzerinformationen möglich ist.
Im letzten Schritt wird bei gesetztem "_end_
" - Parameter das Nutzermodell aus dem Dokument entfernt und somit die Weiterverarbeitung innerhalb der Cocoon-Pipeline sichergestellt.
svg - komplettes Sequenzdiagramm - Vergrössern
Einbindung
Die fertige Komponente wird, wie unter Kapitel 3.1 angesprochen, in zwei Abschnitten der Sitemap des Amacont-Projektes eingefügt. Innerhalb des Definitionsabschnittes gilt es, die Initialisierung vorzunehmen:
<map:components>
<map:transformer name="evalLogic" src="de.amacont.dom.transformation.EvalLogicTransformer"/></map:components>
Während der Pipeline-Abarbeitung folgt dann der verarbeitende Aufruf. Dieser kann mehrmals sequentiell mit unterschiedlichen Parametern erfolgen. Der folgende Codeabschnitt zeigt ein mögliches Beispiel.:
<map:pipeline>
<map:match pattern="testEval">
<map:generate src="web/videothek/testMe.xml"/>
<map:transform type="evalLogic">
<map:parameter name="givParam" value="Age"/>
<map:parameter name="debug" value="true"/>
</map:transform>
<map:transform type="evalLogic">
<map:parameter name="givParam" value="Format;_end_"/>
<map:parameter name="debug" value="true"/>
</map:transform>
</map:match pattern="testEval">
</map:pipeline>
Zu Erprobungszwecken können ebenfalls die dem Projekt beigelegten JUnit-Tests verwendet werden, welche gleichzeitig die Robustheit bei ausgewählten Extremsituationen nachweisen.
Die unter Kapitel 4.2 durchgeführte Testreihe hatte den auf XSL basierenden Adaptions-Transformator als den größten Flaschenhals der Amacont-Pipeline identifiziert. Seine Aufgabe besteht in der Anpassung der Datenquelle an nutzerspezifische Eigenschaften, wie Bildschirmauflösung, Bandbreite, Alter des Nutzers etc. (vergleiche Abb. 14). Er enthält zu diesem Zweck eine aufwendige und unter [Ama03] sowie [Ama04] ausführlich vorgestellte Logik.
Um die Belastungen dieser Logiken abzumindern, wird er aus der rekursiv arbeitenden XSLT-Form in die eines Java-Transformators überführt. Dadurch kommen die unter Kapitel 3.4.3.5 genannten Vorteile zum tragen und der in Kapitel 4.2 gezeigte und nachgewiesenen Performancegewinn stellt sich ein. Folgend soll nun der Aufbau und die Funktionsweise beleuchtet werden.
Auswahl der passenden Unterklasse
Bei der Auswahl der passenden Technik stellt sich die Wahl zwischen der Nutzung einer SAX-basierenden Darstellung oder der Verwendung eines Views auf das komplette “Document Object Model” (DOM). Während bei ersterem der Quellcode wie bei einem Walkthrough durchlaufen wird, bildet ein DOM das XML-Dokument als Baum komplett im Speicher ab.
Die Änderung der Adaptions-Eigenschaften ist eine komplexe Aufgabe. Zunächst werden die übergebenen Parameter aus dem an das eigentliche AmaKomponenten-Dokument angehangene NutzerModell ausgelesen und daraufhin das Dokument nach Vorkommen dieser Parameter in den vorhandenen Logiken durchsucht, vereinfacht bzw. aufgelöst, wobei Zwischenschritte für einen mehrmaligen Durchlauf gespeichert werden. Die jeweilige Varianten-Darstellung ersetzt die vorgegebene Logik und beendet somit den Adaptionsprozess.
Eine Umsetzung anhand eines Sax-Parsers ist möglich, wobei das Dokument für die folgenden Aufgaben durchlaufen werden mu
Eine weitere theoretische Möglichkeit ist die selbständige Erstellung großer XML-Bäume innerhalb des Sax-Transformators, was jedoch als nicht sinnvoll angesehen wird.
Daher fällt die Wahl auf die Nutzung eines DOM-Transformators. Zu dieser Technologie sind innerhalb des Amacont-Projektes gute Erfahrungen vorhanden, da der LinkTransformer
auf diese Weise erstellt wurde. Die Wartung und Erweiterung des DOM-Transformators benötigt daher einen geringen Einarbeitungsaufwand.
Grundaufbau
Für den zu erstellenden AbstractDOMTransformer
sind grundsätzlich folgende zwei Funktionen von Bedeutung:
Um die Überschaubarkeit des Quellcodes zu gewährleisten und Performanz- und Lasttests zu unterstützen, wurde der Transformator in 3 Klassen aufgeteilt: den eigentlichen EvalLogicTransformer
als Hauptklasse, den EvalLogicParameter
als die Parameter enthaltende Klasse, und den EvalLogicResolver
, welcher in der Logik enthaltene Terme gegeneinander auflöst.
Vorgehen innerhalb des Transformers
Zunächst wird beim Start der Laufzeitumgebung die Transformatorenklasse EvalLogicTransformer
instantiiert und der entsprechende Konstruktor public EvalLogicTransformer()
aufgerufen. Cocoon hält diese Instanz bis zum Neustart des Servers.
Erreicht Cocoon nun innerhalb der Sitemap einen die Klasse betreffenden Transformator, so übergibt er mit Hilfe der setup
-Funktion neben Umgebungsvariablen die Parameter der Sitemap.
<map:transform type="evalLogic">
<map:parameter name="givParam" value="Format;Age;InnerSizeX"/>
<map:parameter name="debug" value="true"/>
<map:parameter name="Format" value="xHTML"/>
</map:transform>
Diese werden aus dem Parameter-Array ausgelesen und an die EvalLogicParameter
-Klasse weitergeleitet. Wie im obigen Beispiel ersichtlich ist, beinhaltet der Aufruf bereits einen fest kodierten Parameter. Dieser wird sofort an die Parameterklasse übergeben und ist resistent gegenüber etwaig folgenden Nutzermodell-Einträgen.
Hierbei besteht derzeit eine Fehlverarbeitung innerhalb des Cocoon- oder unterliegenden Avalon-Systems, da bei Nacheinanderausführung des Transformators mit unterschiedlichen Parametern diese hintereinander in den ersten Transformator übertragen werden und sich somit gegenseitig überschrieben. Bei Zwischenschaltung eines fremden Transformators trat dieses Problem nicht auf.
Folgend wird das zu bearbeitende Dokument als org.w3c.Document
-Klasse mit Hilfe der transform
-Funktion an die Klasseninstanz übergeben und durchläuft sequentiell die folgenden Schritte.
Für die Grammatik des Dokuments besitzt die Reihenfolge eine wichtige Bedeutung. Da bei der Dokumenterstellung oftmals Kommentare oder Leerzeichen eingefügt werden, entfernt cleanup(Node node, short nodeType, String name)
sämtliche derartige Knoten. Daraufhin wird das Nutzermodell vom Dokumentende ausgelesen und an die Parameterklasse übergeben, welche die XML-Daten mit den Parametern abgleicht und entsprechende Werte übernimmt.
Nun bildet der Transformator eine alle Logiken enthaltende Knotenliste und leitet diese je nach Typ (If
-, Switch
-, Trinary
-Logik) ab.
Hier wird am Beispiel eines If-Knotens ersichtlich, dass dieser den Logik-Teil <aada:Term> an die Klasse LogicResolver
weiterleitet, welche die Rekursivität der Logik auflöst. Kommen dabei Nutzerparameter der Art <aada:UserParam>
vor, wird versucht, diese mit Hilfe der Parameter-Klasse aufzulösen. Komplett aufgelöste Baumzweige werden durch <aada:Const>Wert</aada:Const>
ersetzt, so dass die sequentielle Ausführung mit verteilten Nutzerinformationen möglich ist.
Im letzten Schritt wird bei gesetztem "_end_
" - Parameter das Nutzermodell aus dem Dokument entfernt und somit die Weiterverarbeitung innerhalb der Cocoon-Pipeline sichergestellt.
svg - komplettes Sequenzdiagramm - Vergrössern
Einbindung
Die fertige Komponente wird, wie unter Kapitel 3.1 angesprochen, in zwei Abschnitten der Sitemap des Amacont-Projektes eingefügt. Innerhalb des Definitionsabschnittes gilt es, die Initialisierung vorzunehmen:
<map:components>
<map:transformer name="evalLogic" src="de.amacont.dom.transformation.EvalLogicTransformer"/></map:components>
Während der Pipeline-Abarbeitung folgt dann der verarbeitende Aufruf. Dieser kann mehrmals sequentiell mit unterschiedlichen Parametern erfolgen. Der folgende Codeabschnitt zeigt ein mögliches Beispiel.:
<map:pipeline>
<map:match pattern="testEval">
<map:generate src="web/videothek/testMe.xml"/>
<map:transform type="evalLogic">
<map:parameter name="givParam" value="Age"/>
<map:parameter name="debug" value="true"/>
</map:transform>
<map:transform type="evalLogic">
<map:parameter name="givParam" value="Format;_end_"/>
<map:parameter name="debug" value="true"/>
</map:transform>
</map:match pattern="testEval">
</map:pipeline>
Zu Erprobungszwecken können ebenfalls die dem Projekt beigelegten JUnit-Tests verwendet werden, welche gleichzeitig die Robustheit bei ausgewählten Extremsituationen nachweisen.
Die unter Kapitel 4.2 durchgeführte Testreihe hatte den auf XSL basierenden Adaptions-Transformator als den größten Flaschenhals der Amacont-Pipeline identifiziert. Seine Aufgabe besteht in der Anpassung der Datenquelle an nutzerspezifische Eigenschaften, wie Bildschirmauflösung, Bandbreite, Alter des Nutzers etc. (vergleiche Abb. 14). Er enthält zu diesem Zweck eine aufwendige und unter [Ama03] sowie [Ama04] ausführlich vorgestellte Logik.
Um die Belastungen dieser Logiken abzumindern, wird er aus der rekursiv arbeitenden XSLT-Form in die eines Java-Transformators überführt. Dadurch kommen die unter Kapitel 3.4.3.5 genannten Vorteile zum tragen und der in Kapitel 4.2 gezeigte und nachgewiesenen Performancegewinn stellt sich ein. Folgend soll nun der Aufbau und die Funktionsweise beleuchtet werden.
Auswahl der passenden Unterklasse
Bei der Auswahl der passenden Technik stellt sich die Wahl zwischen der Nutzung einer SAX-basierenden Darstellung oder der Verwendung eines Views auf das komplette “Document Object Model” (DOM). Während bei ersterem der Quellcode wie bei einem Walkthrough durchlaufen wird, bildet ein DOM das XML-Dokument als Baum komplett im Speicher ab.
Die Änderung der Adaptions-Eigenschaften ist eine komplexe Aufgabe. Zunächst werden die übergebenen Parameter aus dem an das eigentliche AmaKomponenten-Dokument angehangene NutzerModell ausgelesen und daraufhin das Dokument nach Vorkommen dieser Parameter in den vorhandenen Logiken durchsucht, vereinfacht bzw. aufgelöst, wobei Zwischenschritte für einen mehrmaligen Durchlauf gespeichert werden. Die jeweilige Varianten-Darstellung ersetzt die vorgegebene Logik und beendet somit den Adaptionsprozess.
Eine Umsetzung anhand eines Sax-Parsers ist möglich, wobei das Dokument für die folgenden Aufgaben durchlaufen werden mu
Eine weitere theoretische Möglichkeit ist die selbständige Erstellung großer XML-Bäume innerhalb des Sax-Transformators, was jedoch als nicht sinnvoll angesehen wird.
Daher fällt die Wahl auf die Nutzung eines DOM-Transformators. Zu dieser Technologie sind innerhalb des Amacont-Projektes gute Erfahrungen vorhanden, da der LinkTransformer
auf diese Weise erstellt wurde. Die Wartung und Erweiterung des DOM-Transformators benötigt daher einen geringen Einarbeitungsaufwand.
Grundaufbau
Für den zu erstellenden AbstractDOMTransformer
sind grundsätzlich folgende zwei Funktionen von Bedeutung:
Um die Überschaubarkeit des Quellcodes zu gewährleisten und Performanz- und Lasttests zu unterstützen, wurde der Transformator in 3 Klassen aufgeteilt: den eigentlichen EvalLogicTransformer
als Hauptklasse, den EvalLogicParameter
als die Parameter enthaltende Klasse, und den EvalLogicResolver
, welcher in der Logik enthaltene Terme gegeneinander auflöst.
Vorgehen innerhalb des Transformers
Zunächst wird beim Start der Laufzeitumgebung die Transformatorenklasse EvalLogicTransformer
instantiiert und der entsprechende Konstruktor public EvalLogicTransformer()
aufgerufen. Cocoon hält diese Instanz bis zum Neustart des Servers.
Erreicht Cocoon nun innerhalb der Sitemap einen die Klasse betreffenden Transformator, so übergibt er mit Hilfe der setup
-Funktion neben Umgebungsvariablen die Parameter der Sitemap.
<map:transform type="evalLogic">
<map:parameter name="givParam" value="Format;Age;InnerSizeX"/>
<map:parameter name="debug" value="true"/>
<map:parameter name="Format" value="xHTML"/>
</map:transform>
Diese werden aus dem Parameter-Array ausgelesen und an die EvalLogicParameter
-Klasse weitergeleitet. Wie im obigen Beispiel ersichtlich ist, beinhaltet der Aufruf bereits einen fest kodierten Parameter. Dieser wird sofort an die Parameterklasse übergeben und ist resistent gegenüber etwaig folgenden Nutzermodell-Einträgen.
Hierbei besteht derzeit eine Fehlverarbeitung innerhalb des Cocoon- oder unterliegenden Avalon-Systems, da bei Nacheinanderausführung des Transformators mit unterschiedlichen Parametern diese hintereinander in den ersten Transformator übertragen werden und sich somit gegenseitig überschrieben. Bei Zwischenschaltung eines fremden Transformators trat dieses Problem nicht auf.
Folgend wird das zu bearbeitende Dokument als org.w3c.Document
-Klasse mit Hilfe der transform
-Funktion an die Klasseninstanz übergeben und durchläuft sequentiell die folgenden Schritte.
Für die Grammatik des Dokuments besitzt die Reihenfolge eine wichtige Bedeutung. Da bei der Dokumenterstellung oftmals Kommentare oder Leerzeichen eingefügt werden, entfernt cleanup(Node node, short nodeType, String name)
sämtliche derartige Knoten. Daraufhin wird das Nutzermodell vom Dokumentende ausgelesen und an die Parameterklasse übergeben, welche die XML-Daten mit den Parametern abgleicht und entsprechende Werte übernimmt.
Nun bildet der Transformator eine alle Logiken enthaltende Knotenliste und leitet diese je nach Typ (If
-, Switch
-, Trinary
-Logik) ab.
Hier wird am Beispiel eines If-Knotens ersichtlich, dass dieser den Logik-Teil <aada:Term> an die Klasse LogicResolver
weiterleitet, welche die Rekursivität der Logik auflöst. Kommen dabei Nutzerparameter der Art <aada:UserParam>
vor, wird versucht, diese mit Hilfe der Parameter-Klasse aufzulösen. Komplett aufgelöste Baumzweige werden durch <aada:Const>Wert</aada:Const>
ersetzt, so dass die sequentielle Ausführung mit verteilten Nutzerinformationen möglich ist.
Im letzten Schritt wird bei gesetztem "_end_
" - Parameter das Nutzermodell aus dem Dokument entfernt und somit die Weiterverarbeitung innerhalb der Cocoon-Pipeline sichergestellt.
svg - komplettes Sequenzdiagramm - Vergrössern
Einbindung
Die fertige Komponente wird, wie unter Kapitel 3.1 angesprochen, in zwei Abschnitten der Sitemap des Amacont-Projektes eingefügt. Innerhalb des Definitionsabschnittes gilt es, die Initialisierung vorzunehmen:
<map:components>
<map:transformer name="evalLogic" src="de.amacont.dom.transformation.EvalLogicTransformer"/></map:components>
Während der Pipeline-Abarbeitung folgt dann der verarbeitende Aufruf. Dieser kann mehrmals sequentiell mit unterschiedlichen Parametern erfolgen. Der folgende Codeabschnitt zeigt ein mögliches Beispiel.:
<map:pipeline>
<map:match pattern="testEval">
<map:generate src="web/videothek/testMe.xml"/>
<map:transform type="evalLogic">
<map:parameter name="givParam" value="Age"/>
<map:parameter name="debug" value="true"/>
</map:transform>
<map:transform type="evalLogic">
<map:parameter name="givParam" value="Format;_end_"/>
<map:parameter name="debug" value="true"/>
</map:transform>
</map:match pattern="testEval">
</map:pipeline>
Zu Erprobungszwecken können ebenfalls die dem Projekt beigelegten JUnit-Tests verwendet werden, welche gleichzeitig die Robustheit bei ausgewählten Extremsituationen nachweisen.
Die unter Kapitel 4.2 durchgeführte Testreihe hatte den auf XSL basierenden Adaptions-Transformator als den größten Flaschenhals der Amacont-Pipeline identifiziert. Seine Aufgabe besteht in der Anpassung der Datenquelle an nutzerspezifische Eigenschaften, wie Bildschirmauflösung, Bandbreite, Alter des Nutzers etc. (vergleiche Abb. 14). Er enthält zu diesem Zweck eine aufwendige und unter [Ama03] sowie [Ama04] ausführlich vorgestellte Logik.
Um die Belastungen dieser Logiken abzumindern, wird er aus der rekursiv arbeitenden XSLT-Form in die eines Java-Transformators überführt. Dadurch kommen die unter Kapitel 3.4.3.5 genannten Vorteile zum tragen und der in Kapitel 4.2 gezeigte und nachgewiesenen Performancegewinn stellt sich ein. Folgend soll nun der Aufbau und die Funktionsweise beleuchtet werden.
Auswahl der passenden Unterklasse
Bei der Auswahl der passenden Technik stellt sich die Wahl zwischen der Nutzung einer SAX-basierenden Darstellung oder der Verwendung eines Views auf das komplette “Document Object Model” (DOM). Während bei ersterem der Quellcode wie bei einem Walkthrough durchlaufen wird, bildet ein DOM das XML-Dokument als Baum komplett im Speicher ab.
Die Änderung der Adaptions-Eigenschaften ist eine komplexe Aufgabe. Zunächst werden die übergebenen Parameter aus dem an das eigentliche AmaKomponenten-Dokument angehangene NutzerModell ausgelesen und daraufhin das Dokument nach Vorkommen dieser Parameter in den vorhandenen Logiken durchsucht, vereinfacht bzw. aufgelöst, wobei Zwischenschritte für einen mehrmaligen Durchlauf gespeichert werden. Die jeweilige Varianten-Darstellung ersetzt die vorgegebene Logik und beendet somit den Adaptionsprozess.
Eine Umsetzung anhand eines Sax-Parsers ist möglich, wobei das Dokument für die folgenden Aufgaben durchlaufen werden mu
Eine weitere theoretische Möglichkeit ist die selbständige Erstellung großer XML-Bäume innerhalb des Sax-Transformators, was jedoch als nicht sinnvoll angesehen wird.
Daher fällt die Wahl auf die Nutzung eines DOM-Transformators. Zu dieser Technologie sind innerhalb des Amacont-Projektes gute Erfahrungen vorhanden, da der LinkTransformer
auf diese Weise erstellt wurde. Die Wartung und Erweiterung des DOM-Transformators benötigt daher einen geringen Einarbeitungsaufwand.
Grundaufbau
Für den zu erstellenden AbstractDOMTransformer
sind grundsätzlich folgende zwei Funktionen von Bedeutung:
Um die Überschaubarkeit des Quellcodes zu gewährleisten und Performanz- und Lasttests zu unterstützen, wurde der Transformator in 3 Klassen aufgeteilt: den eigentlichen EvalLogicTransformer
als Hauptklasse, den EvalLogicParameter
als die Parameter enthaltende Klasse, und den EvalLogicResolver
, welcher in der Logik enthaltene Terme gegeneinander auflöst.
Vorgehen innerhalb des Transformers
Zunächst wird beim Start der Laufzeitumgebung die Transformatorenklasse EvalLogicTransformer
instantiiert und der entsprechende Konstruktor public EvalLogicTransformer()
aufgerufen. Cocoon hält diese Instanz bis zum Neustart des Servers.
Erreicht Cocoon nun innerhalb der Sitemap einen die Klasse betreffenden Transformator, so übergibt er mit Hilfe der setup
-Funktion neben Umgebungsvariablen die Parameter der Sitemap.
<map:transform type="evalLogic">
<map:parameter name="givParam" value="Format;Age;InnerSizeX"/>
<map:parameter name="debug" value="true"/>
<map:parameter name="Format" value="xHTML"/>
</map:transform>
Diese werden aus dem Parameter-Array ausgelesen und an die EvalLogicParameter
-Klasse weitergeleitet. Wie im obigen Beispiel ersichtlich ist, beinhaltet der Aufruf bereits einen fest kodierten Parameter. Dieser wird sofort an die Parameterklasse übergeben und ist resistent gegenüber etwaig folgenden Nutzermodell-Einträgen.
Hierbei besteht derzeit eine Fehlverarbeitung innerhalb des Cocoon- oder unterliegenden Avalon-Systems, da bei Nacheinanderausführung des Transformators mit unterschiedlichen Parametern diese hintereinander in den ersten Transformator übertragen werden und sich somit gegenseitig überschrieben. Bei Zwischenschaltung eines fremden Transformators trat dieses Problem nicht auf.
Folgend wird das zu bearbeitende Dokument als org.w3c.Document
-Klasse mit Hilfe der transform
-Funktion an die Klasseninstanz übergeben und durchläuft sequentiell die folgenden Schritte.
Für die Grammatik des Dokuments besitzt die Reihenfolge eine wichtige Bedeutung. Da bei der Dokumenterstellung oftmals Kommentare oder Leerzeichen eingefügt werden, entfernt cleanup(Node node, short nodeType, String name)
sämtliche derartige Knoten. Daraufhin wird das Nutzermodell vom Dokumentende ausgelesen und an die Parameterklasse übergeben, welche die XML-Daten mit den Parametern abgleicht und entsprechende Werte übernimmt.
Nun bildet der Transformator eine alle Logiken enthaltende Knotenliste und leitet diese je nach Typ (If
-, Switch
-, Trinary
-Logik) ab.
Hier wird am Beispiel eines If-Knotens ersichtlich, dass dieser den Logik-Teil <aada:Term> an die Klasse LogicResolver
weiterleitet, welche die Rekursivität der Logik auflöst. Kommen dabei Nutzerparameter der Art <aada:UserParam>
vor, wird versucht, diese mit Hilfe der Parameter-Klasse aufzulösen. Komplett aufgelöste Baumzweige werden durch <aada:Const>Wert</aada:Const>
ersetzt, so dass die sequentielle Ausführung mit verteilten Nutzerinformationen möglich ist.
Im letzten Schritt wird bei gesetztem "_end_
" - Parameter das Nutzermodell aus dem Dokument entfernt und somit die Weiterverarbeitung innerhalb der Cocoon-Pipeline sichergestellt.
svg - komplettes Sequenzdiagramm - Vergrössern
Einbindung
Die fertige Komponente wird, wie unter Kapitel 3.1 angesprochen, in zwei Abschnitten der Sitemap des Amacont-Projektes eingefügt. Innerhalb des Definitionsabschnittes gilt es, die Initialisierung vorzunehmen:
<map:components>
<map:transformer name="evalLogic" src="de.amacont.dom.transformation.EvalLogicTransformer"/></map:components>
Während der Pipeline-Abarbeitung folgt dann der verarbeitende Aufruf. Dieser kann mehrmals sequentiell mit unterschiedlichen Parametern erfolgen. Der folgende Codeabschnitt zeigt ein mögliches Beispiel.:
<map:pipeline>
<map:match pattern="testEval">
<map:generate src="web/videothek/testMe.xml"/>
<map:transform type="evalLogic">
<map:parameter name="givParam" value="Age"/>
<map:parameter name="debug" value="true"/>
</map:transform>
<map:transform type="evalLogic">
<map:parameter name="givParam" value="Format;_end_"/>
<map:parameter name="debug" value="true"/>
</map:transform>
</map:match pattern="testEval">
</map:pipeline>
Zu Erprobungszwecken können ebenfalls die dem Projekt beigelegten JUnit-Tests verwendet werden, welche gleichzeitig die Robustheit bei ausgewählten Extremsituationen nachweisen.
Die unter Kapitel 4.2 durchgeführte Testreihe hatte den auf XSL basierenden Adaptions-Transformator als den größten Flaschenhals der Amacont-Pipeline identifiziert. Seine Aufgabe besteht in der Anpassung der Datenquelle an nutzerspezifische Eigenschaften, wie Bildschirmauflösung, Bandbreite, Alter des Nutzers etc. (vergleiche Abb. 14). Er enthält zu diesem Zweck eine aufwendige und unter [Ama03] sowie [Ama04] ausführlich vorgestellte Logik.
Um die Belastungen dieser Logiken abzumindern, wird er aus der rekursiv arbeitenden XSLT-Form in die eines Java-Transformators überführt. Dadurch kommen die unter Kapitel 3.4.3.5 genannten Vorteile zum tragen und der in Kapitel 4.2 gezeigte und nachgewiesenen Performancegewinn stellt sich ein. Folgend soll nun der Aufbau und die Funktionsweise beleuchtet werden.
Auswahl der passenden Unterklasse
Bei der Auswahl der passenden Technik stellt sich die Wahl zwischen der Nutzung einer SAX-basierenden Darstellung oder der Verwendung eines Views auf das komplette “Document Object Model” (DOM). Während bei ersterem der Quellcode wie bei einem Walkthrough durchlaufen wird, bildet ein DOM das XML-Dokument als Baum komplett im Speicher ab.
Die Änderung der Adaptions-Eigenschaften ist eine komplexe Aufgabe. Zunächst werden die übergebenen Parameter aus dem an das eigentliche AmaKomponenten-Dokument angehangene NutzerModell ausgelesen und daraufhin das Dokument nach Vorkommen dieser Parameter in den vorhandenen Logiken durchsucht, vereinfacht bzw. aufgelöst, wobei Zwischenschritte für einen mehrmaligen Durchlauf gespeichert werden. Die jeweilige Varianten-Darstellung ersetzt die vorgegebene Logik und beendet somit den Adaptionsprozess.
Eine Umsetzung anhand eines Sax-Parsers ist möglich, wobei das Dokument für die folgenden Aufgaben durchlaufen werden mu
Eine weitere theoretische Möglichkeit ist die selbständige Erstellung großer XML-Bäume innerhalb des Sax-Transformators, was jedoch als nicht sinnvoll angesehen wird.
Daher fällt die Wahl auf die Nutzung eines DOM-Transformators. Zu dieser Technologie sind innerhalb des Amacont-Projektes gute Erfahrungen vorhanden, da der LinkTransformer
auf diese Weise erstellt wurde. Die Wartung und Erweiterung des DOM-Transformators benötigt daher einen geringen Einarbeitungsaufwand.
Grundaufbau
Für den zu erstellenden AbstractDOMTransformer
sind grundsätzlich folgende zwei Funktionen von Bedeutung:
Um die Überschaubarkeit des Quellcodes zu gewährleisten und Performanz- und Lasttests zu unterstützen, wurde der Transformator in 3 Klassen aufgeteilt: den eigentlichen EvalLogicTransformer
als Hauptklasse, den EvalLogicParameter
als die Parameter enthaltende Klasse, und den EvalLogicResolver
, welcher in der Logik enthaltene Terme gegeneinander auflöst.
Vorgehen innerhalb des Transformers
Zunächst wird beim Start der Laufzeitumgebung die Transformatorenklasse EvalLogicTransformer
instantiiert und der entsprechende Konstruktor public EvalLogicTransformer()
aufgerufen. Cocoon hält diese Instanz bis zum Neustart des Servers.
Erreicht Cocoon nun innerhalb der Sitemap einen die Klasse betreffenden Transformator, so übergibt er mit Hilfe der setup
-Funktion neben Umgebungsvariablen die Parameter der Sitemap.
<map:transform type="evalLogic">
<map:parameter name="givParam" value="Format;Age;InnerSizeX"/>
<map:parameter name="debug" value="true"/>
<map:parameter name="Format" value="xHTML"/>
</map:transform>
Diese werden aus dem Parameter-Array ausgelesen und an die EvalLogicParameter
-Klasse weitergeleitet. Wie im obigen Beispiel ersichtlich ist, beinhaltet der Aufruf bereits einen fest kodierten Parameter. Dieser wird sofort an die Parameterklasse übergeben und ist resistent gegenüber etwaig folgenden Nutzermodell-Einträgen.
Hierbei besteht derzeit eine Fehlverarbeitung innerhalb des Cocoon- oder unterliegenden Avalon-Systems, da bei Nacheinanderausführung des Transformators mit unterschiedlichen Parametern diese hintereinander in den ersten Transformator übertragen werden und sich somit gegenseitig überschrieben. Bei Zwischenschaltung eines fremden Transformators trat dieses Problem nicht auf.
Folgend wird das zu bearbeitende Dokument als org.w3c.Document
-Klasse mit Hilfe der transform
-Funktion an die Klasseninstanz übergeben und durchläuft sequentiell die folgenden Schritte.
Für die Grammatik des Dokuments besitzt die Reihenfolge eine wichtige Bedeutung. Da bei der Dokumenterstellung oftmals Kommentare oder Leerzeichen eingefügt werden, entfernt cleanup(Node node, short nodeType, String name)
sämtliche derartige Knoten. Daraufhin wird das Nutzermodell vom Dokumentende ausgelesen und an die Parameterklasse übergeben, welche die XML-Daten mit den Parametern abgleicht und entsprechende Werte übernimmt.
Nun bildet der Transformator eine alle Logiken enthaltende Knotenliste und leitet diese je nach Typ (If
-, Switch
-, Trinary
-Logik) ab.
Hier wird am Beispiel eines If-Knotens ersichtlich, dass dieser den Logik-Teil <aada:Term> an die Klasse LogicResolver
weiterleitet, welche die Rekursivität der Logik auflöst. Kommen dabei Nutzerparameter der Art <aada:UserParam>
vor, wird versucht, diese mit Hilfe der Parameter-Klasse aufzulösen. Komplett aufgelöste Baumzweige werden durch <aada:Const>Wert</aada:Const>
ersetzt, so dass die sequentielle Ausführung mit verteilten Nutzerinformationen möglich ist.
Im letzten Schritt wird bei gesetztem "_end_
" - Parameter das Nutzermodell aus dem Dokument entfernt und somit die Weiterverarbeitung innerhalb der Cocoon-Pipeline sichergestellt.
svg - komplettes Sequenzdiagramm - Vergrössern
Einbindung
Die fertige Komponente wird, wie unter Kapitel 3.1 angesprochen, in zwei Abschnitten der Sitemap des Amacont-Projektes eingefügt. Innerhalb des Definitionsabschnittes gilt es, die Initialisierung vorzunehmen:
<map:components>
<map:transformer name="evalLogic" src="de.amacont.dom.transformation.EvalLogicTransformer"/></map:components>
Während der Pipeline-Abarbeitung folgt dann der verarbeitende Aufruf. Dieser kann mehrmals sequentiell mit unterschiedlichen Parametern erfolgen. Der folgende Codeabschnitt zeigt ein mögliches Beispiel.:
<map:pipeline>
<map:match pattern="testEval">
<map:generate src="web/videothek/testMe.xml"/>
<map:transform type="evalLogic">
<map:parameter name="givParam" value="Age"/>
<map:parameter name="debug" value="true"/>
</map:transform>
<map:transform type="evalLogic">
<map:parameter name="givParam" value="Format;_end_"/>
<map:parameter name="debug" value="true"/>
</map:transform>
</map:match pattern="testEval">
</map:pipeline>
Zu Erprobungszwecken können ebenfalls die dem Projekt beigelegten JUnit-Tests verwendet werden, welche gleichzeitig die Robustheit bei ausgewählten Extremsituationen nachweisen.
Die unter Kapitel 4.2 durchgeführte Testreihe hatte den auf XSL basierenden Adaptions-Transformator als den größten Flaschenhals der Amacont-Pipeline identifiziert. Seine Aufgabe besteht in der Anpassung der Datenquelle an nutzerspezifische Eigenschaften, wie Bildschirmauflösung, Bandbreite, Alter des Nutzers etc. (vergleiche Abb. 14). Er enthält zu diesem Zweck eine aufwendige und unter [Ama03] sowie [Ama04] ausführlich vorgestellte Logik.
Um die Belastungen dieser Logiken abzumindern, wird er aus der rekursiv arbeitenden XSLT-Form in die eines Java-Transformators überführt. Dadurch kommen die unter Kapitel 3.4.3.5 genannten Vorteile zum tragen und der in Kapitel 4.2 gezeigte und nachgewiesenen Performancegewinn stellt sich ein. Folgend soll nun der Aufbau und die Funktionsweise beleuchtet werden.
Auswahl der passenden Unterklasse
Bei der Auswahl der passenden Technik stellt sich die Wahl zwischen der Nutzung einer SAX-basierenden Darstellung oder der Verwendung eines Views auf das komplette “Document Object Model” (DOM). Während bei ersterem der Quellcode wie bei einem Walkthrough durchlaufen wird, bildet ein DOM das XML-Dokument als Baum komplett im Speicher ab.
Die Änderung der Adaptions-Eigenschaften ist eine komplexe Aufgabe. Zunächst werden die übergebenen Parameter aus dem an das eigentliche AmaKomponenten-Dokument angehangene NutzerModell ausgelesen und daraufhin das Dokument nach Vorkommen dieser Parameter in den vorhandenen Logiken durchsucht, vereinfacht bzw. aufgelöst, wobei Zwischenschritte für einen mehrmaligen Durchlauf gespeichert werden. Die jeweilige Varianten-Darstellung ersetzt die vorgegebene Logik und beendet somit den Adaptionsprozess.
Eine Umsetzung anhand eines Sax-Parsers ist möglich, wobei das Dokument für die folgenden Aufgaben durchlaufen werden mu
- Auslesung des Benutzermodells,
- Finden der ersten Logik,
- Eintreten in die einzelnen Logikknoten der Verzweigung
- Finden und Herauslösen der gefundenen Variante,
- nach erfolgter Umwandlung erneutes Auslesen des Gesamtbaumes
Eine weitere theoretische Möglichkeit ist die selbständige Erstellung großer XML-Bäume innerhalb des Sax-Transformators, was jedoch als nicht sinnvoll angesehen wird.
Daher fällt die Wahl auf die Nutzung eines DOM-Transformators. Zu dieser Technologie sind innerhalb des Amacont-Projektes gute Erfahrungen vorhanden, da der LinkTransformer
auf diese Weise erstellt wurde. Die Wartung und Erweiterung des DOM-Transformators benötigt daher einen geringen Einarbeitungsaufwand.
Grundaufbau
Für den zu erstellenden AbstractDOMTransformer
sind grundsätzlich folgende zwei Funktionen von Bedeutung:
- function setup
Diese erhält die übergebenen Parameter aus der sitemap.xmap und bereitet diese für eine spätere Transformation auf
- function transformer
Hierüber wird das zu bearbeitende Dokument als org.w3c.Document übergeben, als Rückgabewert wird wiederum das geparste Dokument erwartet.
Um die Überschaubarkeit des Quellcodes zu gewährleisten und Performanz- und Lasttests zu unterstützen, wurde der Transformator in 3 Klassen aufgeteilt: den eigentlichen EvalLogicTransformer
als Hauptklasse, den EvalLogicParameter
als die Parameter enthaltende Klasse, und den EvalLogicResolver
, welcher in der Logik enthaltene Terme gegeneinander auflöst.
Vorgehen innerhalb des Transformers
Zunächst wird beim Start der Laufzeitumgebung die Transformatorenklasse EvalLogicTransformer
instantiiert und der entsprechende Konstruktor public EvalLogicTransformer()
aufgerufen. Cocoon hält diese Instanz bis zum Neustart des Servers.
Erreicht Cocoon nun innerhalb der Sitemap einen die Klasse betreffenden Transformator, so übergibt er mit Hilfe der setup
-Funktion neben Umgebungsvariablen die Parameter der Sitemap.
<map:transform type="evalLogic">
<map:parameter name="givParam" value="Format;Age;InnerSizeX"/>
<map:parameter name="debug" value="true"/>
<map:parameter name="Format" value="xHTML"/>
</map:transform>
Diese werden aus dem Parameter-Array ausgelesen und an die EvalLogicParameter
-Klasse weitergeleitet. Wie im obigen Beispiel ersichtlich ist, beinhaltet der Aufruf bereits einen fest kodierten Parameter. Dieser wird sofort an die Parameterklasse übergeben und ist resistent gegenüber etwaig folgenden Nutzermodell-Einträgen.
Hierbei besteht derzeit eine Fehlverarbeitung innerhalb des Cocoon- oder unterliegenden Avalon-Systems, da bei Nacheinanderausführung des Transformators mit unterschiedlichen Parametern diese hintereinander in den ersten Transformator übertragen werden und sich somit gegenseitig überschrieben. Bei Zwischenschaltung eines fremden Transformators trat dieses Problem nicht auf.
Folgend wird das zu bearbeitende Dokument als org.w3c.Document
-Klasse mit Hilfe der transform
-Funktion an die Klasseninstanz übergeben und durchläuft sequentiell die folgenden Schritte.
Für die Grammatik des Dokuments besitzt die Reihenfolge eine wichtige Bedeutung. Da bei der Dokumenterstellung oftmals Kommentare oder Leerzeichen eingefügt werden, entfernt cleanup(Node node, short nodeType, String name)
sämtliche derartige Knoten. Daraufhin wird das Nutzermodell vom Dokumentende ausgelesen und an die Parameterklasse übergeben, welche die XML-Daten mit den Parametern abgleicht und entsprechende Werte übernimmt.
Nun bildet der Transformator eine alle Logiken enthaltende Knotenliste und leitet diese je nach Typ (If
-, Switch
-, Trinary
-Logik) ab.
Hier wird am Beispiel eines If-Knotens ersichtlich, dass dieser den Logik-Teil <aada:Term> an die Klasse LogicResolver
weiterleitet, welche die Rekursivität der Logik auflöst. Kommen dabei Nutzerparameter der Art <aada:UserParam>
vor, wird versucht, diese mit Hilfe der Parameter-Klasse aufzulösen. Komplett aufgelöste Baumzweige werden durch <aada:Const>Wert</aada:Const>
ersetzt, so dass die sequentielle Ausführung mit verteilten Nutzerinformationen möglich ist.
Im letzten Schritt wird bei gesetztem "_end_
" - Parameter das Nutzermodell aus dem Dokument entfernt und somit die Weiterverarbeitung innerhalb der Cocoon-Pipeline sichergestellt.
svg - komplettes Sequenzdiagramm - Vergrössern
Einbindung
Die fertige Komponente wird, wie unter Kapitel 3.1 angesprochen, in zwei Abschnitten der Sitemap des Amacont-Projektes eingefügt. Innerhalb des Definitionsabschnittes gilt es, die Initialisierung vorzunehmen:
<map:components>
<map:transformer name="evalLogic" src="de.amacont.dom.transformation.EvalLogicTransformer"/></map:components>
Während der Pipeline-Abarbeitung folgt dann der verarbeitende Aufruf. Dieser kann mehrmals sequentiell mit unterschiedlichen Parametern erfolgen. Der folgende Codeabschnitt zeigt ein mögliches Beispiel.:
<map:pipeline>
<map:match pattern="testEval">
<map:generate src="web/videothek/testMe.xml"/>
<map:transform type="evalLogic">
<map:parameter name="givParam" value="Age"/>
<map:parameter name="debug" value="true"/>
</map:transform>
<map:transform type="evalLogic">
<map:parameter name="givParam" value="Format;_end_"/>
<map:parameter name="debug" value="true"/>
</map:transform>
</map:match pattern="testEval">
</map:pipeline>
Zu Erprobungszwecken können ebenfalls die dem Projekt beigelegten JUnit-Tests verwendet werden, welche gleichzeitig die Robustheit bei ausgewählten Extremsituationen nachweisen.