1 16 package org.apache.commons.lang.builder; 17 18 import java.lang.reflect.AccessibleObject ; 19 import java.lang.reflect.Field ; 20 import java.lang.reflect.Modifier ; 21 import java.util.HashSet ; 22 import java.util.Set ; 23 24 import org.apache.commons.lang.ClassUtils; 25 26 94 public class ReflectionToStringBuilder extends ToStringBuilder { 95 101 private static ThreadLocal registry = new ThreadLocal () { 102 protected synchronized Object initialValue() { 103 return new HashSet (); 106 } 107 }; 108 109 117 static Set getRegistry() { 118 return (Set ) registry.get(); 119 } 120 121 132 static boolean isRegistered(Object value) { 133 return getRegistry().contains(value); 134 } 135 136 145 static void register(Object value) { 146 getRegistry().add(value); 147 } 148 149 172 public static String toString(Object object) { 173 return toString(object, null, false, false, null); 174 } 175 176 207 public static String toString(Object object, ToStringStyle style) { 208 return toString(object, style, false, false, null); 209 } 210 211 249 public static String toString(Object object, ToStringStyle style, boolean outputTransients) { 250 return toString(object, style, outputTransients, false, null); 251 } 252 253 299 public static String toString(Object object, ToStringStyle style, boolean outputTransients, boolean outputStatics) { 300 return toString(object, style, outputTransients, outputStatics, null); 301 } 302 303 352 public static String toString(Object object, ToStringStyle style, boolean outputTransients, boolean outputStatics, 353 Class reflectUpToClass) { 354 return new ReflectionToStringBuilder(object, style, null, reflectUpToClass, outputTransients, outputStatics) 355 .toString(); 356 } 357 358 404 public static String toString(Object object, ToStringStyle style, boolean outputTransients, 405 Class reflectUpToClass) { 406 return new ReflectionToStringBuilder(object, style, null, reflectUpToClass, outputTransients).toString(); 407 } 408 409 421 static void unregister(Object value) { 422 getRegistry().remove(value); 423 } 424 425 428 private boolean appendStatics = false; 429 430 433 private boolean appendTransients = false; 434 435 438 private Class upToClass = null; 439 440 455 public ReflectionToStringBuilder(Object object) { 456 super(object); 457 } 458 459 477 public ReflectionToStringBuilder(Object object, ToStringStyle style) { 478 super(object, style); 479 } 480 481 504 public ReflectionToStringBuilder(Object object, ToStringStyle style, StringBuffer buffer) { 505 super(object, style, buffer); 506 } 507 508 526 public ReflectionToStringBuilder(Object object, ToStringStyle style, StringBuffer buffer, Class reflectUpToClass, 527 boolean outputTransients) { 528 super(object, style, buffer); 529 this.setUpToClass(reflectUpToClass); 530 this.setAppendTransients(outputTransients); 531 } 532 533 551 public ReflectionToStringBuilder(Object object, ToStringStyle style, StringBuffer buffer, Class reflectUpToClass, 552 boolean outputTransients, boolean outputStatics) { 553 super(object, style, buffer); 554 this.setUpToClass(reflectUpToClass); 555 this.setAppendTransients(outputTransients); 556 this.setAppendStatics(outputStatics); 557 } 558 559 573 protected boolean accept(Field field) { 574 if (field.getName().indexOf(ClassUtils.INNER_CLASS_SEPARATOR_CHAR) != -1) { 575 return false; 577 } 578 if (Modifier.isTransient(field.getModifiers()) && !this.isAppendTransients()) { 579 return false; 581 } 582 if (Modifier.isStatic(field.getModifiers()) && !this.isAppendStatics()) { 583 return false; 585 } 586 return true; 587 } 588 589 604 protected void appendFieldsIn(Class clazz) { 605 if (isRegistered(this.getObject())) { 606 this.appendAsObjectToString(this.getObject()); 611 return; 612 } 613 try { 614 this.registerObject(); 615 if (clazz.isArray()) { 616 this.reflectionAppendArray(this.getObject()); 617 return; 618 } 619 Field [] fields = clazz.getDeclaredFields(); 620 AccessibleObject.setAccessible(fields, true); 621 for (int i = 0; i < fields.length; i++) { 622 Field field = fields[i]; 623 String fieldName = field.getName(); 624 if (this.accept(field)) { 625 try { 626 Object fieldValue = this.getValue(field); 629 if (isRegistered(fieldValue) && !field.getType().isPrimitive()) { 630 this.getStyle().appendFieldStart(this.getStringBuffer(), fieldName); 634 this.appendAsObjectToString(fieldValue); 635 this.getStyle().appendFieldEnd(this.getStringBuffer(), fieldName); 636 } else { 641 try { 642 this.registerObject(); 643 this.append(fieldName, fieldValue); 644 } finally { 645 this.unregisterObject(); 646 } 647 } 648 } catch (IllegalAccessException ex) { 649 throw new InternalError ("Unexpected IllegalAccessException: " + ex.getMessage()); 654 } 655 } 656 } 657 } finally { 658 this.unregisterObject(); 659 } 660 } 661 662 669 public Class getUpToClass() { 670 return this.upToClass; 671 } 672 673 689 protected Object getValue(Field field) throws IllegalArgumentException , IllegalAccessException { 690 return field.get(this.getObject()); 691 } 692 693 701 public boolean isAppendStatics() { 702 return this.appendStatics; 703 } 704 705 712 public boolean isAppendTransients() { 713 return this.appendTransients; 714 } 715 716 725 public ToStringBuilder reflectionAppendArray(Object array) { 726 this.getStyle().reflectionAppendArrayDetail(this.getStringBuffer(), null, array); 727 return this; 728 } 729 730 736 void registerObject() { 737 register(this.getObject()); 738 } 739 740 749 public void setAppendStatics(boolean appendStatics) { 750 this.appendStatics = appendStatics; 751 } 752 753 761 public void setAppendTransients(boolean appendTransients) { 762 this.appendTransients = appendTransients; 763 } 764 765 773 public void setUpToClass(Class clazz) { 774 this.upToClass = clazz; 775 } 776 777 784 public String toString() { 785 if (this.getObject() == null) { 786 return this.getStyle().getNullText(); 787 } 788 Class clazz = this.getObject().getClass(); 789 this.appendFieldsIn(clazz); 790 while (clazz.getSuperclass() != null && clazz != this.getUpToClass()) { 791 clazz = clazz.getSuperclass(); 792 this.appendFieldsIn(clazz); 793 } 794 return super.toString(); 795 } 796 797 803 void unregisterObject() { 804 unregister(this.getObject()); 805 } 806 } 807 | Popular Tags |