\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
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
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
// 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
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
}\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