You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by se...@apache.org on 2009/10/12 16:43:56 UTC

svn commit: r824365 - in /directory/studio/trunk: ldapbrowser-common/ ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/connection/ ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/...

Author: seelmann
Date: Mon Oct 12 14:43:55 2009
New Revision: 824365

URL: http://svn.apache.org/viewvc?rev=824365&view=rev
Log:
Implemented configurable modification operations:
o Fixes DIRSTUDIO-513 (Do delete before add when modifying attribute values)
o Basic support for DIRSTUDIO-528 (Handle schema extension used for OpenLDAP attribute ordering)

Added:
    directory/studio/trunk/ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/connection/EditorParameterPage.java
Modified:
    directory/studio/trunk/ldapbrowser-common/plugin.properties
    directory/studio/trunk/ldapbrowser-common/plugin.xml
    directory/studio/trunk/ldapbrowser-common/plugin_de.properties
    directory/studio/trunk/ldapbrowser-common/plugin_fr.properties
    directory/studio/trunk/ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/connection/messages.properties
    directory/studio/trunk/ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/connection/messages_de.properties
    directory/studio/trunk/ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/connection/messages_fr.properties
    directory/studio/trunk/ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/IBrowserConnection.java
    directory/studio/trunk/ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/impl/BrowserConnection.java
    directory/studio/trunk/ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/impl/DummyConnection.java
    directory/studio/trunk/ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/utils/ModelConverter.java
    directory/studio/trunk/ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/utils/Utils.java

Modified: directory/studio/trunk/ldapbrowser-common/plugin.properties
URL: http://svn.apache.org/viewvc/directory/studio/trunk/ldapbrowser-common/plugin.properties?rev=824365&r1=824364&r2=824365&view=diff
==============================================================================
--- directory/studio/trunk/ldapbrowser-common/plugin.properties (original)
+++ directory/studio/trunk/ldapbrowser-common/plugin.properties Mon Oct 12 14:43:55 2009
@@ -135,7 +135,11 @@
 
 ConnectionParameterPage_BrowserParameterPage_id=org.apache.directory.studio.ldapbrowser.common.widgets.connection.BrowserParameterPage
 ConnectionParameterPage_BrowserParameterPage_name=Browser Options
-ConnectionParameterPage_BrowserParameterPage_description=You can specify additional connection parameters.
+ConnectionParameterPage_BrowserParameterPage_description=You can specify additional parameters for browsing the directory.
+
+ConnectionParameterPage_EditorParameterPage_id=org.apache.directory.studio.ldapbrowser.common.widgets.connection.EditorParameterPage
+ConnectionParameterPage_EditorParameterPage_name=Editor Options
+ConnectionParameterPage_EditorParameterPage_description=You can specify additional parameters for editing entries.
 
 ConnectionParameterPage_AuthenticationParameterPage_id=org.apache.directory.studio.connection.ui.widgets.AuthenticationParameterPage
 

Modified: directory/studio/trunk/ldapbrowser-common/plugin.xml
URL: http://svn.apache.org/viewvc/directory/studio/trunk/ldapbrowser-common/plugin.xml?rev=824365&r1=824364&r2=824365&view=diff
==============================================================================
--- directory/studio/trunk/ldapbrowser-common/plugin.xml (original)
+++ directory/studio/trunk/ldapbrowser-common/plugin.xml Mon Oct 12 14:43:55 2009
@@ -310,6 +310,12 @@
           description="%ConnectionParameterPage_BrowserParameterPage_description"
           id="%ConnectionParameterPage_BrowserParameterPage_id"
           name="%ConnectionParameterPage_BrowserParameterPage_name"/>
+    <connectionParameterPage
+          class="org.apache.directory.studio.ldapbrowser.common.widgets.connection.EditorParameterPage"
+          dependsOnId="%ConnectionParameterPage_BrowserParameterPage_id"
+          description="%ConnectionParameterPage_EditorParameterPage_description"
+          id="%ConnectionParameterPage_EditorParameterPage_id"
+          name="%ConnectionParameterPage_EditorParameterPage_name"/>
  </extension>
  
 </plugin>

Modified: directory/studio/trunk/ldapbrowser-common/plugin_de.properties
URL: http://svn.apache.org/viewvc/directory/studio/trunk/ldapbrowser-common/plugin_de.properties?rev=824365&r1=824364&r2=824365&view=diff
==============================================================================
--- directory/studio/trunk/ldapbrowser-common/plugin_de.properties (original)
+++ directory/studio/trunk/ldapbrowser-common/plugin_de.properties Mon Oct 12 14:43:55 2009
@@ -80,4 +80,7 @@
 Ctx_LdapBrowserDialogs_description=Im LDAP Browser Dialog
 
 ConnectionParameterPage_BrowserParameterPage_name=Browser Optionen
-ConnectionParameterPage_BrowserParameterPage_description=Sie k\u00F6nnen zus\u00E4tzliche Verbindungsparameter spezifizieren.
+ConnectionParameterPage_BrowserParameterPage_description=Sie k\u00F6nnen zus\u00E4tzliche Parameter zum Browsen spezifizieren.
+
+ConnectionParameterPage_EditorParameterPage_name=Editor Optionen
+ConnectionParameterPage_EditorParameterPage_description=Sie k\u00F6nnen zus\u00E4tzliche Parameter zum Editieren von Eintr\u00E4gen spezifizieren.

Modified: directory/studio/trunk/ldapbrowser-common/plugin_fr.properties
URL: http://svn.apache.org/viewvc/directory/studio/trunk/ldapbrowser-common/plugin_fr.properties?rev=824365&r1=824364&r2=824365&view=diff
==============================================================================
--- directory/studio/trunk/ldapbrowser-common/plugin_fr.properties (original)
+++ directory/studio/trunk/ldapbrowser-common/plugin_fr.properties Mon Oct 12 14:43:55 2009
@@ -96,4 +96,7 @@
 Ctx_LdapBrowserDialogs_description=Dans les fen\u00EAtres de dialogue du navigateur LDAP
 
 ConnectionParameterPage_BrowserParameterPage_name=Options du navigateur
-ConnectionParameterPage_BrowserParameterPage_description=Vous pouvez sp\u00E9cifier des param\u00E8tres de connexion additionels
\ No newline at end of file
+ConnectionParameterPage_BrowserParameterPage_description=Vous pouvez sp\u00E9cifier des param\u00E8tres de connexion additionels
+
+ConnectionParameterPage_EditorParameterPage_name=TODO:Editor Options
+ConnectionParameterPage_EditorParameterPage_description=TODO:You can specify additional parameters for editing entries.

Added: directory/studio/trunk/ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/connection/EditorParameterPage.java
URL: http://svn.apache.org/viewvc/directory/studio/trunk/ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/connection/EditorParameterPage.java?rev=824365&view=auto
==============================================================================
--- directory/studio/trunk/ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/connection/EditorParameterPage.java (added)
+++ directory/studio/trunk/ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/connection/EditorParameterPage.java Mon Oct 12 14:43:55 2009
@@ -0,0 +1,355 @@
+/*
+ *  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.ldapbrowser.common.widgets.connection;
+
+
+import org.apache.directory.shared.ldap.util.LdapURL;
+import org.apache.directory.shared.ldap.util.LdapURL.Extension;
+import org.apache.directory.studio.connection.core.ConnectionParameter;
+import org.apache.directory.studio.connection.ui.AbstractConnectionParameterPage;
+import org.apache.directory.studio.connection.ui.widgets.BaseWidgetUtils;
+import org.apache.directory.studio.ldapbrowser.core.model.IBrowserConnection;
+import org.apache.directory.studio.ldapbrowser.core.model.IBrowserConnection.ModifyMode;
+import org.apache.directory.studio.ldapbrowser.core.model.IBrowserConnection.ModifyOrder;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+
+
+/**
+ * The EditorParameterPage is used the edit the editor specific parameters of a
+ * connection.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class EditorParameterPage extends AbstractConnectionParameterPage
+{
+
+    private static final String X_MODIFY_MODE = "X-MODIFY-MODE"; //$NON-NLS-1$
+
+    private static final String X_MODIFY_MODE_NO_EMR = "X-MODIFY-MODE-NO-EMR"; //$NON-NLS-1$
+
+    private static final String X_MODIFY_ORDER = "X-MODIFY-ORDER"; //$NON-NLS-1$
+
+    /** The combo for selecting the modify mode */
+    private Combo modifyModeCombo;
+
+    /** The combo for selecting the modify mode of attribute with no equality matching rule */
+    private Combo modifyModeNoEMRCombo;
+
+    /** The combo for selecting the modify order */
+    private Combo modifyOrderCombo;
+
+
+    /**
+     * Creates a new instance of EditorParameterPage.
+     */
+    public EditorParameterPage()
+    {
+    }
+
+
+    /**
+     * Gets the modify mode.
+     * 
+     * @return the modify mode
+     */
+    private ModifyMode getModifyMode()
+    {
+        return ModifyMode.getByOrdinal( modifyModeCombo.getSelectionIndex() );
+    }
+
+
+    /**
+     * Gets the modify mode of attribute with no equality matching rule.
+     * 
+     * @return the modify mode of attribute with no equality matching rule
+     */
+    private ModifyMode getModifyModeNoEMR()
+    {
+        return ModifyMode.getByOrdinal( modifyModeNoEMRCombo.getSelectionIndex() );
+    }
+
+
+    /**
+     * Gets the modify mode.
+     * 
+     * @return the modify mode
+     */
+    private ModifyOrder getModifyOrder()
+    {
+        return ModifyOrder.getByOrdinal( modifyOrderCombo.getSelectionIndex() );
+    }
+
+
+    /**
+     * @see org.apache.directory.studio.connection.ui.AbstractConnectionParameterPage#createComposite(org.eclipse.swt.widgets.Composite)
+     */
+    protected void createComposite( Composite parent )
+    {
+        addModifyInput( parent );
+    }
+
+
+    /**
+     * Adds the modify input.
+     * 
+     * @param parent the parent
+     */
+    private void addModifyInput( Composite parent )
+    {
+        Composite composite = BaseWidgetUtils.createColumnContainer( parent, 1, 1 );
+
+        Group group = BaseWidgetUtils.createGroup( composite,
+            Messages.getString( "EditorParameterPage.ModifyGroup" ), 1 ); //$NON-NLS-1$
+        Composite groupComposite = BaseWidgetUtils.createColumnContainer( group, 2, 1 );
+
+        Label modifyModeLabel = BaseWidgetUtils.createLabel( groupComposite, Messages
+            .getString( "EditorParameterPage.ModifyMode" ), 1 ); //$NON-NLS-1$
+        modifyModeLabel.setToolTipText( Messages.getString( "EditorParameterPage.ModifyModeTooltip" ) ); //$NON-NLS-1$
+        String[] modifyModeItems = new String[]
+            { Messages.getString( "EditorParameterPage.ModifyModeDefault" ), //$NON-NLS-1$
+                Messages.getString( "EditorParameterPage.ModifyModeReplace" ), //$NON-NLS-1$
+                Messages.getString( "EditorParameterPage.ModifyModeAddDel" ) }; //$NON-NLS-1$
+        modifyModeCombo = BaseWidgetUtils.createReadonlyCombo( groupComposite, modifyModeItems, 0, 1 );
+        modifyModeCombo.setToolTipText( Messages.getString( "EditorParameterPage.ModifyModeTooltip" ) ); //$NON-NLS-1$
+
+        Label modifyModeNoEMRLabel = BaseWidgetUtils.createLabel( groupComposite, Messages
+            .getString( "EditorParameterPage.ModifyModeNoEMR" ), 1 ); //$NON-NLS-1$
+        modifyModeNoEMRLabel.setToolTipText( Messages.getString( "EditorParameterPage.ModifyModeNoEMRTooltip" ) ); //$NON-NLS-1$
+        String[] modifyModeNoEMRItems = new String[]
+            { Messages.getString( "EditorParameterPage.ModifyModeDefault" ), //$NON-NLS-1$
+                Messages.getString( "EditorParameterPage.ModifyModeReplace" ), //$NON-NLS-1$
+                Messages.getString( "EditorParameterPage.ModifyModeAddDel" ) }; //$NON-NLS-1$
+        modifyModeNoEMRCombo = BaseWidgetUtils.createReadonlyCombo( groupComposite, modifyModeNoEMRItems, 0, 1 );
+        modifyModeNoEMRCombo.setToolTipText( Messages.getString( "EditorParameterPage.ModifyModeNoEMRTooltip" ) ); //$NON-NLS-1$
+
+        Label modifyOrderLabel = BaseWidgetUtils.createLabel( groupComposite, Messages
+            .getString( "EditorParameterPage.ModifyOrder" ), 1 ); //$NON-NLS-1$
+        modifyOrderLabel.setToolTipText( Messages.getString( "EditorParameterPage.ModifyOrderTooltip" ) ); //$NON-NLS-1$
+        String[] modifyOrderItems = new String[]
+            { Messages.getString( "EditorParameterPage.ModifyOrderDelFirst" ), //$NON-NLS-1$
+                Messages.getString( "EditorParameterPage.ModifyOrderAddFirst" ) }; //$NON-NLS-1$
+        modifyOrderCombo = BaseWidgetUtils.createReadonlyCombo( groupComposite, modifyOrderItems, 0, 1 );
+        modifyOrderCombo.setToolTipText( Messages.getString( "EditorParameterPage.ModifyOrderTooltip" ) ); //$NON-NLS-1$
+    }
+
+
+    /**
+     * @see org.apache.directory.studio.connection.ui.AbstractConnectionParameterPage#validate()
+     */
+    protected void validate()
+    {
+    }
+
+
+    /**
+     * @see org.apache.directory.studio.connection.ui.AbstractConnectionParameterPage#loadParameters(org.apache.directory.studio.connection.core.ConnectionParameter)
+     */
+    protected void loadParameters( ConnectionParameter parameter )
+    {
+        this.connectionParameter = parameter;
+
+        int modifyMode = parameter.getExtendedIntProperty( IBrowserConnection.CONNECTION_PARAMETER_MODIFY_MODE );
+        modifyModeCombo.select( modifyMode );
+        int modifyModeNoEMR = parameter
+            .getExtendedIntProperty( IBrowserConnection.CONNECTION_PARAMETER_MODIFY_MODE_NO_EMR );
+        modifyModeNoEMRCombo.select( modifyModeNoEMR );
+        int modifyOrder = parameter.getExtendedIntProperty( IBrowserConnection.CONNECTION_PARAMETER_MODIFY_ORDER );
+        modifyOrderCombo.select( modifyOrder );
+    }
+
+
+    /**
+     * @see org.apache.directory.studio.connection.ui.AbstractConnectionParameterPage#initListeners()
+     */
+    protected void initListeners()
+    {
+        modifyModeCombo.addSelectionListener( new SelectionAdapter()
+        {
+            public void widgetSelected( SelectionEvent event )
+            {
+                connectionPageModified();
+            }
+        } );
+
+        modifyModeNoEMRCombo.addSelectionListener( new SelectionAdapter()
+        {
+            public void widgetSelected( SelectionEvent event )
+            {
+                connectionPageModified();
+            }
+        } );
+
+        modifyOrderCombo.addSelectionListener( new SelectionAdapter()
+        {
+            public void widgetSelected( SelectionEvent event )
+            {
+                connectionPageModified();
+            }
+        } );
+    }
+
+
+    /**
+     * @see org.apache.directory.studio.connection.ui.ConnectionParameterPage#saveParameters(org.apache.directory.studio.connection.core.ConnectionParameter)
+     */
+    public void saveParameters( ConnectionParameter parameter )
+    {
+        parameter.setExtendedIntProperty( IBrowserConnection.CONNECTION_PARAMETER_MODIFY_MODE, getModifyMode()
+            .getOrdinal() );
+        parameter.setExtendedIntProperty( IBrowserConnection.CONNECTION_PARAMETER_MODIFY_MODE_NO_EMR,
+            getModifyModeNoEMR().getOrdinal() );
+        parameter.setExtendedIntProperty( IBrowserConnection.CONNECTION_PARAMETER_MODIFY_ORDER, getModifyOrder()
+            .getOrdinal() );
+    }
+
+
+    /**
+     * @see org.apache.directory.studio.connection.ui.ConnectionParameterPage#saveDialogSettings()
+     */
+    public void saveDialogSettings()
+    {
+    }
+
+
+    /**
+     * @see org.apache.directory.studio.connection.ui.ConnectionParameterPage#setFocus()
+     */
+    public void setFocus()
+    {
+    }
+
+
+    /**
+     * @see org.apache.directory.studio.connection.ui.ConnectionParameterPage#areParametersModifed()
+     */
+    public boolean areParametersModifed()
+    {
+        int modifyMode = connectionParameter
+            .getExtendedIntProperty( IBrowserConnection.CONNECTION_PARAMETER_MODIFY_MODE );
+        int modifyModeNoEMR = connectionParameter
+            .getExtendedIntProperty( IBrowserConnection.CONNECTION_PARAMETER_MODIFY_MODE_NO_EMR );
+        int modifyOrder = connectionParameter
+            .getExtendedIntProperty( IBrowserConnection.CONNECTION_PARAMETER_MODIFY_ORDER );
+
+        return modifyMode != getModifyMode().getOrdinal() || modifyModeNoEMR != getModifyModeNoEMR().getOrdinal()
+            || modifyOrder != getModifyOrder().getOrdinal();
+    }
+
+
+    /**
+     * @see org.apache.directory.studio.connection.ui.ConnectionParameterPage#isReconnectionRequired()
+     */
+    public boolean isReconnectionRequired()
+    {
+        if ( connectionParameter == null )
+        {
+            return true;
+        }
+
+        return false;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void mergeParametersToLdapURL( ConnectionParameter parameter, LdapURL ldapUrl )
+    {
+        int modifyMode = connectionParameter
+            .getExtendedIntProperty( IBrowserConnection.CONNECTION_PARAMETER_MODIFY_MODE );
+        if ( modifyMode != 0 )
+        {
+            ldapUrl.getExtensions().add(
+                new Extension( false, X_MODIFY_MODE, parameter
+                    .getExtendedProperty( IBrowserConnection.CONNECTION_PARAMETER_MODIFY_MODE ) ) );
+        }
+
+        int modifyModeNoEMR = connectionParameter
+            .getExtendedIntProperty( IBrowserConnection.CONNECTION_PARAMETER_MODIFY_MODE_NO_EMR );
+        if ( modifyModeNoEMR != 0 )
+        {
+            ldapUrl.getExtensions().add(
+                new Extension( false, X_MODIFY_MODE_NO_EMR, parameter
+                    .getExtendedProperty( IBrowserConnection.CONNECTION_PARAMETER_MODIFY_MODE_NO_EMR ) ) );
+        }
+
+        int modifyOrder = connectionParameter
+            .getExtendedIntProperty( IBrowserConnection.CONNECTION_PARAMETER_MODIFY_ORDER );
+        if ( modifyOrder != 0 )
+        {
+            ldapUrl.getExtensions().add(
+                new Extension( false, X_MODIFY_ORDER, parameter
+                    .getExtendedProperty( IBrowserConnection.CONNECTION_PARAMETER_MODIFY_ORDER ) ) );
+        }
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void mergeLdapUrlToParameters( LdapURL ldapUrl, ConnectionParameter parameter )
+    {
+        // modify mode, DEFAULT if non-numeric or absent 
+        String modifyMode = ldapUrl.getExtensionValue( X_MODIFY_MODE );
+        try
+        {
+            parameter.setExtendedIntProperty( IBrowserConnection.CONNECTION_PARAMETER_MODIFY_MODE, new Integer(
+                modifyMode ).intValue() );
+        }
+        catch ( NumberFormatException e )
+        {
+            parameter.setExtendedIntProperty( IBrowserConnection.CONNECTION_PARAMETER_MODIFY_MODE, ModifyMode.DEFAULT
+                .getOrdinal() );
+        }
+
+        // modify mode no EMR, DEFAULT if non-numeric or absent 
+        String modifyModeNoEMR = ldapUrl.getExtensionValue( X_MODIFY_MODE_NO_EMR );
+        try
+        {
+            parameter.setExtendedIntProperty( IBrowserConnection.CONNECTION_PARAMETER_MODIFY_MODE_NO_EMR, new Integer(
+                modifyModeNoEMR ).intValue() );
+        }
+        catch ( NumberFormatException e )
+        {
+            parameter.setExtendedIntProperty( IBrowserConnection.CONNECTION_PARAMETER_MODIFY_MODE_NO_EMR,
+                ModifyMode.DEFAULT.getOrdinal() );
+        }
+
+        // modify order, DEL_FIRST if non-numeric or absent 
+        String modifyOrder = ldapUrl.getExtensionValue( X_MODIFY_ORDER );
+        try
+        {
+            parameter.setExtendedIntProperty( IBrowserConnection.CONNECTION_PARAMETER_MODIFY_ORDER, new Integer(
+                modifyOrder ).intValue() );
+        }
+        catch ( NumberFormatException e )
+        {
+            parameter.setExtendedIntProperty( IBrowserConnection.CONNECTION_PARAMETER_MODIFY_ORDER,
+                ModifyOrder.DELETE_FIRST.getOrdinal() );
+        }
+    }
+}

Modified: directory/studio/trunk/ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/connection/messages.properties
URL: http://svn.apache.org/viewvc/directory/studio/trunk/ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/connection/messages.properties?rev=824365&r1=824364&r2=824365&view=diff
==============================================================================
--- directory/studio/trunk/ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/connection/messages.properties (original)
+++ directory/studio/trunk/ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/connection/messages.properties Mon Oct 12 14:43:55 2009
@@ -32,4 +32,16 @@
 BrowserParameterPage.ScrollModeTooltip=If enabled only one page is fetched from the server at once while browsing, you could 'scroll' through the pages by using the 'next page' and 'top page' items. If disabled _all_ entries are fetched from the server, the paged result control is only used in background to avoid server-side limits.
 BrowserParameterPage.Features=Features
 BrowserParameterPage.FetchOperationalAttributesWhileBrowsing=Fetch operational attributes while browsing
-BrowserParameterPage.FetchOperationalAttributesWhileBrowsingTooltip=If enabled normal and operational attributes are retrieved.
\ No newline at end of file
+BrowserParameterPage.FetchOperationalAttributesWhileBrowsingTooltip=If enabled normal and operational attributes are retrieved.
+EditorParameterPage.ModifyGroup=Entry Modifcation
+EditorParameterPage.ModifyMode=Modify Mode:
+EditorParameterPage.ModifyModeAddDel=Always use ADD and/or DELETE
+EditorParameterPage.ModifyModeDefault=Optimized Modify Operations
+EditorParameterPage.ModifyModeNoEMR=Modify Mode (no equality matching rule):
+EditorParameterPage.ModifyModeNoEMRTooltip=Specify the modify mode for attributes with *no* equality matching rule.\n\nDescription of options:\n* Optimized Modify Operations: uses add/delete by default, uses replace if operation count is less\n* Always REPLACE: always uses replace operations to perform entry modifications\n* Always ADD/DELETE: always uses add and/or delete operations to perform entry modifications\n\nRecommended values for various LDAP servers:\n* ApacheDS: Optimized Modify Operations or REPLACE\n* OpenLDAP: REPLACE\n* OpenDS / SunDSEE: Optimized Modify Operations or REPLACE\n* FedoraDS / 389DS: Optimized Modify Operations (missing equality matching rules for many standard attribute types)\n* Active Directory: Optimized Modify Operations (exposes no equality matching rules at all)\n* eDirectory: Optimized Modify Operations (exposes no equality matching rules at all)
+EditorParameterPage.ModifyModeReplace=Always use REPLACE
+EditorParameterPage.ModifyModeTooltip=Specify the modify mode for attributes with an equality matching rule.\n\nDescription of options:\n* Optimized Modify Operations: uses add/delete by default, uses replace if operation count is less\n* Always REPLACE: always uses replace operations to perform entry modifications\n* Always ADD/DELETE: always uses add and/or delete operations to perform entry modifications\n\nRecommended value: Optimized Modify Operations
+EditorParameterPage.ModifyOrder=Modify Order:
+EditorParameterPage.ModifyOrderAddFirst=ADD First
+EditorParameterPage.ModifyOrderDelFirst=DELETE First
+EditorParameterPage.ModifyOrderTooltip=Specify the modify order when using add and delete operations.

Modified: directory/studio/trunk/ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/connection/messages_de.properties
URL: http://svn.apache.org/viewvc/directory/studio/trunk/ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/connection/messages_de.properties?rev=824365&r1=824364&r2=824365&view=diff
==============================================================================
--- directory/studio/trunk/ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/connection/messages_de.properties (original)
+++ directory/studio/trunk/ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/connection/messages_de.properties Mon Oct 12 14:43:55 2009
@@ -32,4 +32,16 @@
 BrowserParameterPage.ScrollModeTooltip=Wenn aktiviert, wird nur eine Seite vom Server abgerufen. Sie k\u00F6nnen durch die einzelnen Seiten Bl\u00E4ttern indem Sie auf 'N\u00E4chste Seite' bzw. 'Erste Seite' klicken. Wenn deaktiviert, werden alle Eintr\u00E4ge vom Server abgerufen. Die seitenwiese Suche wird nur im Hintergrund genutzt, um server-seitige Begrenzungen zu vermeiden.
 BrowserParameterPage.Features=Features
 BrowserParameterPage.FetchOperationalAttributesWhileBrowsing=Operationale Attribute w\u00E4hrend des Browsens abrufen
-BrowserParameterPage.FetchOperationalAttributesWhileBrowsingTooltip=Wenn aktiviert, werden normale und operationale Attribute abgerufen.
\ No newline at end of file
+BrowserParameterPage.FetchOperationalAttributesWhileBrowsingTooltip=Wenn aktiviert, werden normale und operationale Attribute abgerufen.
+EditorParameterPage.ModifyGroup=Eintrag \u00c4nderung
+EditorParameterPage.ModifyMode=\u00c4nderungsmodus:
+EditorParameterPage.ModifyModeAddDel=Immer ADD und/oder DELETE verwenden
+EditorParameterPage.ModifyModeDefault=Optimierte \u00c4nderungsoperationen
+EditorParameterPage.ModifyModeNoEMR=\u00c4nderungsmodus (keine Gleichheitsregel):
+EditorParameterPage.ModifyModeNoEMRTooltip=\u00c4nderungsmodus festlegen für Attribute *ohne* Gleichheitsregel.\n\nBeschreibung der Optionen:\n* Optimierte \u00c4nderungsoperationen: verwendet standardm\u00e4\u00dfig add/delete, verwendet replace wenn Anzahl der \u00c4nderungen kleiner ist\n* Immer REPLACE: Immer die replace Operation verwenden\n* Immer ADD/DELETE: Immer add und/oder delete Operationen verwenden\n\nEmpfohlene Werte f\u00fcr einige LDAP Server:\n* ApacheDS: Optimierte \u00c4nderungsoperationen oder REPLACE\n* OpenLDAP: REPLACE\n* OpenDS / Sun DSEE: Optimierte \u00c4nderungsoperationen oder REPLACE\n* FedoraDS / 389DS: Optimierte \u00c4nderungsoperationen (fehlende Gleichheitsregel für viele Standard-Attributtypen)\n* Active Directory: Optimierte \u00c4nderungsoperationen (keine Gleichheitsregel)\n* eDirectory: Optimierte \u00c4nderungsoperationen (keine Gleichheitsregel)
+EditorParameterPage.ModifyModeReplace=Immer REPLACE verwenden
+EditorParameterPage.ModifyModeTooltip=\u00c4nderungsmodus festlegen für Attribute mit einer Gleichheitsregel.\n\nBeschreibung der Optionen:\n* Optimierte \u00c4nderungsoperationen: verwendet standardm\u00e4\u00dfig add/delete, verwendet replace wenn Anzahl der \u00c4nderungen kleiner ist\n* Immer REPLACE: Immer die replace Operation verwenden\n* Immer ADD/DELETE: Immer add und/oder delete Operationen verwenden\n\nEmpfohlener Wert:Optimierte \u00c4nderungsoperationen
+EditorParameterPage.ModifyOrder=\u00c4nderungsreihenfolge:
+EditorParameterPage.ModifyOrderAddFirst=ADD zuerst
+EditorParameterPage.ModifyOrderDelFirst=DELETE zuerst
+EditorParameterPage.ModifyOrderTooltip=\u00c4nderungsreihenfolge festlegen, wenn ADD und DELETE Operationen verwendet werden

Modified: directory/studio/trunk/ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/connection/messages_fr.properties
URL: http://svn.apache.org/viewvc/directory/studio/trunk/ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/connection/messages_fr.properties?rev=824365&r1=824364&r2=824365&view=diff
==============================================================================
--- directory/studio/trunk/ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/connection/messages_fr.properties (original)
+++ directory/studio/trunk/ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/connection/messages_fr.properties Mon Oct 12 14:43:55 2009
@@ -32,4 +32,16 @@
 BrowserParameterPage.ScrollModeTooltip=Si activ\u00E9, une unique page r\u00E9cup\u00E9r\u00E9e du serveur, il est possible de faire d\u00E9filer les pages en utilisant les \u00E9l\u00E9ments 'page suivante' and 'haut de page'. Si d\u00E9sactiv\u00E9, _toutes_ les entr\u00E9es sont r\u00E9cup\u00E9r\u00E9es du serveur, le control paged results est uniquement utilis\u00E9 en arri\u00E8re-fond pour \u00E9viter d'atteindre les limites du serveur.
 BrowserParameterPage.Features=Fonctionnalit\u00E9s
 BrowserParameterPage.FetchOperationalAttributesWhileBrowsing=R\u00E9cup\u00E9rer les attributs op\u00E9rationnels au cours de la navigation
-BrowserParameterPage.FetchOperationalAttributesWhileBrowsingTooltip=Si activ\u00E9, les attributs normaux et op\u00E9rationnels sont r\u00E9cup\u00E9r\u00E9s.
\ No newline at end of file
+BrowserParameterPage.FetchOperationalAttributesWhileBrowsingTooltip=Si activ\u00E9, les attributs normaux et op\u00E9rationnels sont r\u00E9cup\u00E9r\u00E9s.
+EditorParameterPage.ModifyGroup=TODO:Entry Modifcation
+EditorParameterPage.ModifyMode=TODO:Modify Mode:
+EditorParameterPage.ModifyModeAddDel=TODO:Always use ADD and/or DELETE
+EditorParameterPage.ModifyModeDefault=TODO:Optimized Modify Operations
+EditorParameterPage.ModifyModeNoEMR=TODO:Modify Mode (no equality matching rule):
+EditorParameterPage.ModifyModeNoEMRTooltip=TODO:Specify the modify mode for attributes with *no* equality matching rule.\n\nDescription of options:\n* Optimized Modify Operations: uses add/delete by default, uses replace if operation count is less\n* Always REPLACE: always uses replace operations to perform entry modifications\n* Always ADD/DELETE: always uses add and/or delete operations to perform entry modifications\n\nRecommended values for various LDAP servers:\n* ApacheDS: Optimized Modify Operations or REPLACE\n* OpenLDAP: REPLACE\n* OpenDS / SunDSEE: Optimized Modify Operations or REPLACE\n* FedoraDS / 389DS: Optimized Modify Operations (missing equality matching rules for many standard attribute types)\n* Active Directory: Optimized Modify Operations (exposes no equality matching rules at all)\n* eDirectory: Optimized Modify Operations (exposes no equality matching rules at all)
+EditorParameterPage.ModifyModeReplace=TODO:Always use REPLACE
+EditorParameterPage.ModifyModeTooltip=TODO:Specify the modify mode for attributes with an equality matching rule.\n\nDescription of options:\n* Optimized Modify Operations: uses add/delete by default, uses replace if operation count is less\n* Always REPLACE: always uses replace operations to perform entry modifications\n* Always ADD/DELETE: always uses add and/or delete operations to perform entry modifications\n\nRecommended value: Optimized Modify Operations
+EditorParameterPage.ModifyOrder=TODO:Modify Order:
+EditorParameterPage.ModifyOrderAddFirst=TODO:ADD First
+EditorParameterPage.ModifyOrderDelFirst=TODO:DELETE First
+EditorParameterPage.ModifyOrderTooltip=TODO:Specify the modify order when using add and delete operations.

Modified: directory/studio/trunk/ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/IBrowserConnection.java
URL: http://svn.apache.org/viewvc/directory/studio/trunk/ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/IBrowserConnection.java?rev=824365&r1=824364&r2=824365&view=diff
==============================================================================
--- directory/studio/trunk/ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/IBrowserConnection.java (original)
+++ directory/studio/trunk/ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/IBrowserConnection.java Mon Oct 12 14:43:55 2009
@@ -47,6 +47,121 @@
 public interface IBrowserConnection extends Serializable, IAdaptable, ConnectionPropertyPageProvider
 {
 
+    /**
+     * Enum for the modify mode of attributes
+     *
+     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+     * @version $Rev$, $Date$
+     */
+    public enum ModifyMode
+    {
+        /** Default mode */
+        DEFAULT(0),
+
+        /** Always use replace operation */
+        REPLACE(1),
+
+        /** Always use add/delete operation */
+        ADD_DELETE(2);
+
+        private final int ordinal;
+
+
+        private ModifyMode( int ordinal )
+        {
+            this.ordinal = ordinal;
+        }
+
+
+        /**
+         * Gets the ordinal.
+         * 
+         * @return the ordinal
+         */
+        public int getOrdinal()
+        {
+            return ordinal;
+        }
+
+
+        /**
+         * Gets the ModifyMode by ordinal.
+         * 
+         * @param ordinal the ordinal
+         * 
+         * @return the ModifyMode
+         */
+        public static ModifyMode getByOrdinal( int ordinal )
+        {
+            switch ( ordinal )
+            {
+                case 0:
+                    return DEFAULT;
+                case 1:
+                    return REPLACE;
+                case 2:
+                    return ADD_DELETE;
+                default:
+                    return null;
+            }
+        }
+    }
+
+    /**
+     * Enum for modify order when using add/delete operations
+     *
+     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+     * @version $Rev$, $Date$
+     */
+    public enum ModifyOrder
+    {
+        /** Delete first */
+        DELETE_FIRST(0),
+
+        /** Add first */
+        ADD_FIRST(1);
+
+        private final int ordinal;
+
+
+        private ModifyOrder( int ordinal )
+        {
+            this.ordinal = ordinal;
+        }
+
+
+        /**
+         * Gets the ordinal.
+         * 
+         * @return the ordinal
+         */
+        public int getOrdinal()
+        {
+            return ordinal;
+        }
+
+
+        /**
+         * Gets the ModifyOrder by ordinal.
+         * 
+         * @param ordinal the ordinal
+         * 
+         * @return the ModifyOrder
+         */
+        public static ModifyOrder getByOrdinal( int ordinal )
+        {
+            switch ( ordinal )
+            {
+                case 0:
+                    return DELETE_FIRST;
+                case 1:
+                    return ADD_FIRST;
+                default:
+                    return null;
+            }
+        }
+    }
+
     /** The key for the connection parameter "Get Base DNs from Root DSE". */
     public static String CONNECTION_PARAMETER_FETCH_BASE_DNS = "ldapbrowser.fetchBaseDns";
 
@@ -80,8 +195,14 @@
     /** The key for the connection parameter "Paged Search Scroll Mode". */
     public static String CONNECTION_PARAMETER_PAGED_SEARCH_SCROLL_MODE = "ldapbrowser.pagedSearchScrollMode";
 
-    /** The MangageDsaIT control OID. */
-    public static final String CONTROL_MANAGEDSAIT = "2.16.840.1.113730.3.4.2"; //$NON-NLS-1$
+    /** The key for the connection parameter "Modify Mode for attributes with equality matching rule". */
+    public static String CONNECTION_PARAMETER_MODIFY_MODE = "ldapbrowser.modifyMode";
+
+    /** The key for the connection parameter "Modify Mode for attributes without equality matching rule". */
+    public static String CONNECTION_PARAMETER_MODIFY_MODE_NO_EMR = "ldapbrowser.modifyModeNoEMR";
+
+    /** The key for the connection parameter "Modify add delete order". */
+    public static String CONNECTION_PARAMETER_MODIFY_ORDER = "ldapbrowser.modifyOrder";
 
 
     /**
@@ -273,6 +394,54 @@
 
 
     /**
+     * Gets the modify mode for attributes.
+     * 
+     * @return the modify mode for attributes
+     */
+    public abstract ModifyMode getModifyMode();
+
+
+    /**
+     * Sets the modify mode for attributes.
+     * 
+     * @param mode the modify mode for attributes
+     */
+    public abstract void setModifyMode( ModifyMode mode );
+
+
+    /**
+     * Gets the modify mode for attributes without equality matching rule.
+     * 
+     * @return the modify mode for attributes without equality matching rule
+     */
+    public abstract ModifyMode getModifyModeNoEMR();
+
+
+    /**
+     * Sets the modify mode for attributes without equality matching rule.
+     * 
+     * @param mode the modify mode for attributes without equality matching rule
+     */
+    public abstract void setModifyModeNoEMR( ModifyMode mode );
+
+
+    /**
+     * Gets the modify add/delete order.
+     * 
+     * @return the modify add/delete order
+     */
+    public abstract ModifyOrder getModifyAddDeleteOrder();
+
+
+    /**
+     * Sets the modify add/delete order.
+     * 
+     * @param mode the modify add/delete order
+     */
+    public abstract void setModifyAddDeleteOrder( ModifyOrder mode );
+
+
+    /**
      * Gets the root DSE.
      * 
      * @return the root DSE

Modified: directory/studio/trunk/ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/impl/BrowserConnection.java
URL: http://svn.apache.org/viewvc/directory/studio/trunk/ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/impl/BrowserConnection.java?rev=824365&r1=824364&r2=824365&view=diff
==============================================================================
--- directory/studio/trunk/ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/impl/BrowserConnection.java (original)
+++ directory/studio/trunk/ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/impl/BrowserConnection.java Mon Oct 12 14:43:55 2009
@@ -109,6 +109,15 @@
             connection.getConnectionParameter().setExtendedBoolProperty( CONNECTION_PARAMETER_PAGED_SEARCH_SCROLL_MODE,
                 true );
         }
+        if ( connection.getConnectionParameter().getExtendedProperty( CONNECTION_PARAMETER_MODIFY_MODE ) == null )
+        {
+            connection.getConnectionParameter().setExtendedIntProperty( CONNECTION_PARAMETER_MODIFY_MODE,
+                ModifyMode.DEFAULT.getOrdinal() );
+            connection.getConnectionParameter().setExtendedIntProperty( CONNECTION_PARAMETER_MODIFY_MODE_NO_EMR,
+                ModifyMode.DEFAULT.getOrdinal() );
+            connection.getConnectionParameter().setExtendedIntProperty( CONNECTION_PARAMETER_MODIFY_ORDER,
+                ModifyOrder.DELETE_FIRST.getOrdinal() );
+        }
 
         this.searchManager = new SearchManager( this );
         this.bookmarkManager = new BookmarkManager( this );
@@ -405,6 +414,70 @@
     }
 
 
+    /** 
+     * {@inheritDoc}
+     */
+    public ModifyMode getModifyMode()
+    {
+        int ordinal = connection.getConnectionParameter().getExtendedIntProperty( CONNECTION_PARAMETER_MODIFY_MODE );
+        return ModifyMode.getByOrdinal( ordinal );
+    }
+
+
+    /** 
+     * {@inheritDoc}
+     */
+    public void setModifyMode( ModifyMode mode )
+    {
+        connection.getConnectionParameter()
+            .setExtendedIntProperty( CONNECTION_PARAMETER_MODIFY_MODE, mode.getOrdinal() );
+        ConnectionEventRegistry.fireConnectionUpdated( connection, this );
+    }
+
+
+    /** 
+     * {@inheritDoc}
+     */
+    public ModifyMode getModifyModeNoEMR()
+    {
+        int ordinal = connection.getConnectionParameter().getExtendedIntProperty(
+            CONNECTION_PARAMETER_MODIFY_MODE_NO_EMR );
+        return ModifyMode.getByOrdinal( ordinal );
+    }
+
+
+    /** 
+     * {@inheritDoc}
+     */
+    public void setModifyModeNoEMR( ModifyMode mode )
+    {
+        connection.getConnectionParameter().setExtendedIntProperty( CONNECTION_PARAMETER_MODIFY_MODE_NO_EMR,
+            mode.getOrdinal() );
+        ConnectionEventRegistry.fireConnectionUpdated( connection, this );
+    }
+
+
+    /** 
+     * {@inheritDoc}
+     */
+    public ModifyOrder getModifyAddDeleteOrder()
+    {
+        int ordinal = connection.getConnectionParameter().getExtendedIntProperty( CONNECTION_PARAMETER_MODIFY_ORDER );
+        return ModifyOrder.getByOrdinal( ordinal );
+    }
+
+
+    /** 
+     * {@inheritDoc}
+     */
+    public void setModifyAddDeleteOrder( ModifyOrder mode )
+    {
+        connection.getConnectionParameter().setExtendedIntProperty( CONNECTION_PARAMETER_MODIFY_ORDER,
+            mode.getOrdinal() );
+        ConnectionEventRegistry.fireConnectionUpdated( connection, this );
+    }
+
+
     /**
      * {@inheritDoc}
      */

Modified: directory/studio/trunk/ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/impl/DummyConnection.java
URL: http://svn.apache.org/viewvc/directory/studio/trunk/ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/impl/DummyConnection.java?rev=824365&r1=824364&r2=824365&view=diff
==============================================================================
--- directory/studio/trunk/ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/impl/DummyConnection.java (original)
+++ directory/studio/trunk/ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/impl/DummyConnection.java Mon Oct 12 14:43:55 2009
@@ -305,6 +305,57 @@
     /** 
      * {@inheritDoc}
      */
+    public ModifyMode getModifyMode()
+    {
+        return ModifyMode.DEFAULT;
+    }
+
+
+    /** 
+     * {@inheritDoc}
+     */
+    public void setModifyMode( ModifyMode mode )
+    {
+    }
+
+
+    /** 
+     * {@inheritDoc}
+     */
+    public ModifyMode getModifyModeNoEMR()
+    {
+        return ModifyMode.DEFAULT;
+    }
+
+
+    /** 
+     * {@inheritDoc}
+     */
+    public void setModifyModeNoEMR( ModifyMode mode )
+    {
+    }
+
+
+    /** 
+     * {@inheritDoc}
+     */
+    public ModifyOrder getModifyAddDeleteOrder()
+    {
+        return ModifyOrder.DELETE_FIRST;
+    }
+
+
+    /** 
+     * {@inheritDoc}
+     */
+    public void setModifyAddDeleteOrder( ModifyOrder mode )
+    {
+    }
+
+
+    /** 
+     * {@inheritDoc}
+     */
     public boolean isPagedSearchScrollMode()
     {
         return false;

Modified: directory/studio/trunk/ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/utils/ModelConverter.java
URL: http://svn.apache.org/viewvc/directory/studio/trunk/ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/utils/ModelConverter.java?rev=824365&r1=824364&r2=824365&view=diff
==============================================================================
--- directory/studio/trunk/ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/utils/ModelConverter.java (original)
+++ directory/studio/trunk/ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/utils/ModelConverter.java Mon Oct 12 14:43:55 2009
@@ -39,6 +39,7 @@
 import org.apache.directory.studio.ldapbrowser.core.model.IBrowserConnection;
 import org.apache.directory.studio.ldapbrowser.core.model.IEntry;
 import org.apache.directory.studio.ldapbrowser.core.model.IValue;
+import org.apache.directory.studio.ldapbrowser.core.model.StudioControl;
 import org.apache.directory.studio.ldapbrowser.core.model.impl.Attribute;
 import org.apache.directory.studio.ldapbrowser.core.model.impl.DummyEntry;
 import org.apache.directory.studio.ldapbrowser.core.model.impl.Value;
@@ -285,7 +286,8 @@
     {
         if ( entry.isReferral() )
         {
-            cr.addControl( LdifControlLine.create( IBrowserConnection.CONTROL_MANAGEDSAIT, null, ( String ) null ) );
+            cr.addControl( LdifControlLine.create( StudioControl.MANAGEDSAIT_CONTROL.getOid(),
+                StudioControl.MANAGEDSAIT_CONTROL.isCritical(), StudioControl.MANAGEDSAIT_CONTROL.getControlValue() ) );
         }
     }
 

Modified: directory/studio/trunk/ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/utils/Utils.java
URL: http://svn.apache.org/viewvc/directory/studio/trunk/ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/utils/Utils.java?rev=824365&r1=824364&r2=824365&view=diff
==============================================================================
--- directory/studio/trunk/ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/utils/Utils.java (original)
+++ directory/studio/trunk/ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/utils/Utils.java Mon Oct 12 14:43:55 2009
@@ -25,10 +25,14 @@
 import java.beans.XMLEncoder;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import org.apache.directory.shared.ldap.name.AttributeTypeAndValue;
@@ -45,6 +49,8 @@
 import org.apache.directory.studio.ldapbrowser.core.model.ISearch;
 import org.apache.directory.studio.ldapbrowser.core.model.IValue;
 import org.apache.directory.studio.ldapbrowser.core.model.StudioControl;
+import org.apache.directory.studio.ldapbrowser.core.model.IBrowserConnection.ModifyMode;
+import org.apache.directory.studio.ldapbrowser.core.model.IBrowserConnection.ModifyOrder;
 import org.apache.directory.studio.ldapbrowser.core.model.schema.Schema;
 import org.apache.directory.studio.ldapbrowser.core.model.schema.SchemaUtils;
 import org.apache.directory.studio.ldifparser.LdifFormatParameters;
@@ -339,197 +345,242 @@
      * and returns an LDIF that could be applied to the old entry
      * to get new entry.
      *
-     * @param t0 the old entry
-     * @param t1 the new entry
+     * @param oldEntry the old entry
+     * @param newEntry the new entry
      * @return the change modify record or null if there is no difference
      *         between the two entries
      */
-    public static LdifFile computeDiff( IEntry t0, IEntry t1 )
+    public static LdifFile computeDiff( IEntry oldEntry, IEntry newEntry )
     {
-        LdifFile model = new LdifFile();
+        // get connection parameters
+        ModifyMode modifyMode = oldEntry.getBrowserConnection().getModifyMode();
+        ModifyMode modifyModeNoEMR = oldEntry.getBrowserConnection().getModifyModeNoEMR();
+        ModifyOrder modifyAddDeleteOrder = oldEntry.getBrowserConnection().getModifyAddDeleteOrder();
 
-        // check attributes of old entry
-        Set<String> attributesToDelAdd = new HashSet<String>();
-        Set<String> attributesToReplace = new HashSet<String>();
-        for ( IAttribute oldAttr : t0.getAttributes() )
-        {
-            String attributeDescription = oldAttr.getDescription();
-
-            Schema schema = oldAttr.getEntry().getBrowserConnection().getSchema();
-            AttributeTypeDescription atd = schema.getAttributeTypeDescription( oldAttr.getType() );
-            String emr = SchemaUtils.getEqualityMatchingRuleNameOrNumericOidTransitive( atd, schema );
-            boolean hasEMR = emr != null;
-            if ( hasEMR )
-            {
-                attributesToDelAdd.add( attributeDescription );
-            }
-            else
-            {
-                attributesToReplace.add( attributeDescription );
-            }
+        // get all attribute descriptions
+        Set<String> attributeDescriptions = new HashSet<String>();
+        for ( IAttribute oldAttr : oldEntry.getAttributes() )
+        {
+            attributeDescriptions.add( oldAttr.getDescription() );
         }
-
-        // check attributes of new entry
-        for ( IAttribute newAttr : t1.getAttributes() )
+        for ( IAttribute newAttr : newEntry.getAttributes() )
         {
-            String attributeDescription = newAttr.getDescription();
-
-            Schema schema = newAttr.getEntry().getBrowserConnection().getSchema();
-            AttributeTypeDescription atd = schema.getAttributeTypeDescription( newAttr.getType() );
-            String emr = SchemaUtils.getEqualityMatchingRuleNameOrNumericOidTransitive( atd, schema );
-            boolean hasEMR = emr != null;
-
-            if ( hasEMR )
-            {
-                attributesToDelAdd.add( attributeDescription );
-            }
-            else
-            {
-                attributesToReplace.add( attributeDescription );
-            }
+            attributeDescriptions.add( newAttr.getDescription() );
         }
 
-        LdifChangeModifyRecord record = new LdifChangeModifyRecord( LdifDnLine.create( t1.getDn().getUpName() ) );
-        if ( t1.isReferral() )
+        // prepare the LDIF record containing the modifications
+        LdifChangeModifyRecord record = new LdifChangeModifyRecord( LdifDnLine.create( newEntry.getDn().getUpName() ) );
+        if ( newEntry.isReferral() )
         {
             record.addControl( LdifControlLine.create( StudioControl.MANAGEDSAIT_CONTROL.getOid(),
                 StudioControl.MANAGEDSAIT_CONTROL.isCritical(), StudioControl.MANAGEDSAIT_CONTROL.getControlValue() ) );
         }
         record.setChangeType( LdifChangeTypeLine.createModify() );
 
-        // determine attributes to delete and/or add
-        for ( String attributeDescription : attributesToDelAdd )
+        // check all the attributes
+        for ( String attributeDescription : attributeDescriptions )
         {
-            IAttribute oldAttribute = t0.getAttribute( attributeDescription );
-            IAttribute newAttribute = t1.getAttribute( attributeDescription );
+            // get attribute type schema information
+            Schema schema = oldEntry.getBrowserConnection().getSchema();
+            AttributeTypeDescription atd = schema.getAttributeTypeDescription( attributeDescription );
+            boolean hasEMR = SchemaUtils.getEqualityMatchingRuleNameOrNumericOidTransitive( atd, schema ) != null;
+            boolean isReplaceForced = ( hasEMR && modifyMode == ModifyMode.REPLACE )
+                || ( !hasEMR && modifyModeNoEMR == ModifyMode.REPLACE );
+            boolean isAddDelForced = ( hasEMR && modifyMode == ModifyMode.ADD_DELETE )
+                || ( !hasEMR && modifyModeNoEMR == ModifyMode.ADD_DELETE );
+            boolean isOrderedValue = atd.getExtensions().containsKey( "X-ORDERED" )
+                && atd.getExtensions().get( "X-ORDERED" ).contains( "VALUES" );
 
+            // get old an new values for comparison
+            IAttribute oldAttribute = oldEntry.getAttribute( attributeDescription );
             Set<String> oldValues = new HashSet<String>();
+            Map<String, LdifAttrValLine> oldAttrValLines = new LinkedHashMap<String, LdifAttrValLine>();
             if ( oldAttribute != null )
             {
-                oldValues.addAll( Arrays.asList( oldAttribute.getStringValues() ) );
+                for ( IValue value : oldAttribute.getValues() )
+                {
+                    LdifAttrValLine attrValLine = computeDiffCreateAttrValLine( value );
+                    oldValues.add( attrValLine.getUnfoldedValue() );
+                    oldAttrValLines.put( attrValLine.getUnfoldedValue(), attrValLine );
+                }
             }
+            IAttribute newAttribute = newEntry.getAttribute( attributeDescription );
             Set<String> newValues = new HashSet<String>();
+            Map<String, LdifAttrValLine> newAttrValLines = new LinkedHashMap<String, LdifAttrValLine>();
             if ( newAttribute != null )
             {
-                newValues.addAll( Arrays.asList( newAttribute.getStringValues() ) );
+                for ( IValue value : newAttribute.getValues() )
+                {
+                    LdifAttrValLine attrValLine = computeDiffCreateAttrValLine( value );
+                    newValues.add( attrValLine.getUnfoldedValue() );
+                    newAttrValLines.put( attrValLine.getUnfoldedValue(), attrValLine );
+                }
             }
 
-            if ( oldAttribute != null )
+            // check what to do
+            if ( oldAttribute != null && newAttribute == null )
             {
-                LdifModSpec modSpec = LdifModSpec.createDelete( attributeDescription );
-                for ( IValue oldValue : oldAttribute.getValues() )
+                // attribute only exists in the old entry: delete all values
+                LdifModSpec modSpec;
+                if ( isReplaceForced )
                 {
-                    if ( oldValue.isEmpty() )
-                    {
-                        return null;
-                    }
-
-                    if ( !newValues.contains( oldValue.getStringValue() ) )
-                    {
-                        if ( oldAttribute.isBinary() )
-                        {
-                            modSpec.addAttrVal( LdifAttrValLine
-                                .create( attributeDescription, oldValue.getBinaryValue() ) );
-                        }
-                        else
-                        {
-                            modSpec.addAttrVal( LdifAttrValLine
-                                .create( attributeDescription, oldValue.getStringValue() ) );
-                        }
-                    }
+                    // replace (empty value list)
+                    modSpec = LdifModSpec.createReplace( attributeDescription );
+                }
+                else
+                // addDelForced or default
+                {
+                    // delete all
+                    modSpec = LdifModSpec.createDelete( attributeDescription );
                 }
                 modSpec.finish( LdifModSpecSepLine.create() );
-                if ( modSpec.getAttrVals().length > 0 )
+                record.addModSpec( modSpec );
+            }
+            else if ( oldAttribute == null && newAttribute != null )
+            {
+                // attribute only exists in the new entry: add all values
+                LdifModSpec modSpec;
+                if ( isReplaceForced )
                 {
-                    record.addModSpec( modSpec );
+                    // replace (all values)
+                    modSpec = LdifModSpec.createReplace( attributeDescription );
+                }
+                else
+                // addDelForced or default 
+                {
+                    // add (all new values)
+                    modSpec = LdifModSpec.createAdd( attributeDescription );
+                }
+                for ( IValue value : newAttribute.getValues() )
+                {
+                    modSpec.addAttrVal( computeDiffCreateAttrValLine( value ) );
                 }
+                modSpec.finish( LdifModSpecSepLine.create() );
+                record.addModSpec( modSpec );
             }
-
-            if ( newAttribute != null )
+            else if ( oldAttribute != null && newAttribute != null && !oldValues.equals( newValues ) )
             {
-                LdifModSpec modSpec = LdifModSpec.createAdd( attributeDescription );
-                for ( IValue newValue : newAttribute.getValues() )
+                // attribute exists in both entries, check modifications
+                if ( isReplaceForced )
                 {
-                    if ( newValue.isEmpty() )
+                    // replace (all new values)
+                    LdifModSpec modSpec = LdifModSpec.createReplace( attributeDescription );
+                    for ( IValue value : newAttribute.getValues() )
                     {
-                        return null;
+                        modSpec.addAttrVal( computeDiffCreateAttrValLine( value ) );
                     }
+                    modSpec.finish( LdifModSpecSepLine.create() );
+                    record.addModSpec( modSpec );
+                }
+                else
+                {
+                    // compute diff
+                    List<LdifAttrValLine> toDel = new ArrayList<LdifAttrValLine>();
+                    List<LdifAttrValLine> toAdd = new ArrayList<LdifAttrValLine>();
 
-                    if ( !oldValues.contains( newValue.getStringValue() ) )
+                    for ( Map.Entry<String, LdifAttrValLine> entry : oldAttrValLines.entrySet() )
                     {
-                        if ( newAttribute.isBinary() )
+                        if ( !newValues.contains( entry.getKey() ) )
                         {
-                            modSpec.addAttrVal( LdifAttrValLine
-                                .create( attributeDescription, newValue.getBinaryValue() ) );
+                            toDel.add( entry.getValue() );
                         }
-                        else
+                    }
+                    for ( Map.Entry<String, LdifAttrValLine> entry : newAttrValLines.entrySet() )
+                    {
+                        if ( !oldValues.contains( entry.getKey() ) )
                         {
-                            modSpec.addAttrVal( LdifAttrValLine
-                                .create( attributeDescription, newValue.getStringValue() ) );
+                            toAdd.add( entry.getValue() );
                         }
                     }
-                }
-                modSpec.finish( LdifModSpecSepLine.create() );
-                if ( modSpec.getAttrVals().length > 0 )
-                {
-                    record.addModSpec( modSpec );
-                }
-            }
-        }
-
-        // determine attributes to replace
-        for ( String attributeDescription : attributesToReplace )
-        {
-            IAttribute oldAttribute = t0.getAttribute( attributeDescription );
-            IAttribute newAttribute = t1.getAttribute( attributeDescription );
-
-            Set<String> oldValues = new HashSet<String>();
-            if ( oldAttribute != null )
-            {
-                oldValues.addAll( Arrays.asList( oldAttribute.getStringValues() ) );
-            }
-            Set<String> newValues = new HashSet<String>();
-            if ( newAttribute != null )
-            {
-                newValues.addAll( Arrays.asList( newAttribute.getStringValues() ) );
-            }
 
-            if ( !newValues.equals( oldValues ) )
-            {
-                LdifModSpec modSpec = LdifModSpec.createReplace( attributeDescription );
-                if ( newAttribute != null )
-                {
-                    for ( IValue newValue : newAttribute.getValues() )
+                    /*
+                     *  we use add/del in the following cases:
+                     *  - add/del is forced in the connection configuration
+                     *  - only values to add
+                     *  - only values to delete
+                     *  - the sum of adds and deletes is smaller or equal than the number of replaces
+                     *  
+                     *  we use replace in the following cases:
+                     *  - the number of replaces is smaller to the sum of adds and deletes
+                     *  - for attributes with X-ORDERED 'VALUES'
+                     */
+                    if ( isAddDelForced || ( toAdd.size() + toDel.size() <= newAttrValLines.size() && !isOrderedValue )
+                        || ( !toDel.isEmpty() && toAdd.isEmpty() ) || ( !toAdd.isEmpty() && toDel.isEmpty() ) )
                     {
-                        if ( newValue.isEmpty() )
+                        // add/del del/add
+                        LdifModSpec addModSpec = LdifModSpec.createAdd( attributeDescription );
+                        for ( LdifAttrValLine attrValLine : toAdd )
+                        {
+                            addModSpec.addAttrVal( attrValLine );
+                        }
+                        addModSpec.finish( LdifModSpecSepLine.create() );
+                        LdifModSpec delModSpec = LdifModSpec.createDelete( attributeDescription );
+                        for ( LdifAttrValLine attrValLine : toDel )
                         {
-                            return null;
+                            delModSpec.addAttrVal( attrValLine );
                         }
+                        delModSpec.finish( LdifModSpecSepLine.create() );
 
-                        if ( newAttribute.isBinary() )
+                        if ( modifyAddDeleteOrder == ModifyOrder.DELETE_FIRST )
                         {
-                            modSpec.addAttrVal( LdifAttrValLine
-                                .create( attributeDescription, newValue.getBinaryValue() ) );
+                            if ( delModSpec.getAttrVals().length > 0 )
+                            {
+                                record.addModSpec( delModSpec );
+                            }
+                            if ( addModSpec.getAttrVals().length > 0 )
+                            {
+                                record.addModSpec( addModSpec );
+                            }
                         }
                         else
                         {
-                            modSpec.addAttrVal( LdifAttrValLine
-                                .create( attributeDescription, newValue.getStringValue() ) );
+                            if ( addModSpec.getAttrVals().length > 0 )
+                            {
+                                record.addModSpec( addModSpec );
+                            }
+                            if ( delModSpec.getAttrVals().length > 0 )
+                            {
+                                record.addModSpec( delModSpec );
+                            }
                         }
                     }
+                    else
+                    {
+                        // replace (all new values)
+                        LdifModSpec modSpec = LdifModSpec.createReplace( attributeDescription );
+                        for ( LdifAttrValLine attrValLine : newAttrValLines.values() )
+                        {
+                            modSpec.addAttrVal( attrValLine );
+                        }
+                        modSpec.finish( LdifModSpecSepLine.create() );
+                        record.addModSpec( modSpec );
+                    }
                 }
-                modSpec.finish( LdifModSpecSepLine.create() );
-                record.addModSpec( modSpec );
             }
+
         }
 
         record.finish( LdifSepLine.create() );
+
+        LdifFile model = new LdifFile();
         if ( record.isValid() && record.getModSpecs().length > 0 )
         {
             model.addContainer( record );
         }
-
         return model.getRecords().length > 0 ? model : null;
     }
 
+
+    private static LdifAttrValLine computeDiffCreateAttrValLine( IValue value )
+    {
+        IAttribute attribute = value.getAttribute();
+        if ( attribute.isBinary() )
+        {
+            return LdifAttrValLine.create( attribute.getDescription(), value.getBinaryValue() );
+        }
+        else
+        {
+            return LdifAttrValLine.create( attribute.getDescription(), value.getStringValue() );
+        }
+    }
 }