|
From: Edmund H. <so...@us...> - 2002-05-19 18:45:37
|
Update of /cvsroot/xpg-xml/doc
In directory usw-pr-cvs1:/tmp/cvs-serv23785
Modified Files:
Seminarbericht.gdf Seminarbericht.tex
Added Files:
Seminartemplate.tex
Log Message:
seminarbericht update
--- NEW FILE: Seminartemplate.tex ---
\documentclass[oneside,a4paper,10pt]{report}
\usepackage{german}
\usepackage{isolatin1}
% hyphenation of words with umlauts: results in ugly font!
%\usepackage[T1]{fontenc}
%\usepackage[latin1]{inputenc}
\usepackage[dinodraft,german]{dino}
% ---------- change paragraph layout --------------------
\parskip1.2ex % Vertikaler Abstand zwischen Absaetzen
\parindent0cm % Nicht einrücken bei neuem Absatz
% ---------- change layout of page --------------------
%\usepackage{geometry}
%\geometry{a4paper,left=3cm, right=2cm, top=2cm, bottom=1cm}
% works quite ok:
%\textheight 250mm
%\topmargin -20mm
%\headheight 10mm
%\headsep \baselineskip % distance between header and text
%\topskip 10mm % height of header-line
%\textwidth 160mm
%\oddsidemargin 0mm
%\evensidemargin 0mm
%\voffset -5mm
% ---------- change name of tables --------------------
\renewcommand{\tablename}{Tabelle}
\global\def\tableCaption{\tablename}
% ------------------- settings for pdf documents ----------------------------
\expandafter\ifx\csname pdfoutput\endcsname\relax
\else
\hypersetup{backref,
pdfauthor={\ehaselwanter},
pdftitle={Seminarbericht XPG-XDML},
pdfsubject={},
% colorlinks=true,
%% linkcolor=webgreen, %defined below
%% filecolor=webbrown, %defined below
%% citecolor=webgreen, %defined below
% pdfpagemode=None,
a4paper=true,
% bookmarksopen=false
}
%
%Define some eye-pleasing colors for this document
%
% \definecolor{webgreen}{rgb}{0,.5,0}
% \definecolor{webbrown}{rgb}{.6,0,0}
\fi
\setcounter{page}{0}
\begin{document}
\chapter{Das Framework, ein komponentenbasierter Ansatz}
Für das Framework können drei unterschiedliche Gruppen von
Benutzern der Software indentifiziert werden: Der {\em Endanwender},
respektive der Autor von Dokumenten, der ausschließlich daran interessiert ist, seine
Dokumente gemäß der entsprechenden (\ac{ac:Xml}) Struktur - d. h. unter
Verwendung eines bereits genau definierten XML Schemas - zu verfassen. Der
{\em Dokument Entwickler}, der verschiedene Dokumentarten klassifiziert
und die jeweiligen Schematas dazu festlegt und die entsprechendern
Transformationen entwickelt, mit denen er das Basislayout der Zielformate
festlegt. Und der {\em Systementwickler}, der den Kern des Systems entwirft
und ihm weitere Funktionalität hinzufügen kann. Um dem zu entsprechen wurde ein
Framework konzipiert, das es erlaubt auf verschiedene Art und Weise
erweitert und eingesetzt zu werden.
\section{Ein einfaches Beispiel}
Um nun die Grundstrukturen und Vorgangsweisen des Frameworks zu skizzieren
betrachten wir vorerst ein einfaches Beispiel. Wir wollen ein Eingabedokument
das im XML-Format vorliegen soll in ein konkretes Zielformat, in diesem Fall
wählen wir HTML, übersetzten. Als erster Schritt muß eine
Beschreibung des Sourcedokumentes - sozusagen einer Dokumentenklasse -
modelliert werden. Der Einfachheit halber wird in diesem nur ein Element
\texttt{<doc>} und ein Element \texttt{<title>} verarbeitet.
Die Information, welche mit dem \texttt{<title>} Element umschlossen wird,
soll in das HTML-Ausgabedokument übernommen werden.
In XML Syntax sieht dieses Beispiel dann folgendermaßen aus:
\texttt{simpledoc.xml}:
\begin{verbatim}
<doc
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="simpledoc.xsd">
<title>Title Definition</title>
</doc>
\end{verbatim}
Um garantieren zu können, dass die Verarbeitung dieses Dokumentes durch das Framework
korrekt abläuft, muss zu dem Eingabedokument ein XML-Schema (siehe
\ref{subsec:Schema}, S. \pageref{subsec:Schema}) entworfen
werden. Ausserdem ist damit eine ganze Klasse von Dokumenten spezifiziert.
\texttt{simpledoc.xsd}:
\begin{verbatim}
<?xml version="1.0" standalone="no"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="doc">
<xsd:complexType>
<xsd:all>
<xsd:element name="title" type="xsd:string"/>
</xsd:all>
</xsd:complexType>
</xsd:element>
</xsd:schema>
\end{verbatim}
Betrachten wir nun die Abarbeitung dieses Dokumentes im Hinblick auf unser
Ziel, daraus ein HTML Dokument zu machen. Im Eingabedokument sind durch seine
(XML) Struktur folgende Informationen implizit enthalten:
\begin{itemize}
\item \texttt{<doc>} - Drei Informationen: Erstens, dass das Dokument
begonnen hat, zweitens das Auftreten eines \texttt{<doc>} Elementes und
drittens, dass das File \texttt{simpledoc.xsd} das zugehörige XML-Schema ist.
\item \texttt{<title>} Das Auftreten des \texttt{<title>}-Elementes
\item ``\texttt{Title Definition}'' - Alle Zeichen zwischen dem \texttt{<title>} und dem
\texttt{</title>} Element, in diesem Fall die Zeichenfolge ``\texttt{Title Definition}''
\item \texttt{</title>} - Das Auftreten des \texttt{</title>}-Elementes
\item \texttt{</doc>} - Das Auftreten des \texttt{</doc>}-Elementes und das
Ende des Dokumentes
\end{itemize}
Bei einer sequentiellen Abarbeitung dem sogenannten {\em Parsen} des Dokumentes kann man die Folge der
Informationen als Folge von Ereignissen (Events), die etwas bewirken können,
auffassen (im Detail siehe \ref{subsec:DerParser}, S.\pageref{subsec:DerParser}).
Dieses XML-Dokument, das dem zugehörigem XML-Schema genügt, ist nur ein Dokument
aus der Menge der Dokumente die mit dem XML-Schema beschrieben werden. Wir
müssen auf alle Kombinationen respektive Reihenfolgen dieser Ereignisse
reagieren können, die das entworfene XML-Schema eindeutig und überprüfbar
vorgibt. Somit ergibt sich für diese Dokumentenklasse das in Abbildung
\ref{fig:statemachine} dargestellte Ablaufdiagramm, das alle möglichen und
gültigen Pfade enthält.
\image[1.0]{images/bspSimple}{Das Ablaufdiagramm zum \texttt{<doc>} Beispiel }{}{fig:statemachine}
Das alleine stellt allerdings nur eine theoretische Betrachtung aller gewünschten Abläufe der Ereignisse
dar. Wie man am Ablaufdiagramm leicht erkennt, kann dieses Verhalten mit einem
dem Diagramm entsprechendem endlichen Automaten (Finite-State-Machine) FIXXME Referenz erreicht
werden. Dabei bilden die Ereignisse die auslösenden Momente (Trigger, Transitionen) von einem gültigen
Zwischenzustand (State) zum nächsten gültigen Zwischenzustand. Diese Zustände
müssen nicht zwingend verschieden sein. Jedes Dokument wird zumindest zwei
{\em ausgezeichnete} Zustände haben, den Dokument-Start-Zustand und den Dokument-Ende-Zustand.
Die Statemachine ist das Kernstück dieses Frameworks (siehe \ref{sec:DasDesigndesFrameworks},
S. \pageref{sec:DasDesigndesFrameworks}). Es ist nun eine von obigem Schema abgeleitete
Beschreibung dieser erforderlich, damit sie dann das Dokument (respektive
die ganze mit obigem Schema beschriebene Dokumentenart) {\em versteht}. Diese
Beschreibung erfolgt zweckmäßiger Weise auch mittels eines validierbarem
XML-Dokumentes, da wir verschiedene Dokumentklassen verarbeiten wollen und damit auch
entsprechend unterschiedliche endliche Automaten aufbauen müssen. Für die
Validierung muss diese Beschreibung auch einem XML-Schema genügen, dem XML-Schema für
die Statemachine (im Anhang auf Seite \pageref{sec:Schema}).
Bereits an diesem kleinem Beispiel kann man erkennen, dass die Anzahl der Zustände
schnell sehr umfangreich wird. Allerdings muss dies nur einmal für eine
Dokumentklasse gemacht werden. Nachfolgend sind die wesentlichen Abschnitte dieses
XML-Dokumentes, dem sogenannten Konfigurationsfile der Statemaschine, für diese
Dokumentklasse, dargestellt.
1. Angabe des Schemas
% \footnotesize
\begin{verbatim}
<?xml version="1.0" standalone="no"?>
<statemachine
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="StateMachineConfig.xsd">
\end{verbatim}
2. Die Liste aller gültigen Zustände. Der Startzustand muss besonders
ausgezeichnet sein, damit man einen gültigen Ausgangszustand der
Statemachine hat.
\begin{verbatim}
<states>
<startstate>STATE_TOP_LEVEL_FILE</startstate>
<state>STATE_TOP_LEVEL_DOC</state>
<state>STATE_DOC_TITLE_DEF</state>
<state>STATE_FINISHED</state>
</states>
\end{verbatim}
3. Die Liste aller zugelassenen Transitionen. Die Zustände des endlichen
Automaten werden vor den Transitionen bekanntgegeben, damit schon beim
Parsen festgestellt werden kann, ob die Transitionen eine gültige
Zustansänderung beschreiben.
\begin{verbatim}
<transitions>
<transition>
<beginstate>STATE_TOP_LEVEL_FILE</beginstate>
<nextstate>STATE_TOP_LEVEL_DOC</nextstate>
<element type="start">doc</element>
<classname>WriteGeneralHeaderTransition</classname>
</transition>
.
.
.
<transition>
<beginstate>STATE_TOP_LEVEL_FILE</beginstate>
<nextstate>STATE_FINISHED</nextstate>
<element type="enddoc" />
<classname>StopMachineTransition</classname>
</transition>
</transitions>
</statemachine>
\end{verbatim}
%\normalsize
Sämtliche für die Übersetzung des XML-Sourcedokuments notwendigen
Dokumente (Schemata, Konfigurationsfile, ...) sind nun
vorhanden.
Ziel unserer Bemühungen ist es aber aus einem XML-Eingabedokument ein
HTML-Ausgabedokument zu machen. Es fehlt also noch etwas entscheidendes,
nämlich die Anweisungen, welche die Generierung des Outputs in der Zielsprache -
für dieses kleine Beispiel HTML - übernehmen. Diese Anweisungen werden bei der
Beschreibung Transitionen als Klassenname angegeben (im Detail siehe \ref{subsec:Transitions}
, S.\pageref{subsec:Transitions}).
Die hier benötigten Anweisungen bzw. Klassen sind nun:
\begin{description}
\item [PrimitiveTransition] Diese implementiert nur das Interface
einer Transition und trägt weiter nichts zum Output bei. Sie wird
benötigt um von einem Zustand der Statemachine in einen anderen zu wechseln.
\item [WriteGeneralHeaderTransition] Diese schreibt den
allgemeinen Kopf des Outputdokuments. Im diesem Beispiel mit \ac{ac:Html}
als Zielsprache ist dies das öffnende \texttt{<html>} Tag, das komplette
\texttt{<head>} Element und das öffnende \texttt{<body>} Tag.
\item [StoreDocTitleTransition] Diese speichert den Inhalt des
\texttt{<title>} Elements des \ac{ac:Xml} Eingabedokuments (im Detail siehe
\ref{subsec:VerwaltungVonInputdaten}, S.\pageref{subsec:VerwaltungVonInputdaten}).
\item [WriteDocTitleTransition] Diese schreibt den Inhalt des
\texttt{<title>} Elements des \ac{ac:Xml} Source in den Output, eingebettet
in ein \texttt{<h1>} Element.
\item [WriteGeneralFooterTransition] Diese schreibt nun das generelle
Dokumentende des Outputs; für das \ac{ac:Html} Beispiel ist dies das
schließende \texttt{</body>} und das schließende \texttt{</html>} Tag.
\item [StopMachineTransition] Diese wird aufgerufen, wenn der komplette
Input abgearbeitet wurde (EOF bei einem Eingabedokument). Sie stoppt die
Statemachine und stellt somit sicher dass das Framework korrekt terminieren kann.
\end{description}
Mittels dem Konfigurationsfile wird nun also der Statemachine beigebracht
Sourcedokumente, welche dem entsprechenden Schema genügen, zu {\em
verstehen}.
Mit Hilfe der entsprechenden Transitionen generiert die Statemachine beim
Abarbeiten des Inputs den gewünschten Output. Für dieses einfache Beispiel
kann der generierte Output dann folgendermaßen aussehen:
\begin{verbatim}
<html>
<head>
<title></title>
</head>
<body>
<h1>Title Definition</h1>
</body>
</html>
\end{verbatim}
\section{Das Design des Frameworks}
\label{sec:DasDesigndesFrameworks}
Bereits für das vorangehende einfache Beispiel ist eine gewisser Aufwand
notwendig, um zu dem gewünschten Ergebnis zu gelangen. Zusätzlich zu dem eigentlich zu
übersetzenden Eingabedokument mußten ein XML-Schema für dieses, ein XML-Schema
für die Statemaschine, ein Konfigurationsfile und eine Reihe von Transitionen
erstellt werden. Es wurde allerdings der gesamte Aufwand aller
Benutzergruppen {\em Endanwender}, {\em Dokument Entwickler} und {\em Systementwickler} dargestellt. Unterteilt
man nun wieder in diese drei einführend erkannten Gruppen von Benutzern der
Software, dann relativiert sich dieser Aufwand recht rasch wieder:
Der {\em Systementwickler}, welcher den funktionalen Kern des Frameworks
entwickelt, entwirft dazu auch das entsprechende XML-Schema für das
Konfigurationsfile der Statemachine. Dieses Statemachineschema wird
zusammen mit dem Kern des System nur einmal geschrieben und ändert sich in
folge nur bei gravierenden Eingriffen in die Kernfunktionalität des Systems.
Der {\em Dokument Entwickler} schreibt danach für eine ganze Klasse von
Dokumenten ein dem Statemachineschema genügendes Konfigurationsfile mit
welchem dann der Statemachine beigebracht werden soll, Dokumente dieser Klasse zu
{\em verstehen}. Korrespondierend zu dem Konfigurationsfile entwickelt dieser ein
XML-Schema für die Dokumente dieser Klasse. Auch entwickelt er die notwendigen
Transitionen (siehe auch \ref{subsec:Transitions}) die den Output für diese
Klasse von Dokumenten generieren sollen. Somit kreiert er für eine bestimmte Klasse
von Sourcedokumenten ein komplettes wiederverwendbares Package (siehe
\ref{sec:Packages}) - bestehend aus XML-Schema der Dokumentklasse,
Konfigurationsfile der Statemaschine und Transitionen - rumd um den
Systemkern.
Der {\em Endanwender} nimmt nun Systemkern und eines dieser Packages und muß
nur das Sourcedokument erstellen - dieses muß alelrdings dem im ausgewählten Package enthaltenen Schema
entsprechen - und kann somit den Output in der gewünschten Zielsprache
generieren.
Ähnlich der Unterteilung in verschiedene Benutzergruppen des Frameworks kann
dieses nun auch aus funktionaler Sichtweise dreigeteilt werden (siehe Abbildung
\ref{fig:Design}).
\image[1.0]{images/Design}{Framework: funktionale Darstellung}{}{fig:Design}
Der {\em Parser} (siehe \ref{subsec:DerParser}, S.\pageref{subsec:DerParser}) welcher das Sourcedokument parst und diesem
entsprechend Events generiert. Die {\em Statemachine} (siehe
\ref{sec:Statemachine}) welche diese Events dann verarbeitet und
dem entsprechend die {\em Transitionen} (siehe \ref{subsec:Transitions})
triggert, mit deren Hilfe schlußendlich der gewünschte Output erzeugt wird.
Bei den Transitionen kann man außerdem noch unterscheiden zwischen
sogenannten {\em Core }-Transitionen - das sind gleichsam eine kleine Anzahl von
Basistransitionen, die direkt zum Framework gehören - und den Transitionen
in den einzelnen {\em Packages} (siehe \ref{sec:Packages}) zur jeweils
entsprechenden Klasse von Dokumenten die damit verarbeitet werden soll.
\subsection{Der Parser}
\label{subsec:DerParser}
Dieser Teil des Frameworks übernimmt das Einlesen, sprich Parsen, des
XML-Sourcedokuments. Da beim Parsen mit \ac{ac:Dom} - Technologie die Gefahr
besteht, dass es bei großen Dokumenten zu einem Speicherproblem kommen kann,
da der gesamte \ac{ac:Dom}-Baum des Dokumentes einfach zu groß werden könnte, verwenden wir einen
ereignisbasierten Parser.
Wir haben uns für SAX2 und Xerces, den XML-Parser der das
\ac{ac:Sax} - Interface implementiert entschieden (siehe auch
\ref{subsec:Sax}, S.\pageref{subsec:Sax})\cite{xerces}\cite{sax}.
Dazu wird über die \texttt{XMLReaderFactory} der Xerces-SAXParser als
\texttt{XMLReader} erzeugt. Dem \texttt{XMLReader} muss nun ein Handler der das
\texttt{DocumentHandler}-Interface implementiert bzw. von von der
Referenzimplementierung, der Klasse \texttt{DefaultHandler}
abgeleitet ist, bekanntgegeben werden. Wir haben einen \texttt{XMLHandler}, der \texttt{DefaultHandler} abgeleitet ist, implementiert. Hier wird
die Verbindung zur \texttt{Statemachine} hergestellt, indem der \texttt{XMLReader} die
Callback-Methoden des \texttt{XMLHandlers} aufruft, in denen wiederum die
Callback-Methode der \texttt{Statemaschine} aufgerufen wird.
Für ein korrektes Funktionieren des Frameworks muss beim Parsen festgestellt
werden, ob das Eingabedokument korrekt ist. Technisch kann das auf die zwei
vorgestellten Arten, mithilfe einer DTD (siehe \ref{subsec:Dtd},
S.\pageref{subsec:Dtd}) oder eines XML-Schemas (siehe \ref{subsec:Schema},
S.\pageref{subsec:Schema}) geschehen. Aufgrund der Vorteile des XML-Schemas
gegenüber einer DTD verwenden wir hier XML-Schema zur Spezifikation der Eingabedokumente.
Somit muss der \texttt{XMLReader} noch auf Validierung mit XML-Schema
gestellt werden, damit wir auf fehlerhafte Eingabedokumente reagieren können (siehe \ref{sec:Fehlerbehandlung}, S.\pageref{sec:Fehlerbehandlung}).
Hierfür sieht SAX2 die Methode \texttt{setFeature} der Klasse
\texttt{XMLReader} vor. Die entsprechenden Attribute für Validierung und XML-Schema sind nun:
\begin{verbatim}
http://xml.org/sax/features/validation
http://apache.org/xml/features/validation/schema
\end{verbatim}
Der Parser leitet nun die Events XML-Input an die
Statemachine weiter.
\subsection{Die Statemachine}
\label{sec:Statemachine}
Die Statemachine ist die Implementierung eines deterministischen endlichen Automaten. Durch
den XML-Input kommt es zu einer Zustandstransformation
(Transition). Dadurch ergibt sich die gewünschte Ablaufsteuerung der
Verarbeitung der SAX-Events, die durch das Parsen des XML-Eingabedokumentes
hervorgerufen werden. Zusätzlich wird
bei den Transitionen die Ausführung des zu Ihnen gebundenen Java Codes
ausgelöst. Dies stellt somit einen gewünschten Seiteneffekt der
Statemachine dar. Da der gebundene Java Code beliebig und
``außerhalb'' der Statemachine Implementierung ist, können damit SAX
eventgesteuert Aktionen ausgeführt werden, die die Inputdaten (FIXXME
und alle anderen....) verarbeiten.
FIXXME: Referenz Statemachine / endlicher Automat
\subsection{Schemata und Konfigurationsfile}
Aus dem gewünschten Schema des zu verarbeitenden Dokumentes muss eine
Konfiguration der verarbeitenden Statemachine, die dem Schema der
Statemachine genügt, abgeleitet werden.
\subsection{Verwaltung von Inputdaten}
\label{subsec:VerwaltungVonInputdaten}
FIXXME: XMLElement / Stack und DataObject erklären
\subsection{Die Transitionen}
\label{subsec:Transitions}
Die Transitionen erledigen die Hauptarbeit und generieren im Endeffekt
dann den Output.
Interface der Transitionen:
\begin{verbatim}
public interface Transition
{
public String transitionTriggered(Input input,
State from_state,
State to_state,
StateMachine machine,
DataObject data)
throws Exception;
}
\end{verbatim}
Aus funktioneller Sicht kann man die Transitionen in speichernde und
schreibende unterteilen: die speichernden legen den aktuellen Input
(eventuell in modifizierter Form) im DataObject ab und die schreibenden
sind im Gegensatz dazu verantwortlich aus all den Informationen im
DataObject
sequentiell den gewünschten Output zu generieren.
Weiters gibt es sogenannte {\em Core }-Transitionen, welche zum Kern des
Systems gehören (im Gegensatz zu den Transitionen in den einzelnen
Packages).
Diese haben entweder nur eine gewisse Basisfunktionalität oder werden in
der Initialisierungsphase benötigt. Core-Transitionen sind nun folgende:
\begin{description}
\item [PrimitiveTransition]
\item [IgnoreCharsTransition]
\item [RegisterStateTransition]
\item [RegisterStartStateTransition]
\item [RegisterTransitionTransition]
\item [SetSearchPathTransition]
\item [StoreDataTransition]
\item [ClassLoaderTransition]
\item [StopMachineTransition]
\end{description}
\subsection{Packages}
\label{sec:Packages}
\subsection{Konfiguration}
Um mit einer Statemachine arbeiten zu können muss, diese zuerst
aufgebaut werden. Das heißt es müssen die zulässigen States und die
dazugehörigen Transitionen erst registriert werden. Diese sind jedoch
abhängig von der gewünschten Funktionsweise jeweils
unterschiedlich. Es wird also eine Möglichkeit benötigt die
Statemachine zu beschreiben. Um möglichst flexibel zu bleiben, passiert
das mit einem Konfigurationsdokument, welches dem Statemachine Schema
genügen muss.
Das Konfigurationsdokument wird, wie schon bei der Erklärung der SAX API
{\em
eventbasiert} geparst. Zum Registrieren
der States und Transitionen in der Statemachine gibt es nun zwei
Alternativen: entweder wird dies direkt in die Callbacks des SAX
Parsers hineinverpackt, oder man verwendet dazu wiederum eine
Statemachine, welche jedoch ``hardcodiert'' ist. Wir haben uns
entschlossen die zweite Alternative mit der ``hardcodierten''
Statemachine, die sogenannte {\em InitStateMachine },
weiterzuverfolgen.
Im Konfigurationsdokument stehen alle notwendigen Informationen, um
die gewünschte Statemachine aufbauen zu können. Das Schema für das
Konfigurationsdokument ist unabhängig von den unterschiedlichen
Verwendungszwecken immer das selbe. Da die Verarbeitung des
Konfigurationsdokuments hardcodiert ist bedingt eine Änderung dieses
Schemas einen Eingriff in den Sourcecode!
Das Konfigurationsdokument enthält die States für die Statemachine,
inklusive einem ausgezeichnetem Startstate. Weiters enthält es die
Transitionen, wobei jede Transition einen Beginstate, einen Nextstate,
ein Element, durch welches sie getriggert wird, und die Aktion als
Klassenname.
Wobei der Klassenname wegfallen kann, wenn
keine Aktion benötigt wird, dies entspricht dann einer
DefaultTransition. Weiters muss im Konfigurationsdokument noch der
Pfad für die Transitionen angegeben werden.
Genau genommen werden allerdings nicht direkt die entsprechenden
Aktionen/Klassen registriert sondern nur eine sogenannte {\em
ClassLoaderTransition } welche den Namen der entsprechenden Klasse
dann beinhaltet und bei Erhalt eines Triggers dann mittels dem {\em
Factory Pattern} FIXXME (Gamma et al) diese zur Laufzeit nachlädt und
sogleich
einen Trigger auf diese setzt, sie also auch gleich ausführt. Somit
werden die Klassen erst beim Auftreten eines entsprechenden Triggers
nachgeladen. Auch wenn eine Transition mehrmals benötigt wird wird sie
nur einmalig nachgeladen, da diese Implementierung des Factory Patterns in
Java
intern ein Caching betreibt.
\section{Fehlerbehandlung}
\label{sec:Fehlerbehandlung}
Bei der Verarbeitung von Dokumenten können verschiedene Arten von Fehlern
auftreten.
Einerseits Fehler des Parsers und der Statemachine die aufgrund von
``korrupten`` Inputdateien auftreten koennen, andereseits Fehler die durch
Transitionen erzeugt werden.
\subsection{Parser Fehler}
Das \ac{ac:W3c} hat in der {\em XML Recommandation 1.0} \cite{rec-xml} zwei
Arten von Fehlern definiert.
\begin{description}
\item [error:] Eine Verletzung der XML Spezifikation, es sind die Konsiquenzen
nicht definiert. Ein Beispiel hierfür ist bei einem Validierenden Parser,
wenn das Dokument nicht dem angegebnen Schema bzw. der \ac{ac:Dtd}
entspricht.
\item [fatal error:] Eine Verletzung der XML Spezifaktion, es darf die normale
Verabeitung vom Parser nicht fortgesetzt werden. Diese Art von Fehler tritt
zum Beispiel auf wenn ein XML Dokument nicht wohlgeformt ist.
\end{description}
\textbf{FIXXXME --> thick red line} \\
Das SAX API stellt zur Verarbeitung dieser Fehler das Interface
\texttt{ErrorHandler} zur Verfügung. Um von einer Applikation ein eigene
Fehlerbehandlung zu gewährleisten, muss der \texttt{ErrorHandler}
beim XML Reader registiert werden. Es werden dann vom SAX Parser Fehler an
diesen Handler gemeldet.
Es müssen in diesem Interface die zwei
Callback Funtktionen \texttt{error} und \texttt{fatalError} implementiert
werden.Die Informationen über den Aufgetretenen Fehler werden den beiden
Funktionen mittels \texttt{SAXParseException} als Parameter übergeben.
Das Standardverhalten dieser Beiden Funktionen ist, dass sie gar nichts tun.
Dies ist aber im Fall der Statemachine ein nicht wünschenswertes verhalten,
da ja vom \texttt{???Handler} die Trigger fuer die einzelnen Transitionen
ausgelöst werden und ein nicht wohlgeformtes bzw. nicht gültiges XML Dokument
falsche oder nicht Vorhandene Transitionen auslösen kann.
Es werden deshalb Fehler ausgegeben, die Verarbeitung des Inputs abgebrochen
und die Statemachine ``sauber`` heruntergefahren.
\textbf{end FIXXXME --> thick red line} \\
\subsection{Statemachine Fehler}
Da ja die Statemachine dynamisch in Abhängigkeit der zu Verarbeiteten
Dokumentklassen aufgebaut wird können auch hier verschiedene Fehler auftreten,
die noch nicht vom Parser entdeckt und an das Framework gemeldet wurden.
Hierbei handelt es sich um Fehler die bei der Initalisierung der Statemachine
durch eine Konfigurationsdatei auftreten können, welche zwar dem XML Schema
für diese Dokumentklasse entspricht jedoch trotzdem nicht korrekt verarbeitet
wird. Solche Fehler sind zum Beispiel der Versuch mehrere States mit dem
gleichen Namen zu registrieren, oder die Registrierung einer Transition deren Anfangs- und/oder der Endstate nicht registriert wurde.
Da durch ein XML Schema nur die Struktur eines Dokumentes vorgegeben, der
Inhalt jedoch
nur rudimentär eingschränkt werden kann (siehe
Restrictionbase XMLSchema ??? Recomendation) können diese Fehler nicht vom
Parser gefunden werden.
Um die Transparenz, wie das Framework arbeitet, für den
Dokumententwickler zu wahren, wurde die Designentscheidung getroffen, dass die
Initialisierung der Statemachine bei einem solchen Fehler abgebrochen wird.
Es könnte beim Versuch einen solchen Fehler bei der Initialsierung
auszubessern nicht garantiert werden, dass die Statemachine das geplante
Verhalten zeigt.
Bei der eigentlichen Verarbeitung kann es jedoch auch zu Eingaben kommen die
von der Statemachine nicht interpretiert werden können.
Ein solcher Fehler tritt auf, wenn es für einen Input im gerade aktuellen State
keine geine gültige Transitionen gibt. Dies bewirkt, dass das Dokument nicht
korrekt bis zum Ende verarbeitet werden kann und deshalb wird ein solcher
Fehler wie ein Parser Fehler behandelt. Warum kann dies nun auftreten wo
doch der Parser validierend agiert? Einer der Gründe ist, dass die
Statemachine für eine Dokumentklasse initialisiert wurde die nicht dem XML -
Schema des zu verarbeitenden Dokuments entspricht.
Für den den Parser ist dieses Dokument jedoch valide, die Statemachine
versteht es jedoch nicht und liefert dann diesen Fehler.
\textbf{FIXXXME --> thick red line} \\
Die Transitionen können auch Fehler verursachen, wo thalze aber nicht weiss
welche.
\textbf{FIXXXME --> thick red line} \\
\chapter{Anwendungsbeispiele}
\label{sec:Anwendungsbeispiele}
\section{Konfiguration}
Ein Einsatzbeispiel für das Konzept der Statemaschine findet sich
bereits im Gesamtkonzept des komponentenbasierten Ansatzes zur
Übersetzung von Dokumenten in andere Formate mittels einer
Statemachine wieder. Da die hier zur Übersetzung verwendete
Statemachine sehr flexibel sein muß - sie muß mit unterschiedlichen
Eingangsformaten (vorerst unterschiedlichen XML-Schemata) arbeiten und
in unterschiedliche Ausgansformate (z.B. \ac{ac:Html}, LaTeX, ...) übersetzen
können - ist es unmöglich bereits zur Compilezeit alle möglichen Stati
und Transitionen berücksichtigen zu können. Das bedeutet die
Konfiguration dieser Statemachine - das Registrieren der benötigten
Stati und Transitionen - kann erst zur Laufzeit erfolgen. Die
notwendigen Informationen zur Konfiguration werden in ein XML-File -
das sogenannte {\em Configfile } - geschrieben, welches einem
vorgegebenen Schema (dem {\em Configfile-Schema }) gehorcht. Dieses
wird mittels SAX geparst, welcher seine Events an eine
(Konfigurations-)Statemachine weitersendet, welche nun allerdings
hardcodiert und mit den enthaltenen Stati und Transitionen an das
vorgegebene Schema angepasst ist. Diese Konfigurations-Statemachine
übernimmt nun das Registrieren der notweendigen Stati und Transitionen
in der für die Übersetzung benötigten Statemachine; das heißt das
Ergebnis der Konfigurationstatemachine ist wiederum eine Statemachine,
welche nun flexibel konfiguriert ist und zum Übersetzen von
XML-Dokumenten in beliebige Formate eingesetzt werden kann.
\section{Problemstellung XPGForms}
Ein gängiges Problem in der Webseitengestaltung bzw. Programmierung
ist das Verarbeiten von Daten, die vom User eingegeben werden. Es ist
sinnvoll, einen generellen Ansatz für dieses Problem zu schaffen, da
die Abläufe immer dieselben sind, nur die Repräsentation und die
verwendeten Daten ändern sich. Es wäre vom Vorteil, wenn ein Framework
existieren würde, dass diese Abläufe umfasst; es sollte für die
jeweiligen Projekte bzw. Webseiten nur noch eine Datenbeschreibung vom
Programmierer in einer geeigneten Form modelliert werden. Der Grafiker
kann dazu parallel Templates entwerfen, in die per Platzhalter die
Datenfelder eingefügt werden können.
Eine geeignete Lösung wäre dafür, die Datenfelder in einem geeigneten
Format (XML bzw. XML Schema bieten sich an) zu beschreiben. Durch
verschiedene Transformationen wird eine Ablaufsteuerung generiert, die
das User Interface für den Benutzer bereitstellt. Die Erzeugung der
eigentlichen Web Formulare passiert also automatisiert. Dies hat nicht
nur den Vorteil einer Zeitersparnis, sondern durch die Formalisierung
des Prozesses werden Fehlerquellen der Implementierung minimiert. Die
XPG State Machine kommt an dem Punkt der Umwandlung von XML in PHP ins
Spiel; von einer Quellensprache (XML) wird in eine mögliche
Zielsprache (PHP) transformiert. Es wäre jedoch leicht möglich, auch
z. B. JSP oder ASP damit zu erzeugen.
\section{\LaTeX: flexible Handhabung ganzer Dokumentblöcke}
Während der Erstellung größerer Dokumente kann es immer wieder vorkommen,
dass es notwendig ist Teile eines Dokuments umzustrukturieren, ganze
Blöcke des Dokuments zu verschieben. Dabei kann es passieren, dass aus
einem ursprünglich eigenem Kapitel nunmehr ein Unterkapitel wird oder
umgekehrt aus einem anfangs nur als kleines Unterkapitel gedachtem Block
nun ein eigenes großes Kapitel wird. Das bedeutet aber, dass Änderungen in der
Dokumentenhierarchie vorgenommen werden. Nun ist jedoch in
Textbeschreibungssprachen wie \ac{ac:Latex}, dass diese Heirarchie eines
Dokuments eine sehr genau vorgegebene Form haben muß - bei \ac{ac:Latex}
sind dies der Reihe nach {\em part, chapter, section, subsection,
subsubsection, paragraph, subparagraph}. Dies bedeutet nun aber, wenn
bei solchen Umstrukturierungen aus Unterkapiteln eigene Kapitel werden
(und analog umgekehrt), dass diese Modifikationen der Dokumenthierarchie
händisch nachgebessert werden müssen: aus einem {\em section} wird ein
{\em chapter}, aus dem darin enthaltenen {\em subsection} wird ein
{\em section} und gleich weiter im ganzen verschobenen Block (respektive
umgekehrt wenn aus einem Kapitel ein Unterkapitel wird).
Dieses händische Nachbessern wird obsolet, wenn man in der
Dokumenthierarchie nur ein Element (z.B. {\em section }) kennt, unabhängig
von derjeweiligen Hierarchieebene - man dieses also beliebig ineinander
verschachteln kann. Aus der Tiefe dieser Verschachtelung erhält man dann
die Ebene der Hierarchie für die Übersetzung in ein Zielformat (wie
\ac{ac:Latex }) in dem man je Ebene einen unterschiedlichen Bezeichner hat.
Eine solche Dokumentenhierarchie kann nun zum Beispiel ein Aussehen
wie folgt haben:
\begin{verbatim}
<document>
<section>
<title>1. Kapitel</title>
<para> ... </para>
</section>
<section>
<title>2. Kapitel</title>
<para> ... </para>
<section>
<title>1. Abschnitt</title>
<para> ... </para>
</section>
<section>
<title>2. Abschnitt</title>
<para> ... </para>
</section>
</section>
</document>
\end{verbatim}
Der eigentliche Inhalt der einzelnen Abschnitte befindet sich hier in den
\texttt{<para>} Elementen, und wird entsprechend er weiters darin
enthaltenen Elemente ins Zielformat übersetzt. Die \texttt{<title>} Elemente
enthalten die überschriften der einzelnen (Unter-)Kapitel. Für die
\texttt{<section>} Elemente wir die jeweile Verschachtelungstiefe akkumuliert
(d.h. bei einen Starttag um eins erhöht und beim Endtag wieder um eins
erniedrigt) und entsprechend dieser dann der entsprechende Bezeichner in der
Zielsprache ausgewählt.
Zu obigem Beispiel kann nun die dazugehörige Dokumentenhierarchie in
\ac{ac:Latex} folgendermaßen aussehen:
\begin{verbatim}
\begin{document}
\section{1. Kapitel}
...
\section{2. Kapitel}
...
\subsection{1. Abschnitt}
...
\subsection{2. Abschnitt}
...
\end{document}
\end{verbatim}
\section{Rechnen}
Häufig kommt es vor, dann man eine ganze Menge von Daten als Input hat,
sich jedoch nicht für diese gesamte Datenflut interessiert, sondern nur
ein paar davon abgeleitete Daten benötigt. Das heißt wenn als Input zum
Beispiel eine ganze Tabelle mit Meßwerten zu Verfügung steht ist es möglich
daraus zusätzlich oder ausschließlich repräsentative Werte wie Maximalwerte,
Mittelwert, die Summe oder sonstige beliebige aus den Meßwerten generierbare
Daten. Das bedeutet aber gleichzeitig auch, dass bei einem etwaigen Update
der Inputdaten mit einem neuerlichen Übersetzen des Dokuments diese
generierten Daten im Output ebenfalls automatisch mit upgedatet werden.
Implementiert ist dies in dem Framework in folgender Weise, dass aufgrund des
Designs sämtliche Inputdaten der einzelen \ac{ac:Xml}-Elemente im zur
Datenspeicherung vorgesehenen \texttt{DataObject} (siehe
\ref{subsec:VerwaltungVonInputdaten},
S. \pageref{subsec:VerwaltungVonInputdaten}) gespeichert werden können. Es
können somit also auch ganze Tabellen oder Listen von Inputdaten dort
gesammelt abgelegt werden und am Ende dieser können dann daraus die benötigten
Daten, wobei dies beginnend von Extremwerten, Mittelwerten oder Summen bis hin
zu ganzen statistischen Berechnungen oder Verteilungen oder beliebeige andere
komplizierte Berechnungen sein können, akkumuliert und entsprechend in den
Output eingefügt werden.
Als einfaches Beispiel für diese Funktionalität wurde eine Liste
implementiert, aus deren Daten dann wahlweise der Mittelwert oder die Summe
berechnet werden und abschließend jeweils der Liste angefügt werden.
\section{Lebenslauf - 2 verschiedene Zielformate}
Ziel dieses auf den ersten Blick relativ einfachen Anwendungsbeispiel ist es
einen Lebenslauf zu erstellen und zu übersetzen. Dazu wurde auch ein eigenes
Schema entworfen, dass das Eingabeformat desselben beschreibt. Es besteht aus
einem ersten Teil welcher die gesamten persönlichen Daten wie Name, Geburtsdaten,
Adresse, Telefon und dergleichen enthält und anschließend einer Reihe von
Listen zu den einzelnen Themen wie zum Beispiel Schulbildung, beruflicher Werdegang,
weitere Qualifikationen und ähnlichen mehr. Außerdem sind noch als Attribute
eine Bezeichnung des Lebenslauf und eine Sprachauswahl vorgesehen.
Dieser Aufbau für das Eingabeformat des Lebenslauf wurde dadurch gewonnen,
da als erstes Zielformat {\LaTeX } gewählt wurde in Zusammenspiel mit einem
speziellen \ac{ac:Cv} Style. Die Übersetzung des Lebenslauf nach {\LaTeX } wurde
auch speziell auf die Verwendung dieses Styles abgestimmt.
Der Lebenslauf soll nun aber auch noch in andere Zielformate
(z.B. \ac{ac:Html}) übersetzt werden können. Dazu kann der Großteil der
Transitionen für die Übersetzung nach \LaTeX wiederverwendet werden und nur
jene die effektiv den Output formatieren, welche jedoch eine geringere Anzahl
darstellen, entsprechend adaptiert werden. Es können also wenn einmal die
Übersetzung in ein bestimmtes Format vorhanden ist mit relativ geringem
Aufwand Übersetzungen in andere Formate hinzugefügt werden.
\section{Diagramme}
In Geschäftsberichten, Jahresberichten, Marktanalysen, Erhebungen und noch
vielen anderen Dokumenten ähnlicher Art ist es erforderlich
verschiedenste Diagramme (wie z.B. Kurvendiagramme, Tortendiagramme, Blockdiagramme, ...)
ins gewünschte Enddokument einzufügen. Das heißt man hat eine Reihe von Daten
als Ausgangsbasis aus welchen man dann ein Diagramm beliebiger Art
erstellen muß um dieses anschließend in das Dokument einzubinden.
Bei diesem Framework gibt es nun dahingehend eine wesetliche Erleichterung, dass
es nur notwendig ist in das Sourcedokument die gesammelten Daten für das
Diagramm einzufügen, die Art des Diagramms anzugeben, welches gewünscht wird
und die dafür außer
den Daten noch notwendigen Angaben, und beim Übesetzen in das gewünschte
Zielformat wird dann automatisch das erforderliche Diagramm erstellt und in das
Enddokument eingebunden. Diese komfortable Vorgehensweise konnte gewonnen
werden durch das Einbinden des \texttt{Chart2D}-Packages (FIXXME: Referenz
sourceforge.net/projects/chart2d) mit welchen auf einfach Weise aus einer
Reihe von Daten verschiedene Arten von Diagrammen erstellt werden
können. Solche vom \texttt{Chart2D}-Package erstellten Graphiken werden
dann in Files gespeichert und diese werden dann in den Output eingebunden.
Der Dateninput kann also ähnliche Form wie folgt haben:
\begin{verbatim}
<chart>
<title>Quartalsumsätze 2001</title>
<list chart="pie">
<title>Quartalsumsätze</title>
<item caption="1. Quartal">127</item>
<item caption="2. Quartal">158</item>
<item caption="3. Quartal">113</item>
<item caption="4. Quartal">147</item>
</list>
</chart>
\end{verbatim}
Und dementsprechend wird dann folgene Graphik in das Enddokument eingebunden:
\image[1.0]{images/Quartalsumsätze}{}{Beispiel: generiertes Tortendiagramm}{fig:PieChart}
\section{Apache Servlet}
\chapter{Zusammenfassung und Diskussion}
nicht umgesetzte urds
\section{Zusammenfassung und Diskussion}
bla
\section{Ausblick}
bla
\end{document}
Index: Seminarbericht.gdf
===================================================================
RCS file: /cvsroot/xpg-xml/doc/Seminarbericht.gdf,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** Seminarbericht.gdf 18 May 2002 22:07:27 -0000 1.1
--- Seminarbericht.gdf 19 May 2002 18:45:27 -0000 1.2
***************
*** 258,261 ****
--- 258,264 ----
%------------------------------------------------------------
+ @entry{ac:Uri, URI, Uniform Resource Identifier}
+
+ %------------------------------------------------------------
@entry{ac:Url, URL, Uniform Resource Locator}
see also the glossary entry for \gls{gloss:Url}
Index: Seminarbericht.tex
===================================================================
RCS file: /cvsroot/xpg-xml/doc/Seminarbericht.tex,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** Seminarbericht.tex 19 May 2002 11:42:19 -0000 1.2
--- Seminarbericht.tex 19 May 2002 18:45:27 -0000 1.3
***************
*** 51,61 ****
\maketitle
! \section{Abstract}
! Jeder der schon einmal ein Dokument verfasst hat steht früher oder später vor
der Aufgabe dieses auch anderen Personen zugänglich zu machen. Meist ist
allerdings der Inhalt wertvoller als das Aussehen des Dokumentes. Vor allem
bei Wiederverwendung des enthaltenen Wissens bzw. auch nur Teilen davon, steht
! man vor dem grossen Problem der verschiedenen Dokumentformate, die von den
unterschiedlichen Programmen, die zur Erstellung des Dokuments verwendet
[...1085 lines suppressed...]
erniedrigt) und entsprechend dieser dann der entsprechende Bezeichner in der
--- 1885,1889 ----
enthaltenen Elemente ins Zielformat übersetzt. Die \texttt{<title>} Elemente
enthalten die überschriften der einzelnen (Unter-)Kapitel. Für die
! \texttt{<section>} Elemente wir die jeweilige Verschachtelungstiefe akkumuliert
(d.h. bei einen Starttag um eins erhöht und beim Endtag wieder um eins
erniedrigt) und entsprechend dieser dann der entsprechende Bezeichner in der
***************
*** 1884,1888 ****
Zu obigem Beispiel kann nun die dazugehörige Dokumentenhierarchie in
! \ac{ac:Latex} folgendermaßen aussehen:
\begin{verbatim}
--- 1891,1895 ----
Zu obigem Beispiel kann nun die dazugehörige Dokumentenhierarchie in
! \LaTeX\ folgendermaßen aussehen:
\begin{verbatim}
|