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}