1 package org
.argeo
.slc
.core
.execution
;
3 import java
.beans
.PropertyDescriptor
;
4 import java
.util
.HashSet
;
5 import java
.util
.Iterator
;
8 import java
.util
.Properties
;
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
;
27 public class ExecutionParameterPostProcessor
extends
28 InstantiationAwareBeanPostProcessorAdapter
{
30 private final static Log log
= LogFactory
31 .getLog(ExecutionParameterPostProcessor
.class);
33 private ExecutionContext executionContext
;
35 private ExecutionScope executionScope
;
37 private InstantiationManager instantiationManager
;
39 public InstantiationManager
getInstantiationManager() {
40 return instantiationManager
;
43 public void setInstantiationManager(
44 InstantiationManager instantiationManager
) {
45 this.instantiationManager
= instantiationManager
;
48 public void setExecutionScope(ExecutionScope executionScope
) {
49 this.executionScope
= executionScope
;
52 public ExecutionContext
getExecutionContext() {
53 return executionContext
;
56 public void setExecutionContext(ExecutionContext executionContext
) {
57 this.executionContext
= executionContext
;
60 private String placeholderPrefix
= "@{";
61 private String placeholderSuffix
= "}";
62 private String nullValue
;
65 public PropertyValues
postProcessPropertyValues(PropertyValues pvs
,
66 PropertyDescriptor
[] pds
, Object bean
, String beanName
)
67 throws BeansException
{
69 //TODO: resolve at execution only if scope is execution
70 //TODO: deal with placeholders in RuntimeBeanReference and RuntimeBeanNameReference
72 MutablePropertyValues newPvs
= new MutablePropertyValues();
74 boolean changesOccured
= false;
76 CustomPpc ppc
= new CustomPpc(beanName
);
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;
86 return changesOccured ? newPvs
: pvs
;
89 public void setPlaceholderPrefix(String placeholderPrefix
) {
90 this.placeholderPrefix
= placeholderPrefix
;
93 public void setPlaceholderSuffix(String placeholderSuffix
) {
94 this.placeholderSuffix
= placeholderSuffix
;
97 public void setNullValue(String nullValue
) {
98 this.nullValue
= nullValue
;
101 private class CustomPpc
extends PropertyPlaceholderConfigurer
{
102 private final Properties props
;
105 public CustomPpc(String beanName
) {
107 this.props
= new Properties();
108 this.beanName
= beanName
;
109 setPlaceholderPrefix(placeholderPrefix
);
110 setPlaceholderSuffix(placeholderSuffix
);
111 setSystemPropertiesMode(SYSTEM_PROPERTIES_MODE_NEVER
);
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
);
121 public Object
resolveValue(Object value
) {
122 if (value
instanceof TypedStringValue
) {
123 TypedStringValue tsv
= (TypedStringValue
) value
;
124 String originalValue
= tsv
.getValue();
126 String convertedValue
= resolveString(originalValue
);
127 return convertedValue
.equals(originalValue
) ? value
: new TypedStringValue(convertedValue
);
129 else if (value
instanceof String
) {
130 String originalValue
= value
.toString();
131 String convertedValue
= resolveString(originalValue
);
132 return convertedValue
.equals(originalValue
) ? value
: convertedValue
;
134 else if (value
instanceof ManagedMap
) {
135 Map mapVal
= (Map
) value
;
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
);
151 return entriesModified ? newContent
: value
;
153 else if (value
instanceof ManagedList
) {
154 List listVal
= (List
) value
;
155 List newContent
= new ManagedList();
156 boolean valueModified
= false;
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;
166 return valueModified ? newContent
: value
;
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
);
180 return entriesModified ? newContent
: value
;
188 protected String
resolvePlaceholder(String placeholder
, Properties props
) {
189 if ((executionScope
!= null)
190 && (executionScope
.hasExecutionContext())) {
191 Object obj
= executionContext
.findVariable(placeholder
);
193 return obj
.toString();
196 if (instantiationManager
.isInFlowInitialization())
197 return instantiationManager
.getInitializingFlowParameter(
198 placeholder
).toString();
200 throw new SlcException("Could not resolve placeholder '"
201 + placeholder
+ "' in bean '" + beanName
+ "'");