1 package org
.argeo
.slc
.core
.execution
;
3 import java
.util
.ArrayList
;
4 import java
.util
.HashMap
;
8 import org
.apache
.commons
.logging
.Log
;
9 import org
.apache
.commons
.logging
.LogFactory
;
10 import org
.argeo
.slc
.SlcException
;
11 import org
.argeo
.slc
.core
.structure
.tree
.TreeSPath
;
12 import org
.argeo
.slc
.core
.structure
.tree
.TreeSRegistry
;
13 import org
.argeo
.slc
.execution
.ExecutionFlow
;
14 import org
.argeo
.slc
.execution
.ExecutionSpec
;
15 import org
.argeo
.slc
.execution
.ExecutionSpecAttribute
;
16 import org
.argeo
.slc
.structure
.StructureAware
;
17 import org
.argeo
.slc
.structure
.StructureRegistry
;
18 import org
.springframework
.aop
.scope
.ScopedObject
;
19 import org
.springframework
.beans
.factory
.BeanNameAware
;
20 import org
.springframework
.beans
.factory
.InitializingBean
;
21 import org
.springframework
.validation
.MapBindingResult
;
23 public class DefaultExecutionFlow
implements ExecutionFlow
, InitializingBean
,
25 private final static Log log
= LogFactory
26 .getLog(DefaultExecutionFlow
.class);
28 private final ExecutionSpec executionSpec
;
29 private String name
= null;
30 private Map
<String
, Object
> parameters
= new HashMap
<String
, Object
>();
31 private List
<Runnable
> executables
= new ArrayList
<Runnable
>();
34 private StructureRegistry
<TreeSPath
> registry
= new TreeSRegistry();
36 private Boolean failOnError
= true;
38 public DefaultExecutionFlow() {
39 this.executionSpec
= new DefaultExecutionSpec();
42 public DefaultExecutionFlow(ExecutionSpec executionSpec
) {
43 this.executionSpec
= executionSpec
;
46 public DefaultExecutionFlow(ExecutionSpec executionSpec
,
47 Map
<String
, Object
> parameters
) {
48 // be sure to have an execution spec
49 this.executionSpec
= (executionSpec
== null) ?
new DefaultExecutionSpec()
52 // only parameters contained in the executionSpec can be set
53 for (String parameter
: parameters
.keySet()) {
54 if (!executionSpec
.getAttributes().containsKey(parameter
)) {
55 throw new SlcException("Parameter " + parameter
56 + " is not defined in the ExecutionSpec");
61 this.parameters
.putAll(parameters
);
63 // check that all the required parameters are defined
64 MapBindingResult errors
= new MapBindingResult(parameters
, "execution#"
66 for (String key
: executionSpec
.getAttributes().keySet()) {
67 ExecutionSpecAttribute attr
= executionSpec
.getAttributes()
70 if (attr
.getIsParameter() && !isSetAsParameter(key
)) {
71 errors
.rejectValue(key
, "Parameter not set");
75 if (attr
.getIsFrozen() && !isSetAsParameter(key
)) {
76 errors
.rejectValue(key
, "Frozen but not set as parameter");
80 if (attr
.getIsHidden() && !isSetAsParameter(key
)) {
81 errors
.rejectValue(key
, "Hidden but not set as parameter");
86 if (errors
.hasErrors())
87 throw new SlcException("Could not prepare execution flow: "
94 for (Runnable executable
: executables
) {
95 this.doExecuteRunnable(executable
);
97 } catch (RuntimeException e
) {
101 log
.error("Execution flow failed,"
102 + " but process did not fail"
103 + " because failOnError property"
104 + " is set to false: " + e
);
105 if (log
.isTraceEnabled())
111 public void doExecuteRunnable(Runnable runnable
) {
115 @SuppressWarnings(value
= { "unchecked" })
116 public void afterPropertiesSet() throws Exception
{
118 if (name
.charAt(0) == '/') {
119 path
= name
.substring(0, name
.lastIndexOf('/'));
124 for (Runnable executable
: executables
) {
125 if (executable
instanceof StructureAware
126 && !(executable
instanceof ScopedObject
)) {
127 ((StructureAware
<TreeSPath
>) executable
).notifyCurrentPath(
128 registry
, new TreeSPath(path
));
129 } else if (executable
instanceof DefaultExecutionFlow
) {
130 // so we don't need to have DefaultExecutionFlow
131 // implementing StructureAware
132 // FIXME: probably has side effects
133 DefaultExecutionFlow flow
= (DefaultExecutionFlow
) executable
;
134 String newPath
= path
+ '/' + flow
.getName();
135 flow
.setPath(newPath
);
136 log
.warn(newPath
+ " was forcibly set on " + flow
);
142 public void setBeanName(String name
) {
146 public void setExecutables(List
<Runnable
> executables
) {
147 this.executables
= executables
;
150 public void setParameters(Map
<String
, Object
> attributes
) {
151 this.parameters
= attributes
;
154 public String
getName() {
158 public ExecutionSpec
getExecutionSpec() {
159 return executionSpec
;
162 public Object
getParameter(String parameterName
) {
163 // Verify that there is a spec attribute
164 ExecutionSpecAttribute specAttr
= null;
165 if (executionSpec
.getAttributes().containsKey(parameterName
)) {
166 specAttr
= executionSpec
.getAttributes().get(parameterName
);
168 throw new SlcException("Key " + parameterName
169 + " is not defined in the specifications of " + toString());
172 if (parameters
.containsKey(parameterName
)) {
173 Object paramValue
= parameters
.get(parameterName
);
176 if (specAttr
.getValue() != null) {
177 return specAttr
.getValue();
180 throw new SlcException("Key " + parameterName
181 + " is not set as parameter in " + toString());
184 public Boolean
isSetAsParameter(String key
) {
185 return parameters
.containsKey(key
)
186 || (executionSpec
.getAttributes().containsKey(key
) && executionSpec
187 .getAttributes().get(key
).getValue() != null);
191 public String
toString() {
192 return new StringBuffer("Execution flow ").append(name
).toString();
196 public boolean equals(Object obj
) {
197 return ((ExecutionFlow
) obj
).getName().equals(name
);
201 public int hashCode() {
202 return name
.hashCode();
205 public String
getPath() {
209 public void setPath(String path
) {
213 public void setRegistry(StructureRegistry
<TreeSPath
> registry
) {
214 this.registry
= registry
;
217 public Boolean
getFailOnError() {
221 public void setFailOnError(Boolean failOnError
) {
222 this.failOnError
= failOnError
;