improved dwc mapping
[cdmlib.git] / cdmlib-remote / src / main / java / eu / etaxonomy / cdm / remote / dto / assembler / converter / HibernateProxyNullSafeDeepConverter.java
1 // $Id$
2 /**
3 * Copyright (C) 2007 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
6 *
7 * The contents of this file are subject to the Mozilla Public License Version 1.1
8 * See LICENSE.TXT at the top of this package for the full license terms.
9 */
10 package eu.etaxonomy.cdm.remote.dto.assembler.converter;
11
12 import java.beans.PropertyDescriptor;
13 import java.lang.reflect.InvocationTargetException;
14 import java.lang.reflect.Method;
15 import java.util.Arrays;
16 import java.util.Iterator;
17 import java.util.List;
18
19 import org.dozer.ConfigurableCustomConverter;
20 import org.dozer.Mapper;
21 import org.dozer.MappingException;
22 import org.hibernate.Hibernate;
23 import org.springframework.beans.BeanUtils;
24 import org.springframework.beans.BeansException;
25 import org.springframework.context.ApplicationContext;
26 import org.springframework.context.ApplicationContextAware;
27
28 import eu.etaxonomy.cdm.model.common.CdmBase;
29
30 public class HibernateProxyNullSafeDeepConverter implements ConfigurableCustomConverter, ApplicationContextAware {
31
32 private Mapper mapper;
33
34 private ApplicationContext applicationContext;
35
36 String parameter = null;
37
38 private List<String> parameterList;
39
40 /* (non-Javadoc)
41 * @see org.dozer.ConfigurableCustomConverter#setParameter(java.lang.String)
42 */
43 @Override
44 public void setParameter(String parameter) {
45 this.parameter = parameter;
46 if(parameter.indexOf('.') > -1){
47 this.parameterList = Arrays.asList(parameter.split("."));
48 } else {
49 this.parameterList = Arrays.asList(new String[]{parameter});
50 }
51 }
52
53
54 protected Mapper getMapper() {
55 if(mapper == null) {
56 this.setMapper((Mapper)this.applicationContext.getBean("dozerMapper", Mapper.class));
57 }
58 return mapper;
59 }
60
61 public void setMapper(Mapper mapper) {
62 this.mapper = mapper;
63 }
64
65 public Object convert(Object destination, Object source, Class<?> destClass, Class<?> sourceClass) {
66 if (source == null || !Hibernate.isInitialized(source)) {
67 return null;
68 } else {
69
70 try {
71 Object value = invokeProperty(source, sourceClass, parameterList.iterator());
72 if(value == null || !Hibernate.isInitialized(value)) {
73 return null;
74 } else {
75 if(value instanceof CdmBase) {
76 return getMapper().map(value, destClass);
77 } else {
78 return value;
79 }
80 }
81 } catch (Exception e) {
82 throw new MappingException("Converter HibernateProxyNullSafeDeepConverter used incorrectly. Arguments passed in were:"+ destination + " and " + source + " sourceClass " + sourceClass + " destClass " + destClass, e);
83 }
84
85 }
86 }
87
88 private Object invokeProperty(Object source, Class<?> sourceClass, Iterator<String> parameterIterator) throws IllegalAccessException,
89 InvocationTargetException {
90 Object value;
91 String param = parameterIterator.next();
92 PropertyDescriptor propertyDescriptor = BeanUtils.getPropertyDescriptor(sourceClass, param);
93 Method method = propertyDescriptor.getReadMethod();
94 method.setAccessible(true);
95 assert method != null;
96 value = method.invoke(source);
97 if(parameterIterator.hasNext()){
98 return invokeProperty(source, sourceClass, parameterIterator);
99 } else {
100 return value;
101 }
102 }
103
104 public void setApplicationContext(ApplicationContext applicationContext)
105 throws BeansException {
106 this.applicationContext = applicationContext;
107 }
108
109
110 }