Matt, Can you stop mixing up style/format changes with real functional changes - it makes it harder to follow along when you change a few lines and theres 10 pages in the commit email, I guess this is probably an IDE setting to remove trailing spaces. Can you either change your IDE or if you do want to change the format then do it as a separate commit before you make any functional changes.
Thanks Niall On Thu, Feb 4, 2010 at 9:46 PM, <mben...@apache.org> wrote: > Author: mbenson > Date: Thu Feb 4 21:46:22 2010 > New Revision: 906673 > > URL: http://svn.apache.org/viewvc?rev=906673&view=rev > Log: > [LANG-586] clear ThreadLocal recursion registry (compatibly with existing > tests, first pass) > > Modified: > > commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/builder/ToStringStyle.java > > Modified: > commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/builder/ToStringStyle.java > URL: > http://svn.apache.org/viewvc/commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/builder/ToStringStyle.java?rev=906673&r1=906672&r2=906673&view=diff > ============================================================================== > --- > commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/builder/ToStringStyle.java > (original) > +++ > commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/builder/ToStringStyle.java > Thu Feb 4 21:46:22 2010 > @@ -5,9 +5,9 @@ > * 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. > @@ -19,9 +19,10 @@ > import java.io.Serializable; > import java.lang.reflect.Array; > import java.util.Collection; > -import java.util.HashSet; > +import java.util.Collections; > import java.util.Map; > import java.util.Set; > +import java.util.WeakHashMap; > > import org.apache.commons.lang3.ClassUtils; > import org.apache.commons.lang3.ObjectUtils; > @@ -46,7 +47,7 @@ > * <p>For example, the detail version of the array based methods will > * output the whole array, whereas the summary method will just output > * the array length.</p> > - * > + * > * <p>If you want to format the output of certain objects, such as dates, you > * must create a subclass and override a method. > * <pre> > @@ -73,17 +74,17 @@ > /** > * The default toString style. Using the Using the <code>Person</code> > * example from {...@link ToStringBuilder}, the output would look like > this: > - * > + * > * <pre> > * per...@182f0db[name=john Doe,age=33,smoker=false] > * </pre> > */ > public static final ToStringStyle DEFAULT_STYLE = new > DefaultToStringStyle(); > - > + > /** > * The multi line toString style. Using the Using the <code>Person</code> > * example from {...@link ToStringBuilder}, the output would look like > this: > - * > + * > * <pre> > * per...@182f0db[ > * name=John Doe > @@ -93,26 +94,26 @@ > * </pre> > */ > public static final ToStringStyle MULTI_LINE_STYLE = new > MultiLineToStringStyle(); > - > + > /** > * The no field names toString style. Using the Using the > * <code>Person</code> example from {...@link ToStringBuilder}, the output > * would look like this: > - * > + * > * <pre> > * per...@182f0db[john Doe,33,false] > * </pre> > */ > public static final ToStringStyle NO_FIELD_NAMES_STYLE = new > NoFieldNameToStringStyle(); > - > + > /** > * The short prefix toString style. Using the <code>Person</code> example > * from {...@link ToStringBuilder}, the output would look like this: > - * > + * > * <pre> > * Person[name=John Doe,age=33,smoker=false] > * </pre> > - * > + * > * @since 2.1 > */ > public static final ToStringStyle SHORT_PREFIX_STYLE = new > ShortPrefixToStringStyle(); > @@ -120,38 +121,32 @@ > /** > * The simple toString style. Using the Using the <code>Person</code> > * example from {...@link ToStringBuilder}, the output would look like > this: > - * > + * > * <pre> > * John Doe,33,false > * </pre> > */ > public static final ToStringStyle SIMPLE_STYLE = new > SimpleToStringStyle(); > - > + > /** > * <p> > * A registry of objects used by <code>reflectionToString</code> methods > * to detect cyclical object references and avoid infinite loops. > * </p> > */ > - private static final ThreadLocal<Set<Object>> registry = new > ThreadLocal<Set<Object>>() { > - �...@override > - protected Set<Object> initialValue() { > - // The HashSet implementation is not synchronized, > - // which is just what we need here. > - return new HashSet<Object>(); > - } > - }; > + private static final ThreadLocal<WeakHashMap<Object, Object>> REGISTRY = > new ThreadLocal<WeakHashMap<Object,Object>>(); > > /** > * <p> > * Returns the registry of objects being traversed by the > <code>reflectionToString</code> > * methods in the current thread. > * </p> > - * > + * > * @return Set the registry of objects being traversed > */ > static Set<Object> getRegistry() { > - return registry.get(); > + WeakHashMap<Object, Object> m = REGISTRY.get(); > + return m == null ? Collections.<Object> emptySet() : m.keySet(); > } > > /** > @@ -159,7 +154,7 @@ > * Returns <code>true</code> if the registry contains the given object. > * Used by the reflection methods to avoid infinite loops. > * </p> > - * > + * > * @param value > * The object to lookup in the registry. > * @return boolean <code>true</code> if the registry contains the given > @@ -174,13 +169,21 @@ > * Registers the given object. Used by the reflection methods to avoid > * infinite loops. > * </p> > - * > + * > * @param value > * The object to register. > */ > static void register(Object value) { > if (value != null) { > - getRegistry().add(value); > + WeakHashMap<Object, Object> m; > + synchronized (ToStringStyle.class) { > + m = REGISTRY.get(); > + if (m == null) { > + m = new WeakHashMap<Object, Object>(); > + REGISTRY.set(m); > + } > + } > + m.put(value, null); > } > } > > @@ -188,33 +191,44 @@ > * <p> > * Unregisters the given object. > * </p> > - * > + * > * <p> > * Used by the reflection methods to avoid infinite loops. > * </p> > - * > + * > * @param value > * The object to unregister. > */ > static void unregister(Object value) { > - getRegistry().remove(value); > + if (value != null) { > + WeakHashMap<Object, Object> m; > + synchronized (ToStringStyle.class) { > + m = REGISTRY.get(); > + if (m != null) { > + m.remove(value); > + if (m.isEmpty()) { > + REGISTRY.remove(); > + } > + } > + } > + } > } > > /** > * Whether to use the field names, the default is <code>true</code>. > */ > private boolean useFieldNames = true; > - > + > /** > * Whether to use the class name, the default is <code>true</code>. > */ > private boolean useClassName = true; > - > + > /** > * Whether to use short class names, the default is <code>false</code>. > */ > private boolean useShortClassName = false; > - > + > /** > * Whether to use the identity hash code, the default is > <code>true</code>. > */ > @@ -224,78 +238,78 @@ > * The content start <code>'['</code>. > */ > private String contentStart = "["; > - > + > /** > * The content end <code>']'</code>. > */ > private String contentEnd = "]"; > - > + > /** > * The field name value separator <code>'='</code>. > */ > private String fieldNameValueSeparator = "="; > - > + > /** > * Whether the field separator should be added before any other fields. > */ > private boolean fieldSeparatorAtStart = false; > - > + > /** > * Whether the field separator should be added after any other fields. > */ > private boolean fieldSeparatorAtEnd = false; > - > + > /** > * The field separator <code>','</code>. > */ > private String fieldSeparator = ","; > - > + > /** > * The array start <code>'{'</code>. > */ > private String arrayStart = "{"; > - > + > /** > * The array separator <code>','</code>. > */ > private String arraySeparator = ","; > - > + > /** > * The detail for array content. > */ > private boolean arrayContentDetail = true; > - > + > /** > * The array end <code>'}'</code>. > */ > private String arrayEnd = "}"; > - > + > /** > * The value to use when fullDetail is <code>null</code>, > * the default value is <code>true</code>. > */ > private boolean defaultFullDetail = true; > - > + > /** > * The <code>null</code> text <code>'<null>'</code>. > */ > private String nullText = "<null>"; > - > + > /** > * The summary size text start <code>'<size'</code>. > */ > private String sizeStartText = "<size="; > - > + > /** > * The summary size text start <code>'>'</code>. > */ > private String sizeEndText = ">"; > - > + > /** > * The summary object text start <code>'<'</code>. > */ > private String summaryObjectStartText = "<"; > - > + > /** > * The summary object text start <code>'>'</code>. > */ > @@ -315,9 +329,9 @@ > /** > * <p>Append to the <code>toString</code> the superclass toString.</p> > * <p>NOTE: It assumes that the toString has been created from the same > ToStringStyle. </p> > - * > + * > * <p>A <code>null</code> <code>superToString</code> is ignored.</p> > - * > + * > * @param buffer the <code>StringBuffer</code> to populate > * @param superToString the <code>super.toString()</code> > * @since 2.0 > @@ -329,9 +343,9 @@ > /** > * <p>Append to the <code>toString</code> another toString.</p> > * <p>NOTE: It assumes that the toString has been created from the same > ToStringStyle. </p> > - * > + * > * <p>A <code>null</code> <code>toString</code> is ignored.</p> > - * > + * > * @param buffer the <code>StringBuffer</code> to populate > * @param toString the additional <code>toString</code> > * @since 2.0 > @@ -353,7 +367,7 @@ > > /** > * <p>Append to the <code>toString</code> the start of data indicator.</p> > - * > + * > * @param buffer the <code>StringBuffer</code> to populate > * @param object the <code>Object</code> to build a > <code>toString</code> for > */ > @@ -370,7 +384,7 @@ > > /** > * <p>Append to the <code>toString</code> the end of data indicator.</p> > - * > + * > * @param buffer the <code>StringBuffer</code> to populate > * @param object the <code>Object</code> to build a > * <code>toString</code> for. > @@ -385,7 +399,7 @@ > > /** > * <p>Remove the last field separator from the buffer.</p> > - * > + * > * @param buffer the <code>StringBuffer</code> to populate > * @since 2.0 > */ > @@ -456,7 +470,7 @@ > && !(value instanceof Number || value instanceof Boolean || value > instanceof Character)) { > appendCyclicObject(buffer, fieldName, value); > return; > - } > + } > > register(value); > > @@ -467,77 +481,77 @@ > } 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); > @@ -549,17 +563,17 @@ > unregister(value); > } > } > - > + > /** > * <p>Append to the <code>toString</code> an <code>Object</code> > * value that has been detected to participate in a cycle. This > * implementation will print the standard string value of the value.</p> > - * > + * > * @param buffer the <code>StringBuffer</code> to populate > * @param fieldName the field name, typically not used as already > appended > * @param value the value to add to the <code>toString</code>, > * not <code>null</code> > - * > + * > * @since 2.2 > */ > protected void appendCyclicObject(StringBuffer buffer, String fieldName, > Object value) { > @@ -1428,7 +1442,7 @@ > > /** > * <p>Append to the <code>toString</code> the class name.</p> > - * > + * > * @param buffer the <code>StringBuffer</code> to populate > * @param object the <code>Object</code> whose name to output > */ > @@ -1445,7 +1459,7 @@ > > /** > * <p>Append the {...@link System#identityHashCode(java.lang.Object)}.</p> > - * > + * > * @param buffer the <code>StringBuffer</code> to populate > * @param object the <code>Object</code> whose id to output > */ > @@ -1459,7 +1473,7 @@ > > /** > * <p>Append to the <code>toString</code> the content start.</p> > - * > + * > * @param buffer the <code>StringBuffer</code> to populate > */ > protected void appendContentStart(StringBuffer buffer) { > @@ -1468,7 +1482,7 @@ > > /** > * <p>Append to the <code>toString</code> the content end.</p> > - * > + * > * @param buffer the <code>StringBuffer</code> to populate > */ > protected void appendContentEnd(StringBuffer buffer) { > @@ -1479,7 +1493,7 @@ > * <p>Append to the <code>toString</code> an indicator for > <code>null</code>.</p> > * > * <p>The default indicator is <code>'<null>'</code>.</p> > - * > + * > * @param buffer the <code>StringBuffer</code> to populate > * @param fieldName the field name, typically not used as already > appended > */ > @@ -1489,7 +1503,7 @@ > > /** > * <p>Append to the <code>toString</code> the field separator.</p> > - * > + * > * @param buffer the <code>StringBuffer</code> to populate > */ > protected void appendFieldSeparator(StringBuffer buffer) { > @@ -1498,7 +1512,7 @@ > > /** > * <p>Append to the <code>toString</code> the field start.</p> > - * > + * > * @param buffer the <code>StringBuffer</code> to populate > * @param fieldName the field name > */ > @@ -1511,7 +1525,7 @@ > > /** > * <p>Append to the <code>toString<code> the field end.</p> > - * > + * > * @param buffer the <code>StringBuffer</code> to populate > * @param fieldName the field name, typically not used as already > appended > */ > @@ -1550,7 +1564,7 @@ > * <code>null</code> indicating that it doesn't care about > * the detail level. In this case the default detail level is > * used.</p> > - * > + * > * @param fullDetailRequest the detail level requested > * @return whether full detail is to be shown > */ > @@ -1886,9 +1900,9 @@ > //--------------------------------------------------------------------- > > /** > - * <p>Gets whether the field separator should be added at the start > + * <p>Gets whether the field separator should be added at the start > * of each buffer.</p> > - * > + * > * @return the fieldSeparatorAtStart flag > * @since 2.0 > */ > @@ -1897,9 +1911,9 @@ > } > > /** > - * <p>Sets whether the field separator should be added at the start > + * <p>Sets whether the field separator should be added at the start > * of each buffer.</p> > - * > + * > * @param fieldSeparatorAtStart the fieldSeparatorAtStart flag > * @since 2.0 > */ > @@ -1910,9 +1924,9 @@ > //--------------------------------------------------------------------- > > /** > - * <p>Gets whether the field separator should be added at the end > + * <p>Gets whether the field separator should be added at the end > * of each buffer.</p> > - * > + * > * @return fieldSeparatorAtEnd flag > * @since 2.0 > */ > @@ -1921,9 +1935,9 @@ > } > > /** > - * <p>Sets whether the field separator should be added at the end > + * <p>Sets whether the field separator should be added at the end > * of each buffer.</p> > - * > + * > * @param fieldSeparatorAtEnd the fieldSeparatorAtEnd flag > * @since 2.0 > */ > @@ -2097,7 +2111,7 @@ > > /** > * Required for serialization support. > - * > + * > * @see java.io.Serializable > */ > private static final long serialVersionUID = 1L; > @@ -2157,7 +2171,7 @@ > } > > > //---------------------------------------------------------------------------- > - > + > /** > * <p><code>ToStringStyle</code> that prints out the short > * class name and no identity hashcode.</p> > > > --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org For additional commands, e-mail: dev-h...@commons.apache.org