1 30 31 38 39 package com.nightlabs.util.reflect; 40 41 import java.lang.reflect.Array ; 42 import java.lang.reflect.Field ; 43 import java.lang.reflect.InvocationTargetException ; 44 import java.lang.reflect.Method ; 45 import java.lang.reflect.Modifier ; 46 import java.util.ArrayList ; 47 import java.util.HashMap ; 48 import java.util.Iterator ; 49 import java.util.List ; 50 import java.util.Map ; 51 52 53 57 public class ReflectUtil 58 { 59 60 public ReflectUtil() 61 { 62 super(); 63 } 64 65 73 public static Object clone(Object original) { 74 return clone(original, Object .class); 75 } 76 77 public static Object clone(Object original, String [] ignoredMembers) { 78 return clone(original, Object .class, ignoredMembers); 79 } 80 81 public static Object clone(Object original, Class [] cloneDelegates) { 82 return clone(original, Object .class, null, cloneDelegates); 83 } 84 85 public static Object clone(Object original, String [] ignoredMembers, Class [] cloneDelegtes) { 86 return clone(original, Object .class, ignoredMembers, cloneDelegtes); 87 } 88 89 public static Map initCloneDelegates(Class [] cloneDelegates) 90 throws CloneException 91 { 92 Map class2CloneDelegate = new HashMap (cloneDelegates.length); 93 for (int i=0; i<cloneDelegates.length; ++i) { 94 Class cdClass = cloneDelegates[i]; 95 if (CloneDelegate.class.isAssignableFrom(cdClass)) { 96 try { 97 Method getCloneClass = cdClass.getMethod("getCloneClass", null); 98 Class cloneClass = (Class ) getCloneClass.invoke(null, null); 99 class2CloneDelegate.put(cloneClass, cdClass); 100 } 101 catch (SecurityException e) { 102 throw new CloneException(e); 103 } 104 catch (NoSuchMethodException e) { 105 throw new CloneException(e); 106 } 107 catch (IllegalArgumentException e) { 108 throw new CloneException(e); 109 } 110 catch (IllegalAccessException e) { 111 throw new CloneException(e); 112 } 113 catch (InvocationTargetException e) { 114 throw new CloneException(e); 115 } 116 } 117 } 118 return class2CloneDelegate; 119 } 120 121 public static Object clone(Object original, 122 Class stopClass, 123 String [] ignoredMembers, 124 Class [] cloneDelegates) 125 { 126 try 127 { 128 Class orgClass = original.getClass(); 129 List fields = collectAllFields(orgClass, stopClass, true, ignoredMembers); 130 boolean cloneDelegate = false; 131 HashMap class2CloneDelegate = new HashMap (0); 132 if (cloneDelegates != null) { 133 class2CloneDelegate = new HashMap (initCloneDelegates(cloneDelegates)); 134 cloneDelegate = true; 135 } 136 137 try 138 { 139 Object dcInstance = orgClass.newInstance(); 142 for (Iterator it = fields.iterator(); it.hasNext(); ) 143 { 144 Field field = (Field ) it.next(); 145 Class fieldType = field.getType(); 146 147 if (cloneDelegate && class2CloneDelegate.containsKey(fieldType)) 149 { 150 Class cdClass = (Class ) class2CloneDelegate.get(fieldType); 151 Method clone = cdClass.getMethod("clone", new Class [] {fieldType}); 152 Object clonedField = clone.invoke(cdClass.newInstance(), new Object [] {field.get(dcInstance)}); 153 field.set(dcInstance, clonedField); 154 } 155 else if (fieldType.isPrimitive()) 157 { 158 field.set(dcInstance, field.get(original)); 159 } 160 else if (fieldType.isArray()) 162 { 163 Object array = field.get(original); 164 if (array == null) 165 continue; 166 167 int length = Array.getLength(array); 168 Class arrayType = array.getClass(); 169 Object clonedArray = Array.newInstance(arrayType.getComponentType(), length); 170 for (int i=0; i<length; ++i) { 171 Object value = Array.get(array, i); 172 Array.set(clonedArray, i, value); 173 } 174 field.set(dcInstance, clonedArray); 175 } 176 else if (Cloneable .class.isAssignableFrom(fieldType)) 178 { 179 Object org = field.get(original); 180 field.set(dcInstance, 181 org.getClass().getMethod(CLONE, null).invoke(org, null) 182 ); 183 } 184 else 185 throw new IllegalStateException ("Not all members are primitive or Cloneable! Class=\""+original.getClass().getName()+"\" Member=\""+field.getType().getName()+" "+field.getName()+"\""); 186 } 187 return dcInstance; 188 } 189 catch (NoSuchMethodException e) { 190 throw new CloneException(e); 191 } 192 catch (IllegalAccessException e) { 193 throw new CloneException(e); 194 } 195 catch (InstantiationException e) { 196 throw new CloneException(e); 197 } 198 catch (InvocationTargetException e) { 199 throw new CloneException(e); 200 } 201 } 202 catch (CloneException x) { 203 throw new RuntimeException (x); 204 } 205 } 206 207 private static String CLONE = "clone"; 208 public static Object clone(Object original, 209 Class stopClass, 210 String [] ignoredMembers) 211 { 212 return clone(original, stopClass, ignoredMembers, null); 213 } 259 260 261 285 public static Object clone(Object original, Class stopClass) 286 { 287 return clone(original, stopClass, null); 288 } 327 328 338 public static List collectAllFields(Class originalClass, 339 Class stopClass, 340 boolean ignoreFields, 341 String [] ignoredMembers) 342 { 343 List fields = new ArrayList (); 344 Class superClass = originalClass; 345 346 while (superClass != stopClass) 350 { 351 Field [] f = superClass.getDeclaredFields(); 352 if (ignoreFields) { 353 for (int i = 0; i < f.length; ++i) { 354 if (ignoreField(f[i])) 355 continue; 356 else if (ignoreMembers(f[i], ignoredMembers)) 357 continue; 358 else { 359 Field field = f[i]; 360 field.setAccessible(true); 362 fields.add(field); 363 } 364 } 365 } 366 else { 367 for (int i = 0; i < f.length; ++i) 368 { 369 Field field = f[i]; 370 if (ignoreMembers(field, ignoredMembers)) 371 continue; 372 field.setAccessible(true); 374 fields.add(field); 375 } 376 } 377 superClass = superClass.getSuperclass(); 378 } 379 return fields; 380 } 381 382 391 public static List collectAllFields(Class originalClass, boolean ignoreFields) { 392 return collectAllFields(originalClass, Object .class, ignoreFields, null); 393 } 394 395 402 private static boolean ignoreField(Field field) 403 { 404 int modifiers = field.getModifiers(); 405 406 if ((modifiers & Modifier.STATIC) != 0) 407 return true; 408 409 if ((modifiers & Modifier.FINAL) != 0) 410 return true; 411 412 return false; 413 } 414 415 private static boolean ignoreMembers(Field field, String [] names) 416 { 417 if (names == null) 418 return false; 419 420 for (int i=0; i<names.length; ++i) { 421 String name = names[i]; 422 if (field.getName().equals(name)) 423 return true; 424 } 425 return false; 426 } 427 428 438 public static boolean equals(Object original, Object target) 439 { 440 if (original == target) 441 return true; 442 443 Class originalClass = original.getClass(); 444 Class targetClass = target.getClass(); 445 446 if (!originalClass.isAssignableFrom(targetClass)) 447 return false; 448 449 List originalFields = collectAllFields(originalClass, true); 450 List targetFields = collectAllFields(targetClass, true); 451 452 if (originalFields.size() != targetFields.size()) 453 return false; 454 455 for (int i=0; i<originalFields.size(); ++i) 456 { 457 Field originalField = (Field ) originalFields.get(i); 458 Field targetField = (Field ) targetFields.get(i); 459 try { 460 if (!originalField.get(original).equals(targetField.get(target))) 461 return false; 462 } 463 catch (IllegalArgumentException e) { 464 e.printStackTrace(); 465 } 466 catch (IllegalAccessException e) { 467 e.printStackTrace(); 468 } 469 } 470 471 return true; 472 } 473 474 484 public static String toString(Object o, boolean withSuperClasses) 485 { 486 Class oClass = o.getClass(); 487 StringBuffer sb = new StringBuffer (); 488 sb.append(oClass.getName()); 490 sb.append("\n"); 491 if (withSuperClasses) 492 { 493 List fields = collectAllFields(oClass, false); 494 for (Iterator it = fields.iterator(); it.hasNext(); ) { 495 Field field = (Field ) it.next(); 496 try { 497 sb.append(field.getName()); 498 sb.append(" = "); 499 sb.append(field.get(o).toString()); 500 sb.append("\n"); 501 } 502 catch (IllegalArgumentException e) { 503 e.printStackTrace(); 504 } 505 catch (IllegalAccessException e) { 506 e.printStackTrace(); 507 } 508 } 509 } 510 else { 511 Field [] fields = oClass.getDeclaredFields(); 512 for (int i=0; i<fields.length; ++i) { 513 Field field = fields[i]; 514 field.setAccessible(true); 515 try { 516 sb.append(field.getName()); 517 sb.append(" = "); 518 sb.append(field.get(o).toString()); 519 sb.append("\n"); 520 } 521 catch (IllegalArgumentException e) { 522 e.printStackTrace(); 523 } 524 catch (IllegalAccessException e) { 525 e.printStackTrace(); 526 } 527 } 528 } 529 return sb.toString(); 530 } 531 532 } 533 | Popular Tags |