Das Ziel des Einsatzes von programmierbaren Events ist, das Verhalten des Systems so weit wie möglich und so flexibel wie möglich zu steuern.
Programmierbare Events sollen beliebige Funktionen (in Python, Jython oder Java) mit feststehenden Parametern aufrufen.
Langfristig sollen die programmierbaren Events Customizing-Exits durch mächtigere und einfachere Strukturen ersetzen.
Details
Es gibt zwei Event-Arten: datengesteuerte Events und zeitgesteuerte Events.
Datengesteuerte Events sind Events, die beim Schreiben von Daten ausgeführt werde.
Zeitgesteuerte Events werden zu einem bestimmten Zeitpunkt, unabhängig von sonstiger Aktivität, ausgeführt
Beide Arten werden in der DT312 Events gespeichert.
Falls diese Tabelle nicht existiert, oder das Event-Framework aus einem anderen Grund nicht gestartet werden kann (etwa, weil die Jython-Schnittstelle nicht funktioniert) wird der Server NICHT gestartet. In diesem Fall ein Log-Eintrag geschrieben, dem zu entnehmen ist, dass das Event-Framework nicht geladen werden konnte und dass das entsprechende Migrationspaket ausgeführt bzw. PLANTA-Customer-Service benachrichtigt, werden soll, falls der Fehler dann immer noch auftritt.
Events beider Arten haben sowohl gleiche Parameter, wie z.B. UUID, Funktionstyp, Parameter etc, als auch artspezifische Parameter. Die Auflistung und Beschreibung der einzelner Parameter siehe ´hier
Was die gewählte Sprache angeht, in der Event-Funktionen geschrieben werden (Funktionstyp),
so sollen Java-Events nur für systemnahe Anwendungsfälle definiert werden.
Python-Events stehen die volle Python-Funktionalität zur Verfügung, sie benötigen aber einen laufenden Server (also keine reine Web-Anwendung).
Jython-Events sind in Web-Anwendungen und ‚normalen‘ Servern lauffähig.
Für die Verwaltung von Events stellt PLANTA im System-Customizer folgende Module zur Verfügung:
Datengesteuerte Events Datenbank-Tabelle definiert werden. Es gibt folgende Event-Typen:
Pre-Insert/Pre-Update/Pre-Delete (vor dem Speichern von Records)
Post-Insert/Post-Update/Post-Delete (nach dem Speichern von Records)
on-Change-Events sind auch datengesteuerte Events, haben aber einige Besonderheiten (s. nächstes Kapitel)
Diese Events erhalten als Parameter den Event selbst (für Meta-Informationen, wie er sich verhält), sowie das zu speichernde Objekt, das hier vor/nach dem Speichern manipuliert werden kann. Dieses Objekt ist entweder ein DtpRecord (in Python) oder ein Pojo-Objekt, wie es im Target-Ordner definiert wurde (in Java + Jython).
Die prinzipielle Logik ist, dass in den Pre-Funktionen der Record, der gespeichert werden soll, noch einmal geändert werden kann, oder, dass das Speichern abgebrochen werden kann (über Rückgabewert).
Post-Funktionen werden prinzipiell ausgeführt, nachdem die Records gespeichert wurden. Sie dienen zum eventuellen Anpassen des Records (oder anderer Objekte), nachdem das Speichern erfolgreich abgeschlossen wurde.
Details
Datengesteuerte Events haben zusätzlich zu den oben erwähnten gemeinsamen Parametern auch spezifische Parameter. Die Auflistung und Beschreibung siehe hier.
on-Change-Events
Information
on-Change-Events sind datengesteuerte Events, die jedesmal ausgeführt werden, wenn sich ein Datenfeld ändert - also noch VOR dem Speichern.
Sie gleichen daher Wertebereichen, sind aber flexibler, da sie wie alle Events sowohl von Jython als auch von Python getriggert werden.
Methoden, die von onChange-Events aufgerufen werden (Jython oder Python) haben zusätzlich zu den üblichen DataEvent-Parametern (Event selbst, sowie das zu ändernde Pojo-Objekt / den zu ändernden Dtp-Record) noch die zusätzlichen Parameter des Namens der Eigenschaft, die geändert werden soll, den alten Wert dieser Eigenschaft, sowie den neuen Wert. * Wie Pre-Event-Methoden auch können on-Change-Event-Methoden einen Boolean-Wert zurückliefern. Die Änderung wird nur durchgeführt, wenn dieser Wert nicht "False" ist.
Hinweis
Es ist zu beachten, dass diese Events wie alle datengesteuerten Events nur für eine ganze Tabelle definiert werden können, nicht für ein bestimmtes Dataitem. Ob der Event dann wirklich ausgeführt werden soll, müsste entweder Event-Funktion selbst überprüfen (über den Namen der zu ändernden Eigenschaft)
Ablauf
Datengesteuerte Events werden innerhalb der Client-Session ausgeführt, die das Speichern des Objektes veranlasst hat.
Datengesteuerte Events werden jeweils mit einem DtpRecord (für Python-Events) bzw. mit dem Pojo-Objekt (für Java & Jython) aufgerufen, welches gespeichert werden soll. Dies entspricht exakt der vorhandenen Klasse DtpRecord (s. PythonAPIReference) bzw. den Pojo-Objekten, genauso, wie sie im Target-Ordner definiert wurden.
DtpRecords & Java-Pojo-Objekte sind verschiedene Sichten auf die gleichen Datenbank-Records.
Anmerkung:
Die Jython-Funktion should_event_be_executed, die bestimmt, ob ein Event ausgeführt wird, falls eine Condition gesetzt ist, ist momentan noch ein Dummy, der einfach immer True zurückliefert.
Wichtig:
Es wird empfohlen, dass Pre-Funktionen selbst keine Speichern-Aktionen durchführen, da sie aufgerufen werden, nachdem die Transaktion bereits gestartet wurde, und Speichern dann u.U. nochmal den Ablauf starten würde. Es gibt zwar einen Mechanismus, der hier eine Endlosschleife nach zehn Rekursionen abbricht, aber ein neuerliches Speichern an dieser Stelle ist trotzdem nicht sauber.
Pre-Funktionen sind für zweierlei Zwecke gedacht:
Prüfen, ob Speichern wirklich erlaubt ist (durch Rückgabewert). Ist dies False, wird Speichern abgebrochen. Dies führt nicht zu einem Rollback und auch nicht zu einer Exception, da die Änderungen für etwaige Korrekturen erhalten bleiben sollen.
Bei Speichern aus Python heraus liefert dtp_record.save() einfach 0 bzw. false zurück. Das Handling davon ist die Verantwortung des Events selbst bzw. der speichernden Funktion.
Gibt es mehrere Pre-Events, werden nach dem ersten, der false zurückliefert, keine weiteren mehr ausgeführt. (Dies entspricht dem Standard-Handling von and-Operatoren, z.B. in Java, Python oder C).
Nochmal Eigenschaften anpassen; jede Änderung hier wird später automatisch geschrieben
Speichern in Post-Events ist weniger kritisch, weil hier die Transaktion bereits verlassen wurde. Auch hier sind prinzipiell Endlosschleifen möglich, die auch hier nach 10 Rekursionen unterbunden werden.
Geänderte Eigenschaften
Eine besondere Funktionalität für Events ist die Möglichkeit, hier sämtliche Felder des Records bzw. Eigenschaften des Pojo-Objekts abzurufen, die geändert wurden, und dazu auch den Original-Wert, den ein Feld ursprünglich hatte. Original-Werte werden gespeichert, sobald ein Update an einem Objekt aufgerufen wurde (z.B. DataItem.setvalue()).
Original-Werte werden zurückgesetzt, sobald alle Post-Data-Events ausgeführt wurden (s. Diagramm oben).