+1 :) On Thu, Feb 4, 2010 at 4:17 PM, Niall Pemberton <niall.pember...@gmail.com> wrote: > 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 > >
--------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org For additional commands, e-mail: dev-h...@commons.apache.org