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