Package at.bestsolution.efxclipse.text.editor

Source Code of at.bestsolution.efxclipse.text.editor.TextFileDocumentProvider

package at.bestsolution.efxclipse.text.editor;

import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.net.URI;
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.NoSuchElementException;

import org.osgi.framework.Bundle;

import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileInfo;
import org.eclipse.core.filesystem.IFileStore;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
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.MultiStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.core.runtime.jobs.ISchedulingRule;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceRuleFactory;
import org.eclipse.core.resources.IResourceStatus;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;

import org.eclipse.core.filebuffers.FileBuffers;
import org.eclipse.core.filebuffers.IFileBuffer;
import org.eclipse.core.filebuffers.IFileBufferListener;
import org.eclipse.core.filebuffers.IFileBufferManager;
import org.eclipse.core.filebuffers.ITextFileBuffer;
import org.eclipse.core.filebuffers.ITextFileBufferManager;
import org.eclipse.core.filebuffers.LocationKind;

import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ISynchronizable;
import org.eclipse.jface.text.source.IAnnotationModel;

import at.bestsolution.efxclipse.text.editor.internal.EditorMessages;
import at.bestsolution.efxclipse.text.editor.internal.TextEditorPlugin;
import at.bestsolution.efxclipse.text.editor.internal.UISynchronizationContext;

/**
* Shared document provider specialized for {@link org.eclipse.core.resources.IFile} based domain elements.
* A text file document provider can have a parent document provider to which
* it may delegate calls i.e. instead of delegating work to a super class it
* delegates to a parent document provider. The parent chain acts as chain
* of command.
* <p>
* Text file document providers use {@linkplain org.eclipse.core.filebuffers.ITextFileBuffer text file buffers}
* to access the file content. This allows to share it between various clients including
* headless ones. Text file document providers should be preferred over file document
* providers due to this advantage.
* </p>
* <p>
* Use a {@linkplain org.eclipse.ui.editors.text.ForwardingDocumentProvider forwarding document provider}
* if you need to ensure that all documents provided to clients are appropriately set up.
* </p>
* <p>
* Clients can directly instantiate and configure this class with a suitable parent
* document provider or provide their own subclass.
* </p>
*
* @since 3.0
*/
public class TextFileDocumentProvider implements IDocumentProvider, IDocumentProviderExtension, IDocumentProviderExtension2, IDocumentProviderExtension3, IDocumentProviderExtension5, IStorageDocumentProvider, IDocumentProviderExtension4 {

  /**
   * Operation created by the document provider and to be executed by the providers runnable context.
   */
  protected static abstract class DocumentProviderOperation implements IRunnableWithProgress, ISchedulingRuleProvider {

    /**
     * The actual functionality of this operation.
     *
     * @param monitor the progress monitor
     * @throws CoreException if the execution fails
     */
    protected abstract void execute(IProgressMonitor monitor) throws CoreException;

    /*
     * @see org.eclipse.jface.operation.IRunnableWithProgress#run(org.eclipse.core.runtime.IProgressMonitor)
     */
    public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
      try {
        execute(monitor);
      } catch (CoreException x) {
        throw new InvocationTargetException(x);
      }
    }

    /*
     * @see org.eclipse.ui.texteditor.ISchedulingRuleProvider#getSchedulingRule()
     */
    public ISchedulingRule getSchedulingRule() {
      return ResourcesPlugin.getWorkspace().getRoot();
    }
  }

  /**
   * @deprecated As of 3.3 - do not use
   */
  static protected class NullProvider implements IDocumentProvider, IDocumentProviderExtension, IDocumentProviderExtension2, IDocumentProviderExtension3, IDocumentProviderExtension4, IDocumentProviderExtension5, IStorageDocumentProvider  {

    static final private IStatus STATUS_ERROR= new Status(IStatus.ERROR, TextEditorPlugin.PLUGIN_ID, IStatus.OK, EditorMessages.NullProvider_error, null);

    public void connect(Object element) throws CoreException {}
    public void disconnect(Object element) {}
    public IDocument getDocument(Object element) { return null; }
    public void resetDocument(Object element) throws CoreException {}
    public void saveDocument(IProgressMonitor monitor, Object element, IDocument document, boolean overwrite) throws CoreException {}
    public long getModificationStamp(Object element) { return 0; }
    public long getSynchronizationStamp(Object element) { return 0; }
    public boolean isDeleted(Object element) { return true; }
    public boolean mustSaveDocument(Object element) { return false; }
    public boolean canSaveDocument(Object element) { return false; }
    public IAnnotationModel getAnnotationModel(Object element) { return null; }
    public void aboutToChange(Object element) {}
    public void changed(Object element) {}
    public void addElementStateListener(IElementStateListener listener) {}
    public void removeElementStateListener(IElementStateListener listener) {}
    public boolean isReadOnly(Object element) { return true; }
    public boolean isModifiable(Object element) { return false; }
    public void validateState(Object element, Object computationContext) throws CoreException {}
    public boolean isStateValidated(Object element) { return true; }
    public void updateStateCache(Object element) throws CoreException {}
    public void setCanSaveDocument(Object element) {}
    public IStatus getStatus(Object element) { return STATUS_ERROR; }
    public void synchronize(Object element) throws CoreException {}
    public void setProgressMonitor(IProgressMonitor progressMonitor) {}
    public IProgressMonitor getProgressMonitor() { return new NullProgressMonitor(); }
    public boolean isSynchronized(Object element) { return true; }
    public boolean isNotSynchronizedException(Object element, CoreException ex) { return false; }
    public String getDefaultEncoding() { return null; }
    public String getEncoding(Object element) { return null; }
    public void setEncoding(Object element, String encoding) {}
    public IContentType getContentType(Object element) throws CoreException { return null; }
  }

  static protected class FileInfo  {
    public Object fElement;
    public int fCount;
    public ITextFileBuffer fTextFileBuffer;

    /**
     * The file buffer location kind.
     * @since 3.4
     */
    public LocationKind fTextFileBufferLocationKind;

    public IAnnotationModel fModel;
    public boolean fCachedReadOnlyState;
  }

  static private class SingleElementIterator implements Iterator {

    private Object fElement;

    public SingleElementIterator(Object element) {
      fElement= element;
    }

    /*
     * @see java.util.Iterator#hasNext()
     */
    public boolean hasNext() {
      return fElement != null;
    }

    /*
     * @see java.util.Iterator#next()
     */
    public Object next() {
      if (fElement != null) {
        Object result= fElement;
        fElement= null;
        return result;
      }
      throw new NoSuchElementException();
    }

    /*
     * @see java.util.Iterator#remove()
     */
    public void remove() {
      throw new UnsupportedOperationException();
    }
  }

  protected class FileBufferListener implements IFileBufferListener  {

    public FileBufferListener()  {
    }

    /*
     * @see org.eclipse.core.buffer.text.IBufferedFileListener#bufferContentAboutToBeReplaced(org.eclipse.core.buffer.text.IBufferedFile)
     */
    public void bufferContentAboutToBeReplaced(IFileBuffer file) {
      List list= new ArrayList(fElementStateListeners);
      Iterator e= list.iterator();
      while (e.hasNext()) {
        IElementStateListener l= (IElementStateListener) e.next();
        Iterator i= getElements(file);
        while (i.hasNext())
          l.elementContentAboutToBeReplaced(i.next());
      }
    }

    /*
     * @see org.eclipse.core.buffer.text.IBufferedFileListener#bufferContentReplaced(org.eclipse.core.buffer.text.IBufferedFile)
     */
    public void bufferContentReplaced(IFileBuffer file) {
      List list= new ArrayList(fElementStateListeners);
      Iterator e= list.iterator();
      while (e.hasNext()) {
        IElementStateListener l= (IElementStateListener) e.next();
        Iterator i= getElements(file);
        while (i.hasNext())
          l.elementContentReplaced(i.next());
      }
    }

    /*
     * @see org.eclipse.core.buffer.text.IBufferedFileListener#stateChanging(org.eclipse.core.buffer.text.IBufferedFile)
     */
    public void stateChanging(IFileBuffer file) {
      Iterator i= getElements(file);
      while (i.hasNext())
        fireElementStateChanging(i.next());
    }

    /*
     * @see org.eclipse.core.buffer.text.IBufferedFileListener#dirtyStateChanged(org.eclipse.core.buffer.text.IBufferedFile, boolean)
     */
    public void dirtyStateChanged(IFileBuffer file, boolean isDirty) {
      List list= new ArrayList(fElementStateListeners);
      Iterator e= list.iterator();
      while (e.hasNext()) {
        IElementStateListener l= (IElementStateListener) e.next();
        Iterator i= getElements(file);
        while (i.hasNext())
          l.elementDirtyStateChanged(i.next(), isDirty);
      }
    }

    /*
     * @see org.eclipse.core.buffer.text.IBufferedFileListener#stateValidationChanged(org.eclipse.core.buffer.text.IBufferedFile, boolean)
     */
    public void stateValidationChanged(IFileBuffer file, boolean isStateValidated) {
      List list= new ArrayList(fElementStateListeners);
      Iterator e= list.iterator();
      while (e.hasNext()) {
        Object l= e.next();
        if (l instanceof IElementStateListenerExtension) {
          IElementStateListenerExtension x= (IElementStateListenerExtension) l;
          Iterator i= getElements(file);
          while (i.hasNext())
            x.elementStateValidationChanged(i.next(), isStateValidated);
        }
      }
    }

    /*
     * @see org.eclipse.core.buffer.text.IBufferedFileListener#underlyingFileMoved(org.eclipse.core.buffer.text.IBufferedFile, org.eclipse.core.runtime.IPath)
     */
    public void underlyingFileMoved(IFileBuffer file, IPath newLocation) {
      IWorkspace workspace=ResourcesPlugin.getWorkspace();
      IFile newFile= workspace.getRoot().getFile(newLocation);
      IEditorInput input= new FileEditorInput(newFile);
      List list= new ArrayList(fElementStateListeners);
      Iterator e= list.iterator();
      while (e.hasNext()) {
        IElementStateListener l= (IElementStateListener) e.next();
        Iterator i= getElements(file);
        while (i.hasNext())
          l.elementMoved(i.next(), input);
      }
    }

    /*
     * @see org.eclipse.core.buffer.text.IBufferedFileListener#underlyingFileDeleted(org.eclipse.core.buffer.text.IBufferedFile)
     */
    public void underlyingFileDeleted(IFileBuffer file) {
      List list= new ArrayList(fElementStateListeners);
      Iterator e= list.iterator();
      while (e.hasNext()) {
        IElementStateListener l= (IElementStateListener) e.next();
        Iterator i= getElements(file);
        while (i.hasNext())
          l.elementDeleted(i.next());
      }
    }

    /*
     * @see org.eclipse.core.buffer.text.IBufferedFileListener#stateChangeFailed(org.eclipse.core.buffer.text.IBufferedFile)
     */
    public void stateChangeFailed(IFileBuffer file) {
      Iterator i= getElements(file);
      while (i.hasNext())
        fireElementStateChangeFailed(i.next());
    }

    /*
     * @see org.eclipse.core.filebuffers.IFileBufferListener#bufferCreated(org.eclipse.core.filebuffers.IFileBuffer)
     */
    public void bufferCreated(IFileBuffer buffer) {
      // ignore
    }

    /*
     * @see org.eclipse.core.filebuffers.IFileBufferListener#bufferDisposed(org.eclipse.core.filebuffers.IFileBuffer)
     */
    public void bufferDisposed(IFileBuffer buffer) {
      // ignore
    }
  }

  /** The parent document provider. */
  private IDocumentProvider fParentProvider;
  /** Element information of all connected elements. */
  private final Map fFileInfoMap= new HashMap();
  /** Map from file buffers to their connected elements. */
  private final Map fFileBufferMap= new HashMap();
  /** The list of element state listeners. */
  private List fElementStateListeners= new ArrayList();
  /** The file buffer listener. */
  private final IFileBufferListener fFileBufferListener= new FileBufferListener();
  /** The progress monitor. */
  private IProgressMonitor fProgressMonitor;
  /** The operation runner. */
  private WorkspaceOperationRunner fOperationRunner;
  /** The rule factory. */
  private IResourceRuleFactory fResourceRuleFactory;


  /**
   * Creates a new text file document provider
   * with no parent.
   */
  public TextFileDocumentProvider()  {
    this(null);
  }

  /**
   * Creates a new text file document provider
   * which has the given parent provider.
   *
   * @param parentProvider the parent document provider
   */
  public TextFileDocumentProvider(IDocumentProvider parentProvider) {
    IFileBufferManager manager= FileBuffers.getTextFileBufferManager();
    manager.setSynchronizationContext(new UISynchronizationContext());
    if (parentProvider != null)
      setParentDocumentProvider(parentProvider);

    fResourceRuleFactory= ResourcesPlugin.getWorkspace().getRuleFactory();
  }

  /**
   * Sets the given parent provider as this document
   * provider's parent document provider.
   *
   * @param parentProvider the parent document provider
   */
  public final void setParentDocumentProvider(IDocumentProvider parentProvider) {

    Assert.isTrue(parentProvider instanceof IDocumentProviderExtension);
    Assert.isTrue(parentProvider instanceof IDocumentProviderExtension2);
    Assert.isTrue(parentProvider instanceof IDocumentProviderExtension3);
    Assert.isTrue(parentProvider instanceof IStorageDocumentProvider);

    fParentProvider= parentProvider;
  }

  /**
   * Returns the parent document provider.
   *
   * @return the parent document provider
   */
  final protected  IDocumentProvider getParentProvider() {
    if (fParentProvider == null)
      fParentProvider= new StorageDocumentProvider();
    return fParentProvider;
  }

  /**
   * Returns the runnable context for this document provider.
   *
   * @param monitor the progress monitor
   * @return the runnable context for this document provider
   */
  protected IRunnableContext getOperationRunner(IProgressMonitor monitor) {
    if (fOperationRunner == null)
      fOperationRunner = new WorkspaceOperationRunner();
    fOperationRunner.setProgressMonitor(monitor);
    return fOperationRunner;
  }

  /**
   * Executes the given operation in the providers runnable context.
   *
   * @param operation the operation to be executes
   * @param monitor the progress monitor
   * @throws CoreException the operation's core exception
   */
  protected void executeOperation(DocumentProviderOperation operation, IProgressMonitor monitor) throws CoreException {
    try {
      IRunnableContext runner= getOperationRunner(monitor);
      if (runner != null)
        runner.run(false, false, operation);
      else
        operation.run(monitor);
    } catch (InvocationTargetException x) {
      Throwable e= x.getTargetException();
      if (e instanceof CoreException)
        throw (CoreException) e;
      String message= (e.getMessage() != null ? e.getMessage() : ""); //$NON-NLS-1$
      throw new CoreException(new Status(IStatus.ERROR, TextEditorPlugin.PLUGIN_ID, IStatus.OK, message, e));
    } catch (InterruptedException x) {
      String message= (x.getMessage() != null ? x.getMessage() : ""); //$NON-NLS-1$
      throw new CoreException(new Status(IStatus.CANCEL, TextEditorPlugin.PLUGIN_ID, IStatus.OK, message, x));
    }
  }

  /*
   * @see org.eclipse.ui.texteditor.IDocumentProvider#connect(java.lang.Object)
   */
  public void connect(Object element) throws CoreException {
    FileInfo info= (FileInfo) fFileInfoMap.get(element);
    if (info == null) {

      info= createFileInfo(element);
      if (info == null)  {
        getParentProvider().connect(element);
        return;
      }

      info.fElement= element;
      fFileInfoMap.put(element, info);
      storeFileBufferMapping(element, info);
    }
    ++ info.fCount;
  }

  /**
   * Updates the file buffer map with a new relation between the file buffer
   * of the given info and the given element.
   *
   * @param element the element
   * @param info the element's file info object
   */
  private void storeFileBufferMapping(Object element, FileInfo info) {
    Object value= fFileBufferMap.get(info.fTextFileBuffer);

    if (value instanceof List) {
      List list= (List) value;
      list.add(element);
      return;
    }

    if (value == null) {
      value= element;
    } else {
      List list= new ArrayList(2);
      list.add(value);
      list.add(element);

      value= list;
    }
    fFileBufferMap.put(info.fTextFileBuffer, value);
  }

  /**
   * Creates and returns a new and empty file info object.
   * <p>
   * Subclasses which extend {@link org.eclipse.ui.editors.text.TextFileDocumentProvider.FileInfo}
   * should override this method.
   * </p>
   *
   * @return a new and empty object of type <code>FileInfo</code>
   */
  protected FileInfo createEmptyFileInfo()  {
    return new FileInfo();
  }

  /**
   * Creates and returns the file info object
   * for the given element.
   * <p>
   * Subclasses which extend {@link org.eclipse.ui.editors.text.TextFileDocumentProvider.FileInfo}
   * will probably have to extend this method as well.
   * </p>
   *
   * @param element the element
   * @return a file info object of type <code>FileInfo</code>
   *        or <code>null</code> if none can be created
   * @throws CoreException if the file info object could not successfully be created
   */
  protected FileInfo createFileInfo(Object element) throws CoreException {
    if (!(element instanceof IAdaptable))
      return null;
    IAdaptable adaptable= (IAdaptable) element;

    IFile file= null;
    ITextFileBufferManager manager= FileBuffers.getTextFileBufferManager();
    ITextFileBuffer fileBuffer= null;
    LocationKind locationKind= null;

    file= (IFile)adaptable.getAdapter(IFile.class);
    if (file != null) {
      IPath location= file.getFullPath();
      locationKind= LocationKind.IFILE;
      manager.connect(location, locationKind,getProgressMonitor());
      fileBuffer= manager.getTextFileBuffer(location, locationKind);
    } else {
      ILocationProvider provider= (ILocationProvider) adaptable.getAdapter(ILocationProvider.class);
      if (provider instanceof ILocationProviderExtension) {
        URI uri= ((ILocationProviderExtension)provider).getURI(element);
        if (ResourcesPlugin.getWorkspace().getRoot().findFilesForLocationURI(uri).length == 0) {
          IFileStore fileStore= EFS.getStore(uri);
          manager.connectFileStore(fileStore, getProgressMonitor());
          fileBuffer= manager.getFileStoreTextFileBuffer(fileStore);
        }
      }
      if (fileBuffer == null && provider != null) {
        IPath location= provider.getPath(element);
        if (location == null)
          return null;
        locationKind= LocationKind.NORMALIZE;
        manager.connect(location, locationKind, getProgressMonitor());
        fileBuffer= manager.getTextFileBuffer(location, locationKind);
        file= FileBuffers.getWorkspaceFileAtLocation(location);
      }
    }

    if (fileBuffer != null) {
      fileBuffer.requestSynchronizationContext();

      FileInfo info= createEmptyFileInfo();
      info.fTextFileBuffer= fileBuffer;
      info.fTextFileBufferLocationKind= locationKind;
      info.fCachedReadOnlyState= isSystemFileReadOnly(info);

      if (file != null)
        info.fModel= createAnnotationModel(file);

      if (info.fModel == null)
        info.fModel= info.fTextFileBuffer.getAnnotationModel();

      setUpSynchronization(info);

      return info;
    }
    return null;
  }

  /**
   * Sets up the synchronization for the document
   * and the annotation mode.
   *
   * @param info the file info
   * @since 3.2
   */
  protected void setUpSynchronization(FileInfo info) {
    if (info == null || info.fTextFileBuffer == null)
      return;

    IDocument document= info.fTextFileBuffer.getDocument();
    IAnnotationModel model= info.fModel;

    if (document instanceof ISynchronizable) {
      Object lock= ((ISynchronizable)document).getLockObject();
      if (lock == null) {
        lock= new Object();
        ((ISynchronizable)document).setLockObject(lock);
      }
      if (model instanceof ISynchronizable)
        ((ISynchronizable) model).setLockObject(lock);
    }
  }

  /**
   * Creates and returns the annotation model for the given file.
   *
   * @param file the file
   * @return the file's annotation model or <code>null</code> if none
   */
  protected IAnnotationModel createAnnotationModel(IFile file) {
    return null;
  }

  /*
   * @see org.eclipse.ui.texteditor.IDocumentProvider#disconnect(java.lang.Object)
   */
  public void disconnect(Object element) {
    FileInfo info= (FileInfo) fFileInfoMap.get(element);

    if (info == null)  {
      getParentProvider().disconnect(element);
      return;
    }

    if (info.fCount == 1) {

      fFileInfoMap.remove(element);
      removeFileBufferMapping(element, info);
      disposeFileInfo(element, info);

    } else
      -- info.fCount;
  }

  /**
   * Removes the relation between the file buffer of the given info and the
   * given element from the file buffer mapping.
   *
   * @param element the element
   * @param info the element's file info object
   */
  private void removeFileBufferMapping(Object element, FileInfo info) {
    Object value= fFileBufferMap.get(info.fTextFileBuffer);
    if (value == null)
      return;

    if (value instanceof List) {
      List list= (List) value;
      list.remove(element);
      if (list.size() == 1)
        fFileBufferMap.put(info.fTextFileBuffer, list.get(0));
    } else if (value == element) {
      fFileBufferMap.remove(info.fTextFileBuffer);
    }
  }

  /**
   * Releases all resources described by given element's info object.
   * <p>
   * Subclasses which extend {@link org.eclipse.ui.editors.text.TextFileDocumentProvider.FileInfo}
   * will probably have to extend this method as well.
   * </p>
   *
   * @param element the element
   * @param info the element's file info object
   */
  protected void disposeFileInfo(Object element, FileInfo info) {
    IFileBufferManager manager= FileBuffers.getTextFileBufferManager();
    try {
      info.fTextFileBuffer.releaseSynchronizationContext();
      if (info.fTextFileBufferLocationKind != null)
        manager.disconnect(info.fTextFileBuffer.getLocation(), info.fTextFileBufferLocationKind, getProgressMonitor());
      else
        manager.disconnectFileStore(info.fTextFileBuffer.getFileStore(), getProgressMonitor());
    } catch (CoreException x) {
      handleCoreException(x, "FileDocumentProvider.disposeElementInfo"); //$NON-NLS-1$
    }
  }

  /**
   * Returns an iterator for all the elements that are connected to this file buffer.
   *
   * @param file the file buffer
   * @return an iterator for all elements connected with the given file buffer
   */
  protected Iterator getElements(IFileBuffer file) {
    Object value= fFileBufferMap.get(file);
    if (value instanceof List)
      return new ArrayList((List) value).iterator();
    return new SingleElementIterator(value);
  }

  /*
   * @see org.eclipse.ui.texteditor.IDocumentProvider#getDocument(java.lang.Object)
   */
  public IDocument getDocument(Object element) {
    FileInfo info= (FileInfo) fFileInfoMap.get(element);
    if (info != null)
      return info.fTextFileBuffer.getDocument();
    return getParentProvider().getDocument(element);
  }

  /*
   * @see org.eclipse.ui.texteditor.IDocumentProvider#resetDocument(java.lang.Object)
   */
  public void resetDocument(Object element) throws CoreException {
    final FileInfo info= (FileInfo) fFileInfoMap.get(element);
    if (info != null) {
      DocumentProviderOperation operation= new DocumentProviderOperation() {
        /*
         * @see org.eclipse.ui.editors.text.TextFileDocumentProvider.DocumentProviderOperation#execute(org.eclipse.core.runtime.IProgressMonitor)
         */
        protected void execute(IProgressMonitor monitor) throws CoreException {
          info.fTextFileBuffer.revert(monitor);
          System.err.println("Needs porting");
          Thread.dumpStack();
//          if (info.fModel instanceof AbstractMarkerAnnotationModel) {
//            AbstractMarkerAnnotationModel markerModel= (AbstractMarkerAnnotationModel) info.fModel;
//            markerModel.resetMarkers();
//          }
        }
        /*
         * @see org.eclipse.ui.editors.text.TextFileDocumentProvider.DocumentProviderOperation#getSchedulingRule()
         */
        public ISchedulingRule getSchedulingRule() {
          if (info.fElement instanceof IFileEditorInput) {
            IFileEditorInput input= (IFileEditorInput) info.fElement;
            return fResourceRuleFactory.refreshRule((input).getFile());
          }
          return null;
        }
      };
      executeOperation(operation, getProgressMonitor());
    } else {
      getParentProvider().resetDocument(element);
    }
  }

  /*
   * @see IDocumentProvider#saveDocument(IProgressMonitor, Object, IDocument, boolean)
   */
  public final void saveDocument(IProgressMonitor monitor, Object element, IDocument document, boolean overwrite) throws CoreException {

    if (element == null)
      return;

    DocumentProviderOperation operation= createSaveOperation(element, document, overwrite);
    if (operation != null)
      executeOperation(operation, monitor);
    else
      getParentProvider().saveDocument(monitor, element, document, overwrite);
  }

  protected DocumentProviderOperation createSaveOperation(final Object element, final IDocument document, final boolean overwrite) throws CoreException {
    final FileInfo info= (FileInfo) fFileInfoMap.get(element);
    if (info != null) {

      if (info.fTextFileBuffer.getDocument() != document) {
        // the info exists, but not for the given document
        // -> saveAs was executed with a target that is already open
        // in another editor
        // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=85519
        Status status= new Status(IStatus.WARNING, TextEditorPlugin.PLUGIN_ID, IStatus.OK, EditorMessages.TextFileDocumentProvider_saveAsTargetOpenInEditor, null);
        throw new CoreException(status);
      }

      return new DocumentProviderOperation() {
        /*
         * @see org.eclipse.ui.editors.text.TextFileDocumentProvider.DocumentProviderOperation#execute(org.eclipse.core.runtime.IProgressMonitor)
         */
        public void execute(IProgressMonitor monitor) throws CoreException {
          commitFileBuffer(monitor, info, overwrite);
        }
        /*
         * @see org.eclipse.ui.editors.text.TextFileDocumentProvider.DocumentProviderOperation#getSchedulingRule()
         */
        public ISchedulingRule getSchedulingRule() {
          if (info.fElement instanceof IFileEditorInput) {
            IFileEditorInput input= (IFileEditorInput) info.fElement;
            return computeSchedulingRule(input.getFile());
          }
          return null;
        }
      };

    } else if (element instanceof IFileEditorInput) {

      final IFile file= ((IFileEditorInput) element).getFile();
      return new DocumentProviderOperation() {
        /*
         * @see org.eclipse.ui.editors.text.TextFileDocumentProvider.DocumentProviderOperation#execute(org.eclipse.core.runtime.IProgressMonitor)
         */
        public void execute(IProgressMonitor monitor) throws CoreException {
          createFileFromDocument(monitor, file, document);
        }
        /*
         * @see org.eclipse.ui.editors.text.TextFileDocumentProvider.DocumentProviderOperation#getSchedulingRule()
         */
        public ISchedulingRule getSchedulingRule() {
          return computeSchedulingRule(file);
        }
      };
    } else if (element instanceof IURIEditorInput) {
      final URI uri= ((IURIEditorInput)element).getURI();
      return new DocumentProviderOperation() {
        /*
         * @see org.eclipse.ui.editors.text.TextFileDocumentProvider.DocumentProviderOperation#execute(org.eclipse.core.runtime.IProgressMonitor)
         */
        public void execute(IProgressMonitor monitor) throws CoreException {
          createFileStoreFromDocument(monitor, uri, document);
        }
        /*
         * @see org.eclipse.ui.editors.text.TextFileDocumentProvider.DocumentProviderOperation#getSchedulingRule()
         */
        public ISchedulingRule getSchedulingRule() {
          return null;
        }
      };
    }

    return null;
  }

  /**
   * Commits the given file info's file buffer by changing the contents
   * of the underlying file to the contents of this file buffer. After that
   * call, <code>isDirty</code> returns <code>false</code> and <code>isSynchronized</code>
   * returns <code>true</code>.
   *
   * @param monitor the progress monitor
   * @param info the element's file info object
   * @param overwrite indicates whether the underlying file should be overwritten if it is not synchronized with the file system
   * @throws CoreException if writing or accessing the underlying file fails
   */
  protected void commitFileBuffer(IProgressMonitor monitor, FileInfo info, boolean overwrite) throws CoreException {
    Assert.isNotNull(info);

    /* https://bugs.eclipse.org/bugs/show_bug.cgi?id=98327
     * Make sure file gets save in commit() if the underlying file has been deleted */
    if (info.fElement instanceof IFileEditorInput) {
      IFileEditorInput input= (IFileEditorInput) info.fElement;
      IResource resource= input.getFile();
      if (!resource.isSynchronized(IResource.DEPTH_ZERO) && isDeleted(input))
        info.fTextFileBuffer.setDirty(true);
    }

    info.fTextFileBuffer.commit(monitor, overwrite);
   
    System.err.println("Needs porting");
    Thread.dumpStack();
//    if (info.fModel instanceof AbstractMarkerAnnotationModel) {
//      AbstractMarkerAnnotationModel model= (AbstractMarkerAnnotationModel) info.fModel;
//      model.updateMarkers(info.fTextFileBuffer.getDocument());
//    }
  }

  /**
   * Creates the given file with the given document content.
   *
   * @param monitor the progress monitor
   * @param file the file to be created
   * @param document the document to be written to the file
   * @throws CoreException if the creation of the file fails
   */
  protected void createFileFromDocument(IProgressMonitor monitor, IFile file, IDocument document) throws CoreException {
    try {
      monitor.beginTask(EditorMessages.TextFileDocumentProvider_beginTask_saving, 2000);
      ITextFileBufferManager manager= FileBuffers.getTextFileBufferManager();
      manager.connect(file.getFullPath(), LocationKind.IFILE, monitor);
      ITextFileBuffer buffer= ITextFileBufferManager.DEFAULT.getTextFileBuffer(file.getFullPath(), LocationKind.IFILE);
      buffer.getDocument().set(document.get());
      buffer.commit(monitor, true);
      manager.disconnect(file.getFullPath(), LocationKind.IFILE, monitor);
    } finally {
      monitor.done();
    }
  }

  /**
   * Creates the given file store with the given document content.
   *
   * @param monitor the progress monitor
   * @param uri the location where the file store should be created
   * @param document the document to be written to the file store
   * @throws CoreException if the creation of the file store fails
   * @since 3.3
   */
  private void createFileStoreFromDocument(IProgressMonitor monitor, URI uri, IDocument document) throws CoreException {
    try {
      monitor.beginTask(EditorMessages.TextFileDocumentProvider_beginTask_saving, 2000);
      IFileStore fileStore= EFS.getStore(uri);
      FileBuffers.getTextFileBufferManager().connectFileStore(fileStore, monitor);
      ITextFileBuffer buffer= FileBuffers.getTextFileBufferManager().getFileStoreTextFileBuffer(fileStore);
      buffer.getDocument().set(document.get());
      buffer.commit(monitor, true);
      FileBuffers.getTextFileBufferManager().disconnectFileStore(fileStore, monitor);
    } finally {
      monitor.done();
    }
  }

  /*
   * @see org.eclipse.ui.texteditor.IDocumentProvider#getModificationStamp(java.lang.Object)
   */
  public long getModificationStamp(Object element) {
    FileInfo info= (FileInfo) fFileInfoMap.get(element);
    if (info != null)
      return info.fTextFileBuffer.getModificationStamp();
    return getParentProvider().getModificationStamp(element);
  }

  /*
   * @see org.eclipse.ui.texteditor.IDocumentProvider#getSynchronizationStamp(java.lang.Object)
   */
  public long getSynchronizationStamp(Object element) {
    FileInfo info= (FileInfo) fFileInfoMap.get(element);
    if (info != null)
      return 0;
    return getParentProvider().getSynchronizationStamp(element);
  }

  /*
   * @see org.eclipse.ui.texteditor.IDocumentProvider#isDeleted(java.lang.Object)
   */
  public boolean isDeleted(Object element) {
    FileInfo info= (FileInfo) fFileInfoMap.get(element);
    if (info != null)  {
      IFileStore fileStore= getFileStore(info);
      return fileStore == null ? true : !fileStore.fetchInfo().exists();
    }
    return getParentProvider().isDeleted(element);
  }

  /*
   * @see org.eclipse.ui.texteditor.IDocumentProvider#mustSaveDocument(java.lang.Object)
   */
  public boolean mustSaveDocument(Object element) {
    FileInfo info= (FileInfo) fFileInfoMap.get(element);
    if (info != null)
      return (info.fCount == 1) && info.fTextFileBuffer.isDirty();
    return getParentProvider().mustSaveDocument(element);
  }

  /*
   * @see org.eclipse.ui.texteditor.IDocumentProvider#canSaveDocument(java.lang.Object)
   */
  public boolean canSaveDocument(Object element) {
    FileInfo info= (FileInfo) fFileInfoMap.get(element);
    if (info != null)
      return info.fTextFileBuffer.isDirty();
    return getParentProvider().canSaveDocument(element);
  }

  /*
   * @see org.eclipse.ui.texteditor.IDocumentProvider#getAnnotationModel(java.lang.Object)
   */
  public IAnnotationModel getAnnotationModel(Object element) {
    FileInfo info= (FileInfo) fFileInfoMap.get(element);
    if (info != null)
      return info.fModel;
    return getParentProvider().getAnnotationModel(element);
  }

  /*
   * @see org.eclipse.ui.texteditor.IDocumentProvider#aboutToChange(java.lang.Object)
   */
  public void aboutToChange(Object element) {
    FileInfo info= (FileInfo) fFileInfoMap.get(element);
    if (info == null)
      getParentProvider().aboutToChange(element);
  }

  /*
   * @see org.eclipse.ui.texteditor.IDocumentProvider#changed(java.lang.Object)
   */
  public void changed(Object element) {
    FileInfo info= (FileInfo) fFileInfoMap.get(element);
    if (info == null)
      getParentProvider().changed(element);
  }

  /*
   * @see org.eclipse.ui.texteditor.IDocumentProvider#addElementStateListener(org.eclipse.ui.texteditor.IElementStateListener)
   */
  public void addElementStateListener(IElementStateListener listener) {
    Assert.isNotNull(listener);
    if (!fElementStateListeners.contains(listener)) {
      fElementStateListeners.add(listener);
      if (fElementStateListeners.size() == 1) {
        IFileBufferManager manager= FileBuffers.getTextFileBufferManager();
        manager.addFileBufferListener(fFileBufferListener);
      }
    }
    getParentProvider().addElementStateListener(listener);
  }

  /*
   * @see org.eclipse.ui.texteditor.IDocumentProvider#removeElementStateListener(org.eclipse.ui.texteditor.IElementStateListener)
   */
  public void removeElementStateListener(IElementStateListener listener) {
    Assert.isNotNull(listener);
    fElementStateListeners.remove(listener);
    if (fElementStateListeners.size() == 0) {
      IFileBufferManager manager= FileBuffers.getTextFileBufferManager();
      manager.removeFileBufferListener(fFileBufferListener);
    }
    getParentProvider().removeElementStateListener(listener);
  }

  /*
   * @see org.eclipse.ui.texteditor.IDocumentProviderExtension#isReadOnly(java.lang.Object)
   */
  public boolean isReadOnly(Object element) {
    FileInfo info= (FileInfo) fFileInfoMap.get(element);
    if (info != null)
      return info.fCachedReadOnlyState;
    return ((IDocumentProviderExtension) getParentProvider()).isReadOnly(element);
  }

  /*
   * @see org.eclipse.ui.texteditor.IDocumentProviderExtension#isModifiable(java.lang.Object)
   */
  public boolean isModifiable(Object element) {
    FileInfo info= (FileInfo) fFileInfoMap.get(element);
    if (info != null)
      return info.fTextFileBuffer.isStateValidated() ? !isReadOnly(element) : true;
    return ((IDocumentProviderExtension) getParentProvider()).isModifiable(element);
  }

  /*
   * @see org.eclipse.ui.texteditor.IDocumentProviderExtension#validateState(java.lang.Object, java.lang.Object)
   */
  public void validateState(Object element, final Object computationContext) throws CoreException {
    final FileInfo info= (FileInfo) fFileInfoMap.get(element);
    if (info != null) {
      DocumentProviderOperation operation= new DocumentProviderOperation() {
        /*
         * @see org.eclipse.ui.editors.text.TextFileDocumentProvider.DocumentProviderOperation#execute(org.eclipse.core.runtime.IProgressMonitor)
         */
        protected void execute(IProgressMonitor monitor) throws CoreException {
          info.fTextFileBuffer.validateState(monitor, computationContext);
        }
        /*
         * @see org.eclipse.ui.editors.text.TextFileDocumentProvider.DocumentProviderOperation#getSchedulingRule()
         */
        public ISchedulingRule getSchedulingRule() {
          if (info.fElement instanceof IFileEditorInput) {
            IFileEditorInput input= (IFileEditorInput) info.fElement;
            return fResourceRuleFactory.validateEditRule(new IResource[] { input.getFile() });
          }
          return null;
        }
      };
      executeOperation(operation, getProgressMonitor());
    } else
      ((IDocumentProviderExtension) getParentProvider()).validateState(element, computationContext);
  }

  /*
   * @see org.eclipse.ui.texteditor.IDocumentProviderExtension#isStateValidated(java.lang.Object)
   */
  public boolean isStateValidated(Object element) {
    FileInfo info= (FileInfo) fFileInfoMap.get(element);
    if (info != null)
      return info.fTextFileBuffer.isStateValidated();
    return ((IDocumentProviderExtension) getParentProvider()).isStateValidated(element);
  }

  /*
   * @see org.eclipse.ui.texteditor.IDocumentProviderExtension#updateStateCache(java.lang.Object)
   */
  public void updateStateCache(Object element) throws CoreException {
    FileInfo info= (FileInfo) fFileInfoMap.get(element);
    if (info != null) {
      boolean isReadOnly= isSystemFileReadOnly(info);
      // See http://bugs.eclipse.org/bugs/show_bug.cgi?id=14469 for the dirty bit check
      // See https://bugs.eclipse.org/bugs/show_bug.cgi?id=50699 for commenting that out
      if (!info.fCachedReadOnlyState && isReadOnly /*&& !info.fTextFileBuffer.isDirty()*/)
        info.fTextFileBuffer.resetStateValidation();
      info.fCachedReadOnlyState= isReadOnly;
    } else {
      ((IDocumentProviderExtension) getParentProvider()).updateStateCache(element);
    }
  }

  /*
   * @see org.eclipse.ui.texteditor.IDocumentProviderExtension#setCanSaveDocument(java.lang.Object)
   */
  public void setCanSaveDocument(Object element) {
    FileInfo info= (FileInfo) fFileInfoMap.get(element);
    if (info == null)
      ((IDocumentProviderExtension) getParentProvider()).setCanSaveDocument(element);
  }

  /*
   * @see org.eclipse.ui.texteditor.IDocumentProviderExtension#getStatus(java.lang.Object)
   */
  public IStatus getStatus(Object element) {
    FileInfo info= (FileInfo) fFileInfoMap.get(element);
    if (info == null)
      return ((IDocumentProviderExtension) getParentProvider()).getStatus(element);

    IStatus status= info.fTextFileBuffer.getStatus();

//    if (status.getCode() == IResourceStatus.OUT_OF_SYNC_LOCAL) {
//      String message= status.getMessage();
//      IBindingService bindingService= (IBindingService)PlatformUI.getWorkbench().getService(IBindingService.class);
//      String keySequence= bindingService.getBestActiveBindingFormattedFor(IWorkbenchCommandConstants.FILE_REFRESH);
//      if (keySequence != null)
//        message= message + NLSUtility.format(TextEditorMessages.TextFileDocumentProvider_error_outOfSyncHintWithKeyBinding, keySequence);
//      else
//        message= message + TextEditorMessages.TextFileDocumentProvider_error_outOfSyncHint;
//      return new Status(status.getSeverity(), status.getPlugin(), status.getCode(), message, status.getException());
//    }
//
//    // Ensure that we don't open an empty document for an non-existent IFile
//    if (status.getSeverity() != IStatus.ERROR && element instanceof IFileEditorInput) {
//      IFile file= FileBuffers.getWorkspaceFileAtLocation(info.fTextFileBuffer.getLocation());
//      if (file == null || !file.exists()) {
//        String message= NLSUtility.format(TextEditorMessages.TextFileDocumentProvider_error_doesNotExist, ((IFileEditorInput)element).getFile().getFullPath());
//        return new Status(IStatus.ERROR, EditorsUI.PLUGIN_ID, IResourceStatus.RESOURCE_NOT_FOUND, message, null);
//      }
//    }

    return status;
  }

  /*
   * @see org.eclipse.ui.texteditor.IDocumentProviderExtension#synchronize(java.lang.Object)
   */
  public void synchronize(Object element) throws CoreException {
    final FileInfo info= (FileInfo) fFileInfoMap.get(element);
    if (info != null) {
      DocumentProviderOperation operation= new DocumentProviderOperation() {
        /*
         * @see org.eclipse.ui.editors.text.TextFileDocumentProvider.DocumentProviderOperation#execute(org.eclipse.core.runtime.IProgressMonitor)
         */
        protected void execute(IProgressMonitor monitor) throws CoreException {
          info.fTextFileBuffer.revert(monitor);
        }
        /*
         * @see org.eclipse.ui.editors.text.TextFileDocumentProvider.DocumentProviderOperation#getSchedulingRule()
         */
        public ISchedulingRule getSchedulingRule() {
          if (info.fElement instanceof IFileEditorInput) {
            IFileEditorInput input= (IFileEditorInput) info.fElement;
            return fResourceRuleFactory.refreshRule(input.getFile());
          }
          return null;
        }
      };
      executeOperation(operation, getProgressMonitor());
    } else {
      ((IDocumentProviderExtension) getParentProvider()).synchronize(element);
    }
  }

  /*
   * @see org.eclipse.ui.texteditor.IDocumentProviderExtension2#setProgressMonitor(org.eclipse.core.runtime.IProgressMonitor)
   */
  public void setProgressMonitor(IProgressMonitor progressMonitor) {
    fProgressMonitor= progressMonitor;
    ((IDocumentProviderExtension2) getParentProvider()).setProgressMonitor(progressMonitor);
  }

  /*
   * @see org.eclipse.ui.texteditor.IDocumentProviderExtension2#getProgressMonitor()
   */
  public IProgressMonitor getProgressMonitor() {
    return fProgressMonitor;
  }

  /*
   * @see org.eclipse.ui.texteditor.IDocumentProviderExtension3#isSynchronized(java.lang.Object)
   */
  public boolean isSynchronized(Object element) {
    FileInfo info= (FileInfo) fFileInfoMap.get(element);
    if (info != null)
      return info.fTextFileBuffer.isSynchronized();
    return ((IDocumentProviderExtension3) getParentProvider()).isSynchronized(element);
  }

  /*
   * @see org.eclipse.ui.texteditor.IDocumentProviderExtension5#isNotSynchronizedException(Object, CoreException)
   * @since 3.2
   */
  public boolean isNotSynchronizedException(Object element, CoreException ex) {
    IStatus status= ex.getStatus();
    if (status == null || status instanceof MultiStatus)
      return false;

    if (status.getException() != null)
      return false;

    return status.getCode() == IResourceStatus.OUT_OF_SYNC_LOCAL;
  }

  /*
   * @see org.eclipse.ui.editors.text.IStorageDocumentProvider#getDefaultEncoding()
   */
  public String getDefaultEncoding() {
    return FileBuffers.getTextFileBufferManager().getDefaultEncoding();
  }

  /*
   * @see org.eclipse.ui.editors.text.IStorageDocumentProvider#getEncoding(java.lang.Object)
   */
  public String getEncoding(Object element) {
    FileInfo info= (FileInfo) fFileInfoMap.get(element);
    if (info != null)
      return info.fTextFileBuffer.getEncoding();
    return ((IStorageDocumentProvider) getParentProvider()).getEncoding(element);
  }

  /*
   * @see org.eclipse.ui.editors.text.IStorageDocumentProvider#setEncoding(java.lang.Object, java.lang.String)
   */
  public void setEncoding(Object element, String encoding) {
    FileInfo info= (FileInfo) fFileInfoMap.get(element);
    if (info != null)
      info.fTextFileBuffer.setEncoding(encoding);
    else
      ((IStorageDocumentProvider) getParentProvider()).setEncoding(element, encoding);
  }

  /*
   * @see org.eclipse.ui.texteditor.IDocumentProviderExtension4#getContentType(java.lang.Object)
   * @since 3.1
   */
  public IContentType getContentType(Object element) throws CoreException {
    FileInfo info= (FileInfo) fFileInfoMap.get(element);
    if (info != null)
      return info.fTextFileBuffer.getContentType();
    IDocumentProvider parent= getParentProvider();
    if (parent instanceof IDocumentProviderExtension4)
      return ((IDocumentProviderExtension4) parent).getContentType(element);
    return null;
  }

  /**
   * 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
   */
  protected void handleCoreException(CoreException exception, String message) {
    Bundle bundle = Platform.getBundle(TextEditorPlugin.PLUGIN_ID);
    ILog log= Platform.getLog(bundle);
    IStatus status= message != null ? new Status(IStatus.ERROR, TextEditorPlugin.PLUGIN_ID, IStatus.OK, message, exception) : exception.getStatus();
    log.log(status);
  }

  /**
   * Returns the file store denoted by the given info.
   *
   * @param info the element's file info object
   * @return the {@link IFileStore} for the given file info
   * @since 3.2
   */
  protected IFileStore getFileStore(FileInfo info)  {
    return info.fTextFileBuffer.getFileStore();
  }

  /**
   * Returns the system file denoted by the given info.
   *
   * @param info the element's file info object
   * @return the system file for the given file info
   * @deprecated As of 3.2, replaced by {@link #getFileStore(org.eclipse.ui.editors.text.TextFileDocumentProvider.FileInfo)}
   */
  protected File getSystemFile(FileInfo info)  {
    IPath path= info.fTextFileBuffer.getLocation();
    return FileBuffers.getSystemFileAtLocation(path);
  }

  /**
   * Returns whether the system file denoted by
   * the given info is read-only.
   *
   * @param info the element's file info object
   * @return <code>true</code> iff read-only
   */
  protected boolean isSystemFileReadOnly(FileInfo info)  {
    IFileStore fileStore= getFileStore(info);
    if (fileStore == null)
      return false;
    IFileInfo fileInfo= fileStore.fetchInfo();
    return fileInfo.exists() && fileInfo.getAttribute(EFS.ATTRIBUTE_READ_ONLY);
  }

  /**
   * Returns the file info object for the given element.
   *
   * @param element the element
   * @return the file info object, or <code>null</code> if none
   */
  protected FileInfo getFileInfo(Object element)  {
    return (FileInfo) fFileInfoMap.get(element);
  }

  /**
   * Returns an iterator over the elements connected via this document provider.
   *
   * @return an iterator over the list of elements (element type: {@link java.lang.Object})
   */
  protected Iterator getConnectedElementsIterator()  {
    return new HashSet(fFileInfoMap.keySet()).iterator();
  }

  /**
   * Returns an iterator over this document provider's file info objects.
   *
   * @return the iterator over list of file info objects (element type: {@link TextFileDocumentProvider.FileInfo})
   */
  protected Iterator getFileInfosIterator()  {
    return new ArrayList(fFileInfoMap.values()).iterator();
  }

  /**
   * Informs all registered element state listeners
   * about the current state change of the element.
   *
   * @param element the element
   * @see IElementStateListenerExtension#elementStateChanging(Object)
   */
  protected void fireElementStateChanging(Object element) {
    List list= new ArrayList(fElementStateListeners);
    Iterator e= list.iterator();
    while (e.hasNext()) {
      Object l= e.next();
      if (l instanceof IElementStateListenerExtension) {
        IElementStateListenerExtension x= (IElementStateListenerExtension) l;
        x.elementStateChanging(element);
      }
    }
  }

  /**
   * Informs all registered element state listeners
   * about the failed state change of the element.
   *
   * @param element the element
   * @see IElementStateListenerExtension#elementStateChangeFailed(Object)
   */
  protected void fireElementStateChangeFailed(Object element) {
    List list= new ArrayList(fElementStateListeners);
    Iterator e= list.iterator();
    while (e.hasNext()) {
      Object l= e.next();
      if (l instanceof IElementStateListenerExtension) {
        IElementStateListenerExtension x= (IElementStateListenerExtension) l;
        x.elementStateChangeFailed(element);
      }
    }
  }

  /**
   * Computes the scheduling rule needed to create or modify a resource. If
   * the resource exists, its modify rule is returned. If it does not, the
   * resource hierarchy is iterated towards the workspace root to find the
   * first parent of <code>toCreateOrModify</code> that exists. Then the
   * 'create' rule for the last non-existing resource is returned.
   *
   * @param toCreateOrModify the resource to create or modify
   * @return the minimal scheduling rule needed to modify or create a resource
   * @since 3.1
   */
  protected ISchedulingRule computeSchedulingRule(IResource toCreateOrModify) {
    if (toCreateOrModify.exists())
      return fResourceRuleFactory.modifyRule(toCreateOrModify);

    IResource parent= toCreateOrModify;
    do {
      toCreateOrModify= parent;
      parent= toCreateOrModify.getParent();
    } while (parent != null && !parent.exists());

    return fResourceRuleFactory.createRule(toCreateOrModify);
  }
}
TOP

Related Classes of at.bestsolution.efxclipse.text.editor.TextFileDocumentProvider

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.