You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by tr...@apache.org on 2006/01/20 14:48:55 UTC
svn commit: r370807 [13/22] - in /directory/sandbox/trustin/mina-spi: ./
core/src/main/java/org/apache/mina/common/
core/src/main/java/org/apache/mina/common/support/
core/src/main/java/org/apache/mina/common/support/discovery/
core/src/main/java/org/a...
Added: directory/sandbox/trustin/mina-spi/core/src/main/java/org/apache/mina/common/support/lang/builder/HashCodeBuilder.java
URL: http://svn.apache.org/viewcvs/directory/sandbox/trustin/mina-spi/core/src/main/java/org/apache/mina/common/support/lang/builder/HashCodeBuilder.java?rev=370807&view=auto
==============================================================================
--- directory/sandbox/trustin/mina-spi/core/src/main/java/org/apache/mina/common/support/lang/builder/HashCodeBuilder.java (added)
+++ directory/sandbox/trustin/mina-spi/core/src/main/java/org/apache/mina/common/support/lang/builder/HashCodeBuilder.java Fri Jan 20 05:47:50 2006
@@ -0,0 +1,630 @@
+/*
+ * Copyright 2002-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.mina.common.support.lang.builder;
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+
+/**
+ * <p>Assists in implementing {@link Object#hashCode()} methods.</p>
+ *
+ * <p> This class enables a good <code>hashCode</code> method to be built for any class. It
+ * follows the rules laid out in the book
+ * <a href="http://java.sun.com/docs/books/effective/index.html">Effective Java</a>
+ * by Joshua Bloch. Writing a good <code>hashCode</code> method is actually quite
+ * difficult. This class aims to simplify the process.</p>
+ *
+ * <p>All relevant fields from the object should be included in the
+ * <code>hashCode</code> method. Derived fields may be excluded. In general, any
+ * field used in the <code>equals</code> method must be used in the <code>hashCode</code>
+ * method.</p>
+ *
+ * <p>To use this class write code as follows:</p>
+ * <pre>
+ * public class Person {
+ * String name;
+ * int age;
+ * boolean isSmoker;
+ * ...
+ *
+ * public int hashCode() {
+ * // you pick a hard-coded, randomly chosen, non-zero, odd number
+ * // ideally different for each class
+ * return new HashCodeBuilder(17, 37).
+ * append(name).
+ * append(age).
+ * append(smoker).
+ * toHashCode();
+ * }
+ * }
+ * </pre>
+ *
+ * <p>If required, the superclass <code>hashCode()</code> can be added
+ * using {@link #appendSuper}.</p>
+ *
+ * <p>Alternatively, there is a method that uses reflection to determine
+ * the fields to test. Because these fields are usually private, the method,
+ * <code>reflectionHashCode</code>, uses <code>AccessibleObject.setAccessible</code> to
+ * change the visibility of the fields. This will fail under a security manager,
+ * unless the appropriate permissions are set up correctly. It is also slower
+ * than testing explicitly.</p>
+ *
+ * <p>A typical invocation for this method would look like:</p>
+ * <pre>
+ * public int hashCode() {
+ * return HashCodeBuilder.reflectionHashCode(this);
+ * }
+ * </pre>
+ *
+ * @author Stephen Colebourne
+ * @author Gary Gregory
+ * @author Pete Gieser
+ * @since 1.0
+ * @version $Id$
+ */
+public class HashCodeBuilder {
+
+ /**
+ * Constant to use in building the hashCode.
+ */
+ private final int iConstant;
+ /**
+ * Running total of the hashCode.
+ */
+ private int iTotal = 0;
+
+ /**
+ * <p>Uses two hard coded choices for the constants
+ * needed to build a <code>hashCode</code>.</p>
+ */
+ public HashCodeBuilder() {
+ iConstant = 37;
+ iTotal = 17;
+ }
+
+ /**
+ * <p>Two randomly chosen, non-zero, odd numbers must be passed in.
+ * Ideally these should be different for each class, however this is
+ * not vital.</p>
+ *
+ * <p>Prime numbers are preferred, especially for the multiplier.</p>
+ *
+ * @param initialNonZeroOddNumber a non-zero, odd number used as the initial value
+ * @param multiplierNonZeroOddNumber a non-zero, odd number used as the multiplier
+ * @throws IllegalArgumentException if the number is zero or even
+ */
+ public HashCodeBuilder(int initialNonZeroOddNumber, int multiplierNonZeroOddNumber) {
+ if (initialNonZeroOddNumber == 0) {
+ throw new IllegalArgumentException("HashCodeBuilder requires a non zero initial value");
+ }
+ if (initialNonZeroOddNumber % 2 == 0) {
+ throw new IllegalArgumentException("HashCodeBuilder requires an odd initial value");
+ }
+ if (multiplierNonZeroOddNumber == 0) {
+ throw new IllegalArgumentException("HashCodeBuilder requires a non zero multiplier");
+ }
+ if (multiplierNonZeroOddNumber % 2 == 0) {
+ throw new IllegalArgumentException("HashCodeBuilder requires an odd multiplier");
+ }
+ iConstant = multiplierNonZeroOddNumber;
+ iTotal = initialNonZeroOddNumber;
+ }
+
+ //-------------------------------------------------------------------------
+
+ /**
+ * <p>This method uses reflection to build a valid hash code.</p>
+ *
+ * <p>This constructor uses two hard coded choices for the constants
+ * needed to build a hash code.</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 used, as they are likely derived
+ * fields, and not part of the value of the <code>Object</code>.</p>
+ *
+ * <p>Static fields will not be tested. Superclass fields will be included.</p>
+ *
+ * @param object the Object to create a <code>hashCode</code> for
+ * @return int hash code
+ * @throws IllegalArgumentException if the object is <code>null</code>
+ */
+ public static int reflectionHashCode(Object object) {
+ return reflectionHashCode(17, 37, object, false, null);
+ }
+
+ /**
+ * <p>This method uses reflection to build a valid hash code.</p>
+ *
+ * <p>This constructor uses two hard coded choices for the constants needed
+ * to build a hash code.</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 TestTransients parameter is set to <code>true</code>, transient
+ * members will be tested, otherwise they are ignored, as they are likely
+ * derived fields, and not part of the value of the <code>Object</code>.</p>
+ *
+ * <p>Static fields will not be tested. Superclass fields will be included.</p>
+ *
+ * @param object the Object to create a <code>hashCode</code> for
+ * @param testTransients whether to include transient fields
+ * @return int hash code
+ * @throws IllegalArgumentException if the object is <code>null</code>
+ */
+ public static int reflectionHashCode(Object object, boolean testTransients) {
+ return reflectionHashCode(17, 37, object, testTransients, null);
+ }
+
+ /**
+ * <p>This method uses reflection to build a valid hash code.</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 used, as they are likely derived
+ * fields, and not part of the value of the <code>Object</code>.</p>
+ *
+ * <p>Static fields will not be tested. Superclass fields will be included.</p>
+ *
+ * <p>Two randomly chosen, non-zero, odd numbers must be passed in. Ideally
+ * these should be different for each class, however this is not vital.
+ * Prime numbers are preferred, especially for the multiplier.</p>
+ *
+ * @param initialNonZeroOddNumber a non-zero, odd number used as the initial value
+ * @param multiplierNonZeroOddNumber a non-zero, odd number used as the multiplier
+ * @param object the Object to create a <code>hashCode</code> for
+ * @return int hash code
+ * @throws IllegalArgumentException if the Object is <code>null</code>
+ * @throws IllegalArgumentException if the number is zero or even
+ */
+ public static int reflectionHashCode(
+ int initialNonZeroOddNumber, int multiplierNonZeroOddNumber, Object object) {
+ return reflectionHashCode(initialNonZeroOddNumber, multiplierNonZeroOddNumber, object, false, null);
+ }
+
+ /**
+ * <p>This method uses reflection to build a valid hash code.</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 TestTransients parameter is set to <code>true</code>, transient
+ * members will be tested, otherwise they are ignored, as they are likely
+ * derived fields, and not part of the value of the <code>Object</code>.</p>
+ *
+ * <p>Static fields will not be tested. Superclass fields will be included.</p>
+ *
+ * <p>Two randomly chosen, non-zero, odd numbers must be passed in. Ideally
+ * these should be different for each class, however this is not vital.
+ * Prime numbers are preferred, especially for the multiplier.</p>
+ *
+ * @param initialNonZeroOddNumber a non-zero, odd number used as the initial value
+ * @param multiplierNonZeroOddNumber a non-zero, odd number used as the multiplier
+ * @param object the Object to create a <code>hashCode</code> for
+ * @param testTransients whether to include transient fields
+ * @return int hash code
+ * @throws IllegalArgumentException if the Object is <code>null</code>
+ * @throws IllegalArgumentException if the number is zero or even
+ */
+ public static int reflectionHashCode(
+ int initialNonZeroOddNumber, int multiplierNonZeroOddNumber,
+ Object object, boolean testTransients) {
+ return reflectionHashCode(initialNonZeroOddNumber, multiplierNonZeroOddNumber, object, testTransients, null);
+ }
+
+ /**
+ * <p>This method uses reflection to build a valid hash code.</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 TestTransients parameter is set to <code>true</code>, transient
+ * members will be tested, otherwise they are ignored, as they are likely
+ * derived fields, and not part of the value of the <code>Object</code>.</p>
+ *
+ * <p>Static fields will not be included. Superclass fields will be included
+ * up to and including the specified superclass. A null superclass is treated
+ * as java.lang.Object.</p>
+ *
+ * <p>Two randomly chosen, non-zero, odd numbers must be passed in. Ideally
+ * these should be different for each class, however this is not vital.
+ * Prime numbers are preferred, especially for the multiplier.</p>
+ *
+ * @param initialNonZeroOddNumber a non-zero, odd number used as the initial value
+ * @param multiplierNonZeroOddNumber a non-zero, odd number used as the multiplier
+ * @param object the Object to create a <code>hashCode</code> for
+ * @param testTransients whether to include transient fields
+ * @param reflectUpToClass the superclass to reflect up to (inclusive),
+ * may be <code>null</code>
+ * @return int hash code
+ * @throws IllegalArgumentException if the Object is <code>null</code>
+ * @throws IllegalArgumentException if the number is zero or even
+ * @since 2.0
+ */
+ public static int reflectionHashCode(
+ int initialNonZeroOddNumber,
+ int multiplierNonZeroOddNumber,
+ Object object,
+ boolean testTransients,
+ Class reflectUpToClass) {
+
+ if (object == null) {
+ throw new IllegalArgumentException("The object to build a hash code for must not be null");
+ }
+ HashCodeBuilder builder = new HashCodeBuilder(initialNonZeroOddNumber, multiplierNonZeroOddNumber);
+ Class clazz = object.getClass();
+ reflectionAppend(object, clazz, builder, testTransients);
+ while (clazz.getSuperclass() != null && clazz != reflectUpToClass) {
+ clazz = clazz.getSuperclass();
+ reflectionAppend(object, clazz, builder, testTransients);
+ }
+ return builder.toHashCode();
+ }
+
+ /**
+ * <p>Appends the fields and values defined by the given object of the
+ * given <code>Class</code>.</p>
+ *
+ * @param object the object to append details of
+ * @param clazz the class to append details of
+ * @param builder the builder to append to
+ * @param useTransients whether to use transient fields
+ */
+ private static void reflectionAppend(Object object, Class clazz, HashCodeBuilder builder, boolean useTransients) {
+ Field[] fields = clazz.getDeclaredFields();
+ AccessibleObject.setAccessible(fields, true);
+ for (int i = 0; i < fields.length; i++) {
+ Field f = fields[i];
+ if ((f.getName().indexOf('$') == -1)
+ && (useTransients || !Modifier.isTransient(f.getModifiers()))
+ && (!Modifier.isStatic(f.getModifiers()))) {
+ try {
+ builder.append(f.get(object));
+ } catch (IllegalAccessException e) {
+ //this can't happen. Would get a Security exception instead
+ //throw a runtime exception in case the impossible happens.
+ throw new InternalError("Unexpected IllegalAccessException");
+ }
+ }
+ }
+ }
+
+ //-------------------------------------------------------------------------
+
+ /**
+ * <p>Adds the result of super.hashCode() to this builder.</p>
+ *
+ * @param superHashCode the result of calling <code>super.hashCode()</code>
+ * @return this HashCodeBuilder, used to chain calls.
+ * @since 2.0
+ */
+ public HashCodeBuilder appendSuper(int superHashCode) {
+ iTotal = iTotal * iConstant + superHashCode;
+ return this;
+ }
+
+ //-------------------------------------------------------------------------
+
+ /**
+ * <p>Append a <code>hashCode</code> for an <code>Object</code>.</p>
+ *
+ * @param object the Object to add to the <code>hashCode</code>
+ * @return this
+ */
+ public HashCodeBuilder append(Object object) {
+ if (object == null) {
+ iTotal = iTotal * iConstant;
+
+ } else {
+ if (object.getClass().isArray() == false) {
+ //the simple case, not an array, just the element
+ iTotal = iTotal * iConstant + object.hashCode();
+
+ } else {
+ //'Switch' on type of array, to dispatch to the correct handler
+ // This handles multi dimensional arrays
+ if (object instanceof long[]) {
+ append((long[]) object);
+ } else if (object instanceof int[]) {
+ append((int[]) object);
+ } else if (object instanceof short[]) {
+ append((short[]) object);
+ } else if (object instanceof char[]) {
+ append((char[]) object);
+ } else if (object instanceof byte[]) {
+ append((byte[]) object);
+ } else if (object instanceof double[]) {
+ append((double[]) object);
+ } else if (object instanceof float[]) {
+ append((float[]) object);
+ } else if (object instanceof boolean[]) {
+ append((boolean[]) object);
+ } else {
+ // Not an array of primitives
+ append((Object[]) object);
+ }
+ }
+ }
+ return this;
+ }
+
+ /**
+ * <p>Append a <code>hashCode</code> for a <code>long</code>.</p>
+ *
+ * @param value the long to add to the <code>hashCode</code>
+ * @return this
+ */
+ public HashCodeBuilder append(long value) {
+ iTotal = iTotal * iConstant + ((int) (value ^ (value >> 32)));
+ return this;
+ }
+
+ /**
+ * <p>Append a <code>hashCode</code> for an <code>int</code>.</p>
+ *
+ * @param value the int to add to the <code>hashCode</code>
+ * @return this
+ */
+ public HashCodeBuilder append(int value) {
+ iTotal = iTotal * iConstant + value;
+ return this;
+ }
+
+ /**
+ * <p>Append a <code>hashCode</code> for a <code>short</code>.</p>
+ *
+ * @param value the short to add to the <code>hashCode</code>
+ * @return this
+ */
+ public HashCodeBuilder append(short value) {
+ iTotal = iTotal * iConstant + value;
+ return this;
+ }
+
+ /**
+ * <p>Append a <code>hashCode</code> for a <code>char</code>.</p>
+ *
+ * @param value the char to add to the <code>hashCode</code>
+ * @return this
+ */
+ public HashCodeBuilder append(char value) {
+ iTotal = iTotal * iConstant + value;
+ return this;
+ }
+
+ /**
+ * <p>Append a <code>hashCode</code> for a <code>byte</code>.</p>
+ *
+ * @param value the byte to add to the <code>hashCode</code>
+ * @return this
+ */
+ public HashCodeBuilder append(byte value) {
+ iTotal = iTotal * iConstant + value;
+ return this;
+ }
+
+ /**
+ * <p>Append a <code>hashCode</code> for a <code>double</code>.</p>
+ *
+ * @param value the double to add to the <code>hashCode</code>
+ * @return this
+ */
+ public HashCodeBuilder append(double value) {
+ return append(Double.doubleToLongBits(value));
+ }
+
+ /**
+ * <p>Append a <code>hashCode</code> for a <code>float</code>.</p>
+ *
+ * @param value the float to add to the <code>hashCode</code>
+ * @return this
+ */
+ public HashCodeBuilder append(float value) {
+ iTotal = iTotal * iConstant + Float.floatToIntBits(value);
+ return this;
+ }
+
+ /**
+ * <p>Append a <code>hashCode</code> for a <code>boolean</code>.</p>
+ * <p>This adds <code>iConstant * 1</code> to the <code>hashCode</code>
+ * and not a <code>1231</code> or <code>1237</code> as done in java.lang.Boolean.
+ * This is in accordance with the <quote>Effective Java</quote> design. </p>
+ *
+ * @param value the boolean to add to the <code>hashCode</code>
+ * @return this
+ */
+ public HashCodeBuilder append(boolean value) {
+ iTotal = iTotal * iConstant + (value ? 0 : 1);
+ return this;
+ }
+
+ /**
+ * <p>Append a <code>hashCode</code> for an <code>Object</code> array.</p>
+ *
+ * @param array the array to add to the <code>hashCode</code>
+ * @return this
+ */
+ public HashCodeBuilder append(Object[] array) {
+ if (array == null) {
+ iTotal = iTotal * iConstant;
+ } else {
+ for (int i = 0; i < array.length; i++) {
+ append(array[i]);
+ }
+ }
+ return this;
+ }
+
+ /**
+ * <p>Append a <code>hashCode</code> for a <code>long</code> array.</p>
+ *
+ * @param array the array to add to the <code>hashCode</code>
+ * @return this
+ */
+ public HashCodeBuilder append(long[] array) {
+ if (array == null) {
+ iTotal = iTotal * iConstant;
+ } else {
+ for (int i = 0; i < array.length; i++) {
+ append(array[i]);
+ }
+ }
+ return this;
+ }
+
+ /**
+ * <p>Append a <code>hashCode</code> for an <code>int</code> array.</p>
+ *
+ * @param array the array to add to the <code>hashCode</code>
+ * @return this
+ */
+ public HashCodeBuilder append(int[] array) {
+ if (array == null) {
+ iTotal = iTotal * iConstant;
+ } else {
+ for (int i = 0; i < array.length; i++) {
+ append(array[i]);
+ }
+ }
+ return this;
+ }
+
+ /**
+ * <p>Append a <code>hashCode</code> for a <code>short</code> array.</p>
+ *
+ * @param array the array to add to the <code>hashCode</code>
+ * @return this
+ */
+ public HashCodeBuilder append(short[] array) {
+ if (array == null) {
+ iTotal = iTotal * iConstant;
+ } else {
+ for (int i = 0; i < array.length; i++) {
+ append(array[i]);
+ }
+ }
+ return this;
+ }
+
+ /**
+ * <p>Append a <code>hashCode</code> for a <code>char</code> array.</p>
+ *
+ * @param array the array to add to the <code>hashCode</code>
+ * @return this
+ */
+ public HashCodeBuilder append(char[] array) {
+ if (array == null) {
+ iTotal = iTotal * iConstant;
+ } else {
+ for (int i = 0; i < array.length; i++) {
+ append(array[i]);
+ }
+ }
+ return this;
+ }
+
+ /**
+ * <p>Append a <code>hashCode</code> for a <code>byte</code> array.</p>
+ *
+ * @param array the array to add to the <code>hashCode</code>
+ * @return this
+ */
+ public HashCodeBuilder append(byte[] array) {
+ if (array == null) {
+ iTotal = iTotal * iConstant;
+ } else {
+ for (int i = 0; i < array.length; i++) {
+ append(array[i]);
+ }
+ }
+ return this;
+ }
+
+ /**
+ * <p>Append a <code>hashCode</code> for a <code>double</code> array.</p>
+ *
+ * @param array the array to add to the <code>hashCode</code>
+ * @return this
+ */
+ public HashCodeBuilder append(double[] array) {
+ if (array == null) {
+ iTotal = iTotal * iConstant;
+ } else {
+ for (int i = 0; i < array.length; i++) {
+ append(array[i]);
+ }
+ }
+ return this;
+ }
+
+ /**
+ * <p>Append a <code>hashCode</code> for a <code>float</code> array.</p>
+ *
+ * @param array the array to add to the <code>hashCode</code>
+ * @return this
+ */
+ public HashCodeBuilder append(float[] array) {
+ if (array == null) {
+ iTotal = iTotal * iConstant;
+ } else {
+ for (int i = 0; i < array.length; i++) {
+ append(array[i]);
+ }
+ }
+ return this;
+ }
+
+ /**
+ * <p>Append a <code>hashCode</code> for a <code>boolean</code> array.</p>
+ *
+ * @param array the array to add to the <code>hashCode</code>
+ * @return this
+ */
+ public HashCodeBuilder append(boolean[] array) {
+ if (array == null) {
+ iTotal = iTotal * iConstant;
+ } else {
+ for (int i = 0; i < array.length; i++) {
+ append(array[i]);
+ }
+ }
+ return this;
+ }
+
+ /**
+ * <p>Return the computed <code>hashCode</code>.</p>
+ *
+ * @return <code>hashCode</code> based on the fields appended
+ */
+ public int toHashCode() {
+ return iTotal;
+ }
+
+}
Propchange: directory/sandbox/trustin/mina-spi/core/src/main/java/org/apache/mina/common/support/lang/builder/HashCodeBuilder.java
------------------------------------------------------------------------------
svn:keywords = HeadURL Id LastChangedBy LastChangedDate LastChangedRevision
Added: directory/sandbox/trustin/mina-spi/core/src/main/java/org/apache/mina/common/support/lang/builder/ReflectionToStringBuilder.java
URL: http://svn.apache.org/viewcvs/directory/sandbox/trustin/mina-spi/core/src/main/java/org/apache/mina/common/support/lang/builder/ReflectionToStringBuilder.java?rev=370807&view=auto
==============================================================================
--- directory/sandbox/trustin/mina-spi/core/src/main/java/org/apache/mina/common/support/lang/builder/ReflectionToStringBuilder.java (added)
+++ directory/sandbox/trustin/mina-spi/core/src/main/java/org/apache/mina/common/support/lang/builder/ReflectionToStringBuilder.java Fri Jan 20 05:47:50 2006
@@ -0,0 +1,806 @@
+/*
+ * Copyright 2002-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.mina.common.support.lang.builder;
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.mina.common.support.lang.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>
+ *
+ * @author Gary Gregory
+ * @author Stephen Colebourne
+ * @author Pete Gieser
+ * @since 2.0
+ * @version $Id: ReflectionToStringBuilder.java,v 1.15 2003/12/02 19:11:58
+ * ggregory Exp $
+ */
+public class ReflectionToStringBuilder extends ToStringBuilder {
+ /**
+ * <p>
+ * A registry of objects used by <code>reflectionToString</code> methods
+ * to detect cyclical object references and avoid infinite loops.
+ * </p>
+ */
+ private static ThreadLocal registry = new ThreadLocal() {
+ protected synchronized Object initialValue() {
+ // The HashSet implementation is not synchronized,
+ // which is just what we need here.
+ return new HashSet();
+ }
+ };
+
+ /**
+ * <p>
+ * Returns the registry of objects being traversed by the <code>reflectionToString</code>
+ * methods in the current thread.
+ * </p>
+ *
+ * @return Set the registry of objects being traversed
+ */
+ static Set getRegistry() {
+ return (Set) registry.get();
+ }
+
+ /**
+ * <p>
+ * Returns <code>true</code> if the registry contains the given object.
+ * Used by the reflection methods to avoid infinite loops.
+ * </p>
+ *
+ * @param value
+ * The object to lookup in the registry.
+ * @return boolean <code>true</code> if the registry contains the given
+ * object.
+ */
+ static boolean isRegistered(Object value) {
+ return getRegistry().contains(value);
+ }
+
+ /**
+ * <p>
+ * Registers the given object. Used by the reflection methods to avoid
+ * infinite loops.
+ * </p>
+ *
+ * @param value
+ * The object to register.
+ */
+ static void register(Object value) {
+ getRegistry().add(value);
+ }
+
+ /**
+ * <p>
+ * This method uses reflection to build a suitable <code>toString</code>
+ * using the default <code>ToStringStyle</code>.
+ *
+ * <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>
+ * This method uses reflection to build a suitable <code>toString</code>.
+ * </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>
+ * This method uses reflection to build a suitable <code>toString</code>.
+ * </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>
+ * This method uses reflection to build a suitable <code>toString</code>.
+ * </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>
+ * This method uses reflection to build a suitable <code>toString</code>.
+ * </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 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 String toString(Object object, ToStringStyle style, boolean outputTransients, boolean outputStatics,
+ Class reflectUpToClass) {
+ return new ReflectionToStringBuilder(object, style, null, reflectUpToClass, outputTransients, outputStatics)
+ .toString();
+ }
+
+ /**
+ * <p>
+ * This method uses reflection to build a suitable <code>toString</code>.
+ * </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
+ * 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>
+ *
+ * @deprecated Use
+ * {@link #toString(Object,ToStringStyle,boolean,boolean,Class)}
+ *
+ * @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 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.0
+ */
+ public static String toString(Object object, ToStringStyle style, boolean outputTransients,
+ Class reflectUpToClass) {
+ return new ReflectionToStringBuilder(object, style, null, reflectUpToClass, outputTransients).toString();
+ }
+
+ /**
+ * <p>
+ * Unregisters the given object.
+ * </p>
+ *
+ * <p>
+ * Used by the reflection methods to avoid infinite loops.
+ * </p>
+ *
+ * @param value
+ * The object to unregister.
+ */
+ static void unregister(Object value) {
+ getRegistry().remove(value);
+ }
+
+ /**
+ * Whether or not to append static fields.
+ */
+ private boolean appendStatics = false;
+
+ /**
+ * Whether or not to append transient fields.
+ */
+ private boolean appendTransients = false;
+
+ /**
+ * 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.
+ *
+ * @deprecated Use
+ * {@link #ReflectionToStringBuilder(Object,ToStringStyle,StringBuffer,Class,boolean,boolean)}.
+ *
+ * @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
+ */
+ public ReflectionToStringBuilder(Object object, ToStringStyle style, StringBuffer buffer, Class reflectUpToClass,
+ boolean outputTransients) {
+ super(object, style, buffer);
+ this.setUpToClass(reflectUpToClass);
+ this.setAppendTransients(outputTransients);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @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 ReflectionToStringBuilder(Object object, ToStringStyle style, StringBuffer buffer, Class 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()) {
+ // transients.
+ return false;
+ }
+ if (Modifier.isStatic(field.getModifiers()) && !this.isAppendStatics()) {
+ // transients.
+ 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 (isRegistered(this.getObject())) {
+ // The object has already been appended, therefore we have an
+ // object cycle.
+ // Append a simple Object.toString style string. The field name is
+ // already appended at this point.
+ this.appendAsObjectToString(this.getObject());
+ return;
+ }
+ try {
+ this.registerObject();
+ if (clazz.isArray()) {
+ this.reflectionAppendArray(this.getObject());
+ return;
+ }
+ Field[] fields = clazz.getDeclaredFields();
+ AccessibleObject.setAccessible(fields, true);
+ for (int i = 0; i < fields.length; i++) {
+ Field field = fields[i];
+ String fieldName = field.getName();
+ if (this.accept(field)) {
+ try {
+ // Warning: Field.get(Object) creates wrappers objects
+ // for primitive types.
+ Object fieldValue = this.getValue(field);
+ if (isRegistered(fieldValue) && !field.getType().isPrimitive()) {
+ // A known field value has already been appended,
+ // therefore we have an object cycle,
+ // append a simple Object.toString style string.
+ this.getStyle().appendFieldStart(this.getStringBuffer(), fieldName);
+ this.appendAsObjectToString(fieldValue);
+ this.getStyle().appendFieldEnd(this.getStringBuffer(), fieldName);
+ // The recursion out of
+ // builder.append(fieldName, fieldValue);
+ // below will append the field
+ // end marker.
+ } else {
+ try {
+ this.registerObject();
+ this.append(fieldName, fieldValue);
+ } finally {
+ this.unregisterObject();
+ }
+ }
+ } 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());
+ }
+ }
+ }
+ } finally {
+ this.unregisterObject();
+ }
+ }
+
+ /**
+ * <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 ToStringBuilder reflectionAppendArray(Object array) {
+ this.getStyle().reflectionAppendArrayDetail(this.getStringBuffer(), null, array);
+ return this;
+ }
+
+ /**
+ * <p>
+ * Registers this builder's source object to avoid infinite loops when
+ * processing circular object references.
+ * </p>
+ */
+ void registerObject() {
+ register(this.getObject());
+ }
+
+ /**
+ * <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;
+ }
+
+ /**
+ * <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) {
+ this.upToClass = clazz;
+ }
+
+ /**
+ * <p>
+ * Gets the String built by this builder.
+ * </p>
+ *
+ * @return the built string
+ */
+ 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();
+ }
+
+ /**
+ * <p>
+ * Unregisters this builder's source object to avoid infinite loops when
+ * processing circular object references.
+ * </p>
+ */
+ void unregisterObject() {
+ unregister(this.getObject());
+ }
+}
Propchange: directory/sandbox/trustin/mina-spi/core/src/main/java/org/apache/mina/common/support/lang/builder/ReflectionToStringBuilder.java
------------------------------------------------------------------------------
svn:keywords = HeadURL Id LastChangedBy LastChangedDate LastChangedRevision
Added: directory/sandbox/trustin/mina-spi/core/src/main/java/org/apache/mina/common/support/lang/builder/StandardToStringStyle.java
URL: http://svn.apache.org/viewcvs/directory/sandbox/trustin/mina-spi/core/src/main/java/org/apache/mina/common/support/lang/builder/StandardToStringStyle.java?rev=370807&view=auto
==============================================================================
--- directory/sandbox/trustin/mina-spi/core/src/main/java/org/apache/mina/common/support/lang/builder/StandardToStringStyle.java (added)
+++ directory/sandbox/trustin/mina-spi/core/src/main/java/org/apache/mina/common/support/lang/builder/StandardToStringStyle.java Fri Jan 20 05:47:50 2006
@@ -0,0 +1,537 @@
+/*
+ * Copyright 2002-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.mina.common.support.lang.builder;
+
+/**
+ * <p>Works with {@link ToStringBuilder} to create a <code>toString</code>.</p>
+ *
+ * <p>This class is intended to be used as a singleton.
+ * There is no need to instantiate a new style each time.
+ * Simply instantiate the class once, customize the values as required, and
+ * store the result in a public static final variable for the rest of the
+ * program to access.</p>
+ *
+ * @author Stephen Colebourne
+ * @author Pete Gieser
+ * @author Gary Gregory
+ * @since 1.0
+ * @version $Id$
+ */
+public class StandardToStringStyle extends ToStringStyle {
+
+ /**
+ * <p>Constructor.</p>
+ */
+ public StandardToStringStyle() {
+ super();
+ }
+
+ //---------------------------------------------------------------------
+
+ /**
+ * <p>Gets whether to use the class name.</p>
+ *
+ * @return the current useClassName flag
+ */
+ public boolean isUseClassName() {
+ return super.isUseClassName();
+ }
+
+ /**
+ * <p>Sets whether to use the class name.</p>
+ *
+ * @param useClassName the new useClassName flag
+ */
+ public void setUseClassName(boolean useClassName) {
+ super.setUseClassName(useClassName);
+ }
+
+ //---------------------------------------------------------------------
+
+ /**
+ * <p>Gets whether to output short or long class names.</p>
+ *
+ * @return the current useShortClassName flag
+ * @since 2.0
+ */
+ public boolean isUseShortClassName() {
+ return super.isUseShortClassName();
+ }
+
+ /**
+ * <p>Gets whether to output short or long class names.</p>
+ *
+ * @return the current shortClassName flag
+ * @deprecated Use {@link #isUseShortClassName()}
+ * Method will be removed in Commons Lang 3.0.
+ */
+ public boolean isShortClassName() {
+ return super.isUseShortClassName();
+ }
+
+ /**
+ * <p>Sets whether to output short or long class names.</p>
+ *
+ * @param useShortClassName the new useShortClassName flag
+ * @since 2.0
+ */
+ public void setUseShortClassName(boolean useShortClassName) {
+ super.setUseShortClassName(useShortClassName);
+ }
+
+ /**
+ * <p>Sets whether to output short or long class names.</p>
+ *
+ * @param shortClassName the new shortClassName flag
+ * @deprecated Use {@link #setUseShortClassName(boolean)}
+ * Method will be removed in Commons Lang 3.0.
+ */
+ public void setShortClassName(boolean shortClassName) {
+ super.setUseShortClassName(shortClassName);
+ }
+
+ //---------------------------------------------------------------------
+
+ /**
+ * <p>Gets whether to use the identity hash code.</p>
+ * @return the current useIdentityHashCode flag
+ */
+ public boolean isUseIdentityHashCode() {
+ return super.isUseIdentityHashCode();
+ }
+
+ /**
+ * <p>Sets whether to use the identity hash code.</p>
+ *
+ * @param useIdentityHashCode the new useIdentityHashCode flag
+ */
+ public void setUseIdentityHashCode(boolean useIdentityHashCode) {
+ super.setUseIdentityHashCode(useIdentityHashCode);
+ }
+
+ //---------------------------------------------------------------------
+
+ /**
+ * <p>Gets whether to use the field names passed in.</p>
+ *
+ * @return the current useFieldNames flag
+ */
+ public boolean isUseFieldNames() {
+ return super.isUseFieldNames();
+ }
+
+ /**
+ * <p>Sets whether to use the field names passed in.</p>
+ *
+ * @param useFieldNames the new useFieldNames flag
+ */
+ public void setUseFieldNames(boolean useFieldNames) {
+ super.setUseFieldNames(useFieldNames);
+ }
+
+ //---------------------------------------------------------------------
+
+ /**
+ * <p>Gets whether to use full detail when the caller doesn't
+ * specify.</p>
+ *
+ * @return the current defaultFullDetail flag
+ */
+ public boolean isDefaultFullDetail() {
+ return super.isDefaultFullDetail();
+ }
+
+ /**
+ * <p>Sets whether to use full detail when the caller doesn't
+ * specify.</p>
+ *
+ * @param defaultFullDetail the new defaultFullDetail flag
+ */
+ public void setDefaultFullDetail(boolean defaultFullDetail) {
+ super.setDefaultFullDetail(defaultFullDetail);
+ }
+
+ //---------------------------------------------------------------------
+
+ /**
+ * <p>Gets whether to output array content detail.</p>
+ *
+ * @return the current array content detail setting
+ */
+ public boolean isArrayContentDetail() {
+ return super.isArrayContentDetail();
+ }
+
+ /**
+ * <p>Sets whether to output array content detail.</p>
+ *
+ * @param arrayContentDetail the new arrayContentDetail flag
+ */
+ public void setArrayContentDetail(boolean arrayContentDetail) {
+ super.setArrayContentDetail(arrayContentDetail);
+ }
+
+ //---------------------------------------------------------------------
+
+ /**
+ * <p>Gets the array start text.</p>
+ *
+ * @return the current array start text
+ */
+ public String getArrayStart() {
+ return super.getArrayStart();
+ }
+
+ /**
+ * <p>Sets the array start text.</p>
+ *
+ * <p><code>null</code> is accepted, but will be converted
+ * to an empty String.</p>
+ *
+ * @param arrayStart the new array start text
+ */
+ public void setArrayStart(String arrayStart) {
+ super.setArrayStart(arrayStart);
+ }
+
+ //---------------------------------------------------------------------
+
+ /**
+ * <p>Gets the array end text.</p>
+ *
+ * @return the current array end text
+ */
+ public String getArrayEnd() {
+ return super.getArrayEnd();
+ }
+
+ /**
+ * <p>Sets the array end text.</p>
+ *
+ * <p><code>null</code> is accepted, but will be converted
+ * to an empty String.</p>
+ *
+ * @param arrayEnd the new array end text
+ */
+ public void setArrayEnd(String arrayEnd) {
+ super.setArrayEnd(arrayEnd);
+ }
+
+ //---------------------------------------------------------------------
+
+ /**
+ * <p>Gets the array separator text.</p>
+ *
+ * @return the current array separator text
+ */
+ public String getArraySeparator() {
+ return super.getArraySeparator();
+ }
+
+ /**
+ * <p>Sets the array separator text.</p>
+ *
+ * <p><code>null</code> is accepted, but will be converted
+ * to an empty String.</p>
+ *
+ * @param arraySeparator the new array separator text
+ */
+ public void setArraySeparator(String arraySeparator) {
+ super.setArraySeparator(arraySeparator);
+ }
+
+ //---------------------------------------------------------------------
+
+ /**
+ * <p>Gets the content start text.</p>
+ *
+ * @return the current content start text
+ */
+ public String getContentStart() {
+ return super.getContentStart();
+ }
+
+ /**
+ * <p>Sets the content start text.</p>
+ *
+ * <p><code>null</code> is accepted, but will be converted
+ * to an empty String.</p>
+ *
+ * @param contentStart the new content start text
+ */
+ public void setContentStart(String contentStart) {
+ super.setContentStart(contentStart);
+ }
+
+ //---------------------------------------------------------------------
+
+ /**
+ * <p>Gets the content end text.</p>
+ *
+ * @return the current content end text
+ */
+ public String getContentEnd() {
+ return super.getContentEnd();
+ }
+
+ /**
+ * <p>Sets the content end text.</p>
+ *
+ * <p><code>null</code> is accepted, but will be converted
+ * to an empty String.</p>
+ *
+ * @param contentEnd the new content end text
+ */
+ public void setContentEnd(String contentEnd) {
+ super.setContentEnd(contentEnd);
+ }
+
+ //---------------------------------------------------------------------
+
+ /**
+ * <p>Gets the field name value separator text.</p>
+ *
+ * @return the current field name value separator text
+ */
+ public String getFieldNameValueSeparator() {
+ return super.getFieldNameValueSeparator();
+ }
+
+ /**
+ * <p>Sets the field name value separator text.</p>
+ *
+ * <p><code>null</code> is accepted, but will be converted
+ * to an empty String.</p>
+ *
+ * @param fieldNameValueSeparator the new field name value separator text
+ */
+ public void setFieldNameValueSeparator(String fieldNameValueSeparator) {
+ super.setFieldNameValueSeparator(fieldNameValueSeparator);
+ }
+
+ //---------------------------------------------------------------------
+
+ /**
+ * <p>Gets the field separator text.</p>
+ *
+ * @return the current field separator text
+ */
+ public String getFieldSeparator() {
+ return super.getFieldSeparator();
+ }
+
+ /**
+ * <p>Sets the field separator text.</p>
+ *
+ * <p><code>null</code> is accepted, but will be converted
+ * to an empty String.</p>
+ *
+ * @param fieldSeparator the new field separator text
+ */
+ public void setFieldSeparator(String fieldSeparator) {
+ super.setFieldSeparator(fieldSeparator);
+ }
+
+ //---------------------------------------------------------------------
+
+ /**
+ * <p>Gets whether the field separator should be added at the start
+ * of each buffer.</p>
+ *
+ * @return the fieldSeparatorAtStart flag
+ * @since 2.0
+ */
+ public boolean isFieldSeparatorAtStart() {
+ return super.isFieldSeparatorAtStart();
+ }
+
+ /**
+ * <p>Sets whether the field separator should be added at the start
+ * of each buffer.</p>
+ *
+ * @param fieldSeparatorAtStart the fieldSeparatorAtStart flag
+ * @since 2.0
+ */
+ public void setFieldSeparatorAtStart(boolean fieldSeparatorAtStart) {
+ super.setFieldSeparatorAtStart(fieldSeparatorAtStart);
+ }
+
+ //---------------------------------------------------------------------
+
+ /**
+ * <p>Gets whether the field separator should be added at the end
+ * of each buffer.</p>
+ *
+ * @return fieldSeparatorAtEnd flag
+ * @since 2.0
+ */
+ public boolean isFieldSeparatorAtEnd() {
+ return super.isFieldSeparatorAtEnd();
+ }
+
+ /**
+ * <p>Sets whether the field separator should be added at the end
+ * of each buffer.</p>
+ *
+ * @param fieldSeparatorAtEnd the fieldSeparatorAtEnd flag
+ * @since 2.0
+ */
+ public void setFieldSeparatorAtEnd(boolean fieldSeparatorAtEnd) {
+ super.setFieldSeparatorAtEnd(fieldSeparatorAtEnd);
+ }
+
+ //---------------------------------------------------------------------
+
+ /**
+ * <p>Gets the text to output when <code>null</code> found.</p>
+ *
+ * @return the current text to output when <code>null</code> found
+ */
+ public String getNullText() {
+ return super.getNullText();
+ }
+
+ /**
+ * <p>Sets the text to output when <code>null</code> found.</p>
+ *
+ * <p><code>null</code> is accepted, but will be converted
+ * to an empty String.</p>
+ *
+ * @param nullText the new text to output when <code>null</code> found
+ */
+ public void setNullText(String nullText) {
+ super.setNullText(nullText);
+ }
+
+ //---------------------------------------------------------------------
+
+ /**
+ * <p>Gets the text to output when a <code>Collection</code>,
+ * <code>Map</code> or <code>Array</code> size is output.</p>
+ *
+ * <p>This is output before the size value.</p>
+ *
+ * @return the current start of size text
+ */
+ public String getSizeStartText() {
+ return super.getSizeStartText();
+ }
+
+ /**
+ * <p>Sets the start text to output when a <code>Collection</code>,
+ * <code>Map</code> or <code>Array</code> size is output.</p>
+ *
+ * <p>This is output before the size value.</p>
+ *
+ * <p><code>null</code> is accepted, but will be converted to
+ * an empty String.</p>
+ *
+ * @param sizeStartText the new start of size text
+ */
+ public void setSizeStartText(String sizeStartText) {
+ super.setSizeStartText(sizeStartText);
+ }
+
+ //---------------------------------------------------------------------
+
+ /**
+ * Gets the end text to output when a <code>Collection</code>,
+ * <code>Map</code> or <code>Array</code> size is output.</p>
+ *
+ * <p>This is output after the size value.</p>
+ *
+ * @return the current end of size text
+ */
+ public String getSizeEndText() {
+ return super.getSizeEndText();
+ }
+
+ /**
+ * <p>Sets the end text to output when a <code>Collection</code>,
+ * <code>Map</code> or <code>Array</code> size is output.</p>
+ *
+ * <p>This is output after the size value.</p>
+ *
+ * <p><code>null</code> is accepted, but will be converted
+ * to an empty String.</p>
+ *
+ * @param sizeEndText the new end of size text
+ */
+ public void setSizeEndText(String sizeEndText) {
+ super.setSizeEndText(sizeEndText);
+ }
+
+ //---------------------------------------------------------------------
+
+ /**
+ * <p>Gets the start text to output when an <code>Object</code> is
+ * output in summary mode.</p>
+ *
+ * <P>This is output before the size value.</p>
+ *
+ * @return the current start of summary text
+ */
+ public String getSummaryObjectStartText() {
+ return super.getSummaryObjectStartText();
+ }
+
+ /**
+ * <p>Sets the start text to output when an <code>Object</code> is
+ * output in summary mode.</p>
+ *
+ * <p>This is output before the size value.</p>
+ *
+ * <p><code>null</code> is accepted, but will be converted to
+ * an empty String.</p>
+ *
+ * @param summaryObjectStartText the new start of summary text
+ */
+ public void setSummaryObjectStartText(String summaryObjectStartText) {
+ super.setSummaryObjectStartText(summaryObjectStartText);
+ }
+
+ //---------------------------------------------------------------------
+
+ /**
+ * <p>Gets the end text to output when an <code>Object</code> is
+ * output in summary mode.</p>
+ *
+ * <p>This is output after the size value.</p>
+ *
+ * @return the current end of summary text
+ */
+ public String getSummaryObjectEndText() {
+ return super.getSummaryObjectEndText();
+ }
+
+ /**
+ * <p>Sets the end text to output when an <code>Object</code> is
+ * output in summary mode.</p>
+ *
+ * <p>This is output after the size value.</p>
+ *
+ * <p><code>null</code> is accepted, but will be converted to
+ * an empty String.</p>
+ *
+ * @param summaryObjectEndText the new end of summary text
+ */
+ public void setSummaryObjectEndText(String summaryObjectEndText) {
+ super.setSummaryObjectEndText(summaryObjectEndText);
+ }
+
+ //---------------------------------------------------------------------
+
+}
Propchange: directory/sandbox/trustin/mina-spi/core/src/main/java/org/apache/mina/common/support/lang/builder/StandardToStringStyle.java
------------------------------------------------------------------------------
svn:keywords = HeadURL Id LastChangedBy LastChangedDate LastChangedRevision