blob: 0ee33a3b136e301b172bbed6e2effeceacdf5d31 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007, 2015 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.debug.tests.ui;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.model.IThread;
import org.eclipse.debug.internal.core.IInternalDebugCoreConstants;
import org.eclipse.debug.internal.ui.DebugUIPlugin;
import org.eclipse.debug.internal.ui.InstructionPointerAnnotation;
import org.eclipse.debug.internal.ui.InstructionPointerManager;
import org.eclipse.debug.internal.ui.viewers.model.InternalTreeModelViewer;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.debug.ui.IDebugView;
import org.eclipse.jdt.debug.core.IJavaDebugTarget;
import org.eclipse.jdt.debug.core.IJavaLineBreakpoint;
import org.eclipse.jdt.debug.core.IJavaStackFrame;
import org.eclipse.jdt.debug.core.IJavaThread;
import org.eclipse.jdt.debug.tests.AbstractDebugTest;
import org.eclipse.jface.text.source.Annotation;
import org.eclipse.jface.text.source.AnnotationModelEvent;
import org.eclipse.jface.text.source.IAnnotationModel;
import org.eclipse.jface.text.source.IAnnotationModelListener;
import org.eclipse.jface.text.source.IAnnotationModelListenerExtension;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.jface.viewers.TreeSelection;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IPartListener2;
import org.eclipse.ui.IPerspectiveDescriptor;
import org.eclipse.ui.IPerspectiveListener2;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPartReference;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.texteditor.ITextEditor;
/**
* Tests functionality of the InstructionPointerManager.
* The tests are not currently part of the automated suite because they produce
* transient failures that could not be tracked down.
*
* @since 3.3
* @see InstructionPointerManager
*/
public class InstructionPointerManagerTests extends AbstractDebugTest {
private Object fLock = new Object();
private Annotation fAddedAnnotation = null;
private Annotation fRemovedAnnotation = null;
private MyPerspectiveListener fPerspectiveListener;
private MyAnnotationListener fAnnotationListener;
private IPartListener2 fPartListener;
private Set<IAnnotationModel> fAnnotationModelsWithListeners = new HashSet<>();
private static final String typeThreadStack = "org.eclipse.debug.tests.targets.ThreadStack";
private static final String typeClassOne = "org.eclipse.debug.tests.targets.ClassOne";
private static final String typeClassTwo = "org.eclipse.debug.tests.targets.ClassTwo";
private IJavaDebugTarget target1;
private IJavaDebugTarget target2;
private IJavaThread thread1;
private IJavaThread thread2;
private IJavaThread thread3;
private IJavaThread thread4;
public InstructionPointerManagerTests(String name) {
super(name);
}
public void testManagerWithEditorReuse() throws Exception{
boolean restore = DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IDebugUIConstants.PREF_REUSE_EDITOR);
DebugUIPlugin.getDefault().getPreferenceStore().setValue(IDebugUIConstants.PREF_REUSE_EDITOR, true);
try{
addAndRemoveAnnotations(new int[]{1,2,1,2,1,0,1,1}, new int[]{1,1,1,1,1,0,1,1});
} finally {
System.out.println("Cleanup");
if (target1 != null){
terminateAndRemove(target1);
}
if (target2 != null){
terminateAndRemove(target2);
}
Iterator<IAnnotationModel> annModels = fAnnotationModelsWithListeners.iterator();
while (annModels.hasNext()) {
IAnnotationModel currentModel = annModels.next();
currentModel.removeAnnotationModelListener(getAnnotationListener());
}
removeAllBreakpoints();
DebugUIPlugin.getDefault().getPreferenceStore().setValue(IDebugUIConstants.PREF_REUSE_EDITOR, restore);
Runnable cleanup = new Runnable() {
@Override
public void run() {
IWorkbenchWindow activeWorkbenchWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
activeWorkbenchWindow.removePerspectiveListener(getPerspectiveListener());
}
};
DebugUIPlugin.getStandardDisplay().asyncExec(cleanup);
}
}
public void testManagerWithNoEditorReuse() throws Exception{
boolean restore = DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IDebugUIConstants.PREF_REUSE_EDITOR);
DebugUIPlugin.getDefault().getPreferenceStore().setValue(IDebugUIConstants.PREF_REUSE_EDITOR, false);
try{
addAndRemoveAnnotations(new int[]{1,2,3,4,5,3,2,1}, new int[]{1,1,2,2,3,2,2,1});
} finally {
System.out.println("Cleanup");
if (target1 != null){
terminateAndRemove(target1);
}
if (target2 != null){
terminateAndRemove(target2);
}
Iterator<IAnnotationModel> annModels = fAnnotationModelsWithListeners.iterator();
while (annModels.hasNext()) {
IAnnotationModel currentModel = annModels.next();
currentModel.removeAnnotationModelListener(getAnnotationListener());
}
removeAllBreakpoints();
DebugUIPlugin.getDefault().getPreferenceStore().setValue(IDebugUIConstants.PREF_REUSE_EDITOR, restore);
Runnable cleanup = new Runnable() {
@Override
public void run() {
IWorkbenchWindow activeWorkbenchWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
activeWorkbenchWindow.removePerspectiveListener(getPerspectiveListener());
}
};
DebugUIPlugin.getStandardDisplay().asyncExec(cleanup);
}
}
/**
* Tests the ability of the manager to update it's set and mapping as
* annotations are added and removed.
*
* First, all editors are closed and the manager is checked to ensure there are 0 IPCs.
*
* <p>Next, annotations are created as follows:<br>
* (numbers in brackets correspond to index of expected IPC and Mapping counts checked)
* <pre>
* Target1 - Thread1 - IPC1 - ClassOne - Editor1 (line 20) [0]
* - Thread2 - IPC2 - ClassOne - Editor1 (line 20) [1]
* - IPC3 - ThreadStack - Editor2 (line 28) [2]
*
* Target2 - Thread3 - IPC4 - ThreadStack - Editor2 (line 41) [3]
* - Thread4 - IPC5 - ClassTwo - Editor3 (line 24) [4]
* </pre>
* </p>
* <p>They are then removed as follows:<br>
* (numbers in brackets correspond to index of expected IPC and Mapping counts checked)
* <ol>
* <li>Target2 is terminated [5]</li>
* <li>Thread1 is resumed [6]</li>
* <li>Editor2 is closed [7]</li>
* <li>All editors are closed, closing Editor1, No IPCs should exist</li>
* </ol>
* </p>
* @param expectedIPCCounts array of expected values for IPC count at each step as marked above, length must be 8
* @param expectedMappingCounts array of expected values for editor mapping count at each step as marked above, length must be 8
* @throws Exception
*/
private void addAndRemoveAnnotations(int[] expectedIPCCounts, int[] expectedMappingCounts) throws Exception{
assertEquals("Incorrect number of expected counts", 8, expectedIPCCounts.length);
assertEquals("Incorrect number of expected counts", 8, expectedMappingCounts.length);
// Close all editors
Runnable closeAll = new Runnable() {
@Override
public void run() {
IWorkbenchWindow activeWorkbenchWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
activeWorkbenchWindow.getActivePage().closeAllEditors(false);
activeWorkbenchWindow.addPerspectiveListener(getPerspectiveListener());
}
};
DebugUIPlugin.getStandardDisplay().syncExec(closeAll);
assertEquals("Instruction pointer count was incorrect", 0, InstructionPointerManager.getDefault().getInstructionPointerCount());
assertEquals("Editor mapping count was incorrect", 0, InstructionPointerManager.getDefault().getEditorMappingCount());
// ADD ANNOTATIONS
// Launch a target creating two threads, both suspend in ClassOne, one will automatically be selected
IJavaLineBreakpoint breakpoint = createLineBreakpoint(20, typeClassOne);
fAddedAnnotation = null;
getPerspectiveListener().setTitle(typeClassOne);
thread1 = launchAndSuspend(typeThreadStack);
target1 = (IJavaDebugTarget)thread1.getDebugTarget();
assertNotNull("Target was not launched.",target1);
assertNotNull("Target was not launched.",thread1);
waitForAnnotationToBeAdded();
assertEquals("Instruction pointer count was incorrect", expectedIPCCounts[0], InstructionPointerManager.getDefault().getInstructionPointerCount());
assertEquals("Editor mapping count was incorrect", expectedMappingCounts[0], InstructionPointerManager.getDefault().getEditorMappingCount());
// Find and select the top stack frame of the other thread
Runnable openParent = new Runnable() {
@Override
public void run() {
IDebugView debugView = (IDebugView)PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().findView("org.eclipse.debug.ui.DebugView");
Object[] newSegments = new Object[4];
newSegments[0] = target1.getLaunch();
newSegments[1] = target1;
try{
IThread[] threads = ((IJavaDebugTarget)newSegments[1]).getThreads();
for (int i = 0; i < threads.length; i++) {
if (threads[i].isSuspended() && !threads[i].equals(thread1)){
thread2 = (IJavaThread)threads[i];
newSegments[2] = threads[i];
newSegments[3] = threads[i].getTopStackFrame();
}
}
((InternalTreeModelViewer)debugView.getViewer()).setSelection(new TreeSelection(new TreePath(newSegments)), true, true);
} catch (DebugException e){
fail("Exception: " + e.getMessage());
}
}
};
fAddedAnnotation = null;
getPerspectiveListener().setTitle(typeClassOne);
DebugUIPlugin.getStandardDisplay().syncExec(openParent);
waitForAnnotationToBeAdded();
assertNotNull("Thread not selected",thread2);
assertEquals("Instruction pointer count was incorrect", expectedIPCCounts[1], InstructionPointerManager.getDefault().getInstructionPointerCount());
assertEquals("Editor mapping count was incorrect", expectedMappingCounts[1], InstructionPointerManager.getDefault().getEditorMappingCount());
// Select the same stack frame and make sure IPC count doesn't change
Runnable selectSameStackFrame = new Runnable() {
@Override
public void run() {
IDebugView debugView = (IDebugView)PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().findView("org.eclipse.debug.ui.DebugView");
Object[] newSegments = new Object[4];
newSegments[0] = target1.getLaunch();
newSegments[1] = target1;
newSegments[2] = thread2;
try {
newSegments[3] = thread2.getTopStackFrame();
} catch (DebugException e) {
fail("Exception: " + e.getMessage());
}
((InternalTreeModelViewer)debugView.getViewer()).setSelection(new TreeSelection(new TreePath(newSegments)), true, true);
}
};
fAddedAnnotation = null;
getPerspectiveListener().setTitle(typeClassOne);
DebugUIPlugin.getStandardDisplay().syncExec(selectSameStackFrame);
waitForAnnotationToBeAdded();
assertEquals("Instruction pointer count was incorrect", expectedIPCCounts[1], InstructionPointerManager.getDefault().getInstructionPointerCount());
assertEquals("Editor mapping count was incorrect", expectedMappingCounts[1], InstructionPointerManager.getDefault().getEditorMappingCount());
// Select the next stack frame in the same thread
Runnable selectSecondStackFrame = new Runnable() {
@Override
public void run() {
IDebugView debugView = (IDebugView)PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().findView("org.eclipse.debug.ui.DebugView");
Object[] newSegments = new Object[4];
newSegments[0] = target1.getLaunch();
newSegments[1] = target1;
newSegments[2] = thread2;
try{
newSegments[3] = thread2.getStackFrames()[1]; // Select the next stack frame
} catch (DebugException e){
fail("Exception: " + e.getMessage());
}
((InternalTreeModelViewer)debugView.getViewer()).setSelection(new TreeSelection(new TreePath(newSegments)), true, true);
}
};
fAddedAnnotation = null;
getPerspectiveListener().setTitle(typeThreadStack);
DebugUIPlugin.getStandardDisplay().syncExec(selectSecondStackFrame);
waitForAnnotationToBeAdded();
// Failure here, reuse, expected 1 but was 2, also with no reuse, expected 3 but was 2
assertEquals("Instruction pointer count was incorrect", expectedIPCCounts[2], InstructionPointerManager.getDefault().getInstructionPointerCount());
assertEquals("Editor mapping count was incorrect", expectedMappingCounts[2], InstructionPointerManager.getDefault().getEditorMappingCount());
// Remove the breakpoint from before and create new ones, start a new target
breakpoint.delete();
createLineBreakpoint(41, typeThreadStack);
createLineBreakpoint(24, typeClassTwo);
target2 = (IJavaDebugTarget)launchAndSuspend(typeThreadStack).getDebugTarget();
assertNotNull("Target was not launched", target2);
assertEquals("Instruction pointer count was incorrect", expectedIPCCounts[2], InstructionPointerManager.getDefault().getInstructionPointerCount());
assertEquals("Editor mapping count was incorrect", expectedMappingCounts[2], InstructionPointerManager.getDefault().getEditorMappingCount());
// Select the stack frame from the new debug target displaying ThreadStack
Runnable openOtherDebugTarget = new Runnable() {
@Override
public void run() {
IDebugView debugView = (IDebugView)PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().findView("org.eclipse.debug.ui.DebugView");
ILaunch[] launches = DebugPlugin.getDefault().getLaunchManager().getLaunches();
Object[] newSegments = new Object[4];
for (int i = 0; i < launches.length; i++) {
if (target2.equals(launches[i].getDebugTarget())){
newSegments[0] = launches[i];
newSegments[1] = target2;
try{
IThread[] threads = target2.getThreads();
for (int j = 0; j < threads.length; j++) {
if (threads[j].isSuspended()){
if (typeThreadStack.equals(((IJavaStackFrame)threads[j].getTopStackFrame()).getDeclaringTypeName())){
thread3 = (IJavaThread)threads[j];
newSegments[2] = threads[j];
newSegments[3] = threads[j].getTopStackFrame();
break;
}
}
}
} catch (DebugException e){
fail("Exception: " + e.getMessage());
}
break;
}
}
((InternalTreeModelViewer)debugView.getViewer()).setSelection(new TreeSelection(new TreePath(newSegments)), true, true);
}
};
fAddedAnnotation = null;
getPerspectiveListener().setTitle(typeThreadStack);
DebugUIPlugin.getStandardDisplay().syncExec(openOtherDebugTarget);
assertNotNull("Thread was not selected",thread3);
waitForAnnotationToBeAdded();
assertEquals("Instruction pointer count was incorrect", expectedIPCCounts[3], InstructionPointerManager.getDefault().getInstructionPointerCount());
assertEquals("Editor mapping count was incorrect", expectedMappingCounts[3], InstructionPointerManager.getDefault().getEditorMappingCount());
// Select the other thread from the new target displaying ClassTwo
Runnable openOtherThread = new Runnable() {
@Override
public void run() {
IDebugView debugView = (IDebugView)PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().findView("org.eclipse.debug.ui.DebugView");
Object[] newSegments = new Object[4];
newSegments[0] = target2.getLaunch();
newSegments[1] = target2;
try{
IThread[] threads = target2.getThreads();
for (int i = 0; i < threads.length; i++) {
if (threads[i].isSuspended() && !threads[i].equals(thread3)){
thread4 = (IJavaThread)threads[i];
newSegments[2] = threads[i];
newSegments[3] = threads[i].getTopStackFrame();
}
}
((InternalTreeModelViewer)debugView.getViewer()).setSelection(new TreeSelection(new TreePath(newSegments)), true, true);
} catch (DebugException e){
fail("Exception: " + e.getMessage());
}
}
};
fAddedAnnotation = null;
getPerspectiveListener().setTitle(typeClassTwo);
DebugUIPlugin.getStandardDisplay().syncExec(openOtherThread);
assertNotNull("Thread was not selected",thread4);
waitForAnnotationToBeAdded();
assertEquals("Instruction pointer count was incorrect", expectedIPCCounts[4], InstructionPointerManager.getDefault().getInstructionPointerCount());
assertEquals("Editor mapping count was incorrect", expectedMappingCounts[4], InstructionPointerManager.getDefault().getEditorMappingCount());
// REMOVE ANNOTATIONS
// Remove target2
fRemovedAnnotation = null;
target2.terminate();
waitForAnnotationToBeRemoved();
assertEquals("Instruction pointer count was incorrect", expectedIPCCounts[5], InstructionPointerManager.getDefault().getInstructionPointerCount());
assertEquals("Editor mapping count was incorrect", expectedMappingCounts[5], InstructionPointerManager.getDefault().getEditorMappingCount());
// TODO Selection of the other target does not occur automatically. This functionality may change and will break this test.
// Resume thread1
fRemovedAnnotation = null;
thread1.resume();
waitForAnnotationToBeRemoved();
assertEquals("Instruction pointer count was incorrect", expectedIPCCounts[6], InstructionPointerManager.getDefault().getInstructionPointerCount());
assertEquals("Editor mapping count was incorrect", expectedMappingCounts[6], InstructionPointerManager.getDefault().getEditorMappingCount());
// Close the editor displaying ThreadStack.java if it is open
Runnable closeEditor2 = new Runnable() {
@Override
public void run() {
IWorkbenchWindow activeWorkbenchWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
IEditorReference[] editors = activeWorkbenchWindow.getActivePage().getEditorReferences();
for (int i = 0; i < editors.length; i++) {
if (editors[i].getTitle().equals("ThreadStack.java")){
activeWorkbenchWindow.getActivePage().closeEditors(new IEditorReference[]{editors[i]},false);
fRemovedAnnotation = null; // Clear the removed annotation so the test waits for the annotation to be removed
break;
}
}
}
};
// fRemovedAnnotation is used here to check if the editor has been found and closed successfully. It is set to a annotation object, and will only be reset to null (causing the wait to occur) if the editor is closed.
fRemovedAnnotation = new Annotation(true);
DebugUIPlugin.getStandardDisplay().syncExec(closeEditor2);
waitForAnnotationToBeRemoved();
assertEquals("Instruction pointer count was incorrect", expectedIPCCounts[7], InstructionPointerManager.getDefault().getInstructionPointerCount());
assertEquals("Editor mapping count was incorrect", expectedMappingCounts[7], InstructionPointerManager.getDefault().getEditorMappingCount());
// Close all editors
Runnable closeAllEditors = new Runnable() {
@Override
public void run() {
IWorkbenchWindow activeWorkbenchWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
activeWorkbenchWindow.getActivePage().closeAllEditors(false);
}
};
fRemovedAnnotation = null;
DebugUIPlugin.getStandardDisplay().syncExec(closeAllEditors);
waitForAnnotationToBeRemoved();
assertEquals("Instruction pointer count was incorrect", 0, InstructionPointerManager.getDefault().getInstructionPointerCount());
assertEquals("Editor mapping count was incorrect", 0, InstructionPointerManager.getDefault().getEditorMappingCount());
}
protected MyPerspectiveListener getPerspectiveListener(){
if (fPerspectiveListener == null){
fPerspectiveListener = new MyPerspectiveListener();
return fPerspectiveListener;
}
return fPerspectiveListener;
}
protected MyAnnotationListener getAnnotationListener(){
if (fAnnotationListener == null){
fAnnotationListener = new MyAnnotationListener();
return fAnnotationListener;
}
return fAnnotationListener;
}
private IPartListener2 getPartListener(){
if (fPartListener == null){
fPartListener = new MyPartListener();
return fPartListener;
}
return fPartListener;
}
private void waitForAnnotationToBeAdded() throws Exception{
synchronized (fLock) {
if (fAddedAnnotation == null) {
fLock.wait(5000);
}
}
assertNotNull("Annotation was not added properly");
// Synchronize with the UI thread so we know that the annotations have finished
Runnable runner = new Runnable(){
@Override
public void run() {
// Do nothing, just waiting for the UI thread to finish annotations
}
};
DebugUIPlugin.getStandardDisplay().syncExec(runner);
}
private void waitForAnnotationToBeRemoved() throws Exception{
synchronized (fLock) {
if (fRemovedAnnotation == null) {
fLock.wait(5000);
}
}
assertNotNull("Annotation was not removed properly");
// Synchronize with the UI thread so we know that the annotations have finished
Runnable runner = new Runnable(){
@Override
public void run() {
// Do nothing, just waiting for the UI thread to finish annotations
}
};
DebugUIPlugin.getStandardDisplay().syncExec(runner);
}
class MyPerspectiveListener implements IPerspectiveListener2 {
private String fTypeName = IInternalDebugCoreConstants.EMPTY_STRING;
private String fTitle = IInternalDebugCoreConstants.EMPTY_STRING;
@Override
public void perspectiveActivated(IWorkbenchPage page, IPerspectiveDescriptor perspective) {}
@Override
public void perspectiveChanged(IWorkbenchPage page, IPerspectiveDescriptor perspective, String changeId) {}
/* (non-Javadoc)
* @see org.eclipse.ui.IPerspectiveListener2#perspectiveChanged(org.eclipse.ui.IWorkbenchPage, org.eclipse.ui.IPerspectiveDescriptor, org.eclipse.ui.IWorkbenchPartReference, java.lang.String)
*/
@Override
public void perspectiveChanged(IWorkbenchPage page, IPerspectiveDescriptor perspective, IWorkbenchPartReference partRef, String changeId) {
if (partRef.getTitle().equals(fTitle) && changeId == IWorkbenchPage.CHANGE_EDITOR_OPEN) {
IEditorPart editor = (IEditorPart) partRef.getPart(true);
if (editor instanceof ITextEditor){
IDocumentProvider docProvider = ((ITextEditor)editor).getDocumentProvider();
IEditorInput editorInput = editor.getEditorInput();
// If there is no annotation model, there's nothing more to do
IAnnotationModel annModel = docProvider.getAnnotationModel(editorInput);
assertNotNull("Could not get the annotation model", annModel);
annModel.addAnnotationModelListener(getAnnotationListener());
fAnnotationModelsWithListeners.add(annModel);
} else {
fail("Editor was not a text editor");
}
partRef.getPage().addPartListener(getPartListener());
}
if (changeId == IWorkbenchPage.CHANGE_EDITOR_CLOSE) {
if (partRef.getPage().getEditorReferences().length == 0){
partRef.getPage().removePartListener(getPartListener());
}
}
}
public void setTitle(String typeName){
fTypeName = typeName;
int index = typeName.lastIndexOf('.');
if (index >= 0){
fTitle = typeName.substring(index+1) + ".java";
} else {
fTitle = typeName + ".java";
}
}
public String getTypeName(){
return fTypeName;
}
}
class MyPartListener implements IPartListener2{
@Override
public void partActivated(IWorkbenchPartReference partRef) {}
@Override
public void partDeactivated(IWorkbenchPartReference partRef) {}
@Override
public void partHidden(IWorkbenchPartReference partRef) {}
@Override
public void partOpened(IWorkbenchPartReference partRef) {}
@Override
public void partVisible(IWorkbenchPartReference partRef) {}
@Override
public void partBroughtToTop(IWorkbenchPartReference partRef) {}
@Override
public void partClosed(IWorkbenchPartReference partRef) {}
/* (non-Javadoc)
* @see org.eclipse.ui.IPartListener2#partInputChanged(org.eclipse.ui.IWorkbenchPartReference)
*/
@Override
public void partInputChanged(IWorkbenchPartReference partRef) {
IEditorPart editor = (IEditorPart) partRef.getPart(true);
if (editor instanceof ITextEditor){
IDocumentProvider docProvider = ((ITextEditor)editor).getDocumentProvider();
IEditorInput editorInput = editor.getEditorInput();
// If there is no annotation model, there's nothing more to do
IAnnotationModel annModel = docProvider.getAnnotationModel(editorInput);
assertNotNull("Could not get the annotation model", annModel);
annModel.addAnnotationModelListener(getAnnotationListener());
fAnnotationModelsWithListeners.add(annModel);
} else {
fail("Editor was not a text editor");
}
}
}
class MyAnnotationListener implements IAnnotationModelListener, IAnnotationModelListenerExtension{
@Override
public void modelChanged(AnnotationModelEvent event) {
Annotation[] annotations = event.getAddedAnnotations();
for (int i = 0; i < annotations.length; i++) {
if (annotations[i] instanceof InstructionPointerAnnotation){
synchronized (fLock) {
fAddedAnnotation = annotations[i];
fLock.notifyAll();
System.out.println("Annotation added to editor: " + fAddedAnnotation + " (" + this + ")" + event.getAnnotationModel());
}
}
}
annotations = event.getRemovedAnnotations();
for (int i = 0; i < annotations.length; i++) {
if (annotations[i] instanceof InstructionPointerAnnotation){
synchronized (fLock) {
fRemovedAnnotation = annotations[i];
fLock.notifyAll();
}
}
}
}
@Override
public void modelChanged(IAnnotationModel model) {}
}
}