1616package io .serverlessworkflow .utils ;
1717
1818import io .serverlessworkflow .api .Workflow ;
19- import io .serverlessworkflow .api .end .End ;
19+ import io .serverlessworkflow .api .actions .Action ;
20+ import io .serverlessworkflow .api .branches .Branch ;
2021import io .serverlessworkflow .api .events .EventDefinition ;
2122import io .serverlessworkflow .api .interfaces .State ;
2223import io .serverlessworkflow .api .start .Start ;
23- import io .serverlessworkflow .api .states .CallbackState ;
24- import io .serverlessworkflow .api .states .DefaultState ;
25- import io .serverlessworkflow .api .states .EventState ;
26- import io .serverlessworkflow .api .states .SwitchState ;
27- import java .util .ArrayList ;
28- import java .util .HashSet ;
29- import java .util .List ;
30- import java .util .Set ;
24+ import io .serverlessworkflow .api .states .*;
25+ import java .util .*;
3126import java .util .stream .Collectors ;
3227
3328/** Provides common utility methods to provide most often needed answers from a workflow */
3429public final class WorkflowUtils {
3530 private static final int DEFAULT_STARTING_STATE_POSITION = 0 ;
3631
3732 /**
38- * Gets State matching Start state.If start is not present returns first state otherwise returns
39- * null
33+ * Gets State matching Start state. If start is not present returns first state. If start is
34+ * present, returns the matching start State. If matching state is not present, returns null
4035 *
4136 * @param workflow workflow
4237 * @return {@code state} when present else returns {@code null}
4338 */
4439 public static State getStartingState (Workflow workflow ) {
45- if (workflow == null || workflow . getStates () == null || workflow . getStates (). isEmpty ( )) {
40+ if (! hasStates ( workflow )) {
4641 return null ;
4742 }
4843
4944 Start start = workflow .getStart ();
5045 if (start == null ) {
5146 return workflow .getStates ().get (DEFAULT_STARTING_STATE_POSITION );
5247 } else {
53- return workflow .getStates ().stream ()
54- .filter (state -> state .getName ().equals (start .getStateName ()))
55- .findFirst ()
56- .get ();
48+ Optional <State > startingState =
49+ workflow .getStates ().stream ()
50+ .filter (state -> state .getName ().equals (start .getStateName ()))
51+ .findFirst ();
52+ return startingState .orElse (null );
5753 }
5854 }
5955
@@ -65,7 +61,7 @@ public static State getStartingState(Workflow workflow) {
6561 * @return {@code List<State>}. Returns {@code null} when workflow is null.
6662 */
6763 public static List <State > getStates (Workflow workflow , DefaultState .Type stateType ) {
68- if (workflow == null || workflow . getStates () == null ) {
64+ if (! hasStates ( workflow ) ) {
6965 return null ;
7066 }
7167
@@ -99,14 +95,11 @@ public static List<EventDefinition> getDefinedProducedEvents(Workflow workflow)
9995 */
10096 public static List <EventDefinition > getDefinedEvents (
10197 Workflow workflow , EventDefinition .Kind eventKind ) {
102- if (workflow == null || workflow .getEvents () == null ) {
103- return null ;
104- }
105- List <EventDefinition > eventDefs = workflow .getEvents ().getEventDefs ();
106- if (eventDefs == null ) {
98+ if (!hasEventDefs (workflow )) {
10799 return null ;
108100 }
109101
102+ List <EventDefinition > eventDefs = workflow .getEvents ().getEventDefs ();
110103 return eventDefs .stream ()
111104 .filter (eventDef -> eventDef .getKind () == eventKind )
112105 .collect (Collectors .toList ());
@@ -141,27 +134,13 @@ public static List<EventDefinition> getWorkflowConsumedEvents(Workflow workflow)
141134
142135 /**
143136 * Gets Produced Events of parent workflow Iterates through states in parent workflow and collects
144- * all the Produced Events.
137+ * all the ConsumedEvents. Sub Workflows of the Workflow <strong>are not</strong> considered for
138+ * getting Consumed Events
145139 *
146140 * @return Returns {@code List<EventDefinition>}
147141 */
148142 public static List <EventDefinition > getWorkflowProducedEvents (Workflow workflow ) {
149- if (workflow == null || workflow .getStates () == null || workflow .getStates ().size () == 0 ) {
150- return null ;
151- }
152- List <EventDefinition > definedProducedEvents =
153- getDefinedEvents (workflow , EventDefinition .Kind .PRODUCED );
154- Set <String > uniqueEvents = new HashSet <>();
155- for (State state : workflow .getStates ()) {
156- End end = state .getEnd ();
157- if (end != null && end .getProduceEvents () != null && end .getProduceEvents ().size () != 0 ) {
158- end .getProduceEvents ()
159- .forEach (produceEvent -> uniqueEvents .add (produceEvent .getEventRef ()));
160- }
161- }
162- return definedProducedEvents .stream ()
163- .filter (eventDefinition -> uniqueEvents .contains (eventDefinition .getName ()))
164- .collect (Collectors .toList ());
143+ return getWorkflowEventDefinitions (workflow , EventDefinition .Kind .PRODUCED );
165144 }
166145
167146 /**
@@ -172,21 +151,21 @@ public static List<EventDefinition> getWorkflowProducedEvents(Workflow workflow)
172151 */
173152 private static List <EventDefinition > getWorkflowEventDefinitions (
174153 Workflow workflow , EventDefinition .Kind eventKind ) {
175- if (workflow == null || workflow . getStates () == null || workflow . getStates (). size () == 0 ) {
154+ if (! hasStates ( workflow ) ) {
176155 return null ;
177156 }
157+
158+ List <String > uniqueWorkflowEventsFromStates = getUniqueWorkflowEventsFromStates (workflow );
178159 List <EventDefinition > definedConsumedEvents = getDefinedEvents (workflow , eventKind );
179- if (definedConsumedEvents == null ) return null ;
180- Set <String > uniqEventReferences = new HashSet <>();
181- List <String > eventReferencesFromState = getWorkflowConsumedEventsFromState (workflow );
182- uniqEventReferences .addAll (eventReferencesFromState );
183160 return definedConsumedEvents .stream ()
184- .filter (x -> uniqEventReferences .contains (x .getName ()))
161+ .filter (definedEvent -> uniqueWorkflowEventsFromStates .contains (definedEvent .getName ()))
185162 .collect (Collectors .toList ());
186163 }
187164
188- private static List <String > getWorkflowConsumedEventsFromState (Workflow workflow ) {
165+ /** Returns a list of unique event names from workflow states */
166+ private static List <String > getUniqueWorkflowEventsFromStates (Workflow workflow ) {
189167 List <String > eventReferences = new ArrayList <>();
168+
190169 for (State state : workflow .getStates ()) {
191170 if (state instanceof SwitchState ) {
192171 SwitchState switchState = (SwitchState ) state ;
@@ -198,16 +177,46 @@ private static List<String> getWorkflowConsumedEventsFromState(Workflow workflow
198177 } else if (state instanceof CallbackState ) {
199178 CallbackState callbackState = (CallbackState ) state ;
200179 if (callbackState .getEventRef () != null ) eventReferences .add (callbackState .getEventRef ());
180+ if (callbackState .getAction () != null && callbackState .getAction ().getEventRef () != null ) {
181+ eventReferences .addAll (getActionEvents (callbackState .getAction ()));
182+ }
201183 } else if (state instanceof EventState ) {
202184 EventState eventState = (EventState ) state ;
203185 if (eventState .getOnEvents () != null ) {
204186 eventState
205187 .getOnEvents ()
206- .forEach (onEvents -> eventReferences .addAll (onEvents .getEventRefs ()));
188+ .forEach (
189+ onEvents -> {
190+ eventReferences .addAll (onEvents .getEventRefs ());
191+ if (onEvents .getActions () != null ) {
192+ for (Action action : onEvents .getActions ()) {
193+ eventReferences .addAll (getActionEvents (action ));
194+ }
195+ }
196+ });
197+ }
198+ } else if (state instanceof OperationState ) {
199+ OperationState operationState = (OperationState ) state ;
200+ if (operationState .getActions () != null ) {
201+ for (Action action : operationState .getActions ()) {
202+ eventReferences .addAll (getActionEvents (action ));
203+ }
204+ }
205+ } else if (state instanceof ParallelState ) {
206+ ParallelState parallelState = (ParallelState ) state ;
207+ if (parallelState .getBranches () != null ) {
208+ for (Branch branch : parallelState .getBranches ()) {
209+ if (branch .getActions () != null ) {
210+ for (Action action : branch .getActions ()) {
211+ eventReferences .addAll (getActionEvents (action ));
212+ }
213+ }
214+ }
207215 }
208216 }
209217 }
210- return eventReferences ;
218+
219+ return eventReferences .stream ().distinct ().collect (Collectors .toList ());
211220 }
212221
213222 /**
@@ -227,4 +236,33 @@ public static int getWorkflowProducedEventsCount(Workflow workflow) {
227236 List <EventDefinition > workflowProducedEvents = getWorkflowProducedEvents (workflow );
228237 return workflowProducedEvents == null ? 0 : workflowProducedEvents .size ();
229238 }
239+
240+ /** Returns true if workflow has states, otherwise false */
241+ private static boolean hasStates (Workflow workflow ) {
242+ return workflow != null && workflow .getStates () != null && !workflow .getStates ().isEmpty ();
243+ }
244+
245+ /** Returns true if workflow has events definitions, otherwise false */
246+ private static boolean hasEventDefs (Workflow workflow ) {
247+ return workflow != null
248+ && workflow .getEvents () != null
249+ && workflow .getEvents ().getEventDefs () != null
250+ && !workflow .getEvents ().getEventDefs ().isEmpty ();
251+ }
252+
253+ /** Gets event refs of an action */
254+ private static List <String > getActionEvents (Action action ) {
255+ List <String > actionEvents = new ArrayList <>();
256+
257+ if (action != null && action .getEventRef () != null ) {
258+ if (action .getEventRef ().getTriggerEventRef () != null ) {
259+ actionEvents .add (action .getEventRef ().getTriggerEventRef ());
260+ }
261+ if (action .getEventRef ().getResultEventRef () != null ) {
262+ actionEvents .add (action .getEventRef ().getResultEventRef ());
263+ }
264+ }
265+
266+ return actionEvents ;
267+ }
230268}
0 commit comments