1 package org
.argeo
.slc
.runtime
;
3 import java
.util
.HashMap
;
5 import java
.util
.Stack
;
8 import org
.argeo
.api
.cms
.CmsLog
;
9 import org
.argeo
.slc
.SlcException
;
10 import org
.argeo
.slc
.execution
.ExecutionFlow
;
11 import org
.argeo
.slc
.execution
.ExecutionSpecAttribute
;
12 import org
.argeo
.slc
.execution
.ExecutionStack
;
14 /** Canonical implementation of an execution stack. */
15 public class DefaultExecutionStack
implements ExecutionStack
{
17 private final static CmsLog log
= CmsLog
18 .getLog(DefaultExecutionStack
.class);
20 private final Stack
<ExecutionFlowRuntime
> stack
= new Stack
<ExecutionFlowRuntime
>();
22 public synchronized void enterFlow(ExecutionFlow executionFlow
) {
23 ExecutionFlowRuntime runtime
= new ExecutionFlowRuntime(executionFlow
);
26 Map
<String
, ExecutionSpecAttribute
> specAttrs
= executionFlow
27 .getExecutionSpec().getAttributes();
28 for (String key
: specAttrs
.keySet()) {
29 if (executionFlow
.isSetAsParameter(key
)) {
30 runtime
.getLocalVariables().put(key
,
31 executionFlow
.getParameter(key
));
36 public synchronized String
getCurrentStackLevelUuid() {
37 return stack
.peek().getUuid();
40 public synchronized Integer
getStackSize() {
45 * Looks for a set variable in the stack, starting at the upper flows
47 * @return the variable or <code>null</code> if not found
49 public synchronized Object
findLocalVariable(String key
) {
51 for (int i
= 0; i
< stack
.size(); i
++) {
52 if (stack
.get(i
).getLocalVariables().containsKey(key
)) {
53 obj
= stack
.get(i
).getLocalVariables().get(key
);
60 public synchronized void leaveFlow(ExecutionFlow executionFlow
) {
61 ExecutionFlowRuntime leftEf
= stack
.pop();
63 if (!leftEf
.getExecutionFlow().getName()
64 .equals(executionFlow
.getName()))
65 throw new SlcException("Asked to leave " + executionFlow
66 + " but last is " + leftEf
);
68 leftEf
.getScopedObjects().clear();
69 leftEf
.getLocalVariables().clear();
72 public synchronized void addScopedObject(String name
, Object obj
) {
73 ExecutionFlowRuntime runtime
= stack
.peek();
74 // TODO: check that the object is not set yet ?
75 if (log
.isDebugEnabled()) {
76 Object existing
= findScopedObject(name
);
78 log
.warn("Scoped object " + name
+ " of type " + obj
.getClass()
79 + " already registered in " + runtime
);
81 runtime
.getScopedObjects().put(name
, obj
);
84 /** @return </code>null<code> if not found */
85 public synchronized Object
findScopedObject(String name
) {
87 for (int i
= stack
.size() - 1; i
>= 0; i
--) {
88 if (stack
.get(i
).getScopedObjects().containsKey(name
)) {
89 obj
= stack
.get(i
).getScopedObjects().get(name
);
96 protected static class ExecutionFlowRuntime
{
97 private final ExecutionFlow executionFlow
;
98 private final Map
<String
, Object
> scopedObjects
= new HashMap
<String
, Object
>();
99 private final Map
<String
, Object
> localVariables
= new HashMap
<String
, Object
>();
100 private final String uuid
= UUID
.randomUUID().toString();
102 public ExecutionFlowRuntime(ExecutionFlow executionFlow
) {
103 this.executionFlow
= executionFlow
;
106 public ExecutionFlow
getExecutionFlow() {
107 return executionFlow
;
110 public Map
<String
, Object
> getScopedObjects() {
111 return scopedObjects
;
114 public String
getUuid() {
118 public Map
<String
, Object
> getLocalVariables() {
119 return localVariables
;
123 public String
toString() {
124 return "Stack Level #" + uuid
;