Riesenameisen greifen an
von
Thorsten Doherr
25.06.2002
Bestes Druckergebnis mit IE 5.0 und
1.905 cm Rand auf allen Seiten
(Style-Sheets mit Seitenumbruch).

 

Inhalt

Einleitung
Angiff der Riesenameisen
Was ist Formicula?
Die Motivation
Funktionsweise
Formicula ist ein Servlet
Kommunikation mit dem Anwender
Datenbankanbindung
Installation
Testumgebung
Web-Server
Syntax
Allgemein
Die Formularstruktur
Eigenschaften, Variablen und Daten
Substitutionen
Datenfelder als Vektoren
Diagram der Formularstruktur
Objekte
Form
Entry
Group
Frame
Table
Layout
Row
Content
Text
Dummy
Blank
Summary
Refresh
SingleVarContent
Input
Password
Radio
Area
Combo
Submit
MultiVarContent
Image
Likert
Check
Matrix
Evaluator
Utilize
BaseEvaluator
Eval
Not
True
False
Catch
Loop
FunctionEvaluator
NavigationEvaluator
Jump
Skip
Back
UtilityEvaluator
Clear
Copy
Level
Gather
Scatter
Filter
Dir
Sort
VisibilityEvaluator
Hide
Show
SystemEvaluator
Reset
Exit
Transfer
Log
Exec
MessageEvaluator
Error
Valid
DataEvaluator
Connect
Disconnect
Select
Update
Delete
Insert
SQL
Next
Commit
Rollback
Touch
Meta
Catalog
IOEvaluator
Open
Close
Read
Write
Operator
app
at
build
def
gen
ins
join
len
lex
lexcnt
match
padl
padr
rat
replace
set
UnaryOperator
ceil
clean
date
empty
errcnt
floor
free
full
isdate
isbool
isint
isnum
istime
lower
msgcnt
off
on
rand
remove
round
todate
tohtml
topath
totime
trim
trunc
upper
used
NumericOperator
add
div
isfix
left
max
min
moveind
mul
right
setind
sub
substr
tofix
ValueOperator
getind
size
CompareOperator
DynamicCompareOperator
eq, ne, lt, le, gt, ge
rec
NumericCompareOperator
eqnum, nenum, ltnum
lenum, gtnum, genum
StringCompareOperator
eqstr, nestr, ltstr
lestr, gtstr, gestr
Anhang
Systemfelder
Farben
Links
 

Einleitung

Angriff der Riesenameisen

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.

Syntax

Allgemein

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.
integer
Der Typ integer definiert natürliche Zahlen.
float
Der Typ float definiert reale Zahlen.
stringlist, htmllist booleanlist, integerlist, floatlist
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.

Group[Entry] -> Entry

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.

Frame -> Group[Entry] -> Entry

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.";
	}
}
Das ist das erste Entry-Objekt.
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.

Table -> Group[Entry] -> Entry

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."; }
}
Das ist das erste Entry-Objekt.
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.

Layout -> Group[Entry] -> Entry

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 ist das erste Entry-Objekt.
Das ist das zweite Entry-Objekt.
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.

Row -> Group[Entry] -> Entry

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.

Eigenschaften:

integer height = 0
Gibt die minimale Höhe der Row in Pixeln an.

Beispiel:

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&uuml;nfte Entry-Objekt.";
    }
}
Das ist das erste Entry-Objekt.
Das ist das zweite Entry-Objekt.
Das ist das dritte Entry-Objekt.
Das ist das vierte Entry-Objekt.
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.

Content[Evaluator] -> Entry

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.

Text -> Content[Evaluator] -> Entry

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 "&nbsp;" 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.

Dummy -> Content[Evaluator] -> Entry

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.

Beispiel:

maxInactiveInterval = 0;
[padding] = 4;
[spacing] = 0;
[msgAlign] = center;
[backColor] = khaki;
Table
{   padding = 0;
    spacing = 4;
    borderColor = orange;
    Text
    {   text = "2 + 2 = 5";
        Utilize
        {   Error { msg = "Falsch!"; }
        }
    }
    Layout
    {   Text
        {   text = "2 + 2 = 5";
        }
        Dummy
        {   Utilize
            {   Error { msg = "Falsch!"; }
            }
        }
    }
}
Falsch!
2 + 2 = 5
2 + 2 = 5
Falsch!

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.

Blank -> Content[Evaluator] -> Entry

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.

Summary -> Content[Evaluator] -> Entry

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.

Beispiel:

maxInactiveInterval = 0;
[padding] = 4;
[spacing] = 0;
[backColor] = khaki;
[msgHidden];
Layout
{   Summary
    {   backColor = orange;
        msgSpacing = 2;
        padding = 2;
        right;
    }
    Table
    {   padding = 0;
        spacing = 4;
        borderColor = orange;
        Text
        {   text = "Frage 1: 2 + 2 = 5";
            Utilize
            {   Error { msg = "Fehler in Frage 1!"; }
            }
        }
        Text
        {   text = "Frage 2: 5 + 2 = 9";
            Utilize
            {   Error { msg = "Fehler in Frage 2!"; }
            }
        }
    }
}
Fehler in Frage 1! 1
Fehler in Frage 2! 2
Frage 1: 2 + 2 = 5
Frage 2: 5 + 2 = 9

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.

Refresh -> Content[Evaluator] -> Entry

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.

SingleVarContent -> Content[Evaluator] -> Entry

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.

Input -> SingleVarContent -> Content[Evaluator] -> Entry

Die Input-Klasse ist von der SingleVarContent-Klasse abgeleitet. Ein Input-Objekt erzeugt ein einfaches Eingabefeld für Texteingaben.

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] = 0;
[spacing] = 0;
[backColor] = khaki;
Table
{   padding = 4;
    spacing = 4;
    borderColor = orange;
    Input
    {   var = obst;
        label = "Was ist ihr Lieblingsobst:";
        col = 40;
        length = 40;
    }
    Input
    {   var = obst;
        label = "Wieviel essen sie davon am Tag:";
        unit = "Kilo";
        col = 20;
        length = 10;
    }
}
Was ist ihr Lieblingsobst:
Wieviel essen sie davon am Tag: Kilo

Password -> SingleVarContent -> Content[Evaluator] -> Entry

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.

Radio -> SingleVarContent -> Content[Evaluator] -> Entry

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 = "&Auml;pfel", "Bananen", "Kirschen", "Erdbeeren";
        }
    }
    Layout
    {   Text
        {   text = "Was ist Ihr Lieblingsobst?";
        }
        Radio
        {   var = obst;
            spread = "100%";
            left;
            label = "&Auml;pfel", "Bananen", "Kirschen", "Erdbeeren";
        }
    }
    Layout
    {   Text
        {   text = "Was ist Ihr Lieblingsobst?";
        }
        Radio
        {   var = obst;
            vertical;
            margin = 0;
            wide;
            spread = "50%";
            label = "&Auml;pfel", "Bananen", "Kirschen", "Erdbeeren";
        }
    }
}
Was ist Ihr Lieblingsobst?
Äpfel    Bananen    Kirschen    Erdbeeren   
Was ist Ihr Lieblingsobst?
Äpfel Bananen Kirschen Erdbeeren
Was ist Ihr Lieblingsobst?
Äpfel
Bananen
Kirschen
Erdbeeren

Area -> SingleVarContent -> Content[Evaluator] -> Entry

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.

Combo -> SingleVarContent -> Content[Evaluator] -> Entry

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 "&#44;" 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.

Beispiel:

maxInactiveInterval = 0;
[padding] = 4;
[spacing] = 0;
[backColor] = khaki;
Table
{   borderColor = orange;
    spacing = 4;
    padding = 0;
    Text
    {   text = "W&auml;hlen Sie bitte ihre Lieblingsfr&uuml;chte:";
        backColor = orange;
        Utilize
        {   exp = zitrus, set, "Orange,Zitrone,Limone";
        }
    }
    Combo
    {   var = frucht1;
        row = 4;
        multiple;
        label = "Banane","{zitrus}","Kirsche","Kiwi,Pflaume";
    }
    Combo
    {   var = frucht2;
        row = 1;
        numeric;
        label = "Banane","{zitrus}","Kirsche","Kiwi,Pflaume";
        Utilize
        {   exp = frucht2, gen, 3;
        }
    }
    Combo
    {   var = frucht3;
        row = 1;
        numeric;
        multiple;
        label = "Banane","{zitrus}","Kirsche","Kiwi,Pflaume";
    }
}
Wählen Sie bitte ihre Lieblingsfrüchte:

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.

Submit -> SingleVarContent -> Content[Evaluator] -> Entry

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.

MultiVarContent -> Content[Evaluator] -> Entry

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.

Image -> MultiVarContent -> Content[Evaluator] -> Entry

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.

Likert -> MultiVarContent -> Content[Evaluator] -> Entry

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.
int margin = 2
Gibt das interne Padding der Likert-Tafel an.

Beispiel:

maxInactiveInterval = 0;
[padding] = 4;
[spacing] = 0;
[backColor] = khaki;
Table
{   borderColor = orange;
    spacing = 4;
    padding = 0;
    Likert
    {   var = banane, kirsche, kiwi, pflaume, zitrone, orange, andere;
        label = gut,,schlecht;
		label = "<i>nie probiert</i>";
        info = Banane, Kirsche, Kiwi, Pflaume, Zitrone, Orange;
		info = "Andere Fr&uuml;chte";
        intro = "Wie schmecken Ihnen folgende Fr&uuml;chte...";
        spread = 300;
        oddBackColor = orange;
    }
}
Wie schmecken Ihnen folgende Früchte... gut schlecht nie probiert
Banane
Kirsche
Kiwi
Pflaume
Zitrone
Orange
Andere Früchte

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.

Check -> MultiVarContent -> Content[Evaluator] -> Entry

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 = "&Auml;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";
        }
    }
}
Was kommt in den Obstsalat?
Äpfel    Bananen    Kirschen    Erdbeeren   
Was kommt in den Obstsalat?
Äpfel Bananen Kirschen Erdbeeren
Was kommt in den Obstsalat?
Äpfel
Bananen
Kirschen
Erdbeeren

Matrix -> MultiVarContent -> Content[Evaluator] -> Entry

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&uuml;rfelt", "in Scheiben", gepresst;
        info = Banane, Kirsche, Kiwi, Pflaume, Zitrone, "Andere Fr&uuml;chte";
        intro = "Wie kommt was in den Obstsalat?";
        spread = 50%;
        oddBackColor = orange;
    }
}
Wie kommt was in den Obstsalat? gewürfelt in Scheiben gepresst
Banane
Kirsche
Kiwi
Pflaume
Zitrone
Andere Früchte

Evaluator[Evaluator, Operator]

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.

Utilize -> Evaluator[Evaluator, Operator]

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.

BaseEvaluator -> Evaluator[Evaluator, Operator]

Objekte die von BaseEvaluator abgeleitet sind, bilden das Grundgerüst für die Formularauswertung. Sie dürfen beliebig kombiniert und verschachtelt werden.

Eval -> BaseEvaluator -> Evaluator[Evaluator, Operator]

Eval ist die direkteste Implementierung eines Evaluators. Er wertet nur die untergeordneten Evaluator- bzw. Operator-Objekte aus.

Beispiel:

maxInactiveInterval = 0;
Frame
{   border = 1;
    Text
    {   text = "A = 3<br>B = 4<br>C = 1<br>(A < 5) and (B = 7 or C = 1) = {x}";
        Utilize
        {   Eval { exp = a, set, 3, b, set, 4, c, set, 1, x, set, "false"; }
            Eval
            {   Eval
                {   exp = a, lt, 5;
                }
                Eval
                {   or;
                    exp = b, eq, 7;
                    exp = c, eq, 1;
                }
            }
            Eval { exp = x, set, "true"; }
        }
    }
}
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.

Not -> BaseEvaluator -> Evaluator[Evaluator, Operator]

Der Not-Evaluator negiert das boolsche Resultat der untergeordneten Evaluatoren bzw. Operatoren.

Beispiel:

maxInactiveInterval = 0;
Frame
{   border = 1;
    Text
    {   text = "A = 3<br>B = 4<br>C = 1<br>(A < 5) and not(B != 7 or C > 1) = {x}";
        Utilize
        {   Eval
            {   exp = a, set, 3, b, set, 4, c, set, 1, x, set, "false";
            }
            Eval
            {   and;
                Eval
                {   exp = a, lt, 5;
                }
                Not
                {   Eval
                    {   or;
                        exp = b, ne, 7;
                        exp = c, eq, 1;
                    }
                }
            }
            Eval
            {   exp = x, set, "true";
            }
        }
    }
}
A = 3
B = 4
C = 1
(A < 5) and not(B != 7 or C > 1) = false

True -> BaseEvaluator -> Evaluator[Evaluator, Operator]

Der True-Evaluator gibt unabhängig von dem tatsächlichen Resultat immer true zurück.

False -> BaseEvaluator -> Evaluator[Evaluator, Operator]

Der False-Evaluator gibt unabhängig von dem tatsächlichen Resultat immer false zurück.

Catch -> BaseEvaluator -> Evaluator[Evaluator, Operator]

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 Catch false zurück und stellt die Systemmeldung in das Datenfeld "Formicula.Catch", ansonsten verhält er sich wie ein normaler Evaluator.

Loop -> BaseEvaluator -> Evaluator[Evaluator, Operator]

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.

Beispiel:

maxInactiveInterval = 0;
Frame
{   border = 1;
    Text
    {   text = "Countdown: {count}";
        Utilize
        {   Eval
            {   exp = count, set, "10";
                exp = i, set, 10;
            }
            Loop
            {   exp = i, sub, 1;
                exp = i, ge, 1;
                exp = count, join, "...", count, join, i;
            }
            Eval
            {   exp = count, join, "...IGNITION";
            }
        }
    }
}
Countdown: 10...9...8...7...6...5...4...3...2...1...IGNITION

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.

FunctionEvaluator -> Evaluator[Evaluator, Operator]

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.

NavigationEvaluator -> FunctionEvaluator -> Evaluator[Evaluator, Operator]

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.

Jump -> NavigationEvaluator -> FunctionEvaluator -> Evaluator[Evaluator, Operator]

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.

Skip -> NavigationEvaluator -> FunctionEvaluator -> Evaluator[Evaluator, Operator]

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 {}
        }
    }
}

Back -> NavigationEvaluator -> FunctionEvaluator -> Evaluator[Evaluator, Operator]

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 {}
    }
}

UtilityEvaluator -> FunctionEvaluator -> Evaluator[Evaluator, Operator]

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.

Clear -> UtilityEvaluator -> FunctionEvaluator -> Evaluator[Evaluator, Operator]

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.

Copy -> UtilityEvaluator -> FunctionEvaluator -> Evaluator[Evaluator, Operator]

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.

Level -> UtilityEvaluator -> FunctionEvaluator -> Evaluator[Evaluator, Operator]

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.

Gather -> UtilityEvaluator -> FunctionEvaluator -> Evaluator[Evaluator, Operator]

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.

Beispiel:

maxInactiveInterval = 0;
Layout
{	border = 0;
	Text
    {   text = "Formicula-Systemfelder:<br>\n{system}";
        subHtml;
        Utilize
        {   Gather
            {   alias = formicula;
                name = sysname;
                value = sysvalue;
            }
            Eval
            {   exp = system, set, "";
            }
            Loop
            {   exp = system, build, "{system}{sysname} = {sysvalue}<br>\n";
                exp = sysname, moveind, 1;
                exp = sysvalue, moveind, 1;
            }
            Exit {}
        }
    }
}
Formicula-Systemfelder:
formicula.client = 1
formicula.select = false
formicula.insert = 0
formicula.update = 0
formicula.delete = 0
formicula.catch =
formicula.visited = 0
formicula.formid = 0
formicula.sessionid = ZYD8Q80319PN1Y5Z
formicula.userid =
formicula.authorization =
formicula.agent = Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 4.0; DPU)
formicula.link = http://localhost:8080/servlet/FormiculaScriptBrowser
formicula.file = C:\Formicula\ant\System.ant
formicula.created = 2002.03.26 15.49.52.558
formicula.accessed = 2002.03.26 15.49.52.558
formicula.running = 1
formicula.address = 127.0.0.1
formicula.host = localhost

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.

Scatter -> UtilityEvaluator -> FunctionEvaluator -> Evaluator[Evaluator, Operator]

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.

Filter -> UtilityEvaluator -> FunctionEvaluator -> Evaluator[Evaluator, Operator]

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.

Beispiel:

maxInactiveInterval = 0;
Layout
{   border = 0;
    Text
    {   text = "Formicula-ID-Systemfelder:<br>\n{system}";
        subHtml;
        Utilize
        {   Gather
            {   alias = formicula;
                name = x.sysname;
                value = x.sysvalue;
            }
            Filter
            {   alias = x;
                name= sysname;
                filter = "*id";
            }
            Eval
            {   exp = system, set, "";
            }
            Loop
            {   exp = system, build, "{system}{x.sysname} = {x.sysvalue}";
                exp = system, join, "<br>\n";
                exp = x.sysname, moveind, 1;
                exp = x.sysvalue, moveind, 1;
            }
        }
    }
}
Formicula-ID-Systemfelder:
formicula.formid = 0
formicula.sessionid = 379T1A7E733T0M6I
formicula.userid =

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.

Dir -> UtilityEvaluator -> FunctionEvaluator -> Evaluator[Evaluator, Operator]

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.

Beispiel:

Frame
{   border=1;
    Text hihi
    {   text = "<b>{path}<b><br>\n{str}";
        subHtml;
        Utilize
        {   Eval
            {   exp = str, set, "<table width=100%>\n<tr>\n";
                exp = str, join, "<th align=left>name</th>\n";
                exp = str, join, "<th align=right>size</th>\n";
                exp = str, join, "<th align=right>date</th>\n";
                exp = str, join, "<th width=10%>dir</th>\n";
                exp = str, join, "<th width=10%>hidden</th>\n";
                exp = str, join, "<th width=10%>readonly</th>";
                exp = str, join, "\n</tr>\n";
                exp = path, set, "ant", path, topath;
            }
            Dir
            {   alias = d;
                path = "{path}";
                sort;
            }
            Loop
            {   Level
                {   alias = d;
                    name = name;
                    exp = str, build, "{str}<td>{d.name}</td>\n";
                    exp = str, build, "{str}<td align=right>{d.size}</td>\n";
                    exp = str, build, "{str}<td align=right>{d.date}</td>\n";
                    exp = str, build, "{str}<td align=center>{d.dir}</td>\n";
                    exp = str, build, "{str}<td align=center>{d.hidden}</td>\n";
                    exp = str, build, "{str}<td align=center>{d.readonly}</td>";
                    exp = str, join, "\n</tr>\n", d.name, moveind, 1;
                }
            }
            Eval { exp = str, join, "</table>"; }
            Exit {}
        }
    }
}
C:\Formicula\ant
name size date dir hidden readonly
Catalog.ant 733 2001.08.21 14.59.08.000 false false false
dir.ant 1189 2001.08.31 13.51.46.000 false false false
File.ant 579 2001.08.23 13.45.12.000 false false false
Filter.ant 697 2001.08.30 15.15.30.000 false false false
konj2001b.ant 29841 2001.08.22 14.19.18.000 false false false
Test.ant 914 2001.07.27 14.29.28.000 false false false

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.

Sort -> UtilityEvaluator -> FunctionEvaluator -> Evaluator[Evaluator, Operator]

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.

Beispiel:

Frame
{   border=1;
    Text hihi
    {   text = "<b>{path}<b><br>\n{str}";
        subHtml;
        Utilize
        {   Eval
            {   exp = str, set, "<table width=100%>\n<tr>\n";
                exp = str, join, "<th align=left>name</th>\n";
                exp = str, join, "<th align=right>size</th>\n";
                exp = str, join, "<th align=right>date</th>\n";
                exp = str, join, "<th width=10%>dir</th>\n";
                exp = str, join, "<th width=10%>hidden</th>\n";
                exp = str, join, "<th width=10%>readonly</th>\n</tr>\n";
                exp = path, set, "ant", path, topath;
            }
            Dir
            {   alias = d;
                path = "{path}";
            }
            Sort
            {   alias = d;
                name = size;
                numeric;
                down;
            }
            Loop
            {   Level
                {   alias = d;
                    name = name;
                    exp = str, build, "{str}<td>{d.name}</td>\n";
                    exp = str, build, "{str}<td align=right>{d.size}</td>\n";
                    exp = str, build, "{str}<td align=right>{d.date}</td>\n";
                    exp = str, build, "{str}<td align=center>{d.dir}</td>\n";
                    exp = str, build, "{str}<td align=center>{d.hidden}</td>\n";
                    exp = str, build, "{str}<td align=center>{d.readonly}</td>\n</tr>\n";
                    exp = d.name, moveind, 1;
                }
            }
            Eval { exp = str, join, "</table>"; }
            Exit {}
        }
    }
}
C:\Formicula\ant
name size date dir hidden readonly
konj2001b.ant 29841 2001.08.22 14.19.18.000 false false false
dir.ant 1613 2001.08.31 14.57.46.000 false false false
Test.ant 914 2001.07.27 14.29.28.000 false false false
Catalog.ant 733 2001.08.21 14.59.08.000 false false false
Filter.ant 697 2001.08.30 15.15.30.000 false false false
File.ant 579 2001.08.23 13.45.12.000 false false false

Hierbei handelt es sich um eine modifizierte Version des Dir-Beispiels. Die numerische Sortierung nach der Dateigrösse erfolgt absteigend.

VisibilityEvaluator -> FunctionEvaluator -> Evaluator[Evaluator, Operator]

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.

Hide -> VisibilityEvaluator -> FunctionEvaluator -> Evaluator[Evaluator, Operator]

Der Hide-Evaluator deklariert Content-Objekte als unsichtbar.

Show -> VisibilityEvaluator -> FunctionEvaluator -> Evaluator[Evaluator, Operator]

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.

SystemEvaluator -> FunctionEvaluator -> Evaluator[Evaluator, Operator]

Objekte der Klasse SystemEvaluator nehmen direkten Einfluss auf das Anwenderobjekt und die Session. Sie haben Vorrang vor allen anderen Evaluatoren.

Reset -> SystemEvaluator -> FunctionEvaluator -> Evaluator[Evaluator, Operator]

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.

Exit -> SystemEvaluator -> FunctionEvaluator -> Evaluator[Evaluator, Operator]

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.

Transfer -> SystemEvaluator -> FunctionEvaluator -> Evaluator[Evaluator, Operator]

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.

Beispiel:

Skript: login.ant
Row
{   width = "";
    Input
    {   var = login;
        label = "Login: ";
    }
    Submit
    {   var = ok;
        label = "ok","exit";
        Eval
        {   or;
            Transfer
            {   exp = ok, eq, "ok";
                url = "ant/show.ant";
            }
            Exit { url = "{formicula.link}"; }
        }
    }
}
Login:
 
Skript: show.ant
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.

Log -> SystemEvaluator -> FunctionEvaluator -> Evaluator[Evaluator, Operator]

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.

Exec -> SystemEvaluator -> FunctionEvaluator -> Evaluator[Evaluator, Operator]

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.

MessageEvaluator -> FunctionEvaluator -> Evaluator[Evaluator, Operator]

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.

Error -> MessageEvaluator -> FunctionEvaluator -> Evaluator[Evaluator, Operator]

Ein Error-Evaluator erzeugt eine Nachricht, wenn seine Auswertung true zurück gibt. Seine Bedingungen definieren einen Fehler.

Valid -> MessageEvaluator -> FunctionEvaluator -> Evaluator[Evaluator, Operator]

Ein Valid-Evaluator erzeugt eine Nachricht, wenn seine Auswertung false zurück gibt. Seine Bedingungen definieren den fehlerfreien Zustand.

Beispiel:

[msgSpacing] = 2;
Frame
{   border = 1 ;
    Input
    {   var = c;
        label = "Wieviel ist {a} + {b}:";
        Utilize
        {   Eval
            {   exp = a, free;
                exp = a, rand, a, mul, 10, a, add, 1, a, trunc;
                exp = b, rand, b, mul, 10, b, add, 1, b, trunc;
                exp = x, set, a, x, add, b;
            }
        }
        Valid
        {   exp = c, isnum;
            msg = "Nur numerische Eingaben erlaubt.";
        }
        Eval
        {   or;
            Eval { exp = x, eq, c; }
            Error
            {   msg = "Falsche Antwort. Die Summe ist {x}.";
            }
        }
    }
    Submit
    {   var = ok;
        label = "OK";
        Exit {}
    }
}
Nur numerische Eingaben erlaubt.
Falsche Antwort. Die Summe ist 14.
Wieviel ist 7 + 7:

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.

DataEvaluator -> FunctionEvaluator -> Evaluator[Evaluator, Operator]

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.

Connect -> DataEvaluator -> FunctionEvaluator -> Evaluator[Evaluator, Operator]

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.

Beispiel:

Layout
{   Dummy
    {   Connect
        {   driver = "JData2_0.sql.$Driver";
            connection = "jdbc:JDataConnect://127.0.0.1/test";
        }
        Disconnect {}
        Exit {}
    }
}
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.

Disconnect -> DataEvaluator -> FunctionEvaluator -> Evaluator[Evaluator, Operator]

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.

Select -> DataEvaluator -> FunctionEvaluator -> Evaluator[Evaluator, Operator]

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).

Beispiel:

Frame
{   border = 1;
    Text
    {   text = "<b>Mitarbeiter mit hohem Gehalt:\n{liste}";
        subHtml;
        Utilize
        {   Eval
            {   exp = sql.gehalt, set, 4000;
                exp = where, set, "gehalt >= [sql.gehalt]";
                exp = order, set, "order by gehalt";
                exp = liste, set, "<table cellspacing=4>\n";
                exp = liste, join, "<tr><th align=left>ID</th>";
                exp = liste, join, "<th align=left>Name</th>";
                exp = liste, join, "<th align=right>Gehalt</th></tr>\n";
            }
            Connect
            {   driver = "JData2_0.sql.$Driver";
                connection = "jdbc:JDataConnect://127.0.0.1/test";
            }
            Select
            {   sql = "where {where} {order}";
                table = mitarbeiter;
                alias = ma;
                save;
            }
            Eval
            {   exp = liste, build, "{liste}<tr><td>{ma.id}</td>";
                exp = liste, build, "{liste}<td>{ma.vorname} {ma.name}</td>";
                exp = liste, build, "{liste}<td align=right>{ma.gehalt}</td>";
                exp = liste, build, "{liste}</tr>\n";
            }
            Loop
            {   Next { alias = ma; }
                Eval
                { exp = liste, build, "{liste}<tr><td>{ma.id}</td>";
                  exp = liste, build, "{liste}<td>{ma.vorname} {ma.name}</td>";
                  exp = liste, build, "{liste}<td align=right>{ma.gehalt}</td>";
                  exp = liste, build, "{liste}</tr>\n";
                }
            }
            Eval { exp = liste, join, "</table>"; }
        }
        Utilize
        {   Disconnect {}
            Exit {}
        }
    }
}
Mitarbeiter mit hohem Gehalt:
IDNameGehalt
1Hubert Meier 4500
5Isodor Blaumann 4700
2Berta Muster 5000
7Rudi Rechenschieber 5350

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.

Update -> DataEvaluator -> FunctionEvaluator -> Evaluator[Evaluator, Operator]

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.

Beispiel:

Frame
{   border = 1;
    Text
    {   text = "<b>Mitarbeiter mit hohem Gehalt:\n{liste}";
        subHtml;
        Utilize
        {   Eval
            {   exp = liste, set, "<table cellspacing=4>\n";
                exp = liste, join, "<tr><th align=left>ID</th>";
                exp = liste, join, "<th align=left>Name</th>";
                exp = liste, join, "<th align=right>Gehalt</th></tr>\n";
            }
            Connect
            {   driver = "JData2_0.sql.$Driver";
                connection = "jdbc:JDataConnect://127.0.0.1/test";
            }
            Update
            {   exp = new.gehalt, set, 7000;
                sql = "where id = 5";
                table = mitarbeiter;
                alias = new;
                field = gehalt;
            }
            Select
            {   sql = "where gehalt >= 4000 order by gehalt";
                table = mitarbeiter;
                alias = ma;
                save;
            }
            Eval
            {   exp = liste, build, "{liste}<tr><td>{ma.id}</td>";
                exp = liste, build, "{liste}<td>{ma.vorname} {ma.name}</td>";
                exp = liste, build, "{liste}<td align=right>{ma.gehalt}</td>";
                exp = liste, build, "{liste}</tr>\n";
            }
            Loop
            {   Next
                {   alias = ma;
                }
                Eval
                { exp = liste, build, "{liste}<tr><td>{ma.id}</td>";
                  exp = liste, build, "{liste}<td>{ma.vorname} {ma.name}</td>";
                  exp = liste, build, "{liste}<td align=right>{ma.gehalt}</td>";
                  exp = liste, build, "{liste}</tr>\n";
                }
            }
            Eval
            {   exp = liste, join, "</table>";
            }
        }
        Utilize
        {   Disconnect {}
            Exit {}
        }
    }
}
Mitarbeiter mit hohem Gehalt:
IDNameGehalt
1Hubert Meier 4500
2Berta Muster 5000
7Rudi Rechenschieber 5350
5Isodor Blaumann 7000

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.

Delete -> DataEvaluator -> FunctionEvaluator -> Evaluator[Evaluator, Operator]

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.

Beispiel:

Frame
{   border = 1;
    Text
    {   text = "<b>Mitarbeiter:\n{liste}";
        subHtml;
        Utilize
        {   Eval
            {   exp = liste, set, "<table cellspacing=4>\n";
                exp = liste, join, "<tr><th align=left>ID</th>";
                exp = liste, join, "<th align=left>Name</th>";
                exp = liste, join, "<th align=right>Gehalt</th></tr>\n";
            }
            Connect
            {   driver = "JData2_0.sql.$Driver";
                connection = "jdbc:JDataConnect://127.0.0.1/test";
            }
            Delete
            {   sql = "where id = 5";
                table = mitarbeiter;
            }
            Select
            {   sql = "order by id";
                table = mitarbeiter;
                alias = ma;
                save;
            }
            Eval
            {   exp = liste, build, "{liste}<tr><td>{ma.id}</td>";
                exp = liste, build, "{liste}<td>{ma.vorname} {ma.name}</td>";
                exp = liste, build, "{liste}<td align=right>{ma.gehalt}</td>";
                exp = liste, build, "{liste}</tr>\n";
            }
            Loop
            {   Next { alias = ma; }
                Eval
                { exp = liste, build, "{liste}<tr><td>{ma.id}</td>";
                  exp = liste, build, "{liste}<td>{ma.vorname} {ma.name}</td>";
                  exp = liste, build, "{liste}<td align=right>{ma.gehalt}</td>";
                  exp = liste, build, "{liste}</tr>\n";
                }
            }
            Eval { exp = liste, join, "</table>"; }
        }
        Utilize
        {   Disconnect {}
            Exit {}
        }
    }
}
Mitarbeiter mit hohem Gehalt:
IDNameGehalt
1Hubert Meier 4500
2Berta Muster 5000
3Frank Freibier 2450
4Gisella Gundel 3800
6Karl Knatter 1600
7Rudi Rechenschieber 5350
8Luise Lötzinn 2900
9Peter Pausenbrot 4010

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.

Insert -> DataEvaluator -> FunctionEvaluator -> Evaluator[Evaluator, Operator]

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.

Beispiel:

Frame
{   border = 1;
    Text
    {   text = "<b>Mitarbeiter:\n{liste}";
        subHtml;
        Utilize
        {   Eval
            {   exp = m.id, set, 13;
                exp = m.name, set, "Knopf";
                exp = m.vorname, set, "Jim";
                exp = liste, set, "<table cellspacing=4>\n";
                exp = liste, join, "<tr><th align=left>ID</th>";
                exp = liste, join, "<th align=left>Name</th>";
                exp = liste, join, "<th align=right>Gehalt</th></tr>\n";
            }
            Connect
            {   driver = "JData2_0.sql.$Driver";
                connection = "jdbc:JDataConnect://127.0.0.1/test";
            }
            Eval
            {   or;
                Select
                {   sql = "where id = [m.id]";
                    table = mitarbeiter;
                }
                Insert
                {   table = mitarbeiter;
                    alias = m;
                }
            }
            Select
            {   sql = "order by id";
                table = mitarbeiter;
                alias = ma;
                save;
            }
            Eval
            {   exp = liste, build, "{liste}<tr><td>{ma.id}</td>";
                exp = liste, build, "{liste}<td>{ma.vorname} {ma.name}</td>";
                exp = liste, build, "{liste}<td align=right>{ma.gehalt}</td>";
                exp = liste, build, "{liste}</tr>\n";
            }
            Loop
            {   Next
                {   alias = ma;
                }
                Eval
                { exp = liste, build, "{liste}<tr><td>{ma.id}</td>";
                  exp = liste, build, "{liste}<td>{ma.vorname} {ma.name}</td>";
                  exp = liste, build, "{liste}<td align=right>{ma.gehalt}</td>";
                  exp = liste, build, "{liste}</tr>\n";
                }
            }
            Eval
            {   exp = liste, join, "</table>";
            }
        }
        Utilize
        {   Disconnect {}
            Exit {}
        }
    }
}
Mitarbeiter:
IDNameGehalt
1Hubert Meier 4500
2Berta Muster 5000
3Frank Freibier 2450
4Gisella Gundel 3800
6Karl Knatter 1600
7Rudi Rechenschieber 5350
8Luise Lötzinn 2900
9Peter Pausenbrot 4010
13Jim Knopf 0

Der Mitarbeiter "Jim Knopf" mit der Nummer "13", wird nur dann hinzugefügt, wenn die Nummer nicht bereits existiert.

SQL -> DataEvaluator -> FunctionEvaluator -> Evaluator[Evaluator, Operator]

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).

Beispiel:

Frame
{   border = 1;
    Text
    {   text = "<b>Abteilungen:</b>\n{liste}";
        subHtml;
        Utilize
        {   Eval
            {   exp = liste, set, "<dl>\n";
                exp = oldabt, set, 0;
            }
            Connect
            {   driver = "JData2_0.sql.$Driver";
                connection = "jdbc:JDataConnect://127.0.0.1/test";
            }
            SQL
            {   sql = "select a.id, a.vorname, a.name, a.abtnr, b.abteilung";
                sql = "from mitarbeiter a, abteilung b";
                sql = "where a.abtnr = b.abtnr order by a.abtnr, a.name";
                alias = ma;
                save;
            }
            Loop
            {   True
                { exp = oldabt, ne, ma.abtnr;
                  exp = oldabt, set, ma.abtnr;
                  exp = liste, build, "{liste}<dt><b>{ma.abteilung}</b></dt>\n";
                }
                Eval
                { exp = liste, build, "{liste}<dd>{ma.vorname} {ma.name}</dd>\n";
                }
                Next
                {   alias = ma;
                }
            }
            Eval
            {   exp = liste, join, "</dl>";
            }
        }
        Utilize
        {   Disconnect {}
            Exit {}
        }
    }
}
Abteilungen:
Produktion
Frank Freibier
Gisella Gundel
Karl Knatter
Luise Lötzinn
Verwaltung
Hubert Meier
Berta Muster
Entwicklung
Peter Pausenbrot
Rudi Rechenschieber

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.

Next -> DataEvaluator -> FunctionEvaluator -> Evaluator[Evaluator, Operator]

Der Next Evaluator läd den nächsten Ergebnisdatensatz aus einer Ergebnistabelle in die dazugehörige Aliasgruppe. Wenn kein Ergebnisdatensatz mehr vorhanden ist, gibt Next false 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.

Commit -> DataEvaluator -> FunctionEvaluator -> Evaluator[Evaluator, Operator]

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.

Rollback -> DataEvaluator -> FunctionEvaluator -> Evaluator[Evaluator, Operator]

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.

Touch -> DataEvaluator -> FunctionEvaluator -> Evaluator[Evaluator, Operator]

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.

Meta -> DataEvaluator -> FunctionEvaluator -> Evaluator[Evaluator, Operator]

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.

Beispiel:

Frame
{   border = 1;
    Text
    {   text = "<b>Tabellenstruktur: Mitarbeiter</b><br>\n{str}";
        subHtml;
        Utilize
        {   Connect
            {   driver = "JData2_0.sql.$Driver";
                connection = "jdbc:JDataConnect://127.0.0.1/test";
            }
            Eval
            {   exp = str, set, "<table width=100%>\n<tr>\n";
                exp = str, join, "<th align=left>name</th>";
                exp = str, join, "<th align=right>type</th>";
                exp = str, join, "<th align=right>length</th>";
                exp = str, join, "<th align=right>scale</th>";
                exp = str, join, "<th>nullable</th>";
                exp = str, join, "<th>compatible</th>\n</tr>\n";
            }
            Meta
            {   table = mitarbeiter;
                alias = ma;
            }
            Loop
            { Level
              { alias = ma;
                name = name;
                exp = str, build, "{str}<tr>\n<td>{ma.name}</td>";
                exp = str, build, "{str}<td align=right>{ma.type}</td>";
                exp = str, build, "{str}<td align=right>{ma.length}</td>";
                exp = str, build, "{str}<td align=right>{ma.scale}</td>";
                exp = str, build, "{str}<td align=center>{ma.nullable }</td>";
                exp = str, build, "{str}<td align=center>{ma.compatible}</td>";
                exp = str, join, "\n</tr>\n";
                exp = ma.name, moveind, 1;
              }
            }
            Eval
            {   exp = str, join, "</table>";
            }
        }
        Utilize
        {   Disconnect {}
            Exit {}
        }
    }
}
Tabellenstruktur: Mitarbeiter
name type length scale nullable compatible
id 2 5 0 true true
name 1 20 0 true true
vorname 1 20 0 true true
gehalt 2 10 2 true true
abtnr 2 3 0 true true

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.

Catalog -> DataEvaluator -> FunctionEvaluator -> Evaluator[Evaluator, Operator]

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 Catalog false 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).

Beispiel:

Frame
{   border=1;
    Text
    {   text = "<b>Catalog<b><br>\n{str}";
        subHtml;
        Utilize
        {   Catch
            {   Connect
                {   driver = "sun.jdbc.odbc.JdbcOdbcDriver";
                    connection = "jdbc:odbc:test";
                }
            }
            Eval
            {   exp = str, set, "<table width=100%>\n<tr>\n";
            }
            Catalog
            {   alias = db;
                save;
            }
            Gather
            {   alias = db;
                name = dbname;
            }
            Loop
            {   exp = str, build, "{str}<th align=left>{dbname}</th>\n";
                exp = dbname, moveind, 1;
            }
            Eval
            {   exp = str, join, "</tr>\n";
            }
            Loop
            {   Eval
                {   exp = dbname, setind, 1;
                    exp = str, join, "<tr>\n";
                }
                Loop
                {   exp = data, set, *dbname;
                    exp = str, build, "{str}<td>{data}</td>\n";
                    exp = dbname, moveind, 1;
                }
                Eval
                {   exp = str, join, "</tr>\n";
                }
                Next { alias = db; }
            }
            Eval
            {   exp = str, join, "</table>\n";
            }
            Disconnect {}
            Exit {}
        }
    }
}
Catalog
db.table_qualifier db.table_owner db.table_name db.table_type db.remarks
d:\test abteilung TABLE
d:\test mitarbeiter TABLE

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.

IOEvaluator -> FunctionEvaluator -> Evaluator[Evaluator, Operator]

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 -> IOEvaluator -> FunctionEvaluator -> Evaluator[Evaluator, Operator]

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 -> IOEvaluator -> FunctionEvaluator -> Evaluator[Evaluator, Operator]

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.

Read -> IOEvaluator -> FunctionEvaluator -> Evaluator[Evaluator, Operator]

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.

Write -> IOEvaluator -> FunctionEvaluator -> Evaluator[Evaluator, Operator]

Der Write-Evaluator schreibt den Inhalt eines Datenvektors zeilenweise in eine Textdatei.

Eigenschaften:

string var
Diese Eigenschaft definiert den Datenvektor, der komplett zeilenweise in die Datei geschrieben wird.

Beispiel:

Frame
{   border = 1;
    Text
    {   text = "<b>Nachrichten</b><br>";
        text = "<pre>{msg}</pre><hr>Neue Nachricht:";
        Utilize
        {   Open
            {   file = "messageboard/msg.txt";
            }
            Eval
            {   exp = msg, set, "";
            }
            Loop
            {   Read
                {   var = txt;
                    line = 1;
                }
                Eval
                {   exp = msg, join, txt, msg, join, "\n";
                }
            }
        }
    }
    Area
    {   var = newmsg;
        col = 40;
        Utilize
        {   exp = newmsg, used, newmsg, clean;
        }
        Eval
        {   exp = newmsg, trim;
            exp = newmsg, full;
            exp = msg, full;
            exp = newmsg, ins, "-----------------------";
        }
    }
    Submit
    {   var = sub;
        label = "Add","Exit";
        Eval
        {   or;
            Exit
            {   exp = sub, eq, "Exit";
                url = "{formicula.link}";
            }
            Write
            {   exp = newmsg, full;
                var = newmsg;
            }
        }
    }
}
Nachrichten
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.

app -> Operator -> Operator

Parameter
dynamisch
Funktion
Der Datenfeldvektor wird um ein weiteres Element erweitert. Dieses Element wird zum aktiven Element. Skalare Datenfelder werden zu Vektoren. Das Datenfeld muß existieren.
Rückgabe
true

at -> Operator

Parameter
string, string, numerisch
Funktion
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.
Rückgabe
true

build -> Operator

Parameter
string
Funktion
Der String wird substituiert und im Datenfeld gespeichert. Es handelt sich dabei um eine einfache Substitution ohne Maskierung von Html-Steuerzeichen.
Rückgabe
true

def -> Operator

Parameter
dynamisch
Funktion
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").
Rückgabe
true

gen -> Operator

Parameter
dynamisch
Funktion
Wenn das Datenfeld noch nicht definiert ist, wird ihm der Inhalt des Parameters zugewiesen. Existiert es bereits, bleibt es unverändert.
Rückgabe
true

ins -> Operator -> Operator

Parameter
dynamisch
Funktion
An der aktuellen Position im Datenfeldvektor wird ein Element eingefügt. Skalare Datenfelder werden zu Vektoren. Das Datenfeld muß existieren.
Rückgabe
true

join -> Operator

Parameter
string
Funktion
Der String wird an den Inhalt des Datenfeldes angehängt. Das Datenfeld muß existieren.
Rückgabe
true

len -> Operator

Parameter
string
Funktion
Die Länge des Strings wird dem Datenfeld zugewiesen.
Rückgabe
true

lex -> Operator

Parameter
string, string, numerisch
Funktion
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.
Rückgabe
true, wenn der Teilstring existiert
false, sonst

lexcnt -> Operator

Parameter
string, string
Funktion
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.
Rückgabe
true

match -> Operator

Parameter
string
Funktion
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

padl -> Operator

Parameter
string, numerisch
Funktion
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.
Rückgabe
true

padr -> Operator

Parameter
string, numerisch
Funktion
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.
Rückgabe
true

rat -> Operator

Parameter
string, string, numerisch
Funktion
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.
Rückgabe
true

replace -> Operator

Parameter
string, string
Funktion
Im Datenfeld werden alle Vorkommen des ersten Strings durch den zweiten String ersetzt.
Rückgabe
true

set -> Operator

Parameter
dynamisch
Funktion
Dem Datenfeld wird der Inhalt des Parameters unbedingt zugewiesen.
Rückgabe
true

UnaryOperator -> Operator

Ein UnaryOperator hat keine Parameter. Diese abstrakte Klasse stellt keine funktionelle Kategorie dar.

ceil -> UnaryOperator -> Operator

Parameter
keine
Funktion
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.
Rückgabe
true

clean -> UnaryOperator -> Operator

Parameter
keine
Funktion
Der Inhalt des Datenfeldes wird gelöscht. Aus Vekoren wird ein leerer Skalar. Das Datenfeld muß existieren.
Rückgabe
true

date -> UnaryOperator -> Operator

Parameter
keine
Funktion
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
Rückgabe
true

empty -> UnaryOperator -> Operator

Parameter
keine
Funktion
Der Operator prüft, ob das Datenfeld leer ist. Das Datenfeld muß existieren.
Rückgabe
true, wenn das Datenfeld leer ist oder nur Leerzeichen enthält
false, sonst

errcnt -> UnaryOperator -> Operator

Parameter
keine
Funktion
Die Anzahl der Fehlermeldungen der MessageEvaluator-Objekte wird dem Datenfeld zugewiesen. Dabei werden auch mehrfache Meldungen pro Content-Objekt mitgezählt.
Rückgabe
true

floor -> UnaryOperator -> Operator

Parameter
keine
Funktion
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.
Rückgabe
true

free -> UnaryOperator -> Operator

Parameter
keine
Funktion
Der Operator prüft, ob das Datenfeld existiert oder nicht.
Rückgabe
true, wenn das Datenfeld existiert
false, sonst

full -> UnaryOperator -> Operator

Parameter
keine
Funktion
Der Operator prüft, ob das Datenfeld gefüllt ist. Das Datenfeld muß existieren.
Rückgabe
false, wenn das Datenfeld leer ist oder nur Leerzeichen enthält
true, sonst

isdate -> UnaryOperator -> Operator

Parameter
keine
Funktion
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

isbool -> UnaryOperator -> Operator

Parameter
keine
Funktion
Der Operator prüft, ob das Datenfeld den boolschen Werten "true" bzw. "false" entspricht. Das Datenfeld muß existieren.
Rückgabe
true, wenn der Datenfeldinhalt "true" oder "false" ist
false, sonst

isint -> UnaryOperator -> Operator

Parameter
keine
Funktion
Der Operator prüft, ob das Datenfeld in seiner Darstellung einer Integerzahl entspricht. Das Datenfeld muß existieren.
Rückgabe
true, wenn das Datenfeld eine Integerzahl darstellt
false, sonst

isnum -> UnaryOperator -> Operator

Parameter
keine
Funktion
Der Operator prüft, ob das Datenfeld in seiner Darstellung einer beliebigen Zahl entspricht. Das Datenfeld muß existieren.
Rückgabe
true, wenn das Datenfeld eine Zahl darstellt
false, sonst

istime -> UnaryOperator -> Operator

Parameter
keine
Funktion
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

lower -> UnaryOperator -> Operator

Parameter
keine
Funktion
Der Operator wandelt alle Großbuchstaben des Datenfeldes in Kleinbuchstaben um. Das Datenfeld muß existieren.
Rückgabe
true

msgcnt -> UnaryOperator -> Operator

Parameter
keine
Funktion
Dem Datenfeld wird die Anzahl der Content-Objekte mit Fehlermeldungen zugewiesen.
Rückgabe
true

off -> UnaryOperator -> Operator

Parameter
keine
Funktion
Der Operator prüft, ob das Datenfeld dem boolschen Wert "false" entspricht. Das Datenfeld muß existieren.
Rückgabe
true, wenn das Datenfeld "false" ist
false, sonst

on -> UnaryOperator -> Operator

Parameter
keine
Funktion
Der Operator prüft, ob das Datenfeld dem boolschen Wert "true" entspricht. Das Datenfeld muß existieren.
Rückgabe
true, wenn das Datenfeld "true" ist
false, sonst

rand -> UnaryOperator -> Operator

Parameter
keine
Funktion
Eine Zufallszahl größr gleich 0 und kleiner als 1 wird dem Datenfeld zugewiesen.
Rückgabe
true

remove -> UnaryOperator -> Operator

Parameter
keine
Funktion
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.
Rückgabe
false, wenn ein Skalar gelöscht wurde
true, sonst

round -> UnaryOperator -> Operator

Parameter
keine
Funktion
Das Datenfeld wird als Zahl interpretiert und auf den näher liegenden Integerwert gerundet. Das Datenfeld muß existieren.
Rückgabe
true

todate -> UnaryOperator -> Operator

Parameter
keine
Funktion
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

tohtml -> UnaryOperator -> Operator

Parameter
keine
Funktion
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.
Rückgabe
true

topath -> UnaryOperator -> Operator

Parameter
keine
Funktion
Die relative Pfadangabe im Datenfeld wird in eine absolute Pfadangabe umgewandelt.
Rückgabe
true

totime -> UnaryOperator -> Operator

Parameter
keine
Funktion
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

trim -> UnaryOperator -> Operator

Parameter
keine
Funktion
Alle führenden und folgenden Leerzeichen des Datenfeldes werden entfernt. Das Datenfeld muß existieren.
Rückgabe
true

trunc -> UnaryOperator -> Operator

Parameter
keine
Funktion
Das Datenfeld wird als Zahl interpretiert und die Nachkommastellen abgeschnitten. Das Datenfeld muß existieren.
Rückgabe
true

upper -> UnaryOperator -> Operator

Parameter
keine
Funktion
Der Operator wandelt alle Kleinbuchstaben des Datenfeldes in Großbuchstaben um. Das Datenfeld muß existieren.
Rückgabe
true

used -> UnaryOperator -> Operator

Parameter
keine
Funktion
Der Operator prüft, ob das Datenfeld bereits existiert.
Rückgabe
true, wenn das Datenfeld existiert
false, sonst

NumericOperator -> Operator

Ein NumericOperator hat nur numerische Parameter. Diese abstrakte Klasse stellt keine funktionelle Kategorie dar.

add -> NumericOperator -> Operator

Parameter
numerisch
Funktion
Der Parameter wird zum Datenfeld addiert. Das Datenfeld muss existieren.
Rückgabe
true

div -> NumericOperator -> Operator

Parameter
numerisch
Funktion
Der Datenfeld wird durch den Parameter dividiert. Das Datenfeld muss existieren.
Rückgabe
true

isfix -> NumericOperator -> Operator

Parameter
numerisch, numerisch
Funktion
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

left -> NumericOperator -> Operator

Parameter
numerisch
Funktion
Alles was rechts von der Positionsangabe (Parameter) steht wird vom Datenfeld abgeschnitten. Das erste Zeichen hat Position 1. Das Datenfeld muß existieren.
Rückgabe
true

max -> NumericOperator -> Operator

Parameter
numerisch, numerisch
Funktion
Der größere der beiden Parameter wird dem Datenfeld zugewiesen.
Rückgabe
true

min -> NumericOperator -> Operator

Parameter
numerisch, numerisch
Funktion
Der kleinere der beiden Parameter wird dem Datenfeld zugewiesen.
Rückgabe
true

moveind -> NumericOperator -> Operator

Parameter
numerisch
Funktion
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

mul -> NumericOperator -> Operator

Parameter
numerisch
Funktion
Das Datenfeld wird mit dem Parameter multipliziert. Das Datenfeld muss existieren.
Rückgabe
true

right -> NumericOperator -> Operator

Parameter
numerisch
Funktion
Alles was links von der Positionsangabe (Parameter) steht wird vom Datenfeld abgeschnitten. Das erste Zeichen hat Position 1. Das Datenfeld muß existieren.
Rückgabe
true

setind -> NumericOperator -> Operator

Parameter
numerisch
Funktion
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

sub -> NumericOperator -> Operator

Parameter
numerisch
Funktion
Der Parameter wird vom Datenfeld subtrahiert. Das Datenfeld muss existieren.
Rückgabe
true

substr -> NumericOperator -> Operator

Parameter
numerisch, numerisch
Funktion
Der erste Parameter definieren die Position (bei 1 beginnend), der zweite Parameter die Länge des Teilstrings, der aus dem Datenfeld kopiert wird.
Rückgabe
true

tofix -> NumericOperator -> Operator

Parameter
numerisch, numerisch
Funktion
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

ValueOperator -> Operator

Ein ValueOperator hat nur Datenfeld- bzw. Referenzparameter. Konstanten sind nicht erlaubt. Diese abstrakte Klasse stellt keine funktionelle Kategorie dar.

getind -> ValueOperator -> Operator

Parameter
Datenfeld/Referenz
Funktion
Dem Datenfeld wird der aktuelle Index des Datenfeldparameters als Zahl zugewiesen.
Rückgabe
true

size -> ValueOperator -> Operator

Parameter
Datenfeld/Referenz
Funktion
Dem Datenfeld wird die Vektorlänge des Datenfeldparameters zugewiesen.
Rückgabe
true

CompareOperator -> Operator

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.

DynamicCompareOperator -> CompareOperator -> Operator

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 (>=)

rec -> DynamicCompareOperator -> CompareOperator -> Operator

Parameter
dynamisch, dynamisch
Funktion
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.
Rückgabe
true

NumericCompareOperator -> CompareOperator -> Operator

Ein NumericCompareOperator vergleicht immer numerisch. String-Konstanten sind nicht erlaubt. Kann eine Seite nicht als Zahl interpretiert werden, gibt der Operator false zurück. Folgende NumericCompareOperator Klassen wurden realisiert: eqnum (=), nenum (!=), ltnum (<), lenum (<=), gtnum (>), genum (>=)

StringCompareOperator -> CompareOperator -> Operator

Ein StringCompareOperator vergleicht immer alphanumerisch. Numerische Konstanten sind nicht erlaubt. Folgende NumericCompareOperator Klassen wurden realisiert: eqstr (=), nestr (!=), ltstr (<), lestr (<=), gtstr (>), gestr (>=)

 

Anhang

Systemfelder

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.

Farbname Hexadezimal Beispiel-Tabellenzelle mit dieser Farbe
aliceblue #F0F8FF
antiquewhite #FAEBD7
aquamarine #7FFFD4
azure #F0FFFF
beige #F5F5DC
blueviolet #8A2BE2
brown #A52A2A
burlywood #DEB887
cadetblue #5F9EA0
chartreuse #7FFF00
chocolate #D2691E
coral #FF7F50
cornflowerblue #6495ED
cornsilk #FFF8DC
crimson #DC143C
darkblue #00008B
darkcyan #008B8B
darkgoldenrod #B8860B
darkgray #A9A9A9
darkgreen #006400
darkkhaki #BDB76B
darkmagenta #8B008B
darkolivegreen #556B2F
darkorange #FF8C00
darkorchid #9932CC
darkred #8B0000
darksalmon #E9967A
darkseagreen #8FBC8F
darkslateblue #483D8B
darkslategray #2F4F4F
darkturquoise #00CED1
darkviolet #9400D3
deeppink #FF1493
deepskyblue #00BFFF
dimgray #696969
dodgerblue #1E90FF
firebrick #B22222
floralwhite #FFFAF0
forestgreen #228B22
gainsboro #DCDCDC
ghostwhite #F8F8FF
gold #FFD700
goldenrod #DAA520
greenyellow #ADFF2F
honeydew #F0FFF0
hotpink #FF69B4
indianred #CD5C5C
indigo #4B0082
ivory #FFFFF0
khaki #F0E68C
lavender #E6E6FA
lavenderblush #FFF0F5
lawngreen #7CFC00
lemonchiffon #FFFACD
lightblue #ADD8E6
lightcoral #F08080
lightcyan #E0FFFF
lightgoldenrodyellow #FAFAD2
lightgreen #90EE90
lightgrey #D3D3D3
lightpink #FFB6C1
lightsalmon #FFA07A
lightseagreen #20B2AA
lightskyblue #87CEFA
lightslategray #778899
lightsteelblue #B0C4DE
lightyellow #FFFFE0
limegreen #32CD32
linen #FAF0E6
mediumaquamarine #66CDAA
mediumblue #0000CD
mediumorchid #BA55D3
mediumpurple #9370D
mediumseagreen #3CB371
mediumslateblue #7B68EE
mediumspringgreen #00FA9A
mediumturquoise #48D1CC
mediumvioletred #C71585
midnightblue #191970
mintcream #F5FFFA
mistyrose #FFE4E1
moccasin #FFE4B5
navajowhite #FFDEAD
oldlace #FDF5E6
olivedrab #6B8E23
orange #FFA500
orangered #FF4500
orchid #DA70D6
palegoldenrod #EEE8AA
palegreen #98FB98
paleturquoise #AFEEEE
palevioletred #DB7093
papayawhip #FFEFD5
peachpuff #FFDAB9
peru #CD853F
pink #FFC0CB
plum #DDA0DD
powderblue #B0E0E6
rosybrown #BC8F8F
royalblue #4169E1
saddlebrown #8B4513
salmon #FA8072
sandybrown #F4A460
seagreen #2E8B57
seashell #FFF5EE
sienna #A0522D
skyblue #87CEEB
slateblue #6A5ACD
slategray #708090
snow #FFFAFA
springgreen #00FF7F
steelblue #4682B4
tan #D2B48C
thistle #D8BFD8
tomato #FF6347
turquoise #40E0D0
violet #EE82EE
wheat #F5DEB3
whitesmoke #F5F5F5
yellowgreen #9ACD32

Links