KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > debug > internal > ui > viewers > update > EventHandlerModelProxy


1 /*******************************************************************************
2  * Copyright (c) 2005, 2006 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.viewers.update;
12
13 import java.util.HashMap JavaDoc;
14 import java.util.Map JavaDoc;
15 import java.util.Timer JavaDoc;
16 import java.util.TimerTask JavaDoc;
17
18 import org.eclipse.debug.core.DebugEvent;
19 import org.eclipse.debug.core.DebugPlugin;
20 import org.eclipse.debug.core.IDebugEventSetListener;
21 import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
22 import org.eclipse.debug.internal.ui.viewers.provisional.AbstractModelProxy;
23
24 /**
25  * @since 3.2
26  */

27 public abstract class EventHandlerModelProxy extends AbstractModelProxy implements IDebugEventSetListener {
28
29     /**
30      * Map of elements to timer tasks
31      */

32     private Map JavaDoc fTimerTasks = new HashMap JavaDoc();
33
34     /**
35      * Timer for timer tasks
36      */

37     private Timer JavaDoc fTimer = new Timer JavaDoc(true);
38
39     /**
40      * Map of event source to resume events with a pending suspend that timed
41      * out.
42      */

43     private Map JavaDoc fPendingSuspends = new HashMap JavaDoc();
44
45     /**
46      * Event handlers for specific elements
47      */

48     private DebugEventHandler[] fHandlers = new DebugEventHandler[0];
49
50     /**
51      * Task used to update an element that resumed for a step or evaluation that
52      * took too long to suspend.
53      */

54     private class PendingSuspendTask extends TimerTask JavaDoc {
55
56         private DebugEvent fEvent;
57
58         private DebugEventHandler fHandler;
59
60         /**
61          * Resume event for which there is a pending suspend.
62          *
63          * @param resume
64          * event
65          */

66         public PendingSuspendTask(DebugEventHandler handler, DebugEvent resume) {
67             fHandler = handler;
68             fEvent = resume;
69         }
70
71         /*
72          * (non-Javadoc)
73          *
74          * @see java.util.TimerTask#run()
75          */

76         public void run() {
77             synchronized (fPendingSuspends) {
78                 fPendingSuspends.put(fEvent.getSource(), fEvent);
79             }
80             dispatchSuspendTimeout(fHandler, fEvent);
81         }
82
83     }
84
85     /**
86      * Adds the given handler to this event update policy.
87      *
88      * @param handler
89      */

90     protected abstract DebugEventHandler[] createEventHandlers();
91
92     public synchronized void dispose() {
93         super.dispose();
94         fTimer.cancel();
95         fTimerTasks.clear();
96         DebugPlugin.getDefault().removeDebugEventListener(this);
97         for (int i = 0; i < fHandlers.length; i++) {
98             DebugEventHandler handler = fHandlers[i];
99             handler.dispose();
100         }
101     }
102
103     public void init(IPresentationContext context) {
104         super.init(context);
105         DebugPlugin.getDefault().addDebugEventListener(this);
106         fHandlers = createEventHandlers();
107     }
108
109     /*
110      * (non-Javadoc)
111      *
112      * @see org.eclipse.debug.core.IDebugEventSetListener#handleDebugEvents(org.eclipse.debug.core.DebugEvent[])
113      */

114     public final void handleDebugEvents(DebugEvent[] events) {
115         if (isDisposed()) {
116             return;
117         }
118         for (int i = 0; i < events.length; i++) {
119             DebugEvent event = events[i];
120             if (containsEvent(event)) {
121                 for (int j = 0; j < fHandlers.length; j++) {
122                     DebugEventHandler handler = fHandlers[j];
123                     if (isDisposed()) {
124                         return;
125                     }
126                     if (handler.handlesEvent(event)) {
127                         switch (event.getKind()) {
128                             case DebugEvent.CREATE:
129                                 dispatchCreate(handler, event);
130                                 break;
131                             case DebugEvent.TERMINATE:
132                                 dispatchTerminate(handler, event);
133                                 break;
134                             case DebugEvent.SUSPEND:
135                                 dispatchSuspend(handler, event);
136                                 break;
137                             case DebugEvent.RESUME:
138                                 dispatchResume(handler, event);
139                                 break;
140                             case DebugEvent.CHANGE:
141                                 dispatchChange(handler, event);
142                                 break;
143                             default:
144                                 dispatchOther(handler, event);
145                                 break;
146                         }
147                     }
148                 }
149             }
150         }
151     }
152
153     protected boolean containsEvent(DebugEvent event) {
154         return true;
155     }
156
157     /**
158      * Dispatches a create event.
159      *
160      * @param event
161      */

162     protected void dispatchCreate(DebugEventHandler handler, DebugEvent event) {
163         handler.handleCreate(event);
164     }
165
166     /**
167      * Dispatches a terminate event.
168      *
169      * @param event
170      */

171     protected void dispatchTerminate(DebugEventHandler handler, DebugEvent event) {
172         handler.handleTerminate(event);
173     }
174
175     /**
176      * Dispatches a suspend event. Subclasses may override.
177      *
178      * @param event
179      */

180     protected void dispatchSuspend(DebugEventHandler handler, DebugEvent event) {
181         // stop timer, if any
182
synchronized (this) {
183             TimerTask JavaDoc task = (TimerTask JavaDoc) fTimerTasks.remove(event.getSource());
184             if (task != null) {
185                 task.cancel();
186             }
187         }
188         DebugEvent resume = null;
189         synchronized (this) {
190             resume = (DebugEvent) fPendingSuspends.remove(event.getSource());
191         }
192         if (resume == null) {
193             handler.handleSuspend(event);
194         } else {
195             handler.handleLateSuspend(event, resume);
196         }
197     }
198
199     /**
200      * Dispatches a resume event. By default, if the resume is for an evaluation
201      * or a step, a timer is started to update the event source if the step or
202      * evaluation takes more than 500ms. Otherwise the source is refreshed.
203      * Subclasses may override.
204      *
205      * @param event
206      */

207     protected void dispatchResume(DebugEventHandler handler, DebugEvent event) {
208         if (event.isEvaluation() || event.isStepStart()) {
209             // start a timer to update if the corresponding suspend does not
210
// come quickly
211
synchronized (this) {
212                 if (!isDisposed()) {
213                     PendingSuspendTask task = new PendingSuspendTask(handler, event);
214                     fTimerTasks.put(event.getSource(), task);
215                     fTimer.schedule(task, 500);
216                 }
217             }
218             if (!isDisposed()) {
219                 handler.handleResumeExpectingSuspend(event);
220             }
221         } else {
222             handler.handleResume(event);
223         }
224     }
225
226     /**
227      * Dispatches a change event.
228      *
229      * @param event
230      */

231     protected void dispatchChange(DebugEventHandler handler, DebugEvent event) {
232         handler.handleChange(event);
233     }
234
235     /**
236      * Dispatches an unknown event.
237      *
238      * @param event
239      */

240     protected void dispatchOther(DebugEventHandler handler, DebugEvent event) {
241         handler.handleOther(event);
242     }
243
244     /**
245      * Notification that a pending suspend event was not received for the given
246      * resume event and handler within the timeout period.
247      *
248      * @param resume
249      * resume event with missing suspend event
250      */

251     protected void dispatchSuspendTimeout(DebugEventHandler handler, DebugEvent resume) {
252         handler.handleSuspendTimeout(resume);
253     }
254     
255     /**
256      * Returns the index of the given element in the list or -1 if
257      * not present.
258      *
259      * @param list
260      * @param element
261      * @return index or -1 if not present
262      */

263     protected int indexOf(Object JavaDoc[] list, Object JavaDoc element) {
264         for (int i = 0; i < list.length; i++) {
265             if (element.equals(list[i])) {
266                 return i;
267             }
268         }
269         return -1;
270     }
271
272 }
273
Popular Tags