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