Thema dieser Dokumentation / Das FirstSpirit 5 Modul- / Komponenten-Modell / Von Gadgets, Aspects, Brokern und Agents / Agents / Das Interface WorkflowAgent (Starten und Schalten von Arbeitsabläufen)
Das Interface WorkflowAgent (Starten und Schalten von Arbeitsabläufen)
Das nachfolgend vorgestellte Interface ist Bestandteil der FirstSpirit Access-API. |
Package: de.espirit.firstspirit.workflow
Ein Arbeitsablauf ist eine Abfolge von Aufgaben, die nach einer fest vorgegebenen Struktur abgearbeitet werden. Für die jeweiligen Aufgaben können sowohl Fälligkeitszeitpunkte als auch berechtigte Personengruppen festgelegt werden. In FirstSpirit integrierte Arbeitsabläufe sind die Aufgabenerteilung und die Freigabeanforderung.
Mithilfe eines grafischen Arbeitsablauf-Editors können projektspezifische Arbeitsabläufe in der Vorlagen-Verwaltung des FirstSpirit SiteArchitects erstellt werden. Instanzen dieser Arbeitsabläufe können anschließend kontextgebunden auf jedem Element innerhalb des FirstSpirit-Projekts oder kontextlos über die FirstSpirit-Menüleiste gestartet werden. Das Starten und Schalten eines Arbeitsablaufs ist manuell (durch einen Redakteur) über den FirstSpirit SiteArchitect und den FirstSpirit ContentCreator möglich. Jede Instanz eines Arbeitsablaufs muss entsprechend der im Arbeitsablauf festgelegten Regeln durchlaufen werden.
Ab FirstSpirit 5.0R2 ist das Starten und Schalten eines Arbeitsablaufs auch über die FirstSpirit-Access-API möglich. Damit können Instanzen eines Arbeitsablaufs sowohl über Skripte innerhalb des FirstSpirit SiteArchitects oder des FirstSpirit ContentCreators als auch serverseitig über Auftragsskripte (z. B. vor einer Generierung) oder über eine externe Implementierung innerhalb eines FirstSpirit-Moduls durchlaufen werden.
Zum Starten und Schalten eines Arbeitsablaufs wird eine Instanz vom Typ WorkflowAgent benötigt. Eine Instanz vom Typ WorkflowAgent kann über einen (projektgebundenen) SpecialistsBroker (Das Interface SpecialistsBroker siehe Das Interface SpecialistsBroker) mithilfe der Methode requireSpecialist(WorkflowAgent.TYPE) angefordert werden:
Listing: Arbeitsabläufe starten und schalten - WorkflowAgent anfordern
BaseContext context;
final WorkflowAgent workflowAgent =
context.getBroker().requireSpecialist(WorkflowAgent.TYPE);
Das Interface bietet den Zugriff auf folgende Methoden:
WorkflowProcessContext startWorkflow(final Workflow workflow): Mithilfe der Methode kann der übergebene Workflow ohne Kontext gestartet werden. Beim Ausführen erzeugt die Methode intern einen Task. Die Methode liefert eine Instanz vom Typ WorkflowProcessContext zurück (s.u.).
WorkflowProcessContext startWorkflow(final Workflow workflow, final IDProvider element): Mithilfe der Methode kann der übergebene Workflow auf dem übergebenen Objekt vom Typ IDProvider gestartet werden. Beim Ausführen erzeugt die Methode intern einen Task. Die Methode liefert eine Instanz vom Typ WorkflowProcessContext zurück (s.u.).
WorkflowProcessContext process(Task task, Transition transition): Mithilfe der Methode kann ein bereits gestarteter Arbeitsablauf weitergeschaltet werden. Dazu muss der aktuelle Task aus der zuletzt verwendeten Instanz vom Typ WorkflowProcessContext und eine zu schaltende Transition übergeben werden. Bei der Transition muss es sich um eine ausgehende Transition des aktuellen Workflow-Status handeln, die über die Methode task.getTaskState().getModelState().getTargetTransitions() ermittelt werden kann.
Jede dieser Methoden liefert eine Instanz vom Typ WorkflowProcessContext zurück, das die nächste manuelle Aktivität innerhalb des Workflow-Modells repräsentiert. Das Interface WorkflowProcessContext stellt Methoden zur Verfügung, um diese Aktivität abzuarbeiten. Jede Instanz vom Typ WorkflowProcessContext kann nur für einen Schaltvorgang (über die Methode doTransition()) verwendet werden. Danach wird sie als beendet markiert (isActivityProcessed). Das bedeutet, dass nach jedem Schalten einer Transition (sofern nicht bereits der End-Status oder der Fehler-Status des Arbeitsablaufs erreicht wurde), eine neue Instanz vom Typ WorkflowProcessContext geholt werden muss, um die nächste Transition schalten zu können (siehe Beispielskript).
Automatische Aktivitäten müssen auch über die FirstSpirit-API nicht explizit geschaltet werden, sondern werden automatisch in den Status geschaltet, der dieser automatischen Aktivität nachfolgt.
Weiterführende Informationen zum Interface WorkflowAgent und zum Interface WorkflowProcessContext siehe FirstSpirit-Access-API.
Workflow-Modell für den Arbeitsablauf „Freigabe anfordern“:
Beispiel – Starten und Schalten des Arbeitsablaufs „Freigabe anfordern“:
//!Beanshell
import de.espirit.firstspirit.workflow.WorkflowAgent;
import de.espirit.firstspirit.agency.StoreAgent;
import de.espirit.firstspirit.workflow.WorkflowProcessContext;
import de.espirit.firstspirit.access.store.Store;
storeAgent = context.requireSpecialist(StoreAgent.TYPE);
wf = storeAgent.getStore(Store.Type.TEMPLATESTORE)
.getWorkflowByName("Freigabe Anfordern");
homepage = storeAgent.getStore(Store.Type.PAGESTORE, false)
.getStoreElement(6215800);
agent = context.requireSpecialist(WorkflowAgent.TYPE);
// START WORKFLOW
process = agent.startWorkflow(wf, homepage);
task = process.getTask();
for (transition:process.getTransitions()){
if (transition.getUid().equals("Anfordern")){
print("\t" + "State: " + task.getTaskState().getModelState());
print("\t" + "Activity: " + task.getTaskState().getModelActivity());
print("\t" + "Outgoing transitions from current activity: " +
process.getTransitions());
print("\t" + "Do transition from current activity to next state:" +
transition);
print ("\t" + "Is first activity processed?: " +
process.isActivityProcessed());
//DO TRANSITION
process.doTransition(transition);
break;
}
}
//CREATE NEW PROCESS OBJECT
nextProcess = agent.process(task, task.getTaskState().getModelState()
.getTargetTransitions().get(0));
task = nextProcess.getTask();
for (transition:nextProcess.getTransitions()){
if (transition.getUid().equals("Nicht erteilen")){
print("\t" + "State: " + task.getTaskState().getModelState());
print("\t" + "Activity: " + task.getTaskState().getModelActivity());
print("\t" + "Outgoing Transitions from current activity: " +
nextProcess.getTransitions());
print("\t" + "Do transition from current activity to next state: " +
transition);
print ("\t" + "Is first activity processed?: " +
process.isActivityProcessed());
print ("\t" + "Is second activity processed?: " +
nextProcess.isActivityProcessed());
//DO NEXT TRANSITION
nextProcess.doTransition(transition);
break;
}
}
Zunächst wird der Arbeitsablauf „Freigabe anfordern“, die Seite „homepage“, auf der der Arbeitsablauf gestartet werden soll, und ein Spezialist vom Typ WorkflowAgent geholt. Anschließend wird der Arbeitsablauf über die Methode WorkflowProcessContext startWorkflow(final Workflow workflow, final IDProvider element) gestartet. Der Arbeitsablauf hat nach dem Ausführen der Methode den Status „Objekt verändert“ bereits verlassen (die erste Transition wurde also bereits geschaltet (siehe Grafik – Punkt 1).
Die zurückgelieferte Instanz vom Typ WorkflowProcessContext repräsentiert die nächste manuelle Aktivität „Freigabe anfordern“ des Arbeitsablaufs. Die Aktivität wurde noch nicht abgearbeitet (d.h. process.isActivityProcessed() liefert false) und damit ist der Aufruf der Methode process.doTransition(transition) auf der Instanz möglich.
Logausgabe VOR dem Schalten der ersten Transition:
State: Objekt verändert
Activity: null
Outgoing transitions from current activity: [Anfordern, Direkt freigeben]
Do transition from current activity to next state: Anfordern
Is first activity processed?: false
Im nächsten Schritt wird der Arbeitsablauf über die Methode process.doTransition(transition) weitergeschaltet.
Hinweis: Um den nächsten Status „Freigabe angefordert“ zu erreichen, muss immer eine Transition übergeben werden, die der abzuarbeitenden Aktivität nachfolgt. Für die Aktivität „Freigabe anfordern“ ist das also entweder die Transition [Anfordern] (im Beispiel gewählt) oder die Transition [Direkt freigeben]. Der intern erzeugte Task befindet sich nach dem Starten des Arbeitsablaufs noch im Status „Objekt verändert“, da die nachfolgende Aktivität noch nicht abgearbeitet wurde. Die Ziel-Transitionen können damit nicht über den intern erzeugten Task ermittelt werden (task.getTaskState().getModelState().getTargetTransitions()), sondern nur über die Methode process.getTransitions(), die die ausgehenden Transitionen der Aktivität zurückliefert (vgl. Logausgaben).
Logausgabe NACH dem Schalten der Transition:
State: Freigabe angefordert
Activity: Freigabe anfordern
Outgoing Transitions from current activity: [Nicht erteilen, Erteilen]
Do transition from current activity to next state: Nicht erteilen
Is first activity processed?: true
Is second activity processed?: false
Nach dem Aufruf der Methode process.doTransition(transition) hat der intern erzeugte Task den Status „Freigabe angefordert“ bereits verlassen (die Transition „Prüfen“ wurde also bereits geschaltet (siehe Grafik – Punkt 2).
Für das Abarbeiten einer weiteren Aktivität (bzw. für das Schalten einer nachfolgenden Transition) muss über den WorkflowAgent eine neue Instanz vom Typ WorkflowProcessContext geholt werden:
nextProcess = agent.process(task, task.getTaskState().getModelState()
.getTargetTransitions().get(0));
Dazu wird der Task der zuvor ausgeführten Aktivität übergeben und die ausgehende Transition des aktuell erreichten Status, die ebenfalls über den Task der zuvor ausgeführten Aktivität ermittelt werden kann:
(task.getTaskState().getModelState().getTargetTransitions().get(0))