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