]> git.argeo.org Git - gpl/argeo-slc.git/blobdiff - org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/spring/SpringArg.java
Add merge feature to override
[gpl/argeo-slc.git] / org.argeo.slc.agent / src / main / java / org / argeo / slc / ant / spring / SpringArg.java
index d94384d5ca70410508e2f6ed9c3af889f306e55a..3f3bb3c1d126ebfb4d9878f665b97aed4ffef095 100644 (file)
@@ -3,10 +3,10 @@ package org.argeo.slc.ant.spring;
 import java.util.List;\r
 import java.util.Vector;\r
 \r
-import org.apache.tools.ant.BuildException;\r
+import org.apache.commons.logging.Log;\r
+import org.apache.commons.logging.LogFactory;\r
 import org.apache.tools.ant.types.DataType;\r
-import org.argeo.slc.ant.SlcAntConstants;\r
-import org.argeo.slc.ant.SlcAntException;\r
+import org.argeo.slc.ant.AntConstants;\r
 import org.argeo.slc.core.SlcException;\r
 import org.springframework.beans.BeanWrapper;\r
 import org.springframework.beans.BeanWrapperImpl;\r
@@ -15,13 +15,20 @@ import org.springframework.context.ApplicationContext;
 \r
 /** Abstract Ant type wrapping a Spring bean. */\r
 public class SpringArg<T> extends DataType {\r
+       private final static Log log = LogFactory.getLog(SpringArg.class);\r
+\r
        private List<OverrideArg> overrides = new Vector<OverrideArg>();\r
 \r
        private String bean;\r
        private String antref;\r
+       /**\r
+        * Reference to the original object, used to merge overrides. <b>this object\r
+        * will be modified</b>.\r
+        */\r
+       private T original;\r
 \r
        // cache bean instance to avoid reading it twice if it is a prototype\r
-       private T beanInstance = null;\r
+       private T instance = null;\r
 \r
        /** The <u>name</u> of the underlying bean, as set through the attribute. */\r
        public String getBean() {\r
@@ -48,47 +55,63 @@ public class SpringArg<T> extends DataType {
         * Retrieve the instance of the bean, and sets the overridden properties.\r
         * <b>The value is cached.</b>\r
         */\r
-       public T getBeanInstance() {\r
-               if (beanInstance == null) {\r
+       public T getInstance() {\r
+               if (instance == null) {\r
+                       if (log.isTraceEnabled())\r
+                               log.trace(this + "\t: Creates instance");\r
+\r
                        if (bean != null) {\r
-                               beanInstance = (T) getContext().getBean(bean);\r
-                               if (beanInstance == null)\r
-                                       throw new SlcAntException(\r
-                                                       "No object found for Spring bean " + bean);\r
+                               instance = (T) getContext().getBean(bean);\r
+                               if (instance == null)\r
+                                       throw new SlcException("No object found for Spring bean "\r
+                                                       + bean);\r
                        } else if (antref != null) {\r
-                               beanInstance = (T) getProject().getReference(antref);\r
-                               if (beanInstance == null)\r
-                                       throw new SlcAntException(\r
-                                                       "No object found for Ant reference " + antref);\r
+                               instance = (T) getProject().getReference(antref);\r
+                               if (instance == null)\r
+                                       throw new SlcException("No object found for Ant reference "\r
+                                                       + antref);\r
+                       } else if (original != null) {\r
+                               instance = original;\r
                        } else {\r
-                               throw new SlcAntException(\r
+                               throw new SlcException(\r
                                                "Don't know how to retrieve bean instance");\r
                        }\r
 \r
-                       setOverridenProperties(beanInstance);\r
+                       setOverridenProperties(instance);\r
 \r
                        // FIXME: why are we doing this? Could not find any object using it\r
-                       if (beanInstance instanceof InitializingBean) {\r
+                       if (instance instanceof InitializingBean) {\r
                                try {\r
-                                       ((InitializingBean) beanInstance).afterPropertiesSet();\r
+                                       ((InitializingBean) instance).afterPropertiesSet();\r
                                } catch (Exception e) {\r
                                        throw new SlcException("Could not initialize bean", e);\r
                                }\r
                        }\r
+               } else {\r
+                       if (log.isTraceEnabled())\r
+                               log.trace(this + "\t: Returns cached instance");\r
                }\r
-               return beanInstance;\r
+               return instance;\r
        }\r
 \r
        protected void setOverridenProperties(Object obj) {\r
                BeanWrapper wrapper = new BeanWrapperImpl(obj);\r
                for (OverrideArg override : overrides) {\r
                        if (override.getName() == null) {\r
-                               throw new SlcAntException(\r
+                               throw new SlcException(\r
                                                "The name of the property to override has to be set.");\r
                        }\r
 \r
-                       // LogFactory.getLog(getClass()).debug(\r
-                       // "Prop " + override.getName());\r
+                       if (log.isTraceEnabled())\r
+                               log.trace(this + "\t: Overrides property " + override.getName()\r
+                                               + " with " + override);\r
+\r
+                       if (override.getMerge() == true) {\r
+                               // if override is marked as merged retrieve the value and set is\r
+                               // as original\r
+                               override.setOriginal(wrapper.getPropertyValue(override\r
+                                               .getName()));\r
+                       }\r
                        wrapper.setPropertyValue(override.getName(), override.getObject());\r
                }\r
 \r
@@ -104,13 +127,37 @@ public class SpringArg<T> extends DataType {
        /** The related Spring application context. */\r
        protected ApplicationContext getContext() {\r
                return (ApplicationContext) getProject().getReference(\r
-                               SlcAntConstants.REF_ROOT_CONTEXT);\r
+                               AntConstants.REF_ROOT_CONTEXT);\r
        }\r
 \r
        protected void checkValueAlreadySet() {\r
-               if (antref != null || bean != null) {\r
-                       throw new BuildException("Value already set.");\r
+               if (antref != null || bean != null || original != null) {\r
+                       throw new SlcException("Instance value already defined.");\r
                }\r
        }\r
 \r
+       public void setOriginal(T original) {\r
+               checkValueAlreadySet();\r
+               this.original = original;\r
+       }\r
+\r
+       public T getOriginal() {\r
+               return original;\r
+       }\r
+\r
+       @Override\r
+       public String toString() {\r
+               StringBuffer buf = new StringBuffer(getClass().getSimpleName());\r
+               if (bean != null) {\r
+                       buf.append("#bean=").append(bean);\r
+               } else if (antref != null) {\r
+                       buf.append("#antref=").append(antref);\r
+               } else if (original != null) {\r
+                       buf.append("#orig=").append(original.hashCode());\r
+               } else {\r
+                       buf.append("#noid");\r
+               }\r
+               buf.append("#").append(hashCode());\r
+               return buf.toString();\r
+       }\r
 }\r