Berechnung des AWS-State – Grundlegende Konzepte

Werbung
Universität Paderborn
Fakultät für Elektrotechnik, Informatik und Mathematik
Diplomarbeit
Attributberechnung in abstrakten Website-Strukturen
vorgelegt bei:
Prof. Dr. Gerd Szwillus
Dr. Michael Tauber
vorgelegt von:
Jan Stulgies
Paderborn, Juni 2005
Eidesstattliche Erklärung
Hiermit erkläre ich, dass ich die vorliegende Diplomarbeit ohne Hilfe Dritter und ohne Benutzung anderer als den angegebenen Quellen und Hilfsmitteln angefertigt habe. Alle Stellen,
die wörtlich der inhaltlich aus veröffentlichten Schriften entnommen sind, habe ich als solche
kenntlich gemacht. Diese Arbeit hat in gleicher oder ähnlicher Form noch keiner Prüfungsbehörde vorgelegen.
Paderborn, Juni 2005 (Jan Stulgies)
Abstract
i
Abstract
Das Internet gewinnt in der heutigen Zeit immer mehr an Bedeutung. Eine Internetpräsenz
kann daher, gerade für kleine Unternehmen, ein entschiedener Wettbewerbsvorteil sein.
Kleine Unternehmen müssen sich jedoch besonders auf ihr eigentliches Geschäft konzentieren, haben wenig bis gar keine Kompetenz bei der Erstellungen von Web-Anwendungen, oder können sich die kontinuierliche Beauftragung externer Dienstleister nicht leisten.
Um dennoch die Vorteile einer Internetpräsenz nutzen zu können, bietet sich für solche Unternehmen ein modellbasierter Ansatz zur Web-Anwendungsentwicklung an. Ein solcher Ansatz
wurde von Szwillus/Bomsdorf unter der Bezeichnung Website Management System (WSMS)
vorgestellt.
Diese Arbeit beschäftigt sich mit der Entwicklung von Konzepten und Vorgehensweisen zur
Berechnung einer Attributierung einer AWS, dem so genannten AWS-State. Die entwickelten
Konzepte wurden anschließend in einer prototypischen Implementierung umgesetzt.
Inhaltsverzeichnis
ii
Inhaltsverzeichnis
1
Einleitung ...........................................................................................................................1
2
Attributgrammatiken ..........................................................................................................3
3
2.1
Kontextfreie Grammatiken .........................................................................................3
2.2
Attributierung von Grammatiken ...............................................................................4
2.3
Attributauswertung und WOLM ................................................................................7
WOLM/WSMS...................................................................................................................8
3.1
Wolm-WSMS .............................................................................................................8
3.2
Komponenten .............................................................................................................8
4
WOLM-State ....................................................................................................................10
5
AWS .................................................................................................................................11
6
5.1
Überblick ..................................................................................................................11
5.2
Zugriffsregeln ...........................................................................................................12
5.3
Knotentypen .............................................................................................................13
AWS-State ........................................................................................................................19
6.1
Überblick ..................................................................................................................19
6.2
Knotentypen .............................................................................................................20
6.2.1
Project...............................................................................................................20
6.2.2
Page ..................................................................................................................20
6.2.3
Field..................................................................................................................21
6.2.4
Text...................................................................................................................22
6.2.5
Textinput, Hiddentextinput...............................................................................22
6.2.6
Link...................................................................................................................23
6.2.7
Image ................................................................................................................23
6.2.8
Button, Action ..................................................................................................24
6.3
7
Beispiele ...................................................................................................................26
Berechnung des AWS-State .............................................................................................32
7.1
Überblick Berechnungskonzepte..............................................................................32
7.1.1
Berechnungskonzepte als Blackbox .................................................................32
7.1.2
AWS ohne Bezüge ...........................................................................................33
7.1.3
AWS mit AWS-Bezügen..................................................................................34
7.1.4
AWS mit WOLM-Bezügen ..............................................................................39
7.1.5
AWS mit Listenknoten .....................................................................................41
Inhaltsverzeichnis
7.2
Berechnung AWS-State im Detail............................................................................45
7.2.1
Fehlende Informationen bei der AWS-State Berechnung ................................45
7.2.2
Zustandsabhängige Modifikation der AWS .....................................................48
7.2.3
Aufbau Awslink, Wolmpath, Wolmclass .........................................................48
7.2.4
Bezüge ..............................................................................................................50
7.2.5
Abhängigkeiten.................................................................................................52
7.2.6
Entfernen von Knoten, abhängigen Knoten .....................................................55
7.2.7
Rekursion..........................................................................................................55
7.2.8
BerechneAwslink..............................................................................................56
7.2.9
BerechneWolmpath ..........................................................................................58
7.2.10
BerechneBezug.................................................................................................59
7.2.11
BerechneObjectselection ..................................................................................65
7.3
8
iii
Berechnung Knotentypen .........................................................................................69
Prototyp ............................................................................................................................77
Allgemein .................................................................................................................77
8.2
Beispiel 1 ..................................................................................................................78
8.3
Beispiel 2 ..................................................................................................................81
9
8.1
Zusammenfassung ............................................................................................................83
10
Literaturverzeichnis ......................................................................................................84
A
Änderung AWS-DTD.......................................................................................................86
A.1
Action-Knoten ......................................................................................................86
A.2
Listofobjectlists-Knoten .......................................................................................87
A.3
Image-Knoten .......................................................................................................87
B
WOLM-Definiton.............................................................................................................88
C
AWS-State-DTD ..............................................................................................................89
D
CD-ROM ..........................................................................................................................91
Tabellenverzeichnis
iv
Tabellenverzeichnis
Tabelle 1: AWS-State Knotentypen .........................................................................................19
Einleitung
1
1 Einleitung
Es ist unbestritten, dass das Internet aus unserem heutigen Alltag nicht mehr wegzudenken ist.
Dies betrifft sowohl den privaten als auch den geschäftlichen Bereich. War es zu Zeiten des
Internetbooms, zu Beginn dieses Jahrtausends, einfach nur „Hip“ als Privatperson eine eigene
Homepage zu besitzen, so gibt es heute durchaus sinnvolle Anwendungen für private InternetNutzer. Diese reichen von der privaten Fotosammlung des letzten Familienurlaubs, über
Bewerbungsseiten für eine neue Anstellung, bis hin zu den sich momentan stark verbreitenden
Blogs. Allen diesen Anwendungen ist gemein, dass sie sich, entweder mit standardisierten
Tools oder einfachen HTML-Editoren, vergleichsweise einfach erstellen und betreiben lassen.
Auf der anderen Seite wird es für Unternehmen jeder Größe immer wichtiger im Internet vertreten zu sein. Heutzutage sind die meisten der mittleren und großen Unternehmen in Internet
präsent. Diese Unternehmen leisten sich zumeist eigene IT-Abteilungen oder zumindest ein
festes Budget für die Beauftragung externer Dienstleister. Kleine Unternehmen, wie Bäcker,
Handwerker oder Friseure können sich einen solchen Aufwand, verständlicher Weise, nicht
leisten. Dennoch könnten sich gerade diese kleinen Unternehmen, durch geeignete Internetangebote, von der Konkurrenz absetzen. Unternehmen, die dies erkannt haben, verfolgen
meistens folgenden Ansatz. Sie beauftragen eine Firma mit der Erstellung einer Internetseite.
Das Ergebnis sind zumeist statische Webseiten mit einem Minimum an Nutzen für potenzielle
Kunden. Interessant wird ein Internetangebot für kleine Unternehmen bzw. deren Kunden,
erst durch ständige Aktualisierung und Pflege der enthaltenen Inhalte. Mit dem zuvor gewählten Ansatz würde dies eine ständige Kommunikation zwischen beiden Unternehmen erfordern. Dies ist aufwändig und kostspielig, aber notwendig, da ein kleines Unternehmens in
den meisten Fällen nicht über die Kompetenz verfügt, Änderungen an Webseiten selbst vorzunehmen. An dieser Stelle setzt das von Szwillus/Bomsdorf vorgestellte Website Management
System (WSMS) an. Es ermöglicht die selbständige Änderung und Aktualisierung einer
einmalig professionell erstellten Website mit geringem Aufwand und geringsten EDV-Kenntnissen.
In den folgenden Kapiteln werden die einzelnen Komponenten des WSMS kurz vorgestellt.
Es folgt eine Einführung in die wichtigsten Konzepte der AWS. Anschließend folgt der
Hauptteil dieser Arbeit mit der Konkretisierung der AWS-State-Definition, sowie der
Entwicklung von Konzepten und Vorgehensweisen zur Berechnung eines AWS-State aus
Einleitung
2
einem gegebenen WOLM-State und zugehöriger AWS. Der letzte Teil beschäftigt sich mit
der Vorstellung einer prototypischen Implementierung der vorgestellten Berechnungskonzepte, die im Rahmen dieser Arbeit entwickelt wurde.
Attributgrammatiken
3
2 Attributgrammatiken
Attributgrammatiken stellen eine Möglichkeit der formalen Definition von Sprachen dar. Sie
basieren auf kontextfreien Grammatiken, die um einen Attributierungsteil erweitert sind. Eine
starke Verbreitung erfahren Attributgrammatiken im Bereich Compiler- und Übersetzerbau.
Im Folgenden wird in das Konzept der kontextfreien Grammatiken eingeführt bevor eine
Betrachtung von Attributgrammatiken anhand von zwei Beispielen erfolgt. Abschließend
findet eine Beurteilung über den Einsatz von Attributgrammatiken im WOLM, bzw. bei der
Berechnung einer Attributierung einer AWS, statt.
2.1 Kontextfreie Grammatiken
Eine kontextfreie Grammatik besteht aus einer Menge von Terminalsymbolen (Terminale) T,
einer Menge von Nichtterminalsymbolen (Nichtterminale) N, einer Menge von Produktionen
P und einem Startsymbol S. In einer Art Ersetzungssystem lassen sich mit einer kontextfreien
Grammatik unterschiedlichste Strukturen beschreiben. Dies können beispielsweise Programme von Programmiersprachen oder auch Datenaustauschformate wie XML sein. Anhand
eines einfachen Beispiels erfolgt die Beschreibung einer einfachen Struktur zur Speicherung
von Wahlergebnissen in XML. Dokumente sollen folgenden Aufbau aufweisen.
<wahl>
<stimme>cdu</stimme>
<stimme>spd</stimme>
<stimme>cdu</stimme>
</wahl>
Die vier Bestandteile einer kontextfreien Grammatik, für die oben angegebene Struktur, könnten wie folgt aussehen.
Terminale
T = {'<wahl>', '</wahl>', '<stimme>',
'</stimme>', 'spd', 'cdu'}
Nichtterminale N = {ergebnis, stimmen, stimme, partei}
Startsymbol
S = ergebnis
Produktionen
ergebnis
stimmen
stimme
partei
partei
::=
::=
::=
::=
::=
'<wahl>'stimmen'</wahl>'
stimme *
'<stimme>'partei'</item>'
'cdu'
'spd'
Der Inhalt eines XML-Dokuments dieser kontextfreien Grammatik wird durch die sechs
Terminale bestimmt. Die Struktur wird durch die Produktionen vorgegeben. Eine einzelne
Attributgrammatiken
4
Produktion legt für ein bestimmtes Nichtterminal die möglichen Ersetzungen durch Terminale
und oder Nichtterminale fest. Der linke Teil der Produktion gibt das Terminal an, der rechte
Teil seine erlaubte Ersetzung. Mehrere Produktionen für ein Nichtterminal sind möglich
(siehe: „partei“). Der Ausdruck „stimme *“ gibt an, dass das Nichtterminal „stimmen“ durch
ein oder mehrere „stimme“-Terminale ersetzt werden darf. Das Startsymbol gibt das Nichtterminal an, mit dem die Ersetzung begonnen werden muss. Ohne weitere Ersetzung würde
das Startsymbol folgenden Ableitungsbaum sowie das zugehörige XML-Dokument erzeugen.
XML-Dokument:
ergebnis
<wahl></wahl>
„<wahl>“
stimmen
„</wahl>“
Wird das Nichtterminal „stimmen“ gemäß der obigen Produktionen durch weitere Nichtterminale und Terminale ersetzt, so erhält man einen komplexeren Ableitungsbaum, der ein
Dokument der oben vorgestellten Struktur beschreibt.
ergebnis
„<wahl>“
stimmen
„</wahl>“
„<stimme>“ partei
stimme
…
stimme
stimme
„</stimme>“
„cdu“
„<stimme>“ partei
„</stimme>“
„spd“
2.2 Attributierung von Grammatiken
Mit Hilfe kontextfreier Grammatiken lassen sich sehr komplexe Strukturen beschreiben. Ein
Informationstransport zwischen einzelnen Knoten eines Ableitungsbaums ist jedoch nicht
möglich. Attributgrammatiken erlauben genau dies. Informationen können von einem Knoten
des Ableitungsbaums zu einem anderen Knoten transportiert und mit den dort vorliegenden
Informationen verknüpft werden. Bevor darauf eingegangen wird, wie eine kontextfreie
Attributgrammatiken
5
Grammatik um eine solche Attributierung erweitert wird, sei ein weiteres Beispiel eines
Ableitungsbaums mit einer kontextfreien Grammatik gegeben.
S
3
A
B
len
a
A
3
len
2
b
B
len
a
2
len
1
A
b
B
len
a
1
len
b
Terminale
T = {a, b}
Nichtterminale N = {S, A, B}
Startsymbol
S = S
Produktionen
(1)
(2)
(3)
(4)
(5)
S
A
A
B
B
::=
::=
::=
::=
::=
AB
aA
a
bB
b
Wie bereits im Beispiel zu kontextfreien Grammatiken gesehen, kann mittels der gegebenen
Produktionen, Terminalen, Nichtterminalen und dem Startsymbol eine Struktur aufgebaut
werden. Bei der Struktur soll es sich um Folgen der Buchstaben a und b handeln. Dabei soll
sichergestellt sein, dass zunächst eine beliebige Anzahl an Buchstaben a erzeugt wird, der
dann dieselbe Anzahl an Buchstaben b folgt. Beispiele wären „aaabbb“ oder „aabb“. Eine
kontextfreie Grammatik kann diese Bedingung nicht sicherstellen. Sie muss zuvor um eine
Attributierung ergänzt werden. Hierzu wird zunächst den beiden Nichtterminalen A und B
jeweils ein Attribut mit der Bezeichnung len zugeordnet. Der Wert des Attributs len eines
Knoten A soll stets die Anzahl der unter diesem Knoten angehängten Knoten mit der Beschriftung a enthalten. Gleiches gilt für Knoten mit der Beschriftung B. Einhalten lässt sich
Attributgrammatiken
6
diese Forderung durch die Definition einer semantischen Regel für die zweite und vierte der
oben aufgeführten Produktionen. Aufgrund des doppelten Vorkommens der Nichtterminale A
und B innerhalb der beiden Produktionen, werden die Nichtterminale von links nach rechts
durchnummeriert.
Produktion (2)
A1
B1
A ::= aA
len
len
Produktion (4)
a
A2
len
B ::= bB
b
B2
len
Die semantischen Regeln für die zweite und vierte Produktion lauten wie folgt.
A1.len = A2.len + 1
B1.len = B2.len + 1
Diese beiden Definitionen ermöglichen einen Informationstransport von Knoten im Ableitungsbaum zu höher gelegenen Knoten. Die Definition von zwei weiteren semantischen Regeln für die dritte und fünfte Produktion vervollständigen die Attributierung.
A
1
len
Produktion (3)
B
A ::= a
1
len
Produktion (5)
a
B ::= b
b
A.len = 1
B.len = 1
Der Informationstransport von den Blättern des Ableitungsbaums bis hin zu den Knoten
unterhalb des Wurzelknotens ist somit gewährleistet. Abschließend erfolgt die Definition
einer semantischen Bedingung, die der ersten Produktion zugeordnet wird.
check(A.len, B.len)
Bei dem Ausdruck check handelt es sich um ein Prädikat für das gilt:
check(n1, n2) ist wahr falls n1 = n2
Eine Überprüfung der Werte der Attribute len für die Knoten direkt unterhalb der Wurzel auf
Gleichheit, stellt somit die eingangs geforderte Form der Ausdrücke („aaabbb“) sicher.
In diesem Beispiel, dass sich an ein Beispiel aus [Kühnem] anlehnt, werden Informationen
zwischen Knoten nur in Richtung Wurzelknoten ausgetauscht. Solche Attribute werden als
Attributgrammatiken
7
synthetische Attribute bezeichnet. Das Gegenstück, die inheriten Attribute, ermöglichen einen
Informationsaustausch zwischen Knoten aus Richtung Wurzelknoten in Richtung der Blätter.
Beide Arten von Attributen lassen sich kombinieren. Weitere ausführliche Beispiele, die auch
gleichzeitig Gebrauch von synthetischen und inheriten Attributen machen, können [Kühnem]
und [Schütte] entnommen werden.
2.3 Attributauswertung und WOLM
Das erste Beispiel hat gezeigt, dass sich kontextfreie Grammatiken zur Definition von XMLStrukturen einsetzen lassen. Wird eine solche Grammatik um eine Attributierung erweitert, so
lassen sich Informationen zwischen Knoten des Ableitungsbaums austauschen. Der Austausch
der Attributwerte kann sowohl in Richtung der Blätter als auch in Richtung des Wurzelknoten erfolgen. Werden beide Richtungen kombiniert, so lassen sich beispielsweise kleine
Programmiersprachen definieren (vgl. [Kühnem], [Schütte]), die die Deklariertheit von in
Zuweisungen verwendeten Variablen überprüfen. Die Definition einer AWS, sowie der in ihr
enthaltenen Attributabhängigkeiten, verwenden ähnliche Konzepte (XML-Definition, Überprüfung auf existente Knoten). Eine komplette formale Definition der AWS zur Berechnung
eines AWS-State würde den Rahmen dieser Arbeit sprengen.
WOLM/WSMS
8
3 WOLM/WSMS
3.1 Wolm-WSMS
Ziel des Website Management System (WSMS) ist es, den Anwender beim Betrieb einer
Website zu unterstützen. Dabei werden auf Seiten des Anwenders nur geringste Computerkenntnisse vorausgesetzt. Der Anwender wird nicht mit technischen Begriffen, die mit dem
Betrieb einer Website und den zugrunde liegenden Internettechnologien in Verbindung
stehen, konfrontiert. Erreicht werden diese Ziele durch den Einsatz eines Modells, dem Web
Object Life Cycle Model, kurz WOLM. Dieses Modell enthält Informationen zu Daten und
Prozessen der abzubildenden Realität, die in Form von Web-Objekten gespeichert werden. So
lassen sich beispielsweise alle für die Erstellung und den Betrieb einer Website relevanten
Abläufe, innerhalb eines kleinen Unternehmens, in diesem Modell abbilden. Ein solches
Modell wird zu Beginn einmalig von einer professionellen Kraft in Zusammenarbeit mit dem
Unternehmen erstellt. Nach dieser einmaligen Erstellung, kann der Anwender seine Website
selbständig aktualisieren und dabei indirekt die Zustände der einzelnen Web-Objekte ändern.
Der Anwender wird mit Hilfe einer Reihe von Fragen durch die anstehenden Änderungen der
Website geführt („Möchten Sie ein neues Angebot erstellen? Möchten Sie Kundendaten
ändern?“). Nach Beantwortung dieser Fragen und der evtl. Eingabe von Daten, werden intern
die Zustände der Web-Objekte geändert, Web-Objekte werden gelöscht oder neue hinzugefügt. Das WOLM geht in einen neuen Zustand über. Die Website wird automatisch aktualisiert. Die Arbeit des Anwenders beschränkt sich auf die Beantwortung von Fragen und die
Eingabe von Daten.
3.2 Komponenten
Den Ausgangspunkt für die spätere Website bildet das WOLM. Dieses Model beschreibt alle
für eine Website relevanten Prozesse und Funktionen eines Unternehmens. Der WOLM-State
enthält einen konkreten Zustand dieses Modells zu einem bestimmten Zeitpunkt (1). Für die
strukturelle Darstellung des WOLM in einer Website ist die AWS verantwortlich. Sie wird
stets einem WOLM zugeordnet. Eine initiale AWS lässt sich automatisch aus einem WOLM
berechnen (2). Diese initiale AWS muss in den meisten Fällen manuell nachbearbeitet und
oder ergänzt werden um eine sinnvolle Darstellung der späteren Website zu gewährleisten.
Dies kann mittels eines speziellen AWS-Editors (6) geschehen, aber theoretisch auch mit
jedem beliebigen Text-Editor. Als Gegenstück zum WOLM-State gibt es den AWS-State,
welcher ebenfalls einen konkreten Zustand repräsentiert. Der AWS-State füllt die durch die
WOLM/WSMS
9
AWS festgelegte Struktur mit konkreten Daten aus dem WOLM-State (3). Somit sind im
AWS-State sowohl die Struktur als auch alle vorhandenen Daten einer Website gespeichert.
Der AWS-State macht jedoch keinerlei Aussagen über das Aussehen der Website bzw. der in
ihr enthaltenen Seiten und deren Elemente. Ausgehend vom AWS-State muss daher zunächst,
mit Hilfe eines Website-Templates, die finale Website generiert werden (4). Hierbei kann das
Website-Template, und somit auch die finale Website, beispielsweise aus HTML-Code bestehen. Ein Website-Template beschreibt das Layout der finalen Website.
5
AdminSeiten
7
WOLM
1
WOLM-State
Website
3
2
AWS
AWS-State
4
4
3
AWSEditor
6
WebsiteTemplate
Innerhalb der finalen Website ist es durch Benutzerinteraktion möglich Methoden innerhalb
des WOLM aufzurufen, und somit den Zustand des Models zu verändern, was einen
veränderten WOLM-State zur Folge hat (5). Veränderter WOLM-State und AWS ergeben
einen neuen AWS-State und schließlich eine neue finale Website. Die Zustandsänderung des
WOLM kann alternativ auch über die Admin-Seiten erfolgen (7). Die Auswirkungen auf
WOLM-State, AWS-State und finale Website bleiben die gleichen wie bei der durch
Benutzerinteraktion verursachten Änderungen. Die Komponenten WOLM, WOLM-State
sowie Admin-Seiten wurden in den Arbeiten [Minßen] und [Köpke] entwickelt und
beschrieben. Der Schritt zur Berechnung einer initalen AWS in der Arbeit von [Langer] erarbeitet. Die vorliegende Arbeit beschäftigt sich mit der Berechnung eines AWS-State aus
WOLM-State und AWS. Konzepte zum Website-Template und finaler Website, sowie zum
AWS-Editor werden zum Zeitpunkt der Erstellung dieser Arbeit in weiteren Arbeiten
untersucht und umgesetzt, weswegen detaillierte Aussagen zu diesen Schritten noch nicht
möglich sind.
WOLM-State
10
4 WOLM-State
Ein WOLM-State betrachtet alle in einem WOLM vorhandenen Objekte zu einem festen
Zeitpunkt. Dabei werden alle zu diesem Zeitpunkt existenten Objekte, inklusive ihrer
Attributbezeichnungen sowie der aktuellen Attributwerte, in einer Datei festgehalten. Bei
dieser Datei handelt es sich um eine XML-Datei. Da schon die Darstellung kleinerer XMLDateien sehr viel Platz beansprucht und zudem schnell unübersichtlich wird, wird eine
vereinfachte Notation eingeführt. Ziel ist es, die wesentlichen Eigenschaften einer WOLMState-Datei abzubilden damit, im weiteren Verlauf dieser Arbeit, Beispiele zu konkreten
WOLM-State übersichtlicher dargestellt werden können. Die vereinfachte Notation folgt
folgendem Schema.
Klassenname : id (Attributname = Attributwert, ...)
Klassenname ist die Bezeichnung der WOLM-Klasse des jeweiligen Objekts. Weiterhin ist
jedes Objekt im WOLM-State durch eine eindeutige Bezeichnung identifizierbar (id).
Abschließend folgt die Auflistung sämtlicher Attribute mit den momentanen Werten des
jeweiligen Objekts. Bei den Attributen wird zwischen den drei im WOLM zulässigen Arten
unterschieden. Die Werte einfacher Attribute mit atomaren Attributwerten vom Typ int,
string, boolean werden in Anführungszeichen geschrieben. Bei Attributen, die als Wert eine
Referenz auf ein anderes Objekt des WOLM enthalten, wird als Attributwert die eindeutige id
des referenzierten Objekts angegeben.
Auto : a1 (typ=”VW”, ps=60, km=80.000, besitzer=p2)
Person : p2 (name=”Hans”)
Im obigen Beispiel eines WOLM-State erwartet das Attribut besitzer eine Referenz auf ein
Objekt vom Typ Person. Die dritte Art von Attributen betrifft Attribute, die eine Liste von
Referenzen auf andere WOLM-Objekte als Wert haben. Im folgenden Beispiel ist dies das
Attribut studenten.
Lehrstuhl : l1 (studenten=[s1,s3])
Student: s1 (name=”Hans”)
Student: s3 (name=”Paul”)
Mehrere Objektreferenzen werden in eckigen Klammern und durch Kommata getrennt
geschrieben.
AWS
11
5 AWS
5.1 Überblick
Die AWS bildet mit Hilfe einer Hierarchie von Knoten die Struktur einer Website ab. Dabei
hat jeder Knoten in dieser Hierarchie einen bestimmten Typ. Die zur Verfügung stehenden
Knotentypen sind:
Project, Page, Field, Pagelist, Fieldlist,
Text, Textinput, Hiddentextinput, Image, Link, Button, Action,
Object, Objectlist, Listofobjectlists
Dem Knotentyp Project kommt hierbei eine besondere Bedeutung zu. Er darf nur genau
einmal in der AWS vorkommen, hat selbst keine Vorgängerknoten und bildet somit den
Wurzelknoten der AWS. Die gesamte Website wird durch diesen einen Knoten repräsentiert.
Durch Einfügen weiterer Knoten, der oben aufgelisteten Knotentypen, unterhalb des ProjectKnotens werden alle weiteren Elemente der Website definiert. Diese übrigen Knotentypen
können durch eine beliebige Anzahl an Knoten vertreten sein. Sie haben jeweils einen direkten Vorgängerknoten und sind ggf. selbst Vorgänger für weitere Knoten in der AWS. Durch
Strukturregeln für jeden einzelnen Knotentyp wird weiterhin festgelegt, welche Knotentypen
als Nachfolgeknoten erlaubt sind. Zudem kann eine Begrenzung in der Anzahl der zulässigen
Nachfolgeknoten bestehen. So darf beispielsweise ein Knoten vom Typ Image nur genau
einen oder keinen Knoten vom Typ Link als Nachfolgeknoten enthalten. Der Project-Knoten
darf hingegen beliebig viele Knoten vom Typ Link enthalten.
Eine AWS wird stets in Form einer XML-Datei gespeichert. Eine zugehörige AWS-DTD legt
den Aufbau der XML-Datei fest, gewährleistet das Einhalten der Strukturregeln und stellt
sicher, dass Knoten der verschiedenen Knotentypen stets in der richtigen Kardinalität vorhanden sind. Detaillierte Ausführungen zum Aufbau der AWS-DTD sowie eine genaue Beschreibung der einzelnen AWS-Konzepte können [SZW AWS] und [Langer] entnommen werden.
Für das Verständnis des Hauptteils der vorliegenden Arbeit (AWS-State, Berechnung AWSState), ist jedoch ein grundlegendes Verständnis der wichtigsten AWS-Konzepte erforderlich.
Aus diesem Grund wird im Folgenden kurz auf die wichtigsten AWS-Konzepte eingegangen.
Zu einem besseren Verständnis der AWS können die beiden oben genannten Quellen herangezogen werden. Zudem wird im weiteren Verlauf dieser Arbeit an verschiedenen Stellen auf
weitere Konzepte eingegangen bzw. diese vertieft, soweit dies erforderlich ist. Alle AWS oder
AWS
12
Ausschnitte von AWS, die im Rahmen von Beispielen verwendet werden, werden in der
vereinfachten Notation (vgl. [Langer]) der AWS angegeben. Diese vereinfachte Notation
lehnt sich an die XML-Notation an. Mit ihr lässt sich eine AWS kompakter darstellen. Eine
Darstellung der vollständigen XML-Notation wäre schon für kleine Beispiele zu unübersichtlich.
5.2 Zugriffsregeln
Jeder Knoten in der AWS kann mit einem Attribut ausgezeichnet werden, welches dem
Knoten einen Namen zuweist. Somit sind solche Knoten in der AWS unter einem Namen
bekannt. Andere Knoten in der AWS können bei Bedarf einen Bezug zu einem solchen
benannten Knoten herstellen. Der Name eines einzelnen Knoten kann mehrfach in der AWS
verwendet werden. Die Eindeutigkeit eines Zugriffs wird dabei durch folgende drei
Zugriffsregeln gesichert.
1. Jeder Knoten kann auf sich selbst direkt zugreifen.
2. Jeder Knoten kann auf seinen Vorfahren und dessen Vorfahren (...) direkt zugreifen.
3. Jeder Knoten kann auf seine Geschwisterknoten direkt zugreifen.
Ein Beispiel verdeutlicht die verschiedenen Zugriffsmöglichkeiten.
A
B
C
E
D
Knoten C kann nach Regel 1 auf sich selbst, nach Regel 2 auf Knoten B und A und nach
Regel 3 auf Knoten D jeweils direkt zugreifen. Knoten A kann nur auf sich selbst direkt
zugreifen (Regel 1). Ausgehend von direkt erreichbaren Knoten kann, unter Angabe eines
Pfades, auf weitere Knoten zugegriffen werden. Somit sind für den Knoten A (direkter Zugriff
auf A) die Zugriffe A.B, A.B.C, A.B.D und A.E möglich. Entsprechendes gilt für alle anderen
Knoten. Besitzen Geschwisterknoten den gleichen Namen ist ein Zugriff nicht mehr eindeutig
AWS
13
möglich. Der Ausdruck A.B ermöglicht auf Grund der Namensgleichheit der Geschwisterknoten keinen qualifizierten Zugriff.
A
B
B
Ein weiteres Problem stellen rekursive Bezüge dar. Greift der Knoten B auf C, C auf D und
dieser wiederum auf B zu, so entsteht ein rekursiver Bezug.
A
B
C
D
Sowohl die Namensgleichheit von Geschwisterknoten als auch rekursive Bezüge lassen sich
nicht durch die Definition innerhalb der AWS-DTD verhindern. Die Erkennung dieser
Probleme muss optimalerweise bereits bei der Erstellung einer AWS im AWS-Editor
erfolgen, und dem Anwender des Editors mitgeteilt werden. Werden diese Probleme nicht
erkannt bzw. wird kein Editor verwendet, so sollte bei der Berechnung des AWS-State
zumindest die Erkennung von rekursiven Bezügen gewährleistet sein, und die Berechnung
abgebrochen werden.
5.3 Knotentypen
Die unterschiedlichen Knotentypen der AWS lassen sich in unterschiedliche Klassen einteilen. Im Folgenden wird anhand dieser Einteilung ein kurzer Überblick über die verschiedenen AWS-Knotentypen sowie deren Funktion gegeben.
Wurzelknoten
Der Wurzelknoten der AWS ist stets vom Typ Project. Er hat selbst keine Darstellung in der
Website. Er repräsentiert vielmehr die gesamte Website. Alle weiteren Knoten der AWS
haben diesen Knoten als direkten bzw. indirekten Vorgänger. Eine weitere Aufgabe besteht in
der Festlegung der so genannten Startpage. Hierbei handelt es sich um eine einzelne Seite der
Website, die als Einstiegspunkt für den Besucher der Website dient und angezeigt wird, wenn
der Besucher die Website betritt.
AWS
14
Webseite
Eine Website kann in beliebig viele Seiten aufgeteilt werden. Dabei wird jede einzelne Seite
durch einen Knoten vom Typ Page repräsentiert. Page-Knoten können nur direkt unterhalb
des Project-Knotens aufgehängt sein. Eine besondere Funktion haben Page-Knoten nicht. Sie
dienen lediglich der Aufteilung der Website in einzelne Seiten, sowie der Aufnahme weiterer
AWS-Knoten.
Informationstragende Knoten
Diese Art von Knoten repräsentiert die eigentlichen Inhalte der Webseiten. Zu diesen Knoten
zählen Knoten vom Typ Text, Image und Link. Sie sorgen für die Darstellung von Inhalten in
Form von Texten und Bildern und ermöglichen somit die Gestaltung einer Seite. Ein LinkKnoten, für sich alleine betrachtet, führt nicht zu einer Darstellung auf der Seite. Knoten
dieses Typs müssen einem Text- oder Image-Knoten zugeordnet sein um eine Darstellung zu
erzielen. Der Aufbau der AWS könnte bislang wie folgt aussehen.
Project P
Page A
Page B
Text T
Image I
Link L
Gruppierung von Knoten
Mittels Knoten des Typs Field lassen sich Inhalte einer Seite gruppieren. So lassen sich
beispielsweise Texte und Bilder zu Informationseinheiten zusammenfassen und an unterschiedlichen Positionen der Seite darstellen. Diese Funktion von Field-Knoten dient hauptsächlich einer übersichtlicheren Darstellung von Inhalten. Darüber hinaus lassen sich Gruppen
mit Bedingungen verknüpfen. Ist die Bedingung nicht erfüllt, so wird die Gruppe samt all
ihrer enthaltenen Knoten aus der AWS ausgeblendet, was letzten Endes dazu führt, dass diese
Informationen nicht mehr in der späteren Website enthalten sind. Anwendung für eine solche
Funktion wäre beispielsweise die Personalisierung einzelner Seiten der Website. So können,
abhängig vom jeweiligen Besucher, unterschiedliche Teile der AWS ein- bzw. ausgeblendet
werden.
AWS
15
Interaktionsknoten
Ähnlich zu den informationstragenden Knoten verursacht diese Art von Knoten eine Darstellung auf einer Seite der Website. Anstelle von Texten oder Bildern werden dem Besucher
jedoch Steuerelemente präsentiert, in die er Informationen eintragen, oder mit denen er
Aktionen auslösen, kann. Knoten zur Eingabe von Informationen können entweder vom Typ
Textinput oder Hiddentextinput sein. Bei beiden Knotentypen handelt es sich um ein
Eingabefeld, in das der Besucher einen Text eingeben kann. Bei einem HiddentextinputKnoten erfolgt die Darstellung der Benutzereingabe auf dem Bildschirm des Benutzers in
Form von Sternchen, und eignet sich daher besonders für die Eingabe von Passwörtern.
Mit Hilfe von Knoten vom Typ Button kann der Besucher Aktionen auslösen. Bei diesen
Aktionen handelt es sich meistens um die Übernahme von Informationen aus Eingabefeldern
kombiniert mit dem Aufruf von Methoden des WOLM. So lassen sich Zustandsänderungen
im WOLM herbeiführen, was sich letzten Endes in Änderungen der Website auswirkt.
Objektknoten
Objektknoten stellen die Verbindung zwischen AWS und WOLM her. Ein Objektknoten
ermöglicht den Zugriff auf ein oder mehrere Objekte des WOLM, die entsprechend des
aktuellen WOLM-State verfügbar sind. Die Objektknoten stellen lediglich die Verbindung
zum WOLM her und halten die konkreten Daten der Objekte vor. Sie verursachen selbst
jedoch keine Ausgabe in der AWS. Die drei Knotentypen object, objectlist und
listofobjectlists unterscheiden sich jeweils in der Anzahl der referenzierten Objekte. Ein
Knoten vom Typ object enthält als Wert stets die Referenz auf genau ein WOLM-Objekt oder
nimmt den Wert null an. Objectlist-Knoten enthalten als Wert eine Liste von Referenzen auf
WOLM-Objekte. Dabei kann die Liste auch leer sein. Um eine Zuordnung der gewünschten
Referenzen zu den entsprechenden Objektknoten zu gewährleisten, gibt es eine Reihe von
Selektionsmöglichkeiten, die einer Query-Sprache ähneln. So lassen sich beispielsweise mit
dem folgenden Ausdruck, alle Objekte der WOLM-Klasse Person, dessen Attribut alter einen
Wert größer 17 aufweist, selektieren und einem Objectlist-Knoten zuweisen.
Objectlist OL = Person [ alter > 17 ]
Es gibt viele weitere Selektionsmöglichkeiten auf die auch im späteren Verlauf dieser Arbeit,
bei der Berechnung des AWS-State, noch einmal eingegangen wird. Der Zugriff auf ein
Element einer Objektliste erfolgt über einen Index. Zusätzlich besitzt jede Objektliste eine
Eigenschaft size, welche die Anzahl der in der Objektliste enthaltenen Elemente angibt.
OL[3]
OL.size
// drittes Element der Objektliste
// Anzahl Elemente der Objektliste
AWS
16
Listofobjectlists-Knoten lassen sich am ehesten mit einem zweidimensionalem Array vergleichen. Sie können mehrere Objektlisten aufnehmen, die sich jedoch nicht aus beliebigen
Objektreferenzen zusammensetzen dürfen. Die Referenzen müssen in einem Zusammenhang
stehen, was folgendes Beispiel verdeutlicht.
WOLM Klasse:
WOLM Klasse:
class Film
{
Darsteller* dst;
...
}
class Darsteller
{
String name;
...
}
Objekte der Klasse Film enthalten ein Attribut das eine Menge von Objektreferenzen definiert. Existiert nun eine Menge von Objekten des Typs Film, so enthält wiederum jedes
Element dieser Menge eine Menge von Objektreferenzen (vom Typ Darsteller).
1
D1
1,1
F1
D3
1,2
2,1
2
2,2
F2
D2
D4
2,3
Obiges Beispiel enthält zwei Objekte des Typs Film sowie vier Objekte des Typs Darsteller,
die in dem angegebenen Zusammenhang stehen. Auf einen Listofobjectlists-Knoten, der
diesen Zusammenhang abbildet, lässt sich wie folgt zugreifen. Ein direkter Zugriff auf die
Objekte des Typs Film ist nicht möglich.
LOOL[1,1]
LOOL[2,1]
LOOL[2,3]
// Objekt D1
// Objekt D1
// Objekt D4
Analog zum Objectlist-Knoten besitzt der Listofobjectlists-Knoten ebenfalls eine Eigenschaft,
die die Anzahl der Elemente einer Liste angibt.
LOOL.size
LOOL.size(1)
LOOL.size(2)
// 2
// 2
// 3
Der Ausdruck size ohne Angabe eines Parameters bezieht sich auf die äußere Liste. Mit Hilfe
des Parameters lässt sich die Anzahl der jeweiligen inneren Listen abfragen.
AWS
17
Listenknoten
Listenknoten sind Knoten der Typen Pagelist sowie Fieldlist. Sie unterscheiden sich in
besonderer Weise von den restlichen Knotentypen. Grundlegend entsprechen diese beiden
Knotentypen den Page- bzw. Field-Knoten. Die Besonderheit besteht darin, dass eine Pagelist
eine Reihe von Page-Knoten und eine Fieldlist eine Reihe von Field-Knoten in der AWS
definiert. Die Vervielfachung der Knoten wird dabei durch einen Knoten vom Typ Objectlist
gesteuert, der einem Listenknoten zugeordnet wird. Im Falle einer Pagelist wird für jedes
Objekt, der dieser Pagelist zugeordneten Objektliste, ein neuer Page-Knoten in der AWS
definiert.
Project P
Objectlist A
Pagelist B
Text T
Image I
Link L
Alle Knoten die unterhalb des Pagelist-Knotens hängen werden unter die neuen Page-Knoten
angehängt, so dass folgendes Bild entsteht.
Project P
Objectlist A
Page B[1]
Text T
Page B[2]
Image I
Link L
Text T
Page B[3]
Image I
…
…
Link L
Das zur Vervielfachung verwendete Objekt der Objektliste ist im Folgenden innerhalb des
Page-Knoten, sowie all seiner Unterknoten, über den Ausdruck object bekannt. Alternativ
lässt sich mittels object[index] auf das gleiche Objekt zugreifen. Index gibt dabei die
Position innerhalb der Pagelist an. Durch zusätzliche Rechenoperationen lassen sich, ausgehend von der aktuellen Position, andere Objekte derselben Objektliste erreichen
AWS
18
(object[index+1], object[index-1]). Ebenfalls möglich ist ein direkter Zugriff auf
ein bestimmtes Objekt (object[7]). Die Ausführungen für Pagelist-Knoten gelten analog
für Knoten vom Typ Fieldlist. Knoten des Typs Pagelist kann, alternativ zu einem ObjectlistKnoten, auch ein Listofobjectlists-Knoten zugeordnet sein. Die Objekte, die in einem solchen
Fall zur Vervielfachung verwendet werden, werden aus allen inneren Listen der
Listofobjectlists bezogen. Der Zugriff auf die jeweiligen Objekte ist, innerhalb einer Page,
weiterhin mit Hilfe des Ausdrucks object möglich. Indizierte Zugriffe müssen unter
Angabe beider Indizes erfolgen (object[index,index2], object[2,3]).
AWS-State
19
6 AWS-State
6.1 Überblick
Ein AWS-State enthält eine Teilmenge der zur Definition einer AWS eingeführten
Knotentypen. Die Hierarchie zwischen den einzelnen Knotentypen in der AWS bleibt im
AWS-State erhalten. Bei der Berechnung eines AWS-State wird eine AWS mit konkreten
Werten aus dem aktuellen WOLM-State, des zur AWS gehörigen WOLM, gefüllt. Knotentypen, welche im AWS einen WOLM-Bezug hergestellt haben (object, objectlist,
listofobjectlists), werden nicht in den AWS-State übernommen. Knoten vom Typ Pagelist und
Fieldlist werden ebenfalls nicht übernommen. Sie werden im AWS-State durch eine
entsprechende Anzahl an Page bzw. Field-Knoten ersetzt. Alle anderen Knotentypen finden
sich auch im AWS-State wieder. Zu beachten sind jedoch kleinere Änderungen innerhalb der
Strukturregeln der einzelnen Knotentypen. So darf ein Text-Knoten beispielsweise nicht mehr
unterhalb des Project-Knoten existieren. Eine Auflistung der möglichen Knotentypen im
AWS-State, sowie deren mögliche Nachfolger, kann der folgenden Tabelle entnommen
werden.
Knoten im AWS-State
Mögliche Nachfolgeknoten
Project
Page
Page
Field, Text, Image, Textinput, Hiddentextinput, Button
Field
Field, Text, Image, Textinput, Hiddentextinput, Button
Text, Image
Link
Button
Action, Link
Link, Textinput,
Keiner dieser Knoten hat Nachfolgeknoten im AWS-State
Hiddentextinput, Action
Tabelle 1: AWS-State Knotentypen
Dies sind alle Knotentypen, die in einem AWS-State vorkommen können. Die Hierarchie der
einzelnen Knoten beschreibt, genau wie die AWS, die Struktur der späteren Website. Im
Gegensatz zur AWS, enthält der AWS-State jedoch weder WOLM- noch AWS-Bezüge.
Sämtliche Bezüge sind aufgelöst. Das Ergebnis der Berechnung ist eine vollständige, zur
AWS kompatible, Struktur der gesamten Website. Der AWS-State enthält keine Informationen über das Layout der späteren Website. Die Festlegung des Layouts sowie die
Generierung der finalen Website, in einer für den Benutzer lesbaren Form, müssen in einem
AWS-State
20
separaten Vorgang erfolgen. Gespeichert wird der AWS-State, wie das WOLM, der WOLMState und die AWS, in einer XML-Datei. Eine zugehörige AWS-State-DTD sorgt für die
Einhaltung der Strukturregeln, definiert Attribute für die einzelnen Knotentypen und stellt die
Kardinalitäten von Nachfolgeknoten sicher. Anhand der AWS-State-DTD werden im Folgenden alle Knotentypen und evtl. zu beachtende Besonderheiten erläutert.
6.2 Knotentypen
Jeder Knoten innerhalb des AWS-State besitzt ein Attribut mit der Bezeichnung id. Es handelt
sich hierbei um eine innerhalb des AWS-State eindeutige ID, genannt AWS-State-ID. Der
Wert für dieses Attribut muss für jeden Knoten gesetzt sein. Durch die AWS-State-ID ist
jeder Knoten innerhalb des AWS-State eindeutig identifizierbar.
6.2.1 Project
Der Project-Knoten hat die gleiche Aufgabe wie in der AWS. Er dient als Wurzelknoten für
die Hierarchie von Knoten, welche die Struktur der späteren Website beschreibt. Der Knoten
hat selbst keine konkrete Darstellung in der späteren Website, enthält jedoch alle weiteren
Knoten. Der Project-Knoten darf als Kindknoten nur Knoten vom Typ Page enthalten, diese
jedoch in beliebiger Anzahl. Zusätzlich besitzt der Project-Knoten zwei Attribute. Bei dem
ersten Attribut mit der Bezeichnung id handelt es sich um die eingangs erwähnte AWS-StateID, die jeden Knoten innerhalb des AWS-State eindeutig identifiziert. Da jeder Knotentyp
innerhalb des AWS-State dieses Attribut besitzt, und seine Bedeutung nun bekannt ist, wird in
den Ausführungen zu den übrigen Knotentypen nicht mehr explizit auf dieses Attribut
eingegangen. Das zweite Attribut des Project-Knoten ist das Attribut startpage. Als Wert
enthält dieses Attribut eine AWS-State-ID eines Page-Knoten des AWS-State, und gibt somit
den Einstiegssprung, die Startseite, für die spätere Website an.
<!ELEMENT project (page)*>
<!ATTLIST project
id CDATA #REQUIRED
startpage CDATA #REQUIRED
>
6.2.2 Page
Der Page-Knoten beschreibt eine konkrete Seite der späteren Website und kann selbst eine
beliebige Anzahl weiterer Knoten vom Typ Field, Text, Image, Textinput, Hiddentextinput
sowie Button enthalten. Zudem kann der Page-Knoten ein Attribut mit der Bezeichnung listid
AWS-State
21
enthalten. Listid identifiziert eine Pagelist der AWS eindeutig. Die Bezeichnung #IMPLIED
in der AWS-State-DTD gibt an, dass dieses Attribut optional ist. Ein Page-Knoten besitzt
dieses Attribut lediglich dann, wenn er aus einer Pagelist hervorgegangen ist.
<!ELEMENT page (field | text | image | textinput |
hiddentextinput | button)*>
<!ATTLIST page
id CDATA #REQUIRED
listid CDATA #IMPLIED
>
Jede Pagelist innerhalb der AWS wird im AWS-State durch eine entsprechende Anzahl an
Page-Knoten ersetzt, vorausgesetzt die zur Pagelist gehörige Objektliste weist eine
entsprechende Anzahl an Elementen auf. Ohne Angabe der listid ließen sich die einzelnen
Page-Knoten innerhalb des AWS-State keiner Pagelist der AWS mehr zuordnen.
AWS
listid: PL1
...
listid: PL1
Pagelist A
Text t1
AWS-State
Text t2
Page #1
Text #3
Text #4
...
listid: PL1
Page #2
Text #5
...
Text #6
Anhand dieser listid ist es möglich Gruppen von Page-Knoten innerhalb des AWS-State zu
identifizieren. Jede dieser Gruppen entstand aus einer Pagelist. Die Zuordnung der PageKnoten innerhalb des AWS-State zu ihrer gemeinsamen Ursprungs-Pagelist, ist dann
erforderlich und von Vorteil, wenn ein Page-Knoten in der Website dargestellt werden soll.
Auf Grund der Strukturgleichheit von Page-Knoten einer Pagelist ist beispielsweise die
Transformation in eine HTML-Darstellung nur einmal nötig. Für alle folgenden Page-Knoten
bleibt die Struktur gleich. Lediglich die enthaltenen Werte ändern sich.
6.2.3 Field
Die Definition des Field-Knoten in der AWS-State-DTD ist identisch mit der des PageKnoten. Die möglichen Knoten die ein Field-Knoten enthalten kann sind, ebenso wie die
AWS-State
22
Attribute und deren Bedeutung, gleich zu denen des Page-Knoten. Ebenso wie bei einer
Pagelist wird eine Fieldlist im AWS-State durch eine Reihe von Field-Knoten ersetzt.
<!ELEMENT field (field | text | image | textinput |
hiddentextinput | button)*>
<!ATTLIST field
id CDATA #REQUIRED
listid CDATA #IMPLIED
>
6.2.4 Text
Ein Text-Knoten hat außer dem Attribut id, für die AWS-State-ID, keine weiteren Attribute.
Er kann genau einen oder keinen weiteren Knoten vom Typ Link enthalten. Der Knoten const
enthält den konkreten Inhaltswert des Text-Knoten.
<!ELEMENT text (const, link?)>
<!ATTLIST text
id CDATA #REQUIRED
>
Ein Text-Knoten im AWS-State mit dem Inhaltswert “Hallo” hätte somit folgende XMLDarstellung.
<text id=”#1”><const>Inhalt</const></text>
6.2.5 Textinput, Hiddentextinput
Diese beiden Knotentypen sind sowohl vom Aufbau als auch von ihrer Bedeutung her nahezu
identisch. Ein Textinput-Knoten steht für ein Eingabefeld in das der Benutzer der Website
einen Text eingeben kann. Beim Hiddentextinput-Knoten handelt es sich ebenfalls um ein
Eingabefeld in das der Benutzer einen Text eingeben kann. Der eingegebene Text ist jedoch
nicht auf dem Bildschirm sichtbar und wird beispielsweise nur durch Sternchen angedeutet.
Dieser Knotentyp eignet sich somit für die Eingabe von sicherheitsrelevanten Daten (z.Bsp.
Passwörter), die nicht für Dritte am Bildschirm ablesbar sein sollen.
AWS-State
23
<!ELEMENT textinput (const)>
<!ATTLIST textinput
id CDATA #REQUIRED
>
<!ELEMENT hiddentextinput (const)>
<!ATTLIST hiddentextinput
id CDATA #REQUIRED
>
Die Definition in der AWS zeigt, dass die konkreten Inhaltswerte der einzelnen Knoten
wiederum in einem const-Knoten dargestellt werden. Die Inhaltswerte können in beiden
Fällen vom Benutzer oder durch eine Vorbelegung der Eingabefelder mit bestimmten Werten
stammen.
6.2.6 Link
Ein Knoten vom Typ Link kann keine weiteren Knoten enthalten. Die Information steht bei
diesem Knoten direkt innerhalb des Link-Xml-Tags: <link id=“#4“>INHALT</link>
Dies wird in der AWS-State-DTD durch den Ausdruck #PCDATA dargestellt. Als Information enthält ein Link-Knoten eine AWS-State-ID zur Identifizierung des AWS-StateKnotens auf den der Link-Knoten verweisen soll. Ein Link im AWS-State kann auf Knoten
der folgenden Typen verweisen: Page, Field, Text, Textinput, Hiddentextinput, Image,
Button.
<!ELEMENT link (#PCDATA)>
<!ATTLIST link
id CDATA #REQUIRED
>
Der folgende XML-Ausdruck, innerhalb einer AWS-State-Datei, würde beispielsweise einen
Link auf den Knoten mit der AWS-State-ID „#23“ entsprechen.
<link id=“#4“>#23</link>
6.2.7 Image
Ein Image-Knoten im AWS-State beschreibt ein Bild auf der späteren Website. Alle
benötigten Informationen werden als String in einem Const-Knoten innerhalb des ImageKnoten definiert.
AWS-State
24
<!ELEMENT image (const, link?)>
<!ATTLIST image
id CDATA #REQUIRED
>
Dieser String enthält Angaben zum Dateinamen (File) der Breite (Width) und Höhe (Height)
des Bildes. Die Angabe von Width und Height ist optional. Die einzelnen Angaben werden
durch Kommata getrennt. Im Folgenden sind zwei Beispiele für Image-Knoten innerhalb
eines AWS-State dargestellt.
<image id=”#123”>
<const>File=bild.jpg,Width=160,Height=80</const>
</image>
<image id=”#123”>
<const>File=bild.jpg</const>
</image>
6.2.8 Button, Action
Der Button-Knoten beschreibt eine Schaltfläche auf der Website, welche durch einen
Benutzer betätigt werden kann. Nach der Betätigung einer solchen Schaltfläche sind
unterschiedliche Aktionen möglich. Im einfachsten Fall wird lediglich eine beschriftete
Schaltfläche ohne jegliche Funktion angezeigt (const: Beschriftung der Schaltfläche).
<!ELEMENT button (const, action*, link?)>
<!ATTLIST button
id CDATA #REQUIRED
>
Darüber hinaus ist es möglich einen Knoten der Website anzugeben (link), der nach
Betätigung der Schaltfläche angesprungen werden soll, beispielsweise eine andere Seite.
Diese Angabe ist optional. Wird ein solcher Zielknoten nicht angegeben, so wird nach
Betätigen der Schaltfläche die gleiche Seite erneut angezeigt. Die letzte Möglichkeit besteht
im Aufruf einer oder mehrerer Methoden des WOLM, welche zu einem veränderten WOLMState, verändertem AWS-State und letztlich neuen Website führt (action).
Die aufzurufenden Methoden des WOLM werden jeweils durch einen Knoten vom Typ
Action repräsentiert. Die DTD-Definition eines Action-Knotens wurde nahezu unverändert
AWS-State
25
aus der DTD-Definition der AWS übernommen. Lediglich das Attribut name wurde durch das
Attribut id (AWS-State-ID) ersetzt.
<!ELEMENT action (params?)>
<!ATTLIST action
id CDATA #REQUIRED
precedence CDATA #IMPLIED
wolmobject CDATA #REQUIRED
method CDATA #REQUIRED
>
<!ELEMENT params ((const | cvalue)+)>
Ein Button könnte im AWS-State somit folgende Form haben.
<button id="#1">
<const>Klick mich</const>
<action id="#2" wolmobject="42" method="doIt">
<params>
<const>12</const>
<cvalue>#3</cvalue>
// #3 AWS-State-ID
</params>
</action>
</button>
Die Beschriftung des Buttons ist mit „Klick mich“ angegeben. Nach Betätigen des Buttons
soll die Methode mit dem Namen „doIt“ auf dem WOLM-Objekt mit der id 42 aufgerufen
werden. Jedes WOLM-Objekt innerhalb des WOLM-State besitzt eine eindeutige id. Das in
diesem Beispiel nicht angegebene optionale Attribut precedence legt bei mehreren
vorhandenen Action-Knoten innerhalb eines Button-Knotens die Reihenfolge fest, in der die
einzelnen Methoden aufgerufen werden. Fehlt diese Angabe, so werden die Methoden der
Reihe nach aufgerufen. Parameter, die dem Methodenaufruf übergeben werden, können auf
zwei unterschiedliche Arten angegeben werden. Erfolgt die Angabe des Parameters innerhalb
eines const-Knotens, so handelt es sich bei dem Parameter um einen konstanten Wert. Die
Angabe innerhalb eines cvalue-Knotens deutet an, dass es sich bei dem Parameter um einen
clientseitigen Wert innerhalb der finalen Website handelt. Dies können Werte sein, die in
Knoten der Typen Textinput oder Hiddentextinput durch den Benutzer eingegeben und bei
Betätigen eines Buttons verfügbar wurden. Der Bezug zu den Eingabefeldern erfolgt dabei
durch Angabe der AWS-State-ID des entsprechenden Eingabefeldes.
Nähere Informationen zum Ablauf des Aufrufs von Methoden im WOLM aus einer fertigen
Website heraus, sind zum Erstellungszeitpunkt dieser Arbeit noch nicht vorhanden. Es ist
AWS-State
26
somit möglich, dass zu einem späteren Zeitpunkt Änderungen und oder Ergänzungen an den
Knotentypen Button und Action erforderlich werden.
Die komplette zusammenhängende AWS-State-DTD kann dem Anhang entnommen werden.
6.3 Beispiele
Der theoretischen Betrachtung aller möglichen Knotentypen eines AWS-State folgen nun
einige Beispiele konkreter AWS-State. Dabei werden nicht nur die fertigen, berechneten
AWS-State betrachtet, sondern das gesamte WOLM, inklusive WOLM-State und AWS. Alle
Beispiele wurden aus Gründen der Übersichtlichkeit so einfach wie möglich gehalten. Aus
demselben Grund, wird die vereinfachte Notation, bei der Darstellung von WOLM-State,
AWS und AWS-State, anstelle der XML-Darstellung verwendet.
Da sich ein AWS-State immer direkt aus einem WOLM-State und einer zugehörigen AWS
zusammensetzt, wird zunächst ein simples WOLM eingeführt.
WOLM
class Auto
{
String typ
int ps
int km
}
class Geschäft
{
String name
int umsatz
}
class User
{
String name
setName(String n)
}
Das WOLM, welches für die folgenden Beispiele Verwendung findet, besteht aus drei
Klassen. Die einzelnen Klassen enthalten jeweils unterschiedliche Attribute vom Typ string
oder int. Die Klasse User enthält des Weiteren eine Methode, die dazu verwendet werden
kann dem Attribut name selbiger Klasse einen neuen Wert zuzuweisen. Dem ersten Beispiel
eines AWS-State liegt folgender WOLM-State zu Grunde.
WOLM-State (1)
Auto:a1 (typ=”VW”, ps=60, km=80.000)
Der WOLM-State enthält genau ein Objekt der Klasse Auto, mit den obigen Ausprägungen
der drei Attributwerte typ, ps und km. Neben dem WOLM-State wird eine AWS benötigt,
welche die Werte des WOLM-State in einer Website-Struktur darstellt. Eine mögliche AWS
AWS-State
27
für das zugrunde liegende WOLM, sowie den konkreten WOLM-State, könnte wie folgt
aussehen.
AWS (1)
Project P = A
Object obj = Auto
Page A
Text = P.obj.typ + “,” P.obj.ps + “,” + P.obj.km
Die AWS stellt über den Object-Knoten obj eine Verbindung zum WOLM-State her. Der
Knoten obj enthält im aktuellen Beispiel eine Referenz auf das einzige Objekt des WOLMState, das Objekt a1 der Klasse Auto. Anschließend kann innerhalb des Text-Knoten über die
Objekt-Referenz obj auf die Attributwerte des Auto-Objekts zugegriffen werden. Alle
Attributwerte des Objekts sollen in der späteren Website durch Kommata getrennt dargestellt
werden. Mit den nun vorliegenden Informationen (WOLM-State, AWS) kann der AWS-State
berechnet werden. Die Berechnung ist trivial und führt zu folgendem AWS-State.
AWS-State (1)
Project #1 = #2
Page #2
Text #3 = “VW,60,80.000”
Die fertige Website besteht somit aus einer Seite. Die Seite enthält als einzige Information die
aktuellen Attributwerte des Auto-Objekts aus dem WOLM-State.
Im zweiten Beispiel enthält der WOLM-State mehrere Objekte der Klasse Auto mit entsprechenden Attributwerten.
WOLM-State (2)
Auto:a1 (typ=”VW”, ps=60, km=80.000)
Auto:a2 (typ=”VW”, ps=40, km=60.000)
Auto:a3 (typ=”OPEL”, ps=160, km=20.000)
Eine zugehörige AWS soll ähnlich zum ersten Beispiel die Attributwerte eines Auto-Objektes
auf einer Seite darstellen. Jedes Objekt des WOLM-State soll jedoch auf einer eigenen Seite
dargestellt werden. Zudem sollen die einzelnen Seiten, über entsprechende „next“ und „prev“
Links, auf die nächste bzw. vorherige Seite, untereinander verbunden sein. Eine AWS, die
dies gewährleistet könnte wie folgt aussehen.
AWS-State
28
AWS (2)
Project P = A[first]
Objectlist olist = Auto
Pagelist A = olist
Text = object.typ + “,” object.ps + “,” + object.km
Text = “Next”
Link = A[index+1]
Text = “Prev”
Link = A[index-1]
Es wird im Folgenden darauf verzichtet die AWS im Detail zu erläutern. Detaillierte
Informationen können bei Bedarf dem Kapitel AWS bzw. den im Anhang erwähnten Quellen
entnommen werden. Der aus WOLM-State und der AWS resultierende AWS-State sieht wie
folgt aus.
Page #2
AWS-State (2)
Project #1 = #2
Page #2
Text #3 = “VW,60,80.000”
Text #4 = “Next“
Link #5 = #6
Page #6
Text #7 = “VW,40,60.000”
Text #8 = “Next“
Link #9 = #12
Text #10 = “Prev“
Link #11 = #2
Page #12
Text #13 = “OPEL,160,20.000”
Text #14 = “Prev“
Link #15 = #6
VW, 60, 80.000
next
Page #6
VW, 40, 60.000
prev
next
Page #12
OPEL, 160, 20.000
prev
Wie gefordert, werden die Attributinformationen der einzelnen Objekte des WOLM-State
jeweils in einer eigenen Seite dargestellt. Zu beachten ist im obigen Beispiel, dass die drei im
AWS-State vorhandenen Seiten alle die gleiche Struktur aufweisen, da sie alle aus der
gleichen Pagelist (in der AWS) entstanden sind.
Ein letztes, etwas komplexeres Beispiel zeigt die Berechnung des AWS-State in Abhängigkeit vom WOLM-State. Zudem wird das Vorgehen zur Modifikation des WOLM bei durch
AWS-State
29
den Benutzer der Website ausgelösten Aktionen erläutert. Der initiale WOLM-State enthält
zwei Objekte mit entsprechenden Attributwerten. Der Wert des Attributs name des UserObjekts u1 ist zunächst leer bzw. undefiniert.
WOLM-State (3-1)
Geschäft:gs1 (bez=”VW-ULI”, umsatz=250)
User:u1 (name=““)
Folgende zugehörige AWS definiert für die fertige Website zwei Seiten. Auf der ersten Seite
soll die Bezeichnung des Unternehmens dargestellt werden. Zudem wird, abhängig von einer
Bedingung, ein weiterer Text auf der gleichen Seite dargestellt. Der Umsatz des
Unternehmens. Ist die Bedingung hingegen nicht erfüllt, so wird ein Link mit der
Bezeichnung „Login“ dargestellt, welcher auf die zweite Seite der Website verweist.
AWS (3-1)
Project P = A
Object obj_gs = Geschäft
Object obj_u = User
Page A
Text = P.obj_gs.bez
Field ? P.obj_u[name = ”ULI”]
// Bedingung 1
Text = “Umsatz:” + P.obj_gs.umsatz
Field ? P.obj_u[name != “ULI”]
// Bedingung 2
Text = ”Login”
Link = P.B
Page B
Textinput ti = ””
Button = ”Login”
Action = P.obj_u:setName(ti)
Link = P.A
Im hier verwendeten WOLM-State ist der Wert des Attributs name des User-Objektes nicht
definiert. Er ist somit ungleich „ULI“. Bedingung 1 des Field-Knoten ist somit nicht erfüllt.
Die Knoten, die sich unterhalb dieses Field-Knoten befinden werden nicht in den AWS-State
übernommen. Folglich ist in diesem Beispiel Bedingung 2 erfüllt, und alle Knoten unterhalb
des zweiten Field-Knoten werden in den AWS-State übernommen.
Die zweite Seite (Page B) enthält ein Text-Eingabefeld sowie einen Button zur Bestätigung
der Eingabe. Nach betätigen des Buttons durch den Benutzer der Website, wird eine Methode
AWS-State
30
„setName(…)“ auf dem User-Objekt aufgerufen. Als Parameter wird hierbei der Eingabewert
des Text-Eingabefeldes (ti) übergeben. Nach Ausführung dieses Aufrufs soll dem Benutzer
wieder die erste Seite der Website angezeigt werden. Dies wird durch den Link mit dem Ziel
P.A (erste Seite) gewährleistet.
Folgende Abbildung zeigt den berechneten AWS-State sowie eine schematische Darstellung
der fertigen Website zu oben gegebenem WOLM-State und AWS.
Page #2
AWS-State (3-1)
Project #1 = #2
VW-ULI
Page #2
Text #3 = “VW-ULI”
Field #4
Text #5 = “Login”
Link #6 = #7
Page #7
Textinput
Button #9
Action =
Link #10
#8 = “”
= “Login”
P.obj_u:setName(#8)
= #2
Field #4
Login
Page #7
Login
Der Benutzer befindet sich zu Beginn auf der ersten Seite. Der Umsatz des Geschäfts wird
nicht angezeigt. Gelangt der Benutzer über den Link „Login“ zur zweiten Seite der Website,
kann er dort einen Namen in das Text-Eingabefeld eingeben und den Button „Login“
betätigen. Ein Betätigen des Buttons führt zum Aufruf der Methode setName() im WOLM,
welche dem Attribut name des User-Objekts den übergebenen neuen Wert zuweist. Hat der
Benutzer den Namen „ULI“ eingegeben, so führt dies zu folgendem verändertem WOLMState.
WOLM-State (3-2)
Geschäft:gs1 (bez=”VW-ULI”, umsatz=250)
User:u1 (name=“ULI“)
AWS-State
31
Das Attribut name des User-Objekts besitzt nun den Wert „ULI“. Unter Zuhilfenahme der
bereits bekannten AWS kann mit dem veränderten WOLM-State ein neuer AWS-State
berechnet werden. Der so neu berechnete AWS-State enthält wiederum zwei Seiten. Die
zweite Seite ist unverändert gegenüber AWS-State (3-1). Auf der ersten Seite wird nun
allerdings der Umsatz des Geschäfts angezeigt, da jetzt, durch den veränderten WOLM-State,
die Bedingung des ersten Field-Knoten erfüllt ist.
AWS-State (3-2)
Page #2
Project #1 = #2
VW-ULI
Page #2
Text #3 = “VW-ULI”
Field #4
Text #5 = “Umsatz: 250”
Field #4
Umsatz: 250
Page #6
Textinput #7 = „“
Button #8 = „Login“
Action = P.obj_u:setName(#8)
Page #7
Link #9 = #2
Login
Berechnung des AWS-State
32
7 Berechnung des AWS-State
Die Berechnung des AWS-State ist ein komplexer Vorgang. Hierdurch wird auch die
Beschreibung der verwendeten Konzepte und Vorgehensweise, in einer für Dritte, die sich
noch nicht intensiv mit der Materie beschäftigt haben, leicht verständlichen Form, erschwert.
Aus diesem Grund beginnt dieses Kapitel mit einer kompakten Darstellung aller wesentlichen
Konzepte zur Berechnung eines AWS-State. Im darauf folgenden Kapitel (7.2) werden diese
Konzepte vertieft sowie weitere Konzepte eingeführt. Die in diesen beiden Kapiteln
erarbeiteten und vorgestellten Konzepte, ermöglichen dann eine vergleichsweise einfache
Betrachtung der Berechnung jedes einzelnen AWS-Knotentyps (7.3).
7.1 Überblick Berechnungskonzepte
Einige Vorbemerkungen zum Vorgehen bei der Berechnung. Die Berechnung des AWS-State
erfolgt zunächst innerhalb der gegebenen Hierarchie von AWS-Knoten. AWS-Knotentypen
werden nach erfolgter Berechnung in AWS-State-Knotentypen überführt. Erst nach
Berechnung sämtlicher Knoten, werden alle gültigen Knoten in eine AWS-State-Hierarchie
überführt. Dies beinhaltet das Entfernen von Knotentypen, die nicht in einem AWS-State
vorkommen (Pagelist, Fieldlist, Object,…). Ein undefinierter oder ungültiger Knoten ist ein
Knoten, für den keine AWS-State Repräsentation existiert, beispielsweise aufgrund eines
Bezugfehlers. Ein berechneter Knoten befindet sich in seiner AWS-State Repräsentation.
7.1.1 Berechnungskonzepte als Blackbox
Die Berechnung eines AWS-State, aus einem gegebenen WOLM-State sowie einer AWS,
lässt sich mit Hilfe einer einzigen rekursiv definierten Funktion beschreiben.
BerechneKnoten(Knoten, true|false)
Die Funktion erhält als ersten Parameter eine Referenz auf einen Knoten innerhalb der AWS.
Aufgabe der Funktion ist die Berechnung des referenzierten AWS-Knotens. Hat der zweite
Parameter den Wert true, so werden alle Kindknoten des aktuellen Knotens, soweit
vorhanden, ebenfalls berechnet. Dies geschieht jeweils durch einen erneuten Aufruf von
BerechneKnoten(), mit dem entsprechenden Kindknoten als Parameter. Die Berechnung des
kompletten AWS-State könnte damit wie folgt aussehen.
Berechnung des AWS-State
33
refAWS = … // Referenz auf den Wurzelknoten der AWS
BerechneKnoten(refAWS, true)
Betrachtet man folgende Baumdarstellung einer AWS, so würde mit den beiden oben
stehenden Zeilen somit zunächst die Berechnung des Wurzelknotens (Project) angestoßen. Da
auch alle vorhandenen Kindknoten berechnet werden sollen, folgt ein Aufruf auf dem Knoten
Page, welcher wiederum die Berechnung seiner Kindknoten veranlasst.
Project
Page
Text
…
…
...
Dies geschieht solange bis alle Knoten in der AWS erreicht wurden. Nach der Abarbeitung
aller Aufrufe ist ein vollständiger AWS-State berechnet. Dieser Ansatz zur Berechnung ist
recht trivial. Die konkrete Umsetzung der Funktion BerechneKnoten(), kann für praxisrelevante AWS jedoch sehr schnell zu einem komplexen Vorgang werden. Allen weiteren
Betrachtungen liegt jedoch die oben beschriebene rekursive Vorgehensweise zugrunde. Im
Folgenden werden, anhand von zunächst einfachen Beispielen, die notwendigen Vorgehensweisen und Konzepte Schritt für Schritt erläutert.
7.1.2 AWS ohne Bezüge
Betrachtet man eine AWS, welche weder AWS-Bezüge noch WOLM-Bezüge enthält, so lässt
sich die vollständige Berechnung des AWS-State sehr leicht durchführen. In der praktischen
Anwendung werden allerdings in nahezu jeder AWS Bezüge sowohl zwischen Knoten
innerhalb der AWS, als auch Bezüge zu Objektknoten, die eine Verbindung zum WOLM
herstellen, vorhanden sein. Diese Bezüge stellen einen zentralen Bestandteil der AWS dar,
erschweren aber zugleich die Berechnung des AWS-State. Aus diesem Grund wird zunächst
eine AWS ohne Bezüge betrachtet, anhand derer die Schritte zur Berechnung des AWS-State
gut beschrieben werden können. Trotz der Vereinfachung ist die untenstehende AWS
dennoch selbstverständlich eine gültige AWS.
Berechnung des AWS-State
AWS
Project P = A
Page A
Text T1 = "Hallo"
Text T2 = "abc"
34
AWS-State
Project #1 = #2
Page #2
Text #3 = "Hallo"
Text #4 = "abc"
Anhand der gegebenen AWS lässt sich die Aufrufreihenfolge der einzelnen BerechneKnoten
Funktionen aufstellen.
BerechneKnoten(P, true)
BerechneKnoten(A, true)
BerechneKnoten(T1, true)
BerechneKnoten(T2, true)
Innerhalb der Funktionen geschieht nun folgendes. Jeder Knoten bekommt eine eindeutige
AWS-State-ID zugewiesen. Da die beiden Text-Knoten keine Kindknoten haben und auch
keine AWS bzw. WOLM-Bezüge vorhandnen sind, sind die Text-Knoten hiermit vollständig
berechnet. Die Funktion zur Berechnung des Page-Knoten erfordert ebenfalls keine weiteren
Berechnungen. Es muss lediglich sichergestellt sein, dass die Berechnung der Kindknoten
(hier T1, T2) angestoßen wird. Gleiches gilt für den Project-Knoten. Nachdem alle Knoten
berechnet sind, muss der Project-Knoten jedoch noch den Wert seiner Startseite anpassen. Die
Startseite verweist in diesem Fall auf die AWS-State-ID der Page A der AWS (hier: #2). Der
AWS-State ist somit berechnet und hat die oben abgebildete Darstellung. Alle gültigen AWS,
die ebenfalls keine Bezüge enthalten, lassen sich auf die gleiche Weise berechnen. Darüber
hinaus lassen sich auch alle anderen AWS mit derselben Vorgehensweise berechnen. Es
müssen jedoch weitere Punkte beachtet werden, welche in den nächsten Kapiteln erläutert
werden.
7.1.3 AWS mit AWS-Bezügen
Durch die Verwendung von AWS-Bezügen ist es einem AWS-Knoten möglich einen Bezug
zu einem anderen Knoten innerhalb der AWS herzustellen. So kann zum Beispiel der Inhaltswert eines Text-Knotens aus dem Inhaltswert eines anderen Text-Knotens bestimmt werden.
Es gibt viele weitere Anwendungsmöglichkeiten von AWS-Bezügen. Die grundlegende
Vorgehensweise ist jedoch immer gleich, weshalb an dieser Stelle zunächst wiederum nicht
auf alle Details eingegangen wird. Dies wird jedoch in den folgenden Kapiteln nachgeholt.
Berechnung des AWS-State
35
Das Konstrukt zur Herstellung von AWS-Bezügen ist der Awslink. Der Awslink gehört nicht
direkt zu den AWS-Knotentypen, wie sie in Kap. AWS beschrieben sind, und ist daher auch
in der bislang verwendeten Baumdarstellung einer AWS nicht zu erkennen. In der
vereinfachten Notation ist der Awslink ebenfalls nicht direkt zu erkennen und es muss aus
dem Zusammenhang auf ihn geschlossen bzw. dieser explizit, zum Beispiel durch einen
Kommentar, ausgezeichnet werden.
Page A
Text T1 = F.T2 // awslink
Field F
Text T2 = „xy“
Page A
Text T1
Field F
Text T2
awslink
AWS-State:
Page #1
Text #2 = “xy”
Field #3
Text #4 = „xy“
Die notwendigen Aufgaben zur Berechnung eines Awslink werden in einer neuen Funktion
gekapselt.
BerechneAwslink(Knoten, awslink)
Die Funktion bekommt als ersten Parameter eine Referenz auf einen in der AWS befindlichen
Knoten (hier: T1) übergeben. Als zweiter Parameter wird der im Awslink gespeicherte Pfad
angegeben (hier „F.T2“). Die Aufgabe der Funktion besteht nun darin, ausgehend vom
übergebenen Knoten, gemäß der Pfadangabe des Awslinks, einen Zugriff auf den
referenzierten Knoten herzustellen. Dies geschieht anhand der Zugriffsregeln innerhalb der
AWS. Der Knoten T1 kann zunächst direkt auf seinen Geschwisterknoten F und von dort aus
auf den Knoten T2 zugreifen. Ein so referenzierter Knoten kann dann für weitere Berechnungen verwendet werden.
Die im vorangegangenen Kapitel verwendete Vorgehensweise zur Berechnung des AWSState würde für den obigen Ausschnitt einer AWS zu folgender Berechnungsreihenfolge
führen.
BerechneKnoten(A, true)
BerechneKnoten(T1, true)
BerechneKnoten(F, true)
BerechneKnoten(T2, true)
Berechnung des AWS-State
36
Die Existenz des Awslink im Text-Knoten T1 hat aber zur Folge, dass der Knoten T1 nicht
vollständig berechnet werden kann, bevor nicht der Knoten T2 berechnet wurde. Die
Berechnung des Knotens T2 müsste also vor der Berechnung des Knotens T1 erfolgen. Dies
hätte wiederum die vorherige Berechnung des Knotens F zur Folge. Ein möglicher Ansatz
wäre also die Berechnung des rechten Teilbaums von Page A im ersten Schritt und folglich
die Berechnung des linken Teilbaums im zweiten Schritt.
BerechneKnoten(A, true)
BerechneKnoten(F, true)
BerechneKnoten(T2, true)
BerechneKnoten(T1, true)
Somit wäre sichergestellt, dass der Knoten T2 berechnet ist, bevor der Knoten T1 auf selbigen
zugreift. In diesem konkreten Beispiel mit lediglich einem Awslink wäre diese
Vorgehensweise denkbar. Sobald eine AWS jedoch mehr als einen Awslink enthält, ist diese
Vorgehensweise unter Umständen nicht mehr möglich, was im Folgenden anhand eines
Beispiels gezeigt wird.
Page A
Text T1
Page B
Text T2
awslink
Project P =
Page A
Text T1
Text T2
Page B
Text T3
Text T4
P.A
= P.B.T3
= „XYZ“
= „ABC“
= P.A.T2
Text T3
Text T4
awslink
BerechneKnoten(A, true)
BerechneKnoten(T1, true)
BerechneKnoten(T2, true)
BerechneKnoten(B, true)
BerechneKnoten(T3, true)
BerechneKnoten(T4, true)
Der linke Teilbaum enthält in diesem Beispiel einen Knoten mit einem Awslink auf einen
Knoten im rechten Teilbaum und umgekehrt. Ein Austausch der Berechnungsreihenfolge der
Berechnung des AWS-State
37
beiden Teilbäume ist somit nicht mehr möglich. Dennoch muss der Knoten T3 vor dem
Knoten T1, sowie der Knoten T2 vor dem Knoten T4 berechnet werden. Um trotzdem einen
AWS-State berechnen zu können muss also anders vorgegangen werden. Die grundlegende
Vorgehensweise bleibt dabei dieselbe wie im vorigen Kapitel, was die bekannte Aufrufreihenfolge der BerechneKnoten Funktionen zur Folge hat (siehe obige Abbildung). Innerhalb
der
einzelnen
BerechneKnoten
Funktionen
kommt
dabei
der
neuen
Funktion
BerechneAwslink eine bedeutende Rolle zu. Solange die zu berechnenden Knoten keinen
Awslink enthalten erfolgt die Berechnung wie gehabt. Ist dies nicht der Fall, so wird wie
folgt
vorgegangen.
Innerhalb
der
Funktion
BerechneKnoten
wird
die
Funktion
BerechneAwslink aufgerufen. Wie eingangs erwähnt sucht diese Funktion zunächst den referenzierten Knoten. Ist der Bezug zu diesem Knoten hergestellt kann allerdings, wie im obigen
Beispiel der Fall eintreten, dass dieser Knoten zwar innerhalb der AWS existiert, er jedoch
noch nicht berechnet ist. Sollte dies der Fall sein, so wird der Knoten einfach an dieser Stelle
berechnet, jedoch ohne evtl. vorhandene Kindknoten zu berechnen (angedeutet durch „false“).
BerechneAwslink(Knoten, awslink)
{
Zielknoten = … // suche Zielknoten in AWS
BerechneKnoten(Zielknoten, false)
}
Anhand des Beispiels von Knoten T1 wird die Reihenfolge der Aufrufe deutlich.
BerechneKnoten(A, true)
BerechneKnoten(T1, true)
BerechneAwslink(T1, „P.B.T3“)
BerechneKnoten(T3, false)
BerechneKnoten(T2, true)
BerechneKnoten(B, true)
BerechneKnoten(T3, true)
BerechneKnoten(T4, true)
Der erneute Aufruf zur Berechnung des Knotens T3 im rechten Teilbaum würde in diesem
Fall nicht zu einer erneuten Berechnung von T3 führen, da dieser Knoten bereits innerhalb der
Funktion zur Berechnung des Awslink berechnet wurde. Nur evtl. vorhandene Kindknoten
von T3 müssen ggf. an dieser Stelle noch berechnet werden. Durch diese vorzeitige
Berechnung von Knoten, die gemäß der Aufrufreihenfolge erst später hätten berechnet
werden sollen, können alle Awslink innerhalb der AWS aufgelöst und somit alle Knoten
Berechnung des AWS-State
38
innerhalb der AWS berechnet werden. Obwohl sich mit dieser Vorgehensweise zu allen
bislang beschriebenen Arten von AWS ein AWS-State berechnen lässt, kann es bei der
Berechnung des AWS-State durch die Verwendung von Bezügen zu Situationen kommen, in
denen weitere Betrachtungen notwendig sind. Auf diese Situationen wird im Folgenden kurz
eingegangen. Eine detailliere Betrachtung erfolgt innerhalb des Kapitels 7.2 „Berechnung
AWS-State im Detail“.
Das erste und offensichtlichste Problemfeld stellt die Gefahr von Zyklen innerhalb der AWS
dar. Einfachstes Beispiel für einen Zyklus innerhalb einer AWS ist der Selbstbezug eines
Knoten.
Knoten1
awslink
In einem solchen Fall, in dem ein Knoten innerhalb der AWS über einen Awslink einen
Bezug zu sich selbst herstellt, ist die Berechnung eines AWS-State nicht mehr möglich. Ein
Zyklus kann auch indirekt über mehrere Knoten entstehen. Sobald eine AWS einen Zyklus
enthält ist sie ungültig. Es muss also bestenfalls schon zum Zeitpunkt der Erstellung der
AWS, zum Beispiel in einem AWS-Editor, sichergestellt sein, dass eine AWS keine Zyklen
enthält. Enthält eine AWS trotzdem einen Zyklus, würde die Berechnung des AWS-State in
eine Endlosschleife laufen. Es ist also ratsam, eine Zykluserkennung in die Berechnung des
AWS-State zu integrieren. Wird während der Berechnung des AWS-State ein Zyklus erkannt,
so muss die Berechnung abgebrochen werden. Die AWS ist ungültig. Dies ist die einzige
Stelle, an der die Berechnung eines AWS-State abgebrochen werden muss. Alle anderen
Berechnungen führen stets zu einem gültigen, wenn auch möglicherweise leerem, AWS-State.
Knoten1
Knoten2
awslink
Knoten3
awslink
awslink
Ein weiteres Problem stellen Zugriffe auf ungültige Knoten innerhalb der AWS dar. Ist ein
Knoten in einem vorriegen Berechnungsschritt als ungültig gekennzeichnet worden, weil
während der Berechnung ein Fehler aufgetreten ist, so wird dieser ungültige Knoten nicht in
den AWS-State übernommen. Ein Awslink auf einen solchen Knoten führ somit zwangsweise
dazu, dass auch der bezugnehmende Knoten ungültig wird. Möglich ist allerdings auch, dass
ein referenzierter Knoten erst zu einem späteren Zeitpunkt der Berechnung des AWS-State
Berechnung des AWS-State
39
ungültig wird, der Bezug aber auf den, zu dem Zeitpunkt noch gültigen Knoten erfolgte. Der
untere Ausschnitt einer AWS verdeutlicht diesen Zusammenhang. Die Funktion zur
Berechnung des Knotens T1 erfordert die vorzeitige Berechnung des Knotens T2. Treten
keine Fehler auf, so sind T1 und T2 berechnet und gültige Knoten, die in den AWS-State
übernommen werden. Kommt es in der nun folgenden Berechnung des Knotens F sowie
seiner Kindknoten zu einem Fehler, so kann dadurch möglicherweise auch der schon
berechnete Knoten T2 ungültig werden. Dies alleine würde lediglich dazu führen, dass der
Knoten T2 nicht im AWS-State vorhanden ist. Dadurch, dass der Knoten T1 aber von der
Existenz des Knotens T2 abhängig ist, würde dieser Knoten ebenfalls ungültig und aus dem
AWS-State ausgeblendet. Sowohl die Aufzeichnung von Abhängigkeiten zwischen Knoten,
als auch das Deaktivieren von Knoten, sowie von abhängigen Knoten, im Fehlerfall, muss
gewährleistet sein. Details hierzu können ebenfalls innerhalb des Kapitels 7.2 „Berechnung
AWS-State im Detail“ nachgelesen werden.
.
Page A
Text T1
Field F
Text T2
… möglicher Fehler …
awslink
7.1.4 AWS mit WOLM-Bezügen
Alle bislang beschriebenen AWS haben zu keinem Zeitpunkt einen Bezug auf konkrete Daten
des WOLM genommen. Sämtliche Informationen lagen statisch in der AWS vor und Bezüge
beschränkten sich auf Knoten innerhalb der AWS. Interessant wir die Verwendung der AWS
jedoch erst, wenn auch auf konkrete Daten des WOLM, zugegriffen werden kann. Um eine
solche Verbindung herzustellen gibt es in der AWS drei Typen von Knoten: Object, Objectlist
und Listofobjectlists. Eine detaillierte Betrachtung der Berechnung selbiger Knoten soll an
dieser Stelle nicht erfolgen. Das Hauptaugenmerk liegt hier auf der Betrachtung des
Wolmpath-Ausdrucks.
Berechnung des AWS-State
40
AWS
Project P = A
Object obj = Person
Page A
Text T1 = P.obj.name
AWS-State
Project #1 = #2
Page #2
Text #3 = "Franz"
In der obigen vereinfachten Notation der AWS unterscheidet sich der Wolmpath-Ausdruck
(„P.obj.name“) nicht von einem Awslink. Auf einen Wolmpath muss hier aus dem
Zusammenhang geschlossen werden. In der XML-Definition der AWS erfolgt eine explizite
Auszeichnung. Die Vorgehensweise zur Berechnung eines Wolmpath ähnelt jedoch sehr stark
der Vorgehensweise zur Berechnung eines Awslink. Bei einem Awslink besteht der Pfad aus
einer Reihe von Knoten innerhalb der AWS. Bei einem Wolmpath hingegen muss der Pfad in
zwei Teile unterteilt werden. Der erste Teil besteht aus AWS-Knoten und endet mit einem
Knoten vom Typ object, objectlist oder listofobjectlists. Im obigen Beispiel ist dies der Teil
„P.obj“. Der darauf folgende Pfad bezieht sich nicht mehr auf die AWS, sondern auf ein
Objekt des WOLM.
BerechneWolmpathWert(Knoten, wolmpath)
{
Zielknoten = … // suche Zielknoten in AWS
BerechneKnoten(Zielknoten, false)
Wert = … // bestimme Wert aus WOLM-Objekt
return Wert
}
Es wird zunächst wieder ausgehend vom aktuellen Knoten (hier: T1) mit Hilfe der Pfadangabe innerhalb des Wolmpath der Zielknoten des WOLM-Bezugs bestimmt. In obiger
AWS ist dies der Knoten mit der Bezeichnung obj, bei dem es sich um einen Knoten vom Typ
Object handelt. Ist dieser Knoten berechnet, so erhält er als Wert eine Referenz auf ein Objekt
des WOLM. Auf dieses referenzierte Objekt wird dann der zweite Teil des Wolmpath
Ausdrucks angewandt, wodurch letztlich der Wert des Wolmpath-Ausdrucks bestimmt wird.
Auf den ersten Blick wirkt die Berechnung eines Wolmpath im Vergleich zu der eines
Awslink sehr viel einfacher. Da für die Berechnung eines Wolmpath jedoch auch immer die
Berechnung eines Knoten vom Typ object, objectlist oder listofobjectlists erforderlich ist,
können die gleichen Probleme wie bei der Berechnung eines Awslink (Rekursion,
Abhängigkeiten) auftreten.
Berechnung des AWS-State
41
Object obj
objectselection
awslink:
“P.OL“
constraint
awslink:
“X.A“
wolmpath:
“P.O.name“
Dies liegt am internen Aufbau der Objektknoten, welche zur Selektion ihrer referenzierten
WOLM-Objekte bzw. WOLM-Objektmengen wiederum Awslink und oder Wolmpath
Ausdrücke verwenden können, um Bezüge zu anderen Knoten der AWS herzustellen bzw.
konkrete Werte des WOLM abzufragen.
7.1.5 AWS mit Listenknoten
Alle bislang betrachteten AWS enthielten stets eine konstante feste Anzahl an Knoten.
Awslink- und Wolmpath-Ausdrücke konnten Bezüge herstellen und somit über Pfade
innerhalb der AWS andere Knoten erreichen. Wird die Betrachtung um Knoten der Typen
Pagelist und Fieldlist erweitert, so gibt es bei der Berechnung des AWS-State weitere Punkte
zu beachten. Die einem Listenknoten zugeordnete Objektliste bestimmt, durch die Anzahl
ihrer Elemente, die Anzahl der Page- bzw. Field-Knoten in der AWS. In der AWS selbst sind
als Knoten jedoch lediglich Knoten vom Typ Pagelist bzw. Fieldlist existent.
Project P = P.A[1]
Objectlist OL = Person
Pagelist A = OL
Text T1 = object.name
Die einzelnen Page-Knoten, die beispielsweise aus der obigen Definition einer Pagelist hervorgehen, sind nicht als Knoten in der AWS vorhanden. Es ist somit nicht möglich eine
Referenz auf einen solchen Knoten zu erhalten. Ebenso sind die unterhalb des PagelistKnoten angehängten Knoten, die auf jeder neu erzeugten Page vorhanden sind, nicht in der
AWS existent. Die zu Beginn eingeführte Funktion BerechneKnoten verlangt als Parameter
jedoch eine Referenz auf einen Knoten der AWS. Eine separate Berechnung der einzelnen
Page-Knoten einer Pagelist ist somit nicht möglich. Im obigen Beispiel könnte dieses Problem
Berechnung des AWS-State
42
dadurch umgangen werden, dass der Funktion BerechneKnoten eine Referenz auf den
Pagelist-Knoten übergeben würde. Die Behandlung der Berechnung eines Knotens vom Typ
Pagelist müsste dann in einem Schritt erfolgen. In einer Schleife würde für jedes Objekt der
zum Pagelist-Knoten gehörigen Objektliste ein neuer Page-Knoten für den AWS-State
angelegt. Zusätzlich würden für jede Page der Reihe nach alle Unterknoten berechnet. Der
berechnete AWS-State könnte somit wie folgt aussehen.
Project #1 = #2
Page #2
Text #3 = „Name Person 1“
Page #4
Text #5 = “Name Person 2“
Dieses Vorgehen wird jedoch unmöglich, wenn die AWS zusätzlich einen Knoten enthält der
über einen Awslink einen Bezug zu einem Knoten innerhalb einer Pagelist/Fieldlist herstellt,
bzw. wenn innerhalb eines Listenknotens Bezüge zu Knoten außerhalb der eigenen Liste
hergestellt werden. Ersteren Fall verdeutlicht folgende AWS.
Project P
Objectlist OL
Text T1
awslink
Pagelist A
Text T2
?
P.A[2].T2
Der Knoten T1 möchte einen Bezug zu Knoten T2 auf der zweiten Page einer Pagelist mit
dem Namen A herstellen („P.A[2].T2“). Dieser Knoten existiert aber zu diesem Zeitpunkt
noch nicht in der AWS, da die entsprechende Pagelist noch nicht berechnet wurde. Ein
Vorziehen der kompletten Berechnung der Pagelist, wie zuvor beschrieben, wäre in diesem
Fall möglich, führt jedoch bei komplexeren AWS wieder zu den gleichen Problemen, wie sie
bereits im Kapitel zur Berechnung von AWS-Bezügen erläutert wurden. Dadurch, dass die
Knoten innerhalb der Pagelist wieder Bezüge zu anderen Knoten und auch zu Knoten in
anderen Listen enthalten können, ist das Vorziehen einer vollständigen Berechnung einer
Liste in vielen AWS unmöglich. Um dieses Problem zu lösen, wird eine Pagelist bzw.
Fieldlist zunächst „berechnet“ ohne jedoch die in ihr enthaltenen Knoten zu berechnen. In der
Berechnung des AWS-State
43
obenstehenden AWS würde ein Aufruf der Funktion BerechneKnoten(A, false)
zunächst die zu dieser Pagelist gehörige Objektliste bestimmen. Danach wird für jedes Objekt
der Objektliste ein neuer Page-Knoten in der AWS erzeugt. Jeder Page-Knoten erhält als
Kindknoten die jeweiligen Kindknoten der zugehörigen Pagelist. Diese Knoten werden
einfach unter die jeweiligen Page-Knoten angehängt, aber zu diesem Zeitpunkt noch nicht
berechnet.
Project P
Objectlist OL
Text T1
awslink
Pagelist A
Page A[1]
Page A[2]
Text T2
Text T2
Text T2
P.A[2].T2
Diese Vorgehensweise hat den Vorteil, dass nun alle Knoten in der AWS existieren. Der
Awslink auf den Knoten T2 der zweiten Page A verweist somit auf einen in der AWS existenten Knoten und kann wie gehabt berechnet werden. Der Ablauf der Berechnung des TextKnotens T1 läuft somit wie folgt ab.
BerechneKnoten(T1, true)
BerechneAwslink(T1, „P.A[2].T2“)
BerechneKnoten(A, false)
BerechneKnoten(P.A[2].T2, false)
Bevor die Berechnung des Awslink abgeschlossen werden kann, wird zunächst die Pagelist A
berechnet, bzw. präziser gesagt in ihre Page-Knoten aufgelöst, was schließlich die Berechnung des referenzierten Knotens T2 ermöglicht.
Durch das Auflösen einer Pagelist, oder auch Fieldlist, in ihre einzelnen Elemente gehen
jedoch Informationen verloren, die unter Umständen zu einem späteren Zeitpunkt der
Berechnung des AWS-State wieder benötigt werden. Der Informationsverlust kommt dadurch
zu Stande, dass die in der Liste enthaltenen Knoten lediglich in die neu entstehenden Pagebzw. Field-Knoten kopiert werden, aber erst zu einem späteren Zeitpunkt berechnet werden.
Zu diesem späteren Zeitpunkt ist es nicht mehr ohne weiteres möglich auf die der ursprünglichen Liste zugrunde liegende Objektliste, sowie auf den jeweiligen Index innerhalb der Liste
zu schließen.
Berechnung des AWS-State
44
Project P = P.A[1]
Objectlist OL = Person
Pagelist A = OL
Text T1 = object[index+1].name // wolmpath
Der Text-Knoten T1 in obiger AWS bestimmt seinen Inhaltswert über einen WolmpathAusdruck. Die AWS mit der aufgelösten Pagelist enthält zwei neue Page-Knoten, die jeweils
den Inhalt der ursprünglichen Pagelist kopiert haben.
Project P = P.A[1]
Objectlist OL = Person
Page A[1]
Text T1 = object[index+1].name // wolmpath
Page A[2]
Text T1 = object[index+1].name // wolmpath
Den Text-Knoten T1 innerhalb der neuen Page-Knoten fehlt nun allerdings die Verbindung
zur Objektliste der ursprünglichen Pagelist. Ein Zugriff auf WOLM-Objekte innerhalb ihrer
Wolpmpath-Ausdrücke ist somit nicht mehr möglich. Zudem lassen sich Bezeichner wie
index (index gibt die Position in einer Liste an) nicht mehr bestimmen. Zur Lösung dieses
Problems werden alle Kindknoten eines Page- bzw. Field-Knoten zum Zeitpunkt der
Auflösung ihrer zugehörigen Liste mit drei zusätzlichen Attributen versehen. Diese Attribute
sind: oid, index und index2. oid stellt den Bezug zur Objektliste her, index und index2 geben
die Position in einer Objectlist bzw. Listofobjectlists an.
oid: 1
Obectlist
Pagelist A
B
Page A[1]
C
Page A[2]
…
B
C
B
C
oid: 1
oid: 1
oid: 1
oid: 1
index: 1
index: 1
index: 2
index: 2
Die so gekennzeichneten Knoten können somit zu einem späteren Zeitpunkt der Berechnung
des AWS-State direkt und ohne Probleme auf die entsprechenden Listenobjekte zugreifen,
sowie ihre Position in der ursprünglichen Pagelist bestimmen, und somit berechnet werden.
Berechnung des AWS-State
45
Project P = P.A[1]
Objectlist OL = Person
// oid = 1
Page A[1]
Text T1 = object[index+1].name // oid = 1, index = 1
Page A[2]
Text T1 = object[index+1].name // oid = 1, index = 2
Angewandt auf die konkrete AWS, weiß nun der Text-Knoten T1 in der Page A[1], dass er
auf das zweite Element der Objectlist OL zugreifen soll (index+1). Mit dieser zusätzlichen
Attributierung von AWS-Knoten, die ursprünglich in einer Pagelist bzw. Fieldlist enthalten
waren, ist nunmehr kein Unterschied zu Knoten zu erkennen, die bereits zum Zeitpunkt der
Definition der AWS als konkrete Knoten in der AWS existierten. Somit lassen sich auch die
in den bisherigen Kapiteln beschriebenen Berechnungskonzepte weiterhin anwenden.
7.2 Berechnung AWS-State im Detail
Nach der Betrachtung der grundlegenden Konzepte und Vorgehensweise bei der Berechnung
eines AWS-State im vorangegangenen Kapitel, werden diese im Folgenden vertieft. Der
Schwerpunkt liegt dabei auf der Betrachtung der unterschiedlichen Arten von AWS- und
WOLM-Bezügen sowie deren Behandlung. Die Berechnung von Bezügen nimmt einen
wesentlichen Teil der Berechnung eines AWS-State ein.
7.2.1 Fehlende Informationen bei der AWS-State Berechnung
Es gibt verschiedene Situationen in denen ein WOLM-State nicht alle von einer AWS geforderten Informationen enthält. So können beispielsweise Bezüge auf undefinierte WOLMObjekte, Bezüge auf undefinierte Attribute eines WOLM-Objekts oder ungültige Pfade
innerhalb eines Bezugs, zu einem AWS-Bezugsfehler führen. Auch wenn sie als Bezugsfehler
bezeichnet werden, so verursachen solche Situationen bei der Berechnung des AWS-State
keine Fehlermeldungen. Knoten, die auf fehlende Informationen zugreifen und somit einen
AWS-Bezugsfehler verursachen, werden allerdings nicht in den AWS-State übernommen.
Der folgende Ausschnitt einer AWS enthält einen Knoten vom Typ Link, der auf die siebte
Seite einer Pagelist verweist. Für den Fall, dass die zur Pagelist gehörige Objectlist keine oder
weniger als sieben Elemente aufweist, wäre die siebte Seite der Pagelist nicht vorhanden. Der
Link L wäre undefiniert.
Text T = „Person 7“
Link L = PL[7]
Berechnung des AWS-State
46
Auch wenn der Text-Knoten T korrekt definiert ist, wäre es in einem solchen Fall von Vorteil,
wenn der Text-Knoten trotzdem nicht in den AWS-State übernommen würde. Da der Link
undefiniert ist, gibt es für den Text in der späteren Website keine sinnvolle Verwendung
mehr. Bei einem auftretenden Bezugsfehler erscheint es somit sinnvoll, Knoten, die in einem
gewissen Bereich um den bezugsfehlerverursachenden Knoten liegen, ebenfalls nicht in den
AWS-State zu übernehmen. Als Grundregel sei definiert, dass ein Knoten, der einen
Bezugsfehler auslöst, zur kompletten Ausblendung der „kleinsten Gruppe“ (Umgebung) in
der er liegt führt. Als „kleinste Gruppe“ oder Umgebung wird die engste Schachtelung durch
eine Field-/Fieldlist-Definition definiert. Existiert eine solche Definition nicht wird die engste
Page-/Pagelist-Definition verwendet. Liegt der auslösende Knoten direkt unterhalb des
Project-Knoten, so ist das gesamte Project undefiniert. Das Resultat ist ein leerer AWS-State
und somit eine leere Website. Mit dem Einsatz von Gruppen in der AWS können die
Auswirkungen auftretender Fehler, aufgrund fehlender Informationen, gesteuert werden.
Page A
Object O = Person
Text = O.Wohnort
// weitere Knoten
...
Der Text-Knoten im obigen Beispiel könnte aufgrund eines nicht definierten WOLM-Objekts
(O), oder eines nicht definierten Attributs (Wohnort), einen AWS-Bezugsfehler auslösen. Als
Folge würde die komplette Page A ausgeblendet werden, da es sich bei ihr in diesem Fall,
bezogen auf den Text-Knoten, um die „kleinste Gruppe“ handelt. Durch den Einsatz eines
Page A
Field F
Object O = Person
Text = O.Wohnort
// weitere Knoten
...
Field-Knoten, lässt sich der betroffene Bereich verkleinern. In diesem Fall würden nur noch
Knoten, die sich innerhalb des Field-Knoten befinden ausgeblendet. Die Page A wäre damit
im schlimmsten Fall leer, aber immer noch definiert und im AWS-State vorhanden. Eine
Ausnahme bilden die Listenknoten Pagelist und Fieldlist.
Project P
Objectlist ST = Studenten
Pagelist PL = ST
Text = object.Vorname
Text = object[index+1].Vorname
Berechnung des AWS-State
47
Verursacht ein Knoten, der sich innerhalb einer Liste befindet, einen Bezugsfehler, so wird
nicht die komplette Liste, sondern nur das jeweils betroffene Element der Liste ausgeblendet.
Die restlichen Elemente der Liste existieren weiterhin. Obiges Beispiel macht dies deutlich.
Jede Seite der Pagelist enthält zwei Text-Knoten die ihre Inhaltswerte zum einen aus dem
aktuellen und zum anderen aus dem darauf folgenden Objekt der Pagelist bestimmen. Für die
letzte Seite der Pagelist ist der Ausdruck index+1 größer als die Anzahl der Elemente der
Pagelist, welche der Anzahl der zur Pagelist gehörigen Objectlist entspricht. Der letzte TextKnoten der Pagelist ist damit undefiniert. Als Folge wird die komplette letzte Seite nicht in
den AWS-State übernommen. Alle übrigen Seiten der Pagelist werden übernommen. Das
Ausblenden einer einzelnen Komponente der AWS kann in einer Kettenreaktion das Ausblenden weiterer Komponenten der AWS auslösen. Im schlimmsten Fall kann ein Bezugsfehler das komplette Project ungültig machen. Ein Beispiel für eine solche Kettenreaktion
stellt eine verkette Pagelist dar. Jede Seite der Pagelist ist jeweils mit der vorherigen und
nächsten Seite der Pagelist über einen Link verknüpft.
Project P
Objectlist ST = Studenten
Pagelist PL = ST
Text = object.Vorname
Text = “vorheriger Student”
Link = PL[index-1]
Text = “nächster Student”
Link = PL[index+1]
Auf der ersten Seite ist ein Link auf die vorherige Seite (Seite 0) nicht möglich, da diese Seite
nicht existiert. Auf der letzten Seite ist ein Link auf die nächste Seite (n+1) nicht möglich, da
diese Seite ebenfalls nicht existiert. Als Folge werden die erste und letzte Seite der Pagelist
nicht in den AWS-State übernommen. Dies wiederum verursacht Bezugsfehler auf der
ursprünglich zweiten und vorletzten Seite der Pagelist, da deren Vorgänger bzw. Nachfolger
nicht mehr definiert sind. Das Ergebnis ist die Ausblendung sämtlicher Seiten der Pagelist.
Verhindern lässt sich dies im vorliegenden Beispiel durch eine Einbettung der Link-Knoten in
Field-Knoten.
Berechnung des AWS-State
48
Project P
Objectlist ST = Studenten
Pagelist PL = ST
Text = object.Vorname
Field
Text = “vorheriger Student”
Link = PL[index-1]
Field
Text = “nächster Student”
Link = PL[index+1]
Mit einer solchen Definition der AWS resultieren aus Bezugsfehlern, in Folge von Verweisen
auf nicht existente Seiten einer Pagelist, lediglich die Ausblendungen der betroffenen FieldKnoten mit deren enthaltenen Knoten. Im Beispiel würde jeweils ein Link der ersten sowie
letzten Seite der Pagelist ausgeblendet. Alle Seiten der Pagelist würden in den AWS-State
übernommen werden.
7.2.2 Zustandsabhängige Modifikation der AWS
Eine weitere Möglichkeit Teile der AWS auszublenden, dass heißt nicht in den AWS-State zu
übernehmen, besteht in der Definition von Gruppen in Abhängigkeit von WOLM-Objekt
Zuständen. Dazu wird einem Field-Knoten ein ihm bekanntes WOLM-Objekt zugeordnet. In
Kombination mit Abfragen (vgl. Kap. 7.2.11 „BerechneObjectselection“) an dieses WOLMObjekt wird über den Status des Field-Knoten im AWS-State entschieden.
Object obj = Person [ id = 5 ]
Field F ? obj [ alter >= 18 ]
Text = “...”
Ist die obige Bedingung nicht erfüllt, hat das Attribut alter, des durch obj referenzierten
WOLM-Objekts, also nicht einen Attributwert >=18, so wird der Field-Knoten nicht in den
AWS-State übernommen. Eine Abfrage darf sich jeweils nur an ein einziges WOLM-Objekt
richten.
7.2.3 Aufbau Awslink, Wolmpath, Wolmclass
Knoten der Typen Awslink, Wolmpath, Wolmclass zählen nicht zu den AWS-Knotentypen.
Eine Reihe der AWS-Knotentypen verwendet jedoch Knoten dieser Typen, als Bestandteil der
eigenen Definition, um Bezüge zu anderen Knoten der AWS herzustellen oder auf konkrete
Daten des WOLM zuzugreifen. Ein Awslink-Knoten enthält als einzige Information einen
Pfad-Ausdruck in Form eines Strings. Ein solcher Pfad besteht aus einer Reihe benannter
AWS-Knoten, die jeweils durch einen Punkt voneinander getrennt sind. Ausgehend von dem
Berechnung des AWS-State
49
AWS-Knoten, der einen solchen Awslink-Knoten enthält, wird der Pfad gemäß der AWSZugriffsregeln abgearbeitet, bis der Zielknoten erreicht ist. Die folgenden Beispiele zeigen
den prinzipiellen Aufbau solcher Pfade.
// Bezug auf Text-Knoten
Proj.PageX.Text2
// Bezug auf Image in Field-Knoten
Proj.PageX.Field3.Image
// Bezug auf erste Seite einer Pagelist
PL[first]
// Bezug auf Text-Knoten, PL = Pagelist, FL = Fieldlist
Proj.PL[3].FL[2].Text4
// Bezüge auf Objektknoten vom Typ Objectlist und Object
Proj.ObjList
Proj.Obj
Ziel eines solchen Pfads ist stets ein in der AWS existenter Knoten.
Knoten des Typs Wolmpath enthalten ebenfalls einen Pfadausdruck. Der Aufbau des Pfads
kann dabei zunächst dem eines Awslink-Ausdrucks entsprechen. Es wird somit zunächst ein
Pfad aus in der AWS befindlichen Knoten verfolgt. Jedoch nur solange bis ein Objektknoten
erreicht ist.
// Obj = Object-Knoten
Proj.PageB.Obj.Vorname
Der weitere Teil des Pfads bezieht sich dann nicht mehr auf Knoten der AWS, sondern auf
das durch den Objektknoten referenzierte WOLM-Objekt. Im obigen Beispiel wird das
Attribut Vorname des referenzierten WOLM-Objekts angesprochen. Ein Wolmpath liefert
immer einen atomaren Wert vom Typ int, string oder boolean. Der Pfad hinter dem Objektknoten kann auch aus mehr als einem Teil bestehen.
// Obj = Object-Knoten
Proj.PageB.Obj.Adr.Strasse
In einem solchen Fall handelt es sich bei dem durch den Object-Knoten referenziertem
WOLM-Objekt um ein Objekt welches ein Attribut besitzt, das als Wert eine Referenz auf ein
weiteres WOLM-Objekt speichert. Folgende WOLM-Klassen Konstruktion wäre in einem
solchen Fall denkbar.
Berechnung des AWS-State
class Person
{
Adresse Adr
Freund* Freunde
}
50
class Adresse
{
String Strasse
...
}
Komplexere Pfadangaben sind ebenso möglich.
// PL = Pagelist, FL = Fieldlist
Proj.PL[3].FL[2].Obj.Vorname
Auch der dritte Knotentyp, Wolmclass, enthält einen Pfadausdruck. Die erste Möglichkeit für
einen solchen Ausdruck unterscheidet sich grundlegend von denen des Awslink bzw.
Wolmpath.
// Klassenname
Person
Der Ausdruck besteht in einem solchen Fall lediglich aus der Angabe eines Klassennamens
einer im WOLM enthaltenen Klasse. Mit der Angabe im obigen Beispiel werden daraufhin
alle aktuellen im WOLM vorhandenen Objektinstanzen dieses Klassentyps selektiert. Ein
Wolmclass-Ausdruck liefert somit eine Liste von Referenzen auf WOLM-Objekte. Diese
Liste kann leer sein oder beliebig viele Elemente enthalten. Alternativ lässt sich der Pfad
innerhalb eines Wolmclass-Ausdrucks in einer zum Wolmpath ähnlichen Form angeben.
// Obj_Person = Object-Knoten, Referenz auf ein WOLM-Objekt
PageX.Obj_Person.Adr
Obj_Person.Freunde
Es wird zunächst identisch zum Wolmpath ein Bezug zu einem Objektknoten innerhalb der
AWS hergestellt (Knoten Obj_Person). Der Unterschied zum Wolmpath besteht in dem auf
diesen Objektknoten folgenden Teil der Pfadangabe. Es wird nicht, wie beim Wolmpath, ein
Attribut des WOLM-Objekts vom Typ int, string oder boolean angesprochen, sondern ein
Attribut, das als Wert eine Referenz auf ein WOLM-Objekt bzw. eine Menge von Referenzen
auf WOLM-Objekte enthält. Ein Wolmclass-Ausdruck selektiert somit eine Menge von
Referenzen auf WOLM-Objekte.
7.2.4 Bezüge
In den bisherigen Kapiteln wurde bereits auf AWS- sowie WOLM-Bezüge eingegangen. Die
Funktionen BerechneAwslink und BerechneWolmpath zur Behandlung der jeweiligen Bezüge
Berechnung des AWS-State
51
wurden eingeführt. Das vorliegende Kapitel, sowie einige weitere, gehen im Folgenden
detaillierter auf die beiden Funktionen, ihren Zusammenhang mit der BerechneKnoten
Funktion sowie auf die Besonderheiten und Probleme, die bei der Berechnung auftreten
können, ein. In unten stehender Abbildung ist ersichtlich, dass die Funktionen
BerechneAwslink sowie BerechneWolmpath innerhalb der BerechneKnoten Funktion
aufgerufen werden können und selbst erneut die Funktion BerechneKnoten aufrufen können.
Beliebig tiefe Verschachtelungen sind denkbar. Auf Grund dieser Verschachtelungen kommt
es zum einen zu Abhängigkeiten in der Berechung zwischen verschiedenen Knoten der AWS.
BerechneKnoten
BerechneAwslink
BerechneKnoten
…
BerechneWolmpath
…
…
Abhängigkeiten
Rekursions-
zwichen Knoten
gefahr
Die Aufzeichnung dieser Abhängigkeiten sowie die korrekte Behandlung der Abhängigkeiten
in unterschiedlichen Situationen der Berechnung des AWS-State werden im Folgenden
erläutert. Neben den zwangsweise entstehende Abhängigkeiten, bei ausreichen komplexen
AWS, kann es zum anderen zu einer Rekursion in der Berechnung kommen, die ebenfalls
erkannt und behandelt werden muss. Im folgenden Beispiel einer AWS soll der Text-Knoten
t1 berechnet werden.
Project P = A
Page A
Text t1 = P.B.t2
Page B
Object obj = Person
Text t2 = obj.name
// awslink
// wolmpath
Die Aufrufreihenfolge der einzelnen beteiligten Funktionen kann untenstehendem PseudoCode entnommen werden. In Zeile 3 erfolgt der Aufruf zur Berechnung des im Text-Knoten
enthaltenen Awslink. Als Ergebnis erhält die Funktion BerechneAwslink eine Referenz auf
einen berechneten Knoten, den Knoten, auf den Bezug genommen wurde. Gespeichert wird
Berechnung des AWS-State
52
diese Referenz in der Variablen k. In Zeile 20 erfolgt über die so erhaltene Referenz ein
Zugriff auf den Wert des Text-Knotens t2. Der Wert wird im Knoten t1 gespeichert. Der TextKnoten t1 ist berechnet. Die Zeilen 4-19 sind für das Auffinden des Text-Knotens t2, sowie
zur Berechnung weiterer abhängiger Knoten zuständig.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
BerechneKnoten(t1)
{
k = BerechneAwslink(t1, „P.B.t2“)
{
t2 = BerechneBezug(„P.B.t2“)
k = BerechneKnoten(t2)
{
s = BerechneWolmpath(t2, „obj.name“)
{
obj = BerechneBezug(“obj.name”)
k = BerechneKnoten(obj) { }
... // Abhängigkeit P#B#t2 Å P#B#obj
return k.getAttributWert(„name“)
}
t2.value = s
}
... // Abhängigkeit P#A#t1 Å P#B#t2
return k
}
t1.value = k.value
}
7.2.5 Abhängigkeiten
Durch die zuvor beschriebene Berechnung des Text-Knoten t1, sowie durch die Verwendung
von AWS- und WOLM-Bezügen, entstehen Abhängigkeiten zwischen Knoten der AWS. Die
Berechnung des Knoten t1 erfordert beispielsweise die vorherige Berechnung des Knotens t2.
Der Knoten t1 kann somit im späteren AWS-State nur existieren, wenn auch der Knoten t2
existiert. Eine Aussage über die Existenz des Knoten t2 lässt sich jedoch zum Zeitpunkt der
Berechnung des Knoten t1 noch nicht machen. Im Laufe der weiteren Berechnung des AWSState könnten Fehler bei der Berechnung von Knoten auftreten. Diese Fehler könnten sich auf
andere Knoten, beispielsweise t2, auswirken, da sie innerhalb der gleichen Gruppe liegen und
somit ebenfalls ungültig würden. Wäre in einem solchen Fall keine Information über
abhängige Knoten gespeichert, so wäre es dem Knoten t2 nicht mehr möglich eine
Verbindung zum Knoten t1 herzustellen. Eine solche Verbindung wäre jedoch erforderlich, da
der von t2 abhängige Knoten t1 nun ebenfalls ungültig wäre.
Berechnung des AWS-State
Project P = A
Page A
Text t1 = P.B.t2
Page B
Object obj = Person
Text t2 = obj.name
...
53
// awslink
// wolmpath
// weitere AWS-Knoten
Aus diesem Grund ist es erforderlich die Abhängigkeiten zwischen allen Knoten aufzuzeichnen. In der obigen AWS befinden sich zwei Abhängigkeiten. Wie schon erwähnt ist der
Knoten t1 von der Existenz des Knoten t2 abhängig. Des Weiteren ist der Knoten t2 von der
Existenz des Objektknotens obj abhängig. Würde der Objektknoten beispielsweise keine
gültige Referenz auf ein WOLM-Objekt liefern, so wäre auch der Zugriff „obj.name“
innerhalb des Knotens t2 ungültig. Knotentypen welche direkt mittels Awslink oder
Wolmpath einen Bezug zu einem anderen Knoten der AWS herstellen, verursachen somit
immer eine Abhängigkeit. Darüber hinaus gibt es weitere Knotentypen, welche Abhängigkeiten verursachen. Knoten vom Typ Pagelist und Fiedlist stellen über ihr Attribut
sourceobjectlist einen AWS-Bezug zu einem Objectlist-Knoten her. Somit ist jeder Pagelistbzw. Fieldlist-Knoten von der Existenz dieses Objectlist-Knotens abhängig.
Pagelist PL = olist // sourceobjectlist
Eine weitere Quelle für Knotentypen welche Abhängigkeiten verursachen, stellen Knotentypen dar, welche einen Knoten vom Typ objectselection enthalten können (Object,
Objectlist, Fiedlist, Field). Ein solcher objectselection-Knoten kann eine oder mehrere
Constraint-Knoten enthalten, welche wiederum einen Bezug zu einem anderen Knoten der
AWS herstellen können.
Object obj = Person [name = P.B.name]
So wird im obigen Object-Knoten beispielsweise die Menge der WOLM-Objekte auf ein
Objekt mit einem bestimmten Attributwert eingeschränkt. Der rechte Teil des Vergleichs
bezieht sich dabei auf einen Knoten (bsp. Text-Knoten) innerhalb der AWS. Somit verursacht
diese Objectselction und somit der ganze Object-Knoten eine Abhängigkeit.
Auf die zu Beginn dargestellte AWS, mit ihren zwei Abhängigkeiten übertragen, lassen sich
ihre Abhängigkeiten wie folgt darstellen.
Berechnung des AWS-State
54
P#A#t1 Å P#B#t2
Lies: Die Existenz des Knoten t1 ist abhängig von der Existenz des Knoten t2
P#B#t2 Å P#B#obj
Die zweite Abhängigkeit liest sich entsprechend. Bezeichnungen von abhängigen Knoten
werden mit der vollständigen Pfadangabe ausgehend vom Project-Knoten angegeben, um die
Knoten eindeutig identifizieren zu können. Unter Einbeziehung der unterschiedlichen
Gruppen innerhalb einer AWS, lassen sich die beiden Abhängigkeiten vereinfachen. Die
Abhängigkeit des Knoten t1 zum Knoten t2 lässt sich auf eine Abhängigkeit des Knotens t1
auf den Knoten B (Page B) reduzieren. Die kleinste Gruppe, die den Knoten t2 umgibt ist der
Knoten B. Wird ein Knoten dieser Gruppe (bsp. t2) ungültig, so wäre die ganze Gruppe und
somit auch der Knoten B ungültig. Die zweite Abhängigkeit muss nicht zwingend
aufgezeichnet werden, da die Knoten t2 und obj innerhalb der gleichen Gruppe liegen. Wird
der Knoten obj ungültig, so wird die ganze Gruppe (Page B) ungültig und somit auch der
abhängige Knoten t2. Es bleibt eine Abhängigkeit.
P#A#t1 Å P#B
Zusammengefasst lässt sich festhalten, dass ein Knoten der AWS, der einen Bezug zu einem
anderen Knoten der AWS herstellt, stets eine Abhängigkeit zwischen diesen beiden Knoten
erzeugt.
Gruppe
Abhängigkeit
K
X
Bezug
Die Abhängigkeit besteht dann zwischen dem Knoten, der den Bezug hergestellt hat, und der
kleinsten Gruppe in der sich der Zielknoten befindet.
Berechnung des AWS-State
55
7.2.6 Entfernen von Knoten, abhängigen Knoten
Tritt während der Berechnung eines Knotens ein Fehler auf, so wird dieser Knoten als
ungültig markiert. In der unten stehenden AWS weist beispielsweise der Knoten t3 einen
Bezugsfehler auf. Der Knoten ist daher ungültig und wird nicht in den AWS-State
übernommen. Darüber hinaus gibt es zwei weitere Punkte zu beachten. Alle Knoten, die sich
in der gleichen kleinsten Gruppe, wie der ungültig gewordene Knoten, befinden, müssen
ebenfalls als ungültig markiert werden.
Project P = A
Page A
Text t1 = P.B.t2
Page B
Object obj = Person
Text t2 = obj.name
Text t3 = P.X.z
// awslink
// wolmpath
// awslink, Bezugsfehler
In diesem Beispiel wären dies die Knoten t2, obj und B. Weiterhin ist bei jedem Knoten, der
als ungültig gekennzeichnet wird, zu beachten, dass evtl. abhängige Knoten ebenfalls als
ungültig markiert werden müssen. In obiger AWS existiert die Abhängigkeit P#A#t1 Å P#B.
Da der Knoten B bereits ungültig ist, muss auch der Knoten t1 als ungültig markiert werden.
Dies wiederum hat zur Folge, dass die kleinste Gruppe, in der sich der Knoten t1 befindet
(Page A) ebenfalls ungültig wird. Als Folge eines einzigen Bezugsfehlers (in t3) enthält das
Projekt keine einzige Page. Der AWS-State und die Website sind somit leer.
7.2.7 Rekursion
Die Möglichkeit der AWS-Knoten Bezüge zu anderen Knoten der AWS herzustellen birgt die
Gefahr von rekursiven Bezügen. So kann es bei der Berechnung eines AWS-Knotens zu
einem wiederholten Aufruf der BerechneKnoten Funktion auf demselben Knoten kommen,
was letzten Endes in einer Endlosschleife endet. Einfachstes Beispiel für eine solche Situation
ist der Selbstbezug eines Knoten.
Knoten1
Bezug
Ein Knoten stellt, beispielsweise über einen Awslink, einen Bezug zu sich selbst her. Ebenso
möglich ist das entstehen einer Rekursion über mehrere Knoten hinweg.
Berechnung des AWS-State
Knoten1
56
Knoten2
Bezug
Knoten3
Bezug
Bezug
Der Aufruf der BerechneKnoten Funktion für Knoten1 würde eine Berechnung von Knoten2
auslösen. Knoten2 erfordert wiederum die Berechnung von Knoten3 und dieser die
Berechnung von Knoten1. Um Zyklen dieser Art zu erkennen, muss beim ersten Aufruf der
BerechneKnoten Funktion (hier: bei Knoten1), beispielsweise in einer Liste, ein eindeutiger
Vermerk auf den aktuellen Knoten gespeichert werden. Ebenso wird für jeden weiteren
Aufruf der BerechneKnoten Funktion verfahren, bis entweder der Ausgangsknoten berechnet
ist, oder ein Knoten doppelt in der Vermerkliste auftaucht. Im obigen Beispiel wäre das vierte
Element einer solchen Liste (K1, K2, K3, K1) wieder ein Vermerk auf den Ausgangsknoten.
Für den Fall, dass während der Berechnung eines AWS-Knotens eine Rekursion entdeckt
wird, ist die AWS nicht mehr eindeutig definiert. Die Berechnung des AWS-State wird abgebrochen.
7.2.8 BerechneAwslink
Jeder in der AWS auftretende Awslink wird durch die Funktion BerechneAwslink()
behandelt. Die prinzipielle Vorgehensweise bei der Berechnung eines Awslink lässt sich wie
folgt beschreiben.
BerechneAwslink(k, awslink)
{
(1) starte bei Knoten k
(2) verfolge von dort den im awslink gegebenen Pfad in der
AWS bis der Zielknoten erreicht ist
(3) berechneKnoten(Zielknoten)
(4) berücksichtige Abhängigkeiten
(5) gib eine Referenz auf den berechneten Zielknoten zurück
}
Ein Awslink stellt immer, ausgehend von einem Knoten der AWS, einen Bezug zu einem
anderen Knoten der AWS her. Es lassen sich verschiedene Awslink-Arten unterscheiden. Bei
der ersten Art enthält der Pfad des jeweiligen Awslink keine Bezüge zu Knoten einer Pagelist
bzw. Fiedlist.
Berechnung des AWS-State
57
P.Page_A.Text2
P.Page_B.Link2
P.Object_A
P.Objectlist_B
Der oben beschriebene Schritt (2), die Verfolgung des Pfads ausgehend vom Startknoten, lässt
sich in diesen Fällen leicht verwirklichen. Die einzelnen Knoten des Pfades werden dabei
Schritt für Schritt gemäß der Zugriffsregeln der AWS abgearbeitet. Handelte es sich um einen
gültigen Pfad, so ist der Zielknoten nach Abarbeitung des Pfades erreicht. Die zweite Art von
Awslink-Ausdrücken enthält Bezüge auf Knoten einer Pagelist und oder einer oder mehrerer
Fieldlist.
P.PL[first].FL[5].Name
Der obige Awslink bezieht sich auf einen Knoten mit der Bezeichnung „Name“, der sich im
fünften Feld einer Fieldlist befindet, welches sich wiederum auf der ersten Seite einer Pagelist
befindet. Sind die jeweiligen Listen noch nicht berechnet, so müssen zunächst diese, ihre
zugehörigen Objektlisten, sowie evtl. weitere Knoten berechnet werden, bevor der Zielknoten
„Name“ erreicht und eine Referenz auf ihn zurückgegeben werden kann.
Da dieses Vorgehen bereits komplizierter ist und es diverse weitere Pfadkonstruktionen gibt,
empfiehlt es sich den oben mit (2) gekennzeichneten Schritt in einer eigenen Funktion zu
kapseln. Aufgabe dieser Funktion ist es ausgehend von einem Knoten der AWS, mit Hilfe
eines gültigen Pfades, einen anderen Knoten der AWS zu erreichen und eine Referenz
zurückzugeben. Hinzu kommt, das diese neue Funktion auch für Wolmpath-Pfade, welche in
der Funktion BerechneWolmpath verarbeitet werden, sowie für Berechnung weiterer Bezüge
in der AWS (z.Bsp: sourceobjectlist) verwendet werden kann. Die Vergleichweise schwierige
und vielfältige Behandlung von Pfadangaben innerhalb von Bezügen werden also zentral in
der Funktion BerechneBezug behandelt.
Zusammengefasst hat die Funktion BerechneAwslink somit folgenden Aufbau.
1
2
3
4
5
6
7
k = BerechneAwslink(t1, „P.A.B“)
{
r = BerechneBezug(t1, „P.A.B“)
k = BerechneKnoten(r) { ... }
... // Abhängigkeiten beachten
return k
}
Berechnung des AWS-State
58
Die Funktion bekommt einen Startknoten (t1) sowie einen Pfad („P.A.B“) übergeben. Anhand
dieser beiden Parameter wird eine Referenz auf den Zielknoten („B“) erzeugt. Der Zielknoten
wird berechnet. In Zeile 5 wird die Abhängigkeit zwischen Start- und Zielknoten
aufgezeichnet. Die Funktion BerechneAwslink liefert, im Erfolgsfall, immer eine Referenz
auf einen berechneten Knoten.
7.2.9 BerechneWolmpath
Da die Pfadangabe innerhalb eines Wolmpath-Ausdrucks in weiten Teilen denen eines
Awslink-Ausdrucks ähnelt, gestaltet sich auch die Berechnung ähnlich zu der eines Awslink.
BerechneWolmpath(k, wolmpath)
{
(1) starte bei Knoten k
(2) verfolge von dort den im awslink gegebenen Pfad in der
Aws bis der Zielknoten erreicht ist
(3) berechneKnoten(Zielknoten)
(4) bestimme Wolmpath-Wert anhand Objektreferenz und Pfad
(5) berücksichtige Abhängigkeiten
(6) gib Wolmpath-Wert zurück
}
Die Hauptarbeit findet, genau wie bei der Berechnung eines Awslink, in Schritt (2) statt. Die
Ermittlung des Zielknotens erfolgt dabei wieder mit Hilfe der Funktion BerechneBezug, wie
folgendes Beispiel zeigt.
Text t2 = P.A.B[2].Obj.name
// Obj = Object-Knoten
Die Berechnung des Knoten t2 erfolgt dabei wie folgt. Ein Aufruf der Funktion
BerechneBezug bearbeitet den Pfad des Wolmpath-Ausdrucks, und ermittelt eine Referenz
auf den im Pfad enthaltenen Objektknoten Obj, dem Zielknoten. Nach erfolgter Berechnung
des Zielknotens, wird in Zeile 6 das Attribut name, des durch den Objektknoten Obj, auf den
nun eine Referenz vorliegt (k), referenzierten WOLM-Objekts, abgefragt.
1
2
3
4
5
6
7
s = BerechneWolmpath(t2, „P.A.B[2].Obj.name“)
{
obj = BerechneBezug(t2, “P.A.B[2].Obj.name”)
k = BerechneKnoten(obj) { }
... // Abhängigkeiten beachten
return k.getAttributWert(„name“)
}
Berechnung des AWS-State
7.2.10
59
BerechneBezug
Die Funktion BerechneBezug ist eine der wichtigsten Funktionen bei der Berechnung des
AWS-State. Ihre Aufgabe ist die Ermittlung einer Referenz auf einen Knoten der AWS.
Dieser Knoten wird ausgehend von einem anderen Knoten der AWS, mittels eines Pfads,
gemäß der Zugriffsregeln der AWS erreicht. Verwendung findet die Funktion bei der
Berechnung von Knoten, die einen Bezug zu anderen Knoten der AWS herstellen. Diese
Bezüge können beispielsweise mittels eines Awslink oder Wolmpath, aber auch im Rahmen
eines sourceobjectlist-Attributs (Pagelist/Fieldlist), des indexof-Operators oder einer
Objectselection, hergestellt werden. Auf alle Möglichkeiten wird im Folgenden eingegangen.
Die einfachste Form von Bezügen stellen AWS-Bezüge zu anderen Knoten der AWS dar,
welche keine Pagelist oder Fieldlist Knoten enthalten. Ein Beispiel ist ein Awslink innerhalb
eines Text-Knotens, der einen Bezug zu einem Knoten der AWS mit der Bezeichnung A
herstellen möchte. Die Funktion BerechneBezug soll nun eine Referenz auf diesen Knoten A
liefern.
Text t1 = P.B.A
// awslink
In einem ersten Schritt werden dazu die einzelnen Bestandteile des Pfads (P.B.A) anhand des
Zeichens „.“ separiert. Darauf hin wird untersucht, ob der auf diese Weise erste erhaltene
Knoten (P), ausgehend vom bezugnehmenden Knoten (t1), gemäß der AWS Zugriffsregeln
erreicht werden kann. Ist dies der Fall, so wird in einem nächsten Schritt ausgehend vom
aktuellen Knoten versucht den nächsten Knoten zu erreichen. Dies geschieht solange bis alle
Knoten des Pfads abgearbeitet und der Zielknoten erreicht wurde. Ist der Zielknoten erreicht,
so gibt die Funktion BerechneBezug eine Referenz auf ihn zurück. Während des gesamten
Ablaufs werden keine Knoten berechnet. Es wird lediglich der Pfad in der AWS verfolgt und
eine Referenz auf einen Knoten zurückgegeben. Neben der Einhaltung der Zugriffsregeln der
AWS, sind zwei weitere Punkte zu beachten. Es ist möglich, dass ein Knoten innerhalb des
angegebenen Pfads nicht erreicht werden kann. Denkbar wären eine falsche Bezeichnung,
eine Verletzung der Zugriffsregeln oder ein Zugriff auf einen bereits ungültigen Knoten. In
allen Fällen kann der Zielknoten nicht erreicht werden. Es kommt zu einem Bezugsfehler, der
an die aufrufenden Funktionen weitergegeben wird.
Berechnung des AWS-State
Text t1 = P.B.O.A
60
// wolmpath, O = Object-Knoten
Der obige Pfad (P.B.O.A) unterscheidet sich zunächst nicht von dem vorangegangenen
Beispiel. Es handelt sich hierbei jedoch nicht um einen Awslink sondern einen Wolmpath.
Das Vorgehen zum Erreichen des Zielknotens ist identisch mit dem zuvor beschriebenen. Bei
einer Pfadangabe innerhalb eines Wolmpath-Ausdrucks handelt es sich bei dem letzten durch
einen Punkt getrennten Bezeichner (hier: A) jedoch nie um den eigentlichen Zielknoten. Bei
dem Zielknoten handelt es sich immer um einen Objektknoten. Einen Knoten vom Typ Object
oder Objectlist (hier: O). Der Teil des Pfads hinter dem Objekt-Knoten bezieht sich nicht
mehr auf die AWS, sondern auf das durch den Objekt-Knoten referenzierte WOLM-Objekt.
Dieser Teil kann aus mehr als einem Bezeichner bestehen. Für die Funktion BerechneBezug
endet die Verfolgung des Pfads somit sobald ein Objektknoten erreicht wurde. Eine Referenz
auf diesen Objektknoten wird zurückgegeben.
Befindet sich innerhalb der Pfadangabe ein Knoten vom Typ Field, welcher wiederum mittels
einer Objectselection seine Existenz im AWS-State von einem Zustand des WOLM abhängig
macht, so muss dieser Knoten gesondert behandelt werden.
Text T1 = A.F.T2
// F = Field-Knoten mit objectselection
Page A
Text T1
Field F
Text T2
awslink
Object Obj
objectselection
Field F ? Obj [x > 3]
Ist die Verfolgung des Pfads beim Knoten F angekommen, so muss dieser Knoten zunächst
berechnet werden. Der Objectselection-Ausdruck des Field-Knotens wird berechnet. Kommt
die Berechnung zu dem Ergebnis, dass der Field-Knoten im AWS-State existiert so kann die
Verfolgung des Pfads fortgesetzt werden. Würde der Knoten nicht existieren, so würden auch
alle weiteren Knoten unterhalb des Knotens nicht existieren. Eine weitere Verfolgung des
Pfads wäre somit überflüssig. Es läge auf jeden Fall ein Bezugsfehler vor. Eine Berechnung
des Field-Knotens ist nicht zwingend erforderlich. Würde der Field-Knoten nicht an dieser
Berechnung des AWS-State
61
Stelle berechnet und die Verfolgung des Pfads fortgesetzt, so würde die Funktion
BerechneBezug zunächst eine gültige Referenz auf den Zielknoten (hier: T2) bestimmen. Mit
Hilfe der aufgezeichneten Abhängigkeit zwischen Knoten T1 und T2 kann der Knoten
nachträglich als ungültig deklariert werden, falls der Knoten T2 aufgrund eines nicht
existenten Field-Knotens F aus dem AWS-State eliminiert würde. Beide Wege sind möglich.
Welcher Weg effizienter ist, hängt letzten Ende auch von der jeweiligen AWS ab.
Der untenstehende Text-Knoten verwendet wiederum einen Awslink um einen Bezug zu
einem Knoten (A) herzustellen. Im Unterschied zu den bisherigen Pfaden enthält dieser Pfad
indizierte Zugriffe. In diesem Fall wird auf die dritte Seite eines Pagelist-Knoten zugegriffen.
Für den Fall, dass die dritte Seite bereits in der AWS vorhanden ist, unterscheidet sich der
Zugriff nicht von dem Zugriff auf einen normalen Page-Knoten, da der Knoten, der die dritte
Seite der Pagelist repräsentiert den passenden Namen (PL[3]) besitzt. Im aktuellen Beispiel
wird einfach ausgehend vom Knoten P nach einem Knoten mit dem Namen „PL[3]“ gesucht.
Text t1 = P.PL[3].A
// awslink, PL = Pagelist
Sind die entsprechenden einzelnen Page-Knoten der zugehörigen Pagelist noch nicht in der
AWS vorhanden, so kann kein Knoten mit dem Namen „PL[3]“ an der passenden Stelle
gefunden werden. Ein Bezugsfehler würde ausgelöst.
P
Knoten PL[3]
nicht vorhanden
Knoten P
vorhanden
T1
PL
A
Damit dies verhindert werden kann, müssen indizierte Teile von Pfadangaben (Teile mit […])
weiter aufgeteilt werden, in einen Namen und einen Index (hier: PL und 3). In einem zweiten
Versuch kann dann, ausgehend von Knoten P nach einem Knoten mit dem Namen „PL“
gesucht werden, dem Knoten der Pagelist. Anhand der zur Pagelist gehörigen Objektliste
kann die Anzahl der Page-Knoten der Pagelist PL bestimmt werden. Ggf. muss der Objektlistenknoten hierzu zunächst berechnet werden. Für jedes Element der Objektliste wird ein
neuer Page-Knoten in die AWS eingefügt (vgl. auch Berechnung Pagelist). Die Page-Knoten
sowie die jeweiligen Unterknoten werden nur in die AWS eingefügt, jedoch nicht berechnet.
Berechnung des AWS-State
62
Ausgehend vom nun in der AWS vorhandenen Page-Knoten „PL[3]“ kann der Pfad
„P.PL[3].A“ weiterverfolgt und schließlich die gewünschte Referenz auf den Zielknoten A
P
T1
PL
Objectlist
A
PL[1]
PL[2]
PL[3]
A
A
A
awslink: P.PL[3].A
ermittelt werden. Für Knoten vom Typ Fieldlist gelten die gleichen Ausführungen wie die
obigen für Knoten vom Typ Pagelist, wobei Fieldlist-Knoten beliebig oft in einem Pfadausdruck, Pagelist-Knoten hingegen nur maximal einmal vorkommen können.
Text t1 = P.PL[3].FL[5].A
// awslink
Text t1 = P.PL[3].FL[5].Obj.Name
// wolmpath
Wie obiges Beispiel zeigt, können die Pfadangaben innerhalb von Awslink- und WolmpathAusdrücken wiederum sehr ähnlich sein. Die unterschiedliche Behandlung erfolgt beim
Wolmpath-Ausdruck beim Erreichen des Knoten Obj, der einen Objektknoten vom Typ
Object darstellt. Neben dem indizierten Zugriff auf Objekte eines Pagelist- bzw. FieldlistKnoten sind des Weiteren Zugriffe auf Knoten vom Typ Objectlist möglich. Dabei wird ein
einzelnes Element der in der Objektliste enthaltenen Elemente ausgewählt.
Text t1 = P.B.OL[3].A.B
// wolmpath, A.B Pfad im WOLM
Bei allen beschriebenen indizierten Zugriffen kann es zu Bezugsfehlern kommen, falls
versucht wird über einen ungültigen Index auf ein Element zuzugreifen. Dies ist z.Bsp. dann
der Fall, wenn der Index größer ist, als die Anzahl der in der Liste enthaltenen Elemente.
Werden in die Betrachtung Knoten vom Typ Listofobjectlists aufgenommen, so ergibt sich
eine weitere Art der Indizierung von Elementen einer Liste, die in Pfadangaben eines Bezugs
auftreten kann. Der durch das Vorhandensein einer Listofobjectlists notwendige zweite Index
wird durch ein Komma vom ersten Index getrennt dargestellt. Dies muss ggf. bei der oben
beschriebenen Aufteilung eines solchen Ausdrucks, in Namen und Index, berücksichtigt
Berechnung des AWS-State
63
werden. Auftreten können solche doppelten Indizes, bei einem Bezug auf einen Knoten vom
Typ Pagelist, welchem eine Objektliste vom Typ Listofobjectlists zugrunde liegt, oder bei
einem direkten Zugriff auf einen Knoten vom Typ Listofobjectlists (siehe folgendes Beispiel).
// awslink, PL= Pagelist mit Listofobjectlists
Text t1 = P.PL[3,1].FL[5].A
// wolmpath, LOOL = Listofobjectlists
Text t1 = P.B.LOOL[3,1].A.B
Neben der direkten Angabe von numerischen Indizes, können in einer Pfadangabe
verschiedene Schlüsselwörter auftreten. Diese lauten:
index
index2
first
last
//
//
//
//
aktuelle Position innerhalb Pagelist/Fieldlist
zweiter Index, bei Pagelist mit Listofobjectlists
erstes Element = 1
letztes Element einer Page-/Field-/Objectlist
// Position des Objekts O in der Objektliste OL
indexof O in OL
Diese Schlüsselwörter müssen gemäß ihrer Bedeutung ausgewertet werden. Ergebnis dieser
Auswertung ist stets ein numerischer Wert. Zusätzlich sind die Operationen „+“ und „-„ auf
Indizes erlaubt. Gültige Ausdrücke wären somit beispielsweise [index+1], [first+2], [5-3],
usw., welche wiederum zu numerischen Ausdrücken ausgewertet werden müssen. Eine gesonderte Betrachtung bedarf das Schlüsselwort indexof. Am häufigsten Verwendung finden
sicherlich Ausdrücke der ersten Form (1). Hierbei ermittelt indexof die Position des aktuellen
Objekts (object) eines Listenknotens (Pagelist/Fieldlist) innerhalb einer Objectlist (Objlist).
Ein Zugriff auf die beteiligten Knoten ist in einem solchen Fall vergleichsweise einfach
möglich. Die Position lässt sich bestimmen, der Ausdruck indexof kann somit einen
numerischen Wert bestimmen.
(1) [indexof object in Objlist]
(2) [indexof P.A.Obj in P.B.Objlist]
(3) [indexof P.A.Objlist[3] in P.B.Objlist]
Möglich sind aber auch, zumindest theoretisch, Ausdrücke der Formen (2) und (3). Hierbei
handelt es sich bei dem ersten Objektknoten nicht um das aktuelle Objekt eines Listenknotens. Stattdessen wird ein Bezug zu einem Objektknoten der AWS hergestellt, welcher
Berechnung des AWS-State
64
wiederum zunächst ausgewertet werden muss. Dies beinhaltet die Identifizierung des Knotens
in der AWS (BerechneBezug), evtl. Berechnung des Knotens sowie weiterer Knoten, sowie
die Gefahr von Rekursion und das Entstehen von Abhängigkeiten.
Eine Besonderheit für die Funktion BerechneBezug stellen Pfadangaben der folgenden Form
da, wie sie ausschließlich in Knoten vom Typ Wolmpath vorkommen können.
Text t1 = object[index].A.B
// wolmpath
Beginnt eine Pfadangabe mit dem Schlüsselwort object, so ist ein Aufruf der Funktion
BerechneBezug nicht erforderlich, da es sich bei dem Zielknoten dieses Bezugs um den
aktuellen Objektknoten einer Pagelist/Fieldlist handelt. Der bezugnehmende Knoten t1
befindet sich jedoch in der gleichen Liste, ansonsten wäre eine Verwendung von object nicht
möglich. Der Zielknoten ist somit bekannt und eine Ermittlung einer Referenz auf den
Zielknoten mittels Aufruf der Funktion BerechneBezug ist nicht erforderlich.
Eine weitere Verwendung findet die Funktion BerechneBezug bei der Ermittlung der zu einer
Pagelist/Fieldlist gehörigen Objektliste. Das Attribut sourceobjectlist einer Pagelist/Fieldlist
stellt dazu einen AWS-Bezug zu einem Knoten vom Typ Objectlist bzw. Listofobjectlist her.
In vielen Fällen ist dieser Objektknoten dem zugehörigen Listenknoten direkt bekannt, da sich
beide auf der gleichen Ebene befinden, damit Geschwisterknoten sind, und ein direkter
Zugriff gemäß der AWS-Zugriffsregeln möglich ist.
Objectlist OL = Personen
Pagelist PL = OL
// sourceobjectlist: OL
Denkbar sind aber auch komplexere AWS-Bezüge. Beispielsweise könnte sich die zugehörige Objektliste innerhalb einer anderen Seite, innerhalb eines Fieldlist-Knotens befinden.
Pagelist PL = P.A.FL[7].OL
// sourceobjectlist: P.A.FL[7].OL
Für solche Fälle kann mit der Funktion BerechneBezug einfach eine Referenz auf die
entsprechende Objektliste ermittelt werden. Die evtl. Berechnung des so referenzierten
Knotens, das Erkennen von Rekursion sowie die Aufzeichnung von Abhängigkeiten sind
dann wiederum Aufgaben, die in der Funktion zu Berechnung eines Knotens vom Typ
Berechnung des AWS-State
65
Pagelist behandelt werden. Ein letzter Einsatzbereich für die Funktion BerechneBezug stellen
Knoten vom Typ objectselection dar. Ein solcher Knoten kann Bezüge zu anderen Knoten der
AWS herstellen. Der Knoten in Beispiel (1) schränkt mittels einer objectselection die Menge
der Objekte vom Typ „Person“ auf ein Objekt mit dem Attributwert „4“ ein. Bezüge zu
anderen AWS-Knoten sind nicht vorhanden.
(1) Object O1 = Person [knr = 4]
(2) Object O2 = Person [knr = P.PL[4].FL[first].knr]
(3) Objectlist OL = O1, O2, P.A.O3
Beispiel (2) zeigt, dass der Wert für den Vergleich innerhalb einer Bedingung auch aus
anderen Knoten der AWS stammen kann. Dies kann mittels Awslink oder Wolmpath, mit den
für beide typischen und in diesem Kapitel beschriebenen Pfadangaben, geschehen. Mittels
eines Awslink innerhalb einer Objectselection ist es zudem möglich auf andere Objektknoten
zuzugreifen (3), welche dann die Elemente einer neuen Objektliste bilden. Die Identifizierung
sowie Ermittlung der Referenz auf die entsprechenden Knoten ist wiederum Aufgabe der
Funktion BerechneBezug. Rekursion und Abhängigkeiten werden innerhalb der bezugnehmenden Knoten bzw. deren Objectselection-Ausdrücken behandelt. Im folgenden Kapitel
erfolgt eine detaillierte Betrachtung der Berechnung von Knoten vom Typ Objectselection.
7.2.11
BerechneObjectselection
Für die Berechnung eines Objectselection-Ausdrucks ist es zunächst interessant seinen
Aufbau und seine Position in der AWS zu betrachten. Knotentypen die einen oder mehrere
Objectselection-Ausdrücke enthalten bzw. enthalten können sind zum einen die Objektknoten
Object und Objectlist, zum anderen Knoten vom Typ Field bzw. Fieldlist. Auf die genaue
Bedeutung und Verwendung eines Objectselection-Ausdrucks innerhalb dieser Knotentypen,
wird ausführlicher in der Beschreibung der Berechnung der einzelnen Knotentypen eingegangen. Der prinzipielle Aufbau einer Objectselection kann der folgenden Abbildung entnommen werden.
Berechnung des AWS-State
66
Knoten k
objectselection
objectselection
…
…
awslink /
constraint
constraint
…
wolmclass
awslink
wolmpath
…
Die Definition in der AWS-DTD legt den genauen Aufbau fest.
<!ELEMENT objectselection ((wolmclass | awslink)+,
constraint*)>
Ein Knoten vom Typ Objectselection enthält zunächst wahlweise einen Knoten vom Typ
Wolmclass oder Awslink. Aufgabe dieses Knotens ist die Selektion von WOLM-Objekten.
Das „+“-Zeichen in einer DTD hat die Bedeutung, dass der entsprechende Ausdruck (hier:
„(wolmclass | awslink)“) mindestens einmal in dem jeweils definierten Knoten vorkommen
muss. Somit wären laut DTD-Definition theoretisch mehrere Vorkommen von Awslink bzw.
Wolmclass an dieser Stelle des Objectlist-Knotens erlaubt. Die resultierenden AWSDokumente wären laut DTD valide. Eine solche Bedeutung ist jedoch nicht gewünscht. Auf
die AWS bezogen muss die Bedeutung an dieser Stelle hingegen „genau einmal“ und nicht
„mindestens einmal“ sein. Eine solche Definition ist mit Hilfe einer DTD jedoch nicht
möglich. Als weitere Knoten kann ein Objectselection-Knoten optional einen oder mehrere
Knoten vom Typ Constraint enthalten. Mit Hilfe dieser Knoten können Bedingungen definiert
werden, die die im ersten Schritt ausgewählten WOLM-Objekte weiter einschränken können.
Eine genauere Behandlung der Knoten vom Typ Constraint erfolgt in einem späteren
Abschnitt. Aus obiger Abbildung ist jedoch schon ersichtlich, dass Knoten diesen Typs
wiederum Knoten der Typen Awslink und Wolmpath enthalten können. Das Auftreten von
Awslink- und Wolmpath-Knoten an dieser Stelle, sowie an der Stelle der ersten Selektion der
WOLM-Objekte, macht deutlich, dass Knoten, die einen Objectselection-Knoten enthalten,
über diesen Knoten Bezüge zu anderen Knoten der AWS herstellen können. Dies beinhaltet
die bekannten Probleme der Rekursion und Abhängigkeiten zwischen Knoten. Awslink- und
Wolmpath-Knoten lassen sich jedoch wie gehabt mit den Funktionen BerechneAwslink und
BerechneWolmpath berechnen. Der Startknoten ist hierbei immer der Knoten, der den
Objectselection-Knoten enthält.
Berechnung des AWS-State
67
Beispiele ohne "constraint"
Wie beschrieben, kann die erste Selektion von WOLM-Objekten mittels Wolmclass- oder
Awslink-Knoten erfolgen. Mit Hilfe eines Wolmclass-Knotens lässt sich diese Selektion auf
die folgenden Arten durchführen.
<objectselection>
<wolmclass>
Lehrstuhl
</wolmclass>
</objectselection>
In obigem Beispiel werden alle Objekte des aktuellen WOLM-State selektiert, die Instanzen
der Klasse "Lehrstuhl" sind. Das Ergebnis kann ein oder mehrere WOLM-Objekte umfassen,
oder auch leer sein.
<objectselection>
<wolmclass>
Object_Lehrstuhl.diplomanden
</wolmclass>
</objectselection>
In diesem Fall handelt es sich bei dem Knoten Object_Lehrstuhl um einen AWS-Knoten vom
Typ Object, der eine Referenz auf ein WOLM-Objekt enthält. Der zweite Teil des obigen
Ausdrucks („.diplomanden“) stellt einen Pfad in diesem WOLM-Objekt dar. Für die
Berechnung wird zunächst eine Referenz auf den AWS-Knoten ermittelt (mit Hilfe der
Funktion BerechneBezug). Anschließend kann über den entsprechenden Pfad (hier:
„.diplomanden) auf die jeweiligen WOLM-Objekte des aktuellen WOLM-State zugegriffen
werden. Das Ergebnis kann ein oder mehrere WOLM-Objekte umfassen, oder auch leer sein.
Die Selektion mittels Awslink-Knoten kann auf die folgenden Arten geschehen.
<objectselection>
<awslink>
Object_Lehrstuhl
</awslink>
</objectselection>
Mit Hilfe des Awslink-Knoten können die bekannten und bislang beschriebenen AWSBezüge zu anderen Knoten hergestellt werden. Aufbau und Berechnung des Awslink sind
bekannt. Bei der Verwendung des Awslink im Rahmen einer Objectselection ist zu beachten,
dass es sich bei dem Zielknoten um einen Knoten vom Typ Object oder Objectlist handeln
muss. Alle in einem solchen Objektknoten referenzierten WOLM-Objkete werden in der
Selektion übernommen.
Berechnung des AWS-State
68
<objectselection>
<awslink>
P.A.Objectlist_Diplomanden
</awslink>
</objectselection>
Nach erfolgter Selektion, mittels Wolmclass bzw. Awslink, steht eine Menge von Referenzen
auf Objekte des WOLM zu Verfügung. Diese Menge kann in einem zweiten Schritt weiter
eingeschränkt werden.
Einschränkungen mit "constraint"
Die Einschränkungen werden in Knoten vom Typ Constraint definiert. Jede Einschränkung
wird auf alle im ersten Schritt selektierten WOLM-Objekte angewandt. Sollten mehrere
Constraint-Knoten vorhanden sein, so werden diese UND-verknüpft.
<objectselection>
...(awslink|wolmclass)
<constraint>
<wolmattribute>
Bezeichnung
</wolmattribute>
<binaryoperator operator = "eq"/>
<awslink>
P.A.X
</awslink>
</constraint>
</objectselection>
Es gibt zwei Arten der Definition einer Einschränkung. Obiges Beispiel verwendet einen
zweistelligen Operator (binaryopeator). Eine solche Einschränkung bezieht sich immer auf ein
Attribut eines WOLM-Objekts. Dabei wird ein ausgewählter Attributwert, hier der Wert des
Attributs „Bezeichnung“, mit einem weiteren Wert verglichen. Für diesen Vergleich stehen
die Operatoren = , < , > , != , <= , >= bereit, die in der AWS entsprechend
benannt sind (eq | lt | gt | neq | lte | gte). Der Wert für den Vergleich
kann aus einem Knoten vom Typ Const, Awslink oder Wolmpath stammen (vgl. AWS-DTD).
Ist das Ergebnis des Vergleichs negativ, so wird das entsprechende Objekt aus der
Objectselection entfernt. Die zweite Möglichkeit besteht in der Verwendung eines einstelligen
Operators. Bislang ist in der AWS lediglich ein solcher Operator definiert. Eine spätere
Erweiterung wäre jedoch möglich. Der Operator isInstanceOf prüft die Klassenzugehörigkeit
eines WOLM-Objekts.
Berechnung des AWS-State
69
<objectselection>
...(awslink|wolmclass)
<constraint>
<singleoperator operator = "isInstanceOf"/>
<wolmclass>
Lehrstuhl
</wolmclass>
</constraint>
</objectselection>
Im vorliegenden Beispiel wird überprüft, ob das WOLM-Objekt eine Instanz der Klasse
"Lehrstuhl" ist. Ist dies nicht der Fall so wird dieses Objekt ebenfalls aus der Objectselection
entfernt. Ergebnis der Berechnung eines kompletten Objectselection-Knotens ist immer eine
Liste von Referenzen auf WOLM-Objekte. Diese Liste kann leer sein oder beliebig viele
Elemente enthalten.
7.3 Berechnung Knotentypen
Nach der Betrachtung aller zur Berechnung des AWS-State erforderlichen Konzepte, wird in
diesem Kapitel die Berechnung der einzelnen AWS-Knotentypen behandelt. Die wichtigsten
Konzepte, die für diese Berechnung direkt genutzt werden, sollen noch einmal kurz zusammengefasst werden. Die meisten der AWS-Knotentypen enthalten in ihrer eigenen Definition
einen oder mehrere Knoten der Typen Awslink, Wolmpath oder Objectselection. Für jeden
dieser drei Typen wurde im vorangegangenen Kapitel eine Berechnungsfunktion vorgestellt.
Für jedes Auftreten eines dieser drei Typen innerhalb der Berechnungsfunktion eines AWSKnotens genügt also ein entsprechender Aufruf einer dieser Funktionen. Die eigentlichen
Berechnungsfunktionen für die verschiedenen AWS-Knotentypen bleiben dadurch vergleichsweise einfach und übersichtlich.
BerechneAwslink liefert dabei eine Referenz auf den Knoten, auf den Bezug genommen
wurde. Dieser Knoten ist vollständig berechnet. Innerhalb der BerechneKnoten Funktion wird
dann, je nach Knotentyp, über die weitere Verwendung des referenzierten Knoten
entschieden. Dies kann beispielsweise die Ermittlung der AWS-State-ID oder des
Inhaltswertes sein. BerechneWolmpath liefert einen konkreten Wert aus dem WOLM. Dieser
Wert wird ebenfalls, je nach Knotentyp des bezugnehmenden Knotens, weiterverarbeitet. Für
die Berechnung von Knoten vom Typ Object, Objectlist oder Field ist die Funktion
BerechneObjectselection, welche eine Liste von Referenzen auf WOLM-Objekte liefert,
besonders hilfreich, da diese Knotentypen jeweils ein oder mehrere Knoten vom Typ
Objectselection enthalten.
Berechnung des AWS-State
70
Text
Ein Knoten vom Typ Text ist in der AWS wie folgt aufgebaut.
Auszug AWS-DTD:
<!ELEMENT text ((const | awslink | wolmpath)+, link?)>
Er kann seinen Inhaltswert über eine Reihe von konstanten Inhaltswerten (const), AWSBezügen (awslink) und oder WOLM-Bezügen (wolmpath) bestimmen. Die AWS-State
Repräsentation eines Text-Knotens enthält lediglich einen konstanten Inhaltswert. Ziel der
Berechnung ist also die Auflösung von AWS- und WOLM-Bezügen, sowie die Zusammenführung eventueller Mehrfachvorkommen von const-Ausdrücken. Das prinzipielle Vorgehen
bei der Berechnung kann dem untenstehenden Pseudo-Code entnommen werden. Die
Darstellung ist stark vereinfacht und berücksichtig evtl. auftretende Fehler nicht.
BerechneKnotenText(Knoten)
{
// für jeden const-Ausdruck
Knoten.const += const
// für jeden awslink-Ausdruck
Ref = BerechneAwslink(Knoten, awslink)
Knoten.const += Ref.const
// für jeden wolmpath-Ausdruck
Knoten.const += BerechneWolmpath(Knoten, wolmpath)
return Knoten
}
Für jedes Vorkommen eines Const-Ausdrucks wird der konstante Wert des Ausdrucks an den
Wert des zu berechnenden Knoten angehängt. Für jeden vorhandenen Awslink wird die
Funktion BerechneAwslink aufgerufen, welche eine Referenz auf den Knoten im AWS-Bezug
zurückgibt. Da dieser referenzierte Knoten stets bereits berechnet ist, kann über „Ref.const“
auf dessen Inhaltswert zugegriffen werden. Zu beachten ist hierbei, dass es sich bei dem Knoten im AWS-Bezug um einen Knoten vom Typ Text, Hiddentextinput oder Textinput handeln
Berechnung des AWS-State
71
muss. Bezüge zu anderen Knoten sind nicht erlaubt und auf Grund fehlender Inhaltswerte für
einen Text-Knoten auch nicht sinnvoll. Für jedes Vorkommen eines Wolmpath wird die
Funktion BerechneWolmpath aufgerufen und der zurückgegebene Wert dem Inhaltswert des
zu berechnenden Knotens angehängt. Schließlich sind sämtliche AWS- sowie WOLMBezüge aufgelöst. Der Text-Knoten ist berechnet.
Textinput
Konten vom Typ Textinput besitzen bis auf den fehlenden optionalen Knoten vom Typ Link
die gleiche AWS-Definition. Auszug AWS-DTD:
<!ELEMENT textinput ((const | awslink | wolmpath)+)>
Die Berechnung kann daher analog zu der Berechnung von Knoten vom Typ Text erfolgen.
Hiddentextinput
Konten vom Typ Hiddentextinput besitzen bis auf den fehlenden optionalen Knoten vom Typ
Link die gleiche AWS-Definition. Auszug AWS-DTD:
<!ELEMENT hiddentextinput ((const | awslink | wolmpath)+)>
Die Berechnung kann daher analog zu der Berechnung von Knoten vom Typ Text erfolgen.
Image
Knoten vom Typ Image besitzen eine sehr ähnliche AWS-Definition, wie Knoten vom Typ
Text. Auszug AWS-DTD:
<!ELEMENT image ((const | awslink | wolmpath), link?)>
Der Unterschied besteht darin, dass ein Knoten vom Typ Image lediglich genau ein
Vorkommen eines Const-, Awslink- oder Wolmpath-Ausdrucks enthalten darf. Für die
Berechnung spielt dies jedoch keine Rolle. Das gleiche Vorgehen wie bei der Berechnung
eines Knoten vom Typ Text kann angewandt werden. Zusätzlich sind AWS-Bezüge auf
Knoten vom Typ Image erlaubt. In einem solchen Fall wird die Bildinformation aus dem
Zielknoten übernommen.
Link
Der Aufbau von Knoten vom Typ Link ähnelt wieder stark den bislang beschriebenen
Knotentypen. Auszug AWS-DTD:
Berechnung des AWS-State
72
<!ELEMENT link (const | awslink | wolmpath)>
Zu unterscheiden sind externe und interne Links. Bei externen Links handelt es sich bei dem
berechneten Wert um eine korrekte Webadresse der Form „http://www.adresse.de“. Dieser
Wert kann aus dem Const-Ausdruck, aus dem WOLM (Wolmpath) oder einem anderen LinkKnoten innerhalb der AWS (Awslink) stammen. Interne Links hingegen stellen einen Verweis
auf einen anderen Knoten innerhalb der AWS dar. Als Verweisziel sind hierbei alle
Knotentypen mit grafischer Repräsentation zulässig. Das heißt, alle Knotentypen, außer
Object, Objectlist, Listofobjectlist und Action. Als Wert für den aktuellen Link-Knoten wird
dann die AWS-State-ID des Zielknotens gespeichert.
Page
Knoten vom Typ Page dienen lediglich als Container für weitere Knoten. Neben der
Zuweisung der für jeden Knoten erforderlichen AWS-State-ID ist eine weitere Berechnung
nicht erforderlich.
Project
Für Knoten vom Typ Project gilt grundsätzlich das gleiche wie bei Knoten vom Typ Page.
Bei einem Project-Knoten muss zusätzlich überprüft werden, ob der im Attribut „startpage“
angegebene Knoten im AWS-State existiert. Ist dies der Fall, so wird dem Attribut „startpage“
die AWS-State-ID selbigen Knotens zugewiesen.
Field
Die Hauptaufgabe eines Knoten vom Typ Field, ist ähnlich wie bei Knoten vom Typ Project
und Page, die Aufnahme weiterer Knoten. Im Gegensatz zu Project- und Page-Knoten kann
ein Knoten vom Typ Field zusätzlich einen Objectselection-Ausdruck enthalten. Dieser Ausdruck ermöglicht eine zustandsabhängige Modifikation der AWS, in diesem Fall entscheidet
er, ob der jeweilige Field-Knoten, sowie seine enthaltenen Knoten, in den AWS-State
übernommen wird oder nicht.
<!ELEMENT field (objectselection?, (…weitere Knoten…)*)>
Ein dem Field-Knoten bekanntes Objekt (hier: „a“) wird zusammen mit einer Objectselection
(hier: „a[preis>5][fsk<18]“) dem Field-Knoten zugeordnet.
Berechnung des AWS-State
73
Object a = Videos[id=5]
Field F ? a[preis>5][fsk<18]
Text t1 = ...
Liefert die Funktion BerechneObjectselection genau ein Objekt zurück so wird der FieldKnoten in den AWS-State übernommen. In allen anderen Fällen wird der Field-Knoten, sowie
alle an ihm hängenden Unterknoten, aus dem AWS-State ausgeblendet.
Object
Ein Knoten vom Typ Object enthält als Wert eine Referenz auf genau ein Objekt des WOLM
bzw. den Wert null. Ein Object-Knoten besteht aus einem oder mehreren ObjectselectionAusdrücken. Diese Ausdrücke werden jeweils mit der Funktion BerechneObjectselection
behandelt.
<!ELEMENT object (objectselection+)>
Die Funktion BerechneObjectselection gibt eine Liste von Referenzen auf WOLM-Objekte
zurück. Enthält eine solche Liste genau ein Element, so wird die Referenz dieses Elements die
Referenz des Object-Knotens. Enthält ein Object-Knoten mehrere Objectselection-Ausdrücke,
so darf nur einer der Ausdrücke eine einelementige Liste enthalten. Alle anderen Listen
müssen leer sein, da sonst die Bedingung, ein Knoten vom Typ Object enthält als Wert eine
Referenz auf genau ein Objekt des WOLM, nicht mehr erfüllt wäre. Der Object-Knoten wäre
damit ungültig.
Objectlist
Die Definition für Knoten vom Typ Objectlist in der AWS-DTD, ist identisch mit der
Definition von Knoten vom Typ Object.
<!ELEMENT objectlist (objectselection+)>
Ein Objectlist-Knoten enthält als Wert jedoch eine Liste von Referenzen auf WOLM-Objekte.
Die einzelnen Objectselection-Ausdrücke, die analog zum Object-Knoten mit der Funktion
BerechneObjectselection behandelt werden, dürfen nun auch mehrelementige Listen zurückliefern. Jede erhaltene Referenz einer Objectselection wird somit in die Liste von Referenzen
des Objectlist-Knotens übernommen.
Berechnung des AWS-State
74
Listofobjectlists
Ein Knoten vom Typ Listofobjectlists hat in der AWS-DTD folgenden Aufbau.
<!ELEMENT listofobjectlists ((awslink|wolmclass),wolmpath)>
Ein Knoten dieses Typs bestimmt zunächst mittels eines Wolmclass-Knotens, oder eines
Awslink-Knotens, der einen Bezug zu einem Objectlist-Knoten herstellt, eine Menge von
Referenzen auf WOLM-Objekte. Alle diese Referenzen werden in einer äußeren Liste
gespeichert. Jedes der in dieser Liste referenzierten WOLM-Objekte muss mindestens ein
Attribut besitzen, welches als Wert selbst eine Referenz auf ein anderes WOLM-Objekt
enthält. Folgende Beispiele zweier WOLM-Klassen Definitionen verdeutlichen einen solchen
Zusammenhang.
WOLM Klasse:
WOLM Klasse:
class Film
{
Darsteller* dst;
...
}
class Darsteller
{
String name;
...
}
Enthält die äußere Liste eine Menge von Referenzen auf Objekte der Klasse WOLM, so kann
mittels einer Pfadangabe, für jedes Element dieser Liste, eine zweite (innere) Liste erstellt
werden, die dann eine Menge von Referenzen auf Objekte der Klasse Darsteller enthält.
<listofobjectlists>
<awslink>
Objlist_Filme
</awslink>
<wolmpath>
dst
</wolmpath>
</listofobjectlists>
// Bezug auf Objectlist-Knoten
// Pfad im WOLM
Obiges Beispiel einer AWS verdeutlicht die Definition eines Listofobjectlists-Knotens. Der
Knoten Wolmpath enthält innerhalb einer Listofobjectlists-Definition stets eine Pfadangabe,
die sich auf das WOLM bezieht.
Berechnung des AWS-State
75
Pagelist
Die Berechnung eines Knoten vom Typ Pagelist ist genau genommen keine Berechnung. Wie
bereits in Kapitel 7.1.5 beschrieben, werden alle Page-Knoten, die durch eine Pagelist
definiert werden, als neue Page-Knoten in die AWS eingefügt. Die Berechnung der einzelnen
Page-Knoten, kann dann wie gewohnt, auch einzeln, erfolgen. Die Schritte zur „Berechnung“
wurden bereits in Kapitel 7.1.5 „AWS mit Listenknoten“ ausführlich beschrieben.
Fieldlist
Die Berechnung eines Knoten vom Typ Fieldlist erfolgt analog zur Berechnung eines Knoten
vom Typ Pagelist.
Button
Die Berechnung eines Knoten vom Typ Button beschränkt sich wiederum auf das Auflösen
der AWS- und WOLM-Bezüge (awslink, wolmpath), sowie das Zusammenführen der
ermittelten Werte zu einem Wert für die Beschriftung des Buttons.
AWS-DTD:
<!ELEMENT button ((const | awslink | wolmpath), action*,
link?)>
AWS-State-DTD:
<!ELEMENT button ((const), action*, link?)>
Action
Aus der AWS-DTD-Definition eines Action-Knotens wird ersichtlich, welche Schritte zur
Berechnung eines solchen Knotens erforderlich sind.
<!ELEMENT action (params*)>
<!ATTLIST action
name CDATA #IMPLIED
precedence CDATA #IMPLIED
wolmobject CDATA #REQUIRED
method CDATA #REQUIRED
>
<!ELEMENT params (const | awslink | wolmpath)>
Das Attribut wolmobject enthält einen Verweis auf ein WOLM-Objekt. Im AWS-State erhält
dieses Attribut als Wert die eindeutige WOLM-State-ID dieses WOLM-Objekts. Bei den
übrigen Attributwerten handelt es sich um konstante Werte. Eine Berechnung ist somit nicht
erforderlich.
Berechnung des AWS-State
76
<!ELEMENT action (params*)>
<!ATTLIST action
id CDATA #IMPLIED
precedence CDATA #IMPLIED
wolmobject CDATA #REQUIRED
method CDATA #REQUIRED
>
<!ELEMENT params (const | cvalue)>
Bei der Angabe der Parameter wird im AWS-State zwischen konstanten Werten und Werten,
die aus einer Benutzereingabe (Textfeld) stammen, unterschieden. Parameterwerte, die im
AWS mittels Const- oder Wolmpath-Ausdrucks definiert sind, werden im AWS-State als
Const-Ausdruck gespeichert. Wird im AWS mittels Awslink ein Bezug zu einem Textinputoder Hiddentextinput-Knoten hergestellt, so wird die AWS-State-ID dieses Eingabe-Knotens
im AWS-State innerhalb eines cvalue-Ausdrucks gespeichert (vgl. Kapitel AWS-State).
Prototyp
77
8 Prototyp
8.1 Allgemein
Der im Rahmen dieser Arbeit entstandene Prototyp, zur Berechnung eines AWS-State, richtet
sich bei der Implementierung an den in dieser Arbeit beschriebenen Konzepten und Vorgehensweisen aus. Es wird daher nicht auf die genaue Implementierung eingegangen, sondern
die Anwendung des entstandenem Prototypen beschrieben. Klassen, die ihm Rahmen dieser
Arbeit entstanden sind, sind in einem Paket mit der Bezeichnung awsstatebuilder zusammengefasst. Für die Behandlung einer WOLM-State-Datei (Einlesen, Parsen) wurden Klassen aus
der Arbeit [Minßen] wiederverwendet. Diese Klassen sind im Paket utilwst zusammengefasst
und werden vom Paket awsstatebuilder verwendet. Für die Bearbeitung von XML-Strukturen
wurde die JDOM-Bibliothek [JDOM] verwendet.
import java.io.*;
import java.util.Stack;
import wolm.awsstatebuilder.*;
public class BerechneMich
{
public static void main( String[] args )
{
AwsstateBuilder astb = new AwsstateBuilder();
File aws = new File("bsp2/aws_b2.xml");
File wst = new File("wolmstate/wolmstate_1Ls.xml");
File awsstate = new File("bsp2/awsst.xml");
try
{
astb.build(aws, wst, true);
astb.build(aws, wst, awsstate, false);
}
catch (AwsCycleException e)
{
System.out.println("Abbruch, Zyklus:");
Stack cyc = astb.getAwsCycles();
while (!cyc.empty())
{
System.out.println((String)cyc.pop());
}
}
}
}
Obiges Programm verdeutlicht die Verwendung des Pakets awsstatebuilder. Die Klasse
AwsStateBuilder ist für die Berechnung des AWS-State verantwortlich. Ihre Methode build
Prototyp
78
startet den Berechnungsvorgang und erwartet wahlweise drei oder vier Parameter. Beim
ersten Parameter handelt es sich immer um eine Referenz auf eine AWS-Datei, beim zweiten
auf eine WOLM-State-Datei. Bei einem Aufruf mit vier Parametern gibt der dritte Parameter
eine Referenz auf eine Datei an, in der der berechnete AWS-State ausgegeben werden soll.
Standardmäßig erfolgt die Speicherung des AWS-State in einer Datei mit der Bezeichnung
awsstate.xml. Der jeweils letzte Parameter steuert die optionale Ausgabe von Debugginginformationen, auf die im Weiteren noch genauer eingegangen wird. Grundsätzlich treten bei
der Berechnung eines AWS-State, vorausgesetzt die AWS ist gültig (keine Zyklen), keine
Fehler auf. Es erfolgt immer die Ausgabe eines gültigen AWS-State, auch wenn dieser leer
sein kann. Um den einzig möglichen Fehler (Zyklen) behandeln zu können, wird in obigem
Beispiel die Ausnahme AwsCycleException abgefangen. Die Berechnung des AWS-State
wird in einem solchen Fall stets beendet. Es wird keine AWS-State-Datei angelegt.
Alternativ kann die Berechnung über das beiliegende Programm astbcmd von der Kommandozeile aus aufgerufen werden. Dem Aufruf werden dabei die entsprechenden Dateinamen
übergeben. Als optionaler letzter Parameter kann der Ausdruck debug angehängt werden, um
das Programm im Debug-Modus zu starten. Es ergeben sich vier Aufrufmöglichkeiten.
java
java
java
java
astbcmd
astbcmd
astbcmd
astbcmd
[aws-file]
[aws-file]
[aws-file]
[aws-file]
[wolmstate-file] [awsstate-file]
[wolmstate-file] [awsstate-file] debug
[wolmstate-file]
[wolmstate-file] debug
Es folgend zwei Beispiele zur AWS-State Berechnung. Das erste Beispiel beschreibt anhand
einer komplexen AWS die Verwendung einer großen Zahl von AWS Konzepten. Das zweite
Beispiel erläutert die Verwendung des Debug-Modus. Beide Beispiele, sowie weitere Beispiele und das Programm selbst, können der dieser Arbeit beiliegen CD entnommen werden.
8.2 Beispiel 1
Dem Beispiel liegt folgendes WOLM zugrunde.
WOLM:
class Filmliste
{
Film* meineFilme
}
class Film
{
String titel
Darsteller* darsteller
}
class Darsteller
{
String name
Film* seineFilme
}
Der WOLM-State für das Beispiel enthält die folgenden WOLM-Objekte.
Prototyp
79
WOLM-State:
Filmliste : id1 (meineFilme=[2,3])
Film : id2 (titel="Matrix1", darsteller=[4,5])
Film : id3 (titel="Matrix2", darsteller=[4])
Film : id6 (titel="Das Boot", darsteller=[5])
Darsteller : id4 (name="Neo", seineFilme=[2,3])
Darsteller : id5 (name="Triniti", seineFilme=[2,6])
Ziel der Darstellung durch eine AWS ist die untenstehende Struktur einer Website.
Page meineListe
Page F[1]
Matrix1
Darsteller
Page DS[1,1]
Neo
Matrix1
Matrix2
Page F[2]
Matrix2
Darsteller
Page DS[1,2]
Triniti
Matrix1
Das Boot
Page DS[2,1]
Neo
Matrix1
Matrix2
Die Startseite „meineListe“ enthält lediglich einen Link auf die erste Seite der Pagelist F.
Diese Pagelist enthält alle Film-Objekte, die im Attribut meineFilme des einzigen Objekts der
Klasse Filmliste referenziert werden. Dies könnten beispielsweise die Lieblingsfilme einer
Person sein. In diesem Beispiel sind dies die Film-Objekte mit den WOLM-State-IDs id2 und
id3, also die Filme mit dem Titel „Matrix1“ und „Matrix2“. Der Inhalt einer einzelnen Seite
der Pagelist F setzt sich wie folgt zusammen. Neben der Ausgabe des Filmtitels enthält jede
Seite einen Link auf eine weitere Pagelist, die die in einem Film mitwirkenden Darsteller
beinhaltet. Zudem sind alle Seiten der Pagelist F über Links miteinander verkettet.
Der Pagelist DS, zur Darstellung der in einem Film mitwirkenden Darsteller, liegt als Objektliste eine Listofobjectlists zugrunde, die für jedes Film-Objekt die in diesem Objekt referenzierten Darsteller-Objekte enthält, also die Mitwirkenden in einem Film. Für das erste FilmObjekt („Matrix1“) sind im WOLM-State zwei Darsteller-Objekte vorhanden. Für jeden Dar-
Prototyp
80
steller eines Films gibt es eine solche Seite der Pagelist DS. Eine einzelne Seite der Pagelist
DS enthält den Namen des Darstellers, sowie eine Auflistung aller Filme, in denen dieser
Darsteller mitgespielt hat. Diese Filme sind im Attribut „seineFilme“ eines Darsteller-Objekts
gespeichert. Auf der Seite dargestellt werden sie durch eine Fieldlist. Zudem enthält jeder
Eintrag dieser Fieldlist, also jeder Film, wieder einen Link auf die entsprechende Seite der
Pagelist F, die diesen Film darstellt. Die Seite DS[1,2], des Darsteller „Triniti“ stellt hierbei
eine Besonderheit dar. Der Darsteller hat in dem Film mit dem Titel „Das Boot“ mitgespielt.
Somit müsste dieser Film eigentlich auf der Seite DS[1,2] enthalten sein. Da es aber innerhalb
der Pagelist F keinen Eintrag für diesen Film gibt, wird der entsprechende Eintrag auf der
Seite DS[1,2] ausgeblendet und nicht in den AWS-State übernommen.
Project P1 = P1.meineListe
Object Obj_Filmliste = Filmliste
Page meineListe
Text = "Meine Filmliste"
Link = F[first]
Objectlist Objectlist_meineFilme = Obj_Filmliste.meineFilme
Pagelist F = Objectlist_meineFilme
Text = "Titel" + object.titel
Text = "Darsteller"
Link = DS[index,first]
ListOfObjectlists LoolFiDs
Objectlist_meineFilme
darsteller
Pagelist DS = LoolFiDs
Text = "Name" + object.name
Objectlist F2 = object.seineFilme
Fieldlist FL = F2
Text = "Titel" + object.titel
Link = F[indexof object in P1.Objectlist_meineFilme]
Auf Grund der ohnehin schon aufwendigen Darstellung der AWS wurden die Elemente, die
für die Verkettung der einzelnen Seiten der jeweiligen Pagelists verantwortlich sind, nicht
aufgeführt. Die komplette AWS, WOLM-State und AWS-State können der dieser Arbeit beiliegenden CD entnommen werden.
Prototyp
81
8.3 Beispiel 2
Das zweite Beispiel verwendet folgende AWS.
Project P = P.A
Object Obj_Diplomand = Diplomand[name="Hansi"]
Page A
Text T1 = "Diplomand:" + P.B.T2
Page B
Text T2 = P.Obj_Diplomand.name
Ein Object-Knoten stellt einen Bezug zu einem WOLM-Objekt her. Der Wert eines Attributs
(name) dieses Objekts wird in Knoten T2 gespeichert. Der Knoten T1 stellt einen Bezug auf
den Knoten T2 her. Der resultierende AWS-State, bei entsprechendem WOLM-State (siehe
CD), sieht wie folgt aus.
Project #1 = #2
Page #2
Text #3 = "Diplomand: Hansi"
Page #5
Text #4 = "Hansi"
Ein kleiner Tippfehler bei der Definition der AWS, beispielsweise die Angabe eines falschen
Attributnamens,
T2 = P.Obj_Diplomand.nome
// Attribut nome existiert nicht
kann dazu führen, dass die Berechnung einen leeren AWS-State liefert. Durch einen
Bezugsfehler in Knoten T2 würden im obigen Beispiel der Reihe nach die Knoten T2, B, T1,
A ungültig, und somit das ganze Projekt. Um die Fehlersuche zu erleichtern kann die
Berechnung des AWS-State im Debug-Modus gestartet werden. Somit wird zusätzlich zum
AWS-State eine zweite Datei mit dem Namen „debug.txt“ erstellt. Für obiges Beispiel einer
AWS hat diese Datei folgenden Inhalt, für den Fall, dass der Knoten T2 einen Bezugsfehler
verursacht.
Abhängigkeiten:
#P#B -> #P#A#T1
Hinweise:
AccessOnDisabledNode
P.B.T2
--<text name="T1" id="#P#A#T1" nid="3" disabled="1">
<const disabled="1">Diplomand:</const>
<awslink disabled="1">P.B.T2</awslink>
</text>
Prototyp
82
Zunächst werden die Abhängigkeiten zwischen den AWS-Knoten angezeigt. Zudem ist
ersichtlich, dass der Knoten T1 auf einen ungültigen Knoten T2 (AccessOnDisabledNode)
zugegriffen hat. Die Angabe der aktuellen XML-Definition des Knotens T1 erleichtert das
Auffinden des Fehlers in der AWS. Neben diesen zusätzlichen Informationen in der externen
Datei „debug.txt“, enthält der berechnete AWS-State weitere Informationen. So bleiben alle
Objekknoten, Fieldlist- und Pagelist-Knoten im „AWS-State“ erhalten. Zusätzlich kann ein
Knoten in dieser Zwischenform die folgenden Attribute enthalten.
disabled
index
index2
id
nid
=
=
=
=
=
1
1…n
1…n
#P#A#B
42
//
//
//
//
//
Knoten ist ungültig
index innerhalb Page-/Fieldlist
index2 innerhalb Pagelist mit LOOL
AWS-State-ID mit vollem Pfad
numerische AWS-State-ID
Ein solcher „AWS-State“ ist nicht mehr valide gemäß der AWS-State-DTD, erleichtert jedoch
das Auffinden von Fehlern in der AWS. Ist der Fehler gefunden, kann die Berechnung eines
validen AWS-State durch erneuten Aufruf der Berechnung, ohne Debug-Modus, erfolgen.
Zusammenfassung
83
9 Zusammenfassung
Wie diese Arbeit zeigt, erfordert die Berechnung einer Attributierung einer AWS, also das
Füllen einer AWS mit konkreten Daten des WOLM, eine Reihe von Betrachtungen. Als besonders komplex erwiesen sich dabei Bezüge von Knoten zu anderen Knoten der AWS, sowie
der Einsatz der Knotentypen Pagelist und Fieldlist. Durch den Einsatz von Bezügen kommt es
zu Abhängigkeiten zwischen Knoten, die in späteren Berechnungsschritten ggf. berücksichtigt
werden müssen. Zudem besteht die Gefahr von rekursiven Bezügen. Besonders anspruchsvoll
wird das Auflösen von Bezügen, wenn sich die Zielknoten des Bezugs innerhalb eines Listenknotens (Pagelist/Fieldlist) befinden.
Im Rahmen dieser Arbeit wurden Konzepte und Vorgehensweisen zur Berechnung eines
AWS-State aus einer AWS mit zugehörigem WOLM-State erarbeitet. Die Struktur des AWSState wurde dabei mittels einer AWS-State-DTD festgelegt. Schließlich wurde das Erarbeitete
in Form einer prototypischen Implementierung eines Programms zur Berechnung eines AWSState umgesetzt. Mit diesem Programm lässt sich ein AWS-State für komplexe AWSStrukturen (vgl. 8.2, Beispiel 1) berechnen. Bereits kleinste Flüchtigkeitsfehler bei der Definition einer AWS können, ungewollter Weise, zu einem komplett leeren AWS-State führen. Um
die Fehlersuche zu erleichtern, wurde der Prototyp mit Funktionen zur Anzeige von DebugInformationen ausgestattet, die die Fehlersuche in einer AWS erleichtern.
Auf Konzepte zur Benutzerinteraktion konnte ihm Rahmen dieser Arbeit nur begrenzt eingegangen werden, da entsprechende Konzepte noch nicht konkret umgesetzt wurden, sondern
nur theoretische definiert sind. Die Nutzung von Elementen zur Benutzerinteraktion auf der
finalen Website ist allerdings auch kein spezielles Problem der Berechnung eines AWS-State.
Die in dieser Arbeit vorgestellten Konzepte und Vorgehensweisen lassen sich auf alle Elemente der AWS, auch auf mögliche Erweiterungen, anwenden.
In weiteren Arbeiten werden zurzeit Lösungen zur Generierung einer Darstellung der finalen
Website aus einem AWS-State erstellt, so dass in absehbarer Zeit die wichtigsten Komponenten des WSMS zur Verfügung stehen.
Literaturverzeichnis
84
10 Literaturverzeichnis
[Schütte]
Schütte, A.: Spezifikation und Generierung von Übersetzern für GraphSprachen durch attributierte Graph-Grammatiken
EXpress Edition 1987
[Kühnem]
Kühnemann, A.: Attributgrammatiken: eine grundlegende Einführung
Vieweg 1997
[Mahn]
Mahn, U.: Attributierte Grammatiken und Attributierungsalgorithmen
Springer-Verlag 1988
[Kastens]
Kastens, U.: Übersetzerbau
Oldenbourg-Verlag 1990
[Schmitz]
Schmitz, L.: Syntaxbasierte Programmierwerkzeuge
Teubner 1995
[SZW 1]
Bomsdorf, B., Szwillus, G.: Task-Based Web Modeling
(Paper) 2004
[SZW 2]
Bomsdorf, B., Szwillus, G.: Task-Object Models for the Development of
Interactive Web Sites
(Paper) 2004
[SZW 3]
Bomsdorf, B., Szwillus, G.: Web Site Management For All
(Paper)
[SZW 4]
Bomsdorf, B., Szwillus, G.: Web Site Management “for Dummies”
(Paper)
[SZW AWS]
Szwillus, G.: AWS
(interner Text)
[SZW WOLM]
Szwillus, G.: WOLM
(interner Text)
[Langer]
Langer, R.: Generierung einer initialen abstrakten Website Struktur aus
einem Objektlebenszyklusmodell
(Diplomarbeit) 2004
[Köpke]
Köpke, C.: Generierung von Webadministrationsseiten aus einem Objektlebenszyklusmodell
(Studienarbeit) 2003
Literaturverzeichnis
[Minßen]
Minßen, A.: Entwicklung und prototypische Implementation eines
Simulators für Objektlebenszyklusmodelle
(Diplomarbeit) 2003
[Java]
Ullenboom, C.: Java ist auch eine Insel
Galileo Computing 2003
[JDOM]
85
jdom.org
http://www.jdom.org/
Änderung AWS-DTD
86
A Änderung AWS-DTD
A.1 Action-Knoten
Ein Knoten vom Typ Action war in der AWS bislang wie folgt definiert.
<!ELEMENT action EMPTY>
<!ATTLIST action
name
CDATA
precedence
CDATA
wolmobject
CDATA
method
CDATA
params
CDATA
>
#IMPLIED
#IMPLIED
#REQUIRED
#REQUIRED
#IMPLIED
Auf Basis dieser Definition hat ein Action-Knoten folgende XML-Darstellung.
<button>
<const>Klick mich</const>
<action wolmobject="42" method="doIt" params="12">
</action>
</button>
Von Bedeutung für die Änderung ist im Moment nur das Attribut params, mit dessen Hilfe
der jeweiligen Methode Parameter übergeben werden sollen. Die Parameterübergabe mit
obiger Definition ist nicht sehr leistungsfähig. Sie ermöglicht keine Angabe von zwei oder
mehr Parametern und nur die Angabe von konstanten Werten. Werte für Parameter können
nicht aus anderen AWS-Knoten bestimmt werden. Eine veränderte AWS-DTD beseitigt diese
Probleme.
<!ELEMENT action (params?)>
<!ATTLIST action
name CDATA #IMPLIED
precedence CDATA #IMPLIED
wolmobject CDATA #REQUIRED
method CDATA #REQUIRED
>
<!ELEMENT params ((const | awslink | wolmpath)+)>
Die XML-Darstellung sieht nun wie folgt aus.
Änderung AWS-DTD
87
<button>
<const>Klick mich</const>
<action wolmobject="42" method="doIt">
<params>
<const>12</const>
<awslink>P.A.A</awslink>
<wolmpath>P.A.O.N</wolmpath>
</params>
</action>
</button>
Der Vorteil gegenüber der alten Definition besteht in der Möglichkeit beliebig viele Parameter angeben zu können. Zudem können die Parameter konstant oder Bezüge zu AWSKnoten sein.
A.2 Listofobjectlists-Knoten
Die bisherige Definition eines Knoten vom Typ Listofobjectlists sah in der AWS-DTD
bislang wie folgt aus.
<!ELEMENT listofobjectlists ((awslink | wolmpath), wolmpath)>
Die neue Definition muss korrekterweise wie folgt lauten.
<!ELEMENT listofobjectlists ((awslink | wolmclass), wolmpath)>
Der erste Ausdruck, der für die Selektion einer Liste von WOLM-Objekten zuständig ist,
muss wahlweise ein Knoten vom Typ Awslink oder Wolmclass sein, jedoch nicht vom Typ
Wolmpath.
A.3 Image-Knoten
Das überflüssige Attribut data wurde entfernt.
<!ATTLIST image
name CDATA #IMPLIED
data CDATA #REQUIRED
>
WOLM-Definiton
88
B WOLM-Definiton
Die Definition einer WOLM-Datei, wie sie bislang in den Arbeiten [Minßen] und [Köpke]
verwendet wurde, verwendet für die Bezeichnung von Attributen Ausdrücke der folgenden
Form.
<attribute name="Diplomand.attribute.name" type="String"/>
Dieser Ausdruck wird innerhalb einer WOLM-Datei verwendet, um innerhalb einer Klassendefinition ein Attribut mit der Bezeichnung „Diplomand.attribute.name“ zu definieren. Das
Zeichen „.“ wird als Bestandteil des Attributnamens verwendet. Der Grund für die Verwendung einer solchen Bezeichnung liegt in der internen Arbeitsweise des WOLM-Simulators
[Minßen] sowie der Admin-Seiten [Köpke].
Bei der Entwicklung des AWS-Builders [Langer], der eine initiale AWS aus einem WOLM
berechnet, wurde jedoch von Attributbezeichnungen der folgenden Form ausgegangen.
<attribute name="DiplomandName" type="String"/>
Das Zeichen “.” wird nicht für die Bezeichnung von Attributen verwendet, da dies innerhalb
der AWS zu Mehrdeutigkeiten führen würde. Ein Beispiel soll anhand eines Wolmpath
gegeben werden.
Text T1 = Obj.Diplomand.attribute.name
In der AWS würde der Knoten Obj als Object-Knoten, der eine Referenz auf ein Objekt des
WOLM gespeichert hat, erkannt. Der dann folgende Ausdruck „Diplomand.attribute.name“
würde als Pfad auf dem referenzierten WOLM-Objekt gedeutet und nicht als Bezeichnung für
ein einziges Attribut erkannt. Um Probleme dieser Art zu umgehen muss bei der Definition
eines WOLM zukünftig auf das Zeichen „.“ bei der Attributbezeichnung verzichtet werden.
Bei der Erzeugung einiger Beispiel-AWS im Rahmen dieser Arbeit wurde das Zeichen „.“
durch das Zeichen „:“ ersetzt (Beispiele siehe beiliegende CD-ROM).
AWS-State-DTD
C AWS-State-DTD
<?xml version = '1.0' encoding = 'utf-8' ?>
<!ELEMENT awsstate (project?)>
<!ELEMENT project (page|text|image|link)*>
<!ATTLIST project
id
CDATA
#REQUIRED
startpage CDATA
#REQUIRED
>
<!ELEMENT page
(field|text|image|textinput|hiddentextinput|button)*>
<!ATTLIST page
id
CDATA
#REQUIRED
listid
CDATA
#IMPLIED
>
<!ELEMENT field
(field|text|image|textinput|hiddentextinput|button)*>
<!ATTLIST field
id
CDATA
#REQUIRED
listid
CDATA
#IMPLIED
>
<!ELEMENT text (const, link?)>
<!ATTLIST text
id
CDATA
#REQUIRED
>
<!ELEMENT image (const, link?)>
<!ATTLIST image
id
CDATA
#REQUIRED
>
<!ELEMENT textinput (const)>
<!ATTLIST textinput
id
CDATA
#REQUIRED
>
<!ELEMENT hiddentextinput (const)>
<!ATTLIST hiddentextinput
id
CDATA
#REQUIRED
>
<!ELEMENT button (const, action*, link?)>
<!ATTLIST button
id
CDATA
#REQUIRED
>
89
AWS-State-DTD
<!ELEMENT link (#PCDATA)>
<!ATTLIST link
id
CDATA
#REQUIRED
>
<!ELEMENT action (params?)>
<!ATTLIST action
id CDATA #REQUIRED
precedence CDATA #IMPLIED
wolmobject CDATA #REQUIRED
method CDATA #REQUIRED
>
<!ELEMENT params ((const | cvalue)+)>
<!ELEMENT const (#PCDATA)>
<!ELEMENT cvalue (#PCDATA)>
90
CD-ROM
91
D CD-ROM
Die beiliegende CD-ROM enthält die vollständige Arbeit in Form einer PDF-Datei, das
entwickelte JAVA-Programm, die aktuelle AWS-DTD und AWS-State-DTD, sowie diverse
AWS- und WOLM-Beispieldateien.
Herunterladen