KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > lang > builder > ToStringStyle


1 /*
2  * Copyright 2002-2005 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.apache.commons.lang.builder;
17
18 import java.io.Serializable JavaDoc;
19 import java.lang.reflect.Array JavaDoc;
20 import java.util.Collection JavaDoc;
21 import java.util.Map JavaDoc;
22
23 import org.apache.commons.lang.ClassUtils;
24 import org.apache.commons.lang.ObjectUtils;
25 import org.apache.commons.lang.SystemUtils;
26
27 /**
28  * <p>Controls <code>String</code> formatting for {@link ToStringBuilder}.
29  * The main public interface is always via <code>ToStringBuilder</code>.</p>
30  *
31  * <p>These classes are intended to be used as <code>Singletons</code>.
32  * There is no need to instantiate a new style each time. A program
33  * will generally use one of the predefined constants on this class.
34  * Alternatively, the {@link StandardToStringStyle} class can be used
35  * to set the individual settings. Thus most styles can be achieved
36  * without subclassing.</p>
37  *
38  * <p>If required, a subclass can override as many or as few of the
39  * methods as it requires. Each object type (from <code>boolean</code>
40  * to <code>long</code> to <code>Object</code> to <code>int[]</code>) has
41  * its own methods to output it. Most have two versions, detail and summary.
42  *
43  * <p>For example, the detail version of the array based methods will
44  * output the whole array, whereas the summary method will just output
45  * the array length.</p>
46  *
47  * <p>If you want to format the output of certain objects, such as dates, you
48  * must create a subclass and override a method.
49  * <pre>
50  * public class MyStyle extends ToStringStyle {
51  * protected void appendDetail(StringBuffer buffer, String fieldName, Object value) {
52  * if (value instanceof Date) {
53  * value = new SimpleDateFormat("yyyy-MM-dd").format(value);
54  * }
55  * buffer.append(value);
56  * }
57  * }
58  * </pre>
59  * </p>
60  *
61  * @author Stephen Colebourne
62  * @author Gary Gregory
63  * @author Pete Gieser
64  * @author Masato Tezuka
65  * @since 1.0
66  * @version $Id: ToStringStyle.java 161243 2005-04-14 04:30:28Z ggregory $
67  */

68 public abstract class ToStringStyle implements Serializable JavaDoc {
69
70     /**
71      * The default toString style.
72      */

73     public static final ToStringStyle DEFAULT_STYLE = new DefaultToStringStyle();
74     
75     /**
76      * The multi line toString style.
77      */

78     public static final ToStringStyle MULTI_LINE_STYLE = new MultiLineToStringStyle();
79     
80     /**
81      * The no field names toString style.
82      */

83     public static final ToStringStyle NO_FIELD_NAMES_STYLE = new NoFieldNameToStringStyle();
84     
85     /**
86      * The short prefix toString style.
87      * @since 2.1
88      */

89     public static final ToStringStyle SHORT_PREFIX_STYLE = new ShortPrefixToStringStyle();
90
91     /**
92      * The simple toString style.
93      */

94     public static final ToStringStyle SIMPLE_STYLE = new SimpleToStringStyle();
95     
96     /**
97      * Whether to use the field names, the default is <code>true</code>.
98      */

99     private boolean useFieldNames = true;
100     
101     /**
102      * Whether to use the class name, the default is <code>true</code>.
103      */

104     private boolean useClassName = true;
105     
106     /**
107      * Whether to use short class names, the default is <code>false</code>.
108      */

109     private boolean useShortClassName = false;
110     
111     /**
112      * Whether to use the identity hash code, the default is <code>true</code>.
113      */

114     private boolean useIdentityHashCode = true;
115
116     /**
117      * The content start <code>'['</code>.
118      */

119     private String JavaDoc contentStart = "[";
120     
121     /**
122      * The content end <code>']'</code>.
123      */

124     private String JavaDoc contentEnd = "]";
125     
126     /**
127      * The field name value separator <code>'='</code>.
128      */

129     private String JavaDoc fieldNameValueSeparator = "=";
130     
131     /**
132      * Whether the field separator should be added before any other fields.
133      */

134     private boolean fieldSeparatorAtStart = false;
135     
136     /**
137      * Whether the field separator should be added after any other fields.
138      */

139     private boolean fieldSeparatorAtEnd = false;
140     
141     /**
142      * The field separator <code>','</code>.
143      */

144     private String JavaDoc fieldSeparator = ",";
145     
146     /**
147      * The array start <code>'{'</code>.
148      */

149     private String JavaDoc arrayStart = "{";
150     
151     /**
152      * The array separator <code>','</code>.
153      */

154     private String JavaDoc arraySeparator = ",";
155     
156     /**
157      * The detail for array content.
158      */

159     private boolean arrayContentDetail = true;
160     
161     /**
162      * The array end <code>'}'</code>.
163      */

164     private String JavaDoc arrayEnd = "}";
165     
166     /**
167      * The value to use when fullDetail is <code>null</code>,
168      * the default value is <code>true</code>.
169      */

170     private boolean defaultFullDetail = true;
171     
172     /**
173      * The <code>null</code> text <code>'&lt;null&gt;'</code>.
174      */

175     private String JavaDoc nullText = "<null>";
176     
177     /**
178      * The summary size text start <code>'<size'</code>.
179      */

180     private String JavaDoc sizeStartText = "<size=";
181     
182     /**
183      * The summary size text start <code>'&gt;'</code>.
184      */

185     private String JavaDoc sizeEndText = ">";
186     
187     /**
188      * The summary object text start <code>'&lt;'</code>.
189      */

190     private String JavaDoc summaryObjectStartText = "<";
191     
192     /**
193      * The summary object text start <code>'&gt;'</code>.
194      */

195     private String JavaDoc summaryObjectEndText = ">";
196
197     //----------------------------------------------------------------------------
198

199     /**
200      * <p>Constructor.</p>
201      */

202     protected ToStringStyle() {
203         super();
204     }
205
206     //----------------------------------------------------------------------------
207

208     /**
209      * <p>Append to the <code>toString</code> the superclass toString.</p>
210      *
211      * <p>A <code>null</code> <code>superToString</code> is ignored.</p>
212      *
213      * @param buffer the <code>StringBuffer</code> to populate
214      * @param superToString the <code>super.toString()</code>
215      * @since 2.0
216      */

217     public void appendSuper(StringBuffer JavaDoc buffer, String JavaDoc superToString) {
218         appendToString(buffer, superToString);
219     }
220
221     /**
222      * <p>Append to the <code>toString</code> another toString.</p>
223      *
224      * <p>A <code>null</code> <code>toString</code> is ignored.</p>
225      *
226      * @param buffer the <code>StringBuffer</code> to populate
227      * @param toString the additional <code>toString</code>
228      * @since 2.0
229      */

230     public void appendToString(StringBuffer JavaDoc buffer, String JavaDoc toString) {
231         if (toString != null) {
232             int pos1 = toString.indexOf(contentStart) + contentStart.length();
233             int pos2 = toString.lastIndexOf(contentEnd);
234             if (pos1 != pos2 && pos1 >= 0 && pos2 >= 0) {
235                 String JavaDoc data = toString.substring(pos1, pos2);
236                 if (fieldSeparatorAtStart) {
237                     removeLastFieldSeparator(buffer);
238                 }
239                 buffer.append(data);
240                 appendFieldSeparator(buffer);
241             }
242         }
243     }
244
245     /**
246      * <p>Append to the <code>toString</code> the start of data indicator.</p>
247      *
248      * @param buffer the <code>StringBuffer</code> to populate
249      * @param object the <code>Object</code> to build a <code>toString</code> for
250      */

251     public void appendStart(StringBuffer JavaDoc buffer, Object JavaDoc object) {
252         if (object != null) {
253             appendClassName(buffer, object);
254             appendIdentityHashCode(buffer, object);
255             appendContentStart(buffer);
256             if (fieldSeparatorAtStart) {
257                 appendFieldSeparator(buffer);
258             }
259         }
260     }
261
262     /**
263      * <p>Append to the <code>toString</code> the end of data indicator.</p>
264      *
265      * @param buffer the <code>StringBuffer</code> to populate
266      * @param object the <code>Object</code> to build a
267      * <code>toString</code> for.
268      */

269     public void appendEnd(StringBuffer JavaDoc buffer, Object JavaDoc object) {
270         if (this.fieldSeparatorAtEnd == false) {
271             removeLastFieldSeparator(buffer);
272         }
273         appendContentEnd(buffer);
274     }
275
276     /**
277      * <p>Remove the last field separator from the buffer.</p>
278      *
279      * @param buffer the <code>StringBuffer</code> to populate
280      * @since 2.0
281      */

282     protected void removeLastFieldSeparator(StringBuffer JavaDoc buffer) {
283         int len = buffer.length();
284         int sepLen = fieldSeparator.length();
285         if (len > 0 && sepLen > 0 && len >= sepLen) {
286             boolean match = true;
287             for (int i = 0; i < sepLen; i++) {
288                 if (buffer.charAt(len - 1 - i) != fieldSeparator.charAt(sepLen - 1 - i)) {
289                     match = false;
290                     break;
291                 }
292             }
293             if (match) {
294                 buffer.setLength(len - sepLen);
295             }
296         }
297     }
298
299     //----------------------------------------------------------------------------
300

301     /**
302      * <p>Append to the <code>toString</code> an <code>Object</code>
303      * value, printing the full <code>toString</code> of the
304      * <code>Object</code> passed in.</p>
305      *
306      * @param buffer the <code>StringBuffer</code> to populate
307      * @param fieldName the field name
308      * @param value the value to add to the <code>toString</code>
309      * @param fullDetail <code>true</code> for detail, <code>false</code>
310      * for summary info, <code>null</code> for style decides
311      */

312     public void append(StringBuffer JavaDoc buffer, String JavaDoc fieldName, Object JavaDoc value, Boolean JavaDoc fullDetail) {
313         appendFieldStart(buffer, fieldName);
314
315         if (value == null) {
316             appendNullText(buffer, fieldName);
317
318         } else {
319             appendInternal(buffer, fieldName, value, isFullDetail(fullDetail));
320         }
321
322         appendFieldEnd(buffer, fieldName);
323     }
324
325     /**
326      * <p>Append to the <code>toString</code> an <code>Object</code>,
327      * correctly interpreting its type.</p>
328      *
329      * <p>This method performs the main lookup by Class type to correctly
330      * route arrays, <code>Collections</code>, <code>Maps</code> and
331      * <code>Objects</code> to the appropriate method.</p>
332      *
333      * <p>Either detail or summary views can be specified.</p>
334      *
335      * <p>If a cycle is detected, an object will be appended with the
336      * <code>Object.toString()</code> format.</p>
337      *
338      * @param buffer the <code>StringBuffer</code> to populate
339      * @param fieldName the field name, typically not used as already appended
340      * @param value the value to add to the <code>toString</code>,
341      * not <code>null</code>
342      * @param detail output detail or not
343      */

344     protected void appendInternal(StringBuffer JavaDoc buffer, String JavaDoc fieldName, Object JavaDoc value, boolean detail) {
345         if (ReflectionToStringBuilder.isRegistered(value)
346             && !(value instanceof Number JavaDoc || value instanceof Boolean JavaDoc || value instanceof Character JavaDoc)) {
347             ObjectUtils.appendIdentityToString(buffer, value);
348
349         } else if (value instanceof Collection JavaDoc) {
350             if (detail) {
351                 appendDetail(buffer, fieldName, (Collection JavaDoc) value);
352             } else {
353                 appendSummarySize(buffer, fieldName, ((Collection JavaDoc) value).size());
354             }
355
356         } else if (value instanceof Map JavaDoc) {
357             if (detail) {
358                 appendDetail(buffer, fieldName, (Map JavaDoc) value);
359             } else {
360                 appendSummarySize(buffer, fieldName, ((Map JavaDoc) value).size());
361             }
362
363         } else if (value instanceof long[]) {
364             if (detail) {
365                 appendDetail(buffer, fieldName, (long[]) value);
366             } else {
367                 appendSummary(buffer, fieldName, (long[]) value);
368             }
369
370         } else if (value instanceof int[]) {
371             if (detail) {
372                 appendDetail(buffer, fieldName, (int[]) value);
373             } else {
374                 appendSummary(buffer, fieldName, (int[]) value);
375             }
376
377         } else if (value instanceof short[]) {
378             if (detail) {
379                 appendDetail(buffer, fieldName, (short[]) value);
380             } else {
381                 appendSummary(buffer, fieldName, (short[]) value);
382             }
383
384         } else if (value instanceof byte[]) {
385             if (detail) {
386                 appendDetail(buffer, fieldName, (byte[]) value);
387             } else {
388                 appendSummary(buffer, fieldName, (byte[]) value);
389             }
390
391         } else if (value instanceof char[]) {
392             if (detail) {
393                 appendDetail(buffer, fieldName, (char[]) value);
394             } else {
395                 appendSummary(buffer, fieldName, (char[]) value);
396             }
397
398         } else if (value instanceof double[]) {
399             if (detail) {
400                 appendDetail(buffer, fieldName, (double[]) value);
401             } else {
402                 appendSummary(buffer, fieldName, (double[]) value);
403             }
404
405         } else if (value instanceof float[]) {
406             if (detail) {
407                 appendDetail(buffer, fieldName, (float[]) value);
408             } else {
409                 appendSummary(buffer, fieldName, (float[]) value);
410             }
411
412         } else if (value instanceof boolean[]) {
413             if (detail) {
414                 appendDetail(buffer, fieldName, (boolean[]) value);
415             } else {
416                 appendSummary(buffer, fieldName, (boolean[]) value);
417             }
418
419         } else if (value.getClass().isArray()) {
420             if (detail) {
421                 appendDetail(buffer, fieldName, (Object JavaDoc[]) value);
422             } else {
423                 appendSummary(buffer, fieldName, (Object JavaDoc[]) value);
424             }
425
426         } else {
427             if (detail) {
428                 appendDetail(buffer, fieldName, value);
429             } else {
430                 appendSummary(buffer, fieldName, value);
431             }
432         }
433     }
434
435     /**
436      * <p>Append to the <code>toString</code> an <code>Object</code>
437      * value, printing the full detail of the <code>Object</code>.</p>
438      *
439      * @param buffer the <code>StringBuffer</code> to populate
440      * @param fieldName the field name, typically not used as already appended
441      * @param value the value to add to the <code>toString</code>,
442      * not <code>null</code>
443      */

444     protected void appendDetail(StringBuffer JavaDoc buffer, String JavaDoc fieldName, Object JavaDoc value) {
445         buffer.append(value);
446     }
447
448     /**
449      * <p>Append to the <code>toString</code> a <code>Collection</code>.</p>
450      *
451      * @param buffer the <code>StringBuffer</code> to populate
452      * @param fieldName the field name, typically not used as already appended
453      * @param coll the <code>Collection</code> to add to the
454      * <code>toString</code>, not <code>null</code>
455      */

456     protected void appendDetail(StringBuffer JavaDoc buffer, String JavaDoc fieldName, Collection JavaDoc coll) {
457         buffer.append(coll);
458     }
459
460     /**
461      * <p>Append to the <code>toString</code> a <code>Map<code>.</p>
462      *
463      * @param buffer the <code>StringBuffer</code> to populate
464      * @param fieldName the field name, typically not used as already appended
465      * @param map the <code>Map</code> to add to the <code>toString</code>,
466      * not <code>null</code>
467      */

468     protected void appendDetail(StringBuffer JavaDoc buffer, String JavaDoc fieldName, Map JavaDoc map) {
469         buffer.append(map);
470     }
471
472     /**
473      * <p>Append to the <code>toString</code> an <code>Object</code>
474      * value, printing a summary of the <code>Object</code>.</P>
475      *
476      * @param buffer the <code>StringBuffer</code> to populate
477      * @param fieldName the field name, typically not used as already appended
478      * @param value the value to add to the <code>toString</code>,
479      * not <code>null</code>
480      */

481     protected void appendSummary(StringBuffer JavaDoc buffer, String JavaDoc fieldName, Object JavaDoc value) {
482         buffer.append(summaryObjectStartText);
483         buffer.append(getShortClassName(value.getClass()));
484         buffer.append(summaryObjectEndText);
485     }
486
487     //----------------------------------------------------------------------------
488

489     /**
490      * <p>Append to the <code>toString</code> a <code>long</code>
491      * value.</p>
492      *
493      * @param buffer the <code>StringBuffer</code> to populate
494      * @param fieldName the field name
495      * @param value the value to add to the <code>toString</code>
496      */

497     public void append(StringBuffer JavaDoc buffer, String JavaDoc fieldName, long value) {
498         appendFieldStart(buffer, fieldName);
499         appendDetail(buffer, fieldName, value);
500         appendFieldEnd(buffer, fieldName);
501     }
502
503     /**
504      * <p>Append to the <code>toString</code> a <code>long</code>
505      * value.</p>
506      *
507      * @param buffer the <code>StringBuffer</code> to populate
508      * @param fieldName the field name, typically not used as already appended
509      * @param value the value to add to the <code>toString</code>
510      */

511     protected void appendDetail(StringBuffer JavaDoc buffer, String JavaDoc fieldName, long value) {
512         buffer.append(value);
513     }
514
515     //----------------------------------------------------------------------------
516

517     /**
518      * <p>Append to the <code>toString</code> an <code>int</code>
519      * value.</p>
520      *
521      * @param buffer the <code>StringBuffer</code> to populate
522      * @param fieldName the field name
523      * @param value the value to add to the <code>toString</code>
524      */

525     public void append(StringBuffer JavaDoc buffer, String JavaDoc fieldName, int value) {
526         appendFieldStart(buffer, fieldName);
527         appendDetail(buffer, fieldName, value);
528         appendFieldEnd(buffer, fieldName);
529     }
530
531     /**
532      * <p>Append to the <code>toString</code> an <code>int</code>
533      * value.</p>
534      *
535      * @param buffer the <code>StringBuffer</code> to populate
536      * @param fieldName the field name, typically not used as already appended
537      * @param value the value to add to the <code>toString</code>
538      */

539     protected void appendDetail(StringBuffer JavaDoc buffer, String JavaDoc fieldName, int value) {
540         buffer.append(value);
541     }
542
543     //----------------------------------------------------------------------------
544

545     /**
546      * <p>Append to the <code>toString</code> a <code>short</code>
547      * value.</p>
548      *
549      * @param buffer the <code>StringBuffer</code> to populate
550      * @param fieldName the field name
551      * @param value the value to add to the <code>toString</code>
552      */

553     public void append(StringBuffer JavaDoc buffer, String JavaDoc fieldName, short value) {
554         appendFieldStart(buffer, fieldName);
555         appendDetail(buffer, fieldName, value);
556         appendFieldEnd(buffer, fieldName);
557     }
558
559     /**
560      * <p>Append to the <code>toString</code> a <code>short</code>
561      * value.</p>
562      *
563      * @param buffer the <code>StringBuffer</code> to populate
564      * @param fieldName the field name, typically not used as already appended
565      * @param value the value to add to the <code>toString</code>
566      */

567     protected void appendDetail(StringBuffer JavaDoc buffer, String JavaDoc fieldName, short value) {
568         buffer.append(value);
569     }
570
571     //----------------------------------------------------------------------------
572

573     /**
574      * <p>Append to the <code>toString</code> a <code>byte</code>
575      * value.</p>
576      *
577      * @param buffer the <code>StringBuffer</code> to populate
578      * @param fieldName the field name
579      * @param value the value to add to the <code>toString</code>
580      */

581     public void append(StringBuffer JavaDoc buffer, String JavaDoc fieldName, byte value) {
582         appendFieldStart(buffer, fieldName);
583         appendDetail(buffer, fieldName, value);
584         appendFieldEnd(buffer, fieldName);
585     }
586
587     /**
588      * <p>Append to the <code>toString</code> a <code>byte</code>
589      * value.</p>
590      *
591      * @param buffer the <code>StringBuffer</code> to populate
592      * @param fieldName the field name, typically not used as already appended
593      * @param value the value to add to the <code>toString</code>
594      */

595     protected void appendDetail(StringBuffer JavaDoc buffer, String JavaDoc fieldName, byte value) {
596         buffer.append(value);
597     }
598
599     //----------------------------------------------------------------------------
600

601     /**
602      * <p>Append to the <code>toString</code> a <code>char</code>
603      * value.</p>
604      *
605      * @param buffer the <code>StringBuffer</code> to populate
606      * @param fieldName the field name
607      * @param value the value to add to the <code>toString</code>
608      */

609     public void append(StringBuffer JavaDoc buffer, String JavaDoc fieldName, char value) {
610         appendFieldStart(buffer, fieldName);
611         appendDetail(buffer, fieldName, value);
612         appendFieldEnd(buffer, fieldName);
613     }
614
615     /**
616      * <p>Append to the <code>toString</code> a <code>char</code>
617      * value.</p>
618      *
619      * @param buffer the <code>StringBuffer</code> to populate
620      * @param fieldName the field name, typically not used as already appended
621      * @param value the value to add to the <code>toString</code>
622      */

623     protected void appendDetail(StringBuffer JavaDoc buffer, String JavaDoc fieldName, char value) {
624         buffer.append(value);
625     }
626
627     //----------------------------------------------------------------------------
628

629     /**
630      * <p>Append to the <code>toString</code> a <code>double</code>
631      * value.</p>
632      *
633      * @param buffer the <code>StringBuffer</code> to populate
634      * @param fieldName the field name
635      * @param value the value to add to the <code>toString</code>
636      */

637     public void append(StringBuffer JavaDoc buffer, String JavaDoc fieldName, double value) {
638         appendFieldStart(buffer, fieldName);
639         appendDetail(buffer, fieldName, value);
640         appendFieldEnd(buffer, fieldName);
641     }
642
643     /**
644      * <p>Append to the <code>toString</code> a <code>double</code>
645      * value.</p>
646      *
647      * @param buffer the <code>StringBuffer</code> to populate
648      * @param fieldName the field name, typically not used as already appended
649      * @param value the value to add to the <code>toString</code>
650      */

651     protected void appendDetail(StringBuffer JavaDoc buffer, String JavaDoc fieldName, double value) {
652         buffer.append(value);
653     }
654
655     //----------------------------------------------------------------------------
656

657     /**
658      * <p>Append to the <code>toString</code> a <code>float</code>
659      * value.</p>
660      *
661      * @param buffer the <code>StringBuffer</code> to populate
662      * @param fieldName the field name
663      * @param value the value to add to the <code>toString</code>
664      */

665     public void append(StringBuffer JavaDoc buffer, String JavaDoc fieldName, float value) {
666         appendFieldStart(buffer, fieldName);
667         appendDetail(buffer, fieldName, value);
668         appendFieldEnd(buffer, fieldName);
669     }
670
671     /**
672      * <p>Append to the <code>toString</code> a <code>float</code>
673      * value.</p>
674      *
675      * @param buffer the <code>StringBuffer</code> to populate
676      * @param fieldName the field name, typically not used as already appended
677      * @param value the value to add to the <code>toString</code>
678      */

679     protected void appendDetail(StringBuffer JavaDoc buffer, String JavaDoc fieldName, float value) {
680         buffer.append(value);
681     }
682
683     //----------------------------------------------------------------------------
684

685     /**
686      * <p>Append to the <code>toString</code> a <code>boolean</code>
687      * value.</p>
688      *
689      * @param buffer the <code>StringBuffer</code> to populate
690      * @param fieldName the field name
691      * @param value the value to add to the <code>toString</code>
692      */

693     public void append(StringBuffer JavaDoc buffer, String JavaDoc fieldName, boolean value) {
694         appendFieldStart(buffer, fieldName);
695         appendDetail(buffer, fieldName, value);
696         appendFieldEnd(buffer, fieldName);
697     }
698
699     /**
700      * <p>Append to the <code>toString</code> a <code>boolean</code>
701      * value.</p>
702      *
703      * @param buffer the <code>StringBuffer</code> to populate
704      * @param fieldName the field name, typically not used as already appended
705      * @param value the value to add to the <code>toString</code>
706      */

707     protected void appendDetail(StringBuffer JavaDoc buffer, String JavaDoc fieldName, boolean value) {
708         buffer.append(value);
709     }
710
711     /**
712      * <p>Append to the <code>toString</code> an <code>Object</code>
713      * array.</p>
714      *
715      * @param buffer the <code>StringBuffer</code> to populate
716      * @param fieldName the field name
717      * @param array the array to add to the toString
718      * @param fullDetail <code>true</code> for detail, <code>false</code>
719      * for summary info, <code>null</code> for style decides
720      */

721     public void append(StringBuffer JavaDoc buffer, String JavaDoc fieldName, Object JavaDoc[] array, Boolean JavaDoc fullDetail) {
722         appendFieldStart(buffer, fieldName);
723
724         if (array == null) {
725             appendNullText(buffer, fieldName);
726
727         } else if (isFullDetail(fullDetail)) {
728             appendDetail(buffer, fieldName, array);
729
730         } else {
731             appendSummary(buffer, fieldName, array);
732         }
733
734         appendFieldEnd(buffer, fieldName);
735     }
736
737     //----------------------------------------------------------------------------
738

739     /**
740      * <p>Append to the <code>toString</code> the detail of an
741      * <code>Object</code> array.</p>
742      *
743      * @param buffer the <code>StringBuffer</code> to populate
744      * @param fieldName the field name, typically not used as already appended
745      * @param array the array to add to the <code>toString</code>,
746      * not <code>null</code>
747      */

748     protected void appendDetail(StringBuffer JavaDoc buffer, String JavaDoc fieldName, Object JavaDoc[] array) {
749         buffer.append(arrayStart);
750         for (int i = 0; i < array.length; i++) {
751             Object JavaDoc item = array[i];
752             if (i > 0) {
753                 buffer.append(arraySeparator);
754             }
755             if (item == null) {
756                 appendNullText(buffer, fieldName);
757
758             } else {
759                 appendInternal(buffer, fieldName, item, arrayContentDetail);
760             }
761         }
762         buffer.append(arrayEnd);
763     }
764
765     /**
766      * <p>Append to the <code>toString</code> the detail of an array type.</p>
767      *
768      * @param buffer the <code>StringBuffer</code> to populate
769      * @param fieldName the field name, typically not used as already appended
770      * @param array the array to add to the <code>toString</code>,
771      * not <code>null</code>
772      * @since 2.0
773      */

774     protected void reflectionAppendArrayDetail(StringBuffer JavaDoc buffer, String JavaDoc fieldName, Object JavaDoc array) {
775         buffer.append(arrayStart);
776         int length = Array.getLength(array);
777         for (int i = 0; i < length; i++) {
778             Object JavaDoc item = Array.get(array, i);
779             if (i > 0) {
780                 buffer.append(arraySeparator);
781             }
782             if (item == null) {
783                 appendNullText(buffer, fieldName);
784
785             } else {
786                 appendInternal(buffer, fieldName, item, arrayContentDetail);
787             }
788         }
789         buffer.append(arrayEnd);
790     }
791
792     /**
793      * <p>Append to the <code>toString</code> a summary of an
794      * <code>Object</code> array.</p>
795      *
796      * @param buffer the <code>StringBuffer</code> to populate
797      * @param fieldName the field name, typically not used as already appended
798      * @param array the array to add to the <code>toString</code>,
799      * not <code>null</code>
800      */

801     protected void appendSummary(StringBuffer JavaDoc buffer, String JavaDoc fieldName, Object JavaDoc[] array) {
802         appendSummarySize(buffer, fieldName, array.length);
803     }
804
805     //----------------------------------------------------------------------------
806

807     /**
808      * <p>Append to the <code>toString</code> a <code>long</code>
809      * array.</p>
810      *
811      * @param buffer the <code>StringBuffer</code> to populate
812      * @param fieldName the field name
813      * @param array the array to add to the <code>toString</code>
814      * @param fullDetail <code>true</code> for detail, <code>false</code>
815      * for summary info, <code>null</code> for style decides
816      */

817     public void append(StringBuffer JavaDoc buffer, String JavaDoc fieldName, long[] array, Boolean JavaDoc fullDetail) {
818         appendFieldStart(buffer, fieldName);
819
820         if (array == null) {
821             appendNullText(buffer, fieldName);
822
823         } else if (isFullDetail(fullDetail)) {
824             appendDetail(buffer, fieldName, array);
825
826         } else {
827             appendSummary(buffer, fieldName, array);
828         }
829
830         appendFieldEnd(buffer, fieldName);
831     }
832
833     /**
834      * <p>Append to the <code>toString</code> the detail of a
835      * <code>long</code> array.</p>
836      *
837      * @param buffer the <code>StringBuffer</code> to populate
838      * @param fieldName the field name, typically not used as already appended
839      * @param array the array to add to the <code>toString</code>,
840      * not <code>null</code>
841      */

842     protected void appendDetail(StringBuffer JavaDoc buffer, String JavaDoc fieldName, long[] array) {
843         buffer.append(arrayStart);
844         for (int i = 0; i < array.length; i++) {
845             if (i > 0) {
846                 buffer.append(arraySeparator);
847             }
848             appendDetail(buffer, fieldName, array[i]);
849         }
850         buffer.append(arrayEnd);
851     }
852
853     /**
854      * <p>Append to the <code>toString</code> a summary of a
855      * <code>long</code> array.</p>
856      *
857      * @param buffer the <code>StringBuffer</code> to populate
858      * @param fieldName the field name, typically not used as already appended
859      * @param array the array to add to the <code>toString</code>,
860      * not <code>null</code>
861      */

862     protected void appendSummary(StringBuffer JavaDoc buffer, String JavaDoc fieldName, long[] array) {
863         appendSummarySize(buffer, fieldName, array.length);
864     }
865
866     //----------------------------------------------------------------------------
867

868     /**
869      * <p>Append to the <code>toString</code> an <code>int</code>
870      * array.</p>
871      *
872      * @param buffer the <code>StringBuffer</code> to populate
873      * @param fieldName the field name
874      * @param array the array to add to the <code>toString</code>
875      * @param fullDetail <code>true</code> for detail, <code>false</code>
876      * for summary info, <code>null</code> for style decides
877      */

878     public void append(StringBuffer