]> git.argeo.org Git - gpl/argeo-slc.git/commitdiff
Placeholder resolution in Map, List and Set supported
authorOlivier Capillon <olivier.capillon@gmail.com>
Sat, 21 Mar 2009 19:55:09 +0000 (19:55 +0000)
committerOlivier Capillon <olivier.capillon@gmail.com>
Sat, 21 Mar 2009 19:55:09 +0000 (19:55 +0000)
git-svn-id: https://svn.argeo.org/slc/trunk@2296 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/ExecutionParameterPostProcessor.java
runtime/org.argeo.slc.support.simple/src/test/java/org/argeo/slc/core/execution/ExecutionFlowTest.java
runtime/org.argeo.slc.support.simple/src/test/resources/org/argeo/slc/core/execution/listSetMap.xml [new file with mode: 0644]

index 9cb6948297bcd64696bc61cd79c15f329486c08c..a76820465d452692bbe310010e5237b3d39445c2 100644 (file)
@@ -4,8 +4,11 @@ import java.beans.PropertyDescriptor;
 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;
@@ -18,7 +21,10 @@ import org.springframework.beans.PropertyValues;
 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 {
@@ -67,6 +73,57 @@ public class ExecutionParameterPostProcessor extends
                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;
                }
@@ -118,31 +175,10 @@ public class ExecutionParameterPostProcessor extends
                                        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()) {
index 2692ef99f54547db0ccccfbc4373a7d9ba7db78e..d3030e95fca3564d2dfc862a4f68a4addea89bcd 100644 (file)
@@ -21,21 +21,7 @@ import org.springframework.context.support.ClassPathXmlApplicationContext;
 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
@@ -92,10 +78,6 @@ public class ExecutionFlowTest extends TestCase {
                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
@@ -123,7 +105,18 @@ public class ExecutionFlowTest extends TestCase {
                }       \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
diff --git a/runtime/org.argeo.slc.support.simple/src/test/resources/org/argeo/slc/core/execution/listSetMap.xml b/runtime/org.argeo.slc.support.simple/src/test/resources/org/argeo/slc/core/execution/listSetMap.xml
new file mode 100644 (file)
index 0000000..4f22d27
--- /dev/null
@@ -0,0 +1,292 @@
+<?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