]> git.argeo.org Git - gpl/argeo-slc.git/blob - runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/DefaultExecutionFlowDescriptorConverter.java
Security
[gpl/argeo-slc.git] / runtime / org.argeo.slc.core / src / main / java / org / argeo / slc / core / execution / DefaultExecutionFlowDescriptorConverter.java
1 package org.argeo.slc.core.execution;
2
3 import java.util.HashMap;
4 import java.util.Map;
5 import java.util.TreeMap;
6
7 import org.apache.commons.logging.Log;
8 import org.apache.commons.logging.LogFactory;
9 import org.argeo.slc.SlcException;
10 import org.argeo.slc.UnsupportedException;
11 import org.argeo.slc.execution.ExecutionFlow;
12 import org.argeo.slc.execution.ExecutionFlowDescriptor;
13 import org.argeo.slc.execution.ExecutionFlowDescriptorConverter;
14 import org.argeo.slc.execution.ExecutionModuleDescriptor;
15 import org.argeo.slc.execution.ExecutionSpec;
16 import org.argeo.slc.execution.ExecutionSpecAttribute;
17 import org.springframework.aop.scope.ScopedObject;
18 import org.springframework.beans.BeansException;
19 import org.springframework.beans.factory.config.BeanDefinition;
20 import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
21 import org.springframework.context.ApplicationContext;
22 import org.springframework.context.ApplicationContextAware;
23 import org.springframework.context.ConfigurableApplicationContext;
24 import org.springframework.util.Assert;
25
26 public class DefaultExecutionFlowDescriptorConverter implements
27 ExecutionFlowDescriptorConverter, ApplicationContextAware {
28 public final static String REF_VALUE_TYPE_BEAN_NAME = "beanName";
29
30 private final static Log log = LogFactory
31 .getLog(DefaultExecutionFlowDescriptorConverter.class);
32
33 private ApplicationContext applicationContext;
34
35 public Map<String, Object> convertValues(
36 ExecutionFlowDescriptor executionFlowDescriptor) {
37 Map<String, Object> values = executionFlowDescriptor.getValues();
38 Map<String, Object> convertedValues = new HashMap<String, Object>();
39
40 if (values != null) {
41 for (String key : values.keySet()) {
42 Object value = values.get(key);
43 if (value instanceof PrimitiveValue) {
44 PrimitiveValue primitiveValue = (PrimitiveValue) value;
45 // TODO: check class <=> type
46 convertedValues.put(key, primitiveValue.getValue());
47 } else if (value instanceof RefValue) {
48 RefValue refValue = (RefValue) value;
49
50 if (REF_VALUE_TYPE_BEAN_NAME.equals(refValue.getType()))
51 if (refValue.getRef() != null) {
52 Object obj = applicationContext.getBean(refValue
53 .getRef());
54 convertedValues.put(key, obj);
55 } else {
56 log.warn("Cannot interpret " + refValue);
57 }
58 else
59 throw new UnsupportedException("Ref value type",
60 refValue.getType());
61 }
62 }
63 }
64 return convertedValues;
65 }
66
67 public void addFlowsToDescriptor(ExecutionModuleDescriptor md,
68 Map<String, ExecutionFlow> executionFlows) {
69 for (String name : executionFlows.keySet()) {
70 ExecutionFlow executionFlow = executionFlows.get(name);
71
72 Assert.notNull(executionFlow.getName());
73 Assert.state(name.equals(executionFlow.getName()));
74
75 ExecutionSpec executionSpec = executionFlow.getExecutionSpec();
76 Assert.notNull(executionSpec);
77 Assert.notNull(executionSpec.getName());
78
79 Map<String, Object> values = new TreeMap<String, Object>();
80 for (String key : executionSpec.getAttributes().keySet()) {
81 ExecutionSpecAttribute attribute = executionSpec
82 .getAttributes().get(key);
83
84 if (attribute instanceof PrimitiveSpecAttribute) {
85 if (executionFlow.isSetAsParameter(key)) {
86 Object value = executionFlow.getParameter(key);
87 PrimitiveValue primitiveValue = new PrimitiveValue();
88 primitiveValue
89 .setType(((PrimitiveSpecAttribute) attribute)
90 .getType());
91 primitiveValue.setValue(value);
92 values.put(key, primitiveValue);
93 } else {
94 // no need to add a primitive value if it is not set,
95 // all necessary information is in the spec
96 }
97 } else if (attribute instanceof RefSpecAttribute) {
98 values.put(key, buildRefValue((RefSpecAttribute) attribute,
99 executionFlow, key));
100 } else {
101 throw new SlcException("Unkown spec attribute type "
102 + attribute.getClass());
103 }
104
105 }
106
107 ExecutionFlowDescriptor efd = new ExecutionFlowDescriptor(name,
108 values, executionSpec);
109 if (executionFlow.getPath() != null)
110 efd.setPath(executionFlow.getPath());
111
112 // Takes description from spring
113 BeanDefinition bd = getBeanFactory().getBeanDefinition(name);
114 efd.setDescription(bd.getDescription());
115
116 // Add execution spec if necessary
117 if (!md.getExecutionSpecs().contains(executionSpec))
118 md.getExecutionSpecs().add(executionSpec);
119
120 // Add execution flow
121 md.getExecutionFlows().add(efd);
122 }
123 }
124
125 @SuppressWarnings(value = { "unchecked" })
126 protected RefValue buildRefValue(RefSpecAttribute rsa,
127 ExecutionFlow executionFlow, String key) {
128 RefValue refValue = new RefValue();
129 refValue.setType(REF_VALUE_TYPE_BEAN_NAME);
130
131 if (executionFlow.isSetAsParameter(key)) {
132 String ref = null;
133 Object value = executionFlow.getParameter(key);
134 if (applicationContext == null) {
135 log
136 .warn("No application context declared, cannot scan ref value.");
137 ref = value.toString();
138 } else {
139
140 // look for a ref to the value
141 Map<String, Object> beans = getBeanFactory().getBeansOfType(
142 rsa.getTargetClass(), false, false);
143 // TODO: also check scoped beans
144 beans: for (String beanName : beans.keySet()) {
145 Object obj = beans.get(beanName);
146 if (value instanceof ScopedObject) {
147 // don't call methods of the target of the scope
148 if (obj instanceof ScopedObject)
149 if (value == obj) {
150 ref = beanName;
151 break beans;
152 }
153 } else {
154 if (obj.equals(value)) {
155 ref = beanName;
156 break beans;
157 }
158 }
159 }
160 }
161 if (ref == null)
162 log.warn("Cannot define reference for ref spec attribute "
163 + key + " in " + executionFlow + " (" + rsa + ")");
164 else if (log.isDebugEnabled())
165 log.debug(ref + " is the reference for ref spec attribute "
166 + key + " in " + executionFlow + " (" + rsa + ")");
167 refValue.setRef(ref);
168 }
169 return refValue;
170 }
171
172 private ConfigurableListableBeanFactory getBeanFactory() {
173 return ((ConfigurableApplicationContext) applicationContext)
174 .getBeanFactory();
175 }
176
177 /** Must be use within the execution application context */
178 public void setApplicationContext(ApplicationContext applicationContext)
179 throws BeansException {
180 this.applicationContext = applicationContext;
181 }
182
183 }