KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > debug > internal > ui > InstructionPointerManager


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.debug.internal.ui;
12
13 import java.util.HashMap JavaDoc;
14 import java.util.HashSet JavaDoc;
15 import java.util.Iterator JavaDoc;
16 import java.util.Map JavaDoc;
17 import java.util.Set JavaDoc;
18
19 import org.eclipse.debug.core.DebugException;
20 import org.eclipse.debug.core.model.IDebugTarget;
21 import org.eclipse.debug.core.model.IStackFrame;
22 import org.eclipse.debug.core.model.IThread;
23 import org.eclipse.jface.text.BadLocationException;
24 import org.eclipse.jface.text.IDocument;
25 import org.eclipse.jface.text.IRegion;
26 import org.eclipse.jface.text.Position;
27 import org.eclipse.jface.text.source.Annotation;
28 import org.eclipse.jface.text.source.IAnnotationModel;
29 import org.eclipse.ui.IEditorInput;
30 import org.eclipse.ui.IPageListener;
31 import org.eclipse.ui.IPartListener2;
32 import org.eclipse.ui.IWorkbenchPage;
33 import org.eclipse.ui.IWorkbenchPart;
34 import org.eclipse.ui.IWorkbenchPartReference;
35 import org.eclipse.ui.texteditor.IDocumentProvider;
36 import org.eclipse.ui.texteditor.ITextEditor;
37
38 /**
39  * This class tracks instruction pointer contexts for all active debug targets and threads
40  * in the current workbench. There should only ever be one instance of this class, obtained
41  * via 'getDefault()'.
42  */

43 public class InstructionPointerManager{
44
45     /**
46      * The singleton instance of this class.
47      */

48     private static InstructionPointerManager fgDefault;
49
50     /**
51      * Set containing all instruction pointer contexts this class manages
52      */

53     private Set JavaDoc fIPCSet = new HashSet JavaDoc();
54     
55     /**
56      * Maps ITextEditors to the set of instruction pointer contexts that are displayed in the editor
57      */

58     private Map JavaDoc fEditorMap = new HashMap JavaDoc();
59     
60     /**
61      * Part listener added to editors that contain annotations. Allows instruction pointer contexts to
62      * be removed when the editor they are displayed in is removed.
63      */

64     private IPartListener2 fPartListener;
65     
66     /**
67      * Page listener added to the workbench window to remove part listeners when the page is closed.
68      */

69     private IPageListener fPageListener;
70     
71     /**
72      * Clients must not instantiate this class.
73      */

74     private InstructionPointerManager() {
75     }
76     
77     /**
78      * Return the singleton instance of this class, creating it if necessary.
79      */

80     public static InstructionPointerManager getDefault() {
81         if (fgDefault == null) {
82             fgDefault = new InstructionPointerManager();
83         }
84         return fgDefault;
85     }
86     
87     /**
88      * Adds an instruction pointer annotation in the specified editor for the
89      * specified stack frame.
90      */

91     public void addAnnotation(ITextEditor textEditor, IStackFrame frame, Annotation annotation) {
92         
93         IDocumentProvider docProvider = textEditor.getDocumentProvider();
94         IEditorInput editorInput = textEditor.getEditorInput();
95         // If there is no annotation model, there's nothing more to do
96
IAnnotationModel annModel = docProvider.getAnnotationModel(editorInput);
97         if (annModel == null) {
98             return;
99         }
100         
101         // Create the Position object that specifies a location for the annotation
102
Position position = null;
103         int charStart = -1;
104         int length = -1;
105         try {
106             charStart = frame.getCharStart();
107             length = frame.getCharEnd() - charStart;
108         } catch (DebugException de) {
109         }
110         if (charStart < 0) {
111             IDocument doc = docProvider.getDocument(editorInput);
112             if (doc == null) {
113                 return;
114             }
115             try {
116                 int lineNumber = frame.getLineNumber() - 1;
117                 IRegion region = doc.getLineInformation(lineNumber);
118                 charStart = region.getOffset();
119                 length = region.getLength();
120             } catch (BadLocationException ble) {
121                 return;
122             } catch (DebugException de) {
123                 return;
124             }
125         }
126         if (charStart < 0) {
127             return;
128         }
129         position = new Position(charStart, length);
130         
131         if (frame.isTerminated()) {
132             return;
133         }
134         
135         synchronized (fIPCSet) {
136                     
137             // Add the annotation at the position to the editor's annotation model.
138
annModel.removeAnnotation(annotation);
139             annModel.addAnnotation(annotation, position);
140             
141             // Create the instruction pointer context
142
InstructionPointerContext ipc = new InstructionPointerContext(frame.getDebugTarget(), frame.getThread(), textEditor, annotation);
143             
144             // Add the IPC to the set and map
145
Set JavaDoc editorIPCs = (Set JavaDoc)fEditorMap.get(textEditor);
146             if (editorIPCs == null){
147                 editorIPCs = new HashSet JavaDoc();
148                 fEditorMap.put(textEditor, editorIPCs);
149             } else {
150                 editorIPCs.remove(ipc);
151             }
152             editorIPCs.add(ipc);
153             fIPCSet.remove(ipc);
154             fIPCSet.add(ipc);
155             
156             // Add a listener to the editor so we can remove the IPC when the editor is closed
157
textEditor.getSite().getPage().addPartListener(getPartListener());
158             textEditor.getSite().getPage().getWorkbenchWindow().addPageListener(getPageListener());
159         }
160     }
161     
162     /**
163      * Remove all annotations associated with the specified debug target that this class
164      * is tracking.
165      */

166     public void removeAnnotations(IDebugTarget debugTarget) {
167         synchronized (fIPCSet) {
168             Iterator JavaDoc ipcIter = fIPCSet.iterator();
169             while (ipcIter.hasNext()) {
170                 InstructionPointerContext currentIPC = (InstructionPointerContext) ipcIter.next();
171                 if (currentIPC.getDebugTarget().equals(debugTarget)){
172                     removeAnnotationFromModel(currentIPC);
173                     ipcIter.remove();
174                     removeAnnotationFromEditorMapping(currentIPC);
175                 }
176             }
177         }
178     }
179     
180     /**
181      * Remove all annotations associated with the specified thread that this class
182      * is tracking.
183      */

184     public void removeAnnotations(IThread thread) {
185         synchronized (fIPCSet) {
186             Iterator JavaDoc ipcIter = fIPCSet.iterator();
187             while (ipcIter.hasNext()) {
188                 InstructionPointerContext currentIPC = (InstructionPointerContext) ipcIter.next();
189                 if (currentIPC.getThread().equals(thread)){
190                     removeAnnotationFromModel(currentIPC);
191                     ipcIter.remove();
192                     removeAnnotationFromEditorMapping(currentIPC);
193                 }
194             }
195         }
196     }
197     
198     /**
199      * Remove all annotations associated with the specified editor that this class
200      * is tracking.
201      */

202     public void removeAnnotations(ITextEditor editor) {
203         synchronized (fIPCSet) {
204             Set JavaDoc editorIPCs = (Set JavaDoc)fEditorMap.get(editor);
205             if (editorIPCs != null){
206                 Iterator JavaDoc ipcIter = editorIPCs.iterator();
207                 while (ipcIter.hasNext()) {
208                     InstructionPointerContext currentIPC = (InstructionPointerContext) ipcIter.next();
209                     removeAnnotationFromModel(currentIPC);
210                     fIPCSet.remove(currentIPC);
211                 }
212                 fEditorMap.remove(editor);
213             }
214         }
215     }
216
217     /**
218      * Remove the given ipc from the mapping of editors.
219      */

220     private void removeAnnotationFromEditorMapping(InstructionPointerContext ipc) {
221         Set JavaDoc editorIPCs = (Set JavaDoc)fEditorMap.get(ipc.getEditor());
222         if (editorIPCs != null){
223             editorIPCs.remove(ipc);
224             if (editorIPCs.isEmpty()){
225                 fEditorMap.remove(ipc.getEditor());
226             }
227         }
228         
229     }
230     
231     /**
232      * Remove the annotation from the document model.
233      */

234     private void removeAnnotationFromModel(InstructionPointerContext ipc){
235         IDocumentProvider docProvider = ipc.getEditor().getDocumentProvider();
236         if (docProvider != null) {
237             IAnnotationModel annotationModel = docProvider.getAnnotationModel(ipc.getEditor().getEditorInput());
238             if (annotationModel != null) {
239                 annotationModel.removeAnnotation(ipc.getAnnotation());
240             }
241         }
242     }
243     
244     /**
245      * Returns the number of instruction pointers.
246      * Used by the test suite.
247      *
248      * @return the number of instruction pointers
249      * @since 3.2
250      */

251     public int getInstructionPointerCount() {
252         return fIPCSet.size();
253     }
254     
255     /**
256      * Returns the number of keys in the editor to IPC mapping
257      * Used by the test suite.
258      *
259      * @return the number of keys in the editor mapping
260      * @since 3.3
261      */

262     public int getEditorMappingCount() {
263         return fEditorMap.size();
264     }
265     
266     /**
267      * @return the page listener to add to workbench window.
268      */

269     private IPageListener getPageListener(){
270         if (fPageListener == null){
271             fPageListener = new PageListener();
272         }
273         return fPageListener;
274     }
275     
276     /**
277      * @return the part listener to add to editors.
278      */

279     private IPartListener2 getPartListener(){
280         if (fPartListener == null){
281             fPartListener = new PartListener();
282         }
283         return fPartListener;
284     }
285
286     /**
287      * Part listener that is added to editors to track when the editor is no longer is displaying
288      * the input containing instruction pointer annotations.
289      */

290     class PartListener implements IPartListener2{
291         public void partActivated(IWorkbenchPartReference partRef) {}
292         public void partDeactivated(IWorkbenchPartReference partRef) {}
293         public void partHidden(IWorkbenchPartReference partRef) {}
294         public void partOpened(IWorkbenchPartReference partRef) {}
295         public void partVisible(IWorkbenchPartReference partRef) {}
296         public void partBroughtToTop(IWorkbenchPartReference partRef) {}
297     
298         /* (non-Javadoc)
299          * @see org.eclipse.ui.IPartListener2#partClosed(org.eclipse.ui.IWorkbenchPartReference)
300          */

301         public void partClosed(IWorkbenchPartReference partRef) {
302             IWorkbenchPart part = partRef.getPart(false);
303             if (part instanceof ITextEditor){
304                 removeAnnotations((ITextEditor)part);
305             }
306             
307         }
308     
309         /* (non-Javadoc)
310          * @see org.eclipse.ui.IPartListener2#partInputChanged(org.eclipse.ui.IWorkbenchPartReference)
311          */

312         public void partInputChanged(IWorkbenchPartReference partRef) {
313             IWorkbenchPart part = partRef.getPart(false);
314             if (part instanceof ITextEditor){
315                 removeAnnotations((ITextEditor)part);
316             }
317         }
318     }
319     
320     /**
321      * Page listener that is added to the workbench to remove the part listener when the page is closed.
322      */

323     class PageListener implements IPageListener{
324
325         public void pageActivated(IWorkbenchPage page) {}
326         public void pageOpened(IWorkbenchPage page) {}
327
328         /* (non-Javadoc)
329          * @see org.eclipse.ui.IPageListener#pageClosed(org.eclipse.ui.IWorkbenchPage)
330          */

331         public void pageClosed(IWorkbenchPage page) {
332             page.removePartListener(getPartListener());
333             page.getWorkbenchWindow().removePageListener(getPageListener());
334         }
335         
336     }
337     
338 }
339
Popular Tags