]> git.argeo.org Git - gpl/argeo-slc.git/blob - runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/MapExecutionContext.java
Introduce execution flow test case
[gpl/argeo-slc.git] / runtime / org.argeo.slc.core / src / main / java / org / argeo / slc / core / execution / MapExecutionContext.java
1 package org.argeo.slc.core.execution;
2
3 import java.util.Date;
4 import java.util.HashMap;
5 import java.util.Map;
6 import java.util.Stack;
7 import java.util.UUID;
8
9 import org.apache.commons.logging.Log;
10 import org.apache.commons.logging.LogFactory;
11 import org.argeo.slc.SlcException;
12 import org.argeo.slc.execution.ExecutionContext;
13 import org.argeo.slc.execution.ExecutionFlow;
14 import org.argeo.slc.execution.ExecutionSpecAttribute;
15
16 public class MapExecutionContext implements ExecutionContext {
17
18 private final static Log log = LogFactory.getLog(MapExecutionContext.class);
19
20 private final Stack<ExecutionFlowRuntime> stack = new Stack<ExecutionFlowRuntime>();
21
22 // TODO: make it thread safe?
23 private final Map<String, Object> variables = new HashMap<String, Object>();
24
25 private final String uuid;
26
27 private final Date creationDate = new Date();
28
29 public MapExecutionContext() {
30 uuid = UUID.randomUUID().toString();
31 variables.put(VAR_EXECUTION_CONTEXT_ID, uuid);
32 }
33
34 public void addVariables(
35 Map<? extends String, ? extends Object> variablesToAdd) {
36 variables.putAll(variablesToAdd);
37 }
38
39 public void enterFlow(ExecutionFlow executionFlow) {
40 ExecutionFlowRuntime runtime = new ExecutionFlowRuntime(executionFlow);
41 stack.push(runtime);
42 variables.put(VAR_FLOW_ID, runtime.getUuid());
43 variables.put(VAR_FLOW_NAME, runtime.getExecutionFlow().getName());
44
45 if (log.isDebugEnabled())
46 log.debug(depthSpaces(stack.size()) + "=> " + executionFlow + " #"
47 + uuid + ", depth=" + stack.size());
48
49 Map<String, ExecutionSpecAttribute> specAttrs = executionFlow
50 .getExecutionSpec().getAttributes();
51 for (String key : specAttrs.keySet()) {
52 // ExecutionSpecAttribute esa = specAttrs.get(key);
53 if (executionFlow.isSetAsParameter(key)) {
54 runtime.getLocalVariables().put(key,
55 executionFlow.getParameter(key));
56 if (log.isTraceEnabled())
57 log.trace(depthSpaces(stack.size()) + "Add '" + key
58 + "' as local variable.");
59 }
60 }
61
62 }
63
64 public Object getVariable(String key) {
65 Object obj = findVariable(key);
66 if (obj == null)
67 throw new SlcException("Variable '" + key + "' not found.");
68 return obj;
69 }
70
71 public Object findVariable(String key) {
72 Object obj = null;
73
74 // Look if the variable is set in the global execution variables
75 // (i.e. the variable was overridden)
76 if (variables.containsKey(key))
77 obj = variables.get(key);
78
79 // if the variable was not found, look in the stack starting at the
80 // upper flows
81 if (obj == null) {
82 for (int i = 0; i < stack.size(); i++) {
83 if (stack.get(i).getLocalVariables().containsKey(key)) {
84 obj = stack.get(i).getLocalVariables().get(key);
85 break;
86 }
87 }
88 }
89
90 return obj;
91 }
92
93 private static String depthSpaces(int depth) {
94 StringBuffer buf = new StringBuffer(depth * 2);
95 for (int i = 0; i < depth; i++)
96 buf.append(" ");
97 return buf.toString();
98 }
99
100 public void leaveFlow(ExecutionFlow executionFlow) {
101 if (log.isDebugEnabled())
102 log.debug(depthSpaces(stack.size()) + "<= " + executionFlow + " #"
103 + uuid + ", depth=" + stack.size());
104
105 ExecutionFlowRuntime leftEf = stack.pop();
106 if (!leftEf.getExecutionFlow().getName()
107 .equals(executionFlow.getName()))
108 throw new SlcException("Asked to leave " + executionFlow
109 + " but last is " + leftEf);
110
111 leftEf.getScopedObjects().clear();
112 leftEf.getLocalVariables().clear();
113
114 }
115
116 public void addScopedObject(String name, Object obj) {
117 // TODO: check that the object is not set yet ?
118 stack.peek().getScopedObjects().put(name, obj);
119 }
120
121 /** return null if not found */
122 public Object findScopedObject(String name) {
123 Object obj = null;
124 for (int i = stack.size() - 1; i >= 0; i--) {
125 if (stack.get(i).getScopedObjects().containsKey(name)) {
126 obj = stack.get(i).getScopedObjects().get(name);
127 break;
128 }
129 }
130 return obj;
131 }
132
133 public String getUuid() {
134 return uuid;
135 }
136
137 public Date getCreationDate() {
138 return creationDate;
139 }
140
141 private static class ExecutionFlowRuntime {
142 private final ExecutionFlow executionFlow;
143 private final Map<String, Object> scopedObjects = new HashMap<String, Object>();
144 private final Map<String, Object> localVariables = new HashMap<String, Object>();
145 private final String uuid = UUID.randomUUID().toString();
146
147 public ExecutionFlowRuntime(ExecutionFlow executionFlow) {
148 this.executionFlow = executionFlow;
149 }
150
151 public ExecutionFlow getExecutionFlow() {
152 return executionFlow;
153 }
154
155 public Map<String, Object> getScopedObjects() {
156 return scopedObjects;
157 }
158
159 public String getUuid() {
160 return uuid;
161 }
162
163 public Map<String, Object> getLocalVariables() {
164 return localVariables;
165 }
166
167 }
168 }