You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by pa...@apache.org on 2010/12/20 17:16:24 UTC

svn commit: r1051170 - in /directory/studio/trunk/plugins/apacheds.configuration.v2/src/main/java/org/apache/directory/studio/apacheds/configuration/v2: editor/ jobs/

Author: pamarcelot
Date: Mon Dec 20 16:16:24 2010
New Revision: 1051170

URL: http://svn.apache.org/viewvc?rev=1051170&view=rev
Log:
Added a class to compute a diff between two partitions.
Used this class to get the list of modification to execute on an 'online' configuration.

Added:
    directory/studio/trunk/plugins/apacheds.configuration.v2/src/main/java/org/apache/directory/studio/apacheds/configuration/v2/jobs/PartitionsDiffComputer.java
    directory/studio/trunk/plugins/apacheds.configuration.v2/src/main/java/org/apache/directory/studio/apacheds/configuration/v2/jobs/PartitionsDiffException.java
Modified:
    directory/studio/trunk/plugins/apacheds.configuration.v2/src/main/java/org/apache/directory/studio/apacheds/configuration/v2/editor/ConnectionServerConfigurationInput.java
    directory/studio/trunk/plugins/apacheds.configuration.v2/src/main/java/org/apache/directory/studio/apacheds/configuration/v2/editor/ServerConfigurationEditor.java
    directory/studio/trunk/plugins/apacheds.configuration.v2/src/main/java/org/apache/directory/studio/apacheds/configuration/v2/jobs/LoadConfigurationRunnable.java

Modified: directory/studio/trunk/plugins/apacheds.configuration.v2/src/main/java/org/apache/directory/studio/apacheds/configuration/v2/editor/ConnectionServerConfigurationInput.java
URL: http://svn.apache.org/viewvc/directory/studio/trunk/plugins/apacheds.configuration.v2/src/main/java/org/apache/directory/studio/apacheds/configuration/v2/editor/ConnectionServerConfigurationInput.java?rev=1051170&r1=1051169&r2=1051170&view=diff
==============================================================================
--- directory/studio/trunk/plugins/apacheds.configuration.v2/src/main/java/org/apache/directory/studio/apacheds/configuration/v2/editor/ConnectionServerConfigurationInput.java (original)
+++ directory/studio/trunk/plugins/apacheds.configuration.v2/src/main/java/org/apache/directory/studio/apacheds/configuration/v2/editor/ConnectionServerConfigurationInput.java Mon Dec 20 16:16:24 2010
@@ -20,6 +20,7 @@
 package org.apache.directory.studio.apacheds.configuration.v2.editor;
 
 
+import org.apache.directory.studio.apacheds.configuration.v2.jobs.EntryBasedConfigurationPartition;
 import org.apache.directory.studio.connection.core.Connection;
 import org.eclipse.jface.resource.ImageDescriptor;
 import org.eclipse.osgi.util.NLS;
@@ -37,6 +38,9 @@ public class ConnectionServerConfigurati
     /** The connection */
     private Connection connection;
 
+    /** The original configuration partition */
+    private EntryBasedConfigurationPartition originalPartition;
+
 
     /**
      * Creates a new instance of ConnectionServerConfigurationInput.
@@ -49,7 +53,7 @@ public class ConnectionServerConfigurati
         this.connection = connection;
     }
 
-    
+
     /**
      * Gets the connection.
      *
@@ -61,6 +65,31 @@ public class ConnectionServerConfigurati
         return connection;
     }
 
+
+    /**
+     * Gets the original configuration partition.
+     *
+     * @return
+     *      the original configuration partition
+     */
+    public EntryBasedConfigurationPartition getOriginalPartition()
+    {
+        return originalPartition;
+    }
+
+
+    /**
+     * Sets the original configuration partition.
+     *
+     * @param originalPartition
+     *      the original configuration 
+     */
+    public void setOriginalPartition( EntryBasedConfigurationPartition originalPartition )
+    {
+        this.originalPartition = originalPartition;
+    }
+
+
     /**
      * {@inheritDoc}
      */

Modified: directory/studio/trunk/plugins/apacheds.configuration.v2/src/main/java/org/apache/directory/studio/apacheds/configuration/v2/editor/ServerConfigurationEditor.java
URL: http://svn.apache.org/viewvc/directory/studio/trunk/plugins/apacheds.configuration.v2/src/main/java/org/apache/directory/studio/apacheds/configuration/v2/editor/ServerConfigurationEditor.java?rev=1051170&r1=1051169&r2=1051170&view=diff
==============================================================================
--- directory/studio/trunk/plugins/apacheds.configuration.v2/src/main/java/org/apache/directory/studio/apacheds/configuration/v2/editor/ServerConfigurationEditor.java (original)
+++ directory/studio/trunk/plugins/apacheds.configuration.v2/src/main/java/org/apache/directory/studio/apacheds/configuration/v2/editor/ServerConfigurationEditor.java Mon Dec 20 16:16:24 2010
@@ -23,11 +23,18 @@ package org.apache.directory.studio.apac
 import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.lang.reflect.InvocationTargetException;
+import java.util.List;
 
 import org.apache.directory.server.config.ConfigWriter;
+import org.apache.directory.server.config.ConfigurationException;
 import org.apache.directory.server.config.beans.ConfigBean;
+import org.apache.directory.shared.ldap.entry.DefaultEntry;
+import org.apache.directory.shared.ldap.ldif.LdifEntry;
+import org.apache.directory.shared.ldap.schema.SchemaManager;
 import org.apache.directory.studio.apacheds.configuration.v2.ApacheDS2ConfigurationPlugin;
+import org.apache.directory.studio.apacheds.configuration.v2.jobs.EntryBasedConfigurationPartition;
 import org.apache.directory.studio.apacheds.configuration.v2.jobs.LoadConfigurationRunnable;
+import org.apache.directory.studio.apacheds.configuration.v2.jobs.PartitionsDiffComputer;
 import org.apache.directory.studio.common.core.jobs.StudioJob;
 import org.apache.directory.studio.common.core.jobs.StudioRunnableWithProgress;
 import org.apache.directory.studio.common.ui.CommonUIUtils;
@@ -81,7 +88,7 @@ public class ServerConfigurationEditor e
     {
         super.init( site, input );
         setPartName( input.getName() );
-        
+
         readConfiguration();
     }
 
@@ -137,6 +144,14 @@ public class ServerConfigurationEditor e
                     saveConfiguration( ( FileEditorInput ) input, monitor );
                     success = true;
                 }
+                // If the input is a ConnectionServerConfigurationInput, then we 
+                // read the server configuration from the selected connection
+                if ( input instanceof ConnectionServerConfigurationInput )
+                {
+                    // Saving the ServerConfiguration to the connection
+                    saveConfiguration( ( ConnectionServerConfigurationInput ) input, monitor );
+                    success = true;
+                }
                 else if ( input instanceof IPathEditorInput )
                 {
                     // Saving the ServerConfiguration to disk
@@ -177,15 +192,15 @@ public class ServerConfigurationEditor e
     /**
      * Saves the configuration.
      *
-     * @param fei
+     * @param input
      *      the file editor input
      * @param monitor
      *      the monitor
      * @throws Exception
      */
-    private void saveConfiguration( FileEditorInput fei, IProgressMonitor monitor ) throws Exception
+    private void saveConfiguration( FileEditorInput input, IProgressMonitor monitor ) throws Exception
     {
-        fei.getFile().setContents( new ByteArrayInputStream( getConfigWriter().writeToString().getBytes() ), true,
+        input.getFile().setContents( new ByteArrayInputStream( getConfigWriter().writeToString().getBytes() ), true,
             true, monitor );
     }
 
@@ -193,6 +208,44 @@ public class ServerConfigurationEditor e
     /**
      * Saves the configuration.
      *
+     * @param input
+     *      the connection server configuration input
+     * @param monitor
+     *      the monitor
+     * @throws ConfigurationException 
+     * @throws Exception
+     */
+    private void saveConfiguration( ConnectionServerConfigurationInput input, IProgressMonitor monitor )
+        throws ConfigurationException, Exception
+    {
+        // Getting the original configuration partition
+        EntryBasedConfigurationPartition originalPartition = input.getOriginalPartition();
+
+        // Creating a new configuration partition
+        SchemaManager schemaManager = ApacheDS2ConfigurationPlugin.getDefault().getSchemaManager();
+        EntryBasedConfigurationPartition newconfigurationPartition = new EntryBasedConfigurationPartition(
+            schemaManager );
+        newconfigurationPartition.initialize();
+        List<LdifEntry> convertedLdifEntries = getConfigWriter().getConvertedLdifEntries();
+        for ( LdifEntry ldifEntry : convertedLdifEntries )
+        {
+            newconfigurationPartition.addEntry( new DefaultEntry( schemaManager, ldifEntry.getEntry() ) );
+        }
+
+        // Comparing both partitions to get the list of modifications to be applied
+        PartitionsDiffComputer partitionsDiffComputer = new PartitionsDiffComputer();
+        partitionsDiffComputer.setOriginalPartition( originalPartition );
+        partitionsDiffComputer.setDestinationPartition( newconfigurationPartition );
+        List<LdifEntry> modificationsList = partitionsDiffComputer.computeModifications( new String[]
+            { "*" } );
+
+        System.out.println( modificationsList );
+    }
+
+
+    /**
+     * Saves the configuration.
+     *
      * @param file
      *      the file
      * @throws Exception

Modified: directory/studio/trunk/plugins/apacheds.configuration.v2/src/main/java/org/apache/directory/studio/apacheds/configuration/v2/jobs/LoadConfigurationRunnable.java
URL: http://svn.apache.org/viewvc/directory/studio/trunk/plugins/apacheds.configuration.v2/src/main/java/org/apache/directory/studio/apacheds/configuration/v2/jobs/LoadConfigurationRunnable.java?rev=1051170&r1=1051169&r2=1051170&view=diff
==============================================================================
--- directory/studio/trunk/plugins/apacheds.configuration.v2/src/main/java/org/apache/directory/studio/apacheds/configuration/v2/jobs/LoadConfigurationRunnable.java (original)
+++ directory/studio/trunk/plugins/apacheds.configuration.v2/src/main/java/org/apache/directory/studio/apacheds/configuration/v2/jobs/LoadConfigurationRunnable.java Mon Dec 20 16:16:24 2010
@@ -47,7 +47,6 @@ import org.apache.directory.studio.apach
 import org.apache.directory.studio.apacheds.configuration.v2.editor.ServerConfigurationEditor;
 import org.apache.directory.studio.common.core.jobs.StudioProgressMonitor;
 import org.apache.directory.studio.common.core.jobs.StudioRunnableWithProgress;
-import org.apache.directory.studio.connection.core.Connection;
 import org.apache.directory.studio.connection.core.Connection.AliasDereferencingMethod;
 import org.apache.directory.studio.connection.core.Connection.ReferralHandlingMethod;
 import org.apache.directory.studio.connection.core.io.ConnectionWrapper;
@@ -170,8 +169,7 @@ public class LoadConfigurationRunnable i
         // read the server configuration from the selected connection
         if ( input instanceof ConnectionServerConfigurationInput )
         {
-            Connection connection = ( ( ConnectionServerConfigurationInput ) input ).getConnection();
-            return readConfiguration( schemaManager, connection, monitor );
+            return readConfiguration( schemaManager, ( ConnectionServerConfigurationInput ) input, monitor );
         }
         else if ( input instanceof FileEditorInput )
         // The 'FileEditorInput' class is used when the file is opened
@@ -256,20 +254,20 @@ public class LoadConfigurationRunnable i
      *
      * @param schemaManager
      *      the schema manager
-     * @param connection
-     *      the connection
+     * @param input
+     *      the editor input
      * @param monitor 
      *      the studio progress monitor
      * @return
      *      the associated configuration bean
      * @throws Exception
      */
-    private ConfigBean readConfiguration( SchemaManager schemaManager, Connection connection,
+    private ConfigBean readConfiguration( SchemaManager schemaManager, ConnectionServerConfigurationInput input,
         StudioProgressMonitor monitor ) throws Exception
     {
-        if ( connection != null )
+        if ( input != null )
         {
-            ConnectionWrapper connectionWrapper = connection.getConnectionWrapper();
+            ConnectionWrapper connectionWrapper = input.getConnection().getConnectionWrapper();
 
             // Creating and initializing the configuration partition
             EntryBasedConfigurationPartition configurationPartition = new EntryBasedConfigurationPartition(
@@ -351,6 +349,9 @@ public class LoadConfigurationRunnable i
                 childrenEnumeration.close();
             }
 
+            // Setting the created partition to the input
+            input.setOriginalPartition( configurationPartition );
+
             return readConfiguration( configurationPartition );
         }
 

Added: directory/studio/trunk/plugins/apacheds.configuration.v2/src/main/java/org/apache/directory/studio/apacheds/configuration/v2/jobs/PartitionsDiffComputer.java
URL: http://svn.apache.org/viewvc/directory/studio/trunk/plugins/apacheds.configuration.v2/src/main/java/org/apache/directory/studio/apacheds/configuration/v2/jobs/PartitionsDiffComputer.java?rev=1051170&view=auto
==============================================================================
--- directory/studio/trunk/plugins/apacheds.configuration.v2/src/main/java/org/apache/directory/studio/apacheds/configuration/v2/jobs/PartitionsDiffComputer.java (added)
+++ directory/studio/trunk/plugins/apacheds.configuration.v2/src/main/java/org/apache/directory/studio/apacheds/configuration/v2/jobs/PartitionsDiffComputer.java Mon Dec 20 16:16:24 2010
@@ -0,0 +1,430 @@
+/*
+ *  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.studio.apacheds.configuration.v2.jobs;
+
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.directory.server.core.entry.ClonedServerEntry;
+import org.apache.directory.server.core.filtering.EntryFilteringCursor;
+import org.apache.directory.server.core.interceptor.context.LookupOperationContext;
+import org.apache.directory.server.core.interceptor.context.SearchOperationContext;
+import org.apache.directory.server.core.partition.Partition;
+import org.apache.directory.shared.ldap.entry.DefaultEntryAttribute;
+import org.apache.directory.shared.ldap.entry.DefaultModification;
+import org.apache.directory.shared.ldap.entry.Entry;
+import org.apache.directory.shared.ldap.entry.EntryAttribute;
+import org.apache.directory.shared.ldap.entry.Modification;
+import org.apache.directory.shared.ldap.entry.ModificationOperation;
+import org.apache.directory.shared.ldap.entry.Value;
+import org.apache.directory.shared.ldap.filter.FilterParser;
+import org.apache.directory.shared.ldap.filter.SearchScope;
+import org.apache.directory.shared.ldap.ldif.ChangeType;
+import org.apache.directory.shared.ldap.ldif.LdifEntry;
+import org.apache.directory.shared.ldap.message.AliasDerefMode;
+import org.apache.directory.shared.ldap.name.DN;
+import org.apache.directory.shared.ldap.schema.AttributeType;
+import org.apache.directory.shared.ldap.schema.AttributeTypeOptions;
+import org.apache.directory.shared.ldap.schema.SchemaManager;
+import org.apache.directory.shared.ldap.schema.UsageEnum;
+
+
+public class PartitionsDiffComputer
+{
+    /** The original partition */
+    private Partition originalPartition;
+
+    /** The destination partition */
+    private Partition destinationPartition;
+
+
+    public PartitionsDiffComputer()
+    {
+    }
+
+
+    public PartitionsDiffComputer( Partition originalPartition, Partition destinationPartition )
+    {
+        this.originalPartition = originalPartition;
+        this.destinationPartition = destinationPartition;
+    }
+
+
+    public List<LdifEntry> computeModifications() throws Exception
+    {
+        // Using the original partition suffix as base 
+        // '*' for all user attributes, '+' for all operational attributes
+        return computeModifications( originalPartition.getSuffix(), new String[]
+            { "*", "+" } );
+    }
+
+
+    public List<LdifEntry> computeModifications( String[] attributeIds ) throws Exception
+    {
+        return computeModifications( originalPartition.getSuffix(), attributeIds );
+    }
+
+
+    public List<LdifEntry> computeModifications( DN baseDN, String[] attributeIds ) throws Exception
+    {
+        // Checking partitions
+        checkPartitions();
+
+        return comparePartitions( baseDN, attributeIds );
+    }
+
+
+    /**
+     * Checks the partitions.
+     *
+     * @throws PartitionsDiffException
+     */
+    private void checkPartitions() throws PartitionsDiffException
+    {
+        // Checking the original partition
+        if ( originalPartition == null )
+        {
+            throw new PartitionsDiffException( "The original partition must not be 'null'." );
+        }
+        else
+        {
+            if ( !originalPartition.isInitialized() )
+            {
+                throw new PartitionsDiffException( "The original partition must be intialized." );
+            }
+            else if ( originalPartition.getSuffix() == null )
+            {
+                throw new PartitionsDiffException( "The original suffix is null." );
+            }
+        }
+
+        // Checking the destination partition
+        if ( destinationPartition == null )
+        {
+            throw new PartitionsDiffException( "The destination partition must not be 'null'." );
+        }
+        else
+        {
+            if ( !destinationPartition.isInitialized() )
+            {
+                throw new PartitionsDiffException( "The destination partition must be intialized." );
+            }
+            else if ( destinationPartition.getSuffix() == null )
+            {
+                throw new PartitionsDiffException( "The destination suffix is null." );
+            }
+        }
+    }
+
+
+    /**
+     * Compare the two partitions.
+     *
+     * @param baseDN
+     *      the base DN
+     * @param attributeIds
+     *      the IDs of the attributes
+     * @return
+     *      a list containing LDIF entries with all modifications
+     * @throws Exception
+     */
+    public List<LdifEntry> comparePartitions( DN baseDN, String[] attributeIds ) throws PartitionsDiffException
+    {
+        // Creating the list containing all modifications
+        List<LdifEntry> modifications = new ArrayList<LdifEntry>();
+
+        try
+        {
+            // Looking up the original base entry
+            Entry originalBaseEntry = originalPartition
+                .lookup( new LookupOperationContext( null, baseDN, attributeIds ) );
+            if ( originalBaseEntry == null )
+            {
+                throw new PartitionsDiffException( "Unable to find the base entry in the original partition." );
+            }
+
+            // Creating the list containing all the original entries to be processed
+            // and adding it the original base entry
+            List<Entry> originalEntries = new ArrayList<Entry>();
+            originalEntries.add( originalBaseEntry );
+
+            // Looping until all original entries are being processed
+            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() );
+
+                // Looking for the equivalent entry in the destination partition
+                Entry destinationEntry = destinationPartition.lookup( new LookupOperationContext( null, originalEntry
+                    .getDn(), attributeIds ) );
+                if ( destinationEntry != null )
+                {
+                    // Setting the changetype to delete
+                    modificationEntry.setChangeType( ChangeType.Modify );
+
+                    // Comparing both entries
+                    compareEntries( originalEntry, destinationEntry, modificationEntry );
+                }
+                else
+                {
+                    // The original entry is no longer present in the destination partition
+
+                    // Setting the changetype to delete
+                    modificationEntry.setChangeType( ChangeType.Delete );
+                }
+
+                // Checking if modifications occurred on the original entry
+                ChangeType modificationEntryChangeType = modificationEntry.getChangeType();
+                if ( modificationEntryChangeType != ChangeType.None )
+                {
+                    if ( modificationEntryChangeType == ChangeType.Delete
+                        || ( modificationEntryChangeType == ChangeType.Modify && modificationEntry
+                            .getModificationItems().size() > 0 ) )
+                    {
+                        // Adding the modification entry to the list
+                        modifications.add( modificationEntry );
+                    }
+                }
+
+                // TODO add doc
+                SearchOperationContext soc = new SearchOperationContext( null );
+                //                soc.setReturningAttributes( convertReturningAttributes( originalPartition.getSchemaManager(),
+                //                    attributeIds ) );
+                soc.setAllUserAttributes( true );
+                soc.setDn( originalEntry.getDn() );
+                soc.setScope( SearchScope.ONELEVEL );
+                soc.setFilter( FilterParser.parse( originalPartition.getSchemaManager(), "(objectClass=*)" ) );
+                soc.setAliasDerefMode( AliasDerefMode.DEREF_ALWAYS );
+
+                // TODO add doc
+                EntryFilteringCursor cursor = originalPartition.search( soc );
+                while ( cursor.next() )
+                {
+                    ClonedServerEntry entry = cursor.get();
+                    originalEntries.add( entry.getClonedEntry() );
+                }
+            }
+
+        }
+        catch ( Exception e )
+        {
+            throw new PartitionsDiffException( e );
+        }
+
+        return modifications;
+    }
+
+
+    private Set<AttributeTypeOptions> convertReturningAttributes( SchemaManager schemaManager, String[] attributeIds )
+    {
+        Set<AttributeTypeOptions> set = new HashSet<AttributeTypeOptions>();
+
+        for ( String attributeId : attributeIds )
+        {
+            AttributeType attributeType = schemaManager.getAttributeType( attributeId );
+            if ( attributeType != null )
+            {
+                set.add( new AttributeTypeOptions( attributeType ) );
+            }
+        }
+
+        return set;
+    }
+
+
+    /**
+     * Compares the two given entries.
+     *
+     * @param originalEntry
+     *      the original entry
+     * @param destinationEntry
+     *      the destination entry
+     * @param modificationEntry
+     *      the modification LDIF entry holding the modifications 
+     *      between both entries
+     */
+    private void compareEntries( Entry originalEntry, Entry destinationEntry, LdifEntry modificationEntry )
+    {
+        // Creating a list to store the already evaluated attribute type
+        List<AttributeType> evaluatedATs = new ArrayList<AttributeType>();
+
+        // Checking attributes of the original entry
+        for ( EntryAttribute originalAttribute : originalEntry )
+        {
+            AttributeType originalAttributeType = originalAttribute.getAttributeType();
+
+            // We're only working on 'userApplications' attributes
+            if ( originalAttributeType.getUsage() == UsageEnum.USER_APPLICATIONS )
+            {
+                EntryAttribute destinationAttribute = destinationEntry.get( originalAttributeType );
+                if ( destinationAttribute == null )
+                {
+                    // Creating a modification for the removed AT
+                    Modification modification = new DefaultModification();
+                    modification.setOperation( ModificationOperation.REMOVE_ATTRIBUTE );
+                    modification.setAttribute( new DefaultEntryAttribute( originalAttribute.getAttributeType() ) );
+
+                    modificationEntry.addModificationItem( modification );
+                }
+                else
+                {
+                    // Comparing both attributes
+                    compareAttributes( originalAttribute, destinationAttribute, modificationEntry );
+                }
+
+                evaluatedATs.add( originalAttributeType );
+            }
+        }
+
+        // Checking attributes of the destination entry
+        for ( EntryAttribute destinationAttribute : destinationEntry )
+        {
+            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 ) )
+                {
+                    // Creating a modification for the added AT
+                    Modification modification = new DefaultModification();
+                    modification.setOperation( ModificationOperation.ADD_ATTRIBUTE );
+                    EntryAttribute attribute = new DefaultEntryAttribute( destinationAttributeType );
+                    modification.setAttribute( attribute );
+                    for ( Value<?> value : destinationAttribute )
+                    {
+                        attribute.add( value );
+                    }
+
+                    modificationEntry.addModificationItem( modification );
+                }
+            }
+        }
+    }
+
+
+    /**
+     * Compares the two given attributes.
+     *
+     * @param originalAttribute
+     *      the original attribute
+     * @param destinationAttribute
+     *      the destination attribute
+     * @param modificationEntry
+     *      the modification LDIF entry holding the modifications 
+     *      between both attributes
+     */
+    private void compareAttributes( EntryAttribute originalAttribute, EntryAttribute destinationAttribute,
+        LdifEntry modificationEntry )
+    {
+        // Creating a list to store the already evaluated values
+        List<Value<?>> evaluatedValues = new ArrayList<Value<?>>();
+
+        // Checking values of the original attribute
+        for ( Value<?> originalValue : originalAttribute )
+        {
+            if ( !destinationAttribute.contains( originalValue ) )
+            {
+                // Creating a modification for the removed AT value
+                Modification modification = new DefaultModification();
+                modification.setOperation( ModificationOperation.REMOVE_ATTRIBUTE );
+                EntryAttribute attribute = new DefaultEntryAttribute( originalAttribute.getAttributeType() );
+                modification.setAttribute( attribute );
+                attribute.add( originalValue );
+
+                modificationEntry.addModificationItem( modification );
+            }
+
+            evaluatedValues.add( originalValue );
+        }
+
+        // Checking values of the destination attribute
+        for ( Value<?> destinationValue : destinationAttribute )
+        {
+            if ( !evaluatedValues.contains( destinationValue ) )
+            {
+                // Creating a modification for the added AT value
+                Modification modification = new DefaultModification();
+                modification.setOperation( ModificationOperation.ADD_ATTRIBUTE );
+                EntryAttribute attribute = new DefaultEntryAttribute( originalAttribute.getAttributeType() );
+                modification.setAttribute( attribute );
+                attribute.add( destinationValue );
+
+                modificationEntry.addModificationItem( modification );
+            }
+        }
+    }
+
+
+    /**
+     * Gets the original partition.
+     *
+     * @return
+     *      the original partition
+     */
+    public Partition getOriginalPartition()
+    {
+        return originalPartition;
+    }
+
+
+    /**
+     * Sets the original partition.
+     *
+     * @param originalPartition
+     *      the original partition
+     */
+    public void setOriginalPartition( Partition originalPartition )
+    {
+        this.originalPartition = originalPartition;
+    }
+
+
+    /**
+     * Gets the destination partition.
+     *
+     * @return
+     *      the destination partition
+     */
+    public Partition getDestinationPartition()
+    {
+        return destinationPartition;
+    }
+
+
+    /**
+     * Sets the destination partition.
+     *
+     * @param destinationPartition
+     *      the destination partition
+     */
+    public void setDestinationPartition( Partition destinationPartition )
+    {
+        this.destinationPartition = destinationPartition;
+    }
+}

Added: directory/studio/trunk/plugins/apacheds.configuration.v2/src/main/java/org/apache/directory/studio/apacheds/configuration/v2/jobs/PartitionsDiffException.java
URL: http://svn.apache.org/viewvc/directory/studio/trunk/plugins/apacheds.configuration.v2/src/main/java/org/apache/directory/studio/apacheds/configuration/v2/jobs/PartitionsDiffException.java?rev=1051170&view=auto
==============================================================================
--- directory/studio/trunk/plugins/apacheds.configuration.v2/src/main/java/org/apache/directory/studio/apacheds/configuration/v2/jobs/PartitionsDiffException.java (added)
+++ directory/studio/trunk/plugins/apacheds.configuration.v2/src/main/java/org/apache/directory/studio/apacheds/configuration/v2/jobs/PartitionsDiffException.java Mon Dec 20 16:16:24 2010
@@ -0,0 +1,80 @@
+/*
+ *  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.studio.apacheds.configuration.v2.jobs;
+
+
+/**
+ * This exception can be raised when an error occurs when computing the diff
+ * between two partitions.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class PartitionsDiffException extends Exception
+{
+    private static final long serialVersionUID = 1L;
+
+
+    /**
+     * Constructs a new PartitionsDiffException with <code>null</code> as its detail message.
+     */
+    public PartitionsDiffException()
+    {
+        super();
+    }
+
+
+    /**
+     * Constructs a new PartitionsDiffException with the specified detail message and cause.
+     *
+     * @param message
+     *      the message
+     * @param cause
+     *      the cause
+     */
+    public PartitionsDiffException( String message, Throwable cause )
+    {
+        super( message, cause );
+    }
+
+
+    /**
+     * Constructs a new PartitionsDiffException with the specified detail message.
+     *
+     * @param message
+     *      the message
+     */
+    public PartitionsDiffException( String message )
+    {
+        super( message );
+    }
+
+
+    /**
+     * Constructs a new exception with the specified cause and a detail message 
+     * of <code>(cause==null ? null : cause.toString())</code>
+     *
+     * @param cause
+     *      the cause
+     */
+    public PartitionsDiffException( Throwable cause )
+    {
+        super( cause );
+    }
+}