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