Project

General

Profile

Download (27.4 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
 *
3
 */
4
package eu.etaxonomy.cdm.persistence.dao.initializer;
5

    
6
import java.beans.PropertyDescriptor;
7
import java.io.Serializable;
8
import java.lang.reflect.InvocationTargetException;
9
import java.lang.reflect.Method;
10
import java.lang.reflect.ParameterizedType;
11
import java.lang.reflect.Type;
12
import java.lang.reflect.TypeVariable;
13
import java.util.ArrayList;
14
import java.util.Collection;
15
import java.util.Collections;
16
import java.util.HashSet;
17
import java.util.List;
18
import java.util.Map;
19
import java.util.Set;
20

    
21
import org.apache.commons.beanutils.PropertyUtils;
22
import org.apache.log4j.Logger;
23
import org.hibernate.Hibernate;
24
import org.hibernate.HibernateException;
25
import org.hibernate.Query;
26
import org.hibernate.collection.internal.AbstractPersistentCollection;
27
import org.hibernate.collection.internal.PersistentMap;
28
import org.hibernate.envers.internal.entities.mapper.relation.lazy.proxy.CollectionProxy;
29
import org.hibernate.envers.internal.entities.mapper.relation.lazy.proxy.MapProxy;
30
import org.hibernate.envers.internal.entities.mapper.relation.lazy.proxy.SortedMapProxy;
31
import org.hibernate.proxy.HibernateProxy;
32
import org.springframework.beans.factory.annotation.Autowired;
33

    
34
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
35
import eu.etaxonomy.cdm.model.common.CdmBase;
36
import eu.etaxonomy.cdm.persistence.dao.common.ICdmGenericDao;
37
import eu.etaxonomy.cdm.persistence.dao.hibernate.HibernateBeanInitializer;
38

    
39
/**
40
 * For now this is a test if we can improve performance for bean initializing
41
 * @author a.mueller
42
 * @date 2013-10-25
43
 *
44
 */
45
public class AdvancedBeanInitializer extends HibernateBeanInitializer {
46

    
47
    public static final Logger logger = Logger.getLogger(AdvancedBeanInitializer.class);
48

    
49
    @Autowired
50
    ICdmGenericDao genericDao;
51

    
52
    @Override
53
    public void initialize(Object bean, List<String> propertyPaths) {
54
        List<Object> beanList = new ArrayList<Object>(1);
55
        beanList.add(bean);
56
        initializeAll(beanList, propertyPaths);
57
    }
58

    
59
    //TODO optimize algorithm ..
60
    @Override
61
    public <C extends Collection<?>> C initializeAll(C beanList,  List<String> propertyPaths) {
62

    
63
        if (beanList == null || beanList.isEmpty()){
64
            return beanList;
65
        }
66

    
67
        //autoinitialize
68
        for (Object bean : beanList){
69
            autoinitializeBean(bean);
70
        }
71

    
72
        if(propertyPaths == null){
73
            return beanList;
74
        }
75

    
76

    
77
        //new
78
         BeanInitNode rootPath = BeanInitNode.createInitTree(propertyPaths);
79
        if (logger.isTraceEnabled()){logger.trace(rootPath.toStringTree());}
80

    
81

    
82
        if(logger.isDebugEnabled()){ logger.debug(">> starting to initialize beanlist ; class(e.g.):" + beanList.iterator().next().getClass().getSimpleName());}
83
        rootPath.addBeans(beanList);
84
        initializeNodeRecursive(rootPath);
85

    
86

    
87
        //old - keep for safety (this may help to initialize those beans that are not yet correctly initialized by the AdvancedBeanInitializer
88
        if(logger.isTraceEnabled()){logger.trace("Start old initalizer ... ");};
89
        for (Object bean :beanList){
90
            Collections.sort(propertyPaths);
91
            for(String propPath : propertyPaths){
92
//		            initializePropertyPath(bean, propPath);
93
            }
94
        }
95

    
96
        if(logger.isDebugEnabled()){ logger.debug("   Completed initialization of beanlist "); }
97
        return beanList;
98

    
99
    }
100

    
101

    
102
    //new
103
    private void initializeNodeRecursive(BeanInitNode rootPath) {
104
        initializeNode(rootPath);
105
        for (BeanInitNode childPath : rootPath.getChildrenList()){
106
            initializeNodeRecursive(childPath);
107
        }
108
        rootPath.resetBeans();
109
    }
110

    
111
    /**
112
     * Initializes the given single <code>propPath</code> String.
113
     *
114
     * @param bean
115
     * @param propPath
116
     */
117
    private void initializeNode(BeanInitNode node) {
118
        if(logger.isDebugEnabled()){logger.debug(" processing " + node.toString());}
119
        if (node.isRoot()){
120
            return;
121
        }else if (node.isWildcard()){
122
            initializeNodeWildcard(node);
123
        } else {
124
            initializeNodeNoWildcard(node);
125
        }
126
    }
127

    
128
    // if propPath only contains a wildcard (* or $)
129
    // => do a batch initialization of *toOne or *toMany relations
130
    private void initializeNodeWildcard(BeanInitNode node) {
131
//			boolean initToMany = node.isToManyWildcard();
132
        Map<Class<?>, Set<Object>> parentBeans = node.getParentBeans();
133
        for (Class<?> clazz : parentBeans.keySet()){
134
            //new
135
            for (Object bean : parentBeans.get(clazz)){
136

    
137
                if(Collection.class.isAssignableFrom(bean.getClass())){
138
//				        old: initializeAllEntries((Collection<?>)bean, true, initToMany);  //TODO is this a possible case at all??
139
                    throw new RuntimeException("Collection no longer expected in 'initializeNodeWildcard()'. Therefore an exception is thrown.");
140
                } else if(Map.class.isAssignableFrom(bean.getClass())) {
141
//				        old: initializeAllEntries(((Map<?,?>)bean).values(), true, initToMany);  ////TODO is this a possible case at all??
142
                    throw new RuntimeException("Map no longer expected in 'initializeNodeWildcard()'. Therefore an exception is thrown.");
143
                } else{
144
                    prepareBeanWildcardForBulkLoad(node, bean);
145
                }
146
            }
147
            //end new
148

    
149
//		    	initializeNodeWildcardOld(initToMany, beans, clazz);  //if switched on move bulkLoadLazies up
150
        }
151

    
152
        //
153
        bulkLoadLazies(node);
154
    }
155

    
156
    /**
157
     * @param initToMany
158
     * @param beans
159
     * @param clazz
160
     */
161
    private void initializeNodeWildcardOld(boolean initToMany,
162
            Map<Class<?>, Set<Object>> beans, Class<?> clazz) {
163
        for (Object bean : beans.get(clazz)){
164

    
165
            if(Collection.class.isAssignableFrom(bean.getClass())){
166
                initializeAllEntries((Collection<?>)bean, true, initToMany);
167
            } else if(Map.class.isAssignableFrom(bean.getClass())) {
168
                initializeAllEntries(((Map<?,?>)bean).values(), true, initToMany);
169
            } else{
170
                initializeBean(bean, true, initToMany);
171
            }
172
        }
173
    }
174

    
175
    private void prepareBeanWildcardForBulkLoad(BeanInitNode node, Object bean){
176

    
177
        if(logger.isTraceEnabled()){logger.trace(">> prepare bulk wildcard initialization of a bean of type " + bean.getClass().getSimpleName()); }
178
        Set<Class<?>> restrictions = new HashSet<Class<?>>();
179
        restrictions.add(CdmBase.class);
180
        if(node.isToManyWildcard()){
181
            restrictions.add(Collection.class);
182
        }
183
        Set<PropertyDescriptor> props = getProperties(bean, restrictions);
184
        for(PropertyDescriptor propertyDescriptor : props){
185
            try {
186
                String property = propertyDescriptor.getName();
187

    
188
//                  invokeInitialization(bean, propertyDescriptor);
189
                Object propertyValue = PropertyUtils.getProperty( bean, property);
190

    
191
                preparePropertyValueForBulkLoadOrStore(node, bean, property,  propertyValue );
192

    
193
            } catch (IllegalAccessException e) {
194
                logger.error("Illegal access on property " + propertyDescriptor.getName());
195
            } catch (InvocationTargetException e) {
196
                logger.info("Cannot invoke property " + propertyDescriptor.getName() + " not found");
197
            } catch (NoSuchMethodException e) {
198
                logger.info("Property " + propertyDescriptor.getName() + " not found");
199
            }
200
        }
201
        if(logger.isTraceEnabled()){logger.trace(" completed bulk wildcard initialization of a bean");}
202
    }
203

    
204

    
205
    /**
206
     * Initializes all objects matching the given node, where the
207
     * node does not represent a wildcard but a single field or
208
     * a nested path. Splits the next path token off and keeps
209
     * the remaining as nestedPath
210
     *
211
     * @param node
212
     */
213
    private void initializeNodeNoWildcard(BeanInitNode node) {
214

    
215
        String property = node.getPath();
216
        int pos;
217

    
218
        // is the property indexed?
219
        Integer index = null;
220
        if((pos = property.indexOf('[')) > 0){
221
            String indexString = property.substring(pos + 1, property.indexOf(']'));
222
            index = Integer.valueOf(indexString);
223
            property = property.substring(0, pos);
224
        }
225

    
226
        //Class targetClass = HibernateProxyHelper.getClassWithoutInitializingProxy(bean); // used for debugging
227

    
228
        for (Class<?> parentClazz : node.getParentBeans().keySet()){
229
            if (logger.isTraceEnabled()){logger.trace(" invoke initialization on "+ node.toString()+ " beans of class " + parentClazz.getSimpleName() + " ... ");}
230

    
231
            Set<Object> parentBeans = node.getParentBeans().get(parentClazz);
232

    
233
            if (index != null){
234
                logger.warn("Property path index not yet implemented for 'new'");
235
            }
236
            //new
237
            for (Object parentBean : parentBeans){
238
                preparePropertyForSingleBean(node, property, parentClazz, parentBean);
239
            }//end for
240
            //end new
241
//			 initializeNodeNoWildcardOld(node, property, index, parentBeans);  //move bulkLoadLazies up again, if uncomment this line
242
        } //end for
243
        bulkLoadLazies(node);
244
    }
245

    
246
    /**
247
     * Prepare a single property of a non-collection bean. Collections are handled elsewhere.
248
     */
249
    private void preparePropertyForSingleBean(BeanInitNode node, String property, Class<?> parentClazz, Object bean) {
250
        String propertyName = mapFieldToPropertyName(property, bean.getClass().getSimpleName());
251
        try{
252
            Object propertyValue = PropertyUtils.getProperty(bean, propertyName);
253
            preparePropertyValueForBulkLoadOrStore(node, bean, property, propertyValue);
254
        } catch (IllegalAccessException e) {
255
            String message = "Illegal access on property " + property;
256
            logger.error(message);
257
            throw new RuntimeException(message, e);
258
        } catch (InvocationTargetException e) {
259
            String message = "Cannot invoke property " + property + " not found";
260
            logger.error(message);
261
            throw new RuntimeException(message, e);
262
        } catch (NoSuchMethodException e) {
263
            String message = "Property " + propertyName + " not found for class " + parentClazz;
264
            logger.info(message);
265
            //don't throw exception as sometimes property paths will include non matching property names due to subclassing
266
            //#5077  comment 12
267
        }
268
    }
269

    
270
//    /**
271
//     * @param node
272
//     * @param property
273
//     * @param index
274
//     * @param parentBeans
275
//     * @throws IllegalAccessException
276
//     * @throws InvocationTargetException
277
//     * @throws NoSuchMethodException
278
//     */
279
//    private void initializeNodeNoWildcardOld(BeanInitNode node,
280
//                String property,
281
//                Integer index,
282
//                Set<Object> parentBeans)
283
//            throws IllegalAccessException, InvocationTargetException, NoSuchMethodException
284
//    {
285
//        for (Object bean : parentBeans){
286
//
287
//            PropertyDescriptor propertyDescriptor = PropertyUtils.getPropertyDescriptor(bean, property);
288
//            if (logger.isTraceEnabled()){logger.trace("   unwrap " + node.toStringNoWildcard() + " ... ");}
289
//            // [1] initialize the bean named by property
290
//            Object unwrappedPropertyBean = invokeInitialization(bean, propertyDescriptor);
291
//            if (logger.isTraceEnabled()){logger.trace("   unwrap " + node.toStringNoWildcard() + " - DONE ");}
292
//
293
//
294
//            // [2]
295
//            // handle property
296
//            if(unwrappedPropertyBean != null ){
297
//                initializeNodeSinglePropertyOld(node, property, index, bean, unwrappedPropertyBean);
298
//            }
299
//        }
300
//    }
301

    
302
    /**
303
     * @param node
304
     * @param propertyValue
305
     * @param parentBean
306
     * @param param
307
     */
308
    private void preparePropertyValueForBulkLoadOrStore(BeanInitNode node,
309
            Object parentBean,
310
            String param,
311
            Object propertyValue)
312
    {
313
        BeanInitNode sibling = node.getSibling(param);
314

    
315
        if (propertyValue instanceof AbstractPersistentCollection ){
316
            //collections
317
            if (!node.hasWildcardToManySibling()){  //if wildcard sibling exists the lazies are already prepared there
318
                AbstractPersistentCollection collection = (AbstractPersistentCollection)propertyValue;
319
                if (collection.wasInitialized()){
320
                    storeInitializedCollection(collection, node, param);
321
                }else{
322
//						Class<?> parentClass = parentBean.getClass();
323
//						int parentId = ((CdmBase)parentBean).getId();
324
                    if (sibling != null){
325
                        sibling.putLazyCollection(collection);
326
                    }else{
327
                        node.putLazyCollection(collection);
328
                    }
329
                }
330
            }
331
        } else if (propertyValue instanceof CollectionProxy
332
                || propertyValue instanceof MapProxy<?, ?>
333
                || propertyValue instanceof SortedMapProxy<?, ?>){
334
            //hibernate envers collections
335
            //TODO check if other code works with audited data at all as we use HQL queries
336
            if (!node.hasWildcardToManySibling()){  //if wildcard sibling exists the lazies are already prepared there
337
                Collection<?> collection = (Collection<?>)propertyValue;
338
                //TODO it is difficult to find out if an envers collection is initiallized
339
                //but possiblie via reflection. If the "delegate" parameter is null it is not yet initialized.
340
                //However, as we do not know if envers initialization works at all together with the AdvancedBeanInitializer
341
                //we initialize each collection immediately here by calling size()
342
                collection.size();  //initialize
343
                storeInitializedEnversCollection(collection, node, param);
344
            }
345
        }else{
346
            //singles
347
            if (!node.hasWildcardToOneSibling()){  //if wildcard exists the lazies are already prepared there
348
                if (! Hibernate.isInitialized(propertyValue)){
349
                    if (propertyValue instanceof HibernateProxy){
350
                        Serializable id = ((HibernateProxy)propertyValue).getHibernateLazyInitializer().getIdentifier();
351
                        Class<?> persistedClass = ((HibernateProxy)propertyValue).getHibernateLazyInitializer().getPersistentClass();
352
                        if (sibling != null){
353
                            sibling.putLazyBean(persistedClass, id);
354
                        }else{
355
                            node.putLazyBean(persistedClass, id);
356
                        }
357

    
358
                    }else{
359
                        logger.warn("Lazy value is not of type HibernateProxy. This is not yet handled.");
360
                    }
361
                }else if (propertyValue == null){
362
                    // do nothing
363
                }else{
364
                    if (propertyValue instanceof HibernateProxy){  //TODO remove hibernate dependency
365
                        propertyValue = initializeInstance(propertyValue);
366
                    }
367
                    autoinitializeBean(propertyValue);
368
                    node.addBean(propertyValue);
369
                }
370
            }
371
        }
372
    }
373

    
374
    private void autoinitializeBean(Object bean) {
375
        invokePropertyAutoInitializers(bean);
376
    }
377

    
378
    private void autoinitializeBean(CdmBase bean, AutoInit autoInit) {
379
        for(AutoPropertyInitializer<CdmBase> init : autoInit.initlializers) {
380
            init.initialize(bean);
381
        }
382
    }
383

    
384
	private void storeInitializedCollection(AbstractPersistentCollection persistedCollection,
385
			BeanInitNode node, String param) {
386

    
387
	    Collection<?> collection;
388
		if (persistedCollection  instanceof Collection) {
389
			collection = (Collection<?>) persistedCollection;
390
		}else if (persistedCollection instanceof Map) {
391
			collection = ((Map<?,?>)persistedCollection).values();
392
		}else{
393
			throw new RuntimeException ("Non Map and non Collection cas not handled in storeInitializedCollection()");
394
		}
395
		for (Object value : collection){
396
			preparePropertyValueForBulkLoadOrStore(node, null, param, value);
397
		}
398
	}
399

    
400
	/**
401
	 * @see #storeInitializedCollection(AbstractPersistentCollection, BeanInitNode, String)alizedCollection
402
	 */
403
	private void storeInitializedEnversCollection(Collection<?> enversCollection,
404
            BeanInitNode node, String param) {
405
	    if (enversCollection instanceof CollectionProxy
406
                || enversCollection instanceof MapProxy<?, ?>
407
                || enversCollection instanceof SortedMapProxy<?, ?>){
408
	        Collection<?> collection;
409
	        if (enversCollection instanceof MapProxy
410
	                || enversCollection instanceof SortedMapProxy<?, ?>) {
411
	            collection = ((Map<?,?>)enversCollection).values();
412
	        }else if (enversCollection instanceof CollectionProxy) {
413
	            collection = enversCollection;
414
	        }else{
415
	            throw new RuntimeException ("Non MapProxy and non CollectionProxy case not handled in storeInitializedEnversCollection()");
416
	        }
417
	        for (Object value : collection){
418
	            preparePropertyValueForBulkLoadOrStore(node, null, param, value);
419
	        }
420
	    }
421
    }
422

    
423

    
424
	/**
425
	 * Load all beans which are added to the node
426
	 * and which are not yet initialized in bulk.
427
	 * @param node
428
	 */
429
	private void bulkLoadLazies(BeanInitNode node) {
430
		if (logger.isTraceEnabled()){logger.trace("bulk load " +  node);}
431
		//beans
432
		bulkLoadLazyBeans(node);
433
		//collections
434
		bulkLoadLazyCollections(node);
435
		if (logger.isDebugEnabled()){logger.debug("bulk load " +  node + " - DONE ");}
436
	}
437

    
438

    
439
    /**
440
     * Loads all lazy beans added to the node and empty the lazy bean collection of the node.
441
     * Lazy collections are initialized elsewhere: {@link #bulkLoadLazyCollections(BeanInitNode)}
442
     * @param node the {@link BeanInitNode} to load the lazy beans for
443
     */
444
    private void bulkLoadLazyBeans(BeanInitNode node) {
445
        for (Class<?> clazz : node.getLazyBeans().keySet()){
446
            Set<Serializable> idSet = node.getLazyBeans().get(clazz);
447
            if (idSet != null && ! idSet.isEmpty()){
448

    
449
                if (logger.isTraceEnabled()){logger.trace("bulk load beans of class " +  clazz.getSimpleName());}
450
                //TODO use entity name
451
                String hql = " SELECT c FROM %s as c %s WHERE c.id IN (:idSet) ";
452
                AutoInit autoInit = addAutoinitFetchLoading(clazz, "c");
453
                hql = String.format(hql, clazz.getSimpleName(), autoInit.leftJoinFetch);
454
                if (logger.isTraceEnabled()){logger.trace(hql);}
455
                Query query = genericDao.getHqlQuery(hql);
456
                query.setParameterList("idSet", idSet);
457
                List<Object> list = query.list();
458

    
459
                if (logger.isTraceEnabled()){logger.trace("initialize bulk loaded beans of class " +  clazz.getSimpleName());}
460
                for (Object object : list){
461
                    if (object instanceof HibernateProxy){  //TODO remove hibernate dependency
462
                        object = initializeInstance(object);
463
                    }
464
                    autoinitializeBean((CdmBase)object, autoInit);
465
                    node.addBean(object);
466
                }
467
                if (logger.isTraceEnabled()){logger.trace("bulk load - DONE");}
468
            }
469
        }
470
        node.resetLazyBeans();
471
    }
472

    
473
    /**
474
     * Loads all lazy collections added to the node and empty the lazy collections collection of the node.
475
     * Lazy beans are initialized elsewhere: {@link #bulkLoadLazyBeans(BeanInitNode)}
476
     * @param node the {@link BeanInitNode} to load the lazy beans for
477
     */
478
    private void bulkLoadLazyCollections(BeanInitNode node) {
479
        for (Class<?> ownerClazz : node.getLazyCollections().keySet()){
480
			Map<String, Set<Serializable>> lazyParams = node.getLazyCollections().get(ownerClazz);
481
			for (String param : lazyParams.keySet()){
482
				Set<Serializable> idSet = lazyParams.get(param);
483
				if (idSet != null && ! idSet.isEmpty()){
484
					if (logger.isTraceEnabled()){logger.trace("bulk load " + node + " collections ; ownerClass=" +  ownerClazz.getSimpleName() + " ; param = " + param);}
485

    
486
					Type collectionEntitiyType = null;
487
					PropertyDescriptor[] descriptors = PropertyUtils.getPropertyDescriptors(ownerClazz);
488
					for(PropertyDescriptor d : descriptors) {
489
					    if(d.getName().equals(param)) {
490
					        Method readMethod = d.getReadMethod();
491
                            ParameterizedType pt = (ParameterizedType) readMethod.getGenericReturnType();
492
                            Type[] actualTypeArguments = pt.getActualTypeArguments();
493
                            if(actualTypeArguments.length == 2) {
494
                                // this must be a map of <Language, String> (aka LanguageString) there is no other case like this in the cdm
495
                                // in case of Maps the returned Collection will be the Collection of the values, so collectionEntitiyType is the
496
                                // second typeArgument
497
                                collectionEntitiyType = actualTypeArguments[1];
498
                            } else {
499
                                collectionEntitiyType = actualTypeArguments[0];
500
                            }
501
                            if(collectionEntitiyType instanceof TypeVariable) {
502
                                collectionEntitiyType = ((TypeVariable)collectionEntitiyType).getBounds()[0];
503
                            }
504
					    }
505
					}
506

    
507
					//TODO use entity name ??
508
					//get from repository
509
					List<Object[]> list;
510
					String hql = "SELECT oc " +
511
							" FROM %s as oc LEFT JOIN FETCH oc.%s as col %s" +
512
							" WHERE oc.id IN (:idSet) ";
513

    
514
					AutoInit autoInit = addAutoinitFetchLoading((Class)collectionEntitiyType, "col");
515
                    hql = String.format(hql, ownerClazz.getSimpleName(), param,
516
					        autoInit.leftJoinFetch);
517

    
518
					try {
519
						if (logger.isTraceEnabled()){logger.trace(hql);}
520
						Query query = genericDao.getHqlQuery(hql);
521
						query.setParameterList("idSet", idSet);
522
						list = query.list();
523
						if (logger.isTraceEnabled()){logger.trace("size of retrieved list is " + list.size());}
524
					} catch (HibernateException e) {
525
						e.printStackTrace();
526
						throw e;
527
					}
528

    
529
					//getTarget and add to child node
530
					if (logger.isTraceEnabled()){logger.trace("initialize bulk loaded " + node + " collections - DONE");}
531
					for (Object parentBean : list){
532
                        try {
533
						    Object propValue = PropertyUtils.getProperty(
534
						            parentBean,
535
						            mapFieldToPropertyName(param, parentBean.getClass().getSimpleName())
536
						          );
537

    
538
							if (propValue == null){
539
							    logger.trace("Collection is null");
540
							}else {
541
							    if(propValue instanceof PersistentMap) {
542
							        propValue = ((PersistentMap)propValue).values();
543
							    }
544
							    for(Object newBean : (Collection<Object>)propValue ) {
545
							        if(newBean instanceof HibernateProxy){
546
							            newBean = initializeInstance(newBean);
547
							        }
548

    
549
							        if (HibernateProxyHelper.isInstanceOf(newBean, CdmBase.class)){
550
							            autoinitializeBean((CdmBase)newBean, autoInit);
551
							        }
552
							        node.addBean(newBean);
553
							    }
554
							}
555
                        } catch (Exception e) {
556
                            // TODO better throw an exception ?
557
                            logger.error("error while getting collection property", e);
558
                        }
559
					}
560
					if (logger.isTraceEnabled()){logger.trace("bulk load " + node + " collections - DONE");}
561
				}
562
			}
563
		}
564
		for (AbstractPersistentCollection collection : node.getUninitializedCollections()){
565
			if (! collection.wasInitialized()){  //should not happen anymore
566
				collection.forceInitialization();
567
				if (logger.isTraceEnabled()){logger.trace("forceInitialization of collection " + collection);}
568
			} else {
569
			    if (logger.isTraceEnabled()){logger.trace("collection " + collection + " is initialized - OK!");}
570
			}
571
		}
572

    
573
		node.resetLazyCollections();
574
    }
575

    
576
    private AutoInit addAutoinitFetchLoading(Class<?> clazz, String beanAlias) {
577

    
578
        AutoInit autoInit = new AutoInit();
579
        if(clazz != null) {
580
            Set<AutoPropertyInitializer<CdmBase>> inits = getAutoInitializers(clazz);
581
            for (AutoPropertyInitializer<CdmBase> init: inits){
582
                try {
583
                    autoInit.leftJoinFetch +=init.hibernateFetchJoin(clazz, beanAlias);
584
                } catch (Exception e) {
585
                    // the AutoPropertyInitializer is not supporting LEFT JOIN FETCH so it needs to be
586
                    // used explicitly
587
                    autoInit.initlializers.add(init);
588
                }
589

    
590
            }
591
        }
592
        return autoInit;
593
    }
594

    
595
    private Set<AutoPropertyInitializer<CdmBase>> getAutoInitializers(Class<?> clazz) {
596
        Set<AutoPropertyInitializer<CdmBase>> result = new HashSet<AutoPropertyInitializer<CdmBase>>();
597
        for(Class<? extends CdmBase> superClass : getBeanAutoInitializers().keySet()){
598
            if(superClass.isAssignableFrom(clazz)){
599
                result.add(getBeanAutoInitializers().get(superClass));
600
            }
601
        }
602
        return result;
603
    }
604

    
605
    /**
606
     * Rename hibernate (field) attribute to Bean property name, due to bean inconsistencies
607
     * #3841
608
     * @param param
609
     * @param ownerClass
610
     * @return
611
     */
612
    private String mapFieldToPropertyName(String param, String ownerClass) {
613
        if (ownerClass.contains("Description") && param.equals("descriptionElements")){
614
            return "elements";
615
        }
616
        if (ownerClass.startsWith("FeatureNode") && param.equals("children")) {
617
            return "childNodes";
618
        }
619
        if (ownerClass.startsWith("Media") && param.equals("description")) {
620
            return "allDescriptions";
621
        }
622
        else{
623
            return param;
624
        }
625
    }
626

    
627
    /**
628
     * @param node
629
     * @param property
630
     * @param index
631
     * @param bean
632
     * @param unwrappedPropertyBean
633
     */
634
    private void initializeNodeSinglePropertyOld(BeanInitNode node, String property,
635
            Integer index, Object bean, Object unwrappedPropertyBean) {
636
        Collection<?> collection = null;
637
        if(Map.class.isAssignableFrom(unwrappedPropertyBean.getClass())) {
638
            collection = ((Map<?,?>)unwrappedPropertyBean).values();
639
        }else if (Collection.class.isAssignableFrom(unwrappedPropertyBean.getClass())) {
640
            collection =  (Collection<?>) unwrappedPropertyBean;
641
        }
642
        if (collection != null){
643
            //collection or map
644
            if (logger.isTraceEnabled()){logger.trace(" initialize collection for " + node.toStringNoWildcard() + " ... ");}
645
            int i = 0;
646
            for (Object entrybean : collection) {
647
                if(index == null){
648
                    node.addBean(entrybean);
649
                } else if(index.equals(i)){
650
                    node.addBean(entrybean);
651
                    break;
652
                }
653
                i++;
654
            }
655
            if (logger.isTraceEnabled()){logger.trace(" initialize collection for " + node.toString() + " - DONE ");}
656

    
657
        }else {
658
            // nested bean
659
            node.addBean(unwrappedPropertyBean);
660
            setProperty(bean, property, unwrappedPropertyBean);
661
        }
662
    }
663

    
664
    private class AutoInit{
665

    
666
        String leftJoinFetch = "";
667
        Set<AutoPropertyInitializer<CdmBase>> initlializers = new HashSet<AutoPropertyInitializer<CdmBase>>();
668

    
669
        /**
670
         * @param leftJoinFetch
671
         * @param initlializers
672
         */
673
        public AutoInit() {
674
        }
675
    }
676
}
(2-2/12)