directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From seelm...@apache.org
Subject svn commit: r814009 [2/3] - in /directory/studio/trunk: ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/actions/ ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/entryeditor/ ldapbr...
Date Fri, 11 Sep 2009 20:12:00 GMT
Modified: directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/entryeditors/EntryEditorManager.java
URL: http://svn.apache.org/viewvc/directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/entryeditors/EntryEditorManager.java?rev=814009&r1=814008&r2=814009&view=diff
==============================================================================
--- directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/entryeditors/EntryEditorManager.java (original)
+++ directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/entryeditors/EntryEditorManager.java Fri Sep 11 20:11:30 2009
@@ -25,21 +25,43 @@
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
+import org.apache.directory.shared.ldap.name.LdapDN;
+import org.apache.directory.studio.connection.ui.RunnableContextRunner;
+import org.apache.directory.studio.ldapbrowser.common.BrowserCommonActivator;
+import org.apache.directory.studio.ldapbrowser.core.events.EntryModificationEvent;
+import org.apache.directory.studio.ldapbrowser.core.events.EntryUpdateListener;
+import org.apache.directory.studio.ldapbrowser.core.events.EventRegistry;
+import org.apache.directory.studio.ldapbrowser.core.jobs.ExecuteLdifRunnable;
 import org.apache.directory.studio.ldapbrowser.core.model.IBookmark;
+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.ISearchResult;
+import org.apache.directory.studio.ldapbrowser.core.utils.CompoundModification;
+import org.apache.directory.studio.ldapbrowser.core.utils.Utils;
 import org.apache.directory.studio.ldapbrowser.ui.BrowserUIConstants;
 import org.apache.directory.studio.ldapbrowser.ui.BrowserUIPlugin;
+import org.apache.directory.studio.ldifparser.LdifFormatParameters;
+import org.apache.directory.studio.ldifparser.model.container.LdifChangeModifyRecord;
 import org.eclipse.core.runtime.IConfigurationElement;
 import org.eclipse.core.runtime.IExtension;
 import org.eclipse.core.runtime.IExtensionPoint;
 import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Platform;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.MessageDialog;
 import org.eclipse.jface.resource.ImageDescriptor;
 import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorReference;
+import org.eclipse.ui.IPartListener2;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchPartReference;
 import org.eclipse.ui.PartInitException;
 import org.eclipse.ui.PlatformUI;
 import org.eclipse.ui.plugin.AbstractUIPlugin;
@@ -121,6 +143,9 @@
     public EntryEditorManager()
     {
         initEntryEditorExtensions();
+        PlatformUI.getWorkbench().getActiveWorkbenchWindow().getPartService().addPartListener( partListener );
+        EventRegistry
+            .addEntryUpdateListener( entryUpdateListener, BrowserCommonActivator.getDefault().getEventRunner() );
     }
 
 
@@ -164,6 +189,13 @@
     }
 
 
+    public void dispose()
+    {
+        PlatformUI.getWorkbench().getActiveWorkbenchWindow().getPartService().removePartListener( partListener );
+        EventRegistry.removeEntryUpdateListener( entryUpdateListener );
+    }
+
+
     /**
      * Gets the entry editor extensions.
      * 
@@ -351,8 +383,7 @@
         }
         catch ( PartInitException e )
         {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
+            throw new RuntimeException( e );
         }
     }
 
@@ -376,4 +407,491 @@
         EntryEditorExtension next = entryEditors.iterator().next();
         openEntryEditor( next, entries, searchResults, bookmarks );
     }
+
+    /** The shared reference copies for open-save-close editors; original entry -> reference copy */
+    private Map<IEntry, IEntry> oscSharedReferenceCopies = new HashMap<IEntry, IEntry>();
+
+    /** The shared working copies for open-save-close editors; original entry -> working copy */
+    private Map<IEntry, IEntry> oscSharedWorkingCopies = new HashMap<IEntry, IEntry>();
+
+    /** The shared reference copies for auto-save editors; original entry -> reference copy */
+    private Map<IEntry, IEntry> autoSaveSharedReferenceCopies = new HashMap<IEntry, IEntry>();
+
+    /** The shared working copies for auto-save editors; original entry -> working copy */
+    private Map<IEntry, IEntry> autoSaveSharedWorkingCopies = new HashMap<IEntry, IEntry>();
+
+
+    //    IEntry getSharedReferenceCopy( IEntry entry )
+    //    {
+    //        EntryEditorUtils.ensureAttributesInitialized( entry );
+    //
+    //        if ( !oscSharedReferenceCopies.containsKey( entry ) )
+    //        {
+    //            oscSharedReferenceCopies.put( entry, new CompoundModification().cloneEntry( entry ) );
+    //        }
+    //        return oscSharedReferenceCopies.get( entry );
+    //    }
+    //
+    //
+    private void updateOscSharedReferenceCopy( IEntry entry )
+    {
+        EntryEditorUtils.ensureAttributesInitialized( entry );
+        IEntry referenceEntry = oscSharedReferenceCopies.get( entry );
+        EventRegistry.suspendEventFiringInCurrentThread();
+        new CompoundModification().replaceAttributes( entry, referenceEntry );
+        EventRegistry.resumeEventFiringInCurrentThread();
+    }
+
+
+    private void updateOscSharedWorkingCopy( IEntry entry )
+    {
+        EntryEditorUtils.ensureAttributesInitialized( entry );
+        IEntry workingCopy = oscSharedWorkingCopies.get( entry );
+        new CompoundModification().replaceAttributes( entry, workingCopy );
+    }
+
+
+    private void updateAutoSaveSharedReferenceCopy( IEntry entry )
+    {
+        EntryEditorUtils.ensureAttributesInitialized( entry );
+        IEntry workingCopy = autoSaveSharedReferenceCopies.get( entry );
+        EventRegistry.suspendEventFiringInCurrentThread();
+        new CompoundModification().replaceAttributes( entry, workingCopy );
+        EventRegistry.resumeEventFiringInCurrentThread();
+    }
+
+
+    private void updateAutoSaveSharedWorkingCopy( IEntry entry )
+    {
+        EntryEditorUtils.ensureAttributesInitialized( entry );
+        IEntry workingCopy = autoSaveSharedWorkingCopies.get( entry );
+        new CompoundModification().replaceAttributes( entry, workingCopy );
+    }
+
+
+    private List<IEntryEditor> getOscEditors( IEntry workingCopy )
+    {
+        List<IEntryEditor> oscEditors = new ArrayList<IEntryEditor>();
+        IEditorReference[] editorReferences = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage()
+            .getEditorReferences();
+        for ( IEditorReference ref : editorReferences )
+        {
+            IEntryEditor editor = getEntryEditor( ref );
+            if ( editor != null && !editor.isAutoSave()
+                && ( workingCopy == null || editor.getEntryEditorInput().getSharedWorkingCopy( editor ) == workingCopy ) )
+            {
+                oscEditors.add( editor );
+            }
+        }
+        return oscEditors;
+    }
+
+
+    private List<IEntryEditor> getAutoSaveEditors( IEntry workingCopy )
+    {
+        List<IEntryEditor> autoSaveEditors = new ArrayList<IEntryEditor>();
+        IEditorReference[] editorReferences = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage()
+            .getEditorReferences();
+        for ( IEditorReference ref : editorReferences )
+        {
+            IEntryEditor editor = getEntryEditor( ref );
+            if ( editor != null && editor.isAutoSave()
+                && editor.getEntryEditorInput().getSharedWorkingCopy( editor ) == workingCopy )
+            {
+                autoSaveEditors.add( editor );
+            }
+        }
+        return autoSaveEditors;
+    }
+
+
+    private IEntryEditor getEntryEditor( IWorkbenchPartReference partRef )
+    {
+        IWorkbenchPart part = partRef.getPart( false );
+        if ( part != null && part instanceof IEntryEditor )
+        {
+            IEntryEditor entryEditor = ( IEntryEditor ) part;
+            return entryEditor;
+        }
+        return null;
+    }
+
+
+    IEntry getSharedWorkingCopy( IEntry originalEntry, IEntryEditor editor )
+    {
+        EntryEditorUtils.ensureAttributesInitialized( originalEntry );
+        if ( editor.isAutoSave() )
+        {
+            if ( !autoSaveSharedReferenceCopies.containsKey( originalEntry ) )
+            {
+                autoSaveSharedReferenceCopies
+                    .put( originalEntry, new CompoundModification().cloneEntry( originalEntry ) );
+            }
+            if ( !autoSaveSharedWorkingCopies.containsKey( originalEntry ) )
+            {
+                IEntry referenceCopy = autoSaveSharedReferenceCopies.get( originalEntry );
+                autoSaveSharedWorkingCopies.put( originalEntry, new CompoundModification().cloneEntry( referenceCopy ) );
+            }
+            return autoSaveSharedWorkingCopies.get( originalEntry );
+        }
+        else
+        {
+            if ( !oscSharedReferenceCopies.containsKey( originalEntry ) )
+            {
+                oscSharedReferenceCopies.put( originalEntry, new CompoundModification().cloneEntry( originalEntry ) );
+            }
+            if ( !oscSharedWorkingCopies.containsKey( originalEntry ) )
+            {
+                IEntry referenceCopy = oscSharedReferenceCopies.get( originalEntry );
+                oscSharedWorkingCopies.put( originalEntry, new CompoundModification().cloneEntry( referenceCopy ) );
+            }
+            return oscSharedWorkingCopies.get( originalEntry );
+        }
+    }
+
+
+    boolean isSharedWorkingCopyDirty( IEntry originalEntry, IEntryEditor editor )
+    {
+        if ( editor.isAutoSave() )
+        {
+            return false;
+        }
+        else
+        {
+            IEntry referenceCopy = oscSharedReferenceCopies.get( originalEntry );
+            IEntry workingCopy = oscSharedWorkingCopies.get( originalEntry );
+            if ( referenceCopy != null && workingCopy != null )
+            {
+                LdifChangeModifyRecord diff = Utils.computeDiff( referenceCopy, workingCopy );
+                return diff != null;
+            }
+            return false;
+        }
+    }
+
+
+    IStatus saveSharedWorkingCopyDirty( IEntry originalEntry, boolean handleError, IEntryEditor editor )
+    {
+        if ( editor == null || !editor.isAutoSave() )
+        {
+            IEntry referenceCopy = oscSharedReferenceCopies.get( originalEntry );
+            IEntry workingCopy = oscSharedWorkingCopies.get( originalEntry );
+            if ( referenceCopy != null && workingCopy != null )
+            {
+                LdifChangeModifyRecord diff = Utils.computeDiff( referenceCopy, workingCopy );
+                if ( diff != null )
+                {
+                    // save by executing the LDIF
+                    ExecuteLdifRunnable runnable = new ExecuteLdifRunnable( originalEntry.getBrowserConnection(), diff
+                        .toFormattedString( LdifFormatParameters.DEFAULT ), false, false );
+                    IStatus status = RunnableContextRunner.execute( runnable, null, handleError );
+                    if ( status.isOK() )
+                    {
+                        updateOscSharedReferenceCopy( originalEntry );
+                        updateOscSharedWorkingCopy( originalEntry );
+                    }
+                    return status;
+                }
+            }
+        }
+        return null;
+    }
+
+    private IPartListener2 partListener = new IPartListener2()
+    {
+        public void partActivated( IWorkbenchPartReference partRef )
+        {
+
+            partClosed( partRef );
+
+            IEntryEditor editor = getEntryEditor( partRef );
+            if ( editor != null )
+            {
+                EntryEditorInput eei = editor.getEntryEditorInput();
+                IEntry originalEntry = eei.getResolvedEntry();
+                IEntry oscSharedReferenceCopy = oscSharedReferenceCopies.get( originalEntry );
+                IEntry oscSharedWorkingCopy = oscSharedWorkingCopies.get( originalEntry );
+                if ( editor.isAutoSave() )
+                {
+                    // check if the same entry is used in an OSC editor and is dirty -> should save first?
+                    if ( oscSharedReferenceCopy != null && oscSharedWorkingCopy != null )
+                    {
+                        LdifChangeModifyRecord diff = Utils.computeDiff( oscSharedReferenceCopy, oscSharedWorkingCopy );
+                        if ( diff != null )
+                        {
+                            MessageDialog dialog = new MessageDialog( partRef.getPart( false ).getSite().getShell(),
+                                "Save Changes", null, "Entry has been modified in another entry editor. Save changes?",
+                                MessageDialog.QUESTION, new String[]
+                                    { IDialogConstants.YES_LABEL, IDialogConstants.NO_LABEL }, 0 );
+                            int result = dialog.open();
+                            if ( result == 0 )
+                            {
+                                saveSharedWorkingCopyDirty( originalEntry, true, null );
+                            }
+                        }
+                    }
+                }
+                else
+                {
+                    // check if original entry was updated
+                    if ( oscSharedReferenceCopy != null && oscSharedWorkingCopy != null )
+                    {
+                        LdifChangeModifyRecord refDiff = Utils.computeDiff( originalEntry, oscSharedReferenceCopy );
+                        if ( refDiff != null )
+                        {
+                            // check if we could just update the working copy
+                            LdifChangeModifyRecord workDiff = Utils.computeDiff( oscSharedReferenceCopy,
+                                oscSharedWorkingCopy );
+                            if ( workDiff != null )
+                            {
+                                MessageDialog dialog = new MessageDialog(
+                                    partRef.getPart( false ).getSite().getShell(),
+                                    "Entry Changed",
+                                    null,
+                                    "The entry has been changed in the directory server. Do you want to replace the editor contents with these changes?",
+                                    MessageDialog.QUESTION, new String[]
+                                        { IDialogConstants.YES_LABEL, IDialogConstants.NO_LABEL }, 0 );
+                                int result = dialog.open();
+                                if ( result == 0 )
+                                {
+                                    // update reference copy and working copy
+                                    updateOscSharedReferenceCopy( originalEntry );
+                                    updateOscSharedWorkingCopy( originalEntry );
+
+                                    // inform all OSC editors
+                                    List<IEntryEditor> oscEditors = getOscEditors( oscSharedWorkingCopy );
+                                    for ( IEntryEditor oscEditor : oscEditors )
+                                    {
+                                        oscEditor.workingCopyModified();
+                                    }
+                                }
+                                else
+                                {
+                                    // only update the reference copy
+                                    updateOscSharedReferenceCopy( originalEntry );
+                                }
+                            }
+                        }
+                    }
+
+                }
+            }
+        }
+
+
+        public void partOpened( IWorkbenchPartReference partRef )
+        {
+        }
+
+
+        public void partClosed( IWorkbenchPartReference partRef )
+        {
+            // cleanup unused copies (OSC + auto-save)
+            Set<IEntry> oscEntries = new HashSet<IEntry>();
+            Set<IEntry> autoSaveEntries = new HashSet<IEntry>();
+            IEditorReference[] editorReferences = partRef.getPage().getEditorReferences();
+            for ( IEditorReference ref : editorReferences )
+            {
+                IEntryEditor editor = getEntryEditor( ref );
+                if ( editor != null )
+                {
+                    EntryEditorInput input = editor.getEntryEditorInput();
+                    if ( input != null )
+                    {
+                        IEntry entry = input.getResolvedEntry();
+                        if ( editor.isAutoSave() )
+                        {
+                            autoSaveEntries.add( entry );
+                        }
+                        else
+                        {
+                            oscEntries.add( entry );
+                        }
+                    }
+                }
+            }
+            for ( Iterator<IEntry> it = oscSharedReferenceCopies.keySet().iterator(); it.hasNext(); )
+            {
+                IEntry entry = it.next();
+                if ( !oscEntries.contains( entry ) )
+                {
+                    it.remove();
+                    oscSharedWorkingCopies.remove( entry );
+                }
+            }
+            for ( Iterator<IEntry> it = oscSharedWorkingCopies.keySet().iterator(); it.hasNext(); )
+            {
+                IEntry entry = it.next();
+                if ( !oscEntries.contains( entry ) )
+                {
+                    it.remove();
+                }
+            }
+            for ( Iterator<IEntry> it = autoSaveSharedReferenceCopies.keySet().iterator(); it.hasNext(); )
+            {
+                IEntry entry = it.next();
+                if ( !autoSaveEntries.contains( entry ) )
+                {
+                    it.remove();
+                }
+            }
+            for ( Iterator<IEntry> it = autoSaveSharedWorkingCopies.keySet().iterator(); it.hasNext(); )
+            {
+                IEntry entry = it.next();
+                if ( !autoSaveEntries.contains( entry ) )
+                {
+                    it.remove();
+                }
+            }
+        }
+
+
+        public void partInputChanged( IWorkbenchPartReference partRef )
+        {
+            partClosed( partRef );
+        }
+
+
+        public void partHidden( IWorkbenchPartReference partRef )
+        {
+        }
+
+
+        public void partDeactivated( IWorkbenchPartReference partRef )
+        {
+        }
+
+
+        public void partBroughtToTop( IWorkbenchPartReference partRef )
+        {
+        }
+
+
+        public void partVisible( IWorkbenchPartReference partRef )
+        {
+        }
+
+    };
+
+    private EntryUpdateListener entryUpdateListener = new EntryUpdateListener()
+    {
+
+        public void entryUpdated( EntryModificationEvent event )
+        {
+            IEntry modifiedEntry = event.getModifiedEntry();
+            IBrowserConnection browserConnection = modifiedEntry.getBrowserConnection();
+            IEntry originalEntry = browserConnection.getEntryFromCache( modifiedEntry.getDn() );
+
+            if ( modifiedEntry == originalEntry )
+            {
+                // an original entry has been modified, check if we could update the editors
+
+                // if the OSC editor is not dirty we could update the working copy
+                IEntry oscSharedReferenceCopy = oscSharedReferenceCopies.get( originalEntry );
+                IEntry oscSharedWorkingCopy = oscSharedWorkingCopies.get( originalEntry );
+                if ( oscSharedReferenceCopy != null && oscSharedWorkingCopy != null )
+                {
+                    LdifChangeModifyRecord refDiff = Utils.computeDiff( originalEntry, oscSharedReferenceCopy );
+                    if ( refDiff != null )
+                    {
+                        // diff between original entry and reference copy
+                        LdifChangeModifyRecord workDiff = Utils.computeDiff( oscSharedReferenceCopy,
+                            oscSharedWorkingCopy );
+                        if ( workDiff == null )
+                        {
+                            // no changes on working copy, update
+                            updateOscSharedReferenceCopy( originalEntry );
+                            updateOscSharedWorkingCopy( originalEntry );
+
+                            // inform all OSC editors
+                            List<IEntryEditor> oscEditors = getOscEditors( oscSharedWorkingCopy );
+                            for ( IEntryEditor editor : oscEditors )
+                            {
+                                editor.workingCopyModified();
+                            }
+                        }
+                    }
+                }
+
+                // always update auto-save working copies, if necessary
+                IEntry autoSaveSharedReferenceCopy = autoSaveSharedReferenceCopies.get( originalEntry );
+                IEntry autoSaveSharedWorkingCopy = autoSaveSharedWorkingCopies.get( originalEntry );
+                if ( autoSaveSharedReferenceCopy != null && autoSaveSharedWorkingCopy != null )
+                {
+                    LdifChangeModifyRecord diff = Utils.computeDiff( originalEntry, autoSaveSharedReferenceCopy );
+                    if ( diff != null )
+                    {
+                        updateAutoSaveSharedReferenceCopy( originalEntry );
+                        updateAutoSaveSharedWorkingCopy( originalEntry );
+                        List<IEntryEditor> editors = getAutoSaveEditors( autoSaveSharedWorkingCopy );
+                        for ( IEntryEditor editor : editors )
+                        {
+                            editor.workingCopyModified();
+                        }
+                    }
+                }
+
+                // check all editors: if the input does not exist any more then close the editor
+                IEditorReference[] editorReferences = PlatformUI.getWorkbench().getActiveWorkbenchWindow()
+                    .getActivePage().getEditorReferences();
+                for ( IEditorReference ref : editorReferences )
+                {
+                    IEntryEditor editor = getEntryEditor( ref );
+                    if ( editor != null )
+                    {
+                        IBrowserConnection bc = editor.getEntryEditorInput().getResolvedEntry().getBrowserConnection();
+                        LdapDN dn = editor.getEntryEditorInput().getResolvedEntry().getDn();
+                        if ( bc.getEntryFromCache( dn ) == null )
+                        {
+                            ref.getPage().closeEditor( ref.getEditor( false ), false );
+                        }
+                    }
+                }
+            }
+
+            else if ( oscSharedWorkingCopies.containsKey( originalEntry )
+                && oscSharedWorkingCopies.get( originalEntry ) == modifiedEntry )
+            {
+                // OSC working copy has been modified: inform OSC editors
+                IEntry oscSharedWorkingCopy = oscSharedWorkingCopies.get( originalEntry );
+                List<IEntryEditor> oscEditors = getOscEditors( oscSharedWorkingCopy );
+                for ( IEntryEditor editor : oscEditors )
+                {
+                    editor.workingCopyModified();
+                }
+            }
+
+            else if ( autoSaveSharedWorkingCopies.containsValue( originalEntry )
+                && autoSaveSharedWorkingCopies.get( originalEntry ) == modifiedEntry )
+            {
+                // auto-save working copy has been modified: save and inform all auto-save editors
+                IEntry autoSaveSharedReferenceCopy = autoSaveSharedReferenceCopies.get( originalEntry );
+                IEntry autoSaveSharedWorkingCopy = autoSaveSharedWorkingCopies.get( originalEntry );
+                LdifChangeModifyRecord diff = getDiff( autoSaveSharedReferenceCopy, autoSaveSharedWorkingCopy );
+                if ( diff != null )
+                {
+                    ExecuteLdifRunnable runnable = new ExecuteLdifRunnable( browserConnection, diff
+                        .toFormattedString( LdifFormatParameters.DEFAULT ), false, false );
+                    RunnableContextRunner.execute( runnable, null, true );
+                    // don't care if status is ok or not: always update
+                    EntryEditorUtils.ensureAttributesInitialized( originalEntry );
+                    //                    updateAutoSaveSharedReferenceCopy( originalEntry );
+                    //                    updateAutoSaveSharedWorkingCopy( originalEntry );
+                    //
+                    //                    List<IEntryEditor> editors = getAutoSaveEditors( autoSaveSharedWorkingCopy );
+                    //                    for ( IEntryEditor editor : editors )
+                    //                    {
+                    //                        editor.workingCopyModified();
+                    //                    }
+                }
+            }
+        }
+
+
+        private LdifChangeModifyRecord getDiff( IEntry originalEntry, IEntry modifiedEntry )
+        {
+            LdifChangeModifyRecord record = Utils.computeDiff( originalEntry, modifiedEntry );
+            return record;
+        }
+    };
 }

Modified: directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/entryeditors/EntryEditorUtils.java
URL: http://svn.apache.org/viewvc/directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/entryeditors/EntryEditorUtils.java?rev=814009&r1=814008&r2=814009&view=diff
==============================================================================
--- directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/entryeditors/EntryEditorUtils.java (original)
+++ directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/entryeditors/EntryEditorUtils.java Fri Sep 11 20:11:30 2009
@@ -20,11 +20,14 @@
 
 package org.apache.directory.studio.entryeditors;
 
+
 import org.apache.directory.studio.connection.ui.RunnableContextRunner;
 import org.apache.directory.studio.ldapbrowser.core.jobs.InitializeAttributesRunnable;
 import org.apache.directory.studio.ldapbrowser.core.model.IEntry;
 import org.apache.directory.studio.ldapbrowser.core.model.IRootDSE;
 import org.eclipse.osgi.util.NLS;
+import org.eclipse.ui.IEditorInput;
+
 
 public class EntryEditorUtils
 {
@@ -39,13 +42,36 @@
     {
         if ( !entry.isAttributesInitialized() )
         {
-            boolean foa = entry.getBrowserConnection().isFetchOperationalAttributes();
+            boolean foa = entry.getBrowserConnection().isFetchOperationalAttributes()
+                || entry.isOperationalAttributesInitialized();
             InitializeAttributesRunnable iar = new InitializeAttributesRunnable( new IEntry[]
                 { entry }, foa );
             RunnableContextRunner.execute( iar, null, true );
         }
     }
-    
+
+
+    /**
+     * Gets the entry editor input from the editor input.
+     * 
+     * @param input the input
+     * 
+     * @return the entry editor input
+     */
+    public static EntryEditorInput getEntryEditorInput( IEditorInput input )
+    {
+        if ( input instanceof EntryEditorInput )
+        {
+            EntryEditorInput eei = ( EntryEditorInput ) input;
+            return eei;
+        }
+        else
+        {
+            throw new IllegalArgumentException( "Expected an EntryEditorInput" ); //$NON-NLS-1$
+        }
+    }
+
+
     /**
      * Gets the text used in the history navigation list.
      * 
@@ -94,7 +120,7 @@
                 }
             }
         }
-        
+
         return null;
     }
 }

Modified: directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/entryeditors/IEntryEditor.java
URL: http://svn.apache.org/viewvc/directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/entryeditors/IEntryEditor.java?rev=814009&r1=814008&r2=814009&view=diff
==============================================================================
--- directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/entryeditors/IEntryEditor.java (original)
+++ directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/entryeditors/IEntryEditor.java Fri Sep 11 20:11:30 2009
@@ -25,7 +25,7 @@
 
 
 /**
- * An Entry Editor is used to display and edit and LDAP entry.  
+ * An Entry Editor is used to display and edit an LDAP entry.  
  *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  * @version $Rev$, $Date$
@@ -41,4 +41,27 @@
      */
     public boolean canHandle( IEntry entry );
 
+    
+    /**
+     * Informs the entry editor that the working copy was modified
+     */
+    public void workingCopyModified();
+    
+
+    /**
+     * Gets the entry editor input.
+     * 
+     * @return the entry editor input, null if no input was set
+     */
+    public EntryEditorInput getEntryEditorInput();
+
+
+    /**
+     * Checks if the editor uses auto save, i.e. if each modification is
+     * automatically committed to the directory server.
+     * 
+     * @return true, if the editor uses auto save
+     */
+    public boolean isAutoSave();
+
 }

Added: directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/entryeditors/MultiTabEntryEditorMatchingStrategy.java
URL: http://svn.apache.org/viewvc/directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/entryeditors/MultiTabEntryEditorMatchingStrategy.java?rev=814009&view=auto
==============================================================================
--- directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/entryeditors/MultiTabEntryEditorMatchingStrategy.java (added)
+++ directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/entryeditors/MultiTabEntryEditorMatchingStrategy.java Fri Sep 11 20:11:30 2009
@@ -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.entryeditors;
+
+
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorMatchingStrategy;
+import org.eclipse.ui.IEditorReference;
+import org.eclipse.ui.PartInitException;
+
+
+/**
+ * Matching strategy for a multi tab entry editor.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class MultiTabEntryEditorMatchingStrategy implements IEditorMatchingStrategy
+{
+
+    /**
+     * Returns true if the given editor is multi-tab and the input resolved entries
+     * are equal.
+     */
+    public boolean matches( IEditorReference editorRef, IEditorInput input )
+    {
+        if ( !( input instanceof EntryEditorInput ) )
+        {
+            return false;
+        }
+        EntryEditorInput entryEditorInput = ( EntryEditorInput ) input;
+
+        if ( entryEditorInput.getExtension() == null )
+        {
+            return false;
+        }
+        if ( !entryEditorInput.getExtension().isMultiWindow() )
+        {
+            return false;
+        }
+        if ( !editorRef.getId().equals( entryEditorInput.getExtension().getEditorId() ) )
+        {
+            return false;
+        }
+
+        try
+        {
+            IEditorInput otherInput = editorRef.getEditorInput();
+            if ( !( otherInput instanceof EntryEditorInput ) )
+            {
+                return false;
+            }
+            EntryEditorInput otherEntryEditorInput = ( EntryEditorInput ) otherInput;
+            return entryEditorInput.getResolvedEntry().equals( otherEntryEditorInput.getResolvedEntry() );
+        }
+        catch ( PartInitException e )
+        {
+            return false;
+        }
+    }
+
+}

Modified: directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/ldapbrowser/ui/BrowserUIPlugin.java
URL: http://svn.apache.org/viewvc/directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/ldapbrowser/ui/BrowserUIPlugin.java?rev=814009&r1=814008&r2=814009&view=diff
==============================================================================
--- directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/ldapbrowser/ui/BrowserUIPlugin.java (original)
+++ directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/ldapbrowser/ui/BrowserUIPlugin.java Fri Sep 11 20:11:30 2009
@@ -82,6 +82,7 @@
 
         if ( entryEditorManager != null )
         {
+            entryEditorManager.dispose();
             entryEditorManager = null;
         }
 

Modified: directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/ldapbrowser/ui/editors/entry/EntryEditor.java
URL: http://svn.apache.org/viewvc/directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/ldapbrowser/ui/editors/entry/EntryEditor.java?rev=814009&r1=814008&r2=814009&view=diff
==============================================================================
--- directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/ldapbrowser/ui/editors/entry/EntryEditor.java (original)
+++ directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/ldapbrowser/ui/editors/entry/EntryEditor.java Fri Sep 11 20:11:30 2009
@@ -22,11 +22,16 @@
 
 
 import org.apache.directory.studio.entryeditors.EntryEditorInput;
+import org.apache.directory.studio.entryeditors.EntryEditorUtils;
+import org.apache.directory.studio.entryeditors.IEntryEditor;
 import org.apache.directory.studio.ldapbrowser.common.widgets.entryeditor.EntryEditorWidget;
+import org.apache.directory.studio.ldapbrowser.core.model.IBookmark;
 import org.apache.directory.studio.ldapbrowser.core.model.IEntry;
+import org.apache.directory.studio.ldapbrowser.core.model.ISearchResult;
 import org.apache.directory.studio.ldapbrowser.ui.BrowserUIConstants;
 import org.apache.directory.studio.ldapbrowser.ui.views.browser.BrowserView;
 import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.viewers.ISelection;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
@@ -37,6 +42,7 @@
 import org.eclipse.ui.INavigationLocation;
 import org.eclipse.ui.INavigationLocationProvider;
 import org.eclipse.ui.IReusableEditor;
+import org.eclipse.ui.IShowEditorInput;
 import org.eclipse.ui.PartInitException;
 import org.eclipse.ui.PlatformUI;
 import org.eclipse.ui.part.EditorPart;
@@ -52,7 +58,8 @@
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  * @version $Rev$, $Date$
  */
-public abstract class EntryEditor extends EditorPart implements INavigationLocationProvider, IReusableEditor
+public abstract class EntryEditor extends EditorPart implements IEntryEditor, INavigationLocationProvider,
+    IReusableEditor, IShowEditorInput
 {
 
     /** The editor configuration. */
@@ -88,19 +95,14 @@
     {
         super.setInput( input );
 
-        if ( input instanceof EntryEditorInput && universalListener != null )
-        {
-            EntryEditorInput eei = ( EntryEditorInput ) input;
-            IEntry entry = eei.getResolvedEntry();
+        EntryEditorInput eei = getEntryEditorInput();
+        setEntryEditorWidgetInput( eei );
+        setEditorName( eei );
 
-            // inform listener
-            universalListener.setInput( entry );
-
-            // refresh outline
-            if ( outlinePage != null )
-            {
-                outlinePage.refresh();
-            }
+        // refresh outline
+        if ( outlinePage != null )
+        {
+            outlinePage.refresh();
         }
     }
 
@@ -218,8 +220,13 @@
     /**
      * {@inheritDoc}
      */
-    public void doSave( IProgressMonitor monitor )
+    public void doSave( final IProgressMonitor monitor )
     {
+        if ( !isAutoSave() )
+        {
+            EntryEditorInput eei = getEntryEditorInput();
+            eei.saveSharedWorkingCopy( true, this );
+        }
     }
 
 
@@ -236,7 +243,7 @@
      */
     public boolean isDirty()
     {
-        return false;
+        return getEntryEditorInput().isSharedWorkingCopyDirty( this );
     }
 
 
@@ -321,4 +328,105 @@
         return new EntryEditorNavigationLocation( this );
     }
 
+
+    /**
+     * Sets the editor name.
+     * 
+     * @param input the new editor name
+     */
+    protected abstract void setEditorName( EntryEditorInput input );
+
+
+    /**
+     * This implementation returns always true.
+     * 
+     * {@inheritDoc}
+     */
+    public boolean canHandle( IEntry entry )
+    {
+        return true;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public EntryEditorInput getEntryEditorInput()
+    {
+        return EntryEditorUtils.getEntryEditorInput( getEditorInput() );
+    }
+
+
+    public void workingCopyModified()
+    {
+        if ( isAutoSave() )
+        {
+            setEntryEditorWidgetInput( getEntryEditorInput() );
+        }
+        if ( !isAutoSave() )
+        {
+            // mark as dirty only
+            firePropertyChange( PROP_DIRTY );
+        }
+    }
+
+
+    /**
+     * Sets the entry editor widget input. A clone of the real entry
+     * with a read-only connection is used for that.
+     * @param eei 
+     */
+    private void setEntryEditorWidgetInput( EntryEditorInput eei )
+    {
+        if ( mainWidget != null )
+        {
+            // set input, remember old selection and set it afterwards
+            ISelection selection = mainWidget.getViewer().getSelection();
+            universalListener.setInput( getEntryEditorInput().getSharedWorkingCopy( this ) );
+            mainWidget.getViewer().setSelection( selection );
+        }
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void showEditorInput( IEditorInput input )
+    {
+        if ( input instanceof EntryEditorInput )
+        {
+            /*
+             * Workaround to make link-with-editor working for the single-tab editor:
+             * The call of firePropertyChange is used to inform the link-with-editor action.
+             * However firePropertyChange also modifies the navigation history.
+             * Thus, a dummy input with the real entry but a null extension is set.
+             * This avoids to modification of the navigation history.
+             * Afterwards the real input is set.
+             */
+            EntryEditorInput eei = ( EntryEditorInput ) input;
+            IEntry entry = eei.getEntryInput();
+            ISearchResult searchResult = eei.getSearchResultInput();
+            IBookmark bookmark = eei.getBookmarkInput();
+            EntryEditorInput dummyInput;
+            if ( entry != null )
+            {
+                dummyInput = new EntryEditorInput( entry, null );
+            }
+            else if ( searchResult != null )
+            {
+                dummyInput = new EntryEditorInput( searchResult, null );
+            }
+            else
+            {
+                dummyInput = new EntryEditorInput( bookmark, null );
+            }
+            setInput( dummyInput );
+            firePropertyChange( IEditorPart.PROP_INPUT );
+
+            // now set the real input and mark history location
+            setInput( input );
+            getSite().getPage().getNavigationHistory().markLocation( this );
+        }
+    }
+
 }

Modified: directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/ldapbrowser/ui/editors/entry/EntryEditorConfiguration.java
URL: http://svn.apache.org/viewvc/directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/ldapbrowser/ui/editors/entry/EntryEditorConfiguration.java?rev=814009&r1=814008&r2=814009&view=diff
==============================================================================
--- directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/ldapbrowser/ui/editors/entry/EntryEditorConfiguration.java (original)
+++ directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/ldapbrowser/ui/editors/entry/EntryEditorConfiguration.java Fri Sep 11 20:11:30 2009
@@ -23,6 +23,8 @@
 
 import org.apache.directory.studio.ldapbrowser.common.widgets.entryeditor.EntryEditorWidgetConfiguration;
 import org.apache.directory.studio.ldapbrowser.common.widgets.entryeditor.EntryEditorWidgetFilter;
+import org.apache.directory.studio.valueeditors.ValueEditorManager;
+import org.eclipse.jface.viewers.TreeViewer;
 
 
 /**
@@ -57,4 +59,22 @@
         return filter;
     }
 
+
+    /**
+     * Gets the value editor manager.
+     * 
+     * @param viewer the viewer
+     * 
+     * @return the value editor manager
+     */
+    public ValueEditorManager getValueEditorManager( TreeViewer viewer )
+    {
+        if ( valueEditorManager == null )
+        {
+            valueEditorManager = new ValueEditorManager( viewer.getTree(), true );
+        }
+
+        return valueEditorManager;
+    }
+
 }

Added: directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/ldapbrowser/ui/editors/entry/LdifEntryEditor.java
URL: http://svn.apache.org/viewvc/directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/ldapbrowser/ui/editors/entry/LdifEntryEditor.java?rev=814009&view=auto
==============================================================================
--- directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/ldapbrowser/ui/editors/entry/LdifEntryEditor.java (added)
+++ directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/ldapbrowser/ui/editors/entry/LdifEntryEditor.java Fri Sep 11 20:11:30 2009
@@ -0,0 +1,229 @@
+/*
+ *  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.ui.editors.entry;
+
+
+import org.apache.directory.studio.entryeditors.EntryEditorInput;
+import org.apache.directory.studio.entryeditors.EntryEditorUtils;
+import org.apache.directory.studio.entryeditors.IEntryEditor;
+import org.apache.directory.studio.ldapbrowser.core.model.IBookmark;
+import org.apache.directory.studio.ldapbrowser.core.model.IEntry;
+import org.apache.directory.studio.ldapbrowser.core.model.ISearchResult;
+import org.apache.directory.studio.ldifeditor.editor.LdifEditor;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.INavigationLocation;
+import org.eclipse.ui.IShowEditorInput;
+import org.eclipse.ui.PartInitException;
+
+
+/**
+ * An entry editor that uses LDIF format.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public abstract class LdifEntryEditor extends LdifEditor implements IEntryEditor, IShowEditorInput
+{
+
+    private boolean inShowEditorInput = false;
+
+
+    public LdifEntryEditor()
+    {
+        super();
+
+        // use our own document provider that saves changes to the directory
+        setDocumentProvider( new LdifEntryEditorDocumentProvider( this ) );
+    }
+
+
+    @Override
+    public void init( IEditorSite site, IEditorInput input ) throws PartInitException
+    {
+        super.init( site, input );
+    }
+
+
+    @Override
+    public void createPartControl( Composite parent )
+    {
+        // don't show the tool bar
+        showToolBar = false;
+
+        super.createPartControl( parent );
+    }
+
+
+    @Override
+    public boolean isSaveAsAllowed()
+    {
+        // Allowing "Save As..." requires an IPathEditorInput.
+        // Would makes things much more complex, maybe we could add this later.
+        return false;
+    }
+
+
+    @Override
+    public void dispose()
+    {
+        super.dispose();
+    }
+
+
+    @Override
+    public INavigationLocation createNavigationLocation()
+    {
+        return new LdifEntryEditorNavigationLocation( this, true );
+    }
+
+
+    @Override
+    public INavigationLocation createEmptyNavigationLocation()
+    {
+        return new LdifEntryEditorNavigationLocation( this, false );
+    }
+
+
+    /**
+     * This implementation returns always false.
+     * 
+     * {@inheritDoc}
+     */
+    public boolean isAutoSave()
+    {
+        return false;
+    }
+
+
+    /**
+     * This implementation returns always true.
+     * 
+     * {@inheritDoc}
+     */
+    public boolean canHandle( IEntry entry )
+    {
+        return true;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public EntryEditorInput getEntryEditorInput()
+    {
+        return EntryEditorUtils.getEntryEditorInput( getEditorInput() );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void workingCopyModified()
+    {
+        if ( getSite().getPage().getActivePart() == LdifEntryEditor.this )
+        {
+            // This editor instance is the active editor.
+            // Don't apply its own modifications.
+            return;
+        }
+
+        ( ( LdifEntryEditorDocumentProvider ) getDocumentProvider() ).setContent( getEntryEditorInput() );
+    }
+
+
+    public void showEditorInput( IEditorInput input )
+    {
+        if ( inShowEditorInput )
+        {
+            /*
+             *  This is to avoid recursion when using history navigation:
+             *  - when selecting an entry this method is called
+             *  - this method fires an input changed event
+             *  - the LinkWithEditorAction gets the event and selects the entry in the browser tree
+             *  - this selection fires an selection event
+             *  - the selection event causes an openEditor() that calls this method again
+             */
+            return;
+        }
+        
+        try
+        {
+            inShowEditorInput = true;
+
+            if ( input instanceof EntryEditorInput )
+            {
+                EntryEditorInput eei = ( EntryEditorInput ) input;
+
+                /*
+                 * Optimization: no need to set the input again if the same input is already set
+                 */
+                if ( getEntryEditorInput() != null
+                    && getEntryEditorInput().getResolvedEntry() == eei.getResolvedEntry() )
+                {
+                    return;
+                }
+                
+                /*
+                 * Workaround to make link-with-editor working for the single-tab editor:
+                 * The call of firePropertyChange is used to inform the link-with-editor action.
+                 * However firePropertyChange also modifies the navigation history.
+                 * Thus, a dummy input with the real entry but a null extension is set.
+                 * This avoids to modification of the navigation history.
+                 * Afterwards the real input is set.
+                 */
+                IEntry entry = eei.getEntryInput();
+                ISearchResult searchResult = eei.getSearchResultInput();
+                IBookmark bookmark = eei.getBookmarkInput();
+                EntryEditorInput dummyInput;
+                if ( entry != null )
+                {
+                    dummyInput = new EntryEditorInput( entry, null );
+                }
+                else if ( searchResult != null )
+                {
+                    dummyInput = new EntryEditorInput( searchResult, null );
+                }
+                else
+                {
+                    dummyInput = new EntryEditorInput( bookmark, null );
+                }
+                doSetInput( dummyInput );
+                firePropertyChange( IEditorPart.PROP_INPUT );
+
+                // now set the real input and mark history location
+                doSetInput( input );
+                getSite().getPage().getNavigationHistory().markLocation( this );
+            }
+        }
+        catch ( CoreException e )
+        {
+            throw new RuntimeException( e );
+        }
+        finally
+        {
+            inShowEditorInput = false;
+        }
+    }
+}

Modified: directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/ldapbrowser/ui/editors/entry/LdifEntryEditorDocumentProvider.java
URL: http://svn.apache.org/viewvc/directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/ldapbrowser/ui/editors/entry/LdifEntryEditorDocumentProvider.java?rev=814009&r1=814008&r2=814009&view=diff
==============================================================================
--- directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/ldapbrowser/ui/editors/entry/LdifEntryEditorDocumentProvider.java (original)
+++ directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/ldapbrowser/ui/editors/entry/LdifEntryEditorDocumentProvider.java Fri Sep 11 20:11:30 2009
@@ -23,19 +23,15 @@
 
 import javax.naming.InvalidNameException;
 
-import org.apache.directory.studio.connection.ui.RunnableContextRunner;
 import org.apache.directory.studio.entryeditors.EntryEditorInput;
-import org.apache.directory.studio.entryeditors.EntryEditorUtils;
-import org.apache.directory.studio.ldapbrowser.core.jobs.ExecuteLdifRunnable;
 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.impl.DummyEntry;
+import org.apache.directory.studio.ldapbrowser.core.utils.CompoundModification;
 import org.apache.directory.studio.ldapbrowser.core.utils.ModelConverter;
 import org.apache.directory.studio.ldapbrowser.core.utils.Utils;
 import org.apache.directory.studio.ldapbrowser.ui.BrowserUIConstants;
 import org.apache.directory.studio.ldifeditor.editor.LdifDocumentProvider;
-import org.apache.directory.studio.ldifparser.LdifFormatParameters;
-import org.apache.directory.studio.ldifparser.model.container.LdifChangeModifyRecord;
 import org.apache.directory.studio.ldifparser.model.container.LdifContentRecord;
 import org.apache.directory.studio.ldifparser.model.container.LdifRecord;
 import org.eclipse.core.runtime.CoreException;
@@ -43,6 +39,7 @@
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
 import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.DocumentEvent;
 import org.eclipse.jface.text.IDocument;
 
 
@@ -55,31 +52,95 @@
 public class LdifEntryEditorDocumentProvider extends LdifDocumentProvider
 {
 
+    private EntryEditorInput input;
+    private boolean inSetContent = false;
+
+    private LdifEntryEditor editor;
+
+
+    public LdifEntryEditorDocumentProvider( LdifEntryEditor editor )
+    {
+        this.editor = editor;
+    }
+
+
     @Override
     protected void doSaveDocument( IProgressMonitor monitor, Object element, IDocument document, boolean overwrite )
         throws CoreException
     {
-        IEntry entry = getResolvedEntry( element );
-        IBrowserConnection browserConnection = entry.getBrowserConnection();
+        EntryEditorInput input = getEntryEditorInput( element );
+        IStatus status = input.saveSharedWorkingCopy( false, editor );
+        if ( status != null && !status.isOK() )
+        {
+            throw new CoreException( status );
+        }
+    }
+
+
+    @Override
+    public void documentChanged( DocumentEvent event )
+    {
+        super.documentChanged( event );
+
+        if ( input == null )
+        {
+            return;
+        }
+        LdifRecord[] records = getLdifModel().getRecords();
+        if ( records.length != 1 || !( records[0] instanceof LdifContentRecord ) || !records[0].isValid() )
+        {
+            // can't continue
+            return;
+        }
+
+        // the document change was caused by the model update
+        // no need to update the model again, don't fire more events
+        if ( inSetContent )
+        {
+            return;
+        }
+
+        // update shared working copy
+        try
+        {
+            LdifContentRecord modifiedRecord = ( LdifContentRecord ) records[0];
+            IBrowserConnection browserConnection = input.getSharedWorkingCopy( editor ).getBrowserConnection();
+            DummyEntry modifiedEntry = ModelConverter.ldifContentRecordToEntry( modifiedRecord, browserConnection );
+            new CompoundModification().replaceAttributes( modifiedEntry, input.getSharedWorkingCopy( editor ) );
+        }
+        catch ( InvalidNameException e )
+        {
+            throw new RuntimeException( "Failed to set input", e );
+        }
+    }
+
+
+    public void setContent( EntryEditorInput input )
+    {
+        IEntry sharedWorkingCopy = input.getSharedWorkingCopy( editor );
+        LdifContentRecord record = ModelConverter.entryToLdifContentRecord( sharedWorkingCopy );
+        String newContent = record.toFormattedString( Utils.getLdifFormatParameters() );
 
-        LdifChangeModifyRecord diff = getDiff( entry );
-        if ( diff != null )
+        IDocument document = getDocument( input );
+        if ( document != null )
         {
-            // save by executing the LDIF
-            ExecuteLdifRunnable runnable = new ExecuteLdifRunnable( browserConnection, diff
-                .toFormattedString( LdifFormatParameters.DEFAULT ), false, false );
-            IStatus status = RunnableContextRunner.execute( runnable, null, true );
-            if ( !status.isOK() )
+            inSetContent = true;
+            document.set( newContent );
+
+            // reset dirty state
+            if ( !input.isSharedWorkingCopyDirty( editor ) )
             {
-                return;
+                try
+                {
+                    doResetDocument( input, null );
+                }
+                catch ( CoreException e )
+                {
+                    throw new RuntimeException( e );
+                }
             }
+            inSetContent = false;
         }
-
-        // if no difference or if saved successful: refresh input and clean dirty state
-        entry = getResolvedEntry( element );
-        LdifContentRecord record = ModelConverter.entryToLdifContentRecord( entry );
-        String content = record.toFormattedString( Utils.getLdifFormatParameters() );
-        getDocument( element ).set( content );
     }
 
 
@@ -99,39 +160,12 @@
     }
 
 
-    /**
-     * Gets the difference between the original entry and the modified entry.
-     * 
-     * @return the difference
-     */
-    private LdifChangeModifyRecord getDiff( IEntry originalEntry ) throws CoreException
-    {
-        LdifRecord[] records = getLdifModel().getRecords();
-        if ( records.length != 1 || !( records[0] instanceof LdifContentRecord ) )
-        {
-            throw new CoreException( new Status( IStatus.ERROR, BrowserUIConstants.PLUGIN_ID,
-                "Expected exactly one LDIF content record." ) );
-        }
-
-        try
-        {
-            LdifContentRecord modifiedRecord = ( LdifContentRecord ) records[0];
-            DummyEntry modifiedEntry = ModelConverter.ldifContentRecordToEntry( modifiedRecord, originalEntry
-                .getBrowserConnection() );
-            LdifChangeModifyRecord record = Utils.computeDiff( originalEntry, modifiedEntry );
-            return record;
-        }
-        catch ( InvalidNameException e )
-        {
-            throw new RuntimeException( "Failed to set input", e );
-        }
-    }
-
-
     @Override
     protected IDocument createDocument( Object element ) throws CoreException
     {
-        IEntry entry = getResolvedEntry( element );
+        input = getEntryEditorInput( element );
+
+        IEntry entry = getEntryEditorInput( element ).getSharedWorkingCopy( editor );
         LdifContentRecord record = ModelConverter.entryToLdifContentRecord( entry );
         String content = record.toFormattedString( Utils.getLdifFormatParameters() );
 
@@ -142,14 +176,12 @@
     }
 
 
-    private IEntry getResolvedEntry( Object element ) throws CoreException
+    private EntryEditorInput getEntryEditorInput( Object element ) throws CoreException
     {
         if ( element instanceof EntryEditorInput )
         {
             EntryEditorInput input = ( EntryEditorInput ) element;
-            IEntry entry = input.getResolvedEntry();
-            EntryEditorUtils.ensureAttributesInitialized( entry );
-            return entry;
+            return input;
         }
         else
         {

Modified: directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/ldapbrowser/ui/editors/entry/MultiTabEntryEditor.java
URL: http://svn.apache.org/viewvc/directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/ldapbrowser/ui/editors/entry/MultiTabEntryEditor.java?rev=814009&r1=814008&r2=814009&view=diff
==============================================================================
--- directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/ldapbrowser/ui/editors/entry/MultiTabEntryEditor.java (original)
+++ directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/ldapbrowser/ui/editors/entry/MultiTabEntryEditor.java Fri Sep 11 20:11:30 2009
@@ -21,27 +21,8 @@
 package org.apache.directory.studio.ldapbrowser.ui.editors.entry;
 
 
-import org.apache.directory.studio.connection.core.Connection;
-import org.apache.directory.studio.connection.ui.RunnableContextRunner;
 import org.apache.directory.studio.entryeditors.EntryEditorInput;
-import org.apache.directory.studio.ldapbrowser.common.BrowserCommonActivator;
-import org.apache.directory.studio.ldapbrowser.core.events.EntryModificationEvent;
-import org.apache.directory.studio.ldapbrowser.core.events.EntryUpdateListener;
-import org.apache.directory.studio.ldapbrowser.core.events.EventRegistry;
-import org.apache.directory.studio.ldapbrowser.core.jobs.ExecuteLdifRunnable;
-import org.apache.directory.studio.ldapbrowser.core.jobs.InitializeAttributesRunnable;
-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.impl.BrowserConnection;
-import org.apache.directory.studio.ldapbrowser.core.utils.ModelConverter;
-import org.apache.directory.studio.ldapbrowser.core.utils.Utils;
 import org.apache.directory.studio.ldapbrowser.ui.BrowserUIConstants;
-import org.apache.directory.studio.ldifparser.LdifFormatParameters;
-import org.apache.directory.studio.ldifparser.model.container.LdifChangeModifyRecord;
-import org.apache.directory.studio.ldifparser.model.container.LdifContentRecord;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.ui.IEditorInput;
 
 
 /**
@@ -57,21 +38,6 @@
 public class MultiTabEntryEditor extends EntryEditor
 {
 
-    private EntryUpdateListener entryUpdateListener = new EntryUpdateListener()
-    {
-        public void entryUpdated( EntryModificationEvent event )
-        {
-            if ( mainWidget.getViewer() == null || mainWidget.getViewer().getInput() == null
-                || event.getModifiedEntry() != mainWidget.getViewer().getInput() )
-            {
-                return;
-            }
-
-            firePropertyChange( PROP_DIRTY );
-        }
-    };
-
-
     /**
      * Gets the ID of the MultiTabEntryEditor.
      * 
@@ -83,157 +49,15 @@
     }
 
 
-    @Override
-    public void setInput( IEditorInput input )
-    {
-        super.setInput( input );
-
-        setEntryEditorWidgetInput();
-
-        // make the editor dirty when the entry is modified
-        EventRegistry
-            .addEntryUpdateListener( entryUpdateListener, BrowserCommonActivator.getDefault().getEventRunner() );
-
-        // use the entry's DN as tab label
-        if ( input instanceof EntryEditorInput )
-        {
-            EntryEditorInput entryEditorInput = ( EntryEditorInput ) input;
-            setPartName( entryEditorInput.getName() );
-        }
-    }
-
-
-    @Override
-    public boolean isDirty()
-    {
-        LdifChangeModifyRecord diff = getDiff();
-        if ( diff != null )
-        {
-            return true;
-        }
-        else
-        {
-            return false;
-        }
-    }
-
-
-    @Override
-    public void doSave( final IProgressMonitor monitor )
-    {
-        IEditorInput input = getEditorInput();
-        if ( input instanceof EntryEditorInput && mainWidget != null )
-        {
-            EntryEditorInput eei = ( EntryEditorInput ) input;
-            IEntry entry = eei.getResolvedEntry();
-            initAttributes( entry );
-            IBrowserConnection browserConnection = entry.getBrowserConnection();
-
-            LdifChangeModifyRecord diff = getDiff();
-            if ( diff != null )
-            {
-                // save
-                ExecuteLdifRunnable runnable = new ExecuteLdifRunnable( browserConnection, diff
-                    .toFormattedString( LdifFormatParameters.DEFAULT ), false, false );
-                IStatus status = RunnableContextRunner.execute( runnable, null, true );
-                if ( status.isOK() )
-                {
-                    // set new input and refresh the dirty state
-                    setEntryEditorWidgetInput();
-                    firePropertyChange( PROP_DIRTY );
-                }
-            }
-        }
-    }
-
-
-    /**
-     * Sets the entry editor widget input. A clone of the real entry
-     * with a read-only connection is used for that.
-     */
-    private void setEntryEditorWidgetInput()
-    {
-        IEditorInput input = getEditorInput();
-        if ( input instanceof EntryEditorInput && universalListener != null )
-        {
-            EntryEditorInput eei = ( EntryEditorInput ) input;
-            IEntry entry = eei.getResolvedEntry();
-            initAttributes( entry );
-            IBrowserConnection browserConnection = entry.getBrowserConnection();
-
-            try
-            {
-                EventRegistry.suspendEventFiringInCurrentThread();
-
-                // clone connection and set read-only
-                Connection readOnlyConnection = ( Connection ) browserConnection.getConnection().clone();
-                readOnlyConnection.getConnectionParameter().setReadOnly( true );
-                BrowserConnection readOnlyBrowserConnection = new BrowserConnection( readOnlyConnection );
-
-                // clone entry
-                LdifContentRecord record = ModelConverter.entryToLdifContentRecord( entry );
-                IEntry clonedEntry = ModelConverter.ldifContentRecordToEntry( record, readOnlyBrowserConnection );
-
-                // set input
-                universalListener.setInput( clonedEntry );
-            }
-            catch ( Exception e )
-            {
-                throw new RuntimeException( "Failed to set input", e );
-            }
-            finally
-            {
-                EventRegistry.resumeEventFiringInCurrentThread();
-            }
-        }
-    }
-
-
-    /**
-     * Gets the difference between the original entry and the modified entry.
-     * 
-     * @return the difference
-     */
-    private LdifChangeModifyRecord getDiff()
-    {
-        IEditorInput input = getEditorInput();
-        if ( input instanceof EntryEditorInput && mainWidget != null )
-        {
-            EntryEditorInput eei = ( EntryEditorInput ) input;
-            IEntry originalEntry = eei.getResolvedEntry();
-            initAttributes( originalEntry );
-            IEntry modifiedEntry = ( IEntry ) mainWidget.getViewer().getInput();
-
-            LdifChangeModifyRecord record = Utils.computeDiff( originalEntry, modifiedEntry );
-            return record;
-        }
-        return null;
-    }
-
-
-    /**
-     * Initializes the attributes.
-     * 
-     * @param entry the entry
-     */
-    private void initAttributes( IEntry entry )
+    public boolean isAutoSave()
     {
-        if ( !entry.isAttributesInitialized() )
-        {
-            boolean foa = entry.getBrowserConnection().isFetchOperationalAttributes();
-            InitializeAttributesRunnable iar = new InitializeAttributesRunnable( new IEntry[]
-                { entry }, foa );
-            RunnableContextRunner.execute( iar, null, true );
-        }
+        return false;
     }
 
 
-    @Override
-    public void dispose()
+    protected void setEditorName( EntryEditorInput eei )
     {
-        // remove the listener
-        EventRegistry.removeEntryUpdateListener( entryUpdateListener );
-        super.dispose();
+        setPartName( eei.getName() );
     }
 
 }

Modified: directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/ldapbrowser/ui/editors/entry/MultiTabLdifEntryEditor.java
URL: http://svn.apache.org/viewvc/directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/ldapbrowser/ui/editors/entry/MultiTabLdifEntryEditor.java?rev=814009&r1=814008&r2=814009&view=diff
==============================================================================
--- directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/ldapbrowser/ui/editors/entry/MultiTabLdifEntryEditor.java (original)
+++ directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/ldapbrowser/ui/editors/entry/MultiTabLdifEntryEditor.java Fri Sep 11 20:11:30 2009
@@ -22,9 +22,6 @@
 
 
 import org.apache.directory.studio.ldapbrowser.ui.BrowserUIConstants;
-import org.apache.directory.studio.ldifeditor.editor.LdifEditor;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.ui.INavigationLocation;
 
 
 /**
@@ -33,18 +30,9 @@
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  * @version $Rev$, $Date$
  */
-public class MultiTabLdifEntryEditor extends LdifEditor
+public class MultiTabLdifEntryEditor extends LdifEntryEditor
 {
 
-    public MultiTabLdifEntryEditor()
-    {
-        super();
-
-        // use our own document provider that saves changes to the directory
-        setDocumentProvider( new LdifEntryEditorDocumentProvider() );
-    }
-
-
     /**
      * Gets the ID of the MultiTabLdifEntryEditor.
      * 
@@ -55,37 +43,4 @@
         return BrowserUIConstants.EDITOR_MULTI_TAB_LDIF_ENTRY_EDITOR;
     }
 
-
-    @Override
-    public void createPartControl( Composite parent )
-    {
-        // don't show the tool bar
-        showToolBar = false;
-
-        super.createPartControl( parent );
-    }
-
-
-    @Override
-    public boolean isSaveAsAllowed()
-    {
-        // Allowing "Save As..." requires an IPathEditorInput.
-        // Would makes things much more complex, maybe we could add this later.
-        return false;
-    }
-
-
-    @Override
-    public INavigationLocation createNavigationLocation()
-    {
-        return new LdifEntryEditorNavigationLocation( this, true );
-    }
-
-
-    @Override
-    public INavigationLocation createEmptyNavigationLocation()
-    {
-        return new LdifEntryEditorNavigationLocation( this, false );
-    }
-
 }

Modified: directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/ldapbrowser/ui/editors/entry/SingleTabEntryEditor.java
URL: http://svn.apache.org/viewvc/directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/ldapbrowser/ui/editors/entry/SingleTabEntryEditor.java?rev=814009&r1=814008&r2=814009&view=diff
==============================================================================
--- directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/ldapbrowser/ui/editors/entry/SingleTabEntryEditor.java (original)
+++ directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/ldapbrowser/ui/editors/entry/SingleTabEntryEditor.java Fri Sep 11 20:11:30 2009
@@ -22,14 +22,7 @@
 
 
 import org.apache.directory.studio.entryeditors.EntryEditorInput;
-import org.apache.directory.studio.ldapbrowser.core.model.IBookmark;
-import org.apache.directory.studio.ldapbrowser.core.model.IEntry;
-import org.apache.directory.studio.ldapbrowser.core.model.ISearchResult;
 import org.apache.directory.studio.ldapbrowser.ui.BrowserUIConstants;
-import org.eclipse.ui.IEditorInput;
-import org.eclipse.ui.IEditorPart;
-import org.eclipse.ui.IShowEditorInput;
-
 
 
 /**
@@ -38,7 +31,7 @@
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  * @version $Rev$, $Date$
  */
-public class SingleTabEntryEditor extends EntryEditor implements IShowEditorInput
+public class SingleTabEntryEditor extends EntryEditor
 {
 
     /**
@@ -52,45 +45,16 @@
     }
 
 
-    /**
-     * {@inheritDoc}
-     */
-    public void showEditorInput( IEditorInput input )
+    public boolean isAutoSave()
+    {
+        return true;
+    }
+
+
+    @Override
+    protected void setEditorName( EntryEditorInput eei )
     {
-        if ( input instanceof EntryEditorInput )
-        {
-            /*
-             * Workaround to make link-with-editor working for the single-tab editor:
-             * The call of firePropertyChange is used to inform the link-with-editor action.
-             * However firePropertyChange also modifies the navigation history.
-             * Thus, a dummy input with the real entry but a null extension is set.
-             * This avoids to modification of the navigation history.
-             * Afterwards the real input is set.
-             */
-            EntryEditorInput eei = ( EntryEditorInput ) input;
-            IEntry entry = eei.getEntryInput();
-            ISearchResult searchResult = eei.getSearchResultInput();
-            IBookmark bookmark = eei.getBookmarkInput();
-            EntryEditorInput dummyInput; 
-            if(entry != null)
-            {
-                dummyInput = new EntryEditorInput( entry, null );
-            }
-            else if(searchResult != null)
-            {
-                dummyInput = new EntryEditorInput( searchResult, null );
-            }
-            else
-            {
-                dummyInput = new EntryEditorInput( bookmark, null );
-            }
-            setInput( dummyInput );
-            firePropertyChange( IEditorPart.PROP_INPUT );
-            
-            // now set the real input and mark history location
-            setInput( input );
-            getSite().getPage().getNavigationHistory().markLocation( this );
-        }
+        // nothing, keep the default
     }
 
 }

Modified: directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/ldapbrowser/ui/editors/entry/SingleTabLdifEntryEditor.java
URL: http://svn.apache.org/viewvc/directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/ldapbrowser/ui/editors/entry/SingleTabLdifEntryEditor.java?rev=814009&r1=814008&r2=814009&view=diff
==============================================================================
--- directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/ldapbrowser/ui/editors/entry/SingleTabLdifEntryEditor.java (original)
+++ directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/ldapbrowser/ui/editors/entry/SingleTabLdifEntryEditor.java Fri Sep 11 20:11:30 2009
@@ -21,15 +21,7 @@
 package org.apache.directory.studio.ldapbrowser.ui.editors.entry;
 
 
-import org.apache.directory.studio.entryeditors.EntryEditorInput;
-import org.apache.directory.studio.ldapbrowser.core.model.IBookmark;
-import org.apache.directory.studio.ldapbrowser.core.model.IEntry;
-import org.apache.directory.studio.ldapbrowser.core.model.ISearchResult;
 import org.apache.directory.studio.ldapbrowser.ui.BrowserUIConstants;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.ui.IEditorInput;
-import org.eclipse.ui.IEditorPart;
-import org.eclipse.ui.IShowEditorInput;
 
 
 /**
@@ -38,12 +30,9 @@
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  * @version $Rev$, $Date$
  */
-public class SingleTabLdifEntryEditor extends MultiTabLdifEntryEditor implements IShowEditorInput
+public class SingleTabLdifEntryEditor extends LdifEntryEditor
 {
 
-    private boolean inShowEditorInput = false;
-
-
     /**
      * Gets the ID of the SingleTabLdifEntryEditor.
      * 
@@ -54,69 +43,4 @@
         return BrowserUIConstants.EDITOR_SINGLE_TAB_LDIF_ENTRY_EDITOR;
     }
 
-
-    public void showEditorInput( IEditorInput input )
-    {
-        if ( inShowEditorInput )
-        {
-            /*
-             *  This is to avoid recursion when using history navigation:
-             *  - when selecting an entry this method is called
-             *  - this method fires an input changed event
-             *  - the LinkWithEditorAction gets the event and selects the entry in the browser tree
-             *  - this selection fires an selection event
-             *  - the selection event causes an openEditor() that calls this method again
-             */
-            return;
-        }
-
-        try
-        {
-            inShowEditorInput = true;
-
-            if ( input instanceof EntryEditorInput )
-            {
-                /*
-                 * Workaround to make link-with-editor working for the single-tab editor:
-                 * The call of firePropertyChange is used to inform the link-with-editor action.
-                 * However firePropertyChange also modifies the navigation history.
-                 * Thus, a dummy input with the real entry but a null extension is set.
-                 * This avoids to modification of the navigation history.
-                 * Afterwards the real input is set.
-                 */
-                EntryEditorInput eei = ( EntryEditorInput ) input;
-                IEntry entry = eei.getEntryInput();
-                ISearchResult searchResult = eei.getSearchResultInput();
-                IBookmark bookmark = eei.getBookmarkInput();
-                EntryEditorInput dummyInput;
-                if ( entry != null )
-                {
-                    dummyInput = new EntryEditorInput( entry, null );
-                }
-                else if ( searchResult != null )
-                {
-                    dummyInput = new EntryEditorInput( searchResult, null );
-                }
-                else
-                {
-                    dummyInput = new EntryEditorInput( bookmark, null );
-                }
-                doSetInput( dummyInput );
-                firePropertyChange( IEditorPart.PROP_INPUT );
-
-                // now set the real input and mark history location
-                doSetInput( input );
-                getSite().getPage().getNavigationHistory().markLocation( this );
-            }
-        }
-        catch ( CoreException e )
-        {
-            throw new RuntimeException( e );
-        }
-        finally
-        {
-            inShowEditorInput = false;
-        }
-    }
-
 }

Modified: directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/ldapbrowser/ui/editors/searchresult/SearchResultEditor.java
URL: http://svn.apache.org/viewvc/directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/ldapbrowser/ui/editors/searchresult/SearchResultEditor.java?rev=814009&r1=814008&r2=814009&view=diff
==============================================================================
--- directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/ldapbrowser/ui/editors/searchresult/SearchResultEditor.java (original)
+++ directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/ldapbrowser/ui/editors/searchresult/SearchResultEditor.java Fri Sep 11 20:11:30 2009
@@ -21,11 +21,26 @@
 package org.apache.directory.studio.ldapbrowser.ui.editors.searchresult;
 
 
+import org.apache.directory.studio.connection.ui.RunnableContextRunner;
+import org.apache.directory.studio.entryeditors.EntryEditorUtils;
+import org.apache.directory.studio.ldapbrowser.common.BrowserCommonActivator;
+import org.apache.directory.studio.ldapbrowser.core.events.EntryModificationEvent;
+import org.apache.directory.studio.ldapbrowser.core.events.EntryUpdateListener;
+import org.apache.directory.studio.ldapbrowser.core.events.EventRegistry;
+import org.apache.directory.studio.ldapbrowser.core.jobs.ExecuteLdifRunnable;
+import org.apache.directory.studio.ldapbrowser.core.model.IEntry;
 import org.apache.directory.studio.ldapbrowser.core.model.ISearch;
+import org.apache.directory.studio.ldapbrowser.core.model.ISearchResult;
+import org.apache.directory.studio.ldapbrowser.core.model.impl.SearchResult;
+import org.apache.directory.studio.ldapbrowser.core.utils.CompoundModification;
+import org.apache.directory.studio.ldapbrowser.core.utils.Utils;
 import org.apache.directory.studio.ldapbrowser.ui.BrowserUIConstants;
 import org.apache.directory.studio.ldapbrowser.ui.BrowserUIPlugin;
 import org.apache.directory.studio.ldapbrowser.ui.views.browser.BrowserView;
+import org.apache.directory.studio.ldifparser.LdifFormatParameters;
+import org.apache.directory.studio.ldifparser.model.container.LdifChangeModifyRecord;
 import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
 import org.eclipse.jface.util.IPropertyChangeListener;
 import org.eclipse.jface.util.PropertyChangeEvent;
 import org.eclipse.jface.viewers.ISelection;
@@ -70,6 +85,69 @@
     /** The universal listener. */
     private SearchResultEditorUniversalListener universalListener;
 
+    private ISearch workingCopy;
+    
+    protected EntryUpdateListener entryUpdateListener = new EntryUpdateListener()
+    {
+        public void entryUpdated( EntryModificationEvent event )
+        {
+            if ( workingCopy == null || mainWidget.getViewer() == null || mainWidget.getViewer().getInput() == null )
+            {
+                return;
+            }
+
+            IEntry modifiedEntry = event.getModifiedEntry();
+            
+            if(workingCopy != null)
+            {
+                for(ISearchResult sr : workingCopy.getSearchResults() )
+                {
+                    // check on object identity, nothing should be done for equal objects from other editors
+                    if( modifiedEntry == sr.getEntry())
+                    {
+                        // TODO: save
+                        System.out.println("save()");
+                        // doSaveEntry( sr.getEntry(), modifiedEntry );
+                        
+                        IEntry originalEntry = modifiedEntry.getBrowserConnection().getEntryFromCache( modifiedEntry.getDn() );
+                        LdifChangeModifyRecord diff = Utils.computeDiff(originalEntry, modifiedEntry );
+                        if ( diff != null )
+                        {
+                            // save
+                            ExecuteLdifRunnable runnable = new ExecuteLdifRunnable( originalEntry
+                                .getBrowserConnection(), diff.toFormattedString( LdifFormatParameters.DEFAULT ), false,
+                                false );
+                            IStatus status = RunnableContextRunner.execute( runnable, null, true );
+                            if ( status.isOK() )
+                            {
+                                EntryEditorUtils.ensureAttributesInitialized( originalEntry );
+                                setSearchResultEditorWidgetInput( ( SearchResultEditorInput ) getEditorInput() );
+                            }
+                        }
+                        
+                        return;
+                    }
+                }
+                
+            
+            
+                IEditorInput input = getEditorInput();
+                if ( input instanceof SearchResultEditorInput )
+                {
+                    SearchResultEditorInput srei = ( SearchResultEditorInput ) input;
+                    for(ISearchResult sr : srei.getSearch().getSearchResults() )
+                    {
+                        if(modifiedEntry == sr.getEntry())
+                        {
+                            // original entry has been updated, update widget input
+                            setSearchResultEditorWidgetInput( srei );
+                        }
+                    }
+                }
+
+            }
+        }
+    };
 
     /**
      * Gets the ID of the SearchResultEditor.
@@ -93,7 +171,8 @@
         {
             SearchResultEditorInput srei = ( SearchResultEditorInput ) input;
             ISearch search = srei.getSearch();
-            universalListener.setInput( search );
+            
+            setSearchResultEditorWidgetInput( srei );
 
             if ( search != null )
             {
@@ -115,6 +194,31 @@
     }
 
 
+    private void setSearchResultEditorWidgetInput(SearchResultEditorInput srei)
+    {
+        // clone search, search results, entries
+        ISearch search = srei.getSearch();
+        workingCopy = search != null ? ( ISearch ) search.clone() : search;
+        if ( search != null && search.getSearchResults() != null  )
+        {
+            ISearchResult[] searchResults = search.getSearchResults();
+            ISearchResult[] clonedSearchResults = new ISearchResult[searchResults.length];
+            for ( int i = 0; i < searchResults.length; i++ )
+            {
+                IEntry entry = searchResults[i].getEntry();
+                IEntry clonedEntry = new CompoundModification().cloneEntry( entry );
+                clonedSearchResults[i] = new SearchResult( clonedEntry, workingCopy );
+            }
+
+            EventRegistry.suspendEventFiringInCurrentThread();
+            workingCopy.setSearchResults( clonedSearchResults );
+            EventRegistry.resumeEventFiringInCurrentThread();
+        }
+
+        universalListener.setInput( workingCopy );
+    }
+
+
     /**
      * Refreshes this search result editor.
      */
@@ -140,6 +244,9 @@
         getSite().getPage().getNavigationHistory().markLocation( this );
 
         setInput( input );
+        
+        EventRegistry
+            .addEntryUpdateListener( entryUpdateListener, BrowserCommonActivator.getDefault().getEventRunner() );
     }
 
 
@@ -199,6 +306,8 @@
     {
         if ( configuration != null )
         {
+            EventRegistry.removeEntryUpdateListener( entryUpdateListener );
+            workingCopy = null;
             actionGroup.dispose();
             actionGroup = null;
             universalListener.dispose();

Modified: directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/ldapbrowser/ui/editors/searchresult/SearchResultEditorCellModifier.java
URL: http://svn.apache.org/viewvc/directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/ldapbrowser/ui/editors/searchresult/SearchResultEditorCellModifier.java?rev=814009&r1=814008&r2=814009&view=diff
==============================================================================
--- directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/ldapbrowser/ui/editors/searchresult/SearchResultEditorCellModifier.java (original)
+++ directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/ldapbrowser/ui/editors/searchresult/SearchResultEditorCellModifier.java Fri Sep 11 20:11:30 2009
@@ -21,10 +21,15 @@
 package org.apache.directory.studio.ldapbrowser.ui.editors.searchresult;
 
 
+import java.util.ArrayList;
+import java.util.List;
+
 import org.apache.directory.studio.ldapbrowser.core.model.AttributeHierarchy;
 import org.apache.directory.studio.ldapbrowser.core.model.IAttribute;
 import org.apache.directory.studio.ldapbrowser.core.model.ISearchResult;
+import org.apache.directory.studio.ldapbrowser.core.model.IValue;
 import org.apache.directory.studio.ldapbrowser.core.model.impl.Attribute;
+import org.apache.directory.studio.ldapbrowser.core.utils.CompoundModification;
 import org.apache.directory.studio.ldapbrowser.ui.BrowserUIConstants;
 import org.apache.directory.studio.valueeditors.ValueEditorManager;
 import org.eclipse.jface.viewers.ICellModifier;
@@ -146,15 +151,23 @@
             // switch operation:
             if ( ah == null && newRawValue != null )
             {
-                valueEditorManager.createValue( result.getEntry(), property, newRawValue );
+                new CompoundModification().createValue( result.getEntry(), property, newRawValue );
             }
             else if ( ah != null && newRawValue == null )
             {
-                valueEditorManager.deleteAttribute( ah );
+                List<IValue> values = new ArrayList<IValue>(); 
+                for(IAttribute attribute : ah.getAttributes())
+                {
+                    for ( IValue value : attribute.getValues() )
+                    {
+                        values.add(value);
+                    }
+                }
+                new CompoundModification().deleteValues( values );
             }
             else if ( ah != null && ah.size() == 1 && ah.getAttribute().getValueSize() == 1 && newRawValue != null )
             {
-                valueEditorManager.modifyValue( ah.getAttribute().getValues()[0], newRawValue );
+                new CompoundModification().modifyValue( ah.getAttribute().getValues()[0], newRawValue );
             }
         }
     }

Modified: directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/ldapbrowser/ui/editors/searchresult/SearchResultEditorConfiguration.java
URL: http://svn.apache.org/viewvc/directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/ldapbrowser/ui/editors/searchresult/SearchResultEditorConfiguration.java?rev=814009&r1=814008&r2=814009&view=diff
==============================================================================
--- directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/ldapbrowser/ui/editors/searchresult/SearchResultEditorConfiguration.java (original)
+++ directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/ldapbrowser/ui/editors/searchresult/SearchResultEditorConfiguration.java Fri Sep 11 20:11:30 2009
@@ -242,7 +242,7 @@
     {
         if ( valueEditorManager == null )
         {
-            valueEditorManager = new ValueEditorManager( viewer.getTable() );
+            valueEditorManager = new ValueEditorManager( viewer.getTable(), true );
         }
         return valueEditorManager;
     }



Mime
View raw message