directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From elecha...@apache.org
Subject svn commit: r1058265 - /directory/apacheds/branches/apacheds-AP/core/src/main/java/org/apache/directory/server/core/subtree/SubentryInterceptor.java
Date Wed, 12 Jan 2011 18:22:31 GMT
Author: elecharny
Date: Wed Jan 12 18:22:31 2011
New Revision: 1058265

URL: http://svn.apache.org/viewvc?rev=1058265&view=rev
Log:
Added a partial implementation of the AP rename

Modified:
    directory/apacheds/branches/apacheds-AP/core/src/main/java/org/apache/directory/server/core/subtree/SubentryInterceptor.java

Modified: directory/apacheds/branches/apacheds-AP/core/src/main/java/org/apache/directory/server/core/subtree/SubentryInterceptor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-AP/core/src/main/java/org/apache/directory/server/core/subtree/SubentryInterceptor.java?rev=1058265&r1=1058264&r2=1058265&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-AP/core/src/main/java/org/apache/directory/server/core/subtree/SubentryInterceptor.java
(original)
+++ directory/apacheds/branches/apacheds-AP/core/src/main/java/org/apache/directory/server/core/subtree/SubentryInterceptor.java
Wed Jan 12 18:22:31 2011
@@ -2765,8 +2765,75 @@ public class SubentryInterceptor extends
                 nexus.modify( new ModifyOperationContext( moveAndRenameContext.getSession(),
newDn, mods ) );
             }
         }
+    } */
+    
+    
+    /**
+     * Update the AP caches when renaming an AP
+     */
+    private void applyRenameApCache( DN oldDn, DN newDn ) throws LdapException
+    {
+        List<AdministrativePoint> adminpoints = getAdministrativePoints( oldDn );
+        
+        for ( AdministrativePoint adminPoint : adminpoints )
+        {
+            switch ( adminPoint.getRole() )
+            {
+                case AccessControlSpecificArea :
+                    directoryService.getAccessControlAPCache().remove( oldDn );
+                    directoryService.getAccessControlAPCache().add( newDn, adminPoint );
+                    break;
+                    
+                case CollectiveAttributeSpecificArea :
+                    directoryService.getCollectiveAttributeAPCache().remove( oldDn );
+                    directoryService.getCollectiveAttributeAPCache().add( newDn, adminPoint
);
+                    break;
+                    
+                case SubSchemaSpecificArea :
+                    directoryService.getSubschemaAPCache().remove( oldDn );
+                    directoryService.getSubschemaAPCache().add( newDn, adminPoint );
+                    break;
+                    
+                case TriggerExecutionSpecificArea :
+                    directoryService.getTriggerExecutionAPCache().remove( oldDn );
+                    directoryService.getTriggerExecutionAPCache().add( newDn, adminPoint
);
+                    break;
+            }
+        }
     }
 
+    
+    /**
+     * Get the set of roles this AP is handling
+     */
+    private Set<AdministrativeRoleEnum> getRoles( EntryAttribute adminPointAT )
+    {
+        Set<AdministrativeRoleEnum> roles = new HashSet<AdministrativeRoleEnum>();
+        
+        for ( Value<?> attributeRole : adminPointAT )
+        {
+            String role = attributeRole.getString();
+            
+            if ( isAccessControlInnerRole( role ) || isAccessControlSpecificRole( role )
)
+            {
+                roles.add( AdministrativeRoleEnum.AccessControl );
+            }
+            else if ( isCollectiveAttributeInnerRole( role ) || isAccessControlSpecificRole(
role ) )
+            {
+                roles.add( AdministrativeRoleEnum.CollectiveAttribute );
+            }
+            else if ( isSubschemaSpecificRole( role ) )
+            {
+                roles.add( AdministrativeRoleEnum.SubSchema );
+            }
+            else if ( isTriggerExecutionInnerRole( role ) || isTriggerExecutionSpecificRole(
role ) )
+            {
+                roles.add( AdministrativeRoleEnum.TriggerExecution );
+            }
+        }
+        
+        return roles;
+    }
 
     /**
      * {@inheritDoc}
@@ -2799,39 +2866,138 @@ public class SubentryInterceptor extends
             // specificExclusion that depend on the old name.
             if ( isIAP( adminPointAT) )
             {
-            }
-            else
-            {
+                // First apply the rename
                 next.rename( renameContext );
                 
-                List<AdministrativePoint> adminpoints = getAdministrativePoints( oldDn
);
+                // Update the caches
+                applyRenameApCache( oldDn, newDn );
+                
+                // And check if we have to change the parent's AP seqNumbers
+                List<Modification> modifications = null;
                 
-                for ( AdministrativePoint adminPoint : adminpoints )
+                for ( AdministrativeRoleEnum role : getRoles( adminPointAT ) )
                 {
-                    switch ( adminPoint.getRole() )
+                    switch ( role )
                     {
-                        case AccessControlSpecificArea :
-                            directoryService.getAccessControlAPCache().remove( oldDn );
-                            directoryService.getAccessControlAPCache().add( newDn, adminPoint
);
+                        case AccessControl :
                             break;
                             
-                        case CollectiveAttributeSpecificArea :
-                            directoryService.getCollectiveAttributeAPCache().remove( oldDn
);
-                            directoryService.getCollectiveAttributeAPCache().add( newDn,
adminPoint );
-                            break;
+                        case CollectiveAttribute :
+                            DnNode<AdministrativePoint> apCache = directoryService.getCollectiveAttributeAPCache();
+                            DnNode<AdministrativePoint> apNode = apCache.getParentWithElement(
newDn );
+
+                            // We have an AdministrativePoint for this entry, get its SeqNumber
+                            AdministrativePoint adminPoint = 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.
                             
-                        case SubSchemaSpecificArea :
-                            directoryService.getSubschemaAPCache().remove( oldDn );
-                            directoryService.getSubschemaAPCache().add( newDn, adminPoint
);
-                            break;
+                            // First, init the entry seqNumber. If we have no AT, then we
initialize it to -1
+                            boolean sapFound = false;
+                            boolean updateSN = false;
+
+                            do
+                            {
+                                if ( adminPoint.isSpecific() )
+                                {
+                                    sapFound = true;
+                                }
+
+                                Set<Subentry> subentries = adminPoint.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();
+                                adminPoint = apNode.getElement();
+                            } while ( !sapFound && !updateSN );
                             
-                        case TriggerExecutionSpecificArea :
-                            directoryService.getTriggerExecutionAPCache().remove( oldDn );
-                            directoryService.getTriggerExecutionAPCache().add( newDn, adminPoint
);
                             break;
+
+                        case SubSchema :
+                        case TriggerExecution :
                     }
+
+                    // Now, update the seqNumber
+                    /*
+                    // If we have updated the entry, create the list of modifications to
apply
+                    if ( updateSN )
+                    {
+                        // Create the list of modifications : we will inject REPLACE operations.

+                        modifications = new ArrayList<Modification>();
+                        
+                        // The seqNubmer
+                        EntryAttribute newSeqNumberAT = new DefaultEntryAttribute( seqNumberAT,
Long.toString( entrySeqNumber ) );
+                        Modification seqNumberModification = new DefaultModification( ModificationOperation.REPLACE_ATTRIBUTE,
newSeqNumberAT );
+                        
+                        modifications.add( seqNumberModification );
+                        
+                        // The subentry UUID, if any
+                        if ( ( subentryUuids != null ) && ( subentryUuids.size()
!= 0 ) )
+                        {
+                            EntryAttribute newSubentryUuidAT = new DefaultEntryAttribute(
subentryUuidAT, subentryUuids.toArray( new String[]{} ) );
+                            Modification subentryUuiMod = new DefaultModification( ModificationOperation.REPLACE_ATTRIBUTE,
newSubentryUuidAT );
+
+                            modifications.add( subentryUuiMod );
+                        }
+                        else
+                        {
+                            // We may have to remove UUID refs from the entry
+                            if ( entry.containsAttribute( subentryUuidAT ) )
+                            {
+                                EntryAttribute newSubentryUuidAT = new DefaultEntryAttribute(
subentryUuidAT );
+                                Modification subentryUuiMod = new DefaultModification( ModificationOperation.REMOVE_ATTRIBUTE,
newSubentryUuidAT );
+
+                                modifications.add( subentryUuiMod );
+                            }
+                        }
+                    }
+                    */
                 }
             }
+            else
+            {
+                next.rename( renameContext );
+                
+                // Now, update the caches by removing the old reference to AP and adding
the new one
+                applyRenameApCache( oldDn, newDn );
+            }
         }
         else if ( entry.contains( OBJECT_CLASS_AT, SchemaConstants.SUBENTRY_OC ) )
         {



Mime
View raw message