]> git.argeo.org Git - gpl/argeo-slc.git/blob - DefaultExecutionStack.java
b30d51788a8ac9be0b974002bb58aeedc08bbcfa
[gpl/argeo-slc.git] / DefaultExecutionStack.java
1 package org.argeo.slc.runtime;
2
3 import java.util.HashMap;
4 import java.util.Map;
5 import java.util.Stack;
6 import java.util.UUID;
7
8 import org.argeo.slc.SlcException;
9 import org.argeo.slc.execution.ExecutionFlow;
10 import org.argeo.slc.execution.ExecutionSpecAttribute;
11 import org.argeo.slc.execution.ExecutionStack;
12
13 /** Canonical implementation of an execution stack. */
14 public class DefaultExecutionStack implements ExecutionStack {
15 private final Stack<ExecutionFlowRuntime> stack = new Stack<ExecutionFlowRuntime>();
16
17 public synchronized void enterFlow(ExecutionFlow executionFlow) {
18 ExecutionFlowRuntime runtime = new ExecutionFlowRuntime(executionFlow);
19 stack.push(runtime);
20
21 Map<String, ExecutionSpecAttribute> specAttrs = executionFlow.getExecutionSpec().getAttributes();
22 for (String key : specAttrs.keySet()) {
23 if (executionFlow.isSetAsParameter(key)) {
24 runtime.getLocalVariables().put(key, executionFlow.getParameter(key));
25 }
26 }
27 }
28
29 public synchronized String getCurrentStackLevelUuid() {
30 return stack.peek().getUuid();
31 }
32
33 public synchronized Integer getStackSize() {
34 return stack.size();
35 }
36
37 /**
38 * Looks for a set variable in the stack, starting at the upper flows
39 *
40 * @return the variable or <code>null</code> if not found
41 */
42 public synchronized Object findLocalVariable(String key) {
43 Object obj = null;
44 for (int i = 0; i < stack.size(); i++) {
45 if (stack.get(i).getLocalVariables().containsKey(key)) {
46 obj = stack.get(i).getLocalVariables().get(key);
47 break;
48 }
49 }
50 return obj;
51 }
52
53 public synchronized void leaveFlow(ExecutionFlow executionFlow) {
54 ExecutionFlowRuntime leftEf = stack.pop();
55
56 if (!leftEf.getExecutionFlow().getName().equals(executionFlow.getName()))
57 throw new SlcException("Asked to leave " + executionFlow + " but last is " + leftEf);
58
59 leftEf.getScopedObjects().clear();
60 leftEf.getLocalVariables().clear();
61 }
62
63 public synchronized void addScopedObject(String name, Object obj) {
64 ExecutionFlowRuntime runtime = stack.peek();
65 // TODO: check that the object is not set yet ?
66 // if (log.isDebugEnabled()) {
67 // Object existing = findScopedObject(name);
68 // if (existing != null)
69 // log.warn("Scoped object " + name + " of type " + obj.getClass()
70 // + " already registered in " + runtime);
71 // }
72 runtime.getScopedObjects().put(name, obj);
73 }
74
75 /** @return </code>null<code> if not found */
76 public synchronized Object findScopedObject(String name) {
77 Object obj = null;
78 for (int i = stack.size() - 1; i >= 0; i--) {
79 if (stack.get(i).getScopedObjects().containsKey(name)) {
80 obj = stack.get(i).getScopedObjects().get(name);
81 break;
82 }
83 }
84 return obj;
85 }
86
87 protected static class ExecutionFlowRuntime {
88 private final ExecutionFlow executionFlow;
89 private final Map<String, Object> scopedObjects = new HashMap<String, Object>();
90 private final Map<String, Object> localVariables = new HashMap<String, Object>();
91 private final String uuid = UUID.randomUUID().toString();
92
93 public ExecutionFlowRuntime(ExecutionFlow executionFlow) {
94 this.executionFlow = executionFlow;
95 }
96
97 public ExecutionFlow getExecutionFlow() {
98 return executionFlow;
99 }
100
101 public Map<String, Object> getScopedObjects() {
102 return scopedObjects;
103 }
104
105 public String getUuid() {
106 return uuid;
107 }
108
109 public Map<String, Object> getLocalVariables() {
110 return localVariables;
111 }
112
113 @Override
114 public String toString() {
115 return "Stack Level #" + uuid;
116 }
117
118 }
119 }