LANG-1167: Added isExcludeNullValues to ReflectionToStringBuilder and test
This commit is contained in:
parent
40b8ecd3fa
commit
661d16d190
|
@ -300,6 +300,64 @@ public class ReflectionToStringBuilder extends ToStringBuilder {
|
|||
return new ReflectionToStringBuilder(object, style, null, reflectUpToClass, outputTransients, outputStatics)
|
||||
.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Builds a <code>toString</code> value through reflection.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* It uses <code>AccessibleObject.setAccessible</code> to gain access to private fields. This means that it will
|
||||
* throw a security exception if run under a security manager, if the permissions are not set up correctly. It is
|
||||
* also not as efficient as testing explicitly.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* If the <code>outputTransients</code> is <code>true</code>, transient fields will be output, otherwise they
|
||||
* are ignored, as they are likely derived fields, and not part of the value of the Object.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* If the <code>outputStatics</code> is <code>true</code>, static fields will be output, otherwise they are
|
||||
* ignored.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Superclass fields will be appended up to and including the specified superclass. A null superclass is treated as
|
||||
* <code>java.lang.Object</code>.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* If the style is <code>null</code>, the default <code>ToStringStyle</code> is used.
|
||||
* </p>
|
||||
*
|
||||
* @param <T>
|
||||
* the type of the object
|
||||
* @param object
|
||||
* the Object to be output
|
||||
* @param style
|
||||
* the style of the <code>toString</code> to create, may be <code>null</code>
|
||||
* @param outputTransients
|
||||
* whether to include transient fields
|
||||
* @param outputStatics
|
||||
* whether to include static fields
|
||||
* @param excludeNulls
|
||||
* whether to exclude fields whose values are null
|
||||
* @param reflectUpToClass
|
||||
* the superclass to reflect up to (inclusive), may be <code>null</code>
|
||||
* @return the String result
|
||||
* @throws IllegalArgumentException
|
||||
* if the Object is <code>null</code>
|
||||
*
|
||||
* @see ToStringExclude
|
||||
* @since 2.1
|
||||
*/
|
||||
public static <T> String toString(
|
||||
final T object, final ToStringStyle style, final boolean outputTransients,
|
||||
final boolean outputStatics, boolean excludeNulls, final Class<? super T> reflectUpToClass) {
|
||||
return new ReflectionToStringBuilder(object, style, null, reflectUpToClass, outputTransients, outputStatics, excludeNulls)
|
||||
.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a String for a toString method excluding the given field names.
|
||||
|
@ -379,6 +437,11 @@ public class ReflectionToStringBuilder extends ToStringBuilder {
|
|||
* Whether or not to append transient fields.
|
||||
*/
|
||||
private boolean appendTransients = false;
|
||||
|
||||
/**
|
||||
* Whether or not to append fields that are null.
|
||||
*/
|
||||
private boolean excludeNullValues;
|
||||
|
||||
/**
|
||||
* Which field names to exclude from output. Intended for fields like <code>"password"</code>.
|
||||
|
@ -483,6 +546,38 @@ public class ReflectionToStringBuilder extends ToStringBuilder {
|
|||
this.setAppendTransients(outputTransients);
|
||||
this.setAppendStatics(outputStatics);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param <T>
|
||||
* the type of the object
|
||||
* @param object
|
||||
* the Object to build a <code>toString</code> for
|
||||
* @param style
|
||||
* the style of the <code>toString</code> to create, may be <code>null</code>
|
||||
* @param buffer
|
||||
* the <code>StringBuffer</code> to populate, may be <code>null</code>
|
||||
* @param reflectUpToClass
|
||||
* the superclass to reflect up to (inclusive), may be <code>null</code>
|
||||
* @param outputTransients
|
||||
* whether to include transient fields
|
||||
* @param outputStatics
|
||||
* whether to include static fields
|
||||
* @param excludeNullValues
|
||||
* whether to exclude fields who value is null
|
||||
* @since 2.1
|
||||
*/
|
||||
public <T> ReflectionToStringBuilder(
|
||||
final T object, final ToStringStyle style, final StringBuffer buffer,
|
||||
final Class<? super T> reflectUpToClass, final boolean outputTransients, final boolean outputStatics,
|
||||
final boolean excludeNullValues) {
|
||||
super(checkNotNull(object), style, buffer);
|
||||
this.setUpToClass(reflectUpToClass);
|
||||
this.setAppendTransients(outputTransients);
|
||||
this.setAppendStatics(outputStatics);
|
||||
this.setExcludeNullValues(excludeNullValues);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not to append the given <code>Field</code>.
|
||||
|
@ -547,7 +642,9 @@ public class ReflectionToStringBuilder extends ToStringBuilder {
|
|||
// Warning: Field.get(Object) creates wrappers objects
|
||||
// for primitive types.
|
||||
final Object fieldValue = this.getValue(field);
|
||||
this.append(fieldName, fieldValue);
|
||||
if(!excludeNullValues || fieldValue != null){
|
||||
this.append(fieldName, fieldValue);
|
||||
}
|
||||
} catch (final IllegalAccessException ex) {
|
||||
//this can't happen. Would get a Security exception
|
||||
// instead
|
||||
|
@ -619,6 +716,17 @@ public class ReflectionToStringBuilder extends ToStringBuilder {
|
|||
public boolean isAppendTransients() {
|
||||
return this.appendTransients;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Gets whether or not to append fields whose values are null.
|
||||
* </p>
|
||||
*
|
||||
* @return Whether or not to append fields whose values are null.
|
||||
*/
|
||||
public boolean isExcludeNullValues() {
|
||||
return this.excludeNullValues;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
|
@ -658,6 +766,18 @@ public class ReflectionToStringBuilder extends ToStringBuilder {
|
|||
public void setAppendTransients(final boolean appendTransients) {
|
||||
this.appendTransients = appendTransients;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Sets whether or not to append fields whose values are null.
|
||||
* </p>
|
||||
*
|
||||
* @param excludeNullValues
|
||||
* Whether or not to append fields whose values are null.
|
||||
*/
|
||||
public void setExcludeNullValues(final boolean excludeNullValues) {
|
||||
this.excludeNullValues = excludeNullValues;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the field names to exclude.
|
||||
|
|
|
@ -0,0 +1,99 @@
|
|||
package org.apache.commons.lang3.builder;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class ReflectionToStringBuilderExcludeNullValuesTest {
|
||||
|
||||
class TestFixture{
|
||||
private Integer testIntegerField;
|
||||
private String testStringField;
|
||||
|
||||
public TestFixture(Integer a, String b){
|
||||
this.testIntegerField = a;
|
||||
this.testStringField = b;
|
||||
}
|
||||
}
|
||||
|
||||
private static final String INTEGER_FIELD_NAME = "testIntegerField";
|
||||
private static final String STRING_FIELD_NAME = "testStringField";
|
||||
private final TestFixture BOTH_NON_NULL = new TestFixture(0, "str");
|
||||
private final TestFixture FIRST_NULL = new TestFixture(null, "str");
|
||||
private final TestFixture SECOND_NULL = new TestFixture(0, null);
|
||||
private final TestFixture BOTH_NULL = new TestFixture(null, null);
|
||||
|
||||
@Test
|
||||
public void test_NonExclude(){
|
||||
//normal case=
|
||||
String toString = ReflectionToStringBuilder.toString(BOTH_NON_NULL, null, false, false, false, null);
|
||||
assertTrue(toString.contains(INTEGER_FIELD_NAME));
|
||||
assertTrue(toString.contains(STRING_FIELD_NAME));
|
||||
|
||||
//make one null
|
||||
toString = ReflectionToStringBuilder.toString(FIRST_NULL, null, false, false, false, null);
|
||||
assertTrue(toString.contains(INTEGER_FIELD_NAME));
|
||||
assertTrue(toString.contains(STRING_FIELD_NAME));
|
||||
|
||||
//other one null
|
||||
toString = ReflectionToStringBuilder.toString(SECOND_NULL, null, false, false, false, null);
|
||||
assertTrue(toString.contains(INTEGER_FIELD_NAME));
|
||||
assertTrue(toString.contains(STRING_FIELD_NAME));
|
||||
|
||||
//make the both null
|
||||
toString = ReflectionToStringBuilder.toString(BOTH_NULL, null, false, false, false, null);
|
||||
assertTrue(toString.contains(INTEGER_FIELD_NAME));
|
||||
assertTrue(toString.contains(STRING_FIELD_NAME));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_excludeNull(){
|
||||
|
||||
//test normal case
|
||||
String toString = ReflectionToStringBuilder.toString(BOTH_NON_NULL, null, false, false, true, null);
|
||||
assertTrue(toString.contains(INTEGER_FIELD_NAME));
|
||||
assertTrue(toString.contains(STRING_FIELD_NAME));
|
||||
|
||||
//make one null
|
||||
toString = ReflectionToStringBuilder.toString(FIRST_NULL, null, false, false, true, null);
|
||||
assertFalse(toString.contains(INTEGER_FIELD_NAME));
|
||||
assertTrue(toString.contains(STRING_FIELD_NAME));
|
||||
|
||||
//other one null
|
||||
toString = ReflectionToStringBuilder.toString(SECOND_NULL, null, false, false, true, null);
|
||||
assertTrue(toString.contains(INTEGER_FIELD_NAME));
|
||||
assertFalse(toString.contains(STRING_FIELD_NAME));
|
||||
|
||||
//both null
|
||||
toString = ReflectionToStringBuilder.toString(BOTH_NULL, null, false, false, true, null);
|
||||
assertFalse(toString.contains(INTEGER_FIELD_NAME));
|
||||
assertFalse(toString.contains(STRING_FIELD_NAME));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_ConstructorOption(){
|
||||
ReflectionToStringBuilder builder = new ReflectionToStringBuilder(BOTH_NON_NULL, null, null, null, false, false, false);
|
||||
builder.setExcludeNullValues(true);
|
||||
assertTrue(builder.isExcludeNullValues());
|
||||
|
||||
String toString = builder.toString();
|
||||
assertTrue(toString.contains(INTEGER_FIELD_NAME));
|
||||
assertTrue(toString.contains(STRING_FIELD_NAME));
|
||||
|
||||
builder = new ReflectionToStringBuilder(FIRST_NULL, null, null, null, false, false, true);
|
||||
toString = builder.toString();
|
||||
assertFalse(toString.contains(INTEGER_FIELD_NAME));
|
||||
assertTrue(toString.contains(STRING_FIELD_NAME));
|
||||
|
||||
builder = new ReflectionToStringBuilder(SECOND_NULL, null, null, null, false, false, true);
|
||||
toString = builder.toString();
|
||||
assertTrue(toString.contains(INTEGER_FIELD_NAME));
|
||||
assertFalse(toString.contains(STRING_FIELD_NAME));
|
||||
|
||||
builder = new ReflectionToStringBuilder(BOTH_NULL, null, null, null, false, false, true);
|
||||
toString = builder.toString();
|
||||
assertFalse(toString.contains(INTEGER_FIELD_NAME));
|
||||
assertFalse(toString.contains(STRING_FIELD_NAME));
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue