]> git.argeo.org Git - gpl/argeo-slc.git/blob - runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/ExecutionParameterPostProcessor.java
Rename OverrideContextAware task
[gpl/argeo-slc.git] / runtime / org.argeo.slc.support.simple / src / main / java / org / argeo / slc / core / execution / ExecutionParameterPostProcessor.java
1 package org.argeo.slc.core.execution;
2
3 import java.beans.PropertyDescriptor;
4 import java.util.HashSet;
5 import java.util.Iterator;
6 import java.util.List;
7 import java.util.Map;
8 import java.util.Properties;
9 import java.util.Set;
10
11 import org.apache.commons.logging.Log;
12 import org.apache.commons.logging.LogFactory;
13 import org.argeo.slc.SlcException;
14 import org.argeo.slc.execution.ExecutionContext;
15 import org.springframework.beans.BeansException;
16 import org.springframework.beans.MutablePropertyValues;
17 import org.springframework.beans.PropertyValue;
18 import org.springframework.beans.PropertyValues;
19 import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
20 import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
21 import org.springframework.beans.factory.config.TypedStringValue;
22 import org.springframework.beans.factory.support.ManagedList;
23 import org.springframework.beans.factory.support.ManagedMap;
24 import org.springframework.beans.factory.support.ManagedSet;
25 import org.springframework.util.ObjectUtils;
26
27 public class ExecutionParameterPostProcessor extends
28 InstantiationAwareBeanPostProcessorAdapter {
29
30 private final static Log log = LogFactory
31 .getLog(ExecutionParameterPostProcessor.class);
32
33 private ExecutionContext executionContext;
34
35 private ExecutionScope executionScope;
36
37 private InstantiationManager instantiationManager;
38
39 public InstantiationManager getInstantiationManager() {
40 return instantiationManager;
41 }
42
43 public void setInstantiationManager(
44 InstantiationManager instantiationManager) {
45 this.instantiationManager = instantiationManager;
46 }
47
48 public void setExecutionScope(ExecutionScope executionScope) {
49 this.executionScope = executionScope;
50 }
51
52 public ExecutionContext getExecutionContext() {
53 return executionContext;
54 }
55
56 public void setExecutionContext(ExecutionContext executionContext) {
57 this.executionContext = executionContext;
58 }
59
60 private String placeholderPrefix = "@{";
61 private String placeholderSuffix = "}";
62 private String nullValue;
63
64 @Override
65 public PropertyValues postProcessPropertyValues(PropertyValues pvs,
66 PropertyDescriptor[] pds, Object bean, String beanName)
67 throws BeansException {
68
69 //TODO: resolve at execution only if scope is execution
70 //TODO: deal with placeholders in RuntimeBeanReference and RuntimeBeanNameReference
71
72 MutablePropertyValues newPvs = new MutablePropertyValues();
73
74 boolean changesOccured = false;
75
76 CustomPpc ppc = new CustomPpc(beanName);
77
78 for(PropertyValue pv : pvs.getPropertyValues()) {
79 Object convertedValue = ppc.resolveValue(pv.getValue());
80 newPvs.addPropertyValue(new PropertyValue(pv, convertedValue));
81 if(convertedValue != pv.getValue()) {
82 changesOccured = true;
83 }
84 }
85
86 return changesOccured ? newPvs : pvs;
87 }
88
89 public void setPlaceholderPrefix(String placeholderPrefix) {
90 this.placeholderPrefix = placeholderPrefix;
91 }
92
93 public void setPlaceholderSuffix(String placeholderSuffix) {
94 this.placeholderSuffix = placeholderSuffix;
95 }
96
97 public void setNullValue(String nullValue) {
98 this.nullValue = nullValue;
99 }
100
101 private class CustomPpc extends PropertyPlaceholderConfigurer {
102 private final Properties props;
103 String beanName;
104
105 public CustomPpc(String beanName) {
106 super();
107 this.props = new Properties();
108 this.beanName = beanName;
109 setPlaceholderPrefix(placeholderPrefix);
110 setPlaceholderSuffix(placeholderSuffix);
111 setSystemPropertiesMode(SYSTEM_PROPERTIES_MODE_NEVER);
112 }
113
114 /** Public access to the internals of PropertyPlaceholderConfigurer*/
115 public String resolveString(String strVal) {
116 String value = parseStringValue(strVal, this.props,
117 new HashSet<String>());
118 return (value.equals(nullValue) ? null : value);
119 }
120
121 public Object resolveValue(Object value) {
122 if (value instanceof TypedStringValue) {
123 TypedStringValue tsv = (TypedStringValue) value;
124 String originalValue = tsv.getValue();
125
126 String convertedValue = resolveString(originalValue);
127 return convertedValue.equals(originalValue) ? value : new TypedStringValue(convertedValue);
128 }
129 else if (value instanceof String) {
130 String originalValue = value.toString();
131 String convertedValue = resolveString(originalValue);
132 return convertedValue.equals(originalValue) ? value : convertedValue;
133 }
134 else if (value instanceof ManagedMap) {
135 Map mapVal = (Map) value;
136
137 Map newContent = new ManagedMap();
138 boolean entriesModified = false;
139 for (Iterator it = mapVal.entrySet().iterator(); it.hasNext();) {
140 Map.Entry entry = (Map.Entry) it.next();
141 Object key = entry.getKey();
142 int keyHash = (key != null ? key.hashCode() : 0);
143 Object newKey = resolveValue(key);
144 int newKeyHash = (newKey != null ? newKey.hashCode() : 0);
145 Object val = entry.getValue();
146 Object newVal = resolveValue(val);
147 newContent.put(newKey, newVal);
148 entriesModified = entriesModified || (newVal != val || newKey != key || newKeyHash != keyHash);
149 }
150
151 return entriesModified ? newContent : value;
152 }
153 else if (value instanceof ManagedList) {
154 List listVal = (List) value;
155 List newContent = new ManagedList();
156 boolean valueModified = false;
157
158 for (int i = 0; i < listVal.size(); i++) {
159 Object elem = listVal.get(i);
160 Object newVal = resolveValue(elem);
161 newContent.add(newVal);
162 if (!ObjectUtils.nullSafeEquals(newVal, elem)) {
163 valueModified = true;
164 }
165 }
166 return valueModified ? newContent : value;
167 }
168 else if (value instanceof ManagedSet) {
169 Set setVal = (Set) value;
170 Set newContent = new ManagedSet();
171 boolean entriesModified = false;
172 for (Iterator it = setVal.iterator(); it.hasNext();) {
173 Object elem = it.next();
174 int elemHash = (elem != null ? elem.hashCode() : 0);
175 Object newVal = resolveValue(elem);
176 int newValHash = (newVal != null ? newVal.hashCode() : 0);
177 newContent.add(newVal);
178 entriesModified = entriesModified || (newVal != elem || newValHash != elemHash);
179 }
180 return entriesModified ? newContent : value;
181 }
182 else {
183 return value;
184 }
185 }
186
187 @Override
188 protected String resolvePlaceholder(String placeholder, Properties props) {
189 if ((executionScope != null)
190 && (executionScope.hasExecutionContext())) {
191 Object obj = executionContext.findVariable(placeholder);
192 if(obj != null) {
193 return obj.toString();
194 }
195 }
196 if (instantiationManager.isInFlowInitialization())
197 return instantiationManager.getInitializingFlowParameter(
198 placeholder).toString();
199 else
200 throw new SlcException("Could not resolve placeholder '"
201 + placeholder + "' in bean '" + beanName + "'");
202 }
203 }
204 }