import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
import java.util.Map;
import java.util.Properties;
+import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.beans.factory.config.TypedStringValue;
+import org.springframework.beans.factory.support.ManagedList;
import org.springframework.beans.factory.support.ManagedMap;
+import org.springframework.beans.factory.support.ManagedSet;
+import org.springframework.util.ObjectUtils;
public class ExecutionParameterPostProcessor extends
InstantiationAwareBeanPostProcessorAdapter {
else if (value instanceof String) {
return ppc.process(value.toString());
}
+ else if (value instanceof Map) {
+ Map mapVal = (Map) value;
+
+ Map newContent = new LinkedHashMap();
+ boolean entriesModified = false;
+ for (Iterator it = mapVal.entrySet().iterator(); it.hasNext();) {
+ Map.Entry entry = (Map.Entry) it.next();
+ Object key = entry.getKey();
+ int keyHash = (key != null ? key.hashCode() : 0);
+ Object newKey = resolveValue(key,ppc);
+ int newKeyHash = (newKey != null ? newKey.hashCode() : 0);
+ Object val = entry.getValue();
+ Object newVal = resolveValue(val,ppc);
+ newContent.put(newKey, newVal);
+ entriesModified = entriesModified || (newVal != val || newKey != key || newKeyHash != keyHash);
+ }
+ if (entriesModified) {
+ mapVal.clear();
+ mapVal.putAll(newContent);
+ }
+ return mapVal;
+ }
+ else if (value instanceof List) {
+ List listVal = (List) value;
+ for (int i = 0; i < listVal.size(); i++) {
+ Object elem = listVal.get(i);
+ Object newVal = resolveValue(elem,ppc);
+ if (!ObjectUtils.nullSafeEquals(newVal, elem)) {
+ listVal.set(i, newVal);
+ }
+ }
+ return value;
+ }
+ else if (value instanceof Set) {
+ Set setVal = (Set) value;
+ Set newContent = new LinkedHashSet();
+ boolean entriesModified = false;
+ for (Iterator it = setVal.iterator(); it.hasNext();) {
+ Object elem = it.next();
+ int elemHash = (elem != null ? elem.hashCode() : 0);
+ Object newVal = resolveValue(elem,ppc);
+ int newValHash = (newVal != null ? newVal.hashCode() : 0);
+ newContent.add(newVal);
+ entriesModified = entriesModified || (newVal != elem || newValHash != elemHash);
+ }
+ if (entriesModified) {
+ setVal.clear();
+ setVal.addAll(newContent);
+ }
+ return value;
+ }
else {
return value;
}
pv.setConvertedValue(convertedValue);
}
- else if (pv.getValue() instanceof ManagedMap) {
- //debug
- Object obj = pv.getValue();
- String name = pv.getName();
-
-// log.info("##" + name + ":" + obj.getClass());
- ManagedMap mapVal = (ManagedMap) pv.getValue();
-
- Map newContent = new LinkedHashMap();
- boolean entriesModified = false;
- for (Iterator it = mapVal.entrySet().iterator(); it.hasNext();) {
- Map.Entry entry = (Map.Entry) it.next();
- Object key = entry.getKey();
- int keyHash = (key != null ? key.hashCode() : 0);
- Object newKey = resolveValue(key,ppc);
- int newKeyHash = (newKey != null ? newKey.hashCode() : 0);
- Object val = entry.getValue();
- Object newVal = resolveValue(val,ppc);
- newContent.put(newKey, newVal);
- entriesModified = entriesModified || (newVal != val || newKey != key || newKeyHash != keyHash);
- }
- if (entriesModified) {
- mapVal.clear();
- mapVal.putAll(newContent);
- }
+ else if ((pv.getValue() instanceof ManagedMap)
+ ||(pv.getValue() instanceof ManagedList)
+ ||(pv.getValue() instanceof ManagedSet)){
+ resolveValue(pv.getValue(),ppc);
}
if (convertedValue != null && log.isTraceEnabled()) {
public class ExecutionFlowTest extends TestCase {\r
\r
protected final Log log = LogFactory.getLog(getClass());\r
- \r
-\r
- public void testRecursive() throws Exception {\r
- ConfigurableApplicationContext applicationContext = createApplicationContext("test.xml");\r
- ExecutionFlow executionFlow = (ExecutionFlow) applicationContext.getBean("second");\r
- executionFlow.execute(); \r
- \r
- BasicTestData res = (BasicTestData) applicationContext.getBean("basic.testData");\r
- \r
- log.info("res=" + res.getReached().toString());\r
\r
- applicationContext.close(); \r
- } \r
- \r
- \r
/**\r
* Test placeholder resolution in a context without scope execution or proxy\r
* and with cascading flows (the flow A contains the flow B)\r
applicationContext.close();\r
} \r
\r
- public void testSimpleExecution() throws Exception {\r
-// configureAndExecuteSlcFlow("applicationContext.xml", "main");\r
- }\r
- \r
public void testCanonicFlowParameters() throws Exception {\r
configureAndExecuteSlcFlow("canonic-001.xml", "canonic.001");\r
}\r
} \r
} \r
\r
- \r
+ public void testListSetMap() throws Exception {\r
+ ConfigurableApplicationContext applicationContext = createApplicationContext("listSetMap.xml");\r
+ ExecutionFlow executionFlow = (ExecutionFlow) applicationContext.getBean("myFlow");\r
+ executionFlow.execute(); \r
+ \r
+ validateTestResult((SimpleTestResult) applicationContext.getBean("myTestResult"));\r
+ \r
+ BasicTestData res = (BasicTestData) applicationContext.getBean("cascadingComplex.testData");\r
+ log.info("res=" + res.getReached().toString());\r
+ \r
+ applicationContext.close(); \r
+ } \r
\r
\r
protected void logException(Throwable ex) {\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<beans xmlns="http://www.springframework.org/schema/beans"\r
+ xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+ xmlns:aop="http://www.springframework.org/schema/aop"\r
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\r
+ http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">\r
+\r
+ <import resource="imports.xml" /> \r
+\r
+ <bean id="myTestRunTemplate" class="org.argeo.slc.core.test.SimpleTestRun" abstract="true">\r
+ <property name="testDefinition" ref="basic.testDef" />\r
+ <property name="testResult" ref="myTestResult"/>\r
+ </bean> \r
+\r
+ <bean id="myFlow" parent="slcTemplate.simpleFlow">\r
+ <constructor-arg>\r
+ <bean parent="slcTemplate.simpleSpec">\r
+ <property name="attributes">\r
+ <map>\r
+ <entry key="testKey">\r
+ <bean parent="specAttr.primitive" p:value="myValue" />\r
+ </entry>\r
+ </map>\r
+ </property>\r
+ </bean>\r
+ </constructor-arg>\r
+ <property name="executables">\r
+ <list>\r
+ <ref local="echo1" />\r
+ <bean parent="myTestRunTemplate">\r
+ <property name="testData" ref="simpleMap.testData" />\r
+ </bean> \r
+ <bean parent="myTestRunTemplate">\r
+ <property name="testData" ref="cascadingMap.testData" />\r
+ </bean> \r
+ \r
+ <bean parent="myTestRunTemplate">\r
+ <property name="testData" ref="simpleList.testData" />\r
+ </bean> \r
+ <bean parent="myTestRunTemplate">\r
+ <property name="testData" ref="cascadingList.testData" />\r
+ </bean> \r
+ \r
+ <bean parent="myTestRunTemplate">\r
+ <property name="testData" ref="simpleSet.testData" />\r
+ </bean> \r
+ <bean parent="myTestRunTemplate">\r
+ <property name="testData" ref="cascadingSet.testData" />\r
+ </bean> \r
+ \r
+ <bean parent="myTestRunTemplate">\r
+ <property name="testData" ref="cascadingListMap.testData" />\r
+ </bean> \r
+ <bean parent="myTestRunTemplate">\r
+ <property name="testData" ref="cascadingSetMap.testData" />\r
+ </bean> \r
+ <bean parent="myTestRunTemplate">\r
+ <property name="testData" ref="cascadingComplex.testData" />\r
+ </bean> \r
+ \r
+ </list>\r
+ </property>\r
+ </bean>\r
+\r
+\r
+ <bean id="simpleMap.testData" class="org.argeo.slc.core.test.BasicTestData" scope="prototype">\r
+ <property name="expected">\r
+ <map>\r
+ <entry key="key1" value="myValue_myValue" />\r
+ </map>\r
+ </property>\r
+ <property name="reached">\r
+ <map>\r
+ <entry key="key1" value="@{testKey}_@{testKey}" />\r
+ </map>\r
+ </property>\r
+ </bean>\r
+ \r
+ <bean id="cascadingMap.testData" class="org.argeo.slc.core.test.BasicTestData" scope="prototype">\r
+ <property name="expected">\r
+ <map>\r
+ <entry key="key3">\r
+ <map>\r
+ <entry key="key2">\r
+ <map>\r
+ <entry key="key1" value="myValue" />\r
+ </map>\r
+ </entry>\r
+ <entry key="key2bis" value="myValue" />\r
+ </map>\r
+ </entry>\r
+ </map>\r
+ </property>\r
+ <property name="reached">\r
+ <map>\r
+ <entry key="key3">\r
+ <map>\r
+ <entry key="key2">\r
+ <map>\r
+ <entry key="key1" value="@{testKey}" />\r
+ </map>\r
+ </entry>\r
+ <entry key="key2bis" value="@{testKey}" />\r
+ </map>\r
+ </entry>\r
+ </map>\r
+ </property>\r
+ </bean> \r
+ \r
+ <bean id="simpleList.testData" class="org.argeo.slc.core.test.BasicTestData" scope="prototype">\r
+ <property name="expected">\r
+ <list>\r
+ <value>myValue</value>\r
+ <value>_myValue_</value>\r
+ </list>\r
+ </property>\r
+ <property name="reached">\r
+ <list>\r
+ <value>@{testKey}</value>\r
+ <value>_@{testKey}_</value> \r
+ </list>\r
+ </property>\r
+ </bean> \r
+ \r
+ <bean id="cascadingList.testData" class="org.argeo.slc.core.test.BasicTestData" scope="prototype">\r
+ <property name="expected">\r
+ <list>\r
+ <list>\r
+ <value>myValue</value>\r
+ <value>_myValue_</value>\r
+ </list>\r
+ <value>myValue</value>\r
+ </list>\r
+ </property>\r
+ <property name="reached">\r
+ <list>\r
+ <list>\r
+ <value>@{testKey}</value>\r
+ <value>_@{testKey}_</value>\r
+ </list>\r
+ <value>@{testKey}</value>\r
+ </list>\r
+ </property>\r
+ </bean> \r
+ \r
+ <bean id="simpleSet.testData" class="org.argeo.slc.core.test.BasicTestData" scope="prototype">\r
+ <property name="expected">\r
+ <set>\r
+ <value>myValue</value>\r
+ <value>_myValue_</value>\r
+ </set>\r
+ </property>\r
+ <property name="reached">\r
+ <set>\r
+ <value>@{testKey}</value>\r
+ <value>_@{testKey}_</value> \r
+ </set>\r
+ </property>\r
+ </bean> \r
+ \r
+ <bean id="cascadingSet.testData" class="org.argeo.slc.core.test.BasicTestData" scope="prototype">\r
+ <property name="expected">\r
+ <set>\r
+ <set>\r
+ <value>myValue</value>\r
+ <value>_myValue_</value>\r
+ </set>\r
+ <value>myValue</value>\r
+ </set>\r
+ </property>\r
+ <property name="reached">\r
+ <set>\r
+ <set>\r
+ <value>@{testKey}</value>\r
+ <value>_@{testKey}_</value>\r
+ </set>\r
+ <value>@{testKey}</value>\r
+ </set>\r
+ </property>\r
+ </bean> \r
+ \r
+ <bean id="cascadingListMap.testData" class="org.argeo.slc.core.test.BasicTestData" scope="prototype">\r
+ <property name="expected">\r
+ <list>\r
+ <map>\r
+ <entry key="key1" value="myValue" />\r
+ </map> \r
+ </list>\r
+ </property>\r
+ <property name="reached">\r
+ <list>\r
+ <map>\r
+ <entry key="key1" value="@{testKey}" />\r
+ </map> \r
+ </list>\r
+ </property>\r
+ </bean> \r
+ \r
+ <bean id="cascadingSetMap.testData" class="org.argeo.slc.core.test.BasicTestData" scope="prototype">\r
+ <property name="expected">\r
+ <set>\r
+ <map>\r
+ <entry key="key1" value="myValue" />\r
+ </map> \r
+ </set>\r
+ </property>\r
+ <property name="reached">\r
+ <set>\r
+ <map>\r
+ <entry key="key1" value="@{testKey}" />\r
+ </map> \r
+ </set>\r
+ </property>\r
+ </bean> \r
+ \r
+ <bean id="cascadingComplex.testData" class="org.argeo.slc.core.test.BasicTestData" scope="prototype">\r
+ <property name="expected">\r
+ <set>\r
+ <map>\r
+ <entry key="key1" value="myValue" />\r
+ </map> \r
+ <list>\r
+ <map>\r
+ <entry key="key1" value="myValue" />\r
+ </map> \r
+ <set>\r
+ <set>\r
+ <value>myValue</value>\r
+ <value>_myValue_</value>\r
+ <list>\r
+ <list>\r
+ <value>myValue</value>\r
+ <value>_myValue_</value>\r
+ </list>\r
+ <value>myValue</value>\r
+ </list> \r
+ </set>\r
+ <value>myValue</value>\r
+ </set> \r
+ </list> \r
+ <set>\r
+ <map>\r
+ <entry key="key1" value="myValue" />\r
+ </map> \r
+ </set> \r
+ </set>\r
+ </property>\r
+ <property name="reached">\r
+ <set>\r
+ <map>\r
+ <entry key="key1" value="@{testKey}" />\r
+ </map> \r
+ <list>\r
+ <map>\r
+ <entry key="key1" value="@{testKey}" />\r
+ </map> \r
+ <set>\r
+ <set>\r
+ <value>@{testKey}</value>\r
+ <value>_@{testKey}_</value>\r
+ <list>\r
+ <list>\r
+ <value>@{testKey}</value>\r
+ <value>_@{testKey}_</value>\r
+ </list>\r
+ <value>@{testKey}</value>\r
+ </list> \r
+ </set>\r
+ <value>@{testKey}</value>\r
+ </set> \r
+ </list> \r
+ <set>\r
+ <map>\r
+ <entry key="key1" value="@{testKey}" />\r
+ </map> \r
+ </set> \r
+ </set>\r
+ </property>\r
+ </bean> \r
+ \r
+ <bean id="basic.testDef" class="org.argeo.slc.core.test.BasicTestDefinition">\r
+ </bean> \r
+\r
+\r
+ <bean id="echo1" parent="task.echo" scope="prototype">\r
+ <property name="message"\r
+ value="testKey=@{testKey}" />\r
+ </bean>\r
+ \r
+ <bean id="myTestResult" class="org.argeo.slc.core.test.SimpleTestResult" />\r
+\r
+</beans>
\ No newline at end of file