]> git.argeo.org Git - gpl/argeo-slc.git/blob - org.argeo.slc.runtime/src/org/argeo/slc/runtime/InstantiationManager.java
Introduce mbox support
[gpl/argeo-slc.git] / org.argeo.slc.runtime / src / org / argeo / slc / runtime / InstantiationManager.java
1 package org.argeo.slc.runtime;
2
3 import java.lang.System.Logger.Level;
4 import java.util.Stack;
5
6 import org.argeo.slc.SlcException;
7 import org.argeo.slc.execution.ExecutionFlow;
8 import org.argeo.slc.execution.ExecutionSpecAttribute;
9 import org.argeo.slc.execution.RefSpecAttribute;
10 import org.argeo.slc.primitive.PrimitiveSpecAttribute;
11 import org.argeo.slc.primitive.PrimitiveUtils;
12
13 /** Manage parameters that need to be set during the instantiation of a flow */
14 public class InstantiationManager {
15
16 private final static System.Logger logger = System.getLogger(InstantiationManager.class.getName());
17
18 private ThreadLocal<Stack<ExecutionFlow>> flowStack = new ThreadLocal<Stack<ExecutionFlow>>();
19
20 public Object createRef(String name) {
21
22 if ((flowStack.get() == null) || flowStack.get().empty()) {
23 throw new SlcException(
24 "No flow is currently initializing." + " Declare ParameterRef as inner beans or prototypes.");
25 }
26
27 return getInitializingFlowParameter(name);
28 }
29
30 public void flowInitializationStarted(ExecutionFlow flow, String flowName) {
31 // set the flow name if it is DefaultExecutionFlow
32 if (flow instanceof DefaultExecutionFlow) {
33 ((DefaultExecutionFlow) flow).setName(flowName);
34 }
35
36 logger.log(Level.TRACE,
37 () -> "Start initialization of " + flow.hashCode() + " (" + flow + " - " + flow.getClass() + ")");
38
39 // log.info("# flowInitializationStarted " + flowName);
40 // create a stack for this thread if there is none
41 if (flowStack.get() == null) {
42 flowStack.set(new Stack<ExecutionFlow>());
43 }
44 flowStack.get().push(flow);
45 }
46
47 public void flowInitializationFinished(ExecutionFlow flow, String flowName) {
48 logger.log(Level.TRACE,
49 () -> "Finish initialization of " + flow.hashCode() + " (" + flow + " - " + flow.getClass() + ")");
50
51 if (flowStack.get() != null) {
52 ExecutionFlow registeredFlow = flowStack.get().pop();
53 if (registeredFlow != null) {
54 if (!flow.getName().equals(registeredFlow.getName()))
55 throw new SlcException("Current flow is " + flow);
56 // log.info("# flowInitializationFinished " + flowName);
57 // initializingFlow.set(null);
58 }
59 } else {
60 // happens for flows imported as services
61 logger.log(Level.WARNING, "flowInitializationFinished - Flow Stack is null");
62 }
63 }
64
65 protected ExecutionFlow findInitializingFlowWithParameter(String key) {
66 if ((flowStack.get() == null) || flowStack.get().empty())
67 throw new SlcException("No initializing flow available.");
68
69 // first look in the outer flow (that may override parameters)
70 for (int i = 0; i < flowStack.get().size(); i++) {
71 if (flowStack.get().elementAt(i).isSetAsParameter(key)) {
72 return flowStack.get().elementAt(i);
73 }
74 }
75 throw new SlcException("Key " + key + " is not set as parameter in " + flowStack.get().firstElement().toString()
76 + " (stack size=" + flowStack.get().size() + ")");
77
78 }
79
80 public Object getInitializingFlowParameter(String key) {
81 return findInitializingFlowWithParameter(key).getParameter(key);
82 }
83
84 public Class<?> getInitializingFlowParameterClass(String key) {
85 ExecutionSpecAttribute attr = findInitializingFlowWithParameter(key).getExecutionSpec().getAttributes()
86 .get(key);
87 if (attr instanceof RefSpecAttribute)
88 return ((RefSpecAttribute) attr).getTargetClass();
89 else if (attr instanceof PrimitiveSpecAttribute) {
90 String type = ((PrimitiveSpecAttribute) attr).getType();
91 Class<?> clss = PrimitiveUtils.typeAsClass(type);
92 if (clss == null)
93 throw new SlcException("Cannot convert type " + type + " to class.");
94 return clss;
95 } else
96 return null;
97 }
98
99 public Boolean isInFlowInitialization() {
100 return (flowStack.get() != null) && !flowStack.get().empty();
101 }
102 }