]> git.argeo.org Git - gpl/argeo-slc.git/blob - runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/DefaultExecutionStack.java
Document and improve execution model
[gpl/argeo-slc.git] / runtime / org.argeo.slc.core / src / main / java / org / argeo / slc / core / execution / DefaultExecutionStack.java
1 /*
2 * Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org>
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package org.argeo.slc.core.execution;
18
19 import java.util.HashMap;
20 import java.util.Map;
21 import java.util.Stack;
22 import java.util.UUID;
23
24 import org.apache.commons.logging.Log;
25 import org.apache.commons.logging.LogFactory;
26 import org.argeo.slc.SlcException;
27 import org.argeo.slc.execution.ExecutionFlow;
28 import org.argeo.slc.execution.ExecutionSpecAttribute;
29 import org.argeo.slc.execution.ExecutionStack;
30
31 public class DefaultExecutionStack implements ExecutionStack {
32
33 private final static Log log = LogFactory
34 .getLog(DefaultExecutionStack.class);
35
36 private final Stack<ExecutionFlowRuntime> stack = new Stack<ExecutionFlowRuntime>();
37
38 public synchronized void enterFlow(ExecutionFlow executionFlow) {
39 ExecutionFlowRuntime runtime = new ExecutionFlowRuntime(executionFlow);
40 stack.push(runtime);
41
42 Map<String, ExecutionSpecAttribute> specAttrs = executionFlow
43 .getExecutionSpec().getAttributes();
44 for (String key : specAttrs.keySet()) {
45 if (executionFlow.isSetAsParameter(key)) {
46 runtime.getLocalVariables().put(key,
47 executionFlow.getParameter(key));
48 }
49 }
50 }
51
52 public synchronized String getCurrentStackLevelUuid() {
53 return stack.peek().getUuid();
54 }
55
56 public synchronized Integer getStackSize() {
57 return stack.size();
58 }
59
60 /**
61 * Looks for a set variable in the stack, starting at the upper flows
62 *
63 * @return the variable or <code>null</code> if not found
64 */
65 public synchronized Object findLocalVariable(String key) {
66 Object obj = null;
67 for (int i = 0; i < stack.size(); i++) {
68 if (stack.get(i).getLocalVariables().containsKey(key)) {
69 obj = stack.get(i).getLocalVariables().get(key);
70 break;
71 }
72 }
73 return obj;
74 }
75
76 public synchronized void leaveFlow(ExecutionFlow executionFlow) {
77 ExecutionFlowRuntime leftEf = stack.pop();
78
79 if (!leftEf.getExecutionFlow().getName()
80 .equals(executionFlow.getName()))
81 throw new SlcException("Asked to leave " + executionFlow
82 + " but last is " + leftEf);
83
84 leftEf.getScopedObjects().clear();
85 leftEf.getLocalVariables().clear();
86 }
87
88 public synchronized void addScopedObject(String name, Object obj) {
89 ExecutionFlowRuntime runtime = stack.peek();
90 // TODO: check that the object is not set yet ?
91 if (log.isDebugEnabled()) {
92 Object existing = findScopedObject(name);
93 if (existing != null)
94 log.warn("Scoped object " + name + " of type " + obj.getClass()
95 + " already registered in " + runtime);
96 }
97 runtime.getScopedObjects().put(name, obj);
98 }
99
100 /** @return </code>null<code> if not found */
101 public synchronized Object findScopedObject(String name) {
102 Object obj = null;
103 for (int i = stack.size() - 1; i >= 0; i--) {
104 if (stack.get(i).getScopedObjects().containsKey(name)) {
105 obj = stack.get(i).getScopedObjects().get(name);
106 break;
107 }
108 }
109 return obj;
110 }
111
112 protected static class ExecutionFlowRuntime {
113 private final ExecutionFlow executionFlow;
114 private final Map<String, Object> scopedObjects = new HashMap<String, Object>();
115 private final Map<String, Object> localVariables = new HashMap<String, Object>();
116 private final String uuid = UUID.randomUUID().toString();
117
118 public ExecutionFlowRuntime(ExecutionFlow executionFlow) {
119 this.executionFlow = executionFlow;
120 }
121
122 public ExecutionFlow getExecutionFlow() {
123 return executionFlow;
124 }
125
126 public Map<String, Object> getScopedObjects() {
127 return scopedObjects;
128 }
129
130 public String getUuid() {
131 return uuid;
132 }
133
134 public Map<String, Object> getLocalVariables() {
135 return localVariables;
136 }
137
138 @Override
139 public String toString() {
140 return "Stack Level #" + uuid;
141 }
142
143 }
144 }