Remove old license headers
[gpl/argeo-slc.git] / org.argeo.slc.spring / src / org / argeo / slc / core / execution / generator / RunnableCallFlow.java
index 695606c210f803dafda009d5f97c18b078e72f32..04043acff6be12123f3f41a33648262094df7bf4 100644 (file)
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *         http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.slc.core.execution.generator;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Iterator;\r
-import java.util.List;\r
-import java.util.Map;\r
-\r
-import org.apache.commons.logging.Log;\r
-import org.apache.commons.logging.LogFactory;\r
-import org.argeo.slc.SlcException;\r
-import org.argeo.slc.core.execution.DefaultExecutionSpec;\r
-import org.argeo.slc.execution.ExecutionContext;\r
-import org.argeo.slc.execution.ExecutionFlow;\r
-import org.argeo.slc.execution.ExecutionSpec;\r
-import org.springframework.context.ApplicationContext;\r
-import org.springframework.context.ApplicationContextAware;\r
-\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
-       /**\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
-        * Name of the flow. Also bean name\r
-        */\r
-       private String name;\r
-\r
-       /**\r
-        * Path of the flow\r
-        */\r
-       private String path;\r
-\r
-       /**\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
-       /**\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
-        * 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
-        * ExecutionSpec of the flow. Does not contain any attribute.\r
-        */\r
-       private ExecutionSpec executionSpec = new DefaultExecutionSpec();\r
-\r
-       /**\r
-        * Reference to the ExecutionContext\r
-        */\r
-       private ExecutionContext executionContext;\r
-\r
-       /**\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
-        * 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,\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
-                       executionContext.setVariable(entry.getKey(), entry.getValue());\r
-               }\r
-\r
-               // add call Index Variable\r
-               executionContext.setVariable(VAR_CALL_INDEX, callIndex);\r
-\r
-               // clear sharedContextValues and add all values of contextValues\r
-               if (sharedContextValuesMap != null) {\r
-                       sharedContextValuesMap.clear();\r
-                       sharedContextValuesMap.putAll(contextValues);\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
-        * 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
-               try {\r
-                       for (int callIndex = 0; callIndex < runnableCalls.size(); ++callIndex) {\r
-                               RunnableCall runnableCall = runnableCalls.get(callIndex);\r
-                               Object bean = applicationContext.getBean(\r
-                                               runnableCall.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
-                               throw e;\r
-                       else {\r
-                               log.error("Execution flow failed,"\r
-                                               + " but process did not fail"\r
-                                               + " because failOnError property"\r
-                                               + " is set to false: " + e);\r
-                               if (log.isTraceEnabled())\r
-                                       e.printStackTrace();\r
-                       }\r
-               }\r
-       }\r
-\r
-       public Iterator<Runnable> runnables() {\r
-               List<Runnable> runnables = new ArrayList<Runnable>();\r
-               for (int callIndex = 0; callIndex < runnableCalls.size(); ++callIndex) {\r
-                       RunnableCall runnableCall = runnableCalls.get(callIndex);\r
-                       Object bean = applicationContext.getBean(\r
-                                       runnableCall.getBeanName(), Runnable.class);\r
-                       runnables.add((Runnable) bean);\r
-               }\r
-               return runnables.iterator();\r
-       }\r
-\r
-       public Runnable getRunnable() {\r
-               if (runnableCalls.size() == 1)\r
-                       return runnables().next();\r
-               else\r
-                       throw new SlcException("There are " + runnableCalls.size()\r
-                                       + " runnables in flow " + getName());\r
-       }\r
-\r
-       @Override\r
-       public String toString() {\r
-               return new StringBuffer("RunnableCallFlow ").append(name).toString();\r
-       }\r
-\r
-       public ExecutionSpec getExecutionSpec() {\r
-               return executionSpec;\r
-       }\r
-\r
-       public String getName() {\r
-               return name;\r
-       }\r
-\r
-       public Object getParameter(String key) {\r
-               throw new SlcException("RunnableCallFlow have no parameters");\r
-       }\r
-\r
-       public String getPath() {\r
-               return path;\r
-       }\r
-\r
-       public Boolean isSetAsParameter(String key) {\r
-               // The ExecutionSpec having no attribute,\r
-               // always return false\r
-               return false;\r
-       }\r
-\r
-       public void setName(String name) {\r
-               this.name = name;\r
-       }\r
-\r
-       public void setPath(String path) {\r
-               this.path = path;\r
-       }\r
-\r
-       public void setExecutionContext(ExecutionContext executionContext) {\r
-               this.executionContext = executionContext;\r
-       }\r
-\r
-       public void setRunnableCalls(List<RunnableCall> runnableCalls) {\r
-               this.runnableCalls = runnableCalls;\r
-       }\r
-\r
-       public void setApplicationContext(ApplicationContext applicationContext) {\r
-               this.applicationContext = applicationContext;\r
-       }\r
-\r
-       public void setSharedContextValuesMap(Map<String, Object> contextValues) {\r
-               this.sharedContextValuesMap = contextValues;\r
-       }\r
-\r
-       public void setFailOnError(Boolean failOnError) {\r
-               this.failOnError = failOnError;\r
-       }\r
-\r
-}\r
+package org.argeo.slc.core.execution.generator;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.core.execution.DefaultExecutionSpec;
+import org.argeo.slc.execution.ExecutionContext;
+import org.argeo.slc.execution.ExecutionFlow;
+import org.argeo.slc.execution.ExecutionSpec;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+
+/**
+ * Execution Flow calling a list of <code>Runnable</code> (identified by their
+ * bean name in the Spring Application Context) after configuring the Execution
+ * context and a Map potentially shared by the called <code>Runnable</code>
+ * 
+ */
+public class RunnableCallFlow implements ExecutionFlow, ApplicationContextAware {
+
+       private final static Log log = LogFactory.getLog(RunnableCallFlow.class);
+
+       /**
+        * Key in the execution context for the index of the call (e.g. 0 for the
+        * first runnable called, ...)
+        */
+       public final static String VAR_CALL_INDEX = "slcVar.runnableCallFlow.callIndex";
+
+       /**
+        * Name of the flow. Also bean name
+        */
+       private String name;
+
+       /**
+        * Path of the flow
+        */
+       private String path;
+
+       /**
+        * Whether an exception in a <code>Runnable</code> shall stop the execution
+        * of the flow
+        */
+       private Boolean failOnError = true;
+
+       /**
+        * List of <code>Runnable</code> to call, with bean name, execution
+        * variables and context values
+        */
+       private List<RunnableCall> runnableCalls;
+
+       /**
+        * Map potentially referenced by called flows. Updated with the context
+        * values of a Runnable before calling it.
+        */
+       private Map<String, Object> sharedContextValuesMap;
+
+       /**
+        * ExecutionSpec of the flow. Does not contain any attribute.
+        */
+       private ExecutionSpec executionSpec = new DefaultExecutionSpec();
+
+       /**
+        * Reference to the ExecutionContext
+        */
+       private ExecutionContext executionContext;
+
+       /**
+        * Reference to the Spring <code>ApplicationContext</code>. Set via
+        * <code>setApplicationContext</code>, the class implementing
+        * <code>ApplicationContextAware</code>
+        */
+       private ApplicationContext applicationContext;
+
+       /**
+        * Runs a <code>Runnable</code> after configuring the Execution Context and
+        * <code>sharedContextValuesMap</code>
+        * 
+        * @param runnable
+        *            the <code>Runnable</code> to call
+        * @param executionVariables
+        *            the variables to add to the <code>ExecutionContext</code>
+        * @param contextValues
+        *            the variables to add to <code>sharedContextValuesMap</code>
+        * @param callIndex
+        *            index of the call (0 for the first called
+        *            <code>Runnable</code>) set as variable of the
+        *            <code>ExecutionContext</code>
+        */
+       private void run(Runnable runnable, Map<String, Object> executionVariables,
+                       Map<String, Object> contextValues, int callIndex) {
+               // add all variables to the Execution Context
+               for (Map.Entry<String, Object> entry : executionVariables.entrySet()) {
+                       executionContext.setVariable(entry.getKey(), entry.getValue());
+               }
+
+               // add call Index Variable
+               executionContext.setVariable(VAR_CALL_INDEX, callIndex);
+
+               // clear sharedContextValues and add all values of contextValues
+               if (sharedContextValuesMap != null) {
+                       sharedContextValuesMap.clear();
+                       sharedContextValuesMap.putAll(contextValues);
+               }
+
+               // then run the runnable
+               doExecuteRunnable(runnable);
+       }
+
+       public void doExecuteRunnable(Runnable runnable) {
+               runnable.run();
+       }
+
+       /**
+        * Executes the flow. For each <code>RunnableCall</code>, the corresponding
+        * flow is retrieved from the Spring Application Context, the
+        * <code>ExecutionContext</code> and <code>sharedContextValuesMap</code> are
+        * configured and the <code>Runnable</code> is called.
+        */
+       public void run() {
+               if (applicationContext == null) {
+                       throw new SlcException("No ApplicationContext defined");
+               }
+
+               try {
+                       for (int callIndex = 0; callIndex < runnableCalls.size(); ++callIndex) {
+                               RunnableCall runnableCall = runnableCalls.get(callIndex);
+                               Object bean = applicationContext.getBean(
+                                               runnableCall.getBeanName(), Runnable.class);
+                               if (log.isDebugEnabled())
+                                       log.debug("Running flow '" + runnableCall.getBeanName()
+                                                       + "'");
+                               run((Runnable) bean, runnableCall.getExecutionVariables(),
+                                               runnableCall.getContextValues(), callIndex);
+                       }
+               } catch (RuntimeException e) {
+                       if (failOnError)
+                               throw e;
+                       else {
+                               log.error("Execution flow failed,"
+                                               + " but process did not fail"
+                                               + " because failOnError property"
+                                               + " is set to false: " + e);
+                               if (log.isTraceEnabled())
+                                       e.printStackTrace();
+                       }
+               }
+       }
+
+       public Iterator<Runnable> runnables() {
+               List<Runnable> runnables = new ArrayList<Runnable>();
+               for (int callIndex = 0; callIndex < runnableCalls.size(); ++callIndex) {
+                       RunnableCall runnableCall = runnableCalls.get(callIndex);
+                       Object bean = applicationContext.getBean(
+                                       runnableCall.getBeanName(), Runnable.class);
+                       runnables.add((Runnable) bean);
+               }
+               return runnables.iterator();
+       }
+
+       public Runnable getRunnable() {
+               if (runnableCalls.size() == 1)
+                       return runnables().next();
+               else
+                       throw new SlcException("There are " + runnableCalls.size()
+                                       + " runnables in flow " + getName());
+       }
+
+       @Override
+       public String toString() {
+               return new StringBuffer("RunnableCallFlow ").append(name).toString();
+       }
+
+       public ExecutionSpec getExecutionSpec() {
+               return executionSpec;
+       }
+
+       public String getName() {
+               return name;
+       }
+
+       public Object getParameter(String key) {
+               throw new SlcException("RunnableCallFlow have no parameters");
+       }
+
+       public String getPath() {
+               return path;
+       }
+
+       public Boolean isSetAsParameter(String key) {
+               // The ExecutionSpec having no attribute,
+               // always return false
+               return false;
+       }
+
+       public void setName(String name) {
+               this.name = name;
+       }
+
+       public void setPath(String path) {
+               this.path = path;
+       }
+
+       public void setExecutionContext(ExecutionContext executionContext) {
+               this.executionContext = executionContext;
+       }
+
+       public void setRunnableCalls(List<RunnableCall> runnableCalls) {
+               this.runnableCalls = runnableCalls;
+       }
+
+       public void setApplicationContext(ApplicationContext applicationContext) {
+               this.applicationContext = applicationContext;
+       }
+
+       public void setSharedContextValuesMap(Map<String, Object> contextValues) {
+               this.sharedContextValuesMap = contextValues;
+       }
+
+       public void setFailOnError(Boolean failOnError) {
+               this.failOnError = failOnError;
+       }
+
+}