diff --git a/src/java/org/apache/commons/lang/builder/ReflectionToStringBuilder.java b/src/java/org/apache/commons/lang/builder/ReflectionToStringBuilder.java index 52e907303..07ba23428 100644 --- a/src/java/org/apache/commons/lang/builder/ReflectionToStringBuilder.java +++ b/src/java/org/apache/commons/lang/builder/ReflectionToStringBuilder.java @@ -13,11 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.apache.commons.lang.builder; import java.lang.reflect.AccessibleObject; import java.lang.reflect.Field; import java.lang.reflect.Modifier; +import java.util.Arrays; import java.util.HashSet; import java.util.Set; @@ -29,11 +31,10 @@ import org.apache.commons.lang.ClassUtils; *
* *- * This class uses reflection to determine the fields to append. Because these - * fields are usually private, the class uses - * {@link java.lang.reflect.AccessibleObject#setAccessible(java.lang.reflect.AccessibleObject[], boolean)} - * to change the visibility of the fields. This will fail under a security - * manager, unless the appropriate permissions are set up correctly. + * This class uses reflection to determine the fields to append. Because these fields are usually private, the class + * uses {@link java.lang.reflect.AccessibleObject#setAccessible(java.lang.reflect.AccessibleObject[], boolean)} to + * change the visibility of the fields. This will fail under a security manager, unless the appropriate permissions are + * set up correctly. *
* *@@ -64,8 +65,8 @@ import org.apache.commons.lang.ClassUtils; * *
*
- * For example, this method does not include the password
- * field in the returned String
:
+ * For example, this method does not include the password
field in the returned
+ * String
:
*
@@ -80,22 +81,21 @@ import org.apache.commons.lang.ClassUtils; * * *- * The exact format of the
* * @author Gary Gregory * @author Stephen Colebourne * @author Pete Gieser * @since 2.0 - * @version $Id: ReflectionToStringBuilder.java,v 1.15 2003/12/02 19:11:58 - * ggregory Exp $ + * @version $Id$ */ public class ReflectionToStringBuilder extends ToStringBuilder { /** *toString
is determined by the - * {@link ToStringStyle} passed into the constructor. + * The exact format of thetoString
is determined by the {@link ToStringStyle} passed into the + * constructor. *- * A registry of objects used by
*/ private static ThreadLocal registry = new ThreadLocal() { @@ -108,8 +108,8 @@ public class ReflectionToStringBuilder extends ToStringBuilder { /** *reflectionToString
methods - * to detect cyclical object references and avoid infinite loops. + * A registry of objects used byreflectionToString
methods to detect cyclical object references and + * avoid infinite loops. *- * Returns the registry of objects being traversed by the
* * @return Set the registry of objects being traversed @@ -120,14 +120,13 @@ public class ReflectionToStringBuilder extends ToStringBuilder { /** *reflectionToString
- * methods in the current thread. + * Returns the registry of objects being traversed by thereflectionToString
methods in the current + * thread. *- * Returns
* * @param value - * The object to lookup in the registry. - * @return booleantrue
if the registry contains the given object. - * Used by the reflection methods to avoid infinite loops. + * Returnstrue
if the registry contains the given object. Used by the reflection methods to avoid + * infinite loops. *true
if the registry contains the given - * object. + * The object to lookup in the registry. + * @return booleantrue
if the registry contains the given object. */ static boolean isRegistered(Object value) { return getRegistry().contains(value); @@ -135,12 +134,11 @@ public class ReflectionToStringBuilder extends ToStringBuilder { /** *- * Registers the given object. Used by the reflection methods to avoid - * infinite loops. + * Registers the given object. Used by the reflection methods to avoid infinite loops. *
* * @param value - * The object to register. + * The object to register. */ static void register(Object value) { getRegistry().add(value); @@ -152,22 +150,21 @@ public class ReflectionToStringBuilder extends ToStringBuilder { * * *- * It uses
* *AccessibleObject.setAccessible
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. + * It usesAccessibleObject.setAccessible
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. *- * Transient members will be not be included, as they are likely derived. - * Static fields will not be included. Superclass fields will be appended. + * Transient members will be not be included, as they are likely derived. Static fields will not be included. + * Superclass fields will be appended. *
* * @param object - * the Object to be output + * the Object to be output * @return the String result * @throws IllegalArgumentException - * if the Object isnull
+ * if the Object isnull
*/ public static String toString(Object object) { return toString(object, null, false, false, null); @@ -179,30 +176,27 @@ public class ReflectionToStringBuilder extends ToStringBuilder { * * *- * It uses
* *AccessibleObject.setAccessible
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. + * It usesAccessibleObject.setAccessible
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. *- * Transient members will be not be included, as they are likely derived. - * Static fields will not be included. Superclass fields will be appended. + * Transient members will be not be included, as they are likely derived. Static fields will not be included. + * Superclass fields will be appended. *
* *- * If the style is
* * @param object - * the Object to be output + * the Object to be output * @param style - * the style of thenull
, the defaultToStringStyle
- * is used. + * If the style isnull
, the defaultToStringStyle
is used. *toString
to create, may be - *null
+ * the style of thetoString
to create, may benull
* @return the String result * @throws IllegalArgumentException - * if the Object orToStringStyle
isnull
+ * if the Object orToStringStyle
isnull
*/ public static String toString(Object object, ToStringStyle style) { return toString(object, style, false, false, null); @@ -214,16 +208,14 @@ public class ReflectionToStringBuilder extends ToStringBuilder { * * *- * It uses
* *AccessibleObject.setAccessible
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. + * It usesAccessibleObject.setAccessible
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. *- * If the
* *outputTransients
istrue
, - * transient members will be output, otherwise they are ignored, as they - * are likely derived fields, and not part of the value of the Object. + * If theoutputTransients
istrue
, transient members will be output, otherwise they + * are ignored, as they are likely derived fields, and not part of the value of the Object. *@@ -231,20 +223,18 @@ public class ReflectionToStringBuilder extends ToStringBuilder { *
* *- * If the style is
* * @param object - * the Object to be output + * the Object to be output * @param style - * the style of thenull
, the defaultToStringStyle
- * is used. + * If the style isnull
, the defaultToStringStyle
is used. *toString
to create, may be - *null
+ * the style of thetoString
to create, may benull
* @param outputTransients - * whether to include transient fields + * whether to include transient fields * @return the String result * @throws IllegalArgumentException - * if the Object isnull
+ * if the Object isnull
*/ public static String toString(Object object, ToStringStyle style, boolean outputTransients) { return toString(object, style, outputTransients, false, null); @@ -256,21 +246,19 @@ public class ReflectionToStringBuilder extends ToStringBuilder { * * *- * It uses
* *AccessibleObject.setAccessible
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. + * It usesAccessibleObject.setAccessible
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. *- * If the
* *outputTransients
istrue
, - * transient fields will be output, otherwise they are ignored, as they are - * likely derived fields, and not part of the value of the Object. + * If theoutputTransients
istrue
, transient fields will be output, otherwise they + * are ignored, as they are likely derived fields, and not part of the value of the Object. *- * If the
* *outputStatics
istrue
, static - * fields will be output, otherwise they are ignored. + * If theoutputStatics
istrue
, static fields will be output, otherwise they are + * ignored. *@@ -278,22 +266,20 @@ public class ReflectionToStringBuilder extends ToStringBuilder { *
* *- * If the style is
* * @param object - * the Object to be output + * the Object to be output * @param style - * the style of thenull
, the defaultToStringStyle
- * is used. + * If the style isnull
, the defaultToStringStyle
is used. *toString
to create, may be - *null
+ * the style of thetoString
to create, may benull
* @param outputTransients - * whether to include transient fields + * whether to include transient fields * @param outputStatics - * whether to include transient fields + * whether to include transient fields * @return the String result * @throws IllegalArgumentException - * if the Object isnull
+ * if the Object isnull
* @since 2.1 */ public static String toString(Object object, ToStringStyle style, boolean outputTransients, boolean outputStatics) { @@ -306,47 +292,43 @@ public class ReflectionToStringBuilder extends ToStringBuilder { * * *- * It uses
* *AccessibleObject.setAccessible
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. + * It usesAccessibleObject.setAccessible
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. *- * If the
* *outputTransients
istrue
, - * transient fields will be output, otherwise they are ignored, as they are - * likely derived fields, and not part of the value of the Object. + * If theoutputTransients
istrue
, transient fields will be output, otherwise they + * are ignored, as they are likely derived fields, and not part of the value of the Object. *- * If the
* *outputStatics
istrue
, static - * fields will be output, otherwise they are ignored. + * If theoutputStatics
istrue
, static fields will be output, otherwise they are + * ignored. *- * Superclass fields will be appended up to and including the specified - * superclass. A null superclass is treated as
* *java.lang.Object
. + * Superclass fields will be appended up to and including the specified superclass. A null superclass is treated as + *java.lang.Object
. *- * If the style is
* * @param object - * the Object to be output + * the Object to be output * @param style - * the style of thenull
, the defaultToStringStyle
- * is used. + * If the style isnull
, the defaultToStringStyle
is used. *toString
to create, may be - *null
+ * the style of thetoString
to create, may benull
* @param outputTransients - * whether to include transient fields + * whether to include transient fields * @param outputStatics - * whether to include static fields + * whether to include static fields * @param reflectUpToClass - * the superclass to reflect up to (inclusive), may benull
+ * the superclass to reflect up to (inclusive), may benull
* @return the String result * @throws IllegalArgumentException - * if the Object isnull
+ * if the Object isnull
* @since 2.1 */ public static String toString(Object object, ToStringStyle style, boolean outputTransients, boolean outputStatics, @@ -361,51 +343,70 @@ public class ReflectionToStringBuilder extends ToStringBuilder { * * *- * It uses
* *AccessibleObject.setAccessible
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. + * It usesAccessibleObject.setAccessible
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. *- * If the
* *outputTransients
istrue
, - * transient members will be output, otherwise they are ignored, as they - * are likely derived fields, and not part of the value of the Object. + * If theoutputTransients
istrue
, transient members will be output, otherwise they + * are ignored, as they are likely derived fields, and not part of the value of the Object. *- * Static fields will not be included. Superclass fields will be appended - * up to and including the specified superclass. A null superclass is - * treated as
* *java.lang.Object
. + * Static fields will not be included. Superclass fields will be appended up to and including the specified + * superclass. A null superclass is treated asjava.lang.Object
. *- * If the style is
* - * @deprecated Use - * {@link #toString(Object,ToStringStyle,boolean,boolean,Class)} + * @deprecated Use {@link #toString(Object,ToStringStyle,boolean,boolean,Class)} * * @param object - * the Object to be output + * the Object to be output * @param style - * the style of thenull
, the defaultToStringStyle
- * is used. + * If the style isnull
, the defaultToStringStyle
is used. *toString
to create, may be - *null
+ * the style of thetoString
to create, may benull
* @param outputTransients - * whether to include transient fields + * whether to include transient fields * @param reflectUpToClass - * the superclass to reflect up to (inclusive), may benull
+ * the superclass to reflect up to (inclusive), may benull
* @return the String result * @throws IllegalArgumentException - * if the Object isnull
+ * if the Object isnull
* @since 2.0 */ - public static String toString(Object object, ToStringStyle style, boolean outputTransients, - Class reflectUpToClass) { + public static String toString(Object object, ToStringStyle style, boolean outputTransients, Class reflectUpToClass) { return new ReflectionToStringBuilder(object, style, null, reflectUpToClass, outputTransients).toString(); } + /** + * Builds a String for a toString method excluding the given field name. + * + * @param object + * The object to "toString". + * @param excludeFieldName + * The field name to exclude + * @return The toString value. + */ + public static String toStringExclude(Object object, final String excludeFieldName) { + return toStringExclude(object, new String[]{excludeFieldName}); + } + + /** + * Builds a String for a toString method excluding the given field name. + * + * @param object + * The object to "toString". + * @param excludeFieldNames + * The field names to exclude + * @return The toString value. + */ + public static String toStringExclude(Object object, String[] excludeFieldNames) { + return new ReflectionToStringBuilder(object).setExcludeFieldNames(excludeFieldNames).toString(); + } + /** ** Unregisters the given object. @@ -416,7 +417,7 @@ public class ReflectionToStringBuilder extends ToStringBuilder { *
* * @param value - * The object to unregister. + * The object to unregister. */ static void unregister(Object value) { getRegistry().remove(value); @@ -432,6 +433,11 @@ public class ReflectionToStringBuilder extends ToStringBuilder { */ private boolean appendTransients = false; + /** + * Which field names to exclude from output. Intended for fields like"password"
. + */ + private String[] excludeFieldNames; + /** * The last super class to stop appending fields for. */ @@ -447,10 +453,9 @@ public class ReflectionToStringBuilder extends ToStringBuilder { * * * @param object - * the Object to build atoString
for, must not - * benull
+ * the Object to build atoString
for, must not benull
* @throws IllegalArgumentException - * if the Object passed in isnull
+ * if the Object passed in isnull
*/ public ReflectionToStringBuilder(Object object) { super(object); @@ -466,13 +471,11 @@ public class ReflectionToStringBuilder extends ToStringBuilder { * * * @param object - * the Object to build atoString
for, must not - * benull
+ * the Object to build atoString
for, must not benull
* @param style - * the style of thetoString
to create, may be - *null
+ * the style of thetoString
to create, may benull
* @throws IllegalArgumentException - * if the Object passed in isnull
+ * if the Object passed in isnull
*/ public ReflectionToStringBuilder(Object object, ToStringStyle style) { super(object, style); @@ -492,14 +495,13 @@ public class ReflectionToStringBuilder extends ToStringBuilder { * * * @param object - * the Object to build atoString
for + * the Object to build atoString
for * @param style - * the style of thetoString
to create, may be - *null
+ * the style of thetoString
to create, may benull
* @param buffer - * theStringBuffer
to populate, may benull
+ * theStringBuffer
to populate, may benull
* @throws IllegalArgumentException - * if the Object passed in isnull
+ * if the Object passed in isnull
*/ public ReflectionToStringBuilder(Object object, ToStringStyle style, StringBuffer buffer) { super(object, style, buffer); @@ -508,20 +510,18 @@ public class ReflectionToStringBuilder extends ToStringBuilder { /** * Constructor. * - * @deprecated Use - * {@link #ReflectionToStringBuilder(Object,ToStringStyle,StringBuffer,Class,boolean,boolean)}. + * @deprecated Use {@link #ReflectionToStringBuilder(Object,ToStringStyle,StringBuffer,Class,boolean,boolean)}. * * @param object - * the Object to build atoString
for + * the Object to build atoString
for * @param style - * the style of thetoString
to create, may be - *null
+ * the style of thetoString
to create, may benull
* @param buffer - * theStringBuffer
to populate, may benull
+ * theStringBuffer
to populate, may benull
* @param reflectUpToClass - * the superclass to reflect up to (inclusive), may benull
+ * the superclass to reflect up to (inclusive), may benull
* @param outputTransients - * whether to include transient fields + * whether to include transient fields */ public ReflectionToStringBuilder(Object object, ToStringStyle style, StringBuffer buffer, Class reflectUpToClass, boolean outputTransients) { @@ -534,18 +534,17 @@ public class ReflectionToStringBuilder extends ToStringBuilder { * Constructor. * * @param object - * the Object to build atoString
for + * the Object to build atoString
for * @param style - * the style of thetoString
to create, may be - *null
+ * the style of thetoString
to create, may benull
* @param buffer - * theStringBuffer
to populate, may benull
+ * theStringBuffer
to populate, may benull
* @param reflectUpToClass - * the superclass to reflect up to (inclusive), may benull
+ * the superclass to reflect up to (inclusive), may benull
* @param outputTransients - * whether to include transient fields + * whether to include transient fields * @param outputStatics - * whether to include static fields + * whether to include static fields * @since 2.1 */ public ReflectionToStringBuilder(Object object, ToStringStyle style, StringBuffer buffer, Class reflectUpToClass, @@ -559,15 +558,13 @@ public class ReflectionToStringBuilder extends ToStringBuilder { /** * Returns whether or not to append the givenField
. *
true
.
- * true
.
+ * true
.
+ * true
.
* Field
.
*/
protected boolean accept(Field field) {
@@ -576,11 +573,16 @@ public class ReflectionToStringBuilder extends ToStringBuilder {
return false;
}
if (Modifier.isTransient(field.getModifiers()) && !this.isAppendTransients()) {
- // transients.
+ // Reject transient fields.
return false;
}
if (Modifier.isStatic(field.getModifiers()) && !this.isAppendStatics()) {
- // transients.
+ // Rject static fields.
+ return false;
+ }
+ if (this.getExcludeFieldNames() != null
+ && Arrays.binarySearch(this.getExcludeFieldNames(), field.getName()) >= 0) {
+ // Reject fields from the getExcludeFieldNames list.
return false;
}
return true;
@@ -588,18 +590,16 @@ public class ReflectionToStringBuilder extends ToStringBuilder {
/**
* - * Appends the fields and values defined by the given object of the given - * Class. + * Appends the fields and values defined by the given object of the given Class. *
* *
- * If a cycle is detected as an object is "toString()'ed", such
- * an object is rendered as if Object.toString()
had been
- * called and not implemented by the object.
+ * If a cycle is detected as an object is "toString()'ed", such an object is rendered as if
+ * Object.toString()
had been called and not implemented by the object.
*
* Gets the last super class to stop appending fields for. @@ -676,13 +683,13 @@ public class ReflectionToStringBuilder extends ToStringBuilder { *
* * @param field - * The Field to query. + * The Field to query. * @return The Object from the given Field. * * @throws IllegalArgumentException - * see {@link java.lang.reflect.Field#get(Object)} + * see {@link java.lang.reflect.Field#get(Object)} * @throws IllegalAccessException - * see {@link java.lang.reflect.Field#get(Object)} + * see {@link java.lang.reflect.Field#get(Object)} * * @see java.lang.reflect.Field#get(Object) */ @@ -719,7 +726,7 @@ public class ReflectionToStringBuilder extends ToStringBuilder { * * * @param array - * the array to add to thetoString
+ * the array to add to the toString
* @return this
*/
public ToStringBuilder reflectionAppendArray(Object array) {
@@ -729,8 +736,7 @@ public class ReflectionToStringBuilder extends ToStringBuilder {
/**
* - * Registers this builder's source object to avoid infinite loops when - * processing circular object references. + * Registers this builder's source object to avoid infinite loops when processing circular object references. *
*/ void registerObject() { @@ -743,7 +749,7 @@ public class ReflectionToStringBuilder extends ToStringBuilder { * * * @param appendStatics - * Whether or not to append static fields. + * Whether or not to append static fields. * @since 2.1 */ public void setAppendStatics(boolean appendStatics) { @@ -756,19 +762,35 @@ public class ReflectionToStringBuilder extends ToStringBuilder { * * * @param appendTransients - * Whether or not to append transient fields. + * Whether or not to append transient fields. */ public void setAppendTransients(boolean appendTransients) { this.appendTransients = appendTransients; } + /** + * Sets the field names to exclude. + * + * @param excludeFieldNamesParam + * The excludeFieldNames to set. + * @returnthis
+ */
+ public ReflectionToStringBuilder setExcludeFieldNames(String[] excludeFieldNamesParam) {
+ if (excludeFieldNamesParam == null) {
+ this.excludeFieldNames = null;
+ }
+ this.excludeFieldNames = (String[]) excludeFieldNamesParam.clone();
+ Arrays.sort(this.excludeFieldNames);
+ return this;
+ }
+
/**
* * Sets the last super class to stop appending fields for. *
* * @param clazz - * The last super class to stop appending fields for. + * The last super class to stop appending fields for. */ public void setUpToClass(Class clazz) { this.upToClass = clazz; @@ -796,8 +818,7 @@ public class ReflectionToStringBuilder extends ToStringBuilder { /** *- * Unregisters this builder's source object to avoid infinite loops when - * processing circular object references. + * Unregisters this builder's source object to avoid infinite loops when processing circular object references. *
*/ void unregisterObject() { diff --git a/src/test/org/apache/commons/lang/builder/BuilderTestSuite.java b/src/test/org/apache/commons/lang/builder/BuilderTestSuite.java index 89a1cf5fa..6443f3902 100644 --- a/src/test/org/apache/commons/lang/builder/BuilderTestSuite.java +++ b/src/test/org/apache/commons/lang/builder/BuilderTestSuite.java @@ -47,17 +47,18 @@ public class BuilderTestSuite extends TestCase { public static Test suite() { TestSuite suite = new TestSuite(); suite.setName("Commons-Lang-Builder Tests"); - suite.addTest(CompareToBuilderTest.suite()); - suite.addTest(EqualsBuilderTest.suite()); - suite.addTest(HashCodeBuilderTest.suite()); - suite.addTest(HashCodeBuilderAndEqualsBuilderTest.suite()); - suite.addTest(ToStringBuilderTest.suite()); - suite.addTest(DefaultToStringStyleTest.suite()); - suite.addTest(NoFieldNamesToStringStyleTest.suite()); - suite.addTest(MultiLineToStringStyleTest.suite()); - suite.addTest(SimpleToStringStyleTest.suite()); - suite.addTest(StandardToStringStyleTest.suite()); - suite.addTest(ToStringStyleTest.suite()); + suite.addTestSuite(CompareToBuilderTest.class); + suite.addTestSuite(EqualsBuilderTest.class); + suite.addTestSuite(HashCodeBuilderTest.class); + suite.addTestSuite(HashCodeBuilderAndEqualsBuilderTest.class); + suite.addTestSuite(ToStringBuilderTest.class); + suite.addTestSuite(DefaultToStringStyleTest.class); + suite.addTestSuite(NoFieldNamesToStringStyleTest.class); + suite.addTestSuite(MultiLineToStringStyleTest.class); + suite.addTestSuite(ReflectionToStringBuilderExcludeTest.class); + suite.addTestSuite(SimpleToStringStyleTest.class); + suite.addTestSuite(StandardToStringStyleTest.class); + suite.addTestSuite(ToStringStyleTest.class); return suite; } }