o Finished the rename of an IAP

git-svn-id: https://svn.apache.org/repos/asf/directory/apacheds/branches/apacheds-AP@1059157 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/core-integ/src/test/java/org/apache/directory/server/core/subtree/SubentryRenameOperationIT.java b/core-integ/src/test/java/org/apache/directory/server/core/subtree/SubentryRenameOperationIT.java
index b6f23fe..0b5d9e5 100644
--- a/core-integ/src/test/java/org/apache/directory/server/core/subtree/SubentryRenameOperationIT.java
+++ b/core-integ/src/test/java/org/apache/directory/server/core/subtree/SubentryRenameOperationIT.java
@@ -457,7 +457,7 @@
      * Test the rename of a subentry under a IAP with no reference to a local name
      */
     @Test
-    public void testRenameSubentryUnderIAPNoLocalName() throws Exception
+    public void testRenameSubentryUnderCaIAPNoLocalName() throws Exception
     {
         DN iapDn = service.getDNFactory().create( "ou=IAP,ou=SAP,ou=system" );
         DN oldSubentryDn = service.getDNFactory().create( "cn=test,ou=IAP,ou=SAP,ou=system" );
@@ -548,7 +548,7 @@
             }
         }
     }
-    
+
     
     // ===================================================================
     // Test the Rename operation for Entries
diff --git a/core/src/main/java/org/apache/directory/server/core/subtree/SubentryInterceptor.java b/core/src/main/java/org/apache/directory/server/core/subtree/SubentryInterceptor.java
index ff5a2a2..3ba674a 100644
--- a/core/src/main/java/org/apache/directory/server/core/subtree/SubentryInterceptor.java
+++ b/core/src/main/java/org/apache/directory/server/core/subtree/SubentryInterceptor.java
@@ -2837,6 +2837,117 @@
         
         return roles;
     }
+    
+    
+    /**
+     * Propagate the IAP modification
+     */
+    private void updateIAP( AdministrativeRoleEnum role, DN oldDn, DN newDn, List<Modification> modifications ) throws LdapException
+    {
+        DnNode<AdministrativePoint> apCache = null;
+        AttributeType seqNumberAT = null;
+        
+        switch ( role )
+        {
+            case AccessControl :
+                apCache = directoryService.getAccessControlAPCache();
+                seqNumberAT = ACCESS_CONTROL_SEQ_NUMBER_AT;
+                break;
+                
+            case CollectiveAttribute :
+                apCache = directoryService.getCollectiveAttributeAPCache();
+                seqNumberAT = COLLECTIVE_ATTRIBUTE_SEQ_NUMBER_AT;
+                break;
+
+            // It can't be a subSchema, there is no Inner AP for subschemas
+                
+            case TriggerExecution :
+                apCache = directoryService.getTriggerExecutionAPCache();
+                seqNumberAT = TRIGGER_EXECUTION_SEQ_NUMBER_AT;
+                break;
+        }
+
+        
+        DnNode<AdministrativePoint> apNode = apCache.getNode( newDn );
+
+        // We have an AdministrativePoint for this entry, get its SeqNumber
+        AdministrativePoint adminPoint = apNode.getElement();
+        AdministrativePoint currentAP = apNode.getElement();
+
+        // We have to recurse : starting from the IAP, we go up the AP tree
+        // until we find the SAP. For each AP we find, we check the Subentries
+        // to see if any of them have a localname containing the oldDn. if so, we 
+        // will update the AP seqNumber for this role.
+        
+        // First, init the entry seqNumber. If we have no AT, then we initialize it to -1
+        boolean sapFound = false;
+        boolean updateSN = false;
+        long newSeqNumber = -1L;
+
+        do
+        {
+            if ( currentAP.isSpecific() )
+            {
+                sapFound = true;
+            }
+
+            Set<Subentry> subentries = currentAP.getSubentries();
+            
+            if ( ( subentries != null ) && ( subentries.size() != 0 ) )
+            {
+                for ( Subentry subentry : subentries )
+                {
+                    SubtreeSpecification ss = subentry.getSubtreeSpecification();
+                    
+                    Set<DN> dns = new HashSet<DN>();
+                    
+                    if ( ss.getBase() != null )
+                    {
+                        dns.add( ss.getBase() );
+                    }
+                    
+                    dns.addAll( ss.getChopBeforeExclusions() );
+                    dns.addAll( ss.getChopAfterExclusions() );
+                    
+                    for ( DN dn : dns )
+                    {
+                        DN fullDn = apNode.getDn().addAll( dn );
+                        
+                        if ( oldDn.isParentOf( fullDn ) )
+                        {
+                            // We have to update this AP's seqNumber
+                            updateSN = true;
+                            break;
+                        }
+                    }
+                    
+                    if ( updateSN )
+                    {
+                        break;
+                    }
+                }
+            }
+            
+            // Go down one level
+            apNode = apNode.getParentWithElement();
+            currentAP = apNode.getElement();
+        } while ( !sapFound && !updateSN );
+        
+        if ( updateSN )
+        {
+            if ( newSeqNumber == -1L )
+            {
+                newSeqNumber = directoryService.getNewApSeqNumber();
+
+                adminPoint.setSeqNumber( newSeqNumber );
+                
+                EntryAttribute newSeqNumberAT = new DefaultEntryAttribute( seqNumberAT, Long.toString( newSeqNumber ) );
+                Modification seqNumberModification = new DefaultModification( ModificationOperation.REPLACE_ATTRIBUTE, newSeqNumberAT );
+                
+                modifications.add( seqNumberModification );
+            }
+        }
+    }
 
     /**
      * {@inheritDoc}
@@ -2857,9 +2968,20 @@
         // Check if we are adding an Administrative Point
         EntryAttribute adminPointAT = entry.get( ADMINISTRATIVE_ROLE_AT );
 
-        // First, deal with an AP addition
+        // First, deal with an AP rename. We must be admin
         if ( adminPointAT != null )
         {
+            // Only admin can add an AP
+            if ( !isAdmin )
+            {
+                String message = "Cannot rename the given AdministrativePoint " + oldDn + ", user is not an Admin";
+                LOG.error( message );
+                
+                throw new LdapUnwillingToPerformException( message );
+            }
+
+            LOG.debug( "Renaming of an administrative point {} for the roles {}", oldDn, adminPointAT );
+
             // This is an AP. If it's a SAP, we have nothing to do, as a rename does not modify 
             // the subtree evaluations, nor does it impact any underlying entries. We just have to 
             // update the AP caches.
@@ -2877,104 +2999,10 @@
                 
                 // And check if we have to change the parent's AP seqNumbers
                 List<Modification> modifications = new ArrayList<Modification>();
-                long newSeqNumber = -1L;
                 
                 for ( AdministrativeRoleEnum role : getRoles( adminPointAT ) )
                 {
-                    switch ( role )
-                    {
-                        case AccessControl :
-                            break;
-                            
-                        case CollectiveAttribute :
-                            DnNode<AdministrativePoint> apCache = directoryService.getCollectiveAttributeAPCache();
-                            DnNode<AdministrativePoint> apNode = apCache.getNode( newDn );
-
-                            // We have an AdministrativePoint for this entry, get its SeqNumber
-                            AdministrativePoint adminPoint = apNode.getElement();
-                            AdministrativePoint currentAP = apNode.getElement();
-                            EntryAttribute seqNumberAttribute = entry.get( COLLECTIVE_ATTRIBUTE_SEQ_NUMBER_AT );
-
-                            // We have to recurse : starting from the IAP, we go up the AP tree
-                            // until we find the SAP. For each AP we find, we check the Subentries
-                            // to see if any of them have a localname containing the oldDn. if so, we 
-                            // will update the AP seqNumber for this role.
-                            
-                            // First, init the entry seqNumber. If we have no AT, then we initialize it to -1
-                            boolean sapFound = false;
-                            boolean updateSN = false;
-
-                            do
-                            {
-                                if ( currentAP.isSpecific() )
-                                {
-                                    sapFound = true;
-                                }
-
-                                Set<Subentry> subentries = currentAP.getSubentries();
-                                
-                                if ( ( subentries != null ) && ( subentries.size() != 0 ) )
-                                {
-                                    for ( Subentry subentry : subentries )
-                                    {
-                                        SubtreeSpecification ss = subentry.getSubtreeSpecification();
-                                        
-                                        Set<DN> dns = new HashSet<DN>();
-                                        
-                                        if ( ss.getBase() != null )
-                                        {
-                                            dns.add( ss.getBase() );
-                                        }
-                                        
-                                        dns.addAll( ss.getChopBeforeExclusions() );
-                                        dns.addAll( ss.getChopAfterExclusions() );
-                                        
-                                        for ( DN dn : dns )
-                                        {
-                                            DN fullDn = apNode.getDn().addAll( dn );
-                                            
-                                            if ( oldDn.isParentOf( fullDn ) )
-                                            {
-                                                // We have to update this AP's seqNumber
-                                                updateSN = true;
-                                                break;
-                                            }
-                                        }
-                                        
-                                        if ( updateSN )
-                                        {
-                                            break;
-                                        }
-                                    }
-                                }
-                                
-                                // Go down one level
-                                apNode = apNode.getParentWithElement();
-                                currentAP = apNode.getElement();
-                            } while ( !sapFound && !updateSN );
-                            
-                            if ( updateSN )
-                            {
-                                if ( newSeqNumber == -1L )
-                                {
-                                    newSeqNumber = directoryService.getNewApSeqNumber();
-
-                                    adminPoint.setSeqNumber( newSeqNumber );
-                                    
-                                    EntryAttribute newSeqNumberAT = new DefaultEntryAttribute( COLLECTIVE_ATTRIBUTE_SEQ_NUMBER_AT, Long.toString( newSeqNumber ) );
-                                    Modification seqNumberModification = new DefaultModification( ModificationOperation.REPLACE_ATTRIBUTE, newSeqNumberAT );
-                                    
-                                    modifications.add( seqNumberModification );
-                                }
-                            }
-                            break;
-
-                        case SubSchema :
-                        case TriggerExecution :
-                    }
-                    
-                    // Update the AdminPoint
-                    
+                    updateIAP( role, oldDn, newDn, modifications );
 
                     // Now, update the AP entry
                     // If we have updated the entry, create the list of modifications to apply