You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by ak...@apache.org on 2005/02/03 08:18:54 UTC
svn commit: r151131 [8/9] - in
incubator/directory/asn1/branches/rewrite/ber: ./
src/java/org/apache/asn1/ber/ src/java/org/apache/asn1/ber/digester/
src/java/org/apache/asn1/ber/digester/rules/
src/java/org/apache/asn1/ber/primitives/ src/java/org/apache/asn1/tuples/
src/java/org/apache/asn1/util/ src/test/org/apache/asn1/ber/
src/test/org/apache/asn1/ber/primitives/
Added: incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/util/ToStringStyle.java
URL: http://svn.apache.org/viewcvs/incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/util/ToStringStyle.java?view=auto&rev=151131
==============================================================================
--- incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/util/ToStringStyle.java (added)
+++ incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/util/ToStringStyle.java Wed Feb 2 23:18:42 2005
@@ -0,0 +1,2533 @@
+/*
+ * Copyright 2002-2004 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.asn1.util;
+
+
+import java.io.Serializable;
+import java.lang.reflect.Array;
+import java.util.Collection;
+import java.util.Map;
+
+
+/**
+ * <p>Controls <code>String</code> formatting for {@link ToStringBuilder}. The
+ * main public interface is always via <code>ToStringBuilder</code>.</p>
+ * <p/>
+ * <p>These classes are intended to be used as <code>Singletons</code>. There is
+ * no need to instantiate a new style each time. A program will generally use
+ * one of the predefined constants on this class. Alternatively, the {@link }
+ * class can be used to set the individual settings. Thus most styles can be
+ * achieved without subclassing.</p>
+ * <p/>
+ * <p>If required, a subclass can override as many or as few of the methods as
+ * it requires. Each object type (from <code>boolean</code> to <code>long</code>
+ * to <code>Object</code> to <code>int[]</code>) has its own methods to output
+ * it. Most have two versions, detail and summary.
+ * <p/>
+ * <p>For example, the detail version of the array based methods will output the
+ * whole array, whereas the summary method will just output the array
+ * length.</p>
+ *
+ * @author Stephen Colebourne
+ * @author Gary Gregory
+ * @author Pete Gieser
+ * @version $Id: ToStringStyle.java,v 1.32 2004/07/01 17:40:10 ggregory Exp $
+ * @since 1.0
+ */
+public abstract class ToStringStyle implements Serializable
+{
+
+ /**
+ * The default toString style.
+ */
+ public static final ToStringStyle DEFAULT_STYLE = new DefaultToStringStyle();
+
+ /**
+ * The multi line toString style.
+ */
+ public static final ToStringStyle MULTI_LINE_STYLE = new MultiLineToStringStyle();
+
+ /**
+ * The no field names toString style.
+ */
+ public static final ToStringStyle NO_FIELD_NAMES_STYLE = new NoFieldNameToStringStyle();
+
+ /**
+ * The short prefix toString style.
+ */
+ public static final ToStringStyle SHORT_PREFIX_STYLE = new ShortPrefixToStringStyle();
+
+ /**
+ * The simple toString style.
+ */
+ public static final ToStringStyle SIMPLE_STYLE = new SimpleToStringStyle();
+
+ /**
+ * Whether to use the field names, the default is <code>true</code>.
+ */
+ private boolean useFieldNames = true;
+
+ /**
+ * Whether to use the class name, the default is <code>true</code>.
+ */
+ private boolean useClassName = true;
+
+ /**
+ * Whether to use short class names, the default is <code>false</code>.
+ */
+ private boolean useShortClassName = false;
+
+ /**
+ * Whether to use the identity hash code, the default is <code>true</code>.
+ */
+ private boolean useIdentityHashCode = true;
+
+ /**
+ * The content start <code>'['</code>.
+ */
+ private String contentStart = "[";
+
+ /**
+ * The content end <code>']'</code>.
+ */
+ private String contentEnd = "]";
+
+ /**
+ * The field name value separator <code>'='</code>.
+ */
+ private String fieldNameValueSeparator = "=";
+
+ /**
+ * Whether the field separator should be added before any other fields.
+ */
+ private boolean fieldSeparatorAtStart = false;
+
+ /**
+ * Whether the field separator should be added after any other fields.
+ */
+ private boolean fieldSeparatorAtEnd = false;
+
+ /**
+ * The field separator <code>','</code>.
+ */
+ private String fieldSeparator = ",";
+
+ /**
+ * The array start <code>'{'</code>.
+ */
+ private String arrayStart = "{";
+
+ /**
+ * The array separator <code>','</code>.
+ */
+ private String arraySeparator = ",";
+
+ /**
+ * The detail for array content.
+ */
+ private boolean arrayContentDetail = true;
+
+ /**
+ * The array end <code>'}'</code>.
+ */
+ private String arrayEnd = "}";
+
+ /**
+ * The value to use when fullDetail is <code>null</code>, the default value
+ * is <code>true</code>.
+ */
+ private boolean defaultFullDetail = true;
+
+ /**
+ * The <code>null</code> text <code>'<null>'</code>.
+ */
+ private String nullText = "<null>";
+
+ /**
+ * The summary size text start <code>'<size'</code>.
+ */
+ private String sizeStartText = "<size=";
+
+ /**
+ * The summary size text start <code>'>'</code>.
+ */
+ private String sizeEndText = ">";
+
+ /**
+ * The summary object text start <code>'<'</code>.
+ */
+ private String summaryObjectStartText = "<";
+
+ /**
+ * The summary object text start <code>'>'</code>.
+ */
+ private String summaryObjectEndText = ">";
+
+ //----------------------------------------------------------------------------
+
+ /**
+ * <p>Constructor.</p>
+ */
+ protected ToStringStyle()
+ {
+ super();
+ }
+
+ //----------------------------------------------------------------------------
+
+ /**
+ * <p>Append to the <code>toString</code> the superclass toString.</p>
+ * <p/>
+ * <p>A <code>null</code> <code>superToString</code> is ignored.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param superToString the <code>super.toString()</code>
+ * @since 2.0
+ */
+ public void appendSuper( StringBuffer buffer, String superToString )
+ {
+ appendToString( buffer, superToString );
+ }
+
+
+ /**
+ * <p>Append to the <code>toString</code> another toString.</p>
+ * <p/>
+ * <p>A <code>null</code> <code>toString</code> is ignored.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param toString the additional <code>toString</code>
+ * @since 2.0
+ */
+ public void appendToString( StringBuffer buffer, String toString )
+ {
+ if ( toString != null )
+ {
+ int pos1 = toString.indexOf( contentStart ) + contentStart.length();
+ int pos2 = toString.lastIndexOf( contentEnd );
+ if ( pos1 != pos2 && pos1 >= 0 && pos2 >= 0 )
+ {
+ String data = toString.substring( pos1, pos2 );
+ if ( fieldSeparatorAtStart )
+ {
+ removeLastFieldSeparator( buffer );
+ }
+ buffer.append( data );
+ appendFieldSeparator( buffer );
+ }
+ }
+ }
+
+
+ /**
+ * <p>Append to the <code>toString</code> the start of data indicator.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param object the <code>Object</code> to build a <code>toString</code>
+ * for
+ */
+ public void appendStart( StringBuffer buffer, Object object )
+ {
+ if ( object != null )
+ {
+ appendClassName( buffer, object );
+ appendIdentityHashCode( buffer, object );
+ appendContentStart( buffer );
+ if ( fieldSeparatorAtStart )
+ {
+ appendFieldSeparator( buffer );
+ }
+ }
+ }
+
+
+ /**
+ * <p>Append to the <code>toString</code> the end of data indicator.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param object the <code>Object</code> to build a <code>toString</code>
+ * for.
+ */
+ public void appendEnd( StringBuffer buffer, Object object )
+ {
+ if ( this.fieldSeparatorAtEnd == false )
+ {
+ removeLastFieldSeparator( buffer );
+ }
+ appendContentEnd( buffer );
+ }
+
+
+ /**
+ * <p>Remove the last field separator from the buffer.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @since 2.0
+ */
+ protected void removeLastFieldSeparator( StringBuffer buffer )
+ {
+ int len = buffer.length();
+ int sepLen = fieldSeparator.length();
+ if ( len > 0 && sepLen > 0 && len >= sepLen )
+ {
+ boolean match = true;
+ for ( int i = 0; i < sepLen; i++ )
+ {
+ if ( buffer.charAt( len - 1 - i ) != fieldSeparator.charAt( sepLen - 1 - i ) )
+ {
+ match = false;
+ break;
+ }
+ }
+ if ( match )
+ {
+ buffer.setLength( len - sepLen );
+ }
+ }
+ }
+
+ //----------------------------------------------------------------------------
+
+ /**
+ * <p>Append to the <code>toString</code> an <code>Object</code> value,
+ * printing the full <code>toString</code> of the <code>Object</code> passed
+ * in.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param fieldName the field name
+ * @param value the value to add to the <code>toString</code>
+ * @param fullDetail <code>true</code> for detail, <code>false</code> for
+ * summary info, <code>null</code> for style decides
+ */
+ public void append( StringBuffer buffer, String fieldName, Object value, Boolean fullDetail )
+ {
+ appendFieldStart( buffer, fieldName );
+
+ if ( value == null )
+ {
+ appendNullText( buffer, fieldName );
+
+ }
+ else
+ {
+ appendInternal( buffer, fieldName, value, isFullDetail( fullDetail ) );
+ }
+
+ appendFieldEnd( buffer, fieldName );
+ }
+
+
+ /**
+ * <p>Append to the <code>toString</code> an <code>Object</code>, correctly
+ * interpreting its type.</p>
+ * <p/>
+ * <p>This method performs the main lookup by Class type to correctly route
+ * arrays, <code>Collections</code>, <code>Maps</code> and
+ * <code>Objects</code> to the appropriate method.</p>
+ * <p/>
+ * <p>Either detail or summary views can be specified.</p>
+ * <p/>
+ * <p>If a cycle is detected, an object will be appended with the
+ * <code>Object.toString()</code> format.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param fieldName the field name, typically not used as already appended
+ * @param value the value to add to the <code>toString</code>, not
+ * <code>null</code>
+ * @param detail output detail or not
+ */
+ protected void appendInternal( StringBuffer buffer, String fieldName, Object value, boolean detail )
+ {
+ if ( ReflectionToStringBuilder.isRegistered( value )
+ && !( value instanceof Number || value instanceof Boolean || value instanceof Character ) )
+ {
+ ObjectUtils.appendIdentityToString( buffer, value );
+
+ }
+ else if ( value instanceof Collection )
+ {
+ if ( detail )
+ {
+ appendDetail( buffer, fieldName, ( Collection ) value );
+ }
+ else
+ {
+ appendSummarySize( buffer, fieldName, ( ( Collection ) value ).size() );
+ }
+
+ }
+ else if ( value instanceof Map )
+ {
+ if ( detail )
+ {
+ appendDetail( buffer, fieldName, ( Map ) value );
+ }
+ else
+ {
+ appendSummarySize( buffer, fieldName, ( ( Map ) value ).size() );
+ }
+
+ }
+ else if ( value instanceof long[] )
+ {
+ if ( detail )
+ {
+ appendDetail( buffer, fieldName, ( long[] ) value );
+ }
+ else
+ {
+ appendSummary( buffer, fieldName, ( long[] ) value );
+ }
+
+ }
+ else if ( value instanceof int[] )
+ {
+ if ( detail )
+ {
+ appendDetail( buffer, fieldName, ( int[] ) value );
+ }
+ else
+ {
+ appendSummary( buffer, fieldName, ( int[] ) value );
+ }
+
+ }
+ else if ( value instanceof short[] )
+ {
+ if ( detail )
+ {
+ appendDetail( buffer, fieldName, ( short[] ) value );
+ }
+ else
+ {
+ appendSummary( buffer, fieldName, ( short[] ) value );
+ }
+
+ }
+ else if ( value instanceof byte[] )
+ {
+ if ( detail )
+ {
+ appendDetail( buffer, fieldName, ( byte[] ) value );
+ }
+ else
+ {
+ appendSummary( buffer, fieldName, ( byte[] ) value );
+ }
+
+ }
+ else if ( value instanceof char[] )
+ {
+ if ( detail )
+ {
+ appendDetail( buffer, fieldName, ( char[] ) value );
+ }
+ else
+ {
+ appendSummary( buffer, fieldName, ( char[] ) value );
+ }
+
+ }
+ else if ( value instanceof double[] )
+ {
+ if ( detail )
+ {
+ appendDetail( buffer, fieldName, ( double[] ) value );
+ }
+ else
+ {
+ appendSummary( buffer, fieldName, ( double[] ) value );
+ }
+
+ }
+ else if ( value instanceof float[] )
+ {
+ if ( detail )
+ {
+ appendDetail( buffer, fieldName, ( float[] ) value );
+ }
+ else
+ {
+ appendSummary( buffer, fieldName, ( float[] ) value );
+ }
+
+ }
+ else if ( value instanceof boolean[] )
+ {
+ if ( detail )
+ {
+ appendDetail( buffer, fieldName, ( boolean[] ) value );
+ }
+ else
+ {
+ appendSummary( buffer, fieldName, ( boolean[] ) value );
+ }
+
+ }
+ else if ( value.getClass().isArray() )
+ {
+ if ( detail )
+ {
+ appendDetail( buffer, fieldName, ( Object[] ) value );
+ }
+ else
+ {
+ appendSummary( buffer, fieldName, ( Object[] ) value );
+ }
+
+ }
+ else
+ {
+ if ( detail )
+ {
+ appendDetail( buffer, fieldName, value );
+ }
+ else
+ {
+ appendSummary( buffer, fieldName, value );
+ }
+ }
+ }
+
+
+ /**
+ * <p>Append to the <code>toString</code> an <code>Object</code> value,
+ * printing the full detail of the <code>Object</code>.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param fieldName the field name, typically not used as already appended
+ * @param value the value to add to the <code>toString</code>, not
+ * <code>null</code>
+ */
+ protected void appendDetail( StringBuffer buffer, String fieldName, Object value )
+ {
+ buffer.append( value );
+ }
+
+
+ /**
+ * <p>Append to the <code>toString</code> a <code>Collection</code>.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param fieldName the field name, typically not used as already appended
+ * @param coll the <code>Collection</code> to add to the
+ * <code>toString</code>, not <code>null</code>
+ */
+ protected void appendDetail( StringBuffer buffer, String fieldName, Collection coll )
+ {
+ buffer.append( coll );
+ }
+
+
+ /**
+ * <p>Append to the <code>toString</code> a <code>Map<code>.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param fieldName the field name, typically not used as already appended
+ * @param map the <code>Map</code> to add to the <code>toString</code>,
+ * not <code>null</code>
+ */
+ protected void appendDetail( StringBuffer buffer, String fieldName, Map map )
+ {
+ buffer.append( map );
+ }
+
+
+ /**
+ * <p>Append to the <code>toString</code> an <code>Object</code> value,
+ * printing a summary of the <code>Object</code>.</P>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param fieldName the field name, typically not used as already appended
+ * @param value the value to add to the <code>toString</code>, not
+ * <code>null</code>
+ */
+ protected void appendSummary( StringBuffer buffer, String fieldName, Object value )
+ {
+ buffer.append( summaryObjectStartText );
+ buffer.append( getShortClassName( value.getClass() ) );
+ buffer.append( summaryObjectEndText );
+ }
+
+ //----------------------------------------------------------------------------
+
+ /**
+ * <p>Append to the <code>toString</code> a <code>long</code> value.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param fieldName the field name
+ * @param value the value to add to the <code>toString</code>
+ */
+ public void append( StringBuffer buffer, String fieldName, long value )
+ {
+ appendFieldStart( buffer, fieldName );
+ appendDetail( buffer, fieldName, value );
+ appendFieldEnd( buffer, fieldName );
+ }
+
+
+ /**
+ * <p>Append to the <code>toString</code> a <code>long</code> value.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param fieldName the field name, typically not used as already appended
+ * @param value the value to add to the <code>toString</code>
+ */
+ protected void appendDetail( StringBuffer buffer, String fieldName, long value )
+ {
+ buffer.append( value );
+ }
+
+ //----------------------------------------------------------------------------
+
+ /**
+ * <p>Append to the <code>toString</code> an <code>int</code> value.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param fieldName the field name
+ * @param value the value to add to the <code>toString</code>
+ */
+ public void append( StringBuffer buffer, String fieldName, int value )
+ {
+ appendFieldStart( buffer, fieldName );
+ appendDetail( buffer, fieldName, value );
+ appendFieldEnd( buffer, fieldName );
+ }
+
+
+ /**
+ * <p>Append to the <code>toString</code> an <code>int</code> value.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param fieldName the field name, typically not used as already appended
+ * @param value the value to add to the <code>toString</code>
+ */
+ protected void appendDetail( StringBuffer buffer, String fieldName, int value )
+ {
+ buffer.append( value );
+ }
+
+ //----------------------------------------------------------------------------
+
+ /**
+ * <p>Append to the <code>toString</code> a <code>short</code> value.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param fieldName the field name
+ * @param value the value to add to the <code>toString</code>
+ */
+ public void append( StringBuffer buffer, String fieldName, short value )
+ {
+ appendFieldStart( buffer, fieldName );
+ appendDetail( buffer, fieldName, value );
+ appendFieldEnd( buffer, fieldName );
+ }
+
+
+ /**
+ * <p>Append to the <code>toString</code> a <code>short</code> value.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param fieldName the field name, typically not used as already appended
+ * @param value the value to add to the <code>toString</code>
+ */
+ protected void appendDetail( StringBuffer buffer, String fieldName, short value )
+ {
+ buffer.append( value );
+ }
+
+ //----------------------------------------------------------------------------
+
+ /**
+ * <p>Append to the <code>toString</code> a <code>byte</code> value.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param fieldName the field name
+ * @param value the value to add to the <code>toString</code>
+ */
+ public void append( StringBuffer buffer, String fieldName, byte value )
+ {
+ appendFieldStart( buffer, fieldName );
+ appendDetail( buffer, fieldName, value );
+ appendFieldEnd( buffer, fieldName );
+ }
+
+
+ /**
+ * <p>Append to the <code>toString</code> a <code>byte</code> value.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param fieldName the field name, typically not used as already appended
+ * @param value the value to add to the <code>toString</code>
+ */
+ protected void appendDetail( StringBuffer buffer, String fieldName, byte value )
+ {
+ buffer.append( value );
+ }
+
+ //----------------------------------------------------------------------------
+
+ /**
+ * <p>Append to the <code>toString</code> a <code>char</code> value.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param fieldName the field name
+ * @param value the value to add to the <code>toString</code>
+ */
+ public void append( StringBuffer buffer, String fieldName, char value )
+ {
+ appendFieldStart( buffer, fieldName );
+ appendDetail( buffer, fieldName, value );
+ appendFieldEnd( buffer, fieldName );
+ }
+
+
+ /**
+ * <p>Append to the <code>toString</code> a <code>char</code> value.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param fieldName the field name, typically not used as already appended
+ * @param value the value to add to the <code>toString</code>
+ */
+ protected void appendDetail( StringBuffer buffer, String fieldName, char value )
+ {
+ buffer.append( value );
+ }
+
+ //----------------------------------------------------------------------------
+
+ /**
+ * <p>Append to the <code>toString</code> a <code>double</code> value.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param fieldName the field name
+ * @param value the value to add to the <code>toString</code>
+ */
+ public void append( StringBuffer buffer, String fieldName, double value )
+ {
+ appendFieldStart( buffer, fieldName );
+ appendDetail( buffer, fieldName, value );
+ appendFieldEnd( buffer, fieldName );
+ }
+
+
+ /**
+ * <p>Append to the <code>toString</code> a <code>double</code> value.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param fieldName the field name, typically not used as already appended
+ * @param value the value to add to the <code>toString</code>
+ */
+ protected void appendDetail( StringBuffer buffer, String fieldName, double value )
+ {
+ buffer.append( value );
+ }
+
+ //----------------------------------------------------------------------------
+
+ /**
+ * <p>Append to the <code>toString</code> a <code>float</code> value.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param fieldName the field name
+ * @param value the value to add to the <code>toString</code>
+ */
+ public void append( StringBuffer buffer, String fieldName, float value )
+ {
+ appendFieldStart( buffer, fieldName );
+ appendDetail( buffer, fieldName, value );
+ appendFieldEnd( buffer, fieldName );
+ }
+
+
+ /**
+ * <p>Append to the <code>toString</code> a <code>float</code> value.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param fieldName the field name, typically not used as already appended
+ * @param value the value to add to the <code>toString</code>
+ */
+ protected void appendDetail( StringBuffer buffer, String fieldName, float value )
+ {
+ buffer.append( value );
+ }
+
+ //----------------------------------------------------------------------------
+
+ /**
+ * <p>Append to the <code>toString</code> a <code>boolean</code> value.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param fieldName the field name
+ * @param value the value to add to the <code>toString</code>
+ */
+ public void append( StringBuffer buffer, String fieldName, boolean value )
+ {
+ appendFieldStart( buffer, fieldName );
+ appendDetail( buffer, fieldName, value );
+ appendFieldEnd( buffer, fieldName );
+ }
+
+
+ /**
+ * <p>Append to the <code>toString</code> a <code>boolean</code> value.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param fieldName the field name, typically not used as already appended
+ * @param value the value to add to the <code>toString</code>
+ */
+ protected void appendDetail( StringBuffer buffer, String fieldName, boolean value )
+ {
+ buffer.append( value );
+ }
+
+
+ /**
+ * <p>Append to the <code>toString</code> an <code>Object</code> array.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param fieldName the field name
+ * @param array the array to add to the toString
+ * @param fullDetail <code>true</code> for detail, <code>false</code> for
+ * summary info, <code>null</code> for style decides
+ */
+ public void append( StringBuffer buffer, String fieldName, Object[] array, Boolean fullDetail )
+ {
+ appendFieldStart( buffer, fieldName );
+
+ if ( array == null )
+ {
+ appendNullText( buffer, fieldName );
+
+ }
+ else if ( isFullDetail( fullDetail ) )
+ {
+ appendDetail( buffer, fieldName, array );
+
+ }
+ else
+ {
+ appendSummary( buffer, fieldName, array );
+ }
+
+ appendFieldEnd( buffer, fieldName );
+ }
+
+ //----------------------------------------------------------------------------
+
+ /**
+ * <p>Append to the <code>toString</code> the detail of an
+ * <code>Object</code> array.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param fieldName the field name, typically not used as already appended
+ * @param array the array to add to the <code>toString</code>, not
+ * <code>null</code>
+ */
+ protected void appendDetail( StringBuffer buffer, String fieldName, Object[] array )
+ {
+ buffer.append( arrayStart );
+ for ( int i = 0; i < array.length; i++ )
+ {
+ Object item = array[i];
+ if ( i > 0 )
+ {
+ buffer.append( arraySeparator );
+ }
+ if ( item == null )
+ {
+ appendNullText( buffer, fieldName );
+
+ }
+ else
+ {
+ appendInternal( buffer, fieldName, item, arrayContentDetail );
+ }
+ }
+ buffer.append( arrayEnd );
+ }
+
+
+ /**
+ * <p>Append to the <code>toString</code> the detail of an array type.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param fieldName the field name, typically not used as already appended
+ * @param array the array to add to the <code>toString</code>, not
+ * <code>null</code>
+ * @since 2.0
+ */
+ protected void reflectionAppendArrayDetail( StringBuffer buffer, String fieldName, Object array )
+ {
+ buffer.append( arrayStart );
+ int length = Array.getLength( array );
+ for ( int i = 0; i < length; i++ )
+ {
+ Object item = Array.get( array, i );
+ if ( i > 0 )
+ {
+ buffer.append( arraySeparator );
+ }
+ if ( item == null )
+ {
+ appendNullText( buffer, fieldName );
+
+ }
+ else
+ {
+ appendInternal( buffer, fieldName, item, arrayContentDetail );
+ }
+ }
+ buffer.append( arrayEnd );
+ }
+
+
+ /**
+ * <p>Append to the <code>toString</code> a summary of an
+ * <code>Object</code> array.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param fieldName the field name, typically not used as already appended
+ * @param array the array to add to the <code>toString</code>, not
+ * <code>null</code>
+ */
+ protected void appendSummary( StringBuffer buffer, String fieldName, Object[] array )
+ {
+ appendSummarySize( buffer, fieldName, array.length );
+ }
+
+ //----------------------------------------------------------------------------
+
+ /**
+ * <p>Append to the <code>toString</code> a <code>long</code> array.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param fieldName the field name
+ * @param array the array to add to the <code>toString</code>
+ * @param fullDetail <code>true</code> for detail, <code>false</code> for
+ * summary info, <code>null</code> for style decides
+ */
+ public void append( StringBuffer buffer, String fieldName, long[] array, Boolean fullDetail )
+ {
+ appendFieldStart( buffer, fieldName );
+
+ if ( array == null )
+ {
+ appendNullText( buffer, fieldName );
+
+ }
+ else if ( isFullDetail( fullDetail ) )
+ {
+ appendDetail( buffer, fieldName, array );
+
+ }
+ else
+ {
+ appendSummary( buffer, fieldName, array );
+ }
+
+ appendFieldEnd( buffer, fieldName );
+ }
+
+
+ /**
+ * <p>Append to the <code>toString</code> the detail of a <code>long</code>
+ * array.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param fieldName the field name, typically not used as already appended
+ * @param array the array to add to the <code>toString</code>, not
+ * <code>null</code>
+ */
+ protected void appendDetail( StringBuffer buffer, String fieldName, long[] array )
+ {
+ buffer.append( arrayStart );
+ for ( int i = 0; i < array.length; i++ )
+ {
+ if ( i > 0 )
+ {
+ buffer.append( arraySeparator );
+ }
+ appendDetail( buffer, fieldName, array[i] );
+ }
+ buffer.append( arrayEnd );
+ }
+
+
+ /**
+ * <p>Append to the <code>toString</code> a summary of a <code>long</code>
+ * array.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param fieldName the field name, typically not used as already appended
+ * @param array the array to add to the <code>toString</code>, not
+ * <code>null</code>
+ */
+ protected void appendSummary( StringBuffer buffer, String fieldName, long[] array )
+ {
+ appendSummarySize( buffer, fieldName, array.length );
+ }
+
+ //----------------------------------------------------------------------------
+
+ /**
+ * <p>Append to the <code>toString</code> an <code>int</code> array.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param fieldName the field name
+ * @param array the array to add to the <code>toString</code>
+ * @param fullDetail <code>true</code> for detail, <code>false</code> for
+ * summary info, <code>null</code> for style decides
+ */
+ public void append( StringBuffer buffer, String fieldName, int[] array, Boolean fullDetail )
+ {
+ appendFieldStart( buffer, fieldName );
+
+ if ( array == null )
+ {
+ appendNullText( buffer, fieldName );
+
+ }
+ else if ( isFullDetail( fullDetail ) )
+ {
+ appendDetail( buffer, fieldName, array );
+
+ }
+ else
+ {
+ appendSummary( buffer, fieldName, array );
+ }
+
+ appendFieldEnd( buffer, fieldName );
+ }
+
+
+ /**
+ * <p>Append to the <code>toString</code> the detail of an <code>int</code>
+ * array.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param fieldName the field name, typically not used as already appended
+ * @param array the array to add to the <code>toString</code>, not
+ * <code>null</code>
+ */
+ protected void appendDetail( StringBuffer buffer, String fieldName, int[] array )
+ {
+ buffer.append( arrayStart );
+ for ( int i = 0; i < array.length; i++ )
+ {
+ if ( i > 0 )
+ {
+ buffer.append( arraySeparator );
+ }
+ appendDetail( buffer, fieldName, array[i] );
+ }
+ buffer.append( arrayEnd );
+ }
+
+
+ /**
+ * <p>Append to the <code>toString</code> a summary of an <code>int</code>
+ * array.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param fieldName the field name, typically not used as already appended
+ * @param array the array to add to the <code>toString</code>, not
+ * <code>null</code>
+ */
+ protected void appendSummary( StringBuffer buffer, String fieldName, int[] array )
+ {
+ appendSummarySize( buffer, fieldName, array.length );
+ }
+
+ //----------------------------------------------------------------------------
+
+ /**
+ * <p>Append to the <code>toString</code> a <code>short</code> array.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param fieldName the field name
+ * @param array the array to add to the <code>toString</code>
+ * @param fullDetail <code>true</code> for detail, <code>false</code> for
+ * summary info, <code>null</code> for style decides
+ */
+ public void append( StringBuffer buffer, String fieldName, short[] array, Boolean fullDetail )
+ {
+ appendFieldStart( buffer, fieldName );
+
+ if ( array == null )
+ {
+ appendNullText( buffer, fieldName );
+
+ }
+ else if ( isFullDetail( fullDetail ) )
+ {
+ appendDetail( buffer, fieldName, array );
+
+ }
+ else
+ {
+ appendSummary( buffer, fieldName, array );
+ }
+
+ appendFieldEnd( buffer, fieldName );
+ }
+
+
+ /**
+ * <p>Append to the <code>toString</code> the detail of a <code>short</code>
+ * array.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param fieldName the field name, typically not used as already appended
+ * @param array the array to add to the <code>toString</code>, not
+ * <code>null</code>
+ */
+ protected void appendDetail( StringBuffer buffer, String fieldName, short[] array )
+ {
+ buffer.append( arrayStart );
+ for ( int i = 0; i < array.length; i++ )
+ {
+ if ( i > 0 )
+ {
+ buffer.append( arraySeparator );
+ }
+ appendDetail( buffer, fieldName, array[i] );
+ }
+ buffer.append( arrayEnd );
+ }
+
+
+ /**
+ * <p>Append to the <code>toString</code> a summary of a <code>short</code>
+ * array.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param fieldName the field name, typically not used as already appended
+ * @param array the array to add to the <code>toString</code>, not
+ * <code>null</code>
+ */
+ protected void appendSummary( StringBuffer buffer, String fieldName, short[] array )
+ {
+ appendSummarySize( buffer, fieldName, array.length );
+ }
+
+ //----------------------------------------------------------------------------
+
+ /**
+ * <p>Append to the <code>toString</code> a <code>byte</code> array.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param fieldName the field name
+ * @param array the array to add to the <code>toString</code>
+ * @param fullDetail <code>true</code> for detail, <code>false</code> for
+ * summary info, <code>null</code> for style decides
+ */
+ public void append( StringBuffer buffer, String fieldName, byte[] array, Boolean fullDetail )
+ {
+ appendFieldStart( buffer, fieldName );
+
+ if ( array == null )
+ {
+ appendNullText( buffer, fieldName );
+
+ }
+ else if ( isFullDetail( fullDetail ) )
+ {
+ appendDetail( buffer, fieldName, array );
+
+ }
+ else
+ {
+ appendSummary( buffer, fieldName, array );
+ }
+
+ appendFieldEnd( buffer, fieldName );
+ }
+
+
+ /**
+ * <p>Append to the <code>toString</code> the detail of a <code>byte</code>
+ * array.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param fieldName the field name, typically not used as already appended
+ * @param array the array to add to the <code>toString</code>, not
+ * <code>null</code>
+ */
+ protected void appendDetail( StringBuffer buffer, String fieldName, byte[] array )
+ {
+ buffer.append( arrayStart );
+ for ( int i = 0; i < array.length; i++ )
+ {
+ if ( i > 0 )
+ {
+ buffer.append( arraySeparator );
+ }
+ appendDetail( buffer, fieldName, array[i] );
+ }
+ buffer.append( arrayEnd );
+ }
+
+
+ /**
+ * <p>Append to the <code>toString</code> a summary of a <code>byte</code>
+ * array.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param fieldName the field name, typically not used as already appended
+ * @param array the array to add to the <code>toString</code>, not
+ * <code>null</code>
+ */
+ protected void appendSummary( StringBuffer buffer, String fieldName, byte[] array )
+ {
+ appendSummarySize( buffer, fieldName, array.length );
+ }
+
+ //----------------------------------------------------------------------------
+
+ /**
+ * <p>Append to the <code>toString</code> a <code>char</code> array.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param fieldName the field name
+ * @param array the array to add to the <code>toString</code>
+ * @param fullDetail <code>true</code> for detail, <code>false</code> for
+ * summary info, <code>null</code> for style decides
+ */
+ public void append( StringBuffer buffer, String fieldName, char[] array, Boolean fullDetail )
+ {
+ appendFieldStart( buffer, fieldName );
+
+ if ( array == null )
+ {
+ appendNullText( buffer, fieldName );
+
+ }
+ else if ( isFullDetail( fullDetail ) )
+ {
+ appendDetail( buffer, fieldName, array );
+
+ }
+ else
+ {
+ appendSummary( buffer, fieldName, array );
+ }
+
+ appendFieldEnd( buffer, fieldName );
+ }
+
+
+ /**
+ * <p>Append to the <code>toString</code> the detail of a <code>char</code>
+ * array.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param fieldName the field name, typically not used as already appended
+ * @param array the array to add to the <code>toString</code>, not
+ * <code>null</code>
+ */
+ protected void appendDetail( StringBuffer buffer, String fieldName, char[] array )
+ {
+ buffer.append( arrayStart );
+ for ( int i = 0; i < array.length; i++ )
+ {
+ if ( i > 0 )
+ {
+ buffer.append( arraySeparator );
+ }
+ appendDetail( buffer, fieldName, array[i] );
+ }
+ buffer.append( arrayEnd );
+ }
+
+
+ /**
+ * <p>Append to the <code>toString</code> a summary of a <code>char</code>
+ * array.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param fieldName the field name, typically not used as already appended
+ * @param array the array to add to the <code>toString</code>, not
+ * <code>null</code>
+ */
+ protected void appendSummary( StringBuffer buffer, String fieldName, char[] array )
+ {
+ appendSummarySize( buffer, fieldName, array.length );
+ }
+
+ //----------------------------------------------------------------------------
+
+ /**
+ * <p>Append to the <code>toString</code> a <code>double</code> array.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param fieldName the field name
+ * @param array the array to add to the toString
+ * @param fullDetail <code>true</code> for detail, <code>false</code> for
+ * summary info, <code>null</code> for style decides
+ */
+ public void append( StringBuffer buffer, String fieldName, double[] array, Boolean fullDetail )
+ {
+ appendFieldStart( buffer, fieldName );
+
+ if ( array == null )
+ {
+ appendNullText( buffer, fieldName );
+
+ }
+ else if ( isFullDetail( fullDetail ) )
+ {
+ appendDetail( buffer, fieldName, array );
+
+ }
+ else
+ {
+ appendSummary( buffer, fieldName, array );
+ }
+
+ appendFieldEnd( buffer, fieldName );
+ }
+
+
+ /**
+ * <p>Append to the <code>toString</code> the detail of a
+ * <code>double</code> array.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param fieldName the field name, typically not used as already appended
+ * @param array the array to add to the <code>toString</code>, not
+ * <code>null</code>
+ */
+ protected void appendDetail( StringBuffer buffer, String fieldName, double[] array )
+ {
+ buffer.append( arrayStart );
+ for ( int i = 0; i < array.length; i++ )
+ {
+ if ( i > 0 )
+ {
+ buffer.append( arraySeparator );
+ }
+ appendDetail( buffer, fieldName, array[i] );
+ }
+ buffer.append( arrayEnd );
+ }
+
+
+ /**
+ * <p>Append to the <code>toString</code> a summary of a <code>double</code>
+ * array.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param fieldName the field name, typically not used as already appended
+ * @param array the array to add to the <code>toString</code>, not
+ * <code>null</code>
+ */
+ protected void appendSummary( StringBuffer buffer, String fieldName, double[] array )
+ {
+ appendSummarySize( buffer, fieldName, array.length );
+ }
+
+ //----------------------------------------------------------------------------
+
+ /**
+ * <p>Append to the <code>toString</code> a <code>float</code> array.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param fieldName the field name
+ * @param array the array to add to the toString
+ * @param fullDetail <code>true</code> for detail, <code>false</code> for
+ * summary info, <code>null</code> for style decides
+ */
+ public void append( StringBuffer buffer, String fieldName, float[] array, Boolean fullDetail )
+ {
+ appendFieldStart( buffer, fieldName );
+
+ if ( array == null )
+ {
+ appendNullText( buffer, fieldName );
+
+ }
+ else if ( isFullDetail( fullDetail ) )
+ {
+ appendDetail( buffer, fieldName, array );
+
+ }
+ else
+ {
+ appendSummary( buffer, fieldName, array );
+ }
+
+ appendFieldEnd( buffer, fieldName );
+ }
+
+
+ /**
+ * <p>Append to the <code>toString</code> the detail of a <code>float</code>
+ * array.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param fieldName the field name, typically not used as already appended
+ * @param array the array to add to the <code>toString</code>, not
+ * <code>null</code>
+ */
+ protected void appendDetail( StringBuffer buffer, String fieldName, float[] array )
+ {
+ buffer.append( arrayStart );
+ for ( int i = 0; i < array.length; i++ )
+ {
+ if ( i > 0 )
+ {
+ buffer.append( arraySeparator );
+ }
+ appendDetail( buffer, fieldName, array[i] );
+ }
+ buffer.append( arrayEnd );
+ }
+
+
+ /**
+ * <p>Append to the <code>toString</code> a summary of a <code>float</code>
+ * array.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param fieldName the field name, typically not used as already appended
+ * @param array the array to add to the <code>toString</code>, not
+ * <code>null</code>
+ */
+ protected void appendSummary( StringBuffer buffer, String fieldName, float[] array )
+ {
+ appendSummarySize( buffer, fieldName, array.length );
+ }
+
+ //----------------------------------------------------------------------------
+
+ /**
+ * <p>Append to the <code>toString</code> a <code>boolean</code> array.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param fieldName the field name
+ * @param array the array to add to the toString
+ * @param fullDetail <code>true</code> for detail, <code>false</code> for
+ * summary info, <code>null</code> for style decides
+ */
+ public void append( StringBuffer buffer, String fieldName, boolean[] array, Boolean fullDetail )
+ {
+ appendFieldStart( buffer, fieldName );
+
+ if ( array == null )
+ {
+ appendNullText( buffer, fieldName );
+
+ }
+ else if ( isFullDetail( fullDetail ) )
+ {
+ appendDetail( buffer, fieldName, array );
+
+ }
+ else
+ {
+ appendSummary( buffer, fieldName, array );
+ }
+
+ appendFieldEnd( buffer, fieldName );
+ }
+
+
+ /**
+ * <p>Append to the <code>toString</code> the detail of a
+ * <code>boolean</code> array.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param fieldName the field name, typically not used as already appended
+ * @param array the array to add to the <code>toString</code>, not
+ * <code>null</code>
+ */
+ protected void appendDetail( StringBuffer buffer, String fieldName, boolean[] array )
+ {
+ buffer.append( arrayStart );
+ for ( int i = 0; i < array.length; i++ )
+ {
+ if ( i > 0 )
+ {
+ buffer.append( arraySeparator );
+ }
+ appendDetail( buffer, fieldName, array[i] );
+ }
+ buffer.append( arrayEnd );
+ }
+
+
+ /**
+ * <p>Append to the <code>toString</code> a summary of a
+ * <code>boolean</code> array.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param fieldName the field name, typically not used as already appended
+ * @param array the array to add to the <code>toString</code>, not
+ * <code>null</code>
+ */
+ protected void appendSummary( StringBuffer buffer, String fieldName, boolean[] array )
+ {
+ appendSummarySize( buffer, fieldName, array.length );
+ }
+
+ //----------------------------------------------------------------------------
+
+ /**
+ * <p>Append to the <code>toString</code> the class name.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param object the <code>Object</code> whose name to output
+ */
+ protected void appendClassName( StringBuffer buffer, Object object )
+ {
+ if ( useClassName && object != null )
+ {
+ if ( useShortClassName )
+ {
+ buffer.append( getShortClassName( object.getClass() ) );
+ }
+ else
+ {
+ buffer.append( object.getClass().getName() );
+ }
+ }
+ }
+
+
+ /**
+ * <p>Append the {@link System#identityHashCode(java.lang.Object)}.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param object the <code>Object</code> whose id to output
+ */
+ protected void appendIdentityHashCode( StringBuffer buffer, Object object )
+ {
+ if ( this.isUseIdentityHashCode() && object != null )
+ {
+ buffer.append( '@' );
+ buffer.append( Integer.toHexString( System.identityHashCode( object ) ) );
+ }
+ }
+
+
+ /**
+ * <p>Append to the <code>toString</code> the content start.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ */
+ protected void appendContentStart( StringBuffer buffer )
+ {
+ buffer.append( contentStart );
+ }
+
+
+ /**
+ * <p>Append to the <code>toString</code> the content end.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ */
+ protected void appendContentEnd( StringBuffer buffer )
+ {
+ buffer.append( contentEnd );
+ }
+
+
+ /**
+ * <p>Append to the <code>toString</code> an indicator for
+ * <code>null</code>.</p>
+ * <p/>
+ * <p>The default indicator is <code>'<null>'</code>.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param fieldName the field name, typically not used as already appended
+ */
+ protected void appendNullText( StringBuffer buffer, String fieldName )
+ {
+ buffer.append( nullText );
+ }
+
+
+ /**
+ * <p>Append to the <code>toString</code> the field separator.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ */
+ protected void appendFieldSeparator( StringBuffer buffer )
+ {
+ buffer.append( fieldSeparator );
+ }
+
+
+ /**
+ * <p>Append to the <code>toString</code> the field start.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param fieldName the field name
+ */
+ protected void appendFieldStart( StringBuffer buffer, String fieldName )
+ {
+ if ( useFieldNames && fieldName != null )
+ {
+ buffer.append( fieldName );
+ buffer.append( fieldNameValueSeparator );
+ }
+ }
+
+
+ /**
+ * <p>Append to the <code>toString<code> the field end.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param fieldName the field name, typically not used as already appended
+ */
+ protected void appendFieldEnd( StringBuffer buffer, String fieldName )
+ {
+ appendFieldSeparator( buffer );
+ }
+
+
+ /**
+ * <p>Append to the <code>toString</code> a size summary.</p>
+ * <p/>
+ * <p>The size summary is used to summarize the contents of
+ * <code>Collections</code>, <code>Maps</code> and arrays.</p>
+ * <p/>
+ * <p>The output consists of a prefix, the passed in size and a suffix.</p>
+ * <p/>
+ * <p>The default format is <code>'<size=n>'<code>.</p>
+ *
+ * @param buffer the <code>StringBuffer</code> to populate
+ * @param fieldName the field name, typically not used as already appended
+ * @param size the size to append
+ */
+ protected void appendSummarySize( StringBuffer buffer, String fieldName, int size )
+ {
+ buffer.append( sizeStartText );
+ buffer.append( size );
+ buffer.append( sizeEndText );
+ }
+
+
+ /**
+ * <p>Is this field to be output in full detail.</p>
+ * <p/>
+ * <p>This method converts a detail request into a detail level. The calling
+ * code may request full detail (<code>true</code>), but a subclass might
+ * ignore that and always return <code>false</code>. The calling code may
+ * pass in <code>null</code> indicating that it doesn't care about the
+ * detail level. In this case the default detail level is used.</p>
+ *
+ * @param fullDetailRequest the detail level requested
+ * @return whether full detail is to be shown
+ */
+ protected boolean isFullDetail( Boolean fullDetailRequest )
+ {
+ if ( fullDetailRequest == null )
+ {
+ return defaultFullDetail;
+ }
+ return fullDetailRequest.booleanValue();
+ }
+
+
+ /**
+ * <p>Gets the short class name for a class.</p>
+ * <p/>
+ * <p>The short class name is the classname excluding the package name.</p>
+ *
+ * @param cls the <code>Class</code> to get the short name of
+ * @return the short name
+ */
+ protected String getShortClassName( Class cls )
+ {
+ String[] comps = cls.getName().split( "." );
+
+ if ( comps.length - 1 > 0 )
+ {
+ return comps[comps.length - 1];
+ }
+
+ if ( comps.length == 1 )
+ {
+ return comps[0];
+ }
+
+ return null;
+ }
+
+
+ // Setters and getters for the customizable parts of the style
+ // These methods are not expected to be overridden, except to make public
+ // (They are not public so that immutable subclasses can be written)
+ //---------------------------------------------------------------------
+
+ /**
+ * <p>Gets whether to use the class name.</p>
+ *
+ * @return the current useClassName flag
+ */
+ protected boolean isUseClassName()
+ {
+ return useClassName;
+ }
+
+
+ /**
+ * <p>Sets whether to use the class name.</p>
+ *
+ * @param useClassName the new useClassName flag
+ */
+ protected void setUseClassName( boolean useClassName )
+ {
+ this.useClassName = useClassName;
+ }
+
+ //---------------------------------------------------------------------
+
+ /**
+ * <p>Gets whether to output short or long class names.</p>
+ *
+ * @return the current useShortClassName flag
+ * @since 2.0
+ */
+ protected boolean isUseShortClassName()
+ {
+ return useShortClassName;
+ }
+
+
+ /**
+ * <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.
+ */
+ protected boolean isShortClassName()
+ {
+ return useShortClassName;
+ }
+
+
+ /**
+ * <p>Sets whether to output short or long class names.</p>
+ *
+ * @param useShortClassName the new useShortClassName flag
+ * @since 2.0
+ */
+ protected void setUseShortClassName( boolean useShortClassName )
+ {
+ this.useShortClassName = 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.
+ */
+ protected void setShortClassName( boolean shortClassName )
+ {
+ this.useShortClassName = shortClassName;
+ }
+
+ //---------------------------------------------------------------------
+
+ /**
+ * <p>Gets whether to use the identity hash code.</p>
+ *
+ * @return the current useIdentityHashCode flag
+ */
+ protected boolean isUseIdentityHashCode()
+ {
+ return useIdentityHashCode;
+ }
+
+
+ /**
+ * <p>Sets whether to use the identity hash code.</p>
+ *
+ * @param useIdentityHashCode the new useIdentityHashCode flag
+ */
+ protected void setUseIdentityHashCode( boolean useIdentityHashCode )
+ {
+ this.useIdentityHashCode = useIdentityHashCode;
+ }
+
+ //---------------------------------------------------------------------
+
+ /**
+ * <p>Gets whether to use the field names passed in.</p>
+ *
+ * @return the current useFieldNames flag
+ */
+ protected boolean isUseFieldNames()
+ {
+ return useFieldNames;
+ }
+
+
+ /**
+ * <p>Sets whether to use the field names passed in.</p>
+ *
+ * @param useFieldNames the new useFieldNames flag
+ */
+ protected void setUseFieldNames( boolean useFieldNames )
+ {
+ this.useFieldNames = useFieldNames;
+ }
+
+ //---------------------------------------------------------------------
+
+ /**
+ * <p>Gets whether to use full detail when the caller doesn't specify.</p>
+ *
+ * @return the current defaultFullDetail flag
+ */
+ protected boolean isDefaultFullDetail()
+ {
+ return defaultFullDetail;
+ }
+
+
+ /**
+ * <p>Sets whether to use full detail when the caller doesn't specify.</p>
+ *
+ * @param defaultFullDetail the new defaultFullDetail flag
+ */
+ protected void setDefaultFullDetail( boolean defaultFullDetail )
+ {
+ this.defaultFullDetail = defaultFullDetail;
+ }
+
+ //---------------------------------------------------------------------
+
+ /**
+ * <p>Gets whether to output array content detail.</p>
+ *
+ * @return the current array content detail setting
+ */
+ protected boolean isArrayContentDetail()
+ {
+ return arrayContentDetail;
+ }
+
+
+ /**
+ * <p>Sets whether to output array content detail.</p>
+ *
+ * @param arrayContentDetail the new arrayContentDetail flag
+ */
+ protected void setArrayContentDetail( boolean arrayContentDetail )
+ {
+ this.arrayContentDetail = arrayContentDetail;
+ }
+
+ //---------------------------------------------------------------------
+
+ /**
+ * <p>Gets the array start text.</p>
+ *
+ * @return the current array start text
+ */
+ protected String getArrayStart()
+ {
+ return arrayStart;
+ }
+
+
+ /**
+ * <p>Sets the array start text.</p>
+ * <p/>
+ * <p><code>null</code> is accepted, but will be converted to an empty
+ * String.</p>
+ *
+ * @param arrayStart the new array start text
+ */
+ protected void setArrayStart( String arrayStart )
+ {
+ if ( arrayStart == null )
+ {
+ arrayStart = "";
+ }
+ this.arrayStart = arrayStart;
+ }
+
+ //---------------------------------------------------------------------
+
+ /**
+ * <p>Gets the array end text.</p>
+ *
+ * @return the current array end text
+ */
+ protected String getArrayEnd()
+ {
+ return arrayEnd;
+ }
+
+
+ /**
+ * <p>Sets the array end text.</p>
+ * <p/>
+ * <p><code>null</code> is accepted, but will be converted to an empty
+ * String.</p>
+ *
+ * @param arrayEnd the new array end text
+ */
+ protected void setArrayEnd( String arrayEnd )
+ {
+ if ( arrayStart == null )
+ {
+ arrayStart = "";
+ }
+ this.arrayEnd = arrayEnd;
+ }
+
+ //---------------------------------------------------------------------
+
+ /**
+ * <p>Gets the array separator text.</p>
+ *
+ * @return the current array separator text
+ */
+ protected String getArraySeparator()
+ {
+ return arraySeparator;
+ }
+
+
+ /**
+ * <p>Sets the array separator text.</p>
+ * <p/>
+ * <p><code>null</code> is accepted, but will be converted to an empty
+ * String.</p>
+ *
+ * @param arraySeparator the new array separator text
+ */
+ protected void setArraySeparator( String arraySeparator )
+ {
+ if ( arraySeparator == null )
+ {
+ arraySeparator = "";
+ }
+ this.arraySeparator = arraySeparator;
+ }
+
+ //---------------------------------------------------------------------
+
+ /**
+ * <p>Gets the content start text.</p>
+ *
+ * @return the current content start text
+ */
+ protected String getContentStart()
+ {
+ return contentStart;
+ }
+
+
+ /**
+ * <p>Sets the content start text.</p>
+ * <p/>
+ * <p><code>null</code> is accepted, but will be converted to an empty
+ * String.</p>
+ *
+ * @param contentStart the new content start text
+ */
+ protected void setContentStart( String contentStart )
+ {
+ if ( contentStart == null )
+ {
+ contentStart = "";
+ }
+ this.contentStart = contentStart;
+ }
+
+ //---------------------------------------------------------------------
+
+ /**
+ * <p>Gets the content end text.</p>
+ *
+ * @return the current content end text
+ */
+ protected String getContentEnd()
+ {
+ return contentEnd;
+ }
+
+
+ /**
+ * <p>Sets the content end text.</p>
+ * <p/>
+ * <p><code>null</code> is accepted, but will be converted to an empty
+ * String.</p>
+ *
+ * @param contentEnd the new content end text
+ */
+ protected void setContentEnd( String contentEnd )
+ {
+ if ( contentEnd == null )
+ {
+ contentEnd = "";
+ }
+ this.contentEnd = contentEnd;
+ }
+
+ //---------------------------------------------------------------------
+
+ /**
+ * <p>Gets the field name value separator text.</p>
+ *
+ * @return the current field name value separator text
+ */
+ protected String getFieldNameValueSeparator()
+ {
+ return fieldNameValueSeparator;
+ }
+
+
+ /**
+ * <p>Sets the field name value separator text.</p>
+ * <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
+ */
+ protected void setFieldNameValueSeparator( String fieldNameValueSeparator )
+ {
+ if ( fieldNameValueSeparator == null )
+ {
+ fieldNameValueSeparator = "";
+ }
+ this.fieldNameValueSeparator = fieldNameValueSeparator;
+ }
+
+ //---------------------------------------------------------------------
+
+ /**
+ * <p>Gets the field separator text.</p>
+ *
+ * @return the current field separator text
+ */
+ protected String getFieldSeparator()
+ {
+ return fieldSeparator;
+ }
+
+
+ /**
+ * <p>Sets the field separator text.</p>
+ * <p/>
+ * <p><code>null</code> is accepted, but will be converted to an empty
+ * String.</p>
+ *
+ * @param fieldSeparator the new field separator text
+ */
+ protected void setFieldSeparator( String fieldSeparator )
+ {
+ if ( fieldSeparator == null )
+ {
+ fieldSeparator = "";
+ }
+ this.fieldSeparator = fieldSeparator;
+ }
+
+ //---------------------------------------------------------------------
+
+ /**
+ * <p>Gets whether the field separator should be added at the start of each
+ * buffer.</p>
+ *
+ * @return the fieldSeparatorAtStart flag
+ * @since 2.0
+ */
+ protected boolean isFieldSeparatorAtStart()
+ {
+ return fieldSeparatorAtStart;
+ }
+
+
+ /**
+ * <p>Sets whether the field separator should be added at the start of each
+ * buffer.</p>
+ *
+ * @param fieldSeparatorAtStart the fieldSeparatorAtStart flag
+ * @since 2.0
+ */
+ protected void setFieldSeparatorAtStart( boolean fieldSeparatorAtStart )
+ {
+ this.fieldSeparatorAtStart = fieldSeparatorAtStart;
+ }
+
+ //---------------------------------------------------------------------
+
+ /**
+ * <p>Gets whether the field separator should be added at the end of each
+ * buffer.</p>
+ *
+ * @return fieldSeparatorAtEnd flag
+ * @since 2.0
+ */
+ protected boolean isFieldSeparatorAtEnd()
+ {
+ return fieldSeparatorAtEnd;
+ }
+
+
+ /**
+ * <p>Sets whether the field separator should be added at the end of each
+ * buffer.</p>
+ *
+ * @param fieldSeparatorAtEnd the fieldSeparatorAtEnd flag
+ * @since 2.0
+ */
+ protected void setFieldSeparatorAtEnd( boolean fieldSeparatorAtEnd )
+ {
+ this.fieldSeparatorAtEnd = fieldSeparatorAtEnd;
+ }
+
+ //---------------------------------------------------------------------
+
+ /**
+ * <p>Gets the text to output when <code>null</code> found.</p>
+ *
+ * @return the current text to output when null found
+ */
+ protected String getNullText()
+ {
+ return nullText;
+ }
+
+
+ /**
+ * <p>Sets the text to output when <code>null</code> found.</p>
+ * <p/>
+ * <p><code>null</code> is accepted, but will be converted to an empty
+ * String.</p>
+ *
+ * @param nullText the new text to output when null found
+ */
+ protected void setNullText( String nullText )
+ {
+ if ( nullText == null )
+ {
+ nullText = "";
+ }
+ this.nullText = nullText;
+ }
+
+ //---------------------------------------------------------------------
+
+ /**
+ * <p>Gets the start text to output when a <code>Collection</code>,
+ * <code>Map</code> or array size is output.</p>
+ * <p/>
+ * <p>This is output before the size value.</p>
+ *
+ * @return the current start of size text
+ */
+ protected String getSizeStartText()
+ {
+ return sizeStartText;
+ }
+
+
+ /**
+ * <p>Sets the start text to output when a <code>Collection</code>,
+ * <code>Map</code> or array size is output.</p>
+ * <p/>
+ * <p>This is output before the size value.</p>
+ * <p/>
+ * <p><code>null</code> is accepted, but will be converted to an empty
+ * String.</p>
+ *
+ * @param sizeStartText the new start of size text
+ */
+ protected void setSizeStartText( String sizeStartText )
+ {
+ if ( sizeStartText == null )
+ {
+ sizeStartText = "";
+ }
+ this.sizeStartText = sizeStartText;
+ }
+
+ //---------------------------------------------------------------------
+
+ /**
+ * <p>Gets the end text to output when a <code>Collection</code>,
+ * <code>Map</code> or array size is output.</p>
+ * <p/>
+ * <p>This is output after the size value.</p>
+ *
+ * @return the current end of size text
+ */
+ protected String getSizeEndText()
+ {
+ return sizeEndText;
+ }
+
+
+ /**
+ * <p>Sets the end text to output when a <code>Collection</code>,
+ * <code>Map</code> or array size is output.</p>
+ * <p/>
+ * <p>This is output after the size value.</p>
+ * <p/>
+ * <p><code>null</code> is accepted, but will be converted to an empty
+ * String.</p>
+ *
+ * @param sizeEndText the new end of size text
+ */
+ protected void setSizeEndText( String sizeEndText )
+ {
+ if ( sizeEndText == null )
+ {
+ sizeEndText = "";
+ }
+ this.sizeEndText = sizeEndText;
+ }
+
+ //---------------------------------------------------------------------
+
+ /**
+ * <p>Gets the start text to output when an <code>Object</code> is output in
+ * summary mode.</p>
+ * <p/>
+ * <p>This is output before the size value.</p>
+ *
+ * @return the current start of summary text
+ */
+ protected String getSummaryObjectStartText()
+ {
+ return summaryObjectStartText;
+ }
+
+
+ /**
+ * <p>Sets the start text to output when an <code>Object</code> is output in
+ * summary mode.</p>
+ * <p/>
+ * <p>This is output before the size value.</p>
+ * <p/>
+ * <p><code>null</code> is accepted, but will be converted to an empty
+ * String.</p>
+ *
+ * @param summaryObjectStartText the new start of summary text
+ */
+ protected void setSummaryObjectStartText( String summaryObjectStartText )
+ {
+ if ( summaryObjectStartText == null )
+ {
+ summaryObjectStartText = "";
+ }
+ this.summaryObjectStartText = summaryObjectStartText;
+ }
+
+ //---------------------------------------------------------------------
+
+ /**
+ * <p>Gets the end text to output when an <code>Object</code> is output in
+ * summary mode.</p>
+ * <p/>
+ * <p>This is output after the size value.</p>
+ *
+ * @return the current end of summary text
+ */
+ protected String getSummaryObjectEndText()
+ {
+ return summaryObjectEndText;
+ }
+
+
+ /**
+ * <p>Sets the end text to output when an <code>Object</code> is output in
+ * summary mode.</p>
+ * <p/>
+ * <p>This is output after the size value.</p>
+ * <p/>
+ * <p><code>null</code> is accepted, but will be converted to an empty
+ * String.</p>
+ *
+ * @param summaryObjectEndText the new end of summary text
+ */
+ protected void setSummaryObjectEndText( String summaryObjectEndText )
+ {
+ if ( summaryObjectEndText == null )
+ {
+ summaryObjectEndText = "";
+ }
+ this.summaryObjectEndText = summaryObjectEndText;
+ }
+
+ //----------------------------------------------------------------------------
+
+ /**
+ * <p>Default <code>ToStringStyle</code>.</p>
+ * <p/>
+ * <p>This is an inner class rather than using <code>StandardToStringStyle</code>
+ * to ensure its immutability.</p>
+ */
+ private static final class DefaultToStringStyle extends ToStringStyle
+ {
+
+ /**
+ * <p>Constructor.</p>
+ * <p/>
+ * <p>Use the static constant rather than instantiating.</p>
+ */
+ private DefaultToStringStyle()
+ {
+ super();
+ }
+
+
+ /**
+ * <p>Ensure <code>Singleton</code> after serialization.</p>
+ *
+ * @return the singleton
+ */
+ private Object readResolve()
+ {
+ return ToStringStyle.DEFAULT_STYLE;
+ }
+
+ }
+
+ //----------------------------------------------------------------------------
+
+ /**
+ * <p><code>ToStringStyle</code> that does not print out the field
+ * names.</p>
+ * <p/>
+ * <p>This is an inner class rather than using <code>StandardToStringStyle</code>
+ * to ensure its immutability.
+ */
+ private static final class NoFieldNameToStringStyle extends ToStringStyle
+ {
+
+ /**
+ * <p>Constructor.</p>
+ * <p/>
+ * <p>Use the static constant rather than instantiating.</p>
+ */
+ private NoFieldNameToStringStyle()
+ {
+ super();
+ this.setUseFieldNames( false );
+ }
+
+
+ /**
+ * <p>Ensure <code>Singleton</code> after serialization.</p>
+ *
+ * @return the singleton
+ */
+ private Object readResolve()
+ {
+ return ToStringStyle.NO_FIELD_NAMES_STYLE;
+ }
+
+ }
+
+ //----------------------------------------------------------------------------
+
+ /**
+ * <p><code>ToStringStyle</code> that prints out the short class name and no
+ * identity hashcode.</p>
+ * <p/>
+ * <p>This is an inner class rather than using <code>StandardToStringStyle</code>
+ * to ensure its immutability.</p>
+ */
+ private static final class ShortPrefixToStringStyle extends ToStringStyle
+ {
+
+ /**
+ * <p>Constructor.</p>
+ * <p/>
+ * <p>Use the static constant rather than instantiating.</p>
+ */
+ private ShortPrefixToStringStyle()
+ {
+ super();
+ this.setUseShortClassName( true );
+ this.setUseIdentityHashCode( false );
+ }
+
+
+ /**
+ * <p>Ensure <code>Singleton</ode> after serialization.</p>
+ *
+ * @return the singleton
+ */
+ private Object readResolve()
+ {
+ return ToStringStyle.SHORT_PREFIX_STYLE;
+ }
+
+ }
+
+ /**
+ * <p><code>ToStringStyle</code> that does not print out the classname,
+ * identity hashcode, content start or field name.</p>
+ * <p/>
+ * <p>This is an inner class rather than using <code>StandardToStringStyle</code>
+ * to ensure its immutability.</p>
+ */
+ private static final class SimpleToStringStyle extends ToStringStyle
+ {
+
+ /**
+ * <p>Constructor.</p>
+ * <p/>
+ * <p>Use the static constant rather than instantiating.</p>
+ */
+ private SimpleToStringStyle()
+ {
+ super();
+ this.setUseClassName( false );
+ this.setUseIdentityHashCode( false );
+ this.setUseFieldNames( false );
+ this.setContentStart( "" );
+ this.setContentEnd( "" );
+ }
+
+
+ /**
+ * <p>Ensure <code>Singleton</ode> after serialization.</p>
+ *
+ * @return the singleton
+ */
+ private Object readResolve()
+ {
+ return ToStringStyle.SIMPLE_STYLE;
+ }
+
+ }
+
+ //----------------------------------------------------------------------------
+
+ /**
+ * <p><code>ToStringStyle</code> that outputs on multiple lines.</p>
+ * <p/>
+ * <p>This is an inner class rather than using <code>StandardToStringStyle</code>
+ * to ensure its immutability.</p>
+ */
+ private static final class MultiLineToStringStyle extends ToStringStyle
+ {
+
+ /**
+ * <p>Constructor.</p>
+ * <p/>
+ * <p>Use the static constant rather than instantiating.</p>
+ */
+ private MultiLineToStringStyle()
+ {
+ super();
+ this.setContentStart( "[" );
+ this.setFieldSeparator( SystemUtils.LINE_SEPARATOR + " " );
+ this.setFieldSeparatorAtStart( true );
+ this.setContentEnd( SystemUtils.LINE_SEPARATOR + "]" );
+ }
+
+
+ /**
+ * <p>Ensure <code>Singleton</code> after serialization.</p>
+ *
+ * @return the singleton
+ */
+ private Object readResolve()
+ {
+ return ToStringStyle.MULTI_LINE_STYLE;
+ }
+
+ }
+
+ //----------------------------------------------------------------------------
+
+// Removed, as the XML style needs more work for escaping characters, arrays,
+// collections, maps and embedded beans.
+// /**
+// * ToStringStyle that outputs in XML style
+// */
+// private static class XMLToStringStyle extends ToStringStyle {
+//
+// /**
+// * Constructor - use the static constant rather than instantiating.
+// */
+// private XMLToStringStyle() {
+// super();
+// nullText = "null";
+// sizeStartText = "size=";
+// sizeEndText = "";
+// }
+//
+// /**
+// * @see ToStringStyle#appendStart(StringBuffer, Object)
+// */
+// public void appendStart(StringBuffer buffer, Object object) {
+// buffer.append('<');
+// buffer.append(getShortClassName(object.getClass()));
+// buffer.append(" class=\"");
+// appendClassName(buffer, object);
+// buffer.append("\" hashCode=\"");
+// appendIdentityHashCode(buffer, object);
+// buffer.append("\">");
+// buffer.append(SystemUtils.LINE_SEPARATOR);
+// buffer.append(" ");
+// }
+//
+// /**
+// * @see ToStringStyle#appendFieldStart(StringBuffer, String)
+// */
+// protected void appendFieldStart(StringBuffer buffer, String fieldName) {
+// buffer.append('<');
+// buffer.append(fieldName);
+// buffer.append('>');
+// }
+//
+// /**
+// * @see ToStringStyle#appendFieldEnd(StringBuffer, String)
+// */
+// protected void appendFieldEnd(StringBuffer buffer, String fieldName) {
+// buffer.append("</");
+// buffer.append(fieldName);
+// buffer.append('>');
+// buffer.append(SystemUtils.LINE_SEPARATOR);
+// buffer.append(" ");
+// }
+//
+// /**
+// * @see ToStringStyle#appendEnd(StringBuffer, Object)
+// */
+// public void appendEnd(StringBuffer buffer, Object object) {
+// int len = buffer.length();
+// if (len > 2 && buffer.charAt(len - 1) == ' ' && buffer.charAt(len - 2) == ' ') {
+// buffer.setLength(len - 2);
+// }
+// buffer.append("</");
+// buffer.append(getShortClassName(object.getClass()));
+// buffer.append("\">");
+// }
+//
+// }
+
+}