diff options
author | Kai Maetzel | 2003-08-13 15:36:19 +0000 |
---|---|---|
committer | Kai Maetzel | 2003-08-13 15:36:19 +0000 |
commit | f468248b2df4e628526f9c05c894730ec5f4bb10 (patch) | |
tree | ba9d457ba0fc1be07574cd59750f5b44e05fccdb /org.eclipse.core.filebuffers | |
parent | dde83e48764032608c18f8e7a87ee0a582915538 (diff) | |
download | eclipse.platform.text-f468248b2df4e628526f9c05c894730ec5f4bb10.tar.gz eclipse.platform.text-f468248b2df4e628526f9c05c894730ec5f4bb10.tar.xz eclipse.platform.text-f468248b2df4e628526f9c05c894730ec5f4bb10.zip |
*** empty log message ***v1_0
Diffstat (limited to 'org.eclipse.core.filebuffers')
19 files changed, 991 insertions, 2055 deletions
diff --git a/org.eclipse.core.filebuffers/src/org/eclipse/core/filebuffers/FileBuffers.java b/org.eclipse.core.filebuffers/src/org/eclipse/core/filebuffers/FileBuffers.java index 3ab9f6788..83df569e7 100644 --- a/org.eclipse.core.filebuffers/src/org/eclipse/core/filebuffers/FileBuffers.java +++ b/org.eclipse.core.filebuffers/src/org/eclipse/core/filebuffers/FileBuffers.java @@ -13,14 +13,25 @@ package org.eclipse.core.filebuffers; import org.eclipse.core.internal.filebuffers.FileBuffersPlugin; /** - * + * Facade for the file buffers plug-in. Provides access to the + * text file buffer manager. + * + * @since 3.0 */ public final class FileBuffers { + /** + * Cannot be instantiated. + */ private FileBuffers() { } + /** + * Returns the text file buffer manager. + * + * @return the text file buffer manager + */ public static ITextFileBufferManager getTextFileBufferManager() { - return FileBuffersPlugin.getDefault().getBufferedFileManager(); + return FileBuffersPlugin.getDefault().getFileBufferManager(); } } diff --git a/org.eclipse.core.filebuffers/src/org/eclipse/core/filebuffers/IDocumentFactory.java b/org.eclipse.core.filebuffers/src/org/eclipse/core/filebuffers/IDocumentFactory.java index 72496e32b..989ecf993 100644 --- a/org.eclipse.core.filebuffers/src/org/eclipse/core/filebuffers/IDocumentFactory.java +++ b/org.eclipse.core.filebuffers/src/org/eclipse/core/filebuffers/IDocumentFactory.java @@ -13,7 +13,10 @@ package org.eclipse.core.filebuffers; import org.eclipse.jface.text.IDocument; /** - * Factory for documents. + * Factory for text file buffer documents. Used by the text file buffer + * manager to create the document for a new text file buffer. + * + * @since 3.0 */ public interface IDocumentFactory { diff --git a/org.eclipse.core.filebuffers/src/org/eclipse/core/filebuffers/IDocumentSetupParticipant.java b/org.eclipse.core.filebuffers/src/org/eclipse/core/filebuffers/IDocumentSetupParticipant.java index 9e10724d4..93a5d5ad8 100644 --- a/org.eclipse.core.filebuffers/src/org/eclipse/core/filebuffers/IDocumentSetupParticipant.java +++ b/org.eclipse.core.filebuffers/src/org/eclipse/core/filebuffers/IDocumentSetupParticipant.java @@ -13,13 +13,14 @@ package org.eclipse.core.filebuffers; import org.eclipse.jface.text.IDocument; /** - * Participates in the setup of a document. + * Participates in the setup of a text file buffer document. + * * @since 3.0 */ public interface IDocumentSetupParticipant { /** - * Sets up the document to be ready for usage. + * Sets up the document to be ready for use by a text file buffer. * * @param document the document to be set up */ diff --git a/org.eclipse.core.filebuffers/src/org/eclipse/core/filebuffers/IFileBuffer.java b/org.eclipse.core.filebuffers/src/org/eclipse/core/filebuffers/IFileBuffer.java index b44cc693d..c8d60f93a 100644 --- a/org.eclipse.core.filebuffers/src/org/eclipse/core/filebuffers/IFileBuffer.java +++ b/org.eclipse.core.filebuffers/src/org/eclipse/core/filebuffers/IFileBuffer.java @@ -16,25 +16,82 @@ import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; /** - * + * A file buffer represents a file that can be edited by more than one client. Editing is + * session oriented. This means that editing is a sequence of modification steps. The + * start of the sequence and the end of the sequence are explicitly indicated. There are + * no time constraints connected with the sequence of modification steps. A file buffer + * reifies editing sessions and allows them to interleave.<p> + * It is not sepcified whether simultaneous editing sessions can be owned by different + * threads. + * + * @since 3.0 */ public interface IFileBuffer { + /** + * Returns the underlying file of this file buffer. + * + * @return the underlying file of this file buffer + */ IFile getUnderlyingFile(); - void addFileBufferListener(IFileBufferListener listener); - - void removeFileBufferListener(IFileBufferListener listener); - + /** + * Reverts the contents of this file buffer to the content of its underlying file. After + * that call successfully returned, <code>isDirty</code> returns <code>false</code>. + * + * @param monitor the progress monitor + * @throws CoreException if reading or accessing the underlying file fails + */ void revert(IProgressMonitor monitor) throws CoreException; + /** + * Commits this file buffer by changing the contents of th underlying file to + * the contents of this file buffer. After that call, <code>isDirty</code> + * returns <code>false</code>. + * + * @param monitor the progress monitor + * @param overwrite indicates whether the underlying file should be overwritten if it is not uin synch with the file system + * @throws CoreException if writing or accessing the underlying file fails + */ void commit(IProgressMonitor monitor, boolean overwrite) throws CoreException; - + + /** + * Returns whether changes have been applied to this file buffer since initialization, or the most + * recent <code>revert</code> or <code>commit</code> call. + * + * @return <code>true</code> if changes have been applied to this buffer + */ boolean isDirty(); + /** + * Returns whether this file buffer is shared by more than one client. + * + * @return <code>true</code> if this file buffer is shared by more than one client + */ + boolean isShared(); + + /** + * Validates the state of this file buffer and tries to bring the buffer's underlying file into + * a state in which it can be modified. + * + * @param monitor the progress monitor + * @param computationContext the context in which the validation is performed, e.g., a SWT shell + * @exception CoreException if the underlying file can not be accessed to it's state cannot be changed + */ void validateState(IProgressMonitor monitor, Object computationContext) throws CoreException; + /** + * Returns whether the state of this file buffer has been validated. + * + * @return <code>true</code> if the state has been validated, <code>false</code> otherwise + */ boolean isStateValidated(); + /** + * Returns the status of this file buffer. This is the result of the last operation peformed on this file buffer or + * internally initiated by this file buffer. + * + * @return the status of this file buffer + */ IStatus getStatus(); } diff --git a/org.eclipse.core.filebuffers/src/org/eclipse/core/filebuffers/IFileBufferListener.java b/org.eclipse.core.filebuffers/src/org/eclipse/core/filebuffers/IFileBufferListener.java index fd259bf73..2e57914d3 100644 --- a/org.eclipse.core.filebuffers/src/org/eclipse/core/filebuffers/IFileBufferListener.java +++ b/org.eclipse.core.filebuffers/src/org/eclipse/core/filebuffers/IFileBufferListener.java @@ -13,23 +13,72 @@ package org.eclipse.core.filebuffers; import org.eclipse.core.resources.IFile; /** + * Interface for listeners of file buffer changes. * + * @since 3.0 */ public interface IFileBufferListener { + /** + * Informs the listener about an upcoming replace of the contents of the given buffer. + * + * @param buffer the effected file buffer + */ void bufferContentAboutToBeReplaced(IFileBuffer buffer); + /** + * Informs the listener that the buffer of the given buffer has been replaced. + * + * @param buffer the effected file buffer + */ void bufferContentReplaced(IFileBuffer buffer); + /** + * Informs the listener about the start of a state changing operation on + * the given buffer. + * + * @param buffer the effected file buffer + */ void stateChanging(IFileBuffer buffer); + /** + * Informs the listener that the dirty state of the given buffer changed + * to the specified value + * + * @param buffer the effected file buffer + * @param isDirty <code>true</code> if the buffer is dirty, <code>false</code> otherwise + */ void dirtyStateChanged(IFileBuffer buffer, boolean isDirty); - + + /** + * Informs the listener that the state validation changed to the specified value. + * + * @param buffer the effected file buffer + * @param isStateValidated <code>true</code> if the buffer state is validated, <code>false</code> otherwise + */ void stateValidationChanged(IFileBuffer buffer, boolean isStateValidated); - + + /** + * Informs the listener that the file underlying the given file buffer has been moved to the + * given location. + * + * @param buffer the effected file buffer + * @param target the new location + */ void underlyingFileMoved(IFileBuffer buffer, IFile target); + /** + * Informs the listener that the file underlying the given file buffer has been deleted. + * + * @param buffer the effected file buffer + */ void underlyingFileDeleted(IFileBuffer buffer); - + + /** + * Informs the listener that a state changing operation on the given + * file buffer failed. + * + * @param buffer the effected file buffer + */ void stateChangeFailed(IFileBuffer buffer); } diff --git a/org.eclipse.core.filebuffers/src/org/eclipse/core/filebuffers/IFileBufferManager.java b/org.eclipse.core.filebuffers/src/org/eclipse/core/filebuffers/IFileBufferManager.java index 9b843433e..3720ac2b2 100644 --- a/org.eclipse.core.filebuffers/src/org/eclipse/core/filebuffers/IFileBufferManager.java +++ b/org.eclipse.core.filebuffers/src/org/eclipse/core/filebuffers/IFileBufferManager.java @@ -13,11 +13,67 @@ package org.eclipse.core.filebuffers; import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +/** + * A file buffer manager manages file buffers for files while the files are + * connected to the file buffer manager. In order to connect a file to a + * file buffer manager call <code>connect</code>. After that call has + * successfully completed the file buffer can be obtained by <code>getFileBuffer</code>. + * The file buffer is created on the first connect and destroyed on the + * last disconnect. I.e. the file buffer manager keeps track of how often a + * file is connected and returns the same file buffer to each client as long as + * the file is connected. + * + * @since 3.0 + */ public interface IFileBufferManager { - void connect(IFile file) throws CoreException; + /** + * Connects the given file to this manager. After that call successfully completed + * it is guaranteed that each call to <code>getFileBuffer</code> returns the + * same file buffer until <code>disconnect</code> is called. + * + * @param file the file to be connected + * @param monitor the progress monitor + * @throws CoreException if the file could not successfully be connected + */ + void connect(IFile file, IProgressMonitor monitor) throws CoreException; - void disconnect(IFile file) throws CoreException; + /** + * Disconnects the given file from this manager. After that call successfully completed + * there is no guarantee that <code>getFileBuffer</code> will return a valid file buffer. + * + * @param file the file to be disconnected + * @param monitor the progress monitor + * @throws CoreException if the file could not successfully be disconnected + */ + void disconnect(IFile file, IProgressMonitor monitor) throws CoreException; + + /** + * Returns the file buffer for the given file or <code>null</code> if the file + * is not connected to this manager. + * + * @param file the file + * @return the file buffer managed for that file or <code>null</code> + */ + IFileBuffer getFileBuffer(IFile file); + + /** + * Adds the given listener to the list of file buffer listeners. After that call the + * listener is informated about changes related to this file buffer. If the + * listener is already registered with the file buffer, this call has no effect. + * + * @param listener the listener to be added + */ + void addFileBufferListener(IFileBufferListener listener); + + /** + * Removes the given listener from the list of file buffer listeners. If the listener is not + * registered with this file buffer, this call has no effect. + * + * @param listener the listener to be removed + */ + void removeFileBufferListener(IFileBufferListener listener); } diff --git a/org.eclipse.core.filebuffers/src/org/eclipse/core/filebuffers/ITextFileBuffer.java b/org.eclipse.core.filebuffers/src/org/eclipse/core/filebuffers/ITextFileBuffer.java index 9943dde38..60da3a8bb 100644 --- a/org.eclipse.core.filebuffers/src/org/eclipse/core/filebuffers/ITextFileBuffer.java +++ b/org.eclipse.core.filebuffers/src/org/eclipse/core/filebuffers/ITextFileBuffer.java @@ -13,12 +13,36 @@ package org.eclipse.core.filebuffers; import org.eclipse.jface.text.IDocument; - +/** + * A text file buffer is a file buffer for text files. The contents of a text file buffe is + * given in the form of a document. Also, the text file buffer provides methods to + * manage the character encoding used to read and write the buffer's underlying + * text file. + * + * @since 3.0 + */ public interface ITextFileBuffer extends IFileBuffer { + /** + * Returns the document of this text file buffer. + * + * @return the document of this text file buffer + */ IDocument getDocument(); - + + /** + * Returns the character encoding to be used for reading and writing the + * buffer's underlying file. + * + * @return the character encoding + */ String getEncoding(); + /** + * Sets the character encoding to be used for reading and writing the buffer's + * underlyning file. + * + * @param encoding the encoding + */ void setEncoding(String encoding); } diff --git a/org.eclipse.core.filebuffers/src/org/eclipse/core/filebuffers/ITextFileBufferManager.java b/org.eclipse.core.filebuffers/src/org/eclipse/core/filebuffers/ITextFileBufferManager.java index 73a963ac0..268733a96 100644 --- a/org.eclipse.core.filebuffers/src/org/eclipse/core/filebuffers/ITextFileBufferManager.java +++ b/org.eclipse.core.filebuffers/src/org/eclipse/core/filebuffers/ITextFileBufferManager.java @@ -16,11 +16,37 @@ import org.eclipse.core.resources.IFile; import org.eclipse.jface.text.IDocument; +/** + * A text file buffer manager manages text file buffers for files whose contents + * could be considered text. + * + * @since 3.0 + */ public interface ITextFileBufferManager extends IFileBufferManager { + /** + * Returns the text file buffer managed for the given file or <code>null</code> if either + * the file is not connected or the file is not a text file. + * + * @param file the file + * @return the text file buffer managed for that file or <code>null</code> + */ ITextFileBuffer getTextFileBuffer(IFile file); + /** + * Returns the default encoding that is used to read the contents of text files + * if no other encoding is specified. + * + * @return the default text file encoding + */ String getDefaultEncoding(); + /** + * Creates a new empty document . The document is setup in the same way as it would + * be used in a text file buffer for the given file. + * + * @param file the file used to setup the newly created document + * @return a new empty document + */ IDocument createEmptyDocument(IFile file); } diff --git a/org.eclipse.core.filebuffers/src/org/eclipse/core/internal/filebuffers/AbstractDocumentProvider2.java b/org.eclipse.core.filebuffers/src/org/eclipse/core/internal/filebuffers/AbstractDocumentProvider2.java deleted file mode 100644 index d3308a2a0..000000000 --- a/org.eclipse.core.filebuffers/src/org/eclipse/core/internal/filebuffers/AbstractDocumentProvider2.java +++ /dev/null @@ -1,661 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ - -package org.eclipse.core.internal.filebuffers; - -import java.util.ArrayList; -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.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.core.runtime.Status; - -import org.eclipse.jface.text.Assert; -import org.eclipse.jface.text.DocumentEvent; -import org.eclipse.jface.text.IDocument; -import org.eclipse.jface.text.IDocumentListener; - - - -/** - * An abstract implementation of a shareable document provider. - * <p> - * Subclasses must implement <code>createDocument</code>, - * <code>createAnnotationModel</code>, and <code>doSaveDocument</code>. - * </p> - */ -public abstract class AbstractDocumentProvider2 implements IDocumentProvider2 { - - /** - * Collection of all information managed for a connected element. - */ - protected class ElementInfo implements IDocumentListener { - - /** The element for which the info is stored */ - public Object fElement; - /** How often the element has been connected */ - public int fReferenceCount; - /** Can the element be saved */ - public boolean fCanBeSaved; - /** The element's document */ - public IDocument fDocument; - /** Has element state been validated */ - public boolean fIsStateValidated; - /** The status of this element */ - public IStatus fStatus; - - - /** - * Creates a new element info, initialized with the given - * document and annotation model. - * - * @param document the document - */ - public ElementInfo(IDocument document) { - fDocument= document; - fReferenceCount= 0; - fCanBeSaved= false; - fIsStateValidated= false; - } - - /** - * An element info equals another object if this object is an element info - * and if the elements of the two element infos are equal. - */ - public boolean equals(Object o) { - if (o instanceof ElementInfo) { - ElementInfo e= (ElementInfo) o; - return fElement.equals(e.fElement); - } - return false; - } - - /* - * @see Object#hashCode() - */ - public int hashCode() { - return fDocument.hashCode(); - } - - /* - * @see IDocumentListener#documentChanged(DocumentEvent) - */ - public void documentChanged(DocumentEvent event) { - fCanBeSaved= true; - removeUnchangedElementListeners(fElement, this); - fireElementDirtyStateChanged(fElement, fCanBeSaved); - } - - /* - * @see IDocumentListener#documentAboutToBeChanged(DocumentEvent) - */ - public void documentAboutToBeChanged(DocumentEvent event) { - } - }; - - /** - * Constant for representing the ok status. This is considered a value object. - */ - static final protected IStatus STATUS_OK= new Status(IStatus.OK, FileBuffersPlugin.PLUGIN_ID, IStatus.OK, "AbstractDocumentProvider.ok", null); - /** - * Constant for representing the error status. This is considered a value object. - */ - static final protected IStatus STATUS_ERROR= new Status(IStatus.ERROR, FileBuffersPlugin.PLUGIN_ID, IStatus.INFO, "AbstractDocumentProvider.error", null); - - - /** Element information of all connected elements */ - private Map fElementInfoMap= new HashMap(); - /** The element state listeners */ - private List fElementStateListeners= new ArrayList(); - /** The current progress monitor */ - private IProgressMonitor fProgressMonitor; - - - /** - * Creates a new document provider. - */ - protected AbstractDocumentProvider2() { - } - - /** - * Creates the document for the given element. - * <p> - * Subclasses must implement this method.</p> - * - * @param element the element - * @return the document - * @exception CoreException if the document could not be created - */ - protected abstract IDocument createDocument(Object element) throws CoreException; - - /** - * Performs the actual work of saving the given document provided for the given element. - * <p> - * Subclasses must implement this method.</p> - * - * @param element the element - * @param document the document - * @param overwrite indicates whether an overwrite should happen if necessary - * @exception CoreException if document could not be stored to the given element - */ - protected abstract void doSaveDocument(Object element, IDocument document, boolean overwrite) throws CoreException; - - - /** - * Returns the element info object for the given element. - * - * @param element the element - * @return the element info object, or <code>null</code> if none - */ - protected ElementInfo getElementInfo(Object element) { - return (ElementInfo) fElementInfoMap.get(element); - } - - /** - * Creates a new element info object for the given element. - * <p> - * This method is called from <code>connect</code> when an element info needs - * to be created. The <code>AbstractDocumentProvider</code> implementation - * of this method returns a new element info object whose document and - * annotation model are the values of <code>createDocument(element)</code> - * and <code>createAnnotationModel(element)</code>, respectively. Subclasses - * may override.</p> - * - * @param element the element - * @return a new element info object - * @exception CoreException if the document or annotation model could not be created - */ - protected ElementInfo createElementInfo(Object element) throws CoreException { - return new ElementInfo(createDocument(element)); - } - - /** - * Disposes the given element info object. - * <p> - * This method is called when an element info is disposed. The - * <code>AbstractDocumentProvider</code> implementation of this - * method does nothing. Subclasses may reimplement.</p> - * - * @param info the element info object - */ - protected void disposeElementInfo(ElementInfo info) { - } - - /** - * Called on initial creation and when the dirty state of the element - * changes to <code>false</code>. Adds all listeners which must be - * active as long as the element is not dirty. This method is called - * before <code>fireElementDirtyStateChanged</code> or <code> - * fireElementContentReplaced</code> is called. - * Subclasses may extend. - * - * @param element the element - * @param info the element info object - */ - protected void addUnchangedElementListeners(Object element, ElementInfo info) { - if (info.fDocument != null) - info.fDocument.addDocumentListener(info); - } - - /** - * Called when the given element gets dirty. Removes all listeners - * which must be active only when the element is not dirty. This - * method is called before <code>fireElementDirtyStateChanged</code> - * or <code>fireElementContentReplaced</code> is called. - * Subclasses may extend. - * - * @param element the element - * @param info the element info object - */ - protected void removeUnchangedElementListeners(Object element, ElementInfo info) { - if (info.fDocument != null) - info.fDocument.removeDocumentListener(info); - } - - /** - * Enumerates the elements connected via this document provider. - * - * @return the list of elements (element type: <code>Object</code>) - */ - protected Iterator getConnectedElementsIterator() { - Set s= new HashSet(); - Set keys= fElementInfoMap.keySet(); - if (keys != null) - s.addAll(keys); - return s.iterator(); - } - - /* - * @see IDocumentProvider#connect(Object) - */ - public final void connect(Object element) throws CoreException { - ElementInfo info= (ElementInfo) fElementInfoMap.get(element); - if (info == null) { - - info= createElementInfo(element); - if (info == null) - info= new ElementInfo(null); - - info.fElement= element; - - addUnchangedElementListeners(element, info); - - fElementInfoMap.put(element, info); - if (fElementInfoMap.size() == 1) - connected(); - } - ++ info.fReferenceCount; - } - - /** - * This hook method is called when this provider starts managing documents for - * elements. I.e. it is called when the first element gets connected to this provider. - * Subclasses may extend. - */ - protected void connected() { - } - - /* - * @see IDocumentProvider#disconnect - */ - public final void disconnect(Object element) { - ElementInfo info= (ElementInfo) fElementInfoMap.get(element); - - if (info == null) - return; - - if (info.fReferenceCount == 1) { - - fElementInfoMap.remove(element); - removeUnchangedElementListeners(element, info); - disposeElementInfo(info); - - if (fElementInfoMap.size() == 0) - disconnected(); - - } else - -- info.fReferenceCount; - } - - /** - * This hook method is called when this provider stops managing documents for - * element. I.e. it is called when the last element gets disconnected from this provider. - * Subcalles may extend. - */ - protected void disconnected() { - } - - /* - * @see IDocumentProvider#getDocument(Object) - */ - public IDocument getDocument(Object element) { - - if (element == null) - return null; - - ElementInfo info= (ElementInfo) fElementInfoMap.get(element); - return (info != null ? info.fDocument : null); - } - - /* - * @see org.eclipse.core.buffer.text.IDocumentProvider#getElement(org.eclipse.jface.text.IDocument) - */ - public Object getElement(IDocument document) { - Iterator e= fElementInfoMap.keySet().iterator(); - while (e.hasNext()) { - Object key= e.next(); - ElementInfo info= (ElementInfo) fElementInfoMap.get(key); - if (info != null && document == info.fDocument) - return info.fElement; - } - return null; - } - - /* - * @see IDocumentProvider#mustSaveDocument(Object) - */ - public boolean mustSaveDocument(Object element) { - - if (element == null) - return false; - - ElementInfo info= (ElementInfo) fElementInfoMap.get(element); - return (info != null ? info.fReferenceCount == 1 && info.fCanBeSaved : false); - } - - /* - * @see IDocumentProvider#canSaveDocument(Object) - */ - public boolean canSaveDocument(Object element) { - - if (element == null) - return false; - - ElementInfo info= (ElementInfo) fElementInfoMap.get(element); - return (info != null ? info.fCanBeSaved : false); - } - - /* - * @see IDocumentProvider#resetDocument(Object) - */ - public void restoreDocument(Object element) throws CoreException { - if (element == null) - return; - - ElementInfo info= (ElementInfo) fElementInfoMap.get(element); - if (info != null) { - - IDocument original= null; - IStatus status= null; - - try { - original= createDocument(element); - } catch (CoreException x) { - status= x.getStatus(); - } - - info.fStatus= status; - - if (original != null) { - - String originalContents= original.get(); - boolean replaceContents= !originalContents.equals(info.fDocument.get()); - - if (replaceContents) { - fireElementContentAboutToBeReplaced(element); - info.fDocument.set(original.get()); - } - - if (info.fCanBeSaved) { - info.fCanBeSaved= false; - addUnchangedElementListeners(element, info); - } - - if (replaceContents) - fireElementContentReplaced(element); - - fireElementDirtyStateChanged(element, false); - } - } - } - - /* - * @see IDocumentProvider#saveDocument(Object, boolean) - */ - public void saveDocument(Object element, boolean overwrite) throws CoreException { - - if (element == null) - return; - - ElementInfo info= (ElementInfo) fElementInfoMap.get(element); - if (info != null && info.fCanBeSaved) { - doSaveDocument(element, info.fDocument, overwrite); - info.fCanBeSaved= false; - addUnchangedElementListeners(element, info); - fireElementDirtyStateChanged(element, false); - } - } - - /* - * @see IDocumentProvider#addElementStateListener(IElementStateListener) - */ - public void addElementStateListener(IElementStateListener2 listener) { - Assert.isNotNull(listener); - if (!fElementStateListeners.contains(listener)) - fElementStateListeners.add(listener); - } - - /* - * @see IDocumentProvider#removeElementStateListener(IElementStateListener) - */ - public void removeElementStateListener(IElementStateListener2 listener) { - Assert.isNotNull(listener); - fElementStateListeners.remove(listener); - } - - /** - * Informs all registered element state listeners about a change in the - * dirty state of the given element. - * - * @param element the element - * @param isDirty the new dirty state - * @see IElementStateListener#elementDirtyStateChanged(Object, boolean) - */ - protected void fireElementDirtyStateChanged(Object element, boolean isDirty) { - Iterator e= new ArrayList(fElementStateListeners).iterator(); - while (e.hasNext()) { - IElementStateListener2 l= (IElementStateListener2) e.next(); - l.elementDirtyStateChanged(element, isDirty); - } - } - - /** - * Informs all registered element state listeners about an impending - * replace of the given element's content. - * - * @param element the element - * @see IElementStateListener#elementContentAboutToBeReplaced(Object) - */ - protected void fireElementContentAboutToBeReplaced(Object element) { - Iterator e= new ArrayList(fElementStateListeners).iterator(); - while (e.hasNext()) { - IElementStateListener2 l= (IElementStateListener2) e.next(); - l.documentContentAboutToBeReplaced(element); - } - } - - /** - * Informs all registered element state listeners about the just-completed - * replace of the given element's content. - * - * @param element the element - * @see IElementStateListener#elementContentReplaced(Object) - */ - protected void fireElementContentReplaced(Object element) { - Iterator e= new ArrayList(fElementStateListeners).iterator(); - while (e.hasNext()) { - IElementStateListener2 l= (IElementStateListener2) e.next(); - l.documentContentReplaced(element); - } - } - - /** - * Informs all registered element state listeners about a move. - * - * @param originalElement the element before the move - * @param movedElement the element after the move - * @see IElementStateListener#elementMoved(Object, Object) - */ - protected void fireElementMoved(Object originalElement, Object movedElement) { - Iterator e= new ArrayList(fElementStateListeners).iterator(); - while (e.hasNext()) { - IElementStateListener2 l= (IElementStateListener2) e.next(); - l.elementMoved(originalElement, movedElement); - } - } - - /** - * Informs all registered element state listeners about the deletion - * of the given element. - * - * @param element the element - * @see IElementStateListener#elementDeleted(Object) - */ - protected void fireElementDeleted(Object element) { - Iterator e= new ArrayList(fElementStateListeners).iterator(); - while (e.hasNext()) { - IElementStateListener2 l= (IElementStateListener2) e.next(); - l.elementDeleted(element); - } - } - - /* - * @see org.eclipse.core.buffer.text.IDocumentProvider#isStateValidated(java.lang.Object) - */ - public boolean isStateValidated(Object element) { - ElementInfo info= (ElementInfo) fElementInfoMap.get(element); - if (info != null) - return info.fIsStateValidated; - return false; - } - - /** - * Hook method for validating the state of the given element. Must not take care of cache updating etc. - * Default implementation is empty. - * - * @param element the element - * @param computationContext the context in which validation happens - * @exception CoreException in case validation fails - */ - protected void doValidateState(Object element, Object computationContext) throws CoreException { - } - - /* - * @see org.eclipse.core.buffer.text.IDocumentProvider#validateState(java.lang.Object, java.lang.Object) - */ - public void validateState(Object element, Object computationContext) throws CoreException { - ElementInfo info= (ElementInfo) fElementInfoMap.get(element); - if (info != null && !info.fIsStateValidated) { - - doValidateState(element, computationContext); - - doUpdateStateCache(element); - info.fIsStateValidated= true; - fireElementStateValidationChanged(element, true); - } - } - - /** - * Hook method for updating the state of the given element. - * Default implementation is empty. - * - * @param element the element - * @exception CoreException in case state cache updating fails - */ - protected void doUpdateStateCache(Object element) throws CoreException { - } - -// /** -// * Returns whether the state of the element must be invalidated given its -// * previous read-only state. -// * -// * @param element the element -// * @param wasReadOnly the previous read-only state -// * @return <code>true</code> if the state of the given element must be invalidated -// * @since 2.0 -// */ -// protected boolean invalidatesState(Object element, boolean wasReadOnly) { -// boolean readOnlyChanged= (isReadOnly(element) != wasReadOnly); -// return readOnlyChanged && !canSaveDocument(element); -// } - -// final public void updateStateCache(Object element) throws CoreException { -// ElementInfo info= (ElementInfo) fElementInfoMap.get(element); -// if (info != null) { -// boolean wasReadOnly= isReadOnly(element); -// doUpdateStateCache(element); -// if (invalidatesState(element, wasReadOnly)) { -// info.fIsStateValidated= false; -// fireElementStateValidationChanged(element, false); -// } -// } -// } - - -// public void setCanSaveDocument(Object element) { -// if (element != null) { -// ElementInfo info= (ElementInfo) fElementInfoMap.get(element); -// if (info != null) { -// info.fCanBeSaved= true; -// removeUnchangedElementListeners(element, info); -// fireElementDirtyStateChanged(element, info.fCanBeSaved); -// } -// } -// } - - /** - * Informs all registered element state listeners about a change in the - * state validation of the given element. - * - * @param element the element - * @param isStateValidated - */ - protected void fireElementStateValidationChanged(Object element, boolean isStateValidated) { - Iterator e= new ArrayList(fElementStateListeners).iterator(); - while (e.hasNext()) { - IElementStateListener2 l= (IElementStateListener2) e.next(); - l.elementStateValidationChanged(element, isStateValidated); - } - } - - /** - * Informs all registered element state listeners about the current state - * change of the element - * - * @param element the element - */ - protected void fireElementStateChanging(Object element) { - Iterator e= new ArrayList(fElementStateListeners).iterator(); - while (e.hasNext()) { - IElementStateListener2 l= (IElementStateListener2) e.next(); - l.elementStateChanging(element); - } - } - - /** - * Informs all registered element state listeners about the failed - * state change of the element - * - * @param element the element - */ - protected void fireElementStateChangeFailed(Object element) { - Iterator e= new ArrayList(fElementStateListeners).iterator(); - while (e.hasNext()) { - IElementStateListener2 l= (IElementStateListener2) e.next(); - l.elementStateChangeFailed(element); - } - } - - /* - * @see org.eclipse.core.buffer.text.IDocumentProvider#getStatus(java.lang.Object) - */ - public IStatus getStatus(Object element) { - ElementInfo info= (ElementInfo) fElementInfoMap.get(element); - if (info != null) { - if (info.fStatus != null) - return info.fStatus; - return (info.fDocument == null ? STATUS_ERROR : STATUS_OK); - } - - return STATUS_ERROR; - } - - /* - * @see org.eclipse.core.buffer.text.IDocumentProvider#getProgressMonitor() - */ - public IProgressMonitor getProgressMonitor() { - return fProgressMonitor == null ? new NullProgressMonitor() : fProgressMonitor; - } - - /* - * @see org.eclipse.core.buffer.text.IDocumentProvider#setProgressMonitor(org.eclipse.core.runtime.IProgressMonitor) - */ - public void setProgressMonitor(IProgressMonitor progressMonitor) { - fProgressMonitor= progressMonitor; - } -} diff --git a/org.eclipse.core.filebuffers/src/org/eclipse/core/internal/filebuffers/ElementStateListener.java b/org.eclipse.core.filebuffers/src/org/eclipse/core/internal/filebuffers/ElementStateListener.java deleted file mode 100644 index 71ee41afc..000000000 --- a/org.eclipse.core.filebuffers/src/org/eclipse/core/internal/filebuffers/ElementStateListener.java +++ /dev/null @@ -1,102 +0,0 @@ -/********************************************************************** -Copyright (c) 2000, 2003 IBM Corp. and others. -All rights reserved. This program and the accompanying materials -are made available under the terms of the Common Public License v1.0 -which accompanies this distribution, and is available at -http://www.eclipse.org/legal/cpl-v10.html - -Contributors: - IBM Corporation - Initial implementation -**********************************************************************/ -package org.eclipse.core.internal.filebuffers; - -import org.eclipse.core.filebuffers.IFileBuffer; -import org.eclipse.core.filebuffers.IFileBufferListener; -import org.eclipse.core.resources.IFile; - -/** - * - */ -public class ElementStateListener implements IElementStateListener2 { - - private IFileBufferListener fListener; - private IFileBuffer fFile; - - public ElementStateListener(IFileBufferListener bufferedFileListener, IFileBuffer file) { - fListener= bufferedFileListener; - fFile= file; - } - - private boolean isAffected(Object element) { - return element == fFile.getUnderlyingFile(); - } - - /* - * @see org.eclipse.core.buffer.internal.text.IElementStateListener2#elementDirtyStateChanged(java.lang.Object, boolean) - */ - public void elementDirtyStateChanged(Object element, boolean isDirty) { - if (isAffected(element)) - fListener.dirtyStateChanged(fFile, isDirty); - } - - - /* - * @see org.eclipse.core.buffer.internal.text.IElementStateListener2#documentContentAboutToBeReplaced(java.lang.Object) - */ - public void documentContentAboutToBeReplaced(Object element) { - if (isAffected(element)) - fListener.bufferContentAboutToBeReplaced(fFile); - } - - /* - * @see org.eclipse.core.buffer.internal.text.IElementStateListener2#documentContentReplaced(java.lang.Object) - */ - public void documentContentReplaced(Object element) { - if (isAffected(element)) - fListener.bufferContentReplaced(fFile); - } - - /* - * @see org.eclipse.core.buffer.internal.text.IElementStateListener2#elementStateValidationChanged(java.lang.Object, boolean) - */ - public void elementStateValidationChanged(Object element, boolean isStateValidated) { - if (isAffected(element)) - fListener.stateValidationChanged(fFile, isStateValidated); - } - - /* - * @see org.eclipse.core.buffer.internal.text.IElementStateListener2#elementStateChanging(java.lang.Object) - */ - public void elementStateChanging(Object element) { - if (isAffected(element)) - fListener.stateChanging(fFile); - } - - /* - * @see org.eclipse.core.buffer.internal.text.IElementStateListener2#elementStateChangeFailed(java.lang.Object) - */ - public void elementStateChangeFailed(Object element) { - if (isAffected(element)) - fListener.stateChangeFailed(fFile); - } - - public IFileBufferListener getBufferedListener() { - return fListener; - } - - /* - * @see org.eclipse.core.buffer.internal.text.IElementStateListener2#elementMoved(java.lang.Object, java.lang.Object) - */ - public void elementMoved(Object originalElement, Object movedElement) { - if (isAffected(originalElement)) - fListener.underlyingFileMoved(fFile, (IFile) movedElement); - } - - /* - * @see org.eclipse.core.buffer.internal.text.IElementStateListener2#elementDeleted(java.lang.Object) - */ - public void elementDeleted(Object element) { - if (isAffected(element)) - fListener.underlyingFileDeleted(fFile); - } -} diff --git a/org.eclipse.core.filebuffers/src/org/eclipse/core/internal/filebuffers/FileBuffer.java b/org.eclipse.core.filebuffers/src/org/eclipse/core/internal/filebuffers/FileBuffer.java index baef6f00f..eb9d77773 100644 --- a/org.eclipse.core.filebuffers/src/org/eclipse/core/internal/filebuffers/FileBuffer.java +++ b/org.eclipse.core.filebuffers/src/org/eclipse/core/internal/filebuffers/FileBuffer.java @@ -10,131 +10,330 @@ Contributors: **********************************************************************/ package org.eclipse.core.internal.filebuffers; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - import org.eclipse.core.filebuffers.IFileBuffer; -import org.eclipse.core.filebuffers.IFileBufferListener; import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResourceChangeEvent; +import org.eclipse.core.resources.IResourceChangeListener; +import org.eclipse.core.resources.IResourceDelta; +import org.eclipse.core.resources.IResourceDeltaVisitor; +import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.ILog; +import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.core.runtime.Platform; -import org.eclipse.jface.text.Assert; -/** - * - */ -public class FileBuffer implements IFileBuffer { +public abstract class FileBuffer implements IFileBuffer { - private IFile fFile; - private FileDocumentProvider2 fDocumentProvider; - private List fElementStateListeners= new ArrayList(); + /** + * Runnable encapsulating an element state change. This runnable ensures + * that a element change failed message is sent out to the element state + * listeners in case an exception occurred. + */ + private class SafeFileChange implements Runnable { + + /** + * Creates a new safe runnable for the given file. + */ + public SafeFileChange() { + } + + /** + * Execute the change. + * Subclass responsibility. + * + * @exception an exception in case of error + */ + protected void execute() throws Exception { + } + + /* + * @see java.lang.Runnable#run() + */ + public void run() { + + if (isDisposed()) { + fManager.fireStateChangeFailed(FileBuffer.this); + return; + } + + try { + execute(); + } catch (Exception x) { + fManager.fireStateChangeFailed(FileBuffer.this); + } + } + } + + /** + * Synchronizes the document with external resource changes. + */ + private class FileSynchronizer implements IResourceChangeListener, IResourceDeltaVisitor { + + /** A flag indicating whether this synchronizer is installed or not. */ + private boolean fIsInstalled= false; + + /** + * Creates a new file synchronizer. Is not yet installed on a file. + */ + public FileSynchronizer() { + } + + /** + * Installs the synchronizer on the file. + */ + public void install() { + fFile.getWorkspace().addResourceChangeListener(this); + fIsInstalled= true; + } + + /** + * Uninstalls the synchronizer from the file. + */ + public void uninstall() { + fFile.getWorkspace().removeResourceChangeListener(this); + fIsInstalled= false; + } + + /* + * @see IResourceChangeListener#resourceChanged(IResourceChangeEvent) + */ + public void resourceChanged(IResourceChangeEvent e) { + IResourceDelta delta= e.getDelta(); + try { + if (delta != null && fIsInstalled) + delta.accept(this); + } catch (CoreException x) { + handleCoreException(x); + } + } + + /* + * @see IResourceDeltaVisitor#visit(org.eclipse.core.resources.IResourceDelta) + */ + public boolean visit(IResourceDelta delta) throws CoreException { + + if (delta != null && fFile.equals(delta.getResource())) { + + Runnable runnable= null; + + switch (delta.getKind()) { + case IResourceDelta.CHANGED: + if ((IResourceDelta.CONTENT & delta.getFlags()) != 0) { + if (!isDisposed() && !fCanBeSaved && fFile.isSynchronized(IFile.DEPTH_ZERO)) { + runnable= new SafeFileChange() { + protected void execute() throws Exception { + if (fModificationStamp != fFile.getModificationStamp()) + handleFileContentChanged(); + } + }; + } + } + break; + case IResourceDelta.REMOVED: + if ((IResourceDelta.MOVED_TO & delta.getFlags()) != 0) { + final IPath path= delta.getMovedToPath(); + runnable= new SafeFileChange() { + protected void execute() throws Exception { + handleFileMoved(path); + } + }; + } else { + if (!isDisposed() && !fCanBeSaved) { + runnable= new SafeFileChange() { + protected void execute() throws Exception { + handleFileDeleted(); + } + }; + } + } + break; + } + + if (runnable != null) + update(runnable); + } + + return true; // because we are sitting on files anyway + } + + /** + * Posts the update code "behind" the running operation. + * + * @param runnable the update code + */ + protected void update(Runnable runnable) { + if (runnable instanceof SafeFileChange) + fManager.fireStateChanging(FileBuffer.this); + // TODO post behind operation; check necessity + runnable.run(); + } + } + + + + /** The element for which the info is stored */ + protected IFile fFile; + /** How often the element has been connected */ + protected int fReferenceCount; + /** Can the element be saved */ + protected boolean fCanBeSaved= false; + /** Has element state been validated */ + protected boolean fIsStateValidated= false; + /** The status of this element */ + protected IStatus fStatus; + /** The file synchronizer. */ + protected FileSynchronizer fFileSynchronizer; + /** The time stamp at which this provider changed the file. */ + protected long fModificationStamp= IFile.NULL_STAMP; + + /** The text file buffer manager */ + protected TextFileBufferManager fManager; - /** - * - */ - public FileBuffer(IFile file, FileDocumentProvider2 documentProvider) { + + + + public FileBuffer(TextFileBufferManager manager) { super(); - fFile= file; - fDocumentProvider= documentProvider; + fManager= manager; } - protected FileDocumentProvider2 getDocumentProvider() { - return fDocumentProvider; + abstract protected void handleFileContentChanged(); + + abstract protected void addFileBufferContentListeners(); + + abstract protected void removeFileBufferContentListeners(); + + abstract protected void initializeFileBufferContent(IProgressMonitor monitor) throws CoreException; + + abstract protected void commitFileBufferContent(IProgressMonitor monitor, boolean overwrite) throws CoreException; + + + public void create(IFile file, IProgressMonitor monitor) throws CoreException { + fFile= file; + fFileSynchronizer= new FileSynchronizer(); + refreshFile(monitor); + + initializeFileBufferContent(monitor); + addFileBufferContentListeners(); + } + + public void connect() { + ++ fReferenceCount; + if (fReferenceCount == 1) + fFileSynchronizer.install(); + } + + public void disconnect() throws CoreException { + -- fReferenceCount; + if (fReferenceCount == 0) { + if (fFileSynchronizer != null) + fFileSynchronizer.uninstall(); + fFileSynchronizer= null; + } + } + + protected boolean isDisposed() { + return fFileSynchronizer == null; } /* - * @see org.eclipse.core.buffer.text.IBufferedFile#getUnderlyingFile() + * @see org.eclipse.core.filebuffers.IFileBuffer#getUnderlyingFile() */ public IFile getUnderlyingFile() { return fFile; } - private ElementStateListener getStateListener(IFileBufferListener listener) { - Iterator e= fElementStateListeners.iterator(); - while (e.hasNext()) { - ElementStateListener s= (ElementStateListener) e.next(); - if (s.getBufferedListener() == listener) - return s; + /* + * @see org.eclipse.core.filebuffers.IFileBuffer#commit(org.eclipse.core.runtime.IProgressMonitor, boolean) + */ + public void commit(IProgressMonitor monitor, boolean overwrite) throws CoreException { + if (!isDisposed() && fCanBeSaved) { + commitFileBufferContent(monitor, overwrite); + fCanBeSaved= false; + addFileBufferContentListeners(); + fManager.fireDirtyStateChanged(this, fCanBeSaved); } - return null; } /* - * @see org.eclipse.core.buffer.text.IBufferedFile#addBufferedFileListener(org.eclipse.core.buffer.text.IBufferedFileListener) + * @see org.eclipse.core.filebuffers.IFileBuffer#isDirty() */ - public void addFileBufferListener(IFileBufferListener listener) { - Assert.isNotNull(listener); - ElementStateListener stateListener= getStateListener(listener); - if (stateListener == null) { - stateListener= new ElementStateListener(listener, this); - fElementStateListeners.add(stateListener); - } - fDocumentProvider.addElementStateListener(stateListener); + public boolean isDirty() { + return fCanBeSaved; } /* - * @see org.eclipse.core.buffer.text.IBufferedFile#removeBufferedFileListener(org.eclipse.core.buffer.text.IBufferedFileListener) + * @see org.eclipse.core.filebuffers.IFileBuffer#isShared() */ - public void removeFileBufferListener(IFileBufferListener listener) { - Assert.isNotNull(listener); - ElementStateListener stateListener= getStateListener(listener); - if (stateListener != null) { - fDocumentProvider.removeElementStateListener(stateListener); - fElementStateListeners.remove(stateListener); - } + public boolean isShared() { + return fReferenceCount > 1; } /* - * @see org.eclipse.core.buffer.text.IBufferedFile#revert(org.eclipse.core.runtime.IProgressMonitor) + * @see org.eclipse.core.filebuffers.IFileBuffer#validateState(org.eclipse.core.runtime.IProgressMonitor, java.lang.Object) */ - public void revert(IProgressMonitor monitor) throws CoreException { - IProgressMonitor previous= fDocumentProvider.getProgressMonitor(); - fDocumentProvider.setProgressMonitor(monitor); - fDocumentProvider.restoreDocument(fFile); - fDocumentProvider.setProgressMonitor(previous); + public void validateState(IProgressMonitor monitor, Object computationContext) throws CoreException { + if (!isDisposed() && !fIsStateValidated) { + + if (fFile.isReadOnly()) { + IWorkspace workspace= fFile.getWorkspace(); + fStatus= workspace.validateEdit(new IFile[] { fFile }, computationContext); + } + fIsStateValidated= true; + fManager.fireStateValidationChanged(this, fIsStateValidated); + } } /* - * @see org.eclipse.core.buffer.text.IBufferedFile#commit(org.eclipse.core.runtime.IProgressMonitor, boolean) + * @see org.eclipse.core.filebuffers.IFileBuffer#isStateValidated() */ - public void commit(IProgressMonitor monitor, boolean overwrite) throws CoreException { - IProgressMonitor previous= fDocumentProvider.getProgressMonitor(); - fDocumentProvider.setProgressMonitor(monitor); - fDocumentProvider.saveDocument(fFile, overwrite); - fDocumentProvider.setProgressMonitor(previous); + public boolean isStateValidated() { + return fIsStateValidated; } - /* - * @see org.eclipse.core.buffer.text.IBufferedFile#isDirty() + /** + * Sends out the notification that the file serving as document input has been moved. + * + * @param newLocation the path of the new location of the file */ - public boolean isDirty() { - return fDocumentProvider.canSaveDocument(fFile); + protected void handleFileMoved(IPath newLocation) { + IWorkspace workspace=fFile.getWorkspace(); + IFile newFile= workspace.getRoot().getFile(newLocation); + fManager.fireUnderlyingFileMoved(this, newFile); } - - /* - * @see org.eclipse.core.buffer.text.IBufferedFile#validateState(org.eclipse.core.runtime.IProgressMonitor, java.lang.Object) + + /** + * Sends out the notification that the file serving as document input has been deleted. */ - public void validateState(IProgressMonitor monitor, Object computationContext) throws CoreException { - IProgressMonitor previous= fDocumentProvider.getProgressMonitor(); - fDocumentProvider.setProgressMonitor(monitor); - fDocumentProvider.validateState(fFile, computationContext); - fDocumentProvider.setProgressMonitor(previous); + protected void handleFileDeleted() { + fManager.fireUnderlyingFileDeleted(this); } - - /* - * @see org.eclipse.core.buffer.text.IBufferedFile#isStateValidated() + + /** + * Refreshes the given file. */ - public boolean isStateValidated() { - return fDocumentProvider.isStateValidated(fFile); + protected void refreshFile(IProgressMonitor monitor) { + try { + fFile.refreshLocal(IFile.DEPTH_INFINITE, monitor); + } catch (OperationCanceledException x) { + } catch (CoreException x) { + handleCoreException(x); + } } - /* - * @see org.eclipse.core.buffer.text.IBufferedFile#getStatus() + /** + * Defines the standard procedure to handle <code>CoreExceptions</code>. Exceptions + * are written to the plug-in log. + * + * @param exception the exception to be logged + * @param message the message to be logged */ - public IStatus getStatus() { - return fDocumentProvider.getStatus(fFile); + protected void handleCoreException(CoreException exception) { + ILog log= Platform.getPlugin(FileBuffersPlugin.PLUGIN_ID).getLog(); + log.log(exception.getStatus()); } } diff --git a/org.eclipse.core.filebuffers/src/org/eclipse/core/internal/filebuffers/FileBuffersPlugin.java b/org.eclipse.core.filebuffers/src/org/eclipse/core/internal/filebuffers/FileBuffersPlugin.java index 0a6443549..752cffe28 100644 --- a/org.eclipse.core.filebuffers/src/org/eclipse/core/internal/filebuffers/FileBuffersPlugin.java +++ b/org.eclipse.core.filebuffers/src/org/eclipse/core/internal/filebuffers/FileBuffersPlugin.java @@ -31,7 +31,7 @@ public class FileBuffersPlugin extends Plugin { super(descriptor); fgPlugin = this; try { - fResourceBundle= ResourceBundle.getBundle("org.eclipse.core.buffer.internal,text.TextBufferPluginResources"); //$NON-NLS-1$ + fResourceBundle= ResourceBundle.getBundle("org.eclipse.core.internal.filebuffers.FileBuffersPlugin"); //$NON-NLS-1$ } catch (MissingResourceException x) { fResourceBundle = null; } @@ -76,7 +76,7 @@ public class FileBuffersPlugin extends Plugin { * * @return the text file buffer manager of this plug-in */ - public ITextFileBufferManager getBufferedFileManager() { + public ITextFileBufferManager getFileBufferManager() { if (fTextFileBufferManager == null) fTextFileBufferManager= new TextFileBufferManager(); return fTextFileBufferManager; diff --git a/org.eclipse.core.filebuffers/src/org/eclipse/core/internal/filebuffers/FileDocumentProvider2.java b/org.eclipse.core.filebuffers/src/org/eclipse/core/internal/filebuffers/FileDocumentProvider2.java deleted file mode 100644 index 796c4e052..000000000 --- a/org.eclipse.core.filebuffers/src/org/eclipse/core/internal/filebuffers/FileDocumentProvider2.java +++ /dev/null @@ -1,588 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ - -package org.eclipse.core.internal.filebuffers; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; - -import org.eclipse.core.filebuffers.IDocumentFactory; -import org.eclipse.core.filebuffers.IDocumentSetupParticipant; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IResourceChangeEvent; -import org.eclipse.core.resources.IResourceChangeListener; -import org.eclipse.core.resources.IResourceDelta; -import org.eclipse.core.resources.IResourceDeltaVisitor; -import org.eclipse.core.resources.IResourceStatus; -import org.eclipse.core.resources.IWorkspace; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.OperationCanceledException; -import org.eclipse.core.runtime.QualifiedName; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.SubProgressMonitor; - -import org.eclipse.jface.text.IDocument; - - -/** - * Shareable document provider specialized for file resources (<code>IFile</code>). - * <p> - * This class may be instantiated or be subclassed.</p> - */ -public class FileDocumentProvider2 extends StorageDocumentProvider2 { - - /** - * Qualified name for the encoding key. - */ - private static final QualifiedName ENCODING_KEY = new QualifiedName(FileBuffersPlugin.PLUGIN_ID, "encoding"); //$NON-NLS-1$ //$NON-NLS-2$ - - - /** - * Runnable encapsulating an element state change. This runnable ensures - * that a element change failed message is sent out to the element state - * listeners in case an exception occurred. - */ - protected class SafeResourceChange implements Runnable { - - /** The resource that changes. */ - private IResource fChangedResource; - - /** - * Creates a new safe runnable for the given resource. - * - * @param resource the resource that changes - */ - public SafeResourceChange(IResource resource) { - fChangedResource= resource; - } - - /** - * @return the resource - */ - public IResource getChangedResource() { - return fChangedResource; - } - - /** - * Execute the change. - * Subclass responsibility. - * - * @exception an exception in case of error - */ - protected void execute() throws Exception { - } - - /* - * @see java.lang.Runnable#run() - */ - public void run() { - - if (getElementInfo(fChangedResource) == null) { - fireElementStateChangeFailed(fChangedResource); - return; - } - - try { - execute(); - } catch (Exception x) { - fireElementStateChangeFailed(fChangedResource); - } - } - }; - - - /** - * Synchronizes the document with external resource changes. - */ - protected class ResourceSynchronizer implements IResourceChangeListener, IResourceDeltaVisitor { - - /** The resource. */ - protected IResource fSynchronizedResource; - /** A flag indicating whether this synchronizer is installed or not. */ - protected boolean fIsInstalled= false; - - /** - * Creates a new resource synchronizer. Is not yet installed on a resource. - * - * @param resource the resource with which the document is to be synchronized - */ - public ResourceSynchronizer(IResource resource) { - fSynchronizedResource= resource; - }; - - /** - * Returns the resource associated with this synchronizer. - * - * @return the resource associated with this synchronizer - */ - protected IResource getSynchronizedResource() { - return fSynchronizedResource; - } - - /** - * Installs the synchronizer on the resource. - */ - public void install() { - getSynchronizedResource().getWorkspace().addResourceChangeListener(this); - fIsInstalled= true; - } - - /** - * Uninstalls the synchronizer from the resource. - */ - public void uninstall() { - getSynchronizedResource().getWorkspace().removeResourceChangeListener(this); - fIsInstalled= false; - } - - /* - * @see IResourceChangeListener#resourceChanged(IResourceChangeEvent) - */ - public void resourceChanged(IResourceChangeEvent e) { - IResourceDelta delta= e.getDelta(); - try { - if (delta != null && fIsInstalled) - delta.accept(this); - } catch (CoreException x) { - handleCoreException(x, "FileDocumentProvider.resourceChanged"); - } - } - - /* - * @see IResourceDeltaVisitor#visit(org.eclipse.core.resources.IResourceDelta) - */ - public boolean visit(IResourceDelta delta) throws CoreException { - - if (delta != null && getSynchronizedResource().equals(delta.getResource())) { - - Runnable runnable= null; - - switch (delta.getKind()) { - case IResourceDelta.CHANGED: - if ((IResourceDelta.CONTENT & delta.getFlags()) != 0) { - ResourceInfo info= (ResourceInfo) getElementInfo(fSynchronizedResource); - if (info != null && !info.fCanBeSaved && fSynchronizedResource.isSynchronized(IResource.DEPTH_ZERO)) { - runnable= new SafeResourceChange(fSynchronizedResource) { - protected void execute() throws Exception { - IResource r= getChangedResource(); - ResourceInfo i= (ResourceInfo) getElementInfo(r); - if (i.fModificationStamp != r.getModificationStamp()) - handleElementContentChanged(getChangedResource()); - } - }; - } - } - break; - case IResourceDelta.REMOVED: - if ((IResourceDelta.MOVED_TO & delta.getFlags()) != 0) { - final IPath path= delta.getMovedToPath(); - runnable= new SafeResourceChange(fSynchronizedResource) { - protected void execute() throws Exception { - handleElementMoved(getChangedResource(), path); - } - }; - } else { - ResourceInfo info= (ResourceInfo) getElementInfo(fSynchronizedResource); - if (info != null && !info.fCanBeSaved) { - runnable= new SafeResourceChange(fSynchronizedResource) { - protected void execute() throws Exception { - handleElementDeleted(getChangedResource()); - } - }; - } - } - break; - } - - if (runnable != null) - update(runnable); - } - - return true; // because we are sitting on files anyway - } - - /** - * Posts the update code "behind" the running operation. - * - * @param runnable the update code - */ - protected void update(Runnable runnable) { - if (runnable instanceof SafeResourceChange) - fireElementStateChanging(fSynchronizedResource); - // TODO post behind operation - runnable.run(); - } - }; - - - - /** - * Bundle of all required information to allow resources as underlying document content providers. - */ - protected class ResourceInfo extends StorageInfo { - - /** The resource synchronizer. */ - public ResourceSynchronizer fResourceSynchronizer; - /** The time stamp at which this provider changed the file. */ - public long fModificationStamp= IResource.NULL_STAMP; - - /** - * Creates and returns a new resource info. - * - * @param document the document - * @param resourceSynchronizer the file synchronizer - */ - public ResourceInfo(IDocument document, ResourceSynchronizer resourceSynchronizer) { - super(document); - fResourceSynchronizer= resourceSynchronizer; - } - }; - - - /** The document factory registry for this document provider */ - private ExtensionsRegistry fRegistry; - - - /** - * Creates and returns a new document provider. - */ - public FileDocumentProvider2(ExtensionsRegistry registry) { - super(); - fRegistry= registry; - } - - /** - * Checks whether the given resource is synchronized with the the local file system. - * If the resource has been changed, a <code>CoreException</code> is thrown. - * - * @param resource the resource to check - * @exception CoreException if resource has been changed on the file system - */ - protected void checkSynchronizationState(IResource resource) throws CoreException { - if (!resource.isSynchronized(IResource.DEPTH_ZERO)) { - Status status= new Status(IStatus.ERROR, FileBuffersPlugin.PLUGIN_ID, IResourceStatus.OUT_OF_SYNC_LOCAL, "FileDocumentProvider.error.out_of_sync", null); - throw new CoreException(status); - } - } - - /* - * @see AbstractDocumentProvider#doSaveDocument(IProgressMonitor, Object, IDocument, boolean) - */ - protected void doSaveDocument(Object element, IDocument document, boolean overwrite) throws CoreException { - if (element instanceof IResource) { - - try { - - String encoding= getEncoding(element); - if (encoding == null) - encoding= getDefaultEncoding(); - InputStream stream= new ByteArrayInputStream(document.get().getBytes(encoding)); - IFile file= (IFile) element; - - if (file.exists()) { - - ResourceInfo info= (ResourceInfo) getElementInfo(element); - - if (info != null && !overwrite) - checkSynchronizationState(file); - - // inform about the upcoming content change - fireElementStateChanging(element); - try { - - // here the resource synchronizer should actually be removed and afterwards added again. However, - // we are already inside an operation, so the delta is sent AFTER we have added the listener - file.setContents(stream, overwrite, true, getProgressMonitor()); - // set modification stamp to know whether the resource synchronizer must become active - info.fModificationStamp= file.getModificationStamp(); - - } catch (CoreException x) { - // inform about failure - fireElementStateChangeFailed(element); - throw x; - } catch (RuntimeException x) { - // inform about failure - fireElementStateChangeFailed(element); - throw x; - } - - // If here, the editor state will be flipped to "not dirty". - // Thus, the state changing flag will be reset and we don't have to do - // it manually - - // if there is an annotation model update it here - - } else { - IProgressMonitor monitor= getProgressMonitor(); - try { - monitor.beginTask("FileDocumentProvider.task.saving", 2000); //$NON-NLS-1$ - ContainerGenerator generator = new ContainerGenerator(file.getWorkspace(), file.getParent().getFullPath()); - generator.generateContainer(new SubProgressMonitor(monitor, 1000)); - file.create(stream, false, new SubProgressMonitor(monitor, 1000)); - } - finally { - monitor.done(); - } - } - - } catch (IOException x) { - IStatus s= new Status(IStatus.ERROR, FileBuffersPlugin.PLUGIN_ID, IStatus.OK, x.getMessage(), x); - throw new CoreException(s); - } - - } else { - super.doSaveDocument(element, document, overwrite); - } - } - - /* - * @see org.eclipse.core.internal.filebuffers.StorageDocumentProvider2#createEmptyDocument(java.lang.Object) - */ - public IDocument createEmptyDocument(Object element) { - if (element instanceof IFile) { - IDocumentFactory factory= fRegistry.getDocumentFactory((IFile) element); - - IDocument document= null; - if (factory != null) - document= factory.createDocument(); - else - document= super.createEmptyDocument(element); - - IDocumentSetupParticipant[] participants= fRegistry.getDocumentSetupParticipants((IFile) element); - if (participants != null) { - for (int i= 0; i < participants.length; i++) - participants[i].setup(document); - } - - return document; - } - return super.createEmptyDocument(element); - } - - /* - * @see AbstractDocumentProvider#createElementInfo(Object) - */ - protected ElementInfo createElementInfo(Object element) throws CoreException { - if (element instanceof IResource) { - - try { - refreshResource((IResource) element); - } catch (CoreException x) { - handleCoreException(x, "FileDocumentProvider.createElementInfo"); - } - - IDocument d= null; - IStatus s= null; - - try { - d= createDocument(element); - } catch (CoreException x) { - s= x.getStatus(); - d= createEmptyDocument(element); - } - - ResourceSynchronizer f= new ResourceSynchronizer((IResource) element); - f.install(); - - ResourceInfo info= new ResourceInfo(d, f); - info.fStatus= s; - info.fEncoding= getPersistedEncoding(element); - - return info; - } - - return super.createElementInfo(element); - } - - /* - * @see AbstractDocumentProvider#disposeElementInfo(ElementInfo) - */ - protected void disposeElementInfo(ElementInfo info) { - if (info instanceof ResourceInfo) { - ResourceInfo resourceInfo= (ResourceInfo) info; - if (resourceInfo.fResourceSynchronizer != null) - resourceInfo.fResourceSynchronizer.uninstall(); - } - - super.disposeElementInfo(info); - } - - /** - * Updates the element info to a change of the file content and sends out appropriate notifications. - * - * @param object the changed object - */ - protected void handleElementContentChanged(IResource resource) { - ResourceInfo info= (ResourceInfo) getElementInfo(resource); - if (info == null) - return; - - IDocument document= createEmptyDocument(resource); - IStatus status= null; - - try { - -// Should not be neccessary. -// -// try { -// refreshResource(resource); -// } catch (CoreException x) { -// handleCoreException(x, "FileDocumentProvider.handleElementContentChanged"); //$NON-NLS-1$ -// } - - if (resource instanceof IFile) { - IFile file= (IFile) resource; - setDocumentContent(document, file.getContents(false), info.fEncoding); - } - - } catch (CoreException x) { - status= x.getStatus(); - } - - String newContent= document.get(); - - if ( !newContent.equals(info.fDocument.get())) { - - // set the new content and fire content related events - fireElementContentAboutToBeReplaced(resource); - - removeUnchangedElementListeners(resource, info); - - info.fDocument.removeDocumentListener(info); - info.fDocument.set(newContent); - info.fCanBeSaved= false; - info.fStatus= status; - - addUnchangedElementListeners(resource, info); - - fireElementContentReplaced(resource); - - } else { - - removeUnchangedElementListeners(resource, info); - - // fires only the dirty state related event - info.fCanBeSaved= false; - info.fStatus= status; - - addUnchangedElementListeners(resource, info); - - fireElementDirtyStateChanged(resource, false); - } - } - - /** - * Sends out the notification that the file serving as document input has been moved. - * - * @param resource the changed resource - * @param path the path of the new location of the file - */ - protected void handleElementMoved(IResource resource, IPath path) { - IWorkspace workspace= ResourcesPlugin.getWorkspace(); - IFile newFile= workspace.getRoot().getFile(path); - fireElementMoved(resource, newFile); - } - - /** - * Sends out the notification that the file serving as document input has been deleted. - * - * @param resource the deleted resource - */ - protected void handleElementDeleted(IResource resource) { - fireElementDeleted(resource); - } - - /* - * @see AbstractDocumentProvider#doValidateState(Object, Object) - */ - protected void doValidateState(Object element, Object computationContext) throws CoreException { - - if (element instanceof IResource) { - ResourceInfo info= (ResourceInfo) getElementInfo(element); - if (info != null) { - IResource resource= (IResource) element; - if (resource.isReadOnly() && resource instanceof IFile) { - IWorkspace workspace= resource.getWorkspace(); - workspace.validateEdit(new IFile[] { (IFile) resource }, computationContext); - } - } - } - - super.doValidateState(element, computationContext); - } - - /* - * @see IDocumentProvider#resetDocument(Object) - */ - public void restoreDocument(Object element) throws CoreException { - if (element instanceof IResource) { - try { - refreshResource((IResource) element); - } catch (CoreException x) { - handleCoreException(x, "FileDocumentProvider.resetDocument"); - } - } - super.restoreDocument(element); - } - - /** - * Refreshes the given resource. - * - * @param resource the resource to be refreshed - * @throws a CoreException if the refresh fails - */ - protected void refreshResource(IResource resource) throws CoreException { - try { - resource.refreshLocal(IResource.DEPTH_INFINITE, getProgressMonitor()); - } catch (OperationCanceledException x) { - } - } - - // --------------- Encoding support --------------- - - /** - * Returns the persited encoding for the given element. - * - * @param element the element for which to get the persisted encoding - */ - protected String getPersistedEncoding(Object element) { - if (element instanceof IResource) { - try { - IResource resource= (IResource) element; - return resource.getPersistentProperty(ENCODING_KEY); - } catch (CoreException ex) { - return null; - } - } - return super.getPersistedEncoding(element); - } - - /** - * Persists the given encoding for the given element. - * - * @param element the element for which to store the persisted encoding - * @param encoding the encoding - */ - protected void persistEncoding(Object element, String encoding) throws CoreException { - if (element instanceof IResource) { - IResource resource= (IResource) element; - resource.setPersistentProperty(ENCODING_KEY, encoding); - } else { - super.persistEncoding(element, encoding); - } - } -} diff --git a/org.eclipse.core.filebuffers/src/org/eclipse/core/internal/filebuffers/IDocumentProvider2.java b/org.eclipse.core.filebuffers/src/org/eclipse/core/internal/filebuffers/IDocumentProvider2.java deleted file mode 100644 index c43a0f0a4..000000000 --- a/org.eclipse.core.filebuffers/src/org/eclipse/core/internal/filebuffers/IDocumentProvider2.java +++ /dev/null @@ -1,200 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.core.internal.filebuffers; - - - - -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; - -import org.eclipse.jface.text.IDocument; - - - -/** - * A document provider maps between domain elements and documents. - * A document provider has the following responsibilities: - * <ul> - * <li> create an annotation model of a domain model element - * <li> create and manage a textual representation, i.e., a document, of a domain model element - * <li> create and save the content of domain model elements based on given documents - * <li> update the documents this document provider manages for domain model elements - * to changes directly applied to those domain model elements - * <li> notify all element state listeners about changes directly applied to domain model - * elements this document provider manages a document for, i.e. the document - * provider must know which changes of a domain model element are to be interpreted - * as element moves, deletes, etc. - * </ul> - * Text editors use document providers to bridge the gap between their input elements and the - * documents they work on. A single document provider may be shared between multiple editors; - * the methods take the editors' input elements as a parameter. - * <p> - * This interface may be implemented by clients; or subclass the standard - * abstract base class <code>AbstractDocumentProvider</code>.</p> - * - * @see org.eclipse.jface.text.IDocument - * @see org.eclipse.ui.texteditor.AbstractDocumentProvider - */ -public interface IDocumentProvider2 { - - /** - * Adds the given element state listener to this document provider. - * Has no effect if an identical listener is already registered. - * - * @param listener the listener - */ - void addElementStateListener(IElementStateListener2 listener); - - /** - * Removes the given element state listener from this document provider. - * Has no affect if an identical listener is not registered. - * - * @param listener the listener - */ - void removeElementStateListener(IElementStateListener2 listener); - - - /** - * Connects the given element to this document provider. This tells the provider - * that caller of this method is interested to work with the document provided for - * the given domain model element. By counting the invokations of this method and - * <code>disconnect(Object)</code> this provider can assume to know the - * correct number of clients working with the document provided for that - * domain model element. <p> - * The given element must not be <code>null</code>. - * - * @param element the element - * @exception CoreException if the textual representation or the annotation model - * of the element could not be created - */ - void connect(Object element) throws CoreException; - - /** - * Disconnects the given element from this document provider. This tells the provider - * that the caller of this method is no longer interested in working with the document - * provided for the given domain model element. By counting the invokations of - * <code>connect(Object)</code> and of this method this provider can assume to - * know the correct number of clients working with the document provided for that - * domain model element. <p> - * The given element must not be <code>null</code>. - * - * @param element the element - */ - void disconnect(Object element); - - /** - * Returns the document for the given element. Usually the document contains - * a textual presentation of the content of the element, or is the element itself. - * - * @param element the element, or <code>null</code> - * @return the document, or <code>null</code> if none - */ - IDocument getDocument(Object element); - - /** - * Creates a new empty document for the given element. The document is afterwards not - * managed by this provider. - * - * @param element the element - * @return the newly created document, or <code>null</code> if this is not possible - */ - IDocument createEmptyDocument(Object element); - - /** - * Returns the element that is the origin of the given document. - * - * @param document the given document - * @return the element or <code>null</code> if none - */ - Object getElement(IDocument document); - - /** - * Resets the given element's document to its last saved state. - * Element state listeners are notified both before (<code>elementContentAboutToBeReplaced</code>) - * and after (<code>elementContentReplaced</code>) the content is changed. - * - * @param element the element, or <code>null</code> - */ - void restoreDocument(Object element) throws CoreException; - - /** - * Saves the given document provided for the given element. - * - * @param monitor a progress monitor to report progress and request cancelation - * @param element the element, or <code>null</code> - * @param document the document - * @param overwrite indicates whether overwrite should be performed - * while saving the given element if necessary - * @exception CoreException if document could not be stored to the given element - */ - void saveDocument(Object element, boolean overwrite) throws CoreException; - - /** - * Returns whether the document provided for the given element must be saved. - * - * @param element the element, or <code>null</code> - * @return <code>true</code> if the document must be saved, and - * <code>false</code> otherwise (including the element is <code>null</code>) - */ - boolean mustSaveDocument(Object element); - - /** - * Returns whether the document provided for the given element differs from - * its original state which would required that it be saved. - * - * @param element the element, or <code>null</code> - * @return <code>true</code> if the document can be saved, and - * <code>false</code> otherwise (including the element is <code>null</code>) - */ - boolean canSaveDocument(Object element); - - /** - * Validates the state of the given element. This method may change the "real" state of the - * element. If using, it also updates the internal caches, so that this method may also change - * the results returned by <code>isReadOnly</code> and <code>isModifiable</code>. If the - * given element is not connected to this document provider, the effect is undefined. - * - * @param element the element - * @param computationContext the context in which the computation is performed, e.g., a SWT shell - * @exception CoreException if validating fails - */ - void validateState(Object element, Object computationContext) throws CoreException; - - /** - * Returns whether the state of the given element has been validated. - * - * @param element the element - * @return <code>true</code> if the state has been validated - */ - boolean isStateValidated(Object element); - - /** - * Returns the status of the given element. - * - * @param element the element - * @return the status of the given element - */ - IStatus getStatus(Object element); - - /** - * Sets this providers progress monitor. - * @param progressMonitor - */ - void setProgressMonitor(IProgressMonitor progressMonitor); - - /** - * Returns this providers progress monitor. - * @return IProgressMonitor - */ - IProgressMonitor getProgressMonitor(); -} diff --git a/org.eclipse.core.filebuffers/src/org/eclipse/core/internal/filebuffers/IElementStateListener2.java b/org.eclipse.core.filebuffers/src/org/eclipse/core/internal/filebuffers/IElementStateListener2.java deleted file mode 100644 index be7e1e6a3..000000000 --- a/org.eclipse.core.filebuffers/src/org/eclipse/core/internal/filebuffers/IElementStateListener2.java +++ /dev/null @@ -1,89 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.core.internal.filebuffers; - - -/** - * Interface for parties interested in standardized element changes. These - * changes are: - * <ul> - * <li> dirty state changes - * <li> content replacements - * <li> moves - * <li> deletions - * </ul> - * The notifications sent to the element state listeners inform about those standardized, - * abstract changes. The concrete change applied might differ from the one the listeners - * are notified about, but should be interpreted as the one the listeners receive. - */ -public interface IElementStateListener2 { - - /** - * Notifies that the dirty state of the given element has changed. - * - * @param element the element - * @param isDirty the new dirty state - */ - void elementDirtyStateChanged(Object element, boolean isDirty); - - /** - * Notifies that the content of the given element is about to be replaced. - * - * @param element the element - */ - void documentContentAboutToBeReplaced(Object element); - - /** - * Notifies that the content of the given element has been replaced. - * - * @param element the element - */ - void documentContentReplaced(Object element); - - /** - * Notifies that the element has moved. If <code>movedElement</code> - * is <code>null</code> it is similar to <code>elementDeleted(originalElement)</code>. - * - * @param originalElement the element before the move - * @param movedElement the element after the move - */ - void elementMoved(Object originalElement, Object movedElement); - - /** - * Notifies that the given element has been deleted. - * - * @param element the element - */ - void elementDeleted(Object element); - - /** - * Notifies that the state validation of the given element has changed. - * - * @param element the element - * @param isStateValidated the flag indicating whether state validation is done - */ - void elementStateValidationChanged(Object element, boolean isStateValidated); - - /** - * Notifies that the given element is currently being changed. This method may - * be sent from a non-ui thread. - * - * @param element the element - */ - void elementStateChanging(Object element); - - /** - * Notifies that changing the given element has failed. - * - * @param element the element - */ - void elementStateChangeFailed(Object element); -} diff --git a/org.eclipse.core.filebuffers/src/org/eclipse/core/internal/filebuffers/IStorageDocumentProvider2.java b/org.eclipse.core.filebuffers/src/org/eclipse/core/internal/filebuffers/IStorageDocumentProvider2.java deleted file mode 100644 index 721ea5eb3..000000000 --- a/org.eclipse.core.filebuffers/src/org/eclipse/core/internal/filebuffers/IStorageDocumentProvider2.java +++ /dev/null @@ -1,45 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ - -package org.eclipse.core.internal.filebuffers; - - -/** - * Document provider for <code>IStorage</code> based domain elements. - * Basically incorporates the concept of character encoding. - */ -public interface IStorageDocumentProvider2 { - - /** - * Returns the default character encoding used by this provider. - * - * @return the default character encoding used by this provider - */ - String getDefaultEncoding(); - - /** - * Returns the character encoding for the given element, or - * <code>null</code> if the element is not managed by this provider. - * - * @param element the element - * @return the encoding for the given element - */ - String getEncoding(Object element); - - /** - * Sets the encoding for the given element. If <code>encoding</code> - * is <code>null</code> the workbench's character encoding should be used. - * - * @param element the element - * @param encoding the encoding to be used - */ - void setEncoding(Object element, String encoding); -} diff --git a/org.eclipse.core.filebuffers/src/org/eclipse/core/internal/filebuffers/StorageDocumentProvider2.java b/org.eclipse.core.filebuffers/src/org/eclipse/core/internal/filebuffers/StorageDocumentProvider2.java deleted file mode 100644 index 0236cd208..000000000 --- a/org.eclipse.core.filebuffers/src/org/eclipse/core/internal/filebuffers/StorageDocumentProvider2.java +++ /dev/null @@ -1,240 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ - -package org.eclipse.core.internal.filebuffers; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; - -import org.eclipse.core.resources.IStorage; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.ILog; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.Status; - -import org.eclipse.jface.text.Document; -import org.eclipse.jface.text.IDocument; - - -/** - * Shareable document provider specialized for <code>IStorage</code>s. - */ -public class StorageDocumentProvider2 extends AbstractDocumentProvider2 implements IStorageDocumentProvider2 { - - /** - * Reader chunk size. - */ - protected final static int READER_CHUNK_SIZE= 2048; - - /** - * Buffer size. - */ - protected final static int BUFFER_SIZE= 8 * READER_CHUNK_SIZE; - - - /** - * Bundle of all required information to allow <code>IStorage</code> as underlying document resources. - */ - protected class StorageInfo extends ElementInfo { - - /** The encoding used to create the document from the storage or <code>null</code> for workbench encoding. */ - public String fEncoding= null; - - /** - * Creates a new storage info. - * - * @param document the document - */ - public StorageInfo(IDocument document) { - super(document); - } - }; - - /** - * Creates a new document provider. - */ - public StorageDocumentProvider2() { - super(); - } - - /** - * Intitializes the given document with the given stream using the given encoding. - * - * @param document the document to be initialized - * @param contentStream the stream which delivers the document content - * @param encoding the character encoding for reading the given stream - * @exception CoreException if the given stream can not be read - */ - protected void setDocumentContent(IDocument document, InputStream contentStream, String encoding) throws CoreException { - - Reader in= null; - - try { - - if (encoding == null) - encoding= getDefaultEncoding(); - - in= new BufferedReader(new InputStreamReader(contentStream, encoding), BUFFER_SIZE); - StringBuffer buffer= new StringBuffer(BUFFER_SIZE); - char[] readBuffer= new char[READER_CHUNK_SIZE]; - int n= in.read(readBuffer); - while (n > 0) { - buffer.append(readBuffer, 0, n); - n= in.read(readBuffer); - } - - document.set(buffer.toString()); - - } catch (IOException x) { - String msg= x.getMessage() == null ? "" : x.getMessage(); //$NON-NLS-1$ - IStatus s= new Status(IStatus.ERROR, FileBuffersPlugin.PLUGIN_ID, IStatus.OK, msg, x); - throw new CoreException(s); - } finally { - if (in != null) { - try { - in.close(); - } catch (IOException x) { - } - } - } - } - - /* - * @see org.eclipse.core.internal.filebuffers.IDocumentProvider2#createEmptyDocument(java.lang.Object) - */ - public IDocument createEmptyDocument(Object element) { - return new Document(); - } - - /* - * @see AbstractDocumentProvider#createDocument(Object) - */ - protected IDocument createDocument(Object element) throws CoreException { - - if (element instanceof IStorage) { - IStorage storage= (IStorage) element; - IDocument document= createEmptyDocument(element); - setDocumentContent(document, storage.getContents(), getEncoding(element)); - return document; - } - - return null; - } - - /* - * @see AbstractDocumentProvider#createElementInfo(Object) - */ - protected ElementInfo createElementInfo(Object element) throws CoreException { - if (element instanceof IStorage) { - - IDocument document= null; - IStatus status= null; - - try { - document= createDocument(element); - } catch (CoreException x) { - status= x.getStatus(); - document= createEmptyDocument(element); - } - - StorageInfo info= new StorageInfo(document); - info.fStatus= status; - info.fEncoding= getPersistedEncoding(element); - - return info; - } - - return super.createElementInfo(element); - } - - /* - * @see AbstractDocumentProvider#doSaveDocument(IProgressMonitor, Object, IDocument, boolean) - */ - protected void doSaveDocument(Object element, IDocument document, boolean overwrite) throws CoreException { - } - - /** - * Defines the standard procedure to handle <code>CoreExceptions</code>. Exceptions - * are written to the plug-in log. - * - * @param exception the exception to be logged - * @param message the message to be logged - * @since 2.0 - */ - protected void handleCoreException(CoreException exception, String message) { - ILog log= Platform.getPlugin(FileBuffersPlugin.PLUGIN_ID).getLog(); - - if (message != null) - log.log(new Status(IStatus.ERROR, FileBuffersPlugin.PLUGIN_ID, 0, message, exception)); - else - log.log(exception.getStatus()); - } - - /* - * @see IStorageDocumentProvider#getDefaultEncoding() - */ - public String getDefaultEncoding() { - return ResourcesPlugin.getEncoding(); - } - - /* - * @see IStorageDocumentProvider#getEncoding(Object) - */ - public String getEncoding(Object element) { - if (element instanceof IStorage) { - StorageInfo info= (StorageInfo) getElementInfo(element); - if (info != null) - return info.fEncoding; - else - return getPersistedEncoding(element); - } - return null; - } - - /* - * @see IStorageDocumentProvider#setEncoding(Object, String) - */ - public void setEncoding(Object element, String encoding) { - if (element instanceof IStorage) { - StorageInfo info= (StorageInfo) getElementInfo(element); - if (info != null) { - info.fEncoding= encoding; - try { - persistEncoding(element, encoding); - } catch (CoreException x) { - } - } - } - } - - /** - * Returns the persited encoding for the given element. - * - * @param element the element for which to get the persisted encoding - */ - protected String getPersistedEncoding(Object element) { - return null; - } - - /** - * Persists the given encoding for the given element. - * - * @param element the element for which to store the persisted encoding - * @param encoding the encoding - */ - protected void persistEncoding(Object element, String encoding) throws CoreException { - } -} diff --git a/org.eclipse.core.filebuffers/src/org/eclipse/core/internal/filebuffers/TextFileBuffer.java b/org.eclipse.core.filebuffers/src/org/eclipse/core/internal/filebuffers/TextFileBuffer.java index f7bfc8e0a..4ba945a41 100644 --- a/org.eclipse.core.filebuffers/src/org/eclipse/core/internal/filebuffers/TextFileBuffer.java +++ b/org.eclipse.core.filebuffers/src/org/eclipse/core/internal/filebuffers/TextFileBuffer.java @@ -10,38 +10,350 @@ Contributors: **********************************************************************/ package org.eclipse.core.internal.filebuffers; +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; + import org.eclipse.core.filebuffers.ITextFileBuffer; import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResourceStatus; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.QualifiedName; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.SubProgressMonitor; +import org.eclipse.jface.text.DocumentEvent; import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IDocumentListener; /** * */ public class TextFileBuffer extends FileBuffer implements ITextFileBuffer { + + + private class DocumentListener implements IDocumentListener { + + /* + * @see org.eclipse.jface.text.IDocumentListener#documentAboutToBeChanged(org.eclipse.jface.text.DocumentEvent) + */ + public void documentAboutToBeChanged(DocumentEvent event) { + } - public TextFileBuffer(IFile file, FileDocumentProvider2 documentProvider) { - super(file, documentProvider); + /* + * @see org.eclipse.jface.text.IDocumentListener#documentChanged(org.eclipse.jface.text.DocumentEvent) + */ + public void documentChanged(DocumentEvent event) { + fCanBeSaved= true; + removeFileBufferContentListeners(); + fManager.fireDirtyStateChanged(TextFileBuffer.this, fCanBeSaved); + } + } + + /** + * Reader chunk size. + */ + static final private int READER_CHUNK_SIZE= 2048; + /** + * Buffer size. + */ + static final private int BUFFER_SIZE= 8 * READER_CHUNK_SIZE; + /** + * Qualified name for the encoding key. + */ + static final private QualifiedName ENCODING_KEY= new QualifiedName(FileBuffersPlugin.PLUGIN_ID, "encoding"); //$NON-NLS-1$ + /** + * Constant for representing the ok status. This is considered a value object. + */ + static final private IStatus STATUS_OK= new Status(IStatus.OK, FileBuffersPlugin.PLUGIN_ID, IStatus.OK, "OK", null); + /** + * Constant for representing the error status. This is considered a value object. + */ + static final private IStatus STATUS_ERROR= new Status(IStatus.ERROR, FileBuffersPlugin.PLUGIN_ID, IStatus.INFO, "Error", null); + + + + /** The element's document */ + protected IDocument fDocument; + /** The encoding used to create the document from the storage or <code>null</code> for workbench encoding. */ + protected String fEncoding; + /** Internal document listener */ + protected IDocumentListener fDocumentListener= new DocumentListener(); + + + + public TextFileBuffer(TextFileBufferManager manager) { + super(manager); } /* * @see org.eclipse.core.buffer.text.IBufferedTextFile#getDocument() */ public IDocument getDocument() { - return getDocumentProvider().getDocument(getUnderlyingFile()); + return fDocument; } /* * @see org.eclipse.core.buffer.text.IBufferedTextFile#getEncoding() */ public String getEncoding() { - return getDocumentProvider().getEncoding(getUnderlyingFile()); + return fEncoding; } /* * @see org.eclipse.core.buffer.text.IBufferedTextFile#setEncoding(java.lang.String) */ public void setEncoding(String encoding) { - getDocumentProvider().setEncoding(getUnderlyingFile(), encoding); + fEncoding= encoding; + try { + fFile.setPersistentProperty(ENCODING_KEY, encoding); + } catch (CoreException x) { + handleCoreException(x); + } + } + + /* + * @see org.eclipse.core.buffer.text.IBufferedFile#getStatus() + */ + public IStatus getStatus() { + if (!isDisposed()) { + if (fStatus != null) + return fStatus; + return (fDocument == null ? STATUS_ERROR : STATUS_OK); + } + return STATUS_ERROR; + } + + /* + * @see org.eclipse.core.filebuffers.IFileBuffer#revert(org.eclipse.core.runtime.IProgressMonitor) + */ + public void revert(IProgressMonitor monitor) throws CoreException { + if (isDisposed()) + return; + + refreshFile(monitor); + + IDocument original= null; + IStatus status= null; + + try { + original= fManager.createEmptyDocument(fFile); + setDocumentContent(original, fFile.getContents(), fEncoding); + } catch (CoreException x) { + status= x.getStatus(); + } + + fStatus= status; + + if (original != null) { + + String originalContents= original.get(); + boolean replaceContents= !originalContents.equals(fDocument.get()); + + if (replaceContents) { + fManager.fireBufferContentAboutToBeReplaced(this); + fDocument.set(original.get()); + } + + if (fCanBeSaved) { + fCanBeSaved= false; + addFileBufferContentListeners(); + } + + if (replaceContents) + fManager.fireBufferContentReplaced(this); + + fManager.fireDirtyStateChanged(this, fCanBeSaved); + } + } + + /* + * @see org.eclipse.core.internal.filebuffers.FileBuffer#addFileBufferContentListeners() + */ + protected void addFileBufferContentListeners() { + if (fDocument != null) + fDocument.addDocumentListener(fDocumentListener); + } + + /* + * @see org.eclipse.core.internal.filebuffers.FileBuffer#removeFileBufferContentListeners() + */ + protected void removeFileBufferContentListeners() { + if (fDocument != null) + fDocument.removeDocumentListener(fDocumentListener); + } + + /* + * @see org.eclipse.core.internal.filebuffers.FileBuffer#initializeFileBufferContent(org.eclipse.core.runtime.IProgressMonitor) + */ + protected void initializeFileBufferContent(IProgressMonitor monitor) throws CoreException { + try { + fEncoding= fFile.getPersistentProperty(ENCODING_KEY); + fDocument= fManager.createEmptyDocument(fFile); + setDocumentContent(fDocument, fFile.getContents(), fEncoding); + } catch (CoreException x) { + fDocument= fManager.createEmptyDocument(fFile); + fStatus= x.getStatus(); + } + } + + /* + * @see org.eclipse.core.internal.filebuffers.FileBuffer#commitFileBufferContent(org.eclipse.core.runtime.IProgressMonitor, boolean) + */ + protected void commitFileBufferContent(IProgressMonitor monitor, boolean overwrite) throws CoreException { + try { + + String encoding= getEncoding(); + if (encoding == null) + encoding= fManager.getDefaultEncoding(); + + InputStream stream= new ByteArrayInputStream(fDocument.get().getBytes(encoding)); + + if (fFile.exists()) { + + if (!overwrite) + checkSynchronizationState(); + + fManager.fireStateChanging(this); + + try { + + // here the file synchronizer should actually be removed and afterwards added again. However, + // we are already inside an operation, so the delta is sent AFTER we have added the listener + fFile.setContents(stream, overwrite, true, monitor); + // set modification stamp to know whether the file synchronizer must become active + fModificationStamp= fFile.getModificationStamp(); + + } catch (CoreException x) { + fManager.fireStateChangeFailed(this); + throw x; + } catch (RuntimeException x) { + fManager.fireStateChangeFailed(this); + throw x; + } + + // If here, the editor state will be flipped to "not dirty". + // Thus, the state changing flag will be reset and we don't have to do + // it manually + + // if there is an annotation model update it here + + } else { + + try { + monitor.beginTask("Saving", 2000); //$NON-NLS-1$ + ContainerGenerator generator = new ContainerGenerator(fFile.getWorkspace(), fFile.getParent().getFullPath()); + generator.generateContainer(new SubProgressMonitor(monitor, 1000)); + fFile.create(stream, false, new SubProgressMonitor(monitor, 1000)); + } + finally { + monitor.done(); + } + } + + } catch (IOException x) { + IStatus s= new Status(IStatus.ERROR, FileBuffersPlugin.PLUGIN_ID, IStatus.OK, x.getMessage(), x); + throw new CoreException(s); + } + } + + /** + * Updates the element info to a change of the file content and sends out appropriate notifications. + */ + protected void handleFileContentChanged() { + if (isDisposed()) + return; + + IDocument document= fManager.createEmptyDocument(fFile); + IStatus status= null; + + try { + setDocumentContent(document, fFile.getContents(false), fEncoding); + } catch (CoreException x) { + status= x.getStatus(); + } + + String newContent= document.get(); + + if ( !newContent.equals(fDocument.get())) { + + fManager.fireBufferContentAboutToBeReplaced(this); + + removeFileBufferContentListeners(); + fDocument.set(newContent); + fCanBeSaved= false; + fStatus= status; + addFileBufferContentListeners(); + + fManager.fireBufferContentReplaced(this); + + } else { + + removeFileBufferContentListeners(); + fCanBeSaved= false; + fStatus= status; + addFileBufferContentListeners(); + + fManager.fireDirtyStateChanged(this, fCanBeSaved); + } + } + + /** + * Intitializes the given document with the given stream using the given encoding. + * + * @param document the document to be initialized + * @param contentStream the stream which delivers the document content + * @param encoding the character encoding for reading the given stream + * @exception CoreException if the given stream can not be read + */ + private void setDocumentContent(IDocument document, InputStream contentStream, String encoding) throws CoreException { + Reader in= null; + try { + + if (encoding == null) + encoding= fManager.getDefaultEncoding(); + + in= new BufferedReader(new InputStreamReader(contentStream, encoding), BUFFER_SIZE); + StringBuffer buffer= new StringBuffer(BUFFER_SIZE); + char[] readBuffer= new char[READER_CHUNK_SIZE]; + int n= in.read(readBuffer); + while (n > 0) { + buffer.append(readBuffer, 0, n); + n= in.read(readBuffer); + } + + document.set(buffer.toString()); + + } catch (IOException x) { + String msg= x.getMessage() == null ? "" : x.getMessage(); //$NON-NLS-1$ + IStatus s= new Status(IStatus.ERROR, FileBuffersPlugin.PLUGIN_ID, IStatus.OK, msg, x); + throw new CoreException(s); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException x) { + } + } + } + } + + /** + * Checks whether the given file is synchronized with the the local file system. + * If the file has been changed, a <code>CoreException</code> is thrown. + * + * @param file the file to check + * @exception CoreException if file has been changed on the file system + */ + private void checkSynchronizationState() throws CoreException { + if (!fFile.isSynchronized(IFile.DEPTH_ZERO)) { + Status status= new Status(IStatus.ERROR, FileBuffersPlugin.PLUGIN_ID, IResourceStatus.OUT_OF_SYNC_LOCAL, "out of sync", null); + throw new CoreException(status); + } } } diff --git a/org.eclipse.core.filebuffers/src/org/eclipse/core/internal/filebuffers/TextFileBufferManager.java b/org.eclipse.core.filebuffers/src/org/eclipse/core/internal/filebuffers/TextFileBufferManager.java index 3c7bbdabb..25cc0782a 100644 --- a/org.eclipse.core.filebuffers/src/org/eclipse/core/internal/filebuffers/TextFileBufferManager.java +++ b/org.eclipse.core.filebuffers/src/org/eclipse/core/internal/filebuffers/TextFileBufferManager.java @@ -10,79 +10,202 @@ Contributors: **********************************************************************/ package org.eclipse.core.internal.filebuffers; +import java.util.ArrayList; import java.util.HashMap; +import java.util.Iterator; +import java.util.List; import java.util.Map; +import org.eclipse.core.filebuffers.IDocumentFactory; +import org.eclipse.core.filebuffers.IDocumentSetupParticipant; import org.eclipse.core.filebuffers.IFileBuffer; +import org.eclipse.core.filebuffers.IFileBufferListener; import org.eclipse.core.filebuffers.ITextFileBuffer; import org.eclipse.core.filebuffers.ITextFileBufferManager; import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; import org.eclipse.jface.text.Assert; +import org.eclipse.jface.text.Document; import org.eclipse.jface.text.IDocument; /** * */ -public class TextFileBufferManager implements ITextFileBufferManager { - - private FileDocumentProvider2 fFileDocumentProvider; - private Map fManagedFiles= new HashMap(); - +public class TextFileBufferManager implements ITextFileBufferManager { + + private Map fFilesBuffers= new HashMap(); + private List fFileBufferListeners= new ArrayList(); + private ExtensionsRegistry fRegistry; + + public TextFileBufferManager() { - fFileDocumentProvider= new FileDocumentProvider2(new ExtensionsRegistry()); + fRegistry= new ExtensionsRegistry(); } /* - * @see org.eclipse.core.buffer.text.IBufferedFileManager#connect(org.eclipse.core.resources.IFile) + * @see org.eclipse.core.filebuffers.IFileBufferManager#connect(org.eclipse.core.resources.IFile, org.eclipse.core.runtime.IProgressMonitor) */ - public void connect(IFile file) throws CoreException { + public void connect(IFile file, IProgressMonitor monitor) throws CoreException { Assert.isNotNull(file); - IFileBuffer bufferedFile= getTextFileBuffer(file); - if (bufferedFile == null) { - bufferedFile= createBufferedFile(file); - fManagedFiles.put(file, bufferedFile); + FileBuffer fileBuffer= (FileBuffer) fFilesBuffers.get(file); + if (fileBuffer == null) { + fileBuffer= createFileBuffer(file); + if (fileBuffer == null) + throw new CoreException(new Status(IStatus.ERROR, FileBuffersPlugin.PLUGIN_ID, 0, "Cannot create file buffer.", null)); + fileBuffer.create(file, monitor); + fFilesBuffers.put(file, fileBuffer); } - fFileDocumentProvider.connect(file); + fileBuffer.connect(); } + - protected FileBuffer createBufferedFile(IFile file) { - return isTextFile(file) ? new TextFileBuffer(file, fFileDocumentProvider) : new FileBuffer(file, fFileDocumentProvider); + /* + * @see org.eclipse.core.filebuffers.IFileBufferManager#disconnect(org.eclipse.core.resources.IFile, org.eclipse.core.runtime.IProgressMonitor) + */ + public void disconnect(IFile file, IProgressMonitor monitor) throws CoreException { + Assert.isNotNull(file); + FileBuffer fileBuffer= (FileBuffer) fFilesBuffers.get(file); + if (fileBuffer != null) { + fileBuffer.disconnect(); + fFilesBuffers.remove(file); + } } - protected boolean isTextFile(IFile file) { + private FileBuffer createFileBuffer(IFile file) { + if (isTextFile(file)) + return new TextFileBuffer(this); + return null; + } + + private boolean isTextFile(IFile file) { return true; } /* - * @see org.eclipse.core.buffer.text.IBufferedFileManager#disconnect(org.eclipse.core.resources.IFile) + * @see org.eclipse.core.filebuffers.IFileBufferManager#getFileBuffer(org.eclipse.core.resources.IFile) */ - public void disconnect(IFile file) throws CoreException { - Assert.isNotNull(file); - fFileDocumentProvider.disconnect(file); - if (fFileDocumentProvider.getDocument(file) == null) - fManagedFiles.remove(file); + public IFileBuffer getFileBuffer(IFile file) { + return (IFileBuffer) fFilesBuffers.get(file); } /* - * @see org.eclipse.core.buffer.text.IBufferedFileManager#getBufferedFile(org.eclipse.core.resources.IFile) + * @see org.eclipse.core.filebuffers.ITextFileBufferManager#getTextFileBuffer(org.eclipse.core.resources.IFile) */ public ITextFileBuffer getTextFileBuffer(IFile file) { - return (ITextFileBuffer) fManagedFiles.get(file); + return (ITextFileBuffer) fFilesBuffers.get(file); } /* * @see org.eclipse.core.buffer.text.IBufferedFileManager#getDefaultEncoding() */ public String getDefaultEncoding() { - return fFileDocumentProvider.getDefaultEncoding(); + return ResourcesPlugin.getEncoding(); } /* * @see org.eclipse.core.filebuffers.ITextFileBufferManager#createEmptyDocument(org.eclipse.core.resources.IFile) */ public IDocument createEmptyDocument(IFile file) { - return fFileDocumentProvider.createEmptyDocument(file); + IDocumentFactory factory= fRegistry.getDocumentFactory(file); + + IDocument document= null; + if (factory != null) + document= factory.createDocument(); + else + document= new Document(); + + IDocumentSetupParticipant[] participants= fRegistry.getDocumentSetupParticipants((IFile) file); + if (participants != null) { + for (int i= 0; i < participants.length; i++) + participants[i].setup(document); + } + + return document; + } + + /* + * @see org.eclipse.core.filebuffers.IFileBufferManager#addFileBufferListener(org.eclipse.core.filebuffers.IFileBufferListener) + */ + public void addFileBufferListener(IFileBufferListener listener) { + Assert.isNotNull(listener); + if (!fFileBufferListeners.contains(listener)) + fFileBufferListeners.add(listener); + } + + /* + * @see org.eclipse.core.filebuffers.IFileBufferManager#removeFileBufferListener(org.eclipse.core.filebuffers.IFileBufferListener) + */ + public void removeFileBufferListener(IFileBufferListener listener) { + Assert.isNotNull(listener); + fFileBufferListeners.remove(listener); + } + + protected void fireDirtyStateChanged(IFileBuffer buffer, boolean isDirty) { + Iterator e= new ArrayList(fFileBufferListeners).iterator(); + while (e.hasNext()) { + IFileBufferListener l= (IFileBufferListener) e.next(); + l.dirtyStateChanged(buffer, isDirty); + } + } + + protected void fireBufferContentAboutToBeReplaced(IFileBuffer buffer) { + Iterator e= new ArrayList(fFileBufferListeners).iterator(); + while (e.hasNext()) { + IFileBufferListener l= (IFileBufferListener) e.next(); + l.bufferContentAboutToBeReplaced(buffer); + } + } + + protected void fireBufferContentReplaced(IFileBuffer buffer) { + Iterator e= new ArrayList(fFileBufferListeners).iterator(); + while (e.hasNext()) { + IFileBufferListener l= (IFileBufferListener) e.next(); + l.bufferContentReplaced(buffer); + } + } + + protected void fireUnderlyingFileMoved(IFileBuffer buffer, IFile target) { + Iterator e= new ArrayList(fFileBufferListeners).iterator(); + while (e.hasNext()) { + IFileBufferListener l= (IFileBufferListener) e.next(); + l.underlyingFileMoved(buffer, target); + } + } + + protected void fireUnderlyingFileDeleted(IFileBuffer buffer) { + Iterator e= new ArrayList(fFileBufferListeners).iterator(); + while (e.hasNext()) { + IFileBufferListener l= (IFileBufferListener) e.next(); + l.underlyingFileDeleted(buffer); + } + } + + protected void fireStateValidationChanged(IFileBuffer buffer, boolean isStateValidated) { + Iterator e= new ArrayList(fFileBufferListeners).iterator(); + while (e.hasNext()) { + IFileBufferListener l= (IFileBufferListener) e.next(); + l.stateValidationChanged(buffer, isStateValidated); + } + } + + protected void fireStateChanging(IFileBuffer buffer) { + Iterator e= new ArrayList(fFileBufferListeners).iterator(); + while (e.hasNext()) { + IFileBufferListener l= (IFileBufferListener) e.next(); + l.stateChanging(buffer); + } + } + + protected void fireStateChangeFailed(IFileBuffer buffer) { + Iterator e= new ArrayList(fFileBufferListeners).iterator(); + while (e.hasNext()) { + IFileBufferListener l= (IFileBufferListener) e.next(); + l.stateChangeFailed(buffer); + } } } |