Formicula (USA 1954, Regie: Gordon Douglas) ist ein Klassiker seines
Genres. Atomtests in der mexikanischen Wüste verursachten die Mutation
harmloser Ameisen zu riesigen Monstern. Dass nun ein Internet Tool den
gleichen Namen trägt ist folgenden Umständen zu verdanken: dem
Interesse des Programmierers für B-Pictures und der allgemeinen
Ungeduld dieses Berufsstandes bei der Namensgebung. Da dieses Tool
primär zur Gestaltung und Verwaltung von Formularen dient, war nur ein
kleines Wortspiel nötig und das Tool hatte seinen Namen.
Was ist Formicula?
Formicula ist zum einen eine Skript-Sprache mit der das Layout und der
Ablauf von Formularen gesteuert wird, und zum anderen ein Modul für den
Web-Server, dass fast beliebig viele dieser Formulare verwalten kann.
Ausserdem kann das Modul fast beliebig viele Anfragen pro Formular parallel
überwachen. Die Einschränkungen ergeben sich aus der
Leistungsfähigkeit des Web-Servers und eventuell verwendeten,
peripheren Datenbanken.
Die Motivation
Jedes Formular ist prinzipiell auch eine Art Fragebogen. Daher
stammt auch die Grundmotivation, die hinter der Entwicklung von Formicula
steht. Die speziellen Anforderungen sprachen von Anfang an gegen die
Verwendung von herkömmlichen Tools zur Erstellung von Internet-Fragebögen.
Diese basieren auf festen Strukturen bezüglich der
Speicherung der erhobenen Daten und der Verwaltung der Teilnehmer.
Das anlassgebende Projekt hingegen war schon seit mehreren
Jahren in Form einer schriftlichen Befragung im Feld und hat sich seine
eigenen Strukturen geschaffen. Bisher wurden die zurückgesendeten
Fragebögen per Eingabemaske in eine Desktop-Datenbank eingepflegt. Da
die Internet-Befragung nur begleitend erfolgt, soll sich an der bisherigen
Vorgehensweise nichts ändern. Offline- und Online-Erfassung sollen auf
die gleichen Tabellen zugreifen, wobei sich die Online-Erfassung über
das Internet den Gegebenheiten der Offline-Erfassung anzupassen hat. Die
Standard-Tools hätten eine regelmässige Synchronisation der tool-spezifischen
Online- mit der projekt-spezifischen Offline-Datenbank
erforderlich gemacht. Dies hätte unter Umständen zu Inkonsistenzen
geführt, wenn ein Fragebogen sowohl offline als auch online
erfasst worden wäre. Die hohen Anforderungen an die
Flexibilität führten dazu, dass Formicula nicht nur zur
Erstellung von Internet-Fragebögen eingesetzt werden kann, sondern
vielmehr ein Tool zur Darstellung dynamischer und interaktiver Inhalte
geworden ist zu deren Untermenge auch Internet-Fragebögen
gehören.
Funktionsweise
Formicula ist ein Servlet
Formicula ist zu 100% in Java geschrieben. Das bedeutet es ist
plattformunabhängig. Formicula kann auf jedem Web-Server installiert
werden, sofern dieser Servlets unterstützt. Servlets stellen die
Konsolidierung verschiedener Technologien zur Generierung dynamischer Web-Inhalte
durch die Java Software Division der Firma Sun Microsystems dar.
Fast alle Web-Server unterstützen mittlerweile Servlets aufgrund
ihrer erheblichen Vorteile gegenüber den sogennanten CGI-Programmen.
CGI steht für Common Gate Interface und bezeichnet die Schnittstelle
zwischen dem Web-Server und speziellen Programmen, die für den
dynamischen Aufbau von Web-Seiten zuständig sind. Über die
Schnittstelle erhalten die Programme z.B. eingegebe Daten aus
einem Fragebogen, werten diese aus und erzeugen dynamisch eine neue HTML-Seite,
die zurück gesendet wird. Diese Seite kann Fehlermeldungen zu
Falscheingaben oder eine weitere Seite des Fragebogens beinhalten. Auf
diese Art und Weise kann ein Dialog mit dem Anwender geführt werden.
Servlets arbeiten prinzipiell genauso, bieten aber eine deutlich
vereinfachte Schnittstelle, transparentere Standards, bessere Antwortzeiten
und sie sind plattformunabhängig.
Kommunikation mit dem Anwender
Das Formicula-Servlet wartet auf Anfragen durch einen Anwender. Die erste
Anfrage wird immer durch einen Link oder die direkte Angabe der Adresse des
Servlets in einem Browser ausgelöst. Als zusätzliche Information
wird der Name des Formicula-Skriptes mitgegeben. Der Web-Server erkennt,
dass die Anfrage an ein Servlet gerichtet ist und leitet sie weiter. Wurde
das Formicula-Skript zum ersten mal angefordert, interpretiert das Servlet
die Skript-Datei und erzeugt eine Formularstruktur. Es handelt sich dabei um ein
strukturelles Objekt, welches das Aussehen der Formularseiten,
Fehlerabfragen und entsprechende Meldungen, Datenbankzugriffe und die
Benutzerführung durch die Seiten abbildet. Dieses Objekt wird für
jedes aktive Skript nur einmal generiert. Zusätzlich wird ein
Anwenderobjekt erzeugt, das alle anwenderspezifischen Angaben inklusive
eines Verweises auf das Formularobjekt und das aktive Formular verwaltet.
Durch die Trennung in Anwender- und Formularobjekt muss letzteres nicht
für jeden Anwender neu erstellt werden. Das Servlet wertet die erste
Seite der Formularstruktur aus und erzeugt eine HTML-Seite, die zum
Anwender gesendet wird und auf dessen Browser erscheint. Dem Dokument
beigefügt sind versteckte Informationen, die automatisch bei jeder
weiteren Anfrage des Anwenders zum Servlet mitgeschickt werden. Die
Kommunikation des Servlets mit einem Anwender über mehrere Anfragen
hinweg wird Session genannt. Da Formicula viele Sessions parallel
verwalten kann, werden die versteckten Informationen zur Identifizierung
des Anwenders und somit des dazugehörigen Anwenderobjektes
benötigt. Entsprechend der Angaben des Anwenders und der
Formularstruktur wird auf jede Anfrage eine neue HTML-Seite generiert, bis
die Formularstruktur das Ende der Session anzeigt, wodurch die Session
gelöscht und alle anwenderbezogenen Ressourcen freigegeben werden.
Datenbankanbindung
Die Datenbankanbindung von Formicula erfolgt über Java Database
Connectivity. JDBC setzt sie Philosophie von Java - nämlich die
Plattformunabhängigkeit - auf der Ebene der Datenbanken fort. JDBC
besteht aus einer unabhängigen Entwicklungskomponente und einer
datenbankspezifischen Treiberkomponente. Letzere gehört zum
Lieferumfang der meisten Datenbanksysteme. Ausserdem existiert eine
Vielzahl von Treiberprodukten von Drittanbietern. Diese Technologie
erlaubt es Formicula an fast jede Datenbank anzubinden. Zudem stellt
Formicula flexible Standardfunktionen zur Verfügung, die es
ermöglichen die Tabellen der Datenbank beliebig zu verwalten. Somit
ist Formicula nicht nur unabhängig vom Datenbanksystem, es
benötigt auch keine spezifische zugrundeliegende Tabellenstruktur
zur Datenverwaltung.
Installation
Testumgebung
Dieser Abschnitt beschreibt die Installation der Testumgebung und die
Portierung von Formicula auf einen Web-Server. Die Testumgebung basiert
auf dem Java Servlet Development Kit Version 2.1 (JSDK), dass von der Sun-Homepage kostenlos heruntergeladen
werden kann. Ausserdem wird das Java 2 Runtime Environment (ab Version 1.1)
benötigt, welches Sun ebenfalls kostenlos zur Verfügung stellt.
In der Regel gehört das JRE zum Standardumfang von Browsern und ist demzufolge
bereits installiert.
Für die Testumgebung wurden einige Konfigurationsdateien des JSDK
speziell für den Einsatz von Formicula angepasst. Die Datei
"formicula.zip" kann in ein beliebiges Verzeichnis entpackt werden. Das
Unterverzeichnis "classes" enthält die Klassenverzeichnisse
für diverse Hilfsklassen wie z.B. Treiber-Klassen für JDBC. Im
Klassenverzeichnis "formicula" stehen alle Klassen, die das Formicula-Servlet
benötigt. In dieses Verzeichnis können auch neue
Klassen kopiert werden, um die Syntax und die Funktionalität zu
erweitern. In dem Unterverzeichnis "ant" stehen die Formicula-Skripte. Das
Verzeichnis "webpages" enthält die Startseite und in weiteren
Unterverzeichnissen die Servlets.
Der Test-Server wird mit der Batch-Datei "startserver" gestartet.
Mit einem beliebigen Browser kann die Startseite mit der Adresse
http://localhost:8080 aufgerufen werden. Durch klicken auf das Logo wird
das Servlet "FormiculaScriptBrowser" aufgerufen, das alle Skripte im
"ant"-Verzeichnis anzeigt. Es empfiehlt sich eine Bookmark auf diese
Seite zu legen. Die Skripte können durch anklicken der Links
gestartet werden. Fehlermeldungen werden als Server-Fehler angezeigt.
Der Server wird mit der Batch-Datei "stopserver" beendet.
Die Testumgebung stellt auch eine kleine Intranetlösung dar. Dazu
benötigt der Server eine feste IP-Adresse oder einen festen
Netzwerknamen. So können Anwender von beliebigen Rechnern innerhalb
des internen Netzes auf die Formicula-Dienste zugreifen. Die internen
Adressen können z.B. wie folgt aussehen: http://10.1.1.202:8080,
http://ws_formicula:8080.
Web-Server
Die Installation von Formicula auf einem Web-Server kann von der
Testumgebung aus erfolgen. Das Servlet "Formicula.class" muss in ein
spezielles Verzeichnis des Servers kopiert werden. Entweder handelt es
sich dabei um ein vorgegebenes Verzeichnis (z.B.: "servlets") oder es
wird mittels Konfiguration beim Server angemeldet. Das "formicula"-Verzeichnis
muss auf den Web-Server kopiert werden. Auch hier kann es
spezielle Verzeichnisse geben, die automatisch im Klassenpfad der Java-Umgebung
stehen. Andernfalls muss der Administrator darauf achten, dass
sich das "formicula"-Verzeichnis im Klassenpfad (siehe Umgebungsvariable
"classpath") befindet. Die Skript-Dateien können in beliebigen
Verzeichnissen unterhalb des Basisverzeichnisses des Servers stehen.
Die Pfade zu den Skripten folgen der Adressierung des Formicula-Servlets
als zusätzliche Angaben. So hat z.B. das Skript "zufriedenheit.ant" im
Unterverzeichnis "kunden" die Adresse:
http://www.meinefirma.de/servlet/Formicula/kunden/zufriedenheit.ant
Die Spezifizierung der Standardendung ".ant" ist optional.
Weitere Informationen können der Dokumentation des Servers entnommen werden.
Die Syntax von Formicula basiert auf der Scope-Syntax. Als Scope bezeichnet
man in diesem Zusammenhang den Gültigkeitsbereich von Variablennamen.
Scopes können verschachtelt sein. Wenn eine Variable im
übergeordneten Scope als global definiert ist, wird ihr
Gütigkeitsbereich auf alle untergeordneten Scopes ausgedehnt. Alle
anderen Variablen haben nur lokale Gültigkeit bezüglich des
definierenden Scopes. Bei Namensgleichheit einer globalen Variable mit
einer Variablen eines untergeordneten Scopes wird nur die untergordnete
Variable berücksichtigt, unabhängig davon ob sie lokal oder
global definiert ist. Das folgende Beispiel zeigt einen Ausschnitt aus
einem Formicula-Skript, das zugegebenermassen keinen Sinn macht aber einen
guten Überblick über die Sprache verschafft:
Frame bsp1
{ backColor = green; // lokale Variable
[foreColor] = blue; // globale Variable
[gelb] = yellow; // globale Variable
[macro12] = // Definition eines globalen Macros
'Text bsp12
{ foreColor = black; // globale Variable wird ausgeblendet
text = "denn so."; // schwarzer Text auf weissem Hintergrund
}';
subHtml; // entspricht: subHtml = true;
Text bsp11
{ text = "Hallo, wie gehts"; // blauer Text auf gruenen Hintergrund
}
[macro12] // Substitution des globalen Macros
Text bsp13
{ backColor = [gelb]; // globaler Variableninhalt wird verwendet
text = "Der \"Hintergrund\""; // Escapesequenz: Anfuehrungszeichen
text = ist, [gelb]; /* Inhaltsliste mit Substitution */
}
}
Ein Scope ist immer durch geschweifte Klammern begrenzt. Davor muss der
Typ des Scopes definiert sein. Die Angabe eines Namens ist optional. Im
Beispiel enthält das Scope vom Typ Frame mit dem Namen
bsp1 die untergeordneten Scopes bsp11,
bsp12 (als Macro) und bsp13 (jeweils vom Typ
Text). Die Variablennamen werden durch das
Gleichheitszeichen mit dem Inhalt verknüpft. Eine
Variablendefinition wird durch ein Semikolon abgeschlossen. Enthält
der Inhalt Leerzeichen oder andere Symbole der Syntax, muss er durch
Anführungszeichen abgegrenzt werden. Damit eventuelle
Anführungszeichen im String von den begrenzenden
Anführungszeichen unterschieden werden können,
unterstützt der Interpreter sogenannte Escapesequenzen.
Escapesequenzen beginnen immer mit einem Backslash. Das folgende Zeichen
wird vom Interpreter besonders behandelt. Die Sequenz für innere
Anführungszeichen lautet: \". Die Sequenz für den
Backslash selbst lautet: \\. Steht nichts zwischen dem
Gleichheitszeichen und dem Semikolon wird ein Leerstring zugewiesen.
Wird ein Variablenname direkt von einem Semikolon gefolgt wird eine
boolsche Variable mit dem Wert true angenommen. Eine
Variable kann auch mehrere Inhalte in Form einer Liste referenzieren.
Die einzelnen Elemente sind entweder durch Kommas getrennt oder werden
durch Wiederholung der Variablendefinition angezeigt. Eckige Klammern um
den Variablennamen definieren globale Variablen. Sind die eckigen
Klammern um den Variableninhalt, wird dieser als Name einer lokalen bzw.
globalen Variable interpretiert und substituiert. Im Beispiel wird im
Scope Text bsp13 die Variable text mit einer
Inhaltsliste definiert. Da der Text "Der Hintergrund" ein Syntax-Symbol
(Leerzeichen) enthält muss er in Anführungszeichen stehen. Das
zweite und dritte Element der Inhaltsliste wird über die
Kommaschreibweise definiert. Das dritte Element ist eine Substitution
der globalen Variable gelb mit dem Inhalt "yellow".
Kommentare können wie in C durch "/*" und
"*/" geklammert werden. Es kann aber auch der durch
"//" eingeleitete Kommentar verwendet werden, der bis zum
Ende der Zeile gilt. Variableninhalte können auch ausserhalb einer
Variablendefinition substituiert werden. Bei einer solchen
Macrosubstitution wird der Inhalt einer in eckigen Klammern stehenden
Variable separat interpretiert. Macros müssen deshalb immer einen
vollständigen Skriptabschnitt (Scope- oder Variablendefinitionen)
beschreiben. Mit Macros können sich häufig wiederholende
Skriptpassagen effizient abgekürzt werden. Es gibt einen speziellen
Zeichenkettenbegrenzer, der sich für die Definition von Macros
besonders eignet: das einfache Anführungszeichen. Im Gegensatz zu
dem von normalen Anführungszeichen begrenzten Text, kann sich der
Text innerhalb zweier einfacher Anführungszeichen über mehrere
Zeilen erstrecken. Die Zeilenumbrüche werden ignoriert.
Die Formularstruktur
Der Scope-Interpreter ist ein generischer Interpreter, d.h. er ist
unabhängig vom eigentlichen Anwendungszweck der Syntax. Die Typen und
Namen der Scopes oder Variablen haben für ihn noch keine Bedeutung. Er
erzeugt beim Interpretieren eine interne Struktur und stellt Methoden
zur Verfügung mit denen diese Struktur auf externe Strukturen
abgebildet werden kann. Erst durch diesen Vorgang werden
Schlüsselwörter und syntaktische Zusammenhänge geprägt.
Im Fall von Formicula handelt es sich bei der externen Struktur um die
Formularstruktur (siehe Diagramm).
Die Formularstruktur besteht aus hierarchisch gegliederten Objekten. Auf
der höchsten Ebene steht das Formular selbst. Dieses Objekt trägt
den Namen Form. In Form werden globale Einstellung definiert,
wie z.B. einen Verweis auf eine HTML-Seite, die das Formular enthält.
Ausserdem ist es ein sogenannter Container für Objekte der Klasse
Group. Eine Group der höchsten Ebene stellt eine
Formularseite dar. Sie bestimmt das umgebende Layout der eigentlichen
Formularinhalte. Eine Group kann wiederum Objekte der Klasse Entry
beinhalten. Da Group selbst von dieser Basisklasse abstammt, kann
eine Group andere Group-Objekte enthalten. Von der Klasse
Entry wird auch die Klasse Content abgeleitet. Diese
definiert die Grundstruktur für alle Formularinhalte wie Texte oder
Eingabefelder. Die Content-Objekte haben neben der darstellenden
Funktion noch die Aufgabe die sogennanten Evaluatoren zu
beherbergen. Sie stellen das Grundgerüst für die
Funktionalität des Formulars dar. Ein Evaluator wertet immer
irgendeine Bedingung aus und führt bei Erfüllung eine spezielle
Aktion durch. Evaluatoren sind Container für andere Evaluatoren und
für Objekte der Klasse Operator. Letztere sind für das
Handling der Daten zuständig. Dazu gehören Vergleichsoperatoren,
mathematische Operatoren, String- und Systemfunktionen.
Die Klassen der Formularstruktur sind die Schlüsselwörter der
Scope-Syntax. Die Typen der Scopes entsprechen den Klassennamen und ihre
Position in der Scope-Hierarchie muss den Vorgaben der Formularstruktur
entsprechen. Nicht für alle Klassen der Formularstruktur lassen
sich Objekte instanzieren. Die sogennanten abstrakten Klassen (im
Diagramm kursiv dargestellt) definieren allgemeine Eigenschaften, die
sie an die von ihnen abgeleitete Klassen vererben. So verhalten sich
alle Evaluatoren aus der Sicht eines Content-Objektes gleich,
obwohl sie ganz unterschiedliche Funktionen erfüllen. Abstrakte
Klassen können nicht instanziert werden, da einige Bestandteile nur
als Vorgabe für Unterklassen aber nicht als Implementierung
vorliegen. Nur die instanzierbaren Klassen bilden die
Schlüsselwörter der Formicula-Syntax.
Eigenschaften, Variablen und Daten
Der Scope-Interpreter generiert aus einem Scope ein Objekt dessen Klasse
dem Typ des Scopes entspricht. Danach erfolgt ein Abgleich der
Eigenschaften des Objektes mit den Variablen des Scopes. Haben eine
Eigenschaft und eine Variable den gleichen Namen wird der Variableninhalt
der Eigenschaft zugewiesen. Da Eigenschaften immer einen Datentyp haben
(z.B.: Integer, String, Boolean usw.) und der Variableninhalt immer eine
Zeichenkette ist, muss dieser entsprechend umgewandelt werden. Wenn das
nicht möglich ist, wird ein Syntaxfehler gemeldet. Eigenschaften, die
nicht in dem entsprechenden Scope als Variablen definiert sind, bleiben
unverändert. Variablen, denen keine Eigenschaften zugeordnet sind,
haben keine Auswirkung auf das Objekt. Die Eigenschaften der Objekte sind
nicht zu verwechseln mit den eigentlichen Daten, die das Formular verwalten
soll. Diese sind Bestandteil des Anwenderobjektes. Manche Eigenschaften der
Formularobjekte beziehen sich auf die Daten. Ein Datenfeld kann z.B. den
Inhalt eines Formulareintrages oder eines Datenbankfeldes
repräsentieren. Es wird über einen Namen referenziert, dem ein
durch einen Punkt getrennter Aliasname vorangestellt sein kann. Der
Aliasname steht für eine zusammengehörige Gruppe von
Datenfeldern. Manche Evaluatoren benötigen die Angabe eines Aliasnamens,
weil sich ihre Aktionen auf mehrere Datenfelder beziehen. Dies trifft vor
allem auf für Datenbankzugriffe zuständige Evaluatoren zu.
Datenfelder ohne Aliasnamen werden meistens für Zwischenwerte benutzt.
Im Gegensatz zu allen anderen Angaben spielt die Gross- und Kleinschreibung
bei Datenfeldnamen keine Rolle.
Substitutionen
In der Regel sind die Eigenschaften von Objekten statisch. Sie werden bei
der Generierung des Objektes über die Scope-Variablen gesetzt und
können nicht mehr verändert werden. Dies trifft vor allem auf
Eigenschaften zu, die für das Layout zuständig sind. Dadurch
bleibt das Layout erzwungenermassen konsistent und die Performance hoch.
Für inhaltsbezogene Eigenschaften wie z.B. Texte, Label oder Listen
kann es jedoch erforderlich sein, dynamische Inhalte zu präsentieren.
Durch eine Substitution kann ein beliebiger Datenfeldinhalt in einen Text
eingefügt werden. Der Name des Datenfeldes muss in geschweiften
Klammern stehen. Ob eine Eigenschaft Substitutionen unterstützt oder
nicht, ist der jeweiligen Eigenschaftsbeschreibung zu entnehmen.
Datenfelder als Vektoren
Einige Eingabefelder können mehrere Ausprägungen generieren,
deren Anzahl variiert. In einer Auswahlliste können zum Beispiel
mehrere Einträge markiert werden. Das dazugehörige Datenfeld muss
demzufolge auch mehrere Werte speichern können. Es wird zu einem
Vektor. Prinzipiell kann jedes Datenfeld bei Bedarf zu einem Vektor
mutieren. Wird jedoch ein Vektor für ein skalares Eingabefeld
verwendet, wird er unweigerlich zu einem eindimensionalen Vektor (Skalar)
und seine anderen Werte gehen verloren. Es existieren spezielle Operatoren
für vektorisierte Datenfelder. Da sich Vektoren von normalen
Datenfelder syntaktisch nicht unterscheiden, sollten sie sparsam und
möglichst transparent verwendet werden (z.B. durch besondere
Namensgebung).
Diagram der Formularstruktur
Form
Group
Entry
Content...
Evaluator
Group...
Entry
...Content
SingleVarContent
MultiVarContent
Blank
Dummy
Refresh
Text
Summary
Area
Combo
Input
Password
Radio
Image
Likert
Check
Matrix
...Group
Table
Frame
Layout
Row
Evaluator
Operator Evaluator
FunctionEvaluator...
BaseEvaluator
Utilize
Eval
Not
True
False
Catch
Loop
...FunctionEvaluator
Utility...
Data...
System...
IO...
Navigation...
Visibility...
Message...
...UtilityEvaluator
Clear
Copy
Level
Gather
Scatter
Filter
Dir
Sort
...DataEvaluator
Connect
Disconnect
Select
Update
Delete
SQL
Next
Commit
Rollback
Touch
Meta
Catalog
...SystemEvaluator
Reset
Exit
Transfer
Log
Exec
...IOEvaluator
...NavigationEvaluator
...VisibilityEvaluator
...MessageEvaluator
Open
Close
Read
Write
Jump
Skip
Back
Hide
Show
Error
Valid
Operator
CompareOperator...
NumericOperator
UnaryOperator
at
def
...
set
add
div
...
sub
ceil
date
...
used
...CompareOperator
DynamicCompareOperator
NumericCompareOperator
StringCompareOperator
eq
le
...
ne
eqnum
lenum
...
nenum
eqstr
lestr
...
nestr
Objekte
Aufgrund der starken Verknüpfung von Syntax und Objekten ist eine
Beschreibung der Objekte auch immer eine Beschreibung der Syntax. Für
jedes Objekt wird zuerst die Einbettung in die Syntax und die
Funktionalität dargestellt. Es folgt die Auflistung aller
Eigenschaften des Objektes. Vor jeder Eigenschaft steht der Datentyp,
dahinter der Standardwert. Der Standardwert wird verwendet, wenn die
Eigenschaft nicht explizit im Scope definiert wird. Manche Eigenschaften
haben keinen Standardwert. Unterstützt die Eigenschaft dynamische
Substitutionen steht der Datentyp in geschweiften Klammern. Folgende
Datentypen werden verwendet:
string
Strings sind Zeichenketten. Sie können ohne Anführungzeichen
definiert werden, wenn keine Syntaxsymbole oder Leerzeichen darin vorkommen.
Manche dieser Zeichenketten werden innerhalb von Html-Tags verwendet. Bei
diesen Strings werden alle Html-Sonderzeichen (z.B.: "<", ">" oder
Anführungszeichen) mit Html-Zeichenbeschreibungen maskiert, wodurch sie
ihre Wirkung verlieren. Z.B. werden alle Datenfeldinhalte in einem
Formularelement maskiert, damit der Inhalt nicht fäschlicherweise
für ein Html-Steuerbefehl (Tag) gehalten werden kann.
html
Eigenschaften vom Typ html lassen ihren Inhalt direkt als
Html-Code in das Formular einfliessen. Im Gegensatz zu Strings
werden Html-Tags nicht maskiert und können vom Browser interpretiert
werden.
boolean
Eigenschaften vom Typ boolean sind entweder true oder
false.
Listen können mehrere Ausprägungen vom gleichen Typ haben. Der Typ steht
vor dem Wort "list". Die meisten Listen sind Stringlisten.
Form
Das Form-Objekt ist die Basis der hierarchischen Formularstruktur.
Es ist ein Container für Objekte der Klasse Group. Jede
Group auf der höchsten Ebene in Form stellt eine Seite
dar. Das erste Group-Objekt definiert die Startseite. Die
Eigenschaften des Form-Objektes werden direkt auf der höchsten
Ebene des Skriptes definiert. Sie befinden sich nicht innerhalb eines
Scopes.
Eigenschaften:
string servlet = /servlet/Formicula
Definiert den Pfad und Namen des Servlets welches die Anfragen an dieses Formular
verwaltet. Diese Eigenschaft muss nur dann geändert werden, wenn der
verwendete Web-Server von der Norm abweichende Pfadangaben für Servlets
benötigt.
string name = Formicula
Diese Eigenschaft definiert den Namen des Formulars innerhalb des HTML-
Dokuments als Referenz für Formicula-Objekte die JavaScript verwenden.
string method = post
Spezifiziert die Methode mit der die Formulardaten an das Servlet gesendet
werden. Folgende Methoden werden unterstützt: post: Daten sind nicht sichtbar (Standardeinstellung). get: Daten werden an die URL angehängt und sind dadurch im Browser zu sehen.
stringlist parameter
Definiert eine Liste von Datenfeldnamen, die als Startparameter
einglesen werden. Die Parameter werden an die Internet-Adresse (URL) des
Formicula-Aufrufes angehängt. Die Parameterübergabe beginnt
mit einem Fragezeichen (?) gefolgt von der ersten Parameterdefinition.
Jede Definition besteht aus einem Namen, einem Gleichheitszeichen (=)
und einem oder mehreren Werten. Die Trennung der folgenden Parameter
erfolgt durch das Kaufmanns-Und (&). Hat ein Parameter mehrere Werte
sind diese ebenfalls durch ein Kaufmanns-Und unterteilt. Da die
Parameter Bestandteil der URL sind, können bestimmte Zeichen zu
Missinterpretationen führen. Deshalb sieht die
Standardverschlüsselung folgende Ersetzungen vor: Leerzeichen durch
ein Pluszeichen (+) und nicht-alphanumerischen Zeichen durch ein
Prozentzeichen (%) gefolgt vom ASCII-Code in zweistelliger
Hexadezimalform.
string page
Gibt den Filenamen einer Rahmenseite an. Diese benötigt an der Stelle
an der das Formular integriert werden soll das Tag "<Formicula>" (ohne
abschliessendes Tag). Die Definition einer Rahmenseite hat Vorrang vor den
Definitionen von intro bzw. outro.
htmllist intro
Mit dieser Eigenschaft kann ein HTML-Block definiert werden, der vor dem
eigentlichen Formular steht. Bei Angabe der Eigenschaft page
wird intro ignoriert.
htmllist outro
Mit dieser Eigenschaft kann ein HTML-Block definiert werden, der nach dem
eigentlichen Formular steht. Bei Angabe der Eigenschaft page
wird outro ignoriert.
string pageColor
Spezifiziert die Hintergrundfarbe der Formularseiten.
string textColor
Spezifiziert die Textfarbe der Formularseiten.
string linkColor
Spezifiziert die Textfarbe von Links.
string visitiedLinkColor
Spezifiziert die Textfarbe von bereits besuchten Links.
string activeLinkColor
Spezifiziert die Textfarbe von aktivierten Links.
string title = Formicula
Dieser Text erscheint in dem Titelbereich des Browserfensters.
boolean navigationLock = false
Gibt an ob die Navigation über den Browser akzeptiert (Standard) oder
ignoriert werden soll. Die meisten Browser stellen Funktionen zum
Navigieren in der History der besuchten Seiten zur Verfügung. Diese
Seiten werden nicht vom Server sondern direkt aus dem Cache des
Browsers geladen und können veraltet sein. Ist
navigationLock deaktiviert, werden Daten, die in derartige
Formularseiten eingetragen wurden, an Formicula gesendet und die
entsprechende Group aktiviert. Ist diese Eigenschaft
true werden diese Daten ignoriert und die aktuelle
Formularseite erneut angezeigt.
integer maxInactiveInterval = 1800
Definiert die Zeit die zwischen zwei Anfragen eines Anwenders verstreichen
darf. Die Angabe erfolgt in Sekunden. Nach dieser Zeitspanne wird die
Session dieses Anwenders beendet. Diese Eigenschaft kann auf 0 gesetzt werden,
wenn das Skript nur den Aufbau einer passiven, dynamischen Seite beschreibt.
boolean openStartpage = false
Diese Eigenschaft wirkt sich nur aus, wenn die Session bereits abgelaufen bzw.
explizit beendet wurde und der Anwender Daten in die erste Formularseite
eingegeben und diese abgeschickt hat. Ist die Eigenschaft true wird
eine neue Session generiert und die Daten übernommen. Standarmässig
wird die Session ohne die Übernahme der Daten generiert, da sonst unter
Umständen Daten eingelesen werden, die nach einer Skriptänderung nicht
mehr vorgesehen sind.
Entry
Die Entry-Klasse ist die Basisklasse für alle Formularelemente.
Es definiert die grundlegenden Eigenschaften jedes Objektes, das eine
darstellende Funktion im Formular hat. Jedes Entry-Objekt generiert
ein Stück Html-Code, aus dem sich die Formularseite zusammensetzt.
Group-Objekte bilden dabei umschliessende Codeteile und
Content-Objekte die Inhalte. Alle Codefragmente basieren auf Html-Tabellen.
Aus diesem Grund stehen alle Eigenschaften der Entry-Klasse in
direktem Zusammenhang mit dem Aufbau dieser Tabellen.
Eigenschaften:
integer padding = 2
Das padding einer Tabelle bestimmt den Abstand zwischen dem Zellenrand und
dem Zelleninhalt in Pixeln.
integer spacing = 2
Das spacing einer Tabelle bestimmt den Abstand zwischen den Zellen
in Pixeln.
integer border = 0
Ist der border grösser als null, wird ein plastischer
Rand um die Tabelle und die Zellen gezogen. Die Breite des Randes entpricht
dem border in Pixeln. Das spacing definiert dann
den Abstand zwischen den Rändern der Zellen.
string width = 100%
Diese Eigenschaft definiert die Breite einer Tabelle. Bei einer Prozentangabe
handelt es sich um eine relative Angabe zu dem Browserfenster. Absolutangaben
definieren die Breite in Pixeln. Wenn die Eigenschaft explizit auf einen
Leerstring gesetzt wird, wird die Breite über den tatsächlichen
Platzbedarf bestimmt.
string align = left
Diese Eigenschaft definiert die horizontale Ausrichtung der
Tabellenelemente. Folgende Werte werden unterstützt:
left, center, right.
string valign = center
Diese Eigenschaft definiert die vertikale Ausrichtung der
Tabellenelemente. Folgende Werte werden unterstützt:
top, center, bottom.
string backColor
Die backColor ist die Farbe des Zellenhintergrundes.
string borderColor
Die borderColor bestimmt die Farbe der Zellenzwischenräume
(Rahmen), welche mit spacing definiert werden können.
Wenn keine borderColor definiert wurde, erhält der Rahmen
die Farbe des Hintergrundes auf dem die Tabelle dargestellt wird.
Eine Group auf der höchsten Ebene entspricht einer
Formularseite. Sie ist der Container für Entry-Objekte, kann
also Group- und Content-Objekte aufnehmen. Eine Group
repräsentiert auch immer ein bestimmtes Layout mit dem andere
Entry-Objekte dargestellt werden. Die abstrakte Basisklasse
Group definiert keine weiteren Eigenschaften zur Klasse
Entry.
Die Namen der Group-Objekte auf der höchsten Ebene dienen zur
Referenzierung von Formularseiten für den Jump-Evaluator.
Die Angabe ist optional. Die Namen müssen eindeutig sein.
Das Layout eines Frame-Objektes ist ein Rahmen. Dieser basiert auf
einer Tabelle, deren einzige Zelle alle Entry-Objekte dieses
Frame-Objektes in vertikaler Anordnung enthält.
Eigenschaften:
integer height = 0
Gibt die minimale Höhe des Frame in Pixeln an. Erfordert der
Inhalt des Frame mehr Platz in vertikaler Ausrichtung wird diese Angabe
ignoriert.
Beispiel:
maxInactiveInterval = 0;
[padding] = 4;
[backColor] = orange;
[borderColor] = black;
Frame
{ padding=4;
spacing=8;
borderColor=orange;
backColor=khaki;
align=center;
valign=bottom;
height=100;
Text
{ align=right;
border=2;
width=50%;
text = "Das ist das erste Entry-Objekt.";
}
Text
{ text = "Das ist das zweite Entry-Objekt.";
}
}
Zu Beginn dieses Skriptes wird die Seite als passiv deklariert, da die
Form-Eigenschaft maxInactiveInterval auf 0 steht. Die
Session wird nach dem Aufbau der Seite gelöscht. Danach werden globale
Präferenzen für Abstände und Farben gesetzt. Diese werden in der
Definition des Frame-Objektes lokal überblendet. Die beiden
Content-Objekte der Klasse Text übernehmen jedoch diese
Einstellungen. Deutlich ist der 8 Pixel breite, orangene Rahmen zu erkennen,
welcher durch das spacing hervorgerufen wurde. Der Frame hat
einen khakifarbenen Hintergrund. Seine minimale Höhe height
beträgt 100 Pixel. Da der Inhalt weniger benötigt und mit
valign am unteren Rand des Frame ausgerichtet ist, ergibt
sich ein grösserer Abstand zum oberen Rand. Die beiden Text-Objekte
haben schwarze Rahmen aufgrund ihrer spacing-Eigenschaft. Das obere
Text-Objekt ist bezüglich des Frame zentriert. Der Inhalt des
Text-Objektes ist linksbündig ausgerichtet. Zudem hat es einen
plastischen Rand durch die border-Eigenschaft erhalten. Das globale
padding sorgt dafür, dass der Text in den Text-Objekten
etwas Platz zum Rand aufweist. Zwischen den beiden Text-Objekten ist kein
Abstand, da sich das padding des Frame nur auf den
äussersten Rand bezieht.
Die Entry-Objekte innerhalb einer Table werden vertikal
tabelliert. Im Unterschied zu einem Frame wird ein Tabellenrahmen um
jeden Eintrag gezogen. Eine Table eignet sich am besten für
eine einheitliche Darstellung mehrerer Einträge, die selbst keine oder
nur wenige Layouteinstellungen verwenden.
Beispiel:
[padding] = 4;
[spacing] = 0;
[backColor] = khaki;
Table
{ padding=0;
spacing=4;
borderColor=orange;
backColor=khaki;
Text { text = "Das ist das erste Entry-Objekt."; }
Text { text = "Das ist das zweite Entry-Objekt."; }
}
Die beiden Text-Objekte haben ein einheitliches Layout. Sie verzichten
auf die Darstellung von Rahmen, da dies das umschliessende Table-Objekt
übernimmt.
Das Layout-Objekt ist unsichtbar. Es dient nur dazu Entry-Objekte
zusammenzufassen. Dies ist zum Beispiel dann sinnvoll, wenn mehrere
Objekte als ein Eintrag in einem Table- oder Row-Objekt
behandelt werden sollen. Ausserdem kann es verwendet werden, um globale
Eigenschaften für eine Gruppe von Entry-Objekten zu definieren.
Das Layout-Objekt ignoriert alle Eigenschaften. Nur die
width-Eigenschaft wird im Zusammenhang mit dem Row-Objekt
berücksichtigt.
Beispiel:
[padding] = 4;
[spacing] = 0;
[backColor] = khaki;
Table
{ padding=0;
spacing=4;
borderColor=orange;
backColor=khaki;
Layout
{ Text
{ text = "Das ist das erste Entry-Objekt.";
}
Text
{ text = "Das ist das zweite Entry-Objekt.";
}
}
Text
{ text = "Das ist das dritte Entry-Objekt.";
}
}
Das erste und zweite Text-Objekt wurden durch ein Layout
zusammengefasst. Für die Table ist das Layout der erste
und das dritte Text-Objekt der zweite Eintrag.
Die Entry-Objekte innerhalb einer Row werden horizontal
tabelliert. Die width-Eigenschaft der Entry-Objekte
einer Row gibt an wieviel Platz der einzelne Eintrag in Anspruch
nehmen darf. Die Angaben sollten entweder nur absolut oder nur relativ
sein um die Browser nicht unötig zu verwirren. Für
Entry-Objekte ohne explizit definierte width-
Eigenschaft bestimmt der Browser die Breite selbst, was unter
Umständen zu ungewollten Ergebnissen führt.
maxInactiveInterval = 0;
[padding] = 4;
[spacing] = 0;
[backColor] = khaki;
Row
{ padding = 0;
spacing = 4;
borderColor = orange;
Layout
{ width = 75%;
Text
{ text = "Das ist das erste Entry-Objekt.";
}
Text
{ text = "Das ist das zweite Entry-Objekt.";
}
Row
{ padding=0;
Text
{ text = "Das ist das dritte Entry-Objekt.";
}
Text
{ align = right;
text = "Das ist das vierte Entry-Objekt.";
}
}
}
Text
{ align = center;
text = "Das ist das fünfte Entry-Objekt.";
}
}
In diesem Beispiel werden verschiedene Anwendungsmöglichkeiten des
Row-Objektes demonstriert. Zum einen als Hauptlayout für das
Formular und zum anderen als Trick, um bestimmte Anordungen zu erzielen
ohne dass die Anwendung von Row offensichtlich ist. Bei der Angabe
von relativen Breiten kann eine Angabe entfallen.
Die abstrakte Klasse Content definiert zu den Eigenschaften der
Klasse Entry weitere Eigenschaften, die für die Darstellung von
den eigentlichen Formularinhalten von Bedeutung sind. Ausserdem ist
Content eine Containerklasse für Objekte der Klasse
Evaluator. Einige Evaluatoren haben direkte Auswirkung auf die
Darstellung des Content-Objektes, während andere unabhänig
von ihrem Container sind. Z.B. generiert ein MessageEvaluator
Nachrichten, die direkt über dem Html-Code den das Content-Objekt
erzeugt eingefügt werden. Das Nachrichtenlayout
kann für jeden Content
individuell eingestellt werden. Die dafür zuständigen
Eigenschaften beginnen mit dem Term msg.
Ein Content-Objekt besteht aus einem Inhalt und einem Rahmen. Der
Rahmen wird wie bei den Group-Objekten mittels Html-Tabellen
generiert. Wenn ein Content keinen oder einen nur aus Leerzeichen
bestehenden Inhalt hat wird auch der dazugehörige Rahmen nicht
abgebildet. Die übergeordnete Group ignoriert die Existenz
dieses Content-Objektes. Hat eine Group aus diesem Grund keine
Content-Objekte darzustellen, wird auch sie nicht abgebildet.
Eigenschaften:
integer height = 0
Gibt die minimale Höhe des Objektes in Pixeln an. Erfordern der
Inhalt mehr Platz in vertikaler Ausrichtung wird diese Angabe
ignoriert.
string foreColor
Die foreColor gibt die Farbe des Textes an.
stringlist font
Definiert den Font der für den Text verwendet werden soll. Da manche
Fonts unter Umständen dem Browser unbekannt sind, können
alternative Fonts in der Liste definert werden. Gängige Fonts sind zum
Beispiel: Arial, Times, Times New Roman, Helvetica, Sans Serif,
Serif, Courier, Courier New, Impact
integer fontSize = 0
Gibt die relative Grösse des Textes in Bezug auf die vom Browser
vorgegebene Standardgrösse an. Positive Angaben vergrössern den
Text, negative Angaben verkleinern den Text.
integer msgBorder = 0
Ist der border grösser als null, wird ein plastischer Rand
um die Nachricht gezogen. Die Breite dieses Randes wird in Pixeln gemessen.
integer msgPadding = 2
Gibt den Abstand des Nachrichtenrahmens zu dem Nachrichteninhalt in Pixeln
an.
integer msgSpacing = 0
Gibt die Breite des normalen Randes in Pixeln an. Zusammen mit
msgBorder kann damit das Aussehen des Nachrichtenrahmens
gestaltet werden.
stringlist msgFont
Definiert den Font für den Nachrichtentext. Da manche
Fonts unter Umständen dem Browser unbekannt sind, können
alternative Fonts in der Liste definiert werden (siehe font).
integer msgFontSize = 0
Gibt die relative Grösse des Nachrichtentextes in Bezug auf die vom
Browser vorgegebene Standardgrösse an.
string msgBackColor
Gibt die Farbe des Hintergrundes der Nachricht an.
string msgForeColor
Gibt die Farbe des Nachrichtentextes an.
string msgBorderColor
Die msgBorderColor bestimmt die Farbe des Nachrichtenrahmens,
welcher mit msgSpacing definiert wird.
integer msgHeight = 0
Gibt die minimale Höhe in Pixeln an. Erfordert der Inhalt der
Nachricht mehr Platz in vertikaler Ausrichtung wird diese Angabe ignoriert.
string msgAlign = left
Diese Eigenschaft definiert die horizontale Ausrichtung des
Nachrichteninhalts. Folgende Werte werden unterstützt:
left, center, right.
string msgValign = center
Diese Eigenschaft definiert die vertikale Ausrichtung des
Nachrichteninhalts, wenn durch msgHeight
überschüssiger Raum entsteht. Folgende Werte werden
unterstützt: top, center,
bottom.
boolean msgHidden = false
Alle Nachrichten des Content-Objektes werden unterdrückt, wenn
diese Eigenschaft auf true steht. Sie können mit dem
Summary-Objekt zusammengefasst dargestellt werden.
Die Klasse Text wird direkt von der abstrakten Klasse Content
abgeleitet. Sie stellt die Basis für alle Inhalte von Formularen dar.
Da Text nicht nur Substitutionen unterstützt sondern
auch die Art der Substitution eingestellt werden kann, ist das Objekt
geeignet dynamischen Html-Code darzustellen.
Eigenschaften:
{htmllist} text
Gibt den Text an der dargestellt werden soll. Alle Html-Tags werden interpretiert.
Die Art der Substitutionen kann bestimmt werden.
boolean subHtml = false
Ohne Angabe einer Substitutionsregel werden alle Html-Sonderzeichen in der
Substitution maskiert. Sie werden als normale Zeichen dargestellt und nicht
als Tags ausgeführt. Wenn diese Eigenschaft true ist,
werden alle Substitutionen unverändert übernommen. Dies ist
sinnvoll wenn z.B. Texte aus einer Datenbank angezeigt werden sollen, die
absichtlich Html-Tags für das Layout enthalten.
boolean subFix = false
Normalerweise werden mehrfache Leerzeichen in Folge von den Browsern
ignoriert. Die Ausnahme bildet das sogenannte feste Leerzeichen welches mit
der Html-Zeichenbeschreibung " " erzeugt werden kann. Mit
subFix werden alle Leerzeichen in der Substitution durch feste
Leerzeichen ersetzt.
Beispiel:
maxInactiveInterval = 0;
[padding] = 4;
[spacing] = 0;
[backColor] = khaki;
Table
{ padding=0;
spacing=4;
borderColor=orange;
Text
{ text = "Substitution (normal): {sub}";
Utilize { exp = sub, set, "<small> TEST</small>"; }
}
Text
{ text = "Substitution (subHtml): {sub}";
subHtml;
}
Text
{ text = "Substitution (subFix): {sub}";
subFix;
}
Text
{ text = "Substitution (subHtml, subFix): {sub}";
subFix;
subHtml;
}
}
Substitution (normal): <small> TEST</small>
Substitution (subHtml): TEST
Substitution (subFix): <small> TEST</small>
Substitution (subHtml, subFix): TEST
Bei dem Scope Utilize handelt es sich um einen speziellen Evaluator, der vor
der Generierung des Html-Codes für eine Seite aufgerufen wird. In Utilize
wird das Datenfeld sub definiert, das in den vier Text-Objekten
substituiert wird.
Die Klasse Dummy wird direkt von der abstrakten Klasse
Content abgeleitet. Sie ist unsichtbar und hat keinen Einfluss auf
die Darstellung des Formulars. Ein Dummy-Objekt kann jedoch wie
jedes andere Content-Objekt Evaluatoren aufnehmen. Dadurch eignet sich das
Dummy-Objekt zur besseren Strukturierung des Skriptes. Ausserdem werden
Nachrichten von MessageEvaluator-Objekten auch von Dummies dargestellt,
wordurch es möglich wird Nachrichten unabhängig von sichtbaren
Content-Objekten zu plazieren.
Die erste Zeile zeigt die Integration einer Nachricht in den Html-Code
eines Content-Objektes. Die Nachricht befindet sich noch innerhalb
des Rahmens, der über die Eigenschaften (spacing,
padding) des Content-Objektes definiert wird. Die
Nachricht in der zweiten Zeile ist an ein Dummy-Objekt gekoppelt. Da
dieses keine Eigenschaften hat (oder besser gesagt "verwendet"), wird die
Nachricht als eigenständiges Objekt in das Layout-Objekt
übernommen.
Die Klasse Blank repräsentiert einen leeren Inhalt. Im
Gegensatz zur Klasse Dummy werden alle Layoutelemente (Rahmen,
Farben) dargestellt. Sie hat nur keinen sichtbaren Inhalt. Diese Klasse
eignet sich um Abstände zwischen Objekte zu plazieren, die mit der
height-Eigenschaft pixelgenau skaliert werden können.
Ein Summary-Objekt fasst alle Nachrichten eines Formulars zusammen.
Neben jeder Nachricht steht ein Link mit dem die Stelle im Formular
angesprungen werden kann, die diese Nachricht generiert hat. Zur internen
Darstellung verwendet Summary die msg-Eigenschaften:
msgHeight, msgBorder, msgPadding,
msgSpacing, msgBackColor, msgForeColor, msgFont, msgFontSize,
msgAlign und msgValign. Die Eigenschaften font,
foreColor und fontSize werden ignoriert.
Eigenschaften:
string spread = 10%
Das spread gibt die relative bzw. absolute Breite eines
Inhaltselementes an, an der sich die anderen Elemente ausrichten. Es
entspricht einer internen width-Angabe. Diese Eigenschaft
deutet darauf hin, dass der Inhalt selbst eine Tabelle ist. Im Falle des
Summary-Objektes handelt es sich um die Breite des Links.
boolean right = false
Definiert ob der Link rechts oder links von der Nachricht plaziert wird.
Die beiden Fehlernachrichten der Text-Objekte werden nicht lokal angezeigt
weil die Eigenschaft msgHidden global gesetzt wurde. Sie werden im
Summary-Objekt aufgelistet. Durch einen Klick auf die Nachrichtennummer kann
das dazugehörige Text-Objekt direkt angesprungen werden.
Ein Refresh-Objekt generiert eine Taste mit der alle Eingabefelder eines
Formulars zurückgesetzt werden können. Der Server wird dabei nicht kontaktiert.
Eigenschaften:
{html} label
Der label definiert die Aufschrift auf der Refresh-Taste.
Die abstrakte Klasse SingleVarContent ist die Basisklasse für
alle Eingabelayouts des Formulars, die den Inhalt eines Datenfeldes repräsentieren.
Das Datenfeld wird entsprechend des Layouts angezeigt und kann geändert werden.
Die Eingabelayouts sind die klassischen Formularelemente die Html anbietet. Dazu gehören
einfache Eingabefelder, Radio-Tasten, Check-Boxen, Combo-Listen, Textfeldeingaben,
Passwordfelder und Submit-Tasten. Jedes von SingleVarContent abgeleitete Objekt
holt sich das dazugehörige Datenfeld aus dem Anwenderobjekt, interpretiert es nach
seinen Erfordernissen und generiert den passenden Html-Code. So erlauben Radio-Tasten
z.B. nur numerische Datenfelder. Ist das Feld nicht numerisch gibt es zwar keinen Fehler,
aber keine der Radio-Tasten wird als aktiviert angezeigt. Wird keine der Tasten
aktiviert enthält das Datenfeld einen Leerstring als Standardangabe.
Eigenschaften:
string var
Die Eigenschaft var verweist auf den Namen des Datenfeldes.
Das Datenfeld muss nicht existieren und kann einem beliebigen Alias
angehören. Diese Eigenschaft ist eine Pflichtangabe.
Die Password-Klasse ist von der SingleVarContent-Klasse
abgeleitet. Ein Password-Objekt erzeugt ein maskiertes Eingabefeld
für Texteingaben. Alle Zeichen werden als "*" dargestellt.
Eigenschaften:
{html} label
Definiert einen Text der links vom Eingabebereich erscheint. In der Regel beschreibt
er den einzugebenden Inhalt.
{html} unit
Definiert einen Text der rechts vom Eingabebereich erscheint. In der Regel beschreibt
er die Einheit des einzugebenden Inhalts.
int length = 80
Gibt die maximale Länge des Zeichenpuffers an. Soviele Zeichen
können eingegeben werden. Danach wird der Cursor blockiert.
int col
Gibt die Breite des Eingabebereiches in Zeichen an.
Beispiel:
maxInactiveInterval = 0;
[padding] = 4;
[spacing] = 0;
[backColor] = khaki;
Table
{ borderColor = orange;
spacing = 4;
padding = 0;
Text
{ text = "Geben Sie bitte Login und Password an.";
backColor = orange;
align = center;
}
Frame
{ padding = 0;
align = center;
Row
{ width = "";
[height] = 32;
Layout
{ [align] = left;
Text
{ text = "Login:";
}
Text
{ text = "Password:";
}
}
Layout
{ [align] = right;
Input
{ var = login;
length = 8;
col = 20;
}
Password
{ var = password;
length = 8;
col = 20;
}
}
}
}
}
Geben Sie bitte Login und Password an.
Login:
Password:
Damit die Eingabefelder in dieser Form plaziert werden konnten, befinden
sie sich in einem übergeordneten Frame-Objekt, das die
Zentrierung vornimmt. Die Text-Objekte sind linksbündig, die
Eingabefelder rechtsbündig in dem Row-Objekt angeordnet. Das
Row-Objekt hat eine leere width-Eigenschaft, damit die
einzelnen Spalten nicht breiter als nötig werden. Nur so kann das
ganze Objekt im Frame zentriert werden. Bei einer Breite von 100%
wäre eine Zentrierung sinnlos. Damit die Texte auf gleicher Höhe
mit den dazugehörigen Eingabefeldern stehen, erhielten alle Row-Elemente
eine fixe Höhe von 32 Pixel.
Die Radio-Klasse ist von der SingleVarContent-Klasse
abgeleitet. Ein Radio-Objekt bietet mehrere Optionen an, von denen
aber immer nur eine markiert werden kann. Wie bei den Frequenzbandtasten
eines alten Radios springt die Taste der bisherigen Frequenz raus wenn
eine neue Taste gedrückt wurde. Das dazugehörige Datenfeld
enthält die Nummer der angewählten Taste (von 1 beginnend).
Eigenschaften:
{htmllist} label
Definiert die Texte der Optionen, die angewählt werden können. Die
Anzahl der Optionen wird über diese Eigenschaft festgelegt.
boolean vertical = false
Ist diese Eigenschaft true, werden die Optionen vertikal
statt horizontal angeordnet.
boolean left = false
Ist diese Eigenschaft true, werden die Optionen links
von den Markierungskästchen angeordnet.
boolean wide = false
Diese Eigenschaft wirkt sich nur bei einer vertikalen Anordnung aus (siehe
vertical). Ist sie gesetzt haben die Optionen immer den
grösst möglichen Abstand zu den Markierungskästchen. Dadurch
entsteht immer eine blockartige Ausrichtung. Die Breite des Blockes ist von der
Eigenschaft spread abhängig.
string spread
Diese Eigenschaft gibt die absolute (Pixelangabe) bzw. relative (Prozentangabe)
Breite des gesamten Radio-Objektes an. Wenn diese Angabe fehlt oder leer
ist wird die Breite dynamisch angepasst. Durch Verwendung von spread
können mehrere Radio-Objekte einheitlich ausgerichtet werden.
int depth = 0
Mit depth kann die minimale Höhe einer Zeile des
Radio-Objektes definiert werden. Bei horizontaler Ausrichtung gibt
es nur eine Zeile.
int margin = 2
Die Eigenschaft margin entspricht dem padding der
einzelnen Elemente des Radio-Objektes. Je grösser dieser Wert
ist desto grösser sind die Abstände zwischen den Elementen
(Optionen, Kästchen), und um so aufgelockerter ist das
Erscheinungsbild.
Beispiel:
maxInactiveInterval = 0;
[padding] = 0;
[spacing] = 0;
[backColor] = khaki;
Table
{ padding = 4;
spacing = 4;
borderColor = orange;
Layout
{ Text
{ text = "Was ist Ihr Lieblingsobst?";
}
Radio
{ var = obst;
label = "Äpfel", "Bananen", "Kirschen", "Erdbeeren";
}
}
Layout
{ Text
{ text = "Was ist Ihr Lieblingsobst?";
}
Radio
{ var = obst;
spread = "100%";
left;
label = "Äpfel", "Bananen", "Kirschen", "Erdbeeren";
}
}
Layout
{ Text
{ text = "Was ist Ihr Lieblingsobst?";
}
Radio
{ var = obst;
vertical;
margin = 0;
wide;
spread = "50%";
label = "Äpfel", "Bananen", "Kirschen", "Erdbeeren";
}
}
}
Ein Area-Objekt ermöglicht die Eingabe von mehrzeiligen Texten.
Im Gegensatz zu Input-Objekten gibt es keine Beschränkung der
Textlänge.
Eigenschaften:
int row = 4
Mit row wird die Anzahl der Zeilen des Texteingabebereiches
definiert.
int col = 80
Mit col wird die Breite des Texteingabebereiches in Zeichen
definiert.
Beispiel:
maxInactiveInterval = 0;
[padding] = 4;
[spacing] = 0;
[backColor] = khaki;
method = get;
Table
{ borderColor = orange;
spacing = 4;
padding = 0;
width = "";
Text
{ text = "Schreiben Sie doch mal ein Gedicht:";
backColor = orange;
}
Area
{ var = gedicht;
col = 60;
row = 16;
}
}
Schreiben Sie doch mal ein Gedicht:
Das Table-Objekt hat eine leere Breitenangabe width.
Dadurch ist das Formular nur so breit wie erforderlich. Der Eingabebereich
verfügt über automatischen Zeilenumbruch. Wie bei
Textverarbeitungsprogrammen wird durch die Enter-Taste ein Absatz generiert.
Bei einem Combo-Objekt handelt es sich um eine Auswahlliste. Der
Anwender kann aus einer unspezifischen Zahl von Optionen eine oder mehrere
auswählen. Der Auswahlbereich kann gescrollt werden, wenn die Zahl der
Optionen zu groß für den Bereich ist. Ausserdem kann das Objekt so
eingestellt werden, dass der Auswahlbereich erst bei Bedarf erscheint. Das
Datenfeld enthält entweder den Optionstext oder die Optionsnummer
(beginnend bei 1). Das Datenfeld wird zu einem Vektor, wenn mehrere Optionen
markiert sind.
Eigenschaften:
{htmllist} label
Die Eigenschaft label definiert die Optionen. Innerhalb eines
Eintrages der Liste werden die einzelnen Optionen durch Kommas getrennt. So
können die Optionen mittels Substitution dynamisch generiert werden.
Kommas können durch "," maskiert werden, wenn sie Bestandteil
einer Option sind.
string item
Die Eigenschaft item verweist auf den Namen eines Datenfeldes bzw.
Datenvektors. Der Eintrag des Datenfeldes bzw. die Einträge des Vektors
werden an die Optionen, die mit label definiert wurden,
angehängt.
int row = 1
Mit row wird die Höhe des Auswahlbereiches in Zeilen definiert.
Ist dieser Wert 1, so klappt der Auswahlbereich nur bei Bedarf aus.
boolean multiple = false
Normalerweise kann immer nur eine Option markiert sein. Ist
multiple gesetzt, können mehrere Optionen mit der Maus
markiert werden. Dazu muss die Kontroll-Taste gleichzeitig gedrückt
werden. Mit der Umschalt-Taste und Mausklicks können ganze Bereiche
markiert werden.
boolean numeric = false
Normalerweise werden die markierten Optionstexte im Datenfeld var
gespeichert. Steht die Eigenschaft numeric auf true,
werden die Positionsnummern der Optionen verwendet.
Das Combo-Objekt kann zwei Darstellungsformen in Abhängigkeit
von den Eigenschaften row und multiple annehmen.
Wenn die multiple-Eigenschaft gesetzt ist, verwendet der
Browser eine Roll-Liste für die Darstellung des Combo-Objektes.
Ein Popup-Menü wird verwendet, wenn die row-Eigenschaft
den Wert 1 hat. Das letzte Combo-Objekt im Beispiel zeigt eine
einzeilige Roll-Liste. Die Substitutionen in diesem Beispiel sind nicht
sehr sinnvoll, da der Inhalt des Datenfeldes "zitrus" nicht
dynamisch erzeugt wird. Durch die Verwendung von Evaluator-Objekten
können Datenfelder für die Substitution dynamisch generiert
werden, wodurch Combo-Objekte ein breites Einsatzspektrum erhalten.
Mit Submit wird ein Formular bestätigt. Alle Eingaben werden zum
Server gesendet und dort verarbeitet. Ein Formular ohne ein Submit-Objekt
kann seine Daten niemals zu dem Server übermitteln. Deshalb
sollte jedes Formular ein solches Objekt haben. Ein Submit-Objekt
kann sich aus mehreren Tasten zusammensetzen. Das dazugehörige
Datenfeld enthält wahlweise die Aufschrift auf der gedrückten
Taste oder die Nummer der Taste innerhalb des Submit-Objektes. Ein
Formular kann mehrere Submit-Objekte haben. Statt Tasten
können Internet-Links angezeigt werden, die über JavaScript
die Submit-Funktion übernehmen.
Eigenschaften:
{htmllist} label
Definiert die Anzahl der Submit-Tasten und die entsprechenden
Aufschriften.
boolean link = false
Wenn diese Eigenschaft true ist, werden die Submit-Tasten
als Internet-Links dargestellt.
boolean numeric = false
Wenn diese Eigenschaft true ist, wird dem dazugehörigen
Datenfeld die Nummer der Taste entsprechend der Position in
label zugewiesen.
boolean vertical = false
Die Anordnung der Submit-Tasten erfolgt in vertikaler Ausrichtung,
wenn diese Eigenschaft true ist. Standardmässig werden
sie horizontal angeordnet.
Beispiel:
maxInactiveInterval = 0;
[padding] = 4;
[spacing] = 0;
[backColor] = khaki;
Table
{ borderColor = orange;
spacing = 4;
padding = 0;
Text
{ text = "Geben Sie bitte Login und Password an.";
backColor = orange;
align = center;
}
Frame
{ padding = 0;
align = center;
Row
{ width = "";
[height] = 32;
Layout
{ [align] = left;
Text { text = "Login:"; }
Text { text = "Password:"; }
}
Layout
{ [align] = right;
[length] = 8;
[col] = 20;
Input
{ var = login;
}
Password
{ var = password;
}
}
}
}
Submit
{ var = ok;
label = " OK ","Abbrechen";
align = right;
backColor = orange;
}
}
Geben Sie bitte Login und Password an.
Login:
Password:
In den bisherigen Beispielen fand keine Kommunikation mit dem Server statt,
da sie keine Submit-Objekte verwendeten. Dieses Formular kann seine
Daten zum Server senden. Ohne Evaluator-Objekte passiert auf der
Server-Seite jedoch nichts mit diesen Daten.
Die abstrakte Klasse MultiVarContent ist die Basisklasse für
alle Eingabelayouts, die den Inhalt mehrerer Datenfelder repräsentieren.
Die Datenfelder werden entsprechend des Layouts angezeigt und können geändert werden.
Diese speziellen Layouts setzten sich aus mehreren Standardelementen zusammen.
Im Normalfall kann zwar fast jedes MultiVarContent-Objekt durch die geschickte
Anordnung primitiverer Objekte nachgebildet werden, aber die Verwendung der
MultiVarContent-Objekte ist weitaus komfortabler.
Eigenschaften:
stringlist var
Die Eigenschaft var verweist auf die Namen der Datenfelder.
Die Datenfelder müssen nicht existieren und können beliebigen
Aliasnamen angehören. Im Normalfall können beliebig viele
Datenfelder referenziert werden. Das Layout des Objektes richtet sich
an der Anzahl der Felder aus. Da Formicula sehr modular aufgebaut ist und
demzufolge leicht erweitert werden kann, ist es durchaus denkbar, dass
Objekte hinzukommen, die eine vorgegebene Anzahl von Feldern benötigen.
Diese Eigenschaft ist eine Pflichtangabe.
Mit Image wird ein Formular bestätigt. Alle Eingaben werden zum
Server gesendet und dort verarbeitet. Die Image-Klasse hat die
gleiche Funktion wie die Submit-Klasse. Statt Tasten werden jedoch
Bilder angezeigt. Wird eines dieser Bilder angeklickt werden
zwei Datenfelder generiert. Die Namen dieser Datenfelder setzen sich aus
dem Datenfeldnamen (siehe Eigenschaft var) und ".x"
beziehungsweise ".y" zusammen. Die beiden Felder enthalten die in dem Bild
angeklickten Koordinaten. Somit können verschiedenen Regionen des
Bildes unterschiedliche Aktionen zugeordnet werden. Ein Bild kann zum
Beispiel in Regionen für die Aktionen "OK", "Abbrechen", "Zurück"
und "Hilfe" unterteilt sein. Die Gestaltungsmöglichkeiten sind
unbegrenzt. Einfacher - jedoch auch unflexibler - ist es, jeder Funktion
ein Bild zuzuweisen und nur die Existenz der Koordinaten statt deren Position
zu prüfen.
Eigenschaften:
{stringlist} source
Definiert die Pfade zu den Bildern. Diese sollten im "gif"-Format
vorliegen.
boolean vertical = false
Die Bilder werden vertikal statt horizontal angeordnet, wenn diese Eigenschaft
true ist.
Beispiel:
maxInactiveInterval = 0;
[padding] = 4;
[spacing] = 0;
[backColor] = khaki;
Table
{ borderColor = orange;
spacing = 4;
padding = 0;
Text
{ text = "Geben Sie bitte Login und Password an.";
backColor = orange;
align = center;
}
Frame
{ padding = 0;
align = center;
Row
{ width = "";
[height] = 32;
Layout
{ [align] = left;
Text
{ text = "Login:";
}
Text
{ text = "Password:";
}
}
Layout
{ [align] = right;
Input
{ var = login;
length = 8;
col = 20;
}
Password
{ var = password;
length = 8;
col = 20;
}
}
}
}
Image
{ var = img.ok, img.cancel;
source = "../../../execute.gif";
source = "return.gif";
backColor = orange;
align = right;
padding = 0;
}
}
Geben Sie bitte Login und Password an.
Login:
Password:
Die beiden Bilder werden über die source-Eigenschaften
referenziert. Der Pfad der ersten Bildquelle ist relativ. Die zweite Quelle
wurde absolut adressiert. Durch klicken auf das erste Bild, erhält der
Server die beiden Datenfelder "img.ok.x" und "img.ok.y" mit den
Koordinaten des "Klicks". Die Datenfelder von Image-Objekten sollten
immer einen Alias (in diesem Fall "img") haben, da sonst die Datenfeldnamen
selbst zu Aliasnamen werden (z.B. wäre "ok" der Alias des Datenfeldes
"ok.x"). Sie könnten dann ungewollt mit "echten" Aliasnamen
kollidieren. Die Felder "img.ok" und "img.cancel" werden durch dieses
Objekt nicht generiert.
Mit dem Likert-Objekt können sogenannte Likert-Tafeln definiert
werden. Sie erlauben die Bewertung mehrerer Elemente auf einer ordinalen
Skala. Die Anzahl der Skalenpunkte kann vorgegeben werden. Der Wertebereich
der Datenfelder reicht von 1 bis zur Anzahl der Skalenpunkte. Unbewertete
Datenfelder sind leer.
Eigenschaften:
{htmllist} label
Definiert die Anzahl und die Beschreibungen der Skalenpunkte. Es sind
auch leere label erlaubt.
{htmllist} info
Mit info werden die einzelnen zur Bewertung ausstehenden
Elemente beschrieben.
{html} intro
Dieser Text erscheint als Überschrift über den info-Definitionen.
string evenBackColor
Definiert die Hintergrundfarbe der geraden Elemente.
string oddBackColor
Definiert die Hintergrundfarbe der ungeraden Elemente.
string evenForeColor
Definiert die Textfarbe der geraden Elemente.
string oddForeColor
Definiert die Textfarbe der ungeraden Elemente.
boolean random = false
Ist diese Option true, werden die Elemente zufällig
angeordnet. Dadurch können Verzerrungen in den erhobenen Daten vermieden werden,
die bei langen Likert-Tafeln auftreten. Elemente die am Ende der Likert-Tafel stehen,
werden in der Regel nicht so aufmerksam ausgefüllt wie Elemente am Anfang. Durch
die zufällige Anordnung wird die Auswirkung dieses Effektes auf die gesamte Tafel
verteilt.
string spread = 50%
Mit dem spread wird die relative bzw. absolute Breite des Skalenbereiches
definiert.
int depth = 0
Definiert die minimale Höhe eines Elements in Pixeln.
Ein Objekt der Likert-Klasse könnte theoretisch mit einer
Kombination diverser Group-, Text- und Radio-Objekte
gebildet werden. Praktisch ist das jedoch sehr umständlich und das
Likert-Objekt bietet zusätzlich den Vorteil der
random-Eigenschaft.
Die Check-Klasse generiert eine Liste aus Optionen. Im Gegensatz
zur Radio-Klasse können mehrere Elemente markiert werden.
Die Liste kann mit einer Check-Liste für die Startvorbereitung eines
Flugzeugs verglichen werden. Jede Option entspricht einem Datenfeld.
Markierte Datenfelder haben den Wert 1.
Eigenschaften:
{htmllist} label
Definiert die Texte der Optionen, die markiert werden können.
boolean vertical = false
Ist diese Eigenschaft true, werden die Optionen vertikal
statt horizontal angeordnet.
boolean left = false
Ist diese Eigenschaft true, werden die Optionen links
von den Markierungskästchen angeordnet.
boolean wide = false
Diese Eigenschaft wirkt sich nur bei einer vertikalen Anordnung aus (siehe
vertical). Ist sie gesetzt haben die Optionen immer den
größt möglichen Abstand zu den Markierungskästchen. Dadurch
entsteht immer eine blockartige Ausrichtung. Die Breite des Blockes ist von der
Eigenschaft spread abhängig.
string spread
Diese Eigenschaft gibt die absolute (Pixelangabe) bzw. relative (Prozentangabe)
Breite des gesamten Check-Objektes an. Wenn diese Angabe fehlt oder leer
ist wird die Breite dynamisch angepasst. Durch Verwendung von spread
können mehrere Check-Objekte einheitlich ausgerichtet werden.
int depth = 0
Mit depth kann die minimale Höhe einer Zeile des
Check-Objektes definiert werden. Bei horizontaler Ausrichtung gibt
es nur eine Zeile.
int margin = 2
Die Eigenschaft margin entspricht dem padding der
einzelnen Elemente des Check-Objektes. Je grösser dieser Wert
ist desto grösser sind die Abstände zwischen den Elementen
(Optionen, Kästchen), und um so aufgelockerter ist das
Erscheinungsbild.
Beispiel:
maxInactiveInterval = 0;
[padding] = 0;
[spacing] = 0;
[backColor] = khaki;
Table
{ padding = 4;
spacing = 4;
borderColor = orange;
Layout
{ Text
{ text = "Was kommt in den Obstsalat?";
}
Check
{ var = aepfel, bananen, kirschen, erdbeeren;
label = "Äpfel", "Bananen", "Kirschen", "Erdbeeren";
}
}
Layout
{ Text
{ text = "Was kommt in den Obstsalat?";
}
Check
{ var = aepfel, bananen, kirschen, erdbeeren;
spread = "100%";
left;
label = "Äpfel", "Bananen", "Kirschen", "Erdbeeren";
}
}
Layout
{ Text { text = "Was kommt in den Obstsalat?"; }
Check
{ var = aepfel, bananen, kirschen, erdbeeren;
vertical;
margin = 0;
wide;
spread = "50%";
label = "Äpfel", "Bananen", "Kirschen", "Erdbeeren";
}
}
}
Die Matrix-Klasse ist eine Kombination aus der Likert- und der
Check-Klasse. In einer matrixähnlichen Struktur können
beliebige Knotenpunkte markiert werden. Jeder Knotenpunkt entspricht einem
Datenfeld. Markierte Datenfelder erhalten den Wert 1, unmarkierte Datenfelder
sind leer. Da im Gegensatz zu Likert jede Zeile durch mehrere Datenfelder
repräsentiert wird, müssen die Datenfeldnamen Zeile für Zeile
in der var Eigenschaft definiert werden.
Eigenschaften:
{htmllist} label
Definiert die Anzahl und die Beschreibungen der Spalten. Es sind
auch leere label erlaubt.
{htmllist} info
Mit info werden die Zeilen beschrieben.
{html} intro
Dieser Text erscheint als Überschrift über den info-Definitionen.
string evenBackColor
Definiert die Hintergrundfarbe der geraden Zeilen.
string oddBackColor
Definiert die Hintergrundfarbe der ungeraden Zeilen.
string evenForeColor
Definiert die Textfarbe der geraden Zeilen.
string oddForeColor
Definiert die Textfarbe der ungeraden Zeilen.
boolean random = false
Ist diese Option true, werden die Zeilen zufällig
angeordnet. Dadurch können Verzerrungen in den erhobenen Daten vermieden werden,
die bei langen Matrizen auftreten. Zeilen die am Ende der Matrix stehen,
werden in der Regel nicht so aufmerksam ausgefüllt wie Zeilen am Anfang. Durch
die zufällige Anordnung wird die Auswirkung dieses Effektes auf die gesamte Matrix
verteilt.
string spread = 50%
Mit dem spread wird die relative bzw. absolute Breite des Spaltenbereiches
definiert.
int depth = 0
Definiert die minimale Höhe einer Zeile in Pixeln.
int margin = 2
Gibt das interne Padding der Matrix an.
Beispiel:
maxInactiveInterval = 0;
[padding] = 4;
[spacing] = 0;
[backColor] = khaki;
Table
{ borderColor = orange;
spacing = 4;
padding = 0;
Matrix
{ var = banane1, banane2, banane3;
var = kirsche1, kirsche2, kirsche3;
var = kiwi1, kiwi2, kiwi3;
var = pflaume1, pflaume2, pflaume3;
var = zitrone1, zitrone2, zitrone3;
var = andere1, andere2, andere3;
label = "gewürfelt", "in Scheiben", gepresst;
info = Banane, Kirsche, Kiwi, Pflaume, Zitrone, "Andere Früchte";
intro = "Wie kommt was in den Obstsalat?";
spread = 50%;
oddBackColor = orange;
}
}
Objekte der Klasse Evaluator sind für die Funktionalität
des Formulars zuständig. Evaluatoren werden in der Regel (es gibt eine
Ausnahme) nach dem Erhalt der Formulardaten ausgewertet. Sie bestimmen ob
zu einer weiteren Seite gesprungen wird, ob Fehler anzuzeigen sind oder
Datenbankfunktionen durchgeführt werden. Ein Evaluator ist
entweder Container für Objekte der Klasse Operator oder
der Klasse Evaluator. Beide Klassen geben einen boolschen Wert
zurück. Ist dieser true, wird die Funktion des
übergeordneten Evaluator-Objektes ausgeführt.
Manche Evaluator-Funktionen können ihrerseits
den Rückgabewert beeinflussen. Führte eine Datenbankabfrage zu
keinem Ergebnis, gibt der Evaluator den Wert false
zurück.
Die Klasse Content ist als Container für Evaluator-Objekte
definiert. Die Evaluatoren auf der höchsten Ebene des
Content werden sequentiell ausgeführt. Ihre Rückgabewerte
haben keine Bedeutung für das Content-Objekt.
Ein Evaluator hat immer einen bestimmten boolschen Modus. Dieser
definiert wie die Rückgabewerte der Containerobjekte verknüpft
werden. Ausserdem gibt er vor, ob die Auswertung fortgesetzt werden soll,
wenn das Resultat nicht mehr den Wert true erreichen kann. Die
Auswertung eines Evaluator-Objektes ist ein rekursiver Prozess, der
zuerst in die Tiefe der Hierarchie vordringt. Da sich Evaluator- und
Operator-Objekte gegenseitig ausschliessen, können letztere nur
auf der tiefsten Evaluator-Ebene definiert werden.
Es gibt Einschränkungen bezüglich der Verschachtelung von
Evaluator-Objekten. Die Einschränkungen werden auf einer
Ebene abstrakter Unterklassen von Evaluator realisiert. So
können z.B. Evaluatoren der Klasse FunctionEvaluator nicht
miteinander verschachtelt werden oder NavigationEvaluator-Objekte
nicht innerhalb eines Utilize-Evaluators liegen.
Eigenschaften:
stringlist exp
Die Operator-Objekte werden nicht über die herkömmliche Scope-Struktur
definiert. Alle Elemente der Stringliste von exp werden speziell geparst.
Jeder Eintrag entspricht entweder einem Datenfeldnamen, dem Namen einer Operator-Klasse
oder einer Konstanten. Die grundlegende Struktur hat folgenden Aufbau: Datenfeldname, Operator-Klassenname,
Parameter1,...,Parametern
Die Anzahl der Parameter ist abhängig von der Operator-Klasse.
Ein Parameter ist entweder der Name eines Datenfeldes oder eine Konstante.
Manipuliert wird immer das Datenfeld links vom Operator.
Die exp-Eigenschaft kann beliebig viele Operatoren enthalten.
boolean and = true
Diese Eigenschaft legt den boolschen Modus fest. Es kann immer nur ein
Modus vorgegeben werden. Sobald ein Container-Objekt (Evaluator,
Operator) den Wert false zurück gibt, wird die
Auswertung mit dem Resultat false beendet. Der Evaluator
ist true, wenn alle Objekte true sind.
boolean or = false
Diese Eigenschaft legt den boolschen Modus fest. Es kann immer nur ein
Modus vorgegeben werden. Sobald ein Container-Objekt (Evaluator,
Operator) den Wert true zurück gibt, wird die
Auswertung mit dem Resultat true beendet. Der Evaluator
ist false, wenn alle Objekte false sind.
boolean all = false
Diese Eigenschaft legt den boolschen Modus fest. Es kann immer nur ein
Modus vorgegeben werden. Alle Container-Objekte (Evaluator,
Operator) werden unabhängig von ihrem Resultat ausgewertet. Der
Evaluator ist nur dann true, wenn alle Objekte
true sind.
boolean any = false
Diese Eigenschaft legt den boolschen Modus fest. Es kann immer nur ein
Modus vorgegeben werden. Alle Container-Objekte (Evaluator,
Operator) werden unabhängig von ihrem Resultat ausgewertet. Der
Evaluator ist true, wenn mindestens ein Objekt
true ist.
Der Utilize-Evaluator erfüllt eine Sonderfunktion. Er darf nur
auf der höchsten Ebene eines Content-Objektes definiert werden.
Alle untergeordneten Evaluatoren werden ausgewertet bevor die Formularseite
generiert wird. Damit können z.B. vom Formular benötigte
Datenfelder initialisiert bzw. formatiert werden. Evaluatoren, die von der
Klasse VisibilityEvaluator abgeleitet sind, dürfen nur
innerhalb eines Utilize-Evaluators definiert werden.
NavigationEvaluator-Objekte dürfen nicht in einem
Utilize-Objekt definiert werden.
Objekte die von BaseEvaluator abgeleitet sind, bilden das Grundgerüst
für die Formularauswertung. Sie dürfen beliebig kombiniert und
verschachtelt werden.
A = 3 B = 4 C = 1 (A < 5) and (B = 7 or C = 1) = true
In diesem Beispiel wird ein einfacher Ausdruck ausgewertet. Das Resultat
wird über das Feld "x" in dem Text substituiert. Die Auswertung
befindet sich in einem Utilize-Evaluator, damit "x" vor der
Generierung der Seite definiert ist. Im ersten Eval erfolgt die
Initialisierung der Datenfelder. Der set-Operator ist immer
true. Das zweite Eval-Objekt wertet den Ausdruck aus.
Jede Klammer wird durch ein Eval-Objekt repräsentiert. Die
Operatoren lt und eq stehen für "lesser than" bzw.
"equal". Der letzte Evaluator wird nur dann ausgewertet, wenn das
vorherige Evaluator-Objekt true ist.
Der Catch-Evaluator fängt Laufzeitfehler ab. Normalerweise
führt ein Laufzeitfehler zur einer Systemmeldung und der Beendigung
der Session. Mit Catch werden die Fehler der untergeordneten
Evaluator-Objekte aufgefangen. So können z.B.: Fehler bei
unsicheren Datenbankzugriffen abgefangen werden. Im Fehlerfall gibt
Catchfalse zurück und stellt die Systemmeldung
in das Datenfeld "Formicula.Catch", ansonsten verhält er sich wie
ein normaler Evaluator.
Der Loop-Evaluator definiert eine Schleife. Solange sein Resultat
true ist, wird seine Auswertung wiederholt. Nach dem Verlassen
der Schleife liefert er aus rein praktischen Gründen das Resultat
true.
In diesem Beispiel wird ein Countdown mittels Loop-Evaluator
abgezählt. Das Datenfeld "i" wird solange dekrementiert bis es kleiner
als 1 ist. Dann ist die Loop-Auswertung false. Der
nachfolgende Evaluator wird trotzdem ausgeführt, weil
Loop immer true zurück gibt. Der join
Operator verknüpft Zeichenketten. Der sub-Operator führt
eine Subtraktion aus.
Objekte der Klasse FunctionEvaluator erfüllen spezielle Aufgaben.
Sie öffnen Datenbanken, erzeugen Fehlermeldungen, verstecken ganze
Content-Objekte oder navigieren durch die Formularstruktur. Kein
FunctionEvaluator darf innerhalb des Scopes eines anderen
FunctionEvaluator-Objektes definiert sein. Bei konkurrierender
Funktionalität aktivierter FunctionEvaluator-Objekte wird nur die
Funktion des zuletzt Aktivierten ausgeführt. So konkurrierenden zum
Beispiel die Objekte der NavigationEvaluator-Klasse untereinander und mit
dem Exit- bzw. Transfer-Evaluator, die ebenfalls Konkurrenten
sind.
Die Klasse NavigationEvaluator ist für die Navigation von Seite zu
Seite der Formularstruktur zuständig. Objekte dieser Klasse dürfen
nicht innerhalb eines Utilize-Evaluators definiert sein. Die Navigation
wird nicht durchgeführt, wenn MessageEvaluator-Objekte Nachrichten
generiert haben. Mit dem ResetEvaluator können Nachrichten
unterdrückt werden.
Der Jump-Evaluator ermöglicht den Sprung zu einem benannten
Group-Objekt auf der höchsten Ebene der Formularstruktur.
Eigenschaften:
{string} jump
Gibt den Namen der Zielseite (Group) an, die nach der
Auswertung dargestellt werden soll. Bei der Angabe des Namens muss Gross-
und Kleinschreibung beachtet werden.
Beispiel:
Frame
{ Submit
{ var = go;
label = "Seite1", "Seite2", "Ende";
Eval
{ or;
Jump
{ exp = go, eq, "Seite1";
jump = Seite1;
}
Jump
{ exp = go, eq, "Seite2";
jump = Seite2;
}
Jump
{ jump = Ende;
}
}
// Alternative: Jump { jump = "{go}"; }
}
}
Frame Seite1
{ Text
{ text = "Das ist Seite 1";
Utilize { Exit {} }
}
}
Frame Seite2
{ Text
{ text = "Das ist Seite 2";
Utilize { Exit {} }
}
}
Frame Ende
{ Text
{ text = "Das ist das Ende";
Utilize { Exit {} }
}
}
Die Jump-Evaluatoren stehen in einem Evaluator mit
or-Modus. Dadurch wird die Auswertung beschleunigt, da sie
nach der ersten wahren Bedingung beendet wird. Noch effizienter wäre
die Verwendung einer Substitution in der jump-Eigenschaft
(auskommentierter Codeabschnitt). Der Exit-Evaluator beendet die Session.
Mit dem Skip-Evaluator können relative Sprünge innerhalb
der Formularstruktur durchgeführt werden. Der skip-Evaluator ist besonders
für lineare Formularabläufe geeignet.
Eigenschaften:
int skip = 0
Gibt die relative Position der Zielseite in Bezug auf die aktuelle Seite
an. Die Angabe kann auch negativ sein.
Beispiel:
Frame
{ Submit
{ var = go;
label = "Seite1", "Seite2", "Ende";
Eval
{ or;
Skip
{ exp = go, eq, "Seite1";
skip = 1;
}
Skip
{ exp = go, eq, "Seite2";
skip = 2;
}
Skip
{ skip = 3;
}
}
}
}
Frame
{ Text
{ text = "Das ist Seite 1";
Utilize
{ Exit {}
}
}
}
Frame
{ Text
{ text = "Das ist Seite 2";
Utilize
{ Exit {}
}
}
}
Frame
{ Text
{ text = "Das ist das Ende";
Utilize
{ Exit {}
}
}
}
Der Back-Evaluator springt immer zur vorherigen Seite zurück.
Seine Funktion ist ungefähr vergleichbar mit dem Back-Button des Browsers.
Allerdings ist die Verwendung des Back-Evaluators eleganter, da die
Seite nicht eventuell veraltete Informationen aus dem Cache des Browsers
enthält.
Beispiel:
Frame
{ Submit
{ var = go;
label = "Seite1", "Ende";
Eval
{ or;
Skip
{ exp = go, eq, "Seite1";
skip = 1;
}
Skip { skip = 2; }
}
}
}
Frame
{ Text { text = "Das ist Seite 1"; }
Submit
{ var = go;
label = "Weiter","Back";
Eval
{ or;
Back
{ exp = go, eq, "Back";
}
Skip { skip = 1; }
}
}
}
Frame
{ Text { text = "Das ist das Ende"; }
Submit
{ var = go;
label = "Back";
Back {}
}
}
Objekte der Klasse UtilityEvaluator erfüllen diverse nützliche
Funktionen, die sich auf ganze Aliasgruppen beziehen.
Eigenschaften:
string alias
Gibt den Aliasnamen der Datenfeldgruppe an auf die sich der UtilityEvaluator
bezieht. Wenn die Angabe fehlt oder leer ist, wird der Standardalias verwendet, dem
alle Datenfelder ohne spezifischen Alias zugeordnet sind.
Der Clear-Evaluator löscht die Inhalte einer Aliasgruppe oder die gesamte Gruppe.
Eigenschaften:
boolean drop = false
Ist diese Eigenschaft false werden nur die Inhalte der Aliasgruppe
gelöscht. Vektoren werden zu einfachen Datenfeldern. Ist diese Eigenschaft
true wird die komplette Aliasgruppe aus dem Speicher entfernt. Diese
Eigenschaft eignet sich vor allem für temporäre Aliasgruppen.
Der Copy-Evaluator kopiert die Inhalte einer Aliasgruppe in eine
andere. Standardmässig wird bei Vektoren nur das aktuelle Element kopiert
(siehe Eigenschaft full). Der Zielalias muss nicht existieren.
Eigenschaften:
string to
Gibt den Alias-Namen der Datenfeldgruppe an, die als Ziel dient.
Wenn die Angabe fehlt oder leer ist, sind die Zielfelder keinem
Alias zugeordnet.
boolean append = false
Wenn diese Eigenschaft true ist, werden die Zielfelder
zu Vektoren. Die Quellfelder werden als neue Elemente an die Zielfelder
angehängt.
boolean full = false
Wenn ein Quellfeld ein Vektor ist wird standardmässig nur das
aktuelle Element kopiert. Ist diese Eigenschaft true,
werden die kompletten Vektoren kopiert. Eine Kombination mit
append ist möglich.
{string} filter = *
Mit filter wird ein Selektionskriterium definiert.
Ein "*" steht für beliebig viele Zeichen, während ein
"?" genau ein Zeichen repräsentiert. Alle anderen Zeichen im
Filter müssen übereinstimmen. So lässt der Filter
"*?Fil?er*" z.B. die Begriffe "XFilter", "Der Filzer filzt" durch,
verweigert aber den Begriffen "Filter", "Der Filtser Hannes" oder
"XFiler" den Durchgang.
Der Copy-Filter wirkt sich auf die zu kopierenden Feldnamen des
in from definierten Alias aus. Gross- und Kleinschreibung
wird ignoriert.
Der Level-Evaluator synchronisiert die Vektoren einer Aliasgruppe
auf den Index eines Feldes dieser Gruppe. Dieser Evaluator
erleichtert die Handhabung von Datenfeldgruppen mit vielen Vektoren, die
den gleichen Index haben sollen. Ein Datenfeld gibt den neuen Index vor und
die anderen ziehen mit Level gleich. Wenn der neue Index die
Vektorgröße überschreitet, wird die oberste Indexgrenze für
den Vektor verwendet.
Eigenschaften:
{string} name
Mit name wird das Datenfeld spezifiziert, nach dessen Index
alle anderen Datenfelder der Aliasgruppe synchronisiert werden. Aliasangaben
werden ignoriert.
Der Gather-Evaluator erzeugt Vektoren, die zum einen
die Inhalte aller Datenfelder und zum anderen die Namen der Datenfelder
einer Aliasgruppe enthalten.
Eigenschaften:
string value
Mit value wird ein Datenfeld spezifiziert, welches alle
Inhalte der Aliasgruppe alias als Vektor aufnimmt. Wenn nur
die Namen der Gruppe von Interesse sind, kann diese Angabe entfallen.
string name
Mit name wird ein Datenfeld spezifiziert, welches alle
Datenfeldnamen der Aliasgruppe alias als Vektor aufnimmt.
Wenn nur die Inhalte der Gruppe von Interesse sind, kann diese Angabe
entfallen.
Die hier aufgelisteten Systemfelder sind dem Alias "formicula"
zugeordnet. Die Namen und Inhalte werden mit dem Gather-Evaluator
in die Datenfelder "sysname" und "sysvalue" als Vektoren
übertragen. Die Vektoren werden in einem Loop-Evaluator
Element für Element abgearbeitet. Der Operator moveind
verschiebt den internen Index eines Vektors entsprechend der
Parameterangabe. Er gibt false zurück, wenn eine
Verletzung der Indexgrenzen stattfinden würde, womit auch die
Schleife beendet wird. Der build-Operator erlaubt die Angabe von
Zeichenketten mit Substitutionen. Mit jedem Schritt wird das Datenfeld
"system" um eine Zeile erweitert. Aufgrund des Substitutionsmodus in
Text wird das Html-Tag "<br>" im Datenfeld "system" nicht
maskiert. Die Escape-Sequenz "\n" (Zeilenwechsel) hat keine Auswirkung
auf die Darstellung der Seite. Sie dient nur der etwas schöneren
Aufbereitung des generierten Html-Codes.
Der Scatter-Evaluator erzeugt einfache Datenfelder aus Vektoren. Er
ist die Umkehrung des Gather-Evaluators. Ein Vekor enthält die
Namen der Datenfelder, ein anderer enthält die dazugehörigen Inhalte.
Feldinhalte die keinem gültigen Namen entsprechen werden ignoriert. Wenn
die Namen inklusive Aliasnamen sind, werden sie diesen spezifischen Aliasguppen
zugeordnet. Einfache Feldnamen werden dem in alias spezifiziertem
Alias zugeordnet.
Eigenschaften:
string name
Mit name wird ein Vektor spezifiziert, der
Datenfeldnamen enthält. Diese werden entsprechend der Angabe
bei alias zu echten Datenfeldern.
string value
Mit value wird ein Vektor spezifiziert, der die
Inhalte zu den generierten Datenfeldern enthält. Wenn die Angabe
fehlt oder leer ist oder die Vektorgrösse kleiner als die von
name ist, werden die restlichen Felder mit dem Leerwert
initialisiert.
Beispiel:
maxInactiveInterval = 0;
Frame
{ border = 1;
Text
{ text = "Sie sind Client {sys.client}. Ihre ID lautet {sys.sessionid}.";
subHtml;
Utilize
{ Gather
{ alias = formicula;
name = sysname;
value = sysvalue;
}
Scatter
{ alias = sys;
name = sysname;
value = sysvalue;
}
}
}
}
Sie sind Client 1. Ihre ID lautet G1T32A2V7128C2X7.
Aus den Systemfeldern der Aliasgruppe "formicula" werden zuerst
mit Gather Vektoren generiert. Der Scatter-Evaluator
setzt diese in Datenfelder der Aliasgruppe "sys" um.
Der Filter-Evaluator wertet einen Datenfeldvektor einer Datenfeldgruppe aus.
Passt der Inhalt eines Elements nicht in das Filterschema wird es gelöscht.
Standardmässig werden alle korrespondierenden Elemente der anderen Datenfeldvektoren
ebenfalls gelöscht. Es wird sozusagen eine Zeile entfernt. Mit der Eigenschaft
single kann die Zeilenlöschung verhindert werden.
Eigenschaften:
Mit name wird der Vektor spezifiziert, der gefiltert wird.
Aliasangaben im Namen werden ignoriert.
boolean single = false
Ist diese Eigenschaft true wirkt sich die Filteroperation
nur auf den in name spezifizierten Vektor aus.
boolean exact = false
Ist diese Eigenschaft true, wird Gross- und Kleinschreibung
beachtet. Standardmässig findet keine Unterscheidung statt.
boolean inverse = false
Ist diese Eigenschaft true, wirkt sich der Filter umgekehrt aus.
Alle Elemente, die nicht zum Filter passen, bleiben erhalten. Der Filter definiert
ein Ausschlusskriterium.
{string} filter = *
Mit filter wird ein Selektionskriterium definiert.
Ein "*" steht für beliebig viele Zeichen, während ein
"?" genau ein Zeichen repräsentiert. Alle anderen Zeichen im
Filter müssen übereinstimmen. So lässt der Filter
"*?Fil?er*" z.B. die Begriffe "XFilter", "Der Filzer filzt" durch,
verweigert aber den Begriffen "Filter", "Der Filtser Hannes" oder
"XFiler" den Durchgang.
Dieses Beispiel ist eine Erweiterung des Beispiels für den Gather-Evaluator.
Der Filter lässt nur die Elemente des "sysname" Datenvektors mit der Endung "id"
durch. Da die korrespondierenden Elemente in "sysvalue" ebenfalls gefiltert werden sind
beide Vektoren synchron.
Der Dir-Evaluator erzeugt eine Inhaltsliste eines Verzeichnisses.
Alle Dateien und Unterverzeichnisse werden in einer Aliasgruppe gespeichert.
Die Angaben können nach dem Dateinamen gefiltert und sortiert werden.
Der Evaluator gibt false zurück, wenn die
Inhaltsliste leer ist.
Eigenschaften:
{string} path = .
Diese Eigenschaft spezifiziert das Verzeichnis. Standardmässig wird
das Arbeitsverzeichnis des Servers verwendet. Für die Pfadangaben
können auch "/" (Slash) statt "\" (Backslash) verwendet werden. Da
letztere auch Escapesequenzen einleiten müssen sie durch "\\"
(doppeltes Backslash) maskiert werden.
{string} filter = *
Mit filter wird ein Selektionskriterium definiert.
Ein "*" steht für beliebig viele Zeichen, während ein
"?" genau ein Zeichen repräsentiert. Alle anderen Zeichen im
Filter müssen übereinstimmen. So lässt der Filter
"*?Fil?er*" z.B. die Begriffe "XFilter", "Der Filzer filzt" durch,
verweigert aber den Begriffen "Filter", "Der Filtser Hannes" oder
"XFiler" den Durchgang. Gross- und Kleinschreibung wird nicht beachtet.
Dieser Filter wirkt sich auf die Datei- und Verzeichnisnamen aus.
Wenn kein Name den Filter passiert, wird eine leere Inhaltsliste
erzeugt. Bezieht sich der Filter auf eine spezifische Datei (das heisst
es sind keine Filtersymbole vorhanden) werden die Informationen
zu dieser Datei direkt geladen. Dadurch können die Attribute
von einzelnen Dateien oder Verzeichnissen schneller ermittelt werden.
boolean sort = false
Ist diese Eigenschaft true werden die Angaben nach dem
Dateinamen sortiert.
Der topath-Operator wandelt die relative Verzeichnisangabe "ant"
in die absolute Angabe "c:\formicula\ant" um. Das Inhaltsverzeichnis
wird im Alias "d" gespeichert. Die Datenvektoren "name", "size", "date",
"dir", "hidden" und "readonly" dieses Alias enthalten die Informationen
zu den einzelnen Dateien und Unterverzeichnissen. Diese Informationen
werden in Form einer dynamisch generierten Html-Tabelle
präsentiert.
Mit dem Sort-Evaluator können ganze Aliasgruppen nach einem
Datenvektor sortiert werden. Dazu müssen alle Datenvektoren des Alias
die gleiche Elementzahl aufweisen. Mit der Eigenschaft single
kann aber auch die Sortierung eines einzigen Vektors spezifiziert werden.
Eigenschaften:
{string} name
Mit name wird der Vektor spezifiziert, der die Sortierung vorgibt.
Aliasangaben werden ignoriert.
boolean single = false
Ist diese Eigenschaft true wirkt sich die Sortierung
nur auf den in name spezifizierten Vektor aus.
boolean down = false
Ist diese Eigenschaft true wird absteigend sortiert.
Die Standardsortierung ist aufsteigend.
boolean exact = false
Ist diese Eigenschaft true wird Gross- und Kleinschreibung
beachtet. Standardmässig findet keine Unterscheidung statt.
boolean numeric = false
Ist diese Eigenschaft true wird der Inhalt des Vektors
numerisch interpretiert und entsprechend sortiert. Standardmässig
findet eine alphanumerische Sortierung statt.
Ein VisibilityEvaluator kontrolliert die Sichtbarkeit von
Content-Objekten. Ein unsichtbares Content-Objekt liefert
keinen Html-Code für die Darstellung. Es entstehen also keine
Lücken an der entsprechenden Stelle. Sind alle Content-Objekte
einer Group unsichtbar, wird auch die Group nicht mehr
dargestellt. Ein VisibilityEvaluator wirkt sich entweder nur auf das
übergeordnete Content-Objekt oder auf alle Content-Objekte
der ganzen Seite aus. Bei letzterer Anwendung können
Content-Objekte explizit als sichtbar deklariert werden.
Formicula erzeugt eine Fehlermeldung, wenn sich ein VisibilityEvaluator
ausserhalb eines Utilize-Evaluators befindet.
Eigenschaften:
boolean global = false
Ist diese Eigenschaft true wirkt sich der VisibilityEvaluatory
auf die gesamte Seite aus.
Der Show-Evaluator hebt die Wirkung eines Hide-Evaluators auf.
Beispiel:
Layout quiz
{ Text
{ text = "Durch welches Verfahren schickte man im alten Athen";
text = "seine Mitbürger in die Verbannung?";
Error
{ exp = athen, empty;
msg = "Antwort erforderlich!";
}
}
Radio
{ var = athen;
label = "Götterspeise", "Henkersmahlzeit";
label = "Scherbengericht", "Grillteller";
vertical;
}
Submit
{ var = ok;
label = "OK";
Skip
{ skip = 1;
}
}
}
Layout aufloesung
{ Frame
{ Text
{ backColor = red;
foreColor = white;
text = "Das war die falsche Antwort.";
Utilize
{ Exit {}
Hide {}
Eval { exp = athen, ne, 3; }
Show {}
Hide { global; }
}
}
}
Frame
{ Text { text = "Sie haben gewonnen!"; }
}
}
Bei diesem kleinen Quiz wird die Auflösung durch
VisibilityEvaluator-Objekte gesteuert. Der erste Text wird
zuerst als unsichtbar deklariert. Wenn die Quiz-Frage falsch beantwortet
wurde, wird das Text-Objekt explizit als sichtbar und alle anderen
Objekte dieser Seite als unsichtbar deklariert. Die lokale Definition
hat Vorrang vor der globalen Definition.
Der Reset-Evaluator setzt die Einstellungen der bisher ausgewerteten
Evaluatoren zurück. Davon sind folgende Klassen betroffen:
NavigationEvaluator, VisibilityEvaluator,
MessageEvaluator, Exit, Transfer.
Dieser Evaluator kann z.B. verwendet werden, um einen unbedingten
Seitenwechsel zu ermöglichen, da Reset die bisher aufgelaufenen
Nachrichten löscht.
Der Exit-Evaluator deklariert die Session als beendet. Diese
Einstellung kann mit dem Reset-Evaluator aufgehoben werden. Steht
Exit in einem Utilize-Evaluator, wird die aktuelle Seite noch
angezeigt. Jede Session sollte durch einen Exit-Evaluator explizit
beendet werden, damit nicht mehr benötigte Resourcen freigegeben
werden können. Eine Session wird automatisch beendet, wenn der
Zeitrahmen zwischen zwei Anfragen die in der Form-Eigenschaft
maxInactiveInterval definierte Spanne überschreitet.
Eigenschaften:
{string} url
Diese Eigenschaft definiert eine Internetadresse (URL), die nach dem Schließen
der Session durch Exit angesprungen wird. Damit kann z.B. wieder zur Seite
gesprungen werden, die den Link auf das Formular enthält.
int pause = 0
Mit pause wird die Zeitverzögerung in Sekunden angegeben,
bis die mit url definierte Adresse aufgerufen wird. Eine
kleine Abschiedsseite könnte so dem Anwender für seine Mühen
danken und nach 5 Sekunden verschwinden.
Beispiel:
Frame
{ Text
{ text = "Vielen Dank, dass Sie mich besucht haben.";
Utilize
{ Exit
{ url = "{formicula.link}";
pause = 5;
}
}
}
}
Diese Seite bedankt sich artig und gibt nach 5 Sekunden wieder zur aufrufenden Seite zurück.
In der Eigenschaft url wird von einem der vielen System-Datenfeldern Gebrauch
gemacht. Diese Felder gehören alle dem Alias "Formicula" an. Das Datenfeld "Formicula.Link"
enthält die aufrufende Adresse.
Der Transfer-Evaluator meldet das Anwenderobjekt von dem aktuellen
Formularobjekt ab und transferiert es zu einem anderen Formularobjekt. Alle
bisher gespeicherten Daten, Datenbankverbindungen, geöffnete Dateien
usw. bleiben erhalten. So ist es möglich ein Anwenderobjekt über
mehrere Formularobjekte zu bearbeiten. Komplexere Anwendungen können
auf mehrere Skripte verteilt werden.
Eigenschaften:
{string} url
Diese Eigenschaft definiert den Dateinamen eines Formicula-Skriptes. Bei relativen
Pfadangaben ist das Standardverzeichnis des Servers zu berücksichtigen.
Diese Eigenschaft ist eine Pflichtangabe.
Row
{ width = "";
Text { text = "Ihr Login war: {login}"; }
Submit
{ var = ok;
label = "ok";
Transfer { url = "ant/login.ant"; }
}
}
Ihr Login war: yogibaer
In dem oberen Skript erfolgt die Eingabe eines Logins. Ein Passwort ist aufgrund der
wirklich extrem eingeschränkten Funktionalität dieser Anwendung nicht erforderlich.
Der Transfer zum "show"-Skript im Unterverzeichnis "ant" erfolgt nach der Bestätigung
der Eingabe mit "ok". Das "show"-Skript wird geladen und das Anwenderobjekt mit dem neuen
Formularobjekt verknüpft. Als Beweis für die gelungene Aktion, wird das Login
angezeigt. Auch in diesem Formular gibt es eine "ok"-Taste mit der das Anwenderobjekt wieder
zum "Login"-Formular zurücktransferiert werden kann.
Der Log-Evaluator gibt eine Meldung an die "Standard-Ausgabe" weiter.
Die Standard-Ausgabe kann eine Log-Datei oder eine Konsole sein. Bei manchen
Servern kann die Log-Datei in einer Konfigurationsdatei für
jedes Servlet separat spezifiziert werden.
Eigenschaften:
{stringlist} log
Diese Eigenschaft enthält die Meldung an die Standard-Ausgabe.
Der Exec-Evaluator führt ein externes Programm aus. Es kann sich dabei
um ein beliebiges, ausführbares Programm handeln. Es ist möglich
Parameter an das Programm zu übergeben.
Eigenschaften:
{stringlist} exec
Das erste Element der Eigenschaft exec definiert den Aufruf des
Programms. Alle folgenden Elemente der Stringliste werden als Parameter
weitergeleitet.
boolean wait = false
Wenn diese Eigenschaft true ist wartet der Evaluator auf die Beendigung des
Programms. Standardmässig läuft der exec-Prozess parallel.
Ein MessageEvaluator meldet eine Nachricht, die dem übergordneten
Content-Objekt zugeordnet ist und direkt über diesem in den Html-
Code integriert wird. Bezüglich Group-Objekten werden sie behandelt
als seien sie ein Bestandteil des Content-Objektes. Nachrichten werden
nicht durch VisibilityEvaluator-Einstellungen beeinflusst. Formicula
versucht grundsätzlich Nachrichten darzustellen. Deshalb blockieren
Nachrichten die Navigation auf andere Formularseiten oder das Verlassen des
Formulars aufgrund anderer Evaluatoren. Nachrichten können
allerdings mit dem Reset-Evaluator explizit zurückgesetzt werden,
wodurch die Navigation wieder möglich wird. Eine Nachricht, die innerhalb
eines Utilize-Evaluators gemeldet wird, hat nur informativen Charakter und
blockiert die Funktionalität anderer Evaluatoren nicht. Die Eigenschaften
ihrer Darstellung können für jedes Content-Objekt individuell
eingestellt werden. Es können auch mehrere Nachrichten pro Content-
Objekt auflaufen.
Eigenschaften:
{htmllist} msg
Die Eigenschaft msg enthält die Nachricht. Substitutionen
werden direkt bei der Auswertung ausgeführt. Diese Eigenschaft ist eine
Pflichtangabe.
In diesem Beispiel wird eine kleine Rechenaufgabe gestellt. Im
Utilize-Evaluator werden die Datenfelder "a" und "b" mit
zufälligen Zahlenwerten zwischen 1 und 10 initialisiert. Der Operator
rand liefert eine Zufallszahl zwischen 0 (einschliesslich) und 1
(ausschliesslich). Der Operator mul führt eine Multiplikation
durch, add eine Addition und trunc schneidet die Kommastellen
ab. Das Feld "x" enthält die Summe. Mit dem Operator free wird
die Existenz des Datenfeldes "a" geprüft, damit die Felder nur einmal
initialisiert werden.
Der Valid-Evaluator prüft, ob die Eingabe von "c" numerisch ist.
Wenn das nicht der Fall ist, wird eine Fehlernachricht gemeldet. Der
Error-Evaluator wird nur aufgerufen, wenn "c" ungleich der wahren
Summe "x" ist. Diese Konstruktion hätte einfacher durch einen
Valid-Evaluator realisiert werden können.
Alle von DataEvaluator abgeleiteten Klassen haben etwas mit
Datenbanken zu tun. Sie öffnen Datenbankverbindungen und schliessen
sie wieder, führen SQL-Anweisungen aus oder steuern Transaktionen.
Ohne die Klasse DataEvaluator könnten die Formulareingaben
nicht gesichert und für die Nutzung durch externe Systeme
verfügbar gemacht werden. Die Kommunikation mit den Datenbanken
erfolgt mittels JDBC-Technologie (Java Database Connectivity). Auch dieser
Bestandteil von Java ist plattformunabhängig, wobei sich der Begriff
Plattform auf die verschiedenen Datenbanksysteme bezieht. Allerdings werden
spezielle Treiberklassen für die jeweiligen Systeme benötigt, die
von der Java-Engine dynamisch geladen werden. Diese Klassen gehören
zum Lieferumfang vieler Datenbankanbieter. Ausserdem wird von Dritten
sogenannte Middleware angeboten, die eine Brückenfunktion zwischen der
Java-Anwendung und der Datenbankwelt übernimmt. Diese Brücken
nutzen die sogenannten ODBC-Treiber um auf die Datenbanken zuzugreifen.
ODBC steht für Open Database Connectivity und ist der Standard
für offene Datenbankanbindungen. Über eine ODBC-JDBC-Bridge
können die verschiedensten Datenbanken mit nur einem Treiber
angesprochen werden. Die Einrichtung der Verbindungen erfolgt über das
leicht konfigurierbare ODBC-System. Zusätzlich können viele Bridges
Client-Server-Dienste für Desktop-Datenbanken übernehmen, wodurch
sich die Leistungsfähigkeit der Client-Server-Architektur mit der
einfachen Handhabung dieser Datenbanksysteme kombinieren lässt.
Eigenschaften:
string handle
Da mehrere Verbindungen zu Datenbanken parallel aufgebaut werden können
muss über diese Eigenschaft zwischen den unterschiedlichen Verbindungen
differenziert werden. Das handle ist ein Bezeichner für die
Verbindung. Er muss bei jedem DataEvaluator angegeben werden, es sei denn
es wird nur eine Verbindung benötigt. Als Standard wird ein leerer Bezeichner
verwendet.
Mit Connect wird die Verbindung zur Datenbank hergestellt. Alle
offenen Verbindungen werden automatisch zusammen mit der Session
geschlossen. Wird eine weitere Verbindung mit dem gleichen
handle aufgebaut wird die bisherige Verbindung geschlossen.
Der explizite Verbindungsabbau kann mit dem
Disconnect-Evaluator durchgeführt werden. In vielen Anwendungen
werden die Eingabedaten mehrerer Formularseiten erst am Ende gespeichert.
Obwohl die Datenbankverbindung nur am Schluss benötigt wird, empfiehlt
es sich sie bereits zu Beginn des Skriptes zu öffnen, damit die Daten
auch sicher geschrieben werden können. Wenn ein Fehler beim
Öffnen der Verbindung auftritt, wird die Session abgebrochen und eine
Systemfehlermeldung angezeigt, die Aufschluss über die Ursache des
Fehlers gibt. Kommt es häufiger vor, dass die Datenbank nicht online
ist, sollte der Connect-Evaluator innerhalb eines Catch-Evaluators
stehen. Der vorhersehbare Fehler führt dann nicht
automatisch zu einem Abbruch und die Session kann z.B. mit einer Hinweisseite
kontrolliert beendet werden.
Eigenschaften:
{string} driver
Hier muss der Name des JDBC-Treibers für die Datenbank angegeben
werden. Solche Treiber werden bei den meisten Datenbanken mitgeliefert. Er
muss über die CLASSPATH Systemvariable lokalisierbar sein. In der
Regel bietet der Web-Server auch ein spezielles Verzeichnis an, in das
die Klassenverzeichnisse aller Hilfsklassen kopiert werden können.
Dieses Verzeichnis wird automatisch im CLASSPATH registriert. Auch das
Formicula-Klassenverzeichnis befindet sich normalerweise darin. Ein
Treiber wird immer nur einmal geladen und muss nicht bei jedem Aufruf von
Connect spezifiziert werden. Es ist möglich Treiber von verschiedenen
Datenbanken zu laden.
{string} connection
Mit connection wird die Verbindung zur Datenbank
hergestellt. Die Angabe enthält die Kennung des zu verwendeten
Treibers und die Adresse der Datenbank. In Zusammenspiel mit dem Treiber
ermöglicht er den Verbindungsaufbau mit der Datenbank. Wenn diese
Angabe fehlt wird nur der Treiber geladen. Der Aufbau des Connection-Strings
ist der Dokumentation für die JDBC-Komponenten der
Datenbank zu entnehmen.
{string} user
Der user einer Datenbank bezeichnet das Login für
einen bestimmten Datenbankbereich. Mit dem user sind die
Zugriffsrechte auf die Datenbank verknüpft. In der Regel versteht
man unter einem user eine ganze Gruppe von Anwendern. Nicht
alle Datenbanken verlangen die Angabe von user oder
password.
{string} password
Mit dem password muss sich der user bei der
Datenbank authentisieren. Nicht alle Datenbanken verlangen
die Angabe von user oder password.
Dieses Skript öffnet eine Datenbankverbindung und schliesst sie gleich
wieder. Der Treiber gehört zu einer JDBC-ODBC-Bridge. Der Connection-String
hat immer den gleichen Aufbau. Nach dem Kürzel "jdbc" folgt
eine Beschreibung der Datenbank. In diesem Fall heisst das Produkt
"JDataConnect". Damit ist das Protokoll wie bei einer Internetadresse
definiert. Es folgt die Adressierung der Datenbank. Der JDBC-ODBC-Server
hat eine lokale IP-Adresse. Die Datenbank ist mit der Bezeichnung "konj" im
ODBC-System eingetragen. Sie benötigt weder user noch
password.
Mit Disconnect wird die Verbindung zur Datenbank geschlossen und die
damit verbundenen Resourcen freigegeben. Sie sollte nur dann geschlossen
werden, wenn sie nicht mehr benötigt wird, da der Verbindungsaufbau
bei den meisten Systemen eine recht aufwendige und zeitintensive Aktion
ist. Mit Disconnect können Resourcen gezielt freigesetzt werden,
wenn die Datenbank z.B. nur anfänglich benötigt wird.
Der Select-Evaluator führt eine einfache SQL-Select-Anweisung
aus. Wenn keine Datensätze der Abfrage entsprechen,
gibt dieser Evaluator als Resultat false zurück.
Das System-Datenfeld "Formicula.Select" ist "true", wenn ein
oder mehrere Datensätze gefunden wurden, ansonsten ist das Feld
"false". Die Tabellenfelder des ersten Ergebnisdatensatzes
werden in entprechende Datenfelder kopiert.
Eigenschaften:
{string} table
Mit table muss ein Tabellenname der Datenbank
spezifiziert werden.
string alias
Die Ergebnisdatenfelder werden unter dieser Aliasgruppe
gespeichert. Wenn die Angabe fehlt oder leer ist, wird table
als Aliasname verwendet.
stringlist field
Diese Liste enthält die Namen der Tabellenfelder, die selektiert und
in die Ergebnisdatenfelder übernommen werden sollen. Wenn diese
Angabe fehlt oder leer ist, werden alle Tabellenfelder übernommen.
{stringlist} sql
Diese Eigenschaft definiert die SQL-Klauseln nach der "from"-Klausel.
Datenfelder können integriert werden, in dem sie in
eckige Klammern gesetzt werden. Dabei ist zu beachten, dass sie die
gleichen Namen wie Felder der Tabelle haben. Der Typ des Tabellenfeldes
bestimmt dann die Umformung des typenlosen Datenfeldes. Nur so kann die
korrekte Generierung der SQL-Anweisung gewährleistet werden. Der
Aliasname des Datenfeldes spielt dabei keine Rolle. Grundsätzlich
sollten alle typenspezifischen Merkmale wie z.B. Anführungszeichen bei
Zeichenketten bei der Integration von Datenfeldern vermieden werden.
Zusätzlich unterstützt die SQL-Eigenschaft die
Standardsubstitution, die vor der Integration durchgeführt wird.
boolean save = false
Wenn diese Eigenschaft true ist, wird das Ergebnis der
Abfrage intern unter dem in alias definierten Namen gesichert.
Dieser Name dient als Referenz für andere DataEvaluator-Objekte,
die sich die Ergebnisse von Abfragen beziehen (siehe Next-Evaluator).
In diesem Beispiel erfolgt ein Zugriff auf die lokale Beispieldatenbank
"test". Der Select-Evaluator selektiert alle Datensätze aus der
Mitarbeiter-Tabelle mit einem Gehalt größer gleich 4000. Die
SQL-Klausel wird über die Substitution der Felder
"where" und "order" gebildet. Das Datenfeld "sql.gehalt" hat den gleichen
Namen wie das Bezugsfeld in der Tabelle, damit es typenspezifisch
integriert werden kann. Nach der Selektion werden die Ergebnisfelder
des Alias "ma" in Form einer Html-Tabelle in das Datenfeld "liste"
transferiert. Der Loop-Evaluator arbeitet das Ergebnis Datensatz
für Datensatz ab. Mit Next wird jeweils der nächste
Ergebnissatz in die Datenfelder des Alias "ma" geladen. Sind keine Ergebnisse
mehr vorhanden, gibt Next den Wert false zurück, womit die
Loop-Schleife beendet wird. Im zweiten Utilize-Evaluator wird
die Verbindung explizit geschlossen.
Der Update-Evaluator führt eine einfache SQL-Update-Anweisung
aus. Wenn keine Datensätze der Abfrage entsprechen,
gibt dieser Evaluator als Resultat false zurück.
Das System-Datenfeld "Formicula.Update" enthält die Anzahl der
geänderten Datensätze.
Eigenschaften:
{string} table
Mit table muss ein Tabellenname der Datenbank
spezifiziert werden.
string alias
Diese Eigenschaft enthält den Aliasnamen der Datenfelder, die für
die Aktualisierung der gleichnamigen Tabellenfelder verwendet werden. Wenn
die Angabe fehlt oder leer ist, wird table als Aliasname
verwendet.
stringlist field
Diese Liste enthält die Namen der Tabellenfelder, die aktualisiert
werden sollen. Wenn die Angabe fehlt oder leer ist, versucht der
Update-Evaluator alle Tabellenfelder mit den gleichnamigen
Datenfelder der Aliasgruppe alias zu aktualisieren.
Die in field definierten Felder sind eine Teilmenge
der Aliasgruppe.
{stringlist} sql
Diese Eigenschaft definiert die SQL-Klauseln nach der "from"-Klausel.
Datenfelder können integriert werden, indem sie in
eckige Klammern gesetzt werden. Dabei ist zu beachten, dass sie die
gleichen Namen wie Felder der Tabelle haben. Der Typ des Tabellenfeldes
bestimmt dann die Umformung des typenlosen Datenfeldes. Nur so kann die
korrekte Generierung der SQL-Anweisung gewährleistet werden. Der
Aliasname des Datenfeldes spielt dabei keine Rolle. Grundsätzlich
sollten alle typenspezifischen Merkmale wie z.B. Anführungszeichen bei
Zeichenketten bei der Integration von Datenfeldern vermieden werden.
Zusätzlich unterstützt die SQL-Eigenschaft die
Standardsubstitution, die vor der Integration durchgeführt wird.
Der Mitarbeiter, dessen Feld "ID" gleich 5 ist, erhält eine
Gehaltserhöung auf 7000. Für die Aktualisierung von
Tabellenfeldern mit dem Update-Evaluator dürfen nur
Datenfelder, die einer Aliasgruppe angehören, verwendet werden. Das
Datenfeld "new.gehalt" aktualisiert das Tabellenfeld "gehalt" der
"Mitarbeiter"-Tabelle. In diesem Fall ist die Angabe der
field-Eigenschaft überflüssig, da die Aliasgruppe
"new" keine Felder enthält, die nicht zur Aktualisierung herangezogen
werden sollen. Trotzdem ist es sinnvoll field anzugeben,
damit die Intention des Updates deutlich wird.
Der Delete-Evaluator führt eine einfache SQL-Delete-Anweisung
aus. Wenn keine Datensätze der Abfrage entsprechen,
gibt dieser Evaluator als Resultat false zurück.
Das System-Datenfeld "Formicula.Delete" enthält die Anzahl der
gelöschten Datensätze.
Eigenschaften:
{string} table
Mit table muss ein Tabellenname der Datenbank
spezifiziert werden.
{stringlist} sql
Diese Eigenschaft definiert die SQL-Klauseln nach der "from"-Klausel.
Datenfelder können integriert werden, indem sie in
eckige Klammern gesetzt werden. Dabei ist zu beachten, dass sie die
gleichen Namen wie Felder der Tabelle haben. Der Typ des Tabellenfeldes
bestimmt dann die Umformung des typenlosen Datenfeldes. Nur so kann die
korrekte Generierung der SQL-Anweisung gewährleistet werden. Der
Aliasname des Datenfeldes spielt dabei keine Rolle. Grundsätzlich
sollten alle typenspezifischen Merkmale wie z.B. Anführungszeichen bei
Zeichenketten bei der Integration von Datenfeldern vermieden werden.
Zusätzlich unterstützt die SQL-Eigenschaft die
Standardsubstitution, die vor der Integration durchgeführt wird.
Dieses Beispiel entspricht bis auf ein paar kleine Änderungen dem
Update-Beispiel. Statt einem Update wird ein Delete
ausgeführt. Die Liste umfasst nun alle Mitarbeiter, allerdings ohne
den Mitarbeiter mit der Nummer 5.
Der Insert-Evaluator führt eine einfache SQL-Insert-Anweisung
aus. Wenn keine Datensätze hinzugefügt wurden, gibt dieser
Evaluator als Resultat false zurück. Das System-Datenfeld
"Formicula.Insert" enthält die Anzahl der hinzugefügten
Datensätze. Da ein SQL-Insert immer einen Datensatz anhängt,
werden diese Angaben nur aus Konsistenzgründen gemacht.
Eigenschaften:
{string} table
Mit table muss ein Tabellenname der Datenbank
spezifiziert werden.
string alias
Diese Eigenschaft enthält den Aliasnamen der Datenfelder, die
für die Initialisierung der gleichnamigen Tabellenfelder verwendet
werden. Wenn die Angabe fehlt oder leer ist, wird table als
Aliasname verwendet.
stringlist field
Diese Liste enthält die Namen der Tabellenfelder, die im neuen
Datensatz initialisiert werden sollen. Wenn die Angabe fehlt oder leer ist,
initialisiert der Update-Evaluator alle Tabellenfelder mit den
gleichnamigen Datenfelder der Aliasgruppe alias. Die in
field definierten Felder sind eine Teilmenge der Aliasgruppe.
Der SQL-Evaluator ist der mächtigste aller
DataEvaluator-Klassen, die SQL-Anweisungen generieren. Mit ihm
können beliebige SQL-Anweisungen ausgeführt werden. Seine
Anwendung ist in den meisten Fällen umständlicher und
fehleranfälliger als die der Select-, Update-,
Delete- oder Insert-Evaluatoren. Der SQL-Evaluator
sollte nur dann verwendet werden, wenn diese Evaluator-Klassen nicht
eingesetzt werden können. Handelt es sich bei der SQL-Anweisung um
einen der Standardbefehle "select", "update", "insert" oder "delete", wird
das entsprechende Formicula-Systemfeld mit der Rückgabe der Anweisung
gefüllt. Ausserdem gibt er false zurück, wenn der
Standardbefehl kein Resultat in Form von gefundenen, geänderten,
gelöschten oder hinzugefügten Datensätzen produzierte. Ist
die Anweisung kein Standardbefehl (z.B. "create table"), gibt der Evaluator
immer true zurück.
Eigenschaften:
string alias
Wenn die sql-Eigenschaft eine "select"-Anweisung ist, werden
die Ergebnisdatenfelder unter dieser Aliasgruppe gespeichert. Diese
Angabe darf nicht leer sein oder fehlen.
{stringlist} sql
Diese Eigenschaft definiert die komplette SQL-Anweisung.
Datenfelder können integriert werden, indem sie in
eckige Klammern gesetzt werden. Dabei ist zu beachten, dass sie die
gleichen Namen wie Felder der Tabelle haben. Der Typ des Tabellenfeldes
bestimmt dann die Umformung des typenlosen Datenfeldes. Nur so kann die
korrekte Generierung der SQL-Anweisung gewährleistet werden. Der
Aliasname des Datenfeldes spielt dabei keine Rolle. Grundsätzlich
sollten alle typenspezifischen Merkmale wie z.B. Anführungszeichen bei
Zeichenketten bei der Integration von Datenfeldern vermieden werden.
Zusätzlich unterstützt die SQL-Eigenschaft die
Standardsubstitution, die vor der Integration durchgeführt wird.
boolean save = false
Wenn diese Eigenschaft true und die sql-Eigenschaft
eine "select"-Anweisung ist, wird das Ergebnis der Abfrage
intern unter dem in alias definierten Namen gesichert. Dieser
Name dient als Referenz für andere DataEvaluator-Objekte, die
sich die Ergebnisse von Abfragen beziehen (siehe Next-Evaluator).
Die Definitionsliste ordnet jeder Abteilung die dazugehörigen
Mitarbeiter zu. Die SQL-Abfrage verknüpft die "Mitarbeiter"-Tabelle
mit der Tabelle "Abteilung" über die Abteilungsnummer "abtnr". Das
Ergebnis ist nach der Abteilungsnummer sortiert. Die Sortierung
ermöglicht eine Darstellung mit Gruppenwechsel auf Abteilungsebene.
Der Next Evaluator läd den nächsten Ergebnisdatensatz
aus einer Ergebnistabelle in die dazugehörige Aliasgruppe. Wenn
kein Ergebnisdatensatz mehr vorhanden ist, gibt Nextfalse zurück. Ergebnistabellen werden über den
dazugehörigen Aliasnamen referenziert. Die Evaluatoren Select und
SQL erzeugen Ergebnistabellen, wenn die Eigenschaft save auf
true steht.
Eigenschaften:
string alias
Mit dieser Eigenschaft wird zum einen die Ergebnistabelle und zum
anderen die dazugehörige Aliasgruppe referenziert. Die
entsprechenden Felder in der Aliasgruppe werden mit den Inhalten der
Ergebnisfelder überschrieben.
Der Commit-Evaluator ist für die Bestätigung von
Transaktionen zuständig. Eine Transaktion besteht aus mehreren
Vorgängen, die nur dann eine abgeschlossene Aktion darstellen,
wenn sie komplett abgearbeitet wurden. Sollte einer dieser Vorgänge
abbrechen, ist die Datenbank in einem inkonsistenten Zustand. Um das zu
vermeiden verfügen die meisten Datenbanken über eine
Transaktionskontrolle. Alle Vorgänge einer Transaktion werden
protokolliert und können rückgängig gemacht werden. Ein
Commit bestätigt eine Transaktion als gelungen. Ein
Rollback macht alle Vorgänge rückgängig. Sollte die
Datenbankverbindung während einer Transaktion abbrechen, wird ein
automatischer Rollback durchgeführt. Dies gilt auch, wenn
die Session während einer Transaktion beendet wird.
Eigenschaften:
boolean auto = false
Die Verbindung wird nach dem Commit in den automatischen
Commit-Modus versetzt, wenn diese Eigenschaft true ist.
Alle Vorgänge werden automatisch bestätigt. Dies ist auch die
Voreinstellung für neu geöffnete Datenbankverbindungen. Wenn
auto nicht true ist, beginnt die nächste
Transaktion mit der Bestätigung der aktuellen Transaktion.
Der Rollback-Evaluator macht alle Vorgänge einer aktiven
Transaktion rückgängig. Er ist das Gegenstück zu dem
Commit-Evaluator.
Eigenschaften:
boolean auto = false
Die Verbindung wird nach dem Rollback in den automatischen
Commit-Modus versetzt, wenn diese Eigenschaft true ist.
Alle Vorgänge werden automatisch bestätigt. Dies ist auch die
Voreinstellung für neu geöffnete Datenbankverbindungen. Wenn
auto nicht true ist, beginnt die nächste
Transaktion mit dem Abbruch der aktuellen Transaktion.
Mit dem Touch-Evaluator kann die Datenbankverbindung,
die Existenz von Tabellen und von Tabellenfeldern getestet werden.
Schlägt einer dieser Tests fehl, gibt der Touch-Evaluator
false zurück.
Eigenschaften:
{string} table
Der Touch-Evaluator prüft die Existenz dieser
Tabelle. Fehlt diese Angabe, wird nur die Datenbankverbindung
getestet.
{stringlist} field
Der Touch-Evaluator prüft die Existenz dieser
Tabellenfelder in der Tabelle table. Wenn
ein Feld nicht existiert gibt der Evaluator false
zurück.
Der Meta-Evaluator speichert Meta-Informationen zu einer
Tabelle in einer Aliasgruppe. Dabei werden die Datenfelder "name", "type" (Feldtyp),
"length" (Länge), "scale" (Anzahl Kommastellen), "nullable" (Nullwerte erlaub)
und "compatible" (Kompatibilität zu Formicula) in Form einer Matrix
generiert. Für jedes Tabellenfeld wird eine Zeile angelegt.
Eigenschaften:
{String} table
Gibt den Namen der Tabelle an, deren Meta-Informationen extrahiert werden.
String alias
Gibt die Aliasgruppe an, unter deren Namen die Meta-Informationen
gespeichert werden. Fehlt diese Angabe oder ist sie leer, wird der
Tabellenname als Aliasname verwendet.
Die Meta-Informationen der Tabelle "Mitarbeiter" werden in die
Aliasgruppe "ma" geladen. Die Typen der Tabellenfelder sind numerisch
codiert. Der Code 1 steht für Textfelder, der Code 2 für
Zahlenfelder. Die weiteren Codes können mit einer Variante dieses
Beispiels ermittelt werden. Das Tabellenfeld "gehalt" ist ein
Zahlenfeld, es hat die Länge 10 mit 2 Nachkommastellen, kann
Nullwerte speichern und ist kompatibel mit Formicula. Die letzte Angabe
bedeutet, dass eine Umwandlungsroutine für diesen Tabellenfeldtyp
existiert.
Mit dem Catalog-Evaluator kann ein Katalog aller Tabellen der
Datenbankverbindung abgefragt werden. Catalog erzeugt eine
interne Meta-Tabelle, die wie das Ergebnis einer SQL-Abfrage Datensatz
für Datensatz mittels Next in den entsprechenden Alias
geladen werden kann. Im Gegensatz zu dem Meta-Evaluator werden
die Informationen nicht komplett als Vektoren gespeichert, da eine
Datenbank unter Umständen mehrere tausend Tabellen verwaltet. Die
Tabellennamen und -typen können gefiltert werden. Wenn keine
Tabelle dem Filter entspricht, gibt Catalogfalse
zurück. Die Kataloginformation setzt sich aus folgenden Feldern
zusammen: TABLE_CAT, TABLE_SCHEM, TABLE_NAME, TABLE_TYPE, REMARKS.
Eigenschaften:
string alias
Gibt die Aliasgruppe an, unter deren Namen die Katalog-Informationen
einer Tabelle gespeichert werden. Diese Angabe darf nicht leer sein oder
fehlen.
{string} filter = *
Mit filter wird ein Selektionskriterium definiert.
Ein "*" bzw. "_" steht für beliebig viele Zeichen, während ein
"?" bzw. "%" genau ein Zeichen repräsentiert. Alle anderen Zeichen im
Filter müssen übereinstimmen. So lässt der Filter
"*?Fil?er*" z.B. die Begriffe "XFilter", "Der Filzer filzt" durch,
verweigert aber den Begriffen "Filter", "Der Filtser Hannes" oder
"XFiler" den Durchgang. Gross- und Kleinschreibung wird nicht beachtet.
Dieser Filter wirkt sich auf die Tabellennamen aus.
{stringliste} type
Diese Eigenschaft definiert eine Liste von Tabellentypen, die selektiert
werden sollen. Typische Typen sind TABLE, VIEW, SYSTEM TABLE, GLOBAL
TEMPORARY, LOCAL TEMPORARY, ALIAS oder SYNONYM.
Fehlt diese Angabe oder ist sie leer werden alle Typen selektiert.
boolean save = false
Wenn diese Eigenschaft true ist, wird das Ergebnis der
Katalog-Abfrage intern unter dem in alias definierten Namen gesichert.
Dieser Name dient als Referenz für andere DataEvaluator-Objekte,
die sich die Ergebnisse von Abfragen beziehen (siehe Next-Evaluator).
In diesem Beispiel wird nicht wie bisher der "JDataConnect"-Treiber
sondern die Standard-JDBC-ODBC-Bridge von SUN verwendet. Der ODBC-
Treiber muss auf dem Server installiert sein. Der Katalog der JDBC-ODBC-
Bridge verwendet allerdings andere Feldnamen als die JDBC-Dokumentation
vorgibt. Offensichtlich legt SUN die eigenen Vorgaben sehr liberal aus.
Andere Treiberanbieter wie z.B. NetDirekt (JDataConnect-Treiber) nehmen es
glücklicherweise etwas genauer.
Da die Feldnamen des Kataloges nicht bei jedem Treiber den Regeln
entsprechen, wird in diesem Beispiel ein voll dynamischer Seitenaufbau
demonstriert. Mittels Gather werden die Namen der Ergebnistabelle
aus Catalog in den Vektor "dbname" geladen. Dieser wird verwendet
um auf die einzelnen Felder des Ergebnisalias "db" zuzugreifen. Dabei
ist es nicht notwendig zu wissen wie die Felder heissen. Der Ausdruck
"data, set, *dbname" verwendet den Inhalt des Datenfeldes "dbname" als
Referenz für den eigentlichen Feldnamen. Die Syntax mit dem "*"
definiert eine sogenannte Datenfeldreferenz (siehe Klassenbeschreibung:
Operator). In der ersten Loop-Schleife wird die
Überschrift der Tabelle generiert. Die folgende Schleife läuft
über alle Ergebnissätze, während die innere Schleife
über die Spaltennamen läuft.
Die von IOEvaluator abgeleiteten Klassen ermöglichen
das Schreiben in bzw. das Lesen aus Dateien. Sie sind in erster
Linie für das Speichern nicht anwenderbezogener Daten
oder den Zugriff auf dynamische Seiteninhalte gedacht. Zwar können
mit einigem Aufwand auch anwenderbezogene Daten verwaltet werden, aber
grundsätzlich sind diese Daten in Datenbanken besser aufgehoben.
Eigenschaften:
string handle
Da mehrere Dateien parallel geöffnet sein können, muss
über diese Eigenschaft zwischen den unterschiedlichen Dateien
differenziert werden. Das handle ist ein Bezeichner
für die geöffnete Datei. Er muss bei jedem IOEvaluator
angegeben werden, es sei denn es wird nur eine Datei benötigt. Als
Standard wird ein leerer Bezeichner verwendet.
Open öffnet eine Datei zum Lesen und zum Schreiben.
Geschrieben wird immer an das Ende der Datei, während vom Anfang
zum Ende gelesen wird. Dateien werden automatisch mit der
Session geschlossen. Sie können auch explizit geschlossen werden um
Resourcen frühzeitig freizugeben. Eine Datei wird auch geschlossen,
wenn ihr Handle nochmals verwendet wird. Open generiert automatisch neue Verzeichnisse, wenn diese
in der Pfadangabe zu der Datei spezifiziert wurden aber noch nicht existieren.
Eigenschaften:
{string} file
Mit dieser Eigenschaft wird der Dateinamen der zu öffnenden Datei
spezifiziert. Bei Pfadangaben ist zu beachten, dass ein einfacher Backslash ("\")
immer durch zwei aufeinanderfolgende Backslashs dargestellt werden muß.
Deshalb ist es einfacher Slashs ("/") zu verwenden.
boolean replace = false
Standardmässig werden Dateien so geöffnet, dass sie durch Schreiben
ergänzt werden. Ist diese Eigenschaft true wird ihr bisheriger
Inhalt gelöscht. Die Datei wird dann überschrieben.
boolean erase = false
Ist diese Eigenschaft true, wird die Datei beim Schliessen
gelöscht unabhängig davon ob sie automatisch oder explizit
geschlossen wurde. Diese Eigenschaft eignet sich zur Deklaration von
temporären Dateien. Bei der Namensgebung von temporären
Dateien kann die Session-ID, die im Datenfeld "Formicula.SessionID"
gespeichert ist, verwendet werden. Wenn sie als Bestandteil des
Dateinamens vorkommt, ist die Eindeutigkeit der Datei
gewährleistet. Da die ID keine feste Länge hat, sollten
zusätzliche Bezeichner durch nicht alphanumerische Zeichen von ihr
getrennt sein, damit nicht durch Zufall eine bereits existierende ID
generiert wird (was zugegebenermassen sehr unwahrscheinlich ist).
Eine Datei kann nicht gelöscht werden, wenn eine weitere Session
auf sie zugreift.
Close schliesst eine mit Open geöffnete Datei wieder.
Wenn die erase-Eigenschaft des Open- bzw.
Close-Evaluators true ist, wird die Datei nach dem
Schliessen glöscht. Der in Open spezifizierte
Verzeichnispfad wird entfernt, wenn das Verzeichnis danach leer
ist. Der Löschvorgang stoppt an dem ersten nicht leeren
übergeordneten Verzeichnis. Eine Datei kann nicht entfernt werden,
wenn sie noch von anderen Sessions benutzt wird. Aus diesem Grund sollten nur
session- bzw. anwenderbezogene Dateien gelöscht werden.
Eigenschaften:
boolean erase = false
Ist diese Eigenschaft true, wird die Datei beim Schliessen
entfernt.
Der Read-Evaluator liest eine Datei zeilenweise. Es sollte sich dabei um eine Textdatei
handeln. Die gelesenen Zeilen werden in einem Datenfeld gespeichert.
Eigenschaften:
string var
In dieses Datenfeld werden die Textzeilen des aktuellen Lesevorgangs als
Vektor gespeichert.
int line = 0
Diese Eigenschaft bestimmt wieviele Zeilen gelesen werden sollen. Ist der Wert
kleiner gleich null, werden alle verbleibenden Zeilen gelesen.
Nachricht Nr. 1
-----------------------
Nachricht Nr. 2
-----------------------
Nachricht Nr. 3
Neue Nachricht:
Dieses primitive Messageboard zeigt die Datei "msg.txt" an. Das
Verzeichnis "messageboard" wird bei Bedarf generiert. Mit "Add"
können neue Nachrichten hinzugefügt werden. Die Datei wird
nach jeder hinzugefügten Nachricht geschlossen und neu
geöffnet damit der Lesezeiger wieder am Anfang steht. Da das
Messageboard beliebig groß werden kann, ist es besser die Datei
Zeile für Zeile in das Datenfeld "msg" zu übertragen und nicht
komplett (line = 0), da sonst der doppelte Speicher benötigt
würde (für "msg" und "txt").
Operator
Die Objekte der Klasse Operator manipulieren oder analysieren
Datenfelder. Dabei reicht das Spektrum ihrer Funktionalität von
einfachen mathematischen und logischen Operationen bis hin zu relativ
komplexen Zeichenkettenmanipulationen. Die Integration von Operator-Objekten
in die Syntax von Formicula weicht von der der anderen Objekte ab.
Sie sind Elemente der Stringliste exp, die eine Eigenschaft
der Klasse Evaluator ist. Ein Operator hat grundsätzlich
folgenden Aufbau: Datenfeldname/-referenz, Operator-Klassenname,
Parameter1,...,Parametern
Die exp-Eigenschaft kann beliebig viele Operatoren in dieser
Form enthalten. Der Evaluator arbeitet sie in der spezifizierten
Reihenfolge ab. Jeder Operator führt seine Funktion aus und
gibt einen boolschen Wert zurück. Der boolsche Modus des
Evaluator-Objektes bestimmt wie diese Rückgabewerte
verknüpft werden und ob die Auswertung fortgesetzt wird, wenn das
verknüpfte Resultat nicht mehr den Wert true erreichen
kann.
Alle Operationen wirken sich auf den Datenfeldnamen bzw. auf die
Datenfeldreferenz vor dem Operator aus. Eine Referenz ist durch einen
Stern "*" gekennzeichnet, der vor einem Datenfeldnamen steht. Der Inhalt
des spezifizierten Datenfeldes wird als Name des referenzierten
Datenfeldes interpretiert. Eine Referenz ist nichts weiter als eine
spezielle Form der Substitution, die nur innerhalb der exp-Eigenschaft
erlaubt ist. Ein Operator hat eine bestimmte Anzahl
von Parametern, die die Operation an dem Datenfeld steuern. Manche
Operationen benötigen keine Parameter. Es werden fünf
verschiedene Typen von Parametern unterschieden:
Numerische Konstante
Hierbei handelt es sich um eine beliebige Zahl. Es gibt keine
Unterscheidung zwischen Integer- und Float-Zahlen. Überflüssige
Nachkommastellen werden einfach abgeschnitten. Dieser Parametertyp
produziert einen Fehler, wenn er anstelle einer String-Konstante verwendet
wird.
String-Konstante
Eine String-Konstante steht immer in Anführungszeichen. Fehlen diese,
wird der Parameter als Datenfeld bzw. Referenz interpretiert. Dieser
Parametertyp produziert einen Fehler, wenn er anstelle einer numerischen
Konstante verwendet wird.
Datenfeld-Parameter
Ein Datenfeld-Parameter steht nicht in Anführungszeichen und ist keine
Zahl. Ausserdem darf kein Stern "*" direkt davor stehen, da er sonst als
Referenz-Parameter interpretiert wird. Dieser Parameter-Typ ist dynamisch,
das heisst er kann immer verwendet werden. Der Operator versucht den
Inhalt des Datenfeldes entsprechend den Erfordernissen umzuwandeln. Gelingt
das nicht, wird die Operation nicht ausgeführt und der Operator gibt
false zurück.
Referenz-Parameter
Ein Referenz-Parameter steht nicht in Anführungszeichen und ist keine
Zahl. Ausserdem muß ein Stern "*" direkt davor stehen, da er sonst
als Datenfeld-Parameter interpretiert wird. Dieser Parameter-Typ ist
dynamisch, das heisst er kann immer verwendet werden. Der Operator
versucht den Inhalt des referenzierten Datenfeldes entsprechend den
Erfordernissen umzuwandeln. Gelingt das nicht, wird die Operation nicht
ausgeführt und der Operator gibt false zurück.
Dynamischer Parameter
Ein dynamischer Parameter kann eine beliebige Konstante, ein
Datenfeldname oder eine Referenz sein. Der Operator passt seine
Funktionalität dem verwendeten Parameter-Typ an. Sollte er
dazu nicht in der Lage sein, gibt er false zurück;
Jeder Operator gibt false zurück, wenn eine
erforderliche Interpretation eines Datenfeldinhalts als Zahl
fehlschlägt. Diese Regel gilt für die Parameter auf der
rechten Seite ebenso wie für das Datenfeld auf der linken Seite des
Operator-Namens.
Der Datenfeldvektor wird um ein weiteres Element erweitert. Dieses
Element wird zum aktiven Element. Skalare Datenfelder
werden zu Vektoren. Das Datenfeld muß existieren.
Der erste String wird im zweiten String von links nach recht gesucht. Der
numerische Parameter gibt die Startposition an, ab der gesucht werden soll.
Gespeichert wird die Position des gefundenen Strings oder 0 bei erfolgloser
Suche.
Wenn das Datenfeld leer bzw. noch nicht definiert ist, wird ihm der Inhalt
des Parameters zugewiesen. Dieser Operator eignet sich zum ersetzen
von Leerfeldern mit bestimmten Werten (z.B. mit dem Ausdruck "keine
Angabe").
Der erste String besteht aus Teilstrings, welche sich durch
ein bestimmtes Trennzeichen abgrenzen. Der zweite String definiert
das Trennzeichen. Der numerische Parameter gibt an, welcher Teilstring
dem Datenfeld zugewiesen wird.
Der erste String besteht aus Teilstrings, welche sich durch
ein bestimmtes Trennzeichen abgrenzen. Der zweite String definiert
das Trennzeichen. Dem Datenfeld wird die Anzahl der Teilstrings
zugewiesen.
Der String definiert einen Filterausdruck. Es wird geprüft ob das
Datenfeld dem Filter entspricht. Ein "*" steht für beliebig viele
Zeichen, während ein "?" genau ein Zeichen repräsentiert. Alle
anderen Zeichen im Filter müssen übereinstimmen. So lässt
der Filter "*?Fil?er*" z.B. die Begriffe "XFilter", "Der Filzer filzt"
durch, verweigert aber den Begriffen "Filter", "Der Filtser Hannes" oder
"XFiler" den Durchgang.
Rückgabe
true, wenn das Datenfeld dem Filter entspricht
false, sonst
Das Datenfeld wird nach links mit einem Zeichen aufgefüllt. Der String
definiert das Zeichen und der numerische Parameter die Länge bis zu
der aufgefüllt wird. Das Datenfeld muß existieren.
Das Datenfeld wird nach rechts mit einem Zeichen aufgefüllt. Der String
definiert das Zeichen und der numerische Parameter die Länge bis zu
der aufgefüllt wird. Das Datenfeld muß existieren.
Der erste String wird im zweiten String von rechts nach links gesucht. Der
numerische Parameter gibt die Startposition an, ab der gesucht werden soll.
Gespeichert wird die Position des gefundenen Strings oder 0 bei erfolgloser
Suche. Wenn die Startposition 0 oder kleiner ist, wird von Ende des Strings
gesucht.
Der Inhalt des Datenfeldes wird als Zahl interpretiert. Es erhält den
kleinsten Wert, der nicht kleiner ist als der ursprüngliche Wert
und eine Integerzahl darstellt (z.B.: -5.23 wird zu -5, 12.01 wird zu 13).
Das Datenfeld muß existieren.
Das aktuelle Systemdatum mit Zeitangabe wird dem Datenfeld zugewiesen.
Die Angabe hat folgendes Format: yyyy.MM.dd hh.mm.ss.SSS y : Jahr M : Monat d : Tag h : Stunde m : Minute s : Sekunde S : Tausendstel Sekunde
Beispiel: 2001.05.23 15.58.05.372
Die Anzahl der Fehlermeldungen der MessageEvaluator-Objekte wird
dem Datenfeld zugewiesen. Dabei werden auch mehrfache Meldungen pro
Content-Objekt mitgezählt.
Der Inhalt des Datenfeldes wird als Zahl interpretiert. Es erhält den
grössten Wert, der nicht grösser ist als der ursprüngliche Wert
und eine Integerzahl darstellt (z.B.: -5.23 wird zu -6, 12.01 wird zu 12).
Das Datenfeld muß existieren.
Der Operator prüft, ob das Datenfeld eine korrekte
Datumsangabe darstellt. Ein korrektes Datum kann folgende Formate
haben:
yyyy.MM.dd hh.mm.ss.SSS, yyyy.MM.dd hh.mm.ss,
yyyy.MM.dd hh.mm, yyyy.MM.dd y : Jahr M : Monat d : Tag h : Stunde m : Minute s : Sekunde S : Millisekunde
Beispiel: 2001.5.23
Das Datenfeld muß existieren.
Rückgabe
true, wenn der Datenfeldinhalt eine korrekte Datumsangabe darstellt
false, sonst
Der Operator prüft, ob das Datenfeld der internen
Zeitdarstellung entspricht. Die interne Zeit wird in Millisekunden
seit dem 1. Januar 1970 gemessen. Das Datenfeld muß existieren.
Rückgabe
true, wenn das Datenfeld der internen Zeitdarstellung entspricht
false, sonst
Das aktuelle Element des Datenfeldvektors wird entfernt. Bei einem
Skalar wird der Inhalt gelöscht. Der Index des aktuellen
Objektes bleibt erhalten. Wenn das gelöschte Element den
höchsten Index hatte, wird er an die neue Vektorgrösse
angepasst.
Das Datenfeld wird als interne Zeitdarstellung interpretiert und in das
entsprechende Datum umgewandelt. Die interne Zeit wird in Millisekunden
seit dem 1. Januar 1970 gemessen. Das Datum hat folgendes Format:
yyyy.MM.dd hh.mm.ss.SSS y : Jahr M : Monat d : Tag h : Stunde m : Minute s : Sekunde S : Millisekunde
Das Datenfeld muß existieren.
Rückgabe
false, wenn das Datenfeld keine gültige Zeit ist
true, sonst
Alle Html-Sonderzeichen und Tags des Datenfeldes werden maskiert. Wenn
das Datenfeld in einer Html-Seite substituiert wird (siehe Text
mit Eigenschaft subHtml = true), wird der Inhalt
unverändert dargestellt.
Das Datenfeld wird als Datum interpretiert und in die entsprechende
interne Zeitdarstellung umgewandelt. Die interne Zeit wird in
Millisekunden seit dem 1. Januar 1970 gemessen. Das Datum hat folgendes
Format:
yyyy.MM.dd hh.mm.ss.SSS y : Jahr M : Monat d : Tag h : Stunde m : Minute s : Sekunde S : Millisekunde
Das Datenfeld muß existieren.
Rückgabe
false, wenn der Datenfeldinhalt kein gütiges Datum ist
true, sonst
Es wird geprüft ob das Datenfeld dem fixen numerischen Format entspricht,
welches durch die Parameter vorgegeben wird. Der erste Parameter gibt die
maximale Länge des Formates an. Der zweite Parameter gibt die Anzahl der
Nachkommastellen an. Das Komma selbst zählt als Stelle ebenso wie das
Minuszeichen bei negativen Zahlen. Punkte und Kommas werden gleich behandelt.
Die Zahl entspricht dem Format, wenn sie ohne Änderung ihres Wertes
angepasst werden könnte. Das Datenfeld muß existieren.
Rückgabe
false, wenn eine Anpassung an das fixe Format die Zahl verändern
würde
true, sonst
Alles was rechts von der Positionsangabe (Parameter) steht wird vom
Datenfeld abgeschnitten. Das erste Zeichen hat Position 1.
Das Datenfeld muß existieren.
Der interne Index des Datenfeldvektors wird entsprechend des Parameters
verschoben. Durch die Angabe eines negativen Parameters wird der Index
nach hinten verschoben. Bei Verletzung einer Indexgrenze des Vektors,
wird er auf diese Grenze gesetzt (1 bzw. Vektorlänge).
Das Datenfeld muß existieren.
Rückgabe
false, bei potenzieller Verletzung einer Indexgrenze
true, sonst
Alles was links von der Positionsangabe (Parameter) steht wird vom
Datenfeld abgeschnitten. Das erste Zeichen hat Position 1.
Das Datenfeld muß existieren.
Der interne Index des Datenfeldvektors wird auf den Wert des Parameters
gesetzt. Würde eine Verletzung der Indexgrenzen stattfinden, wird
der Index auf die verletzte Grenze gesetzt (1 bzw. Vektorglänge).
Das Datenfeld muß existieren.
Rückgabe
false, bei potenzieller Verletzung einer Indexgrenze
true, sonst
Das Datenfeld wird entsprechend dem fixen numerischen Format, welches durch die
Parameter vorgegeben wird, umgewandelt. Der erste Parameter gibt die maximale
Länge des Formates an. Der zweite Parameter gibt die Anzahl der
Nachkommastellen an. Das Komma selbst zählt als Stelle ebenso wie das
Minuszeichen bei negativen Zahlen. Punkte und Kommas werden gleich behandelt.
Die Umwandlung findet nicht statt, wenn sich der Wert der Zahl ändern
würde.
Rückgabe
false, wenn eine Anpassung an das fixe Format die Zahl verändern würde
true, sonst
Ein ValueOperator hat nur Datenfeld- bzw. Referenzparameter.
Konstanten sind nicht erlaubt. Diese abstrakte Klasse stellt keine
funktionelle Kategorie dar.
Die abstrakte Klasse CompareOperator stellt Methoden
für Vergleichsoperatoren zur Verfügung. Sie bildet
die funktionelle Kategorie aller Vergleichsoperatoren. Ein
CompareOperator vergleicht das was auf der linken Seite
des Operators steht mit der rechten Seite. Trifft der Vergleich zu
gibt der Operator das boolsche Ergebnis true
zurück, sonst false.
Es wird zwischen numerischen und alphanumerischen Vergleichen
unterschieden. Beim numerischen Vergleich werden beide Seiten
als Zahlen interpretiert. Ist eine der beiden
Seiten keine Zahl, gibt der Operator immer false zurück.
Beim alphanumerischen Vergleich gilt die lexikalische Reihenfolge
des ASCII-Standards.
Die von DynamicCompareOperator abgeleiteten Klassen
sind Vergleichsoperatoren, die die Art des Vergleichs dynamisch
bestimmen. Ist die rechte Seite eine numerische Konstante
erfolgt ein numerischer Vergleich. Bei einer String-Konstante
wird alphanumerisch verglichen. Wenn die rechte Seite ein Datenfeld bzw.
eine Referenz ist und beide Seiten als Zahlen interpretiert werden
können, wird numerisch verglichen, sonst alphanumerisch.
Folgende DynamicCompareOperator Klassen wurden realisiert:
eq (=), ne (!=),
lt (<), le (<=),
gt (>), ge (>=)
Wenn das Datenfeld gleich dem Inhalt des ersten Parameters ist, wird
ihm der Inhalt des zweiten Parameters zugewiesen. Die Art des Vergleichs
wird dynamisch bestimmt. Dieser Operator eignet sich zum
Umkodieren (recode) von Datenfeldern. Im Gegensatz zu den anderen
CompareOperator-Objekten gibt rec immer true
zurück.
Ein NumericCompareOperator vergleicht immer numerisch.
String-Konstanten sind nicht erlaubt. Kann eine Seite nicht als Zahl
interpretiert werden, gibt der Operatorfalse
zurück.
Folgende NumericCompareOperator Klassen wurden realisiert:
eqnum (=), nenum (!=),
ltnum (<), lenum (<=),
gtnum (>), genum (>=)
Formicula stellt mehrere Systemfelder zur Verfügung. Einige stellen
hilfreiche Informationen für den Programmierer zur Verfügung,
während die sogenannten internen Felder wichtig für die
Funktionalität von Formicula sind. Alle Systemfelder gehören
zur Aliasgruppe "Formicula". Felder dieser Gruppe können wie
normale Datenfelder mittels Evaluatoren und Operatoren verwaltet werden.
Wenn sie als Formularfelder oder Parameter spezifiziert werden, findet
keine Aktualisierung der dazugehörigen Datenfelder statt.
Der "Client" ist das Anwenderobjekt.
Formicula.
Intern
Aktualisierung
Beschreibung
SessionID
ja
Client-Generierung
Über die "SessionID" identifiziert das Formicula-Servlet den Client. Sie wird als
verstecktes Formularfeld mitgesendet. Sie ist eindeutig für den Server und kann
deshalb als Bestandteil für Namen temporärer Dateien verwendet werden.
"SessionIDs" haben eine feste Länge von 16 Zeichen.
FormID
ja
Servlet-Aufruf
Gibt die Nummer der aktuellen Formularseite an. Diese ID wird bei jedem Formular als
verstecktes Formularfeld integriert. Sie wird benötigt um Browser-Navigation
festzustellen und entsprechend darauf zu reagieren (siehe Eigenschaft navigationLock
des Form-Objektes).
Visited
ja
Servlet-Aufruf
Über diesen Datenvektor wird das Backtracking gesteuert (siehe
Back-Evaluator). Er enthält die Nummern der bisher
aufgerufenen Formulare ohne Schleifen. Der aktuellste Eintrag hat den
höchsten Index. Nach dem Servlet-Aufruf steht der Index auf dem
aktuellen Eintrag. Es ist möglich den Datenvektor zu manipulieren
um eine andere Backtrack-Reihenfolge zu erhalten.
File
ja
Client-Generierung
Spezifiziert den Skript-File des Formulars. Das Formular enthält
diese Angabe als verstecktes Formularfeld. Es wird verwendet, wenn der
Client das maximale Antwortzeit-Intervall überschritten hat und die
Session gelöscht wurde. Das Servlet erkennt anhand dieses
Formularfeldes das Skript und erzeugt eine neue Session dafür.
Dieses Feld kann geändert werden, wenn stattdessen ein spezielles Skript
ausgeführt werden soll.
Running
nein
Servlet-Aufruf
Gibt die Anzahl der aktiven Sessions an.
Client
nein
Client-Generierung
Enthält die Anzahl der vom Servlet verwalteten Sessions zum Zeitpunkt der
Client-Anmeldung. Mit dieser Angabe können Mengenrestriktionen
für den Zugang realisiert werden.
Select
nein
Select/SQL
Gibt an, ob die letzte Select-Abfrage (Select- oder SQL-Evaluator) ein Ergebnis
lieferte ("true") oder nicht ("false").
Insert
nein
Insert/SQL
Gibt die Anzahl der durch den letzten Insert- bzw. SQL-Evaluator
eingefügten Datensätze an.
Update
nein
Update/SQL
Gibt die Anzahl der durch den letzten Update- bzw. SQL-Evaluator
geänderten Datensätze an.
Delete
nein
Delete/SQL
Gibt die Anzahl der durch den letzten Delete- bzw. SQL-Evaluator
gelöschten Datensätze an.
Catch
nein
Catch
Enthält die Fehlermeldung des zuletzt mit dem Catch-Evaluators aufgefangenen
Fehlers.
Host
nein
Servlet-Aufruf
Dieses Feld spezifiziert den Namen des Host-Servers über den sich der Client eingewählt
hat. Diese Angabe wird bei jedem Aufruf aktualisiert, da es theoretisch möglich ist, dass der
Host-Server während der Session wechselt.
Address
nein
Servlet-Aufruf
Gibt den die IP-Adresse des Clients an. Diese kann von Aufruf zu Aufruf wechseln, wenn
spezielle Einwahlverfahren zur IP-Verschleierung verwendet wurden.
UserID
nein
Client-Generierung
Gibt die Login-Kennung des Users auf dem Web-Server an, wenn das Formicula-Servlet in
einem Password-geschützten Bereich liegt. Dieser Schutz ist unabhängig von
Password-Abfragen durch das Formicula-Skript.
Authorization
nein
Client-Generierung
Gibt das Autorisationsschema des Server an. Wenn es sich z.B. um das
Verschlüsselungsschema SSL (Secure Socket Layer) handelt,
enthält dieses Feld die Angabe "SSL".
Agent
nein
Client-Generierung
Gibt die Kennung des vom Client verwendet Browsers an.
Link
nein
Client-Generierung
Dieses Feld enthält den sogennanten "Referrer"-Link. Dabei handelt es sich um die Adresse
der Seite von der aus das Servlet aufgerufen wurde. Es eignet sich besonders für den
Exit-Evaluator.
Created
nein
Client-Generierung
Gibt das Datum und die Zeit der Client-Generierung im Standardformat an
(siehe date-Operator).
Accessed
nein
Servlet-Aufruf
Gibt das Datum und die Zeit des letzten Servlet-Aufrufs für diese Session
im Standardformat an (siehe date-Operator).
Farben
Farben können als hexadezimaler RGB-Wert oder mit dem Farbnamen
definiert werden. Jede hexadezimale Farbdefinition ist 6stellig und hat
das Schema: #XXXXXX. Nach einem Gatter (#) folgen 6 Stellen
für die Farbdefinition. Die ersten beiden Stellen stellen den Rot-Wert
der Farbe dar, die zweiten beiden Stellen den Grün-Wert, und die letzten
beiden Stellen den Blau-Wert. Um eine Farbe mit Hilfe eines Farbnamens
zu definieren, kann anstelle des hexadezimalen RGB-Werts einfach der
gewünschte Farbname angegeben werden. Die folgenden Farbnamen werden von
vielen WWW-Browsern verstanden.