2 * Copyright (C) 2007-2012 Mathieu Baudier
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package org
.argeo
.slc
.core
.execution
;
18 import java
.util
.HashMap
;
20 import java
.util
.Stack
;
21 import java
.util
.UUID
;
23 import org
.apache
.commons
.logging
.Log
;
24 import org
.apache
.commons
.logging
.LogFactory
;
25 import org
.argeo
.slc
.SlcException
;
26 import org
.argeo
.slc
.execution
.ExecutionFlow
;
27 import org
.argeo
.slc
.execution
.ExecutionSpecAttribute
;
28 import org
.argeo
.slc
.execution
.ExecutionStack
;
30 /** Canonical implementation of an execution stack. */
31 public class DefaultExecutionStack
implements ExecutionStack
{
33 private final static Log log
= LogFactory
34 .getLog(DefaultExecutionStack
.class);
36 private final Stack
<ExecutionFlowRuntime
> stack
= new Stack
<ExecutionFlowRuntime
>();
38 public synchronized void enterFlow(ExecutionFlow executionFlow
) {
39 ExecutionFlowRuntime runtime
= new ExecutionFlowRuntime(executionFlow
);
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
));
52 public synchronized String
getCurrentStackLevelUuid() {
53 return stack
.peek().getUuid();
56 public synchronized Integer
getStackSize() {
61 * Looks for a set variable in the stack, starting at the upper flows
63 * @return the variable or <code>null</code> if not found
65 public synchronized Object
findLocalVariable(String key
) {
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
);
76 public synchronized void leaveFlow(ExecutionFlow executionFlow
) {
77 ExecutionFlowRuntime leftEf
= stack
.pop();
79 if (!leftEf
.getExecutionFlow().getName()
80 .equals(executionFlow
.getName()))
81 throw new SlcException("Asked to leave " + executionFlow
82 + " but last is " + leftEf
);
84 leftEf
.getScopedObjects().clear();
85 leftEf
.getLocalVariables().clear();
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
);
94 log
.warn("Scoped object " + name
+ " of type " + obj
.getClass()
95 + " already registered in " + runtime
);
97 runtime
.getScopedObjects().put(name
, obj
);
100 /** @return </code>null<code> if not found */
101 public synchronized Object
findScopedObject(String name
) {
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
);
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();
118 public ExecutionFlowRuntime(ExecutionFlow executionFlow
) {
119 this.executionFlow
= executionFlow
;
122 public ExecutionFlow
getExecutionFlow() {
123 return executionFlow
;
126 public Map
<String
, Object
> getScopedObjects() {
127 return scopedObjects
;
130 public String
getUuid() {
134 public Map
<String
, Object
> getLocalVariables() {
135 return localVariables
;
139 public String
toString() {
140 return "Stack Level #" + uuid
;