directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From elecha...@apache.org
Subject svn commit: r1684939 - /directory/studio/trunk/plugins/openldap.config.editor/src/main/java/org/apache/directory/studio/openldap/config/jobs/PartitionsDiffComputer.java
Date Thu, 11 Jun 2015 16:27:10 GMT
Author: elecharny
Date: Thu Jun 11 16:27:09 2015
New Revision: 1684939

URL: http://svn.apache.org/r1684939
Log:
Refactored the class, adding the missing Javadoc, fixing the order of deletions

Modified:
    directory/studio/trunk/plugins/openldap.config.editor/src/main/java/org/apache/directory/studio/openldap/config/jobs/PartitionsDiffComputer.java

Modified: directory/studio/trunk/plugins/openldap.config.editor/src/main/java/org/apache/directory/studio/openldap/config/jobs/PartitionsDiffComputer.java
URL: http://svn.apache.org/viewvc/directory/studio/trunk/plugins/openldap.config.editor/src/main/java/org/apache/directory/studio/openldap/config/jobs/PartitionsDiffComputer.java?rev=1684939&r1=1684938&r2=1684939&view=diff
==============================================================================
--- directory/studio/trunk/plugins/openldap.config.editor/src/main/java/org/apache/directory/studio/openldap/config/jobs/PartitionsDiffComputer.java
(original)
+++ directory/studio/trunk/plugins/openldap.config.editor/src/main/java/org/apache/directory/studio/openldap/config/jobs/PartitionsDiffComputer.java
Thu Jun 11 16:27:09 2015
@@ -20,17 +20,18 @@
 package org.apache.directory.studio.openldap.config.jobs;
 
 
+import java.text.ParseException;
 import java.util.ArrayList;
 import java.util.List;
 
 import org.apache.directory.api.ldap.model.constants.SchemaConstants;
+import org.apache.directory.api.ldap.model.cursor.CursorException;
 import org.apache.directory.api.ldap.model.entry.Attribute;
-import org.apache.directory.api.ldap.model.entry.DefaultAttribute;
 import org.apache.directory.api.ldap.model.entry.DefaultModification;
 import org.apache.directory.api.ldap.model.entry.Entry;
 import org.apache.directory.api.ldap.model.entry.Modification;
 import org.apache.directory.api.ldap.model.entry.ModificationOperation;
-import org.apache.directory.api.ldap.model.entry.Value;
+import org.apache.directory.api.ldap.model.exception.LdapException;
 import org.apache.directory.api.ldap.model.exception.LdapInvalidAttributeValueException;
 import org.apache.directory.api.ldap.model.filter.FilterParser;
 import org.apache.directory.api.ldap.model.ldif.ChangeType;
@@ -40,7 +41,6 @@ import org.apache.directory.api.ldap.mod
 import org.apache.directory.api.ldap.model.name.Dn;
 import org.apache.directory.api.ldap.model.schema.AttributeType;
 import org.apache.directory.api.ldap.model.schema.UsageEnum;
-import org.apache.directory.server.core.api.entry.ClonedServerEntry;
 import org.apache.directory.server.core.api.filtering.EntryFilteringCursor;
 import org.apache.directory.server.core.api.interceptor.context.LookupOperationContext;
 import org.apache.directory.server.core.api.interceptor.context.SearchOperationContext;
@@ -54,21 +54,69 @@ import org.apache.directory.server.core.
  */
 public class PartitionsDiffComputer
 {
+    /**
+     * Compute the difference between two partitions :
+     * <ul>
+     *   <li>Added entries</li>
+     *   <li>Removed entries</li>
+     *   <li>Modified entries
+     *     <ul>
+     *       <li>Added Attributes</li>
+     *       <li>Removed Attributes</li>
+     *       <li>Modified Attributes
+     *         <ul>
+     *           <li>Added Values</li>
+     *           <li>Removed Values</li>
+     *         </ul>
+     *       </li>
+     *     </ul>
+     *   </li>
+     * </ul>
+     * @param originalPartition The original partition
+     * @param modifiedPartition The modified partition
+     * @return A list of LDIF Additions, Deletions or Modifications 
+     * @throws Exception If something went wrong
+     */
     public static List<LdifEntry> computeModifications( Partition originalPartition,
Partition modifiedPartition ) throws Exception
     {
-        // Using the original partition suffix as base 
         // '*' for all user attributes, '+' for all operational attributes
-        return computeModifications( originalPartition, modifiedPartition, originalPartition.getSuffixDn(),
new String[]
-            { "*", "+" } );
+        return computeModifications( originalPartition, modifiedPartition, SchemaConstants.ALL_ATTRIBUTES_ARRAY
);
     }
 
 
+    /**
+     * Compute the difference between two partitions :
+     * <ul>
+     *   <li>Added entries</li>
+     *   <li>Removed entries</li>
+     *   <li>Modified entries
+     *     <ul>
+     *       <li>Added Attributes</li>
+     *       <li>Removed Attributes</li>
+     *       <li>Modified Attributes
+     *         <ul>
+     *           <li>Added Values</li>
+     *           <li>Removed Values</li>
+     *         </ul>
+     *       </li>
+     *     </ul>
+     *   </li>
+     * </ul>
+     * @param originalPartition The original partition
+     * @param modifiedPartition The modified partition
+     * @param attributeIds The list of attributes we want to compare
+     * @return A list of LDIF Additions, Deletions or Modifications 
+     * @throws Exception If something went wrong
+     */
     public static List<LdifEntry> computeModifications(  Partition originalPartition,
Partition modifiedPartition, String[] attributeIds ) throws Exception
     {
         return computeModifications( originalPartition, modifiedPartition, originalPartition.getSuffixDn(),
attributeIds );
     }
 
 
+    /** 
+     * Compute the actual diff.
+     */
     private static List<LdifEntry> computeModifications( Partition originalPartition,
Partition modifiedPartition, Dn baseDn, String[] attributeIds ) throws Exception
     {
         // Checking partitions
@@ -80,8 +128,6 @@ public class PartitionsDiffComputer
 
     /**
      * Checks the partitions.
-     *
-     * @throws PartitionsDiffException
      */
     private static void checkPartitions( Partition originalPartition, Partition modifiedPartition
) throws PartitionsDiffException
     {
@@ -105,40 +151,42 @@ public class PartitionsDiffComputer
         // Checking the destination partition
         if ( modifiedPartition == null )
         {
-            throw new PartitionsDiffException( "The destination partition must not be 'null'."
);
+            throw new PartitionsDiffException( "The modified partition must not be 'null'."
);
         }
         else
         {
             if ( !modifiedPartition.isInitialized() )
             {
-                throw new PartitionsDiffException( "The destination partition must be intialized."
);
+                throw new PartitionsDiffException( "The modified partition must be intialized."
);
             }
             else if ( modifiedPartition.getSuffixDn() == null )
             {
-                throw new PartitionsDiffException( "The destination suffix is null." );
+                throw new PartitionsDiffException( "The modified suffix is null." );
             }
         }
     }
 
 
     /**
-     * Compare the two partitions.
+     * Compare two partitions.
      *
-     * @param baseDn the base Dn
-     * @param attributeIds the IDs of the attributes
+     * @param originalPartition The original partition
+     * @param modifiedPartition The modified partition
+     * @param baseDn the Dn from which we will iterate
+     * @param attributeIds the IDs of the attributes we will compare
      * @return a list containing LDIF entries with all modifications
-     * @throws Exception
+     * @throws Exception If something went wrong
      */
-    public static List<LdifEntry> comparePartitions(  Partition originalPartition,
Partition modifiedPartition,Dn baseDn, String[] attributeIds ) throws PartitionsDiffException
+    public static List<LdifEntry> comparePartitions(  Partition originalPartition,
Partition modifiedPartition,
+        Dn baseDn, String[] attributeIds ) throws PartitionsDiffException
     {
-        // Creating the list containing all modifications
+        // Creating the list containing all the modifications
         List<LdifEntry> modifications = new ArrayList<LdifEntry>();
 
         try
         {
             // Looking up the original base entry
-            Entry originalBaseEntry = originalPartition
-                .lookup( new LookupOperationContext( null, baseDn, attributeIds ) );
+            Entry originalBaseEntry = originalPartition.lookup( new LookupOperationContext(
null, baseDn, attributeIds ) );
             
             if ( originalBaseEntry == null )
             {
@@ -146,51 +194,63 @@ public class PartitionsDiffComputer
             }
 
             // Creating the list containing all the original entries to be processed
-            // and adding it the original base entry
+            // and adding it the original base entry. This is done going down the tree.
             List<Entry> originalEntries = new ArrayList<Entry>();
             originalEntries.add( originalBaseEntry );
 
-            // Looping until all original entries are being processed
+            // Looping until all original entries are being processed. We will read all the
children,
+            // adding each of them at the end of the list, consuming the first element of
the list
+            // at every iteration. When we have processed all the tree in depth, we should
not have 
+            // any left entries in the list.
+            // We don't dereference aliases and referrals.
             while ( originalEntries.size() > 0 )
             {
                 // Getting the first original entry from the list
                 Entry originalEntry = originalEntries.remove( 0 );
 
                 // Creating a modification entry to hold all modifications
-                LdifEntry modificationEntry = new LdifEntry();
-                modificationEntry.setDn( originalEntry.getDn() );
+                LdifEntry ldifEntry = new LdifEntry();
+                ldifEntry.setDn( originalEntry.getDn() );
 
                 // Looking for the equivalent entry in the destination partition
-                Entry destinationEntry = modifiedPartition.lookup( new LookupOperationContext(
null, originalEntry
+                Entry modifiedEntry = modifiedPartition.lookup( new LookupOperationContext(
null, originalEntry
                     .getDn(), attributeIds ) );
                 
-                if ( destinationEntry != null )
+                if ( modifiedEntry != null )
                 {
-                    // Setting the changetype to delete
-                    modificationEntry.setChangeType( ChangeType.Modify );
+                    // Setting the changeType to Modify atm
+                    ldifEntry.setChangeType( ChangeType.Modify );
 
                     // Comparing both entries
-                    compareEntries( originalEntry, destinationEntry, modificationEntry );
+                    compareEntries( originalEntry, modifiedEntry, ldifEntry );
                 }
                 else
                 {
-                    // The original entry is no longer present in the destination partition
-
-                    // Setting the changetype to delete
-                    modificationEntry.setChangeType( ChangeType.Delete );
+                    // The entry has been deleted from the partition. It has to be deleted.
+                    // Note : we *must* delete all of it's children first !!!
+                    List<LdifEntry> deletions = deleteEntry( originalPartition, originalEntry.getDn()
);
+                    
+                    // Append the children
+                    modifications.addAll( deletions );
+
+                    // and add the parent entry
+                    ldifEntry.setChangeType( ChangeType.Delete );
+                    
+                    // And go on with the remaining entries
+                    continue;
                 }
 
                 // Checking if modifications occurred on the original entry
-                ChangeType modificationEntryChangeType = modificationEntry.getChangeType();
+                ChangeType modificationEntryChangeType = ldifEntry.getChangeType();
                 
                 if ( modificationEntryChangeType != ChangeType.None )
                 {
                     if ( modificationEntryChangeType == ChangeType.Delete
-                        || ( modificationEntryChangeType == ChangeType.Modify &&
modificationEntry
+                        || ( modificationEntryChangeType == ChangeType.Modify &&
ldifEntry
                             .getModifications().size() > 0 ) )
                     {
                         // Adding the modification entry to the list
-                        modifications.add( modificationEntry );
+                        modifications.add( ldifEntry );
                     }
                 }
 
@@ -205,11 +265,12 @@ public class PartitionsDiffComputer
                 
                 while ( cursor.next() )
                 {
-                    originalEntries.add( ( ( ClonedServerEntry ) cursor.get() ).getClonedEntry()
);
+                    originalEntries.add( cursor.get() );
                 }
             }
 
-            // Looking up the destination base entry
+            // Now, iterate on the modified partition, to see if some entries have
+            // been added.
             Entry destinationBaseEntry = modifiedPartition
                 .lookup( new LookupOperationContext( null, baseDn, attributeIds ) );
             
@@ -220,17 +281,17 @@ public class PartitionsDiffComputer
 
             // Creating the list containing all the destination entries to be processed
             // and adding it the destination base entry
-            List<Entry> destinationEntries = new ArrayList<Entry>();
-            destinationEntries.add( originalBaseEntry );
+            List<Entry> modifiedEntries = new ArrayList<Entry>();
+            modifiedEntries.add( originalBaseEntry );
 
-            // Looping until all destination entries are being processed
-            while ( destinationEntries.size() > 0 )
+            // Looping until all modified entries are being processed
+            while ( modifiedEntries.size() > 0 )
             {
-                // Getting the first destination entry from the list
-                Entry destinationEntry = destinationEntries.remove( 0 );
+                // Getting the first modification entry from the list
+                Entry modifiedEntry = modifiedEntries.remove( 0 );
 
                 // Looking for the equivalent entry in the destination partition
-                Entry originalEntry = originalPartition.lookup( new LookupOperationContext(
null, destinationEntry
+                Entry originalEntry = originalPartition.lookup( new LookupOperationContext(
null, modifiedEntry
                     .getDn(), attributeIds ) );
                 
                 // We're only looking for new entries, modified or removed 
@@ -239,13 +300,13 @@ public class PartitionsDiffComputer
                 {
                     // Creating a modification entry to hold all modifications
                     LdifEntry modificationEntry = new LdifEntry();
-                    modificationEntry.setDn( destinationEntry.getDn() );
+                    modificationEntry.setDn( modifiedEntry.getDn() );
 
-                    // Setting the changetype to addition
+                    // Setting the changeType to addition
                     modificationEntry.setChangeType( ChangeType.Add );
 
                     // Copying attributes
-                    for ( Attribute attribute : destinationEntry )
+                    for ( Attribute attribute : modifiedEntry )
                     {
                         modificationEntry.addAttribute( attribute );
                     }
@@ -255,7 +316,7 @@ public class PartitionsDiffComputer
                 }
 
                 // Creating a search operation context to get the children of the current
entry
-                SearchOperationContext soc = new SearchOperationContext( null, destinationEntry.getDn(),
+                SearchOperationContext soc = new SearchOperationContext( null, modifiedEntry.getDn(),
                     SearchScope.ONELEVEL,
                     FilterParser.parse( originalPartition.getSchemaManager(), "(objectClass=*)"
), attributeIds );
                 soc.setAliasDerefMode( AliasDerefMode.DEREF_ALWAYS );
@@ -265,7 +326,7 @@ public class PartitionsDiffComputer
 
                 while ( cursor.next() )
                 {
-                    destinationEntries.add( ( ( ClonedServerEntry ) cursor.get() ).getClonedEntry()
);
+                    modifiedEntries.add( cursor.get() );
                 }
             }
         }
@@ -277,20 +338,49 @@ public class PartitionsDiffComputer
         return modifications;
     }
 
+    
+    /**
+     * Delete recursively the entries under a parent
+     */
+    private static List<LdifEntry> deleteEntry( Partition originalPartition, Dn parentDn
) throws LdapException, ParseException, CursorException
+    {
+        List<LdifEntry> deletions = new ArrayList<LdifEntry>();
+        
+        // Lookup for the children
+        SearchOperationContext soc = new SearchOperationContext( null, parentDn,
+            SearchScope.ONELEVEL,
+            FilterParser.parse( originalPartition.getSchemaManager(), "(objectClass=*)" ),
SchemaConstants.NO_ATTRIBUTE_ARRAY );
+        soc.setAliasDerefMode( AliasDerefMode.DEREF_ALWAYS );
+
+        // Looking for the children of the current entry
+        EntryFilteringCursor cursor = originalPartition.search( soc );
+
+        while ( cursor.next() )
+        {
+            LdifEntry deletion = new LdifEntry( cursor.get().getDn() );
+            
+            // Iterate 
+            List<LdifEntry> childrenDeletions = deleteEntry( originalPartition, deletion.getDn()
);
+            deletions.addAll( childrenDeletions );
+            deletions.add( deletion );
+        }
+        
+        return deletions;
+    }
 
     /**
      * Compares the two given entries.
      *
      * @param originalEntry the original entry
-     * @param destinationEntry the destination entry
+     * @param modifiedEntry the destination entry
      * @param modificationEntry the modification LDIF entry holding the modifications between
both entries
+     * @throws LdapInvalidAttributeValueException 
      */
-    private static void compareEntries( Entry originalEntry, Entry destinationEntry, LdifEntry
modificationEntry )
+    private static void compareEntries( Entry originalEntry, Entry modifiedEntry, LdifEntry
modificationEntry ) 
+        throws LdapInvalidAttributeValueException
     {
-        // Creating a list to store the already evaluated attribute type
-        List<AttributeType> evaluatedATs = new ArrayList<AttributeType>();
-
-        // Checking attributes of the original entry
+        // We loop on all the attributes of the original entries, to detect the 
+        // modified ones and the deleted ones
         for ( Attribute originalAttribute : originalEntry )
         {
             AttributeType originalAttributeType = originalAttribute.getAttributeType();
@@ -298,55 +388,41 @@ public class PartitionsDiffComputer
             // We're only working on 'userApplications' attributes
             if ( originalAttributeType.getUsage() == UsageEnum.USER_APPLICATIONS )
             {
-                Attribute destinationAttribute = destinationEntry.get( originalAttributeType
);
+                Attribute modifiedAttribute = modifiedEntry.get( originalAttributeType );
                 
-                if ( destinationAttribute == null )
+                if ( modifiedAttribute == null )
                 {
+                    // The attribute has been deleted
                     // Creating a modification for the removed AT
-                    Modification modification = new DefaultModification();
-                    modification.setOperation( ModificationOperation.REMOVE_ATTRIBUTE );
-                    modification.setAttribute( new DefaultAttribute( originalAttribute.getAttributeType()
) );
+                    Modification modification = new DefaultModification(
+                        ModificationOperation.REMOVE_ATTRIBUTE, originalAttributeType );
 
                     modificationEntry.addModification( modification );
                 }
                 else
                 {
                     // Comparing both attributes
-                    compareAttributes( originalAttribute, destinationAttribute, modificationEntry
);
+                    compareAttributes( originalAttribute, modifiedAttribute, modificationEntry
);
                 }
-
-                evaluatedATs.add( originalAttributeType );
             }
         }
 
-        // Checking attributes of the destination entry
-        for ( Attribute destinationAttribute : destinationEntry )
+        // Now, check all the modified entry's attributes to see what are the added ones
+        for ( Attribute destinationAttribute : modifiedEntry )
         {
             AttributeType destinationAttributeType = destinationAttribute.getAttributeType();
 
             // We're only working on 'userApplications' attributes
             if ( destinationAttributeType.getUsage() == UsageEnum.USER_APPLICATIONS )
             {
-                // Checking if the current AT has already been evaluated
-                if ( !evaluatedATs.contains( destinationAttributeType ) )
+                // Checking if the current AT is not present in the original entry : if so,
+                // it has been added
+                if ( !originalEntry.containsAttribute( destinationAttributeType ) )
                 {
                     // Creating a modification for the added AT
-                    Modification modification = new DefaultModification();
-                    modification.setOperation( ModificationOperation.ADD_ATTRIBUTE );
-                    Attribute attribute = new DefaultAttribute( destinationAttributeType
);
-                    modification.setAttribute( attribute );
-
-                    for ( Value<?> value : destinationAttribute )
-                    {
-                        try
-                        {
-                            attribute.add( value );
-                        }
-                        catch ( LdapInvalidAttributeValueException liave )
-                        {
-                            // TODO : handle the exception
-                        }
-                    }
+                    Modification modification = new DefaultModification( 
+                        ModificationOperation.ADD_ATTRIBUTE,
+                        destinationAttribute );
 
                     modificationEntry.addModification( modification );
                 }
@@ -356,26 +432,25 @@ public class PartitionsDiffComputer
 
 
     /**
-     * Compares the two given attributes.
+     * Compares two attributes.
      *
      * @param originalAttribute the original attribute
-     * @param destinationAttribute the destination attribute
+     * @param modifiedAttribute the destination attribute
      * @param modificationEntry the modification LDIF entry holding the modifications between
both attributes
      */
-    private static void compareAttributes( Attribute originalAttribute, Attribute destinationAttribute,
+    private static void compareAttributes( Attribute originalAttribute, Attribute modifiedAttribute,
         LdifEntry modificationEntry )
     {
-        // Special case for 'objectClass' attribute, due to a bug in OpenLDAP
+        // Special case for 'objectClass' attribute, due to a limitation in OpenLDAP
         // which does not allow us to modify the 'objectClass' attribute
-        if ( !SchemaConstants.OBJECT_CLASS_AT.equalsIgnoreCase( originalAttribute.getUpId()
) )
+        if ( !SchemaConstants.OBJECT_CLASS_AT.equalsIgnoreCase( originalAttribute.getAttributeType().getName()
) )
         {
             // Checking if the two attributes are equivalent
-            if ( !originalAttribute.equals( destinationAttribute ) )
+            if ( !originalAttribute.equals( modifiedAttribute ) )
             {
-                // Creating a modification for the modified AT values
-                Modification modification = new DefaultModification();
-                modification.setOperation( ModificationOperation.REPLACE_ATTRIBUTE );
-                modification.setAttribute( destinationAttribute );
+                // Creating a modification for the modified AT values. We do that globally,
for all the values
+                Modification modification = new DefaultModification(
+                    ModificationOperation.REPLACE_ATTRIBUTE, modifiedAttribute );
 
                 modificationEntry.addModification( modification );
             }



Mime
View raw message