diff options
Diffstat (limited to 'src/org/apache/commons/lang3/builder/ReflectionToStringBuilder.java')
| -rw-r--r-- | src/org/apache/commons/lang3/builder/ReflectionToStringBuilder.java | 697 |
1 files changed, 0 insertions, 697 deletions
diff --git a/src/org/apache/commons/lang3/builder/ReflectionToStringBuilder.java b/src/org/apache/commons/lang3/builder/ReflectionToStringBuilder.java deleted file mode 100644 index a7ecbac..0000000 --- a/src/org/apache/commons/lang3/builder/ReflectionToStringBuilder.java +++ /dev/null @@ -1,697 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.commons.lang3.builder; - -import java.lang.reflect.AccessibleObject; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; - -import org.apache.commons.lang3.ArrayUtils; -import org.apache.commons.lang3.ClassUtils; - -/** - * <p> - * Assists in implementing {@link Object#toString()} methods using reflection. - * </p> - * - * <p> - * This class uses reflection to determine the fields to append. Because these fields are usually private, the class - * uses {@link java.lang.reflect.AccessibleObject#setAccessible(java.lang.reflect.AccessibleObject[], boolean)} to - * change the visibility of the fields. This will fail under a security manager, unless the appropriate permissions are - * set up correctly. - * </p> - * - * <p> - * A typical invocation for this method would look like: - * </p> - * - * <pre> - * public String toString() { - * return ReflectionToStringBuilder.toString(this); - * }</pre> - * - * - * - * <p> - * You can also use the builder to debug 3rd party objects: - * </p> - * - * <pre> - * System.out.println("An object: " + ReflectionToStringBuilder.toString(anObject));</pre> - * - * - * - * <p> - * A subclass can control field output by overriding the methods: - * <ul> - * <li>{@link #accept(java.lang.reflect.Field)}</li> - * <li>{@link #getValue(java.lang.reflect.Field)}</li> - * </ul> - * </p> - * <p> - * For example, this method does <i>not</i> include the <code>password</code> field in the returned - * <code>String</code>: - * </p> - * - * <pre> - * public String toString() { - * return (new ReflectionToStringBuilder(this) { - * protected boolean accept(Field f) { - * return super.accept(f) && !f.getName().equals("password"); - * } - * }).toString(); - * }</pre> - * - * - * - * <p> - * The exact format of the <code>toString</code> is determined by the {@link ToStringStyle} passed into the - * constructor. - * </p> - * - * @since 2.0 - * @version $Id: ReflectionToStringBuilder.java 1090821 2011-04-10 15:59:07Z mbenson $ - */ -public class ReflectionToStringBuilder extends ToStringBuilder { - - /** - * <p> - * Builds a <code>toString</code> value using the default <code>ToStringStyle</code> through reflection. - * </p> - * - * <p> - * It uses <code>AccessibleObject.setAccessible</code> to gain access to private fields. This means that it will - * throw a security exception if run under a security manager, if the permissions are not set up correctly. It is - * also not as efficient as testing explicitly. - * </p> - * - * <p> - * Transient members will be not be included, as they are likely derived. Static fields will not be included. - * Superclass fields will be appended. - * </p> - * - * @param object - * the Object to be output - * @return the String result - * @throws IllegalArgumentException - * if the Object is <code>null</code> - */ - public static String toString(Object object) { - return toString(object, null, false, false, null); - } - - /** - * <p> - * Builds a <code>toString</code> value through reflection. - * </p> - * - * <p> - * It uses <code>AccessibleObject.setAccessible</code> to gain access to private fields. This means that it will - * throw a security exception if run under a security manager, if the permissions are not set up correctly. It is - * also not as efficient as testing explicitly. - * </p> - * - * <p> - * Transient members will be not be included, as they are likely derived. Static fields will not be included. - * Superclass fields will be appended. - * </p> - * - * <p> - * If the style is <code>null</code>, the default <code>ToStringStyle</code> is used. - * </p> - * - * @param object - * the Object to be output - * @param style - * the style of the <code>toString</code> to create, may be <code>null</code> - * @return the String result - * @throws IllegalArgumentException - * if the Object or <code>ToStringStyle</code> is <code>null</code> - */ - public static String toString(Object object, ToStringStyle style) { - return toString(object, style, false, false, null); - } - - /** - * <p> - * Builds a <code>toString</code> value through reflection. - * </p> - * - * <p> - * It uses <code>AccessibleObject.setAccessible</code> to gain access to private fields. This means that it will - * throw a security exception if run under a security manager, if the permissions are not set up correctly. It is - * also not as efficient as testing explicitly. - * </p> - * - * <p> - * If the <code>outputTransients</code> is <code>true</code>, transient members will be output, otherwise they - * are ignored, as they are likely derived fields, and not part of the value of the Object. - * </p> - * - * <p> - * Static fields will not be included. Superclass fields will be appended. - * </p> - * - * <p> - * If the style is <code>null</code>, the default <code>ToStringStyle</code> is used. - * </p> - * - * @param object - * the Object to be output - * @param style - * the style of the <code>toString</code> to create, may be <code>null</code> - * @param outputTransients - * whether to include transient fields - * @return the String result - * @throws IllegalArgumentException - * if the Object is <code>null</code> - */ - public static String toString(Object object, ToStringStyle style, boolean outputTransients) { - return toString(object, style, outputTransients, false, null); - } - - /** - * <p> - * Builds a <code>toString</code> value through reflection. - * </p> - * - * <p> - * It uses <code>AccessibleObject.setAccessible</code> to gain access to private fields. This means that it will - * throw a security exception if run under a security manager, if the permissions are not set up correctly. It is - * also not as efficient as testing explicitly. - * </p> - * - * <p> - * If the <code>outputTransients</code> is <code>true</code>, transient fields will be output, otherwise they - * are ignored, as they are likely derived fields, and not part of the value of the Object. - * </p> - * - * <p> - * If the <code>outputStatics</code> is <code>true</code>, static fields will be output, otherwise they are - * ignored. - * </p> - * - * <p> - * Static fields will not be included. Superclass fields will be appended. - * </p> - * - * <p> - * If the style is <code>null</code>, the default <code>ToStringStyle</code> is used. - * </p> - * - * @param object - * the Object to be output - * @param style - * the style of the <code>toString</code> to create, may be <code>null</code> - * @param outputTransients - * whether to include transient fields - * @param outputStatics - * whether to include transient fields - * @return the String result - * @throws IllegalArgumentException - * if the Object is <code>null</code> - * @since 2.1 - */ - public static String toString(Object object, ToStringStyle style, boolean outputTransients, boolean outputStatics) { - return toString(object, style, outputTransients, outputStatics, null); - } - - /** - * <p> - * Builds a <code>toString</code> value through reflection. - * </p> - * - * <p> - * It uses <code>AccessibleObject.setAccessible</code> to gain access to private fields. This means that it will - * throw a security exception if run under a security manager, if the permissions are not set up correctly. It is - * also not as efficient as testing explicitly. - * </p> - * - * <p> - * If the <code>outputTransients</code> is <code>true</code>, transient fields will be output, otherwise they - * are ignored, as they are likely derived fields, and not part of the value of the Object. - * </p> - * - * <p> - * If the <code>outputStatics</code> is <code>true</code>, static fields will be output, otherwise they are - * ignored. - * </p> - * - * <p> - * Superclass fields will be appended up to and including the specified superclass. A null superclass is treated as - * <code>java.lang.Object</code>. - * </p> - * - * <p> - * If the style is <code>null</code>, the default <code>ToStringStyle</code> is used. - * </p> - * - * @param <T> - * the type of the object - * @param object - * the Object to be output - * @param style - * the style of the <code>toString</code> to create, may be <code>null</code> - * @param outputTransients - * whether to include transient fields - * @param outputStatics - * whether to include static fields - * @param reflectUpToClass - * the superclass to reflect up to (inclusive), may be <code>null</code> - * @return the String result - * @throws IllegalArgumentException - * if the Object is <code>null</code> - * @since 2.1 - */ - public static <T> String toString( - T object, ToStringStyle style, boolean outputTransients, - boolean outputStatics, Class<? super T> reflectUpToClass) { - return new ReflectionToStringBuilder(object, style, null, reflectUpToClass, outputTransients, outputStatics) - .toString(); - } - - /** - * Builds a String for a toString method excluding the given field names. - * - * @param object - * The object to "toString". - * @param excludeFieldNames - * The field names to exclude. Null excludes nothing. - * @return The toString value. - */ - public static String toStringExclude(Object object, Collection<String> excludeFieldNames) { - return toStringExclude(object, toNoNullStringArray(excludeFieldNames)); - } - - /** - * Converts the given Collection into an array of Strings. The returned array does not contain <code>null</code> - * entries. Note that {@link Arrays#sort(Object[])} will throw an {@link NullPointerException} if an array element - * is <code>null</code>. - * - * @param collection - * The collection to convert - * @return A new array of Strings. - */ - static String[] toNoNullStringArray(Collection<String> collection) { - if (collection == null) { - return ArrayUtils.EMPTY_STRING_ARRAY; - } - return toNoNullStringArray(collection.toArray()); - } - - /** - * Returns a new array of Strings without null elements. Internal method used to normalize exclude lists - * (arrays and collections). Note that {@link Arrays#sort(Object[])} will throw an {@link NullPointerException} - * if an array element is <code>null</code>. - * - * @param array - * The array to check - * @return The given array or a new array without null. - */ - static String[] toNoNullStringArray(Object[] array) { - List<String> list = new ArrayList<String>(array.length); - for (Object e : array) { - if (e != null) { - list.add(e.toString()); - } - } - return list.toArray(ArrayUtils.EMPTY_STRING_ARRAY); - } - - - /** - * Builds a String for a toString method excluding the given field names. - * - * @param object - * The object to "toString". - * @param excludeFieldNames - * The field names to exclude - * @return The toString value. - */ - public static String toStringExclude(Object object, String... excludeFieldNames) { - return new ReflectionToStringBuilder(object).setExcludeFieldNames(excludeFieldNames).toString(); - } - - /** - * Whether or not to append static fields. - */ - private boolean appendStatics = false; - - /** - * Whether or not to append transient fields. - */ - private boolean appendTransients = false; - - /** - * Which field names to exclude from output. Intended for fields like <code>"password"</code>. - * - * @since 3.0 this is protected instead of private - */ - protected String[] excludeFieldNames; - - /** - * The last super class to stop appending fields for. - */ - private Class<?> upToClass = null; - - /** - * <p> - * Constructor. - * </p> - * - * <p> - * This constructor outputs using the default style set with <code>setDefaultStyle</code>. - * </p> - * - * @param object - * the Object to build a <code>toString</code> for, must not be <code>null</code> - * @throws IllegalArgumentException - * if the Object passed in is <code>null</code> - */ - public ReflectionToStringBuilder(Object object) { - super(object); - } - - /** - * <p> - * Constructor. - * </p> - * - * <p> - * If the style is <code>null</code>, the default style is used. - * </p> - * - * @param object - * the Object to build a <code>toString</code> for, must not be <code>null</code> - * @param style - * the style of the <code>toString</code> to create, may be <code>null</code> - * @throws IllegalArgumentException - * if the Object passed in is <code>null</code> - */ - public ReflectionToStringBuilder(Object object, ToStringStyle style) { - super(object, style); - } - - /** - * <p> - * Constructor. - * </p> - * - * <p> - * If the style is <code>null</code>, the default style is used. - * </p> - * - * <p> - * If the buffer is <code>null</code>, a new one is created. - * </p> - * - * @param object - * the Object to build a <code>toString</code> for - * @param style - * the style of the <code>toString</code> to create, may be <code>null</code> - * @param buffer - * the <code>StringBuffer</code> to populate, may be <code>null</code> - * @throws IllegalArgumentException - * if the Object passed in is <code>null</code> - */ - public ReflectionToStringBuilder(Object object, ToStringStyle style, StringBuffer buffer) { - super(object, style, buffer); - } - - /** - * Constructor. - * - * @param <T> - * the type of the object - * @param object - * the Object to build a <code>toString</code> for - * @param style - * the style of the <code>toString</code> to create, may be <code>null</code> - * @param buffer - * the <code>StringBuffer</code> to populate, may be <code>null</code> - * @param reflectUpToClass - * the superclass to reflect up to (inclusive), may be <code>null</code> - * @param outputTransients - * whether to include transient fields - * @param outputStatics - * whether to include static fields - * @since 2.1 - */ - public <T> ReflectionToStringBuilder( - T object, ToStringStyle style, StringBuffer buffer, - Class<? super T> reflectUpToClass, boolean outputTransients, boolean outputStatics) { - super(object, style, buffer); - this.setUpToClass(reflectUpToClass); - this.setAppendTransients(outputTransients); - this.setAppendStatics(outputStatics); - } - - /** - * Returns whether or not to append the given <code>Field</code>. - * <ul> - * <li>Transient fields are appended only if {@link #isAppendTransients()} returns <code>true</code>. - * <li>Static fields are appended only if {@link #isAppendStatics()} returns <code>true</code>. - * <li>Inner class fields are not appened.</li> - * </ul> - * - * @param field - * The Field to test. - * @return Whether or not to append the given <code>Field</code>. - */ - protected boolean accept(Field field) { - if (field.getName().indexOf(ClassUtils.INNER_CLASS_SEPARATOR_CHAR) != -1) { - // Reject field from inner class. - return false; - } - if (Modifier.isTransient(field.getModifiers()) && !this.isAppendTransients()) { - // Reject transient fields. - return false; - } - if (Modifier.isStatic(field.getModifiers()) && !this.isAppendStatics()) { - // Reject static fields. - return false; - } - if (this.excludeFieldNames != null - && Arrays.binarySearch(this.excludeFieldNames, field.getName()) >= 0) { - // Reject fields from the getExcludeFieldNames list. - return false; - } - return true; - } - - /** - * <p> - * Appends the fields and values defined by the given object of the given Class. - * </p> - * - * <p> - * If a cycle is detected as an object is "toString()'ed", such an object is rendered as if - * <code>Object.toString()</code> had been called and not implemented by the object. - * </p> - * - * @param clazz - * The class of object parameter - */ - protected void appendFieldsIn(Class<?> clazz) { - if (clazz.isArray()) { - this.reflectionAppendArray(this.getObject()); - return; - } - Field[] fields = clazz.getDeclaredFields(); - AccessibleObject.setAccessible(fields, true); - for (Field field : fields) { - String fieldName = field.getName(); - if (this.accept(field)) { - try { - // Warning: Field.get(Object) creates wrappers objects - // for primitive types. - Object fieldValue = this.getValue(field); - this.append(fieldName, fieldValue); - } catch (IllegalAccessException ex) { - //this can't happen. Would get a Security exception - // instead - //throw a runtime exception in case the impossible - // happens. - throw new InternalError("Unexpected IllegalAccessException: " + ex.getMessage()); - } - } - } - } - - /** - * @return Returns the excludeFieldNames. - */ - public String[] getExcludeFieldNames() { - return this.excludeFieldNames.clone(); - } - - /** - * <p> - * Gets the last super class to stop appending fields for. - * </p> - * - * @return The last super class to stop appending fields for. - */ - public Class<?> getUpToClass() { - return this.upToClass; - } - - /** - * <p> - * Calls <code>java.lang.reflect.Field.get(Object)</code>. - * </p> - * - * @param field - * The Field to query. - * @return The Object from the given Field. - * - * @throws IllegalArgumentException - * see {@link java.lang.reflect.Field#get(Object)} - * @throws IllegalAccessException - * see {@link java.lang.reflect.Field#get(Object)} - * - * @see java.lang.reflect.Field#get(Object) - */ - protected Object getValue(Field field) throws IllegalArgumentException, IllegalAccessException { - return field.get(this.getObject()); - } - - /** - * <p> - * Gets whether or not to append static fields. - * </p> - * - * @return Whether or not to append static fields. - * @since 2.1 - */ - public boolean isAppendStatics() { - return this.appendStatics; - } - - /** - * <p> - * Gets whether or not to append transient fields. - * </p> - * - * @return Whether or not to append transient fields. - */ - public boolean isAppendTransients() { - return this.appendTransients; - } - - /** - * <p> - * Append to the <code>toString</code> an <code>Object</code> array. - * </p> - * - * @param array - * the array to add to the <code>toString</code> - * @return this - */ - public ReflectionToStringBuilder reflectionAppendArray(Object array) { - this.getStyle().reflectionAppendArrayDetail(this.getStringBuffer(), null, array); - return this; - } - - /** - * <p> - * Sets whether or not to append static fields. - * </p> - * - * @param appendStatics - * Whether or not to append static fields. - * @since 2.1 - */ - public void setAppendStatics(boolean appendStatics) { - this.appendStatics = appendStatics; - } - - /** - * <p> - * Sets whether or not to append transient fields. - * </p> - * - * @param appendTransients - * Whether or not to append transient fields. - */ - public void setAppendTransients(boolean appendTransients) { - this.appendTransients = appendTransients; - } - - /** - * Sets the field names to exclude. - * - * @param excludeFieldNamesParam - * The excludeFieldNames to excluding from toString or <code>null</code>. - * @return <code>this</code> - */ - public ReflectionToStringBuilder setExcludeFieldNames(String... excludeFieldNamesParam) { - if (excludeFieldNamesParam == null) { - this.excludeFieldNames = null; - } else { - //clone and remove nulls - this.excludeFieldNames = toNoNullStringArray(excludeFieldNamesParam); - Arrays.sort(this.excludeFieldNames); - } - return this; - } - - /** - * <p> - * Sets the last super class to stop appending fields for. - * </p> - * - * @param clazz - * The last super class to stop appending fields for. - */ - public void setUpToClass(Class<?> clazz) { - if (clazz != null) { - Object object = getObject(); - if (object != null && clazz.isInstance(object) == false) { - throw new IllegalArgumentException("Specified class is not a superclass of the object"); - } - } - this.upToClass = clazz; - } - - /** - * <p> - * Gets the String built by this builder. - * </p> - * - * @return the built string - */ - @Override - public String toString() { - if (this.getObject() == null) { - return this.getStyle().getNullText(); - } - Class<?> clazz = this.getObject().getClass(); - this.appendFieldsIn(clazz); - while (clazz.getSuperclass() != null && clazz != this.getUpToClass()) { - clazz = clazz.getSuperclass(); - this.appendFieldsIn(clazz); - } - return super.toString(); - } - -} |
