]> git.argeo.org Git - gpl/argeo-slc.git/blob - runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/DefaultExecutionStack.java
Modular distributions
[gpl/argeo-slc.git] / runtime / org.argeo.slc.core / src / main / java / org / argeo / slc / core / execution / DefaultExecutionStack.java
1 package org.argeo.slc.core.execution;
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.apache.commons.logging.Log;
9 import org.apache.commons.logging.LogFactory;
10 import org.argeo.slc.SlcException;
11 import org.argeo.slc.execution.ExecutionFlow;
12 import org.argeo.slc.execution.ExecutionSpecAttribute;
13 import org.argeo.slc.execution.ExecutionStack;
14
15 public class DefaultExecutionStack implements ExecutionStack {
16
17 private final static Log log = LogFactory
18 .getLog(DefaultExecutionStack.class);
19
20 private final Stack<ExecutionFlowRuntime> stack = new Stack<ExecutionFlowRuntime>();
21
22 public synchronized void enterFlow(ExecutionFlow executionFlow) {
23 ExecutionFlowRuntime runtime = new ExecutionFlowRuntime(executionFlow);
24 stack.push(runtime);
25
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));
32 }
33 }
34 }
35
36 public synchronized String getCurrentStackLevelUuid() {
37 return stack.peek().getUuid();
38 }
39
40 public synchronized Integer getStackSize() {
41 return stack.size();
42 }
43
44 /**
45 * Looks for a set variable in the stack, starting at the upper flows
46 *
47 * @return the variable or <code>null</code> if not found
48 */
49 public synchronized Object findLocalVariable(String key) {
50 Object obj = null;
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);
54 break;
55 }
56 }
57 return obj;
58 }
59
60 public synchronized void leaveFlow(ExecutionFlow executionFlow) {
61 ExecutionFlowRuntime leftEf = stack.pop();
62
63 if (!leftEf.getExecutionFlow().getName()
64 .equals(executionFlow.getName()))
65 throw new SlcException("Asked to leave " + executionFlow
66 + " but last is " + leftEf);
67
68 leftEf.getScopedObjects().clear();
69 leftEf.getLocalVariables().clear();
70 }
71
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);
77 if (existing != null)
78 log.warn("Scoped object " + name + " of type " + obj.getClass()
79 + " already registered in " + runtime);
80 }
81 runtime.getScopedObjects().put(name, obj);
82 }
83
84 /** @return </code>null<code> if not found */
85 public synchronized Object findScopedObject(String name) {
86 Object obj = null;
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);
90 break;
91 }
92 }
93 return obj;
94 }
95
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();
101
102 public ExecutionFlowRuntime(ExecutionFlow executionFlow) {
103 this.executionFlow = executionFlow;
104 }
105
106 public ExecutionFlow getExecutionFlow() {
107 return executionFlow;
108 }
109
110 public Map<String, Object> getScopedObjects() {
111 return scopedObjects;
112 }
113
114 public String getUuid() {
115 return uuid;
116 }
117
118 public Map<String, Object> getLocalVariables() {
119 return localVariables;
120 }
121
122 @Override
123 public String toString() {
124 return "Stack Level #" + uuid;
125 }
126
127 }
128 }