diff options
Diffstat (limited to 'target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/compare/EditableSharedDocumentAdapter.java')
-rw-r--r-- | target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/compare/EditableSharedDocumentAdapter.java | 256 |
1 files changed, 256 insertions, 0 deletions
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/compare/EditableSharedDocumentAdapter.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/compare/EditableSharedDocumentAdapter.java new file mode 100644 index 000000000..ae087ace0 --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/compare/EditableSharedDocumentAdapter.java @@ -0,0 +1,256 @@ +/******************************************************************************* + * Copyright (c) 2005, 2014 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.tcf.filesystem.ui.internal.compare; + +import org.eclipse.compare.SharedDocumentAdapter; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jface.text.IDocument; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.texteditor.IDocumentProvider; +import org.eclipse.ui.texteditor.IElementStateListener; + +/** + * A shared document adapter that tracks whether the element is connected to a + * shared document and whether the contents have been flushed from a compare + * viewer. When contents are flushed, this adapter will connect to the document + * provider to ensure that the changes are not lost (see + * {@link #hasBufferedContents()}). In order to avoid a leak, the buffer must + * either be saved (see + * {@link #saveDocument(IEditorInput, boolean, IProgressMonitor)}) or released + * (see {@link #releaseBuffer()}). + * <p> + * This adapter must have a one-to-one correspondence to a typed element. + * + * @since 3.7 - Copied from + * org.eclipse.team.internal.ui.synchronize.EditableSharedDocumentAdapter + */ +public class EditableSharedDocumentAdapter extends SharedDocumentAdapter implements IElementStateListener { + + private int connectionCount; + private final ISharedDocumentAdapterListener listener; + private IEditorInput bufferedKey; + + /** + * Interface that provides this adapter with the action of the typed element + * and supports call backs to the element when the adapter action changes. + */ + public interface ISharedDocumentAdapterListener { + + /** + * Method that is invoked when the adapter connects to the document + * provider. This method is only invoked when the adapter first connects + * to the document. + */ + void handleDocumentConnected(); + + /** + * Method that is invoked when the adapter disconnects from the document + * provider. This method is only invoked when the adapter no longer has + * any connection to the document provider. + */ + void handleDocumentDisconnected(); + + /** + * Method invoked when changes in the document are flushed to the + * adapter. + */ + void handleDocumentFlushed(); + + /** + * Method invoked when the file behind the shared document is deleted. + */ + void handleDocumentDeleted(); + + /** + * Method invoked when the document dirty action changes from dirty to + * clean. + */ + void handleDocumentSaved(); + } + + /** + * Create the shared document adapter for the given element. + * + * @param listener + * access to element internals + */ + public EditableSharedDocumentAdapter(ISharedDocumentAdapterListener listener) { + super(); + this.listener = listener; + } + + /* (non-Javadoc) + * @see org.eclipse.compare.SharedDocumentAdapter#connect(org.eclipse.ui.texteditor.IDocumentProvider, org.eclipse.ui.IEditorInput) + */ + @Override + public void connect(IDocumentProvider provider, IEditorInput documentKey) + throws CoreException { + super.connect(provider, documentKey); + connectionCount++; + if (connectionCount == 1) { + provider.addElementStateListener(this); + listener.handleDocumentConnected(); + } + } + + /* (non-Javadoc) + * @see org.eclipse.compare.SharedDocumentAdapter#disconnect(org.eclipse.ui.texteditor.IDocumentProvider, org.eclipse.ui.IEditorInput) + */ + @Override + public void disconnect(IDocumentProvider provider, IEditorInput documentKey) { + try { + super.disconnect(provider, documentKey); + } finally { + if (connectionCount > 0) + connectionCount--; + if (connectionCount == 0) { + provider.removeElementStateListener(this); + listener.handleDocumentDisconnected(); + } + } + } + + /** + * Return whether the element is connected to a shared document. + * + * @return whether the element is connected to a shared document + */ + public boolean isConnected() { + return connectionCount > 0; + } + + /** + * Save the shared document of the element of this adapter. + * + * @param input + * the document key of the element. + * @param monitor + * a progress monitor + * @return whether the save succeeded or not + * @throws CoreException + */ + public boolean saveDocument(IEditorInput input, IProgressMonitor monitor) + throws CoreException { + if (isConnected()) { + IDocumentProvider provider = SharedDocumentAdapter + .getDocumentProvider(input); + try { + saveDocument(provider, input, provider.getDocument(input), + true, monitor); + } finally { + // When we write the document, remove out hold on the buffer + releaseBuffer(); + } + return true; + } + return false; + } + + /** + * Release the buffer if this adapter has buffered the contents in response + * to a + * {@link #flushDocument(IDocumentProvider, IEditorInput, IDocument, boolean)} + * . + */ + public void releaseBuffer() { + if (bufferedKey != null) { + IDocumentProvider provider = SharedDocumentAdapter + .getDocumentProvider(bufferedKey); + provider.disconnect(bufferedKey); + bufferedKey = null; + } + } + + /* (non-Javadoc) + * @see org.eclipse.compare.ISharedDocumentAdapter#flushDocument(org.eclipse.ui.texteditor.IDocumentProvider, org.eclipse.ui.IEditorInput, org.eclipse.jface.text.IDocument, boolean) + */ + @Override + public void flushDocument(IDocumentProvider provider, + IEditorInput documentKey, IDocument document, boolean overwrite) + throws CoreException { + if (!hasBufferedContents()) { + // On a flush, make an extra connection to the shared document so it + // will be kept even + // if it is no longer being viewed. + bufferedKey = documentKey; + provider.connect(bufferedKey); + } + this.listener.handleDocumentFlushed(); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.IElementStateListener#elementContentAboutToBeReplaced(java.lang.Object) + */ + @Override + public void elementContentAboutToBeReplaced(Object element) { + // Nothing to do + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.IElementStateListener#elementContentReplaced(java.lang.Object) + */ + @Override + public void elementContentReplaced(Object element) { + // Nothing to do + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.IElementStateListener#elementDeleted(java.lang.Object) + */ + @Override + public void elementDeleted(Object element) { + listener.handleDocumentDeleted(); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.IElementStateListener#elementDirtyStateChanged(java.lang.Object, boolean) + */ + @Override + public void elementDirtyStateChanged(Object element, boolean isDirty) { + if (!isDirty) { + this.listener.handleDocumentSaved(); + } + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.IElementStateListener#elementMoved(java.lang.Object, java.lang.Object) + */ + @Override + public void elementMoved(Object originalElement, Object movedElement) { + // Nothing to do + } + + /** + * Return whether the adapter has buffered contents. The adapter buffers + * contents by connecting to the document through the document provider. + * This means that the adapter must be disconnected either by saving or + * discarding the buffer. + * + * @return whether the adapter has buffered contents + */ + public boolean hasBufferedContents() { + return bufferedKey != null; + } + + /** + * Override getDocumentKey in the super class to provide an editor input + * when the element is a <code>LocalTypedElement</code>. + */ + @Override + public IEditorInput getDocumentKey(Object element) { + if (element instanceof LocalTypedElement) { + LocalTypedElement localElement = (LocalTypedElement) element; + return localElement.getEditorInput(); + } + return super.getDocumentKey(element); + } +} |