Package it.tref.eclipse.wicket.plugin.editors

Source Code of it.tref.eclipse.wicket.plugin.editors.WicketFunMarkOccurrenceInstaller$OccurrencesFinderJob

package it.tref.eclipse.wicket.plugin.editors;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

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.core.runtime.jobs.Job;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.IBinding;
import org.eclipse.jdt.core.dom.IVariableBinding;
import org.eclipse.jdt.core.dom.Name;
import org.eclipse.jdt.core.dom.NodeFinder;
import org.eclipse.jdt.core.util.IModifierConstants;
import org.eclipse.jdt.internal.ui.JavaPlugin;
import org.eclipse.jdt.internal.ui.javaeditor.EditorUtility;
import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor;
import org.eclipse.jdt.internal.ui.search.BreakContinueTargetFinder;
import org.eclipse.jdt.internal.ui.search.ExceptionOccurrencesFinder;
import org.eclipse.jdt.internal.ui.search.IOccurrencesFinder.OccurrenceLocation;
import org.eclipse.jdt.internal.ui.search.ImplementOccurrencesFinder;
import org.eclipse.jdt.internal.ui.search.MethodExitsFinder;
import org.eclipse.jdt.internal.ui.search.OccurrencesFinder;
import org.eclipse.jdt.internal.ui.text.JavaWordFinder;
import org.eclipse.jdt.internal.ui.viewsupport.ISelectionListenerWithAST;
import org.eclipse.jdt.ui.SharedASTProvider;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentExtension4;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ISelectionValidator;
import org.eclipse.jface.text.ISynchronizable;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.link.LinkedModeModel;
import org.eclipse.jface.text.source.Annotation;
import org.eclipse.jface.text.source.IAnnotationModel;
import org.eclipse.jface.text.source.IAnnotationModelExtension;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.texteditor.IDocumentProvider;

@SuppressWarnings("restriction")
public class WicketFunMarkOccurrenceInstaller {
  private ISelection fForcedMarkOccurrencesSelection;
  private IRegion fMarkOccurrenceTargetRegion;
  private OccurrencesFinderJob fOccurrencesFinderJob;
  private Annotation[] fOccurrenceAnnotations;

  private long fMarkOccurrenceModificationStamp;

  private boolean fMarkExceptions = true;
  private boolean fMarkTypeOccurrences = true;
  private boolean fMarkMethodExitPoints = true;
  private boolean fMarkBreakContinueTargets = true;
  private boolean fMarkImplementors = true;
  private boolean fMarkMethodOccurrences = true;
  private boolean fMarkConstantOccurrences = true;
  private boolean fMarkFieldOccurrences = true;
  private boolean fMarkLocalVariableypeOccurrences = true;
  private boolean fStickyOccurrenceAnnotations = false;

  private final JavaEditor editor;
  private ISelectionListenerWithAST fPostSelectionListenerWithAST;

  public WicketFunMarkOccurrenceInstaller(JavaEditor editor) {
    this.editor = editor;
  }

  public void installOccurrencesFinder(boolean forceUpdate) {
    fPostSelectionListenerWithAST = new ISelectionListenerWithAST()
    {
      public void selectionChanged(IEditorPart part, ITextSelection selection, CompilationUnit astRoot)
      {
        if(editor.getViewer() == null)
        {
          SelectionListenerWithASTManager.getDefault().removeListener(editor, fPostSelectionListenerWithAST);
        }
        else
        {
          updateOccurrenceAnnotations(selection, astRoot, editor);
        }
      }
    };

    SelectionListenerWithASTManager.getDefault().addListener(editor,
        fPostSelectionListenerWithAST);
   
    if (forceUpdate && editor.getSelectionProvider() != null) {
      fForcedMarkOccurrencesSelection = editor.getSelectionProvider()
          .getSelection();
      updateOccurrenceAnnotations(
          (ITextSelection) fForcedMarkOccurrencesSelection,
          JavaPlugin
              .getDefault()
              .getASTProvider()
              .getAST(EditorUtility.getEditorInputJavaElement(
                  editor, false), SharedASTProvider.WAIT_YES,
                  null), editor);
    }

    /*
     * if (fOccurrencesFinderJobCanceler == null) {
     * fOccurrencesFinderJobCanceler= new OccurrencesFinderJobCanceler();
     * fOccurrencesFinderJobCanceler.install(); }
     */
  }

  private void updateOccurrenceAnnotations(ITextSelection selection,
      CompilationUnit astRoot, JavaEditor editor) {
    if (fOccurrencesFinderJob != null)
      fOccurrencesFinderJob.cancel();

    /*
     * if (!fMarkOccurrenceAnnotations) return;
     */

    if (astRoot == null || selection == null)
      return;

    IDocument document = editor.getViewer().getDocument();
    if (document == null)
      return;

    if (document instanceof IDocumentExtension4) {
      int offset = selection.getOffset();
      long currentModificationStamp = ((IDocumentExtension4) document)
          .getModificationStamp();
      IRegion markOccurrenceTargetRegion = fMarkOccurrenceTargetRegion;
      if (markOccurrenceTargetRegion != null
          && currentModificationStamp == fMarkOccurrenceModificationStamp) {
        if (markOccurrenceTargetRegion.getOffset() <= offset
            && offset <= markOccurrenceTargetRegion.getOffset()
                + markOccurrenceTargetRegion.getLength())
          return;
      }
      fMarkOccurrenceTargetRegion = JavaWordFinder.findWord(document,
          offset);
      fMarkOccurrenceModificationStamp = currentModificationStamp;
    }

    OccurrenceLocation[] matches = null;

    ASTNode selectedNode = NodeFinder.perform(astRoot,
        selection.getOffset(), selection.getLength());

    if (fMarkExceptions || fMarkTypeOccurrences) {
      ExceptionOccurrencesFinder exceptionFinder = new ExceptionOccurrencesFinder();
      String message = exceptionFinder.initialize(astRoot, selectedNode);
      if (message == null) {
        matches = exceptionFinder.getOccurrences();
        if (!fMarkExceptions && matches != null)
          matches = null;
      }
    }

    if ((matches == null)
        && (fMarkMethodExitPoints || fMarkTypeOccurrences)) {
      MethodExitsFinder finder = new MethodExitsFinder();
      String message = finder.initialize(astRoot, selectedNode);
      if (message == null) {
        matches = finder.getOccurrences();
        if (!fMarkMethodExitPoints && matches != null)
          matches = null;
      }
    }

    if ((matches == null)
        && (fMarkBreakContinueTargets || fMarkTypeOccurrences)) {
      BreakContinueTargetFinder finder = new BreakContinueTargetFinder();
      String message = finder.initialize(astRoot, selectedNode);
      if (message == null) {
        matches = finder.getOccurrences();
        if (!fMarkBreakContinueTargets && matches != null)
          matches = null;
      }
    }

    if ((matches == null) && (fMarkImplementors || fMarkTypeOccurrences)) {
      ImplementOccurrencesFinder finder = new ImplementOccurrencesFinder();
      String message = finder.initialize(astRoot, selectedNode);
      if (message == null) {
        matches = finder.getOccurrences();
        if (!fMarkImplementors && matches != null)
          matches = null;
      }
    }

    if (matches == null) {
      IBinding binding = null;
      if (selectedNode instanceof Name)
        binding = ((Name) selectedNode).resolveBinding();

      if (binding != null && markOccurrencesOfType(binding)) {
        // Find the matches && extract positions so we can forget the
        // AST
        OccurrencesFinder finder = new OccurrencesFinder();
        String message = finder.initialize(astRoot, selectedNode);
        if (message == null)
          matches = finder.getOccurrences();
      }
    }

    if (matches == null || matches.length == 0) {
      if (!fStickyOccurrenceAnnotations)
        removeOccurrenceAnnotations(editor);
      return;
    }

    Position[] positions = new Position[matches.length];
    int i = 0;
    for (int c = 0; c < matches.length; c++) {
      positions[i++] = new Position(matches[c].getOffset(),
          matches[c].getLength());
    }

    fOccurrencesFinderJob = new OccurrencesFinderJob(document, positions,
        selection, editor);
    fOccurrencesFinderJob.run(new NullProgressMonitor());
  }

  private void removeOccurrenceAnnotations(JavaEditor editor) {
    fMarkOccurrenceModificationStamp = IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP;
    fMarkOccurrenceTargetRegion = null;

    IDocumentProvider documentProvider = editor.getDocumentProvider();
    if (documentProvider == null)
      return;

    IAnnotationModel annotationModel = documentProvider
        .getAnnotationModel(editor.getEditorInput());
    if (annotationModel == null || fOccurrenceAnnotations == null)
      return;

    synchronized (getLockObject(annotationModel)) {
      if (annotationModel instanceof IAnnotationModelExtension) {
        ((IAnnotationModelExtension) annotationModel)
            .replaceAnnotations(fOccurrenceAnnotations, null);
      } else {
        for (int i = 0, length = fOccurrenceAnnotations.length; i < length; i++)
          annotationModel.removeAnnotation(fOccurrenceAnnotations[i]);
      }
      fOccurrenceAnnotations = null;
    }
   
   
  }

  private class OccurrencesFinderJob extends Job {
    private IDocument fDocument;
    private ISelection fSelection;
    private ISelectionValidator fPostSelectionValidator;
    private boolean fCanceled = false;
    private IProgressMonitor fProgressMonitor;
    private Position[] fPositions;

    private JavaEditor editor;

    public OccurrencesFinderJob(IDocument document, Position[] positions,
        ISelection selection, JavaEditor editor) {
      super("WicketFun_MarkOccurrencesJob");

      fDocument = document;
      fSelection = selection;
      fPositions = positions;
      this.editor = editor;

      if (editor.getSelectionProvider() instanceof ISelectionValidator)
        fPostSelectionValidator = (ISelectionValidator) editor
            .getSelectionProvider();
    }

    // cannot use cancel() because it is declared final
    @SuppressWarnings("unused")
    private void doCancel() {
      fCanceled = true;
      cancel();
    }

    private boolean isCanceled() {
      return fCanceled
          || fProgressMonitor.isCanceled()
          || fPostSelectionValidator != null
          && !(fPostSelectionValidator.isValid(fSelection) || fForcedMarkOccurrencesSelection == fSelection)
          || LinkedModeModel.hasInstalledModel(fDocument);
    }

    /*
     * @see Job#run(org.eclipse.core.runtime.IProgressMonitor)
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public IStatus run(IProgressMonitor progressMonitor) {
      fProgressMonitor = progressMonitor;

      if (isCanceled())
        return Status.CANCEL_STATUS;

      ITextViewer textViewer = editor.getViewer();
      if (textViewer == null)
        return Status.CANCEL_STATUS;

      IDocument document = textViewer.getDocument();
      if (document == null)
        return Status.CANCEL_STATUS;

      IDocumentProvider documentProvider = editor.getDocumentProvider();
      if (documentProvider == null)
        return Status.CANCEL_STATUS;

      IAnnotationModel annotationModel = documentProvider
          .getAnnotationModel(editor.getEditorInput());
      if (annotationModel == null)
        return Status.CANCEL_STATUS;

      // Add occurrence annotations
      int length = fPositions.length;

      Map annotationMap = new HashMap(length);
      for (int i = 0; i < length; i++) {
        if (isCanceled())
          return Status.CANCEL_STATUS;

        String message;
        Position position = fPositions[i];

        // Create & add annotation
        try {
          message = document.get(position.offset, position.length);
        } catch (BadLocationException ex) {
          // Skip this match
          continue;
        }

        annotationMap.put(new Annotation(
            "org.eclipse.jdt.ui.occurrences", false, message), //$NON-NLS-1$
            position);
      }

      if (isCanceled())
        return Status.CANCEL_STATUS;

      synchronized (getLockObject(annotationModel)) {
        if (annotationModel instanceof IAnnotationModelExtension) {
          ((IAnnotationModelExtension) annotationModel)
              .replaceAnnotations(fOccurrenceAnnotations,
                  annotationMap);
        } else {
          // removeOccurrenceAnnotations();
          Iterator iter = annotationMap.entrySet().iterator();
          while (iter.hasNext()) {
            Map.Entry mapEntry = (Map.Entry) iter.next();
            annotationModel.addAnnotation(
                (Annotation) mapEntry.getKey(),
                (Position) mapEntry.getValue());
          }
        }
        fOccurrenceAnnotations = (Annotation[]) annotationMap.keySet()
            .toArray(new Annotation[annotationMap.keySet().size()]);
      }

      return Status.OK_STATUS;
    }
  }

  private Object getLockObject(IAnnotationModel annotationModel) {
    if (annotationModel instanceof ISynchronizable) {
      Object lock = ((ISynchronizable) annotationModel).getLockObject();
      if (lock != null)
        return lock;
    }
    return annotationModel;
  }

  boolean markOccurrencesOfType(IBinding binding) {
    if (binding == null)
      return false;

    int kind = binding.getKind();

    if (fMarkTypeOccurrences && kind == IBinding.TYPE)
      return true;

    if (fMarkMethodOccurrences && kind == IBinding.METHOD)
      return true;

    if (kind == IBinding.VARIABLE) {
      IVariableBinding variableBinding = (IVariableBinding) binding;
      if (variableBinding.isField()) {
        int constantModifier = IModifierConstants.ACC_STATIC
            | IModifierConstants.ACC_FINAL;
        boolean isConstant = (variableBinding.getModifiers() & constantModifier) == constantModifier;
        if (isConstant)
          return fMarkConstantOccurrences;
        else
          return fMarkFieldOccurrences;
      }

      return fMarkLocalVariableypeOccurrences;
    }

    return false;
  }
}
TOP

Related Classes of it.tref.eclipse.wicket.plugin.editors.WicketFunMarkOccurrenceInstaller$OccurrencesFinderJob

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.