1 package org
.argeo
.slc
.core
.execution
.generator
;
6 import org
.apache
.commons
.logging
.Log
;
7 import org
.apache
.commons
.logging
.LogFactory
;
8 import org
.argeo
.slc
.SlcException
;
9 import org
.argeo
.slc
.core
.execution
.DefaultExecutionSpec
;
10 import org
.argeo
.slc
.execution
.ExecutionContext
;
11 import org
.argeo
.slc
.execution
.ExecutionFlow
;
12 import org
.argeo
.slc
.execution
.ExecutionSpec
;
13 import org
.springframework
.context
.ApplicationContext
;
14 import org
.springframework
.context
.ApplicationContextAware
;
17 * Execution Flow calling a list of <code>Runnable</code> (identified by their
18 * bean name in the Spring Application Context) after configuring the Execution
19 * context and a Map potentially shared by the called <code>Runnable</code>
22 public class RunnableCallFlow
implements ExecutionFlow
, ApplicationContextAware
{
24 private final static Log log
= LogFactory
.getLog(RunnableCallFlow
.class);
27 * Key in the execution context for the index of the call (e.g. 0 for the
28 * first runnable called, ...)
30 public final static String VAR_CALL_INDEX
= "slcVar.runnableCallFlow.callIndex";
33 * Name of the flow. Also bean name
43 * Whether an exception in a <code>Runnable</code> shall stop the execution
46 private Boolean failOnError
= true;
49 * List of <code>Runnable</code> to call, with bean name, execution
50 * variables and context values
52 private List
<RunnableCall
> runnableCalls
;
55 * Map potentially referenced by called flows. Updated with the context
56 * values of a Runnable before calling it.
58 private Map
<String
, Object
> sharedContextValuesMap
;
61 * ExecutionSpec of the flow. Does not contain any attribute.
63 private ExecutionSpec executionSpec
= new DefaultExecutionSpec();
66 * Reference to the ExecutionContext
68 private ExecutionContext executionContext
;
71 * Reference to the Spring <code>ApplicationContext</code>. Set via
72 * <code>setApplicationContext</code>, the class implementing
73 * <code>ApplicationContextAware</code>
75 private ApplicationContext applicationContext
;
78 * Runs a <code>Runnable</code> after configuring the Execution Context and
79 * <code>sharedContextValuesMap</code>
82 * the <code>Runnable</code> to call
83 * @param executionVariables
84 * the variables to add to the <code>ExecutionContext</code>
85 * @param contextValues
86 * the variables to add to <code>sharedContextValuesMap</code>
88 * index of the call (0 for the first called
89 * <code>Runnable</code>) set as variable of the
90 * <code>ExecutionContext</code>
92 private void run(Runnable runnable
, Map
<String
, Object
> executionVariables
,
93 Map
<String
, Object
> contextValues
, int callIndex
) {
94 // add all variables to the Execution Context
95 for (Map
.Entry
<String
, Object
> entry
: executionVariables
.entrySet()) {
96 executionContext
.setVariable(entry
.getKey(), entry
.getValue());
99 // add call Index Variable
100 executionContext
.setVariable(VAR_CALL_INDEX
, callIndex
);
102 // clear sharedContextValues and add all values of contextValues
103 if (sharedContextValuesMap
!= null) {
104 sharedContextValuesMap
.clear();
105 sharedContextValuesMap
.putAll(contextValues
);
108 // then run the runnable
109 doExecuteRunnable(runnable
);
112 public void doExecuteRunnable(Runnable runnable
) {
117 * Executes the flow. For each <code>RunnableCall</code>, the corresponding
118 * flow is retrieved from the Spring Application Context, the
119 * <code>ExecutionContext</code> and <code>sharedContextValuesMap</code> are
120 * configured and the <code>Runnable</code> is called.
123 if (applicationContext
== null) {
124 throw new SlcException("No ApplicationContext defined");
128 for (int callIndex
= 0; callIndex
< runnableCalls
.size(); ++callIndex
) {
129 RunnableCall runnableCall
= runnableCalls
.get(callIndex
);
130 Object bean
= applicationContext
.getBean(runnableCall
131 .getBeanName(), Runnable
.class);
132 if (log
.isDebugEnabled())
133 log
.debug("Running flow '" + runnableCall
.getBeanName()
135 run((Runnable
) bean
, runnableCall
.getExecutionVariables(),
136 runnableCall
.getContextValues(), callIndex
);
138 } catch (RuntimeException e
) {
142 log
.error("Execution flow failed,"
143 + " but process did not fail"
144 + " because failOnError property"
145 + " is set to false: " + e
);
146 if (log
.isTraceEnabled())
152 public ExecutionSpec
getExecutionSpec() {
153 return executionSpec
;
156 public String
getName() {
160 public Object
getParameter(String key
) {
161 throw new SlcException("RunnableCallFlow have no parameters");
164 public String
getPath() {
168 public Boolean
isSetAsParameter(String key
) {
169 // The ExecutionSpec having no attribute,
170 // always return false
174 public void setName(String name
) {
178 public void setPath(String path
) {
182 public void setExecutionContext(ExecutionContext executionContext
) {
183 this.executionContext
= executionContext
;
186 public void setRunnableCalls(List
<RunnableCall
> runnableCalls
) {
187 this.runnableCalls
= runnableCalls
;
190 public void setApplicationContext(ApplicationContext applicationContext
) {
191 this.applicationContext
= applicationContext
;
194 public void setSharedContextValuesMap(Map
<String
, Object
> contextValues
) {
195 this.sharedContextValuesMap
= contextValues
;
198 public void setFailOnError(Boolean failOnError
) {
199 this.failOnError
= failOnError
;