From commits-return-22889-apmail-directory-commits-archive=directory.apache.org@directory.apache.org Wed Sep 02 12:41:34 2009 Return-Path: Delivered-To: apmail-directory-commits-archive@www.apache.org Received: (qmail 50725 invoked from network); 2 Sep 2009 12:41:34 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 2 Sep 2009 12:41:34 -0000 Received: (qmail 65156 invoked by uid 500); 2 Sep 2009 12:41:34 -0000 Delivered-To: apmail-directory-commits-archive@directory.apache.org Received: (qmail 65096 invoked by uid 500); 2 Sep 2009 12:41:34 -0000 Mailing-List: contact commits-help@directory.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@directory.apache.org Delivered-To: mailing list commits@directory.apache.org Received: (qmail 65087 invoked by uid 99); 2 Sep 2009 12:41:34 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 02 Sep 2009 12:41:34 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 02 Sep 2009 12:41:32 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 5FC5F2388908; Wed, 2 Sep 2009 12:41:12 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r810484 - in /directory/studio/trunk: ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/impl/ ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/utils/ ldapbrowser-ui/src/main/java/or... Date: Wed, 02 Sep 2009 12:41:12 -0000 To: commits@directory.apache.org From: seelmann@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20090902124112.5FC5F2388908@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: seelmann Date: Wed Sep 2 12:41:11 2009 New Revision: 810484 URL: http://svn.apache.org/viewvc?rev=810484&view=rev Log: Partial fix for DIRSTUDIO-518: The multi-tab entry editor now follows the open-save-close lifecycle. Modified: directory/studio/trunk/ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/impl/DummyEntry.java directory/studio/trunk/ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/utils/Utils.java directory/studio/trunk/ldapbrowser-ui/src/main/java/org/apache/directory/studio/ldapbrowser/ui/editors/entry/MultiTabEntryEditor.java Modified: directory/studio/trunk/ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/impl/DummyEntry.java URL: http://svn.apache.org/viewvc/directory/studio/trunk/ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/impl/DummyEntry.java?rev=810484&r1=810483&r2=810484&view=diff ============================================================================== --- directory/studio/trunk/ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/impl/DummyEntry.java (original) +++ directory/studio/trunk/ldapbrowser-core/src/main/java/org/apache/directory/studio/ldapbrowser/core/model/impl/DummyEntry.java Wed Sep 2 12:41:11 2009 @@ -33,7 +33,6 @@ import org.apache.directory.shared.ldap.schema.parsers.ObjectClassDescription; import org.apache.directory.shared.ldap.util.LdapURL; import org.apache.directory.studio.connection.core.jobs.StudioBulkRunnableWithProgress; -import org.apache.directory.studio.ldapbrowser.core.BrowserCorePlugin; import org.apache.directory.studio.ldapbrowser.core.events.AttributeAddedEvent; import org.apache.directory.studio.ldapbrowser.core.events.AttributeDeletedEvent; import org.apache.directory.studio.ldapbrowser.core.events.EventRegistry; @@ -67,12 +66,9 @@ /** The DN. */ private LdapDN dn; - /** The dummy connection. */ - private DummyConnection dummyConnection; - - /** The connection id. */ - private String connectionId; - + /** The browser connection. */ + private IBrowserConnection browserConnection; + /** The attribute map. */ private Map attributeMap; @@ -90,17 +86,8 @@ */ public DummyEntry( LdapDN dn, IBrowserConnection browserConnection ) { - if ( browserConnection instanceof DummyConnection ) - { - this.dummyConnection = ( DummyConnection ) browserConnection; - } - else - { - this.connectionId = browserConnection.getConnection() != null ? browserConnection.getConnection().getId() - : null; - } - this.dn = dn; + this.browserConnection = browserConnection; attributeMap = new LinkedHashMap(); } @@ -214,12 +201,6 @@ */ public IBrowserConnection getBrowserConnection() { - IBrowserConnection browserConnection = dummyConnection != null ? dummyConnection : BrowserCorePlugin - .getDefault().getConnectionManager().getBrowserConnectionById( this.connectionId ); - if ( browserConnection == null ) - { - throw new IllegalStateException( "Connection " + connectionId + " does not exist." ); - } return browserConnection; } 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=810484&r1=810483&r2=810484&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 Wed Sep 2 12:41:11 2009 @@ -503,7 +503,7 @@ // check for changes: if there are no changes the record does not include // any modifications and so it is not valid. - return record.isValid() ? record : null; + return record.isValid() && record.getModSpecs().length > 0 ? record : null; } } 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=810484&r1=810483&r2=810484&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 Wed Sep 2 12:41:11 2009 @@ -21,13 +21,39 @@ package org.apache.directory.studio.ldapbrowser.ui.editors.entry; +import java.lang.reflect.InvocationTargetException; + +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.jface.operation.IRunnableContext; +import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.ui.IEditorInput; /** * An entry editor the opens a new editor tab for each entry. + * + * TODO: Configurable modificaton mode + * Right now the modification mode is fixed: no immediate commit of changes, + * instead the editor follows the open-save-close lifecycle. * * @author Apache Directory Project * @version $Rev$, $Date$ @@ -35,6 +61,21 @@ 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. * @@ -45,16 +86,167 @@ return BrowserUIConstants.EDITOR_MULTI_TAB_ENTRY_EDITOR; } + @Override public void setInput( IEditorInput input ) { super.setInput( input ); - - if(input instanceof EntryEditorInput) + + 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; + EntryEditorInput entryEditorInput = ( EntryEditorInput ) input; setPartName( entryEditorInput.getName() ); - //setContentDescription( 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 ) + { + IRunnableContext runnableContext = new IRunnableContext() + { + public void run( boolean fork, boolean cancelable, IRunnableWithProgress runnable ) + throws InvocationTargetException, InterruptedException + { + runnable.run( monitor ); + } + }; + + // save + ExecuteLdifRunnable runnable = new ExecuteLdifRunnable( browserConnection, diff + .toFormattedString( LdifFormatParameters.DEFAULT ), false, false ); + IStatus status = RunnableContextRunner.execute( runnable, runnableContext, 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 ) + { + if ( !entry.isAttributesInitialized() ) + { + boolean foa = entry.getBrowserConnection().isFetchOperationalAttributes(); + InitializeAttributesRunnable iar = new InitializeAttributesRunnable( new IEntry[] + { entry }, foa ); + RunnableContextRunner.execute( iar, null, true ); + } + } + + + @Override + public void dispose() + { + // remove the listener + EventRegistry.removeEntryUpdateListener( entryUpdateListener ); + super.dispose(); + } + }