KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > debug > internal > ui > views > AbstractDebugEventHandler


1 /*******************************************************************************
2  * Copyright (c) 2000, 2005 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.views;
12
13
14 import java.util.ArrayList JavaDoc;
15 import java.util.List JavaDoc;
16
17 import org.eclipse.core.runtime.IProgressMonitor;
18 import org.eclipse.core.runtime.IStatus;
19 import org.eclipse.core.runtime.Status;
20 import org.eclipse.core.runtime.jobs.Job;
21 import org.eclipse.debug.core.DebugEvent;
22 import org.eclipse.debug.core.DebugPlugin;
23 import org.eclipse.debug.core.IDebugEventSetListener;
24 import org.eclipse.debug.ui.AbstractDebugView;
25 import org.eclipse.jface.viewers.IBasicPropertyConstants;
26 import org.eclipse.jface.viewers.ITreeContentProvider;
27 import org.eclipse.jface.viewers.StructuredSelection;
28 import org.eclipse.jface.viewers.TreeViewer;
29 import org.eclipse.jface.viewers.Viewer;
30 import org.eclipse.ui.progress.UIJob;
31
32 /**
33  * Handles debug events, updating a view and viewer.
34  */

35 public abstract class AbstractDebugEventHandler implements IDebugEventSetListener {
36     
37     /**
38      * This event handler's view
39      */

40     private AbstractDebugView fView;
41     
42     /**
43      * Queued debug event sets (arrays of events) to process.
44      */

45     private List JavaDoc fEventSetQueue = new ArrayList JavaDoc();
46     
47     /**
48      * Queued data associated with event sets. Entries may be <code>null</code>.
49      */

50     private List JavaDoc fDataQueue = new ArrayList JavaDoc();
51     
52     /**
53      * Lock to add to/remove from data and event queues.
54      */

55     private Object JavaDoc LOCK = new Object JavaDoc();
56     
57     /**
58      * Update job
59      */

60     private EventProcessingJob fUpdateJob = new EventProcessingJob();
61     
62     /**
63      * Empty event set constant
64      */

65     protected static final DebugEvent[] EMPTY_EVENT_SET = new DebugEvent[0];
66     
67     private Object JavaDoc NULL = new Object JavaDoc();
68     
69     /**
70      * Job to dispatch debug event sets
71      */

72     private class EventProcessingJob extends UIJob {
73
74         private static final int TIMEOUT = 200;
75         
76         public EventProcessingJob() {
77             super(DebugUIViewsMessages.AbstractDebugEventHandler_0); //$NON-NLS-1$
78
setSystem(true);
79             setPriority(Job.INTERACTIVE);
80         }
81         
82         /* (non-Javadoc)
83          * @see org.eclipse.ui.progress.UIJob#runInUIThread(org.eclipse.core.runtime.IProgressMonitor)
84          */

85         public IStatus runInUIThread(IProgressMonitor monitor) {
86             boolean more = true;
87             long start = System.currentTimeMillis();
88             // to avoid blocking the UI thread, process a max of 50 event sets at once
89
while (more) {
90                 DebugEvent[] eventSet = null;
91                 Object JavaDoc data = null;
92                 synchronized (LOCK) {
93                     if (fEventSetQueue.isEmpty()) {
94                         return Status.OK_STATUS;
95                     }
96                     eventSet = (DebugEvent[]) fEventSetQueue.remove(0);
97                     more = !fEventSetQueue.isEmpty();
98                     data = fDataQueue.remove(0);
99                     if (data == NULL) {
100                         data = null;
101                     }
102                 }
103                 if (isAvailable()) {
104                     if (isViewVisible()) {
105                         doHandleDebugEvents(eventSet, data);
106                     }
107                     updateForDebugEvents(eventSet, data);
108                 }
109                 
110                 if (more) {
111                     long current = System.currentTimeMillis();
112                     if (current - start > TIMEOUT) {
113                         break;
114                     }
115                 }
116             }
117             if (more) {
118                 // re-schedule with a delay if there are still events to process
119
schedule(50);
120             }
121             return Status.OK_STATUS;
122         }
123         
124     }
125     /**
126      * Constructs an event handler for the given view.
127      *
128      * @param view debug view
129      */

130     public AbstractDebugEventHandler(AbstractDebugView view) {
131         setView(view);
132         DebugPlugin plugin= DebugPlugin.getDefault();
133         plugin.addDebugEventListener(this);
134     }
135
136     /**
137      * @see IDebugEventSetListener#handleDebugEvents(DebugEvent[])
138      */

139     public void handleDebugEvents(DebugEvent[] events) {
140         if (!isAvailable()) {
141             return;
142         }
143         // filter events
144
events = filterEvents(events);
145         if (events.length == 0) {
146             return;
147         }
148         synchronized (LOCK) {
149             events = doPreprocessEvents(events);
150             if (events.length == 0) {
151                 return;
152             }
153             // add the event set to the queue and schedule update
154
fEventSetQueue.add(events);
155             if (fDataQueue.size() < fEventSetQueue.size()) {
156                 fDataQueue.add(NULL);
157             }
158         }
159         fUpdateJob.schedule();
160     }
161     
162     protected void queueData(Object JavaDoc data) {
163         synchronized (LOCK) {
164             fDataQueue.add(data);
165         }
166     }
167     
168     protected DebugEvent[] doPreprocessEvents(DebugEvent[] events) {
169         return events;
170     }
171     
172     /**
173      * Filters the given events before processing.
174      *
175      * @param events event set received for processing
176      * @return events to be processed
177      */

178     protected DebugEvent[] filterEvents(DebugEvent[] events) {
179         return events;
180     }
181     
182     /**
183      * Updates this view for the given debug events. Unlike
184      * doHandleDebugEvents(DebugEvent[]) which is only called if the view is
185      * visible, this method is always called. This allows the view to perform
186      * updating that must always be performed, even when the view is not
187      * visible.
188      */

189     protected void updateForDebugEvents(DebugEvent[] events, Object JavaDoc data) {
190     }
191     
192     /**
193      * Implementation specific handling of debug events.
194      * Subclasses should override.
195      */

196     protected abstract void doHandleDebugEvents(DebugEvent[] events, Object JavaDoc data);
197         
198     /**
199      * Helper method for inserting the given element - must be called in UI thread
200      */

201     protected void insert(Object JavaDoc element) {
202         if (isAvailable()) {
203             Object JavaDoc parent= ((ITreeContentProvider)getTreeViewer().getContentProvider()).getParent(element);
204             // a parent can be null for a debug target or process that has not yet been associated
205
// with a launch
206
if (parent != null) {
207                 getView().showViewer();
208                 getTreeViewer().add(parent, element);
209             }
210         }
211     }
212
213     /**
214      * Helper method to remove the given element - must be called in UI thread.
215      */

216     protected void remove(Object JavaDoc element) {
217         if (isAvailable()) {
218             getView().showViewer();
219             getTreeViewer().remove(element);
220         }
221     }
222
223     /**
224      * Helper method to update the label of the given element - must be called in UI thread
225      */

226     protected void labelChanged(Object JavaDoc element) {
227         if (isAvailable()) {
228             getView().showViewer();
229             getTreeViewer().update(element, new String JavaDoc[] {IBasicPropertyConstants.P_TEXT});
230         }
231     }
232
233     /**
234      * Refresh the given element in the viewer - must be called in UI thread.
235      */

236     protected void refresh(Object JavaDoc element) {
237         if (isAvailable()) {
238              getView().showViewer();
239              getTreeViewer().refresh(element);
240         }
241     }
242     
243     /**
244      * Refresh the viewer - must be called in UI thread.
245      */

246     public void refresh() {
247         if (isAvailable()) {
248              getView().showViewer();
249              getTreeViewer().refresh();
250         }
251     }
252
253     /**
254      * Helper method to select and reveal the given element - must be called in UI thread
255      */

256     protected void selectAndReveal(Object JavaDoc element) {
257         if (isAvailable()) {
258             getViewer().setSelection(new StructuredSelection(element), true);
259         }
260     }
261     
262     /**
263      * De-registers this event handler from the debug model.
264      */

265     public void dispose() {
266         DebugPlugin plugin= DebugPlugin.getDefault();
267         plugin.removeDebugEventListener(this);
268         synchronized (LOCK) {
269             fEventSetQueue.clear();
270             fDataQueue.clear();
271         }
272     }
273     
274     /**
275      * Returns the view this event handler is
276      * updating.
277      *
278      * @return debug view
279      */

280     protected AbstractDebugView getView() {
281         return fView;
282     }
283     
284     /**
285      * Sets the view this event handler is updating.
286      *
287      * @param view debug view
288      */

289     private void setView(AbstractDebugView view) {
290         fView = view;
291     }
292
293     /**
294      * Returns the viewer this event handler is
295      * updating.
296      *
297      * @return viewer
298      */

299     protected Viewer getViewer() {
300         return getView().getViewer();
301     }
302     
303     /**
304      * Returns this event handler's viewer as a tree
305      * viewer or <code>null</code> if none.
306      *
307      * @return this event handler's viewer as a tree
308      * viewer or <code>null</code> if none
309      */

310     protected TreeViewer getTreeViewer() {
311         if (getViewer() instanceof TreeViewer) {
312             return (TreeViewer)getViewer();
313         }
314         return null;
315     }
316     
317     /**
318      * Returns whether this event handler's viewer is
319      * currently available.
320      *
321      * @return whether this event handler's viewer is
322      * currently available
323      */

324     protected boolean isAvailable() {
325         return getView().isAvailable();
326     }
327     
328     /**
329      * Returns whether this event handler's view is currently visible.
330      *
331      * @return whether this event handler's view is currently visible
332      */

333     protected boolean isViewVisible() {
334         return getView().isVisible();
335     }
336     
337     /**
338      * Called when this event handler's view becomes visible. Default behavior
339      * is to refresh the view.
340      */

341     protected void viewBecomesVisible() {
342         refresh();
343     }
344     
345     /**
346      * Called when this event handler's view becomes hidden. Default behavior is
347      * to do nothing. Subclasses may override.
348      */

349     protected void viewBecomesHidden() {
350     }
351 }
352
353
Popular Tags