# Übersicht ELO Flows-Komponenten
An dieser Stelle sind alle grafischen Komponenten mit den dazugehörigen Annotationen in jeweils einem Beispiel aufgeführt.
# ELO Flows-Komponente
Jeder Flow basiert auf Komponenten. Komponenten können mehrere Elemente enthalten. Beispielsweise stellt eine Komponente einen oder mehrere Trigger zur Verfügung. Diese Trigger lösen dann weitere Aktionen im Flow aus. Diese Aktionen werden über Dienste realisiert. Die Dienste werden ebenfalls von Komponenten bereitgestellt.
Definition der Komponentenklasse (hier CounterComponent):
@Component(version = "0.0.1", namespace = "academy.training", name = "Counter", displayName = "Dokumentenzähler", description = "Eindeutige Zuweisung von Identifikationsnummern")
public class CounterComponent {
}
# Trigger
Trigger werden zum Aufruf eines Flows verwendet.
Wird eine Komponente in einem Flow als erste Komponente eingesetzt, so stellt sie automatisch in der ELO Flows Administration, Trigger zur Verfügung.
Beachten Sie
Trigger werden immer in der Komponentenklasse definiert.
@Component(version = "0.0.1", namespace = "academy.training", name = "Counter", displayName = "Dokumentenzähler", description = "Eindeutige Zuweisung von Identifikationsnummern")
public class CounterComponent {
@Trigger(displayName="Dokumentenzähler aufrufen")
@WebHook(endpoint="createCounter")
public CounterTriggerData triggerCounter(@Config CounterTriggerData triggerData) {
//Implementierung
}
@Trigger(…)
@Scheduled(…)
public TriggerData otherTrigger(@Config TriggerData triggerData) {
//Implementierung
}
}
# Dienst
Dienste stellen unterschiedliche Funktionalitäten in ELO Flows zur Verfügung. Wird eine Komponente nicht als erste Komponente in ELO Flows verwendet, dann stellt sie unterschiedliche Dienste zur Auswahl bereit. Stehen mehrere Dienste zur Auswahl, so können sie zusätzlich gruppiert werden.
Beachten Sie
Dienste werden in der Komponentenklasse definiert.
@Component(version = "0.0.1", namespace = "academy.training", name = "Counter", displayName = "Dokumentenzähler", description = "Eindeutige Zuweisung von Identifikationsnummern")
public class CounterComponent {
@Service(…)
public ServiceOutputData createCounter(SerivceInputData ) {
//Implementierung
}
}
# Eingabefelder
Die Eingabefelder dienen der Erfassung der Benutzerdaten. Die Felder können von verschiedenem Typ sein und zusätzlich Eingabevorschläge anbieten. Über die Eingabefelder können ebenfalls Daten aus vorhergehenden Komponenten über Schlüssel verwendet werden. Die Eingabefelder werden an einen Dienst @Service
bzw. Trigger @Trigger
übergeben, wo sie für Konfigurationsaufgaben im Ablauf des Flows genutzt werden.
Folgende Typen sind möglich:
- String
- Integer
- Boolean
- Object
- Array
# Eingabefeld String (Text)
Die Eingabefelder für Werte unterschiedlichen Typs beinhalten zusätzlich den Konfigurationsbaum und einen JSONata-Editor.
Um ein Eingabefeld umzusetzen wird eine Klasse deklariert, die Felder über die Annotation @Property
bereitstellt. Diese Klasse wird als Parameter an eine Dienst- bzw. Trigger-Methode übergeben. Der Typ der Variablen (String counterName unter der Annotation @Property
) bestimmt den Typ des Feldes im Editor.
CounterInput.java
public class CounterInput {
@Property(displayName="Zählername" description="Beim neuen Zähler bitte Postfix und Prefix angeben")
private String counterName; // Typ String im Eingabefeldeditor
//Getter- und Settermethoden implementieren
}
CounterComponent.java
@Component(version = "0.0.1", namespace = "academy.training", name = "Counter", displayName = "Dokumentenzähler", description = "Eindeutige Zuweisung von Identifikationsnummern")
public class CounterComponent {
@Service(name="CreateCounter")
public CounterOutput createCounter(CounterInput input) {}
}
# Eingabefeld Integer
Um ein Eingabefeld vom Typ Integer umzusetzen, wird analog zum Eingabefeld String vorgegangen. Der Typ der Variablen, in unserem Beispiel postfix wird vom Typ int
deklariert.
CounterInput.java
public class CounterInput {
@Property(displayName="Postfix")
private int postfix; //Typ Integer im Eingabefeldeditor
//Getter- und Settermethoden implementieren
}
CounterComponent.java
@Component(version = "0.0.1", namespace = "academy.training",
name = "Counter", displayName = "Dokumentenzähler",
description = "Eindeutige Zuweisung von Identifikationsnummern")
public class CounterComponent {
@Service(name="CreateCounter")
public CounterOutput createCounter(CounterInput input) {}
}
# Eingabefeld Boolean
CounterInput.java
public class CounterInput {
@Property(displayName="Zähler importieren")
private boolean importCounter; //Typ Boolean im Eingabefeldeditor
//Getter- und Settermethoden implementieren
}
CounterComponent.java
@Component(version = "0.0.1", namespace = "academy.training",
name = "Counter", displayName = "Dokumentenzähler",
description = "Eindeutige Zuweisung von Identifikationsnummern")
public class CounterComponent {
@Service(name="CreateCounter")
public CounterOutput createCounter(CounterInput input) {}
}
}
# Eingabefeld Object
Werden gleichzeitig mehrere Eingabezeilen (auch mit unterschiedlichen Typen) benötigt, so kann ein Eingabefeld vom Typ Object implementiert werden. Hier können mehrere Felder zu einem Objekt zusammengefasst werden.
Das Beispiel zeigt die Umsetzung der CounterObject Klasse als innere Klasse.
public class CounterInput {
@Property(displayName="Zähler definieren", description="Definieren Sie einen Zähler. Name und initialer Wert")
private CounterObject counterObj;//Typ CounterObject im Eingabefeldeditor
class CounterObject {
@Property(displayName="Initialer Wert", description="Der initiale Wert ist optional. Der Standardwert ist 1"
@DisplayOptions(order = 2, suggestValue = true)
private int value = 1;
@Property(displayName="Zählername", description="Bitte tragen Sie Zählerbezeichnung ein"
@DisplayOptions(order = 1)
private String counterName;
//Getter- und Settermethoden implementieren
}
}
@Component(version = "0.0.1", namespace = "academy.training", name = "Counter", displayName = "Dokumentenzähler", description = "Eindeutige Zuweisung von Identifikationsnummern")
public class CounterComponent {
@Service(name="CreateCounter")
public CounterOutput createCounter(CounterInput input) {}
}
# Eingabefeld Array
Werden von einem Typ (String, Boolean, Integer oder Objekt) mehrere Felder benötigt, so können diese zu einem Array zusammengefasst werden. In dem unten aufgeführten Beispiel werden mehrere Objekteingabefelder gruppiert.
public class CounterInput {
@Property(displayName="Zähler definieren", description="Definieren Sie einen Zähler mit Name und initialen Wert")
private CounterObject[] counterObjects;//Typ CounterObject[] im Eingabefeldeditor
class CounterObject {
//siehe Eingabefeld Object
}
}
# Pflichtfelder
Alle Eingabefelder können als Pflichtfelder gekennzeichnet werden. Dabei wird der Bezeichner des Feldes mit einem Stern (*) markiert. Dadurch kann auch die gesamte Eingabemaske nicht verlassen werden, wenn die Eingaben fehlen.
Durch das Setzen des Attributes required
auf true
in der Property
Annotation, wird programmtechnisch das Feld als Pflichtfeld markiert.
@Property(displayName="Zählername" description="Beim neuen Zähler bitte
Postfix und Prefix angeben", required=true)
private String counterName; // Typ String im Eingabefeldeditor
# Reihenfolge, Vorbelegung der Felder
Über die Annotation @DisplayOptions
können die Felder zusätzlich konfiguriert werden. Hier kann z. B. die Vorbelegung (suggestValue) bzw. die Reihenfolge (order) der Felder gesetzt werden.
@Property(displayName="Postfix")
@DisplayOptions(order=2, suggestValue=true)
private int postfix = 6;
@Property(displayName="Prefix")
@DisplayOptions(order=1, size=2)
private String prefix = "Rechnung";
# Tab 'Vorschläge'
In allen Eingabefeldern können Vorschlaglisten über die Annotationen @Lookup
und @LookupProvider
gefüllt werden. Die Implementierung der Funktion mit der Annotation @LookupProvider
muss in der Hauptkomponentenklasse @Component
umgesetzt sein.
public class CounterInput {
@Property(displayName = "Zählername", required=true)
@Lookup("getCounters")
private String counterName;
}
@Component(version = "0.0.1", namespace = "academy.training", name = "Counter", displayName = "Dokumentenzähler", description = "Eindeutige Zuweisung von Identifikationsnummern")
public class CounterComponent {
@LookupProvider("getCounters")
public Map<String,String> getCounters() throws CounterException {
HashMap<String,String> map = new HashMap<>();
//Implementierung
return map;
}
}
# Feldergruppen
Die Eingabefelder können zu Gruppen thematisch zusammengefasst werden. In der Abbildung wurden die Felder Prefix und Postfix in der Gruppe Neuer Zähler zusammengefasst.
Um die Gruppierung von Eingabefelder zu erreichen, wird die Klassendeklaration um die Annotationen @PropertyGroups
und @PropertyGroup
erweitert. Die Felder, die zu einer Gruppe zusammengefasst werden, werden zusätzlich um die Annotation @PropertyGroupRef
mit dem entsprechenden Gruppennamen erweitert.
@PropertyGroups(@PropertyGroup(displayName="Neuer Zähler", name="counterGroup"))
public class CounterInput {
@Property(displayName = "Zählername", required = true, description = "Bitte wählen Sie einen Zählername aus")
@Lookup("getCounters")
private String counterName;
@Property(displayName = "Prefix", description = "Nur in Verbindung mit Zählername")
@PropertyGroupRef("countergroup")
@DisplayOptions(order = 1)
private String prefix;
@Property(displayName = "Postfix", description = "Nur in Verbindung mit Zählername")
@PropertyGroupRef("countergroup")
@DisplayOptions(order = 2, suggestValue = true)
private int postfix = 6;
}
# Dienstgruppen
Verschiedene Dienste, siehe auch die ELO Objekte & Metadaten-Komponente, können in Gruppen zusammengefasst werden.
Um die Gruppierung der Dienste zu erreichen, werden die Dienste in einzelnen Klassen implementiert, die um die Annotation @ComponentServices
erweitert werden. Damit die Gruppen angezeigt werden, müssen mindestens zwei Gruppen definiert sein (d.h. zwei Klassen mit @ComponentServices
und darin enthaltenen @Services
). Die Annotation @ComponentServices
muss immer über das Attribut component
auf die Komponentenhauptklasse (hier CounterComponent
) verweisen.
@Component(version = "0.0.1", namespace = "academy.training", name = "Counter", displayName = "Dokumentenzähler", description = "Eindeutige Zuweisung von Identifikationsnummern")
public class CounterComponent {
}
@ComponentServices(component = CounterComponent.class, name = "CounterServices", displayName = "Verwalten der Zähler")
public class CounterServices {
@Service(name="CreateCounter")
public CounterOutput createCounter(CounterInput input) {}
@Service(name="ChooseCounter")
public CounterOutput chooseCounter(CounterInput input) {}
}
@ComponentServices(component = CounterComponent.class, name = "CounterServices", displayName = "Import der Zähler")
public class CounterServicesImportGroup {
@Service(name="ImportCounter")
public CounterImportOutput importCounter(CounterImportInput input) {}
@Service(name="FindImportCounter")
public CounterImportOutput findImportCounter(CounterImportInput input) {}
}
# Indexserververbindung
Die Verbindung zum ELO Indexserver kann automatisch über die Annotation @Connection
und @ConnectionRequired
hergestellt werden.
Über die Annotation @Connection
in der Variablen vom Typ IXConnection wird die Verbindung zum ELOix in einer Klasse deklariert und kann über die Annotation @ConnectionRequired
in jeder Methode verwendet werden.
public class CounterComponent {
@Connection
IXConnection ixConnect;
@LookupProvider("getCounters")
@ConnectionRequired
public Map<String,String> getCounters() {
HashMap<String,String> map = new HashMap<>();
//Implementierung
return map;
}
}
# Komponenteninformation
Die Dokumentation kann über die Annotaion @Guide
an verschiedenen Stellen, z. B. Dienst- oder Komponentenbeschreibung, eingebunden werden. Dafür ist zunächst in der entsprechenden Projektstruktur die relevante Markdown-Datei abzulegen, auf die später in der Implementierung der Lösung verwiesen wird.
Beachten Sie
Die Markdown-Dateien werden in der dafür vorgesehenen Projektstruktur (siehe Abbildung) abgelegt. Ansonsten kann die Dokumentation nicht gelesen und angezeigt werden.
Folgende Kombinationsmöglichkeiten sind mit anderen Annotationen möglich:
Informationen über eine Komponente (
@Component
und@Guide
). Sie sind sowohl in der Dienste- als auch in Trigger-Auswahlansicht sichtbar.Informationen über einen Dienst (
@Service
und@Guide
).Informationen über einen Trigger (
@Trigger
und@Guide
)