]> 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
Improve execution specs
[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 public static void enterFlow(ExecutionFlow executionFlow) {
52 Stack<ExecutionFlowRuntime> stack = executionContext.get().stack;
53
54 ExecutionFlowRuntime runtime = new ExecutionFlowRuntime(executionFlow);
55 stack.push(runtime);
56
57 if (log.isDebugEnabled())
58 log.debug(depthSpaces(stack.size()) + "=> " + executionFlow + " #"
59 + getCurrentStackUuid() + ", depth=" + stack.size());
60
61 Map<String, ExecutionSpecAttribute> specAttrs = executionFlow
62 .getExecutionSpec().getAttributes();
63 for (String key : specAttrs.keySet()) {
64 //ExecutionSpecAttribute esa = specAttrs.get(key);
65 if (executionFlow.isSetAsParameter(key)) {
66 runtime.getLocalVariables().put(key,
67 executionFlow.getParameter(key));
68 if (log.isTraceEnabled())
69 log.trace(depthSpaces(stack.size()) + "Add '" + key
70 + "' as local variable.");
71 }
72 }
73
74 }
75
76 public static Object getVariable(String key) {
77 Object obj = getWithCheck().findVariable(key);
78 if (obj == null)
79 throw new SlcException("Variable '" + key + "' not found.");
80 return obj;
81 }
82
83 protected Object findVariable(String key) {
84 Object obj = null;
85 for (int i = stack.size() - 1; i >= 0; i--) {
86 if (stack.get(i).getLocalVariables().containsKey(key)) {
87 obj = stack.get(i).getLocalVariables().get(key);
88 break;
89 }
90 }
91
92 // Look into global execution variables
93 if (obj == null) {
94 if (variables.containsKey(key))
95 obj = variables.get(key);
96 }
97
98 return obj;
99 }
100
101 private static String depthSpaces(int depth) {
102 StringBuffer buf = new StringBuffer(depth * 2);
103 for (int i = 0; i < depth; i++)
104 buf.append(" ");
105 return buf.toString();
106 }
107
108 public static void leaveFlow(ExecutionFlow executionFlow) {
109 Stack<ExecutionFlowRuntime> stack = executionContext.get().stack;
110 if (log.isDebugEnabled())
111 log.debug(depthSpaces(stack.size()) + "<= " + executionFlow + " #"
112 + getCurrentStackUuid() + ", depth=" + stack.size());
113
114 ExecutionFlowRuntime leftEf = stack.pop();
115 if (!leftEf.getExecutionFlow().getName()
116 .equals(executionFlow.getName()))
117 throw new SlcException("Asked to leave " + executionFlow
118 + " but last is " + leftEf);
119
120 leftEf.getScopedObjects().clear();
121 leftEf.getLocalVariables().clear();
122
123 }
124
125 public static String getCurrentStackUuid() {
126 return getWithCheck().stack.peek().uuid;
127 }
128
129 // public static ExecutionFlow getCurrentFlow() {
130 // return getWithCheck().stack.peek().executionFlow;
131 // }
132
133 public static Boolean isExecuting() {
134 return executionContext.get() != null;
135 }
136
137 protected static ExecutionContext getWithCheck() {
138 if (executionContext.get() == null)
139 throw new SlcException("No execution context");
140 return executionContext.get();
141 }
142
143 public static Object findOrAddScopedObject(String name,
144 ObjectFactory objectFactory) {
145 ExecutionContext executionContext = getWithCheck();
146 Object obj = executionContext.findScopedObject(name);
147 if (obj == null) {
148 obj = objectFactory.getObject();
149 executionContext.stack.peek().getScopedObjects().put(name, obj);
150 }
151 return obj;
152 }
153
154 /** return null if not found */
155 protected Object findScopedObject(String key) {
156 Object obj = null;
157 for (int i = stack.size() - 1; i >= 0; i--) {
158 if (stack.get(i).getScopedObjects().containsKey(key)) {
159 obj = stack.get(i).getScopedObjects().get(key);
160 break;
161 }
162 }
163 return obj;
164 }
165
166 public String getUuid() {
167 return uuid;
168 }
169
170 private static class ExecutionFlowRuntime {
171 private final ExecutionFlow executionFlow;
172 private final Map<String, Object> scopedObjects = new HashMap<String, Object>();
173 private final Map<String, Object> localVariables = new HashMap<String, Object>();
174 private final String uuid = UUID.randomUUID().toString();
175
176 public ExecutionFlowRuntime(ExecutionFlow executionFlow) {
177 this.executionFlow = executionFlow;
178 }
179
180 public ExecutionFlow getExecutionFlow() {
181 return executionFlow;
182 }
183
184 public Map<String, Object> getScopedObjects() {
185 return scopedObjects;
186 }
187
188 public String getUuid() {
189 return uuid;
190 }
191
192 public Map<String, Object> getLocalVariables() {
193 return localVariables;
194 }
195
196 }
197 }