1 16 package net.sf.dozer.util.mapping.propertydescriptor; 17 18 import java.beans.PropertyDescriptor ; 19 import java.lang.reflect.Array ; 20 import java.lang.reflect.InvocationTargetException ; 21 import java.lang.reflect.Method ; 22 import java.util.ArrayList ; 23 import java.util.Collection ; 24 import java.util.HashSet ; 25 import java.util.Iterator ; 26 import java.util.Set ; 27 28 import net.sf.dozer.util.mapping.DozerBeanMapper; 29 import net.sf.dozer.util.mapping.MappingException; 30 import net.sf.dozer.util.mapping.fieldmap.ClassMap; 31 import net.sf.dozer.util.mapping.fieldmap.Field; 32 import net.sf.dozer.util.mapping.fieldmap.Hint; 33 import net.sf.dozer.util.mapping.util.CollectionUtils; 34 import net.sf.dozer.util.mapping.util.DestBeanCreator; 35 import net.sf.dozer.util.mapping.util.MapperConstants; 36 import net.sf.dozer.util.mapping.util.MappingUtils; 37 import net.sf.dozer.util.mapping.util.ReflectionUtils; 38 39 import org.apache.commons.logging.Log; 40 import org.apache.commons.logging.LogFactory; 41 42 45 public class BruteForcePropertyDescriptor implements DozerPropertyDescriptorIF { 46 47 private static final Log log = LogFactory.getLog(DozerBeanMapper.class); 49 50 51 private final Field field; 52 private final ReflectionUtils reflectionUtils = new ReflectionUtils(); 53 private final CollectionUtils collectionUtils = new CollectionUtils(); 54 private final MappingUtils mappingUtils = new MappingUtils(); 55 private final DestBeanCreator destBeanCreator = new DestBeanCreator(MappingUtils.storedFactories); 57 58 public BruteForcePropertyDescriptor(Field field) { 59 this.field = field; 60 } 61 62 public Class getPropertyType(Class clazz) { 63 Class returnType; 64 try { 65 returnType = getReadMethod(clazz).getReturnType(); 66 } catch (Exception e) { 67 log.debug("Read method exception:" + e); 68 returnType = getWriteMethod(clazz).getParameterTypes()[0]; 70 } 71 return returnType; 72 } 73 74 public void setPropertyValue(Object bean, Object value, Hint hint, ClassMap classMap) { 75 try { 76 if (field.getName().indexOf(MapperConstants.DEEP_FIELD_DELIMITOR) < 0) { 77 if (getPropertyType(bean.getClass()).isPrimitive() && value == null) { 78 } else { 80 try { 82 if (getPropertyValue(bean) == value) { 83 return; 84 } 85 } catch (Exception e) { 86 } 88 if (!field.isIndexed()) { 89 getWriteMethod(bean.getClass()).invoke(bean, new Object [] { value }); 90 } else { 91 writeIndexedValue(null, bean, value); 92 } 93 } 94 } else { 95 writeDeepDestinationValue(bean, value, hint, classMap); 96 } 97 } catch (Exception e) { 98 throw new MappingException(e); 99 } 100 } 101 102 public Object getPropertyValue(Object bean) { 103 Object o = null; 104 try { 105 if (field.getName().indexOf(MapperConstants.DEEP_FIELD_DELIMITOR) < 0) { 106 o = getReadMethod(bean.getClass()).invoke(bean, null); 107 if (field.isIndexed()) { 108 return mappingUtils.getIndexedValue(o, field.getIndex()); 109 } else { 110 return o; 111 } 112 } else { 113 return getDeepSrcFieldValue(bean); 114 } 115 } catch (Exception e) { 116 throw new MappingException(e); 117 } 118 } 119 120 121 protected Object getDeepSrcFieldValue(Object srcObj) throws InvocationTargetException , IllegalAccessException { 122 Object parentObj = srcObj; 124 Object hierarchyValue = null; 125 PropertyDescriptor [] hierarchy = getHierarchy(srcObj); 126 int size = hierarchy.length; 127 for (int i = 0; i < size; i++) { 128 PropertyDescriptor pd = hierarchy[i]; 129 hierarchyValue = pd.getReadMethod().invoke(parentObj, null); 130 parentObj = hierarchyValue; 131 if (hierarchyValue == null) { 132 break; 133 } 134 } 135 136 if (field.isIndexed()) { 138 hierarchyValue = mappingUtils.getIndexedValue(hierarchyValue, field.getIndex()); 139 } 140 141 return hierarchyValue; 142 } 143 144 protected Method getReadMethod(Class objectClass, String fieldName) { 145 PropertyDescriptor pd = reflectionUtils.getPropertyDescriptor(objectClass, fieldName); 146 if ((pd == null || pd.getReadMethod() == null)) { 147 throw new MappingException("Unable to determine read method for field: " + fieldName + " class: " + objectClass); 148 } 149 return pd.getReadMethod(); 150 } 151 152 protected Method getWriteMethod(Class objectClass, String fieldName) { 153 PropertyDescriptor pd = reflectionUtils.getPropertyDescriptor(objectClass, fieldName); 154 if ((pd == null || pd.getWriteMethod() == null)) { 155 throw new MappingException("Unable to determine write method for field: " + fieldName + " class: " + objectClass); 156 } 157 return pd.getWriteMethod(); 158 } 159 160 protected void writeDeepDestinationValue(Object destObj, Object destFieldValue, Hint destHint, ClassMap classMap) 161 throws IllegalAccessException , InvocationTargetException , InstantiationException , ClassNotFoundException , 162 NoSuchMethodException , NoSuchFieldException { 163 PropertyDescriptor [] hierarchy = getHierarchy(destObj); 165 Object parentObj = destObj; 167 int hierarchyLength = hierarchy.length - 1; 168 for (int i = 0; i < hierarchyLength; i++) { 169 PropertyDescriptor pd = hierarchy[i]; 170 Object value = pd.getReadMethod().invoke(parentObj, null); 171 Class clazz = null; 172 if (value == null) { 173 clazz = pd.getPropertyType(); 174 if (clazz.isInterface()) { 175 if ((i + 1) == hierarchyLength) { 178 if (destHint != null) { 180 clazz = destHint.getHint(); 181 } 182 } 183 } 184 Object o; 185 try { 186 o = clazz.newInstance(); 187 pd.getWriteMethod().invoke(parentObj, new Object [] { o }); 188 } catch (InstantiationException e) { 189 if (classMap.getDestClass().getBeanFactory() != null) { 191 o = destBeanCreator.createFromFactory(null, classMap.getSourceClass().getClassToMap(), classMap 192 .getDestClass().getBeanFactory(), classMap.getDestClass().getFactoryBeanId(), clazz); 193 pd.getWriteMethod().invoke(parentObj, new Object [] { o }); 194 } else { 195 throw e; 196 } 197 } 198 value = pd.getReadMethod().invoke(parentObj, null); 199 } 200 parentObj = value; 201 } 202 PropertyDescriptor pd = hierarchy[hierarchy.length - 1]; 204 if (pd.getReadMethod().getReturnType().isPrimitive() && destFieldValue == null) { 205 } else { 206 if (!field.isIndexed()) { 207 Method method = pd.getWriteMethod(); 208 if(method == null && field.getTheSetMethod() != null) { 209 method = reflectionUtils.findAMethod(parentObj.getClass(), field.getTheSetMethod()); 211 } 212 method.invoke(parentObj, new Object [] { destFieldValue }); 213 } else { 214 writeIndexedValue(pd, parentObj, destFieldValue); 215 } 216 } 217 } 218 219 protected PropertyDescriptor [] getHierarchy(Object obj) { 220 return reflectionUtils.getDeepFieldHierarchy(obj.getClass(), field.getName()); 221 } 222 223 public String getReadMethodName(Class clazz) { 224 Method readMethod; 225 try { 226 readMethod = getReadMethod(clazz); 227 } catch (MappingException e) { 228 log.debug("Can't find read method for class:" + clazz + " and field:" + field.getName()); 229 return "NoReadMethodFound"; 230 } 231 return readMethod.getName(); 232 } 233 234 public String getWriteMethodName(Class clazz) { 235 return getWriteMethod(clazz).getName(); 236 } 237 238 public Method getReadMethod(Class bean) { 239 Method readMethod; 240 if (field.getTheGetMethod() == null) { 241 readMethod = getReadMethod(bean, field.getName()); 242 } else { 243 try { 244 readMethod = reflectionUtils.findAMethod(bean, field.getTheGetMethod()); 245 } catch (Exception e) { 246 throw new MappingException(e); 247 } 248 } 249 return readMethod; 250 } 251 252 public Method getWriteMethod(Class clazz) { 253 Method writeMethod; 254 if (field.getTheSetMethod() == null || field.getName().indexOf(MapperConstants.DEEP_FIELD_DELIMITOR) > 0) { 255 writeMethod = getWriteMethod(clazz, field.getName()); 256 } else { 257 try { 258 writeMethod = reflectionUtils.findAMethod(clazz, field.getTheSetMethod()); 259 } catch (Exception e) { 260 throw new MappingException(e); 261 } 262 } 263 return writeMethod; 264 } 265 266 protected void writeIndexedValue(PropertyDescriptor pd, Object destObj, Object destFieldValue) 267 throws IllegalAccessException , InvocationTargetException , NoSuchMethodException , ClassNotFoundException , 268 NoSuchFieldException { 269 int index = field.getIndex(); 270 Object o = null; 271 if (pd != null) { 272 o = pd.getReadMethod().invoke(destObj, null); 273 } else { 274 o = getReadMethod(destObj.getClass()).invoke(destObj, null); 275 } 276 if (o == null) { 277 Class returnType = null; 278 if (pd != null) { 279 returnType = pd.getReadMethod().getReturnType(); 280 } else { 281 returnType = getPropertyType(destObj.getClass()); 282 } 283 if (returnType.isArray()) { 284 o = Array.newInstance(returnType.getComponentType(), 0); 285 } else if (collectionUtils.isSet(returnType)) { 286 o = new HashSet (); 287 } else { o = new ArrayList (); 289 } 290 } 291 if (o instanceof Collection ) { 292 Collection newCollection; 293 if (o instanceof Set ) { 294 newCollection = new HashSet (); 295 } else { 296 newCollection = new ArrayList (); 297 } 298 299 Collection c = (Collection ) o; 300 Iterator i = c.iterator(); 301 int x = 0; 302 while (i.hasNext()) { 303 if (x != index) { 304 newCollection.add(i.next()); 305 } else { 306 newCollection.add(destFieldValue); 307 } 308 x++; 309 } 310 if (newCollection.size() <= index) { 311 while (newCollection.size() < index) { 312 newCollection.add(null); 313 } 314 newCollection.add(destFieldValue); 315 } 316 if (pd != null) { 317 pd.getWriteMethod().invoke(destObj, new Object [] { newCollection }); 318 } else { 319 getWriteMethod(destObj.getClass()).invoke(destObj, new Object [] { newCollection }); 320 } 321 } else if (o.getClass().isArray()) { 322 Object [] objs = (Object []) o; 323 Object [] x = (Object []) Array.newInstance(objs.getClass().getComponentType(), 324 objs.length > index ? objs.length + 1 : index + 1); 325 for (int i = 0; i < objs.length; i++) { 326 x[i] = objs[i]; 327 } 328 x[index] = destFieldValue; 329 330 if (pd == null) { 331 getWriteMethod(destObj.getClass()).invoke(destObj, new Object [] { x }); 332 } else { 333 pd.getWriteMethod().invoke(destObj, new Object [] { x }); 334 } 335 } 336 } 337 338 } | Popular Tags |