Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.feilong.lib.lang3.builder.ToStringStyle Maven / Gradle / Ivy
Go to download
feilong is a suite of core and expanded libraries that include utility classes, http, excel,cvs, io classes, and much much more.
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.feilong.lib.lang3.builder;
import java.io.Serializable;
import java.lang.reflect.Array;
import java.util.Collection;
import java.util.Map;
import java.util.Objects;
import java.util.WeakHashMap;
import com.feilong.lib.lang3.ClassUtils;
/**
*
* Controls {@code String} formatting for {@link ToStringBuilder}.
* The main public interface is always via {@code ToStringBuilder}.
*
*
*
* These classes are intended to be used as {@code Singletons}.
* 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 StandardToStringStyle} class can be used
* to set the individual settings. Thus most styles can be achieved
* without subclassing.
*
*
*
* If required, a subclass can override as many or as few of the
* methods as it requires. Each object type (from {@code boolean}
* to {@code long} to {@code Object} to {@code int[]}) has
* its own methods to output it. Most have two versions, detail and summary.
*
*
* 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.
*
*
*
* If you want to format the output of certain objects, such as dates, you
* must create a subclass and override a method.
*
*
*
* public class MyStyle extends ToStringStyle{
*
* protected void appendDetail(StringBuffer buffer,String fieldName,Object value){
* if (value instanceof Date){
* value = new SimpleDateFormat("yyyy-MM-dd").format(value);
* }
* buffer.append(value);
* }
* }
*
*
* @since 1.0
*/
// StringEscapeUtils
public abstract class ToStringStyle implements Serializable{
private static final String EMPTY = "";
/**
* Serialization version ID.
*/
private static final long serialVersionUID = -2587890625525655916L;
/**
* The default toString style. Using the {@code Person}
* example from {@link ToStringBuilder}, the output would look like this:
*
*
* Person@182f0db[name=John Doe,age=33,smoker=false]
*
*/
public static final ToStringStyle DEFAULT_STYLE = new DefaultToStringStyle();
/**
* The multi line toString style. Using the {@code Person}
* example from {@link ToStringBuilder}, the output would look like this:
*
*
* Person@182f0db[
* name=John Doe
* age=33
* smoker=false
* ]
*
*/
public static final ToStringStyle MULTI_LINE_STYLE = new MultiLineToStringStyle();
/**
* The no field names toString style. Using the
* {@code Person} example from {@link ToStringBuilder}, the output
* would look like this:
*
*
* Person@182f0db[John Doe,33,false]
*
*/
public static final ToStringStyle NO_FIELD_NAMES_STYLE = new NoFieldNameToStringStyle();
/**
* The short prefix toString style. Using the {@code Person} example
* from {@link ToStringBuilder}, the output would look like this:
*
*
* Person[name=John Doe,age=33,smoker=false]
*
*
* @since 2.1
*/
public static final ToStringStyle SHORT_PREFIX_STYLE = new ShortPrefixToStringStyle();
/**
* The simple toString style. Using the {@code Person}
* example from {@link ToStringBuilder}, the output would look like this:
*
*
* John Doe,33,false
*
*/
public static final ToStringStyle SIMPLE_STYLE = new SimpleToStringStyle();
/**
* The no class name toString style. Using the {@code Person}
* example from {@link ToStringBuilder}, the output would look like this:
*
*
* [name=John Doe,age=33,smoker=false]
*
*
* @since 3.4
*/
public static final ToStringStyle NO_CLASS_NAME_STYLE = new NoClassNameToStringStyle();
/**
*
* A registry of objects used by {@code reflectionToString} methods
* to detect cyclical object references and avoid infinite loops.
*
*/
private static final ThreadLocal> REGISTRY = new ThreadLocal<>();
/*
* Note that objects of this class are generally shared between threads, so
* an instance variable would not be suitable here.
*
* In normal use the registry should always be left empty, because the caller
* should call toString() which will clean up.
*
* See LANG-792
*/
/**
*
* Returns the registry of objects being traversed by the {@code reflectionToString}
* methods in the current thread.
*
*
* @return Set the registry of objects being traversed
*/
static Map getRegistry(){
return REGISTRY.get();
}
/**
*
* Returns {@code true} if the registry contains the given object.
* Used by the reflection methods to avoid infinite loops.
*
*
* @param value
* The object to lookup in the registry.
* @return boolean {@code true} if the registry contains the given
* object.
*/
static boolean isRegistered(final Object value){
final Map m = getRegistry();
return m != null && m.containsKey(value);
}
/**
*
* Registers the given object. Used by the reflection methods to avoid
* infinite loops.
*
*
* @param value
* The object to register.
*/
static void register(final Object value){
if (value != null){
final Map m = getRegistry();
if (m == null){
REGISTRY.set(new WeakHashMap<>());
}
getRegistry().put(value, null);
}
}
/**
*
* Unregisters the given object.
*
*
*
* Used by the reflection methods to avoid infinite loops.
*
*
* @param value
* The object to unregister.
*/
static void unregister(final Object value){
if (value != null){
final Map m = getRegistry();
if (m != null){
m.remove(value);
if (m.isEmpty()){
REGISTRY.remove();
}
}
}
}
/**
* Whether to use the field names, the default is {@code true}.
*/
private boolean useFieldNames = true;
/**
* Whether to use the class name, the default is {@code true}.
*/
private boolean useClassName = true;
/**
* Whether to use short class names, the default is {@code false}.
*/
private boolean useShortClassName = false;
/**
* Whether to use the identity hash code, the default is {@code true}.
*/
private boolean useIdentityHashCode = true;
/**
* The content start {@code '['}.
*/
private String contentStart = "[";
/**
* The content end {@code ']'}.
*/
private String contentEnd = "]";
/**
* The field name value separator {@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 ','}.
*/
private String fieldSeparator = ",";
/**
* The array start '{'
.
*/
private String arrayStart = "{";
/**
* The array separator {@code ','}.
*/
private String arraySeparator = ",";
/**
* The detail for array content.
*/
private boolean arrayContentDetail = true;
/**
* The array end {@code '}'}.
*/
private String arrayEnd = "}";
/**
* The value to use when fullDetail is {@code null},
* the default value is {@code true}.
*/
private boolean defaultFullDetail = true;
/**
* The {@code null} text {@code '<null>'}.
*/
private String nullText = "";
/**
* The summary size text start {@code '<size'}.
*/
private String sizeStartText = "
* Constructor.
*
*/
protected ToStringStyle(){
super();
}
//----------------------------------------------------------------------------
/**
*
* Append to the {@code toString} the superclass toString.
*
*
* NOTE: It assumes that the toString has been created from the same ToStringStyle.
*
*
*
* A {@code null} {@code superToString} is ignored.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param superToString
* the {@code super.toString()}
* @since 2.0
*/
public void appendSuper(final StringBuffer buffer,final String superToString){
appendToString(buffer, superToString);
}
/**
*
* Append to the {@code toString} another toString.
*
*
* NOTE: It assumes that the toString has been created from the same ToStringStyle.
*
*
*
* A {@code null} {@code toString} is ignored.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param toString
* the additional {@code toString}
* @since 2.0
*/
public void appendToString(final StringBuffer buffer,final String toString){
if (toString != null){
final int pos1 = toString.indexOf(contentStart) + contentStart.length();
final int pos2 = toString.lastIndexOf(contentEnd);
if (pos1 != pos2 && pos1 >= 0 && pos2 >= 0){
if (fieldSeparatorAtStart){
removeLastFieldSeparator(buffer);
}
buffer.append(toString, pos1, pos2);
appendFieldSeparator(buffer);
}
}
}
/**
*
* Append to the {@code toString} the start of data indicator.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param object
* the {@code Object} to build a {@code toString} for
*/
public void appendStart(final StringBuffer buffer,final Object object){
if (object != null){
appendClassName(buffer, object);
appendIdentityHashCode(buffer, object);
appendContentStart(buffer);
if (fieldSeparatorAtStart){
appendFieldSeparator(buffer);
}
}
}
/**
*
* Append to the {@code toString} the end of data indicator.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param object
* the {@code Object} to build a
* {@code toString} for.
*/
public void appendEnd(final StringBuffer buffer,final Object object){
if (!this.fieldSeparatorAtEnd){
removeLastFieldSeparator(buffer);
}
appendContentEnd(buffer);
unregister(object);
}
/**
*
* Remove the last field separator from the buffer.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @since 2.0
*/
protected void removeLastFieldSeparator(final StringBuffer buffer){
final int len = buffer.length();
final 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);
}
}
}
//----------------------------------------------------------------------------
/**
*
* Append to the {@code toString} an {@code Object}
* value, printing the full {@code toString} of the
* {@code Object} passed in.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param fieldName
* the field name
* @param value
* the value to add to the {@code toString}
* @param fullDetail
* {@code true} for detail, {@code false}
* for summary info, {@code null} for style decides
*/
public void append(final StringBuffer buffer,final String fieldName,final Object value,final Boolean fullDetail){
appendFieldStart(buffer, fieldName);
if (value == null){
appendNullText(buffer, fieldName);
}else{
appendInternal(buffer, fieldName, value, isFullDetail(fullDetail));
}
appendFieldEnd(buffer, fieldName);
}
/**
*
* Append to the {@code toString} an {@code Object},
* correctly interpreting its type.
*
*
*
* This method performs the main lookup by Class type to correctly
* route arrays, {@code Collections}, {@code Maps} and
* {@code Objects} to the appropriate method.
*
*
*
* Either detail or summary views can be specified.
*
*
*
* If a cycle is detected, an object will be appended with the
* {@code Object.toString()} format.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param fieldName
* the field name, typically not used as already appended
* @param value
* the value to add to the {@code toString},
* not {@code null}
* @param detail
* output detail or not
*/
protected void appendInternal(final StringBuffer buffer,final String fieldName,final Object value,final boolean detail){
if (isRegistered(value) && !(value instanceof Number || value instanceof Boolean || value instanceof Character)){
appendCyclicObject(buffer, fieldName, value);
return;
}
register(value);
try{
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);
}
}
}finally{
unregister(value);
}
}
/**
*
* Append to the {@code toString} an {@code Object}
* value that has been detected to participate in a cycle. This
* implementation will print the standard string value of the value.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param fieldName
* the field name, typically not used as already appended
* @param value
* the value to add to the {@code toString},
* not {@code null}
*
* @since 2.2
*/
protected void appendCyclicObject(final StringBuffer buffer,final String fieldName,final Object value){
buffer.append(Objects.toString(value));
}
/**
*
* Append to the {@code toString} an {@code Object}
* value, printing the full detail of the {@code Object}.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param fieldName
* the field name, typically not used as already appended
* @param value
* the value to add to the {@code toString},
* not {@code null}
*/
protected void appendDetail(final StringBuffer buffer,final String fieldName,final Object value){
buffer.append(value);
}
/**
*
* Append to the {@code toString} a {@code Collection}.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param fieldName
* the field name, typically not used as already appended
* @param coll
* the {@code Collection} to add to the
* {@code toString}, not {@code null}
*/
protected void appendDetail(final StringBuffer buffer,final String fieldName,final Collection> coll){
buffer.append(coll);
}
/**
*
* Append to the {@code toString} a {@code Map}.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param fieldName
* the field name, typically not used as already appended
* @param map
* the {@code Map} to add to the {@code toString},
* not {@code null}
*/
protected void appendDetail(final StringBuffer buffer,final String fieldName,final Map, ?> map){
buffer.append(map);
}
/**
*
* Append to the {@code toString} an {@code Object}
* value, printing a summary of the {@code Object}.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param fieldName
* the field name, typically not used as already appended
* @param value
* the value to add to the {@code toString},
* not {@code null}
*/
protected void appendSummary(final StringBuffer buffer,final String fieldName,final Object value){
buffer.append(summaryObjectStartText);
buffer.append(getShortClassName(value.getClass()));
buffer.append(summaryObjectEndText);
}
//----------------------------------------------------------------------------
/**
*
* Append to the {@code toString} a {@code long}
* value.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param fieldName
* the field name
* @param value
* the value to add to the {@code toString}
*/
public void append(final StringBuffer buffer,final String fieldName,final long value){
appendFieldStart(buffer, fieldName);
appendDetail(buffer, fieldName, value);
appendFieldEnd(buffer, fieldName);
}
/**
*
* Append to the {@code toString} a {@code long}
* value.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param fieldName
* the field name, typically not used as already appended
* @param value
* the value to add to the {@code toString}
*/
protected void appendDetail(final StringBuffer buffer,final String fieldName,final long value){
buffer.append(value);
}
//----------------------------------------------------------------------------
/**
*
* Append to the {@code toString} an {@code int}
* value.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param fieldName
* the field name
* @param value
* the value to add to the {@code toString}
*/
public void append(final StringBuffer buffer,final String fieldName,final int value){
appendFieldStart(buffer, fieldName);
appendDetail(buffer, fieldName, value);
appendFieldEnd(buffer, fieldName);
}
/**
*
* Append to the {@code toString} an {@code int}
* value.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param fieldName
* the field name, typically not used as already appended
* @param value
* the value to add to the {@code toString}
*/
protected void appendDetail(final StringBuffer buffer,@SuppressWarnings("unused") final String fieldName,final int value){
buffer.append(value);
}
//----------------------------------------------------------------------------
/**
*
* Append to the {@code toString} a {@code short}
* value.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param fieldName
* the field name
* @param value
* the value to add to the {@code toString}
*/
public void append(final StringBuffer buffer,final String fieldName,final short value){
appendFieldStart(buffer, fieldName);
appendDetail(buffer, fieldName, value);
appendFieldEnd(buffer, fieldName);
}
/**
*
* Append to the {@code toString} a {@code short}
* value.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param fieldName
* the field name, typically not used as already appended
* @param value
* the value to add to the {@code toString}
*/
protected void appendDetail(final StringBuffer buffer,final String fieldName,final short value){
buffer.append(value);
}
//----------------------------------------------------------------------------
/**
*
* Append to the {@code toString} a {@code byte}
* value.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param fieldName
* the field name
* @param value
* the value to add to the {@code toString}
*/
public void append(final StringBuffer buffer,final String fieldName,final byte value){
appendFieldStart(buffer, fieldName);
appendDetail(buffer, fieldName, value);
appendFieldEnd(buffer, fieldName);
}
/**
*
* Append to the {@code toString} a {@code byte}
* value.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param fieldName
* the field name, typically not used as already appended
* @param value
* the value to add to the {@code toString}
*/
protected void appendDetail(final StringBuffer buffer,final String fieldName,final byte value){
buffer.append(value);
}
//----------------------------------------------------------------------------
/**
*
* Append to the {@code toString} a {@code char}
* value.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param fieldName
* the field name
* @param value
* the value to add to the {@code toString}
*/
public void append(final StringBuffer buffer,final String fieldName,final char value){
appendFieldStart(buffer, fieldName);
appendDetail(buffer, fieldName, value);
appendFieldEnd(buffer, fieldName);
}
/**
*
* Append to the {@code toString} a {@code char}
* value.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param fieldName
* the field name, typically not used as already appended
* @param value
* the value to add to the {@code toString}
*/
protected void appendDetail(final StringBuffer buffer,final String fieldName,final char value){
buffer.append(value);
}
//----------------------------------------------------------------------------
/**
*
* Append to the {@code toString} a {@code double}
* value.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param fieldName
* the field name
* @param value
* the value to add to the {@code toString}
*/
public void append(final StringBuffer buffer,final String fieldName,final double value){
appendFieldStart(buffer, fieldName);
appendDetail(buffer, fieldName, value);
appendFieldEnd(buffer, fieldName);
}
/**
*
* Append to the {@code toString} a {@code double}
* value.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param fieldName
* the field name, typically not used as already appended
* @param value
* the value to add to the {@code toString}
*/
protected void appendDetail(final StringBuffer buffer,final String fieldName,final double value){
buffer.append(value);
}
//----------------------------------------------------------------------------
/**
*
* Append to the {@code toString} a {@code float}
* value.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param fieldName
* the field name
* @param value
* the value to add to the {@code toString}
*/
public void append(final StringBuffer buffer,final String fieldName,final float value){
appendFieldStart(buffer, fieldName);
appendDetail(buffer, fieldName, value);
appendFieldEnd(buffer, fieldName);
}
/**
*
* Append to the {@code toString} a {@code float}
* value.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param fieldName
* the field name, typically not used as already appended
* @param value
* the value to add to the {@code toString}
*/
protected void appendDetail(final StringBuffer buffer,final String fieldName,final float value){
buffer.append(value);
}
//----------------------------------------------------------------------------
/**
*
* Append to the {@code toString} a {@code boolean}
* value.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param fieldName
* the field name
* @param value
* the value to add to the {@code toString}
*/
public void append(final StringBuffer buffer,final String fieldName,final boolean value){
appendFieldStart(buffer, fieldName);
appendDetail(buffer, fieldName, value);
appendFieldEnd(buffer, fieldName);
}
/**
*
* Append to the {@code toString} a {@code boolean}
* value.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param fieldName
* the field name, typically not used as already appended
* @param value
* the value to add to the {@code toString}
*/
protected void appendDetail(final StringBuffer buffer,final String fieldName,final boolean value){
buffer.append(value);
}
/**
*
* Append to the {@code toString} an {@code Object}
* array.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param fieldName
* the field name
* @param array
* the array to add to the toString
* @param fullDetail
* {@code true} for detail, {@code false}
* for summary info, {@code null} for style decides
*/
public void append(final StringBuffer buffer,final String fieldName,final Object[] array,final 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);
}
//----------------------------------------------------------------------------
/**
*
* Append to the {@code toString} the detail of an
* {@code Object} array.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param fieldName
* the field name, typically not used as already appended
* @param array
* the array to add to the {@code toString},
* not {@code null}
*/
protected void appendDetail(final StringBuffer buffer,final String fieldName,final Object[] array){
buffer.append(arrayStart);
for (int i = 0; i < array.length; i++){
final 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);
}
/**
*
* Append to the {@code toString} the detail of an array type.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param fieldName
* the field name, typically not used as already appended
* @param array
* the array to add to the {@code toString},
* not {@code null}
* @since 2.0
*/
protected void reflectionAppendArrayDetail(final StringBuffer buffer,final String fieldName,final Object array){
buffer.append(arrayStart);
final int length = Array.getLength(array);
for (int i = 0; i < length; i++){
final 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);
}
/**
*
* Append to the {@code toString} a summary of an
* {@code Object} array.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param fieldName
* the field name, typically not used as already appended
* @param array
* the array to add to the {@code toString},
* not {@code null}
*/
protected void appendSummary(final StringBuffer buffer,final String fieldName,final Object[] array){
appendSummarySize(buffer, fieldName, array.length);
}
//----------------------------------------------------------------------------
/**
*
* Append to the {@code toString} a {@code long}
* array.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param fieldName
* the field name
* @param array
* the array to add to the {@code toString}
* @param fullDetail
* {@code true} for detail, {@code false}
* for summary info, {@code null} for style decides
*/
public void append(final StringBuffer buffer,final String fieldName,final long[] array,final 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);
}
/**
*
* Append to the {@code toString} the detail of a
* {@code long} array.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param fieldName
* the field name, typically not used as already appended
* @param array
* the array to add to the {@code toString},
* not {@code null}
*/
protected void appendDetail(final StringBuffer buffer,final String fieldName,final 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);
}
/**
*
* Append to the {@code toString} a summary of a
* {@code long} array.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param fieldName
* the field name, typically not used as already appended
* @param array
* the array to add to the {@code toString},
* not {@code null}
*/
protected void appendSummary(final StringBuffer buffer,final String fieldName,final long[] array){
appendSummarySize(buffer, fieldName, array.length);
}
//----------------------------------------------------------------------------
/**
*
* Append to the {@code toString} an {@code int}
* array.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param fieldName
* the field name
* @param array
* the array to add to the {@code toString}
* @param fullDetail
* {@code true} for detail, {@code false}
* for summary info, {@code null} for style decides
*/
public void append(final StringBuffer buffer,final String fieldName,final int[] array,final 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);
}
/**
*
* Append to the {@code toString} the detail of an
* {@code int} array.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param fieldName
* the field name, typically not used as already appended
* @param array
* the array to add to the {@code toString},
* not {@code null}
*/
protected void appendDetail(final StringBuffer buffer,final String fieldName,final 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);
}
/**
*
* Append to the {@code toString} a summary of an
* {@code int} array.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param fieldName
* the field name, typically not used as already appended
* @param array
* the array to add to the {@code toString},
* not {@code null}
*/
protected void appendSummary(final StringBuffer buffer,final String fieldName,final int[] array){
appendSummarySize(buffer, fieldName, array.length);
}
//----------------------------------------------------------------------------
/**
*
* Append to the {@code toString} a {@code short}
* array.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param fieldName
* the field name
* @param array
* the array to add to the {@code toString}
* @param fullDetail
* {@code true} for detail, {@code false}
* for summary info, {@code null} for style decides
*/
public void append(final StringBuffer buffer,final String fieldName,final short[] array,final 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);
}
/**
*
* Append to the {@code toString} the detail of a
* {@code short} array.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param fieldName
* the field name, typically not used as already appended
* @param array
* the array to add to the {@code toString},
* not {@code null}
*/
protected void appendDetail(final StringBuffer buffer,final String fieldName,final 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);
}
/**
*
* Append to the {@code toString} a summary of a
* {@code short} array.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param fieldName
* the field name, typically not used as already appended
* @param array
* the array to add to the {@code toString},
* not {@code null}
*/
protected void appendSummary(final StringBuffer buffer,final String fieldName,final short[] array){
appendSummarySize(buffer, fieldName, array.length);
}
//----------------------------------------------------------------------------
/**
*
* Append to the {@code toString} a {@code byte}
* array.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param fieldName
* the field name
* @param array
* the array to add to the {@code toString}
* @param fullDetail
* {@code true} for detail, {@code false}
* for summary info, {@code null} for style decides
*/
public void append(final StringBuffer buffer,final String fieldName,final byte[] array,final 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);
}
/**
*
* Append to the {@code toString} the detail of a
* {@code byte} array.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param fieldName
* the field name, typically not used as already appended
* @param array
* the array to add to the {@code toString},
* not {@code null}
*/
protected void appendDetail(final StringBuffer buffer,final String fieldName,final 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);
}
/**
*
* Append to the {@code toString} a summary of a
* {@code byte} array.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param fieldName
* the field name, typically not used as already appended
* @param array
* the array to add to the {@code toString},
* not {@code null}
*/
protected void appendSummary(final StringBuffer buffer,final String fieldName,final byte[] array){
appendSummarySize(buffer, fieldName, array.length);
}
//----------------------------------------------------------------------------
/**
*
* Append to the {@code toString} a {@code char}
* array.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param fieldName
* the field name
* @param array
* the array to add to the {@code toString}
* @param fullDetail
* {@code true} for detail, {@code false}
* for summary info, {@code null} for style decides
*/
public void append(final StringBuffer buffer,final String fieldName,final char[] array,final 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);
}
/**
*
* Append to the {@code toString} the detail of a
* {@code char} array.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param fieldName
* the field name, typically not used as already appended
* @param array
* the array to add to the {@code toString},
* not {@code null}
*/
protected void appendDetail(final StringBuffer buffer,final String fieldName,final 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);
}
/**
*
* Append to the {@code toString} a summary of a
* {@code char} array.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param fieldName
* the field name, typically not used as already appended
* @param array
* the array to add to the {@code toString},
* not {@code null}
*/
protected void appendSummary(final StringBuffer buffer,final String fieldName,final char[] array){
appendSummarySize(buffer, fieldName, array.length);
}
//----------------------------------------------------------------------------
/**
*
* Append to the {@code toString} a {@code double}
* array.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param fieldName
* the field name
* @param array
* the array to add to the toString
* @param fullDetail
* {@code true} for detail, {@code false}
* for summary info, {@code null} for style decides
*/
public void append(final StringBuffer buffer,final String fieldName,final double[] array,final 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);
}
/**
*
* Append to the {@code toString} the detail of a
* {@code double} array.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param fieldName
* the field name, typically not used as already appended
* @param array
* the array to add to the {@code toString},
* not {@code null}
*/
protected void appendDetail(final StringBuffer buffer,final String fieldName,final 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);
}
/**
*
* Append to the {@code toString} a summary of a
* {@code double} array.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param fieldName
* the field name, typically not used as already appended
* @param array
* the array to add to the {@code toString},
* not {@code null}
*/
protected void appendSummary(final StringBuffer buffer,final String fieldName,final double[] array){
appendSummarySize(buffer, fieldName, array.length);
}
//----------------------------------------------------------------------------
/**
*
* Append to the {@code toString} a {@code float}
* array.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param fieldName
* the field name
* @param array
* the array to add to the toString
* @param fullDetail
* {@code true} for detail, {@code false}
* for summary info, {@code null} for style decides
*/
public void append(final StringBuffer buffer,final String fieldName,final float[] array,final 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);
}
/**
*
* Append to the {@code toString} the detail of a
* {@code float} array.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param fieldName
* the field name, typically not used as already appended
* @param array
* the array to add to the {@code toString},
* not {@code null}
*/
protected void appendDetail(final StringBuffer buffer,final String fieldName,final 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);
}
/**
*
* Append to the {@code toString} a summary of a
* {@code float} array.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param fieldName
* the field name, typically not used as already appended
* @param array
* the array to add to the {@code toString},
* not {@code null}
*/
protected void appendSummary(final StringBuffer buffer,final String fieldName,final float[] array){
appendSummarySize(buffer, fieldName, array.length);
}
//----------------------------------------------------------------------------
/**
*
* Append to the {@code toString} a {@code boolean}
* array.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param fieldName
* the field name
* @param array
* the array to add to the toString
* @param fullDetail
* {@code true} for detail, {@code false}
* for summary info, {@code null} for style decides
*/
public void append(final StringBuffer buffer,final String fieldName,final boolean[] array,final 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);
}
/**
*
* Append to the {@code toString} the detail of a
* {@code boolean} array.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param fieldName
* the field name, typically not used as already appended
* @param array
* the array to add to the {@code toString},
* not {@code null}
*/
protected void appendDetail(final StringBuffer buffer,final String fieldName,final 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);
}
/**
*
* Append to the {@code toString} a summary of a
* {@code boolean} array.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param fieldName
* the field name, typically not used as already appended
* @param array
* the array to add to the {@code toString},
* not {@code null}
*/
protected void appendSummary(final StringBuffer buffer,final String fieldName,final boolean[] array){
appendSummarySize(buffer, fieldName, array.length);
}
//----------------------------------------------------------------------------
/**
*
* Append to the {@code toString} the class name.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param object
* the {@code Object} whose name to output
*/
protected void appendClassName(final StringBuffer buffer,final Object object){
if (useClassName && object != null){
register(object);
if (useShortClassName){
buffer.append(getShortClassName(object.getClass()));
}else{
buffer.append(object.getClass().getName());
}
}
}
/**
*
* Append the {@link System#identityHashCode(java.lang.Object)}.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param object
* the {@code Object} whose id to output
*/
protected void appendIdentityHashCode(final StringBuffer buffer,final Object object){
if (this.isUseIdentityHashCode() && object != null){
register(object);
buffer.append('@');
buffer.append(Integer.toHexString(System.identityHashCode(object)));
}
}
/**
*
* Append to the {@code toString} the content start.
*
*
* @param buffer
* the {@code StringBuffer} to populate
*/
protected void appendContentStart(final StringBuffer buffer){
buffer.append(contentStart);
}
/**
*
* Append to the {@code toString} the content end.
*
*
* @param buffer
* the {@code StringBuffer} to populate
*/
protected void appendContentEnd(final StringBuffer buffer){
buffer.append(contentEnd);
}
/**
*
* Append to the {@code toString} an indicator for {@code null}.
*
*
*
* The default indicator is {@code '<null>'}.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param fieldName
* the field name, typically not used as already appended
*/
protected void appendNullText(final StringBuffer buffer,final String fieldName){
buffer.append(nullText);
}
/**
*
* Append to the {@code toString} the field separator.
*
*
* @param buffer
* the {@code StringBuffer} to populate
*/
protected void appendFieldSeparator(final StringBuffer buffer){
buffer.append(fieldSeparator);
}
/**
*
* Append to the {@code toString} the field start.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param fieldName
* the field name
*/
protected void appendFieldStart(final StringBuffer buffer,final String fieldName){
if (useFieldNames && fieldName != null){
buffer.append(fieldName);
buffer.append(fieldNameValueSeparator);
}
}
/**
*
* Append to the {@code toString} the field end.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param fieldName
* the field name, typically not used as already appended
*/
protected void appendFieldEnd(final StringBuffer buffer,final String fieldName){
appendFieldSeparator(buffer);
}
/**
*
* Append to the {@code toString} a size summary.
*
*
*
* The size summary is used to summarize the contents of
* {@code Collections}, {@code Maps} and arrays.
*
*
*
* The output consists of a prefix, the passed in size
* and a suffix.
*
*
*
* The default format is {@code '<size=n>'}.
*
*
* @param buffer
* the {@code StringBuffer} to populate
* @param fieldName
* the field name, typically not used as already appended
* @param size
* the size to append
*/
protected void appendSummarySize(final StringBuffer buffer,final String fieldName,final int size){
buffer.append(sizeStartText);
buffer.append(size);
buffer.append(sizeEndText);
}
/**
*
* Is this field to be output in full detail.
*
*
*
* This method converts a detail request into a detail level.
* The calling code may request full detail ({@code true}),
* but a subclass might ignore that and always return
* {@code false}. The calling code may pass in
* {@code null} indicating that it doesn't care about
* the detail level. In this case the default detail level is
* used.
*
*
* @param fullDetailRequest
* the detail level requested
* @return whether full detail is to be shown
*/
protected boolean isFullDetail(final Boolean fullDetailRequest){
if (fullDetailRequest == null){
return defaultFullDetail;
}
return fullDetailRequest.booleanValue();
}
/**
*
* Gets the short class name for a class.
*
*
*
* The short class name is the classname excluding
* the package name.
*
*
* @param cls
* the {@code Class} to get the short name of
* @return the short name
*/
protected String getShortClassName(final Class> cls){
return ClassUtils.getShortClassName(cls);
}
// 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)
//---------------------------------------------------------------------
/**
*
* Gets whether to use the class name.
*
*
* @return the current useClassName flag
*/
protected boolean isUseClassName(){
return useClassName;
}
/**
*
* Sets whether to use the class name.
*
*
* @param useClassName
* the new useClassName flag
*/
protected void setUseClassName(final boolean useClassName){
this.useClassName = useClassName;
}
//---------------------------------------------------------------------
/**
*
* Gets whether to output short or long class names.
*
*
* @return the current useShortClassName flag
* @since 2.0
*/
protected boolean isUseShortClassName(){
return useShortClassName;
}
/**
*
* Sets whether to output short or long class names.
*
*
* @param useShortClassName
* the new useShortClassName flag
* @since 2.0
*/
protected void setUseShortClassName(final boolean useShortClassName){
this.useShortClassName = useShortClassName;
}
//---------------------------------------------------------------------
/**
*
* Gets whether to use the identity hash code.
*
*
* @return the current useIdentityHashCode flag
*/
protected boolean isUseIdentityHashCode(){
return useIdentityHashCode;
}
/**
*
* Sets whether to use the identity hash code.
*
*
* @param useIdentityHashCode
* the new useIdentityHashCode flag
*/
protected void setUseIdentityHashCode(final boolean useIdentityHashCode){
this.useIdentityHashCode = useIdentityHashCode;
}
//---------------------------------------------------------------------
/**
*
* Gets whether to use the field names passed in.
*
*
* @return the current useFieldNames flag
*/
protected boolean isUseFieldNames(){
return useFieldNames;
}
/**
*
* Sets whether to use the field names passed in.
*
*
* @param useFieldNames
* the new useFieldNames flag
*/
protected void setUseFieldNames(final boolean useFieldNames){
this.useFieldNames = useFieldNames;
}
//---------------------------------------------------------------------
/**
*
* Gets whether to use full detail when the caller doesn't
* specify.
*
*
* @return the current defaultFullDetail flag
*/
protected boolean isDefaultFullDetail(){
return defaultFullDetail;
}
/**
*
* Sets whether to use full detail when the caller doesn't
* specify.
*
*
* @param defaultFullDetail
* the new defaultFullDetail flag
*/
protected void setDefaultFullDetail(final boolean defaultFullDetail){
this.defaultFullDetail = defaultFullDetail;
}
//---------------------------------------------------------------------
/**
*
* Gets whether to output array content detail.
*
*
* @return the current array content detail setting
*/
protected boolean isArrayContentDetail(){
return arrayContentDetail;
}
/**
*
* Sets whether to output array content detail.
*
*
* @param arrayContentDetail
* the new arrayContentDetail flag
*/
protected void setArrayContentDetail(final boolean arrayContentDetail){
this.arrayContentDetail = arrayContentDetail;
}
//---------------------------------------------------------------------
/**
*
* Gets the array start text.
*
*
* @return the current array start text
*/
protected String getArrayStart(){
return arrayStart;
}
/**
*
* Sets the array start text.
*
*
*
* {@code null} is accepted, but will be converted to
* an empty String.
*
*
* @param arrayStart
* the new array start text
*/
protected void setArrayStart(String arrayStart){
if (arrayStart == null){
arrayStart = EMPTY;
}
this.arrayStart = arrayStart;
}
//---------------------------------------------------------------------
/**
*
* Gets the array end text.
*
*
* @return the current array end text
*/
protected String getArrayEnd(){
return arrayEnd;
}
/**
*
* Sets the array end text.
*
*
*
* {@code null} is accepted, but will be converted to
* an empty String.
*
*
* @param arrayEnd
* the new array end text
*/
protected void setArrayEnd(String arrayEnd){
if (arrayEnd == null){
arrayEnd = EMPTY;
}
this.arrayEnd = arrayEnd;
}
//---------------------------------------------------------------------
/**
*
* Gets the array separator text.
*
*
* @return the current array separator text
*/
protected String getArraySeparator(){
return arraySeparator;
}
/**
*
* Sets the array separator text.
*
*
*
* {@code null} is accepted, but will be converted to
* an empty String.
*
*
* @param arraySeparator
* the new array separator text
*/
protected void setArraySeparator(String arraySeparator){
if (arraySeparator == null){
arraySeparator = EMPTY;
}
this.arraySeparator = arraySeparator;
}
//---------------------------------------------------------------------
/**
*
* Gets the content start text.
*
*
* @return the current content start text
*/
protected String getContentStart(){
return contentStart;
}
/**
*
* Sets the content start text.
*
*
*
* {@code null} is accepted, but will be converted to
* an empty String.
*
*
* @param contentStart
* the new content start text
*/
protected void setContentStart(String contentStart){
if (contentStart == null){
contentStart = EMPTY;
}
this.contentStart = contentStart;
}
//---------------------------------------------------------------------
/**
*
* Gets the content end text.
*
*
* @return the current content end text
*/
protected String getContentEnd(){
return contentEnd;
}
/**
*
* Sets the content end text.
*
*
*
* {@code null} is accepted, but will be converted to
* an empty String.
*
*
* @param contentEnd
* the new content end text
*/
protected void setContentEnd(String contentEnd){
if (contentEnd == null){
contentEnd = EMPTY;
}
this.contentEnd = contentEnd;
}
//---------------------------------------------------------------------
/**
*
* Gets the field name value separator text.
*
*
* @return the current field name value separator text
*/
protected String getFieldNameValueSeparator(){
return fieldNameValueSeparator;
}
/**
*
* Sets the field name value separator text.
*
*
*
* {@code null} is accepted, but will be converted to
* an empty String.
*
*
* @param fieldNameValueSeparator
* the new field name value separator text
*/
protected void setFieldNameValueSeparator(String fieldNameValueSeparator){
if (fieldNameValueSeparator == null){
fieldNameValueSeparator = EMPTY;
}
this.fieldNameValueSeparator = fieldNameValueSeparator;
}
//---------------------------------------------------------------------
/**
*
* Gets the field separator text.
*
*
* @return the current field separator text
*/
protected String getFieldSeparator(){
return fieldSeparator;
}
/**
*
* Sets the field separator text.
*
*
*
* {@code null} is accepted, but will be converted to
* an empty String.
*
*
* @param fieldSeparator
* the new field separator text
*/
protected void setFieldSeparator(String fieldSeparator){
if (fieldSeparator == null){
fieldSeparator = EMPTY;
}
this.fieldSeparator = fieldSeparator;
}
//---------------------------------------------------------------------
/**
*
* Gets whether the field separator should be added at the start
* of each buffer.
*
*
* @return the fieldSeparatorAtStart flag
* @since 2.0
*/
protected boolean isFieldSeparatorAtStart(){
return fieldSeparatorAtStart;
}
/**
*
* Sets whether the field separator should be added at the start
* of each buffer.
*
*
* @param fieldSeparatorAtStart
* the fieldSeparatorAtStart flag
* @since 2.0
*/
protected void setFieldSeparatorAtStart(final boolean fieldSeparatorAtStart){
this.fieldSeparatorAtStart = fieldSeparatorAtStart;
}
//---------------------------------------------------------------------
/**
*
* Gets whether the field separator should be added at the end
* of each buffer.
*
*
* @return fieldSeparatorAtEnd flag
* @since 2.0
*/
protected boolean isFieldSeparatorAtEnd(){
return fieldSeparatorAtEnd;
}
/**
*
* Sets whether the field separator should be added at the end
* of each buffer.
*
*
* @param fieldSeparatorAtEnd
* the fieldSeparatorAtEnd flag
* @since 2.0
*/
protected void setFieldSeparatorAtEnd(final boolean fieldSeparatorAtEnd){
this.fieldSeparatorAtEnd = fieldSeparatorAtEnd;
}
//---------------------------------------------------------------------
/**
*
* Gets the text to output when {@code null} found.
*
*
* @return the current text to output when null found
*/
protected String getNullText(){
return nullText;
}
/**
*
* Sets the text to output when {@code null} found.
*
*
*
* {@code null} is accepted, but will be converted to
* an empty String.
*
*
* @param nullText
* the new text to output when null found
*/
protected void setNullText(String nullText){
if (nullText == null){
nullText = EMPTY;
}
this.nullText = nullText;
}
//---------------------------------------------------------------------
/**
*
* Gets the start text to output when a {@code Collection},
* {@code Map} or array size is output.
*
*
*
* This is output before the size value.
*
*
* @return the current start of size text
*/
protected String getSizeStartText(){
return sizeStartText;
}
/**
*
* Sets the start text to output when a {@code Collection},
* {@code Map} or array size is output.
*
*
*
* This is output before the size value.
*
*
*
* {@code null} is accepted, but will be converted to
* an empty String.
*
*
* @param sizeStartText
* the new start of size text
*/
protected void setSizeStartText(String sizeStartText){
if (sizeStartText == null){
sizeStartText = EMPTY;
}
this.sizeStartText = sizeStartText;
}
//---------------------------------------------------------------------
/**
*
* Gets the end text to output when a {@code Collection},
* {@code Map} or array size is output.
*
*
*
* This is output after the size value.
*
*
* @return the current end of size text
*/
protected String getSizeEndText(){
return sizeEndText;
}
/**
*
* Sets the end text to output when a {@code Collection},
* {@code Map} or array size is output.
*
*
*
* This is output after the size value.
*
*
*
* {@code null} is accepted, but will be converted to
* an empty String.
*
*
* @param sizeEndText
* the new end of size text
*/
protected void setSizeEndText(String sizeEndText){
if (sizeEndText == null){
sizeEndText = EMPTY;
}
this.sizeEndText = sizeEndText;
}
//---------------------------------------------------------------------
/**
*
* Gets the start text to output when an {@code Object} is
* output in summary mode.
*
*
*
* This is output before the size value.
*
*
* @return the current start of summary text
*/
protected String getSummaryObjectStartText(){
return summaryObjectStartText;
}
/**
*
* Sets the start text to output when an {@code Object} is
* output in summary mode.
*
*
*
* This is output before the size value.
*
*
*
* {@code null} is accepted, but will be converted to
* an empty String.
*
*
* @param summaryObjectStartText
* the new start of summary text
*/
protected void setSummaryObjectStartText(String summaryObjectStartText){
if (summaryObjectStartText == null){
summaryObjectStartText = EMPTY;
}
this.summaryObjectStartText = summaryObjectStartText;
}
//---------------------------------------------------------------------
/**
*
* Gets the end text to output when an {@code Object} is
* output in summary mode.
*
*
*
* This is output after the size value.
*
*
* @return the current end of summary text
*/
protected String getSummaryObjectEndText(){
return summaryObjectEndText;
}
/**
*
* Sets the end text to output when an {@code Object} is
* output in summary mode.
*
*
*
* This is output after the size value.
*
*
*
* {@code null} is accepted, but will be converted to
* an empty String.
*
*
* @param summaryObjectEndText
* the new end of summary text
*/
protected void setSummaryObjectEndText(String summaryObjectEndText){
if (summaryObjectEndText == null){
summaryObjectEndText = EMPTY;
}
this.summaryObjectEndText = summaryObjectEndText;
}
//----------------------------------------------------------------------------
/**
*
* Default {@code ToStringStyle}.
*
*
*
* This is an inner class rather than using
* {@code StandardToStringStyle} to ensure its immutability.
*
*/
private static final class DefaultToStringStyle extends ToStringStyle{
/**
* Required for serialization support.
*
* @see java.io.Serializable
*/
private static final long serialVersionUID = 1L;
/**
*
* Constructor.
*
*
*
* Use the static constant rather than instantiating.
*
*/
DefaultToStringStyle(){
super();
}
/**
*
* Ensure {@code Singleton} after serialization.
*
*
* @return the singleton
*/
private Object readResolve(){
return DEFAULT_STYLE;
}
}
//----------------------------------------------------------------------------
/**
*
* {@code ToStringStyle} that does not print out
* the field names.
*
*
*
* This is an inner class rather than using
* {@code StandardToStringStyle} to ensure its immutability.
*/
private static final class NoFieldNameToStringStyle extends ToStringStyle{
private static final long serialVersionUID = 1L;
/**
*
* Constructor.
*
*
*
* Use the static constant rather than instantiating.
*
*/
NoFieldNameToStringStyle(){
super();
this.setUseFieldNames(false);
}
/**
*
* Ensure {@code Singleton} after serialization.
*
*
* @return the singleton
*/
private Object readResolve(){
return NO_FIELD_NAMES_STYLE;
}
}
//----------------------------------------------------------------------------
/**
*
* {@code ToStringStyle} that prints out the short
* class name and no identity hashcode.
*
*
*
* This is an inner class rather than using
* {@code StandardToStringStyle} to ensure its immutability.
*
*/
private static final class ShortPrefixToStringStyle extends ToStringStyle{
private static final long serialVersionUID = 1L;
/**
*
* Constructor.
*
*
*
* Use the static constant rather than instantiating.
*
*/
ShortPrefixToStringStyle(){
super();
this.setUseShortClassName(true);
this.setUseIdentityHashCode(false);
}
/**
*
* Ensure Singleton after serialization.
*
*
* @return the singleton
*/
private Object readResolve(){
return SHORT_PREFIX_STYLE;
}
}
//----------------------------------------------------------------------------
/**
*
* {@code ToStringStyle} that does not print out the
* classname, identity hashcode, content start or field name.
*
*
*
* This is an inner class rather than using
* {@code StandardToStringStyle} to ensure its immutability.
*
*/
private static final class SimpleToStringStyle extends ToStringStyle{
private static final long serialVersionUID = 1L;
/**
*
* Constructor.
*
*
*
* Use the static constant rather than instantiating.
*
*/
SimpleToStringStyle(){
super();
this.setUseClassName(false);
this.setUseIdentityHashCode(false);
this.setUseFieldNames(false);
this.setContentStart(EMPTY);
this.setContentEnd(EMPTY);
}
/**
*
* Ensure Singleton after serialization.
*
*
* @return the singleton
*/
private Object readResolve(){
return SIMPLE_STYLE;
}
}
//----------------------------------------------------------------------------
/**
*
* {@code ToStringStyle} that outputs on multiple lines.
*
*
*
* This is an inner class rather than using
* {@code StandardToStringStyle} to ensure its immutability.
*
*/
private static final class MultiLineToStringStyle extends ToStringStyle{
private static final long serialVersionUID = 1L;
/**
*
* Constructor.
*
*
*
* Use the static constant rather than instantiating.
*
*/
MultiLineToStringStyle(){
super();
this.setContentStart("[");
this.setFieldSeparator(System.lineSeparator() + " ");
this.setFieldSeparatorAtStart(true);
this.setContentEnd(System.lineSeparator() + "]");
}
/**
*
* Ensure {@code Singleton} after serialization.
*
*
* @return the singleton
*/
private Object readResolve(){
return MULTI_LINE_STYLE;
}
}
//----------------------------------------------------------------------------
/**
*
* {@code ToStringStyle} that does not print out the classname
* and identity hash code but prints content start and field names.
*
*
*
* This is an inner class rather than using
* {@code StandardToStringStyle} to ensure its immutability.
*
*/
private static final class NoClassNameToStringStyle extends ToStringStyle{
private static final long serialVersionUID = 1L;
/**
*
* Constructor.
*
*
*
* Use the static constant rather than instantiating.
*
*/
NoClassNameToStringStyle(){
super();
this.setUseClassName(false);
this.setUseIdentityHashCode(false);
}
/**
*
* Ensure {@code Singleton} after serialization.
*
*
* @return the singleton
*/
private Object readResolve(){
return NO_CLASS_NAME_STYLE;
}
}
// ----------------------------------------------------------------------------
}