MyTISM ist ein leistungsstarkes Framework zur Entwicklung und Verwaltung von Datenbankanwendungen. Es ist plattformunabhängig, objektorientiert, dezentral, multiuserfähig, individuell anpassbar und quelloffen. Mit MyTISM erstellen Sie effizient komplexe Anwendungen, dank einer umfassenden Sammlung von Tools und Funktionen, inklusive GUI und Web-Application-Server. MyTISM wird entwickelt und betreut von der OAshi S.à r.l.
Diese Dokumentation richtet sich an Entwickler und interessierte Anwender, die tief in die Interna und den Aufbau von MyTISM eintauchen möchten.
Voraussetzungen: Um diese Dokumentation optimal nutzen zu können, sollten Sie über gute bis sehr gute Kenntnisse in folgenden Bereichen verfügen:
-
Java
-
Groovy
-
NetRexx
-
Relationale und objektorientierte Datenbanken
Idealerweise haben Sie bereits erste Erfahrungen mit der Bedienung von MyTISM gesammelt.
Diese Dokumentation befindet sich noch im Aufbau. Wir arbeiten kontinuierlich an der Vervollständigung und Verbesserung der Inhalte. |
Bei Fragen, Problemen oder Anregungen zu MyTISM oder dieser Dokumentation kontaktieren Sie uns gerne über https://www.mytism.de/#contact.
MyTISM: Das 3-Tier-Framework für Ihre Anwendung
MyTISM ist ein robustes und flexibles 3-Tier-Framework, das die Entwicklung skalierbarer und wartbarer Anwendungen deutlich vereinfacht. Durch die strikte Trennung von Präsentation, Anwendungslogik und Datenhaltung ermöglicht MyTISM effiziente Entwicklungsprozesse und bietet maximale Flexibilität bei der Anpassung an zukünftige Anforderungen.
Die drei Schichten in MyTISM:
-
Präsentationsschicht (Frontend): MyTISM stellt Ihnen Werkzeuge und Komponenten zur Verfügung, um Benutzeroberflächen nach Ihren Bedürfnissen zu gestalten.
-
Anwendungsschicht (Middleware): In der MyTISM Middleware implementieren Sie die Geschäftslogik Ihrer Anwendung, verarbeiten Daten und greifen auf die Datenbank zu.
-
Datenbankschicht (Backend): MyTISM abstrahiert und vereinfacht den Zugriff auf die Datenbank durch die integrierte Object Query Language (OQL). OQL ermöglicht einen objektorientierten, einfachen und performanten Zugriff auf die zugrundeliegende relationale Datenbank.
Die 3-Tier-Architektur sorgt für eine übersichtliche und leicht verständliche Codebasis. Änderungen an einer Schicht haben minimale Auswirkungen auf die anderen Schichten. Diese Modularität erleichtert die Wartung und Aktualisierung der Anwendung und erhöht ihre Skalierbarkeit.
MyTISM bietet Ihnen ein solides Fundament für die Entwicklung Ihrer Anwendung. Durch die konsequente Anwendung des 3-Tier-Modells profitieren Sie von einer strukturierten, flexiblen und zukunftssicheren Architektur.
Vorstellung von MyTISM
Was ist MyTISM?
MyTISM ist ein Java-basiertes Anwendungsframework mit integrierter Datenbankunterstützung. Es besteht aus einem oder mehreren miteinander verbundenen Servern (inkl. PostgreSQL-Datenbank) und Clients, die über das Netzwerk darauf zugreifen. Der Hauptclient, Solstice, bietet eine grafische Benutzeroberfläche mit umfangreichen Konfigurationsmöglichkeiten.
MyTISM ermöglicht die Entwicklung von Webanwendungen, die auf das MyTISM-System zugreifen, und bietet Funktionen zur Erstellung von Berichten, zur Verwaltung von Benutzerrechten, zur Versendung von Benachrichtigungen, zur Reaktion auf Ereignisse mittels seines Alarmsystems und zur Automatisierung von Aufgaben via eigener Dienste.
MyTISM entstand aus der Vision, ein Framework zu schaffen, das die Lücken bestehender Lösungen schließt und eine wirklich integrierte und effiziente Entwicklungsumgebung bietet. MyTISM wurde aus der Notwendigkeit heraus geboren, komplexe Datenbankanwendungen zu vereinfachen und zu beschleunigen. Es ist das Ergebnis jahrzehntelanger Erfahrung und Entwicklung und bietet eine einzigartige Kombination von Funktionen und Flexibilität.
Warum MyTISM?
Eine gute Frage. Warum tut man sich heutzutage noch den Aufwand an, ein Datenbank-Framework und all das Drumherum bis zum Applikationsserver von Grund auf neu zu entwickeln, wenn es die entsprechenden Werkzeuge am Markt doch in Hülle und Fülle bereits gibt? Oder ist es nur der Wunsch eines jeden Programmierers, "sein" Framework zu bauen und zu verwenden?
Die Wahrheit ist: Als ich mir auf der Suche nach den passenden Puzzleteilen die verschiedenen Frameworks angeschaut habe (wohlgemerkt Stand Mitte 2001) musste ich feststellen, daß es zwar immer wieder gute Teile gab, aber nichts, was zusammengepaßt hätte. Osage, XwingML, verschiedene Wrapper für native GUIs, RAD-Tools zum Erstellen von Swing-Code etc; ganz zu schweigen von Standards wie J2EE mit ihren CMP, BMP und weiß Gott was sonst noch so alles. Aber es paßte einfach nicht wirklich ins Bild. Immer, wenn ich einen Prototypen zusammensetzte, blieb ich entweder an einer Lizenz-Ecke hängen oder es hakte einfach technisch an der Möglichkeit der Umsetzung.
Noch lange nicht am Ende dieses Weges angelangt, kann ich nach inzwischen drei Jahren Entwicklung (diese Zeilen entstanden im September 2004) sagen, daß es, und das ist das schönste Lob von allen, immer wieder Programmierer gibt, die einen Blick auf das entstandene Werk werfen und feststellen, daß es sich substantiell von allem unterscheidet, was sie bislang gesehen haben. Das kann natürlich auch an der Unwissenheit oder Unerfahrenheit dieser Programmierer liegen, aber trotzdem interpretiere ich es als ein großes Kompliment für unsere Firma und auch persönlich für mich.
Historie
Den Anfang nahm alles im August 2000 (das Wochenende vom 26.-27., um genau zu sein), als ich anfing, ein neues Projekt für einen Industriekunden zu durchdenken, und mir, nachdem ich schon monatelang um OODBMSe mit einem befreundeten Programmierer diskutiert hatte, der Paradigmenbruch eines Java-Programmierers, der Datenbankanwendungen schreibt, wirklich bewußt wurde.
Irgendwie ist es fast wie Autofahren: Am Anfang freut man sich, daß man das Vehikel wenigstens schadfrei über die Straßen bewegen kann und freut sich, heil anzukommen. Doch je mehr Routine man erlangt, umso mehr fallen Unzulänglichkeiten wie schlechtes Fahrwerk, Sitze, leistungsschwache Motoren oder auch einfach das unbehende und unvorausschauende Treiben anderer Verkehrsteilnehmer auf - nicht, daß sie vorher nicht dagewesen sind, man war möglicherweise sogar ein Teil davon. Aber mit der Routine kommt auch der Drang, besser zu werden, die Prozesse zu optimieren, schneller voran zu kommen, die Resourcen sinnvoller zu nutzen.
So ist man am Anfang froh, überhaupt aus einer DBMS irgendwie Daten zu bekommen, bestaunte jede abgesetzte Query und war froh, die Daten an Ort und Stelle irgendwie laden und wieder zurückspeichern zu können. Auch war es anfangs keine Mühe, sondern eher fast magisch, an dem Schema der SQL-Datenbank herumzuschrauben und Trigger zu setzen, kleine SQL-Scripts zu schreiben etc. Alles war ein großer Spaß und ich war stolz, eine SQL-Datenbank "zu beherrschen". Wie naiv man doch manchmal ist…
Aber mit der Routine kam auch die Redundanz. Schon wieder eine Tabelle ändern, die Query erweitern um eine Spalte, ein bißchen Javacode anpassen, in der GUI das Feld dazubauen, den Serializer erweitern und so weiter. Alles Jobs, um die man sich als Programmierer nicht gerade reißt. Zumindest ich reiße mich nicht darum. Dazu kam, daß man ständig das Verhalten der Anwendung teilweise in der Datenbank, teilweise in der Persistenz und zu guter Letzt auch noch in der GUI bestimmte. Wo wurde nochmal diese zehnstellige Zahl abgefragt? Welche Klasse prüft die Artikelnummer? Die Arbeit mit Datenbankanwendungen wurde schnell zu einer leidigen Pflichtübung und hatte mit Design nur noch wenig zu tun. Ich drückte mich um jedes geänderte Feld, um jede veränderte Definition, weil sie sich mehr oder weniger durch den gesamten Code zog und nach jedem weiteren Programmteil noch aufwändiger wurde. Mal abgesehen davon, daß der Wechsel der SQL-Servers ein reiner Albtraum gewesen wäre, aber dazu kam es Gott sei Dank nie.
Die erste Verbesserung kam dann in jenem August 2000, als ich konkret daran ging, die Anwendung dieses Kunden zu entwerfen und nach einigen Tests mit Osage und anderen ORM’s, deren Namen ich heute nicht mehr weiß, einen Test mit der Castor-API machte. Dieser Test wurde dann schnell zum Prototypen und bald hatte ich ein Problem weniger: Der Persistenz-Code war jetzt an einer Stelle zu finden und viele Aspekte der Business-Logik waren nun in Objekten, die persistiert wurden, gekapselt. Außerdem konnte man mit einem Subset vom OQL Abfragen aus objektorientierter Sicht erstellen, die die API in SQL-Queries abhängig vom verwendeten SQL-Server verwandelte. Sie schirmte einen sozusagen vom SQL-Code völlig ab - eine völlig faszinierende Sache aus Sicht des Programmierers.
Leider war der Castor noch nicht fertig (er ist es heute noch nicht), und seine Unzulänglichkeiten zwangen mich zeitweise wochenlang in die Fehlersuche und haben mich wahrscheinlich um Jahre altern lassen. Aber er ließ Dinge geschehen, die für mich magisch waren und deren Mechanismen ich im Detail erst viel später verstand. Das einzige, an dem ich immer noch basteln musste, waren die Mapping-Files, die eigentlichen BO-Klassen und die Datenbank an sich. Wenn diese drei ordentlich synchron gepflegt wurden, lief alles reibungslos. Wenn nicht, dann…
Dieses erste Projekt mit einem ORM war ein voller Erfolg; es lief vom ersten Tag fast störungsfrei und bewältigte eine Aufgabe, die recht komplex viele Datenströme zur rechten Zeit zum richtigen Ort schaffen musste und als Schalt- und Regelzentrale eine anspruchsvolle und verantwortungsvolle Stellung in der Firma hatte. Einige der Probleme, die vorher bestanden und die durch eine vorherige Lösung bereits längst erledigt sein sollten, wurden nun endlich erledigt. Einige Folgeaufträge stand das nächste neue Projekt an, ein Vertriebssystem.
Ein altes chinesisches Sprichwort sagt: Für einen Mann mit einem Hammer sieht alles wie ein Nagel aus. Wie wahr. Da hatten wir nun dieses Projekt mit dem Castor ORM und einen Kunden, dessen zugegeben etwas hoch gesteckte Ziel so nicht kauffertig zu erwerben war. Was lag näher, als auch ihm eine individuelle Lösung zu bauen - 60% davon sind ja schon fertig. Nun, zumindest schien das so, und nach einer kurzen Preisverhandlung sollte 3-4 Monate später das Programm fertig sein. Das war im März 2001. Im August 2001 hatte ich eine eher wackelige Fassade dessen, was der Kunde eigentlich wollte (wobei die Frage im Raum steht, welcher Kunde schon am Anfang eines solchen Projekts weiß, was er wirklich will). Synchronisation war noch in weiter Ferne, das Transportprotokoll RMI und die Geschwindigkeit insgesamt lausig. Aber mit wenigen Testdaten blieb alles im RAM und so fiel es nicht weiter auf, daß das eigentliche Produkt, so wie ich es im Kopf hatte, noch viel Arbeit kosten würde.
So wurde zunächst die Formularengine grob zusammengestoppelt und die damals recht junge JNLP-Spezifikation zur Installation der Clients fertiggestellt. Eine erste Version des Schema-Generators erlaubte im Compile-Zyklus eine Anpassung der Datenbank, generierte Sourcecode und erstellte statische Mapping-Files für den späteren Server-Start. Das Projektverzeichnis war ein einziger Wust von kleinen Dateien, in denen kleine Informationsbröckchen lagen, die Auskunft über die Konfiguration einzelner Teile der Software gab. Ein Apache auf der gleichen Maschine lieferte eine kleine Website mit den JNLP-Deskriptoren samt jars aus. Somit war ein zumindest installationsfähiger Client samt Server zusammengestellt, der die anfänglichen Anforderungen des Kunden, der langsam aber sicher auch etwas ungeduldig wurde, bediente (November 2001).
Zur gleichen Zeit hatte ich einen Kunden, der ein altes PHP-Framework von uns um Mehrsprachigkeit und Skins erweitern wollte. Mir war klar, daß in diesem Code-Moloch eigentlich ein Neubau die einzige mögliche Strategie der Weiterentwicklung lag. Aber warum jetzt ein PHP-Framework bauen, wenn gerade ein Java-ORM Framework entstand? Die Idee zu Equinox entstand und wurde von mir bereits im Oktober 2001 gegenüber diesem Kunden über den grünen Klee gelobt. Eigentlich hatte dieser Programmteil als erster seinen Namen; dieser Kunde brauchte einen Namen für ein Produkt, also nannte Thorsten es Equinox.
Die Formularengine bekam alsbald eine Script-Schnittstelle, der Schema-Generator wurde zerteilt und erzeugte im Compile-Stage nur noch den Quellcode der persistenten Klassen und der Server brauchte für die Initialisierung nur noch eine ini und die Log-Konfiguration. Daran hat sich bis heute auch nicht mehr viel verändert, wenngleich der Inhalt der ini inzwischen leicht gewachsen ist. Außerdem entstand in den Weihnachstagen eine erste Version des Synchronisationsmechanismus, der auf Basis der Zeitstempel an den Objekten funktionierte, der sogenannte Statesync. Er funktionierte mit einer nicht allzu großen Menge an Objekten gemessen an der Komplexität erstaunlich gut. Aber er tat dies weder vollständig noch in einer annehmbaren Geschwindigkeit. Ich hatte die Geschwindigkeit des Gesamtsystems einfach grob überschätzt. Außerdem brauchte er Unmengen an RAM. Eine Alternative musste her, und die war nur im Logsync zu finden - diese Variante ist heute die einzig Mögliche in MyTISM.
Im Lauf der ersten Monate von 2002, inzwischen arbeiteten drei Programmierer aktiv an der Entwicklung von MyTISM, wie es inzwischen hieß, wurden das Logging verfeinert. Erst jetzt wurde der Float-Datentyp in MyTISM eingebaut. Die Formularengine konnte inzwischen Scripts nach allen Regeln der Kunst, ein BX-Objekt (eine nicht persistente Entität, die jedoch per Schema zugreifbar und damit funktionell identisch mit anderen BOs) wurde eingeführt. Ende April gab es eine erste Version der GUI des Hotelvermittlers, der zweite Kunde für MyTISM überhaupt. Anfang Mai wurden dann die ersten wirklich lauffähigen Versionen von Equinox gesichtet; der Equinox-Kunde wollte Juni 2002 live gehen mit der neuen Website, aber leider hatte er durch viele Updates an seine alten Site derartig Resourcen gebunden, daß es uns nicht möglich war, mit der nötigen Intensität an Equinox weiterzubauen. Außerdem waren der Designer und der ERP-Supplier nicht unbedingt unseren Anforderungen gewachsen, so daß wir viele Arbeiten, die eigentlich nicht unser Job waren, mit erledigen mussten. Aber alles in allem ging die Entwicklung von Equinox voran, und die ersten Seiten krabbelten aus dem Web, frisch aus MyTISM, in XML gewandelt, per XSLT transformiert und dann ausgegeben…
Die Logschreiberei war im April soweit beendet, daß ein weiterer Mechanismus gebaut werden konnte: der Export-Handler, der auf Basis der Logs Daten an Fremdsysteme ausliefern konnte - per Timetravel sogar mit echten "Snapshots" der Daten zum jeweiligen Zeitpunkt.
Zukunft?
MyTISM hat sich seit seiner Entstehung zu einem robusten und flexiblen Framework entwickelt, das sich in verschiedenen Anwendungsbereichen bewährt hat. Die Zukunft von MyTISM sieht vielversprechend aus und bietet spannende Möglichkeiten für weitere Innovationen und Verbesserungen.
To be continued…
Schema
Das Schema ist das Herzstück jeder MyTISM-Anwendung. Es definiert die Struktur der Datenobjekte und bildet die Grundlage für die gesamte Anwendungslogik.
Funktionsweise
-
Datenmodellierung: Im Schema definieren Sie die Entitäten (z. B. Kunde, Produkt, Auftrag) und deren Attribute (z. B. Name, Preis, Datum) sowie die Beziehungen zwischen den Entitäten.
-
Codegenerierung: MyTISM generiert automatisch den Java-Quellcode für die benötigten Klassen basierend auf Ihrem Schema.
-
Datenbankintegration: Die Datenbanktabellen werden anhand des Schemas angelegt und verwaltet.
-
UI-Generierung: Für Solstice (die MyTISM-GUI) werden automatisch Formulare, Schablonen und Lesezeichen generiert, die auf dem Schema basieren.
Vorteile
-
Effizienz: Schnelle und einfache Datenmodellierung ohne manuelle Codeerstellung.
-
Konsistenz: Das Schema stellt sicher, dass Datenstruktur und Anwendungslogik synchron bleiben.
-
Flexibilität: Änderungen am Schema werden automatisch in Code, Datenbank und UI übernommen.
Die Schema-Definition erfolgt in der deklarativen Sprache XML
.
Eine detaillierte Beschreibung der Syntax und der verfügbaren Elemente finden Sie im folgenden Kapitel "Schema-Definition".
Schema-Definition
Das <Schema>
-Element definiert das Schema für Ihr MyTISM-System.
Es enthält alle Informationen über die Entitäten, Attribute, Beziehungen und andere Elemente, die Ihr Datenmodell ausmachen.
Einleitender Tag: <Schema BEFEHLE>
Schliessender Tag: </Schema>
Attribute
Attribut | Beschreibung | Beispiel |
---|---|---|
|
Gibt die Version des Schemas an.
Enthält Platzhalter wie |
|
|
Definiert das Basis-Package für Entitäten und Attribute.
Ermöglicht die Vermeidung von redundanten Package-Angaben bei |
|
|
Definiert den Standardordner im Navigationsbaum für die im Schema definierten Entitäten. |
|
Unter-Elemente des Schema-Elements
Das <Schema>
-Element kann die folgenden Unter-Elemente enthalten:
-
Entity
: Definiert eine Entität, die ein Datenobjekt innerhalb des MyTISM-Systems repräsentiert (z. B. Kunde, Produkt, Auftrag).-
Entitäten besitzen Attribute und können Beziehungen zu anderen Entitäten haben.
-
-
Include
: Ermöglicht das Einbinden externer Schema-Definitionen aus anderen Dateien, um das Schema modular zu organisieren. -
ModuleProvider
: Definiert einen Anbieter für Module, die zusätzliche Funktionen oder Erweiterungen für MyTISM bereitstellen. -
ModuleIntegrator
: Definiert einen Integrator für Module, der die Integration von Modulen in das MyTISM-System übernimmt. -
Module
: Definiert ein spezifisches Modul, das im MyTISM-System verwendet werden soll.-
Module werden von ModuleProvidern bereitgestellt.
-
-
Generator
: Definiert einen Generator, der Code, Datenbankstrukturen oder andere Artefakte basierend auf dem Schema generiert. -
Folder
: Definiert einen Ordner im Navigationsbaum der MyTISM-Benutzeroberfläche, um Entitäten und andere Elemente zu organisieren. -
Type
: Definiert einen benutzerdefinierten Datentyp, der in Attributen verwendet werden kann. -
Interface
: Definiert ein Interface, das von Entitäten implementiert werden kann. -
GDPR*
: Definiert GDPR-relevante Elemente, die Informationen zur Einhaltung der Datenschutz-Grundverordnung (DSGVO) enthalten.-
GDPRDataCategory
: Definiert eine Kategorie von personenbezogenen Daten (z. B. Vertragsdaten, Gesundheitsdaten). -
GDPRBusinessInterest
: Definiert ein berechtigtes Interesse des Unternehmens an der Verarbeitung personenbezogener Daten. -
GDPRProcessingPurpose
: Definiert den Zweck der Verarbeitung personenbezogener Daten (z. B. Vertragserfüllung, Werbung). -
GDPRProcessingLegalBasis
: Definiert die Rechtsgrundlage für die Verarbeitung personenbezogener Daten (z. B. Einwilligung, Vertragserfüllung). -
GDPRLaw
: Definiert ein relevantes Gesetz im Zusammenhang mit der DSGVO (z. B. Artikel 6 DSGVO). -
GDPRRetentionPurpose
: Definiert den Zweck der Aufbewahrung personenbezogener Daten.
-
Include
Mit dem <Include>
-Element können Sie, ähnlich wie in Programmiersprachen, eine bestehende Schema-Definition aus einer anderen Datei einbinden.
Dies ermöglicht die modulare Organisation des Schemas.
Tag: <Include BEFEHLE />
Attribut | Beschreibung | Beispiel |
---|---|---|
|
Name der einzubindenden Datei. |
|
|
Gibt an, ob das eingebundene Schema ein Kindschema ist. |
|
Folder
Legt einen Ordner im Navigationsbaum an, in dem die automatisch generierten Formulare und anderen Strukturelemente für die nachfolgend definierten Entitäten einsortiert werden.
Tag: <Folder Foldername />
Attribut | Beschreibung | Beispiel |
---|---|---|
|
Name des Ordners. |
|
ModuleProvider
Definiert einen ModuleProvider.
Attribut | Beschreibung | Beispiel |
---|---|---|
|
Name des ModuleProviders. |
|
|
Pfad des ModuleProviders. |
|
ModuleIntegrator
Definiert einen ModuleIntegrator.
Attribut | Beschreibung | Beispiel |
---|---|---|
|
Name der Klasse. |
|
Module
Definiert ein Modul.
Attribut | Beschreibung | Beispiel |
---|---|---|
|
Name des Moduls. |
|
|
Name des ModuleProviders. |
|
Generator
Definiert einen Generator.
Attribut | Beschreibung | Beispiel |
---|---|---|
|
Name der Klasse. |
|
|
Scope des Generators. Alle Werte außer "local" werden als globaler Scope interpretiert. |
|
Type
Definiert einen benutzerdefinierten Datentyp.
Attribut | Beschreibung | Beispiel |
---|---|---|
|
Name des Typs. |
|
|
Name der Klasse. |
|
|
Basistyp. |
|
Interface
Definiert ein Interface.
Attribut | Beschreibung | Beispiel |
---|---|---|
|
Name des Interfaces. |
|
GDPR*
Definiert GDPR-relevante Elemente.
GDPRDataCategory
Definiert eine GDPR-Datenkategorie.
Attribut | Beschreibung | Beispiel |
---|---|---|
|
ID der Datenkategorie. |
|
|
Titel der Datenkategorie (optional). |
|
GDPRBusinessInterest
Definiert ein GDPR-Geschäftsinteresse.
Attribut | Beschreibung | Beispiel |
---|---|---|
|
ID des Geschäftsinteresses. |
|
GDPRProcessingPurpose
Definiert einen GDPR-Verarbeitungszweck.
Attribut | Beschreibung | Beispiel |
---|---|---|
|
ID des Verarbeitungszwecks. |
|
GDPRProcessingLegalBasis
Definiert eine GDPR-Rechtsgrundlage.
Attribut | Beschreibung | Beispiel |
---|---|---|
|
ID der Rechtsgrundlage. |
|
GDPRLaw
Definiert ein GDPR-Gesetz.
Attribut | Beschreibung | Beispiel |
---|---|---|
|
ID des Gesetzes. |
|
|
Paragraph des Gesetzes (z. B. "Art. 6 para. 1 lit. b GDPR"). |
|
|
ISO-Code des Landes. |
|
|
URL zum Gesetzestext (optional). |
|
GDPRRetentionPurpose
Definiert einen GDPR-Aufbewahrungszweck.
Attribut | Beschreibung | Beispiel |
---|---|---|
|
ID des Aufbewahrungszwecks. |
|
Entity
Eine Entity repräsentiert ein Datenobjekt innerhalb Ihres MyTISM-Systems, z. B. einen Kunden, ein Produkt oder einen Auftrag. Im Schema definieren Sie die Struktur einer Entity, indem Sie ihre Attribute festlegen und Beziehungen zu anderen Entitäten herstellen.
Einleitender Tag: <Entity BEFEHLE>
Schliessender Tag: </Entity>
Attribut | Beschreibung | Beispiel |
---|---|---|
|
Name der Entität. |
|
|
Plural-Bezeichnung der Entität. |
|
|
Gibt die Basisklasse an, von der die Entität erbt. |
|
|
Gibt an, ob die Entität abstrakt ist.
Abstrakte Entitäten können nicht direkt instanziiert werden und dienen als Basisklassen für andere Entitäten.
Standardwert: |
|
|
Unterdrückt die Warnung, dass die Entität abstrakt ist, und erlaubt (eingeschränkt) die Instanziierung der Entität. Dies ist für technische Entitäten nützlich, die programmatisch erstellt, aber nicht über die MyTISM-GUI bearbeitet werden sollen. |
|
|
Gibt an, ob Rückwärtsbeziehungen für eine Entität ignoriert werden sollen. |
|
|
Setzt einen benutzerdefinierten Diskriminator (d.h. die BOT Id) für die Entität. |
|
|
Legt eine speziellen suid (SerialVersionUID, serial version unique ID, Klassenversionskennung) fest. |
|
|
Gibt ein abweichendes Package für die Entität an. |
|
Unter-Element "gdpr" von Entity
Der <gdpr>
-Knoten ist ein optionaler Unterknoten innerhalb einer Entity, der alle DSGVO-relevanten Informationen für diese Entity bündelt.
Struktur des <gdpr>
-Knotens:
<gdpr dataCategory="Contract Data" retentionStartDatePath="Vertragsende">
<affectedPerson path="Kunde.AbstraktePerson"/>
<affectedPerson path="Adressat"/>
<retentionVeto path="BuchungsKonto.AbstraktePerson"/>
</gdpr>
Attribut/Element | Beschreibung | Beispiel |
---|---|---|
|
Gibt die Datenkategorie der Entity an (z. B. "Contract Data", "Invoice Data", "Health Data"). Dieses Attribut ist erforderlich. |
|
|
Enthält den Pfad zu einem Datumswert, der den Start der Aufbewahrungsfrist definiert (z. B. Vertragsende). Nur anwendbar, wenn der data retention start der dataCategorie den Wert "custom" enthält. |
|
|
Enthält den Pfad zu einer von dem Datensatz betroffenen Person.
Mehrere |
|
|
Gibt den Pfad zu einem Datensatz an, der ein Veto gegen die Löschung dieser Entity einlegen kann (z. B. eine Archivierungsanforderung).
Mehrere |
|
Unter-Element "ui" von Entity
Das <ui>
-Element innerhalb einer Entity-Definition enthält Attribute, die das Verhalten und die Darstellung der Entität in der Benutzeroberfläche (UI) beeinflussen.
Attribut | Beschreibung | Beispiel |
---|---|---|
|
Beschreibung der Entität.
Definiert die Ausgabe der |
|
|
Gibt an, ob eine Übersicht (Liste) der Objekte der Entität direkt in einem geöffneten Lesezeichen (FTable) angezeigt werden soll.
Aus Performance-Gründen nur sinnvoll bei Entitäten mit einer überschaubaren Anzahl von Objekten.
Standardwert: |
|
|
Gibt an, ob Objekte nicht im Kontext dieses Objekts angelegt, sondern lediglich mit diesem Objekt verknüpft werden können.
Standardwert: |
|
|
Zum Angeben von GUI-Tipps, d.h. durch Leerzeichen getrennte |
|
|
Definiert die Standardsortierung für Tabellen, die Objekte dieses Typs anzeigen.
Format: |
|
|
Nur sinnvoll für Entity-Attribute vom Typ "String".
Legt fest, ob Whitespace am Anfang und Ende der Eingabe in der GUI automatisch entfernt wird.
Standardwert für String-Attribute ist |
|
|
Definiert einen nicht-interaktiven Filter für die Auswahl von Objekten dieses Typs.
Der Filter wird als |
|
Unter-Element "lookup" von Entity
Das <lookup>
-Element innerhalb einer Entity-Definition ermöglicht die Konfiguration der Standardsuche für die Entität, wenn sie in einem Popup-Feld in der Benutzeroberfläche referenziert wird.
Attribut | Beschreibung | Beispiel |
---|---|---|
|
Gibt an, in welchem Attribut der Entität bei der Suche im Popup-Feld standardmäßig gesucht werden soll. Wenn der Benutzer einen Suchbegriff eingibt, werden die Objekte der Entität durchsucht, deren Wert im angegebenen Attribut dem Suchbegriff entspricht. |
|
|
Gibt an, ob die Suche nach einer exakten Übereinstimmung oder einem Teilstring suchen soll.
* |
|
|
Gibt an, ob die Suche die Groß-/Kleinschreibung beachten soll.
* |
|
Beispiel:
<Entity name="Person">
<lookup defaultProperty="Nachname" defaultSubstring="true" defaultCaseSensitive="false"/>
<attr name="Vorname" type="String"/>
<attr name="Nachname" type="String"/>
</Entity>
In diesem Beispiel wird festgelegt, dass bei der Suche nach Personen in einem Popup-Feld standardmäßig im Attribut Nachname
gesucht wird.
Die Suche erfolgt dabei ohne Berücksichtigung der Groß-/Kleinschreibung und akzeptiert auch Teilstrings.
Hinweis: Diese Einstellungen können für einzelne Attribute durch das <lookup>
-Element innerhalb des Attributs überschrieben werden.
Unter-Element "code" von Entity
Das <code/>
-Element innerhalb einer Entity-Definition enthält Attribute, die die Codegenerierung für die Entität beeinflussen.
Attribut | Beschreibung | Beispiel |
---|---|---|
|
Gibt ein abweichendes Package für die Entität an. |
|
|
Gibt den Namen der generierten Basisklasse an. Es muss dann manuell eine Klasse erstellt werden, die von dieser Basisklasse erbt. |
|
|
Gibt an, ob die Basisklasse mit dem Suffix "Base" generiert werden soll. Es muss dann manuell eine Klasse erstellt werden, die von dieser Basisklasse erbt. |
|
|
Gibt an, ob für die Entität Sourcecode generiert werden soll.
Standardwert: |
|
|
Gibt an, welche Klassen von dieser Entität abhängen und bei Änderungen neu generiert werden müssen. |
|
Unter-Element "db" von Entity
Das <db>
-Element innerhalb einer Entity-Definition enthält Attribute, die das Datenbankverhalten der Entität beeinflussen.
Attribut | Beschreibung | Beispiel |
---|---|---|
|
Gibt an, ob die Objekte der Entität in der Datenbank persistiert werden sollen.
Standardwert: |
|
|
Gibt einen optionalen, abweichenden Tabellennamen für die Entität an. Der Name darf maximal 63 Zeichen lang sein und keine Unterstriche enthalten. |
|
|
Gibt an, ob mit Instanzen dieses Typs normalerweise ein BLOB (Binary Large Object) verknüpft sein kann.
Wird verwendet, um zu entscheiden, ob beim Synchronisieren von Objekten ins Dateisystem auch das BLOB exportiert werden soll.
Standardwert: |
|
|
Legt fest, dass keine Sicherheitskopien der BLOBs beim Ersetzen im Dateisystem des Servers angelegt werden sollen.
Standardwert: |
|
|
Gibt an, ob direkte Änderungen an Objekten dieses Typs nur vom Server vorgenommen werden dürfen.
Solche Objekte werden nicht zwischen MyTISM-Nodes synchronisiert.
Standardwert: |
|
Unter-Element "report" von Entity
Das <report>
-Element innerhalb einer Entity-Definition enthält Attribute, die die Generierung von Reports für die Entität beeinflussen.
Attribut | Beschreibung | Beispiel |
---|---|---|
|
Titel für automatisch generierte Reports. |
|
|
Seitenausrichtung für automatisch generierte Reports ("Portrait" oder "Landscape"). |
|
|
Standard-Schriftgröße für automatisch generierte Reports. Standardwert: 9. |
|
|
Große Schriftgröße für automatisch generierte Reports. Standardwert: 16. |
|
Unter-Element "export" von Entity
Das <export>
-Element innerhalb einer Entity-Definition ermöglicht die Konfiguration des Exports von Entitätsdaten.
Diese Funktionalität befindet sich noch in der Entwicklung und soll zukünftig den Struktur-Sync, den Initialdaten-Import und manuelle Exports in Fremdsysteme ersetzen.
Zukünftig soll es auch möglich sein, Objekte über die Zwischenablage zwischen verschiedenen MyTISM-Systemen zu kopieren, sofern die entsprechenden Entitäten in beiden Systemen existieren.
Attribut | Beschreibung | Beispiel |
---|---|---|
|
Name des Exports. (Pflichtangabe) |
|
|
Primärer Schlüssel für den Export. Wird für Referenzen aus anderen Exporten verwendet. (Pflichtangabe) |
|
|
Modus für den Export:
* |
|
Hinweise:
-
Die genaue Funktionsweise und die Verwendung des
<export>
-Elements werden in der zukünftigen Dokumentation detailliert beschrieben. -
Derzeit ist die Funktionalität noch nicht vollständig implementiert.
Beispiel für eine Entity-Definition
<Entity name="Person" extends="CBO" plural="Personen" folder="Kontakte">
<code custom="true"/>
<ui description="Nachname(', 'Vorname)"/>
</Entity>
Diese Definition erstellt eine Entität namens "Person" mit den folgenden Eigenschaften:
-
Sie erbt von der Klasse
CBO
. -
Der Plural ist "Personen".
-
Sie wird im Ordner "Kontakte" im Navigationsbaum angezeigt.
-
Es wird eine benutzerdefinierte Klasse generiert (
custom="true"
). -
Die
describe()
-Methode verwendet als Format "Nachname(', 'Vorname)".
Attribut
Attribute beschreiben die Eigenschaften einer Entität.
Sie werden innerhalb einer Entity-Definition mit den Tags <attr>
, <vattr>
(für virtuelle Attribute) und <npattr>
(für nicht-persistente Attribute) definiert.
Tag für Attribute: <attr BEFEHLE />
Tag für virtuelle Attribute: <vattr BEFEHLE />
Tag für nicht-persistente Attribute: <npattr BEFEHLE />
Attribut | Beschreibung | Beispiel |
---|---|---|
|
Name des Attributs. |
|
|
Definiert den Namen des Attributs auf der "anderen Seite" einer Beziehung. |
|
|
Singularform des Attributnamens (falls abweichend von |
|
|
Datentyp des Attributs. |
|
|
Standard-Anzeigeformat des Attributs. |
|
|
Beziehung des Attributs zu einer anderen Entität ("n-1", "1-n", "n-m"). |
|
|
Gibt an, ob abhängige Objekte beim Löschen des übergeordneten Objekts ebenfalls gelöscht werden.
Standardwert: |
|
|
Ermöglicht die manuelle Sortierung von Objekten in einer 1-n- oder n-m-Beziehung über die UI. |
|
|
Bestimmt, ob die Referenz von der Entität dieses Attributs geteilt wird.
Standardwert: |
|
|
Definiert einen Standardwert für das Attribut. |
|
|
Gibt an, ob Methoden für die Rückwärtsbeziehung generiert werden sollen. |
|
|
Gibt an, ob das Attribut in der UI schreibgeschützt ist.
Standardwert: |
|
|
Gibt für many-relations an, ob die in Beziehung stehenden Objekte erst bei der Verwendung nachgeladen werden sollen.
Standardwert: |
|
|
Gibt an, ob das Attribut beim Kopieren eines Objekts dieses Typs ignoriert werden soll. |
|
Unter-Element "ui" von Attribute
Das <ui>
-Element innerhalb eines Attributs beeinflusst die Darstellung und das Verhalten des Attributs in der Benutzeroberfläche.
Attribut | Beschreibung | Beispiel |
---|---|---|
|
Gibt an, wie das Attribut in der UI bearbeitet werden kann ( |
|
|
Gibt an, ob im Formular der Entität Eingabefelder für die Many-Relation erstellt werden sollen.
Standardwert: |
|
|
Definiert das Attribut als Pflichtfeld.
Derzeit nur teilweise unterstützt (z. B. nicht von Solstice).
Standardwert: |
|
|
Zum Angeben von GUI-Tipps, d.h. durch Leerzeichen getrennte |
|
|
Gibt an, ob das Attribut im Formular angezeigt werden soll.
Standardwert: |
|
|
Definiert die erwartete Breite des Attributs im Formular (in Zeichen). |
|
|
Definiert einen nicht-interaktiven Filter für die Auswahl von Objekten in diesem Attribut.
Der Filter kann als |
|
Unter-Element "lookup" von Attribute
Das <lookup>
-Element innerhalb eines Attributs ermöglicht die Konfiguration der Suche nach zugehörigen Objekten, wenn das Attribut als Popup-Feld in der Benutzeroberfläche dargestellt wird.
Attribut | Beschreibung | Beispiel |
---|---|---|
|
Gibt an, in welchem Attribut der referenzierten Entität bei der Suche im Popup-Feld gesucht werden soll. Wenn der Benutzer einen Suchbegriff eingibt, werden die Objekte der referenzierten Entität durchsucht, deren Wert im angegebenen Attribut dem Suchbegriff entspricht. |
|
|
Gibt an, ob die Suche nach einer exakten Übereinstimmung oder einem Teilstring suchen soll.
* |
|
|
Gibt an, ob die Suche die Groß-/Kleinschreibung beachten soll.
* |
|
Beispiel:
<Entity name="Kunde">
<attr name="Ansprechpartner" type="Person" relation="n-1">
<lookup property="Name" substring="true" caseSensitive="false"/>
</attr>
</Entity>
In diesem Beispiel wird das Attribut Ansprechpartner
der Entität Kunde
als Popup-Feld dargestellt.
Wenn der Benutzer in diesem Feld einen Suchbegriff eingibt, werden alle Personen gesucht, deren Name den Suchbegriff enthält (substring="true"
).
Die Suche erfolgt dabei ohne Berücksichtigung der Groß-/Kleinschreibung (caseSensitive="false"
).
Unter-Element "report" von Attribute
Das <report>
-Element innerhalb eines Attributs ermöglicht die Anpassung der Darstellung des Attributs in automatisch generierten Reports.
Attribut | Beschreibung | Beispiel |
---|---|---|
|
Steuert die Sichtbarkeit des Attributs im Report.
* |
|
|
Legt die relative Breite des Feldes für das Attribut im Report fest. Der Standardwert ist 1. Ein höherer Wert vergrößert die Breite des Feldes. |
|
|
Bestimmt die Position des Attributs im Report. Attribute mit niedrigeren Positionswerten werden zuerst angezeigt. |
|
|
Gibt an, ob die Daten im Report nach diesem Attribut sortiert werden sollen.
* |
|
|
Ermöglicht die Sortierung nach mehreren Attributen.
Die Attributnamen werden als kommaseparierte Liste angegeben, wobei jedem Attributname der Suffix |
|
|
Erstellt im Report eine Gruppe mit dem angegebenen Alias, um die Attribute der zugehörigen Entität aus einer Many-Relation anzuzeigen. |
Beispiele:
<Entity name="Produkt">
<attr name="Name" type="String">
<report relativeWidth="2" position="1" sort="asc"/>
</attr>
<attr name="EAN" type="String">
<report relativeWidth="1" position="2"/>
</attr>
<attr name="Preis" type="Decimal">
<report visible="false"/>
</attr>
</Entity>
In diesem Beispiel wird das Attribut Name
im Report mit doppelter Breite (relativeWidth="2"
) an erster Stelle (position="1"
) angezeigt und die Daten werden alphabetisch nach dem Namen sortiert (sort="asc"
).
Das Attribut EAN
wird an zweiter Stelle (position="2"
) angezeigt.
Das Attribut Preis
wird im Report nicht angezeigt (visible="false"
).
<Entity name="Auftrag">
<attr name="Auftragsnummer" type="String"/>
<attr name="Positionen" type="Auftragsposition" relation="1-n">
<report alias="Position"/>
</attr>
</Entity>
<Entity name="Auftragsposition">
<attr name="Artikelnummer" type="String"/>
<attr name="Menge" type="Integer"/>
</Entity><report alias="Position">
Dieses Beispiel zeigt die Attribute der Entität Auftragsposition in einer Gruppe namens "Position" an.
Unter-Element "virtual" von Attribute
Das <virtual>
-Element innerhalb eines Attributs definiert zusätzliche Eigenschaften für virtuelle Attribute.
Attribut | Beschreibung | Beispiel |
---|---|---|
|
Gibt an, ob der Wert des virtuellen Attributs durch eine Aggregatfunktion berechnet werden soll. |
|
|
Gibt an, ob der Wert des virtuellen Attributs versioniert werden soll. |
|
|
Name einer Methode, die auf den Wert des virtuellen Attributs angewendet wird, bevor er im Cache gespeichert wird. |
|
Aggregatfunktionen:
Aggregatfunktionen ermöglichen die einfache Definition von virtuellen Attributen, die berechnete Werte zurückgeben (z. B. die Summe aller Elemente einer Relation).
Beispiele für Aggregatfunktionen:
-
String.sortJoinCommaList
: Verbindet alle Strings einer Liste zu einem kommaseparierten String. -
BigDecimal.sum
: Summiert alle Zahlen einer Liste. -
BO.union
: Bildet die Vereinigung mehrerer Objektmengen. -
Object.firstNonNull
: Gibt das erste nicht-null
-Element einer Liste zurück.
Unter-Element "np" von Attribute
Das <np>
-Element innerhalb eines Attributs definiert zusätzliche Eigenschaften für nicht-persistente Attribute.
Attribut | Beschreibung | Beispiel |
---|---|---|
|
Gibt an, wo der Wert des nicht-persistenten Attributs berechnet werden soll ("client" oder "server").
Wenn die Berechnung auf dem Server erfolgt, wird der berechnete Wert an den Client übertragen und dort der bestehende Wert ersetzt.
Standardwert: |
|
Unter-Element "db" von Attribute
Das <db>
-Element innerhalb eines Attributs beeinflusst das Datenbankverhalten des Attributs.
Attribut | Beschreibung | Beispiel |
---|---|---|
|
Gibt an, ob die Werte des Attributs für die Datenbank-Volltextsuche indiziert werden sollen.
Standardwert: |
|
|
Gibt an, ob die Eindeutigkeit der Werte des Attributs in der Datenbank erzwungen werden soll.
Standardwert: |
|
Restliche Unter-Elemente von Attribute
Unter-Element | Beschreibung | Beispiel |
---|---|---|
|
Ermöglicht die explizite Definition der Rückwärtsbeziehung, z. B. um einen anderen Namen zu verwenden oder die Beziehung genauer zu konfigurieren. |
|
|
Ermöglicht das Hinzufügen eines Kommentars zum Attribut im Schema. |
|
Beispiel für eine Attribut-Definition
<attr name="Adressen" singular="Adresse" type="Kontakt" relation="1-n"
dependent="true" itemProperty="Position">
</attr>
Diese Definition erstellt ein Attribut namens "Adressen" mit den folgenden Eigenschaften:
-
Der Singular ist "Adresse".
-
Der Datentyp ist "Kontakt".
-
Es handelt sich um eine 1-n-Beziehung.
-
Abhängige Objekte werden beim Löschen des übergeordneten Objekts ebenfalls gelöscht.
-
Die Reihenfolge der Objekte wird über das Attribut "Position" bestimmt und kann in der UI manuell angepasst werden.
Vordefinierte Datentypen für Attribute
MyTISM bietet eine Reihe von vordefinierten Datentypen für Attribute. Hier sind zwei Beispiele:
Timespan
Der Datentyp Timespan
speichert eine feste Zeitspanne als Anzahl von Sekunden.
Aktuell werden intern Sekunden verwendet, dies sollte aber ggfs. aktualisiert werden, da Millisekunden präziser wären und möglicherweise in Zukunft verwendet werden.
Wenn ein Attribut mit type="Timespan"
definiert wird, ist der entsprechende Java-Typ Long
.
Timespan
eignet sich für Anwendungsfälle, in denen die genaue Dauer eines Ereignisses oder Vorgangs gespeichert werden soll.
Duration
Im Gegensatz zu Timespan
speichert Duration
eine variable Zeitspanne als Kombination von Jahren, Monaten, Tagen, Stunden, Minuten und Sekunden (inklusive Millisekunden).
Die genaue Zeitspanne wird in Abhängigkeit von einem Referenzdatum berechnet.
Intern wird der Wert als javax.xml.datatype.Duration
gespeichert.
Beispiel: P1Y0M0DT0H0M0S
entspricht 365 Tagen ab dem 1.1.2015, aber 366 Tagen ab dem 1.1.2012 (Schaltjahr).
Wichtig: Die Behandlung von Duration
im Code ist an einigen Stellen noch nicht optimal und sollte verbessert werden.
Die Verarbeitung von Duration-Werten im Code ist an einigen Stellen noch nicht optimal. Beispielsweise wird in L10nTimespanFormat.nrx und DurationType.nrx die Duration oftmals in eine feste Zeitspanne umgewandelt, wobei das Epoch-Datum (1. Januar 1970) als Referenzdatum verwendet wird, anstatt ein anderes Referenzdatum zu berücksichtigen. Dies kann zu Ungenauigkeiten oder Fehlern bei der Berechnung von Zeitspannen führen. |
Schemapflege / Datenbankupdates
Einige Schemaänderungen können automatisch vom Schemagenerator verarbeitet werden. Für komplexere Änderungen, die nicht automatisch durchgeführt werden können, müssen Datenbank-Update-Skripte verwendet werden.
Liste der durch den UpdateHandler zur Verfügung gestellten Hilfsmethoden
Der UpdateHandler
bietet Hilfsmethoden für die Durchführung von Datenbankupdates.
Hier sind zwei Beispiele:
Name | Parameter | Beschreibung | Beispielaufruf |
---|---|---|---|
|
Tabellenname |
Prüft, ob die angegebene Tabelle in der Datenbank existiert. |
|
|
|
Prüft, ob die angegebene Spalte in der angegebenen Tabelle existiert. |
|
Coredata-Generator
Der Coredata-Generator (de/ipcon/schema/generators/CoreData.nrx
) füllt die Datenbank mit initialen Daten und Objekten:
-
Füllt die BOT-Liste für alle Entitäten.
-
Legt den Admin-Benutzer und die Admins-Gruppe an.
-
Legt Sammelordner für automatisch generierte Objekte an (werden normalerweise wieder gelöscht, da alle Entitäten explizit einen anderen Ordner angeben sollten).
-
Legt Standard-Druckziele an.
-
Erzeugt Standardformulare, -schablonen und -lesezeichen für jede Entität (außer Schablonen für abstrakte Entitäten und Lesezeichen für nicht-persistente Entitäten).
-
Erzeugt Standard-Reports (Einzel und Liste) für jede Entität.
-
Lädt und erzeugt zusätzliche, vorgebaute Strukturelemente.
-
Löscht obsolete automatisch generierte Strukturelemente und leere Ordner.
Zusätzliche, vorgebaute Strukturelemente
Zusätzlich zu den automatisch generierten Strukturelementen können vorgebaute Formulare, Schablonen und Lesezeichen in die Datenbank eingespielt werden.
Diese müssen im Verzeichnis de/ipcon/db/core/resources
abgelegt werden.
Das Format entspricht dem der exportierten Dateien aus der Formularsynchronisation.
Beim Bauen von MyTISM-Kernel.jar
werden die Dateien im Verzeichnis de/ipcon/db/core/resources
gesammelt und in einer Liste ("ResourceIndex") im JAR gespeichert.
Der Coredata-Generator liest diese Liste und erstellt die entsprechenden Objekte in der Datenbank.
Unterstützte Angaben für vorgebaute Strukturelemente
Vorgebaute Strukturelemente (Formulare, Schablonen und Lesezeichen) werden durch XML-Dateien definiert. Folgende Elemente und Attribute werden unterstützt:
Root-Element:
-
Name: Gibt den Typ des Strukturelements an (
Formular
,Schablone
oderLesezeichen
).
Attribute des Root-Elements:
-
Name: Name des Strukturelements.
-
Frei wählbar, aber es wird die Konvention "<Entityname> (Vorgebaut)" oder "<Entityname> (Vorgebaut; <Kommentar>)" empfohlen.
-
-
ElterPfad: Pfad des Ordners, in dem das Strukturelement abgelegt werden soll (z. B.
/Ordner1/Ordner2
).-
Ordner werden bei Bedarf automatisch erstellt.
-
-
Prioritaet: Priorität des Strukturelements (höhere Werte bedeuten höhere Priorität).
-
Sollte im Allgemeinen nicht verwendet werden, da automatisch ein Standardwert (-50) vergeben wird.
-
-
Tid: "Klartext-Identifier" des Strukturelements.
-
Sollte im Allgemeinen nicht verwendet werden, da automatisch ein konsistenter Wert vergeben wird.
-
Kind-Elemente des Root-Elements:
-
Beschreibung: Textuelle Beschreibung des Strukturelements.
-
BOTyp: Gibt an, für welche Entität das Strukturelement verwendet werden soll (Attribut
Name
). -
Parameter: Enthält die detaillierte Definition des Strukturelements, insbesondere für Formulare.
-
Formular: (Nur für Schablonen) Gibt das Formular an, das zum Bearbeiten neuer Objekte verwendet werden soll (Attribut
Name
).
Nicht unterstützte Elemente/Attribute:
-
Gruppen, Polymorphic: Diese Elemente/Attribute werden derzeit nicht unterstützt. Alle Strukturelemente werden automatisch der Admins-Gruppe zugewiesen.
Beispiel für ein vorgebautes Formular:
<Formular Name="$R{_Benutzer} (Vorgebaut)" ElterPfad="/Admins/MyTISM/Benutzerverwaltung">
<Beschreibung>Vorgebautes, aufgeraeumteres Benutzer-Formular, mit Gruppierungen der Alarm-
und Benachrichtigungsinfos und einfacherer, halbautomatischer
Benachrichtigungskonfiguration.</Beschreibung>
<Parameter>
<TabbedView tabPlacement="TOP">
<!-- ... Inhalt ... -->
</TabbedView>
</Parameter>
<BOTyp Name="Benutzer"/>
<Gruppen>
<Gruppe Name="RG_Solstice_Login"/>
</Gruppen>
</Formular>
Wichtig: Wenn ein vorgebautes Strukturelement geändert oder hinzugefügt wurde, muss die Datei .checked-initialdata
vor dem Start des Servers gelöscht werden, damit die Änderungen wirksam werden.
Dies wird in Zukunft evtl. automatisiert werden.
Der Array Datentyp
Arrays sind ein weiterer Datentyp, der vom Schema unterstützt wird. Mit ihnen können geordnete Listen von skalaren Werten in der Datenbank abgelegt werden. Arrays sind in ihrer Länge, zumindest theoretisch, unbeschränkt und nicht auf eine feste Anzahl Einträge pro Attribut festgelegt. Praktisch muss natürlich abgewogen werden, wie "groß" ein Array werden darf, da praktische Limits sowohl im Speicher als auch auf Datenbankebene existieren.
Jedoch eigenen sich Arrays nicht für Situationen, in denen Datenbankqueries häufig einzelne im Array enthaltene Werte abfragen müssen, denn hierfür gelten teils starke Geschwindigkeitseinbußen. Für diese Fälle sollte eine explizite Posten-Relation bevorzugt werden. Oder, falls die maximale Länge der Arrays konstant und ausreichend klein ist, eine umsetzung der möglichen Werte als einzelne Attribute.
Vordefinierte Arrays von Skalaren
Die folgenden Skalare können in Array Form abgelegt werden. In den meisten Fällen reicht es, eckige Klammern hinter den Typnamen des Skalars hinzuzufügen um einen neuen Typ als dessen Array zu definieren.
Arrays werden im Zuge der Übertragung zwischen Server und Client zu String normalisiert und serialisiert. Dabei wird üblicherweise eine json kompatible Darstellung verwendet. Die Spalte Protokollserialisierung gibt das Format der einzelnen Werte in der Json-Liste an. Fehlt bei einem Index der Wert, sofern erlaubt, wird dieser immer als null (ohne Anführungszeichen) gerendert.
Skalar | Typname des Arrays | SQL interner Datentyp | interne Serialisierung |
---|---|---|---|
Boolean |
Boolean[] |
boolean[] |
boolean, d.h. true, false |
Datetime |
Datetime[] |
timestamptz[] |
String, im ISO 8601 Format |
Decimal |
Decimal[] |
decimal[] |
Dezimalzahl, int./U.S. Notation (Punkt), ohne Anführungszeichen |
Duration |
Duration[] |
interval[] |
String, im XML 1.0 Duration Format |
Email[] |
text[] |
String |
|
Integer |
Integer[] |
int4[] |
Ganzzahl, ohne Anführungszeichen |
Long |
Long[] |
bigint[] |
Ganzzahl, ohne Anführungszeichen |
String |
String[] |
text[] |
String |
Timespan |
Timespan[] |
bigint[] |
Ganzzahl, in Sekunden |
Bei Datentyp String[] sollte die Anwendungslogik darauf achten, dass die Textmenge pro Index nicht Überhand nimmt. Für große bzw. viel Text sind alternative Speichermöglichkeiten, z.B. als BLOB, möglicherweise die bessere Wahl. |
Verwendung als Attributtyp
Arrays lassen sich im Schema wie normale Skalare verwenden.
<attr name="Longs" type="Long[]"/> <attr name="Integers" type="Long[]"/> <attr name="Kommazahlen" type="Decimal[]"/>
Attributnamen von Arrays sollten im Plural sein, da es sich um eine Menge handelt. |
Derzeit darf kein Singular bei der Attributedefinition angegeben werden, da sonst der Singular den Namen der Tabellenspalte in der DB bestimmt. Das kann bei OQL Queries zu Verwirrung und Datenverlust führen, falls sich das Verhalten hier ändern sollte. |
Definition von neuen Arraytypen
Es gibt folgende Möglichkeiten einen neuen Array-Type zu definieren:
-
Man leitet von einem existierendem Array ab. In diesem Fall erbt man alle vorhandenen Parameter, sowohl auf der Array- als auch der Komponenten Ebene. Parameter des abgeleiteten Arrays werden übernommen und können überschrieben werden. Nachteil ist, dass man die einzelnen Komponenten nicht weiter einschränken kann.
-
Man erstellt einen neuen Array, der sich auf eine existierende Komponente stützt. In diesem Fall kann man Einschränkungen auf Komponenten Ebene beliebig bestimmen. Nachteil kann sein, dass man Einschränkungen auf Array Ebene explizit definieren muss.
Beispiele hierzu werden in der Sektion Vererbung genannt.
Limitiere die Komponenten
Einschränkungen auf den Wert einzelner Komponenten werden über die Typdefinition der Komponente bestimmt.
Parameter
Die folgenden Parameter stehen Arraytypen zur Verfügung.
- allowNullElements
-
Erlaubte Werte: true/false
Default: false
Wenn true, dann ist null ein gültiger Einzelwert innerhalb des Arrays. Wenn false, dann darf der Array auf keinem Index ein null enthalten. - useComponentsGUIText
-
Erlaubte Werte: true/false
Default: variabel
Wenn true, dann wird die Textdarstellung in der GUI der Einzelwerte von der definierten Komponente übernommen. Um korrektes Escaping des Inhaltes zu gewährleisten wird wird der Array in diesem Fall wie ein String[] dargestellt, unabhängig vom echten Datentyp. Wenn false, dann entspricht die Textdarstellung des Arrays dem json Standart. Sofern nichts angegeben ist, wird für Ganzzahlen false genommen, für Strings oder internationalisierbare Komponenten true. - minElements
-
Erlaubte Werte: Integer >= 0
Default: ohne Wert
Legt eine untere Schranke (inklusive) für die Anzahl an Einzelwerten des Arrays fest. Ohne Angabe: Unbeschränkt, d.h. effektiv 0. - maxElements
-
Erlaubte Werte: Integer > 0
Default: ohne Wert
Legt eine obere Schranke (inklusive) für die Anzahl an Einzelwerten des Arrays fest. Muss größer oder gleich minElements sein, sofern beide Werte angegeben sind. Ohne Angabe: Unbeschränkt.
Vererbung
Arrays müssen entweder einen anderen Array erweitern oder einen neuen Array definieren. Ein neuer Array kann definiert werden, indem dem Namen des Typs einer einzelnen Komponente ein [] nachgestellt wird.
<Type name="NumericStringArrayKomponententyp" extends="String"> (1) <parms mustMatch="[+-]?[0-9]+"/> (2) </Type> <Type name="NumericStringArray" extends="NumericStringArrayKomponententyp[]"> (3) <parms allowNullElements="false"/> (4) </Type> <Type name="NullableNumericStringArray" extends="NumericStringArray"> (5) <parms allowNullElements="true"/> (6) </Type>
1 | Definiert einen neuen String-Typ, der sich von String ableitet. |
2 | Einschränkungen, die für jeden einzelnen Wert dieses Typs gelten. |
3 | Typname der Komponente + [] definiert einen Array dieses Typs. |
4 | Einschränkungen auf Länge und Inhalte des Arrays, hier: verbiete null als Wert im Array. |
5 | Erweitert einen existieren Array typ. Der Komponententyp wird übernommen und ist NumericStringArrayKomponententyp |
6 | Erlaube null als Array Werte. |
Tabellenansicht in der GUI
Verwendet der aktuelle BOLoader ein InstrumentingSchema, kann der Inhalt eines Arrays auch als Relation dargestellt werden. Dies ist in erster Linie für Darstellung in der GUI und (readonly) Zugriff in Reports gedacht. Intern sollten Arrays immer direkt verwendet werden.
Das "AsRelation" Postfix von Array Attributen
Das InstrumentingSchema erzeugt die nötige Infrastruktur automatisch, wenn das erste Mal auf ein Attribut mit Postix AsRelation zugegriffen wird, dieses Attribut derzeit noch nicht existiert und der Name ohne das Postfix ein Array Attribut ist.
Daraufhin wird intern ein Objekt vom Typ ArrayZeilenWrapper gebaut, welches jede Komponente des Arrays über ArrayZeilenDelegate erzeugt und den Zugriff als 1-n Manyrelation erlaubt. Der Wert der Komponente ist typsicher über das Attribut Value verfügbar. Um Namenskonflikte bei virtuellen Properties zu vermeiden, wird eine virtuelle Sub-Entität von ArrayZeilenDelegate als Namensraum erzeugt.
<attr name="Werte" type="Decimal[]"/>
<Table property="WerteAsRelation" columns="Position, ASC | Value | Attributname | Id | Index">
<DetailView>
<Border etched="true" title="$R{Details}">
<View>
<Text property="Attributname"/>
<Text property="Value"/>
</View>
</Border>
</DetailView>
</Table>
Mit den Beispielwerten [9.9,7.8,5.5]
(en_us) bzw. ["9,9","7,8","5,5"]
(de_de) sieht das Formular dann folgendermaßen aus:
Position wird automatisch als itemProperty der Relation gesetzt, wodurch es möglich wird zwei Komponenten zu vertauschen, neue einzufügen oder existierende zu löschen. Sofern das Array Attribut nicht Readonly ist, kann der Benutzer über das Value Attribut den Wert auch verändern.
Die virtuelle Entität als virtueller Namensraum
Der von den ArrayAsRelation aufgespannte virtuelle Namensraum ist nichts anderes als eine virtuelle Entität. Diese virtuelle Entität existiert nur innerhalb des aktuellen InstrumentingSchemas. Die von Arrays verwendete v-Entität leitet sich immer von ArrayZeilenDelegate ab, sie ist folglich nicht persistent.
Die virtuellen Entitäen erlauben eine einfachere Formulardefinition. So ist der Einzelwert des Arrays immer mit dem (virtuellen) Attribut Value definiert. Dieses Attribut enthält sogar die Typinformationen des Arrays, dadurch wird der Wert korrekt gerendert und die GUI kann das Format bei der Eingabe prüfen. Kurz: Dadurch verhält sich die GUI bei den einzelnen Komponenten genau wie bei Skalaren dieses Typs.
Der Name der virtuellen Entität besteht aus drei Elementen, welche durch Unterstriche _
voneinander getrennt sind.
-
ArrayComponent ist ein konstanter Prefixtext. Er wurde als 'Future proofing' hinzugefügt und grenzt den erzeugten Namen von anderen bestmöglich ab.
-
Entitätsname der Name der Entität, auf dem das Array Attribut definiert ist.
-
Attributname der Name des Array Attributs.
Die Kombination Entity + Attribut muss innerhalb des Schemas immer eindeutig sein und bietet deswegen eine gute Basis für eindeutige, generierte Namen. Ist das Array Attribut Werte auf einer Entität Messwert deklariert, so heißt die virtuelle Entität ArrayComponent_Messwert_Werte. Das gilt auch, falls das anzuzeigende BO eine Subklasse von Messwert sein sollte.
Werden mehrere Arrays verglichen, so folgt dem o.g. Namensschema noch ein numerischer Hashcode. Dieser berechnet sich aus den Entitäten und Array Attributen bei Initialisierung des Wrappers. Dieser Postfix sollte als instabil angesehen und ist nicht für die Verwendung mit virtualProperties im Formular vorgesehen, sofern diese nicht dynamisch erzeugt werden.
Um in diesem Fall virtualProperties mitgeben zu können, muss dem ArrayZeilenWrapper bei der Initialisierung ein expliziter Name für die Entität mitgegeben werden.
Siehe der Parameter mit Wert AUniqueEntityName
in diesem Beispiel.
Zeilen um virtuelle Properties anreichern
Das Vorgehen um weitere Tabellenspalten zu generieren ist (fast) wie im normalen Fall.
Namen ist hier ein einfaches Attribut vom Typ String[]
, welches auf einer Entität Schauspieler definiert ist und eine Liste von Charakternamen enthält.
Die virtuelle property Greeter greift auf den einzelnen Namen sowie die Position in der Liste zu und erzeugt einen einfachen Text. Da der Text etwas länger ist, wurde die expectedWidth erhöht - alternativ lässt sich das natürlich auch über die Spaltendefinition machen.
Der erzeugte Namensraum für die Entität (singular) Schauspieler und das Attribut Namen ist ArrayComponent_Schauspieler_Namen.
<Table property="NamenAsRelation" columns="Position, ASC | Value | Greeter">
<virtualProperty name="Greeter" entity="ArrayComponent_Schauspieler_Namen">
<ui expectedWidth="30"/>
<get><![CDATA[ return "Hallo $bo.value, du bist ${bo.position > 3 ? 'leider nicht ' : ''}in den Top 3" ]]></get>
</virtualProperty>
<DetailView>
<Border etched="true" title="$R{Details}">
<View>
<Text property="Value"/>
<Text property="Greeter"/>
</View>
</Border>
</DetailView>
</Table>
Der Namensraum wird lazy erzeugt, wenn im Formular das erste mal auf das AsRelation Attribut zugegriffen wird. Deswegen muss die virtualProperty derzeit innerhalb des Table-Elements definiert werden. Ausserhalb kommt es zu folgender Fehlermeldung: |
Selbstdefinierte Tabellenansicht in der GUI
Es ist möglich beliebig viele Arrays miteinander zu vergleichen, diese müssen nichteinmal von der gleichen Instanz kommen.
Gegeben sei folgende, einfache Entität.
<Entity name="Beispiel" extends="CoreBO"....>
<attr name="Other" type="Beispiel" relation="n-1"/>
<attr name="Longs" type="Long[]"/>
<attr name="Strings" type="String[]"/>
</Entity>
Um die einzelnen Werte von Longs und Strings des aktuellen BOs mit dem von Other zu vergleichen, ist folgende Infrastruktur nötig:
<virtualProperty name="CombinedArrayWrapper" entity="Beispiel" type="ArrayZeilenWrapper" relation="n-1" cached="SIMPLE">
<get><![CDATA[
import de.ipcon.db.core.ArrayZeilenWrapper
return ArrayZeilenWrapper.of([bo, bo, bo.other, bo.other] as BO[],
['Longs', 'Strings', 'Longs', 'Strings'] as String[],
['MyLong', 'MyString', 'OtherLong', 'OtherString'] as String[],
'AUnqiueRelationName',
'AUniqueEntityName')
]]></get>
</virtualProperty>
<!-- switch the bo to the wrapper -->
<Element property="CombinedArrayWrapper">
<visibleIf language="groovy"><![CDATA[ true //FIXME currently needed ]]></visibleIf>
<!-- show the arrays as relation -->
<Table property="AUnqiueRelationName"
columns="Position, ASC | MyLong | OtherLong | MyString | OtherString">
<!-- optional, define additional properties -->
<virtualProperty name="Identisch" entity="AUniqueEntityName" type="Boolean">
<get><![CDATA[ return bo.MyLong == bo.OtherLong && bo.MyString == bo.OtherString ]]></get>
</virtualProperty>
<DetailView>
<Border etched="true" title="$R{Details}">
<View>
<Text property="MyLong"/>
<Text property="OtherLong"/>
<Text property="MyString"/>
<Text property="OtherString"/>
<Checkbox property="Identisch"/>
</View>
</Border>
</DetailView>
</Table>
</Element>
-
cached="SIMPLE" ist wichtig, da der ArrayZeilenWrapper bei einer Änderung am bo nicht neu erzeugt werden darf.
-
Ein ArrayZeilenWrapper registriert sich als Listener an den Quell-Arrays und reagiert auf Änderungen an den Daten.
-
Mehrere Wrapper die von der Definition identisch sind, könnten sich ohne die cached Anweisung gegenseitig in die Quere kommen.
-
-
ArrayZeilenWrapper#of hat einige Parameter, welche, über den gleichen Index als Tuple zusammengefasst, die Datengrundlage definieren.
-
BO[] bos : Die BO Instanzen mit den konkreten Daten.
-
String[] attribute: Der Name des Array Attributs, aufgelöst auf dem entsprechenden BO Parameter, welches als Datengrundlage gilt.
-
String[] aliase: Entweder komplett null für autom. generierte Attribute ODER eine Liste mit eindeutigen Bezeichnern, die eine Komponente des BO x Attribut - Tupels repräsentieren.
-
Im folgenden bedeutet 'alias': Der Name des autom. generierten virtualProperties, welches auf einer virtualEntity von ArrayZeilenDelegate definiert ist.
-
-
AUnqiueRelationName darf noch nicht als Attribut auf der Entität ArrayZeilenWrapper existieren.
-
Es ermöglicht den Wechsel in den erzeugten Namensraum.
-
Dies ist das Gegenstück zum autom. generierten "…AsRelation" Attributnamen des einfachen Falls.
-
Übliches Fehlerbild, wenn der Name nicht eindeutig ist: Die Columns können im Formular nicht aufgelöst werden, zudem haben die Properties u.U. die falsche Formatierung.
-
-
AUniqueEntityName bestimmt den Namen der virtuellen Entität, die sich von ArrayZeilenDelegate ableiten muss.
-
Wird automatisch angelegt, sofern sie noch nicht existiert.
-
Kann weggelassen werden, solange der Namensraum nicht erratbar sein muss - i.e. keine virtualProperties hinzugefügt werden müssen.
-
-
-
visibleIf und Element-Wrapper sind derzeit nötig.
-
Todo: Zumindest für das 'visibleIf' die Ursache prüfen und vereinfachen.
-
-
Die Kombination bo-Instanz zu Attribut muss eindeutig sein, d.h. wird es zu einem Fehler kommen, falls
bo.other == bo
ist. -
Die verwendeten Aliase dürfen noch nicht als Attribute auf ArrayZeilenDelegate oder einer super-Entität existieren.
-
Ein Alias 'Id' ist z.B. nicht erlaubt, weil das Attribut 'Id' auf der Entität BO definiert ist.
-
Als Referenz-Entität gilt ArrayZeilenDelegate, d.h. es sind nur Aliase erlaubt, die auf ArrayZeilenDelegate noch nicht existieren.
-
Gleiche Aliase in unterschiedlichen virtualEntities von ArrayZeilenDelegate sind jedoch explizit erlaubt. Der Alias 'Value' ist solches ein Beispiel.
-
-
Die zusammengefassten Arrays müssen alle die gleiche Länge haben. Ansonsten kommt es zu einer Exception und/oder die Tabelle wird leer dargestellt.
-
Falls Arrays mit unterschiedlichen Dimensionen angezeigt werden sollen, kann dies über ein/mehrere addVirtualProperty gemacht werden, die jeweils einen Array zurückgegeben. Das virtualProperty muss sich darum kümmern, den Rückgabewert mit passenden Dummy-Werten auf die richtige Länge zu padden. Ist etwas umständlich, aber machbar.
Ansicht in Automatikformularen als String
In Automatikformularen werden Arrays in einfachen Textfeldern mit ihrer an json angelehnten Textdarstellung angezeigt. Diese Darstellung kann die Locale beachten, d.h. der angezeigte String kann sich vom newValue der BPs unterscheiden.
-
FIXME ein paar konkrete Beispiele.
ArrayZeilenDelegate / Wrapper
-
Erklärung Attribute auf ArrayZeilenDelegate
-
Index nur für interne verwendung, maximal readonly zugriff von außerhalb erlaubt. Falsche Verwendung kann die Arraydaten zerstören.
-
Verwendung in OQL Queries
siehe OQL Dokumentation
Umgang mit Arrays im Code
Der Umgang mit Arrays im Code wurde bestmöglichst an das Verhalten der normalen Attribute angelehnt. Im Gegensatz zu den normalen Skalaren sind Arrays jedoch von rund am "mutable", was in der Implementierung von beschreibbaren v-attrs beachtet werden muss.
Persistente Array Attribute
Verfügbare Methoden
Beispiel: Ein Attribut "Werte" ist im Schema als "Integer[]" definiert. Dann werden die folgenden Methoden automatisch generiert:
-
getWerte():Integer[]
gibt eine Kopie des gespeicherten Arrays zurück. Das zurückgegebene Array darf modifiziert werden, es hat keinen Einfluss auf die Werte des BOs. Kann null oder leer sein. -
getWerte(fallback:Integer[]):Integer[]
gibt eine Kopie des gespeicherten Arrays zurück bzw.fallback
, falls das Attribut null ist. Ist das Attribut das leere Array, dann wird dieses leere Array zurückgegeben. -
getWerteNN():Integer[]
wie oben, mit einem leeren Array als fallback. -
getWerte(index:int):Integer
gibt die Komponente des Arrays mit diesem 0 basierten Index zurück. Hierdurch können auf einzelne Werte zugegriffen werden, ohne das eine Kopie des Arrays erstellt wird. Es findet keine Indexprüfung statt und der Array wird direkt zugegriffen, d.h. NullPointer- oder IndexOutOfBounds-Exceptions sind möglich. -
getWerteLength():int
gibt die aktuelle Länge des Arrays zurück. Ist das Attribut null, wird 0 zurückgegeben. -
setWerte(neuerWert = Integer[]):void
setzt das Attribut auf einen neuen Wert und zeichnet die Änderungen auf, sofern das BO included wurde. Die übergebene Instanz wird intern als Kopie gespeichert, wodurch spätere/implizite Änderungen an der Parmameter Instanz ignoriert werden. -
setWerte(index:int, v:Integer)
aktualisiert eine einzelne Komponente des Arrays am gegebenen Index auf einen neuen Wert. Es findet keine Indexprüfung statt, d.h. NullPointer- oder IndexOutOfBounds-Exceptions sind möglich. Erstellt im Hintergrund eine Kopie des Arrays.
Hinweise
-
Code sollte so strukturiert werden, dass ein Array zuerst vollständig gebaut und befüllt wird, bevor dessen es einem Attribut zugewiesen wird. Da Arrays bei den Attributzugriffen kopiert werden müssen, erhöht das die Performance und verhindert je nach Kontext, z.B. während verifyOnServer, dass Zwischenergebnisse aufgezeichnet werden.
-
Soll nur über ein Array iteriert werden, dann kann ist ein indexbasierter loop effizienter als ein 'loop over':
loop i=0 to bo.getWerteLength() val = bo.getWerte(i) ... end
-
Die generierten Methoden verwenden Arrays statt immutable Listen, da zum Zeitpunkt der implementation keine Generics in Netrexx verfügbar waren. D.h. konnten dadurch mehrere explizite Casts vermieden werden.
Hinweise bei v-attrs:
-
Vorsicht, wenn der Rückgabewert des getters intern gecached wird. Arrays sind von natur aus mutable und sollten nicht direkt rausgegeben werden, falls Caching im Spiel ist.
Persistenzschicht von MyTISM
MyTISM verwendet ein mehrschichtiges Persistenzkonzept, um Daten sicher und effizient zu speichern. Ein zentrales Element ist dabei die Unterscheidung zwischen "Soft Delete" und "Hard Delete" (Purge), die im Folgenden detailliert erläutert wird.
Löschen von Daten in MyTISM
Soft Delete
Standardmäßig werden Objekte in MyTISM nicht physisch aus der Datenbank gelöscht, sondern lediglich als "gelöscht" markiert.
Dies geschieht durch das Setzen eines Flags namens "Ldel" auf den Wert TRUE
.
Dieser Mechanismus wird als "Soft Delete" bezeichnet.
Diese Objekte werden in den meisten Abfragen und Ansichten dann nicht mehr angezeigt. Admins könnten diese Objekte einblenden. Sie werden dann normalerweise durchgestrichen dargestellt.
Vorteile:
-
Datenwiederherstellung: Versehentlich gelöschte Objekte können von Admins leicht wiederhergestellt werden.
-
Datenhistorie: Gelöschte Objekte sind weiterhin mit ihrer kompletten Änderungshistorie inkl. des Löschvorgangs in der Datenbank verfügbar, was für Audits oder Analysen nützlich sein kann.
Nachteile:
-
Speicherplatz: "Soft deleted" Objekte belegen weiterhin Speicherplatz in der Datenbank.
-
Performance: Bei einer großen Anzahl von "soft deleted" Objekten könnte die Performance der Datenbankabfragen beeinträchtigt werden, da die Tabellen größer sind, als sie sein müssten.
-
Fehlerquelle: Bei selbst erstellen programmatischen Abfragen in der Datenbank oder beim Traversieren von Objekten in Relationen muss man daran denken, gelöschte Objekte explizit auszunehmen oder zu überspringen, wenn das gewünscht ist.
-
Datenschutz: Reicht für personenbezogene Daten nicht zur Einhaltung von Datenschutzbestimmungen wie der DSGVO aus.
Wiederherstellung von "Soft Deleted" Objekten
"Soft deleted" Objekte können über die MyTISM-GUI (sofern die Undelete-Action für den Benutzer verfügbar ist und die gelöschten Objekte sichtbar sind) oder programmgesteuert über die Methoden BO#undelete()
bzw. BO#markUndelete()
wiederhergestellt werden.
Hard Delete (Purge)
Im Gegensatz zum Soft Delete ermöglicht ein Hard Delete das endgültige Löschen von Objekten aus der Datenbank. In MyTISM wird dieser Vorgang als "Purge" bezeichnet und ist nur dem Backend und speziellen Backend-Diensten vorbehalten.
Anwendungsfälle:
-
DSGVO-Konformität: Zum Löschen von Daten, die gemäß der Datenschutzgrundverordnung (DSGVO) gelöscht werden müssen.
-
Datenbereinigung: Zum Entfernen von alten, irrelevanten Daten, um Speicherplatz freizugeben.
Purging ist unwiderruflich! Gelöschte Daten können nicht wiederhergestellt werden! |
Unterschiede zwischen Soft und Hard Delete im Überblick
Feature | Soft Delete | Hard Delete (Purge) |
---|---|---|
Löschvorgang |
Objekt wird als "gelöscht" markiert (Ldel = TRUE) |
Objekt wird physisch aus der Datenbank entfernt |
Wiederherstellung |
Möglich |
Nicht möglich |
Zugriff |
Standardmethode für Benutzer |
Nur für Backend und spezielle Dienste |
Anwendungsfälle |
Standardlöschvorgänge |
DSGVO-Konformität, Datenbereinigung |
Zusammenfassung
MyTISM bietet mit Soft Delete und Hard Delete (Purge) zwei Mechanismen zum Löschen von Daten. "Soft Delete" ist die Standardmethode und ermöglicht die Wiederherstellung von Daten. "Hard Delete" dient dem endgültigen Löschen von Daten und ist nur für spezielle Anwendungsfälle vorgesehen.
Sprachunterstützung und Internationalisierung
Einführung
MyTISM bietet eine durchgehende Unterstützung für verschiedene Locales, sowohl für die Übersetzung von Texten und Namen als auch für Ein- und Ausgabe von Zahlen, Daten, etc.
Wo wird Mehrsprachigkeit unterstützt und wie benutze ich sie?
Neben der direkten Benutzung in Programmcode mittels der Methoden L10n.msg() bzw. L10n.applyL10n() gibt es weitere Stellen an denen die Mehrsprachigkeit unterstützt wird.
Im GUI-Client Solstice, an vom Benutzer bearbeitbaren Stellen:
-
In den Benutzer-Login-Scripten. Beispiel:
---- <Configuration> [...] <Locale>de</Locale> </Configuration> ----
-
In den XML-Definitionen für Plugins in den Benutzer-Voreinstellungen.
-
In den XML-Definitionen für Defaults in Benutzer-Voreinstellungen.
-
In Report-Definitionen und in den Parametern von Formularen, Schablonen und Lesezeichen.
Im GUI-Client Solstice, interne Funktionalität:
-
Ausgabe von Name und ElterPfad von Benannts im Navigationsbaum bzw. in PolymorphicTemplateSelectionTreeModel.
In diesen "Texten" können Platzhalter $R{key}
eingefügt werden. Diese
werden dann automatisch vor der "Benutzung" durch zum aktuellen Locale
passende Texte ersetzt.
Wie wird die konkrete Zeichenkette für einen Schlüssel gefunden?
L10nPackProviderI (z.Zt. de/ipcon/tools/L10n und de/ipcon/db/AbstractClient) halten benannte L10nPacks bereit, welche die diversen Textbausteine in unterschiedlichen Sprachen enthalten, gruppiert mittels entsprechender Schlüssel für jeden Textbaustein.
Beim Auflösen von $R{key}
-Platzhaltern z.B. im Formularcode (und
ebenso beim direkten Aufruf der L10n.msg()-Methoden) wird eine - je nach
Aufrufart bzw. -ort unterschiedliche, und bei den im vorherigen
Abschnitt aufgeführten Stellen, automatisch zusammengestellte - Liste
der an dieser Stelle beteiligten bzw. relevanten Objekte übergeben (Z.B.
für Formulare das Formular-Objekt selbst).
Mittels dieser übergebenen Objekte wird nun eine Liste von relevanten L10nPacks erstellt, in denen mittels des Schlüssels "key" nach den angeforderten Textbausteinen gesucht wird. Wird ein zum Schlüssel passender Textbaustein gefunden, wird seine zur gewünschten Sprache passende Version zurückgeliefert.
Schlüsselnamen dürfen nur Buchstaben, Zahlen, '_', '-', '.', '~' und '/' enthalten. |
Welche L10nPacks gibt es und wie sind diese organisiert? Wie wird bestimmt, welche L10nPacks nach Texten durchsucht werden?
Die Benamsung bzw. Hierarchie der L10nPacks folgt in der Regel der Klassen- bzw. Paketstruktur der Java-Klassen. In den meisten Fällen bestimmen die Java-Klassen der beteiligten Objekte und die Java-Pakete denen diese angehören die zu durchsuchenden L10nPacks.
L10nPack-Namen dürfen nur Buchstaben, Zahlen, '_', '-' und '.' enthalten, wobei '.' das Trennzeichen zum Aufsplitten der Namen ist. |
Beispiel: Ein Objekt der Klasse "de.ipcon.form.FText" will den Textbaustein mit Schlüssel "eineNachricht" in der aktuellen Sprache ausgeben. In diesem Fall werden - sofern vorhanden - die L10nPacks "de.ipcon.form.FText", "de.ipcon.form.FPanel" (FText leitet sich von FPanel ab), "de.ipcon.form", "de.ipcon" und "de" in dieser Reihenfolge nach einer zum Schlüssel passenden Version des Textes durchsucht.
Web
Abweichend hiervon ist in Grails und Cauldron aktuell historisch bedingt noch eine andere Namensgebung üblich und es gibt kein eigentliches Mapping mit Automatismen für Klassen oder Entitäten.
In Grails gibt es oft nur ein einzelnes Bundle Grails
, das aber auch aufgeteilt werden kann.
Die Namensgebung lautet dann bspw. Grails.checkout
oder Grails.user.settings
.
In Cauldron besteht hier prinzipiell freie Namenswahl, neue Projekte sollten sich aber ebenfalls an das Paketnamensschema halten.
Welches sind die "beteiligten bzw. relevanten Objekte"?
Dies ist unterschiedlich und hängt davon ab, wo und wie die L10n-Funktionalität genutzt wird, z.B.:
-
Beim direkten Aufruf von L10n.msg() wird normalerweise automatisch die aufrufende Klasse ermittelt und als das (einzige) beteiligte Objekt übergeben.
-
Bei Benutzung von
$R{key}
-Platzhaltern im Parameter von Formularen, etc. wird die Klasse des im Formular, der Schablone oder im Lesezeichen dargestellten BOs sowie die Klasse des Strukturelements (Formular.class, etc.) selbst übergeben.
Im Normalfall wird die Liste der L10nPacks für eine Klasse einfach nach der im vorherigen Abschnitt beschriebenen Methode (Klassen + Pakete) erstellt. Ist für eine Klasse aber ein sog. L10nPathCompilerI beim L10n registriert, so bestimmt dieser, welche L10nPacks für die entsprechende Klasse in die Liste aufgenommen werden (siehe z.B. "FormularPathCompiler" in Formular.nrx).
Genauere Informationen finden sich bei den entsprechenden Aufrufen von L10n.applyL10n() bzw. L10n.msg() (bei letzterem nur selten, da dort fast nie ein expliziter "path" übergeben wird und fast immer die oben erwähnte Automatik benutzt wird) im Quellcode von MyTISM. L10n.compilePath() enthält weitere Informationen darüber, wie die Liste der zu durchsuchenden L10nPacks zusammengestellt wird.
Wo kommen die (Daten der) L10nPacks her?
Die Texte/Daten für die L10nPacks werden z.Zt. aus zwei Quellen gezogen. Die L10n-Klasse lädt ihre Daten aus Dateien …/resources/*.properties die in den Quellcode-Verzeichnissen liegen und beim Bauen ebenfalls in die JARs eingebunden werden. Daneben lädt der Server noch die in der Datenbank befindlichen L10nBundles in seinen L10nCache.
Die Texte der *.properties-Dateien werden alle "von Hand" angelegt und bearbeitet. Die L10nBundles, etc. werden teilweise automatisch generiert, können aber auch von Hand angelegt und bearbeitet werden.
Für jede im Schema definierte Entität, Beispiel "de.ipcon.db.core.Benannt", werden einige L10n-Daten automatisch angelegt und "gewartet". Diese sind im Beispiel zuerst das L10nBundle "de.ipcon.db.core" mit den L10nResourcen "_Benannt" sowie "_Benannt-s" (Name/Singular und Plural der Entität), L10nResources für die Ordner, also hier "Interna" (FIXME ggf. weitere) sowie L10nResources für jedes Attribut der Entität also hier "Name", "Beschreibung" usw.
Desweiteren wird für jede Entität noch ein eigenes Bundle, im Beispiel "de.ipcon.db.core.Benannt", angelegt und dort werden ebenfalls noch einmal wie oben für alle Attribute L10nResources angelegt.
Diese L10nBundles, bzw. deren L10nEntries und L10nResources, werden bei jedem Serverstart überprüft, ob Entitäten oder Attribute hinzugekommen sind - diese werden dann automatisch angelegt - bzw. weggefallen sind - dort werden dann für weggefallene Attribute automatisch entsprechende, ehemals gebrauchte L10nEntries und L10nResources entfernt.
In neueren Projekten werden Daten aus
nrx/[…Projektverzeichnis…]/resources/l10n/[…Projekt-Package…].bo_[ISO-Kürzel]
automatisch importiert. In diesen, von Hand angelegten Dateien, dürfen
(bzw. zumindest sollten) sich nur Schlüssel-Text-Paare für im Schema
definierte Entitäten und deren Attribute befinden. Ansonsten werden die
"überzähligen" Texte bei jedem Serverstart erst angelegt, und dann, da
es keine entsprechenden Entitäten bzw. Attribute (mehr) gibt, direkt
wieder gelöscht.
"Freie" Texte (z.B. solche für Titel/Texte in Formularen) sollten -
selbst wenn sie im Prinzip nur für eine Entität benutzt werden - in
einem eigenen Paket
nrx/[…Projektverzeichnis…]/resources/l10n/[…Projekt-Package…]_[ISO-Kürzel]
untergebracht werden.
Genauere Informationen finden sich in L10nBundle.initEnvironment() und den dort benutzten Methoden.
L10n und das Anführungszeichen bzw. Apostroph
Die Verwendung von Anführungszeichen oder Apostrophen in Übersetzungen (in properties
- oder Bundles-Dateien im Verzeichnis resources/l10n/
) kann zu Problemen führen, insbesondere wenn diese in XML-Texten verwendet werden und unbeabsichtigt Abschnitte beenden, die nicht beendet werden sollten.
Dies tritt häufig auf, wenn es um die Definition von Tabellenspalten geht.
Besondere Vorsicht ist geboten, wenn es um Übersetzungen von Entitäts- und Attributnamen geht, da diese oft an solchen Stellen eingesetzt werden.
Um solche Probleme zu vermeiden, empfiehlt es sich, anstelle der „einfachen“ Zeichen '
und "
, die ursprünglich noch aus der Zeit der Schreibmaschinen stammen und lediglich eine vereinfachte Darstellung dieser Zeichen bieten, die schöneren und eigentlich korrekten typographischen Zeichen ’
(erreichbar über AltGR+'
) sowie „
(AltGr+V
) und “
(AltGr+B
) zu verwenden.
Diese Zeichen werden in der Regel nicht als Steuerzeichen zur Abtrennung verwendet und tragen somit zur Vermeidung von unerwünschten Effekten bei.
Wichtige Klassen
- de.ipcon.tools.L10n
-
Die zentrale Klasse. Enthält u.A. die msg()-Methoden die zu einem gegebenen Key die zum gewünschten/aktuellen Locale passende Version der entsprechenden Zeichenkette liefern. Enthält auch diverse Methoden um Format-Objekte zum formatieren von Zahlen, Daten, etc. zu erhalten.
- de.ipcon.db.core.L10nBundle
-
Sammlung von L10nResources.
- de.ipcon.db.core.L10nResource
-
Entspricht grob einer Zeichenkette welche in unterschiedlichen Sprachen ausgegeben werden können soll. Hat einen oder mehrere L10nEntries.
- de.ipcon.db.core.L10nEntry
-
Konkrete Version der Zeichenkette für ein bestimmtes Locale (grob: eine Sprache).
Eingabe von L10n-Daten
FIXME Stichworte
neues Bundle anlegen (de.venice) bzw. in einem bestehenden Bundle (de.venice.bo) was hinzufuegen ⇒ schauen, dass das Bundle auch Preloaded wird und auch die PfadPos setzen (0). Wenn trotzdem ein neuer Eintrag nicht direkt gefunden wird, dann kann es noetig sein den Server durchzustarten. Das kann der Fall sein, wenn das Bundle erstmalig auf Preload und/oder PfadPos gesetzt wird.
Einfaches Hochkomma muss "escaped" werden ⇒ doppelt schreiben
$R-Tags in Formularen, etc.: Suche nach title=", label=", text=".
Die Formularengine des Solstice Clients
de.ipcon.form
Nachfolgende Dokumentation behandelt den Aufbau eines sogenannten Formulars im de.ipcon.form Package des MyTISM Frameworks. Sie soll den Entwickler in die Lage versetzen, Wünsche des Anwenders an die grafische Oberfläche umzusetzen. Im Gegensatz zu Web-Oberflächen sind diese für den Anwender viel effektiver und schneller bedienbar als die etwas generischeren und graphisch meist viel ansprechenderen, aber dennoch umständlich zu bedienenden Web-Oberflächen. Allerdings ist das Abstraktionsniveau im grafischen Client etwas geringer, um schneller zum Ergebnis zu kommen - manchmal ist es besser, den ein oder anderen Wunsch eines Anwenders zugunsten einer saubereren oder aber auch für eingeschränkte Benutzer (sei es technisch (niedrige Farbe, langsamer Rechner) oder auch körperlich (Farbenblindheit, Kurzsichtigkeit)) bedienbaren Lösung abzulehnen.
Hintergrund
Das Formularframework bzw. die Engine, die die Formulare aufbaut, hat zwei Ziele: Flexible Formulare und eine flexible Verwaltung dieser Formulare. Das HTML-Format bzw. dessen Vorgänger SGML bzw. XML haben mit ihrem Markup-Konzept einen entscheidenden Denkanstoß zur Entwicklung der jetzigen Implementation geliefert. Angereichert mit einer Meta-Ebene, die aus dem Datenbank-Backend MyTISM kommt und somit einen schnellen und effizienten Zugriff auf die Formulare gestattet sowie die Synchronisation der Formulare realisiert. Im folgenden werden die Objekte einzeln ausführlich vorgestellt, ihre Eigenschaften und ihre Verwendung dokumentiert. Alle Objekte außer den Lesezeichen haben die Eigenschaft, in bestimmten Kontexten als Auswahl zur Verfügung zu stehen, sei es, um ein neues Objekt zu erzeugen oder ein bestehendes anzuzeigen. Das Verfahren, diese Auswahl zu generieren, wird ebenfalls beschrieben.
Das Formular-Objekt
Das Formular-Objekt hat die Aufgabe, eine Eingabemaske für ein Objekt einer bestimmten BO-Klasse zu beschreiben. Das de.ipcon.form Package enthält die notwendigen Methoden, um eine solche Eingabemaske bestehend aus Oberflächenelementen wie Textfelder, Popuplisten und ähnlichem zu erzeugen und verwalten. Es stellt eigentlich das wichtigste und gleichzeitig das komplizierteste Objekt des Formularframeworks dar.
Eigenschaften
Das Formular-Objekt hat im wesentlichen folgende Eigenschaften:
-
Name: Eine klar abgrenzende Bezeichnung, die auch im Kontextmenu des jeweiligen Objektes erscheint.
-
Beschreibung: Eine etwas ausführlichere Beschreibung, durchaus als Platz für Bemerkungen wie den Verweis auf spezielle Versionen oder Spezifika. Sie wird dem Benutzer nicht in der GUI präsentiert und ist ausschließlich den Entwicklern vorbehalten.
-
Elter: Ein Verweis auf die ID des Strukturelements (meist ein Ordner oder eine Gruppe), unter dessen Repräsentation im Menubaum dieses Element absortiert wird. Wird gesetzt beim Drag’n’Drop im NavigationTree in der GUI.
-
IstAutomatik: Ein Wahrheitswert, der anzeigt, ob das Formular direkt aus dem Formulargenerator stammt. Falls Sie ein Formular abändern, achten Sie bitte darauf, daß dieser Wert false ist, sonst wird beim nächsten Schema-Update das Formular neu erstellt; der NavigationTree setzt es beim 'Move' dieses Flag automatisch auf false, um eine Fehlbedienung zu vermeiden.
-
Parameter: Hier steckt der Source des eigentlichen Formulars. Im folgenden wird der Inhalt dieser Eigenschaft ausführlich beschrieben.
-
BOTyp: Ein Verweis auf den Typ des BO (selbst natürlich ebenfalls ein BO), welches mit diesem Formular angezeigt werden kann. [fixme: Polymorphie?]
-
Gruppen: Ein Mehrfach-Verweis auf die Gruppen, die dieses Formular benutzen sollen.
-
Schablonen: Ein Mehrfach-Verweis auf die Schablonen-Objekte, die direkten Gebrauch von diesem Formular machen.
-
Priorität: ein 32bit signed Integer, der die Priorität des Formulars im Falle einer mehrfachen Auswahl von Formularen für ein Objekt festlegt und damit die Präferenz in diesem Fall festlegt.
Auswahl
Die Auswahl eines Formulars wird aufgrund folgender Regeln getroffen:
-
Zunächst werden alle passenden (gleicher BOTyp [fixme: Polymorphie]) Formulare erfragt, deren Priorität gesetzt ist und einer der eigenen Gruppen zugeordnet ist. Beim Benutzer Admin werden als Ausnahme auch diejenigen Formulare mit einbezogen, die keine Priorität haben (diese Mechanismus wird in einer der nächsten Versionen ausgebaut und ist damit als obsolet deklariert!).
-
Diese passenden Formulare werden der Priorität nach absteigend geordnet und dem Benutzer ggfs. per Kontextmenu zur Verfügung gestellt. Ein Doppelklick oder adäquate Aktion öffnet das nach dieser Sortierung am höchsten priorisierte Element. Die momentane Implementation ersetzt Formulare gleicher Priorität ohne eine deterministische (oder vielmehr eine dokumentierte Deterministik) oder vorhersehbare Präferenz. Daher bitte ich unbedingt auf eine klare Priorisierung zu achten. Der Zahlenraum der Priorität bietet genügend Spielraum: ca. -2 bis 2 Milliarden.
Definition
Fehler und Ursachen
Einige Fehler denen ich bei der MyTISM-Entwicklung schon begegnet sind und deren Ursachen bzw. Lösungsmöglichkeiten:
Compiler-Meldung "Object cannot be null"
BOs brauchen einen Konstruktor (ohne Argumente); es wird nicht automatisch einer gebaut oder der der Superklasse benutzt. BO-Klassen duerfen nicht "abstract" sein
bi-Tabelle kann nicht erstellt werden (nachdem die Datenbank gedropped und recreated wurde)
".checked*"-Dateien im Projektverzeichnis löschen.
Compiler-Meldung "Object bla is null but shouldn’t" (sic)
Beispiel: "Zustellversuch" hängt an "Sendeauftrag". Neuer Zustellversuch wurde angelegt, in Transaction included und an Sendeauftrag angehängt. Dumm nur: Sendeauftrag war nicht in Transaction included! FIXME: Hmm … das war aber wohl doch nicht das Problem :-(
Synchronisation der Strukturelemente
Das Formular "DateiSystemSync"
Das Benutzerhandbuch enthält bereits einen Abschnitt zu diesem Thema; ggf. sollten diese zusammengeführt werden.
FIXME! (werde später noch ein bisschen was dazu schreiben - sw) - anhand was wird rein- bzw. rausgesynct - Konventionen Dateiname - wofuer Tid - …
Volltextsuche
Die Volltextsuche erlaubt die einfache und schnelle Suche nach gegebenen Suchbegriffen über alle in der MyTISM-Datenbank gespeicherten Objekte. Informationen zur allgemeinen Konfiguration und Bedienung finden sich in der MyTISM-Benutzerdokumentation. In diesem Kapitel befinden sich noch einige nur für Entwickler interessante Informationen, insb. zur Konfiguration der Suche im Schema und der Benutzung von Volltextsuche-Queries in Programm- oder Skriptcode.
Konfiguration im Schema
Berücksichtigte Daten
Standardmässig werden, mit wenigen Aussnahmen, die BOs aller Entitäten für die Volltextsuche aufbereitet. Von diesen BOs werden standardmässig die Inhalte alle Attribute, wiederum mit einigen Aussnahmen, in den Suchindex aufgenommen.
Berücksichtigte Entitäten
vgl. de/ipcon/db/fulltext/compass/SchemaMappingBuilder.isEntityIgnored() |
Explizit immer ausgeschlossen werden die BOs nicht persistenter
Entitäten, sowie die BOs der Entiäten BT
, BP
und BX
.
Durch explizite Angabe von indexed="no"
im Schema ist es möglich,
weitere Entitäten von der Indexierung auszunehmen.
Beispiel:
<Entity name="InterneEntitaet" extends="BO" plural="InterneEntitaeten"> <fulltext indexed="no"/> <attr name="KryptischerString"/> </Entity>
FIXME Infos zum "Cascading", (Nicht-)Indexierung von Unterklassen
Berücksichtigte Attribute
vgl. de/ipcon/db/fulltext/compass/SchemaMappingBuilder.isAttributeIgnored() |
Standardmässig ausgeschlossen werden die Daten von
-
Relationen-Attributen (sowohl Single als auch Many)
-
Attributen mit (Java-)Typ
Boolean
,Date
oderNumber
-
virtuelle Attribute
Durch explizite Angabe im Schema ist es jedoch möglich, entsprechende Attribute von bestimmten Entitäten doch in den Index aufzunehmen. Andererseits können auch normalerweise indexierte Attribute explizit von der Indexierung ausgenommen werden.
Beispiel:
<Entity name="InterneEntitaet" extends="BO" plural="InterneEntitaeten"> <attr name="Name"> <attr name="InteressantesDatum" type="DateTime"> <fulltext indexed="yes"/> </attr> <attr name="KryptischerString"> <fulltext indexed="no"/> </attr> </Entity>
Wird für Relationen-Attribute (sowohl Single- als auch Many-Relationen)
indexed="yes"
angegeben, ist das Resultat, dass Objekte der
"Elter"-Klasse (die, die das Relationen-Attribut enthält) auch als
Suchtreffer gefunden werden, wenn ein Suchbegriff "nur" auf eines der
"Kind"-Objekte (die in der Relation enthaltenen Objekte) zutrifft.
Beispiel:
<Entity name="Elter" extends="BO" plural="Eltern"> <attr name="Name"> <attr name="Kinder" type="Kind" relation="1-n"> <fulltext indexed="yes"/> </attr> </Entity> <Entity name="Kind" extends="BO" plural="Kinder"> <attr name="Name"> </Entity>
Es existiert ein Elter "Elter1" mit Kindern "Kind1" und "Kind2". Wird jetzt z.B. im "Eltern"-Lesezeichen nach "Kind1" gesucht, so wird das Objekt "Elter1" als Ergebnis geliefert, obwohl der Suchbegriff "Kind1" eigentlich nur in einem der "Kinder"-Objekte vorkommt.
Weitere Einstellungen im Schema
analyzed
vgl. de/ipcon/db/fulltext/compass/SchemaMappingBuilder.buildScalarConfig() sowie das entsprechende Kapitel in der Compass-Dokumentation |
Für einzelne Attribute kann im Schema definiert werden, ob die entsprechenden Inhalte bei der Indexierung "analysiert" werden sollen oder nicht.
Ein Text wie "Dies ist ein Attributwert" wird normalerweise nicht in dieser Form im Index abgelegt, sondern in seine einzelnen Bestandteile (normalerweise "Wörter", d.h. durch Whitespace abgetrennte Tokens) aufgeteilt. Auch werden einige sehr häufig vorkommende Wörter (sog. "Stopwords") entfernt.
Durch diese Behandlung ist es möglich, dass bei der Suche nach z.B. "Dies" das Objekt mit dem obigen Attributwert gefunden wird.
Wäre der Wert nicht "analysiert" worden, so wäre nur die gesamte Zeichenkette genau in dieser Form im Index abgelegt und das Objekt würde nur bei Eingabe genau von "Dies ist ein Attributwert" (oder ggf. noch bei Benutzung von Platzhaltern oder Ähnlichkeitssuche) gefunden, nicht aber nur bei Eingabe von "Dies".
Standardmässig werden alle Attribute mit (Java-)Typ String
"analysiert"; alle anderen Attribute (insb. z.B. Zahlen) nicht. Im
Normalfall ist diese Einstellung wohl sinnig; in Einzelfällen (z.B.
vielleicht wenn es sich um eine Bezeichnung handelt, die nur genau in
der eingegebenen Form gefunden werden soll) kann das Verhalten aber
durch eine explizite Angabe beim Attribut geändert werden.
Beispiel:
<Entity name="InterneEntitaet" extends="BO" plural="InterneEntitaeten"> <attr name="Name"> <attr name="Typenbezeichnung"> <fulltext analyzed="no"/> </attr> </Entity>
boost
Sowohl für Entitäten als auch für einzelne Attribute kann ein "Boost"-Wert im Schema angegeben werden. Dieser dient dazu, einen Treffer für die entsprechende Entität oder das entsprechende Attribut höher oder niedriger zu bewerten und damit im Ranking der Suchergebnisse weiter nach vorne oder hinten zu plazieren. Da jedoch z.Zt. in MyTISM kein Ranking von Suchergebnissen benutzt wird, ist die Angabe dieses Wertes z.Zt. weder erforderlich noch sinnvoll. :toc: left :toc-title: Inhaltsverzeichnis :toclevels: 2 :icons: font
Formularelemente
Action
Name | Erlaubte Werte | Beschreibung |
---|---|---|
|
String: z. B. |
|
|
siehe |
|
|
Boolean: true, false |
Während die Action ausgeführt wird, eine Ladeanimation über das Formular legen. |
|
String |
Funktionsname, der z. B. von Buttons gerufen werden kann. |
|
Boolean: true, false |
|
|
Boolean: true, false |
|
|
String: icon="20x20/New.gif" |
Pfad zum gewünschten icon. |
|
Boolean: true, false |
Wird zu Boolean Action mit dem angegebenen Anfangszustand. Dieser schaltet bei jeder Ausführung der Action um. Wird aktuell nur vom ToggleButton unterstützt. |
|
Boolean: true, false |
|
|
String |
|
|
Boolean: true, false |
Actions können zusammengeführt oder überschrieben werden. |
|
||
|
String |
Name der Action. Optional - wenn nicht angegeben, gleich |
|
Boolean: true, false |
Action in neuem Thread ausführen. |
|
int: 0 |
|
|
int: 1000 |
|
|
Boolean: true, false |
|
|
Kurze Beschreibung. Wird als Tooltip angezeigt. |
|
|
Boolean: true, false |
Den Namen der Action unterhalb eines ggf. vorhandenen Icons anzeigen. |
|
||
|
Leerer String. Bsp.: toolBar="" |
Wird hinzugefügt, falls die Action in der Standard-ToolBar neben einer Table bzw. im Falle von topMdiOnly in der "obersten" Toolbar erscheinen soll. |
|
Boolean: true, false |
Bei |
availableOn
Liefert ein hier angegebenes Skript true
zurück, wird die Action angezeigt, bei false
nicht.
Die Bedingung für availableOn wird nur einmal und dann sehr früh evaluiert (bei der Entscheidung ob die Komponente überhaupt gebaut werden soll)
|
enabledOn
Die Action ist die ganze Zeit sichtbar und jenachdem ob ein hier angegebenes Skript true
oder false
zurückliefert, kann die Action angeklickt werden bzw. is ausgegraut.
enabledOn wird laufend, d.h. bei jedem Statuswechsel, evaluiert (nicht wie bei availableOn ).
|
initialState
Erfüllt die gleiche Aufgabe wie das Attribut initialState
. Nur das hier ein Skript zur Bestimmung des Anfangszustandes angegeben wird.
longDescription
Wenn man mal mehr (formatierten) Text zur Erklärung der Action anzeigen möchte (auch HTML ist möglich):
<Action cmd="resetData" name="Daten resetten" shortDescription="Daten zuruecksetzen" toolBar="" accKey="control R">
<onAction language="groovy">rootBO.doMagic()</onAction>
<longDescription><![CDATA[<html>
Folgende Voraussetzungen müssen erfüllt sein, damit die Daten der selektierten Zeilen zurückgesetzt werden können:
<ul>
<li>Der Benutzer ist Mitglied der "Verwaltung" oder ein ADMIN</li>
<li>Es ist mindestens eine Zeile ausgewählt</li>
</ul>
</html>]]></longDescription>
</Action>
onAction
Hier wird das Script definiert, welches für die jeweilige Action
ablaufen soll.
BooleanInputComponent
Attribute: FIXME
Name | Erlaubte Werte | Beschreibung |
---|---|---|
|
||
|
siehe |
|
|
String: Property accessor. Beispiele: property="Buch.Autor.Alter"; property="." |
Das Attribut der aktuell betrachteten Entität, das im Kontext dieses Elementes verwendet werden soll. Im zweiten Beispiel wird das BO des aktuellen Formkontexts als Property gesetzt. |
|
Border
Attribute:
Name | Erlaubte Werte | Beschreibung |
---|---|---|
|
Farbangabe. Bitte entweder als "#rrggbbaa" oder "r,g,b,a", "r g b a" oder eine Farbkonstante der java.awt.Color, z.B. YELLOW angeben. Farbnamen mit Postfix "ISH" werden in Richtung weiss verschoben (Mittelwert der einzelnen Farbwerte und 255). Der Alphawert ist optional. Die einzelnen Werte sind bei den beiden letzteren Varianten entweder Float-Werte von 0.0..1.0 (bei 1 bitte 1.0 angeben!) oder Integer-Werte von 0..255. bitte nur die eine Sorte Werte verwenden. Oder fuer Random-Farbe: random.' |
|
|
Farbangabe. #rrggbbaa, r,g,b,a, r g b a. Alpha optional. Beispiele: #14f900, 255,255,0,0, 0.5 0.4 0.3 0.2, GREEN, YELLOWISH |
|
|
Farbangabe. #rrggbbaa, r,g,b,a, r g b a. Alpha optional. Beispiele: #14f900, 255,255,0,0, 0.5 0.4 0.3 0.2, GREEN, YELLOWISH |
|
|
Farbangabe. #rrggbbaa, r,g,b,a, r g b a. Alpha optional. Beispiele: #14f900, 255,255,0,0, 0.5 0.4 0.3 0.2, GREEN, YELLOWISH |
|
|
Farbangabe. #rrggbbaa, r,g,b,a, r g b a. Alpha optional. Beispiele: #14f900, 255,255,0,0, 0.5 0.4 0.3 0.2, GREEN, YELLOWISH |
|
|
Farbangabe. #rrggbbaa, r,g,b,a, r g b a. Alpha optional. Beispiele: #14f900, 255,255,0,0, 0.5 0.4 0.3 0.2, GREEN, YELLOWISH |
|
|
|
Abschrägung. |
|
|
|
|
||
|
||
|
Farbangabe. #rrggbbaa, r,g,b,a, r g b a. Alpha optional. Beispiele: #14f900, 255,255,0,0, 0.5 0.4 0.3 0.2, GREEN, YELLOWISH |
Hervorhebung. Muss immer zusammen mit |
|
Farbangabe. #rrggbbaa, r,g,b,a, r g b a. Alpha optional. Beispiele: #14f900, 255,255,0,0, 0.5 0.4 0.3 0.2, GREEN, YELLOWISH |
Schattierung. Muss immer zusammen mit |
|
String: |
Begrenzung als Vertiefung oder Erhöhung darstellen. |
|
Boolean: true, false |
|
|
String: +X% |
Gibt an, um wieviel Prozent die Schrift vergrößert werden soll. |
|
String: z. B. fontStyle="bold", fontStyle="italics" oder fontStyle="BOLD", fontStyle="italics" |
|
|
||
|
Farbangabe. #rrggbbaa, r,g,b,a, r g b a. Alpha optional. Beispiele: #14f900, 255,255,0,0, 0.5 0.4 0.3 0.2, GREEN, YELLOWISH |
|
|
Boolean: true, false |
|
|
||
|
||
|
Alias. Siehe |
|
|
Tupel: (horizontal, vertikal). Beispiele: minSize="4c, 5c"; minSize="4c,"; minSize=",5c" |
Gibt die minimale Größe des Elements mit horizontalem und vertikalem Wert an und ersetzt die ansonsten automatische Größenberechnung. Diese würde das Element auf das Minimum an Platz für dessen Inhalt setzen. Beide Werte sind jeweils optional. |
|
||
|
String |
Um das Form-Element innerhalb des Formulars referenzieren zu können |
|
Alias. Siehe |
|
|
Tupel: (horizontal, vertikal). Beispiele: prefSize="8c, 6c"; prefSize="8c,"; prefSize=",6c" |
Gibt die bevorzugte Größe des Elements mit horizontalem und vertikalem Wert an und ersetzt die ansonsten automatische Größenberechnung. Diese würde das Element auf das Minimum an Platz für dessen Inhalt setzen. Beide Werte sind jeweils optional. |
|
String: |
|
|
String: |
|
|
String |
Überschrift für die durch die Border abgegrenzten Inhalte. |
|
||
|
||
|
String: |
|
|
String: |
|
|
||
|
||
|
Button
Attribute: FIXME
Name | Erlaubte Werte | Beschreibung |
---|---|---|
|
String |
|
|
Farbangabe. #rrggbbaa, r,g,b,a, r g b a. Alpha optional. Beispiele: #14f900, 255,255,0,0, 0.5 0.4 0.3 0.2, GREEN, YELLOWISH |
|
|
Boolean: true, false |
Falls true, wird der Button aktiviert, wenn der Container den Fokus hat und z.B. die ENTER Taste gedrückt wurde. |
|
String: +X% |
Gibt an, um wieviel Prozent die Schrift vergrößert werden soll. |
|
String: z. B. fontStyle="bold", fontStyle="italics" oder fontStyle="BOLD", fontStyle="italics" |
|
|
Farbangabe. #rrggbbaa, r,g,b,a, r g b a. Alpha optional. Beispiele: #14f900, 255,255,0,0, 0.5 0.4 0.3 0.2, GREEN, YELLOWISH |
|
|
||
|
String: icon="20x20/New.gif" |
Pfad zum gewünschten icon. |
|
Integer (750ms) |
Spezifiziert innerhalb welchen Zeitraums mehrfaches Klicken des Buttons als ein einfaches Klicken interpretiert wird |
|
String |
Beschriftung des Buttons. |
|
String: TOP, CENTER, BOTTOM, z. B. vAlign="TOP" |
Bestimmt die vertikale Ausrichtung des Textes innerhalb des Elements. Die Höhe des Elements muss größer sein als eine normale Zeilenhöhe, was z. B. durch Setzen des Attributs prefSize erreicht werden kann. |
Canvas
Attribute: FIXME
Name | Erlaubte Werte | Beschreibung |
---|---|---|
|
String. |
Text, der angezeigt wird, wenn man den Mauszeiger über das Element hält. |
Chart
Komponente zur Darstellung von Diagrammen in Formularen. Die zugrundeliegende Bibliothek ist "JFreeChart".
Derzeit werden von unserer direkten Implementierung folgende Diagramme unterstützt:
-
timeSeriesChart
-
stackedXYAreaChart
-
scatterPlot
-
xYAreaChart
-
xYLineChart
-
xYStepAreaChart
-
xYStepChart
Darüber hinaus kennt JFreeChart noch einige andere Diagramme (z.B. Torten-Diagramme).
Über das Kontextmenü stehen weitere Funktionen wie Export als Bild, Drucken, Einstellungsmöglichkeiten, etc zur Verfügung.
Beispiel unter Verwendung unserer direkten Implementierung:
Das folgende Beispiel dient der Erklärung des Aufbaus. Es werden die ZeiterfassungsEinträge eines Mitarbeiters dargestellt, mit der jeweiligen Anwesenheitsdauer in y-Richtung.
Der JFreeChartBuilder wird als builder
an das buildScript übergeben. Über diesen können dann die verschiedenen Diagramme gezeichnet werden.
Innerhalb der Closure steht das anchor
-Objekt zur Verfügung, welches das im Formular geöffnete BO referenziert.
<Chart>
<buildScript><![CDATA[
builder.xYLineChart(title:'oneTitle', xAxisLabel:"EK", yAxisLabel:'VK') {
def zes = anchor.ZeiterfassungsEintraege
antiAlias=true
borderVisible=false
borderPaint='#c0c0c0'
plot {
tableXYDataset() {
rows = {
(0..zes.size()-1).each{ it }
}
x = {
it
}
series(name: anchor.kontakt.describe()) {
values = {
zes.values().getAt(it).Anwesenheitsdauer
}
stroke = 2
paint = '#4c1e67'
}
}
}
}
]]></buildScript>
</Chart>
Beispiel der generischen Verwendung (Prüfserie hat Einzelprüfungen mit deren Messwerten):
<Chart>
<buildScript><![CDATA[
import org.jfree.chart.ChartFactory
import org.jfree.chart.ChartPanel
import org.jfree.chart.JFreeChart
import org.jfree.chart.plot.PlotOrientation
import org.jfree.data.category.DefaultCategoryDataset
def pserie = builder.anchor
// dataset definieren
def dataset = new DefaultCategoryDataset()
pserie.getEinzelpruefungen().values().sort{ it.getPosition() }.each{
dataset.addValue(it.getFeinheitNm(), 'FeinheitNm', it.getPosition())
dataset.addValue(it.getElastizitaet(), 'Elastizitaet', it.getPosition())
dataset.addValue(it.getHeissluftschrumpfS130(), 'HLS130', it.getPosition())
}
// Chart generieren
JFreeChart chart = ChartFactory.createLineChart(
'Messwerte der Einzelpruefungen',
'Position','Skala',
dataset,
PlotOrientation.VERTICAL,
true, true, false)
return chart
]]></buildScript>
</Chart>
Attribute: FIXME
Name | Erlaubte Werte | Beschreibung |
---|---|---|
|
Boolean: true, false |
|
|
Boolean: true, false |
|
|
||
|
Boolean: true, false |
|
|
Boolean: true, false |
|
|
Boolean: true, false |
|
|
Boolean: true, false |
CheckBox
Die Checkbox kann benutzt werden, um Boolean-Werte zu beeinflussen.
Attribute:
Name | Erlaubte Werte | Beschreibung |
---|---|---|
|
||
|
||
|
siehe |
|
|
Boolean: true, false |
false verhindert das Editieren des Feldes. Das Feld WIRD NICHT ausgegraut. |
|
||
|
||
|
||
|
Alias. Siehe |
|
|
Tupel: (horizontal, vertikal). Beispiele: minSize="4c, 5c"; minSize="4c,"; minSize=",5c" |
Gibt die minimale Größe des Elements mit horizontalem und vertikalem Wert an und ersetzt die ansonsten automatische Größenberechnung. Diese würde das Element auf das Minimum an Platz für dessen Inhalt setzen. Beide Werte sind jeweils optional. |
|
||
|
String |
Um das Form-Element innerhalb des Formulars referenzieren zu können |
|
Alias. Siehe |
|
|
Tupel: (horizontal, vertikal). Beispiele: prefSize="8c, 6c"; prefSize="8c,"; prefSize=",6c" |
Gibt die bevorzugte Größe des Elements mit horizontalem und vertikalem Wert an und ersetzt die ansonsten automatische Größenberechnung. Diese würde das Element auf das Minimum an Platz für dessen Inhalt setzen. Beide Werte sind jeweils optional. |
|
String: Property accessor. Beispiele: property="Buch.Autor.Alter"; property="." |
Das Attribut der aktuell betrachteten Entität, das im Kontext dieses Elementes verwendet werden soll. Im zweiten Beispiel wird das BO des aktuellen Formkontexts als Property gesetzt. |
|
String |
Text, der zusätzlich hinter der Checkbox angezeigt wird. |
|
Boolean: true, false |
Wenn hier true gesetzt ist, kann das Element drei Zustände annehmen: true, false und null. Ansonsten nur true und false. Wenn false, kann Null nicht mehr ausgewählt werden. Kann durch eine Angabe im Schema bereits definiert werden. |
ComboBox
Die API-Dokumentation enthält ebenfalls weitere Informationen zu dieser Komponente. |
Wie in dem Bereich über Widgets bereits gezeigt, kann eine ComboBox direkt auf ein property zeigen, woraufhin alle möglichen BOs angezeigt werden.
Beispiel:
Will man programmatisch eigene Auswahlmöglichkeiten anbieten kann man das über das choiceSkript machen:
...
<ComboBox property="FilterZeitraum" e-label="$R{Zeitraum}" chooseOnly="true" nullable="false">
<choiceScript>
// Title: Value
['letzten 2 Tage' : '2Tage',
'letzten 7 Tage' : '7Tage',
'letzten 30 Tage' : '30Tage',
'letzten 60 Tage' : '60Tage',
'letzten 100 Tage' : '100Tage',
'letztes halbe Jahr': 'HalbesJahr',
'letztes Jahr' : 'LetztesJahr',
'Alle' : 'Alle']
</choiceScript>
</ComboBox>
...
Attribute
Name |
Erlaubte Werte | Beschreibung |
---|---|---|
|
String: first/last/firstNonNull |
Gibt an welches Element als default ausgewählt werden soll. |
|
Boolean: true, false |
Wenn true, dürfen keine eigenen Werte in das Feld eingetragen werden. |
|
siehe |
|
|
siehe |
|
|
String (CBOFormat). |
Legt fest, wie das BO für die Anzeige im Dropdown-Menü und im Feld formatiert ist. Bsp: "Id': 'Name" |
|
Boolean: true, false |
Wenn false wird null nicht als mögliche Auswahl angeboten. |
|
String |
Wird angezeigt, wenn nichts ausgewählt wurde. Gilt sowohl für das Feld als auch für den Eintrag im Dropdown-Menü, der den leeren Wert repräsentiert. |
|
||
|
||
|
String |
Name der Entität, deren Objekte hier zur Auswahl angeboten werden sollen. |
|
String |
Name der Relation, aus der Objekte zur Auswahl angeboten werden sollen. |
|
String |
Name des Attributes, nach dem sortiert werden soll. |
|
String (OQL) |
Optionaler Filter für im Attribut |
|
Boolean: true, false |
Wenn true, wird die Id jedes (BO-)Elements in eckigen Klammern hinter dem Element angezeigt. |
|
Boolean: true, false |
Wenn true, werden für Comboboxen, die keine Relation anzeigen, Duplikate in der Auswahlliste verhindert, indem die Id jedes (BO-)Elements in eckigen Klammern hinter dem Element angezeigt wird, sofern Duplikate auftreten. |
DateChooser
Attribute:
Name | Erlaubte Werte | Beschreibung |
---|---|---|
|
||
|
||
|
||
|
siehe |
|
|
siehe |
|
|
Boolean: true, false |
false verhindert das Editieren des Feldes. Das Feld WIRD NICHT ausgegraut. |
|
Boolean: true, false |
|
|
String: +X% |
Gibt an, um wieviel Prozent die Schrift vergrößert werden soll. |
|
String: z. B. fontStyle="bold", fontStyle="italics" oder fontStyle="BOLD", fontStyle="italics" |
|
|
String: |
Bestimmt die Formatierung des angezeigten Datums. Beispiele:
|
|
Boolean: true, false |
|
|
||
|
||
|
Alias. Siehe |
|
|
Tupel: (horizontal, vertikal). Beispiele: minSize="4c, 5c"; minSize="4c,"; minSize=",5c" |
Gibt die minimale Größe des Elements mit horizontalem und vertikalem Wert an und ersetzt die ansonsten automatische Größenberechnung. Diese würde das Element auf das Minimum an Platz für dessen Inhalt setzen. Beide Werte sind jeweils optional. |
|
||
|
String |
Um das Form-Element innerhalb des Formulars referenzieren zu können. |
|
Integer mit Einheit px, c, em oder dlu |
Die Angabe in Character "c" ist die zu favorisierende Bestimmt die Höhe des Fensters, in dem der Kalender zur Datumsauswahl angezeigt wird. |
|
Integer mit Einheit px, c, em oder dlu |
Die Angabe in Character "c" ist die zu favorisierende Bestimmt die Breite des Fensters, in dem der Kalender zur Datumsauswahl angezeigt wird. |
|
Alias. Siehe |
|
|
Tupel: (horizontal, vertikal). Beispiele: prefSize="8c, 6c"; prefSize="8c,"; prefSize=",6c" |
Gibt die bevorzugte Größe des Elements mit horizontalem und vertikalem Wert an und ersetzt die ansonsten automatische Größenberechnung. Diese würde das Element auf das Minimum an Platz für dessen Inhalt setzen. Beide Werte sind jeweils optional. |
|
String: Property accessor. Beispiele: property="Buch.Autor.Alter"; property="." |
Das Attribut der aktuell betrachteten Entität, das im Kontext dieses Elementes verwendet werden soll. Im zweiten Beispiel wird das BO des aktuellen Formkontexts als Property gesetzt. |
|
Boolean: true, *false* |
Wenn das Form-Element den Fokus bekommt wird der gesamte Inhalt selektiert |
Editor
Der Editor kann für String-Attribute angezeigt werden. Durch die Angabe des Modus kann die Darstellungsart beeinflusst werden. Es werden dazu intern JEdit-Klassen benutzt.
Beispiel:
...
<Editor property="Bemerkung" mode="patch"/>
...
Attribute: FIXME
Name | Erlaubte Werte | Beschreibung |
---|---|---|
|
int: 60 |
Gibt an wieviele Spalten angezeigt werden sollen. |
|
int: 3 |
Wird der Cursor an eine bestimmte Stelle bewegt, wird sichergestellt, dass x Zeilen über & unter der Position angezeigt werden. |
|
Boolean: true, false |
Ist focusable false, kann das Textfeld nicht fokussiert werden… |
|
String: +X% |
Gibt an, um wieviel Prozent die Schrift vergrößert werden soll. |
|
int: 500 |
Gibt die Anzahl der gespeicherten Schritte und damit der möglichen Undos an |
|
String: xml, groovy, log, patch |
Definiert die Formatierung des Editor-Fensters. |
|
int: 10 |
Gibt an wieviele Zeilen angezeigt werden sollen. |
|
String |
Füllt das Attribut automatisch mit dem eingegebenen Text |
Element
Attribute: FIXME
Name | Erlaubte Werte | Beschreibung |
---|---|---|
|
Boolean: true, false |
|
|
Boolean: true, false |
|
|
siehe |
|
|
String: +X% |
Gibt an, um wieviel Prozent die Schrift vergrößert werden soll. |
|
String: z. B. fontStyle="bold", fontStyle="italics" oder fontStyle="BOLD", fontStyle="italics" |
|
|
Boolean: true, false |
Bei true wird das eingebettete GUI-Element nicht angezeigt, wenn das BO des angegebenen Attributs null ist, ansonsten ist es ausgegraut.
Das ist nützlich im Fall von Attributketten, z.Bsp. bei |
|
Double -1 |
Was soll mit dem restlichen Platz von rightFill geschehen, sofern != 0 (default: FView.defaultCellHAlign); Beispiel: siehe ipcon/db/core/Report.nrx Beschriftung, die vor dem Inhalt des Element Tags angezeigt wird. |
|
String |
Beschriftung, die vor dem Inhalt des Element Tags angezeigt wird. |
|
Farbangabe. Bitte entweder als "#rrggbbaa" oder "r,g,b,a", "r g b a" oder eine Farbkonstante der java.awt.Color, z.B. YELLOW angeben. Farbnamen mit Postfix "ISH" werden in Richtung weiss verschoben (Mittelwert der einzelnen Farbwerte und 255). Der Alphawert ist optional. Die einzelnen Werte sind bei den beiden letzteren Varianten entweder Float-Werte von 0.0..1.0 (bei 1 bitte 1.0 angeben!) oder Integer-Werte von 0..255. bitte nur die eine Sorte Werte verwenden. Oder fuer Random-Farbe: random.' |
Bestimmt die Hintergrundfarbe des Labels. |
|
Farbangabe. #rrggbbaa, r,g,b,a, r g b a. Alpha optional. Beispiele: #14f900, 255,255,0,0, 0.5 0.4 0.3 0.2, GREEN, YELLOWISH |
Bestimmt die Schriftfarbe des Labes. |
|
String: |
|
|
Boolean: true, false |
|
|
String: Property accessor. Beispiele: property="Buch.Autor.Alter"; property="." |
Das Attribut der aktuell betrachteten Entität, das im Kontext dieses Elementes verwendet werden soll. Im zweiten Beispiel wird das BO des aktuellen Formkontexts als Property gesetzt. Nähere Informationen hierzu im GUI-Kochbuch |
|
||
|
||
|
||
|
||
|
Attribute: FIXME
Name | Erlaubte Werte | Beschreibung |
---|---|---|
|
String: |
|
|
||
|
||
|
||
|
Boolean: true, false |
false verhindert das Editieren des Feldes. Das Feld WIRD ausgegraut. |
|
siehe |
|
|
siehe |
|
|
Boolean: true, false |
false verhindert das Editieren des Feldes. Das Feld WIRD NICHT ausgegraut. |
|
||
|
String: +X% |
Gibt an, um wieviel Prozent die Schrift vergrößert werden soll. |
|
String: z. B. fontStyle="bold", fontStyle="italics" oder fontStyle="BOLD", fontStyle="italics" |
|
|
Farbangabe. Bitte entweder als "#rrggbbaa" oder "r,g,b,a", "r g b a" oder eine Farbkonstante der java.awt.Color, z.B. YELLOW angeben. Farbnamen mit Postfix "ISH" werden in Richtung weiss verschoben (Mittelwert der einzelnen Farbwerte und 255). Der Alphawert ist optional. Die einzelnen Werte sind bei den beiden letzteren Varianten entweder Float-Werte von 0.0..1.0 (bei 1 bitte 1.0 angeben!) oder Integer-Werte von 0..255. bitte nur die eine Sorte Werte verwenden. Oder fuer Random-Farbe: random.' |
|
|
||
|
||
|
Boolean: true, false |
Bricht Text an der rechten Kante um, statt eine Scrollbar anzuzeigen. |
|
||
|
||
|
Alias. Siehe |
|
|
Tupel: (horizontal, vertikal). Beispiele: minSize="4c, 5c"; minSize="4c,"; minSize=",5c" |
Gibt die minimale Größe des Elements mit horizontalem und vertikalem Wert an und ersetzt die ansonsten automatische Größenberechnung. Diese würde das Element auf das Minimum an Platz für dessen Inhalt setzen. Beide Werte sind jeweils optional. |
|
||
|
||
|
Boolean: true, false |
Passwortfeld statt normalem Text. |
|
Tupel: (horizontal, vertikal). Beispiele: prefSize="8c, 6c"; prefSize="8c,"; prefSize=",6c" |
Gibt die bevorzugte Größe des Elements mit horizontalem und vertikalem Wert an und ersetzt die ansonsten automatische Größenberechnung. Diese würde das Element auf das Minimum an Platz für dessen Inhalt setzen. Beide Werte sind jeweils optional. |
|
Alias. Siehe |
|
|
String: Property accessor. Beispiele: property="Buch.Autor.Alter"; property="." |
Das Attribut der aktuell betrachteten Entität, das im Kontext dieses Elementes verwendet werden soll. Im zweiten Beispiel wird das BO des aktuellen Formkontexts als Property gesetzt. |
|
||
|
int: 4 |
|
|
Boolean: true, *false* |
Wenn das Form-Element den Fokus bekommt wird der gesamte Inhalt selektiert |
|
||
|
||
|
int: 4 |
|
|
||
|
Boolean: true, false |
Wenn Text umgebrochen wird, dann möglichst an Whitespace-Grenzen. |
Image
Attribute: FIXME
Name | Erlaubte Werte | Beschreibung |
---|---|---|
|
siehe |
|
|
Tupel: (horizontal, vertikal). Beispiele: prefSize="8c, 6c"; prefSize="8c,"; prefSize=",6c" |
Gibt die bevorzugte Größe des Elements mit horizontalem und vertikalem Wert an und ersetzt die ansonsten automatische Größenberechnung. Diese würde das Element auf das Minimum an Platz für dessen Inhalt setzen. Beide Werte sind jeweils optional. |
|
String: Property accessor. Beispiele: property="Buch.Autor.Alter"; property="." |
Das Attribut der aktuell betrachteten Entität, das im Kontext dieses Elementes verwendet werden soll. Im zweiten Beispiel wird das BO des aktuellen Formkontexts als Property gesetzt. |
|
Boolean: true, false |
Label
Name | Erlaubte Werte | Beschreibung |
---|---|---|
|
Boolean: true, false, null |
Explizit synchrones oder asynchrones Verhalten erzwingen. Synchrones Verhalten ist hilfreich, falls das Label variierenden Platzbedarf hat. (Üblicherweise bei mehrzeiliger HTML-Ausgabe.) |
|
Farbangabe. Bitte entweder als "#rrggbbaa" oder "r,g,b,a", "r g b a" oder eine Farbkonstante der java.awt.Color, z.B. YELLOW angeben. Farbnamen mit Postfix "ISH" werden in Richtung weiss verschoben (Mittelwert der einzelnen Farbwerte und 255). Der Alphawert ist optional. Die einzelnen Werte sind bei den beiden letzteren Varianten entweder Float-Werte von 0.0..1.0 (bei 1 bitte 1.0 angeben!) oder Integer-Werte von 0..255. bitte nur die eine Sorte Werte verwenden. Oder fuer Random-Farbe: random.' |
Farbangabe. Bitte entweder als "#rrggbbaa" oder "r,g,b,a", "r g b a" oder eine Farbkonstante der java.awt.Color, z.B. YELLOW angeben. Farbnamen mit Postfix "ISH" werden in Richtung weiss verschoben (Mittelwert der einzelnen Farbwerte und 255). Der Alphawert ist optional. Die einzelnen Werte sind bei den beiden letzteren Varianten entweder Float-Werte von 0.0..1.0 (bei 1 bitte 1.0 angeben!) oder Integer-Werte von 0..255. bitte nur die eine Sorte Werte verwenden. Oder fuer Random-Farbe: random.' |
|
||
|
||
|
siehe |
|
|
siehe |
|
|
||
|
String: +X% |
Gibt an, um wieviel Prozent die Schrift vergrößert werden soll. |
|
String: z. B. fontStyle="bold", fontStyle="italics" oder fontStyle="BOLD", fontStyle="italics" |
|
|
Farbangabe. Bitte entweder als "#rrggbbaa" oder "r,g,b,a", "r g b a" oder eine Farbkonstante der java.awt.Color, z.B. YELLOW angeben. Farbnamen mit Postfix "ISH" werden in Richtung weiss verschoben (Mittelwert der einzelnen Farbwerte und 255). Der Alphawert ist optional. Die einzelnen Werte sind bei den beiden letzteren Varianten entweder Float-Werte von 0.0..1.0 (bei 1 bitte 1.0 angeben!) oder Integer-Werte von 0..255. bitte nur die eine Sorte Werte verwenden. Oder fuer Random-Farbe: random.' |
Farbangabe. Bitte entweder als "#rrggbbaa" oder "r,g,b,a", "r g b a" oder eine Farbkonstante der java.awt.Color, z.B. YELLOW angeben. Farbnamen mit Postfix "ISH" werden in Richtung weiss verschoben (Mittelwert der einzelnen Farbwerte und 255). Der Alphawert ist optional. Die einzelnen Werte sind bei den beiden letzteren Varianten entweder Float-Werte von 0.0..1.0 (bei 1 bitte 1.0 angeben!) oder Integer-Werte von 0..255. bitte nur die eine Sorte Werte verwenden. Oder fuer Random-Farbe: random.' |
|
String (CBOFormat). Bsp.: |
Ermöglicht dynamisches Erzeugen des Labeltextes durch CBOFormat. Voraussetzung, um, wie im Beispiel, auf einen Attributswert zugreifen zu können, ist es, dass die Property gesetzt ist (siehe |
|
Farbangabe. Bsp: |
Hinterlegt das Label mit einem Farbverlauf von links nach rechts. Kann zusammen
mit |
|
String: |
Verlegt den Anfang des Farbverlaufs. |
|
Farbangabe. Bsp: |
Hinterlegt das Label mit einem Farbverlauf von rechts nach links. Kann zusammen
mit |
|
String: |
Verlegt das Ende des Farbverlaufs. |
|
String: |
Horizontale Ausrichtung. |
|
String: |
|
|
Boolean: true, false |
Erlaubt es, im |
|
String: icon="20x20/New.gif" |
Pfad zum gewünschten icon. Das icon erscheint vor dem in |
|
Bsp: |
Angabe des Abstandes zwischen dem Icon und Text (als Ganzzahl) |
|
Vier positive ganze Zahlen, getrennt durch Komma oder Leerzeichen, die den jeweiligen Abstand in Pixeln zum oberen, linken, unteren und rechten Rand spezifizieren: |
Außenabstand in Pixeln. |
|
String: Property accessor. Beispiele: property="Buch.Autor.Alter"; property="." |
Das Attribut der aktuell betrachteten Entität, das im Kontext dieses Elementes verwendet werden soll. Im zweiten Beispiel wird das BO des aktuellen Formkontexts als Property gesetzt. |
|
String |
Text des Labels. Kann HTML beinhalten, wenn |
|
||
|
String. |
Text, der angezeigt wird, wenn man den Mauszeiger über das Element hält. |
|
String: TOP, CENTER, BOTTOM, z. B. vAlign="TOP" |
Bestimmt die vertikale Ausrichtung des Textes innerhalb des Elements. Die Höhe des Elements muss größer sein als eine normale Zeilenhöhe, was z. B. durch Setzen des Attributs prefSize erreicht werden kann. |
|
String: |
FPanel (abstrakt)
Superklasse für viele Elemente. Bringt die unten stehenden Attribute und Sub-Elemente mit.
Skriptvariablen
In den Skripten sind diese Bindings verfügbar:
Variablenname | Klasse/Interface | Definition | Beschreibung |
---|---|---|---|
|
ClientContextI |
ftx.getCtx() |
Client-weiter Kontext, wird z.Bsp. zum Öffnen von Dialogen oder Formularen benutzt |
|
Benutzer |
ftx.getCtx().getCurrentUser() |
der im Client angemeldete Benutzer |
|
FormContextI |
ftx |
Kontext des Formulars, in dem das FPanel eingesetzt ist. Wird gebraucht, um andere Formularelemente anzusprechen. |
|
BO |
ftx.getBO() |
Das zugrundeliegende BO des FPanels. (Kann vom rootBO abweichen) |
|
Transaction |
ftx.getRoot().getTransaction() |
Die Transaction, mit der das rootBO geladen wurde, wenn |
|
FormElementI |
fe |
Das FPanel (als FormElementI) |
|
BOLoaderI |
ftx.getRoot().getBOLoader() |
Der Loader, mit dem die Daten des Strukturelements geladen wurde. |
|
BO |
ftx.getRoot().getBO() |
Das zugrundeliegende BO des Formulars. |
Subelemente
onAfterSelectValue
Ermöglicht es, ein Skript zu definieren, das nach dem Setzen eines Werts ausgeführt wird.
<Text property="Beschreibung">
<onAfterSelectValue language="groovy">ftx['v_lbl_beschreibung_fehlt'].ftx.refreshForms()</onAfterSelectValue>
</Text>
Attribute
Name | Erlaubte Werte | Beschreibung |
---|---|---|
|
String: groovy, beanshell |
Die zu verwendende Skriptsprache. |
editableIf
Ergebnis des Ausdrucks (hier bo.kannEditiertWerden
) bestimmt, ob das Elternelement
editiert werden kann.
<Text property="Beschreibung">
<editableIf language="groovy">bo.kannEditiertWerden</editableIf>
</Text>
Attribute
Name | Erlaubte Werte | Beschreibung |
---|---|---|
|
String: groovy, beanshell |
Die zu verwendende Skriptsprache. |
visibleIf
Ergebnis des Ausdrucks (hier bo.istSichtbar
) bestimmt, ob das Elternelement
angezeigt wird.
<Text property="Beschreibung">
<visibleIf language="groovy">bo.istSichtbar</visibleIf>
</Text>
Attribute
Name | Erlaubte Werte | Beschreibung |
---|---|---|
|
String: Entitätsname |
Die Entität, an der das |
|
String: groovy, beanshell |
Die zu verwendende Skriptsprache. |
|
DEPRECATED |
siehe |
|
Boolean: true, false |
Wenn true, wird das Elternelement niemals angezeigt. |
|
||
|
||
|
||
|
OnDrop
OnDrop ist ein Tag, dass benutzt werden kann um Dateien zu behandeln die auf das Element gedropt wurden:
Beispiel:
<onDrop language="groovy">
def result = Datei.importFileFromDnD(ftx, tx, files, rootBO)
ftx.toast("${result.size()} Dateien importiert.")
ftx.getRoot().refreshForms()
</onDrop>
Attribute: FIXME
onFocusGained
Eventhandler. Wird beim Setzen des Eingabe-Focus auf das Elternelement ausgeführt.
<Text property="Beschreibung">
<onFocusGained language="groovy">ftx.toast('Das Textfeld "Beschreibung" hat jetzt den Fokus.')</onFocusGained>
</Text>
onFocusLost
Eventhandler. Wird ausgeführt, wenn das Elternelement den Fokus verliert.
<Text property="Beschreibung">
<onFocusLost language="groovy">ftx.toast('Tschüss!')</onFocusLost>
</Text>
onRefresh
Eventhandler. Wird beim Übertragen von Model-Daten in die View aufgerufen.
<Text property="Beschreibung">
<onRefresh language="groovy">ftx.toast('Lade Beschreibung.')</onRefresh>
</Text>
onSync
Eventhandler. Wird beim Übertragen von View-Daten ins Model aufgerufen.
<Text property="Beschreibung">
<onSync language="groovy">ftx.toast('Speichere Beschreibung.')</onSync>
</Text>
FInputPanel (abstrakt)
Leitet sich von FPanel ab.
Alle Komponenten, die einen Input erwarten leiten sich daraufhin von FInputPanel ab.
Zentralisiert die Mandatory-Berechnung, sodass alle Subklassen ein gleiches Verhalten besitzen.
Außerdem wird noch ein neues Skript-Tag - alsoMandatoryIf
- hinzugefügt.
alsoMandatoryIf
Kann benutzt werden um ein Eingabeelement zum Pflichtfeld zu machen.
<alsoMandatoryIf language="groovy">
ctx.currentUser.istMitgliedVon("Pflichtgruppe")
</alsoMandatoryIf>
Per default ist das angegebene Skript gecached (wird also nur beim Öffnen des Formulars ausgewertet), da man von komplexerem Code ausgegangen ist.
Möchte man aber, dass bei einem Refresh das Skript erneut evaluiert wird, kann man das Caching mittels cached="false"
deaktivieren.
<alsoMandatoryIf cached="false" language="groovy">
!rootBO.KundeWillDatenNichtNennen
</alsoMandatoryIf>
Falls das Schema vorgibt, dass ein Element mandatory ist, kann dies NICHT über alsoMandatoryIf ausgehebelt werden.
|
PDFViewer
Attribute: FIXME
Name | Erlaubte Werte | Beschreibung |
---|---|---|
|
Farbangabe. #rrggbbaa, r,g,b,a, r g b a. Alpha optional. Beispiele: #14f900, 255,255,0,0, 0.5 0.4 0.3 0.2, GREEN, YELLOWISH Standard: #000000 |
|
|
Farbangabe. #rrggbbaa, r,g,b,a, r g b a. Alpha optional. Beispiele: #14f900, 255,255,0,0, 0.5 0.4 0.3 0.2, GREEN, YELLOWISH Standard: FF0000 |
|
|
String: Helvetica-18 |
|
|
Boolean: true, false |
false = ein volatiles Bild wird direkt in den Grafik(karten)-Speicher geladen, was je nach Treiber(/Karte/System) länger dauern kann. true = ein gepuffertes (aber speicher-intensiveres) Bild wird in den Grafik(karten)-Speicher geladen. Diese Vorgehensweise ist mitunter unter Windows etwas schneller |
|
Boolean: true, false |
Unterdrückt die Anzeige des zugehörigen Labels |
|
Boolean: true, false |
|
|
Boolean: true, false |
|
|
Boolean: true, false |
|
|
Boolean: true, false |
|
|
Boolean: true, false |
|
|
||
|
||
|
||
|
||
|
Tupel: (horizontal, vertikal). Beispiele: prefSize="8c, 6c"; prefSize="8c,"; prefSize=",6c" |
Gibt die bevorzugte Größe des Elements mit horizontalem und vertikalem Wert an und ersetzt die ansonsten automatische Größenberechnung. Diese würde das Element auf das Minimum an Platz für dessen Inhalt setzen. Beide Werte sind jeweils optional. |
|
String: Property accessor. Beispiele: property="Buch.Autor.Alter"; property="." |
Das Attribut der aktuell betrachteten Entität, das im Kontext dieses Elementes verwendet werden soll. Im zweiten Beispiel wird das BO des aktuellen Formkontexts als Property gesetzt. |
|
Boolean: true, false |
|
|
Boolean: true, false |
Alias für |
|
Double: 0.05 |
Popup
Ein Popup-Element mit einem Eingabefeld und einem weißen Blatt-Icon auf der rechten Seite zeigt an, dass Sie hier ein bereits vorhandenes Objekt auswählen und verknüpfen können. Wenn daneben ein gelber Stift erscheint, können Sie an dieser Stelle direkt ein neues Objekt erstellen. Das Doppelblatt-Icon kopiert den aktuellen Inhalt in ein neues Objekt und verknüpft dieses. Diese Funktion ist hilfreich, wenn das ursprüngliche verknüpfte Objekt unverändert bleiben soll, Sie jedoch an dieser Stelle eine angepasste Version benötigen.
Attribute:
Name | Erlaubte Werte | Beschreibung |
---|---|---|
|
String: |
|
|
Boolean: true, false |
Attribute in der Detailview eines Popup Elements sind normalerweise schreibgeschützt, d.h. Wert 'false'.
Grund ist, dass ein Popup mit Detailview oft allgemeinere Informationen im Formular anzeigt, das BO des Popups jedoch nicht nur von dem aktuellen Soll der Benutzer die Attribute des BOs ändern dürfen, jedoch das eigentliche BO nicht sehen können, dann ist eine Umsetzung über eine Attributkette in der property-Definition bzw. ein Wrapper- |
|
||
|
||
|
siehe |
|
|
||
|
||
|
||
|
siehe |
|
|
||
|
Boolean: true, false |
|
|
||
|
||
|
String: +X% |
Gibt an, um wieviel Prozent die Schrift vergrößert werden soll. |
|
String: +X% |
Gibt an, um wieviel Prozent die Schrift vergrößert werden soll. |
|
String: z. B. fontStyle="bold", fontStyle="italics" oder fontStyle="BOLD", fontStyle="italics" |
|
|
String: z. B. fontStyle="bold", fontStyle="italics" oder fontStyle="BOLD", fontStyle="italics" |
|
|
Farbangabe. Bitte entweder als "#rrggbbaa" oder "r,g,b,a", "r g b a" oder eine Farbkonstante der java.awt.Color, z.B. YELLOW angeben. Farbnamen mit Postfix "ISH" werden in Richtung weiss verschoben (Mittelwert der einzelnen Farbwerte und 255). Der Alphawert ist optional. Die einzelnen Werte sind bei den beiden letzteren Varianten entweder Float-Werte von 0.0..1.0 (bei 1 bitte 1.0 angeben!) oder Integer-Werte von 0..255. bitte nur die eine Sorte Werte verwenden. Oder fuer Random-Farbe: random.' |
Farbangabe. Bitte entweder als "#rrggbbaa" oder "r,g,b,a", "r g b a" oder eine Farbkonstante der java.awt.Color, z.B. YELLOW angeben. Farbnamen mit Postfix "ISH" werden in Richtung weiss verschoben (Mittelwert der einzelnen Farbwerte und 255). Der Alphawert ist optional. Die einzelnen Werte sind bei den beiden letzteren Varianten entweder Float-Werte von 0.0..1.0 (bei 1 bitte 1.0 angeben!) oder Integer-Werte von 0..255. bitte nur die eine Sorte Werte verwenden. Oder fuer Random-Farbe: random.' |
|
String (CBOFormat). |
Legt fest, wie das BO für die Anzeige im Feld formatiert ist. Bsp: "Id': 'Name" |
|
||
|
||
|
Boolean: true, false |
Definiert ob die Eingabe mit oder ohne Berücksichtigung der Gross-/Kleinschreibung gesucht werden soll |
|
String |
Komma-separierte Liste von Attributen/Attribut-Ketten, die bei der "Schnelleingabe" durchsucht werden sollen; bei einem eindeutigen Ergebnis wird automatisch selektiert |
|
||
|
Boolean: true, false |
|
|
||
|
||
|
Alias. Siehe |
|
|
Tupel: (horizontal, vertikal). Beispiele: minSize="4c, 5c"; minSize="4c,"; minSize=",5c" |
Gibt die minimale Größe des Elements mit horizontalem und vertikalem Wert an und ersetzt die ansonsten automatische Größenberechnung. Diese würde das Element auf das Minimum an Platz für dessen Inhalt setzen. Beide Werte sind jeweils optional. |
|
||
|
String |
Um das Form-Element innerhalb des Formulars referenzieren zu können |
|
||
|
||
|
String |
Tid des Formulars, das benutzt werden soll, um Objekte aus diesem Popup zu öffnen. |
|
||
|
||
|
Integer mit Einheit px, c, em oder dlu. Bsp.: popupHeight="40c" |
Die Höhe des resultierenden Popups. Wird keine Einheit angegeben, wird von einem px-Wert ausgegangen. |
|
Komma-separierte Integer mit Einheit px, c, em oder dlu. Bsp.: popupSize="960, 20c" |
Kurzform für |
|
Integer mit Einheit px, c, em oder dlu. Bsp.: popupWidth="40c" |
Die Breite des resultierenden Popups. Wird keine Einheit angegeben, wird von einem px-Wert ausgegangen. |
|
Alias. Siehe |
|
|
Tupel: (horizontal, vertikal). Beispiele: prefSize="8c, 6c"; prefSize="8c,"; prefSize=",6c" |
Gibt die bevorzugte Größe des Elements mit horizontalem und vertikalem Wert an und ersetzt die ansonsten automatische Größenberechnung. Diese würde das Element auf das Minimum an Platz für dessen Inhalt setzen. Beide Werte sind jeweils optional. |
|
String: Property accessor. Beispiele: property="Buch.Autor.Alter"; property="." |
Das Attribut der aktuell betrachteten Entität, das im Kontext dieses Elementes verwendet werden soll. Im zweiten Beispiel wird das BO des aktuellen Formkontexts als Property gesetzt. |
|
Boolean: true, false |
|
|
Boolean: true, false. Bsp.: |
Bestimmt, ob im Feld ein Icon (Blatt mit Stern) angezeigt wird, das beim Anklicken ein neues Fenster zum Erstellen eines neuen Objektes für die jeweilige Relation öffnet. |
|
Boolean: true, false. Bsp.: |
Bestimmt, ob im Feld ein Icon (Blatt Papier) angezeigt wird, das beim Anklicken eine Tabelle bereits existierender Objekte öffnet, die für die Relation ausgewählt werden können. |
|
||
|
||
|
Tab
Attribute:
Name | Erlaubte Werte | Beschreibung |
---|---|---|
|
Farbangabe. Bitte entweder als "#rrggbbaa" oder "r,g,b,a", "r g b a" oder eine Farbkonstante der java.awt.Color, z.B. YELLOW angeben. Farbnamen mit Postfix "ISH" werden in Richtung weiss verschoben (Mittelwert der einzelnen Farbwerte und 255). Der Alphawert ist optional. Die einzelnen Werte sind bei den beiden letzteren Varianten entweder Float-Werte von 0.0..1.0 (bei 1 bitte 1.0 angeben!) oder Integer-Werte von 0..255. bitte nur die eine Sorte Werte verwenden. Oder fuer Random-Farbe: random.' |
Farbangabe. Bitte entweder als "#rrggbbaa" oder "r,g,b,a", "r g b a" oder eine Farbkonstante der java.awt.Color, z.B. YELLOW angeben. Farbnamen mit Postfix "ISH" werden in Richtung weiss verschoben (Mittelwert der einzelnen Farbwerte und 255). Der Alphawert ist optional. Die einzelnen Werte sind bei den beiden letzteren Varianten entweder Float-Werte von 0.0..1.0 (bei 1 bitte 1.0 angeben!) oder Integer-Werte von 0..255. bitte nur die eine Sorte Werte verwenden. Oder fuer Random-Farbe: random.' |
|
||
|
Boolean: true, false |
Bei false kann innerhalb dieses Elements kein Feld mehr editiert werden. |
|
Farbangabe. Bitte entweder als "#rrggbbaa" oder "r,g,b,a", "r g b a" oder eine Farbkonstante der java.awt.Color, z.B. YELLOW angeben. Farbnamen mit Postfix "ISH" werden in Richtung weiss verschoben (Mittelwert der einzelnen Farbwerte und 255). Der Alphawert ist optional. Die einzelnen Werte sind bei den beiden letzteren Varianten entweder Float-Werte von 0.0..1.0 (bei 1 bitte 1.0 angeben!) oder Integer-Werte von 0..255. bitte nur die eine Sorte Werte verwenden. Oder fuer Random-Farbe: random.' |
Farbangabe. Bitte entweder als "#rrggbbaa" oder "r,g,b,a", "r g b a" oder eine Farbkonstante der java.awt.Color, z.B. YELLOW angeben. Farbnamen mit Postfix "ISH" werden in Richtung weiss verschoben (Mittelwert der einzelnen Farbwerte und 255). Der Alphawert ist optional. Die einzelnen Werte sind bei den beiden letzteren Varianten entweder Float-Werte von 0.0..1.0 (bei 1 bitte 1.0 angeben!) oder Integer-Werte von 0..255. bitte nur die eine Sorte Werte verwenden. Oder fuer Random-Farbe: random.' |
|
Boolean: true, false |
|
|
||
|
Boolean: true, false |
Daten dieses Tabs erst beim Öffnen des Tabs laden, nicht schon beim Öffnen des Formulars. |
|
||
|
||
|
Alias. Siehe |
|
|
Tupel: (horizontal, vertikal). Beispiele: minSize="4c, 5c"; minSize="4c,"; minSize=",5c" |
Gibt die minimale Größe des Elements mit horizontalem und vertikalem Wert an und ersetzt die ansonsten automatische Größenberechnung. Diese würde das Element auf das Minimum an Platz für dessen Inhalt setzen. Beide Werte sind jeweils optional. |
|
||
|
String |
Um das Form-Element innerhalb des Formulars referenzieren zu können |
|
Alias. Siehe |
|
|
Tupel: (horizontal, vertikal). Beispiele: prefSize="8c, 6c"; prefSize="8c,"; prefSize=",6c" |
Gibt die bevorzugte Größe des Elements mit horizontalem und vertikalem Wert an und ersetzt die ansonsten automatische Größenberechnung. Diese würde das Element auf das Minimum an Platz für dessen Inhalt setzen. Beide Werte sind jeweils optional. |
|
Boolean: true, false; Oder Richtungsbeschränkung, z. B. scrollable="VERTICAL_ONLY" |
Scrollbar für dieses Element ein- oder ausschalten bzw. auf eine Richtung beschränken. |
|
String |
Wird als Titel des Tabs angezeigt. |
|
String. |
Text, der angezeigt wird, wenn man den Mauszeiger über das Element hält. |
Subelemente:
Name | Erlaubte Werte | Beschreibung |
---|---|---|
|
||
|
||
|
||
|
||
|
||
|
Wird ausgeführt, sobald der Tab aktiviert (angezeigt) wird |
|
|
Wird ausgeführt, sobald der Tab deaktiviert (versteckt) wird |
|
|
||
|
TabbedView
Attribute:
Name | Erlaubte Werte | Beschreibung |
---|---|---|
|
Boolean: true, false |
|
|
String: 'IGNORE', 'ASK' |
Gibt an, wie Konflikte beim Speichern durch veraltete BOs behandelt werden sollen.
Nur in der äussersten TabbedView / View erlaubt. |
|
||
|
Boolean: true, false |
Bei false kann innerhalb dieses Elements kein Feld mehr editiert werden. |
|
Integer mit Einheit px, c, em oder dlu |
Initiale Höhe der View in Pixeln oder der angegebenen Einheit. |
|
Boolean: true, false |
Nur für Formular-Roots. Änderungen aus lokalen Speichervorgängen im Client in diesem Formular nicht nachziehen |
|
||
|
||
|
||
|
Tupel: (horizontal, vertikal). Beispiele: maxSize="4c, 5c"; maxSize="4c,"; maxSize=",5c" |
|
|
Alias. Siehe |
|
|
Tupel: (horizontal, vertikal). Beispiele: minSize="4c, 5c"; minSize="4c,"; minSize=",5c" |
Gibt die minimale Größe des Elements mit horizontalem und vertikalem Wert an und ersetzt die ansonsten automatische Größenberechnung. Diese würde das Element auf das Minimum an Platz für dessen Inhalt setzen. Beide Werte sind jeweils optional. |
|
||
|
String |
Um das Form-Element innerhalb des Formulars referenzieren zu können |
|
Alias. Siehe |
|
|
Tupel: (horizontal, vertikal). Beispiele: prefSize="8c, 6c"; prefSize="8c,"; prefSize=",6c" |
Gibt die bevorzugte Größe des Elements mit horizontalem und vertikalem Wert an und ersetzt die ansonsten automatische Größenberechnung. Diese würde das Element auf das Minimum an Platz für dessen Inhalt setzen. Beide Werte sind jeweils optional. |
|
Boolean: true, false |
Gibt an, ob bei tabPlacement |
|
||
|
String: |
Die Reiter der TabbedView unten, oben, links oder rechts anzeigen. |
|
Boolean: true, false, z. B.: useMaximumHeight="true" |
|
|
Boolean: true, false, z. B.: useMaximumWidth="true" |
|
|
Integer mit Einheit px, c, em oder dlu |
Initiale Breite der View in Pixeln oder der angegebenen Einheit. |
Subelemente:
Name | Erlaubte Werte | Beschreibung |
---|---|---|
|
Table
Attribute: FIXME
Name | Erlaubte Werte | Beschreibung |
---|---|---|
|
Boolean: true, false |
|
|
Boolean: true, false |
Änderungen an Objekten des Typs, welche in der Tabelle angezeigt werden, führen zu einer Aktualisierung der Tabelle |
|
String |
komma-separierte Liste von Entitätsnamen; Änderungen an Objekten dieser Typen führen zusätzlich zum in der Tabelle angezeigten Typ zu einer Aktualisierung der Tabelle; funktioniert nur zusammen mit |
|
Boolean: true, false |
|
|
Boolean: true, false |
|
|
Boolean: true, false |
|
|
String |
Definition der Spalten einer Tabelle im Kurzformat. Bsp.: Einzelne Spaltendefintionen werden durch Spalten werden ausgeblendet, indem sie einfach nicht deklariert werden. Die Reihenfolge kann geändert werden. Bei polymorphem Tabelleninhalt kann es hilfreich sein, den Typ des jeweiligen Objektes mit |
|
Boolean: true, false |
False: Bei Mausklick (oder |
|
Boolean: true, false |
|
|
Boolean: true, false |
Die anzuzeigenden Elemente sind nicht eigenständig und leben nur in diesem View. |
|
||
|
siehe |
|
|
Boolean: true, false |
Selektion per Doppelklick |
|
Boolean: true, false |
Bewirkt, dass die DetailView der Tabelle das Bearbeiten der dort angezeigten Werte zulässt. Nützlich, wenn es sich bei diesen Werten bspw. um Attribute aus Subrelationen eines virtuellen Attributs handelt, die eigentlich gesperrt wären. |
|
Boolean: true, false |
|
|
String: Entitätsname |
Bestimmt die Entität, deren Objekte diese Tabelle darstellen soll. |
|
Boolean: true, false |
Die Daten im Lesezeichen werden erst vom Server geladen, wenn man das explizit mit F5 oder RETURN "anfordert". Man kann also erstmal alle nötigen Filter setzen und das Lesezeichen beginnt nicht bereits nach dem ersten gesetzten Filter mit dem Laden. Nützlich bei Entitäten mit sehr vielen Objekten, bei denen es angeraten ist erst mal ein bisschen vorzufiltern. |
|
String |
|
|
String: +X% |
Gibt an, um wieviel Prozent die Schrift vergrößert werden soll. |
|
Boolean: true, false |
|
|
Integer |
|
|
String: |
|
|
Boolean: true, false |
|
|
||
|
Integer |
Zusätzlicher freier Raum in Zellen horizontal. |
|
Integer |
Zusätzlicher freier Raum in Zellen vertikal. |
|
String |
Zeiger auf die Property, die in den Elementen die Postennummer darstellt. Posten-Modus. Fuehrt dazu, dass zwei Aktionen, naemlich Posten-rauf und Posten-runter gebaut werden, und die ITable standardmaessig die Postenspalte aufsteigend sortiert. |
|
Boolean: true, false |
Es können nur bestehende Objekte verknüpft werden und keine neue erstellt |
|
Boolean: true, false |
Bestimmt, ob die Objekte in der Tabelle sofort geladen werden sollen. Wenn
|
|
Integer |
|
|
Integer: 100000 |
Definiert die maximale Anzeige von Objekten (vergleichbar mit dem von SQL bekannten "LIMIT 100000") |
|
siehe |
|
|
Tupel: (horizontal, vertikal). Beispiele: maxSize="4c, 5c"; maxSize="4c,"; maxSize=",5c" |
|
|
siehe |
|
|
Tupel: (horizontal, vertikal). Beispiele: minSize="4c, 5c"; minSize="4c,"; minSize=",5c" |
|
|
String: error, ignore, log |
Wie soll mit nicht existierenden oder falsch geschriebene Attributen in der Spaltendefinition umgegangen werden |
|
String |
Um das Form-Element innerhalb des Formulars referenzieren zu können |
|
String |
Tid des Formulars, das benutzt werden soll, um Objekte aus dieser Tabelle zu öffnen. |
|
String |
Name der Property für welche beim Doppelklick das Standardformular geöffnet wird. |
|
||
|
String |
|
|
Alias. Siehe |
|
|
Tupel: (horizontal, vertikal). Beispiele: prefSize="8c, 6c"; prefSize="8c,"; prefSize=",6c" |
Gibt die bevorzugte Größe des Elements mit horizontalem und vertikalem Wert an und ersetzt die ansonsten automatische Größenberechnung. Diese würde das Element auf das Minimum an Platz für dessen Inhalt setzen. Beide Werte sind jeweils optional. |
|
Integer: 5 |
Definiert die bevorzugte Anzahl angezeigter Zeilen |
|
String |
|
|
Boolean: true, false |
|
|
Boolean: true, false |
True: Beim Öffnen von BOs über dieses Lesezeichen werden die BOs immer neu vom Server neu geladen, anstatt die Instanz aus dem Lesezeichen zu verwenden. |
|
String: |
Bestimmt das Verhalten der Spaltenbreite beim Vergrößern/Verkleinern der Tabelle. |
|
Boolean: true, false |
False: Bei Mausklick wird die komplette Spalte ausgewählt |
|
Boolean: true, false |
|
|
Boolean: true, false |
|
|
Boolean: true, false |
|
|
Boolean: true, false |
|
|
Boolean: true, false |
|
|
String: Kommaseparierte Liste von Entitätsnamen |
Subentitäten der in der Tabelle dargestellten Entität, die nicht angezeigt werden sollen. |
|
String |
|
|
Boolean: true, false, z. B.: useMaximumHeight="true" |
|
|
Boolean: true, false, z. B.: useMaximumWidth="true" |
|
|
Boolean: true, false |
|
|
String: |
|
|
Boolean: true, false |
Es darf nur geschaut werden, verlinken bestehender Objekte, etc ist nicht möglich |
|
Integer |
Column
Attribute:
Name | Erlaubte Werte | Beschreibung |
---|---|---|
|
String: Property accessor. Beispiele: property="Buch.Autor.Alter"; property="." |
Das Attribut der aktuell betrachteten Entität, das im Kontext dieses Elementes verwendet werden soll. Im zweiten Beispiel wird das BO des aktuellen Formkontexts als Property gesetzt. |
|
siehe |
|
|
String (CBOFormat). |
Legt fest, wie das BO aus der property für die Anzeige in der Zelle formatiert wird. Bsp: "Id': 'Name"; funktioniert nur, wenn das letzte Attribut in der property auf eine Relation verweist |
|
siehe |
|
|
String (CBOFormat). |
Legt fest, wie das BO der aktuellen Zeile als ToolTip für diese Spalte formatiert wird. Bsp: "Id': 'Name" |
|
String |
Überschrift für die Spalte. |
|
Integer mit Einheit px, c, em oder dlu |
Initiale Breite der Spalte in Pixeln oder der angegebenen Einheit. |
|
String: TOP, CENTER, BOTTOM, z. B. vAlign="TOP" |
Bestimmt die vertikale Ausrichtung des Textes innerhalb des Elements. Die Höhe des Elements muss größer sein als eine normale Zeilenhöhe, was z. B. durch Setzen des Attributs prefSize erreicht werden kann. |
|
Farbangabe. Bitte entweder als "#rrggbbaa" oder "r,g,b,a", "r g b a" oder eine Farbkonstante der java.awt.Color, z.B. YELLOW angeben. Farbnamen mit Postfix "ISH" werden in Richtung weiss verschoben (Mittelwert der einzelnen Farbwerte und 255). Der Alphawert ist optional. Die einzelnen Werte sind bei den beiden letzteren Varianten entweder Float-Werte von 0.0..1.0 (bei 1 bitte 1.0 angeben!) oder Integer-Werte von 0..255. bitte nur die eine Sorte Werte verwenden. Oder fuer Random-Farbe: random.' |
Bestimmt die Hintergrundfarbe der Spalte für ungerade Zeilennummern. |
|
Farbangabe. Bitte entweder als "#rrggbbaa" oder "r,g,b,a", "r g b a" oder eine Farbkonstante der java.awt.Color, z.B. YELLOW angeben. Farbnamen mit Postfix "ISH" werden in Richtung weiss verschoben (Mittelwert der einzelnen Farbwerte und 255). Der Alphawert ist optional. Die einzelnen Werte sind bei den beiden letzteren Varianten entweder Float-Werte von 0.0..1.0 (bei 1 bitte 1.0 angeben!) oder Integer-Werte von 0..255. bitte nur die eine Sorte Werte verwenden. Oder fuer Random-Farbe: random.' |
Bestimmt die alternative Hintergrundfarbe der Spalte für gerade Zeilennummern. |
|
Farbangabe. #rrggbbaa, r,g,b,a, r g b a. Alpha optional. Beispiele: #14f900, 255,255,0,0, 0.5 0.4 0.3 0.2, GREEN, YELLOWISH |
Bestimmt die Schriftfarbe der Spalte für ungerade Zeilennummern. |
|
Farbangabe. #rrggbbaa, r,g,b,a, r g b a. Alpha optional. Beispiele: #14f900, 255,255,0,0, 0.5 0.4 0.3 0.2, GREEN, YELLOWISH |
Bestimmt die Schriftfarbe der Spalte für gerade Zeilennummern. |
|
Boolean: true, false |
FIXME aktuell ohne Funktion? |
|
Boolean: true, false |
Aktiviert Info-Level Logging beim Rendern von Zellen. |
|
Boolean: true, false |
Aktiviert oder deaktiviert das Caching von angezeigten Werten. |
|
String: z. B. fontStyle="bold", fontStyle="italics" oder fontStyle="BOLD", fontStyle="italics" |
|
|
String: |
|
|
|
Gibt an, in welcher Richtung die Spalte sortiert werden soll. NONE verbietet das Sortieren. |
|
int: 0 |
Gibt die Sortier-Reihenfolge der Spalten an. |
|
String |
Hier kann der Name einer TableCellRenderer-Klasse angegeben werden, die statt des Default Renderers benutzt werden soll. |
headerRenderer und renderer
Hier können spezielle Renderer konfiguriert werden um z.B. die Farbe abhängig vom Inhalt der Zelle zu ändern. Sie müssen auf Spaltenebene definiert werden:
<Column property="Enabled">
<renderer>
import java.awt.Color
renderer.setHorizontalAlignment(javax.swing.SwingConstants.CENTER)
if (!value) { (1)
renderer.setBackground((row&1) == 0 ? new Color(234, 176, 176) : new Color(240, 200, 200)) (2)
renderer.setText('\u2717') (3)
} else {
renderer.setBackground((row&1) == 0 ? new Color(199, 234, 176) : new Color(207, 226, 186))
renderer.setText('\u2714')
}
</renderer>
</Column>
1 | value beinhaltet den Wert aus dem Property. In diesem Fall also Enabled als Boolean. |
2 | Falls der Wert von Enabled false/null ist wird der Hintergrund abhängig von der Zeilen-Nummer in einem unterschiedlichen Rot-Ton eingefärbt. |
3 | Der Inhalt wird auf das Unicode-Zeichen ✗ gesetzt. |
Wenn man am Background rumfuhrwerkt, muss man natürlich auch den "isSelected"-Status abfragen und den Background selbst entsprechend setzen (z.B. das gesetzte Rot bei markierten Zellen etwas bläulich einfärben). |
DetailView
Die DetailView wird als Subelement der Table verwendet, um Details zum jeweils gerade innerhalb der Tabelle angeklickten Objekt anzuzeigen bzw. um das Bearbeiten der Attribute des Objekts zu ermöglichen. Sind von den Änderungen innerhalb der DetailView Inhalte der Tabelle betroffen, werden diese automatisch aktualisiert.
Achtung: Falls die DetailView für eine Tabelle
in einem Lesezeichen verwendet wird, muss im <table>
Element das Attribut viewOnly="true"
gesetzt sein.
Attribute: FIXME
Name | Erlaubte Werte | Beschreibung |
---|---|---|
|
Boolean: true, false |
Falls Wert auf true, kann der Bereich der DetailView mit der Maus verschoben, sprich vergrößert/verkleinert werden. |
|
String: |
|
|
Float: 0.0 |
|
|
Boolean: true, false; Oder Richtungsbeschränkung, z. B. scrollable="VERTICAL_ONLY" |
Scrollbar für dieses Element ein- oder ausschalten bzw. auf eine Richtung beschränken. |
Sollen Attribute von Objekten aus Relationen des Tabellenobjekts geändert werden,
müssen für diese jedoch onAfterSetValue -Hooks implementiert werden, der die Version des
eigentlichen Objekts anstößt, um ein Aktualisieren der Tabelle zu erzwingen.
|
Beispiel mit onAfterSetValue
:
<Table property="Buecher" columns="Titel | Erscheinungsjahr | Autor.Familienname">
<DetailView name="autor">
<Border etched="true" title="Details zum Autor">
<View scrollable="true">
<Element label="Familienname">
<Text property="Autor.Familienname">
<onAfterSetValue language="groovy">ftx['autor'].getBO().bumpVersion()</onAfterSetValue>
</Text>
</Element>
</View>
</Border>
</DetailView>
</Table>
MultipleChoiceFilterGUI
Hierbei handelt es sich um einen Filter, der via <filter type="multipleChoice">
in eine FTable (Lesezeichen, Popup) eingebaut werden kann.
Für Hilfe beim Anlegen eines Filters die Solstice User-Dokumentation lesen.
Name | Erlaubte Werte | Beschreibung |
---|---|---|
preselectIdx |
int |
Gibt an, welcher Index in dem Dropdown standardmäßig ausgewählt ist. |
sort |
|
Gibt an, in welcher Reihenfolge die Queryergebnisse sortiert werden sollen |
Text
Attributes:
Name | Erlaubte Werte | Beschreibung |
---|---|---|
|
String: |
|
|
Angabe der Klasse zur Textdarstellung, z.B. |
|
|
Boolean: true, false |
Das Feld wird ausgegraut und kann nicht editiert werden. |
|
siehe |
|
|
siehe |
|
|
||
|
Farbangabe. Bitte entweder als "#rrggbbaa" oder "r,g,b,a", "r g b a" oder eine Farbkonstante der java.awt.Color, z.B. YELLOW angeben. Farbnamen mit Postfix "ISH" werden in Richtung weiss verschoben (Mittelwert der einzelnen Farbwerte und 255). Der Alphawert ist optional. Die einzelnen Werte sind bei den beiden letzteren Varianten entweder Float-Werte von 0.0..1.0 (bei 1 bitte 1.0 angeben!) oder Integer-Werte von 0..255. bitte nur die eine Sorte Werte verwenden. Oder fuer Random-Farbe: random.' |
|
|
||
|
Boolean: true, false |
Bricht Text an der rechten Kante um, statt eine Scrollbar anzuzeigen. |
|
Boolean: true, false |
Passwortfeld statt normalem Text. |
|
||
|
int: 4 |
|
|
Boolean: true, *false* |
Wenn das Form-Element den Fokus bekommt wird der gesamte Inhalt selektiert |
|
||
|
||
|
int: 4 |
|
|
||
|
Boolean: true, false |
Wenn Text umgebrochen wird, dann möglichst an Whitespace-Grenzen. |
TimeSelector
Eingabe-/Bearbeitungsmöglichkeit für ein oder mehrere Zeitspannen innerhalb eines Zeitraums.
FIXME TT 2019-05-08: Wird praktisch nie benutzt. |
Name | Erlaubte Werte | Beschreibung |
---|---|---|
|
int: 0-23 |
Erste mögliche auszuwählende Stunde des Tages |
|
int: 1-n (24) |
Anzahl der von |
|
int: 5,10,15,20,30,60 |
Länge der Intervall-Aufteilung innerhalb einer Stunde |
|
String: Property accessor. Beispiele: property="Buch.Autor.Alter"; property="." |
Das Attribut der aktuell betrachteten Entität, das im Kontext dieses Elementes verwendet werden soll. Im zweiten Beispiel wird das BO des aktuellen Formkontexts als Property gesetzt. |
|
Element FIXME ??? |
FIXME ??? |
ToggleButton
Knopf der zwischen zwei Zuständen wechselt; Eingabe-/Bearbeitungsmöglichkeit für Boolean-Werte.
Name | Erlaubte Werte | Beschreibung |
---|---|---|
|
String |
|
|
siehe |
|
|
String: Property accessor. Beispiele: property="Buch.Autor.Alter"; property="." |
Das Attribut der aktuell betrachteten Entität, das im Kontext dieses Elementes verwendet werden soll. Im zweiten Beispiel wird das BO des aktuellen Formkontexts als Property gesetzt. |
|
Angabe eigener Klasse für das GUI Control Element. Diese muss vom Typ |
|
|
Farbangabe. #rrggbbaa, r,g,b,a, r g b a. Alpha optional. Beispiele: #14f900, 255,255,0,0, 0.5 0.4 0.3 0.2, GREEN, YELLOWISH |
Hintergrundfarbe des Buttons im "nicht-gedrückten" Zustand. |
|
Farbangabe. #rrggbbaa, r,g,b,a, r g b a. Alpha optional. Beispiele: #14f900, 255,255,0,0, 0.5 0.4 0.3 0.2, GREEN, YELLOWISH |
Vordergrundfarbe (d.h. Schriftfarbe). |
|
Farbangabe. #rrggbbaa, r,g,b,a, r g b a. Alpha optional. Beispiele: #14f900, 255,255,0,0, 0.5 0.4 0.3 0.2, GREEN, YELLOWISH |
Hintergrundfarbe des Buttons im gedrückten Zustand. Falls |
|
String: +X% |
Gibt an, um wieviel Prozent die Schrift vergrößert werden soll. |
|
String: z. B. fontStyle="bold", fontStyle="italics" oder fontStyle="BOLD", fontStyle="italics" |
|
|
||
|
String: TOP, CENTER, BOTTOM, z. B. vAlign="TOP" |
Bestimmt die vertikale Ausrichtung des Textes innerhalb des Elements. Die Höhe des Elements muss größer sein als eine normale Zeilenhöhe, was z. B. durch Setzen des Attributs prefSize erreicht werden kann. |
|
Integer (750ms) |
Spezifiziert innerhalb welches Zeitraums mehrfaches Klicken des Buttons als ein einfaches Klicken interpretiert wird |
|
String: icon="20x20/New.gif" |
Pfad zum gewünschten icon. Icon für den Toggle-Button im "gedrückten" Zustand. |
|
String: icon="20x20/New.gif" |
Pfad zum gewünschten icon. Icon für den Toggle-Button im "nicht-gedrückten" Zustand. |
|
String |
Beschriftung des Toggle-Buttons. Falls |
|
String |
Alias für |
|
String |
Text für den Toggle-Button im "nicht-gedrückten" Zustand. |
Tree
Auswahl von Einträgen für eine Relation, deren mögliche Einträge hierarchisch in einer Baumstruktur angeordnet sind.
Attributes:
Name | Erlaubte Werte | Beschreibung |
---|---|---|
|
String. Bsp.: |
Kinder-Attribut. Bei Subentitäten von Querbaum einfach "Kinder." |
|
||
|
siehe |
|
|
String: Entitätsname. Bsp.: |
Die Entität, deren Instanzen als Baum dargestellt werden sollen. Obligatorisch. |
|
ACHTUNG: Dieses Attribut wird im Moment noch nicht vom Tree unterstützt. |
|
|
String: Attributname, z. B. |
Das Attribut, das die Beschriftung der Knoten im Baum stellen soll. Default: |
|
Integer. Bsp.: |
|
|
String. Bsp.: |
Eltern Attribut. Bei Subentitäten von Querbaum einfach "Elter." |
|
String: Property accessor. Beispiele: property="Buch.Autor.Alter"; property="." |
Das Attribut der aktuell betrachteten Entität, das im Kontext dieses Elementes verwendet werden soll. Im zweiten Beispiel wird das BO des aktuellen Formkontexts als Property gesetzt. |
|
||
|
Boolean: true, false |
|
|
Integer. Bsp.: |
Uri
Attributes:
Name | Erlaubte Werte | Beschreibung |
---|---|---|
|
Boolean: true, false |
View
Attributes:
Name | Erlaubte Werte | Beschreibung |
---|---|---|
|
Boolean: true, false |
|
|
||
|
Integer, z. B.: |
Teilt die Inhalte der View auf die angegebene Anzahl Spalten auf. |
|
String: 'IGNORE', 'ASK' |
Gibt an, wie Konflikte beim Speichern durch veraltete BOs behandelt werden sollen.
Nur in der äussersten TabbedView / View erlaubt.
IGNORE: Ignoriere Konflikte und übernehme/merge die Änderungen, |
|
||
|
Double: 1. Wert zwischen |
Verhindert Streckung von Feldern und benutzt |
|
Boolean: true, false |
Die View übernimmt die Anzeigeeinstellungen (z.B. Anzahl columns) der übergeordneten View. Dadurch kann z.B. einheiltiche Anzeige der Formularelemente in verscheidenen Views erreicht werden. |
|
Boolean: true, false |
Wenn false werden Kindelemente gesperrt, sodass diese nicht editiert werden können. |
|
Integer mit Einheit px, c, em oder dlu. Bsp.: |
Erzeugt links und rechts der View den angegebenen Abstand. |
|
Integer mit Einheit px, c, em oder dlu. Bsp.: |
Erzeugt über und unter der View den angegebenen Abstand. |
|
||
|
Boolean: true, false |
|
|
Boolean: true, false |
Nur für Formular-Roots. Änderungen aus lokalen Speichervorgängen im Client in diesem Formular nicht nachziehen |
|
||
|
Integer mit Einheit px, c, em oder dlu. Bsp.: |
Fügt den angegebenen Abstand zwischen Labels und Feldern ein. |
|
Integer mit Einheit px, c, em oder dlu. Bsp.: |
Fügt den angegebenen Abstand zwischen Zeilen ein. |
|
||
|
Alias. Siehe |
|
|
Tupel: (horizontal, vertikal). Beispiele: maxSize="4c, 5c"; maxSize="4c,"; maxSize=",5c" |
|
|
Alias. Siehe |
|
|
Tupel: (horizontal, vertikal). Beispiele: minSize="4c, 5c"; minSize="4c,"; minSize=",5c" |
Gibt die minimale Größe des Elements mit horizontalem und vertikalem Wert an und ersetzt die ansonsten automatische Größenberechnung. Diese würde das Element auf das Minimum an Platz für dessen Inhalt setzen. Beide Werte sind jeweils optional. |
|
||
|
String |
Um das Form-Element innerhalb des Formulars referenzieren zu können |
|
Alias. Siehe |
|
|
Tupel: (horizontal, vertikal). Beispiele: prefSize="8c, 6c"; prefSize="8c,"; prefSize=",6c" |
Gibt die bevorzugte Größe des Elements mit horizontalem und vertikalem Wert an und ersetzt die ansonsten automatische Größenberechnung. Diese würde das Element auf das Minimum an Platz für dessen Inhalt setzen. Beide Werte sind jeweils optional. |
|
Boolean: true, false; Oder Richtungsbeschränkung, z. B. scrollable="VERTICAL_ONLY" |
Scrollbar für dieses Element ein- oder ausschalten bzw. auf eine Richtung beschränken. |
|
<Farbwert>[@<Intensität>], Intensität ist default 0.1; Beispiele: tint="#ff0000 @ 0.1"; tint="GREENISH" |
Färbt den Hintergrund des Views in der angegebenen Farbe ein |
|
Boolean: true, false, z. B.: useMaximumHeight="true" |
|
|
Boolean: true, false, z. B.: useMaximumWidth="true" |
|
|
Datenaustausch
MyTISM bietet diverse Möglichkeiten des Imports als auch Export von Daten.
Import
FIXME
Export
Excel
Für den Datenaustausch nach Excel bzw. kompatiblen Tabellenkalkulationsprogrammen kommt intern die Apache POI Bibliothek zum Einsatz (https://poi.apache.org).
Etwas schöner benutzen lässt sich das mit dem XlsHandler, der in dem ein oder anderen Projekt bereits zur Anwendung gekommen ist (einfach über das Repository
nach XlsHandler.nrx suchen).
Dort gibt es drei Methoden:
. Bauen von Header
. Befüllen des Sheets
. Den eigentlichen Export erstellen
Die Features, die man nutzen kann, findet man auf der Seite von Apache POI beschrieben. Grob gesagt geht "fast" alles:
-
mehrere Sheets
-
Styles
-
Formeln
-
Bilder
-
…
(Siehe die Tabelle unten hier: https://poi.apache.org/components/spreadsheet/index.html)
Bekannte Einschränkungen sind:
-
wenige Charts
-
keine Makros
-
kein Pivot
-
gewisse Größenbeschränkungen der Files
Für das, was normalerweise benötigt wird, sollte es aber hoffentlich ausreichend sein.
Ein Beispiel für den Export findet man im Repository, wenn man nach der Klasse AngebotsgruppeGas.nrx sucht (Methode "exportSummenlastgaenge").
Natürlich kann man das auch in einem Groovy-Skript direkt im Client / einem Lesezeichen / einem Formular machen.
Zu überlegen ist, ob bei entsprechend häufiger Verwendung (u.a. auch direkt durch den Kunden), wir die interne API möglichst benutzerfreundlich gestalten, damit die Skripte nicht zu kompliziert werden.
Lokale autoritative sowie synchronisierende Instanzen zum Entwickeln aufsetzen
Manchmal benötigt man beim Entwickeln bestimmter Features - meist bei Core-Arbeiten - eine Konstellation von autoritativem Server und synchronisierendem/n Servern.
Hier eine stichwortartige Anleitung wie man solche eine Konstellation auf seinem lokalen Entwickersystem aufsetzen kann. Ausgegangen wird davon, dass eine Instanz - die autoritative Instanz - bereits existiert. Außerdem wird davon ausgegangen, dass beide Instanzen immer denselben Codestand nutzen sollen - falls nicht muss für die synchronisierende Instanz ein eigenes "deploy"-Verzeichnis angelegt werden, statt das der autoritativen Instanz zu verlinken.
Im folgenden wurde überall der Zusatz "syncnode" für Namen von zur synchronisierende Instanz gehörigen Dingen gewählt. Dieser ist aber prinzipiell beliebig bzw. das Verzeichnis könnte generell theoretisch beliebig benannt werden. Der besseren Zuordnung halber sollte man allerdings die hier beschriebene Variante wählen.
Folgendes ist dann zum Aufsetzen der zugehörigen synchronisierende Instanz zu tun:
-
Verzeichnis
/.<projektkuerzel>-syncnode
anlegen (muss normalerweise als root/via sudo gemacht werden, um das /-Verzeichnis modifizieren zu dürfen) -
Besitzer korrekt setzen (wie vom Verzeichnis der autoritativen Instanz
/.<projektkuerzel>
) -
/.<projektkuerzel>/deploy
nach/.<projektkuerzel>-syncnode/deploy
verlinken -
/.<projektkuerzel>/filesRoot
nach/.<projektkuerzel>-syncnode/filesRoot
verlinken -
/.<projektkuerzel>/lib/mytism
nach/.<projektkuerzel>-syncnode/lib/mytism
verlinken -
Dateien
/.<projektkuerzel>mytism.ini
etc. nach/.<projektkuerzel>-syncnode
kopieren -
/.<projektkuerzel>-syncnode/mytism.ini
anpassen:-
nodeNumber
anpassen, falls Id der zugehörigen BN bekannt; oder Zeile komplett löschen, dann wird automatisch eine neue angelegt -
(DB-)
url
anpassen:<dbname>
→<dbname>-syncnode
-
filesRoot
anpassen →/.<projektkuerzel>-syncnode/filesRoot
-
authoritative=1
→authoritative=0
-
SyncService*-Einträge aktivieren:
[Sync] url=socket://localhost:4242?compress=zlib9 user=Admin pass=
Statt "Admin" und leerem Passwort bitte die korrekten Zugangsdaten aus der Datenbank eintragen.
-
port
undtlsPort
anpassen → z.B. statt 4242 und 4243 Ports 14242 und 14243 nutzen -
DeploySite
-Einstellungen anpassen oder neu eintragen, falls noch nicht vorhanden:[DeploySite] host=localhost port=18080 --tlsHost= --tlsPort= requireAuthentication=0 --reauthEveryXDays=90
-
-
Skript
mytism
anpassen:-
export PRJDIR="/.<projektkuerzel>-syncnode"
-
export DBNAME="<dbname>-syncnode"
-
Danach kann, wie in der Admin-Doku unter "Aufsetzen eines syncenden MyTISM-Servers aus einem Backup des autoritativen Servers" beschrieben, ein Datenbank-Backup der autoritativen Instanz eingespielt und die beiden Instanzen genutzt werden.