[slf4j-dev] svn commit: r1049 - in slf4j/trunk: slf4j-api/src/main/java/org/slf4j slf4j-api/src/main/java/org/slf4j/helpers slf4j-api/src/test/java/org/slf4j slf4j-site/src/site/pages

ceki at slf4j.org ceki at slf4j.org
Thu Jun 5 22:53:19 CEST 2008


Author: ceki
Date: Thu Jun  5 22:53:19 2008
New Revision: 1049

Added:
   slf4j/trunk/slf4j-api/src/test/java/org/slf4j/Differentiator.java
Modified:
   slf4j/trunk/slf4j-api/src/main/java/org/slf4j/IMarkerFactory.java
   slf4j/trunk/slf4j-api/src/main/java/org/slf4j/Marker.java
   slf4j/trunk/slf4j-api/src/main/java/org/slf4j/MarkerFactory.java
   slf4j/trunk/slf4j-api/src/main/java/org/slf4j/helpers/BasicMarker.java
   slf4j/trunk/slf4j-api/src/main/java/org/slf4j/helpers/BasicMarkerFactory.java
   slf4j/trunk/slf4j-api/src/test/java/org/slf4j/BasicMarkerTest.java
   slf4j/trunk/slf4j-site/src/site/pages/compatibility.html
   slf4j/trunk/slf4j-site/src/site/pages/news.html

Log:
- fixed bug 74,  an endless recursion problem in Marker.contains method
  
  also added getDetachedMarker method to IMarkerFactory
  and MarkerFactory classes

  updated compatibility.html, news.html accordingly

Modified: slf4j/trunk/slf4j-api/src/main/java/org/slf4j/IMarkerFactory.java
==============================================================================
--- slf4j/trunk/slf4j-api/src/main/java/org/slf4j/IMarkerFactory.java	(original)
+++ slf4j/trunk/slf4j-api/src/main/java/org/slf4j/IMarkerFactory.java	Thu Jun  5 22:53:19 2008
@@ -69,4 +69,13 @@
    * @return whether the marker  could be detached or not
    */
   boolean detachMarker(String name);
+  
+  
+  /**
+   * Create a marker which is detached (even at birth) from this IMarkerFactory.
+   *
+   * @return a dangling marker
+   * @since 1.5.1
+   */
+  Marker getDetachedMarker(String name);
 }

Modified: slf4j/trunk/slf4j-api/src/main/java/org/slf4j/Marker.java
==============================================================================
--- slf4j/trunk/slf4j-api/src/main/java/org/slf4j/Marker.java	(original)
+++ slf4j/trunk/slf4j-api/src/main/java/org/slf4j/Marker.java	Thu Jun  5 22:53:19 2008
@@ -1,5 +1,5 @@
 /* 
- * Copyright (c) 2004-2007 QOS.ch
+ * Copyright (c) 2004-2008 QOS.ch
  * All rights reserved.
  * 
  * Permission is hereby granted, free  of charge, to any person obtaining
@@ -28,85 +28,108 @@
 import java.util.Iterator;
 
 /**
- * Markers are named objects used to enrich log statements. Conforming
- * logging system Implementations of SLF4J determine how information
- * conveyed by markers are used, if at all. In particular, many
- * conforming logging systems ignore marker data.
+ * Markers are named objects used to enrich log statements. Conforming logging
+ * system Implementations of SLF4J determine how information conveyed by markers
+ * are used, if at all. In particular, many conforming logging systems ignore
+ * marker data.
+ * 
+ * <p>
+ * Markers can contain child markers, which in turn can contain children of
+ * their own.
  * 
- * <p>Markers can contain child markers, which in turn  can contain children 
- * of their own.
- *
  * @author Ceki G&uuml;lc&uuml;
  */
 public interface Marker extends Serializable {
- 
+
   /**
    * This constant represents any marker, including a null marker.
    */
-  public static final String ANY_MARKER = "*";
-  
+  public final String ANY_MARKER = "*";
+
   /**
    * This constant represents any non-null marker.
    */
-  public static final String ANY_NON_NULL_MARKER = "+";
-  
-  
+  public final String ANY_NON_NULL_MARKER = "+";
+
   /**
    * Get the name of this Marker.
+   * 
    * @return name of marker
-   */ 
+   */
   public String getName();
 
   /**
    * Add a child Marker to this Marker.
-   * @param child a child marker
+   * 
+   * @param child
+   *                a child marker
    */
   public void add(Marker child);
-  
+
   /**
    * Remove a child Marker.
-   * @param child the child Marker to remove
+   * 
+   * @param child
+   *                the child Marker to remove
    * @return true if child could be found and removed, false otherwise.
    */
   public boolean remove(Marker child);
-  
+
   /**
    * Does this marker have children?
+   * 
    * @return true if this marker has children, false otherwise.
    */
   public boolean hasChildren();
-  
+
   /**
-   * Returns an Iterator which can be used to iterate over the
-   * children of this marker. An empty iterator is returned when this
-   * marker has no children.
+   * Returns an Iterator which can be used to iterate over the children of this
+   * marker. An empty iterator is returned when this marker has no children.
    * 
    * @return Iterator over the children of this marker
    */
   public Iterator iterator();
-  
+
   /**
-   * Does this marker contain the 'other' marker? Marker A is defined to 
-   * contain marker B, if A == B or if B is a child of A. 
+   * Does this marker contain the 'other' marker? Marker A is defined to contain
+   * marker B, if A == B or if B is a child of A.
    * 
-   * @param other The marker to test for inclusion.
-   * @throws IllegalArgumentException if 'other' is null
+   * @param other
+   *                The marker to test for inclusion.
+   * @throws IllegalArgumentException
+   *                 if 'other' is null
    * @return Whether this marker contains the other marker.
    */
   public boolean contains(Marker other);
 
-  
-  
   /**
-   * Does this marker contain the marker named 'name'? 
+   * Does this marker contain the marker named 'name'?
    * 
    * If 'name' is null the returned value is always false.
    * 
-   * @param other The marker to test for inclusion.
+   * @param other
+   *                The marker to test for inclusion.
    * @return Whether this marker contains the other marker.
    */
   public boolean contains(String name);
-  
-//  void makeImmutable();
-//  public boolean isImmutable();
+
+  /**
+   * Markers are considered equal if they have the same name.
+   *
+   * @param o
+   * @return true, if this.name equals o.name
+   *
+   * @since 1.5.1
+   */
+  public boolean equals(Object o);
+
+  /**
+   * Compute the hash code based on the name of this marker.
+   * Note that markers are considered equal if they have the same name.
+   * 
+   * @return the computed hashCode
+   * @since 1.5.1
+   */
+  public int hashCode();
+
 }

Modified: slf4j/trunk/slf4j-api/src/main/java/org/slf4j/MarkerFactory.java
==============================================================================
--- slf4j/trunk/slf4j-api/src/main/java/org/slf4j/MarkerFactory.java	(original)
+++ slf4j/trunk/slf4j-api/src/main/java/org/slf4j/MarkerFactory.java	Thu Jun  5 22:53:19 2008
@@ -69,6 +69,16 @@
   }
 
   /**
+   * Create a marker which is detached (even at birth) from the MarkerFactory.
+   *
+   * @return a dangling marker
+   * @since 1.5.1
+   */
+  public static Marker getDetachedMarker(String name) {
+    return markerFactory.getDetachedMarker(name);
+  }
+  
+  /**
    * Return the {@link IMarkerFactory}instance in use.
    * 
    * <p>The IMarkerFactory instance is usually bound with this class at 

Modified: slf4j/trunk/slf4j-api/src/main/java/org/slf4j/helpers/BasicMarker.java
==============================================================================
--- slf4j/trunk/slf4j-api/src/main/java/org/slf4j/helpers/BasicMarker.java	(original)
+++ slf4j/trunk/slf4j-api/src/main/java/org/slf4j/helpers/BasicMarker.java	Thu Jun  5 22:53:19 2008
@@ -1,5 +1,5 @@
 /* 
- * Copyright (c) 2004-2007 QOS.ch
+ * Copyright (c) 2004-2008 QOS.ch
  * All rights reserved.
  * 
  * Permission is hereby granted, free  of charge, to any person obtaining
@@ -49,10 +49,13 @@
 
   private static final long serialVersionUID = 1803952589649545191L;
 
-  final String name;
-  List children;
+  private final String name;
+  private List children;
 
   BasicMarker(String name) {
+    if (name == null) {
+      throw new IllegalArgumentException("A merker name cannot be null");
+    }
     this.name = name;
   }
 
@@ -60,21 +63,25 @@
     return name;
   }
 
-  public synchronized void add(Marker child) {
-    if (child == null) {
-      throw new NullPointerException(
-          "Null children cannot be added to a Marker.");
-    }
-    if (children == null) {
-      children = new Vector();
+  public synchronized void add(Marker markerToAddAsChild) {
+    if (markerToAddAsChild == null) {
+      throw new IllegalArgumentException(
+          "A null value cannot be added to a Marker as child.");
     }
 
     // no point in adding the child multiple times
-    if (children.contains(child)) {
+    if (this.contains(markerToAddAsChild)) {
+      return;
+
+    } else if (markerToAddAsChild.contains(this)) { // avoid recursion
+      // a potential child should not its future parent as a child
       return;
     } else {
-      // add the child
-      children.add(child);
+      // let's add the child
+      if (children == null) {
+        children = new Vector();
+      }
+      children.add(markerToAddAsChild);
     }
 
   }
@@ -155,12 +162,27 @@
   private static String CLOSE = " ]";
   private static String SEP = ", ";
 
-  public String toString() {
 
+  public boolean equals(Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (!(obj instanceof Marker))
+      return false;
+
+    final Marker other = (Marker) obj;
+    return name.equals(other.getName());
+  }
+
+  public int hashCode() {
+    return name.hashCode();
+  }
+
+  public String toString() {
     if (!this.hasChildren()) {
       return this.getName();
     }
-
     Iterator it = this.iterator();
     Marker child;
     StringBuffer sb = new StringBuffer(this.getName());

Modified: slf4j/trunk/slf4j-api/src/main/java/org/slf4j/helpers/BasicMarkerFactory.java
==============================================================================
--- slf4j/trunk/slf4j-api/src/main/java/org/slf4j/helpers/BasicMarkerFactory.java	(original)
+++ slf4j/trunk/slf4j-api/src/main/java/org/slf4j/helpers/BasicMarkerFactory.java	Thu Jun  5 22:53:19 2008
@@ -88,5 +88,12 @@
     }
     return (markerMap.remove(name) != null);
   }
+
+  
+  public Marker getDetachedMarker(String name) {
+    return  new BasicMarker(name);
+  }
+  
+  
   
 }

Modified: slf4j/trunk/slf4j-api/src/test/java/org/slf4j/BasicMarkerTest.java
==============================================================================
--- slf4j/trunk/slf4j-api/src/test/java/org/slf4j/BasicMarkerTest.java	(original)
+++ slf4j/trunk/slf4j-api/src/test/java/org/slf4j/BasicMarkerTest.java	Thu Jun  5 22:53:19 2008
@@ -1,35 +1,27 @@
 /*
- * Copyright (c) 2004-2005 SLF4J.ORG
- * Copyright (c) 2004-2005 QOS.ch
- *
+ * Copyright (c) 2004-2008 QOS.ch
  * All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
+ * 
+ * Permission is hereby granted, free  of charge, to any person obtaining
+ * a  copy  of this  software  and  associated  documentation files  (the
  * "Software"), to  deal in  the Software without  restriction, including
  * without limitation  the rights to  use, copy, modify,  merge, publish,
- * distribute, and/or sell copies of  the Software, and to permit persons
- * to whom  the Software is furnished  to do so, provided  that the above
- * copyright notice(s) and this permission notice appear in all copies of
- * the  Software and  that both  the above  copyright notice(s)  and this
- * permission notice appear in supporting documentation.
- *
+ * distribute,  sublicense, and/or sell  copies of  the Software,  and to
+ * permit persons to whom the Software  is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The  above  copyright  notice  and  this permission  notice  shall  be
+ * included in all copies or substantial portions of the Software.
+ * 
  * THE  SOFTWARE IS  PROVIDED  "AS  IS", WITHOUT  WARRANTY  OF ANY  KIND,
  * EXPRESS OR  IMPLIED, INCLUDING  BUT NOT LIMITED  TO THE  WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR  A PARTICULAR PURPOSE AND NONINFRINGEMENT
- * OF  THIRD PARTY  RIGHTS. IN  NO EVENT  SHALL THE  COPYRIGHT  HOLDER OR
- * HOLDERS  INCLUDED IN  THIS  NOTICE BE  LIABLE  FOR ANY  CLAIM, OR  ANY
- * SPECIAL INDIRECT  OR CONSEQUENTIAL DAMAGES, OR  ANY DAMAGES WHATSOEVER
- * RESULTING FROM LOSS  OF USE, DATA OR PROFITS, WHETHER  IN AN ACTION OF
- * CONTRACT, NEGLIGENCE  OR OTHER TORTIOUS  ACTION, ARISING OUT OF  OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Except as  contained in  this notice, the  name of a  copyright holder
- * shall not be used in advertising or otherwise to promote the sale, use
- * or other dealings in this Software without prior written authorization
- * of the copyright holder.
- *
+ * MERCHANTABILITY,    FITNESS    FOR    A   PARTICULAR    PURPOSE    AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE,  ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
+
 package org.slf4j;
 
 import java.util.Iterator;
@@ -52,7 +44,8 @@
   static final String MULTI_COMP_STR = "MULTI_COMP";
   static final String PARENT_MARKER_STR = "PARENT_MARKER";
   static final String CHILD_MARKER_STR = "CHILD_MARKER";
-  
+  static final String NOT_CONTAINED_MARKER_STR = "NOT_CONTAINED";
+
   final IMarkerFactory factory;
   final Marker blue;
   final Marker red;
@@ -60,6 +53,8 @@
   final Marker comp;
   final Marker multiComp;
 
+  short diff = Differentiator.getDiffentiator();
+  
   public BasicMarkerTest() {
     factory = new BasicMarkerFactory();
 
@@ -119,7 +114,7 @@
     for (int i = 0; i < 10; i++) {
       parent.add(child);
     }
-    
+
     // check that the child was added once and only once
     Iterator iterator = parent.iterator();
     assertTrue(iterator.hasNext());
@@ -147,4 +142,37 @@
     assertFalse(parent.remove(child));
   }
 
+  public void testSelfRecursion() {
+    final String diffPrefix = "NEW_"+diff;
+    final String PARENT_NAME = diffPrefix + PARENT_MARKER_STR;
+    final String NOT_CONTAINED_NAME = diffPrefix + NOT_CONTAINED_MARKER_STR;
+    Marker parent = factory.getMarker(PARENT_NAME);
+    Marker notContained = factory.getMarker(NOT_CONTAINED_NAME);
+    parent.add(parent);
+    assertTrue(parent.contains(parent));
+    assertTrue(parent.contains(PARENT_NAME));
+    assertFalse(parent.contains(notContained));
+    assertFalse(parent.contains(NOT_CONTAINED_MARKER_STR));
+  }
+
+  public void testIndirectRecursion() {
+    final String diffPrefix = "NEW_"+diff;
+    final String PARENT_NAME=diffPrefix+PARENT_MARKER_STR;
+    final String CHILD_NAME=diffPrefix+CHILD_MARKER_STR;
+    final String NOT_CONTAINED_NAME=diffPrefix+NOT_CONTAINED_MARKER_STR;
+
+    Marker parent = factory.getMarker(PARENT_NAME);
+    Marker child = factory.getMarker(CHILD_NAME);
+    Marker notContained = factory.getMarker(NOT_CONTAINED_NAME);
+
+    parent.add(child);
+    child.add(parent);
+    assertTrue(parent.contains(parent));
+    assertTrue(parent.contains(child));
+    assertTrue(parent.contains(PARENT_NAME));
+    assertTrue(parent.contains(CHILD_NAME));
+    assertFalse(parent.contains(notContained));
+    assertFalse(parent.contains(NOT_CONTAINED_MARKER_STR));
+  }
+
 }

Added: slf4j/trunk/slf4j-api/src/test/java/org/slf4j/Differentiator.java
==============================================================================
--- (empty file)
+++ slf4j/trunk/slf4j-api/src/test/java/org/slf4j/Differentiator.java	Thu Jun  5 22:53:19 2008
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2004-2008 QOS.ch
+ * All rights reserved.
+ * 
+ * Permission is hereby granted, free  of charge, to any person obtaining
+ * a  copy  of this  software  and  associated  documentation files  (the
+ * "Software"), to  deal in  the Software without  restriction, including
+ * without limitation  the rights to  use, copy, modify,  merge, publish,
+ * distribute,  sublicense, and/or sell  copies of  the Software,  and to
+ * permit persons to whom the Software  is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The  above  copyright  notice  and  this permission  notice  shall  be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE  SOFTWARE IS  PROVIDED  "AS  IS", WITHOUT  WARRANTY  OF ANY  KIND,
+ * EXPRESS OR  IMPLIED, INCLUDING  BUT NOT LIMITED  TO THE  WARRANTIES OF
+ * MERCHANTABILITY,    FITNESS    FOR    A   PARTICULAR    PURPOSE    AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE,  ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+package org.slf4j;
+
+import java.util.Random;
+
+public class Differentiator {
+
+  static Random random = new Random(System.currentTimeMillis());
+  
+  static public short getDiffentiator() {
+    return (short) random.nextInt(Short.MAX_VALUE);
+  }
+}

Modified: slf4j/trunk/slf4j-site/src/site/pages/compatibility.html
==============================================================================
--- slf4j/trunk/slf4j-site/src/site/pages/compatibility.html	(original)
+++ slf4j/trunk/slf4j-site/src/site/pages/compatibility.html	Thu Jun  5 22:53:19 2008
@@ -66,8 +66,35 @@
       <td>org.slf4j.spi.MDCAdapter</td>
       <td>public void setContextMap(java.util.Map)</td>
     </tr>
-  </table>
 
+    <tr>
+      <td>Error</td>
+      <td>Method 'getDetachedMarker(String)' has been added to an
+      interface
+      </td>
+      <td>org.slf4j.IMarkerFactory</td>
+      <td>public org.slf4j.Marker getDetachedMarker(java.lang.String)</td>
+    </tr>
+
+    <tr class="alt">
+      <td>Info</td>
+      <td>Method 'equals(Object)' has been added to an
+      interface
+      </td>
+      <td>org.slf4j.Marker</td>
+      <td>public boolean equals(java.lang.Object)</td>
+    </tr>
+
+    <tr>
+      <td>info</td>
+      <td>Method 'hashCode()' has been added to an
+      interface
+      </td>
+      <td>org.slf4j.Marker</td>
+      <td>public int hashCode()</td>
+    </tr>
+
+  </table>
 
   <p>The addition of the <code>getCopyOfContextMap()</code> method in
   the <code>MDCAdapter</code> class should only impact users who have
@@ -88,6 +115,18 @@
   <p>Similar reasoning applies to the <code>setContextMap(Map)</code>
   method.</p> 
 
+  <p>The addition of <code>getDetachedMarker(String)</code> method in
+  the <code>org.slf4j.IMarkerFactory</code> should not impact users as
+  the only (known) implementation of this interface ships with SLF4J
+  itself.
+  </p>
+
+  <p>The <code>equals()</code> and <code>hashCode()</code> methods
+  were added to the <code>org.slf4j.Marker</code> interface for
+  documentation purposes. Given that all objects implicitly implement
+  these methods, their addition should theoretically not break
+  existing code. </p>
+
 
   <h3>Other modules</h3>
 

Modified: slf4j/trunk/slf4j-site/src/site/pages/news.html
==============================================================================
--- slf4j/trunk/slf4j-site/src/site/pages/news.html	(original)
+++ slf4j/trunk/slf4j-site/src/site/pages/news.html	Thu Jun  5 22:53:19 2008
@@ -44,6 +44,10 @@
   href="http://bugzilla.slf4j.org/show_bug.cgi?id=85">bug 85</a> as
   reported by Niklas Gustavsson.
   </p>
+  
+  <p>The <em>slf4j-jcl</em> binding now depends on commons-logging
+  version 1.1.1 instead of the older 1.0.4</p>
+
 
   <p>Added a java.util.logging to SLF4J bridge as requested in <a
   href="http://bugzilla.slf4j.org/show_bug.cgi?id=38">bug 38</a> by
@@ -76,11 +80,19 @@
   Anton Tagunov.
   </p>
 
+  <p>Fixed <a href="http://bugzilla.slf4j.org/show_bug.cgi?id=74">bug
+  74</a>, an endless recursion problem in Marker.contains method,
+  reported by Michael Newcomb. Also added he
+  <code>getDetachedMarker</code> method to <code>IMarkerFactor</code>
+  and <code>MarkerFactory</code> classes which was indirectly
+  requested in bug 74.
+  </p>
+
   <p>Added the methods <code>getLevel()</code> and
   <code>getEffectiveLevel()</code> to the <code>Category</code> class
-  in log4j-over-slf4j. This addition was requested in <a
-  href="http://bugzilla.slf4j.org/show_bug.cgi?id=74">bug 74</a> by
-  Michael Newcomb.
+  in log4j-over-slf4j. 
+
+This addition was requested indirectly in 
   </p>
 
   <p>The <a href="migrator.html">SLF4J Migrator</a>



More information about the slf4j-dev mailing list