You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by se...@apache.org on 2010/10/19 09:40:10 UTC

svn commit: r1024148 - in /directory/shared/trunk/ldap/src: main/java/org/apache/directory/shared/ldap/name/RDN.java test/java/org/apache/directory/shared/ldap/name/MultiThreadedTest.java

Author: seelmann
Date: Tue Oct 19 07:40:10 2010
New Revision: 1024148

URL: http://svn.apache.org/viewvc?rev=1024148&view=rev
Log:
Fixed some concurrency issues when calling normalize()

Added:
    directory/shared/trunk/ldap/src/test/java/org/apache/directory/shared/ldap/name/MultiThreadedTest.java
Modified:
    directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/name/RDN.java

Modified: directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/name/RDN.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/name/RDN.java?rev=1024148&r1=1024147&r2=1024148&view=diff
==============================================================================
--- directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/name/RDN.java (original)
+++ directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/name/RDN.java Tue Oct 19 07:40:10 2010
@@ -29,6 +29,7 @@ import java.util.Iterator;
 import java.util.Map;
 import java.util.Set;
 import java.util.TreeSet;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.apache.commons.collections.MultiMap;
 import org.apache.commons.collections.map.MultiValueMap;
@@ -188,7 +189,7 @@ public class RDN implements Cloneable, C
     public static final int EQUAL = 0;
 
     /** A flag used to tell if the RDN has been normalized */
-    private boolean normalized;
+    private final AtomicBoolean normalized = new AtomicBoolean();
 
     /** the schema manager */
     private transient SchemaManager schemaManager;
@@ -217,7 +218,7 @@ public class RDN implements Cloneable, C
         this.schemaManager = schemaManager;
         upName = "";
         normName = "";
-        normalized = false;
+        normalized.set( false );
     }
 
 
@@ -243,12 +244,12 @@ public class RDN implements Cloneable, C
             {
                 this.schemaManager = schemaManager;
                 normalize( schemaManager.getNormalizerMapping() );
-                normalized = true;
+                normalized.set( true );
             }
             else
             {
                 normalize();
-                normalized = false;
+                normalized.set( false );
             }
 
             upName = rdn;
@@ -259,7 +260,7 @@ public class RDN implements Cloneable, C
             upName = "";
             normName = "";
             length = 0;
-            normalized = false;
+            normalized.set( false );
         }
     }
 
@@ -304,12 +305,12 @@ public class RDN implements Cloneable, C
 
         if( schemaManager != null )
         {
-            normalized = true;
+            normalized.set( true );
         }
         else
         {
             // As strange as it seems, the RDN is *not* normalized against the schema at this point
-            normalized = false;
+            normalized.set( false );
         }
     }
 
@@ -353,7 +354,7 @@ public class RDN implements Cloneable, C
         {
             this.schemaManager = schemaManager;
             normalize( schemaManager.getNormalizerMapping() );
-            normalized = true;
+            normalized.set( true );
         }
         else
         {
@@ -361,7 +362,7 @@ public class RDN implements Cloneable, C
             normalize();
 
             // As strange as it seems, the RDN is *not* normalized against the schema at this point
-            normalized = false;
+            normalized.set( false );
         }
     }
 
@@ -394,7 +395,7 @@ public class RDN implements Cloneable, C
         this.length = length;
         this.upName = upName;
         this.normName = normName;
-        normalized = true;
+        normalized.set( true );
     }
 
 
@@ -411,7 +412,7 @@ public class RDN implements Cloneable, C
         this.upName = rdn.getName();
         this.start = rdn.start;
         this.length = rdn.length;
-        normalized = rdn.normalized;
+        normalized.set(rdn.normalized.get());
 
         switch ( rdn.getNbAtavs() )
         {
@@ -520,13 +521,26 @@ public class RDN implements Cloneable, C
      */
     public RDN normalize( Map<String, OidNormalizer> oidsMap ) throws LdapInvalidDnException
     {
-        String savedUpName = getName();
-        DN.rdnOidToName( this, oidsMap );
-        normalize();
-        this.upName = savedUpName;
-        normalized = true;
+        if ( ( oidsMap == null ) || ( oidsMap.isEmpty() ) )
+        {
+            return this;
+        }
 
-        return this;
+        if ( normalized.get() )
+        {
+            return this;
+        }
+
+        synchronized ( this )
+        {
+            String savedUpName = getName();
+            DN.rdnOidToName( this, oidsMap );
+            normalize();
+            this.upName = savedUpName;
+            normalized.set( true );
+    
+            return this;
+        }
     }
 
 
@@ -668,7 +682,7 @@ public class RDN implements Cloneable, C
         upName = "";
         start = -1;
         length = 0;
-        normalized = false;
+        normalized.set( false );
     }
 
 
@@ -1443,7 +1457,7 @@ public class RDN implements Cloneable, C
      */
     public boolean isNormalized()
     {
-        return normalized;
+        return normalized.get();
     }
 
 

Added: directory/shared/trunk/ldap/src/test/java/org/apache/directory/shared/ldap/name/MultiThreadedTest.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/src/test/java/org/apache/directory/shared/ldap/name/MultiThreadedTest.java?rev=1024148&view=auto
==============================================================================
--- directory/shared/trunk/ldap/src/test/java/org/apache/directory/shared/ldap/name/MultiThreadedTest.java (added)
+++ directory/shared/trunk/ldap/src/test/java/org/apache/directory/shared/ldap/name/MultiThreadedTest.java Tue Oct 19 07:40:10 2010
@@ -0,0 +1,157 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  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.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *
+ */
+package org.apache.directory.shared.ldap.name;
+
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.directory.junit.tools.Concurrent;
+import org.apache.directory.junit.tools.ConcurrentJunitRunner;
+import org.apache.directory.junit.tools.MultiThreadedMultiInvoker;
+import org.apache.directory.shared.ldap.exception.LdapInvalidDnException;
+import org.apache.directory.shared.ldap.schema.normalizers.DeepTrimToLowerNormalizer;
+import org.apache.directory.shared.ldap.schema.normalizers.OidNormalizer;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+
+/**
+ * Multi-threaded 
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+@RunWith(ConcurrentJunitRunner.class)
+@Concurrent()
+public class MultiThreadedTest
+{
+    @Rule
+    public MultiThreadedMultiInvoker i = new MultiThreadedMultiInvoker( 100, 1000 );
+
+    private static Map<String, OidNormalizer> oidsMap;
+
+    private static DN referenceDn;
+    private static DN sharedDn;
+    private static RDN referenceRdn;
+    private static RDN sharedRdn;
+    private static AVA referenceAva;
+    private static AVA sharedAva;
+
+
+    @BeforeClass
+    public static void initMapOids() throws LdapInvalidDnException
+    {
+        // Another map where we store OIDs instead of names.
+        oidsMap = new HashMap<String, OidNormalizer>();
+        oidsMap.put( "dc", new OidNormalizer( "0.9.2342.19200300.100.1.25", new DeepTrimToLowerNormalizer() ) );
+        oidsMap.put( "domaincomponent", new OidNormalizer( "0.9.2342.19200300.100.1.25",
+            new DeepTrimToLowerNormalizer() ) );
+        oidsMap.put( "0.9.2342.19200300.100.1.25", new OidNormalizer( "0.9.2342.19200300.100.1.25",
+            new DeepTrimToLowerNormalizer() ) );
+        oidsMap.put( "ou", new OidNormalizer( "2.5.4.11", new DeepTrimToLowerNormalizer() ) );
+        oidsMap.put( "organizationalUnitName", new OidNormalizer( "2.5.4.11", new DeepTrimToLowerNormalizer() ) );
+        oidsMap.put( "2.5.4.11", new OidNormalizer( "2.5.4.11", new DeepTrimToLowerNormalizer() ) );
+
+        referenceDn = new DN( "dc=example,dc=com" );
+        referenceDn.normalize( oidsMap );
+        sharedDn = new DN( "dc=example,dc=com" );
+        sharedDn.normalize( oidsMap );
+
+        referenceRdn = new RDN( "ou=system" );
+        referenceRdn.normalize( oidsMap );
+        sharedRdn = new RDN( "ou=system" );
+        sharedRdn.normalize( oidsMap );
+
+        referenceAva = new AVA( "ou", "2.5.4.11", "System", "system" );
+        referenceAva.normalize();
+        sharedAva = new AVA( "ou", "2.5.4.11", "System", "system" );
+        sharedAva.normalize();
+    }
+
+
+    @Test
+    public void testNormalize() throws Exception
+    {
+        sharedAva.normalize();
+
+        sharedRdn.normalize( oidsMap );
+        assertTrue( sharedRdn.isNormalized() );
+
+        sharedDn.normalize( oidsMap );
+        assertTrue( sharedDn.isNormalized() );
+    }
+
+
+    @Test
+    public void testNormalizeHashCode() throws Exception
+    {
+        sharedAva.normalize();
+        assertEquals( referenceAva.hashCode(), sharedAva.hashCode() );
+
+        sharedRdn.normalize( oidsMap );
+        assertEquals( referenceRdn.hashCode(), sharedRdn.hashCode() );
+
+        sharedDn.normalize( oidsMap );
+        assertEquals( referenceDn.hashCode(), sharedDn.hashCode() );
+    }
+
+
+    @Test
+    public void testNormalizeEquals() throws Exception
+    {
+        sharedAva.normalize();
+        assertEquals( referenceAva, sharedAva );
+        assertTrue( referenceAva.equals( sharedAva ) );
+        assertTrue( sharedAva.equals( referenceAva ) );
+
+        sharedRdn.normalize( oidsMap );
+        assertEquals( referenceRdn, sharedRdn );
+        assertTrue( referenceRdn.equals( sharedRdn ) );
+        assertTrue( sharedRdn.equals( referenceRdn ) );
+
+        sharedDn.normalize( oidsMap );
+        assertEquals( referenceDn, sharedDn );
+        assertTrue( referenceDn.equals( sharedDn ) );
+        assertTrue( sharedDn.equals( referenceDn ) );
+    }
+
+
+    @Test
+    public void testNormalizeCompare() throws Exception
+    {
+        sharedAva.normalize();
+        assertEquals( 0, sharedAva.compareTo( referenceAva ) );
+        assertEquals( 0, referenceAva.compareTo( sharedAva ) );
+
+        sharedRdn.normalize( oidsMap );
+        assertEquals( 0, referenceRdn.compareTo( sharedRdn ) );
+        assertEquals( 0, sharedRdn.compareTo( referenceRdn ) );
+
+        sharedDn.normalize( oidsMap );
+        assertEquals( 0, referenceDn.compareTo( sharedDn ) );
+        assertEquals( 0, sharedDn.compareTo( referenceDn ) );
+    }
+
+}