]> git.argeo.org Git - gpl/argeo-slc.git/blob - runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/ExecutionContext.java
db8af23d5d76657665cf19991335bde8a38da69c
[gpl/argeo-slc.git] / runtime / org.argeo.slc.execution / src / main / java / org / argeo / slc / execution / ExecutionContext.java
1 package org.argeo.slc.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.process.SlcExecution;
12 import org.springframework.beans.factory.ObjectFactory;
13
14 public class ExecutionContext {
15 private final static Log log = LogFactory.getLog(ExecutionContext.class);
16
17 private final static ThreadLocal<ExecutionContext> executionContext = new ThreadLocal<ExecutionContext>();
18
19 private final Stack<ExecutionFlowRuntime> stack = new Stack<ExecutionFlowRuntime>();
20
21 // TODO: make it thread safe?
22 private final Map<String, Object> variables = new HashMap<String, Object>();
23
24 private final String uuid = UUID.randomUUID().toString();
25
26 public static Map<String, Object> getVariables() {
27 if (executionContext.get() == null)
28 return null;
29 return executionContext.get().variables;
30 }
31
32 public static ExecutionContext getCurrent() {
33 return executionContext.get();
34 }
35
36 public static String getExecutionUuid() {
37 if (executionContext.get() == null)
38 return null;
39 return executionContext.get().getUuid();
40 }
41
42 public static void registerExecutionContext(ExecutionContext context) {
43 if (executionContext.get() != null)
44 throw new SlcException("Context #" + executionContext.get().uuid
45 + " already registered.");
46 executionContext.set(context);
47 }
48
49 public static void enterFlow(ExecutionFlow executionFlow) {
50 Stack<ExecutionFlowRuntime> stack = executionContext.get().stack;
51
52 ExecutionFlowRuntime runtime = new ExecutionFlowRuntime(executionFlow);
53 stack.push(runtime);
54
55 if (log.isTraceEnabled())
56 log.debug(depthSpaces(stack.size()) + "=> " + executionFlow + " #"
57 + getCurrentStackUuid() + ", depth=" + stack.size());
58
59 Map<String, ExecutionSpecAttribute> specAttrs = executionFlow
60 .getExecutionSpec().getAttributes();
61 for (String key : specAttrs.keySet()) {
62 ExecutionSpecAttribute esa = specAttrs.get(key);
63 if (esa.getIsParameter()) {
64 runtime.getLocalVariables().put(key,
65 executionFlow.getParameter(key));
66 if (log.isTraceEnabled())
67 log.trace(depthSpaces(stack.size()) + "Add '" + key
68 + "' as local variable.");
69 }
70 }
71
72 }
73
74 public static Object getVariable(String key) {
75 Object obj = getWithCheck().findVariable(key);
76 if (obj == null)
77 throw new SlcException("Variable '" + key + "' not found.");
78 return obj;
79 }
80
81 protected Object findVariable(String key) {
82 Object obj = null;
83 for (int i = stack.size() - 1; i >= 0; i--) {
84 if (stack.get(i).getLocalVariables().containsKey(key)) {
85 obj = stack.get(i).getLocalVariables().get(key);
86 break;
87 }
88 }
89
90 // Look into global execution variables
91 if (obj == null) {
92 if (variables.containsKey(key))
93 obj = variables.get(key);
94 }
95
96 return obj;
97 }
98
99 private static String depthSpaces(int depth) {
100 StringBuffer buf = new StringBuffer(depth * 2);
101 for (int i = 0; i < depth; i++)
102 buf.append(" ");
103 return buf.toString();
104 }
105
106 public static void leaveFlow(ExecutionFlow executionFlow) {
107 Stack<ExecutionFlowRuntime> stack = executionContext.get().stack;
108 if (log.isTraceEnabled())
109 log.debug(depthSpaces(stack.size()) + "<= " + executionFlow + " #"
110 + getCurrentStackUuid() + ", depth=" + stack.size());
111
112 ExecutionFlowRuntime leftEf = stack.pop();
113 if (!leftEf.getExecutionFlow().getUuid()
114 .equals(executionFlow.getUuid()))
115 throw new SlcException("Asked to leave " + executionFlow
116 + " but last is " + leftEf);
117
118 leftEf.getScopedObjects().clear();
119 leftEf.getLocalVariables().clear();
120
121 }
122
123 public static String getCurrentStackUuid() {
124 return getWithCheck().stack.peek().uuid;
125 }
126
127 // public static ExecutionFlow getCurrentFlow() {
128 // return getWithCheck().stack.peek().executionFlow;
129 // }
130
131 public static Boolean isExecuting() {
132 return executionContext.get() != null;
133 }
134
135 protected static ExecutionContext getWithCheck() {
136 if (executionContext.get() == null)
137 throw new SlcException("No execution context");
138 return executionContext.get();
139 }
140
141 public static Object findOrAddScopedObject(String name,
142 ObjectFactory objectFactory) {
143 ExecutionContext executionContext = getWithCheck();
144 Object obj = executionContext.findScopedObject(name);
145 if (obj == null) {
146 obj = objectFactory.getObject();
147 executionContext.stack.peek().getScopedObjects().put(name, obj);
148 }
149 return obj;
150 }
151
152 /** return null if not found */
153 protected Object findScopedObject(String key) {
154 Object obj = null;
155 for (int i = stack.size() - 1; i >= 0; i--) {
156 if (stack.get(i).getScopedObjects().containsKey(key)) {
157 obj = stack.get(i).getScopedObjects().get(key);
158 break;
159 }
160 }
161 return obj;
162 }
163
164 public String getUuid() {
165 return uuid;
166 }
167
168 private static class ExecutionFlowRuntime {
169 private final ExecutionFlow executionFlow;
170 private final Map<String, Object> scopedObjects = new HashMap<String, Object>();
171 private final Map<String, Object> localVariables = new HashMap<String, Object>();
172 private final String uuid = UUID.randomUUID().toString();
173
174 public ExecutionFlowRuntime(ExecutionFlow executionFlow) {
175 this.executionFlow = executionFlow;
176 }
177
178 public ExecutionFlow getExecutionFlow() {
179 return executionFlow;
180 }
181
182 public Map<String, Object> getScopedObjects() {
183 return scopedObjects;
184 }
185
186 public String getUuid() {
187 return uuid;
188 }
189
190 public Map<String, Object> getLocalVariables() {
191 return localVariables;
192 }
193
194 }
195 }