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 *      https://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 */
017package org.apache.commons.lang3.builder;
018
019import java.util.Objects;
020
021import org.apache.commons.lang3.ObjectUtils;
022
023/**
024 * Assists in implementing {@link Object#toString()} methods.
025 *
026 * <p>
027 * This class enables a good and consistent {@code toString()} to be built for any
028 * class or object. This class aims to simplify the process by:
029 * </p>
030 * <ul>
031 *  <li>allowing field names</li>
032 *  <li>handling all types consistently</li>
033 *  <li>handling nulls consistently</li>
034 *  <li>outputting arrays and multi-dimensional arrays</li>
035 *  <li>enabling the detail level to be controlled for Objects and Collections</li>
036 *  <li>handling class hierarchies</li>
037 * </ul>
038 *
039 * <p>
040 * To use this class write code as follows:
041 * </p>
042 *
043 * <pre>
044 * public class Person {
045 *   String name;
046 *   int age;
047 *   boolean smoker;
048 *
049 *   ...
050 *
051 *   public String toString() {
052 *     return new ToStringBuilder(this).
053 *       append("name", name).
054 *       append("age", age).
055 *       append("smoker", smoker).
056 *       toString();
057 *   }
058 * }
059 * </pre>
060 *
061 * <p>
062 * This will produce a toString of the format:
063 * {@code Person@7f54[name=Stephen,age=29,smoker=false]}
064 * </p>
065 *
066 * <p>
067 * To add the superclass {@code toString}, use {@link #appendSuper}.
068 * To append the {@code toString} from an object that is delegated
069 * to (or any other object), use {@link #appendToString}.
070 * </p>
071 *
072 * <p>
073 * Alternatively, there is a method that uses reflection to determine
074 * the fields to test. Because these fields are usually private, the method,
075 * {@code reflectionToString}, uses {@code AccessibleObject.setAccessible} to
076 * change the visibility of the fields. This will fail under a security manager,
077 * unless the appropriate permissions are set up correctly. It is also
078 * slower than testing explicitly.
079 * </p>
080 * <p>
081 * See also {@link AbstractBuilder#setForceAccessible(boolean)}
082 * </p>
083 *
084 * <p>
085 * A typical invocation for this method would look like:
086 * </p>
087 *
088 * <pre>
089 * public String toString() {
090 *   return ToStringBuilder.reflectionToString(this);
091 * }
092 * </pre>
093 *
094 * <p>
095 * You can also use the builder to debug 3rd party objects:
096 * </p>
097 *
098 * <pre>
099 * System.out.println("An object: " + ToStringBuilder.reflectionToString(anObject));
100 * </pre>
101 *
102 * <p>
103 * The exact format of the {@code toString} is determined by
104 * the {@link ToStringStyle} passed into the constructor.
105 * </p>
106 *
107 * @see AbstractBuilder#setForceAccessible(boolean)
108 * @since 1.0
109 */
110public class ToStringBuilder extends AbstractReflection implements Builder<String> {
111
112    /**
113     * Builds instances of CompareToBuilder.
114     *
115     * @since 3.21.0
116     */
117    public static class Builder extends AbstractBuilder<Builder> {
118
119        private Object object;
120        private ToStringStyle style;
121        private StringBuffer buffer;
122
123        /**
124         * Constructs a new Builder instance.
125         */
126        private Builder() {
127            // empty
128        }
129
130        @Override
131        public ToStringBuilder get() {
132            return new ToStringBuilder(this);
133        }
134
135        /**
136         * Sets the {@link StringBuffer} to populate, may be null.
137         *
138         * @param buffer The {@link StringBuffer} to populate, may be null
139         * @return {@code this} builder instance.
140         */
141        public Builder setBuffer(final StringBuffer buffer) {
142            this.buffer = buffer;
143            return asThis();
144        }
145
146        /**
147         * Sets the Object to build a {@code toString} for, not recommended to be null.
148         *
149         * @param object The Object to build a {@code toString} for, not recommended to be null.
150         * @return {@code this} builder instance.
151         */
152        public Builder setObject(final Object object) {
153            this.object = object;
154            return asThis();
155        }
156
157        /**
158         * Sets the style of the {@code toString} to create, null uses the default style.
159         *
160         * @param style The style of the {@code toString} to create, null uses the default style
161         * @return {@code this} builder instance.
162         */
163        public Builder setStyle(final ToStringStyle style) {
164            this.style = style;
165            return asThis();
166        }
167    }
168
169    /**
170     * The default style of output to use, not null.
171     */
172    private static volatile ToStringStyle defaultStyle = ToStringStyle.DEFAULT_STYLE;
173
174    /**
175     * Constructs a new Builder.
176     *
177     * @return A new Builder.
178     * @since 3.21.0
179     */
180    public static Builder builder() {
181        return new Builder();
182    }
183
184    /**
185     * Gets the default {@link ToStringStyle} to use.
186     *
187     * <p>
188     * This method gets a singleton default value, typically for the whole JVM.
189     * Changing this default should generally only be done during application startup.
190     * It is recommended to pass a {@link ToStringStyle} to the constructor instead
191     * of using this global default.
192     * </p>
193     *
194     * <p>
195     * This method can be used from multiple threads.
196     * Internally, a {@code volatile} variable is used to provide the guarantee
197     * that the latest value set using {@link #setDefaultStyle} is the value returned.
198     * It is strongly recommended that the default style is only changed during application startup.
199     * </p>
200     *
201     * <p>
202     * One reason for changing the default could be to have a verbose style during
203     * development and a compact style in production.
204     * </p>
205     *
206     * @return The default {@link ToStringStyle}, never null
207     */
208    public static ToStringStyle getDefaultStyle() {
209        return defaultStyle;
210    }
211
212    /**
213     * Uses {@link ReflectionToStringBuilder} to generate a
214     * {@code toString} for the specified object.
215     *
216     * @param object  The Object to be output
217     * @return The String result
218     * @see ReflectionToStringBuilder#toString(Object)
219     */
220    public static String reflectionToString(final Object object) {
221        return ReflectionToStringBuilder.toString(object);
222    }
223
224    /**
225     * Uses {@link ReflectionToStringBuilder} to generate a
226     * {@code toString} for the specified object.
227     *
228     * @param object  The Object to be output
229     * @param style  The style of the {@code toString} to create, may be {@code null}
230     * @return The String result
231     * @see ReflectionToStringBuilder#toString(Object,ToStringStyle)
232     */
233    public static String reflectionToString(final Object object, final ToStringStyle style) {
234        return ReflectionToStringBuilder.toString(object, style);
235    }
236
237    /**
238     * Uses {@link ReflectionToStringBuilder} to generate a
239     * {@code toString} for the specified object.
240     *
241     * @param object  The Object to be output
242     * @param style  The style of the {@code toString} to create, may be {@code null}
243     * @param outputTransients  whether to include transient fields
244     * @return The String result
245     * @see ReflectionToStringBuilder#toString(Object,ToStringStyle,boolean)
246     */
247    public static String reflectionToString(final Object object, final ToStringStyle style, final boolean outputTransients) {
248        return ReflectionToStringBuilder.toString(object, style, outputTransients, false, null);
249    }
250
251    /**
252     * Uses {@link ReflectionToStringBuilder} to generate a
253     * {@code toString} for the specified object.
254     *
255     * @param <T> The type of the object
256     * @param object  The Object to be output
257     * @param style  The style of the {@code toString} to create, may be {@code null}
258     * @param outputTransients  whether to include transient fields
259     * @param reflectUpToClass  The superclass to reflect up to (inclusive), may be {@code null}
260     * @return The String result
261     * @see ReflectionToStringBuilder#toString(Object,ToStringStyle,boolean,boolean,Class)
262     * @since 2.0
263     */
264    public static <T> String reflectionToString(
265        final T object,
266        final ToStringStyle style,
267        final boolean outputTransients,
268        final Class<? super T> reflectUpToClass) {
269        return ReflectionToStringBuilder.toString(object, style, outputTransients, false, reflectUpToClass);
270    }
271
272    /**
273     * Sets the default {@link ToStringStyle} to use.
274     *
275     * <p>
276     * This method sets a singleton default value, typically for the whole JVM.
277     * Changing this default should generally only be done during application startup.
278     * It is recommended to pass a {@link ToStringStyle} to the constructor instead
279     * of changing this global default.
280     * </p>
281     *
282     * <p>
283     * This method is not intended for use from multiple threads.
284     * Internally, a {@code volatile} variable is used to provide the guarantee
285     * that the latest value set is the value returned from {@link #getDefaultStyle}.
286     * </p>
287     *
288     * @param style  The default {@link ToStringStyle}
289     * @throws NullPointerException Thrown if the style is {@code null}.
290     */
291    public static void setDefaultStyle(final ToStringStyle style) {
292        defaultStyle = Objects.requireNonNull(style, "style");
293    }
294
295    /**
296     * Current toString buffer, not null.
297     */
298    private final StringBuffer buffer;
299
300    /**
301     * The object being output, may be null.
302     */
303    private final Object object;
304
305    /**
306     * The style of output to use, not null.
307     */
308    private final ToStringStyle style;
309
310    /**
311     * Visited-object tracking for this builder's output buffer.
312     */
313    private final ToStringStyle.Traversal traversal;
314
315    private ToStringBuilder(final Builder builder) {
316        super(builder);
317        this.style = builder.style != null ? builder.style : getDefaultStyle();
318        this.buffer = builder.buffer != null ? builder.buffer : new StringBuffer(512);
319        this.object = builder.object;
320        this.traversal = ToStringStyle.getTraversal(buffer);
321        appenTraversal(() -> style.appendStart(buffer, object));
322    }
323
324    /**
325     * Constructs a builder for the specified object using the default output style.
326     *
327     * <p>
328     * This default style is obtained from {@link #getDefaultStyle()}.
329     * </p>
330     *
331     * @param object  The Object to build a {@code toString} for, not recommended to be null
332     */
333    public ToStringBuilder(final Object object) {
334        this(object, null, null);
335    }
336
337    /**
338     * Constructs a builder for the specified object using the defined output style.
339     *
340     * <p>
341     * If the style is {@code null}, the default style is used.
342     * </p>
343     *
344     * @param object  The Object to build a {@code toString} for, not recommended to be null
345     * @param style  The style of the {@code toString} to create, null uses the default style
346     */
347    public ToStringBuilder(final Object object, final ToStringStyle style) {
348        this(object, style, null);
349    }
350
351    /**
352     * Constructs a builder for the specified object.
353     *
354     * <p>
355     * If the style is {@code null}, the default style is used.
356     * </p>
357     *
358     * <p>
359     * If the buffer is {@code null}, a new one is created.
360     * </p>
361     *
362     * @param object  The Object to build a {@code toString} for, not recommended to be null
363     * @param style  The style of the {@code toString} to create, null uses the default style
364     * @param buffer  The {@link StringBuffer} to populate, may be null
365     */
366    public ToStringBuilder(final Object object, final ToStringStyle style, final StringBuffer buffer) {
367        this(builder().setObject(object).setStyle(style).setBuffer(buffer));
368    }
369
370    /**
371     * Appends to the {@code toString} a {@code boolean}
372     * value.
373     *
374     * @param value  The value to add to the {@code toString}
375     * @return {@code this} instance.
376     */
377    public ToStringBuilder append(final boolean value) {
378        return appenTraversal(() -> style.append(buffer, null, value));
379    }
380
381    /**
382     * Appends to the {@code toString} a {@code boolean}
383     * array.
384     *
385     * @param array  The array to add to the {@code toString}
386     * @return {@code this} instance.
387     */
388    public ToStringBuilder append(final boolean[] array) {
389        return appenTraversal(() -> style.append(buffer, null, array, null));
390    }
391
392    /**
393     * Appends to the {@code toString} a {@code byte}
394     * value.
395     *
396     * @param value  The value to add to the {@code toString}
397     * @return {@code this} instance.
398     */
399    public ToStringBuilder append(final byte value) {
400        return appenTraversal(() -> style.append(buffer, null, value));
401    }
402
403    /**
404     * Appends to the {@code toString} a {@code byte}
405     * array.
406     *
407     * @param array  The array to add to the {@code toString}
408     * @return {@code this} instance.
409     */
410    public ToStringBuilder append(final byte[] array) {
411        return appenTraversal(() -> style.append(buffer, null, array, null));
412    }
413
414    /**
415     * Appends to the {@code toString} a {@code char}
416     * value.
417     *
418     * @param value  The value to add to the {@code toString}
419     * @return {@code this} instance.
420     */
421    public ToStringBuilder append(final char value) {
422        return appenTraversal(() -> style.append(buffer, null, value));
423    }
424
425    /**
426     * Appends to the {@code toString} a {@code char}
427     * array.
428     *
429     * @param array  The array to add to the {@code toString}
430     * @return {@code this} instance.
431     */
432    public ToStringBuilder append(final char[] array) {
433        return appenTraversal(() -> style.append(buffer, null, array, null));
434    }
435
436    /**
437     * Appends to the {@code toString} a {@code double}
438     * value.
439     *
440     * @param value  The value to add to the {@code toString}
441     * @return {@code this} instance.
442     */
443    public ToStringBuilder append(final double value) {
444        return appenTraversal(() -> style.append(buffer, null, value));
445    }
446
447    /**
448     * Appends to the {@code toString} a {@code double}
449     * array.
450     *
451     * @param array  The array to add to the {@code toString}
452     * @return {@code this} instance.
453     */
454    public ToStringBuilder append(final double[] array) {
455        return appenTraversal(() -> style.append(buffer, null, array, null));
456    }
457
458    /**
459     * Appends to the {@code toString} a {@code float}
460     * value.
461     *
462     * @param value  The value to add to the {@code toString}
463     * @return {@code this} instance.
464     */
465    public ToStringBuilder append(final float value) {
466        return appenTraversal(() -> style.append(buffer, null, value));
467    }
468
469    /**
470     * Appends to the {@code toString} a {@code float}
471     * array.
472     *
473     * @param array  The array to add to the {@code toString}
474     * @return {@code this} instance.
475     */
476    public ToStringBuilder append(final float[] array) {
477        return appenTraversal(() -> style.append(buffer, null, array, null));
478    }
479
480    /**
481     * Appends to the {@code toString} an {@code int}
482     * value.
483     *
484     * @param value  The value to add to the {@code toString}
485     * @return {@code this} instance.
486     */
487    public ToStringBuilder append(final int value) {
488        return appenTraversal(() -> style.append(buffer, null, value));
489    }
490
491    /**
492     * Appends to the {@code toString} an {@code int}
493     * array.
494     *
495     * @param array  The array to add to the {@code toString}
496     * @return {@code this} instance.
497     */
498    public ToStringBuilder append(final int[] array) {
499        return appenTraversal(() -> style.append(buffer, null, array, null));
500    }
501
502    /**
503     * Appends to the {@code toString} a {@code long}
504     * value.
505     *
506     * @param value  The value to add to the {@code toString}
507     * @return {@code this} instance.
508     */
509    public ToStringBuilder append(final long value) {
510        return appenTraversal(() -> style.append(buffer, null, value));
511    }
512
513    /**
514     * Appends to the {@code toString} a {@code long}
515     * array.
516     *
517     * @param array  The array to add to the {@code toString}
518     * @return {@code this} instance.
519     */
520    public ToStringBuilder append(final long[] array) {
521        return appenTraversal(() -> style.append(buffer, null, array, null));
522    }
523
524    /**
525     * Appends to the {@code toString} an {@link Object}
526     * value.
527     *
528     * @param obj  The value to add to the {@code toString}
529     * @return {@code this} instance.
530     */
531    public ToStringBuilder append(final Object obj) {
532        return appenTraversal(() -> style.append(buffer, null, obj, null));
533    }
534
535    /**
536     * Appends to the {@code toString} an {@link Object}
537     * array.
538     *
539     * @param array  The array to add to the {@code toString}
540     * @return {@code this} instance.
541     */
542    public ToStringBuilder append(final Object[] array) {
543        return appenTraversal(() -> style.append(buffer, null, array, null));
544    }
545
546    /**
547     * Appends to the {@code toString} a {@code short}
548     * value.
549     *
550     * @param value  The value to add to the {@code toString}
551     * @return {@code this} instance.
552     */
553    public ToStringBuilder append(final short value) {
554        return appenTraversal(() -> style.append(buffer, null, value));
555    }
556
557    /**
558     * Appends to the {@code toString} a {@code short}
559     * array.
560     *
561     * @param array  The array to add to the {@code toString}
562     * @return {@code this} instance.
563     */
564    public ToStringBuilder append(final short[] array) {
565        return appenTraversal(() -> style.append(buffer, null, array, null));
566    }
567
568    /**
569     * Appends to the {@code toString} a {@code boolean}
570     * value.
571     *
572     * @param fieldName  The field name
573     * @param value  The value to add to the {@code toString}
574     * @return {@code this} instance.
575     */
576    public ToStringBuilder append(final String fieldName, final boolean value) {
577        return appenTraversal(() -> style.append(buffer, fieldName, value));
578    }
579
580    /**
581     * Appends to the {@code toString} a {@code boolean}
582     * array.
583     *
584     * @param fieldName  The field name
585     * @param array  The array to add to the {@code hashCode}
586     * @return {@code this} instance.
587     */
588    public ToStringBuilder append(final String fieldName, final boolean[] array) {
589        return appenTraversal(() -> style.append(buffer, fieldName, array, null));
590    }
591
592    /**
593     * Appends to the {@code toString} a {@code boolean}
594     * array.
595     *
596     * <p>
597     * A boolean parameter controls the level of detail to show.
598     * Setting {@code true} will output the array in full. Setting
599     * {@code false} will output a summary, typically the size of
600     * the array.
601     * </p>
602     *
603     * @param fieldName  The field name
604     * @param array  The array to add to the {@code toString}
605     * @param fullDetail  {@code true} for detail, {@code false}
606     *  for summary info
607     * @return {@code this} instance.
608     */
609    public ToStringBuilder append(final String fieldName, final boolean[] array, final boolean fullDetail) {
610        return appenTraversal(() -> style.append(buffer, fieldName, array, Boolean.valueOf(fullDetail)));
611    }
612
613    /**
614     * Appends to the {@code toString} an {@code byte}
615     * value.
616     *
617     * @param fieldName  The field name
618     * @param value  The value to add to the {@code toString}
619     * @return {@code this} instance.
620     */
621    public ToStringBuilder append(final String fieldName, final byte value) {
622        return appenTraversal(() -> style.append(buffer, fieldName, value));
623    }
624
625    /**
626     * Appends to the {@code toString} a {@code byte} array.
627     *
628     * @param fieldName  The field name
629     * @param array  The array to add to the {@code toString}
630     * @return {@code this} instance.
631     */
632    public ToStringBuilder append(final String fieldName, final byte[] array) {
633        return appenTraversal(() -> style.append(buffer, fieldName, array, null));
634    }
635
636    /**
637     * Appends to the {@code toString} a {@code byte}
638     * array.
639     *
640     * <p>
641     * A boolean parameter controls the level of detail to show.
642     * Setting {@code true} will output the array in full. Setting
643     * {@code false} will output a summary, typically the size of
644     * the array.
645     * </p>
646     *
647     * @param fieldName  The field name
648     * @param array  The array to add to the {@code toString}
649     * @param fullDetail  {@code true} for detail, {@code false}
650     *  for summary info
651     * @return {@code this} instance.
652     */
653    public ToStringBuilder append(final String fieldName, final byte[] array, final boolean fullDetail) {
654        return appenTraversal(() -> style.append(buffer, fieldName, array, Boolean.valueOf(fullDetail)));
655    }
656
657    /**
658     * Appends to the {@code toString} a {@code char}
659     * value.
660     *
661     * @param fieldName  The field name
662     * @param value  The value to add to the {@code toString}
663     * @return {@code this} instance.
664     */
665    public ToStringBuilder append(final String fieldName, final char value) {
666        return appenTraversal(() -> style.append(buffer, fieldName, value));
667    }
668
669    /**
670     * Appends to the {@code toString} a {@code char}
671     * array.
672     *
673     * @param fieldName  The field name
674     * @param array  The array to add to the {@code toString}
675     * @return {@code this} instance.
676     */
677    public ToStringBuilder append(final String fieldName, final char[] array) {
678        return appenTraversal(() -> style.append(buffer, fieldName, array, null));
679    }
680
681    /**
682     * Appends to the {@code toString} a {@code char}
683     * array.
684     *
685     * <p>
686     * A boolean parameter controls the level of detail to show.
687     * Setting {@code true} will output the array in full. Setting
688     * {@code false} will output a summary, typically the size of
689     * the array.
690     * </p>
691     *
692     * @param fieldName  The field name
693     * @param array  The array to add to the {@code toString}
694     * @param fullDetail  {@code true} for detail, {@code false}
695     *  for summary info
696     * @return {@code this} instance.
697     */
698    public ToStringBuilder append(final String fieldName, final char[] array, final boolean fullDetail) {
699        return appenTraversal(() -> style.append(buffer, fieldName, array, Boolean.valueOf(fullDetail)));
700    }
701
702    /**
703     * Appends to the {@code toString} a {@code double}
704     * value.
705     *
706     * @param fieldName  The field name
707     * @param value  The value to add to the {@code toString}
708     * @return {@code this} instance.
709     */
710    public ToStringBuilder append(final String fieldName, final double value) {
711        return appenTraversal(() -> style.append(buffer, fieldName, value));
712    }
713
714    /**
715     * Appends to the {@code toString} a {@code double}
716     * array.
717     *
718     * @param fieldName  The field name
719     * @param array  The array to add to the {@code toString}
720     * @return {@code this} instance.
721     */
722    public ToStringBuilder append(final String fieldName, final double[] array) {
723        return appenTraversal(() -> style.append(buffer, fieldName, array, null));
724    }
725
726    /**
727     * Appends to the {@code toString} a {@code double}
728     * array.
729     *
730     * <p>
731     * A boolean parameter controls the level of detail to show.
732     * Setting {@code true} will output the array in full. Setting
733     * {@code false} will output a summary, typically the size of
734     * the array.
735     * </p>
736     *
737     * @param fieldName  The field name
738     * @param array  The array to add to the {@code toString}
739     * @param fullDetail  {@code true} for detail, {@code false}
740     *  for summary info
741     * @return {@code this} instance.
742     */
743    public ToStringBuilder append(final String fieldName, final double[] array, final boolean fullDetail) {
744        return appenTraversal(() -> style.append(buffer, fieldName, array, Boolean.valueOf(fullDetail)));
745    }
746
747    /**
748     * Appends to the {@code toString} an {@code float}
749     * value.
750     *
751     * @param fieldName  The field name
752     * @param value  The value to add to the {@code toString}
753     * @return {@code this} instance.
754     */
755    public ToStringBuilder append(final String fieldName, final float value) {
756        return appenTraversal(() -> style.append(buffer, fieldName, value));
757    }
758
759    /**
760     * Appends to the {@code toString} a {@code float}
761     * array.
762     *
763     * @param fieldName  The field name
764     * @param array  The array to add to the {@code toString}
765     * @return {@code this} instance.
766     */
767    public ToStringBuilder append(final String fieldName, final float[] array) {
768        return appenTraversal(() -> style.append(buffer, fieldName, array, null));
769    }
770
771    /**
772     * Appends to the {@code toString} a {@code float}
773     * array.
774     *
775     * <p>
776     * A boolean parameter controls the level of detail to show.
777     * Setting {@code true} will output the array in full. Setting
778     * {@code false} will output a summary, typically the size of
779     * the array.
780     * </p>
781     *
782     * @param fieldName  The field name
783     * @param array  The array to add to the {@code toString}
784     * @param fullDetail  {@code true} for detail, {@code false}
785     *  for summary info
786     * @return {@code this} instance.
787     */
788    public ToStringBuilder append(final String fieldName, final float[] array, final boolean fullDetail) {
789        return appenTraversal(() -> style.append(buffer, fieldName, array, Boolean.valueOf(fullDetail)));
790    }
791
792    /**
793     * Appends to the {@code toString} an {@code int}
794     * value.
795     *
796     * @param fieldName  The field name
797     * @param value  The value to add to the {@code toString}
798     * @return {@code this} instance.
799     */
800    public ToStringBuilder append(final String fieldName, final int value) {
801        return appenTraversal(() -> style.append(buffer, fieldName, value));
802    }
803
804    /**
805     * Appends to the {@code toString} an {@code int}
806     * array.
807     *
808     * @param fieldName  The field name
809     * @param array  The array to add to the {@code toString}
810     * @return {@code this} instance.
811     */
812    public ToStringBuilder append(final String fieldName, final int[] array) {
813        return appenTraversal(() -> style.append(buffer, fieldName, array, null));
814    }
815
816    /**
817     * Appends to the {@code toString} an {@code int}
818     * array.
819     *
820     * <p>
821     * A boolean parameter controls the level of detail to show.
822     * Setting {@code true} will output the array in full. Setting
823     * {@code false} will output a summary, typically the size of
824     * the array.
825     * </p>
826     *
827     * @param fieldName  The field name
828     * @param array  The array to add to the {@code toString}
829     * @param fullDetail  {@code true} for detail, {@code false}
830     *  for summary info
831     * @return {@code this} instance.
832     */
833    public ToStringBuilder append(final String fieldName, final int[] array, final boolean fullDetail) {
834        return appenTraversal(() -> style.append(buffer, fieldName, array, Boolean.valueOf(fullDetail)));
835    }
836
837    /**
838     * Appends to the {@code toString} a {@code long}
839     * value.
840     *
841     * @param fieldName  The field name
842     * @param value  The value to add to the {@code toString}
843     * @return {@code this} instance.
844     */
845    public ToStringBuilder append(final String fieldName, final long value) {
846        return appenTraversal(() -> style.append(buffer, fieldName, value));
847    }
848
849    /**
850     * Appends to the {@code toString} a {@code long}
851     * array.
852     *
853     * @param fieldName  The field name
854     * @param array  The array to add to the {@code toString}
855     * @return {@code this} instance.
856     */
857    public ToStringBuilder append(final String fieldName, final long[] array) {
858        return appenTraversal(() -> style.append(buffer, fieldName, array, null));
859    }
860
861    /**
862     * Appends to the {@code toString} a {@code long}
863     * array.
864     *
865     * <p>
866     * A boolean parameter controls the level of detail to show.
867     * Setting {@code true} will output the array in full. Setting
868     * {@code false} will output a summary, typically the size of
869     * the array.
870     * </p>
871     *
872     * @param fieldName  The field name
873     * @param array  The array to add to the {@code toString}
874     * @param fullDetail  {@code true} for detail, {@code false}
875     *  for summary info
876     * @return {@code this} instance.
877     */
878    public ToStringBuilder append(final String fieldName, final long[] array, final boolean fullDetail) {
879        return appenTraversal(() -> style.append(buffer, fieldName, array, Boolean.valueOf(fullDetail)));
880    }
881
882    /**
883     * Appends to the {@code toString} an {@link Object}
884     * value.
885     *
886     * @param fieldName  The field name
887     * @param obj  The value to add to the {@code toString}
888     * @return {@code this} instance.
889     */
890    public ToStringBuilder append(final String fieldName, final Object obj) {
891        return appenTraversal(() -> style.append(buffer, fieldName, obj, null));
892    }
893
894    /**
895     * Appends to the {@code toString} an {@link Object}
896     * value.
897     *
898     * @param fieldName  The field name
899     * @param obj  The value to add to the {@code toString}
900     * @param fullDetail  {@code true} for detail,
901     *  {@code false} for summary info
902     * @return {@code this} instance.
903     */
904    public ToStringBuilder append(final String fieldName, final Object obj, final boolean fullDetail) {
905        return appenTraversal(() -> style.append(buffer, fieldName, obj, Boolean.valueOf(fullDetail)));
906    }
907
908    /**
909     * Appends to the {@code toString} an {@link Object}
910     * array.
911     *
912     * @param fieldName  The field name
913     * @param array  The array to add to the {@code toString}
914     * @return {@code this} instance.
915     */
916    public ToStringBuilder append(final String fieldName, final Object[] array) {
917        return appenTraversal(() -> style.append(buffer, fieldName, array, null));
918    }
919
920    /**
921     * Appends to the {@code toString} an {@link Object}
922     * array.
923     *
924     * <p>
925     * A boolean parameter controls the level of detail to show.
926     * Setting {@code true} will output the array in full. Setting
927     * {@code false} will output a summary, typically the size of
928     * the array.
929     * </p>
930     *
931     * @param fieldName  The field name
932     * @param array  The array to add to the {@code toString}
933     * @param fullDetail  {@code true} for detail, {@code false}
934     *  for summary info
935     * @return {@code this} instance.
936     */
937    public ToStringBuilder append(final String fieldName, final Object[] array, final boolean fullDetail) {
938        return appenTraversal(() -> style.append(buffer, fieldName, array, Boolean.valueOf(fullDetail)));
939    }
940
941    /**
942     * Appends to the {@code toString} an {@code short}
943     * value.
944     *
945     * @param fieldName  The field name
946     * @param value  The value to add to the {@code toString}
947     * @return {@code this} instance.
948     */
949    public ToStringBuilder append(final String fieldName, final short value) {
950        return appenTraversal(() -> style.append(buffer, fieldName, value));
951    }
952
953    /**
954     * Appends to the {@code toString} a {@code short}
955     * array.
956     *
957     * @param fieldName  The field name
958     * @param array  The array to add to the {@code toString}
959     * @return {@code this} instance.
960     */
961    public ToStringBuilder append(final String fieldName, final short[] array) {
962        return appenTraversal(() -> style.append(buffer, fieldName, array, null));
963    }
964
965    /**
966     * Appends to the {@code toString} a {@code short}
967     * array.
968     *
969     * <p>
970     * A boolean parameter controls the level of detail to show.
971     * Setting {@code true} will output the array in full. Setting
972     * {@code false} will output a summary, typically the size of
973     * the array.
974     * </p>
975     *
976     * @param fieldName  The field name
977     * @param array  The array to add to the {@code toString}
978     * @param fullDetail  {@code true} for detail, {@code false}
979     *  for summary info
980     * @return {@code this} instance.
981     */
982    public ToStringBuilder append(final String fieldName, final short[] array, final boolean fullDetail) {
983        return appenTraversal(() -> style.append(buffer, fieldName, array, Boolean.valueOf(fullDetail)));
984    }
985
986    /**
987     * Appends with the same format as the default {@code Object toString()
988     * } method. Appends the class name followed by
989     * {@link System#identityHashCode(Object)}.
990     *
991     * @param srcObject  The {@link Object} whose class name and id to output
992     * @return {@code this} instance.
993     * @throws NullPointerException Thrown if {@code srcObject} is {@code null}.
994     * @since 2.0
995     */
996    public ToStringBuilder appendAsObjectToString(final Object srcObject) {
997        ObjectUtils.identityToString(getStringBuffer(), srcObject);
998        return this;
999    }
1000
1001    /**
1002     * Append the {@code toString} from the superclass.
1003     *
1004     * <p>
1005     * This method assumes that the superclass uses the same {@link ToStringStyle}
1006     * as this one.
1007     * </p>
1008     *
1009     * <p>
1010     * If {@code superToString} is {@code null}, no change is made.
1011     * </p>
1012     *
1013     * @param superToString  The result of {@code super.toString()}
1014     * @return {@code this} instance.
1015     * @since 2.0
1016     */
1017    public ToStringBuilder appendSuper(final String superToString) {
1018        if (superToString != null) {
1019            appenTraversal(() -> style.appendSuper(buffer, superToString));
1020        }
1021        return this;
1022    }
1023
1024    /**
1025     * Append the {@code toString} from another object.
1026     *
1027     * <p>
1028     * This method is useful where a class delegates most of the implementation of
1029     * its properties to another class. You can then call {@code toString()} on
1030     * the other class and pass the result into this method.
1031     * </p>
1032     *
1033     * <pre>
1034     *   private AnotherObject delegate;
1035     *   private String fieldInThisClass;
1036     *
1037     *   public String toString() {
1038     *     return new ToStringBuilder(this).
1039     *       appendToString(delegate.toString()).
1040     *       append(fieldInThisClass).
1041     *       toString();
1042     *   }</pre>
1043     *
1044     * <p>
1045     * This method assumes that the other object uses the same {@link ToStringStyle}
1046     * as this one.
1047     * </p>
1048     *
1049     * <p>
1050     * If the {@code toString} is {@code null}, no change is made.
1051     * </p>
1052     *
1053     * @param toString  The result of {@code toString()} on another object
1054     * @return {@code this} instance.
1055     * @since 2.0
1056     */
1057    public ToStringBuilder appendToString(final String toString) {
1058        if (toString != null) {
1059            appenTraversal(() -> style.appendToString(buffer, toString));
1060        }
1061        return this;
1062    }
1063
1064    /**
1065     * Appends content while sharing visited objects with nested builders.
1066     *
1067     * @param appender the action that appends content.
1068     * @return {@code this} builder.
1069     */
1070    ToStringBuilder appenTraversal(final Runnable appender) {
1071        final boolean owner = startTraversal();
1072        boolean completed = false;
1073        try {
1074            appender.run();
1075            completed = true;
1076            return this;
1077        } finally {
1078            ToStringStyle.endTraversal(buffer, traversal, owner, !completed);
1079        }
1080    }
1081
1082    /**
1083     * Returns the String that was build as an object representation. The
1084     * default implementation utilizes the {@link #toString()} implementation.
1085     *
1086     * @return The String {@code toString}
1087     * @see #toString()
1088     * @since 3.0
1089     */
1090    @Override
1091    public String build() {
1092        return toString();
1093    }
1094
1095    /**
1096     * Completes this builder's traversal and releases its visited objects.
1097     *
1098     * @param owner whether this builder started the active traversal.
1099     */
1100    void endTraversal(final boolean owner) {
1101        ToStringStyle.endTraversal(buffer, traversal, owner, true);
1102    }
1103
1104    /**
1105     * Gets the {@link Object} being output.
1106     *
1107     * @return The object being output.
1108     * @since 2.0
1109     */
1110    public Object getObject() {
1111        return object;
1112    }
1113
1114    /**
1115     * Gets the {@link StringBuffer} being populated.
1116     *
1117     * @return The {@link StringBuffer} being populated
1118     */
1119    public StringBuffer getStringBuffer() {
1120        return buffer;
1121    }
1122
1123    /**
1124     * Gets the {@link ToStringStyle} being used.
1125     *
1126     * @return The {@link ToStringStyle} being used
1127     * @since 2.0
1128     */
1129    public ToStringStyle getStyle() {
1130        return style;
1131    }
1132
1133    /**
1134     * Gets the traversal state associated with this builder's output buffer.
1135     *
1136     * @return the traversal state, never {@code null}.
1137     */
1138    ToStringStyle.Traversal getTraversal() {
1139        return traversal;
1140    }
1141
1142    /**
1143     * Starts or joins the active traversal using this builder's earlier appends.
1144     *
1145     * @return whether this builder owns the active traversal.
1146     */
1147    boolean startTraversal() {
1148        return ToStringStyle.startTraversal(traversal);
1149    }
1150
1151
1152    /**
1153     * Returns the built {@code toString}.
1154     *
1155     * <p>
1156     * This method appends the end of data indicator, and can only be called once.
1157     * Use {@link #getStringBuffer} to get the current string state.
1158     * </p>
1159     *
1160     * <p>
1161     * If the object is {@code null}, return the style's {@code nullText}
1162     * </p>
1163     *
1164     * @return The String {@code toString}
1165     */
1166    @Override
1167    public String toString() {
1168        final boolean owner = startTraversal();
1169        try {
1170            if (getObject() == null) {
1171                getStringBuffer().append(getStyle().getNullText());
1172            } else {
1173                style.appendEnd(getStringBuffer(), getObject());
1174            }
1175            return getStringBuffer().toString();
1176        } finally {
1177            endTraversal(owner);
1178        }
1179    }
1180}