    001/*
    002 * Licensed to the Apache Software Foundation (ASF) under one or more
    003 * contributor license agreements.  See the NOTICE file distributed with
    004 * this work for additional information regarding copyright ownership.
    005 * The ASF licenses this file to You under the Apache License, Version 2.0
    006 * (the "License"); you may not use this file except in compliance with
    007 * the License.  You may obtain a copy of the License at
    008 *
    009 *      http://www.apache.org/licenses/LICENSE-2.0
    010 *
    011 * Unless required by applicable law or agreed to in writing, software
    012 * distributed under the License is distributed on an "AS IS" BASIS,
    013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    014 * See the License for the specific language governing permissions and
    015 * limitations under the License.
    016 */
    017
    018package org.apache.commons.lang3.builder;
    019
    020import java.lang.reflect.AccessibleObject;
    021import java.lang.reflect.Field;
    022import java.lang.reflect.Modifier;
    023import java.util.ArrayList;
    024import java.util.Arrays;
    025import java.util.Collection;
    026import java.util.List;
    027
    028import org.apache.commons.lang3.ArrayUtils;
    029import org.apache.commons.lang3.ClassUtils;
    030import org.apache.commons.lang3.Validate;
    031
    032/**
    033 * <p>
    034 * Assists in implementing {@link Object#toString()} methods using reflection.
    035 * </p>
    036 * <p>
    037 * This class uses reflection to determine the fields to append. Because these fields are usually private, the class
    038 * uses {@link java.lang.reflect.AccessibleObject#setAccessible(java.lang.reflect.AccessibleObject[], boolean)} to
    039 * change the visibility of the fields. This will fail under a security manager, unless the appropriate permissions are
    040 * set up correctly.
    041 * </p>
    042 * <p>
    043 * Using reflection to access (private) fields circumvents any synchronization protection guarding access to these
    044 * fields. If a toString method cannot safely read a field, you should exclude it from the toString method, or use
    045 * synchronization consistent with the class' lock management around the invocation of the method. Take special care to
    046 * exclude non-thread-safe collection classes, because these classes may throw ConcurrentModificationException if
    047 * modified while the toString method is executing.
    048 * </p>
    049 * <p>
    050 * A typical invocation for this method would look like:
    051 * </p>
    052 * <pre>
    053 * public String toString() {
    054 *     return ReflectionToStringBuilder.toString(this);
    055 * }
    056 * </pre>
    057 * <p>
    058 * You can also use the builder to debug 3rd party objects:
    059 * </p>
    060 * <pre>
    061 * System.out.println(&quot;An object: &quot; + ReflectionToStringBuilder.toString(anObject));
    062 * </pre>
    063 * <p>
    064 * A subclass can control field output by overriding the methods:
    065 * </p>
    066 * <ul>
    067 * <li>{@link #accept(java.lang.reflect.Field)}</li>
    068 * <li>{@link #getValue(java.lang.reflect.Field)}</li>
    069 * </ul>
    070 * <p>
    071 * For example, this method does <i>not</i> include the <code>password</code> field in the returned <code>String</code>:
    072 * </p>
    073 * <pre>
    074 * public String toString() {
    075 *     return (new ReflectionToStringBuilder(this) {
    076 *         protected boolean accept(Field f) {
    077 *             return super.accept(f) &amp;&amp; !f.getName().equals(&quot;password&quot;);
    078 *         }
    079 *     }).toString();
    080 * }
    081 * </pre>
    082 * <p>
    083 * Alternatively the {@link ToStringExclude} annotation can be used to exclude fields from being incorporated in the
    084 * result.
    085 * </p>
    086 * <p>
    087 * It is also possible to use the {@link ToStringSummary} annotation to output the summary information instead of the
    088 * detailed information of a field.
    089 * </p>
    090 * <p>
    091 * The exact format of the <code>toString</code> is determined by the {@link ToStringStyle} passed into the constructor.
    092 * </p>
    093 *
    094 * <p>
    095 * <b>Note:</b> the default {@link ToStringStyle} will only do a "shallow" formatting, i.e. composed objects are not
    096 * further traversed. To get "deep" formatting, use an instance of {@link RecursiveToStringStyle}.
    097 * </p>
    098 *
    099 * @since 2.0
    100 */
    101public class ReflectionToStringBuilder extends ToStringBuilder {
    102
    103    /**
    104     * <p>
    105     * Builds a <code>toString</code> value using the default <code>ToStringStyle</code> through reflection.
    106     * </p>
    107     *
    108     * <p>
    109     * It uses <code>AccessibleObject.setAccessible</code> to gain access to private fields. This means that it will
    110     * throw a security exception if run under a security manager, if the permissions are not set up correctly. It is
    111     * also not as efficient as testing explicitly.
    112     * </p>
    113     *
    114     * <p>
    115     * Transient members will be not be included, as they are likely derived. Static fields will not be included.
    116     * Superclass fields will be appended.
    117     * </p>
    118     *
    119     * @param object
    120     *            the Object to be output
    121     * @return the String result
    122     * @throws IllegalArgumentException
    123     *             if the Object is <code>null</code>
    124     *
    125     * @see ToStringExclude
    126     * @see ToStringSummary
    127     */
    128    public static String toString(final Object object) {
    129        return toString(object, null, false, false, null);
    130    }
    131
    132    /**
    133     * <p>
    134     * Builds a <code>toString</code> value through reflection.
    135     * </p>
    136     *
    137     * <p>
    138     * It uses <code>AccessibleObject.setAccessible</code> to gain access to private fields. This means that it will
    139     * throw a security exception if run under a security manager, if the permissions are not set up correctly. It is
    140     * also not as efficient as testing explicitly.
    141     * </p>
    142     *
    143     * <p>
    144     * Transient members will be not be included, as they are likely derived. Static fields will not be included.
    145     * Superclass fields will be appended.
    146     * </p>
    147     *
    148     * <p>
    149     * If the style is <code>null</code>, the default <code>ToStringStyle</code> is used.
    150     * </p>
    151     *
    152     * @param object
    153     *            the Object to be output
    154     * @param style
    155     *            the style of the <code>toString</code> to create, may be <code>null</code>
    156     * @return the String result
    157     * @throws IllegalArgumentException
    158     *             if the Object or <code>ToStringStyle</code> is <code>null</code>
    159     *
    160     * @see ToStringExclude
    161     * @see ToStringSummary
    162     */
    163    public static String toString(final Object object, final ToStringStyle style) {
    164        return toString(object, style, false, false, null);
    165    }
    166
    167    /**
    168     * <p>
    169     * Builds a <code>toString</code> value through reflection.
    170     * </p>
    171     *
    172     * <p>
    173     * It uses <code>AccessibleObject.setAccessible</code> to gain access to private fields. This means that it will
    174     * throw a security exception if run under a security manager, if the permissions are not set up correctly. It is
    175     * also not as efficient as testing explicitly.
    176     * </p>
    177     *
    178     * <p>
    179     * If the <code>outputTransients</code> is <code>true</code>, transient members will be output, otherwise they
    180     * are ignored, as they are likely derived fields, and not part of the value of the Object.
    181     * </p>
    182     *
    183     * <p>
    184     * Static fields will not be included. Superclass fields will be appended.
    185     * </p>
    186     *
    187     * <p>
    188     * If the style is <code>null</code>, the default <code>ToStringStyle</code> is used.
    189     * </p>
    190     *
    191     * @param object
    192     *            the Object to be output
    193     * @param style
    194     *            the style of the <code>toString</code> to create, may be <code>null</code>
    195     * @param outputTransients
    196     *            whether to include transient fields
    197     * @return the String result
    198     * @throws IllegalArgumentException
    199     *             if the Object is <code>null</code>
    200     *
    201     * @see ToStringExclude
    202     * @see ToStringSummary
    203     */
    204    public static String toString(final Object object, final ToStringStyle style, final boolean outputTransients) {
    205        return toString(object, style, outputTransients, false, null);
    206    }
    207
    208    /**
    209     * <p>
    210     * Builds a <code>toString</code> value through reflection.
    211     * </p>
    212     *
    213     * <p>
    214     * It uses <code>AccessibleObject.setAccessible</code> to gain access to private fields. This means that it will
    215     * throw a security exception if run under a security manager, if the permissions are not set up correctly. It is
    216     * also not as efficient as testing explicitly.
    217     * </p>
    218     *
    219     * <p>
    220     * If the <code>outputTransients</code> is <code>true</code>, transient fields will be output, otherwise they
    221     * are ignored, as they are likely derived fields, and not part of the value of the Object.
    222     * </p>
    223     *
    224     * <p>
    225     * If the <code>outputStatics</code> is <code>true</code>, static fields will be output, otherwise they are
    226     * ignored.
    227     * </p>
    228     *
    229     * <p>
    230     * Static fields will not be included. Superclass fields will be appended.
    231     * </p>
    232     *
    233     * <p>
    234     * If the style is <code>null</code>, the default <code>ToStringStyle</code> is used.
    235     * </p>
    236     *
    237     * @param object
    238     *            the Object to be output
    239     * @param style
    240     *            the style of the <code>toString</code> to create, may be <code>null</code>
    241     * @param outputTransients
    242     *            whether to include transient fields
    243     * @param outputStatics
    244     *            whether to include static fields
    245     * @return the String result
    246     * @throws IllegalArgumentException
    247     *             if the Object is <code>null</code>
    248     *
    249     * @see ToStringExclude
    250     * @see ToStringSummary
    251     * @since 2.1
    252     */
    253    public static String toString(final Object object, final ToStringStyle style, final boolean outputTransients, final boolean outputStatics) {
    254        return toString(object, style, outputTransients, outputStatics, null);
    255    }
    256
    257    /**
    258     * <p>
    259     * Builds a <code>toString</code> value through reflection.
    260     * </p>
    261     *
    262     * <p>
    263     * It uses <code>AccessibleObject.setAccessible</code> to gain access to private fields. This means that it will
    264     * throw a security exception if run under a security manager, if the permissions are not set up correctly. It is
    265     * also not as efficient as testing explicitly.
    266     * </p>
    267     *
    268     * <p>
    269     * If the <code>outputTransients</code> is <code>true</code>, transient fields will be output, otherwise they
    270     * are ignored, as they are likely derived fields, and not part of the value of the Object.
    271     * </p>
    272     *
    273     * <p>
    274     * If the <code>outputStatics</code> is <code>true</code>, static fields will be output, otherwise they are
    275     * ignored.
    276     * </p>
    277     *
    278     * <p>
    279     * Superclass fields will be appended up to and including the specified superclass. A null superclass is treated as
    280     * <code>java.lang.Object</code>.
    281     * </p>
    282     *
    283     * <p>
    284     * If the style is <code>null</code>, the default <code>ToStringStyle</code> is used.
    285     * </p>
    286     *
    287     * @param <T>
    288     *            the type of the object
    289     * @param object
    290     *            the Object to be output
    291     * @param style
    292     *            the style of the <code>toString</code> to create, may be <code>null</code>
    293     * @param outputTransients
    294     *            whether to include transient fields
    295     * @param outputStatics
    296     *            whether to include static fields
    297     * @param reflectUpToClass
    298     *            the superclass to reflect up to (inclusive), may be <code>null</code>
    299     * @return the String result
    300     * @throws IllegalArgumentException
    301     *             if the Object is <code>null</code>
    302     *
    303     * @see ToStringExclude
    304     * @see ToStringSummary
    305     * @since 2.1
    306     */
    307    public static <T> String toString(
    308            final T object, final ToStringStyle style, final boolean outputTransients,
    309            final boolean outputStatics, final Class<? super T> reflectUpToClass) {
    310        return new ReflectionToStringBuilder(object, style, null, reflectUpToClass, outputTransients, outputStatics)
    311                .toString();
    312    }
    313
    314    /**
    315     * <p>
    316     * Builds a <code>toString</code> value through reflection.
    317     * </p>
    318     *
    319     * <p>
    320     * It uses <code>AccessibleObject.setAccessible</code> to gain access to private fields. This means that it will
    321     * throw a security exception if run under a security manager, if the permissions are not set up correctly. It is
    322     * also not as efficient as testing explicitly.
    323     * </p>
    324     *
    325     * <p>
    326     * If the <code>outputTransients</code> is <code>true</code>, transient fields will be output, otherwise they
    327     * are ignored, as they are likely derived fields, and not part of the value of the Object.
    328     * </p>
    329     *
    330     * <p>
    331     * If the <code>outputStatics</code> is <code>true</code>, static fields will be output, otherwise they are
    332     * ignored.
    333     * </p>
    334     *
    335     * <p>
    336     * Superclass fields will be appended up to and including the specified superclass. A null superclass is treated as
    337     * <code>java.lang.Object</code>.
    338     * </p>
    339     *
    340     * <p>
    341     * If the style is <code>null</code>, the default <code>ToStringStyle</code> is used.
    342     * </p>
    343     *
    344     * @param <T>
    345     *            the type of the object
    346     * @param object
    347     *            the Object to be output
    348     * @param style
    349     *            the style of the <code>toString</code> to create, may be <code>null</code>
    350     * @param outputTransients
    351     *            whether to include transient fields
    352     * @param outputStatics
    353     *            whether to include static fields
    354     * @param excludeNullValues
    355     *            whether to exclude fields whose values are null
    356     * @param reflectUpToClass
    357     *            the superclass to reflect up to (inclusive), may be <code>null</code>
    358     * @return the String result
    359     * @throws IllegalArgumentException
    360     *             if the Object is <code>null</code>
    361     *
    362     * @see ToStringExclude
    363     * @see ToStringSummary
    364     * @since 3.6
    365     */
    366    public static <T> String toString(
    367            final T object, final ToStringStyle style, final boolean outputTransients,
    368            final boolean outputStatics, final boolean excludeNullValues, final Class<? super T> reflectUpToClass) {
    369        return new ReflectionToStringBuilder(object, style, null, reflectUpToClass, outputTransients, outputStatics, excludeNullValues)
    370                .toString();
    371    }
    372
    373    /**
    374     * Builds a String for a toString method excluding the given field names.
    375     *
    376     * @param object
    377     *            The object to "toString".
    378     * @param excludeFieldNames
    379     *            The field names to exclude. Null excludes nothing.
    380     * @return The toString value.
    381     */
    382    public static String toStringExclude(final Object object, final Collection<String> excludeFieldNames) {
    383        return toStringExclude(object, toNoNullStringArray(excludeFieldNames));
    384    }
    385
    386    /**
    387     * Converts the given Collection into an array of Strings. The returned array does not contain <code>null</code>
    388     * entries. Note that {@link Arrays#sort(Object[])} will throw an {@link NullPointerException} if an array element
    389     * is <code>null</code>.
    390     *
    391     * @param collection
    392     *            The collection to convert
    393     * @return A new array of Strings.
    394     */
    395    static String[] toNoNullStringArray(final Collection<String> collection) {
    396        if (collection == null) {
    397            return ArrayUtils.EMPTY_STRING_ARRAY;
    398        }
    399        return toNoNullStringArray(collection.toArray());
    400    }
    401
    402    /**
    403     * Returns a new array of Strings without null elements. Internal method used to normalize exclude lists
    404     * (arrays and collections). Note that {@link Arrays#sort(Object[])} will throw an {@link NullPointerException}
    405     * if an array element is <code>null</code>.
    406     *
    407     * @param array
    408     *            The array to check
    409     * @return The given array or a new array without null.
    410     */
    411    static String[] toNoNullStringArray(final Object[] array) {
    412        final List<String> list = new ArrayList<>(array.length);
    413        for (final Object e : array) {
    414            if (e != null) {
    415                list.add(e.toString());
    416            }
    417        }
    418        return list.toArray(ArrayUtils.EMPTY_STRING_ARRAY);
    419    }
    420
    421
    422    /**
    423     * Builds a String for a toString method excluding the given field names.
    424     *
    425     * @param object
    426     *            The object to "toString".
    427     * @param excludeFieldNames
    428     *            The field names to exclude
    429     * @return The toString value.
    430     */
    431    public static String toStringExclude(final Object object, final String... excludeFieldNames) {
    432        return new ReflectionToStringBuilder(object).setExcludeFieldNames(excludeFieldNames).toString();
    433    }
    434
    435    private static Object checkNotNull(final Object obj) {
    436        Validate.isTrue(obj != null, "The Object passed in should not be null.");
    437        return obj;
    438    }
    439
    440    /**
    441     * Whether or not to append static fields.
    442     */
    443    private boolean appendStatics = false;
    444
    445    /**
    446     * Whether or not to append transient fields.
    447     */
    448    private boolean appendTransients = false;
    449
    450    /**
    451     * Whether or not to append fields that are null.
    452     */
    453    private boolean excludeNullValues;
    454
    455    /**
    456     * Which field names to exclude from output. Intended for fields like <code>"password"</code>.
    457     *
    458     * @since 3.0 this is protected instead of private
    459     */
    460    protected String[] excludeFieldNames;
    461
    462    /**
    463     * The last super class to stop appending fields for.
    464     */
    465    private Class<?> upToClass = null;
    466
    467    /**
    468     * <p>
    469     * Constructor.
    470     * </p>
    471     *
    472     * <p>
    473     * This constructor outputs using the default style set with <code>setDefaultStyle</code>.
    474     * </p>
    475     *
    476     * @param object
    477     *            the Object to build a <code>toString</code> for, must not be <code>null</code>
    478     * @throws IllegalArgumentException
    479     *             if the Object passed in is <code>null</code>
    480     */
    481    public ReflectionToStringBuilder(final Object object) {
    482        super(checkNotNull(object));
    483    }
    484
    485    /**
    486     * <p>
    487     * Constructor.
    488     * </p>
    489     *
    490     * <p>
    491     * If the style is <code>null</code>, the default style is used.
    492     * </p>
    493     *
    494     * @param object
    495     *            the Object to build a <code>toString</code> for, must not be <code>null</code>
    496     * @param style
    497     *            the style of the <code>toString</code> to create, may be <code>null</code>
    498     * @throws IllegalArgumentException
    499     *             if the Object passed in is <code>null</code>
    500     */
    501    public ReflectionToStringBuilder(final Object object, final ToStringStyle style) {
    502        super(checkNotNull(object), style);
    503    }
    504
    505    /**
    506     * <p>
    507     * Constructor.
    508     * </p>
    509     *
    510     * <p>
    511     * If the style is <code>null</code>, the default style is used.
    512     * </p>
    513     *
    514     * <p>
    515     * If the buffer is <code>null</code>, a new one is created.
    516     * </p>
    517     *
    518     * @param object
    519     *            the Object to build a <code>toString</code> for
    520     * @param style
    521     *            the style of the <code>toString</code> to create, may be <code>null</code>
    522     * @param buffer
    523     *            the <code>StringBuffer</code> to populate, may be <code>null</code>
    524     * @throws IllegalArgumentException
    525     *             if the Object passed in is <code>null</code>
    526     */
    527    public ReflectionToStringBuilder(final Object object, final ToStringStyle style, final StringBuffer buffer) {
    528        super(checkNotNull(object), style, buffer);
    529    }
    530
    531    /**
    532     * Constructor.
    533     *
    534     * @param <T>
    535     *            the type of the object
    536     * @param object
    537     *            the Object to build a <code>toString</code> for
    538     * @param style
    539     *            the style of the <code>toString</code> to create, may be <code>null</code>
    540     * @param buffer
    541     *            the <code>StringBuffer</code> to populate, may be <code>null</code>
    542     * @param reflectUpToClass
    543     *            the superclass to reflect up to (inclusive), may be <code>null</code>
    544     * @param outputTransients
    545     *            whether to include transient fields
    546     * @param outputStatics
    547     *            whether to include static fields
    548     * @since 2.1
    549     */
    550    public <T> ReflectionToStringBuilder(
    551            final T object, final ToStringStyle style, final StringBuffer buffer,
    552            final Class<? super T> reflectUpToClass, final boolean outputTransients, final boolean outputStatics) {
    553        super(checkNotNull(object), style, buffer);
    554        this.setUpToClass(reflectUpToClass);
    555        this.setAppendTransients(outputTransients);
    556        this.setAppendStatics(outputStatics);
    557    }
    558
    559    /**
    560     * Constructor.
    561     *
    562     * @param <T>
    563     *            the type of the object
    564     * @param object
    565     *            the Object to build a <code>toString</code> for
    566     * @param style
    567     *            the style of the <code>toString</code> to create, may be <code>null</code>
    568     * @param buffer
    569     *            the <code>StringBuffer</code> to populate, may be <code>null</code>
    570     * @param reflectUpToClass
    571     *            the superclass to reflect up to (inclusive), may be <code>null</code>
    572     * @param outputTransients
    573     *            whether to include transient fields
    574     * @param outputStatics
    575     *            whether to include static fields
    576     * @param excludeNullValues
    577     *            whether to exclude fields who value is null
    578     * @since 3.6
    579     */
    580    public <T> ReflectionToStringBuilder(
    581            final T object, final ToStringStyle style, final StringBuffer buffer,
    582            final Class<? super T> reflectUpToClass, final boolean outputTransients, final boolean outputStatics,
    583            final boolean excludeNullValues) {
    584        super(checkNotNull(object), style, buffer);
    585        this.setUpToClass(reflectUpToClass);
    586        this.setAppendTransients(outputTransients);
    587        this.setAppendStatics(outputStatics);
    588        this.setExcludeNullValues(excludeNullValues);
    589    }
    590
    591    /**
    592     * Returns whether or not to append the given <code>Field</code>.
    593     * <ul>
    594     * <li>Transient fields are appended only if {@link #isAppendTransients()} returns <code>true</code>.
    595     * <li>Static fields are appended only if {@link #isAppendStatics()} returns <code>true</code>.
    596     * <li>Inner class fields are not appended.</li>
    597     * </ul>
    598     *
    599     * @param field
    600     *            The Field to test.
    601     * @return Whether or not to append the given <code>Field</code>.
    602     */
    603    protected boolean accept(final Field field) {
    604        if (field.getName().indexOf(ClassUtils.INNER_CLASS_SEPARATOR_CHAR) != -1) {
    605            // Reject field from inner class.
    606            return false;
    607        }
    608        if (Modifier.isTransient(field.getModifiers()) && !this.isAppendTransients()) {
    609            // Reject transient fields.
    610            return false;
    611        }
    612        if (Modifier.isStatic(field.getModifiers()) && !this.isAppendStatics()) {
    613            // Reject static fields.
    614            return false;
    615        }
    616        if (this.excludeFieldNames != null
    617            && Arrays.binarySearch(this.excludeFieldNames, field.getName()) >= 0) {
    618            // Reject fields from the getExcludeFieldNames list.
    619            return false;
    620        }
    621        return !field.isAnnotationPresent(ToStringExclude.class);
    622    }
    623
    624    /**
    625     * <p>
    626     * Appends the fields and values defined by the given object of the given Class.
    627     * </p>
    628     *
    629     * <p>
    630     * If a cycle is detected as an object is &quot;toString()'ed&quot;, such an object is rendered as if
    631     * <code>Object.toString()</code> had been called and not implemented by the object.
    632     * </p>
    633     *
    634     * @param clazz
    635     *            The class of object parameter
    636     */
    637    protected void appendFieldsIn(final Class<?> clazz) {
    638        if (clazz.isArray()) {
    639            this.reflectionAppendArray(this.getObject());
    640            return;
    641        }
    642        final Field[] fields = clazz.getDeclaredFields();
    643        AccessibleObject.setAccessible(fields, true);
    644        for (final Field field : fields) {
    645            final String fieldName = field.getName();
    646            if (this.accept(field)) {
    647                try {
    648                    // Warning: Field.get(Object) creates wrappers objects
    649                    // for primitive types.
    650                    final Object fieldValue = this.getValue(field);
    651                    if (!excludeNullValues || fieldValue != null) {
    652                        this.append(fieldName, fieldValue, !field.isAnnotationPresent(ToStringSummary.class));
    653                    }
    654                } catch (final IllegalAccessException ex) {
    655                    //this can't happen. Would get a Security exception
    656                    // instead
    657                    //throw a runtime exception in case the impossible
    658                    // happens.
    659                    throw new InternalError("Unexpected IllegalAccessException: " + ex.getMessage());
    660                }
    661            }
    662        }
    663    }
    664
    665    /**
    666     * @return Returns the excludeFieldNames.
    667     */
    668    public String[] getExcludeFieldNames() {
    669        return this.excludeFieldNames.clone();
    670    }
    671
    672    /**
    673     * <p>
    674     * Gets the last super class to stop appending fields for.
    675     * </p>
    676     *
    677     * @return The last super class to stop appending fields for.
    678     */
    679    public Class<?> getUpToClass() {
    680        return this.upToClass;
    681    }
    682
    683    /**
    684     * <p>
    685     * Calls <code>java.lang.reflect.Field.get(Object)</code>.
    686     * </p>
    687     *
    688     * @param field
    689     *            The Field to query.
    690     * @return The Object from the given Field.
    691     *
    692     * @throws IllegalArgumentException
    693     *             see {@link java.lang.reflect.Field#get(Object)}
    694     * @throws IllegalAccessException
    695     *             see {@link java.lang.reflect.Field#get(Object)}
    696     *
    697     * @see java.lang.reflect.Field#get(Object)
    698     */
    699    protected Object getValue(final Field field) throws IllegalAccessException {
    700        return field.get(this.getObject());
    701    }
    702
    703    /**
    704     * <p>
    705     * Gets whether or not to append static fields.
    706     * </p>
    707     *
    708     * @return Whether or not to append static fields.
    709     * @since 2.1
    710     */
    711    public boolean isAppendStatics() {
    712        return this.appendStatics;
    713    }
    714
    715    /**
    716     * <p>
    717     * Gets whether or not to append transient fields.
    718     * </p>
    719     *
    720     * @return Whether or not to append transient fields.
    721     */
    722    public boolean isAppendTransients() {
    723        return this.appendTransients;
    724    }
    725
    726    /**
    727     * <p>
    728     * Gets whether or not to append fields whose values are null.
    729     * </p>
    730     *
    731     * @return Whether or not to append fields whose values are null.
    732     * @since 3.6
    733     */
    734    public boolean isExcludeNullValues() {
    735        return this.excludeNullValues;
    736    }
    737
    738    /**
    739     * <p>
    740     * Append to the <code>toString</code> an <code>Object</code> array.
    741     * </p>
    742     *
    743     * @param array
    744     *            the array to add to the <code>toString</code>
    745     * @return this
    746     */
    747    public ReflectionToStringBuilder reflectionAppendArray(final Object array) {
    748        this.getStyle().reflectionAppendArrayDetail(this.getStringBuffer(), null, array);
    749        return this;
    750    }
    751
    752    /**
    753     * <p>
    754     * Sets whether or not to append static fields.
    755     * </p>
    756     *
    757     * @param appendStatics
    758     *            Whether or not to append static fields.
    759     * @since 2.1
    760     */
    761    public void setAppendStatics(final boolean appendStatics) {
    762        this.appendStatics = appendStatics;
    763    }
    764
    765    /**
    766     * <p>
    767     * Sets whether or not to append transient fields.
    768     * </p>
    769     *
    770     * @param appendTransients
    771     *            Whether or not to append transient fields.
    772     */
    773    public void setAppendTransients(final boolean appendTransients) {
    774        this.appendTransients = appendTransients;
    775    }
    776
    777    /**
    778     * <p>
    779     * Sets whether or not to append fields whose values are null.
    780     * </p>
    781     *
    782     * @param excludeNullValues
    783     *            Whether or not to append fields whose values are null.
    784     * @since 3.6
    785     */
    786    public void setExcludeNullValues(final boolean excludeNullValues) {
    787        this.excludeNullValues = excludeNullValues;
    788    }
    789
    790    /**
    791     * Sets the field names to exclude.
    792     *
    793     * @param excludeFieldNamesParam
    794     *            The excludeFieldNames to excluding from toString or <code>null</code>.
    795     * @return <code>this</code>
    796     */
    797    public ReflectionToStringBuilder setExcludeFieldNames(final String... excludeFieldNamesParam) {
    798        if (excludeFieldNamesParam == null) {
    799            this.excludeFieldNames = null;
    800        } else {
    801            //clone and remove nulls
    802            this.excludeFieldNames = toNoNullStringArray(excludeFieldNamesParam);
    803            Arrays.sort(this.excludeFieldNames);
    804        }
    805        return this;
    806    }
    807
    808    /**
    809     * <p>
    810     * Sets the last super class to stop appending fields for.
    811     * </p>
    812     *
    813     * @param clazz
    814     *            The last super class to stop appending fields for.
    815     */
    816    public void setUpToClass(final Class<?> clazz) {
    817        if (clazz != null) {
    818            final Object object = getObject();
    819            if (object != null && !clazz.isInstance(object)) {
    820                throw new IllegalArgumentException("Specified class is not a superclass of the object");
    821            }
    822        }
    823        this.upToClass = clazz;
    824    }
    825
    826    /**
    827     * <p>
    828     * Gets the String built by this builder.
    829     * </p>
    830     *
    831     * @return the built string
    832     */
    833    @Override
    834    public String toString() {
    835        if (this.getObject() == null) {
    836            return this.getStyle().getNullText();
    837        }
    838        Class<?> clazz = this.getObject().getClass();
    839        this.appendFieldsIn(clazz);
    840        while (clazz.getSuperclass() != null && clazz != this.getUpToClass()) {
    841            clazz = clazz.getSuperclass();
    842            this.appendFieldsIn(clazz);
    843        }
    844        return super.toString();
    845    }
    846
    847}