Coverage Report - org.apache.commons.lang3.builder.ReflectionToStringBuilder
 
Classes in this File Line Coverage Branch Coverage Complexity
ReflectionToStringBuilder
93%
92/98
95%
46/48
2,032
 
 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  
 
 18  
 package org.apache.commons.lang3.builder;
 19  
 
 20  
 import java.lang.reflect.AccessibleObject;
 21  
 import java.lang.reflect.Field;
 22  
 import java.lang.reflect.Modifier;
 23  
 import java.util.ArrayList;
 24  
 import java.util.Arrays;
 25  
 import java.util.Collection;
 26  
 import java.util.List;
 27  
 
 28  
 import org.apache.commons.lang3.ArrayUtils;
 29  
 import org.apache.commons.lang3.ClassUtils;
 30  
 import org.apache.commons.lang3.Validate;
 31  
 
 32  
 /**
 33  
  * <p>
 34  
  * Assists in implementing {@link Object#toString()} methods using reflection.
 35  
  * </p>
 36  
  * <p>
 37  
  * This class uses reflection to determine the fields to append. Because these fields are usually private, the class
 38  
  * uses {@link java.lang.reflect.AccessibleObject#setAccessible(java.lang.reflect.AccessibleObject[], boolean)} to
 39  
  * change the visibility of the fields. This will fail under a security manager, unless the appropriate permissions are
 40  
  * set up correctly.
 41  
  * </p>
 42  
  * <p>
 43  
  * Using reflection to access (private) fields circumvents any synchronization protection guarding access to these
 44  
  * fields. If a toString method cannot safely read a field, you should exclude it from the toString method, or use
 45  
  * synchronization consistent with the class' lock management around the invocation of the method. Take special care to
 46  
  * exclude non-thread-safe collection classes, because these classes may throw ConcurrentModificationException if
 47  
  * modified while the toString method is executing.
 48  
  * </p>
 49  
  * <p>
 50  
  * A typical invocation for this method would look like:
 51  
  * </p>
 52  
  * <pre>
 53  
  * public String toString() {
 54  
  *     return ReflectionToStringBuilder.toString(this);
 55  
  * }
 56  
  * </pre>
 57  
  * <p>
 58  
  * You can also use the builder to debug 3rd party objects:
 59  
  * </p>
 60  
  * <pre>
 61  
  * System.out.println(&quot;An object: &quot; + ReflectionToStringBuilder.toString(anObject));
 62  
  * </pre>
 63  
  * <p>
 64  
  * A subclass can control field output by overriding the methods:
 65  
  * </p>
 66  
  * <ul>
 67  
  * <li>{@link #accept(java.lang.reflect.Field)}</li>
 68  
  * <li>{@link #getValue(java.lang.reflect.Field)}</li>
 69  
  * </ul>
 70  
  * <p>
 71  
  * For example, this method does <i>not</i> include the <code>password</code> field in the returned <code>String</code>:
 72  
  * </p>
 73  
  * <pre>
 74  
  * public String toString() {
 75  
  *     return (new ReflectionToStringBuilder(this) {
 76  
  *         protected boolean accept(Field f) {
 77  
  *             return super.accept(f) &amp;&amp; !f.getName().equals(&quot;password&quot;);
 78  
  *         }
 79  
  *     }).toString();
 80  
  * }
 81  
  * </pre>
 82  
  * <p>
 83  
  * Alternatively the {@link ToStringExclude} annotation can be used to exclude fields from being incorporated in the
 84  
  * result.
 85  
  * </p>
 86  
  * <p>
 87  
  * The exact format of the <code>toString</code> is determined by the {@link ToStringStyle} passed into the constructor.
 88  
  * </p>
 89  
  *
 90  
  * <p>
 91  
  * <b>Note:</b> the default {@link ToStringStyle} will only do a "shallow" formatting, i.e. composed objects are not
 92  
  * further traversed. To get "deep" formatting, use an instance of {@link RecursiveToStringStyle}.
 93  
  * </p>
 94  
  *
 95  
  * @since 2.0
 96  
  */
 97  
 public class ReflectionToStringBuilder extends ToStringBuilder {
 98  
 
 99  
     /**
 100  
      * <p>
 101  
      * Builds a <code>toString</code> value using the default <code>ToStringStyle</code> through reflection.
 102  
      * </p>
 103  
      *
 104  
      * <p>
 105  
      * It uses <code>AccessibleObject.setAccessible</code> to gain access to private fields. This means that it will
 106  
      * throw a security exception if run under a security manager, if the permissions are not set up correctly. It is
 107  
      * also not as efficient as testing explicitly.
 108  
      * </p>
 109  
      *
 110  
      * <p>
 111  
      * Transient members will be not be included, as they are likely derived. Static fields will not be included.
 112  
      * Superclass fields will be appended.
 113  
      * </p>
 114  
      *
 115  
      * @param object
 116  
      *            the Object to be output
 117  
      * @return the String result
 118  
      * @throws IllegalArgumentException
 119  
      *             if the Object is <code>null</code>
 120  
      *
 121  
      * @see ToStringExclude
 122  
      */
 123  
     public static String toString(final Object object) {
 124  41
         return toString(object, null, false, false, null);
 125  
     }
 126  
 
 127  
     /**
 128  
      * <p>
 129  
      * Builds a <code>toString</code> value through reflection.
 130  
      * </p>
 131  
      *
 132  
      * <p>
 133  
      * It uses <code>AccessibleObject.setAccessible</code> to gain access to private fields. This means that it will
 134  
      * throw a security exception if run under a security manager, if the permissions are not set up correctly. It is
 135  
      * also not as efficient as testing explicitly.
 136  
      * </p>
 137  
      *
 138  
      * <p>
 139  
      * Transient members will be not be included, as they are likely derived. Static fields will not be included.
 140  
      * Superclass fields will be appended.
 141  
      * </p>
 142  
      *
 143  
      * <p>
 144  
      * If the style is <code>null</code>, the default <code>ToStringStyle</code> is used.
 145  
      * </p>
 146  
      *
 147  
      * @param object
 148  
      *            the Object to be output
 149  
      * @param style
 150  
      *            the style of the <code>toString</code> to create, may be <code>null</code>
 151  
      * @return the String result
 152  
      * @throws IllegalArgumentException
 153  
      *             if the Object or <code>ToStringStyle</code> is <code>null</code>
 154  
      *
 155  
      * @see ToStringExclude
 156  
      */
 157  
     public static String toString(final Object object, final ToStringStyle style) {
 158  6
         return toString(object, style, false, false, null);
 159  
     }
 160  
 
 161  
     /**
 162  
      * <p>
 163  
      * Builds a <code>toString</code> value through reflection.
 164  
      * </p>
 165  
      *
 166  
      * <p>
 167  
      * It uses <code>AccessibleObject.setAccessible</code> to gain access to private fields. This means that it will
 168  
      * throw a security exception if run under a security manager, if the permissions are not set up correctly. It is
 169  
      * also not as efficient as testing explicitly.
 170  
      * </p>
 171  
      *
 172  
      * <p>
 173  
      * If the <code>outputTransients</code> is <code>true</code>, transient members will be output, otherwise they
 174  
      * are ignored, as they are likely derived fields, and not part of the value of the Object.
 175  
      * </p>
 176  
      *
 177  
      * <p>
 178  
      * Static fields will not be included. Superclass fields will be appended.
 179  
      * </p>
 180  
      *
 181  
      * <p>
 182  
      * If the style is <code>null</code>, the default <code>ToStringStyle</code> is used.
 183  
      * </p>
 184  
      *
 185  
      * @param object
 186  
      *            the Object to be output
 187  
      * @param style
 188  
      *            the style of the <code>toString</code> to create, may be <code>null</code>
 189  
      * @param outputTransients
 190  
      *            whether to include transient fields
 191  
      * @return the String result
 192  
      * @throws IllegalArgumentException
 193  
      *             if the Object is <code>null</code>
 194  
      *
 195  
      * @see ToStringExclude
 196  
      */
 197  
     public static String toString(final Object object, final ToStringStyle style, final boolean outputTransients) {
 198  0
         return toString(object, style, outputTransients, false, null);
 199  
     }
 200  
 
 201  
     /**
 202  
      * <p>
 203  
      * Builds a <code>toString</code> value through reflection.
 204  
      * </p>
 205  
      *
 206  
      * <p>
 207  
      * It uses <code>AccessibleObject.setAccessible</code> to gain access to private fields. This means that it will
 208  
      * throw a security exception if run under a security manager, if the permissions are not set up correctly. It is
 209  
      * also not as efficient as testing explicitly.
 210  
      * </p>
 211  
      *
 212  
      * <p>
 213  
      * If the <code>outputTransients</code> is <code>true</code>, transient fields will be output, otherwise they
 214  
      * are ignored, as they are likely derived fields, and not part of the value of the Object.
 215  
      * </p>
 216  
      *
 217  
      * <p>
 218  
      * If the <code>outputStatics</code> is <code>true</code>, static fields will be output, otherwise they are
 219  
      * ignored.
 220  
      * </p>
 221  
      *
 222  
      * <p>
 223  
      * Static fields will not be included. Superclass fields will be appended.
 224  
      * </p>
 225  
      *
 226  
      * <p>
 227  
      * If the style is <code>null</code>, the default <code>ToStringStyle</code> is used.
 228  
      * </p>
 229  
      *
 230  
      * @param object
 231  
      *            the Object to be output
 232  
      * @param style
 233  
      *            the style of the <code>toString</code> to create, may be <code>null</code>
 234  
      * @param outputTransients
 235  
      *            whether to include transient fields
 236  
      * @param outputStatics
 237  
      *            whether to include static fields
 238  
      * @return the String result
 239  
      * @throws IllegalArgumentException
 240  
      *             if the Object is <code>null</code>
 241  
      *
 242  
      * @see ToStringExclude
 243  
      * @since 2.1
 244  
      */
 245  
     public static String toString(final Object object, final ToStringStyle style, final boolean outputTransients, final boolean outputStatics) {
 246  0
         return toString(object, style, outputTransients, outputStatics, null);
 247  
     }
 248  
 
 249  
     /**
 250  
      * <p>
 251  
      * Builds a <code>toString</code> value through reflection.
 252  
      * </p>
 253  
      *
 254  
      * <p>
 255  
      * It uses <code>AccessibleObject.setAccessible</code> to gain access to private fields. This means that it will
 256  
      * throw a security exception if run under a security manager, if the permissions are not set up correctly. It is
 257  
      * also not as efficient as testing explicitly.
 258  
      * </p>
 259  
      *
 260  
      * <p>
 261  
      * If the <code>outputTransients</code> is <code>true</code>, transient fields will be output, otherwise they
 262  
      * are ignored, as they are likely derived fields, and not part of the value of the Object.
 263  
      * </p>
 264  
      *
 265  
      * <p>
 266  
      * If the <code>outputStatics</code> is <code>true</code>, static fields will be output, otherwise they are
 267  
      * ignored.
 268  
      * </p>
 269  
      *
 270  
      * <p>
 271  
      * Superclass fields will be appended up to and including the specified superclass. A null superclass is treated as
 272  
      * <code>java.lang.Object</code>.
 273  
      * </p>
 274  
      *
 275  
      * <p>
 276  
      * If the style is <code>null</code>, the default <code>ToStringStyle</code> is used.
 277  
      * </p>
 278  
      *
 279  
      * @param <T>
 280  
      *            the type of the object
 281  
      * @param object
 282  
      *            the Object to be output
 283  
      * @param style
 284  
      *            the style of the <code>toString</code> to create, may be <code>null</code>
 285  
      * @param outputTransients
 286  
      *            whether to include transient fields
 287  
      * @param outputStatics
 288  
      *            whether to include static fields
 289  
      * @param reflectUpToClass
 290  
      *            the superclass to reflect up to (inclusive), may be <code>null</code>
 291  
      * @return the String result
 292  
      * @throws IllegalArgumentException
 293  
      *             if the Object is <code>null</code>
 294  
      *
 295  
      * @see ToStringExclude
 296  
      * @since 2.1
 297  
      */
 298  
     public static <T> String toString(
 299  
             final T object, final ToStringStyle style, final boolean outputTransients,
 300  
             final boolean outputStatics, final Class<? super T> reflectUpToClass) {
 301  139
         return new ReflectionToStringBuilder(object, style, null, reflectUpToClass, outputTransients, outputStatics)
 302  69
                 .toString();
 303  
     }
 304  
 
 305  
     /**
 306  
      * <p>
 307  
      * Builds a <code>toString</code> value through reflection.
 308  
      * </p>
 309  
      *
 310  
      * <p>
 311  
      * It uses <code>AccessibleObject.setAccessible</code> to gain access to private fields. This means that it will
 312  
      * throw a security exception if run under a security manager, if the permissions are not set up correctly. It is
 313  
      * also not as efficient as testing explicitly.
 314  
      * </p>
 315  
      *
 316  
      * <p>
 317  
      * If the <code>outputTransients</code> is <code>true</code>, transient fields will be output, otherwise they
 318  
      * are ignored, as they are likely derived fields, and not part of the value of the Object.
 319  
      * </p>
 320  
      *
 321  
      * <p>
 322  
      * If the <code>outputStatics</code> is <code>true</code>, static fields will be output, otherwise they are
 323  
      * ignored.
 324  
      * </p>
 325  
      *
 326  
      * <p>
 327  
      * Superclass fields will be appended up to and including the specified superclass. A null superclass is treated as
 328  
      * <code>java.lang.Object</code>.
 329  
      * </p>
 330  
      *
 331  
      * <p>
 332  
      * If the style is <code>null</code>, the default <code>ToStringStyle</code> is used.
 333  
      * </p>
 334  
      *
 335  
      * @param <T>
 336  
      *            the type of the object
 337  
      * @param object
 338  
      *            the Object to be output
 339  
      * @param style
 340  
      *            the style of the <code>toString</code> to create, may be <code>null</code>
 341  
      * @param outputTransients
 342  
      *            whether to include transient fields
 343  
      * @param outputStatics
 344  
      *            whether to include static fields
 345  
      * @param excludeNullValues
 346  
      *            whether to exclude fields whose values are null
 347  
      * @param reflectUpToClass
 348  
      *            the superclass to reflect up to (inclusive), may be <code>null</code>
 349  
      * @return the String result
 350  
      * @throws IllegalArgumentException
 351  
      *             if the Object is <code>null</code>
 352  
      *
 353  
      * @see ToStringExclude
 354  
      * @since 3.6
 355  
      */
 356  
     public static <T> String toString(
 357  
             final T object, final ToStringStyle style, final boolean outputTransients,
 358  
             final boolean outputStatics, boolean excludeNullValues, final Class<? super T> reflectUpToClass) {
 359  16
         return new ReflectionToStringBuilder(object, style, null, reflectUpToClass, outputTransients, outputStatics, excludeNullValues)
 360  8
                 .toString();
 361  
     }
 362  
 
 363  
     /**
 364  
      * Builds a String for a toString method excluding the given field names.
 365  
      *
 366  
      * @param object
 367  
      *            The object to "toString".
 368  
      * @param excludeFieldNames
 369  
      *            The field names to exclude. Null excludes nothing.
 370  
      * @return The toString value.
 371  
      */
 372  
     public static String toStringExclude(final Object object, final Collection<String> excludeFieldNames) {
 373  5
         return toStringExclude(object, toNoNullStringArray(excludeFieldNames));
 374  
     }
 375  
 
 376  
     /**
 377  
      * Converts the given Collection into an array of Strings. The returned array does not contain <code>null</code>
 378  
      * entries. Note that {@link Arrays#sort(Object[])} will throw an {@link NullPointerException} if an array element
 379  
      * is <code>null</code>.
 380  
      *
 381  
      * @param collection
 382  
      *            The collection to convert
 383  
      * @return A new array of Strings.
 384  
      */
 385  
     static String[] toNoNullStringArray(final Collection<String> collection) {
 386  5
         if (collection == null) {
 387  1
             return ArrayUtils.EMPTY_STRING_ARRAY;
 388  
         }
 389  4
         return toNoNullStringArray(collection.toArray());
 390  
     }
 391  
 
 392  
     /**
 393  
      * Returns a new array of Strings without null elements. Internal method used to normalize exclude lists
 394  
      * (arrays and collections). Note that {@link Arrays#sort(Object[])} will throw an {@link NullPointerException}
 395  
      * if an array element is <code>null</code>.
 396  
      *
 397  
      * @param array
 398  
      *            The array to check
 399  
      * @return The given array or a new array without null.
 400  
      */
 401  
     static String[] toNoNullStringArray(final Object[] array) {
 402  14
         final List<String> list = new ArrayList<>(array.length);
 403  24
         for (final Object e : array) {
 404  10
             if (e != null) {
 405  4
                 list.add(e.toString());
 406  
             }
 407  
         }
 408  14
         return list.toArray(ArrayUtils.EMPTY_STRING_ARRAY);
 409  
     }
 410  
 
 411  
 
 412  
     /**
 413  
      * Builds a String for a toString method excluding the given field names.
 414  
      *
 415  
      * @param object
 416  
      *            The object to "toString".
 417  
      * @param excludeFieldNames
 418  
      *            The field names to exclude
 419  
      * @return The toString value.
 420  
      */
 421  
     public static String toStringExclude(final Object object, final String... excludeFieldNames) {
 422  11
         return new ReflectionToStringBuilder(object).setExcludeFieldNames(excludeFieldNames).toString();
 423  
     }
 424  
 
 425  
     private static Object checkNotNull(final Object obj) {
 426  115
         Validate.isTrue(obj != null, "The Object passed in should not be null.");
 427  113
         return obj;
 428  
     }
 429  
 
 430  
     /**
 431  
      * Whether or not to append static fields.
 432  
      */
 433  113
     private boolean appendStatics = false;
 434  
 
 435  
     /**
 436  
      * Whether or not to append transient fields.
 437  
      */
 438  113
     private boolean appendTransients = false;
 439  
 
 440  
     /**
 441  
      * Whether or not to append fields that are null.
 442  
      */
 443  
     private boolean excludeNullValues;
 444  
 
 445  
     /**
 446  
      * Which field names to exclude from output. Intended for fields like <code>"password"</code>.
 447  
      *
 448  
      * @since 3.0 this is protected instead of private
 449  
      */
 450  
     protected String[] excludeFieldNames;
 451  
 
 452  
     /**
 453  
      * The last super class to stop appending fields for.
 454  
      */
 455  113
     private Class<?> upToClass = null;
 456  
 
 457  
     /**
 458  
      * <p>
 459  
      * Constructor.
 460  
      * </p>
 461  
      *
 462  
      * <p>
 463  
      * This constructor outputs using the default style set with <code>setDefaultStyle</code>.
 464  
      * </p>
 465  
      *
 466  
      * @param object
 467  
      *            the Object to build a <code>toString</code> for, must not be <code>null</code>
 468  
      * @throws IllegalArgumentException
 469  
      *             if the Object passed in is <code>null</code>
 470  
      */
 471  
     public ReflectionToStringBuilder(final Object object) {
 472  15
         super(checkNotNull(object));
 473  15
     }
 474  
 
 475  
     /**
 476  
      * <p>
 477  
      * Constructor.
 478  
      * </p>
 479  
      *
 480  
      * <p>
 481  
      * If the style is <code>null</code>, the default style is used.
 482  
      * </p>
 483  
      *
 484  
      * @param object
 485  
      *            the Object to build a <code>toString</code> for, must not be <code>null</code>
 486  
      * @param style
 487  
      *            the style of the <code>toString</code> to create, may be <code>null</code>
 488  
      * @throws IllegalArgumentException
 489  
      *             if the Object passed in is <code>null</code>
 490  
      */
 491  
     public ReflectionToStringBuilder(final Object object, final ToStringStyle style) {
 492  12
         super(checkNotNull(object), style);
 493  12
     }
 494  
 
 495  
     /**
 496  
      * <p>
 497  
      * Constructor.
 498  
      * </p>
 499  
      *
 500  
      * <p>
 501  
      * If the style is <code>null</code>, the default style is used.
 502  
      * </p>
 503  
      *
 504  
      * <p>
 505  
      * If the buffer is <code>null</code>, a new one is created.
 506  
      * </p>
 507  
      *
 508  
      * @param object
 509  
      *            the Object to build a <code>toString</code> for
 510  
      * @param style
 511  
      *            the style of the <code>toString</code> to create, may be <code>null</code>
 512  
      * @param buffer
 513  
      *            the <code>StringBuffer</code> to populate, may be <code>null</code>
 514  
      * @throws IllegalArgumentException
 515  
      *             if the Object passed in is <code>null</code>
 516  
      */
 517  
     public ReflectionToStringBuilder(final Object object, final ToStringStyle style, final StringBuffer buffer) {
 518  2
         super(checkNotNull(object), style, buffer);
 519  1
     }
 520  
 
 521  
     /**
 522  
      * Constructor.
 523  
      *
 524  
      * @param <T>
 525  
      *            the type of the object
 526  
      * @param object
 527  
      *            the Object to build a <code>toString</code> for
 528  
      * @param style
 529  
      *            the style of the <code>toString</code> to create, may be <code>null</code>
 530  
      * @param buffer
 531  
      *            the <code>StringBuffer</code> to populate, may be <code>null</code>
 532  
      * @param reflectUpToClass
 533  
      *            the superclass to reflect up to (inclusive), may be <code>null</code>
 534  
      * @param outputTransients
 535  
      *            whether to include transient fields
 536  
      * @param outputStatics
 537  
      *            whether to include static fields
 538  
      * @since 2.1
 539  
      */
 540  
     public <T> ReflectionToStringBuilder(
 541  
             final T object, final ToStringStyle style, final StringBuffer buffer,
 542  
             final Class<? super T> reflectUpToClass, final boolean outputTransients, final boolean outputStatics) {
 543  71
         super(checkNotNull(object), style, buffer);
 544  70
         this.setUpToClass(reflectUpToClass);
 545  70
         this.setAppendTransients(outputTransients);
 546  70
         this.setAppendStatics(outputStatics);
 547  70
     }
 548  
 
 549  
     /**
 550  
      * Constructor.
 551  
      *
 552  
      * @param <T>
 553  
      *            the type of the object
 554  
      * @param object
 555  
      *            the Object to build a <code>toString</code> for
 556  
      * @param style
 557  
      *            the style of the <code>toString</code> to create, may be <code>null</code>
 558  
      * @param buffer
 559  
      *            the <code>StringBuffer</code> to populate, may be <code>null</code>
 560  
      * @param reflectUpToClass
 561  
      *            the superclass to reflect up to (inclusive), may be <code>null</code>
 562  
      * @param outputTransients
 563  
      *            whether to include transient fields
 564  
      * @param outputStatics
 565  
      *            whether to include static fields
 566  
      * @param excludeNullValues
 567  
      *            whether to exclude fields who value is null
 568  
      * @since 3.6
 569  
      */
 570  
     public <T> ReflectionToStringBuilder(
 571  
             final T object, final ToStringStyle style, final StringBuffer buffer,
 572  
             final Class<? super T> reflectUpToClass, final boolean outputTransients, final boolean outputStatics,
 573  
             final boolean excludeNullValues) {
 574  15
         super(checkNotNull(object), style, buffer);
 575  15
         this.setUpToClass(reflectUpToClass);
 576  15
         this.setAppendTransients(outputTransients);
 577  15
         this.setAppendStatics(outputStatics);
 578  15
         this.setExcludeNullValues(excludeNullValues);
 579  15
     }
 580  
 
 581  
     /**
 582  
      * Returns whether or not to append the given <code>Field</code>.
 583  
      * <ul>
 584  
      * <li>Transient fields are appended only if {@link #isAppendTransients()} returns <code>true</code>.
 585  
      * <li>Static fields are appended only if {@link #isAppendStatics()} returns <code>true</code>.
 586  
      * <li>Inner class fields are not appended.</li>
 587  
      * </ul>
 588  
      *
 589  
      * @param field
 590  
      *            The Field to test.
 591  
      * @return Whether or not to append the given <code>Field</code>.
 592  
      */
 593  
     protected boolean accept(final Field field) {
 594  376
         if (field.getName().indexOf(ClassUtils.INNER_CLASS_SEPARATOR_CHAR) != -1) {
 595  
             // Reject field from inner class.
 596  29
             return false;
 597  
         }
 598  347
         if (Modifier.isTransient(field.getModifiers()) && !this.isAppendTransients()) {
 599  
             // Reject transient fields.
 600  33
             return false;
 601  
         }
 602  314
         if (Modifier.isStatic(field.getModifiers()) && !this.isAppendStatics()) {
 603  
             // Reject static fields.
 604  109
             return false;
 605  
         }
 606  205
         if (this.excludeFieldNames != null
 607  20
             && Arrays.binarySearch(this.excludeFieldNames, field.getName()) >= 0) {
 608  
             // Reject fields from the getExcludeFieldNames list.
 609  3
             return false;
 610  
         }
 611  202
         return !field.isAnnotationPresent(ToStringExclude.class);
 612  
     }
 613  
 
 614  
     /**
 615  
      * <p>
 616  
      * Appends the fields and values defined by the given object of the given Class.
 617  
      * </p>
 618  
      *
 619  
      * <p>
 620  
      * If a cycle is detected as an object is &quot;toString()'ed&quot;, such an object is rendered as if
 621  
      * <code>Object.toString()</code> had been called and not implemented by the object.
 622  
      * </p>
 623  
      *
 624  
      * @param clazz
 625  
      *            The class of object parameter
 626  
      */
 627  
     protected void appendFieldsIn(final Class<?> clazz) {
 628  224
         if (clazz.isArray()) {
 629  24
             this.reflectionAppendArray(this.getObject());
 630  24
             return;
 631  
         }
 632  200
         final Field[] fields = clazz.getDeclaredFields();
 633  200
         AccessibleObject.setAccessible(fields, true);
 634  576
         for (final Field field : fields) {
 635  376
             final String fieldName = field.getName();
 636  376
             if (this.accept(field)) {
 637  
                 try {
 638  
                     // Warning: Field.get(Object) creates wrappers objects
 639  
                     // for primitive types.
 640  201
                     final Object fieldValue = this.getValue(field);
 641  201
                     if (!excludeNullValues || fieldValue != null) {
 642  187
                         this.append(fieldName, fieldValue);
 643  
                     }
 644  0
                 } catch (final IllegalAccessException ex) {
 645  
                     //this can't happen. Would get a Security exception
 646  
                     // instead
 647  
                     //throw a runtime exception in case the impossible
 648  
                     // happens.
 649  0
                     throw new InternalError("Unexpected IllegalAccessException: " + ex.getMessage());
 650  201
                 }
 651  
             }
 652  
         }
 653  200
     }
 654  
 
 655  
     /**
 656  
      * @return Returns the excludeFieldNames.
 657  
      */
 658  
     public String[] getExcludeFieldNames() {
 659  0
         return this.excludeFieldNames.clone();
 660  
     }
 661  
 
 662  
     /**
 663  
      * <p>
 664  
      * Gets the last super class to stop appending fields for.
 665  
      * </p>
 666  
      *
 667  
      * @return The last super class to stop appending fields for.
 668  
      */
 669  
     public Class<?> getUpToClass() {
 670  127
         return this.upToClass;
 671  
     }
 672  
 
 673  
     /**
 674  
      * <p>
 675  
      * Calls <code>java.lang.reflect.Field.get(Object)</code>.
 676  
      * </p>
 677  
      *
 678  
      * @param field
 679  
      *            The Field to query.
 680  
      * @return The Object from the given Field.
 681  
      *
 682  
      * @throws IllegalArgumentException
 683  
      *             see {@link java.lang.reflect.Field#get(Object)}
 684  
      * @throws IllegalAccessException
 685  
      *             see {@link java.lang.reflect.Field#get(Object)}
 686  
      *
 687  
      * @see java.lang.reflect.Field#get(Object)
 688  
      */
 689  
     protected Object getValue(final Field field) throws IllegalArgumentException, IllegalAccessException {
 690  201
         return field.get(this.getObject());
 691  
     }
 692  
 
 693  
     /**
 694  
      * <p>
 695  
      * Gets whether or not to append static fields.
 696  
      * </p>
 697  
      *
 698  
      * @return Whether or not to append static fields.
 699  
      * @since 2.1
 700  
      */
 701  
     public boolean isAppendStatics() {
 702  141
         return this.appendStatics;
 703  
     }
 704  
 
 705  
     /**
 706  
      * <p>
 707  
      * Gets whether or not to append transient fields.
 708  
      * </p>
 709  
      *
 710  
      * @return Whether or not to append transient fields.
 711  
      */
 712  
     public boolean isAppendTransients() {
 713  40
         return this.appendTransients;
 714  
     }
 715  
 
 716  
     /**
 717  
      * <p>
 718  
      * Gets whether or not to append fields whose values are null.
 719  
      * </p>
 720  
      *
 721  
      * @return Whether or not to append fields whose values are null.
 722  
      * @since 3.6
 723  
      */
 724  
     public boolean isExcludeNullValues() {
 725  4
         return this.excludeNullValues;
 726  
     }
 727  
 
 728  
     /**
 729  
      * <p>
 730  
      * Append to the <code>toString</code> an <code>Object</code> array.
 731  
      * </p>
 732  
      *
 733  
      * @param array
 734  
      *            the array to add to the <code>toString</code>
 735  
      * @return this
 736  
      */
 737  
     public ReflectionToStringBuilder reflectionAppendArray(final Object array) {
 738  24
         this.getStyle().reflectionAppendArrayDetail(this.getStringBuffer(), null, array);
 739  24
         return this;
 740  
     }
 741  
 
 742  
     /**
 743  
      * <p>
 744  
      * Sets whether or not to append static fields.
 745  
      * </p>
 746  
      *
 747  
      * @param appendStatics
 748  
      *            Whether or not to append static fields.
 749  
      * @since 2.1
 750  
      */
 751  
     public void setAppendStatics(final boolean appendStatics) {
 752  85
         this.appendStatics = appendStatics;
 753  85
     }
 754  
 
 755  
     /**
 756  
      * <p>
 757  
      * Sets whether or not to append transient fields.
 758  
      * </p>
 759  
      *
 760  
      * @param appendTransients
 761  
      *            Whether or not to append transient fields.
 762  
      */
 763  
     public void setAppendTransients(final boolean appendTransients) {
 764  85
         this.appendTransients = appendTransients;
 765  85
     }
 766  
 
 767  
     /**
 768  
      * <p>
 769  
      * Sets whether or not to append fields whose values are null.
 770  
      * </p>
 771  
      *
 772  
      * @param excludeNullValues
 773  
      *            Whether or not to append fields whose values are null.
 774  
      * @since 3.6
 775  
      */
 776  
     public void setExcludeNullValues(final boolean excludeNullValues) {
 777  17
         this.excludeNullValues = excludeNullValues;
 778  17
     }
 779  
 
 780  
     /**
 781  
      * Sets the field names to exclude.
 782  
      *
 783  
      * @param excludeFieldNamesParam
 784  
      *            The excludeFieldNames to excluding from toString or <code>null</code>.
 785  
      * @return <code>this</code>
 786  
      */
 787  
     public ReflectionToStringBuilder setExcludeFieldNames(final String... excludeFieldNamesParam) {
 788  11
         if (excludeFieldNamesParam == null) {
 789  1
             this.excludeFieldNames = null;
 790  
         } else {
 791  
             //clone and remove nulls
 792  10
             this.excludeFieldNames = toNoNullStringArray(excludeFieldNamesParam);
 793  10
             Arrays.sort(this.excludeFieldNames);
 794  
         }
 795  11
         return this;
 796  
     }
 797  
 
 798  
     /**
 799  
      * <p>
 800  
      * Sets the last super class to stop appending fields for.
 801  
      * </p>
 802  
      *
 803  
      * @param clazz
 804  
      *            The last super class to stop appending fields for.
 805  
      */
 806  
     public void setUpToClass(final Class<?> clazz) {
 807  87
         if (clazz != null) {
 808  19
             final Object object = getObject();
 809  19
             if (object != null && clazz.isInstance(object) == false) {
 810  1
                 throw new IllegalArgumentException("Specified class is not a superclass of the object");
 811  
             }
 812  
         }
 813  86
         this.upToClass = clazz;
 814  86
     }
 815  
 
 816  
     /**
 817  
      * <p>
 818  
      * Gets the String built by this builder.
 819  
      * </p>
 820  
      *
 821  
      * @return the built string
 822  
      */
 823  
     @Override
 824  
     public String toString() {
 825  113
         if (this.getObject() == null) {
 826  0
             return this.getStyle().getNullText();
 827  
         }
 828  113
         Class<?> clazz = this.getObject().getClass();
 829  113
         this.appendFieldsIn(clazz);
 830  224
         while (clazz.getSuperclass() != null && clazz != this.getUpToClass()) {
 831  111
             clazz = clazz.getSuperclass();
 832  111
             this.appendFieldsIn(clazz);
 833  
         }
 834  113
         return super.toString();
 835  
     }
 836  
 
 837  
 }