| /******************************************************************************* |
| * 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); |
| if (annModel == null) { |
| fail("Could not get the annotation model"); |
| } |
| 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); |
| if (annModel == null) { |
| fail("Could not get the annotation model"); |
| } |
| 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) {} |
| } |
| } |
| |
| |