Startseite / Vorlagen (Grundlagen) / Aufbau von Vorlagen / Arbeitsabläufe / Programmatische Verwendung

Programmatische VerwendungVerfügbar ab FirstSpirit-Version 5.0R2

Das Starten und Schalten eines Arbeitsablaufs ist auch über die FirstSpirit-Access-API möglich. Damit können Instanzen eines Arbeitsablaufs sowohl über Skripte innerhalb des FirstSpirit SiteArchitect oder des FirstSpirit ContentCreator als auch serverseitig über Auftragsskripte (z. B. vor einer Generierung) oder über eine externe Implementierung innerhalb eines FirstSpirit-Moduls durchlaufen werden.

Der WorkflowAgent

Interface: de.espirit.firstspirit.workflow.WorkflowAgent
Access-API-Dokumentation: WorkflowAgent

Zum Starten und Schalten eines Arbeitsablaufs wird eine Instanz vom Typ WorkflowAgent benötigt. Eine solche Instanz kann über einen projektgebundenen SpecialistsBroker (oder Erweiterungen des Interfaces, z. B. BaseContext) mithilfe der Methoden requestSpecialist(SpecialistType) bzw. requireSpecialist(SpecialistType) angefordert werden (zu Unterschieden zwischen diesen Methoden siehe FirstSpirit-Funktionalität verwenden / Agents anfragen). Als Parameter wird hierbei der entsprechende SpecialistType, hier die Konstante WorkflowAgent.TYPE, angegeben.

import de.espirit.firstspirit.workflow.WorkflowAgent;

// The variable 'context' used below is of type de.espirit.firstspirit.access.BaseContext,
// an extension interface of the interface de.espirit.firstspirit.agency.SpecialistsBroker.

final WorkflowAgent workflowAgent = context.requireSpecialist(WorkflowAgent.TYPE);

Einen Arbeitsablauf starten

Arbeitsabläufe können je nach Verwendungszweck kontextgebunden (auf einem Store-Element operierend) oder kontextlos gestartet werden.

Kontextlose Arbeitsabläufe
WorkflowProcessContext WorkflowAgent#startWorkflow(Workflow)

Ein kontextloser Arbeitsablauf kann über die Methode startWorkflow(Workflow) gestartet werden. Beim Ausführen erzeugt die Methode intern einen Task. Die Methode liefert eine Instanz vom Typ WorkflowProcessContext zurück.

Kontextgebundene Arbeitsabläufe
WorkflowProcessContext WorkflowAgent#startWorkflow(Workflow, IDProvider)

Ein kontextgebundener (d.h., auf einem Element vom Typ IDProvider operierender) Arbeitsablauf kann über die Methode startWorkflow(Workflow, IDProvider) gestartet werden. Beim Ausführen erzeugt die Methode intern einen Task. Die Methode liefert eine Instanz vom Typ WorkflowProcessContext zurück.

Einen Arbeitsablauf schalten

Ein bereits gestarteter Arbeitsablauf kann über den WorkflowAgent weitergeschaltet werden.

Arbeitsablauf weiterschalten
WorkflowProcessContext WorkflowAgent#process(Task, Transition)

Zum Weiterschalten eines bereits gestarteten Arbeitsablaufs muss dieser Methode der aktuelle Task aus der zuletzt verwendeten WorkflowProcessContext-Instanz und die zu schaltende Transition als Parameter übergeben werden. Bei der Transition muss es sich um eine vom aktuellen Workflow-Status ausgehende Transition handeln, die über die Methode Task#getTaskState().getModelState().getTargetTransitions() ermittelt werden kann.

Der WorkflowProcessContext

Interface: de.espirit.firstspirit.workflow.WorkflowAgent$WorkflowProcessContext
Access-API-Dokumentation: WorkflowProcessContext

Die oben genannten Methoden liefern jeweils eine Instanz vom Typ WorkflowProcessContext zurück, das eine manuelle Aktivität innerhalb des Workflow-Modells repräsentiert. Das Interface stellt Methoden zur Verfügung, um diese Aktivität abzuarbeiten.

Jede Instanz dieses Typs kann nur für einen Schaltvorgang (über die Methode doTransition(Transition)) verwendet werden, danach wird sie als beendet markiert (isActivityProcessed()). Dies bedeutet, dass nach jedem Schalten einer Transition (sofern nicht bereits der Endstatus oder der Fehlerstatus des Arbeitsablaufs erreicht wurde) eine neue Instanz vom Typ WorkflowProcessContext eingeholt werden muss, um die nächste Transition schalten zu können.

Wichtig Automatische Aktivitäten müssen auch über die FirstSpirit-API nicht explizit geschaltet werden, sondern werden automatisch in den Status geschaltet, der der jeweiligen automatischen Aktivität nachfolgt.

Beispiel

Das folgende Beispiel illustriert einen Code-Fluss, der einen Arbeitsablauf „Freigabe Anfordern“ auf einem FirstSpirit-Element startet und die Transitionen vom Ausgangsstatus „Objekt verändert“ bis hin zum Zielstatus „Objekt nicht freigegeben“ schaltet.

Wichtig Das unten angeführte Script-Beispiel verwendet die Standard-Arbeitsabläufe, die in ein neu erstelltes FirstSpirit-Projekt installiert werden können. Der Standard-Freigabe-Arbeitsablauf verwendet deutschsprachige Referenznamen wie z.B. "Freigabe Anfordern" und "anfordern", welche im Script-Beispiel unten erscheinen.

Das Script kann als Menü-Script konfiguriert werden und nimmt an, dass in der Inhalte-Verwaltung ein Seiten-Element mit dem Referenznamen example_page existiert.
//!Beanshell

import de.espirit.firstspirit.workflow.WorkflowAgent;
import de.espirit.firstspirit.agency.StoreAgent;
import de.espirit.firstspirit.access.store.IDProvider;
import de.espirit.firstspirit.access.store.Store;

storeAgent = context.requireSpecialist(StoreAgent.TYPE);
workflowAgent = context.requireSpecialist(WorkflowAgent.TYPE);

pageElement = storeAgent.getStore(Store.Type.PAGESTORE, false)
.getStoreElement("example_page", IDProvider.UidType.PAGESTORE);

releaseWorkflow = storeAgent.getStore(Store.Type.TEMPLATESTORE)
.getWorkflowByName("Freigabe Anfordern");

// START A WORKFLOW

// Obtain a first workflow process context object.
firstWorkflowProcessContext = workflowAgent.startWorkflow(releaseWorkflow, pageElement);
task = firstWorkflowProcessContext.getTask();

print ("=== FIRST Workflow Process Context ===");

for (transition : firstWorkflowProcessContext.getTransitions()) {
if ("anfordern".equals(transition.getUid())) {
// We're only going to work with the transition named "anfordern".
// If we found it, output some info about the current state to the console:

print ("State: " + task.getTaskState().getModelState());
print ("Activity: " + task.getTaskState().getModelActivity());
print ("Outgoing transitions from current activity: "+ firstWorkflowProcessContext.getTransitions());
print ("Transition from current activity to next state (selected by script): " + transition);
print ("Is first activity processed? " + firstWorkflowProcessContext.isActivityProcessed());

// Do transition
firstWorkflowProcessContext.doTransition(transition);

break;
}
}

// ADVANCE A WORKFLOW

// Obtain a new workflow process context object by processing the transition "prüfen",
// which is available on the state "Freigabe angefordert".
secondWorkflowProcessContext = workflowAgent.process(task,
task.getTaskState().getModelState().getTargetTransitions().get(0));
task = secondWorkflowProcessContext.getTask();

print ("=== SECOND Workflow Process Context ===");

for (transition : secondWorkflowProcessContext.getTransitions()) {
if ("nicht erteilen".equals(transition.getUid())) {
// We're only going to work with the transition named "nicht erteilen".
// If we found it, output some info about the current state to the console:

print ("State: " + task.getTaskState().getModelState());
print ("Activity: " + task.getTaskState().getModelActivity());
print ("Outgoing transitions from current activity: "+ secondWorkflowProcessContext.getTransitions());
print ("Transition from current activity to next state (selected by script): " + transition);
print ("Is first activity processed? " + firstWorkflowProcessContext.isActivityProcessed());
print ("Is second activity processed? " + secondWorkflowProcessContext.isActivityProcessed());

// Do transition
secondWorkflowProcessContext.doTransition(transition);

break;
}
}

Zunächst werden der Arbeitsablauf „Freigabe Anfordern“, eine Seite mit UID example_page, auf der der Arbeitsablauf gestartet werden soll, und ein Spezialist vom Typ WorkflowAgent eingeholt. Anschliessend wird der Arbeitsablauf über die Methode workflowAgent.startWorkflow(Workflow, IDProvider) gestartet. Der Arbeitsablauf hat nach dem Ausführen der Methode den Status „Objekt verändert“ bereits verlassen (die erste Transition hin zur Aktivität „Freigabe anfordern“ wurde also bereits automatisch geschaltet).

Die zurückgelieferte Instanz vom Typ WorkflowProcessContext (Variable firstWorkflowProcessContext) repräsentiert die nächste manuelle Aktivität „Freigabe anfordern“ des Arbeitsablaufs. Diese Aktivität wurde noch nicht abgearbeitet (d.h., firstWorkflowProcessContext.isActivityProcessed() liefert false), somit ist der Aufruf der Methode firstWorkflowProcessContext.doTransition(Transition) auf der Instanz möglich.

Logausgabe vor dem Schalten der Transition „anfordern“:

=== FIRST Workflow Process Context ===
State: Objekt verändert
Activity: null
Outgoing transitions from current activity: [anfordern]
Transition from current activity to next state (selected by script): anfordern
Is first activity processed? false

Im nächsten Schritt wird der Arbeitsablauf über die Methode firstWorkflowProcessContext.doTransition(Transition) in den Status „Freigabe angefordert“ weitergeschaltet.

Wichtig Um von der aktuellen Aktivität einen nächsten Status zu erreichen, muss immer eine Transition übergeben werden, die die abzuarbeitende Aktivität und den erwünschten nächsten Status verbindet. In diesem Beispiel muss zum Erreichen des Status „Freigabe angefordert“ von der Aktivität „Freigabe anfordern“ aus die Transition „anfordern“ gewählt werden.

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 verfügbaren Transitionen können zu diesem Zeitpunkt nicht über den intern erzeugten Task ermittelt werden (task.getTaskState().getModelState().getTargetTransitions()), sondern müssen über den aktuellen WorkflowProcessContext (firstWorkflowProcessContext.getTransitions()) abgefragt werden.

Der Status „Freigabe angefordert“ hat nur eine ausgehende Transition, „prüfen“, welche zur Aktivität „Freigabe prüfen“ führt. Diese Transition wird über die Methode workflowAgent.process(task, task.getTaskState().getModelState().getTargetTransitions().get(0)) geschaltet.

Das nach der Verarbeitung der Transition „prüfen“ zurückgegebene WorkflowProcessContext-Objekt wird als Variable secondWorkflowProcessContext vorgehalten, und aus diesem können nun Informationen zur aktuellen (noch nicht abgearbeiteten) Aktivität „Freigabe prüfen“ ausgelesen werden.

Logausgabe nach dem Schalten der Transition „prüfen“:

=== SECOND Workflow Process Context ===
State: Freigabe angefordert
Activity: Freigabe anfordern
Outgoing transitions from current activity: [nicht erteilen, erteilen]
Transition from current activity to next state (selected by script): nicht erteilen
Is first activity processed? true
Is second activity processed? false

© 2005 - 2024 Crownpeak Technology GmbH | Alle Rechte vorbehalten. | FirstSpirit 2024.5 | Datenschutz