Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKai Maetzel2003-08-13 15:36:19 +0000
committerKai Maetzel2003-08-13 15:36:19 +0000
commitf468248b2df4e628526f9c05c894730ec5f4bb10 (patch)
treeba9d457ba0fc1be07574cd59750f5b44e05fccdb /org.eclipse.core.filebuffers
parentdde83e48764032608c18f8e7a87ee0a582915538 (diff)
downloadeclipse.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')
-rw-r--r--org.eclipse.core.filebuffers/src/org/eclipse/core/filebuffers/FileBuffers.java15
-rw-r--r--org.eclipse.core.filebuffers/src/org/eclipse/core/filebuffers/IDocumentFactory.java5
-rw-r--r--org.eclipse.core.filebuffers/src/org/eclipse/core/filebuffers/IDocumentSetupParticipant.java5
-rw-r--r--org.eclipse.core.filebuffers/src/org/eclipse/core/filebuffers/IFileBuffer.java69
-rw-r--r--org.eclipse.core.filebuffers/src/org/eclipse/core/filebuffers/IFileBufferListener.java55
-rw-r--r--org.eclipse.core.filebuffers/src/org/eclipse/core/filebuffers/IFileBufferManager.java60
-rw-r--r--org.eclipse.core.filebuffers/src/org/eclipse/core/filebuffers/ITextFileBuffer.java28
-rw-r--r--org.eclipse.core.filebuffers/src/org/eclipse/core/filebuffers/ITextFileBufferManager.java26
-rw-r--r--org.eclipse.core.filebuffers/src/org/eclipse/core/internal/filebuffers/AbstractDocumentProvider2.java661
-rw-r--r--org.eclipse.core.filebuffers/src/org/eclipse/core/internal/filebuffers/ElementStateListener.java102
-rw-r--r--org.eclipse.core.filebuffers/src/org/eclipse/core/internal/filebuffers/FileBuffer.java357
-rw-r--r--org.eclipse.core.filebuffers/src/org/eclipse/core/internal/filebuffers/FileBuffersPlugin.java4
-rw-r--r--org.eclipse.core.filebuffers/src/org/eclipse/core/internal/filebuffers/FileDocumentProvider2.java588
-rw-r--r--org.eclipse.core.filebuffers/src/org/eclipse/core/internal/filebuffers/IDocumentProvider2.java200
-rw-r--r--org.eclipse.core.filebuffers/src/org/eclipse/core/internal/filebuffers/IElementStateListener2.java89
-rw-r--r--org.eclipse.core.filebuffers/src/org/eclipse/core/internal/filebuffers/IStorageDocumentProvider2.java45
-rw-r--r--org.eclipse.core.filebuffers/src/org/eclipse/core/internal/filebuffers/StorageDocumentProvider2.java240
-rw-r--r--org.eclipse.core.filebuffers/src/org/eclipse/core/internal/filebuffers/TextFileBuffer.java322
-rw-r--r--org.eclipse.core.filebuffers/src/org/eclipse/core/internal/filebuffers/TextFileBufferManager.java175
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);
+ }
}
}

Back to the top