2 * Copyright (C) 2007-2012 Mathieu Baudier
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package org
.argeo
.slc
.core
.execution
;
18 import java
.util
.ArrayList
;
19 import java
.util
.HashMap
;
20 import java
.util
.List
;
23 import org
.apache
.commons
.logging
.Log
;
24 import org
.apache
.commons
.logging
.LogFactory
;
25 import org
.argeo
.slc
.SlcException
;
26 import org
.argeo
.slc
.execution
.ExecutionFlow
;
27 import org
.argeo
.slc
.execution
.ExecutionSpec
;
28 import org
.argeo
.slc
.execution
.ExecutionSpecAttribute
;
29 import org
.springframework
.beans
.factory
.BeanNameAware
;
30 import org
.springframework
.validation
.MapBindingResult
;
32 /** Default implementation of an execution flow. */
33 public class DefaultExecutionFlow
implements ExecutionFlow
, BeanNameAware
{
34 private final static Log log
= LogFactory
35 .getLog(DefaultExecutionFlow
.class);
37 private final ExecutionSpec executionSpec
;
38 private String name
= null;
39 private Map
<String
, Object
> parameters
= new HashMap
<String
, Object
>();
40 private List
<Runnable
> executables
= new ArrayList
<Runnable
>();
42 private Boolean failOnError
= true;
44 public DefaultExecutionFlow() {
45 this.executionSpec
= new DefaultExecutionSpec();
48 public DefaultExecutionFlow(ExecutionSpec executionSpec
) {
49 this.executionSpec
= executionSpec
;
52 public DefaultExecutionFlow(ExecutionSpec executionSpec
,
53 Map
<String
, Object
> parameters
) {
54 // be sure to have an execution spec
55 this.executionSpec
= (executionSpec
== null) ?
new DefaultExecutionSpec()
58 // only parameters contained in the executionSpec can be set
59 for (String parameter
: parameters
.keySet()) {
60 if (!executionSpec
.getAttributes().containsKey(parameter
)) {
61 throw new SlcException("Parameter " + parameter
62 + " is not defined in the ExecutionSpec");
67 this.parameters
.putAll(parameters
);
69 // check that all the required parameters are defined
70 MapBindingResult errors
= new MapBindingResult(parameters
, "execution#"
72 for (String key
: executionSpec
.getAttributes().keySet()) {
73 ExecutionSpecAttribute attr
= executionSpec
.getAttributes()
76 if (attr
.getIsImmutable() && !isSetAsParameter(key
)) {
77 errors
.rejectValue(key
, "Immutable but not set");
81 if (attr
.getIsConstant() && !isSetAsParameter(key
)) {
82 errors
.rejectValue(key
, "Constant but not set as parameter");
86 if (attr
.getIsHidden() && !isSetAsParameter(key
)) {
87 errors
.rejectValue(key
, "Hidden but not set as parameter");
92 if (errors
.hasErrors())
93 throw new SlcException("Could not prepare execution flow: "
100 for (Runnable executable
: executables
) {
101 if (Thread
.interrupted()) {
102 log
.error("Flow '" + getName() + "' killed before '"
104 Thread
.currentThread().interrupt();
106 // throw new ThreadDeath();
108 this.doExecuteRunnable(executable
);
110 } catch (RuntimeException e
) {
111 if (Thread
.interrupted()) {
112 log
.error("Flow '" + getName()
113 + "' killed while receiving an unrelated exception", e
);
114 Thread
.currentThread().interrupt();
116 // throw new ThreadDeath();
121 log
.error("Execution flow failed,"
122 + " but process did not fail"
123 + " because failOnError property"
124 + " is set to false: " + e
);
125 if (log
.isTraceEnabled())
131 public void doExecuteRunnable(Runnable runnable
) {
135 public void setBeanName(String name
) {
139 public void setExecutables(List
<Runnable
> executables
) {
140 this.executables
= executables
;
143 public void setParameters(Map
<String
, Object
> attributes
) {
144 this.parameters
= attributes
;
147 public String
getName() {
151 public ExecutionSpec
getExecutionSpec() {
152 return executionSpec
;
155 public Object
getParameter(String parameterName
) {
156 // Verify that there is a spec attribute
157 ExecutionSpecAttribute specAttr
= null;
158 if (executionSpec
.getAttributes().containsKey(parameterName
)) {
159 specAttr
= executionSpec
.getAttributes().get(parameterName
);
161 throw new SlcException("Key " + parameterName
162 + " is not defined in the specifications of " + toString());
165 if (parameters
.containsKey(parameterName
)) {
166 Object paramValue
= parameters
.get(parameterName
);
169 if (specAttr
.getValue() != null) {
170 return specAttr
.getValue();
173 throw new SlcException("Key " + parameterName
174 + " is not set as parameter in " + toString());
177 public Boolean
isSetAsParameter(String key
) {
178 return parameters
.containsKey(key
)
179 || (executionSpec
.getAttributes().containsKey(key
) && executionSpec
180 .getAttributes().get(key
).getValue() != null);
184 public String
toString() {
185 return new StringBuffer("Execution flow ").append(name
).toString();
189 public boolean equals(Object obj
) {
190 return ((ExecutionFlow
) obj
).getName().equals(name
);
194 public int hashCode() {
195 return name
.hashCode();
198 /** @deprecated does nothing */
200 public void setPath(String path
) {
203 public Boolean
getFailOnError() {
207 public void setFailOnError(Boolean failOnError
) {
208 this.failOnError
= failOnError
;