/*
   * @see org.eclipse.core.internal.filebuffers.textmanipulation.IFileBufferOperation#run(org.eclipse.core.filebuffers.IFileBuffer, org.eclipse.core.runtime.IProgressMonitor)
   */
  public void run(IFileBuffer fileBuffer, IProgressMonitor progressMonitor)
      throws CoreException, OperationCanceledException {

    if (fileBuffer instanceof ITextFileBuffer) {
      ITextFileBuffer textFileBuffer = (ITextFileBuffer) fileBuffer;
      IPath path = textFileBuffer.getLocation();
      String taskName = path == null ? getOperationName() : path.lastSegment();
      progressMonitor = Progress.getMonitor(progressMonitor);
      progressMonitor.beginTask(taskName, 100);
      try {
        IProgressMonitor subMonitor = Progress.getSubMonitor(progressMonitor, 10);
        MultiTextEditWithProgress edit = computeTextEdit(textFileBuffer, subMonitor);
        subMonitor.done();
        if (edit != null) {
          Object stateData = startRewriteSession(textFileBuffer);
          try {
            subMonitor = Progress.getSubMonitor(progressMonitor, 90);
            applyTextEdit(textFileBuffer, edit, subMonitor);
            subMonitor.done();
          } finally {
            stopRewriteSession(textFileBuffer, stateData);
          }
        }
      } finally {
        progressMonitor.done();
      }
    }
  }
    protected MultiTextEditWithProgress computeTextEdit(
        ITextFileBuffer textFileBuffer, IProgressMonitor progressMonitor)
        throws CoreException, OperationCanceledException {

      IResource bufferRes =
          ResourcesPlugin.getWorkspace().getRoot().findMember(textFileBuffer.getLocation());
      Map<?, ?> options = null;
      if (bufferRes != null) {
        IJavaProject project = JavaCore.create(bufferRes.getProject());
        options = project.getOptions(true);
      }

      CodeFormatter codeFormatter = ToolFactory.createCodeFormatter(options);

      IDocument document = textFileBuffer.getDocument();
      String string = document.get();
      TextEdit edit =
          codeFormatter.format(
              CodeFormatter.K_COMPILATION_UNIT, string, 0, string.length(), 0, null);
      MultiTextEditWithProgress multiTextEditWithProgress =
          new MultiTextEditWithProgress(getOperationName());
      if (edit == null) {
        // HibernateConsolePlugin.getDefault().log("empty format for " +
        // textFileBuffer.getLocation().toOSString());
      } else {
        multiTextEditWithProgress.addChild(edit);
      }
      return multiTextEditWithProgress;
    }
  private IHyperlink openModule(Node current, ITextViewer textViewer, int offset) {
    while (current != null && !(current instanceof Element)) {
      current = current.getParentNode();
    }
    if (current == null) {
      return null;
    }
    String pathUp = XmlUtils.pathUp(current, 2);
    if (!"modules/module".equals(pathUp)) { // $NON-NLS-1$
      // just in case we are in some random plugin configuration snippet..
      return null;
    }

    ITextFileBuffer buf =
        FileBuffers.getTextFileBufferManager().getTextFileBuffer(textViewer.getDocument());
    if (buf == null) {
      // for repository based poms..
      return null;
    }
    IFileStore folder = buf.getFileStore().getParent();

    String path = XmlUtils.getTextValue(current);
    final String fPath = path;
    // construct IPath for the child pom file, handle relative paths..
    while (folder != null && path.startsWith("../")) { // $NON-NLS-1$
      folder = folder.getParent();
      path = path.substring("../".length()); // $NON-NLS-1$
    }
    if (folder == null) {
      return null;
    }
    IFileStore modulePom = folder.getChild(path);
    if (!modulePom.getName().endsWith("xml")) { // $NON-NLS-1$
      modulePom = modulePom.getChild("pom.xml"); // $NON-NLS-1$
    }
    final IFileStore fileStore = modulePom;
    if (!fileStore.fetchInfo().exists()) {
      return null;
    }
    assert current instanceof IndexedRegion;
    final IndexedRegion region = (IndexedRegion) current;

    return new IHyperlink() {
      public IRegion getHyperlinkRegion() {
        return new Region(region.getStartOffset(), region.getEndOffset() - region.getStartOffset());
      }

      public String getHyperlinkText() {
        return NLS.bind(Messages.PomHyperlinkDetector_open_module, fPath);
      }

      public String getTypeLabel() {
        return "pom-module"; //$NON-NLS-1$
      }

      public void open() {
        openXmlEditor(fileStore);
      }
    };
  }
  /* (non-Javadoc)
   * @see org.eclipse.ui.texteditor.AbstractDocumentProvider#doSaveDocument(org.eclipse.core.runtime.IProgressMonitor, java.lang.Object, org.eclipse.jface.text.IDocument, boolean)
   * tau 21.03.2005
   */
  protected void doSaveDocument(
      IProgressMonitor monitor, Object element, IDocument document, boolean overwrite)
      throws CoreException {

    if (element instanceof IFileEditorInput) {
      doSaveFileResource(monitor, element, document, overwrite);
    } else if (element instanceof IAdaptable) {
      // reuses code from TextFileDocumentProvider to handle external files (195615)
      // TODO consider converting the super class to TextFileDocumentProvider
      IAdaptable adaptable = (IAdaptable) element;

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

      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) {
          locationKind = LocationKind.NORMALIZE;
          manager.connect(location, locationKind, getProgressMonitor());
          fileBuffer = manager.getTextFileBuffer(location, locationKind);
        }
      }

      if (fileBuffer != null) {
        fileBuffer.getDocument().set(document.get());
        fileBuffer.commit(null, true);
      }
    }

    // tau 21.03.05
    // First attempt show Message Connection through SQLScrapbookEditorInput
    if (element instanceof SQLScrapbookEditorInput)
      ((SQLScrapbookEditorInput) element).showMessageConnection();
    // Second attempt show Message Connection through sqlEditor
    IEditorPart editor =
        PlatformUI.getWorkbench()
            .getActiveWorkbenchWindow()
            .getActivePage()
            .findEditor((IEditorInput) element);
    if ((editor != null) && (editor instanceof SQLEditor)) {
      ((SQLEditor) editor).refreshConnectionStatus();
    }
  }
  private InputStream createInputStream(IFile propertiesFile) throws CoreException {
    ITextFileBufferManager manager = FileBuffers.getTextFileBufferManager();
    if (manager != null) {
      ITextFileBuffer buffer =
          manager.getTextFileBuffer(propertiesFile.getFullPath(), LocationKind.IFILE);
      if (buffer != null) {
        return new ByteArrayInputStream(buffer.getDocument().get().getBytes());
      }
    }

    return propertiesFile.getContents();
  }
Example #6
0
 public static IDocument getDocFromFile(IFile file) {
   IPath path = file.getFullPath();
   ITextFileBufferManager mgr = FileBuffers.getTextFileBufferManager();
   try {
     mgr.connect(path, LocationKind.IFILE, null);
   } catch (CoreException e) {
     e.printStackTrace();
     return null;
   }
   ITextFileBuffer buf = mgr.getTextFileBuffer(path, LocationKind.IFILE);
   return buf.getDocument();
 }
 protected static void saveFileIfNeeded(IFile file, IProgressMonitor pm) throws CoreException {
   ITextFileBuffer buffer =
       FileBuffers.getTextFileBufferManager()
           .getTextFileBuffer(file.getFullPath(), LocationKind.IFILE);
   if (buffer != null
       && buffer.isDirty()
       && buffer.isStateValidated()
       && buffer.isSynchronized()) {
     pm.beginTask("", 2); // $NON-NLS-1$
     buffer.commit(new SubProgressMonitor(pm, 1), false);
     file.refreshLocal(IResource.DEPTH_ONE, new SubProgressMonitor(pm, 1));
   }
   pm.done();
 }
 public boolean isContainerDirty(TypeNameMatch match) {
   ICompilationUnit cu = match.getType().getCompilationUnit();
   if (cu == null) {
     return false;
   }
   IResource resource = cu.getResource();
   ITextFileBufferManager manager = FileBuffers.getTextFileBufferManager();
   ITextFileBuffer textFileBuffer =
       manager.getTextFileBuffer(resource.getFullPath(), LocationKind.IFILE);
   if (textFileBuffer != null) {
     return textFileBuffer.isDirty();
   }
   return false;
 }
  public void testSingleNonUIThreadUpdatesToEditorDocument() throws Exception {
    IFile file = getOrCreateFile(PROJECT_NAME + "/" + "testBackgroundChanges.xml");
    ITextFileBufferManager textFileBufferManager = FileBuffers.getTextFileBufferManager();
    textFileBufferManager.connect(
        file.getFullPath(), LocationKind.IFILE, new NullProgressMonitor());

    ITextFileBuffer textFileBuffer =
        textFileBufferManager.getTextFileBuffer(file.getFullPath(), LocationKind.IFILE);
    final IDocument document = textFileBuffer.getDocument();
    document.replace(0, 0, "<?xml encoding=\"UTF-8\" version=\"1.0\"?>\n");
    textFileBuffer.commit(new NullProgressMonitor(), true);

    String testText = document.get() + "<c/><b/><a/>";
    final int end = document.getLength();
    IWorkbenchPage activePage =
        PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
    IEditorPart openedEditor = IDE.openEditor(activePage, file);

    final boolean state[] = new boolean[] {false};
    Job changer =
        new Job("text changer") {
          protected IStatus run(IProgressMonitor monitor) {
            try {
              document.replace(end, 0, "<a/>");
              document.replace(end, 0, "<b/>");
              document.replace(end, 0, "<c/>");
            } catch (Exception e) {
              return new Status(IStatus.ERROR, SSEUIPlugin.ID, e.getMessage());
            } finally {
              state[0] = true;
            }
            return Status.OK_STATUS;
          }
        };
    changer.setUser(true);
    changer.setSystem(false);
    changer.schedule();

    while (!state[0]) {
      openedEditor.getSite().getShell().getDisplay().readAndDispatch();
    }

    String finalText = document.get();
    textFileBuffer.commit(new NullProgressMonitor(), true);
    textFileBufferManager.disconnect(
        file.getFullPath(), LocationKind.IFILE, new NullProgressMonitor());
    activePage.closeEditor(openedEditor, false);
    assertEquals("Non-UI changes did not apply", testText, finalText);
  }
Example #10
0
 public long getModificationStamp(IResource resource) {
   if (!(resource instanceof IFile)) return resource.getModificationStamp();
   IFile file = (IFile) resource;
   ITextFileBuffer buffer = getBuffer(file);
   if (buffer == null) {
     return file.getModificationStamp();
   } else {
     IDocument document = buffer.getDocument();
     if (document instanceof IDocumentExtension4) {
       return ((IDocumentExtension4) document).getModificationStamp();
     } else {
       return file.getModificationStamp();
     }
   }
 }
 private void checkDirtyFile(RefactoringStatus result, IFile file) {
   if (!file.exists()) return;
   ITextFileBuffer buffer =
       FileBuffers.getTextFileBufferManager()
           .getTextFileBuffer(file.getFullPath(), LocationKind.IFILE);
   if (buffer != null && buffer.isDirty()) {
     String message = RefactoringCoreMessages.DeleteResourcesProcessor_warning_unsaved_file;
     if (buffer.isStateValidated() && buffer.isSynchronized()) {
       result.addWarning(
           Messages.format(message, BasicElementLabels.getPathLabel(file.getFullPath(), false)));
     } else {
       result.addFatalError(
           Messages.format(message, BasicElementLabels.getPathLabel(file.getFullPath(), false)));
     }
   }
 }
Example #12
0
 private void initializeFile(IFile file) {
   fTextFileBuffer = getBuffer(file);
   if (fTextFileBuffer == null) {
     initializeResource(file);
   } else {
     IDocument document = fTextFileBuffer.getDocument();
     fDirty = fTextFileBuffer.isDirty();
     fReadOnly = isReadOnly(file);
     if (document instanceof IDocumentExtension4) {
       fKind = DOCUMENT;
       fModificationStamp = ((IDocumentExtension4) document).getModificationStamp();
     } else {
       fKind = RESOURCE;
       fModificationStamp = file.getModificationStamp();
     }
   }
 }
 private void stopRewriteSession(ITextFileBuffer fileBuffer, Object stateData) {
   IDocument document = fileBuffer.getDocument();
   if (document instanceof IDocumentExtension4) {
     IDocumentExtension4 extension = (IDocumentExtension4) document;
     extension.stopRewriteSession(fDocumentRewriteSession);
     fDocumentRewriteSession = null;
   } else if (stateData instanceof Map)
     TextUtilities.addDocumentPartitioners(document, (Map) stateData);
 }
 private static TextChange addTextEditFromRewrite(
     TextChangeManager manager, ICompilationUnit cu, ASTRewrite rewrite) throws CoreException {
   try {
     ITextFileBuffer buffer = RefactoringFileBuffers.acquire(cu);
     TextEdit resultingEdits =
         rewrite.rewriteAST(buffer.getDocument(), cu.getJavaProject().getOptions(true));
     TextChange textChange = manager.get(cu);
     if (textChange instanceof TextFileChange) {
       TextFileChange tfc = (TextFileChange) textChange;
       tfc.setSaveMode(TextFileChange.KEEP_SAVE_STATE);
     }
     String message = RefactoringCoreMessages.DeleteChangeCreator_1;
     TextChangeCompatibility.addTextEdit(textChange, message, resultingEdits);
     return textChange;
   } finally {
     RefactoringFileBuffers.release(cu);
   }
 }
Example #15
0
 public void checkDirty(RefactoringStatus status, long stampToMatch, IProgressMonitor pm)
     throws CoreException {
   if (fDirty) {
     if (fKind == DOCUMENT && fTextFileBuffer != null && stampToMatch == fModificationStamp) {
       fTextFileBuffer.commit(pm, false);
     } else {
       status.addFatalError(
           StringUtils.format("Resource %s is unsaved", fResource.getFullPath()));
     }
   }
 }
  private Object startRewriteSession(ITextFileBuffer fileBuffer) {
    Object stateData = null;

    IDocument document = fileBuffer.getDocument();
    if (document instanceof IDocumentExtension4) {
      IDocumentExtension4 extension = (IDocumentExtension4) document;
      fDocumentRewriteSession = extension.startRewriteSession(getDocumentRewriteSessionType());
    } else stateData = TextUtilities.removeDocumentPartitioners(document);

    return stateData;
  }
Example #17
0
 /**
  * what is this method supposed to do? for the sourceViewer find the associated file on disk and
  * for that one find the IProject it belongs to. The required condition for the IProject instance
  * is that project relative path of the file shall only be pom.xml (thus no nested, unopened maven
  * pom). So that when MavenPlugin.getMavenProjectManager().getProject(prj); is called later on the
  * instance, it actually returns the maven model facade for the pom.xml backing the sourceViewer.
  *
  * @param sourceViewer
  * @return
  */
 public static IProject extractProject(ITextViewer sourceViewer) {
   ITextFileBuffer buf =
       FileBuffers.getTextFileBufferManager().getTextFileBuffer(sourceViewer.getDocument());
   if (buf == null) {
     // eg. for viewers of pom files in local repository
     return null;
   }
   IFileStore folder = buf.getFileStore();
   File file = new File(folder.toURI());
   IPath path = Path.fromOSString(file.getAbsolutePath());
   Stack<IFile> stack = new Stack<IFile>();
   // here we need to find the most inner project to the path.
   // we do so by shortening the path and remembering all the resources identified.
   // at the end we pick the last one from the stack. is there a catch to it?
   IFile ifile = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(path);
   if (ifile != null) {
     stack.push(ifile);
   }
   while (path.segmentCount() > 1) {
     IResource ires = ResourcesPlugin.getWorkspace().getRoot().findMember(path);
     if (ires != null && ires instanceof IFile) {
       stack.push((IFile) ires);
     }
     path = path.removeFirstSegments(1);
   }
   IFile res = stack.empty() ? null : stack.pop();
   if (res != null) {
     IProject prj = res.getProject();
     // the project returned is in a way unrelated to nested child poms that don't have an opened
     // project,
     // in that case we pass along a wrong parent/aggregator
     if (res.getProjectRelativePath().segmentCount() != 1) {
       // if the project were the pom's project, the relative path would be just "pom.xml", if it's
       // not just throw it out of the window..
       prj = null;
     }
     return prj;
   }
   return null;
 }
 /**
  * Adds the specified tag to the source member defined by the member name and signature
  *
  * @param unit
  * @param membername
  * @param signature
  * @param tagname
  * @param remove
  * @throws CoreException
  * @throws MalformedTreeException
  * @throws BadLocationException
  */
 private void updateTagInSource(
     ICompilationUnit unit, String membername, String signature, String tagname, boolean remove)
     throws CoreException, MalformedTreeException, BadLocationException {
   ASTParser parser = ASTParser.newParser(AST.JLS4);
   parser.setSource(unit);
   CompilationUnit cunit = (CompilationUnit) parser.createAST(new NullProgressMonitor());
   assertNotNull("the ast compilation unit cannot be null", cunit);
   cunit.recordModifications();
   ASTRewrite rewrite = ASTRewrite.create(cunit.getAST());
   cunit.accept(new SourceChangeVisitor(membername, signature, tagname, remove, rewrite));
   ITextFileBufferManager bm = FileBuffers.getTextFileBufferManager();
   IPath path = cunit.getJavaElement().getPath();
   try {
     bm.connect(path, LocationKind.IFILE, null);
     ITextFileBuffer tfb = bm.getTextFileBuffer(path, LocationKind.IFILE);
     IDocument document = tfb.getDocument();
     TextEdit edits = rewrite.rewriteAST(document, null);
     edits.apply(document);
     tfb.commit(new NullProgressMonitor(), true);
   } finally {
     bm.disconnect(path, LocationKind.IFILE, null);
   }
 }
 private void applyTextEdit(
     ITextFileBuffer fileBuffer,
     MultiTextEditWithProgress textEdit,
     IProgressMonitor progressMonitor)
     throws CoreException, OperationCanceledException {
   try {
     textEdit.apply(fileBuffer.getDocument(), TextEdit.NONE, progressMonitor);
   } catch (BadLocationException x) {
     throw new CoreException(
         new Status(
             IStatus.ERROR,
             FileBuffersPlugin.PLUGIN_ID,
             IFileBufferStatusCodes.CONTENT_CHANGE_FAILED,
             "",
             x)); //$NON-NLS-1$
   }
 }
  /*
   * @see org.eclipse.core.internal.filebuffers.textmanipulation.TextFileBufferOperation#computeTextEdit(org.eclipse.core.filebuffers.ITextFileBuffer, org.eclipse.core.runtime.IProgressMonitor)
   */
  protected MultiTextEditWithProgress computeTextEdit(
      ITextFileBuffer fileBuffer, IProgressMonitor progressMonitor) throws CoreException {
    IDocument document = fileBuffer.getDocument();
    int lineCount = document.getNumberOfLines();

    progressMonitor = Progress.getMonitor(progressMonitor);
    progressMonitor.beginTask(
        FileBuffersMessages.RemoveTrailingWhitespaceOperation_task_generatingChanges, lineCount);
    try {

      MultiTextEditWithProgress multiEdit =
          new MultiTextEditWithProgress(
              FileBuffersMessages.RemoveTrailingWhitespaceOperation_task_applyingChanges);

      for (int i = 0; i < lineCount; i++) {
        if (progressMonitor.isCanceled()) throw new OperationCanceledException();

        IRegion region = document.getLineInformation(i);
        if (region.getLength() == 0) continue;

        int lineStart = region.getOffset();
        int lineExclusiveEnd = lineStart + region.getLength();
        int j = lineExclusiveEnd - 1;
        while (j >= lineStart && Character.isWhitespace(document.getChar(j))) --j;
        ++j;
        if (j < lineExclusiveEnd) multiEdit.addChild(new DeleteEdit(j, lineExclusiveEnd - j));
        progressMonitor.worked(1);
      }

      return multiEdit.getChildrenSize() <= 0 ? null : multiEdit;

    } catch (BadLocationException x) {
      throw new CoreException(
          new Status(
              IStatus.ERROR,
              FileBuffersPlugin.PLUGIN_ID,
              IFileBufferStatusCodes.CONTENT_CHANGE_FAILED,
              "",
              x)); //$NON-NLS-1$
    } finally {
      progressMonitor.done();
    }
  }
  /**
   * Note: This test takes a while to run, but it's testing scalability after all.
   *
   * @throws Exception
   */
  public void testManyNonUIThreadsUpdatingEditorDocument() throws Exception {
    final int numberOfJobs = 30;
    /** 15 minute timeout before we stop waiting for the change jobs to complete */
    long timeout = 15 * 60 * 1000;

    long startTime = System.currentTimeMillis();
    IFile file = getOrCreateFile(PROJECT_NAME + "/" + "testManyBackgroundChanges.xml");
    ITextFileBufferManager textFileBufferManager = FileBuffers.getTextFileBufferManager();
    textFileBufferManager.connect(
        file.getFullPath(), LocationKind.IFILE, new NullProgressMonitor());

    ITextFileBuffer textFileBuffer =
        textFileBufferManager.getTextFileBuffer(file.getFullPath(), LocationKind.IFILE);
    final IDocument document = textFileBuffer.getDocument();
    document.replace(0, 0, "<?xml encoding=\"UTF-8\" version=\"1.0\"?>\n");
    textFileBuffer.commit(new NullProgressMonitor(), true);

    final int insertionPoint = document.getLength();
    final char names[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
    // numberOfJobs Jobs, inserting 26 tags, each 4 characters long
    int expectedLength = insertionPoint + numberOfJobs * 4 * names.length;
    IWorkbenchPage activePage =
        PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
    activePage.showView(IPageLayout.ID_PROGRESS_VIEW);
    IEditorPart openedEditor = IDE.openEditor(activePage, file);

    final int finished[] = new int[] {numberOfJobs};
    Job changers[] = new Job[numberOfJobs];
    for (int i = 0; i < changers.length; i++) {
      changers[i] =
          new Job("Text Changer " + Integer.toString(i)) {
            protected IStatus run(IProgressMonitor monitor) {
              try {
                for (int j = 0; j < names.length; j++) {
                  document.replace(insertionPoint + 4 * j, 0, "<" + names[j] + "/>");
                }
              } catch (Exception e) {
                return new Status(IStatus.ERROR, SSEUIPlugin.ID, e.getMessage());
              } finally {
                finished[0]--;
              }
              return Status.OK_STATUS;
            }
          };
      changers[i].setUser(true);
      changers[i].setSystem(false);
    }
    for (int i = 0; i < changers.length; i++) {
      changers[i].schedule();
    }

    long runtime = 0;
    while (finished[0] > 0 && (runtime = System.currentTimeMillis()) - startTime < timeout) {
      openedEditor.getSite().getShell().getDisplay().readAndDispatch();
    }
    assertTrue("Test timed out: (" + timeout + " was allowed)", runtime - startTime < timeout);

    int finalLength = document.getLength();
    textFileBuffer.commit(new NullProgressMonitor(), true);
    textFileBufferManager.disconnect(
        file.getFullPath(), LocationKind.IFILE, new NullProgressMonitor());
    activePage.closeEditor(openedEditor, false);
    assertEquals("Some non-UI changes did not apply", expectedLength, finalLength);
  }
  /**
   * This validate call is for the ISourceValidator partial document validation approach
   *
   * @param dirtyRegion
   * @param helper
   * @param reporter
   * @see org.eclipse.wst.sse.ui.internal.reconcile.validator.ISourceValidator
   */
  public void validate(IRegion dirtyRegion, IValidationContext helper, IReporter reporter) {
    if (helper == null || fDocument == null || !fEnableSourceValidation) return;

    if ((reporter != null) && (reporter.isCancelled() == true)) {
      throw new OperationCanceledException();
    }

    IStructuredModel model =
        StructuredModelManager.getModelManager().getExistingModelForRead(fDocument);
    if (model == null) return; // error

    try {

      IDOMDocument document = null;
      if (model instanceof IDOMModel) {
        document = ((IDOMModel) model).getDocument();
      }

      if (document == null || !hasHTMLFeature(document)) return; // ignore

      ITextFileBuffer fb = FileBufferModelManager.getInstance().getBuffer(fDocument);
      if (fb == null) return;

      IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(fb.getLocation());
      if (file == null || !file.exists()) return;

      // this will be the wrong region if it's Text (instead of Element)
      // we don't know how to validate Text
      IndexedRegion ir =
          getCoveringNode(dirtyRegion); // model.getIndexedRegion(dirtyRegion.getOffset());
      if (ir instanceof Text) {
        while (ir != null && ir instanceof Text) {
          // it's assumed that this gets the IndexedRegion to
          // the right of the end offset
          ir = model.getIndexedRegion(ir.getEndOffset());
        }
      }

      if (ir instanceof INodeNotifier) {

        INodeAdapterFactory factory = HTMLValidationAdapterFactory.getInstance();
        ValidationAdapter adapter = (ValidationAdapter) factory.adapt((INodeNotifier) ir);
        if (adapter == null) return; // error

        if (reporter != null) {
          HTMLValidationReporter rep = null;
          rep = getReporter(reporter, file, (IDOMModel) model);
          rep.clear();
          adapter.setReporter(rep);

          Message mess =
              new LocalizedMessage(
                  IMessage.LOW_SEVERITY, file.getFullPath().toString().substring(1));
          reporter.displaySubtask(this, mess);
        }
        adapter.validate(ir);
      }
    } finally {
      if (model != null) model.releaseFromRead();
    }
  }
  public void run(ISelection selection) {

    String errorTitle = CompareMessages.AddFromHistory_title;
    String errorMessage = CompareMessages.AddFromHistory_internalErrorMessage;
    Shell shell = getShell();

    ICompilationUnit cu = null;
    IParent parent = null;
    IMember input = null;

    // analyze selection
    if (selection.isEmpty()) {
      // no selection: we try to use the editor's input
      JavaEditor editor = getEditor();
      if (editor != null) {
        IEditorInput editorInput = editor.getEditorInput();
        IWorkingCopyManager manager = JavaPlugin.getDefault().getWorkingCopyManager();
        if (manager != null) {
          cu = manager.getWorkingCopy(editorInput);
          parent = cu;
        }
      }
    } else {
      input = getEditionElement(selection);
      if (input != null) {
        cu = input.getCompilationUnit();
        parent = input;
        input = null;

      } else {
        if (selection instanceof IStructuredSelection) {
          Object o = ((IStructuredSelection) selection).getFirstElement();
          if (o instanceof ICompilationUnit) {
            cu = (ICompilationUnit) o;
            parent = cu;
          }
        }
      }
    }

    if (parent == null || cu == null) {
      String invalidSelectionMessage = CompareMessages.AddFromHistory_invalidSelectionMessage;
      MessageDialog.openInformation(shell, errorTitle, invalidSelectionMessage);
      return;
    }

    IFile file = getFile(parent);
    if (file == null) {
      MessageDialog.openError(shell, errorTitle, errorMessage);
      return;
    }

    boolean inEditor = beingEdited(file);

    IStatus status = Resources.makeCommittable(file, shell);
    if (!status.isOK()) {
      return;
    }

    // get the document where to insert the text
    IPath path = file.getFullPath();
    ITextFileBufferManager bufferManager = FileBuffers.getTextFileBufferManager();
    ITextFileBuffer textFileBuffer = null;
    try {
      bufferManager.connect(path, LocationKind.IFILE, null);
      textFileBuffer = bufferManager.getTextFileBuffer(path, LocationKind.IFILE);
      IDocument document = textFileBuffer.getDocument();

      // configure EditionSelectionDialog and let user select an edition
      ITypedElement target = new JavaTextBufferNode(file, document, inEditor);
      ITypedElement[] editions = buildEditions(target, file);

      ResourceBundle bundle = ResourceBundle.getBundle(BUNDLE_NAME);
      EditionSelectionDialog d = new EditionSelectionDialog(shell, bundle);
      d.setAddMode(true);
      d.setHelpContextId(IJavaHelpContextIds.ADD_ELEMENT_FROM_HISTORY_DIALOG);
      ITypedElement selected = d.selectEdition(target, editions, parent);
      if (selected == null) return; // user cancel

      ICompilationUnit cu2 = cu;
      if (parent instanceof IMember) cu2 = ((IMember) parent).getCompilationUnit();

      CompilationUnit root = parsePartialCompilationUnit(cu2);
      ASTRewrite rewriter = ASTRewrite.create(root.getAST());

      ITypedElement[] results = d.getSelection();
      for (int i = 0; i < results.length; i++) {

        // create an AST node
        ASTNode newNode =
            createASTNode(
                rewriter,
                results[i],
                TextUtilities.getDefaultLineDelimiter(document),
                cu.getJavaProject());
        if (newNode == null) {
          MessageDialog.openError(shell, errorTitle, errorMessage);
          return;
        }

        // now determine where to put the new node
        if (newNode instanceof PackageDeclaration) {
          rewriter.set(root, CompilationUnit.PACKAGE_PROPERTY, newNode, null);

        } else if (newNode instanceof ImportDeclaration) {
          ListRewrite lw = rewriter.getListRewrite(root, CompilationUnit.IMPORTS_PROPERTY);
          lw.insertFirst(newNode, null);

        } else { // class, interface, enum, annotation, method, field

          if (parent instanceof ICompilationUnit) { // top level
            ListRewrite lw = rewriter.getListRewrite(root, CompilationUnit.TYPES_PROPERTY);
            int index = ASTNodes.getInsertionIndex((BodyDeclaration) newNode, root.types());
            lw.insertAt(newNode, index, null);

          } else if (parent instanceof IType) {
            ASTNode declaration = getBodyContainer(root, (IType) parent);
            if (declaration instanceof TypeDeclaration
                || declaration instanceof AnnotationTypeDeclaration) {
              List container = ASTNodes.getBodyDeclarations(declaration);
              int index = ASTNodes.getInsertionIndex((BodyDeclaration) newNode, container);
              ListRewrite lw =
                  rewriter.getListRewrite(
                      declaration, ASTNodes.getBodyDeclarationsProperty(declaration));
              lw.insertAt(newNode, index, null);
            } else if (declaration instanceof EnumDeclaration) {
              List container = ((EnumDeclaration) declaration).enumConstants();
              int index = ASTNodes.getInsertionIndex((FieldDeclaration) newNode, container);
              ListRewrite lw =
                  rewriter.getListRewrite(declaration, EnumDeclaration.ENUM_CONSTANTS_PROPERTY);
              lw.insertAt(newNode, index, null);
            }
          } else {
            JavaPlugin.logErrorMessage(
                "JavaAddElementFromHistoryImpl: unknown container " + parent); // $NON-NLS-1$
          }
        }
      }

      Map options = null;
      IJavaProject javaProject = cu2.getJavaProject();
      if (javaProject != null) options = javaProject.getOptions(true);
      applyChanges(rewriter, document, textFileBuffer, shell, inEditor, options);

    } catch (InvocationTargetException ex) {
      ExceptionHandler.handle(ex, shell, errorTitle, errorMessage);

    } catch (InterruptedException ex) {
      // shouldn't be called because is not cancelable
      Assert.isTrue(false);

    } catch (CoreException ex) {
      ExceptionHandler.handle(ex, shell, errorTitle, errorMessage);

    } finally {
      try {
        if (textFileBuffer != null) bufferManager.disconnect(path, LocationKind.IFILE, null);
      } catch (CoreException e) {
        JavaPlugin.log(e);
      }
    }
  }
  private void doRunOnMultiple(ICompilationUnit[] cus, MultiStatus status, IProgressMonitor monitor)
      throws OperationCanceledException {
    if (monitor == null) {
      monitor = new NullProgressMonitor();
    }
    monitor.setTaskName("Organizing imports...");

    monitor.beginTask("", cus.length); // $NON-NLS-1$
    try {
      IChooseImportQuery query =
          new IChooseImportQuery() {
            public TypeNameMatch[] chooseImports(
                TypeNameMatch[][] openChoices, ISourceRange[] ranges) {
              throw new OrganizeImportError();
            }
          };
      IJavaProject lastProject = null;

      for (int i = 0; i < cus.length; i++) {
        ICompilationUnit cu = cus[i];
        if (testOnBuildPath(cu, status)) {
          if (lastProject == null || !lastProject.equals(cu.getJavaProject())) {
            lastProject = cu.getJavaProject();
          }
          CodeGenerationSettings settings =
              JavaPreferencesSettings.getCodeGenerationSettings(lastProject);

          String cuLocation = cu.getPath().makeRelative().toString();

          monitor.subTask(cuLocation);

          try {
            boolean save = !cu.isWorkingCopy();
            if (!save) {
              ITextFileBuffer textFileBuffer =
                  FileBuffers.getTextFileBufferManager().getTextFileBuffer(cu.getPath());
              save = textFileBuffer != null && !textFileBuffer.isDirty(); // save when not dirty
            }

            AJOrganizeImportsOperation op =
                new AJOrganizeImportsOperation(
                    cu, null, settings.importIgnoreLowercase, save, true, query);
            runInSync(op, cuLocation, status, monitor);

            IProblem parseError = op.getParseError();
            if (parseError != null) {
              String message =
                  Messages.format(
                      ActionMessages.OrganizeImportsAction_multi_error_parse, cuLocation);
              status.add(new Status(IStatus.INFO, JavaUI.ID_PLUGIN, IStatus.ERROR, message, null));
            }
          } catch (CoreException e) {
            JavaPlugin.log(e);
            String message =
                Messages.format(
                    "{0}: Unexpected error. See log for details.", e.getStatus().getMessage());
            status.add(new Status(IStatus.ERROR, JavaUI.ID_PLUGIN, IStatus.ERROR, message, null));
          }

          if (monitor.isCanceled()) {
            throw new OperationCanceledException();
          }
        }
      }
    } finally {
      monitor.done();
    }
  }