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 2010/06/10 15:06:15 UTC

svn commit: r953315 - in /directory/apacheds/trunk: core-integ/src/test/java/org/apache/directory/server/core/jndi/referral/ core-integ/src/test/java/org/apache/directory/server/core/operations/move/ core/src/main/java/org/apache/directory/server/core/...

Author: elecharny
Date: Thu Jun 10 13:06:14 2010
New Revision: 953315

URL: http://svn.apache.org/viewvc?rev=953315&view=rev
Log:
o Added a test in MoveReferralITTest (@Igored atm) for DIRSERVER-1518
o Changed an error name to be more explicit
o The move() method in store which takes a RDN parameter has been renamed moveAndRename
o The Move() operation can now take an Entry parameter to make the operation atomic (not yet implemented)
o Added some missing Javadoc
o Reviewed the move() operation, which now does nothing but a move
o Fixing tests accordingly to the changes

Modified:
    directory/apacheds/trunk/core-integ/src/test/java/org/apache/directory/server/core/jndi/referral/MoveReferralIT.java
    directory/apacheds/trunk/core-integ/src/test/java/org/apache/directory/server/core/operations/move/MovePerfIT.java
    directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/exception/ExceptionInterceptor.java
    directory/apacheds/trunk/i18n/src/main/java/org/apache/directory/server/i18n/I18n.java
    directory/apacheds/trunk/i18n/src/main/resources/org/apache/directory/server/i18n/errors.properties
    directory/apacheds/trunk/jdbm-partition/src/test/java/org/apache/directory/server/core/partition/impl/btree/jdbm/JdbmStoreTest.java
    directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/xdbm/AbstractXdbmPartition.java
    directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/AbstractStore.java
    directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/Store.java
    directory/apacheds/trunk/xdbm-partition/src/test/java/org/apache/directory/server/xdbm/impl/avl/AvlStoreTest.java

Modified: 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=953315&r1=953314&r2=953315&view=diff
==============================================================================
--- directory/apacheds/trunk/core-integ/src/test/java/org/apache/directory/server/core/jndi/referral/MoveReferralIT.java (original)
+++ directory/apacheds/trunk/core-integ/src/test/java/org/apache/directory/server/core/jndi/referral/MoveReferralIT.java Thu Jun 10 13:06:14 2010
@@ -48,6 +48,7 @@ import org.apache.directory.shared.ldap.
 import org.apache.directory.shared.ldap.exception.LdapReferralException;
 import org.apache.directory.shared.ldap.name.DN;
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -335,7 +336,43 @@ public class MoveReferralIT extends Abst
         catch ( NamingException ne )
         {
             assertTrue( true );
-            //assertEquals( ResultCodeEnum.AFFECTS_MULTIPLE_DSAS, ((LdapNamingException)ne).getResultCode() );
+        }
+    }
+
+    
+    /**
+     * Test a move of an existing referral to a new superior
+     * being a referral
+     */
+    @Test
+    @Ignore
+    public void testMoveExistingReferralJNDIIgnore() throws Exception
+    {
+        WWCtx.addToEnvironment( DirContext.REFERRAL, "ignore" );
+        WWCtx.rename( "ou=Roles,o=MNN", "ou=Roles,o=PNN" );
+
+        // Check that the entry has been moved
+        Object moved = PNNCtx.lookup( "ou=Roles" );
+        assertNotNull( moved );
+    }
+
+    
+    /**
+     * Test a move of an existing referral to a new superior
+     * being a referral
+     */
+    @Test
+    public void testMoveExistingReferralJNDIThrow() throws Exception
+    {
+        try
+        {
+            MNNCtx.addToEnvironment( DirContext.REFERRAL, "throw" );
+            MNNCtx.rename( "ou=Roles", "ou=New Roles" );
+            fail();
+        }
+        catch ( NamingException ne )
+        {
+            assertTrue( true );
         }
     }
 

Modified: directory/apacheds/trunk/core-integ/src/test/java/org/apache/directory/server/core/operations/move/MovePerfIT.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core-integ/src/test/java/org/apache/directory/server/core/operations/move/MovePerfIT.java?rev=953315&r1=953314&r2=953315&view=diff
==============================================================================
--- directory/apacheds/trunk/core-integ/src/test/java/org/apache/directory/server/core/operations/move/MovePerfIT.java (original)
+++ directory/apacheds/trunk/core-integ/src/test/java/org/apache/directory/server/core/operations/move/MovePerfIT.java Thu Jun 10 13:06:14 2010
@@ -19,7 +19,11 @@
  */
 package org.apache.directory.server.core.operations.move;
 
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
 import org.apache.directory.ldap.client.api.LdapConnection;
+import org.apache.directory.ldap.client.api.message.SearchResponse;
 import org.apache.directory.server.core.annotations.ContextEntry;
 import org.apache.directory.server.core.annotations.CreateDS;
 import org.apache.directory.server.core.annotations.CreateIndex;
@@ -33,6 +37,7 @@ import org.apache.directory.shared.ldap.
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+
 /**
  * Test the move operation performances
  *
@@ -83,7 +88,7 @@ public class MovePerfIT extends Abstract
         entry.add( "cn", "test" );
 
         connection.add( entry );
-        int nbIterations = 15000;
+        int nbIterations = 25000;
 
         long t0 = System.currentTimeMillis();
         long t00 = 0L;
@@ -99,7 +104,7 @@ public class MovePerfIT extends Abstract
                 tt0 = tt1;
             }
 
-            if ( i == 5000 )
+            if ( i == 15000 )
             {
                 t00 = System.currentTimeMillis();
             }
@@ -108,6 +113,12 @@ public class MovePerfIT extends Abstract
             
             long ttt0 = System.nanoTime();
             connection.move( oldDn, newSuperior );
+            
+            SearchResponse oldEntry = connection.lookup( oldDn );
+            SearchResponse newEntry = connection.lookup( newDn );
+            
+            assertNull( oldEntry );
+            assertNotNull( newEntry );
             long ttt1 = System.nanoTime();
 
             // Swap the dn
@@ -125,7 +136,7 @@ public class MovePerfIT extends Abstract
         long t1 = System.currentTimeMillis();
 
         Long deltaWarmed = ( t1 - t00 );
-        System.out.println( "Delta : " + deltaWarmed + "( " + ( ( ( nbIterations - 5000 ) * 1000 ) / deltaWarmed ) + " per s ) /" + ( t1 - t0 ) );
+        System.out.println( "Delta : " + deltaWarmed + "( " + ( ( ( nbIterations - 15000 ) * 1000 ) / deltaWarmed ) + " per s ) /" + ( t1 - t0 ) );
         connection.close();
     }
 

Modified: directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/exception/ExceptionInterceptor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/exception/ExceptionInterceptor.java?rev=953315&r1=953314&r2=953315&view=diff
==============================================================================
--- directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/exception/ExceptionInterceptor.java (original)
+++ directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/exception/ExceptionInterceptor.java Thu Jun 10 13:06:14 2010
@@ -139,9 +139,8 @@ public class ExceptionInterceptor extend
         // check if the entry already exists
         if ( nextInterceptor.hasEntry( new EntryOperationContext( opContext.getSession(), name ) ) )
         {
-            LdapEntryAlreadyExistsException ne = new LdapEntryAlreadyExistsException( I18n.err( I18n.ERR_250, name
-                .getName() ) );
-            //ne.setResolvedName( new DN( name.getName() ) );
+            LdapEntryAlreadyExistsException ne = new LdapEntryAlreadyExistsException( 
+                I18n.err( I18n.ERR_250_ENTRY_ALREADY_EXISTS, name.getName() ) );
             throw ne;
         }
 
@@ -177,8 +176,8 @@ public class ExceptionInterceptor extend
             }
             catch ( Exception e )
             {
-                LdapNoSuchObjectException e2 = new LdapNoSuchObjectException( I18n.err( I18n.ERR_251, parentDn
-                    .getName() ) );
+                LdapNoSuchObjectException e2 = new LdapNoSuchObjectException( 
+                    I18n.err( I18n.ERR_251_PARENT_NOT_FOUND, parentDn.getName() ) );
                 throw e2;
             }
 

Modified: directory/apacheds/trunk/i18n/src/main/java/org/apache/directory/server/i18n/I18n.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/i18n/src/main/java/org/apache/directory/server/i18n/I18n.java?rev=953315&r1=953314&r2=953315&view=diff
==============================================================================
--- directory/apacheds/trunk/i18n/src/main/java/org/apache/directory/server/i18n/I18n.java (original)
+++ directory/apacheds/trunk/i18n/src/main/java/org/apache/directory/server/i18n/I18n.java Thu Jun 10 13:06:14 2010
@@ -283,8 +283,8 @@ public enum I18n
     ERR_247("ERR_247"),
     ERR_248("ERR_248"),
     ERR_249("ERR_249"),
-    ERR_250("ERR_250"),
-    ERR_251("ERR_251"),
+    ERR_250_ENTRY_ALREADY_EXISTS("ERR_250_ENTRY_ALREADY_EXISTS"),
+    ERR_251_PARENT_NOT_FOUND("ERR_251_PARENT_NOT_FOUND"),
     ERR_252("ERR_252"),
     ERR_253("ERR_253"),
     ERR_254_ADD_EXISTING_VALUE("ERR_254_ADD_EXISTING_VALUE"),

Modified: directory/apacheds/trunk/i18n/src/main/resources/org/apache/directory/server/i18n/errors.properties
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/i18n/src/main/resources/org/apache/directory/server/i18n/errors.properties?rev=953315&r1=953314&r2=953315&view=diff
==============================================================================
--- directory/apacheds/trunk/i18n/src/main/resources/org/apache/directory/server/i18n/errors.properties (original)
+++ directory/apacheds/trunk/i18n/src/main/resources/org/apache/directory/server/i18n/errors.properties Thu Jun 10 13:06:14 2010
@@ -271,8 +271,8 @@ ERR_246=Unknown match type: {0}
 ERR_247=Unrecognized search scope!
 ERR_248=SubstringNode ''{0}'' had incorrect syntax
 ERR_249=The global schema subentry cannot be added since it exists by default.
-ERR_250={0} already exists!
-ERR_251=Parent {0} not found
+ERR_250_ENTRY_ALREADY_EXISTS={0} already exists!
+ERR_251_PARENT_NOT_FOUND=Parent {0} not found
 ERR_252=Attempt to add entry to alias ''{0}'' not allowed.
 ERR_253=Can not allow the deletion of the subschemaSubentry ({0}) for the global schema.
 ERR_254_ADD_EXISTING_VALUE=Trying to add existing value ''{0}'' to attribute {1}

Modified: directory/apacheds/trunk/jdbm-partition/src/test/java/org/apache/directory/server/core/partition/impl/btree/jdbm/JdbmStoreTest.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/jdbm-partition/src/test/java/org/apache/directory/server/core/partition/impl/btree/jdbm/JdbmStoreTest.java?rev=953315&r1=953314&r2=953315&view=diff
==============================================================================
--- directory/apacheds/trunk/jdbm-partition/src/test/java/org/apache/directory/server/core/partition/impl/btree/jdbm/JdbmStoreTest.java (original)
+++ directory/apacheds/trunk/jdbm-partition/src/test/java/org/apache/directory/server/core/partition/impl/btree/jdbm/JdbmStoreTest.java Thu Jun 10 13:06:14 2010
@@ -561,8 +561,10 @@ public class JdbmStoreTest
 
         DN newParentDn = new DN( "ou=Board of Directors,o=Good Times Co." );
         newParentDn.normalize( schemaManager.getNormalizerMapping() );
+        
+        DN newDn = ((DN)newParentDn.clone()).add( martinDn.getRdn() );
 
-        store.move( martinDn, newParentDn );
+        store.move( martinDn, newParentDn, newDn, entry );
         cursor = idx.forwardCursor( 3L );
         cursor.afterLast();
         assertTrue( cursor.previous() );
@@ -589,7 +591,9 @@ public class JdbmStoreTest
         entry.add( "entryUUID", UUID.randomUUID().toString() );
         store.add( entry );
 
-        store.move( marketingDn, newParentDn );
+        newDn = ((DN)newParentDn.clone()).add( marketingDn.getRdn() );
+
+        store.move( marketingDn, newParentDn, newDn, entry );
 
         cursor = idx.forwardCursor( 3L );
         cursor.afterLast();
@@ -748,7 +752,7 @@ public class JdbmStoreTest
 
         RDN rdn = new RDN( "cn=Ryan" );
 
-        store.move( childDn, parentDn, rdn, true );
+        store.moveAndRename( childDn, parentDn, rdn, childEntry, true );
 
         // to drop the alias indices   
         childDn = new DN( "commonName=Jim Bean,ou=Apache,ou=Board of Directors,o=Good Times Co." );
@@ -759,7 +763,9 @@ public class JdbmStoreTest
 
         assertEquals( 3, store.getSubAliasIndex().count() );
 
-        store.move( childDn, parentDn );
+        DN newDn = ((DN)parentDn.clone()).add( childDn.getRdn() );
+        
+        store.move( childDn, parentDn, newDn, childEntry );
 
         assertEquals( 4, store.getSubAliasIndex().count() );
     }

Modified: directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/xdbm/AbstractXdbmPartition.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/xdbm/AbstractXdbmPartition.java?rev=953315&r1=953314&r2=953315&view=diff
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/xdbm/AbstractXdbmPartition.java (original)
+++ directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/xdbm/AbstractXdbmPartition.java Thu Jun 10 13:06:14 2010
@@ -343,8 +343,8 @@ public abstract class AbstractXdbmPartit
 
         try
         {
-            store.move( moveAndRenameContext.getDn(), moveAndRenameContext.getParent(), moveAndRenameContext.getNewRdn(),
-                moveAndRenameContext.getDelOldDn() );
+            store.moveAndRename( moveAndRenameContext.getDn(), moveAndRenameContext.getParent(), moveAndRenameContext.getNewRdn(),
+                null, moveAndRenameContext.getDelOldDn() );
         }
         catch ( Exception e )
         {
@@ -363,7 +363,11 @@ public abstract class AbstractXdbmPartit
 
         try
         {
-            store.move( moveContext.getDn(), moveContext.getNewSuperior() ); //, moveContext.getEntry().getClonedEntry() );
+            DN oldDn = moveContext.getDn();
+            DN newSuperior = moveContext.getNewSuperior();
+            DN newDn = moveContext.getNewDn();
+            
+            store.move( oldDn, newSuperior, newDn );
         }
         catch ( Exception e )
         {

Modified: directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/AbstractStore.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/AbstractStore.java?rev=953315&r1=953314&r2=953315&view=diff
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/AbstractStore.java (original)
+++ directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/AbstractStore.java Thu Jun 10 13:06:14 2010
@@ -42,6 +42,7 @@ import org.apache.directory.shared.ldap.
 import org.apache.directory.shared.ldap.entry.Value;
 import org.apache.directory.shared.ldap.exception.LdapAliasDereferencingException;
 import org.apache.directory.shared.ldap.exception.LdapAliasException;
+import org.apache.directory.shared.ldap.exception.LdapEntryAlreadyExistsException;
 import org.apache.directory.shared.ldap.exception.LdapException;
 import org.apache.directory.shared.ldap.exception.LdapNoSuchObjectException;
 import org.apache.directory.shared.ldap.exception.LdapSchemaViolationException;
@@ -673,17 +674,15 @@ public abstract class AbstractStore<E, I
     //------------------------------------------------------------------------
     // DN and ID handling
     //------------------------------------------------------------------------
-
     /**
      * {@inheritDoc}
      */
     public ID getEntryId( DN dn ) throws Exception
     {
+        // Just to be sure that the DN is normalized
         if ( !dn.isNormalized() )
         {
             dn.normalize( schemaManager.getNormalizerMapping() );
-            // TODO: force normalized DN
-            //throw new IllegalArgumentException( I18n.err( I18n.ERR_218, suffixDn.getName() ) );
         }
 
         int dnSize = dn.size();
@@ -691,12 +690,14 @@ public abstract class AbstractStore<E, I
 
         ParentIdAndRdn<ID> key = new ParentIdAndRdn<ID>( getRootId(), suffixDn.getRdns() );
 
+        // Check into the RDN index
         ID curEntryId = rdnIdx.forwardLookup( key );
 
         for ( ; i < dnSize; i++ )
         {
             key = new ParentIdAndRdn<ID>( curEntryId, dn.getRdn( i ) );
             curEntryId = rdnIdx.forwardLookup( key );
+            
             if ( curEntryId == null )
             {
                 break;
@@ -1197,11 +1198,14 @@ public abstract class AbstractStore<E, I
     }
 
 
-    public synchronized void move( DN oldChildDn, DN newParentDn, RDN newRdn, boolean deleteOldRdn ) throws Exception
+    /**
+     * {@inheritDoc}
+     */
+    public synchronized void moveAndRename( DN oldDn, DN newSuperior, RDN newRdn, Entry modifiedEntry, boolean deleteOldRdn ) throws Exception
     {
-        ID childId = getEntryId( oldChildDn );
-        rename( oldChildDn, newRdn, deleteOldRdn );
-        move( oldChildDn, childId, newParentDn, newRdn );
+        ID childId = getEntryId( oldDn );
+        rename( oldDn, newRdn, deleteOldRdn );
+        moveAndRename( oldDn, childId, newSuperior, newRdn );
 
         if ( isSyncOnWrite )
         {
@@ -1210,10 +1214,99 @@ public abstract class AbstractStore<E, I
     }
 
 
-    public synchronized void move( DN oldChildDn, DN newParentDn ) throws Exception
+    /**
+     * {@inheritDoc}
+     */
+    public synchronized void move( DN oldDn, DN newSuperiorDn, DN newDn  ) throws Exception
+    {
+        move( oldDn, newSuperiorDn, newDn, null );
+    }
+    
+    
+    /**
+     * {@inheritDoc}
+     */
+    public synchronized void move( DN oldDn, DN newSuperiorDn, DN newDn, Entry modifiedEntry ) throws Exception
     {
-        ID childId = getEntryId( oldChildDn );
-        move( oldChildDn, childId, newParentDn, oldChildDn.getRdn() );
+        // Check that the parent DN exists
+        ID newParentId = getEntryId( newSuperiorDn );
+        
+        if ( newParentId == null )
+        {
+            // This is not allowed : the parent must exist
+            LdapEntryAlreadyExistsException ne = new LdapEntryAlreadyExistsException( 
+                I18n.err( I18n.ERR_250_ENTRY_ALREADY_EXISTS, newSuperiorDn.getName() ) );
+            throw ne;
+        }
+        
+        // Now check that the new entry does not exist
+        ID newId = getEntryId( newDn );
+        
+        if ( newId != null )
+        {
+            // This is not allowed : we should not be able to move an entry
+            // to an existing position
+            LdapEntryAlreadyExistsException ne = new LdapEntryAlreadyExistsException( 
+                I18n.err( I18n.ERR_250_ENTRY_ALREADY_EXISTS, newSuperiorDn.getName() ) );
+            throw ne;
+        }
+        
+
+        // Get the entry and the old parent IDs
+        ID entryId = getEntryId( oldDn );
+        ID oldParentId = getParentId( entryId );
+
+        /*
+         * All aliases including and below oldChildDn, will be affected by
+         * the move operation with respect to one and subtree userIndices since
+         * their relationship to ancestors above oldChildDn will be 
+         * destroyed.  For each alias below and including oldChildDn we will
+         * drop the index tuples mapping ancestor ids above oldChildDn to the
+         * respective target ids of the aliases.
+         */
+        dropMovedAliasIndices( oldDn );
+
+        /*
+         * Drop the old parent child relationship and add the new one
+         * Set the new parent id for the child replacing the old parent id
+         */
+        oneLevelIdx.drop( oldParentId, entryId );
+        oneLevelIdx.add( newParentId, entryId );
+
+        updateSubLevelIndex( entryId, oldParentId, newParentId );
+
+        // Update the RDN index
+        rdnIdx.drop( entryId );
+        ParentIdAndRdn<ID> key = new ParentIdAndRdn<ID>( newParentId, oldDn.getRdn() );
+        rdnIdx.add( key, entryId );
+
+        
+        /* 
+         * Read Alias Index Tuples
+         * 
+         * If this is a name change due to a move operation then the one and
+         * subtree userIndices for aliases were purged before the aliases were
+         * moved.  Now we must add them for each alias entry we have moved.  
+         * 
+         * aliasTarget is used as a marker to tell us if we're moving an 
+         * alias.  If it is null then the moved entry is not an alias.
+         */
+        String aliasTarget = aliasIdx.reverseLookup( entryId );
+
+        if ( null != aliasTarget )
+        {
+            addAliasIndices( entryId, buildEntryDn( entryId ), aliasTarget );
+        }
+        
+        // Update the master table with the modified entry
+        // Warning : this test is an hack. As we may call the Store API directly
+        // we may not have a modified entry to update. For instance, if the ModifierName
+        // or ModifyTimeStamp AT are not updated, there is no reason we want to update the
+        // master table.
+        if ( modifiedEntry != null )
+        {
+            master.put( entryId, modifiedEntry );
+        }
 
         if ( isSyncOnWrite )
         {
@@ -1801,10 +1894,10 @@ public abstract class AbstractStore<E, I
      * @param newParentDn the normalized dn of the new parent for the child
      * @throws Exception if something goes wrong
      */
-    protected void move( DN oldChildDn, ID childId, DN newParentDn, RDN newRdn ) throws Exception
+    protected void moveAndRename( DN oldDn, ID childId, DN newSuperior, RDN newRdn ) throws Exception
     {
         // Get the child and the new parent to be entries and Ids
-        ID newParentId = getEntryId( newParentDn );
+        ID newParentId = getEntryId( newSuperior );
         ID oldParentId = getParentId( childId );
 
         /*
@@ -1815,7 +1908,7 @@ public abstract class AbstractStore<E, I
          * drop the index tuples mapping ancestor ids above oldChildDn to the
          * respective target ids of the aliases.
          */
-        dropMovedAliasIndices( oldChildDn );
+        dropMovedAliasIndices( oldDn );
 
         /*
          * Drop the old parent child relationship and add the new one
@@ -1855,28 +1948,28 @@ public abstract class AbstractStore<E, I
     /**
      * Updates the SubLevel Index as part of a move operation.
      *
-     * @param childId child id to be moved
+     * @param entrtyId child id to be moved
      * @param oldParentId old parent's id
      * @param newParentId new parent's id
      * @throws Exception
      */
-    protected void updateSubLevelIndex( ID childId, ID oldParentId, ID newParentId ) throws Exception
+    protected void updateSubLevelIndex( ID entryId, ID oldParentId, ID newParentId ) throws Exception
     {
         ID tempId = oldParentId;
         List<ID> parentIds = new ArrayList<ID>();
 
         // find all the parents of the oldParentId
-        while ( tempId != null && !tempId.equals( getRootId() ) && !tempId.equals( getSuffixId() ) )
+        while ( ( tempId != null ) && !tempId.equals( getRootId() ) && !tempId.equals( getSuffixId() ) )
         {
             parentIds.add( tempId );
             tempId = getParentId( tempId );
         }
 
         // find all the children of the childId
-        Cursor<IndexEntry<ID, E, ID>> cursor = subLevelIdx.forwardCursor( childId );
+        Cursor<IndexEntry<ID, E, ID>> cursor = subLevelIdx.forwardCursor( entryId );
 
         List<ID> childIds = new ArrayList<ID>();
-        childIds.add( childId );
+        childIds.add( entryId );
 
         while ( cursor.next() )
         {
@@ -1896,7 +1989,7 @@ public abstract class AbstractStore<E, I
         tempId = newParentId;
 
         // find all the parents of the newParentId
-        while ( tempId != null && !tempId.equals( getRootId() ) && !tempId.equals( getSuffixId() ) )
+        while ( ( tempId != null)  && !tempId.equals( getRootId() ) && !tempId.equals( getSuffixId() ) )
         {
             parentIds.add( tempId );
             tempId = getParentId( tempId );

Modified: directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/Store.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/Store.java?rev=953315&r1=953314&r2=953315&view=diff
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/Store.java (original)
+++ directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/Store.java Thu Jun 10 13:06:14 2010
@@ -530,10 +530,72 @@ public interface Store<E, ID extends Com
     void rename( DN dn, RDN newRdn, boolean deleteOldRdn ) throws Exception;
 
     
-    void move( DN oldChildDn, DN newParentDn, RDN newRdn, boolean deleteOldRdn ) throws Exception;
+    void moveAndRename( DN oldChildDn, DN newParentDn, RDN newRdn, Entry entry, boolean deleteOldRdn ) throws Exception;
 
 
-    void move( DN oldChildDn, DN newParentDn ) throws Exception;
+    /**
+     * <p>Move an entry from one place to the other. The RDN remains unchanged,
+     * the parent DN changes</p>
+     * <p>We have to update some of the index when moving an entry. Assuming
+     * that the target destination does not exist, the following index must
+     * be updated :</p>
+     * <ul>
+     * <li><b>oneLevel</b> index</li>
+     * <li><b>subLevel</b> index</li>
+     * </ul>
+     * <p>If the moved entry is an alias, then we also have to update the
+     * following index :</p>
+     * <ul>
+     * <li><b>oneAlias</b> index</li>
+     * <li><b>subAlias</b> index</li>
+     * </ul>
+     * <p>The <b>Alias</b> index is not updated, as the entry ID won't change.</p> 
+     * <p>We have a few check we must do before moving the entry :
+     * <ul>
+     * <li>The destination must not exist
+     * <li>The moved entry must exist (this has already been checked)
+     * <li>The moved entry must not inherit from a referral (already checked)
+     * </ul>
+     *
+     * @param oldDn The previous entry DN
+     * @param newSuperior The new superior DN
+     * @param newDn The new DN
+     * @throws Exception If the move failed
+     */
+    void move( DN oldDn, DN newSuperior, DN newDn ) throws Exception;
+
+
+    /**
+     * <p>Move an entry from one place to the other. The RDN remains unchanged,
+     * the parent DN changes</p>
+     * <p>We have to update some of the index when moving an entry. Assuming
+     * that the target destination does not exist, the following index must
+     * be updated :</p>
+     * <ul>
+     * <li><b>oneLevel</b> index</li>
+     * <li><b>subLevel</b> index</li>
+     * </ul>
+     * <p>If the moved entry is an alias, then we also have to update the
+     * following index :</p>
+     * <ul>
+     * <li><b>oneAlias</b> index</li>
+     * <li><b>subAlias</b> index</li>
+     * </ul>
+     * <p>The <b>Alias</b> index is not updated, as the entry ID won't change.</p> 
+     * <p>We have a few check we must do before moving the entry :
+     * <ul>
+     * <li>The destination must not exist
+     * <li>The moved entry must exist (this has already been checked)
+     * <li>The moved entry must not inherit from a referral (already checked)
+     * </ul>
+     *
+     * @param oldDn The previous entry DN
+     * @param newSuperior The new superior DN
+     * @param newDn The new DN
+     * @param entry The entry to move
+     * @throws Exception If the move failed
+     */
+    void move( DN oldDn, DN newSuperior, DN newDn, Entry entry ) throws Exception;
 
 
     /**

Modified: directory/apacheds/trunk/xdbm-partition/src/test/java/org/apache/directory/server/xdbm/impl/avl/AvlStoreTest.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/test/java/org/apache/directory/server/xdbm/impl/avl/AvlStoreTest.java?rev=953315&r1=953314&r2=953315&view=diff
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/test/java/org/apache/directory/server/xdbm/impl/avl/AvlStoreTest.java (original)
+++ directory/apacheds/trunk/xdbm-partition/src/test/java/org/apache/directory/server/xdbm/impl/avl/AvlStoreTest.java Thu Jun 10 13:06:14 2010
@@ -37,6 +37,7 @@ import java.util.UUID;
 import javax.naming.directory.Attributes;
 
 import org.apache.directory.server.constants.ApacheSchemaConstants;
+import org.apache.directory.server.core.entry.ClonedServerEntry;
 import org.apache.directory.server.xdbm.GenericIndex;
 import org.apache.directory.server.xdbm.Index;
 import org.apache.directory.server.xdbm.IndexEntry;
@@ -487,7 +488,9 @@ public class AvlStoreTest
         DN newParentDn = new DN( "ou=Board of Directors,o=Good Times Co." );
         newParentDn.normalize( schemaManager.getNormalizerMapping() );
 
-        store.move( martinDn, newParentDn );
+        DN newDn = ((DN)newParentDn.clone()).add( martinDn.getRdn() );
+        store.move( martinDn, newParentDn, newDn, new ClonedServerEntry( entry ) );
+
         cursor = idx.forwardCursor( 3L );
         cursor.afterLast();
         assertTrue( cursor.previous() );
@@ -514,7 +517,8 @@ public class AvlStoreTest
         entry.add( "entryUUID", UUID.randomUUID().toString() );
         store.add( entry );
 
-        store.move( marketingDn, newParentDn );
+        newDn = ((DN)newParentDn.clone()).add( marketingDn.getRdn() );
+        store.move( marketingDn, newParentDn, newDn, new ClonedServerEntry( entry ) );
 
         cursor = idx.forwardCursor( 3L );
         cursor.afterLast();
@@ -668,7 +672,7 @@ public class AvlStoreTest
 
         RDN rdn = new RDN( "cn=Ryan" );
 
-        store.move( childDn, parentDn, rdn, true );
+        store.moveAndRename( childDn, parentDn, rdn, new ClonedServerEntry( childEntry ), true );
 
         // to drop the alias indices   
         childDn = new DN( "commonName=Jim Bean,ou=Apache,ou=Board of Directors,o=Good Times Co." );
@@ -679,7 +683,8 @@ public class AvlStoreTest
 
         assertEquals( 3, store.getSubAliasIndex().count() );
 
-        store.move( childDn, parentDn );
+        DN newDn = ((DN)parentDn.clone()).add( childDn.getRdn() );
+        store.move( childDn, parentDn, newDn, childEntry );
 
         assertEquals( 4, store.getSubAliasIndex().count() );
     }