@Around("flowExecution()")
public void aroundFlow(ProceedingJoinPoint pjp) throws Throwable {
- // IMPORTANT: Make sure that the execution context is called before the execution stack
+ // IMPORTANT: Make sure that the execution context is called before the
+ // execution stack
executionContext.getUuid();
-
+
ExecutionFlow executionFlow = (ExecutionFlow) pjp.getTarget();
executionStack.enterFlow(executionFlow);
executionContext.setVariable(ExecutionContext.VAR_FLOW_ID,
executionStack.leaveFlow(executionFlow);
}
+ @Around("runnableExecution()")
+ public void aroundRunnable(ProceedingJoinPoint pjp) throws Throwable {
+ ExecutionFlow executionFlow = (ExecutionFlow) pjp.getTarget();
+ Runnable runnable = (Runnable) pjp.getArgs()[0];
+ if (log.isDebugEnabled())
+ logRunnableExecution(executionFlow, runnable);
+ // Actually execute the runnable
+ pjp.proceed();
+ }
+
@Around("getVariable()")
public Object aroundGetVariable(ProceedingJoinPoint pjp) throws Throwable {
Object obj = pjp.proceed();
public void flowExecution() {
}
+ @Pointcut("execution(void org.argeo.slc.execution.ExecutionFlow.doExecuteRunnable(..))")
+ public void runnableExecution() {
+ }
+
@Pointcut("execution(* org.argeo.slc.execution.ExecutionContext.getVariable(..))")
public void getVariable() {
}
+ stackSize);
}
+ protected void logRunnableExecution(ExecutionFlow executionFlow,
+ Runnable runnable) {
+ Integer stackSize = executionStack.getStackSize();
+ log.debug(depthSpaces(stackSize + 1)
+ + runnable.getClass().getSimpleName() + " in " + executionFlow);
+ }
+
private String depthSpaces(int depth) {
StringBuffer buf = new StringBuffer(depth * 2);
for (int i = 0; i < depth; i++)
import org.springframework.context.ApplicationContextAware;\r
\r
/**\r
- * Execution Flow calling a list of <code>Runnable</code> (identified by their bean \r
- * name in the Spring Application Context) after configuring the Execution\r
- * context and a Map potentially shared by the called <code>Runnable</code> \r
- *\r
+ * Execution Flow calling a list of <code>Runnable</code> (identified by their\r
+ * bean name in the Spring Application Context) after configuring the Execution\r
+ * context and a Map potentially shared by the called <code>Runnable</code>\r
+ * \r
*/\r
public class RunnableCallFlow implements ExecutionFlow, ApplicationContextAware {\r
\r
- private final static Log log = LogFactory.getLog(RunnableCallFlow.class); \r
- \r
+ private final static Log log = LogFactory.getLog(RunnableCallFlow.class);\r
+\r
/**\r
- * Key in the execution context for the index of the call (e.g. 0 \r
- * for the first runnable called, ...)\r
+ * Key in the execution context for the index of the call (e.g. 0 for the\r
+ * first runnable called, ...)\r
*/\r
public final static String VAR_CALL_INDEX = "slcVar.runnableCallFlow.callIndex";\r
- \r
+\r
/**\r
* Name of the flow. Also bean name\r
*/\r
private String name;\r
- \r
+\r
/**\r
* Path of the flow\r
*/\r
private String path;\r
\r
/**\r
- * Whether an exception in a <code>Runnable</code> shall\r
- * stop the execution of the flow\r
+ * Whether an exception in a <code>Runnable</code> shall stop the execution\r
+ * of the flow\r
*/\r
- private Boolean failOnError = true; \r
- \r
+ private Boolean failOnError = true;\r
+\r
/**\r
- * List of <code>Runnable</code> to call, with bean name, execution variables and \r
- * context values\r
+ * List of <code>Runnable</code> to call, with bean name, execution\r
+ * variables and context values\r
*/\r
private List<RunnableCall> runnableCalls;\r
- \r
+\r
/**\r
- * Map potentially referenced by called flows. Updated with\r
- * the context values of a Runnable before calling it.\r
+ * Map potentially referenced by called flows. Updated with the context\r
+ * values of a Runnable before calling it.\r
*/\r
private Map<String, Object> sharedContextValuesMap;\r
- \r
+\r
/**\r
- * ExecutionSpec of the flow. Does not contain any \r
- * attribute.\r
+ * ExecutionSpec of the flow. Does not contain any attribute.\r
*/\r
- private ExecutionSpec executionSpec = new DefaultExecutionSpec(); \r
- \r
+ private ExecutionSpec executionSpec = new DefaultExecutionSpec();\r
+\r
/**\r
* Reference to the ExecutionContext\r
*/\r
- private ExecutionContext executionContext; \r
- \r
+ private ExecutionContext executionContext;\r
+\r
/**\r
- * Reference to the Spring <code>ApplicationContext</code>.\r
- * Set via <code>setApplicationContext</code>, the class implementing\r
+ * Reference to the Spring <code>ApplicationContext</code>. Set via\r
+ * <code>setApplicationContext</code>, the class implementing\r
* <code>ApplicationContextAware</code>\r
*/\r
private ApplicationContext applicationContext;\r
- \r
+\r
/**\r
- * Runs a <code>Runnable</code> after configuring the Execution Context \r
- * and <code>sharedContextValuesMap</code>\r
- * @param runnable the <code>Runnable</code> to call\r
- * @param executionVariables the variables to add to the <code>ExecutionContext</code>\r
- * @param contextValues the variables to add to <code>sharedContextValuesMap</code>\r
- * @param callIndex index of the call (0 for the first called <code>Runnable</code>)\r
- * set as variable of the <code>ExecutionContext</code>\r
+ * Runs a <code>Runnable</code> after configuring the Execution Context and\r
+ * <code>sharedContextValuesMap</code>\r
+ * \r
+ * @param runnable\r
+ * the <code>Runnable</code> to call\r
+ * @param executionVariables\r
+ * the variables to add to the <code>ExecutionContext</code>\r
+ * @param contextValues\r
+ * the variables to add to <code>sharedContextValuesMap</code>\r
+ * @param callIndex\r
+ * index of the call (0 for the first called\r
+ * <code>Runnable</code>) set as variable of the\r
+ * <code>ExecutionContext</code>\r
*/\r
- private void run(Runnable runnable, Map<String, Object> executionVariables, Map<String, Object> contextValues, int callIndex) {\r
+ private void run(Runnable runnable, Map<String, Object> executionVariables,\r
+ Map<String, Object> contextValues, int callIndex) {\r
// add all variables to the Execution Context\r
- for(Map.Entry<String,Object> entry : executionVariables.entrySet()) {\r
+ for (Map.Entry<String, Object> entry : executionVariables.entrySet()) {\r
executionContext.setVariable(entry.getKey(), entry.getValue());\r
}\r
- \r
+\r
// add call Index Variable\r
executionContext.setVariable(VAR_CALL_INDEX, callIndex);\r
- \r
+\r
// clear sharedContextValues and add all values of contextValues\r
- if(sharedContextValuesMap != null) {\r
+ if (sharedContextValuesMap != null) {\r
sharedContextValuesMap.clear();\r
sharedContextValuesMap.putAll(contextValues);\r
}\r
- \r
+\r
// then run the runnable\r
+ doExecuteRunnable(runnable);\r
+ }\r
+\r
+ public void doExecuteRunnable(Runnable runnable) {\r
runnable.run();\r
}\r
- \r
+\r
/**\r
- * Executes the flow. \r
- * For each <code>RunnableCall</code>, the corresponding flow\r
- * is retrieved from the Spring Application Context, the \r
- * <code>ExecutionContext</code> and <code>sharedContextValuesMap</code>\r
- * are configured and the <code>Runnable</code> is called.\r
+ * Executes the flow. For each <code>RunnableCall</code>, the corresponding\r
+ * flow is retrieved from the Spring Application Context, the\r
+ * <code>ExecutionContext</code> and <code>sharedContextValuesMap</code> are\r
+ * configured and the <code>Runnable</code> is called.\r
*/\r
public void run() {\r
if (applicationContext == null) {\r
throw new SlcException("No ApplicationContext defined");\r
- } \r
- \r
+ }\r
+\r
try {\r
- for(int callIndex = 0; callIndex < runnableCalls.size(); ++callIndex) {\r
+ for (int callIndex = 0; callIndex < runnableCalls.size(); ++callIndex) {\r
RunnableCall runnableCall = runnableCalls.get(callIndex);\r
- Object bean = applicationContext.getBean(runnableCall.getBeanName(), Runnable.class);\r
- if(log.isDebugEnabled()) \r
- log.debug("Running flow '" + runnableCall.getBeanName() + "'");\r
- run((Runnable)bean, runnableCall.getExecutionVariables(), runnableCall.getContextValues(), callIndex);\r
+ Object bean = applicationContext.getBean(runnableCall\r
+ .getBeanName(), Runnable.class);\r
+ if (log.isDebugEnabled())\r
+ log.debug("Running flow '" + runnableCall.getBeanName()\r
+ + "'");\r
+ run((Runnable) bean, runnableCall.getExecutionVariables(),\r
+ runnableCall.getContextValues(), callIndex);\r
}\r
} catch (RuntimeException e) {\r
if (failOnError)\r
if (log.isTraceEnabled())\r
e.printStackTrace();\r
}\r
- } \r
+ }\r
}\r
\r
public ExecutionSpec getExecutionSpec() {\r
// The ExecutionSpec having no attribute,\r
// always return false\r
return false;\r
- } \r
- \r
+ }\r
+\r
public void setName(String name) {\r
this.name = name;\r
}\r