Add ability to build compound toStrings using superclass and delegates

git-svn-id: https://svn.apache.org/repos/asf/jakarta/commons/proper/lang/trunk@137173 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Stephen Colebourne 2002-12-08 20:48:46 +00:00
parent a2fd090995
commit ecb4235c77
9 changed files with 303 additions and 18 deletions

View File

@ -64,7 +64,7 @@ package org.apache.commons.lang.builder;
* program to access.</p>
*
* @author <a href="mailto:scolebourne@joda.org">Stephen Colebourne</a>
* @version $Id: StandardToStringStyle.java,v 1.5 2002/11/17 21:46:42 scolebourne Exp $
* @version $Id: StandardToStringStyle.java,v 1.6 2002/12/08 20:45:08 scolebourne Exp $
*/
public class StandardToStringStyle extends ToStringStyle {
@ -359,6 +359,50 @@ public class StandardToStringStyle extends ToStringStyle {
//---------------------------------------------------------------------
/**
* <p>Gets whether the field separator should be added at the start
* of each buffer.</p>
*
* @return the fieldSeparatorAtStart flag
*/
public boolean isFieldSeparatorAtStart() {
return super.isFieldSeparatorAtStart();
}
/**
* <p>Sets whether the field separator should be added at the start
* of each buffer.</p>
*
* @param fieldSeparatorAtStart the fieldSeparatorAtStart flag
*/
public void setFieldSeparatorAtStart(boolean fieldSeparatorAtStart) {
super.setFieldSeparatorAtStart(fieldSeparatorAtStart);
}
//---------------------------------------------------------------------
/**
* <p>Gets whether the field separator should be added at the end
* of each buffer.</p>
*
* @return fieldSeparatorAtEnd flag
*/
public boolean isFieldSeparatorAtEnd() {
return super.isFieldSeparatorAtEnd();
}
/**
* <p>Sets whether the field separator should be added at the end
* of each buffer.</p>
*
* @param fieldSeparatorAtEnd the fieldSeparatorAtEnd flag
*/
public void setFieldSeparatorAtEnd(boolean fieldSeparatorAtEnd) {
super.setFieldSeparatorAtEnd(fieldSeparatorAtEnd);
}
//---------------------------------------------------------------------
/**
* <p>Gets the text to output when <code>null</code> found.</p>
*

View File

@ -88,13 +88,17 @@ import java.lang.reflect.Modifier;
* </pre>
* <p>This will produce a toString of the format:
* <code>Person@7f54[name=Stephen,age=29,smoker=false]</code></p>
*
* <p>To add the superclass <code>toString</code>, use {@link #appendSuper}.
* To append the <code>toString</code> from an object that is delegated
* to (or any other object), use {@link #appendToString}.</p>
*
* <p>Alternatively, there is a method that uses reflection to determine
* the fields to test. Because these fields are usually private, the method,
* <code>reflectionToString</code>, uses <code>Field.setAccessible</code> to
* change the visibility of the fields. This will fail under a security manager,
* unless the appropriate permissions are set up correctly. It is also
* slower than testing explicitly.</p>
* slower than testing explicitly and does not handle superclasses.</p>
*
* <p>A typical invocation for this method would look like:</p>
* <pre>
@ -107,7 +111,7 @@ import java.lang.reflect.Modifier;
* the {@link ToStringStyle} passed into the constructor.</p>
*
* @author <a href="mailto:scolebourne@joda.org">Stephen Colebourne</a>
* @version $Id: ToStringBuilder.java,v 1.8 2002/11/17 21:46:42 scolebourne Exp $
* @version $Id: ToStringBuilder.java,v 1.9 2002/12/08 20:45:08 scolebourne Exp $
*/
public class ToStringBuilder {
@ -334,6 +338,59 @@ public class ToStringBuilder {
//----------------------------------------------------------------------------
/**
* <p>Append the <code>toString</code> from the superclass.</p>
*
* <p>This method asumes that the superclass uses the same <code>ToStringStyle</code>
* as this one.</p>
*
* <p>If the <code>superToString</code> is null, no change is made.</p>
*
* @param superToString the result of <code>super.toString()</code>
* @return this
*/
public ToStringBuilder appendSuper(String superToString) {
if (superToString != null) {
style.appendSuper(buffer, superToString);
}
return this;
}
/**
* <p>Append the <code>toString</code> from another object.</p>
*
* <p>This method is useful where a class delegates most of the implementation of
* it's properties to another class. You can then call toString() on the other
* class and pass the result into this method.</p>
*
* <pre>
* private AnotherObject delegate;
* private String fieldInThisClass;
*
* public String toString() {
* return new ToStringBuilder(this).
* appendToString(delegate.toString()).
* append(fieldInThisClass).
* toString();
* }</pre>
*
* <p>This method asumes that the other object uses the same <code>ToStringStyle</code>
* as this one.</p>
*
* <p>If the <code>toString</code> is null, no change is made.</p>
*
* @param toString the result of <code>toString()</code> on another object
* @return this
*/
public ToStringBuilder appendToString(String toString) {
if (toString != null) {
style.appendToString(buffer, toString);
}
return this;
}
//----------------------------------------------------------------------------
/**
* <p>Append to the <code>toString</code> an <code>Object</code>
* value.</p>
@ -1015,6 +1072,15 @@ public class ToStringBuilder {
//----------------------------------------------------------------------------
/**
* <p>Gets the <code>ToStringStyle</code> being used.</p>
*
* @return the <code>ToStringStyle</code> being used
*/
public ToStringStyle getStyle() {
return style;
}
/**
* <p>Gets the <code>StringBuffer</code> being populated.</p>
*
@ -1027,6 +1093,9 @@ public class ToStringBuilder {
/**
* <p>Returns the built <code>toString</code>.</p>
*
* <p>This method appends the end of the buffer, and can only be called once.
* Use {@link #getStringBuffer} to get the current string state.</p>
*
* @return the String <code>toString</code>
*/
public String toString() {

View File

@ -80,7 +80,7 @@ import org.apache.commons.lang.SystemUtils;
* the array length.</p>
*
* @author <a href="mailto:scolebourne@joda.org">Stephen Colebourne</a>
* @version $Id: ToStringStyle.java,v 1.7 2002/11/22 22:52:17 bayard Exp $
* @version $Id: ToStringStyle.java,v 1.8 2002/12/08 20:45:08 scolebourne Exp $
*/
public abstract class ToStringStyle implements Serializable {
@ -130,6 +130,14 @@ public abstract class ToStringStyle implements Serializable {
* 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>.
*/
@ -187,6 +195,41 @@ public abstract class ToStringStyle implements Serializable {
//----------------------------------------------------------------------------
/**
* <p>Append the superclass toString.</p>
*
* <p>A null <code>super.toString()</code> is ignored.</p>
*
* @param buffer the <code>StringBuffer</code> to populate
* @param superToString the <code>super.toString()</code>
*/
public void appendSuper(StringBuffer buffer, String superToString) {
appendToString(buffer, superToString);
}
/**
* <p>Append a toString.</p>
*
* <p>A null <code>toString()</code> is ignored.</p>
*
* @param buffer the <code>StringBuffer</code> to populate
* @param toString the <code>super.toString()</code>
*/
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 the start of data indicator.</p>
*
@ -198,6 +241,9 @@ public abstract class ToStringStyle implements Serializable {
appendClassName(buffer, object);
appendIdentityHashCode(buffer, object);
appendContentStart(buffer);
if (fieldSeparatorAtStart) {
appendFieldSeparator(buffer);
}
}
/**
@ -208,8 +254,33 @@ public abstract class ToStringStyle implements Serializable {
* <code>toString</code> for, must not be <code>null</code>
*/
public void appendEnd(StringBuffer buffer, Object object) {
if (fieldSeparatorAtEnd == false) {
removeLastFieldSeparator(buffer);
}
appendContentEnd(buffer);
}
/**
* <p>Remove the last field separator from the buffer</p>
*
* @param buffer the <code>StringBuffer</code> to populate
*/
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);
}
}
}
//----------------------------------------------------------------------------
@ -1217,11 +1288,6 @@ public abstract class ToStringStyle implements Serializable {
* @param buffer the <code>StringBuffer</code> to populate
*/
protected void appendContentEnd(StringBuffer buffer) {
int len = buffer.length();
int sepLen = fieldSeparator.length();
if (len > 0 && sepLen > 0 && len >= sepLen && buffer.charAt(len - 1) == fieldSeparator.charAt(sepLen - 1)) {
buffer.setLength(len - sepLen);
}
buffer.append(contentEnd);
}
@ -1638,6 +1704,50 @@ public abstract class ToStringStyle implements Serializable {
//---------------------------------------------------------------------
/**
* <p>Gets whether the field separator should be added at the start
* of each buffer.</p>
*
* @return the fieldSeparatorAtStart flag
*/
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
*/
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
*/
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
*/
protected void setFieldSeparatorAtEnd(boolean fieldSeparatorAtEnd) {
this.fieldSeparatorAtEnd = fieldSeparatorAtEnd;
}
//---------------------------------------------------------------------
/**
* <p>Gets the text to output when <code>null</code> found.</p>
*
@ -1790,8 +1900,6 @@ public abstract class ToStringStyle implements Serializable {
this.summaryObjectEndText = summaryObjectEndText;
}
//---------------------------------------------------------------------
//----------------------------------------------------------------------------
/**
@ -1906,8 +2014,9 @@ public abstract class ToStringStyle implements Serializable {
*/
private MultiLineToStringStyle() {
super();
this.setContentStart("[" + SystemUtils.LINE_SEPARATOR + " ");
this.setContentStart("[");
this.setFieldSeparator(SystemUtils.LINE_SEPARATOR + " ");
this.setFieldSeparatorAtStart(true);
this.setContentEnd(SystemUtils.LINE_SEPARATOR + "]");
}

View File

@ -65,7 +65,7 @@ import junit.textui.TestRunner;
* Unit tests {@link org.apache.commons.lang.ToStringStyle}.
*
* @author <a href="mailto:scolebourne@joda.org">Stephen Colebourne</a>
* @version $Id: DefaultToStringStyleTest.java,v 1.1 2002/09/17 22:07:50 scolebourne Exp $
* @version $Id: DefaultToStringStyleTest.java,v 1.2 2002/12/08 20:48:46 scolebourne Exp $
*/
public class DefaultToStringStyleTest extends TestCase {
@ -102,6 +102,15 @@ public class DefaultToStringStyleTest extends TestCase {
assertEquals(baseStr + "[]", new ToStringBuilder(base).toString());
}
public void testAppendSuper() {
assertEquals(baseStr + "[]", new ToStringBuilder(base).appendSuper("Integer@8888[]").toString());
assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).appendSuper("Integer@8888[<null>]").toString());
assertEquals(baseStr + "[a=hello]", new ToStringBuilder(base).appendSuper("Integer@8888[]").append("a", "hello").toString());
assertEquals(baseStr + "[<null>,a=hello]", new ToStringBuilder(base).appendSuper("Integer@8888[<null>]").append("a", "hello").toString());
assertEquals(baseStr + "[a=hello]", new ToStringBuilder(base).appendSuper(null).append("a", "hello").toString());
}
public void testObject() {
Integer i3 = new Integer(3);
Integer i4 = new Integer(4);

View File

@ -67,7 +67,7 @@ import junit.textui.TestRunner;
* Unit tests {@link org.apache.commons.lang.ToStringStyle}.
*
* @author <a href="mailto:scolebourne@joda.org">Stephen Colebourne</a>
* @version $Id: MultiLineToStringStyleTest.java,v 1.1 2002/09/17 22:07:50 scolebourne Exp $
* @version $Id: MultiLineToStringStyleTest.java,v 1.2 2002/12/08 20:48:46 scolebourne Exp $
*/
public class MultiLineToStringStyleTest extends TestCase {
@ -104,6 +104,15 @@ public class MultiLineToStringStyleTest extends TestCase {
assertEquals(baseStr + "[" + SystemUtils.LINE_SEPARATOR + "]", new ToStringBuilder(base).toString());
}
public void testAppendSuper() {
assertEquals(baseStr + "[" + SystemUtils.LINE_SEPARATOR + "]", new ToStringBuilder(base).appendSuper("Integer@8888[" + SystemUtils.LINE_SEPARATOR + "]").toString());
assertEquals(baseStr + "[" + SystemUtils.LINE_SEPARATOR + " <null>" + SystemUtils.LINE_SEPARATOR + "]", new ToStringBuilder(base).appendSuper("Integer@8888[" + SystemUtils.LINE_SEPARATOR + " <null>" + SystemUtils.LINE_SEPARATOR + "]").toString());
assertEquals(baseStr + "[" + SystemUtils.LINE_SEPARATOR + " a=hello" + SystemUtils.LINE_SEPARATOR + "]", new ToStringBuilder(base).appendSuper("Integer@8888[" + SystemUtils.LINE_SEPARATOR + "]").append("a", "hello").toString());
assertEquals(baseStr + "[" + SystemUtils.LINE_SEPARATOR + " <null>" + SystemUtils.LINE_SEPARATOR + " a=hello" + SystemUtils.LINE_SEPARATOR + "]", new ToStringBuilder(base).appendSuper("Integer@8888[" + SystemUtils.LINE_SEPARATOR + " <null>" + SystemUtils.LINE_SEPARATOR + "]").append("a", "hello").toString());
assertEquals(baseStr + "[" + SystemUtils.LINE_SEPARATOR + " a=hello" + SystemUtils.LINE_SEPARATOR + "]", new ToStringBuilder(base).appendSuper(null).append("a", "hello").toString());
}
public void testObject() {
Integer i3 = new Integer(3);
Integer i4 = new Integer(4);

View File

@ -65,7 +65,7 @@ import junit.textui.TestRunner;
* Unit tests {@link org.apache.commons.lang.ToStringStyle}.
*
* @author <a href="mailto:scolebourne@joda.org">Stephen Colebourne</a>
* @version $Id: NoFieldNamesToStringStyleTest.java,v 1.1 2002/09/17 22:07:50 scolebourne Exp $
* @version $Id: NoFieldNamesToStringStyleTest.java,v 1.2 2002/12/08 20:48:46 scolebourne Exp $
*/
public class NoFieldNamesToStringStyleTest extends TestCase {
@ -102,6 +102,15 @@ public class NoFieldNamesToStringStyleTest extends TestCase {
assertEquals(baseStr + "[]", new ToStringBuilder(base).toString());
}
public void testAppendSuper() {
assertEquals(baseStr + "[]", new ToStringBuilder(base).appendSuper("Integer@8888[]").toString());
assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).appendSuper("Integer@8888[<null>]").toString());
assertEquals(baseStr + "[hello]", new ToStringBuilder(base).appendSuper("Integer@8888[]").append("a", "hello").toString());
assertEquals(baseStr + "[<null>,hello]", new ToStringBuilder(base).appendSuper("Integer@8888[<null>]").append("a", "hello").toString());
assertEquals(baseStr + "[hello]", new ToStringBuilder(base).appendSuper(null).append("a", "hello").toString());
}
public void testObject() {
Integer i3 = new Integer(3);
Integer i4 = new Integer(4);

View File

@ -65,7 +65,7 @@ import junit.textui.TestRunner;
* Unit tests {@link org.apache.commons.lang.ToStringStyle}.
*
* @author <a href="mailto:scolebourne@joda.org">Stephen Colebourne</a>
* @version $Id: SimpleToStringStyleTest.java,v 1.1 2002/09/17 22:07:50 scolebourne Exp $
* @version $Id: SimpleToStringStyleTest.java,v 1.2 2002/12/08 20:48:46 scolebourne Exp $
*/
public class SimpleToStringStyleTest extends TestCase {
@ -101,6 +101,15 @@ public class SimpleToStringStyleTest extends TestCase {
assertEquals("", new ToStringBuilder(base).toString());
}
public void testAppendSuper() {
assertEquals("", new ToStringBuilder(base).appendSuper("").toString());
assertEquals("<null>", new ToStringBuilder(base).appendSuper("<null>").toString());
assertEquals("hello", new ToStringBuilder(base).appendSuper("").append("a", "hello").toString());
assertEquals("<null>,hello", new ToStringBuilder(base).appendSuper("<null>").append("a", "hello").toString());
assertEquals("hello", new ToStringBuilder(base).appendSuper(null).append("a", "hello").toString());
}
public void testObject() {
Integer i3 = new Integer(3);
Integer i4 = new Integer(4);

View File

@ -65,7 +65,7 @@ import junit.textui.TestRunner;
* Unit tests {@link org.apache.commons.lang.ToStringStyle}.
*
* @author <a href="mailto:scolebourne@joda.org">Stephen Colebourne</a>
* @version $Id: StandardToStringStyleTest.java,v 1.1 2002/09/17 22:07:50 scolebourne Exp $
* @version $Id: StandardToStringStyleTest.java,v 1.2 2002/12/08 20:48:46 scolebourne Exp $
*/
public class StandardToStringStyleTest extends TestCase {
@ -117,6 +117,15 @@ public class StandardToStringStyleTest extends TestCase {
assertEquals(baseStr + "[]", new ToStringBuilder(base).toString());
}
public void testAppendSuper() {
assertEquals(baseStr + "[]", new ToStringBuilder(base).appendSuper("Integer@8888[]").toString());
assertEquals(baseStr + "[%NULL%]", new ToStringBuilder(base).appendSuper("Integer@8888[%NULL%]").toString());
assertEquals(baseStr + "[a=hello]", new ToStringBuilder(base).appendSuper("Integer@8888[]").append("a", "hello").toString());
assertEquals(baseStr + "[%NULL%,a=hello]", new ToStringBuilder(base).appendSuper("Integer@8888[%NULL%]").append("a", "hello").toString());
assertEquals(baseStr + "[a=hello]", new ToStringBuilder(base).appendSuper(null).append("a", "hello").toString());
}
public void testObject() {
Integer i3 = new Integer(3);
Integer i4 = new Integer(4);

View File

@ -65,7 +65,7 @@ import junit.textui.TestRunner;
* Unit tests {@link org.apache.commons.lang.ToStringBuilder}.
*
* @author <a href="mailto:scolebourne@joda.org">Stephen Colebourne</a>
* @version $Id: ToStringBuilderTest.java,v 1.1 2002/09/17 22:07:50 scolebourne Exp $
* @version $Id: ToStringBuilderTest.java,v 1.2 2002/12/08 20:48:46 scolebourne Exp $
*/
public class ToStringBuilderTest extends TestCase {
@ -167,6 +167,24 @@ public class ToStringBuilderTest extends TestCase {
assertEquals(baseStr + "[value=5]", ToStringBuilder.reflectionToString(base));
}
public void testAppendSuper() {
assertEquals(baseStr + "[]", new ToStringBuilder(base).appendSuper("Integer@8888[]").toString());
assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).appendSuper("Integer@8888[<null>]").toString());
assertEquals(baseStr + "[a=hello]", new ToStringBuilder(base).appendSuper("Integer@8888[]").append("a", "hello").toString());
assertEquals(baseStr + "[<null>,a=hello]", new ToStringBuilder(base).appendSuper("Integer@8888[<null>]").append("a", "hello").toString());
assertEquals(baseStr + "[a=hello]", new ToStringBuilder(base).appendSuper(null).append("a", "hello").toString());
}
public void testAppendToString() {
assertEquals(baseStr + "[]", new ToStringBuilder(base).appendToString("Integer@8888[]").toString());
assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).appendToString("Integer@8888[<null>]").toString());
assertEquals(baseStr + "[a=hello]", new ToStringBuilder(base).appendToString("Integer@8888[]").append("a", "hello").toString());
assertEquals(baseStr + "[<null>,a=hello]", new ToStringBuilder(base).appendToString("Integer@8888[<null>]").append("a", "hello").toString());
assertEquals(baseStr + "[a=hello]", new ToStringBuilder(base).appendToString(null).append("a", "hello").toString());
}
public void testObject() {
Integer i3 = new Integer(3);
Integer i4 = new Integer(4);