Applying a modified version of Maarten Coene's patch for #LANG-69. All unit tests pass; opinions would be very welcome though.
git-svn-id: https://svn.apache.org/repos/asf/jakarta/commons/proper/lang/trunk@500495 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
87ee821a5d
commit
ec4a0fdfac
|
@ -95,57 +95,6 @@
|
|||
* @version $Id$
|
||||
*/
|
||||
public class ReflectionToStringBuilder extends ToStringBuilder {
|
||||
/**
|
||||
* <p>
|
||||
* A registry of objects used by <code>reflectionToString</code> methods to detect cyclical object references and
|
||||
* avoid infinite loops.
|
||||
* </p>
|
||||
*/
|
||||
private static ThreadLocal registry = new ThreadLocal() {
|
||||
protected synchronized Object initialValue() {
|
||||
// The HashSet implementation is not synchronized,
|
||||
// which is just what we need here.
|
||||
return new HashSet();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Returns the registry of objects being traversed by the <code>reflectionToString</code> methods in the current
|
||||
* thread.
|
||||
* </p>
|
||||
*
|
||||
* @return Set the registry of objects being traversed
|
||||
*/
|
||||
static Set getRegistry() {
|
||||
return (Set) registry.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Returns <code>true</code> if the registry contains the given object. Used by the reflection methods to avoid
|
||||
* infinite loops.
|
||||
* </p>
|
||||
*
|
||||
* @param value
|
||||
* The object to lookup in the registry.
|
||||
* @return boolean <code>true</code> if the registry contains the given object.
|
||||
*/
|
||||
static boolean isRegistered(Object value) {
|
||||
return getRegistry().contains(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Registers the given object. Used by the reflection methods to avoid infinite loops.
|
||||
* </p>
|
||||
*
|
||||
* @param value
|
||||
* The object to register.
|
||||
*/
|
||||
static void register(Object value) {
|
||||
getRegistry().add(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
|
@ -462,22 +411,6 @@ public static String toStringExclude(Object object, String[] excludeFieldNames)
|
|||
return new ReflectionToStringBuilder(object).setExcludeFieldNames(excludeFieldNames).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Unregisters the given object.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Used by the reflection methods to avoid infinite loops.
|
||||
* </p>
|
||||
*
|
||||
* @param value
|
||||
* The object to unregister.
|
||||
*/
|
||||
static void unregister(Object value) {
|
||||
getRegistry().remove(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not to append static fields.
|
||||
*/
|
||||
|
@ -657,16 +590,6 @@ protected boolean accept(Field field) {
|
|||
* The class of object parameter
|
||||
*/
|
||||
protected void appendFieldsIn(Class clazz) {
|
||||
if (isRegistered(this.getObject())) {
|
||||
// The object has already been appended, therefore we have an
|
||||
// object cycle.
|
||||
// Append a simple Object.toString style string. The field name is
|
||||
// already appended at this point.
|
||||
this.appendAsObjectToString(this.getObject());
|
||||
return;
|
||||
}
|
||||
try {
|
||||
this.registerObject();
|
||||
if (clazz.isArray()) {
|
||||
this.reflectionAppendArray(this.getObject());
|
||||
return;
|
||||
|
@ -681,37 +604,16 @@ protected void appendFieldsIn(Class clazz) {
|
|||
// Warning: Field.get(Object) creates wrappers objects
|
||||
// for primitive types.
|
||||
Object fieldValue = this.getValue(field);
|
||||
if (isRegistered(fieldValue) && !field.getType().isPrimitive()) {
|
||||
// A known field value has already been appended,
|
||||
// therefore we have an object cycle,
|
||||
// append a simple Object.toString style string.
|
||||
this.getStyle().appendFieldStart(this.getStringBuffer(), fieldName);
|
||||
this.appendAsObjectToString(fieldValue);
|
||||
this.getStyle().appendFieldEnd(this.getStringBuffer(), fieldName);
|
||||
// The recursion out of
|
||||
// builder.append(fieldName, fieldValue);
|
||||
// below will append the field
|
||||
// end marker.
|
||||
} else {
|
||||
try {
|
||||
this.registerObject();
|
||||
this.append(fieldName, fieldValue);
|
||||
} finally {
|
||||
this.unregisterObject();
|
||||
}
|
||||
}
|
||||
} catch (IllegalAccessException ex) {
|
||||
// this can't happen. Would get a Security exception
|
||||
//this can't happen. Would get a Security exception
|
||||
// instead
|
||||
// throw a runtime exception in case the impossible
|
||||
//throw a runtime exception in case the impossible
|
||||
// happens.
|
||||
throw new InternalError("Unexpected IllegalAccessException: " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
this.unregisterObject();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -789,15 +691,6 @@ public ToStringBuilder reflectionAppendArray(Object array) {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Registers this builder's source object to avoid infinite loops when processing circular object references.
|
||||
* </p>
|
||||
*/
|
||||
void registerObject() {
|
||||
register(this.getObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Sets whether or not to append static fields.
|
||||
|
@ -872,12 +765,4 @@ public String toString() {
|
|||
return super.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Unregisters this builder's source object to avoid infinite loops when processing circular object references.
|
||||
* </p>
|
||||
*/
|
||||
void unregisterObject() {
|
||||
unregister(this.getObject());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,9 @@
|
|||
import java.io.Serializable;
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang.ClassUtils;
|
||||
import org.apache.commons.lang.ObjectUtils;
|
||||
|
@ -94,6 +96,78 @@ public abstract class ToStringStyle implements Serializable {
|
|||
*/
|
||||
public static final ToStringStyle SIMPLE_STYLE = new SimpleToStringStyle();
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* A registry of objects used by <code>reflectionToString</code> methods
|
||||
* to detect cyclical object references and avoid infinite loops.
|
||||
* </p>
|
||||
*/
|
||||
private static ThreadLocal registry = new ThreadLocal() {
|
||||
protected synchronized Object initialValue() {
|
||||
// The HashSet implementation is not synchronized,
|
||||
// which is just what we need here.
|
||||
return new HashSet();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Returns the registry of objects being traversed by the <code>reflectionToString</code>
|
||||
* methods in the current thread.
|
||||
* </p>
|
||||
*
|
||||
* @return Set the registry of objects being traversed
|
||||
*/
|
||||
static Set getRegistry() {
|
||||
return (Set) registry.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Returns <code>true</code> if the registry contains the given object.
|
||||
* Used by the reflection methods to avoid infinite loops.
|
||||
* </p>
|
||||
*
|
||||
* @param value
|
||||
* The object to lookup in the registry.
|
||||
* @return boolean <code>true</code> if the registry contains the given
|
||||
* object.
|
||||
*/
|
||||
static boolean isRegistered(Object value) {
|
||||
return getRegistry().contains(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Registers the given object. Used by the reflection methods to avoid
|
||||
* infinite loops.
|
||||
* </p>
|
||||
*
|
||||
* @param value
|
||||
* The object to register.
|
||||
*/
|
||||
static void register(Object value) {
|
||||
if (value != null) {
|
||||
getRegistry().add(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Unregisters the given object.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Used by the reflection methods to avoid infinite loops.
|
||||
* </p>
|
||||
*
|
||||
* @param value
|
||||
* The object to unregister.
|
||||
*/
|
||||
static void unregister(Object value) {
|
||||
getRegistry().remove(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether to use the field names, the default is <code>true</code>.
|
||||
*/
|
||||
|
@ -272,6 +346,7 @@ public void appendEnd(StringBuffer buffer, Object object) {
|
|||
removeLastFieldSeparator(buffer);
|
||||
}
|
||||
appendContentEnd(buffer);
|
||||
unregister(object);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -343,11 +418,14 @@ public void append(StringBuffer buffer, String fieldName, Object value, Boolean
|
|||
* @param detail output detail or not
|
||||
*/
|
||||
protected void appendInternal(StringBuffer buffer, String fieldName, Object value, boolean detail) {
|
||||
if (ReflectionToStringBuilder.isRegistered(value)
|
||||
if (isRegistered(value)
|
||||
&& !(value instanceof Number || value instanceof Boolean || value instanceof Character)) {
|
||||
ObjectUtils.appendIdentityToString(buffer, value);
|
||||
|
||||
} else if (value instanceof Collection) {
|
||||
appendCyclicObject(buffer, fieldName, value);
|
||||
return;
|
||||
}
|
||||
register(value);
|
||||
try {
|
||||
if (value instanceof Collection) {
|
||||
if (detail) {
|
||||
appendDetail(buffer, fieldName, (Collection) value);
|
||||
} else {
|
||||
|
@ -431,6 +509,25 @@ protected void appendInternal(StringBuffer buffer, String fieldName, Object valu
|
|||
appendSummary(buffer, fieldName, value);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
unregister(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Append to the <code>toString</code> an <code>Object</code>
|
||||
* value that has been detected to participate in a cycle. This
|
||||
* implementation will print the standard string value of the value.</p>
|
||||
*
|
||||
* @param buffer the <code>StringBuffer</code> to populate
|
||||
* @param fieldName the field name, typically not used as already appended
|
||||
* @param value the value to add to the <code>toString</code>,
|
||||
* not <code>null</code>
|
||||
*
|
||||
* @since 2.2
|
||||
*/
|
||||
protected void appendCyclicObject(StringBuffer buffer, String fieldName, Object value) {
|
||||
ObjectUtils.appendIdentityToString(buffer, value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1301,6 +1398,7 @@ protected void appendSummary(StringBuffer buffer, String fieldName, boolean[] ar
|
|||
*/
|
||||
protected void appendClassName(StringBuffer buffer, Object object) {
|
||||
if (useClassName && object != null) {
|
||||
register(object);
|
||||
if (useShortClassName) {
|
||||
buffer.append(getShortClassName(object.getClass()));
|
||||
} else {
|
||||
|
@ -1317,6 +1415,7 @@ protected void appendClassName(StringBuffer buffer, Object object) {
|
|||
*/
|
||||
protected void appendIdentityHashCode(StringBuffer buffer, Object object) {
|
||||
if (this.isUseIdentityHashCode() && object!=null) {
|
||||
register(object);
|
||||
buffer.append('@');
|
||||
buffer.append(Integer.toHexString(System.identityHashCode(object)));
|
||||
}
|
||||
|
|
|
@ -168,7 +168,7 @@ public void testReflectionObjectArray() {
|
|||
assertEquals(baseStr + "[{<null>,5,{3,6}}]", ToStringBuilder.reflectionToString(array));
|
||||
array = null;
|
||||
assertReflectionArray("<null>", array);
|
||||
this.validateEmptyReflectionRegistry();
|
||||
this.validateEmptyToStringStyleRegistry();
|
||||
}
|
||||
|
||||
public void testReflectionLongArray() {
|
||||
|
@ -177,7 +177,7 @@ public void testReflectionLongArray() {
|
|||
assertEquals(baseStr + "[{1,2,-3,4}]", ToStringBuilder.reflectionToString(array));
|
||||
array = null;
|
||||
assertReflectionArray("<null>", array);
|
||||
this.validateEmptyReflectionRegistry();
|
||||
this.validateEmptyToStringStyleRegistry();
|
||||
}
|
||||
|
||||
public void testReflectionIntArray() {
|
||||
|
@ -186,7 +186,7 @@ public void testReflectionIntArray() {
|
|||
assertEquals(baseStr + "[{1,2,-3,4}]", ToStringBuilder.reflectionToString(array));
|
||||
array = null;
|
||||
assertReflectionArray("<null>", array);
|
||||
this.validateEmptyReflectionRegistry();
|
||||
this.validateEmptyToStringStyleRegistry();
|
||||
}
|
||||
|
||||
public void testReflectionShortArray() {
|
||||
|
@ -195,7 +195,7 @@ public void testReflectionShortArray() {
|
|||
assertEquals(baseStr + "[{1,2,-3,4}]", ToStringBuilder.reflectionToString(array));
|
||||
array = null;
|
||||
assertReflectionArray("<null>", array);
|
||||
this.validateEmptyReflectionRegistry();
|
||||
this.validateEmptyToStringStyleRegistry();
|
||||
}
|
||||
|
||||
public void testReflectionyteArray() {
|
||||
|
@ -204,7 +204,7 @@ public void testReflectionyteArray() {
|
|||
assertEquals(baseStr + "[{1,2,-3,4}]", ToStringBuilder.reflectionToString(array));
|
||||
array = null;
|
||||
assertReflectionArray("<null>", array);
|
||||
this.validateEmptyReflectionRegistry();
|
||||
this.validateEmptyToStringStyleRegistry();
|
||||
}
|
||||
|
||||
public void testReflectionCharArray() {
|
||||
|
@ -213,7 +213,7 @@ public void testReflectionCharArray() {
|
|||
assertEquals(baseStr + "[{A,2,_,D}]", ToStringBuilder.reflectionToString(array));
|
||||
array = null;
|
||||
assertReflectionArray("<null>", array);
|
||||
this.validateEmptyReflectionRegistry();
|
||||
this.validateEmptyToStringStyleRegistry();
|
||||
}
|
||||
|
||||
public void testReflectionDoubleArray() {
|
||||
|
@ -222,7 +222,7 @@ public void testReflectionDoubleArray() {
|
|||
assertEquals(baseStr + "[{1.0,2.9876,-3.00001,4.3}]", ToStringBuilder.reflectionToString(array));
|
||||
array = null;
|
||||
assertReflectionArray("<null>", array);
|
||||
this.validateEmptyReflectionRegistry();
|
||||
this.validateEmptyToStringStyleRegistry();
|
||||
}
|
||||
|
||||
public void testReflectionFloatArray() {
|
||||
|
@ -231,7 +231,7 @@ public void testReflectionFloatArray() {
|
|||
assertEquals(baseStr + "[{1.0,2.9876,-3.00001,4.3}]", ToStringBuilder.reflectionToString(array));
|
||||
array = null;
|
||||
assertReflectionArray("<null>", array);
|
||||
this.validateEmptyReflectionRegistry();
|
||||
this.validateEmptyToStringStyleRegistry();
|
||||
}
|
||||
|
||||
public void testReflectionBooleanArray() {
|
||||
|
@ -240,7 +240,7 @@ public void testReflectionBooleanArray() {
|
|||
assertEquals(baseStr + "[{true,false,false}]", ToStringBuilder.reflectionToString(array));
|
||||
array = null;
|
||||
assertReflectionArray("<null>", array);
|
||||
this.validateEmptyReflectionRegistry();
|
||||
this.validateEmptyToStringStyleRegistry();
|
||||
}
|
||||
|
||||
// Reflection Array Array tests
|
||||
|
@ -251,7 +251,7 @@ public void testReflectionFloatArrayArray() {
|
|||
assertEquals(baseStr + "[{{1.0,2.29686},<null>,{NaN}}]", ToStringBuilder.reflectionToString(array));
|
||||
array = null;
|
||||
assertReflectionArray("<null>", array);
|
||||
this.validateEmptyReflectionRegistry();
|
||||
this.validateEmptyToStringStyleRegistry();
|
||||
}
|
||||
|
||||
|
||||
|
@ -261,7 +261,7 @@ public void testReflectionLongArrayArray() {
|
|||
assertEquals(baseStr + "[{{1,2},<null>,{5}}]", ToStringBuilder.reflectionToString(array));
|
||||
array = null;
|
||||
assertReflectionArray("<null>", array);
|
||||
this.validateEmptyReflectionRegistry();
|
||||
this.validateEmptyToStringStyleRegistry();
|
||||
}
|
||||
|
||||
public void testReflectionIntArrayArray() {
|
||||
|
@ -270,7 +270,7 @@ public void testReflectionIntArrayArray() {
|
|||
assertEquals(baseStr + "[{{1,2},<null>,{5}}]", ToStringBuilder.reflectionToString(array));
|
||||
array = null;
|
||||
assertReflectionArray("<null>", array);
|
||||
this.validateEmptyReflectionRegistry();
|
||||
this.validateEmptyToStringStyleRegistry();
|
||||
}
|
||||
|
||||
public void testReflectionhortArrayArray() {
|
||||
|
@ -279,7 +279,7 @@ public void testReflectionhortArrayArray() {
|
|||
assertEquals(baseStr + "[{{1,2},<null>,{5}}]", ToStringBuilder.reflectionToString(array));
|
||||
array = null;
|
||||
assertReflectionArray("<null>", array);
|
||||
this.validateEmptyReflectionRegistry();
|
||||
this.validateEmptyToStringStyleRegistry();
|
||||
}
|
||||
|
||||
public void testReflectionByteArrayArray() {
|
||||
|
@ -288,7 +288,7 @@ public void testReflectionByteArrayArray() {
|
|||
assertEquals(baseStr + "[{{1,2},<null>,{5}}]", ToStringBuilder.reflectionToString(array));
|
||||
array = null;
|
||||
assertReflectionArray("<null>", array);
|
||||
this.validateEmptyReflectionRegistry();
|
||||
this.validateEmptyToStringStyleRegistry();
|
||||
}
|
||||
|
||||
public void testReflectionCharArrayArray() {
|
||||
|
@ -297,7 +297,7 @@ public void testReflectionCharArrayArray() {
|
|||
assertEquals(baseStr + "[{{A,B},<null>,{p}}]", ToStringBuilder.reflectionToString(array));
|
||||
array = null;
|
||||
assertReflectionArray("<null>", array);
|
||||
this.validateEmptyReflectionRegistry();
|
||||
this.validateEmptyToStringStyleRegistry();
|
||||
}
|
||||
|
||||
public void testReflectionDoubleArrayArray() {
|
||||
|
@ -306,7 +306,7 @@ public void testReflectionDoubleArrayArray() {
|
|||
assertEquals(baseStr + "[{{1.0,2.29686},<null>,{NaN}}]", ToStringBuilder.reflectionToString(array));
|
||||
array = null;
|
||||
assertReflectionArray("<null>", array);
|
||||
this.validateEmptyReflectionRegistry();
|
||||
this.validateEmptyToStringStyleRegistry();
|
||||
}
|
||||
|
||||
public void testReflectionBooleanArrayArray() {
|
||||
|
@ -316,7 +316,7 @@ public void testReflectionBooleanArrayArray() {
|
|||
assertEquals(baseStr + "[{{true,false},<null>,{false}}]", ToStringBuilder.reflectionToString(array));
|
||||
array = null;
|
||||
assertReflectionArray("<null>", array);
|
||||
this.validateEmptyReflectionRegistry();
|
||||
this.validateEmptyToStringStyleRegistry();
|
||||
}
|
||||
|
||||
// Reflection hierarchy tests
|
||||
|
@ -326,7 +326,7 @@ public void testReflectionHierarchyArrayList() {
|
|||
String baseStr = this.toBaseString(base);
|
||||
assertEquals(baseStr + "[elementData={<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>},size=0,modCount=0]", ToStringBuilder.reflectionToString(base, null, true));
|
||||
assertEquals(baseStr + "[size=0]", ToStringBuilder.reflectionToString(base, null, false));
|
||||
this.validateEmptyReflectionRegistry();
|
||||
this.validateEmptyToStringStyleRegistry();
|
||||
}
|
||||
|
||||
public void testReflectionHierarchy() {
|
||||
|
@ -353,7 +353,7 @@ public void testReflectionHierarchy() {
|
|||
assertEquals(baseStr + "[b=b,a=a]", ToStringBuilder.reflectionToString(baseB, null, false, List.class));
|
||||
assertEquals(baseStr + "[b=b,a=a]", ToStringBuilder.reflectionToString(baseB, null, false, ReflectionTestFixtureA.class));
|
||||
assertEquals(baseStr + "[b=b]", ToStringBuilder.reflectionToString(baseB, null, false, ReflectionTestFixtureB.class));
|
||||
this.validateEmptyReflectionRegistry();
|
||||
this.validateEmptyToStringStyleRegistry();
|
||||
}
|
||||
|
||||
static class ReflectionTestFixtureA {
|
||||
|
@ -394,7 +394,7 @@ public void testReflectionArrayCycle() throws Exception {
|
|||
assertEquals(
|
||||
this.toBaseString(objects) + "[{" + this.toBaseString(objects) + "}]",
|
||||
ToStringBuilder.reflectionToString(objects));
|
||||
this.validateEmptyReflectionRegistry();
|
||||
this.validateEmptyToStringStyleRegistry();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -411,7 +411,7 @@ public void testReflectionArrayCycleLevel2() throws Exception {
|
|||
assertEquals(
|
||||
this.toBaseString(objectsLevel2) + "[{{" + this.toBaseString(objectsLevel2) + "}}]",
|
||||
ToStringBuilder.reflectionToString(objectsLevel2));
|
||||
this.validateEmptyReflectionRegistry();
|
||||
this.validateEmptyToStringStyleRegistry();
|
||||
}
|
||||
|
||||
public void testReflectionArrayArrayCycle() throws Exception {
|
||||
|
@ -433,7 +433,7 @@ public void testReflectionArrayArrayCycle() throws Exception {
|
|||
+ basicToString
|
||||
+ "}}]",
|
||||
ToStringBuilder.reflectionToString(objects));
|
||||
this.validateEmptyReflectionRegistry();
|
||||
this.validateEmptyToStringStyleRegistry();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -514,9 +514,9 @@ public String toString() {
|
|||
public void testSimpleReflectionObjectCycle() throws Exception {
|
||||
SimpleReflectionTestFixture simple = new SimpleReflectionTestFixture();
|
||||
simple.o = simple;
|
||||
assertTrue(ReflectionToStringBuilder.getRegistry().isEmpty());
|
||||
assertTrue(ToStringStyle.getRegistry().isEmpty());
|
||||
assertEquals(this.toBaseString(simple) + "[o=" + this.toBaseString(simple) + "]", simple.toString());
|
||||
this.validateEmptyReflectionRegistry();
|
||||
this.validateEmptyToStringStyleRegistry();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -526,9 +526,9 @@ public void testSimpleReflectionObjectCycle() throws Exception {
|
|||
*/
|
||||
public void testSelfInstanceVarReflectionObjectCycle() throws Exception {
|
||||
SelfInstanceVarReflectionTestFixture test = new SelfInstanceVarReflectionTestFixture();
|
||||
assertTrue(ReflectionToStringBuilder.getRegistry().isEmpty());
|
||||
assertTrue(ToStringStyle.getRegistry().isEmpty());
|
||||
assertEquals(this.toBaseString(test) + "[typeIsSelf=" + this.toBaseString(test) + "]", test.toString());
|
||||
this.validateEmptyReflectionRegistry();
|
||||
this.validateEmptyToStringStyleRegistry();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -539,9 +539,9 @@ public void testSelfInstanceVarReflectionObjectCycle() throws Exception {
|
|||
*/
|
||||
public void testSelfInstanceTwoVarsReflectionObjectCycle() throws Exception {
|
||||
SelfInstanceTwoVarsReflectionTestFixture test = new SelfInstanceTwoVarsReflectionTestFixture();
|
||||
assertTrue(ReflectionToStringBuilder.getRegistry().isEmpty());
|
||||
assertTrue(ToStringStyle.getRegistry().isEmpty());
|
||||
assertEquals(this.toBaseString(test) + "[typeIsSelf=" + this.toBaseString(test) + ",otherType=" + test.getOtherType().toString() + "]", test.toString());
|
||||
this.validateEmptyReflectionRegistry();
|
||||
this.validateEmptyToStringStyleRegistry();
|
||||
}
|
||||
|
||||
|
||||
|
@ -558,7 +558,7 @@ public void testReflectionObjectCycle() throws Exception {
|
|||
assertEquals(
|
||||
this.toBaseString(a) + "[b=" + this.toBaseString(b) + "[a=" + this.toBaseString(a) + "]]",
|
||||
a.toString());
|
||||
this.validateEmptyReflectionRegistry();
|
||||
this.validateEmptyToStringStyleRegistry();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -586,11 +586,15 @@ public void testReflectionArrayAndObjectCycle() throws Exception {
|
|||
+ this.toBaseString(simple)
|
||||
+ "}]",
|
||||
ToStringBuilder.reflectionToString(simple));
|
||||
this.validateEmptyReflectionRegistry();
|
||||
this.validateEmptyToStringStyleRegistry();
|
||||
}
|
||||
|
||||
void validateEmptyReflectionRegistry() {
|
||||
assertTrue(ReflectionToStringBuilder.getRegistry().isEmpty());
|
||||
void validateEmptyToStringStyleRegistry() {
|
||||
if (!ToStringStyle.getRegistry().isEmpty()) {
|
||||
System.out.println(ToStringStyle.getRegistry());
|
||||
}
|
||||
|
||||
assertTrue(ToStringStyle.getRegistry().isEmpty());
|
||||
}
|
||||
// End: Reflection cycle tests
|
||||
|
||||
|
@ -831,6 +835,25 @@ public void testBooleanArrayArray() {
|
|||
assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).append((Object) array).toString());
|
||||
}
|
||||
|
||||
public void testObjectCycle() {
|
||||
ObjectCycle a = new ObjectCycle();
|
||||
ObjectCycle b = new ObjectCycle();
|
||||
a.obj = b;
|
||||
b.obj = a;
|
||||
|
||||
String expected = toBaseString(a) + "[" + toBaseString(b) + "[" + toBaseString(a) + "]]";
|
||||
assertEquals(expected, a.toString());
|
||||
validateEmptyToStringStyleRegistry();
|
||||
}
|
||||
|
||||
static class ObjectCycle {
|
||||
Object obj;
|
||||
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this).append(obj).toString();
|
||||
}
|
||||
}
|
||||
|
||||
public void testSimpleReflectionStatics() {
|
||||
SimpleReflectionStaticFieldsFixture instance1 = new SimpleReflectionStaticFieldsFixture();
|
||||
assertEquals(
|
||||
|
@ -948,25 +971,4 @@ public void testReflectionNull() {
|
|||
assertEquals("<null>", ReflectionToStringBuilder.toString(null));
|
||||
}
|
||||
|
||||
/* Unit test for #36061
|
||||
public void testObjectCycle() {
|
||||
ObjectCycle a = new ObjectCycle();
|
||||
ObjectCycle b = new ObjectCycle();
|
||||
a.obj = b;
|
||||
b.obj = a;
|
||||
|
||||
String expected = toBaseString(a) + "[" + toBaseString(b) + "[" + toBaseString(a) + "]]";
|
||||
assertEquals(expected, a.toString());
|
||||
validateEmptyReflectionRegistry();
|
||||
}
|
||||
|
||||
static class ObjectCycle {
|
||||
Object obj;
|
||||
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this).append(obj).toString();
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue