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 [EMAIL PROTECTED] 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 [EMAIL PROTECTED] } + * 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 [EMAIL PROTECTED] 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 [EMAIL PROTECTED] #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 [EMAIL PROTECTED] #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("\">"); +// } +// +// } + +}
