source: src/main/java/agents/org/apache/commons/lang/builder/ToStringStyle.java

Last change on this file was 127, checked in by Wouter Pasman, 6 years ago

#41 ROLL BACK of rev.126 . So this version is equal to rev. 125

File size: 76.0 KB
Line 
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17package agents.org.apache.commons.lang.builder;
18
19import java.io.Serializable;
20import java.lang.reflect.Array;
21import java.util.Collection;
22import java.util.Map;
23import java.util.WeakHashMap;
24
25import agents.org.apache.commons.lang.ClassUtils;
26import agents.org.apache.commons.lang.ObjectUtils;
27import agents.org.apache.commons.lang.SystemUtils;
28
29/**
30 * <p>Controls <code>String</code> formatting for {@link ToStringBuilder}.
31 * The main public interface is always via <code>ToStringBuilder</code>.</p>
32 *
33 * <p>These classes are intended to be used as <code>Singletons</code>.
34 * There is no need to instantiate a new style each time. A program
35 * will generally use one of the predefined constants on this class.
36 * Alternatively, the {@link StandardToStringStyle} class can be used
37 * to set the individual settings. Thus most styles can be achieved
38 * without subclassing.</p>
39 *
40 * <p>If required, a subclass can override as many or as few of the
41 * methods as it requires. Each object type (from <code>boolean</code>
42 * to <code>long</code> to <code>Object</code> to <code>int[]</code>) has
43 * its own methods to output it. Most have two versions, detail and summary.
44 *
45 * <p>For example, the detail version of the array based methods will
46 * output the whole array, whereas the summary method will just output
47 * the array length.</p>
48 *
49 * <p>If you want to format the output of certain objects, such as dates, you
50 * must create a subclass and override a method.
51 * <pre>
52 * public class MyStyle extends ToStringStyle {
53 * protected void appendDetail(StringBuffer buffer, String fieldName, Object value) {
54 * if (value instanceof Date) {
55 * value = new SimpleDateFormat("yyyy-MM-dd").format(value);
56 * }
57 * buffer.append(value);
58 * }
59 * }
60 * </pre>
61 * </p>
62 *
63 * @author Apache Software Foundation
64 * @author Gary Gregory
65 * @author Pete Gieser
66 * @author Masato Tezuka
67 * @since 1.0
68 * @version $Id: ToStringStyle.java 907168 2010-02-06 03:33:50Z mbenson $
69 */
70public abstract class ToStringStyle implements Serializable {
71
72 /**
73 * The default toString style. Using the Using the <code>Person</code>
74 * example from {@link ToStringBuilder}, the output would look like this:
75 *
76 * <pre>
77 * Person@182f0db[name=John Doe,age=33,smoker=false]
78 * </pre>
79 */
80 public static final ToStringStyle DEFAULT_STYLE = new DefaultToStringStyle();
81
82 /**
83 * The multi line toString style. Using the Using the <code>Person</code>
84 * example from {@link ToStringBuilder}, the output would look like this:
85 *
86 * <pre>
87 * Person@182f0db[
88 * name=John Doe
89 * age=33
90 * smoker=false
91 * ]
92 * </pre>
93 */
94 public static final ToStringStyle MULTI_LINE_STYLE = new MultiLineToStringStyle();
95
96 /**
97 * The no field names toString style. Using the Using the
98 * <code>Person</code> example from {@link ToStringBuilder}, the output
99 * would look like this:
100 *
101 * <pre>
102 * Person@182f0db[John Doe,33,false]
103 * </pre>
104 */
105 public static final ToStringStyle NO_FIELD_NAMES_STYLE = new NoFieldNameToStringStyle();
106
107 /**
108 * The short prefix toString style. Using the <code>Person</code> example
109 * from {@link ToStringBuilder}, the output would look like this:
110 *
111 * <pre>
112 * Person[name=John Doe,age=33,smoker=false]
113 * </pre>
114 *
115 * @since 2.1
116 */
117 public static final ToStringStyle SHORT_PREFIX_STYLE = new ShortPrefixToStringStyle();
118
119 /**
120 * The simple toString style. Using the Using the <code>Person</code>
121 * example from {@link ToStringBuilder}, the output would look like this:
122 *
123 * <pre>
124 * John Doe,33,false
125 * </pre>
126 */
127 public static final ToStringStyle SIMPLE_STYLE = new SimpleToStringStyle();
128
129 /**
130 * <p>
131 * A registry of objects used by <code>reflectionToString</code> methods
132 * to detect cyclical object references and avoid infinite loops.
133 * </p>
134 */
135 private static final ThreadLocal REGISTRY = new ThreadLocal();
136
137 /**
138 * <p>
139 * Returns the registry of objects being traversed by the <code>reflectionToString</code>
140 * methods in the current thread.
141 * </p>
142 *
143 * @return Set the registry of objects being traversed
144 */
145 static Map getRegistry() {
146 return (Map) REGISTRY.get();
147 }
148
149 /**
150 * <p>
151 * Returns <code>true</code> if the registry contains the given object.
152 * Used by the reflection methods to avoid infinite loops.
153 * </p>
154 *
155 * @param value
156 * The object to lookup in the registry.
157 * @return boolean <code>true</code> if the registry contains the given
158 * object.
159 */
160 static boolean isRegistered(Object value) {
161 Map m = getRegistry();
162 return m != null && m.containsKey(value);
163 }
164
165 /**
166 * <p>
167 * Registers the given object. Used by the reflection methods to avoid
168 * infinite loops.
169 * </p>
170 *
171 * @param value
172 * The object to register.
173 */
174 static void register(Object value) {
175 if (value != null) {
176 Map m = getRegistry();
177 if (m == null) {
178 m = new WeakHashMap();
179 REGISTRY.set(m);
180 }
181 m.put(value, null);
182 }
183 }
184
185 /**
186 * <p>
187 * Unregisters the given object.
188 * </p>
189 *
190 * <p>
191 * Used by the reflection methods to avoid infinite loops.
192 * </p>
193 *
194 * @param value
195 * The object to unregister.
196 */
197 static void unregister(Object value) {
198 if (value != null) {
199 Map m = getRegistry();
200 if (m != null) {
201 m.remove(value);
202 if (m.isEmpty()) {
203 REGISTRY.set(null);
204 }
205 }
206 }
207 }
208
209 /**
210 * Whether to use the field names, the default is <code>true</code>.
211 */
212 private boolean useFieldNames = true;
213
214 /**
215 * Whether to use the class name, the default is <code>true</code>.
216 */
217 private boolean useClassName = true;
218
219 /**
220 * Whether to use short class names, the default is <code>false</code>.
221 */
222 private boolean useShortClassName = false;
223
224 /**
225 * Whether to use the identity hash code, the default is <code>true</code>.
226 */
227 private boolean useIdentityHashCode = true;
228
229 /**
230 * The content start <code>'['</code>.
231 */
232 private String contentStart = "[";
233
234 /**
235 * The content end <code>']'</code>.
236 */
237 private String contentEnd = "]";
238
239 /**
240 * The field name value separator <code>'='</code>.
241 */
242 private String fieldNameValueSeparator = "=";
243
244 /**
245 * Whether the field separator should be added before any other fields.
246 */
247 private boolean fieldSeparatorAtStart = false;
248
249 /**
250 * Whether the field separator should be added after any other fields.
251 */
252 private boolean fieldSeparatorAtEnd = false;
253
254 /**
255 * The field separator <code>','</code>.
256 */
257 private String fieldSeparator = ",";
258
259 /**
260 * The array start <code>'{'</code>.
261 */
262 private String arrayStart = "{";
263
264 /**
265 * The array separator <code>','</code>.
266 */
267 private String arraySeparator = ",";
268
269 /**
270 * The detail for array content.
271 */
272 private boolean arrayContentDetail = true;
273
274 /**
275 * The array end <code>'}'</code>.
276 */
277 private String arrayEnd = "}";
278
279 /**
280 * The value to use when fullDetail is <code>null</code>,
281 * the default value is <code>true</code>.
282 */
283 private boolean defaultFullDetail = true;
284
285 /**
286 * The <code>null</code> text <code>'&lt;null&gt;'</code>.
287 */
288 private String nullText = "<null>";
289
290 /**
291 * The summary size text start <code>'<size'</code>.
292 */
293 private String sizeStartText = "<size=";
294
295 /**
296 * The summary size text start <code>'&gt;'</code>.
297 */
298 private String sizeEndText = ">";
299
300 /**
301 * The summary object text start <code>'&lt;'</code>.
302 */
303 private String summaryObjectStartText = "<";
304
305 /**
306 * The summary object text start <code>'&gt;'</code>.
307 */
308 private String summaryObjectEndText = ">";
309
310 //----------------------------------------------------------------------------
311
312 /**
313 * <p>Constructor.</p>
314 */
315 protected ToStringStyle() {
316 super();
317 }
318
319 //----------------------------------------------------------------------------
320
321 /**
322 * <p>Append to the <code>toString</code> the superclass toString.</p>
323 * <p>NOTE: It assumes that the toString has been created from the same ToStringStyle. </p>
324 *
325 * <p>A <code>null</code> <code>superToString</code> is ignored.</p>
326 *
327 * @param buffer the <code>StringBuffer</code> to populate
328 * @param superToString the <code>super.toString()</code>
329 * @since 2.0
330 */
331 public void appendSuper(StringBuffer buffer, String superToString) {
332 appendToString(buffer, superToString);
333 }
334
335 /**
336 * <p>Append to the <code>toString</code> another toString.</p>
337 * <p>NOTE: It assumes that the toString has been created from the same ToStringStyle. </p>
338 *
339 * <p>A <code>null</code> <code>toString</code> is ignored.</p>
340 *
341 * @param buffer the <code>StringBuffer</code> to populate
342 * @param toString the additional <code>toString</code>
343 * @since 2.0
344 */
345 public void appendToString(StringBuffer buffer, String toString) {
346 if (toString != null) {
347 int pos1 = toString.indexOf(contentStart) + contentStart.length();
348 int pos2 = toString.lastIndexOf(contentEnd);
349 if (pos1 != pos2 && pos1 >= 0 && pos2 >= 0) {
350 String data = toString.substring(pos1, pos2);
351 if (fieldSeparatorAtStart) {
352 removeLastFieldSeparator(buffer);
353 }
354 buffer.append(data);
355 appendFieldSeparator(buffer);
356 }
357 }
358 }
359
360 /**
361 * <p>Append to the <code>toString</code> the start of data indicator.</p>
362 *
363 * @param buffer the <code>StringBuffer</code> to populate
364 * @param object the <code>Object</code> to build a <code>toString</code> for
365 */
366 public void appendStart(StringBuffer buffer, Object object) {
367 if (object != null) {
368 appendClassName(buffer, object);
369 appendIdentityHashCode(buffer, object);
370 appendContentStart(buffer);
371 if (fieldSeparatorAtStart) {
372 appendFieldSeparator(buffer);
373 }
374 }
375 }
376
377 /**
378 * <p>Append to the <code>toString</code> the end of data indicator.</p>
379 *
380 * @param buffer the <code>StringBuffer</code> to populate
381 * @param object the <code>Object</code> to build a
382 * <code>toString</code> for.
383 */
384 public void appendEnd(StringBuffer buffer, Object object) {
385 if (this.fieldSeparatorAtEnd == false) {
386 removeLastFieldSeparator(buffer);
387 }
388 appendContentEnd(buffer);
389 unregister(object);
390 }
391
392 /**
393 * <p>Remove the last field separator from the buffer.</p>
394 *
395 * @param buffer the <code>StringBuffer</code> to populate
396 * @since 2.0
397 */
398 protected void removeLastFieldSeparator(StringBuffer buffer) {
399 int len = buffer.length();
400 int sepLen = fieldSeparator.length();
401 if (len > 0 && sepLen > 0 && len >= sepLen) {
402 boolean match = true;
403 for (int i = 0; i < sepLen; i++) {
404 if (buffer.charAt(len - 1 - i) != fieldSeparator.charAt(sepLen - 1 - i)) {
405 match = false;
406 break;
407 }
408 }
409 if (match) {
410 buffer.setLength(len - sepLen);
411 }
412 }
413 }
414
415 //----------------------------------------------------------------------------
416
417 /**
418 * <p>Append to the <code>toString</code> an <code>Object</code>
419 * value, printing the full <code>toString</code> of the
420 * <code>Object</code> passed in.</p>
421 *
422 * @param buffer the <code>StringBuffer</code> to populate
423 * @param fieldName the field name
424 * @param value the value to add to the <code>toString</code>
425 * @param fullDetail <code>true</code> for detail, <code>false</code>
426 * for summary info, <code>null</code> for style decides
427 */
428 public void append(StringBuffer buffer, String fieldName, Object value, Boolean fullDetail) {
429 appendFieldStart(buffer, fieldName);
430
431 if (value == null) {
432 appendNullText(buffer, fieldName);
433
434 } else {
435 appendInternal(buffer, fieldName, value, isFullDetail(fullDetail));
436 }
437
438 appendFieldEnd(buffer, fieldName);
439 }
440
441 /**
442 * <p>Append to the <code>toString</code> an <code>Object</code>,
443 * correctly interpreting its type.</p>
444 *
445 * <p>This method performs the main lookup by Class type to correctly
446 * route arrays, <code>Collections</code>, <code>Maps</code> and
447 * <code>Objects</code> to the appropriate method.</p>
448 *
449 * <p>Either detail or summary views can be specified.</p>
450 *
451 * <p>If a cycle is detected, an object will be appended with the
452 * <code>Object.toString()</code> format.</p>
453 *
454 * @param buffer the <code>StringBuffer</code> to populate
455 * @param fieldName the field name, typically not used as already appended
456 * @param value the value to add to the <code>toString</code>,
457 * not <code>null</code>
458 * @param detail output detail or not
459 */
460 protected void appendInternal(StringBuffer buffer, String fieldName, Object value, boolean detail) {
461 if (isRegistered(value)
462 && !(value instanceof Number || value instanceof Boolean || value instanceof Character)) {
463 appendCyclicObject(buffer, fieldName, value);
464 return;
465 }
466
467 register(value);
468
469 try {
470 if (value instanceof Collection) {
471 if (detail) {
472 appendDetail(buffer, fieldName, (Collection) value);
473 } else {
474 appendSummarySize(buffer, fieldName, ((Collection) value).size());
475 }
476
477 } else if (value instanceof Map) {
478 if (detail) {
479 appendDetail(buffer, fieldName, (Map) value);
480 } else {
481 appendSummarySize(buffer, fieldName, ((Map) value).size());
482 }
483
484 } else if (value instanceof long[]) {
485 if (detail) {
486 appendDetail(buffer, fieldName, (long[]) value);
487 } else {
488 appendSummary(buffer, fieldName, (long[]) value);
489 }
490
491 } else if (value instanceof int[]) {
492 if (detail) {
493 appendDetail(buffer, fieldName, (int[]) value);
494 } else {
495 appendSummary(buffer, fieldName, (int[]) value);
496 }
497
498 } else if (value instanceof short[]) {
499 if (detail) {
500 appendDetail(buffer, fieldName, (short[]) value);
501 } else {
502 appendSummary(buffer, fieldName, (short[]) value);
503 }
504
505 } else if (value instanceof byte[]) {
506 if (detail) {
507 appendDetail(buffer, fieldName, (byte[]) value);
508 } else {
509 appendSummary(buffer, fieldName, (byte[]) value);
510 }
511
512 } else if (value instanceof char[]) {
513 if (detail) {
514 appendDetail(buffer, fieldName, (char[]) value);
515 } else {
516 appendSummary(buffer, fieldName, (char[]) value);
517 }
518
519 } else if (value instanceof double[]) {
520 if (detail) {
521 appendDetail(buffer, fieldName, (double[]) value);
522 } else {
523 appendSummary(buffer, fieldName, (double[]) value);
524 }
525
526 } else if (value instanceof float[]) {
527 if (detail) {
528 appendDetail(buffer, fieldName, (float[]) value);
529 } else {
530 appendSummary(buffer, fieldName, (float[]) value);
531 }
532
533 } else if (value instanceof boolean[]) {
534 if (detail) {
535 appendDetail(buffer, fieldName, (boolean[]) value);
536 } else {
537 appendSummary(buffer, fieldName, (boolean[]) value);
538 }
539
540 } else if (value.getClass().isArray()) {
541 if (detail) {
542 appendDetail(buffer, fieldName, (Object[]) value);
543 } else {
544 appendSummary(buffer, fieldName, (Object[]) value);
545 }
546
547 } else {
548 if (detail) {
549 appendDetail(buffer, fieldName, value);
550 } else {
551 appendSummary(buffer, fieldName, value);
552 }
553 }
554 } finally {
555 unregister(value);
556 }
557 }
558
559 /**
560 * <p>Append to the <code>toString</code> an <code>Object</code>
561 * value that has been detected to participate in a cycle. This
562 * implementation will print the standard string value of the value.</p>
563 *
564 * @param buffer the <code>StringBuffer</code> to populate
565 * @param fieldName the field name, typically not used as already appended
566 * @param value the value to add to the <code>toString</code>,
567 * not <code>null</code>
568 *
569 * @since 2.2
570 */
571 protected void appendCyclicObject(StringBuffer buffer, String fieldName, Object value) {
572 ObjectUtils.identityToString(buffer, value);
573 }
574
575 /**
576 * <p>Append to the <code>toString</code> an <code>Object</code>
577 * value, printing the full detail of the <code>Object</code>.</p>
578 *
579 * @param buffer the <code>StringBuffer</code> to populate
580 * @param fieldName the field name, typically not used as already appended
581 * @param value the value to add to the <code>toString</code>,
582 * not <code>null</code>
583 */
584 protected void appendDetail(StringBuffer buffer, String fieldName, Object value) {
585 buffer.append(value);
586 }
587
588 /**
589 * <p>Append to the <code>toString</code> a <code>Collection</code>.</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 coll the <code>Collection</code> to add to the
594 * <code>toString</code>, not <code>null</code>
595 */
596 protected void appendDetail(StringBuffer buffer, String fieldName, Collection coll) {
597 buffer.append(coll);
598 }
599
600 /**
601 * <p>Append to the <code>toString</code> a <code>Map<code>.</p>
602 *
603 * @param buffer the <code>StringBuffer</code> to populate
604 * @param fieldName the field name, typically not used as already appended
605 * @param map the <code>Map</code> to add to the <code>toString</code>,
606 * not <code>null</code>
607 */
608 protected void appendDetail(StringBuffer buffer, String fieldName, Map map) {
609 buffer.append(map);
610 }
611
612 /**
613 * <p>Append to the <code>toString</code> an <code>Object</code>
614 * value, printing a summary of the <code>Object</code>.</P>
615 *
616 * @param buffer the <code>StringBuffer</code> to populate
617 * @param fieldName the field name, typically not used as already appended
618 * @param value the value to add to the <code>toString</code>,
619 * not <code>null</code>
620 */
621 protected void appendSummary(StringBuffer buffer, String fieldName, Object value) {
622 buffer.append(summaryObjectStartText);
623 buffer.append(getShortClassName(value.getClass()));
624 buffer.append(summaryObjectEndText);
625 }
626
627 //----------------------------------------------------------------------------
628
629 /**
630 * <p>Append to the <code>toString</code> a <code>long</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 buffer, String fieldName, long 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>long</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 buffer, String fieldName, long value) {
652 buffer.append(value);
653 }
654
655 //----------------------------------------------------------------------------
656
657 /**
658 * <p>Append to the <code>toString</code> an <code>int</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 buffer, String fieldName, int 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> an <code>int</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 buffer, String fieldName, int value) {
680 buffer.append(value);
681 }
682
683 //----------------------------------------------------------------------------
684
685 /**
686 * <p>Append to the <code>toString</code> a <code>short</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 buffer, String fieldName, short 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>short</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 buffer, String fieldName, short value) {
708 buffer.append(value);
709 }
710
711 //----------------------------------------------------------------------------
712
713 /**
714 * <p>Append to the <code>toString</code> a <code>byte</code>
715 * value.</p>
716 *
717 * @param buffer the <code>StringBuffer</code> to populate
718 * @param fieldName the field name
719 * @param value the value to add to the <code>toString</code>
720 */
721 public void append(StringBuffer buffer, String fieldName, byte value) {
722 appendFieldStart(buffer, fieldName);
723 appendDetail(buffer, fieldName, value);
724 appendFieldEnd(buffer, fieldName);
725 }
726
727 /**
728 * <p>Append to the <code>toString</code> a <code>byte</code>
729 * value.</p>
730 *
731 * @param buffer the <code>StringBuffer</code> to populate
732 * @param fieldName the field name, typically not used as already appended
733 * @param value the value to add to the <code>toString</code>
734 */
735 protected void appendDetail(StringBuffer buffer, String fieldName, byte value) {
736 buffer.append(value);
737 }
738
739 //----------------------------------------------------------------------------
740
741 /**
742 * <p>Append to the <code>toString</code> a <code>char</code>
743 * value.</p>
744 *
745 * @param buffer the <code>StringBuffer</code> to populate
746 * @param fieldName the field name
747 * @param value the value to add to the <code>toString</code>
748 */
749 public void append(StringBuffer buffer, String fieldName, char value) {
750 appendFieldStart(buffer, fieldName);
751 appendDetail(buffer, fieldName, value);
752 appendFieldEnd(buffer, fieldName);
753 }
754
755 /**
756 * <p>Append to the <code>toString</code> a <code>char</code>
757 * value.</p>
758 *
759 * @param buffer the <code>StringBuffer</code> to populate
760 * @param fieldName the field name, typically not used as already appended
761 * @param value the value to add to the <code>toString</code>
762 */
763 protected void appendDetail(StringBuffer buffer, String fieldName, char value) {
764 buffer.append(value);
765 }
766
767 //----------------------------------------------------------------------------
768
769 /**
770 * <p>Append to the <code>toString</code> a <code>double</code>
771 * value.</p>
772 *
773 * @param buffer the <code>StringBuffer</code> to populate
774 * @param fieldName the field name
775 * @param value the value to add to the <code>toString</code>
776 */
777 public void append(StringBuffer buffer, String fieldName, double value) {
778 appendFieldStart(buffer, fieldName);
779 appendDetail(buffer, fieldName, value);
780 appendFieldEnd(buffer, fieldName);
781 }
782
783 /**
784 * <p>Append to the <code>toString</code> a <code>double</code>
785 * value.</p>
786 *
787 * @param buffer the <code>StringBuffer</code> to populate
788 * @param fieldName the field name, typically not used as already appended
789 * @param value the value to add to the <code>toString</code>
790 */
791 protected void appendDetail(StringBuffer buffer, String fieldName, double value) {
792 buffer.append(value);
793 }
794
795 //----------------------------------------------------------------------------
796
797 /**
798 * <p>Append to the <code>toString</code> a <code>float</code>
799 * value.</p>
800 *
801 * @param buffer the <code>StringBuffer</code> to populate
802 * @param fieldName the field name
803 * @param value the value to add to the <code>toString</code>
804 */
805 public void append(StringBuffer buffer, String fieldName, float value) {
806 appendFieldStart(buffer, fieldName);
807 appendDetail(buffer, fieldName, value);
808 appendFieldEnd(buffer, fieldName);
809 }
810
811 /**
812 * <p>Append to the <code>toString</code> a <code>float</code>
813 * value.</p>
814 *
815 * @param buffer the <code>StringBuffer</code> to populate
816 * @param fieldName the field name, typically not used as already appended
817 * @param value the value to add to the <code>toString</code>
818 */
819 protected void appendDetail(StringBuffer buffer, String fieldName, float value) {
820 buffer.append(value);
821 }
822
823 //----------------------------------------------------------------------------
824
825 /**
826 * <p>Append to the <code>toString</code> a <code>boolean</code>
827 * value.</p>
828 *
829 * @param buffer the <code>StringBuffer</code> to populate
830 * @param fieldName the field name
831 * @param value the value to add to the <code>toString</code>
832 */
833 public void append(StringBuffer buffer, String fieldName, boolean value) {
834 appendFieldStart(buffer, fieldName);
835 appendDetail(buffer, fieldName, value);
836 appendFieldEnd(buffer, fieldName);
837 }
838
839 /**
840 * <p>Append to the <code>toString</code> a <code>boolean</code>
841 * value.</p>
842 *
843 * @param buffer the <code>StringBuffer</code> to populate
844 * @param fieldName the field name, typically not used as already appended
845 * @param value the value to add to the <code>toString</code>
846 */
847 protected void appendDetail(StringBuffer buffer, String fieldName, boolean value) {
848 buffer.append(value);
849 }
850
851 /**
852 * <p>Append to the <code>toString</code> an <code>Object</code>
853 * array.</p>
854 *
855 * @param buffer the <code>StringBuffer</code> to populate
856 * @param fieldName the field name
857 * @param array the array to add to the toString
858 * @param fullDetail <code>true</code> for detail, <code>false</code>
859 * for summary info, <code>null</code> for style decides
860 */
861 public void append(StringBuffer buffer, String fieldName, Object[] array, Boolean fullDetail) {
862 appendFieldStart(buffer, fieldName);
863
864 if (array == null) {
865 appendNullText(buffer, fieldName);
866
867 } else if (isFullDetail(fullDetail)) {
868 appendDetail(buffer, fieldName, array);
869
870 } else {
871 appendSummary(buffer, fieldName, array);
872 }
873
874 appendFieldEnd(buffer, fieldName);
875 }
876
877 //----------------------------------------------------------------------------
878
879 /**
880 * <p>Append to the <code>toString</code> the detail of an
881 * <code>Object</code> array.</p>
882 *
883 * @param buffer the <code>StringBuffer</code> to populate
884 * @param fieldName the field name, typically not used as already appended
885 * @param array the array to add to the <code>toString</code>,
886 * not <code>null</code>
887 */
888 protected void appendDetail(StringBuffer buffer, String fieldName, Object[] array) {
889 buffer.append(arrayStart);
890 for (int i = 0; i < array.length; i++) {
891 Object item = array[i];
892 if (i > 0) {
893 buffer.append(arraySeparator);
894 }
895 if (item == null) {
896 appendNullText(buffer, fieldName);
897
898 } else {
899 appendInternal(buffer, fieldName, item, arrayContentDetail);
900 }
901 }
902 buffer.append(arrayEnd);
903 }
904
905 /**
906 * <p>Append to the <code>toString</code> the detail of an array type.</p>
907 *
908 * @param buffer the <code>StringBuffer</code> to populate
909 * @param fieldName the field name, typically not used as already appended
910 * @param array the array to add to the <code>toString</code>,
911 * not <code>null</code>
912 * @since 2.0
913 */
914 protected void reflectionAppendArrayDetail(StringBuffer buffer, String fieldName, Object array) {
915 buffer.append(arrayStart);
916 int length = Array.getLength(array);
917 for (int i = 0; i < length; i++) {
918 Object item = Array.get(array, i);
919 if (i > 0) {
920 buffer.append(arraySeparator);
921 }
922 if (item == null) {
923 appendNullText(buffer, fieldName);
924
925 } else {
926 appendInternal(buffer, fieldName, item, arrayContentDetail);
927 }
928 }
929 buffer.append(arrayEnd);
930 }
931
932 /**
933 * <p>Append to the <code>toString</code> a summary of an
934 * <code>Object</code> array.</p>
935 *
936 * @param buffer the <code>StringBuffer</code> to populate
937 * @param fieldName the field name, typically not used as already appended
938 * @param array the array to add to the <code>toString</code>,
939 * not <code>null</code>
940 */
941 protected void appendSummary(StringBuffer buffer, String fieldName, Object[] array) {
942 appendSummarySize(buffer, fieldName, array.length);
943 }
944
945 //----------------------------------------------------------------------------
946
947 /**
948 * <p>Append to the <code>toString</code> a <code>long</code>
949 * array.</p>
950 *
951 * @param buffer the <code>StringBuffer</code> to populate
952 * @param fieldName the field name
953 * @param array the array to add to the <code>toString</code>
954 * @param fullDetail <code>true</code> for detail, <code>false</code>
955 * for summary info, <code>null</code> for style decides
956 */
957 public void append(StringBuffer buffer, String fieldName, long[] array, Boolean fullDetail) {
958 appendFieldStart(buffer, fieldName);
959
960 if (array == null) {
961 appendNullText(buffer, fieldName);
962
963 } else if (isFullDetail(fullDetail)) {
964 appendDetail(buffer, fieldName, array);
965
966 } else {
967 appendSummary(buffer, fieldName, array);
968 }
969
970 appendFieldEnd(buffer, fieldName);
971 }
972
973 /**
974 * <p>Append to the <code>toString</code> the detail of a
975 * <code>long</code> array.</p>
976 *
977 * @param buffer the <code>StringBuffer</code> to populate
978 * @param fieldName the field name, typically not used as already appended
979 * @param array the array to add to the <code>toString</code>,
980 * not <code>null</code>
981 */
982 protected void appendDetail(StringBuffer buffer, String fieldName, long[] array) {
983 buffer.append(arrayStart);
984 for (int i = 0; i < array.length; i++) {
985 if (i > 0) {
986 buffer.append(arraySeparator);
987 }
988 appendDetail(buffer, fieldName, array[i]);
989 }
990 buffer.append(arrayEnd);
991 }
992
993 /**
994 * <p>Append to the <code>toString</code> a summary of a
995 * <code>long</code> array.</p>
996 *
997 * @param buffer the <code>StringBuffer</code> to populate
998 * @param fieldName the field name, typically not used as already appended
999 * @param array the array to add to the <code>toString</code>,
1000 * not <code>null</code>
1001 */
1002 protected void appendSummary(StringBuffer buffer, String fieldName, long[] array) {
1003 appendSummarySize(buffer, fieldName, array.length);
1004 }
1005
1006 //----------------------------------------------------------------------------
1007
1008 /**
1009 * <p>Append to the <code>toString</code> an <code>int</code>
1010 * array.</p>
1011 *
1012 * @param buffer the <code>StringBuffer</code> to populate
1013 * @param fieldName the field name
1014 * @param array the array to add to the <code>toString</code>
1015 * @param fullDetail <code>true</code> for detail, <code>false</code>
1016 * for summary info, <code>null</code> for style decides
1017 */
1018 public void append(StringBuffer buffer, String fieldName, int[] array, Boolean fullDetail) {
1019 appendFieldStart(buffer, fieldName);
1020
1021 if (array == null) {
1022 appendNullText(buffer, fieldName);
1023
1024 } else if (isFullDetail(fullDetail)) {
1025 appendDetail(buffer, fieldName, array);
1026
1027 } else {
1028 appendSummary(buffer, fieldName, array);
1029 }
1030
1031 appendFieldEnd(buffer, fieldName);
1032 }
1033
1034 /**
1035 * <p>Append to the <code>toString</code> the detail of an
1036 * <code>int</code> array.</p>
1037 *
1038 * @param buffer the <code>StringBuffer</code> to populate
1039 * @param fieldName the field name, typically not used as already appended
1040 * @param array the array to add to the <code>toString</code>,
1041 * not <code>null</code>
1042 */
1043 protected void appendDetail(StringBuffer buffer, String fieldName, int[] array) {
1044 buffer.append(arrayStart);
1045 for (int i = 0; i < array.length; i++) {
1046 if (i > 0) {
1047 buffer.append(arraySeparator);
1048 }
1049 appendDetail(buffer, fieldName, array[i]);
1050 }
1051 buffer.append(arrayEnd);
1052 }
1053
1054 /**
1055 * <p>Append to the <code>toString</code> a summary of an
1056 * <code>int</code> array.</p>
1057 *
1058 * @param buffer the <code>StringBuffer</code> to populate
1059 * @param fieldName the field name, typically not used as already appended
1060 * @param array the array to add to the <code>toString</code>,
1061 * not <code>null</code>
1062 */
1063 protected void appendSummary(StringBuffer buffer, String fieldName, int[] array) {
1064 appendSummarySize(buffer, fieldName, array.length);
1065 }
1066
1067 //----------------------------------------------------------------------------
1068
1069 /**
1070 * <p>Append to the <code>toString</code> a <code>short</code>
1071 * array.</p>
1072 *
1073 * @param buffer the <code>StringBuffer</code> to populate
1074 * @param fieldName the field name
1075 * @param array the array to add to the <code>toString</code>
1076 * @param fullDetail <code>true</code> for detail, <code>false</code>
1077 * for summary info, <code>null</code> for style decides
1078 */
1079 public void append(StringBuffer buffer, String fieldName, short[] array, Boolean fullDetail) {
1080 appendFieldStart(buffer, fieldName);
1081
1082 if (array == null) {
1083 appendNullText(buffer, fieldName);
1084
1085 } else if (isFullDetail(fullDetail)) {
1086 appendDetail(buffer, fieldName, array);
1087
1088 } else {
1089 appendSummary(buffer, fieldName, array);
1090 }
1091
1092 appendFieldEnd(buffer, fieldName);
1093 }
1094
1095 /**
1096 * <p>Append to the <code>toString</code> the detail of a
1097 * <code>short</code> array.</p>
1098 *
1099 * @param buffer the <code>StringBuffer</code> to populate
1100 * @param fieldName the field name, typically not used as already appended
1101 * @param array the array to add to the <code>toString</code>,
1102 * not <code>null</code>
1103 */
1104 protected void appendDetail(StringBuffer buffer, String fieldName, short[] array) {
1105 buffer.append(arrayStart);
1106 for (int i = 0; i < array.length; i++) {
1107 if (i > 0) {
1108 buffer.append(arraySeparator);
1109 }
1110 appendDetail(buffer, fieldName, array[i]);
1111 }
1112 buffer.append(arrayEnd);
1113 }
1114
1115 /**
1116 * <p>Append to the <code>toString</code> a summary of a
1117 * <code>short</code> array.</p>
1118 *
1119 * @param buffer the <code>StringBuffer</code> to populate
1120 * @param fieldName the field name, typically not used as already appended
1121 * @param array the array to add to the <code>toString</code>,
1122 * not <code>null</code>
1123 */
1124 protected void appendSummary(StringBuffer buffer, String fieldName, short[] array) {
1125 appendSummarySize(buffer, fieldName, array.length);
1126 }
1127
1128 //----------------------------------------------------------------------------
1129
1130 /**
1131 * <p>Append to the <code>toString</code> a <code>byte</code>
1132 * array.</p>
1133 *
1134 * @param buffer the <code>StringBuffer</code> to populate
1135 * @param fieldName the field name
1136 * @param array the array to add to the <code>toString</code>
1137 * @param fullDetail <code>true</code> for detail, <code>false</code>
1138 * for summary info, <code>null</code> for style decides
1139 */
1140 public void append(StringBuffer buffer, String fieldName, byte[] array, Boolean fullDetail) {
1141 appendFieldStart(buffer, fieldName);
1142
1143 if (array == null) {
1144 appendNullText(buffer, fieldName);
1145
1146 } else if (isFullDetail(fullDetail)) {
1147 appendDetail(buffer, fieldName, array);
1148
1149 } else {
1150 appendSummary(buffer, fieldName, array);
1151 }
1152
1153 appendFieldEnd(buffer, fieldName);
1154 }
1155
1156 /**
1157 * <p>Append to the <code>toString</code> the detail of a
1158 * <code>byte</code> array.</p>
1159 *
1160 * @param buffer the <code>StringBuffer</code> to populate
1161 * @param fieldName the field name, typically not used as already appended
1162 * @param array the array to add to the <code>toString</code>,
1163 * not <code>null</code>
1164 */
1165 protected void appendDetail(StringBuffer buffer, String fieldName, byte[] array) {
1166 buffer.append(arrayStart);
1167 for (int i = 0; i < array.length; i++) {
1168 if (i > 0) {
1169 buffer.append(arraySeparator);
1170 }
1171 appendDetail(buffer, fieldName, array[i]);
1172 }
1173 buffer.append(arrayEnd);
1174 }
1175
1176 /**
1177 * <p>Append to the <code>toString</code> a summary of a
1178 * <code>byte</code> array.</p>
1179 *
1180 * @param buffer the <code>StringBuffer</code> to populate
1181 * @param fieldName the field name, typically not used as already appended
1182 * @param array the array to add to the <code>toString</code>,
1183 * not <code>null</code>
1184 */
1185 protected void appendSummary(StringBuffer buffer, String fieldName, byte[] array) {
1186 appendSummarySize(buffer, fieldName, array.length);
1187 }
1188
1189 //----------------------------------------------------------------------------
1190
1191 /**
1192 * <p>Append to the <code>toString</code> a <code>char</code>
1193 * array.</p>
1194 *
1195 * @param buffer the <code>StringBuffer</code> to populate
1196 * @param fieldName the field name
1197 * @param array the array to add to the <code>toString</code>
1198 * @param fullDetail <code>true</code> for detail, <code>false</code>
1199 * for summary info, <code>null</code> for style decides
1200 */
1201 public void append(StringBuffer buffer, String fieldName, char[] array, Boolean fullDetail) {
1202 appendFieldStart(buffer, fieldName);
1203
1204 if (array == null) {
1205 appendNullText(buffer, fieldName);
1206
1207 } else if (isFullDetail(fullDetail)) {
1208 appendDetail(buffer, fieldName, array);
1209
1210 } else {
1211 appendSummary(buffer, fieldName, array);
1212 }
1213
1214 appendFieldEnd(buffer, fieldName);
1215 }
1216
1217 /**
1218 * <p>Append to the <code>toString</code> the detail of a
1219 * <code>char</code> array.</p>
1220 *
1221 * @param buffer the <code>StringBuffer</code> to populate
1222 * @param fieldName the field name, typically not used as already appended
1223 * @param array the array to add to the <code>toString</code>,
1224 * not <code>null</code>
1225 */
1226 protected void appendDetail(StringBuffer buffer, String fieldName, char[] array) {
1227 buffer.append(arrayStart);
1228 for (int i = 0; i < array.length; i++) {
1229 if (i > 0) {
1230 buffer.append(arraySeparator);
1231 }
1232 appendDetail(buffer, fieldName, array[i]);
1233 }
1234 buffer.append(arrayEnd);
1235 }
1236
1237 /**
1238 * <p>Append to the <code>toString</code> a summary of a
1239 * <code>char</code> array.</p>
1240 *
1241 * @param buffer the <code>StringBuffer</code> to populate
1242 * @param fieldName the field name, typically not used as already appended
1243 * @param array the array to add to the <code>toString</code>,
1244 * not <code>null</code>
1245 */
1246 protected void appendSummary(StringBuffer buffer, String fieldName, char[] array) {
1247 appendSummarySize(buffer, fieldName, array.length);
1248 }
1249
1250 //----------------------------------------------------------------------------
1251
1252 /**
1253 * <p>Append to the <code>toString</code> a <code>double</code>
1254 * array.</p>
1255 *
1256 * @param buffer the <code>StringBuffer</code> to populate
1257 * @param fieldName the field name
1258 * @param array the array to add to the toString
1259 * @param fullDetail <code>true</code> for detail, <code>false</code>
1260 * for summary info, <code>null</code> for style decides
1261 */
1262 public void append(StringBuffer buffer, String fieldName, double[] array, Boolean fullDetail) {
1263 appendFieldStart(buffer, fieldName);
1264
1265 if (array == null) {
1266 appendNullText(buffer, fieldName);
1267
1268 } else if (isFullDetail(fullDetail)) {
1269 appendDetail(buffer, fieldName, array);
1270
1271 } else {
1272 appendSummary(buffer, fieldName, array);
1273 }
1274
1275 appendFieldEnd(buffer, fieldName);
1276 }
1277
1278 /**
1279 * <p>Append to the <code>toString</code> the detail of a
1280 * <code>double</code> array.</p>
1281 *
1282 * @param buffer the <code>StringBuffer</code> to populate
1283 * @param fieldName the field name, typically not used as already appended
1284 * @param array the array to add to the <code>toString</code>,
1285 * not <code>null</code>
1286 */
1287 protected void appendDetail(StringBuffer buffer, String fieldName, double[] array) {
1288 buffer.append(arrayStart);
1289 for (int i = 0; i < array.length; i++) {
1290 if (i > 0) {
1291 buffer.append(arraySeparator);
1292 }
1293 appendDetail(buffer, fieldName, array[i]);
1294 }
1295 buffer.append(arrayEnd);
1296 }
1297
1298 /**
1299 * <p>Append to the <code>toString</code> a summary of a
1300 * <code>double</code> array.</p>
1301 *
1302 * @param buffer the <code>StringBuffer</code> to populate
1303 * @param fieldName the field name, typically not used as already appended
1304 * @param array the array to add to the <code>toString</code>,
1305 * not <code>null</code>
1306 */
1307 protected void appendSummary(StringBuffer buffer, String fieldName, double[] array) {
1308 appendSummarySize(buffer, fieldName, array.length);
1309 }
1310
1311 //----------------------------------------------------------------------------
1312
1313 /**
1314 * <p>Append to the <code>toString</code> a <code>float</code>
1315 * array.</p>
1316 *
1317 * @param buffer the <code>StringBuffer</code> to populate
1318 * @param fieldName the field name
1319 * @param array the array to add to the toString
1320 * @param fullDetail <code>true</code> for detail, <code>false</code>
1321 * for summary info, <code>null</code> for style decides
1322 */
1323 public void append(StringBuffer buffer, String fieldName, float[] array, Boolean fullDetail) {
1324 appendFieldStart(buffer, fieldName);
1325
1326 if (array == null) {
1327 appendNullText(buffer, fieldName);
1328
1329 } else if (isFullDetail(fullDetail)) {
1330 appendDetail(buffer, fieldName, array);
1331
1332 } else {
1333 appendSummary(buffer, fieldName, array);
1334 }
1335
1336 appendFieldEnd(buffer, fieldName);
1337 }
1338
1339 /**
1340 * <p>Append to the <code>toString</code> the detail of a
1341 * <code>float</code> array.</p>
1342 *
1343 * @param buffer the <code>StringBuffer</code> to populate
1344 * @param fieldName the field name, typically not used as already appended
1345 * @param array the array to add to the <code>toString</code>,
1346 * not <code>null</code>
1347 */
1348 protected void appendDetail(StringBuffer buffer, String fieldName, float[] array) {
1349 buffer.append(arrayStart);
1350 for (int i = 0; i < array.length; i++) {
1351 if (i > 0) {
1352 buffer.append(arraySeparator);
1353 }
1354 appendDetail(buffer, fieldName, array[i]);
1355 }
1356 buffer.append(arrayEnd);
1357 }
1358
1359 /**
1360 * <p>Append to the <code>toString</code> a summary of a
1361 * <code>float</code> array.</p>
1362 *
1363 * @param buffer the <code>StringBuffer</code> to populate
1364 * @param fieldName the field name, typically not used as already appended
1365 * @param array the array to add to the <code>toString</code>,
1366 * not <code>null</code>
1367 */
1368 protected void appendSummary(StringBuffer buffer, String fieldName, float[] array) {
1369 appendSummarySize(buffer, fieldName, array.length);
1370 }
1371
1372 //----------------------------------------------------------------------------
1373
1374 /**
1375 * <p>Append to the <code>toString</code> a <code>boolean</code>
1376 * array.</p>
1377 *
1378 * @param buffer the <code>StringBuffer</code> to populate
1379 * @param fieldName the field name
1380 * @param array the array to add to the toString
1381 * @param fullDetail <code>true</code> for detail, <code>false</code>
1382 * for summary info, <code>null</code> for style decides
1383 */
1384 public void append(StringBuffer buffer, String fieldName, boolean[] array, Boolean fullDetail) {
1385 appendFieldStart(buffer, fieldName);
1386
1387 if (array == null) {
1388 appendNullText(buffer, fieldName);
1389
1390 } else if (isFullDetail(fullDetail)) {
1391 appendDetail(buffer, fieldName, array);
1392
1393 } else {
1394 appendSummary(buffer, fieldName, array);
1395 }
1396
1397 appendFieldEnd(buffer, fieldName);
1398 }
1399
1400 /**
1401 * <p>Append to the <code>toString</code> the detail of a
1402 * <code>boolean</code> array.</p>
1403 *
1404 * @param buffer the <code>StringBuffer</code> to populate
1405 * @param fieldName the field name, typically not used as already appended
1406 * @param array the array to add to the <code>toString</code>,
1407 * not <code>null</code>
1408 */
1409 protected void appendDetail(StringBuffer buffer, String fieldName, boolean[] array) {
1410 buffer.append(arrayStart);
1411 for (int i = 0; i < array.length; i++) {
1412 if (i > 0) {
1413 buffer.append(arraySeparator);
1414 }
1415 appendDetail(buffer, fieldName, array[i]);
1416 }
1417 buffer.append(arrayEnd);
1418 }
1419
1420 /**
1421 * <p>Append to the <code>toString</code> a summary of a
1422 * <code>boolean</code> array.</p>
1423 *
1424 * @param buffer the <code>StringBuffer</code> to populate
1425 * @param fieldName the field name, typically not used as already appended
1426 * @param array the array to add to the <code>toString</code>,
1427 * not <code>null</code>
1428 */
1429 protected void appendSummary(StringBuffer buffer, String fieldName, boolean[] array) {
1430 appendSummarySize(buffer, fieldName, array.length);
1431 }
1432
1433 //----------------------------------------------------------------------------
1434
1435 /**
1436 * <p>Append to the <code>toString</code> the class name.</p>
1437 *
1438 * @param buffer the <code>StringBuffer</code> to populate
1439 * @param object the <code>Object</code> whose name to output
1440 */
1441 protected void appendClassName(StringBuffer buffer, Object object) {
1442 if (useClassName && object != null) {
1443 register(object);
1444 if (useShortClassName) {
1445 buffer.append(getShortClassName(object.getClass()));
1446 } else {
1447 buffer.append(object.getClass().getName());
1448 }
1449 }
1450 }
1451
1452 /**
1453 * <p>Append the {@link System#identityHashCode(java.lang.Object)}.</p>
1454 *
1455 * @param buffer the <code>StringBuffer</code> to populate
1456 * @param object the <code>Object</code> whose id to output
1457 */
1458 protected void appendIdentityHashCode(StringBuffer buffer, Object object) {
1459 if (this.isUseIdentityHashCode() && object!=null) {
1460 register(object);
1461 buffer.append('@');
1462 buffer.append(Integer.toHexString(System.identityHashCode(object)));
1463 }
1464 }
1465
1466 /**
1467 * <p>Append to the <code>toString</code> the content start.</p>
1468 *
1469 * @param buffer the <code>StringBuffer</code> to populate
1470 */
1471 protected void appendContentStart(StringBuffer buffer) {
1472 buffer.append(contentStart);
1473 }
1474
1475 /**
1476 * <p>Append to the <code>toString</code> the content end.</p>
1477 *
1478 * @param buffer the <code>StringBuffer</code> to populate
1479 */
1480 protected void appendContentEnd(StringBuffer buffer) {
1481 buffer.append(contentEnd);
1482 }
1483
1484 /**
1485 * <p>Append to the <code>toString</code> an indicator for <code>null</code>.</p>
1486 *
1487 * <p>The default indicator is <code>'&lt;null&gt;'</code>.</p>
1488 *
1489 * @param buffer the <code>StringBuffer</code> to populate
1490 * @param fieldName the field name, typically not used as already appended
1491 */
1492 protected void appendNullText(StringBuffer buffer, String fieldName) {
1493 buffer.append(nullText);
1494 }
1495
1496 /**
1497 * <p>Append to the <code>toString</code> the field separator.</p>
1498 *
1499 * @param buffer the <code>StringBuffer</code> to populate
1500 */
1501 protected void appendFieldSeparator(StringBuffer buffer) {
1502 buffer.append(fieldSeparator);
1503 }
1504
1505 /**
1506 * <p>Append to the <code>toString</code> the field start.</p>
1507 *
1508 * @param buffer the <code>StringBuffer</code> to populate
1509 * @param fieldName the field name
1510 */
1511 protected void appendFieldStart(StringBuffer buffer, String fieldName) {
1512 if (useFieldNames && fieldName != null) {
1513 buffer.append(fieldName);
1514 buffer.append(fieldNameValueSeparator);
1515 }
1516 }
1517
1518 /**
1519 * <p>Append to the <code>toString<code> the field end.</p>
1520 *
1521 * @param buffer the <code>StringBuffer</code> to populate
1522 * @param fieldName the field name, typically not used as already appended
1523 */
1524 protected void appendFieldEnd(StringBuffer buffer, String fieldName) {
1525 appendFieldSeparator(buffer);
1526 }
1527
1528 /**
1529 * <p>Append to the <code>toString</code> a size summary.</p>
1530 *
1531 * <p>The size summary is used to summarize the contents of
1532 * <code>Collections</code>, <code>Maps</code> and arrays.</p>
1533 *
1534 * <p>The output consists of a prefix, the passed in size
1535 * and a suffix.</p>
1536 *
1537 * <p>The default format is <code>'&lt;size=n&gt;'<code>.</p>
1538 *
1539 * @param buffer the <code>StringBuffer</code> to populate
1540 * @param fieldName the field name, typically not used as already appended
1541 * @param size the size to append
1542 */
1543 protected void appendSummarySize(StringBuffer buffer, String fieldName, int size) {
1544 buffer.append(sizeStartText);
1545 buffer.append(size);
1546 buffer.append(sizeEndText);
1547 }
1548
1549 /**
1550 * <p>Is this field to be output in full detail.</p>
1551 *
1552 * <p>This method converts a detail request into a detail level.
1553 * The calling code may request full detail (<code>true</code>),
1554 * but a subclass might ignore that and always return
1555 * <code>false</code>. The calling code may pass in
1556 * <code>null</code> indicating that it doesn't care about
1557 * the detail level. In this case the default detail level is
1558 * used.</p>
1559 *
1560 * @param fullDetailRequest the detail level requested
1561 * @return whether full detail is to be shown
1562 */
1563 protected boolean isFullDetail(Boolean fullDetailRequest) {
1564 if (fullDetailRequest == null) {
1565 return defaultFullDetail;
1566 }
1567 return fullDetailRequest.booleanValue();
1568 }
1569
1570 /**
1571 * <p>Gets the short class name for a class.</p>
1572 *
1573 * <p>The short class name is the classname excluding
1574 * the package name.</p>
1575 *
1576 * @param cls the <code>Class</code> to get the short name of
1577 * @return the short name
1578 */
1579 protected String getShortClassName(Class cls) {
1580 return ClassUtils.getShortClassName(cls);
1581 }
1582
1583 // Setters and getters for the customizable parts of the style
1584 // These methods are not expected to be overridden, except to make public
1585 // (They are not public so that immutable subclasses can be written)
1586 //---------------------------------------------------------------------
1587
1588 /**
1589 * <p>Gets whether to use the class name.</p>
1590 *
1591 * @return the current useClassName flag
1592 */
1593 protected boolean isUseClassName() {
1594 return useClassName;
1595 }
1596
1597 /**
1598 * <p>Sets whether to use the class name.</p>
1599 *
1600 * @param useClassName the new useClassName flag
1601 */
1602 protected void setUseClassName(boolean useClassName) {
1603 this.useClassName = useClassName;
1604 }
1605
1606 //---------------------------------------------------------------------
1607
1608 /**
1609 * <p>Gets whether to output short or long class names.</p>
1610 *
1611 * @return the current useShortClassName flag
1612 * @since 2.0
1613 */
1614 protected boolean isUseShortClassName() {
1615 return useShortClassName;
1616 }
1617
1618 /**
1619 * <p>Gets whether to output short or long class names.</p>
1620 *
1621 * @return the current shortClassName flag
1622 * @deprecated Use {@link #isUseShortClassName()}
1623 * Method will be removed in Commons Lang 3.0.
1624 */
1625 protected boolean isShortClassName() {
1626 return useShortClassName;
1627 }
1628
1629 /**
1630 * <p>Sets whether to output short or long class names.</p>
1631 *
1632 * @param useShortClassName the new useShortClassName flag
1633 * @since 2.0
1634 */
1635 protected void setUseShortClassName(boolean useShortClassName) {
1636 this.useShortClassName = useShortClassName;
1637 }
1638
1639 /**
1640 * <p>Sets whether to output short or long class names.</p>
1641 *
1642 * @param shortClassName the new shortClassName flag
1643 * @deprecated Use {@link #setUseShortClassName(boolean)}
1644 * Method will be removed in Commons Lang 3.0.
1645 */
1646 protected void setShortClassName(boolean shortClassName) {
1647 this.useShortClassName = shortClassName;
1648 }
1649
1650 //---------------------------------------------------------------------
1651
1652 /**
1653 * <p>Gets whether to use the identity hash code.</p>
1654 *
1655 * @return the current useIdentityHashCode flag
1656 */
1657 protected boolean isUseIdentityHashCode() {
1658 return useIdentityHashCode;
1659 }
1660
1661 /**
1662 * <p>Sets whether to use the identity hash code.</p>
1663 *
1664 * @param useIdentityHashCode the new useIdentityHashCode flag
1665 */
1666 protected void setUseIdentityHashCode(boolean useIdentityHashCode) {
1667 this.useIdentityHashCode = useIdentityHashCode;
1668 }
1669
1670 //---------------------------------------------------------------------
1671
1672 /**
1673 * <p>Gets whether to use the field names passed in.</p>
1674 *
1675 * @return the current useFieldNames flag
1676 */
1677 protected boolean isUseFieldNames() {
1678 return useFieldNames;
1679 }
1680
1681 /**
1682 * <p>Sets whether to use the field names passed in.</p>
1683 *
1684 * @param useFieldNames the new useFieldNames flag
1685 */
1686 protected void setUseFieldNames(boolean useFieldNames) {
1687 this.useFieldNames = useFieldNames;
1688 }
1689
1690 //---------------------------------------------------------------------
1691
1692 /**
1693 * <p>Gets whether to use full detail when the caller doesn't
1694 * specify.</p>
1695 *
1696 * @return the current defaultFullDetail flag
1697 */
1698 protected boolean isDefaultFullDetail() {
1699 return defaultFullDetail;
1700 }
1701
1702 /**
1703 * <p>Sets whether to use full detail when the caller doesn't
1704 * specify.</p>
1705 *
1706 * @param defaultFullDetail the new defaultFullDetail flag
1707 */
1708 protected void setDefaultFullDetail(boolean defaultFullDetail) {
1709 this.defaultFullDetail = defaultFullDetail;
1710 }
1711
1712 //---------------------------------------------------------------------
1713
1714 /**
1715 * <p>Gets whether to output array content detail.</p>
1716 *
1717 * @return the current array content detail setting
1718 */
1719 protected boolean isArrayContentDetail() {
1720 return arrayContentDetail;
1721 }
1722
1723 /**
1724 * <p>Sets whether to output array content detail.</p>
1725 *
1726 * @param arrayContentDetail the new arrayContentDetail flag
1727 */
1728 protected void setArrayContentDetail(boolean arrayContentDetail) {
1729 this.arrayContentDetail = arrayContentDetail;
1730 }
1731
1732 //---------------------------------------------------------------------
1733
1734 /**
1735 * <p>Gets the array start text.</p>
1736 *
1737 * @return the current array start text
1738 */
1739 protected String getArrayStart() {
1740 return arrayStart;
1741 }
1742
1743 /**
1744 * <p>Sets the array start text.</p>
1745 *
1746 * <p><code>null</code> is accepted, but will be converted to
1747 * an empty String.</p>
1748 *
1749 * @param arrayStart the new array start text
1750 */
1751 protected void setArrayStart(String arrayStart) {
1752 if (arrayStart == null) {
1753 arrayStart = "";
1754 }
1755 this.arrayStart = arrayStart;
1756 }
1757
1758 //---------------------------------------------------------------------
1759
1760 /**
1761 * <p>Gets the array end text.</p>
1762 *
1763 * @return the current array end text
1764 */
1765 protected String getArrayEnd() {
1766 return arrayEnd;
1767 }
1768
1769 /**
1770 * <p>Sets the array end text.</p>
1771 *
1772 * <p><code>null</code> is accepted, but will be converted to
1773 * an empty String.</p>
1774 *
1775 * @param arrayEnd the new array end text
1776 */
1777 protected void setArrayEnd(String arrayEnd) {
1778 if (arrayEnd == null) {
1779 arrayEnd = "";
1780 }
1781 this.arrayEnd = arrayEnd;
1782 }
1783
1784 //---------------------------------------------------------------------
1785
1786 /**
1787 * <p>Gets the array separator text.</p>
1788 *
1789 * @return the current array separator text
1790 */
1791 protected String getArraySeparator() {
1792 return arraySeparator;
1793 }
1794
1795 /**
1796 * <p>Sets the array separator text.</p>
1797 *
1798 * <p><code>null</code> is accepted, but will be converted to
1799 * an empty String.</p>
1800 *
1801 * @param arraySeparator the new array separator text
1802 */
1803 protected void setArraySeparator(String arraySeparator) {
1804 if (arraySeparator == null) {
1805 arraySeparator = "";
1806 }
1807 this.arraySeparator = arraySeparator;
1808 }
1809
1810 //---------------------------------------------------------------------
1811
1812 /**
1813 * <p>Gets the content start text.</p>
1814 *
1815 * @return the current content start text
1816 */
1817 protected String getContentStart() {
1818 return contentStart;
1819 }
1820
1821 /**
1822 * <p>Sets the content start text.</p>
1823 *
1824 * <p><code>null</code> is accepted, but will be converted to
1825 * an empty String.</p>
1826 *
1827 * @param contentStart the new content start text
1828 */
1829 protected void setContentStart(String contentStart) {
1830 if (contentStart == null) {
1831 contentStart = "";
1832 }
1833 this.contentStart = contentStart;
1834 }
1835
1836 //---------------------------------------------------------------------
1837
1838 /**
1839 * <p>Gets the content end text.</p>
1840 *
1841 * @return the current content end text
1842 */
1843 protected String getContentEnd() {
1844 return contentEnd;
1845 }
1846
1847 /**
1848 * <p>Sets the content end text.</p>
1849 *
1850 * <p><code>null</code> is accepted, but will be converted to
1851 * an empty String.</p>
1852 *
1853 * @param contentEnd the new content end text
1854 */
1855 protected void setContentEnd(String contentEnd) {
1856 if (contentEnd == null) {
1857 contentEnd = "";
1858 }
1859 this.contentEnd = contentEnd;
1860 }
1861
1862 //---------------------------------------------------------------------
1863
1864 /**
1865 * <p>Gets the field name value separator text.</p>
1866 *
1867 * @return the current field name value separator text
1868 */
1869 protected String getFieldNameValueSeparator() {
1870 return fieldNameValueSeparator;
1871 }
1872
1873 /**
1874 * <p>Sets the field name value separator text.</p>
1875 *
1876 * <p><code>null</code> is accepted, but will be converted to
1877 * an empty String.</p>
1878 *
1879 * @param fieldNameValueSeparator the new field name value separator text
1880 */
1881 protected void setFieldNameValueSeparator(String fieldNameValueSeparator) {
1882 if (fieldNameValueSeparator == null) {
1883 fieldNameValueSeparator = "";
1884 }
1885 this.fieldNameValueSeparator = fieldNameValueSeparator;
1886 }
1887
1888 //---------------------------------------------------------------------
1889
1890 /**
1891 * <p>Gets the field separator text.</p>
1892 *
1893 * @return the current field separator text
1894 */
1895 protected String getFieldSeparator() {
1896 return fieldSeparator;
1897 }
1898
1899 /**
1900 * <p>Sets the field separator text.</p>
1901 *
1902 * <p><code>null</code> is accepted, but will be converted to
1903 * an empty String.</p>
1904 *
1905 * @param fieldSeparator the new field separator text
1906 */
1907 protected void setFieldSeparator(String fieldSeparator) {
1908 if (fieldSeparator == null) {
1909 fieldSeparator = "";
1910 }
1911 this.fieldSeparator = fieldSeparator;
1912 }
1913
1914 //---------------------------------------------------------------------
1915
1916 /**
1917 * <p>Gets whether the field separator should be added at the start
1918 * of each buffer.</p>
1919 *
1920 * @return the fieldSeparatorAtStart flag
1921 * @since 2.0
1922 */
1923 protected boolean isFieldSeparatorAtStart() {
1924 return fieldSeparatorAtStart;
1925 }
1926
1927 /**
1928 * <p>Sets whether the field separator should be added at the start
1929 * of each buffer.</p>
1930 *
1931 * @param fieldSeparatorAtStart the fieldSeparatorAtStart flag
1932 * @since 2.0
1933 */
1934 protected void setFieldSeparatorAtStart(boolean fieldSeparatorAtStart) {
1935 this.fieldSeparatorAtStart = fieldSeparatorAtStart;
1936 }
1937
1938 //---------------------------------------------------------------------
1939
1940 /**
1941 * <p>Gets whether the field separator should be added at the end
1942 * of each buffer.</p>
1943 *
1944 * @return fieldSeparatorAtEnd flag
1945 * @since 2.0
1946 */
1947 protected boolean isFieldSeparatorAtEnd() {
1948 return fieldSeparatorAtEnd;
1949 }
1950
1951 /**
1952 * <p>Sets whether the field separator should be added at the end
1953 * of each buffer.</p>
1954 *
1955 * @param fieldSeparatorAtEnd the fieldSeparatorAtEnd flag
1956 * @since 2.0
1957 */
1958 protected void setFieldSeparatorAtEnd(boolean fieldSeparatorAtEnd) {
1959 this.fieldSeparatorAtEnd = fieldSeparatorAtEnd;
1960 }
1961
1962 //---------------------------------------------------------------------
1963
1964 /**
1965 * <p>Gets the text to output when <code>null</code> found.</p>
1966 *
1967 * @return the current text to output when null found
1968 */
1969 protected String getNullText() {
1970 return nullText;
1971 }
1972
1973 /**
1974 * <p>Sets the text to output when <code>null</code> found.</p>
1975 *
1976 * <p><code>null</code> is accepted, but will be converted to
1977 * an empty String.</p>
1978 *
1979 * @param nullText the new text to output when null found
1980 */
1981 protected void setNullText(String nullText) {
1982 if (nullText == null) {
1983 nullText = "";
1984 }
1985 this.nullText = nullText;
1986 }
1987
1988 //---------------------------------------------------------------------
1989
1990 /**
1991 * <p>Gets the start text to output when a <code>Collection</code>,
1992 * <code>Map</code> or array size is output.</p>
1993 *
1994 * <p>This is output before the size value.</p>
1995 *
1996 * @return the current start of size text
1997 */
1998 protected String getSizeStartText() {
1999 return sizeStartText;
2000 }
2001
2002 /**
2003 * <p>Sets the start text to output when a <code>Collection</code>,
2004 * <code>Map</code> or array size is output.</p>
2005 *
2006 * <p>This is output before the size value.</p>
2007 *
2008 * <p><code>null</code> is accepted, but will be converted to
2009 * an empty String.</p>
2010 *
2011 * @param sizeStartText the new start of size text
2012 */
2013 protected void setSizeStartText(String sizeStartText) {
2014 if (sizeStartText == null) {
2015 sizeStartText = "";
2016 }
2017 this.sizeStartText = sizeStartText;
2018 }
2019
2020 //---------------------------------------------------------------------
2021
2022 /**
2023 * <p>Gets the end text to output when a <code>Collection</code>,
2024 * <code>Map</code> or array size is output.</p>
2025 *
2026 * <p>This is output after the size value.</p>
2027 *
2028 * @return the current end of size text
2029 */
2030 protected String getSizeEndText() {
2031 return sizeEndText;
2032 }
2033
2034 /**
2035 * <p>Sets the end text to output when a <code>Collection</code>,
2036 * <code>Map</code> or array size is output.</p>
2037 *
2038 * <p>This is output after the size value.</p>
2039 *
2040 * <p><code>null</code> is accepted, but will be converted to
2041 * an empty String.</p>
2042 *
2043 * @param sizeEndText the new end of size text
2044 */
2045 protected void setSizeEndText(String sizeEndText) {
2046 if (sizeEndText == null) {
2047 sizeEndText = "";
2048 }
2049 this.sizeEndText = sizeEndText;
2050 }
2051
2052 //---------------------------------------------------------------------
2053
2054 /**
2055 * <p>Gets the start text to output when an <code>Object</code> is
2056 * output in summary mode.</p>
2057 *
2058 * <p>This is output before the size value.</p>
2059 *
2060 * @return the current start of summary text
2061 */
2062 protected String getSummaryObjectStartText() {
2063 return summaryObjectStartText;
2064 }
2065
2066 /**
2067 * <p>Sets the start text to output when an <code>Object</code> is
2068 * output in summary mode.</p>
2069 *
2070 * <p>This is output before the size value.</p>
2071 *
2072 * <p><code>null</code> is accepted, but will be converted to
2073 * an empty String.</p>
2074 *
2075 * @param summaryObjectStartText the new start of summary text
2076 */
2077 protected void setSummaryObjectStartText(String summaryObjectStartText) {
2078 if (summaryObjectStartText == null) {
2079 summaryObjectStartText = "";
2080 }
2081 this.summaryObjectStartText = summaryObjectStartText;
2082 }
2083
2084 //---------------------------------------------------------------------
2085
2086 /**
2087 * <p>Gets the end text to output when an <code>Object</code> is
2088 * output in summary mode.</p>
2089 *
2090 * <p>This is output after the size value.</p>
2091 *
2092 * @return the current end of summary text
2093 */
2094 protected String getSummaryObjectEndText() {
2095 return summaryObjectEndText;
2096 }
2097
2098 /**
2099 * <p>Sets the end text to output when an <code>Object</code> is
2100 * output in summary mode.</p>
2101 *
2102 * <p>This is output after the size value.</p>
2103 *
2104 * <p><code>null</code> is accepted, but will be converted to
2105 * an empty String.</p>
2106 *
2107 * @param summaryObjectEndText the new end of summary text
2108 */
2109 protected void setSummaryObjectEndText(String summaryObjectEndText) {
2110 if (summaryObjectEndText == null) {
2111 summaryObjectEndText = "";
2112 }
2113 this.summaryObjectEndText = summaryObjectEndText;
2114 }
2115
2116 //----------------------------------------------------------------------------
2117
2118 /**
2119 * <p>Default <code>ToStringStyle</code>.</p>
2120 *
2121 * <p>This is an inner class rather than using
2122 * <code>StandardToStringStyle</code> to ensure its immutability.</p>
2123 */
2124 private static final class DefaultToStringStyle extends ToStringStyle {
2125
2126 /**
2127 * Required for serialization support.
2128 *
2129 * @see java.io.Serializable
2130 */
2131 private static final long serialVersionUID = 1L;
2132
2133 /**
2134 * <p>Constructor.</p>
2135 *
2136 * <p>Use the static constant rather than instantiating.</p>
2137 */
2138 DefaultToStringStyle() {
2139 super();
2140 }
2141
2142 /**
2143 * <p>Ensure <code>Singleton</code> after serialization.</p>
2144 *
2145 * @return the singleton
2146 */
2147 private Object readResolve() {
2148 return ToStringStyle.DEFAULT_STYLE;
2149 }
2150
2151 }
2152
2153 //----------------------------------------------------------------------------
2154
2155 /**
2156 * <p><code>ToStringStyle</code> that does not print out
2157 * the field names.</p>
2158 *
2159 * <p>This is an inner class rather than using
2160 * <code>StandardToStringStyle</code> to ensure its immutability.
2161 */
2162 private static final class NoFieldNameToStringStyle extends ToStringStyle {
2163
2164 private static final long serialVersionUID = 1L;
2165
2166 /**
2167 * <p>Constructor.</p>
2168 *
2169 * <p>Use the static constant rather than instantiating.</p>
2170 */
2171 NoFieldNameToStringStyle() {
2172 super();
2173 this.setUseFieldNames(false);
2174 }
2175
2176 /**
2177 * <p>Ensure <code>Singleton</code> after serialization.</p>
2178 *
2179 * @return the singleton
2180 */
2181 private Object readResolve() {
2182 return ToStringStyle.NO_FIELD_NAMES_STYLE;
2183 }
2184
2185 }
2186
2187 //----------------------------------------------------------------------------
2188
2189 /**
2190 * <p><code>ToStringStyle</code> that prints out the short
2191 * class name and no identity hashcode.</p>
2192 *
2193 * <p>This is an inner class rather than using
2194 * <code>StandardToStringStyle</code> to ensure its immutability.</p>
2195 */
2196 private static final class ShortPrefixToStringStyle extends ToStringStyle {
2197
2198 private static final long serialVersionUID = 1L;
2199
2200 /**
2201 * <p>Constructor.</p>
2202 *
2203 * <p>Use the static constant rather than instantiating.</p>
2204 */
2205 ShortPrefixToStringStyle() {
2206 super();
2207 this.setUseShortClassName(true);
2208 this.setUseIdentityHashCode(false);
2209 }
2210
2211 /**
2212 * <p>Ensure <code>Singleton</ode> after serialization.</p>
2213 * @return the singleton
2214 */
2215 private Object readResolve() {
2216 return ToStringStyle.SHORT_PREFIX_STYLE;
2217 }
2218
2219 }
2220
2221 /**
2222 * <p><code>ToStringStyle</code> that does not print out the
2223 * classname, identity hashcode, content start or field name.</p>
2224 *
2225 * <p>This is an inner class rather than using
2226 * <code>StandardToStringStyle</code> to ensure its immutability.</p>
2227 */
2228 private static final class SimpleToStringStyle extends ToStringStyle {
2229
2230 private static final long serialVersionUID = 1L;
2231
2232 /**
2233 * <p>Constructor.</p>
2234 *
2235 * <p>Use the static constant rather than instantiating.</p>
2236 */
2237 SimpleToStringStyle() {
2238 super();
2239 this.setUseClassName(false);
2240 this.setUseIdentityHashCode(false);
2241 this.setUseFieldNames(false);
2242 this.setContentStart("");
2243 this.setContentEnd("");
2244 }
2245
2246 /**
2247 * <p>Ensure <code>Singleton</ode> after serialization.</p>
2248 * @return the singleton
2249 */
2250 private Object readResolve() {
2251 return ToStringStyle.SIMPLE_STYLE;
2252 }
2253
2254 }
2255
2256 //----------------------------------------------------------------------------
2257
2258 /**
2259 * <p><code>ToStringStyle</code> that outputs on multiple lines.</p>
2260 *
2261 * <p>This is an inner class rather than using
2262 * <code>StandardToStringStyle</code> to ensure its immutability.</p>
2263 */
2264 private static final class MultiLineToStringStyle extends ToStringStyle {
2265
2266 private static final long serialVersionUID = 1L;
2267
2268 /**
2269 * <p>Constructor.</p>
2270 *
2271 * <p>Use the static constant rather than instantiating.</p>
2272 */
2273 MultiLineToStringStyle() {
2274 super();
2275 this.setContentStart("[");
2276 this.setFieldSeparator(SystemUtils.LINE_SEPARATOR + " ");
2277 this.setFieldSeparatorAtStart(true);
2278 this.setContentEnd(SystemUtils.LINE_SEPARATOR + "]");
2279 }
2280
2281 /**
2282 * <p>Ensure <code>Singleton</code> after serialization.</p>
2283 *
2284 * @return the singleton
2285 */
2286 private Object readResolve() {
2287 return ToStringStyle.MULTI_LINE_STYLE;
2288 }
2289
2290 }
2291
2292}
Note: See TracBrowser for help on using the repository browser.