You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by el...@apache.org on 2008/10/07 13:27:01 UTC

svn commit: r702434 [2/5] - in /directory: apacheds/trunk/ apacheds/trunk/all/ apacheds/trunk/core-entry/src/main/java/org/apache/directory/server/core/entry/ apacheds/trunk/core-integ/src/main/java/org/apache/directory/server/core/integ/state/ apached...

Added: directory/apacheds/trunk/core-integ/src/test/java/org/apache/directory/server/core/jndi/referral/MoveAndRenameReferralIT.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core-integ/src/test/java/org/apache/directory/server/core/jndi/referral/MoveAndRenameReferralIT.java?rev=702434&view=auto
==============================================================================
--- directory/apacheds/trunk/core-integ/src/test/java/org/apache/directory/server/core/jndi/referral/MoveAndRenameReferralIT.java (added)
+++ directory/apacheds/trunk/core-integ/src/test/java/org/apache/directory/server/core/jndi/referral/MoveAndRenameReferralIT.java Tue Oct  7 04:26:55 2008
@@ -0,0 +1,484 @@
+/*
+ *  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.server.core.jndi.referral;
+
+import static org.apache.directory.server.core.integ.IntegrationUtils.getContext;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.naming.NameAlreadyBoundException;
+import javax.naming.NameNotFoundException;
+import javax.naming.NamingException;
+import javax.naming.PartialResultException;
+import javax.naming.ReferralException;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.BasicAttributes;
+import javax.naming.directory.DirContext;
+import javax.naming.ldap.LdapContext;
+
+import org.apache.directory.server.constants.ServerDNConstants;
+import org.apache.directory.server.core.CoreSession;
+import org.apache.directory.server.core.DirectoryService;
+import org.apache.directory.server.core.entry.DefaultServerEntry;
+import org.apache.directory.server.core.entry.ServerEntry;
+import org.apache.directory.server.core.integ.CiRunner;
+import org.apache.directory.server.core.integ.Level;
+import org.apache.directory.server.core.integ.annotations.ApplyLdifs;
+import org.apache.directory.server.core.integ.annotations.CleanupLevel;
+import org.apache.directory.shared.ldap.exception.LdapNamingException;
+import org.apache.directory.shared.ldap.message.ResultCodeEnum;
+import org.apache.directory.shared.ldap.name.LdapDN;
+import org.apache.directory.shared.ldap.name.Rdn;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+
+/**
+ * Tests the referral handling functionality for the Modify operation 
+ * within the server's core.
+ * 
+ * All the tests are described on this page :
+ * http://cwiki.apache.org/confluence/display/DIRxSRVx11/Referral+Handling+Changes
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev: 691179 $
+ */
+@RunWith ( CiRunner.class )
+@CleanupLevel ( Level.CLASS )
+@ApplyLdifs( {
+    // Root
+    "dn: c=WW,ou=system\n" +
+    "objectClass: country\n" +
+    "objectClass: top\n" +
+    "c: WW\n\n" +
+    
+    // Sub-root #1
+    "dn: o=MNN,c=WW,ou=system\n" +
+    "objectClass: organization\n" +
+    "objectClass: top\n" +
+    "o: MNN\n\n" +
+    
+    // Sub-root #2
+    "dn: o=PNN,c=WW,ou=system\n" +
+    "objectClass: organization\n" +
+    "objectClass: top\n" +
+    "o: PNN\n\n" +
+
+    // Referral #1
+    "dn: ou=Roles,o=MNN,c=WW,ou=system\n" +
+    "objectClass: extensibleObject\n" +
+    "objectClass: referral\n" +
+    "objectClass: top\n" +
+    "ou: Roles\n" +
+    "ref: ldap://hostd/ou=Roles,dc=apache,dc=org\n\n" +
+    
+    // Referral #2
+    "dn: ou=People,o=MNN,c=WW,ou=system\n" +
+    "objectClass: extensibleObject\n" +
+    "objectClass: referral\n" +
+    "objectClass: top\n" +
+    "ou: People\n" +
+    "ref: ldap://hostb/OU=People,DC=example,DC=com\n" +
+    "ref: ldap://hostc/OU=People,O=MNN,C=WW\n\n" +
+    
+    // Entry # 1
+    "dn: cn=Alex Karasulu,o=MNN,c=WW,ou=system\n" +
+    "objectClass: person\n" +
+    "objectClass: top\n" +
+    "cn: Alex Karasulu\n" +
+    "sn: akarasulu\n\n" +
+    
+    // Entry # 2
+    "dn: cn=Alex,o=MNN,c=WW,ou=system\n" +
+    "objectClass: person\n" +
+    "objectClass: top\n" +
+    "cn: Alex\n" +
+    "sn: akarasulu\n\n" +
+    
+    // Entry # 3
+    "dn: cn=Emmanuel,o=PNN,c=WW,ou=system\n" +
+    "objectClass: person\n" +
+    "objectClass: top\n" +
+    "cn: Emmanuel\n" +
+    "sn: elecharny\n\n"
+    }
+)
+public class MoveAndRenameReferralIT
+{
+    /** The directory service */
+    public static DirectoryService service;
+
+    /** The Context we are using to inject entries with JNDI */
+    LdapContext MNNCtx;
+    LdapContext PNNCtx;
+    LdapContext WWCtx;
+    
+    /** The entries we are using to do the tests */
+    Attributes userEntry;
+    ServerEntry serverEntry;
+    
+    @Before
+    public void setUp() throws Exception
+    {
+        MNNCtx = getContext( ServerDNConstants.ADMIN_SYSTEM_DN, service, "o=MNN,c=WW,ou=system" );
+        PNNCtx = getContext( ServerDNConstants.ADMIN_SYSTEM_DN, service, "o=PNN,c=WW,ou=system" );
+        WWCtx = getContext( ServerDNConstants.ADMIN_SYSTEM_DN, service, "c=WW,ou=system" );
+
+        // JNDI entry
+        userEntry = new BasicAttributes( "objectClass", "top", true );
+        userEntry.get( "objectClass" ).add( "person" );
+        userEntry.put( "sn", "elecharny" );
+        userEntry.put( "cn", "Emmanuel Lecharny" );
+        
+        // Core API entry
+        LdapDN dn = new LdapDN( "cn=Emmanuel Lecharny, ou=apache, ou=people, o=MNN, c=WW, ou=system" );
+        serverEntry = new DefaultServerEntry( service.getRegistries(), dn );
+
+        serverEntry.put( "ObjectClass", "top", "person" );
+        serverEntry.put( "sn", "elecharny" );
+        serverEntry.put( "cn", "Emmanuel Lecharny" );
+    }
+
+    /**
+     * Test a move and rename of a non existing entry (not a referral), with no referral 
+     * in its ancestor.
+     */
+    @Test
+    public void testMoveAndRenNotExistingSuperiorNoReferralAncestor() throws Exception
+    {
+        try
+        {
+            WWCtx.rename( "cn=Emmanuel Lecharny,o=MNN", "cn=Emmanuel,o=PNN" );
+            fail();
+        }
+        catch ( NameNotFoundException nnfe )
+        {
+            assertTrue( true );
+        }
+    }
+
+    
+    /**
+     * Test a move and rename of an entry having some referral ancestor,
+     * using JNDI throw.
+     */
+    @Test
+    public void testMoveAndRenameSuperiorHasReferralAncestorJNDIThrow() throws Exception
+    {
+        try
+        {
+            MNNCtx.addToEnvironment( DirContext.REFERRAL, "throw" );
+            MNNCtx.rename( "cn=Emmanuel Lecharny,ou=apache,ou=Roles", "cn=Alex,o=PNN,c=WW,ou=system" );
+            fail();
+        }
+        catch ( ReferralException re )
+        {
+            int nbRefs = 0;
+            Set<String> expectedRefs = new HashSet<String>();
+            expectedRefs.add( "ldap://hostd/cn=Emmanuel%20Lecharny,ou=apache,ou=Roles,dc=apache,dc=org" );
+            
+            do 
+            {
+                String ref = (String)re.getReferralInfo();
+                
+                assertTrue( expectedRefs.contains( ref ) );
+                nbRefs ++;
+            }
+            while ( re.skipReferral() );
+            
+            assertEquals( 1, nbRefs );
+        }
+    }
+
+    
+    /**
+     * Test a move and rename of an entry having some referral ancestor,
+     * using JNDI ignore.
+     */
+    @Test
+    public void testMoveAndRenameSuperiorHasReferralAncestorJNDIIgnore() throws Exception
+    {
+        try
+        {
+            MNNCtx.addToEnvironment( DirContext.REFERRAL, "ignore" );
+            MNNCtx.rename( "cn=Emmanuel Lecharny,ou=apache,ou=Roles", "cn=Alex,o=PNN,c=WW,ou=system" );
+            fail();
+        }
+        catch ( PartialResultException pre )
+        {
+            assertTrue( true );
+        }
+    }
+
+    
+    /**
+     * Test a move and rename of an entry having some referral ancestor, 
+     * using the Core API without the ManageDsaIT flag.
+     */
+    @Test
+    public void testMoveAndRenameEntrySuperiorHasReferralAncestorCoreAPIWithoutManageDsaIT() throws Exception
+    {
+        CoreSession coreSession = service.getAdminSession();
+        LdapDN dn = new LdapDN( "cn=Emmanuel Lecharny,ou=apache,ou=Roles,o=MNN,c=WW,ou=system" );
+        LdapDN newParent = new LdapDN( "o=PNN,c=WW,ou=system" );
+        Rdn newRdn = new Rdn( "cn=Alex" );
+        
+        try
+        {
+            coreSession.moveAndRename( dn, newParent, newRdn, false, false );
+            fail();
+        }
+        catch ( ReferralException re )
+        {
+            int nbRefs = 0;
+            Set<String> expectedRefs = new HashSet<String>();
+            expectedRefs.add( "ldap://hostd/cn=Emmanuel%20Lecharny,ou=apache,ou=Roles,dc=apache,dc=org" );
+            
+            do 
+            {
+                String ref = (String)re.getReferralInfo();
+                
+                assertTrue( expectedRefs.contains( ref ) );
+                nbRefs ++;
+            }
+            while ( re.skipReferral() );
+            
+            assertEquals( 1, nbRefs );
+        }
+    }
+
+    
+    /**
+     * Test a move and rename of an entry having some referral ancestor, 
+     * using the Core API with the ManageDsaIT flag
+     */
+    @Test
+    public void testMoveAndRenameSuperiorHasReferralAncestorCoreAPIWithManageDsaIT() throws Exception
+    {
+        CoreSession coreSession = service.getAdminSession();
+        LdapDN dn = new LdapDN( "cn=Emmanuel Lecharny,ou=apache,ou=Roles,o=MNN,c=WW,ou=system" );
+        LdapDN newParent = new LdapDN( "o=PNN,c=WW,ou=system" ); 
+        Rdn newRdn = new Rdn( "cn=Alex" );
+        
+        try
+        {
+            coreSession.moveAndRename( dn, newParent, newRdn, false, true );
+            fail();
+        }
+        catch ( PartialResultException pre )
+        {
+            assertTrue( true );
+        }
+    }
+    
+    
+    /**
+     * Test a move and rename of an existing entry (not a referral), with no referral 
+     * in its ancestor.
+     */
+    @Test
+    public void testMoveAndRenameExistingSuperiorNoReferralAncestor() throws Exception
+    {
+        // First check that the object exists
+        Object moved = MNNCtx.lookup( "cn=Alex" );
+        assertNotNull( moved );
+
+        // and that the target entry is not present
+        try
+        {
+            moved = PNNCtx.lookup( "cn=BugsBunny" );
+            fail();
+        }
+        catch ( NameNotFoundException nnfe )
+        {
+            assertTrue( true );
+        }
+
+        WWCtx.rename( "cn=Alex,o=MNN", "cn=BugsBunny,o=PNN" );
+        
+        // Check that the entry has been moved
+        moved = PNNCtx.lookup( "cn=BugsBunny" );
+        assertNotNull( moved );
+
+        // and that the original entry is not present anymore
+        try
+        {
+            moved = MNNCtx.lookup( "cn=Alex" );
+            fail();
+        }
+        catch ( NameNotFoundException nnfe )
+        {
+            assertTrue( true );
+        }
+    }
+
+    
+    /**
+     * Test a move and rename of an existing entry (not a referral), to an 
+     * entry with a referral in its ancestor
+     */
+    @Test
+    public void testMoveAndRenameExistingToEntryWithReferralAncestor() throws Exception
+    {
+        try
+        {
+            MNNCtx.rename( "cn=Alex", "cn=Emmanuel,ou=Roles" );
+        }
+        catch ( NamingException ne )
+        {
+            assertTrue( true );
+            assertEquals( ResultCodeEnum.AFFECTS_MULTIPLE_DSAS, ((LdapNamingException)ne).getResultCode() );
+        }
+    }
+
+    
+    /**
+     * Test a move and rename of an existing entry (not a referral), to an 
+     * entry which already exists.
+     */
+    @Test
+    public void testMoveAndRenameExistingToAnotherExistingEntry() throws Exception
+    {
+        try
+        {
+            WWCtx.rename( "cn=Alex,o=MNN", "cn=Emmanuel,o=PNN" );
+        }
+        catch ( NameAlreadyBoundException ne )
+        {
+            assertTrue( true );
+        }
+    }
+    /**
+     * Test a move and rename of a referral entry, using JNDI throw.
+     */
+    @Test
+    public void testMoveAndRenameIsReferralJNDIThrow() throws Exception
+    {
+        try
+        {
+            MNNCtx.addToEnvironment( DirContext.REFERRAL, "throw" );
+            MNNCtx.rename( "cn=Emmanuel Lecharny,ou=Roles", "cn=Alex,o=PNN,c=WW,ou=system" );
+            fail();
+        }
+        catch ( ReferralException re )
+        {
+            int nbRefs = 0;
+            Set<String> expectedRefs = new HashSet<String>();
+            expectedRefs.add( "ldap://hostd/cn=Emmanuel%20Lecharny,ou=Roles,dc=apache,dc=org" );
+            
+            do 
+            {
+                String ref = (String)re.getReferralInfo();
+                
+                assertTrue( expectedRefs.contains( ref ) );
+                nbRefs ++;
+            }
+            while ( re.skipReferral() );
+            
+            assertEquals( 1, nbRefs );
+        }
+    }
+
+    
+    /**
+     * Test a move and rename of a referral entry, using JNDI ignore.
+     */
+    @Test
+    public void testMoveAndRenameIsReferralJNDIIgnore() throws Exception
+    {
+        try
+        {
+            MNNCtx.addToEnvironment( DirContext.REFERRAL, "ignore" );
+            MNNCtx.rename( "cn=Emmanuel Lecharny,ou=Roles", "cn=Alex,o=PNN,c=WW,ou=system" );
+            fail();
+        }
+        catch ( PartialResultException pre )
+        {
+            assertTrue( true );
+        }
+    }
+
+    
+    /**
+     * Test a move and rename of a referral entry, using the Core API 
+     * without the ManageDsaIT flag.
+     */
+    @Test
+    public void testMoveAndRenameIsReferralCoreAPIWithoutManageDsaIT() throws Exception
+    {
+        CoreSession coreSession = service.getAdminSession();
+        LdapDN dn = new LdapDN( "cn=Emmanuel Lecharny,ou=Roles,o=MNN,c=WW,ou=system" );
+        LdapDN newParent = new LdapDN( "o=PNN,c=WW,ou=system" );
+        Rdn newRdn = new Rdn( "cn=Alex" );
+        
+        try
+        {
+            coreSession.moveAndRename( dn, newParent, newRdn, false, false );
+            fail();
+        }
+        catch ( ReferralException re )
+        {
+            int nbRefs = 0;
+            Set<String> expectedRefs = new HashSet<String>();
+            expectedRefs.add( "ldap://hostd/cn=Emmanuel%20Lecharny,ou=Roles,dc=apache,dc=org" );
+            
+            do 
+            {
+                String ref = (String)re.getReferralInfo();
+                
+                assertTrue( expectedRefs.contains( ref ) );
+                nbRefs ++;
+            }
+            while ( re.skipReferral() );
+            
+            assertEquals( 1, nbRefs );
+        }
+    }
+
+    
+    /**
+     * Test a move and rename of a referral entry, using the Core API 
+     * with the ManageDsaIT flag
+     */
+    @Test
+    public void testMoveAndRenameIsReferralCoreAPIWithManageDsaIT() throws Exception
+    {
+        CoreSession coreSession = service.getAdminSession();
+        LdapDN dn = new LdapDN( "cn=Emmanuel Lecharny,ou=apache,ou=Roles,o=MNN,c=WW,ou=system" );
+        LdapDN newParent = new LdapDN( "o=PNN,c=WW,ou=system" ); 
+        Rdn newRdn = new Rdn( "cn=Alex" );
+        
+        try
+        {
+            coreSession.moveAndRename( dn, newParent, newRdn, false, true );
+            fail();
+        }
+        catch ( PartialResultException pre )
+        {
+            assertTrue( true );
+        }
+    }
+}

Added: directory/apacheds/trunk/core-integ/src/test/java/org/apache/directory/server/core/jndi/referral/MoveReferralIT.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core-integ/src/test/java/org/apache/directory/server/core/jndi/referral/MoveReferralIT.java?rev=702434&view=auto
==============================================================================
--- directory/apacheds/trunk/core-integ/src/test/java/org/apache/directory/server/core/jndi/referral/MoveReferralIT.java (added)
+++ directory/apacheds/trunk/core-integ/src/test/java/org/apache/directory/server/core/jndi/referral/MoveReferralIT.java Tue Oct  7 04:26:55 2008
@@ -0,0 +1,479 @@
+/*
+ *  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.server.core.jndi.referral;
+
+import static org.apache.directory.server.core.integ.IntegrationUtils.getContext;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.naming.NameNotFoundException;
+import javax.naming.NamingException;
+import javax.naming.PartialResultException;
+import javax.naming.ReferralException;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.BasicAttributes;
+import javax.naming.directory.DirContext;
+import javax.naming.ldap.LdapContext;
+
+import org.apache.directory.server.constants.ServerDNConstants;
+import org.apache.directory.server.core.CoreSession;
+import org.apache.directory.server.core.DirectoryService;
+import org.apache.directory.server.core.entry.DefaultServerEntry;
+import org.apache.directory.server.core.entry.ServerEntry;
+import org.apache.directory.server.core.integ.CiRunner;
+import org.apache.directory.server.core.integ.Level;
+import org.apache.directory.server.core.integ.annotations.ApplyLdifs;
+import org.apache.directory.server.core.integ.annotations.CleanupLevel;
+import org.apache.directory.shared.ldap.exception.LdapNamingException;
+import org.apache.directory.shared.ldap.message.ResultCodeEnum;
+import org.apache.directory.shared.ldap.name.LdapDN;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+
+/**
+ * Tests the referral handling functionality for the Move operation 
+ * within the server's core. (Move is a ModifyDN where the superior is changed)
+ * 
+ * All the tests are described on this page :
+ * http://cwiki.apache.org/confluence/display/DIRxSRVx11/Referral+Handling+Changes
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev: 691179 $
+ */
+@RunWith ( CiRunner.class )
+@CleanupLevel ( Level.CLASS )
+@ApplyLdifs( {
+    // Root
+    "dn: c=WW,ou=system\n" +
+    "objectClass: country\n" +
+    "objectClass: top\n" +
+    "c: WW\n\n" +
+    
+    // Sub-root #1
+    "dn: o=MNN,c=WW,ou=system\n" +
+    "objectClass: organization\n" +
+    "objectClass: top\n" +
+    "o: MNN\n\n" +
+    
+    // Sub-root #2
+    "dn: o=PNN,c=WW,ou=system\n" +
+    "objectClass: organization\n" +
+    "objectClass: top\n" +
+    "o: PNN\n\n" +
+    
+    // Referral #1
+    "dn: ou=Roles,o=MNN,c=WW,ou=system\n" +
+    "objectClass: extensibleObject\n" +
+    "objectClass: referral\n" +
+    "objectClass: top\n" +
+    "ou: Roles\n" +
+    "ref: ldap://hostd/ou=Roles,dc=apache,dc=org\n\n" +
+    
+    // Referral #2
+    "dn: ou=People,o=MNN,c=WW,ou=system\n" +
+    "objectClass: extensibleObject\n" +
+    "objectClass: referral\n" +
+    "objectClass: top\n" +
+    "ou: People\n" +
+    "ref: ldap://hostb/OU=People,DC=example,DC=com\n" +
+    "ref: ldap://hostc/OU=People,O=MNN,C=WW\n\n" +
+    
+    // Entry # 1
+    "dn: cn=Alex Karasulu,o=MNN,c=WW,ou=system\n" +
+    "objectClass: person\n" +
+    "objectClass: top\n" +
+    "cn: Alex Karasulu\n" +
+    "sn: akarasulu\n\n" +
+    
+    // Entry # 2
+    "dn: cn=Alex,o=MNN,c=WW,ou=system\n" +
+    "objectClass: person\n" +
+    "objectClass: top\n" +
+    "cn: Alex\n" +
+    "sn: akarasulu\n\n"
+    }
+)
+public class MoveReferralIT
+{
+    /** The directory service */
+    public static DirectoryService service;
+
+    /** The Contexts we are using to inject entries with JNDI */
+    LdapContext MNNCtx;
+    LdapContext PNNCtx;
+    LdapContext WWCtx;
+    
+    /** The entries we are using to do the tests */
+    Attributes userEntry;
+    ServerEntry serverEntry;
+    
+    @Before
+    public void setUp() throws Exception
+    {
+        MNNCtx = getContext( ServerDNConstants.ADMIN_SYSTEM_DN, service, "o=MNN,c=WW,ou=system" );
+        PNNCtx = getContext( ServerDNConstants.ADMIN_SYSTEM_DN, service, "o=PNN,c=WW,ou=system" );
+        WWCtx = getContext( ServerDNConstants.ADMIN_SYSTEM_DN, service, "c=WW,ou=system" );
+
+        // JNDI entry
+        userEntry = new BasicAttributes( "objectClass", "top", true );
+        userEntry.get( "objectClass" ).add( "person" );
+        userEntry.put( "sn", "elecharny" );
+        userEntry.put( "cn", "Emmanuel Lecharny" );
+        
+        // Core API entry
+        LdapDN dn = new LdapDN( "cn=Emmanuel Lecharny, ou=apache, ou=people, o=MNN, c=WW, ou=system" );
+        serverEntry = new DefaultServerEntry( service.getRegistries(), dn );
+
+        serverEntry.put( "ObjectClass", "top", "person" );
+        serverEntry.put( "sn", "elecharny" );
+        serverEntry.put( "cn", "Emmanuel Lecharny" );
+    }
+
+    
+    /**
+     * Test a move of a non existing entry (not a referral), with no referral 
+     * in its ancestor.
+     */
+    @Test
+    public void testMoveNotExistingSuperiorNoReferralAncestor() throws Exception
+    {
+        try
+        {
+            WWCtx.rename( "cn=Emmanuel Lecharny,o=MNN", "cn=Emmanuel Lecharny,o=PNN" );
+            fail();
+        }
+        catch ( NameNotFoundException nnfe )
+        {
+            assertTrue( true );
+        }
+    }
+    
+    
+    /**
+     * Test a move of a non existing entry having some referral ancestor in its ancestor,
+     * using JNDI throw.
+     */
+    @Test
+    public void testMoveNotExistingSuperiorReferralAncestorJNDIThrow() throws Exception
+    {
+        try
+        {
+            MNNCtx.addToEnvironment( DirContext.REFERRAL, "throw" );
+            MNNCtx.rename( "cn=Emmanuel Lecharny,ou=Roles", "cn=Emmanuel Lecharny,o=PNN,c=WW,ou=system" );
+            fail();
+        }
+        catch ( ReferralException re )
+        {
+            int nbRefs = 0;
+            Set<String> expectedRefs = new HashSet<String>();
+            expectedRefs.add( "ldap://hostd/cn=Emmanuel%20Lecharny,ou=Roles,dc=apache,dc=org" );
+            
+            do 
+            {
+                String ref = (String)re.getReferralInfo();
+                
+                assertTrue( expectedRefs.contains( ref ) );
+                nbRefs ++;
+            }
+            while ( re.skipReferral() );
+            
+            assertEquals( 1, nbRefs );
+        }
+    }
+    
+    
+    /**
+     * Test a move of a non existing entry having some referral ancestor in its ancestor,
+     * using JNDI ignore.
+     */
+    @Test
+    public void testMoveNotExistingSuperiorReferralAncestorJNDIIgnore() throws Exception
+    {
+        try
+        {
+            MNNCtx.addToEnvironment( DirContext.REFERRAL, "ignore" );
+            MNNCtx.rename( "cn=Emmanuel Lecharny,ou=Roles", "cn=Emmanuel Lecharny,o=PNN,c=WW,ou=system" );
+            fail();
+        }
+        catch ( PartialResultException re )
+        {
+            assertTrue( true );
+        }
+    }
+    
+    
+    /**
+     * Test a move of a non existing entry having some referral ancestor in its ancestor,
+     * using the Core API without ManageDsaIt flag
+     */
+    @Test
+    public void testMoveNotExistingSuperiorReferralAncestorCoreAPIWithoutManageDsaIt() throws Exception
+    {
+        CoreSession coreSession = service.getAdminSession();
+        LdapDN dn = new LdapDN( "cn=Emmanuel Lecharny,ou=Roles,o=MNN,c=WW,ou=system" );
+        LdapDN newParent = new LdapDN( "cn=Emmanuel Lecharny,o=PNN,c=WW,ou=system" ); 
+        
+        try
+        {
+            coreSession.move( dn, newParent, false );
+            fail();
+        }
+        catch ( ReferralException re )
+        {
+            int nbRefs = 0;
+            Set<String> expectedRefs = new HashSet<String>();
+            expectedRefs.add( "ldap://hostd/cn=Emmanuel%20Lecharny,ou=Roles,dc=apache,dc=org" );
+            
+            do 
+            {
+                String ref = (String)re.getReferralInfo();
+                
+                assertTrue( expectedRefs.contains( ref ) );
+                nbRefs ++;
+            }
+            while ( re.skipReferral() );
+            
+            assertEquals( 1, nbRefs );
+        }
+    }
+    
+    
+    /**
+     * Test a move of a non existing entry having some referral ancestor in its ancestor,
+     * using the Core API with ManageDsaIt flag
+     */
+    @Test
+    public void testMoveNotExistingSuperiorReferralAncestorCoreAPIWithManageDsaIt() throws Exception
+    {
+        CoreSession coreSession = service.getAdminSession();
+        LdapDN dn = new LdapDN( "cn=Emmanuel Lecharny,ou=Roles,o=MNN,c=WW,ou=system" );
+        LdapDN newParent = new LdapDN( "cn=Emmanuel Lecharny,o=PNN,c=WW,ou=system" ); 
+        
+        try
+        {
+            coreSession.move( dn, newParent, true );
+            fail();
+        }
+        catch ( PartialResultException re )
+        {
+            assertTrue( true );
+        }
+    }
+
+    
+    /**
+     * Test a move of an existing entry (not a referral), with no referral 
+     * in its ancestor.
+     */
+    @Test
+    public void testMoveExistingSuperiorNoReferralAncestor() throws Exception
+    {
+        // First check that the object exists
+        Object moved = MNNCtx.lookup( "cn=Alex" );
+        assertNotNull( moved );
+
+        // and that the target entry is not present
+        try
+        {
+            moved = PNNCtx.lookup( "cn=Alex" );
+            fail();
+        }
+        catch ( NameNotFoundException nnfe )
+        {
+            assertTrue( true );
+        }
+
+        WWCtx.rename( "cn=Alex,o=MNN", "cn=Alex,o=PNN" );
+        
+        // Check that the entry has been moved
+        moved = PNNCtx.lookup( "cn=Alex" );
+        assertNotNull( moved );
+
+        // and that the original entry is not present anymore
+        try
+        {
+            moved = MNNCtx.lookup( "cn=Alex" );
+            fail();
+        }
+        catch ( NameNotFoundException nnfe )
+        {
+            assertTrue( true );
+        }
+    }
+
+    
+    /**
+     * Test a move of an existing entry (not a referral), to a new superior
+     * being a referral
+     */
+    @Test
+    public void testMoveExistingSuperiorIsReferral() throws Exception
+    {
+        try
+        {
+            MNNCtx.rename( "cn=Alex", "cn=Alex,ou=Roles" );
+            fail();
+        }
+        catch ( NamingException ne )
+        {
+            assertTrue( true );
+            assertEquals( ResultCodeEnum.AFFECTS_MULTIPLE_DSAS, ((LdapNamingException)ne).getResultCode() );
+        }
+    }
+
+    
+    /**
+     * Test a move of an existing entry (not a referral), to a new superior
+     * having a referral ancestor
+     */
+    @Test
+    public void testMoveExistingSuperiorHasReferralAncestor() throws Exception
+    {
+        try
+        {
+            MNNCtx.rename( "cn=Alex", "cn=Alex,ou=apache,ou=Roles" );
+            fail();
+        }
+        catch ( NamingException ne )
+        {
+            assertTrue( true );
+            assertEquals( ResultCodeEnum.AFFECTS_MULTIPLE_DSAS, ((LdapNamingException)ne).getResultCode() );
+        }
+    }
+
+    
+    /**
+     * Test a move of an existing entry with a referral in its ancestot, 
+     * to a new superior, using JNDI throw
+     */
+    @Test
+    public void testMoveEntryWithReferralAncestorJNDIThrow() throws Exception
+    {
+        try
+        {
+            MNNCtx.addToEnvironment( DirContext.REFERRAL, "throw" );
+            MNNCtx.rename( "cn=Alex,ou=roles", "cn=Alex,ou=People" );
+            fail();
+        }
+        catch ( ReferralException re )
+        {
+            int nbRefs = 0;
+            Set<String> expectedRefs = new HashSet<String>();
+            expectedRefs.add( "ldap://hostd/cn=Alex,ou=Roles,dc=apache,dc=org" );
+            
+            do 
+            {
+                String ref = (String)re.getReferralInfo();
+                
+                assertTrue( expectedRefs.contains( ref ) );
+                nbRefs ++;
+            }
+            while ( re.skipReferral() );
+            
+            assertEquals( 1, nbRefs );
+        }
+    }
+
+    
+    /**
+     * Test a move of an existing entry with a referral in its ancestot, 
+     * to a new superior, using JNDI ignore
+     */
+    @Test
+    public void testMoveEntryWithReferralAncestorJNDIIgnore() throws Exception
+    {
+        try
+        {
+            MNNCtx.addToEnvironment( DirContext.REFERRAL, "ignore" );
+            MNNCtx.rename( "cn=Alex,ou=roles", "cn=Alex,ou=People" );
+            fail();
+        }
+        catch ( PartialResultException pre )
+        {
+            assertTrue( true );
+        }
+    }
+
+    
+    /**
+     * Test a move of an existing entry with a referral in its ancestot, 
+     * to a new superior, using CoreAPI without the ManageDsaIT flag
+     */
+    @Test
+    public void testMoveEntryWithReferralAncestorCoreAPIWithoutManageDsaIt() throws Exception
+    {
+        CoreSession coreSession = service.getAdminSession();
+        LdapDN orig = new LdapDN( "cn=Alex,ou=roles,o=MNN,c=WW,ou=system" );
+        LdapDN dest = new LdapDN( "cn=Alex,ou=People,o=MNN,c=WW,ou=system" );
+        
+        try
+        {
+            coreSession.move( orig, dest, false );
+            fail();
+        }
+        catch ( ReferralException re )
+        {
+            int nbRefs = 0;
+            Set<String> expectedRefs = new HashSet<String>();
+            expectedRefs.add( "ldap://hostd/cn=Alex,ou=Roles,dc=apache,dc=org" );
+            
+            do 
+            {
+                String ref = (String)re.getReferralInfo();
+                
+                assertTrue( expectedRefs.contains( ref ) );
+                nbRefs ++;
+            }
+            while ( re.skipReferral() );
+            
+            assertEquals( 1, nbRefs );
+        }
+    }
+
+
+    /**
+     * Test a move of an existing entry with a referral in its ancestot, 
+     * to a new superior, using CoreAPI with the ManageDsaIT flag
+     */
+    @Test
+    public void testMoveEntryWithReferralAncestorCoreAPIWithManageDsaIt() throws Exception
+    {
+        CoreSession coreSession = service.getAdminSession();
+        LdapDN orig = new LdapDN( "cn=Alex,ou=roles,o=MNN,c=WW,ou=system" );
+        LdapDN dest = new LdapDN( "cn=Alex,ou=People,o=MNN,c=WW,ou=system" );
+        
+        try
+        {
+            coreSession.move( orig, dest, true );
+            fail();
+        }
+        catch ( PartialResultException pre )
+        {
+            assertTrue( true );
+        }
+    }
+}

Added: directory/apacheds/trunk/core-integ/src/test/java/org/apache/directory/server/core/jndi/referral/RenameReferralIT.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core-integ/src/test/java/org/apache/directory/server/core/jndi/referral/RenameReferralIT.java?rev=702434&view=auto
==============================================================================
--- directory/apacheds/trunk/core-integ/src/test/java/org/apache/directory/server/core/jndi/referral/RenameReferralIT.java (added)
+++ directory/apacheds/trunk/core-integ/src/test/java/org/apache/directory/server/core/jndi/referral/RenameReferralIT.java Tue Oct  7 04:26:55 2008
@@ -0,0 +1,612 @@
+/*
+ *  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.server.core.jndi.referral;
+
+import static org.apache.directory.server.core.integ.IntegrationUtils.getContext;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.naming.NameAlreadyBoundException;
+import javax.naming.NameNotFoundException;
+import javax.naming.PartialResultException;
+import javax.naming.ReferralException;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.BasicAttributes;
+import javax.naming.directory.DirContext;
+import javax.naming.ldap.LdapContext;
+
+import org.apache.directory.server.constants.ServerDNConstants;
+import org.apache.directory.server.core.CoreSession;
+import org.apache.directory.server.core.DirectoryService;
+import org.apache.directory.server.core.entry.DefaultServerEntry;
+import org.apache.directory.server.core.entry.ServerEntry;
+import org.apache.directory.server.core.integ.CiRunner;
+import org.apache.directory.server.core.integ.Level;
+import org.apache.directory.server.core.integ.annotations.ApplyLdifs;
+import org.apache.directory.server.core.integ.annotations.CleanupLevel;
+import org.apache.directory.shared.ldap.name.LdapDN;
+import org.apache.directory.shared.ldap.name.Rdn;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+
+/**
+ * Tests the referral handling functionality for the Modify operation 
+ * within the server's core.
+ * 
+ * The Move operation is a ModifyDN where the RDN is changed, not the superior.
+ * 
+ * All the tests are described on this page :
+ * http://cwiki.apache.org/confluence/display/DIRxSRVx11/Referral+Handling+Changes
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev: 691179 $
+ */
+@RunWith ( CiRunner.class )
+@CleanupLevel ( Level.CLASS )
+@ApplyLdifs( {
+    // Root
+    "dn: c=WW,ou=system\n" +
+    "objectClass: country\n" +
+    "objectClass: top\n" +
+    "c: WW\n\n" +
+    
+    // Sub-root
+    "dn: o=MNN,c=WW,ou=system\n" +
+    "objectClass: organization\n" +
+    "objectClass: top\n" +
+    "o: MNN\n\n" +
+    
+    // Another Sub-root
+    "dn: o=PNN,c=WW,ou=system\n" +
+    "objectClass: organization\n" +
+    "objectClass: top\n" +
+    "o: MNN\n\n" +
+    
+    // Referral #1
+    "dn: ou=Roles,o=MNN,c=WW,ou=system\n" +
+    "objectClass: extensibleObject\n" +
+    "objectClass: referral\n" +
+    "objectClass: top\n" +
+    "ou: Roles\n" +
+    "ref: ldap://hostd/ou=Roles,dc=apache,dc=org\n\n" +
+    
+    // Referral #2
+    "dn: ou=People,o=MNN,c=WW,ou=system\n" +
+    "objectClass: extensibleObject\n" +
+    "objectClass: referral\n" +
+    "objectClass: top\n" +
+    "ou: People\n" +
+    "ref: ldap://hostb/OU=People,DC=example,DC=com\n" +
+    "ref: ldap://hostc/OU=People,O=MNN,C=WW\n\n" +
+    
+    // Entry # 1
+    "dn: cn=Alex Karasulu,o=MNN,c=WW,ou=system\n" +
+    "objectClass: person\n" +
+    "objectClass: top\n" +
+    "cn: Alex Karasulu\n" +
+    "sn: akarasulu\n\n" +
+    
+    // Entry # 2
+    "dn: cn=Alex,o=MNN,c=WW,ou=system\n" +
+    "objectClass: person\n" +
+    "objectClass: top\n" +
+    "cn: Alex\n" +
+    "sn: akarasulu\n\n"
+    }
+)
+public class RenameReferralIT
+{
+    /** The directory service */
+    public static DirectoryService service;
+
+    /** The Context we are using to inject entries with JNDI */
+    LdapContext MNNCtx;
+    
+    /** The entries we are using to do the tests */
+    Attributes userEntry;
+    ServerEntry serverEntry;
+    
+    @Before
+    public void setUp() throws Exception
+    {
+        MNNCtx = getContext( ServerDNConstants.ADMIN_SYSTEM_DN, service, "o=MNN,c=WW,ou=system" );
+
+        // JNDI entry
+        userEntry = new BasicAttributes( "objectClass", "top", true );
+        userEntry.get( "objectClass" ).add( "person" );
+        userEntry.put( "sn", "elecharny" );
+        userEntry.put( "cn", "Emmanuel Lecharny" );
+        
+        // Core API entry
+        LdapDN dn = new LdapDN( "cn=Emmanuel Lecharny, ou=apache, ou=people, o=MNN, c=WW, ou=system" );
+        serverEntry = new DefaultServerEntry( service.getRegistries(), dn );
+
+        serverEntry.put( "ObjectClass", "top", "person" );
+        serverEntry.put( "sn", "elecharny" );
+        serverEntry.put( "cn", "Emmanuel Lecharny" );
+    }
+
+    
+    /**
+     * Test a rename of a non existing entry (not a referral), with no referral 
+     * in its ancestor.
+     */
+    @Test
+    public void testRenameNotExistingSuperiorNoReferralAncestor() throws Exception
+    {
+        try
+        {
+            MNNCtx.rename( "cn=Emmanuel Lecharny", "cn=Alex Karasulu" );
+            fail();
+        }
+        catch ( NameNotFoundException nnfe )
+        {
+            assertTrue( true );
+        }
+    }
+
+
+    /**
+     * Test a rename of a non existing entry (not a referral), with a referral 
+     * in its ancestor, using JNDI throw.
+     */
+    @Test
+    public void testRenameNotExistingSuperiorReferralAncestorJNDIThrow() throws Exception
+    {
+        try
+        {
+            MNNCtx.addToEnvironment( DirContext.REFERRAL, "throw" );
+            MNNCtx.rename( "cn=Emmanuel Lecharny,ou=apache,ou=roles", "cn=Alex Karasulu,ou=apache,ou=roles" );
+            fail();
+        }
+        catch ( ReferralException re )
+        {
+            int nbRefs = 0;
+            Set<String> expectedRefs = new HashSet<String>();
+            expectedRefs.add( "ldap://hostd/cn=Emmanuel%20Lecharny,ou=apache,ou=Roles,dc=apache,dc=org" );
+            
+            do 
+            {
+                String ref = (String)re.getReferralInfo();
+                
+                assertTrue( expectedRefs.contains( ref ) );
+                nbRefs ++;
+            }
+            while ( re.skipReferral() );
+            
+            assertEquals( 1, nbRefs );
+        }
+    }
+
+
+    /**
+     * Test a rename of a non existing entry (not a referral), with a referral 
+     * in its ancestor, using JNDI ignore.
+     */
+    @Test
+    public void testRenameNotExistingSuperiorReferralAncestorJNDIIgnore() throws Exception
+    {
+        try
+        {
+            MNNCtx.addToEnvironment( DirContext.REFERRAL, "ignore" );
+            MNNCtx.rename( "cn=Emmanuel Lecharny,ou=apache,ou=roles", "cn=Alex Karasulu,ou=apache,ou=roles" );
+            fail();
+        }
+        catch ( PartialResultException pre )
+        {
+            assertTrue( true );
+        }
+    }
+
+
+    /**
+     * Test a rename of a non existing entry (not a referral), with a referral 
+     * in its ancestor, using the Core API without the ManageDsaIT flag.
+     */
+    @Test
+    public void testRenameNotExistingSuperiorReferralAncestorCoreAPIWithoutManageDsaIt() throws Exception
+    {
+        CoreSession session = service.getAdminSession();
+
+        try
+        {
+            LdapDN dn = new LdapDN( "cn=Emmanuel Lecharny,ou=apache,ou=roles,o=MNN,c=WW,ou=system" );
+            Rdn newRdn = new Rdn( "cn=Alex Karasulu" );
+            session.rename( dn, newRdn, false, false );
+            fail();
+        }
+        catch ( ReferralException re )
+        {
+            int nbRefs = 0;
+            Set<String> expectedRefs = new HashSet<String>();
+            expectedRefs.add( "ldap://hostd/cn=Emmanuel%20Lecharny,ou=apache,ou=Roles,dc=apache,dc=org" );
+            
+            do 
+            {
+                String ref = (String)re.getReferralInfo();
+                
+                assertTrue( expectedRefs.contains( ref ) );
+                nbRefs ++;
+            }
+            while ( re.skipReferral() );
+            
+            assertEquals( 1, nbRefs );
+        }
+    }
+
+
+    /**
+     * Test a rename of a non existing entry (not a referral), with a referral 
+     * in its ancestor, using the Core API with the ManageDsaIT flag.
+     */
+    @Test
+    public void testRenameNotExistingSuperiorReferralAncestorCoreAPIWithManageDsaIt() throws Exception
+    {
+        CoreSession session = service.getAdminSession();
+        try
+        {
+            LdapDN dn = new LdapDN( "cn=Emmanuel Lecharny,ou=apache,ou=roles,o=MNN,c=WW,ou=system" );
+            Rdn newRdn = new Rdn( "cn=Alex Karasulu" );
+            session.rename( dn, newRdn, false, true );
+            fail();
+        }
+        catch ( PartialResultException pre )
+        {
+            assertTrue( true );
+        }
+    }
+
+
+    /**
+     * Test a rename of an existing entry (not a referral), with no referral 
+     * in its ancestor.
+     */
+    @Test
+    public void testRenameExistingSuperiorNotExistingNewRdnNoReferralAncestor() throws Exception
+    {
+        // First check that the object exists
+        Object renamed = MNNCtx.lookup( "cn=Alex Karasulu" );
+        assertNotNull( renamed );
+
+        // and that the target entry is not present
+        try
+        {
+            renamed = MNNCtx.lookup( "cn=Emmanuel Lecharny" );
+            fail();
+        }
+        catch ( NameNotFoundException nnfe )
+        {
+            assertTrue( true );
+        }
+
+        // Rename it
+        MNNCtx.rename( "cn=Alex Karasulu", "cn=Emmanuel Lecharny" );
+        
+        // It should not be there anymore
+        try
+        {
+            renamed = MNNCtx.lookup( "cn=Alex Karasulu" );
+            fail();
+        }
+        catch ( NameNotFoundException nnfe )
+        {
+            assertTrue( true );
+        }
+
+        // But the new one should be there
+        renamed = MNNCtx.lookup( "cn=Emmanuel Lecharny" );
+        assertNotNull( renamed );
+    }
+
+
+    /**
+     * Test a rename of an existing referral, using JNDI throw. 
+     */
+    @Test
+    public void testRenameExistingReferralJNDIThrow() throws Exception
+    {
+        try
+        {
+            MNNCtx.addToEnvironment( DirContext.REFERRAL, "throw" );
+            MNNCtx.rename( "ou=roles", "cn=Alex Karasulu" );
+            fail();
+        }
+        catch ( ReferralException re )
+        {
+            int nbRefs = 0;
+            Set<String> expectedRefs = new HashSet<String>();
+            expectedRefs.add( "ldap://hostd/ou=Roles,dc=apache,dc=org" );
+            
+            do 
+            {
+                String ref = (String)re.getReferralInfo();
+                
+                assertTrue( expectedRefs.contains( ref ) );
+                nbRefs ++;
+            }
+            while ( re.skipReferral() );
+            
+            assertEquals( 1, nbRefs );
+        }
+    }
+
+
+    /**
+     * Test a rename of an existing referral, using JNDI ignore. 
+     */
+    @Test
+    public void testRenameExistingReferralJNDIIgnore() throws Exception
+    {
+        MNNCtx.addToEnvironment( DirContext.REFERRAL, "ignore" );
+
+        // First check that the object exists
+        Object renamed = MNNCtx.lookup( "ou=Roles" );
+        assertNotNull( renamed );
+
+        // Also check that the new entry does not exist
+        try
+        {
+            renamed = MNNCtx.lookup( "ou=Groups" );
+            fail();
+        }
+        catch ( NameNotFoundException nnfe )
+        {
+            assertTrue( true );
+        }
+        
+        // Now renames the referral
+        MNNCtx.rename( "ou=roles", "ou=groups" );
+
+        // It should not be there anymore
+        try
+        {
+            renamed = MNNCtx.lookup( "ou=Roles" );
+            fail();
+        }
+        catch ( NameNotFoundException nnfe )
+        {
+            assertTrue( true );
+        }
+
+        // But the new one should be there
+        renamed = MNNCtx.lookup( "ou=groups" );
+        assertNotNull( renamed );
+    }
+
+
+    /**
+     * Test a rename of an existing referral, using the Core API without 
+     * the ManageDsaIt flag. 
+     */
+    @Test
+    public void testRenameExistingReferralCoreApiWithoutManageDsaIt() throws Exception
+    {
+        CoreSession session = service.getAdminSession();
+
+        try
+        {
+            LdapDN dn = new LdapDN( "ou=roles,o=MNN,c=WW,ou=system" );
+            Rdn newRdn = new Rdn( "cn=Alex Karasulu" );
+            session.rename( dn, newRdn, false, false );
+            fail();
+        }
+        catch ( ReferralException re )
+        {
+            int nbRefs = 0;
+            Set<String> expectedRefs = new HashSet<String>();
+            expectedRefs.add( "ldap://hostd/ou=Roles,dc=apache,dc=org" );
+            
+            do 
+            {
+                String ref = (String)re.getReferralInfo();
+                
+                assertTrue( expectedRefs.contains( ref ) );
+                nbRefs ++;
+            }
+            while ( re.skipReferral() );
+            
+            assertEquals( 1, nbRefs );
+        }
+    }
+
+
+    /**
+     * Test a rename of an existing referral,  using the Core API with
+     * the ManageDsaIt flag.  
+     */
+    @Test
+    public void testRenameExistingReferralCoreAPIWithManageDsaIt() throws Exception
+    {
+        CoreSession session = service.getAdminSession();
+        LdapDN dnRoles = new LdapDN( "ou=Roles,o=MNN,c=WW,ou=system" );
+        LdapDN dnGroups = new LdapDN( "ou=Groups,o=MNN,c=WW,ou=system" );
+        Rdn newRdn = new Rdn( "ou=Groups" );
+
+        // First check that the object exists
+        ServerEntry renamed = session.lookup( dnRoles );
+        assertNotNull( renamed );
+
+        // Also check that the new entry does not exist
+        try
+        {
+            renamed = session.lookup( dnGroups );
+            fail();
+        }
+        catch ( NameNotFoundException nnfe )
+        {
+            assertTrue( true );
+        }
+        
+        // Now renames the referral
+        session.rename( dnRoles, newRdn, false, true );
+
+        // It should not be there anymore
+        try
+        {
+            renamed = session.lookup( dnRoles );
+            fail();
+        }
+        catch ( NameNotFoundException nnfe )
+        {
+            assertTrue( true );
+        }
+
+        // But the new one should be there
+        renamed = session.lookup( dnGroups );
+        assertNotNull( renamed );
+    }
+
+
+    /**
+     * Test a rename an entry using an already existing RDN (the new entry already exists), not a referral
+     */
+    @Test
+    public void testRenameRdnExistNotReferral() throws Exception
+    {
+        try
+        {
+            MNNCtx.rename( "cn=Alex Karasulu", "cn=Alex" );
+            fail();
+        }
+        catch ( NameAlreadyBoundException nabe )
+        {
+            assertTrue( true );
+        }
+    }
+
+
+    /**
+     * Test a rename a referral using an already existing RDN (the new entry already exists and is a referral),
+     * using JNDI throw
+     */
+    @Test
+    public void testRenameRdnExistIsReferralJNDIThrow() throws Exception
+    {
+        try
+        {
+            MNNCtx.addToEnvironment( DirContext.REFERRAL, "throw" );
+            MNNCtx.rename( "ou=Roles", "ou=People" );
+            fail();
+        }
+        catch ( ReferralException re )
+        {
+            int nbRefs = 0;
+            Set<String> expectedRefs = new HashSet<String>();
+            expectedRefs.add( "ldap://hostd/ou=Roles,dc=apache,dc=org" );
+            
+            do 
+            {
+                String ref = (String)re.getReferralInfo();
+                
+                assertTrue( expectedRefs.contains( ref ) );
+                nbRefs ++;
+            }
+            while ( re.skipReferral() );
+            
+            assertEquals( 1, nbRefs );
+        }
+    }
+
+
+    /**
+     * Test a rename a referral using an already existing RDN (the new entry already exists and is a referral),
+     * using JNDI ignore
+     */
+    @Test
+    public void testRenameRdnExistIsReferralJNDIIgnore() throws Exception
+    {
+        try
+        {
+            MNNCtx.addToEnvironment( DirContext.REFERRAL, "ignore" );
+            MNNCtx.rename( "ou=Roles", "ou=People" );
+            fail();
+        }
+        catch ( NameAlreadyBoundException nabe )
+        {
+            assertTrue( true );
+        }
+    }
+
+
+    /**
+     * Test a rename a referral using an already existing RDN (the new entry already exists and is a referral),
+     * using the Core API, without the ManageDsaIt flag
+     */
+    @Test
+    public void testRenameRdnExistIsReferralCoreAPIWithoutManageDsaIt() throws Exception
+    {
+        CoreSession session = service.getAdminSession();
+        LdapDN dn = new LdapDN( "ou=Roles,o=MNN,c=WW,ou=system" );
+        Rdn newRdn = new Rdn( "ou=People" );
+
+        try
+        {
+            session.rename( dn, newRdn, false, false );
+            fail();
+        }
+        catch ( ReferralException re )
+        {
+            int nbRefs = 0;
+            Set<String> expectedRefs = new HashSet<String>();
+            expectedRefs.add( "ldap://hostd/ou=Roles,dc=apache,dc=org" );
+            
+            do 
+            {
+                String ref = (String)re.getReferralInfo();
+                
+                assertTrue( expectedRefs.contains( ref ) );
+                nbRefs ++;
+            }
+            while ( re.skipReferral() );
+            
+            assertEquals( 1, nbRefs );
+        }
+    }
+
+
+    /**
+     * Test a rename a referral using an already existing RDN (the new entry already exists and is a referral),
+     * using the Core API, with the ManageDsaIt flag
+     */
+    @Test
+    public void testRenameRdnExistIsReferralCoreAPIWithManageDsaIt() throws Exception
+    {
+        CoreSession session = service.getAdminSession();
+        LdapDN dn = new LdapDN( "ou=Roles,o=MNN,c=WW,ou=system" );
+        Rdn newRdn = new Rdn( "ou=People" );
+
+        try
+        {
+            session.rename( dn, newRdn, false, true );
+            fail();
+        }
+        catch ( NameAlreadyBoundException nabe )
+        {
+            assertTrue( true );
+        }
+    }
+}

Added: directory/apacheds/trunk/core-integ/src/test/java/org/apache/directory/server/core/jndi/referral/SearchReferralIT.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core-integ/src/test/java/org/apache/directory/server/core/jndi/referral/SearchReferralIT.java?rev=702434&view=auto
==============================================================================
--- directory/apacheds/trunk/core-integ/src/test/java/org/apache/directory/server/core/jndi/referral/SearchReferralIT.java (added)
+++ directory/apacheds/trunk/core-integ/src/test/java/org/apache/directory/server/core/jndi/referral/SearchReferralIT.java Tue Oct  7 04:26:55 2008
@@ -0,0 +1,447 @@
+/*
+ *  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.server.core.jndi.referral;
+
+import static org.apache.directory.server.core.integ.IntegrationUtils.getContext;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.naming.NameNotFoundException;
+import javax.naming.NamingEnumeration;
+import javax.naming.PartialResultException;
+import javax.naming.ReferralException;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.BasicAttributes;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.SearchControls;
+import javax.naming.directory.SearchResult;
+import javax.naming.ldap.LdapContext;
+
+import org.apache.directory.server.constants.ServerDNConstants;
+import org.apache.directory.server.core.CoreSession;
+import org.apache.directory.server.core.DirectoryService;
+import org.apache.directory.server.core.entry.DefaultServerEntry;
+import org.apache.directory.server.core.entry.ServerEntry;
+import org.apache.directory.server.core.filtering.EntryFilteringCursor;
+import org.apache.directory.server.core.integ.CiRunner;
+import org.apache.directory.server.core.integ.Level;
+import org.apache.directory.server.core.integ.annotations.ApplyLdifs;
+import org.apache.directory.server.core.integ.annotations.CleanupLevel;
+import org.apache.directory.shared.ldap.entry.Entry;
+import org.apache.directory.shared.ldap.name.LdapDN;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+
+/**
+ * Tests the referral handling functionality for the Search operation 
+ * within the server's core.
+ * 
+ * All the tests are described on this page :
+ * http://cwiki.apache.org/confluence/display/DIRxSRVx11/Referral+Handling+Changes
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev: 691179 $
+ */
+@RunWith ( CiRunner.class )
+@CleanupLevel ( Level.CLASS )
+@ApplyLdifs( {
+    // Root
+    "dn: c=WW,ou=system\n" +
+    "objectClass: country\n" +
+    "objectClass: top\n" +
+    "c: WW\n\n" +
+    
+    // Sub-root
+    "dn: o=MNN,c=WW,ou=system\n" +
+    "objectClass: organization\n" +
+    "objectClass: top\n" +
+    "o: MNN\n\n" +
+    
+    // Another Sub-root
+    "dn: o=PNN,c=WW,ou=system\n" +
+    "objectClass: organization\n" +
+    "objectClass: top\n" +
+    "o: MNN\n\n" +
+    
+    // Referral #1
+    "dn: ou=Roles,o=MNN,c=WW,ou=system\n" +
+    "objectClass: extensibleObject\n" +
+    "objectClass: referral\n" +
+    "objectClass: top\n" +
+    "ou: Roles\n" +
+    "ref: ldap://hostd/ou=Roles,dc=apache,dc=org\n\n" +
+    
+    // Referral #2
+    "dn: ou=People,o=MNN,c=WW,ou=system\n" +
+    "objectClass: extensibleObject\n" +
+    "objectClass: referral\n" +
+    "objectClass: top\n" +
+    "ou: People\n" +
+    "ref: ldap://hostb/OU=People,DC=example,DC=com\n" +
+    "ref: ldap://hostc/OU=People,O=MNN,C=WW\n\n" +
+    
+    // Entry # 1
+    "dn: cn=Alex Karasulu,o=MNN,c=WW,ou=system\n" +
+    "objectClass: person\n" +
+    "objectClass: top\n" +
+    "cn: Alex Karasulu\n" +
+    "sn: akarasulu\n\n" +
+    
+    // Entry # 2
+    "dn: cn=Alex,o=MNN,c=WW,ou=system\n" +
+    "objectClass: person\n" +
+    "objectClass: top\n" +
+    "cn: Alex\n" +
+    "sn: akarasulu\n\n"
+    }
+)
+public class SearchReferralIT
+{
+    /** The directory service */
+    public static DirectoryService service;
+
+    /** The Context we are using to inject entries with JNDI */
+    LdapContext MNNCtx;
+    
+    /** The entries we are using to do the tests */
+    Attributes userEntry;
+    ServerEntry serverEntry;
+    
+    @Before
+    public void setUp() throws Exception
+    {
+        MNNCtx = getContext( ServerDNConstants.ADMIN_SYSTEM_DN, service, "o=MNN,c=WW,ou=system" );
+
+        // JNDI entry
+        userEntry = new BasicAttributes( "objectClass", "top", true );
+        userEntry.get( "objectClass" ).add( "person" );
+        userEntry.put( "sn", "elecharny" );
+        userEntry.put( "cn", "Emmanuel Lecharny" );
+        
+        // Core API entry
+        LdapDN dn = new LdapDN( "cn=Emmanuel Lecharny, ou=apache, ou=people, o=MNN, c=WW, ou=system" );
+        serverEntry = new DefaultServerEntry( service.getRegistries(), dn );
+
+        serverEntry.put( "ObjectClass", "top", "person" );
+        serverEntry.put( "sn", "elecharny" );
+        serverEntry.put( "cn", "Emmanuel Lecharny" );
+    }
+
+    
+    /**
+     * Test a search of a non existing entry (not a referral), with no referral 
+     * in its ancestor.
+     */
+    @Test
+    public void testSearchNotExistingSuperiorNoReferralAncestor() throws Exception
+    {
+        Attributes attrs = new BasicAttributes( "ObjectClass", "top", true );
+        
+        try
+        {
+            MNNCtx.search( "cn=nobody", attrs );
+            fail();
+        }
+        catch ( NameNotFoundException nnfe )
+        {
+            assertTrue( true );
+        }
+    }
+
+    
+    /**
+     * Test a search of a non existing entry (not a referral), with a referral 
+     * in its ancestor, using JNDI throw.
+     */
+    @Test
+    public void testSearchWithReferralAncestorJNDIThrow() throws Exception
+    {
+        Attributes attrs = new BasicAttributes( "ObjectClass", "top", true );
+        
+        try
+        {
+            MNNCtx.addToEnvironment( DirContext.REFERRAL, "throw" );
+            MNNCtx.search( "ou=nobody,ou=apache,ou=roles", attrs );
+            fail();
+        }
+        catch ( ReferralException re )
+        {
+            int nbRefs = 0;
+            Set<String> expectedRefs = new HashSet<String>();
+            expectedRefs.add( "ldap://hostd/ou=nobody,ou=apache,ou=Roles,dc=apache,dc=org??one" );
+            
+            do 
+            {
+                String ref = (String)re.getReferralInfo();
+                
+                assertTrue( expectedRefs.contains( ref ) );
+                nbRefs ++;
+            }
+            while ( re.skipReferral() );
+            
+            assertEquals( 1, nbRefs );
+        }
+    }
+
+    
+    /**
+     * Test a search of a non existing entry (not a referral), with a referral 
+     * in its ancestor, using JNDI ignore.
+     */
+    @Test
+    public void testSearchWithReferralAncestorJNDIIgnore() throws Exception
+    {
+        Attributes attrs = new BasicAttributes( "ObjectClass", "top", true );
+        
+        try
+        {
+            MNNCtx.addToEnvironment( DirContext.REFERRAL, "ignore" );
+            MNNCtx.search( "ou=nobody,ou=apache,ou=roles", attrs );
+            fail();
+        }
+        catch ( PartialResultException pre )
+        {
+            assertTrue( true );
+        }
+    }
+
+    
+    /**
+     * Test a search of a non existing entry (not a referral), with a referral 
+     * in its ancestor, using the Core API without the ManageDsaIt flag.
+     */
+    @Test
+    public void testSearchWithReferralAncestorCoreAPIWithoutManageDSAIt() throws Exception
+    {
+        CoreSession coreSession = service.getAdminSession();
+        LdapDN dn = new LdapDN( "ou=nobody,ou=apache,ou=roles,o=Mnn,c=WW,ou=system" );
+        
+        try
+        {
+            coreSession.search( dn, "(ObjectClass=*)", false );
+            fail();
+        }
+        catch ( ReferralException re )
+        {
+            int nbRefs = 0;
+            Set<String> expectedRefs = new HashSet<String>();
+            expectedRefs.add( "ldap://hostd/ou=nobody,ou=apache,ou=Roles,dc=apache,dc=org??base" );
+            
+            do 
+            {
+                String ref = (String)re.getReferralInfo();
+                
+                assertTrue( expectedRefs.contains( ref ) );
+                nbRefs ++;
+            }
+            while ( re.skipReferral() );
+            
+            assertEquals( 1, nbRefs );
+        }
+    }
+
+    
+    /**
+     * Test a search of a non existing entry (not a referral), with a referral 
+     * in its ancestor, using the Core API with the ManageDsaIt flag.
+     */
+    @Test
+    public void testSearchWithReferralAncestorCoreAPIWithManageDSAIt() throws Exception
+    {
+        CoreSession coreSession = service.getAdminSession();
+        LdapDN dn = new LdapDN( "ou=nobody,ou=apache,ou=roles,o=Mnn,c=WW,ou=system" );
+        
+        try
+        {
+            coreSession.search( dn, "(ObjectClass=*)", true );
+            fail();
+        }
+        catch ( PartialResultException pre )
+        {
+            assertTrue( true );
+        }
+    }
+
+    
+    /**
+     * Test a search of an existing entry (not a referral).
+     */
+    @Test
+    public void testSearchExistingNoReferral() throws Exception
+    {
+        SearchControls sCtrls = new SearchControls();
+        sCtrls.setReturningAttributes( new String[]{ "*" } );
+        sCtrls.setSearchScope( SearchControls.OBJECT_SCOPE );
+        
+        NamingEnumeration<SearchResult> result = MNNCtx.search( "cn=Alex Karasulu", "(ObjectClass=top)", sCtrls );
+        
+        assertNotNull( result );
+        int nbRes = 0;
+        
+        while ( result.hasMoreElements() )
+        {
+            SearchResult entry = result.nextElement();
+            assertNotNull( entry );
+            assertNotNull( entry.getAttributes() );
+            assertNotNull( entry.getAttributes().get( "cn" ) );
+            assertEquals( "Alex Karasulu", entry.getAttributes().get( "cn" ).get() );
+            nbRes++;
+        }
+        
+        assertEquals( 1, nbRes );
+    }
+
+    
+    /**
+     * Test a search of an existing referral, using JNDI throw.
+     */
+    @Test
+    public void testSearchExistingReferralJNDIThrow() throws Exception
+    {
+        SearchControls sCtrls = new SearchControls();
+        sCtrls.setReturningAttributes( new String[]{ "*" } );
+        sCtrls.setSearchScope( SearchControls.OBJECT_SCOPE );
+        
+        MNNCtx.addToEnvironment( DirContext.REFERRAL, "throw" );
+        
+        try
+        {
+            MNNCtx.search( "ou=Roles", "(ObjectClass=top)", sCtrls );
+            fail();
+        }
+        catch ( ReferralException re )
+        {
+            int nbRefs = 0;
+            Set<String> expectedRefs = new HashSet<String>();
+            expectedRefs.add( "ldap://hostd/ou=Roles,dc=apache,dc=org??base" );
+            
+            do 
+            {
+                String ref = (String)re.getReferralInfo();
+                
+                assertTrue( expectedRefs.contains( ref ) );
+                nbRefs ++;
+            }
+            while ( re.skipReferral() );
+            
+            assertEquals( 1, nbRefs );
+        }
+    }
+
+    
+    /**
+     * Test a search of an existing referral, using JNDI ignore.
+     */
+    @Test
+    public void testSearchExistingReferralJNDIIgnore() throws Exception
+    {
+        SearchControls sCtrls = new SearchControls();
+        sCtrls.setReturningAttributes( new String[]{ "*" } );
+        sCtrls.setSearchScope( SearchControls.OBJECT_SCOPE );
+        
+        MNNCtx.addToEnvironment( DirContext.REFERRAL, "ignore" );
+        
+        NamingEnumeration<SearchResult> result = MNNCtx.search( "ou=Roles", "(ObjectClass=top)", sCtrls );
+        
+        assertNotNull( result );
+        int nbRes = 0;
+        
+        while ( result.hasMoreElements() )
+        {
+            SearchResult entry = result.nextElement();
+            assertNotNull( entry );
+            assertNotNull( entry.getAttributes() );
+            assertNotNull( entry.getAttributes().get( "ou" ) );
+            assertEquals( "Roles", entry.getAttributes().get( "ou" ).get() );
+            nbRes++;
+        }
+        
+        assertEquals( 1, nbRes );
+    }
+    
+    /**
+     * Test a search of an existing referral, using the Core API without the ManageDsaIt flag.
+     */
+    @Test
+    public void testSearchExistingReferralCoreAPIWithoutManageDsaIT() throws Exception
+    {
+        CoreSession coreSession = service.getAdminSession();
+        LdapDN dn = new LdapDN( "ou=roles,o=Mnn,c=WW,ou=system" );
+        
+        try
+        {
+            coreSession.search( dn, "(ObjectClass=*)", false );
+            fail();
+        }
+        catch ( ReferralException re )
+        {
+            int nbRefs = 0;
+            Set<String> expectedRefs = new HashSet<String>();
+            expectedRefs.add( "ldap://hostd/ou=Roles,dc=apache,dc=org??base" );
+            
+            do 
+            {
+                String ref = (String)re.getReferralInfo();
+                
+                assertTrue( expectedRefs.contains( ref ) );
+                nbRefs ++;
+            }
+            while ( re.skipReferral() );
+            
+            assertEquals( 1, nbRefs );
+        }
+    }
+
+    
+    /**
+     * Test a search of an existing referral, using the Core API with the ManageDsaIt flag.
+     */
+    @Test
+    public void testSearchExistingReferralCoreAPIWithManageDsaIT() throws Exception
+    {
+        CoreSession coreSession = service.getAdminSession();
+        LdapDN dn = new LdapDN( "ou=roles,o=Mnn,c=WW,ou=system" );
+        
+        EntryFilteringCursor cursor = coreSession.search( dn, "(ObjectClass=*)", true );
+        
+        assertNotNull( cursor );
+        
+        cursor.beforeFirst();
+        int nbRes = 0;
+        
+        while ( cursor.next() )
+        {
+            Entry entry = cursor.get();
+            assertNotNull( entry );
+            assertNotNull( entry.get( "ou" ) );
+            assertEquals( "Roles", entry.get( "ou" ).getString() );
+            nbRes++;
+        }
+        
+        assertEquals( 1, nbRes );
+    }
+}

Modified: directory/apacheds/trunk/core-integ/src/test/java/org/apache/directory/server/core/schema/MetaSyntaxHandlerIT.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core-integ/src/test/java/org/apache/directory/server/core/schema/MetaSyntaxHandlerIT.java?rev=702434&r1=702433&r2=702434&view=diff
==============================================================================
--- directory/apacheds/trunk/core-integ/src/test/java/org/apache/directory/server/core/schema/MetaSyntaxHandlerIT.java (original)
+++ directory/apacheds/trunk/core-integ/src/test/java/org/apache/directory/server/core/schema/MetaSyntaxHandlerIT.java Tue Oct  7 04:26:55 2008
@@ -558,6 +558,7 @@
     private void modify( int op, List<String> descriptions, String opAttr ) throws Exception
     {
         LdapDN dn = new LdapDN( getSubschemaSubentryDN() );
+        dn.normalize( service.getRegistries().getAttributeTypeRegistry().getNormalizerMapping() );
         Attribute attr = new BasicAttribute( opAttr );
         for ( String description : descriptions )
         {

Modified: directory/apacheds/trunk/core-jndi/src/main/java/org/apache/directory/server/core/jndi/ServerContext.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core-jndi/src/main/java/org/apache/directory/server/core/jndi/ServerContext.java?rev=702434&r1=702433&r2=702434&view=diff
==============================================================================
--- directory/apacheds/trunk/core-jndi/src/main/java/org/apache/directory/server/core/jndi/ServerContext.java (original)
+++ directory/apacheds/trunk/core-jndi/src/main/java/org/apache/directory/server/core/jndi/ServerContext.java Tue Oct  7 04:26:55 2008
@@ -23,16 +23,22 @@
 import org.apache.directory.server.core.CoreSession;
 import org.apache.directory.server.core.DefaultCoreSession;
 import org.apache.directory.server.core.DirectoryService;
+import org.apache.directory.server.core.OperationManager;
 import org.apache.directory.server.core.authn.LdapPrincipal;
+import org.apache.directory.server.core.cursor.EmptyCursor;
+import org.apache.directory.server.core.cursor.SingletonCursor;
 import org.apache.directory.shared.ldap.entry.EntryAttribute;
 import org.apache.directory.server.core.entry.ClonedServerEntry;
+import org.apache.directory.server.core.entry.DefaultServerEntry;
 import org.apache.directory.server.core.entry.ServerEntry;
 import org.apache.directory.server.core.entry.ServerEntryUtils;
 import org.apache.directory.server.core.event.DirectoryListener;
 import org.apache.directory.server.core.event.NotificationCriteria;
+import org.apache.directory.server.core.filtering.BaseEntryFilteringCursor;
 import org.apache.directory.server.core.filtering.EntryFilteringCursor;
 import org.apache.directory.server.core.interceptor.context.AddOperationContext;
 import org.apache.directory.server.core.interceptor.context.BindOperationContext;
+import org.apache.directory.server.core.interceptor.context.CompareOperationContext;
 import org.apache.directory.server.core.interceptor.context.DeleteOperationContext;
 import org.apache.directory.server.core.interceptor.context.EntryOperationContext;
 import org.apache.directory.server.core.interceptor.context.GetRootDSEOperationContext;
@@ -41,6 +47,7 @@
 import org.apache.directory.server.core.interceptor.context.ModifyOperationContext;
 import org.apache.directory.server.core.interceptor.context.MoveAndRenameOperationContext;
 import org.apache.directory.server.core.interceptor.context.MoveOperationContext;
+import org.apache.directory.server.core.interceptor.context.OperationContext;
 import org.apache.directory.server.core.interceptor.context.RenameOperationContext;
 import org.apache.directory.server.core.interceptor.context.SearchOperationContext;
 import org.apache.directory.shared.ldap.constants.JndiPropertyConstants;
@@ -48,6 +55,7 @@
 import org.apache.directory.shared.ldap.entry.Modification;
 import org.apache.directory.shared.ldap.exception.LdapNoPermissionException;
 import org.apache.directory.shared.ldap.exception.LdapSchemaViolationException;
+import org.apache.directory.shared.ldap.filter.EqualityNode;
 import org.apache.directory.shared.ldap.filter.ExprNode;
 import org.apache.directory.shared.ldap.filter.PresenceNode;
 import org.apache.directory.shared.ldap.filter.SearchScope;
@@ -158,8 +166,9 @@
             props.getSaslMechanism(), props.getSaslAuthId() );
 
         session = opContext.getSession();
+        OperationManager operationManager = service.getOperationManager();
         
-        if ( ! service.getOperationManager().hasEntry( new EntryOperationContext( session, dn ) ) )
+        if ( ! operationManager.hasEntry( new EntryOperationContext( session, dn ) ) )
         {
             throw new NameNotFoundException( dn + " does not exist" );
         }
@@ -185,8 +194,9 @@
         this.env.put( PROVIDER_URL, dn.toString() );
         this.env.put( DirectoryService.JNDI_KEY, service );
         session = new DefaultCoreSession( principal, service );
+        OperationManager operationManager = service.getOperationManager();
         
-        if ( ! service.getOperationManager().hasEntry( new EntryOperationContext( session, ( LdapDN ) dn ) ) )
+        if ( ! operationManager.hasEntry( new EntryOperationContext( session, ( LdapDN ) dn ) ) )
         {
             throw new NameNotFoundException( dn + " does not exist" );
         }
@@ -201,14 +211,35 @@
         this.env.put( PROVIDER_URL, dn.toString() );
         this.env.put( DirectoryService.JNDI_KEY, service );
         this.session = session;
+        OperationManager operationManager = service.getOperationManager();
         
-        if ( ! service.getOperationManager().hasEntry( new EntryOperationContext( session, ( LdapDN ) dn ) ) )
+        if ( ! operationManager.hasEntry( new EntryOperationContext( session, ( LdapDN ) dn ) ) )
         {
             throw new NameNotFoundException( dn + " does not exist" );
         }
     }
 
 
+    /**
+     * Set the referral handling flag into the operation context using
+     * the JNDI value stored into the environment.
+     */
+    protected void injectReferralControl( OperationContext opCtx )
+    {
+        if ( "ignore".equalsIgnoreCase( (String)env.get( Context.REFERRAL ) ) )
+        {
+            opCtx.ignoreReferral();
+        }
+        else if ( "throw".equalsIgnoreCase( (String)env.get( Context.REFERRAL ) ) )
+        {
+            opCtx.throwReferral();
+        }
+        else
+        {
+            // TODO : handle the 'follow' referral option 
+            opCtx.throwReferral();
+        }
+    }
     // ------------------------------------------------------------------------
     // Protected Methods for Operations
     // ------------------------------------------------------------------------
@@ -230,10 +261,14 @@
         AddOperationContext opCtx = new AddOperationContext( session, entry );
 
         opCtx.addRequestControls( requestControls );
-
+        
+        // Inject the referral handling into the operation context
+        injectReferralControl( opCtx );
+        
         // execute add operation
-        service.getOperationManager().add( opCtx );
-
+        OperationManager operationManager = service.getOperationManager();
+        operationManager.add( opCtx );
+    
         // clear the request controls and set the response controls 
         requestControls = EMPTY_CONTROLS;
         responseControls = opCtx.getResponseControls();
@@ -248,10 +283,15 @@
     {
         // setup the op context and populate with request controls
         DeleteOperationContext opCtx = new DeleteOperationContext( session, target );
+
         opCtx.addRequestControls( requestControls );
 
+        // Inject the referral handling into the operation context
+        injectReferralControl( opCtx );
+
         // execute delete operation
-        service.getOperationManager().delete( opCtx );
+        OperationManager operationManager = service.getOperationManager();
+        operationManager.delete( opCtx );
 
         // clear the request controls and set the response controls 
         requestControls = EMPTY_CONTROLS;
@@ -270,17 +310,61 @@
     protected EntryFilteringCursor doSearchOperation( LdapDN dn, AliasDerefMode aliasDerefMode,
         ExprNode filter, SearchControls searchControls ) throws Exception
     {
-        // setup the op context and populate with request controls
-        SearchOperationContext opCtx = new SearchOperationContext( session, dn, aliasDerefMode, filter,
-            searchControls );
-        opCtx.addRequestControls( requestControls );
+        OperationManager operationManager = service.getOperationManager();
+        EntryFilteringCursor results = null;
+        OperationContext opContext;
+
+        // We have to check if it's a compare operation or a search. 
+        // A compare operation has a OBJECT scope search, the filter must
+        // be of the form (object=value) (no wildcards), and no attributes
+        // should be asked to be returned.
+        if ( ( searchControls.getSearchScope() == SearchControls.OBJECT_SCOPE )
+            && ( ( searchControls.getReturningAttributes() != null )
+                && ( searchControls.getReturningAttributes().length == 0 ) )
+            && ( filter instanceof EqualityNode ) )
+        {
+            opContext = new CompareOperationContext( session, dn, ((EqualityNode)filter).getAttribute(), ((EqualityNode)filter).getValue() );
+            
+            // Inject the referral handling into the operation context
+            injectReferralControl( opContext );
 
-        // execute search operation
-        EntryFilteringCursor results = service.getOperationManager().search( opCtx );
+            // Call the operation
+            boolean result = operationManager.compare( (CompareOperationContext)opContext );
+
+            // setup the op context and populate with request controls
+            opContext = new SearchOperationContext( session, dn, aliasDerefMode, filter,
+                searchControls );
+            opContext.addRequestControls( requestControls );
+            
+            if ( result )
+            {
+                ServerEntry emptyEntry = new DefaultServerEntry( service.getRegistries(), LdapDN.EMPTY_LDAPDN ); 
+                return new BaseEntryFilteringCursor( new SingletonCursor<ServerEntry>( emptyEntry ), (SearchOperationContext)opContext );
+            }
+            else
+            {
+                return new BaseEntryFilteringCursor( new EmptyCursor<ServerEntry>(), (SearchOperationContext)opContext );
+            }
+        }
+        else
+        {
+            // It's a Search
+            
+            // setup the op context and populate with request controls
+            opContext = new SearchOperationContext( session, dn, aliasDerefMode, filter,
+                searchControls );
+            opContext.addRequestControls( requestControls );
+
+            // Inject the referral handling into the operation context
+            injectReferralControl( opContext );
+
+            // execute search operation
+            results = operationManager.search( (SearchOperationContext)opContext );
+        }
 
         // clear the request controls and set the response controls 
         requestControls = EMPTY_CONTROLS;
-        responseControls = opCtx.getResponseControls();
+        responseControls = opContext.getResponseControls();
 
         return results;
     }
@@ -296,7 +380,8 @@
         opCtx.addRequestControls( requestControls );
 
         // execute list operation
-        EntryFilteringCursor results = service.getOperationManager().list( opCtx );
+        OperationManager operationManager = service.getOperationManager();
+        EntryFilteringCursor results = operationManager.list( opCtx );
 
         // clear the request controls and set the response controls 
         requestControls = EMPTY_CONTROLS;
@@ -313,7 +398,8 @@
 
         // do not reset request controls since this is not an external 
         // operation and not do bother setting the response controls either
-        return service.getOperationManager().getRootDSE( opCtx );
+        OperationManager operationManager = service.getOperationManager();
+        return operationManager.getRootDSE( opCtx );
     }
 
 
@@ -328,7 +414,8 @@
         // execute lookup/getRootDSE operation
         opCtx = new LookupOperationContext( session, target );
         opCtx.addRequestControls( requestControls );
-        ServerEntry serverEntry = service.getOperationManager().lookup( opCtx );
+        OperationManager operationManager = service.getOperationManager();
+        ServerEntry serverEntry = operationManager.lookup( opCtx );
 
         // clear the request controls and set the response controls 
         requestControls = EMPTY_CONTROLS;
@@ -348,7 +435,8 @@
         // execute lookup/getRootDSE operation
         opCtx = new LookupOperationContext( session, target, attrIds );
         opCtx.addRequestControls( requestControls );
-        ClonedServerEntry serverEntry = service.getOperationManager().lookup( opCtx );
+        OperationManager operationManager = service.getOperationManager();
+        ClonedServerEntry serverEntry = operationManager.lookup( opCtx );
 
         // clear the request controls and set the response controls 
         requestControls = EMPTY_CONTROLS;
@@ -383,7 +471,8 @@
         opCtx.addRequestControls( requestControls );
 
         // execute bind operation
-        service.getOperationManager().bind( opCtx );
+        OperationManager operationManager = service.getOperationManager();
+        operationManager.bind( opCtx );
 
         // clear the request controls and set the response controls 
         requestControls = EMPTY_CONTROLS;
@@ -403,8 +492,12 @@
             newRdn ), delOldDn );
         opCtx.addRequestControls( requestControls );
 
+        // Inject the referral handling into the operation context
+        injectReferralControl( opCtx );
+        
         // execute moveAndRename operation
-        service.getOperationManager().moveAndRename( opCtx );
+        OperationManager operationManager = service.getOperationManager();
+        operationManager.moveAndRename( opCtx );
 
         // clear the request controls and set the response controls 
         requestControls = EMPTY_CONTROLS;
@@ -421,8 +514,12 @@
         ModifyOperationContext opCtx = new ModifyOperationContext( session, dn, modifications );
         opCtx.addRequestControls( requestControls );
 
+        // Inject the referral handling into the operation context
+        injectReferralControl( opCtx );
+        
         // execute modify operation
-        service.getOperationManager().modify( opCtx );
+        OperationManager operationManager = service.getOperationManager();
+        operationManager.modify( opCtx );
 
         // clear the request controls and set the response controls 
         requestControls = EMPTY_CONTROLS;
@@ -439,8 +536,12 @@
         MoveOperationContext opCtx = new MoveOperationContext( session, oldDn, target );
         opCtx.addRequestControls( requestControls );
 
+        // Inject the referral handling into the operation context
+        injectReferralControl( opCtx );
+        
         // execute move operation
-        service.getOperationManager().move( opCtx );
+        OperationManager operationManager = service.getOperationManager();
+        operationManager.move( opCtx );
 
         // clear the request controls and set the response controls 
         requestControls = EMPTY_CONTROLS;
@@ -457,8 +558,12 @@
         RenameOperationContext opCtx = new RenameOperationContext( session, oldDn, new Rdn( newRdn ), delOldRdn );
         opCtx.addRequestControls( requestControls );
 
+        // Inject the referral handling into the operation context
+        injectReferralControl( opCtx );
+        
         // execute rename operation
-        service.getOperationManager().rename( opCtx );
+        OperationManager operationManager = service.getOperationManager();
+        operationManager.rename( opCtx );
 
         // clear the request controls and set the response controls 
         requestControls = EMPTY_CONTROLS;
@@ -929,10 +1034,11 @@
     public void rebind( Name name, Object obj ) throws NamingException
     {
         LdapDN target = buildTarget( name );
-
+        OperationManager operationManager = service.getOperationManager();
+        
         try
         {
-            if ( service.getOperationManager().hasEntry( new EntryOperationContext( session, target ) ) )
+            if ( operationManager.hasEntry( new EntryOperationContext( session, target ) ) )
             {
                 doDeleteOperation( target );
             }

Modified: directory/apacheds/trunk/core-jndi/src/main/java/org/apache/directory/server/core/jndi/ServerDirContext.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core-jndi/src/main/java/org/apache/directory/server/core/jndi/ServerDirContext.java?rev=702434&r1=702433&r2=702434&view=diff
==============================================================================
--- directory/apacheds/trunk/core-jndi/src/main/java/org/apache/directory/server/core/jndi/ServerDirContext.java (original)
+++ directory/apacheds/trunk/core-jndi/src/main/java/org/apache/directory/server/core/jndi/ServerDirContext.java Tue Oct  7 04:26:55 2008
@@ -27,6 +27,7 @@
 import org.apache.directory.server.core.entry.ServerEntryUtils;
 import org.apache.directory.server.core.event.DirectoryListener;
 import org.apache.directory.server.core.event.NotificationCriteria;
+import org.apache.directory.server.core.filtering.EntryFilteringCursor;
 import org.apache.directory.server.core.interceptor.context.EntryOperationContext;
 import org.apache.directory.shared.ldap.constants.SchemaConstants;
 import org.apache.directory.shared.ldap.entry.EntryAttribute;
@@ -650,8 +651,8 @@
             AliasDerefMode aliasDerefMode = AliasDerefMode.getEnum( getEnvironment() );
             try
             {
-                return new NamingEnumerationAdapter ( 
-                    doSearchOperation( target, aliasDerefMode, filter, ctls ) );
+                EntryFilteringCursor cursor = doSearchOperation( target, aliasDerefMode, filter, ctls );               
+                return new NamingEnumerationAdapter ( cursor );
             }
             catch ( Exception e )
             {
@@ -683,8 +684,8 @@
                 AliasDerefMode aliasDerefMode = AliasDerefMode.getEnum( getEnvironment() );
                 try
                 {
-                    return new NamingEnumerationAdapter ( 
-                        doSearchOperation( target, aliasDerefMode, node, ctls ) );
+                    EntryFilteringCursor cursor = doSearchOperation( target, aliasDerefMode, node, ctls );
+                    return new NamingEnumerationAdapter ( cursor ); 
                 }
                 catch ( Exception e )
                 {
@@ -739,7 +740,8 @@
         AliasDerefMode aliasDerefMode = AliasDerefMode.getEnum( getEnvironment() );
         try
         {
-            return new NamingEnumerationAdapter( doSearchOperation( target, aliasDerefMode, filter, ctls ) );
+            EntryFilteringCursor cursor = doSearchOperation( target, aliasDerefMode, filter, ctls );
+            return new NamingEnumerationAdapter( cursor );
         }
         catch ( Exception e )
         {
@@ -813,7 +815,8 @@
         AliasDerefMode aliasDerefMode = AliasDerefMode.getEnum( getEnvironment() );
         try
         {
-            return new NamingEnumerationAdapter( doSearchOperation( target, aliasDerefMode, filterNode, cons ) );
+            EntryFilteringCursor cursor = doSearchOperation( target, aliasDerefMode, filterNode, cons );
+            return new NamingEnumerationAdapter( cursor );
         }
         catch ( Exception e )
         {

Modified: directory/apacheds/trunk/core-jndi/src/main/java/org/apache/directory/server/core/jndi/ServerLdapContext.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core-jndi/src/main/java/org/apache/directory/server/core/jndi/ServerLdapContext.java?rev=702434&r1=702433&r2=702434&view=diff
==============================================================================
--- directory/apacheds/trunk/core-jndi/src/main/java/org/apache/directory/server/core/jndi/ServerLdapContext.java (original)
+++ directory/apacheds/trunk/core-jndi/src/main/java/org/apache/directory/server/core/jndi/ServerLdapContext.java Tue Oct  7 04:26:55 2008
@@ -218,6 +218,9 @@
         
         CompareOperationContext opCtx = new CompareOperationContext( getSession(), name, oid, val );
         opCtx.addRequestControls( requestControls );
+        
+        // Inject the Referral flag
+        injectReferralControl( opCtx );
 
         // execute operation
         boolean result = false;

Modified: directory/apacheds/trunk/core/pom.xml
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core/pom.xml?rev=702434&r1=702433&r2=702434&view=diff
==============================================================================
--- directory/apacheds/trunk/core/pom.xml (original)
+++ directory/apacheds/trunk/core/pom.xml Tue Oct  7 04:26:55 2008
@@ -117,17 +117,9 @@
     </dependency>
 
     <dependency>
-      <groupId>org.apache.directory.shared</groupId>
-      <artifactId>shared-bouncycastle-reduced</artifactId>
-    </dependency>
-
-<!--
-    <dependency>
       <groupId>bouncycastle</groupId>
       <artifactId>bcprov-jdk15</artifactId>
     </dependency>
--->
-
   </dependencies>
 
   <build>