scolebourne 2002/12/08 12:45:08 Modified: lang/src/java/org/apache/commons/lang/builder ToStringBuilder.java ToStringStyle.java StandardToStringStyle.java Log: Add ability to build compound toStrings using superclass and delegates Revision Changes Path 1.9 +71 -2 jakarta-commons/lang/src/java/org/apache/commons/lang/builder/ToStringBuilder.java Index: ToStringBuilder.java =================================================================== RCS file: /home/cvs/jakarta-commons/lang/src/java/org/apache/commons/lang/builder/ToStringBuilder.java,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- ToStringBuilder.java 17 Nov 2002 21:46:42 -0000 1.8 +++ ToStringBuilder.java 8 Dec 2002 20:45:08 -0000 1.9 @@ -88,13 +88,17 @@ * </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> @@ -335,6 +339,59 @@ //---------------------------------------------------------------------------- /** + * <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> * @@ -1016,6 +1073,15 @@ //---------------------------------------------------------------------------- /** + * <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> * * @return the <code>StringBuffer</code> being populated @@ -1026,6 +1092,9 @@ /** * <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> */ 1.8 +118 -9 jakarta-commons/lang/src/java/org/apache/commons/lang/builder/ToStringStyle.java Index: ToStringStyle.java =================================================================== RCS file: /home/cvs/jakarta-commons/lang/src/java/org/apache/commons/lang/builder/ToStringStyle.java,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- ToStringStyle.java 22 Nov 2002 22:52:17 -0000 1.7 +++ ToStringStyle.java 8 Dec 2002 20:45:08 -0000 1.8 @@ -131,6 +131,14 @@ */ 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 = ","; @@ -188,6 +196,41 @@ //---------------------------------------------------------------------------- /** + * <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> * * @param buffer the <code>StringBuffer</code> to populate @@ -198,6 +241,9 @@ appendClassName(buffer, object); appendIdentityHashCode(buffer, object); appendContentStart(buffer); + if (fieldSeparatorAtStart) { + appendFieldSeparator(buffer); + } } /** @@ -208,8 +254,33 @@ * <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 @@ * @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); } @@ -1639,6 +1705,50 @@ //--------------------------------------------------------------------- /** + * <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> * * @return the current text to output when null found @@ -1790,8 +1900,6 @@ this.summaryObjectEndText = summaryObjectEndText; } - //--------------------------------------------------------------------- - //---------------------------------------------------------------------------- /** @@ -1906,8 +2014,9 @@ */ private MultiLineToStringStyle() { super(); - this.setContentStart("[" + SystemUtils.LINE_SEPARATOR + " "); + this.setContentStart("["); this.setFieldSeparator(SystemUtils.LINE_SEPARATOR + " "); + this.setFieldSeparatorAtStart(true); this.setContentEnd(SystemUtils.LINE_SEPARATOR + "]"); } 1.6 +45 -1 jakarta-commons/lang/src/java/org/apache/commons/lang/builder/StandardToStringStyle.java Index: StandardToStringStyle.java =================================================================== RCS file: /home/cvs/jakarta-commons/lang/src/java/org/apache/commons/lang/builder/StandardToStringStyle.java,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- StandardToStringStyle.java 17 Nov 2002 21:46:42 -0000 1.5 +++ StandardToStringStyle.java 8 Dec 2002 20:45:08 -0000 1.6 @@ -360,6 +360,50 @@ //--------------------------------------------------------------------- /** + * <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> * * @return the current text to output when <code>null</code> found
-- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>