]> git.argeo.org Git - gpl/argeo-slc.git/blob - runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/generator/RunnableCallFlow.java
Add log4j support
[gpl/argeo-slc.git] / runtime / org.argeo.slc.core / src / main / java / org / argeo / slc / core / execution / generator / RunnableCallFlow.java
1 package org.argeo.slc.core.execution.generator;
2
3 import java.util.List;
4 import java.util.Map;
5
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;
15
16 /**
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>
20 *
21 */
22 public class RunnableCallFlow implements ExecutionFlow, ApplicationContextAware {
23
24 private final static Log log = LogFactory.getLog(RunnableCallFlow.class);
25
26 /**
27 * Key in the execution context for the index of the call (e.g. 0 for the
28 * first runnable called, ...)
29 */
30 public final static String VAR_CALL_INDEX = "slcVar.runnableCallFlow.callIndex";
31
32 /**
33 * Name of the flow. Also bean name
34 */
35 private String name;
36
37 /**
38 * Path of the flow
39 */
40 private String path;
41
42 /**
43 * Whether an exception in a <code>Runnable</code> shall stop the execution
44 * of the flow
45 */
46 private Boolean failOnError = true;
47
48 /**
49 * List of <code>Runnable</code> to call, with bean name, execution
50 * variables and context values
51 */
52 private List<RunnableCall> runnableCalls;
53
54 /**
55 * Map potentially referenced by called flows. Updated with the context
56 * values of a Runnable before calling it.
57 */
58 private Map<String, Object> sharedContextValuesMap;
59
60 /**
61 * ExecutionSpec of the flow. Does not contain any attribute.
62 */
63 private ExecutionSpec executionSpec = new DefaultExecutionSpec();
64
65 /**
66 * Reference to the ExecutionContext
67 */
68 private ExecutionContext executionContext;
69
70 /**
71 * Reference to the Spring <code>ApplicationContext</code>. Set via
72 * <code>setApplicationContext</code>, the class implementing
73 * <code>ApplicationContextAware</code>
74 */
75 private ApplicationContext applicationContext;
76
77 /**
78 * Runs a <code>Runnable</code> after configuring the Execution Context and
79 * <code>sharedContextValuesMap</code>
80 *
81 * @param runnable
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>
87 * @param callIndex
88 * index of the call (0 for the first called
89 * <code>Runnable</code>) set as variable of the
90 * <code>ExecutionContext</code>
91 */
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());
97 }
98
99 // add call Index Variable
100 executionContext.setVariable(VAR_CALL_INDEX, callIndex);
101
102 // clear sharedContextValues and add all values of contextValues
103 if (sharedContextValuesMap != null) {
104 sharedContextValuesMap.clear();
105 sharedContextValuesMap.putAll(contextValues);
106 }
107
108 // then run the runnable
109 doExecuteRunnable(runnable);
110 }
111
112 public void doExecuteRunnable(Runnable runnable) {
113 runnable.run();
114 }
115
116 /**
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.
121 */
122 public void run() {
123 if (applicationContext == null) {
124 throw new SlcException("No ApplicationContext defined");
125 }
126
127 try {
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()
134 + "'");
135 run((Runnable) bean, runnableCall.getExecutionVariables(),
136 runnableCall.getContextValues(), callIndex);
137 }
138 } catch (RuntimeException e) {
139 if (failOnError)
140 throw e;
141 else {
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())
147 e.printStackTrace();
148 }
149 }
150 }
151
152 public ExecutionSpec getExecutionSpec() {
153 return executionSpec;
154 }
155
156 public String getName() {
157 return name;
158 }
159
160 public Object getParameter(String key) {
161 throw new SlcException("RunnableCallFlow have no parameters");
162 }
163
164 public String getPath() {
165 return path;
166 }
167
168 public Boolean isSetAsParameter(String key) {
169 // The ExecutionSpec having no attribute,
170 // always return false
171 return false;
172 }
173
174 public void setName(String name) {
175 this.name = name;
176 }
177
178 public void setPath(String path) {
179 this.path = path;
180 }
181
182 public void setExecutionContext(ExecutionContext executionContext) {
183 this.executionContext = executionContext;
184 }
185
186 public void setRunnableCalls(List<RunnableCall> runnableCalls) {
187 this.runnableCalls = runnableCalls;
188 }
189
190 public void setApplicationContext(ApplicationContext applicationContext) {
191 this.applicationContext = applicationContext;
192 }
193
194 public void setSharedContextValuesMap(Map<String, Object> contextValues) {
195 this.sharedContextValuesMap = contextValues;
196 }
197
198 public void setFailOnError(Boolean failOnError) {
199 this.failOnError = failOnError;
200 }
201
202 }