move to width first initialization in Advanced Init
authorAndreas Müller <a.mueller@bgbm.org>
Sun, 27 Oct 2013 03:19:02 +0000 (03:19 +0000)
committerAndreas Müller <a.mueller@bgbm.org>
Sun, 27 Oct 2013 03:19:02 +0000 (03:19 +0000)
cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/initializer/AbstractBeanInitializer.java
cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/initializer/AdvancedBeanInitializer.java
cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/initializer/BeanInitNode.java

index 6383efdfb0d8ec607cd17bcc8dd8b27fa6bf4368..bdfdbc7b935b2aeea9a3205d3564fe5907bfdea2 100644 (file)
@@ -274,7 +274,7 @@ public abstract class AbstractBeanInitializer implements IBeanInitializer{
         }\r
     }\r
 \r
-    private Object invokeInitialization(Object bean, PropertyDescriptor propertyDescriptor) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {\r
+    protected Object invokeInitialization(Object bean, PropertyDescriptor propertyDescriptor) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {\r
 \r
         if(propertyDescriptor == null || bean == null){\r
             return null;\r
@@ -369,7 +369,7 @@ public abstract class AbstractBeanInitializer implements IBeanInitializer{
      * @param cdmEntities initialize all *toOne relations to cdm entities\r
      * @param collections initialize all *toMany relations\r
      */\r
-    private void initializeAllEntries(Collection collection, boolean cdmEntities, boolean collections) {\r
+    protected void initializeAllEntries(Collection collection, boolean cdmEntities, boolean collections) {\r
         for(Object bean : collection){\r
             initializeBean(bean, cdmEntities, collections);\r
         }\r
index b05686d9ad0cb73f3c5b5bee3684d58756da9f06..801e6777f5c86dc5c73de4251aed05acc2872d56 100644 (file)
@@ -5,11 +5,8 @@ package eu.etaxonomy.cdm.persistence.dao.initializer;
 \r
 import java.beans.PropertyDescriptor;\r
 import java.lang.reflect.InvocationTargetException;\r
-import java.lang.reflect.Method;\r
-import java.lang.reflect.ParameterizedType;\r
-import java.lang.reflect.Type;\r
+import java.util.ArrayList;\r
 import java.util.Collection;\r
-import java.util.Collections;\r
 import java.util.List;\r
 import java.util.Map;\r
 \r
@@ -17,7 +14,6 @@ import org.apache.commons.beanutils.PropertyUtils;
 import org.apache.commons.lang.StringUtils;\r
 import org.apache.log4j.Logger;\r
 \r
-import eu.etaxonomy.cdm.model.common.CdmBase;\r
 import eu.etaxonomy.cdm.persistence.dao.hibernate.HibernateBeanInitializer;\r
 \r
 /**\r
@@ -31,34 +27,38 @@ public class AdvancedBeanInitializer extends HibernateBeanInitializer {
           public static final Logger logger = Logger.getLogger(AdvancedBeanInitializer.class);\r
 \r
            @Override\r
-           public void load(Object bean) {\r
-               initializeBean(bean, true, false);\r
-           }\r
-\r
-           @Override\r
-           public void loadFully(Object bean) {\r
-               initializeBean(bean, true, true);\r
+           public void initialize(Object bean, List<String> propertyPaths) {\r
+               List<Object> beanList = new ArrayList<Object>(1);\r
+               beanList.add(bean);\r
+               initializeAll(beanList, propertyPaths);\r
            }\r
-\r
-\r
+           \r
            //TODO optimize algorithm ..\r
            @Override\r
-           public void initialize(Object bean, List<String> propertyPaths) {\r
+           public <C extends Collection<?>> C initializeAll(C beanList,  List<String> propertyPaths) {\r
 \r
-               invokePropertyAutoInitializers(bean);\r
+               if (beanList == null || beanList.isEmpty()){\r
+                       return beanList;\r
+               }\r
+               \r
+               //TODO new required?\r
+//             invokePropertyAutoInitializers(bean);\r
 \r
-               if(propertyPaths == null){\r
-                   return;\r
+               if(propertyPaths == null){  //TODO if AutoInitializer is not requiredfor top level bean, this can be merged with previous "if"\r
+                   return beanList;\r
                }\r
 \r
-               if(logger.isDebugEnabled()){\r
-                   logger.debug(">> starting to initialize " + bean + " ;class:" + bean.getClass().getSimpleName());\r
-               }\r
                \r
                //new\r
-               BeanInitNode rootInitializer = BeanInitNode.createInitTree(propertyPaths);\r
-               System.out.println(rootInitializer.toStringTree());\r
-               initializeBean(bean, rootInitializer);\r
+               BeanInitNode rootPath = BeanInitNode.createInitTree(propertyPaths);\r
+               System.out.println(rootPath.toStringTree());\r
+               \r
+\r
+               if(logger.isDebugEnabled()){\r
+                   logger.debug(">> starting to initialize beanlist ; class(e.g.):" + beanList.iterator().next().getClass().getSimpleName());\r
+               }\r
+               rootPath.addBeans(beanList);\r
+               initializeBean(rootPath);\r
                \r
                \r
 //             //old\r
@@ -68,67 +68,62 @@ public class AdvancedBeanInitializer extends HibernateBeanInitializer {
 //                 initializePropertyPath(bean, propPath);\r
 //             }\r
                if(logger.isDebugEnabled()){\r
-                   logger.debug("   Completed initialization of " + bean);\r
+                   logger.debug("   Completed initialization of beanlist ");\r
                }\r
+               return beanList;\r
 \r
            }\r
            \r
 \r
                //new\r
-           \r
-           public void initializeBean(Object bean, BeanInitNode rootInitializer) {\r
-                       initializePropertyPath(bean, rootInitializer);\r
-                       for (BeanInitNode child : rootInitializer.getChildrenList()){\r
-                               initializeBean(bean, child);\r
+           private void initializeBean(BeanInitNode rootPath) {\r
+                       initializePropertyPath(rootPath);\r
+                       for (BeanInitNode childPath : rootPath.getChildrenList()){\r
+                               initializeBean(childPath);\r
                        }\r
+                       rootPath.resetBeans();\r
                }\r
            \r
-\r
-           @Override\r
-           public <C extends Collection<?>> C initializeAll(C beanList,  List<String> propertyPaths) {\r
-               if(propertyPaths != null){\r
-                   for(Object bean : beanList){\r
-                       initialize(bean, propertyPaths);\r
-                   }\r
-               }\r
-               return beanList;\r
-           }\r
-\r
            /**\r
             * Initializes the given single <code>propPath</code> String.\r
             *\r
             * @param bean\r
             * @param propPath\r
             */\r
-           void initializePropertyPath(Object bean, BeanInitNode node) {\r
+           private void initializePropertyPath(BeanInitNode node) {\r
                if(logger.isDebugEnabled()){logger.debug("processing " + node.toString());}\r
                if (StringUtils.isBlank(node.getPath())){\r
                        return;\r
                }\r
 \r
                if (node.isWildcard()){\r
-                       initializeWildcardPropertyPath(bean, node);\r
+                       initializeWildcardPropertyPath(node);\r
                } else {\r
-                   initializeNoWildcardPropertyPath(bean, node);\r
+                   initializeNoWildcardPropertyPath(node);\r
                }\r
            }\r
 \r
                // if propPath only contains a wildcard (* or $)\r
         // => do a batch initialization of *toOne or *toMany relations\r
-        private void initializeWildcardPropertyPath(Object bean, BeanInitNode node) {\r
+        private void initializeWildcardPropertyPath(BeanInitNode node) {\r
                        boolean initToMany = node.getPath().equals(LOAD_2ONE_2MANY_WILDCARD);\r
-                   if(Collection.class.isAssignableFrom(bean.getClass())){\r
-                       initializeAllEntries((Collection)bean, true, initToMany);\r
-                   } else if(Map.class.isAssignableFrom(bean.getClass())) {\r
-                       initializeAllEntries(((Map)bean).values(), true, initToMany);\r
-                   } else{\r
-                       initializeBean(bean, true, initToMany);\r
+                   for (Class<?> clazz : node.getParentBeans().keySet()){\r
+                               for (Object bean : node.getParentBeans().get(clazz)){\r
+                               \r
+                                       if(Collection.class.isAssignableFrom(bean.getClass())){\r
+                                       initializeAllEntries((Collection<?>)bean, true, initToMany);\r
+                                   } else if(Map.class.isAssignableFrom(bean.getClass())) {\r
+                                       initializeAllEntries(((Map<?,?>)bean).values(), true, initToMany);\r
+                                   } else{\r
+                                       initializeBean(bean, true, initToMany);\r
+                                   }\r
+                           }\r
                    }\r
                }\r
 \r
        // propPath contains either a single field or a nested path\r
                // split next path token off and keep the remaining as nestedPath\r
-        private void initializeNoWildcardPropertyPath(Object bean, BeanInitNode node) {\r
+        private void initializeNoWildcardPropertyPath(BeanInitNode node) {\r
                        \r
                String property = node.getPath();\r
                        int pos;\r
@@ -144,47 +139,53 @@ public class AdvancedBeanInitializer extends HibernateBeanInitializer {
                        try {\r
                            //Class targetClass = HibernateProxyHelper.getClassWithoutInitializingProxy(bean); // used for debugging\r
 \r
-                           // [2.a] initialize the bean named by property\r
-\r
-                           PropertyDescriptor propertyDescriptor = PropertyUtils.getPropertyDescriptor(bean, property);\r
-                           if (logger.isDebugEnabled()){logger.debug("invokeInitialization "+node+" ... ");}\r
-                           Object unwrappedPropertyBean = invokeInitialization(bean, propertyDescriptor);\r
-                           if (logger.isDebugEnabled()){logger.debug("invokeInitialization "+node+" - DONE ");}\r
-                               //TODO continue\r
-//                         node.addBean(unwrappedPropertyBean);\r
-                           \r
-                           // [2.b]\r
-                           // recurse into nested properties\r
-                           if(unwrappedPropertyBean != null ){\r
-                               for (BeanInitNode childNode : node.getChildrenList()){\r
-                                       Collection<?> collection = null;\r
-                                       if(Map.class.isAssignableFrom(unwrappedPropertyBean.getClass())) {\r
-                                               collection = ((Map<?,?>)unwrappedPropertyBean).values();\r
-                                       }else if (Collection.class.isAssignableFrom(unwrappedPropertyBean.getClass())) {\r
-                                       collection =  (Collection<?>) unwrappedPropertyBean;    \r
-                                       }\r
-                                       if (collection != null){\r
-                                       //collection or map\r
-                                               if (logger.isDebugEnabled()){logger.debug(" initialize collection for " + childNode.toString() + " ... ");}\r
-                                           int i = 0;\r
-                                               for (Object entrybean : collection) {\r
-                                           if(index == null){\r
-                                               initializePropertyPath(entrybean, childNode);\r
-                                           } else if(index.equals(i)){\r
-                                               initializePropertyPath(entrybean, childNode);\r
-                                               break;\r
-                                           }\r
-                                           i++;\r
-                                       }\r
-                                               if (logger.isDebugEnabled()){logger.debug(" initialize collection for " + childNode.toString() + " - DONE ");}\r
-                                           \r
-                                   }else {\r
-                                       // nested bean\r
-                                       initializePropertyPath(unwrappedPropertyBean, childNode);\r
-                                       setProperty(bean, property, unwrappedPropertyBean);\r
-                                   }\r
-                               }\r
-                           }\r
+                           // [1] initialize the bean named by property\r
+                           for (Class<?> clazz : node.getParentBeans().keySet()){\r
+                                       for (Object bean : node.getParentBeans().get(clazz)){\r
+               \r
+                                           PropertyDescriptor propertyDescriptor = PropertyUtils.getPropertyDescriptor(bean, property);\r
+                                           if (logger.isDebugEnabled()){logger.debug("invokeInitialization "+node+" ... ");}\r
+                                           Object unwrappedPropertyBean = invokeInitialization(bean, propertyDescriptor);\r
+                                           if (logger.isDebugEnabled()){logger.debug("invokeInitialization "+node+" - DONE ");}\r
+               \r
+       \r
+                                           // [2]\r
+                                           // recurse into nested properties\r
+                                           if(unwrappedPropertyBean != null ){\r
+       //                                      for (BeanInitNode childNode : node.getChildrenList()){\r
+                                                       Collection<?> collection = null;\r
+                                                       if(Map.class.isAssignableFrom(unwrappedPropertyBean.getClass())) {\r
+                                                               collection = ((Map<?,?>)unwrappedPropertyBean).values();\r
+                                                       }else if (Collection.class.isAssignableFrom(unwrappedPropertyBean.getClass())) {\r
+                                                       collection =  (Collection<?>) unwrappedPropertyBean;    \r
+                                                       }\r
+                                                       if (collection != null){\r
+                                                       //collection or map\r
+                                                               if (logger.isDebugEnabled()){logger.debug(" initialize collection for " + node.toString() + " ... ");}\r
+                                                           int i = 0;\r
+                                                               for (Object entrybean : collection) {\r
+                                                           if(index == null){\r
+                                                                           node.addBean(entrybean);\r
+       //                                                      initializePropertyPath(entrybean, childNode);\r
+                                                           } else if(index.equals(i)){\r
+                                                               node.addBean(entrybean);\r
+       //                                                      initializePropertyPath(entrybean, childNode);\r
+                                                               break;\r
+                                                           }\r
+                                                           i++;\r
+                                                       }\r
+                                                               if (logger.isDebugEnabled()){logger.debug(" initialize collection for " + node.toString() + " - DONE ");}\r
+                                                           \r
+                                                   }else {\r
+                                                       // nested bean\r
+                                                       node.addBean(unwrappedPropertyBean);\r
+       //                                              initializePropertyPath(unwrappedPropertyBean, childNode);\r
+                                                       setProperty(bean, property, unwrappedPropertyBean);\r
+                                                   }\r
+                                               }\r
+                                               }\r
+//                                 }\r
+                               }                               \r
 \r
                        } catch (IllegalAccessException e) {\r
                            logger.error("Illegal access on property " + property);\r
@@ -195,67 +196,4 @@ public class AdvancedBeanInitializer extends HibernateBeanInitializer {
                        }\r
                }\r
 \r
-           //TODO check if needed in advanced\r
-           private Object invokeInitialization(Object bean, PropertyDescriptor propertyDescriptor) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {\r
-\r
-               if(propertyDescriptor == null || bean == null){\r
-                   return null;\r
-               }\r
-\r
-               // (1)\r
-               // initialialization of the bean\r
-               //\r
-               Object propertyProxy = PropertyUtils.getProperty( bean, propertyDescriptor.getName());\r
-               Object propertyBean = initializeInstance(propertyProxy);\r
-\r
-               if(propertyBean != null){\r
-                   // (2)\r
-                   // auto initialialization of sub properties\r
-                   //\r
-                   if(CdmBase.class.isAssignableFrom(propertyBean.getClass())){\r
-\r
-                       // initialization of a single bean\r
-                       CdmBase cdmBaseBean = (CdmBase)propertyBean;\r
-                       invokePropertyAutoInitializers(cdmBaseBean);\r
-\r
-                   } else if(Collection.class.isAssignableFrom(propertyBean.getClass()) ||\r
-                           Map.class.isAssignableFrom(propertyBean.getClass()) ) {\r
-\r
-                       // it is a collection or map\r
-                       Method readMethod = propertyDescriptor.getReadMethod();\r
-                       Type genericReturnType = readMethod.getGenericReturnType();\r
-\r
-                       if(genericReturnType instanceof ParameterizedType){\r
-                           ParameterizedType type = (ParameterizedType) genericReturnType;\r
-                           Type[] typeArguments = type.getActualTypeArguments();\r
-\r
-                           if(typeArguments.length > 0\r
-                                   && typeArguments[0] instanceof Class<?>\r
-                                   && CdmBase.class.isAssignableFrom((Class<?>) typeArguments[0])){\r
-\r
-                               if(Collection.class.isAssignableFrom((Class<?>) type.getRawType())){\r
-                                   for(CdmBase entry : ((Collection<CdmBase>)propertyBean)){\r
-                                       invokePropertyAutoInitializers(entry);\r
-                                   }\r
-                               }\r
-                           }\r
-\r
-                       }\r
-                   }\r
-               }\r
-\r
-               return propertyBean;\r
-           }\r
-\r
-           /**\r
-            * @param collection of which all entities are to be initialized\r
-            * @param cdmEntities initialize all *toOne relations to cdm entities\r
-            * @param collections initialize all *toMany relations\r
-            */\r
-           private void initializeAllEntries(Collection collection, boolean cdmEntities, boolean collections) {\r
-               for(Object bean : collection){\r
-                   initializeBean(bean, cdmEntities, collections);\r
-               }\r
-           }\r
-\r
 }\r
index 03f106cb4b53dd78e5f5f95d0be7973712e7e671..0f8d438af273edca02d58e0d438efd1a2e2cd43a 100644 (file)
@@ -4,10 +4,13 @@
 package eu.etaxonomy.cdm.persistence.dao.initializer;\r
 \r
 import java.util.ArrayList;\r
+import java.util.Collection;\r
 import java.util.Collections;\r
 import java.util.HashMap;\r
+import java.util.HashSet;\r
 import java.util.List;\r
 import java.util.Map;\r
+import java.util.Set;\r
 \r
 import eu.etaxonomy.cdm.common.CdmUtils;\r
 \r
@@ -27,6 +30,9 @@ public class BeanInitNode implements Comparable<BeanInitNode>{
        \r
        private boolean isToOneInitialized = false;\r
        \r
+       private  Map<Class<?>, Set<Object>> beans = new HashMap<Class<?>, Set<Object>>();\r
+\r
+       \r
        \r
        public BeanInitNode(BeanInitNode parent, String part) {\r
                this.path = CdmUtils.Nz(part);\r
@@ -46,6 +52,7 @@ public class BeanInitNode implements Comparable<BeanInitNode>{
                }\r
        }\r
 \r
+\r
        public static BeanInitNode createInitTree(List<String> propertyPaths) {\r
                \r
                //sort paths  //TODO needed?\r
@@ -76,6 +83,31 @@ public class BeanInitNode implements Comparable<BeanInitNode>{
        }\r
 \r
 \r
+       public void addBean(Object bean) {\r
+               if (bean != null){\r
+                       Class<?> key = bean.getClass();\r
+                       Set<Object> classedBeans = beans.get(key);\r
+                       if (classedBeans == null){\r
+                               classedBeans = new HashSet<Object>();\r
+                               beans.put(key, classedBeans);\r
+                       }\r
+                       classedBeans.add(bean);\r
+               }\r
+       }\r
+       public void addBeans(Collection<?> beans) {\r
+               for (Object bean : beans){\r
+                       addBean(bean);\r
+               }\r
+       }\r
+       \r
+       private Map<Class<?>, Set<Object>> getClassedBeans(){\r
+               return this.beans;\r
+       }\r
+       \r
+       public void resetBeans(){\r
+               beans.clear();\r
+       }\r
+\r
        public String getPath() {\r
                return path;\r
        }\r
@@ -94,6 +126,15 @@ public class BeanInitNode implements Comparable<BeanInitNode>{
                return path.equals(AbstractBeanInitializer.LOAD_2ONE_2MANY_WILDCARD);\r
        }\r
 \r
+\r
+       public boolean isInitializedIfSingle(){\r
+               return parent.isToOneInitialized;\r
+       }\r
+       \r
+       public boolean isInitializedAny(){\r
+               return parent.isToManyInitialized;\r
+       }\r
+       \r
        @Override\r
        public int compareTo(BeanInitNode o) {\r
                String toMany = AbstractBeanInitializer.LOAD_2ONE_2MANY_WILDCARD;\r
@@ -131,13 +172,14 @@ public class BeanInitNode implements Comparable<BeanInitNode>{
                \r
                return result;\r
        }\r
-       \r
-       public boolean isInitializedIfSingle(){\r
-               return parent.isToOneInitialized;\r
-       }\r
-       \r
-       public boolean isInitializedAny(){\r
-               return parent.isToManyInitialized;\r
+\r
+       public Map<Class<?>, Set<Object>> getParentBeans() {\r
+               if (parent == null){\r
+                       return new HashMap<Class<?>, Set<Object>>();\r
+               }else{\r
+                       return parent.getClassedBeans();\r
+               }\r
        }\r
 \r
+\r
 }\r