]> 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
9cb6948297bcd64696bc61cd79c15f329486c08c
[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.LinkedHashMap;
7 import java.util.Map;
8 import java.util.Properties;
9
10 import org.apache.commons.logging.Log;
11 import org.apache.commons.logging.LogFactory;
12 import org.argeo.slc.SlcException;
13 import org.argeo.slc.execution.ExecutionContext;
14 import org.springframework.beans.BeansException;
15 import org.springframework.beans.MutablePropertyValues;
16 import org.springframework.beans.PropertyValue;
17 import org.springframework.beans.PropertyValues;
18 import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
19 import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
20 import org.springframework.beans.factory.config.TypedStringValue;
21 import org.springframework.beans.factory.support.ManagedMap;
22
23 public class ExecutionParameterPostProcessor extends
24 InstantiationAwareBeanPostProcessorAdapter {
25
26 private final static Log log = LogFactory
27 .getLog(ExecutionParameterPostProcessor.class);
28
29 // private CustomPpc ppc = new CustomPpc(new Properties());
30
31 private ExecutionContext executionContext;
32
33 private ExecutionScope executionScope;
34
35 private InstantiationManager instantiationManager;
36
37 public InstantiationManager getInstantiationManager() {
38 return instantiationManager;
39 }
40
41 public void setInstantiationManager(
42 InstantiationManager instantiationManager) {
43 this.instantiationManager = instantiationManager;
44 }
45
46 public void setExecutionScope(ExecutionScope executionScope) {
47 this.executionScope = executionScope;
48 }
49
50 public ExecutionContext getExecutionContext() {
51 return executionContext;
52 }
53
54 public void setExecutionContext(ExecutionContext executionContext) {
55 this.executionContext = executionContext;
56 }
57
58 private String placeholderPrefix = "@{";
59 private String placeholderSuffix = "}";
60 private String nullValue;
61
62 protected Object resolveValue(Object value, CustomPpc ppc) {
63 if (value instanceof TypedStringValue) {
64 TypedStringValue tsv = (TypedStringValue) value;
65 return ppc.process(tsv.getValue());
66 }
67 else if (value instanceof String) {
68 return ppc.process(value.toString());
69 }
70 else {
71 return value;
72 }
73 }
74
75 @Override
76 public PropertyValues postProcessPropertyValues(PropertyValues pvs,
77 PropertyDescriptor[] pds, Object bean, String beanName)
78 throws BeansException {
79
80 //TODO: resolve at execution only if scope is execution
81
82 // boolean inFlowInitialization = instantiationManager
83 // .isInFlowInitialization();
84 //
85 // if (((executionScope == null) || (!executionScope.hasExecutionContext()))
86 // && !inFlowInitialization) {
87 // // log.info("Skip parameter conversion for bean " + beanName);
88 // return pvs;
89 // } else {
90 // // log.info("Execute parameter conversion for bean " + beanName);
91 // }
92
93 // copy the property values
94 //MutablePropertyValues newPv = new MutablePropertyValues(pvs);
95
96 Properties props = new Properties();
97 CustomPpc ppc = new CustomPpc(props);
98
99 for (PropertyValue pv : pvs.getPropertyValues()) {
100 // log.info(" PropertyValue pv " + pv.getValue() + " - "
101 // + pv.getValue().getClass());
102 String originalValue = null;
103 String convertedValue = null;
104
105 if (pv.getValue() instanceof TypedStringValue) {
106 TypedStringValue tsv = (TypedStringValue) pv.getValue();
107 originalValue = tsv.getValue();
108 convertedValue = ppc.process(originalValue);
109 if (!convertedValue.equals(originalValue))
110 tsv.setValue(convertedValue);
111 }
112 else if (pv.getValue() instanceof String) {
113 originalValue = pv.getValue().toString();
114 convertedValue = ppc.process(originalValue);
115 // Setting the convertedValue can be problematic since
116 // calling setConvertedValue also sets a flag setConvertedValue
117 if (!convertedValue.equals(originalValue))
118 pv.setConvertedValue(convertedValue);
119 }
120
121 else if (pv.getValue() instanceof ManagedMap) {
122 //debug
123 Object obj = pv.getValue();
124 String name = pv.getName();
125
126 // log.info("##" + name + ":" + obj.getClass());
127 ManagedMap mapVal = (ManagedMap) pv.getValue();
128
129 Map newContent = new LinkedHashMap();
130 boolean entriesModified = false;
131 for (Iterator it = mapVal.entrySet().iterator(); it.hasNext();) {
132 Map.Entry entry = (Map.Entry) it.next();
133 Object key = entry.getKey();
134 int keyHash = (key != null ? key.hashCode() : 0);
135 Object newKey = resolveValue(key,ppc);
136 int newKeyHash = (newKey != null ? newKey.hashCode() : 0);
137 Object val = entry.getValue();
138 Object newVal = resolveValue(val,ppc);
139 newContent.put(newKey, newVal);
140 entriesModified = entriesModified || (newVal != val || newKey != key || newKeyHash != keyHash);
141 }
142 if (entriesModified) {
143 mapVal.clear();
144 mapVal.putAll(newContent);
145 }
146 }
147
148 if (convertedValue != null && log.isTraceEnabled()) {
149 if (!originalValue.equals(convertedValue))
150 log.trace("Converted field '" + pv.getName() + "': '"
151 + originalValue + "' to '" + convertedValue
152 + "' in bean " + beanName);
153 }
154 }
155
156 return pvs;
157 }
158
159 public void setPlaceholderPrefix(String placeholderPrefix) {
160 this.placeholderPrefix = placeholderPrefix;
161 }
162
163 public void setPlaceholderSuffix(String placeholderSuffix) {
164 this.placeholderSuffix = placeholderSuffix;
165 }
166
167 public void setNullValue(String nullValue) {
168 this.nullValue = nullValue;
169 }
170
171 private class CustomPpc extends PropertyPlaceholderConfigurer {
172 private final Properties props;
173
174 public CustomPpc(Properties props) {
175 super();
176 this.props = props;
177 setPlaceholderPrefix(placeholderPrefix);
178 setPlaceholderSuffix(placeholderSuffix);
179 setSystemPropertiesMode(SYSTEM_PROPERTIES_MODE_NEVER);
180 }
181
182 /** Public access to the internals of PropertyPlaceholderConfigurer*/
183 public String process(String strVal) {
184 String value = parseStringValue(strVal, this.props,
185 new HashSet<String>());
186 return (value.equals(nullValue) ? null : value);
187 }
188
189 @Override
190 protected String resolvePlaceholder(String placeholder, Properties props) {
191 // log.info("Try convert placeholder " + placeholder);
192 if ((executionScope != null)
193 && (executionScope.hasExecutionContext()))
194 return executionContext.getVariable(placeholder).toString();
195 else if (instantiationManager.isInFlowInitialization())
196 return instantiationManager.getInitializingFlowParameter(
197 placeholder).toString();
198 else
199 return super.resolvePlaceholder(placeholder, props);
200 }
201 }
202 }