KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > tools > example > debug > tty > EventHandler


1 /*
2  * @(#)EventHandler.java 1.37 05/11/17
3  *
4  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7 /*
8  * Copyright (c) 1997-1999 by Sun Microsystems, Inc. All Rights Reserved.
9  *
10  * Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
11  * modify and redistribute this software in source and binary code form,
12  * provided that i) this copyright notice and license appear on all copies of
13  * the software; and ii) Licensee does not utilize the software in a manner
14  * which is disparaging to Sun.
15  *
16  * This software is provided "AS IS," without a warranty of any kind. ALL
17  * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
18  * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
19  * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
20  * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
21  * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
22  * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
23  * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
24  * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
25  * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGES.
27  *
28  * This software is not designed or intended for use in on-line control of
29  * aircraft, air traffic, aircraft navigation or aircraft communications; or in
30  * the design, construction, operation or maintenance of any nuclear
31  * facility. Licensee represents and warrants that it will not use or
32  * redistribute the Software for such purposes.
33  */

34
35 package com.sun.tools.example.debug.tty;
36
37 import com.sun.jdi.*;
38 import com.sun.jdi.event.*;
39 import com.sun.jdi.request.EventRequestManager;
40 import com.sun.jdi.request.EventRequest;
41
42 import java.io.PrintStream JavaDoc;
43 import java.util.StringTokenizer JavaDoc;
44 import java.util.Collection JavaDoc;
45 import java.util.Iterator JavaDoc;
46
47 public class EventHandler implements Runnable JavaDoc {
48
49     EventNotifier notifier;
50     Thread JavaDoc thread;
51     volatile boolean connected = true;
52     boolean completed = false;
53     String JavaDoc shutdownMessageKey;
54     boolean stopOnVMStart;
55
56     EventHandler(EventNotifier notifier, boolean stopOnVMStart) {
57         this.notifier = notifier;
58         this.stopOnVMStart = stopOnVMStart;
59         this.thread = new Thread JavaDoc(this, "event-handler");
60         this.thread.start();
61     }
62
63     synchronized void shutdown() {
64         connected = false; // force run() loop termination
65
thread.interrupt();
66         while (!completed) {
67             try {wait();} catch (InterruptedException JavaDoc exc) {}
68         }
69     }
70
71     public void run() {
72         EventQueue queue = Env.vm().eventQueue();
73         while (connected) {
74             try {
75                 EventSet eventSet = queue.remove();
76                 boolean resumeStoppedApp = false;
77                 EventIterator it = eventSet.eventIterator();
78                 while (it.hasNext()) {
79                     resumeStoppedApp |= !handleEvent(it.nextEvent());
80                 }
81
82                 if (resumeStoppedApp) {
83                     eventSet.resume();
84                 } else if (eventSet.suspendPolicy() == EventRequest.SUSPEND_ALL) {
85                     setCurrentThread(eventSet);
86                     notifier.vmInterrupted();
87                 }
88             } catch (InterruptedException JavaDoc exc) {
89                 // Do nothing. Any changes will be seen at top of loop.
90
} catch (VMDisconnectedException discExc) {
91                 handleDisconnectedException();
92                 break;
93             }
94         }
95         synchronized (this) {
96             completed = true;
97             notifyAll();
98         }
99     }
100
101     private boolean handleEvent(Event event) {
102         notifier.receivedEvent(event);
103
104         if (event instanceof ExceptionEvent) {
105             return exceptionEvent(event);
106         } else if (event instanceof BreakpointEvent) {
107             return breakpointEvent(event);
108         } else if (event instanceof WatchpointEvent) {
109             return fieldWatchEvent(event);
110         } else if (event instanceof StepEvent) {
111             return stepEvent(event);
112         } else if (event instanceof MethodEntryEvent) {
113             return methodEntryEvent(event);
114         } else if (event instanceof MethodExitEvent) {
115             return methodExitEvent(event);
116         } else if (event instanceof ClassPrepareEvent) {
117             return classPrepareEvent(event);
118         } else if (event instanceof ClassUnloadEvent) {
119             return classUnloadEvent(event);
120         } else if (event instanceof ThreadStartEvent) {
121             return threadStartEvent(event);
122         } else if (event instanceof ThreadDeathEvent) {
123             return threadDeathEvent(event);
124         } else if (event instanceof VMStartEvent) {
125             return vmStartEvent(event);
126         } else {
127             return handleExitEvent(event);
128         }
129     }
130
131     private boolean vmDied = false;
132     private boolean handleExitEvent(Event event) {
133         if (event instanceof VMDeathEvent) {
134             vmDied = true;
135             return vmDeathEvent(event);
136         } else if (event instanceof VMDisconnectEvent) {
137             connected = false;
138             if (!vmDied) {
139                 vmDisconnectEvent(event);
140             }
141             Env.shutdown(shutdownMessageKey);
142             return false;
143         } else {
144             throw new InternalError JavaDoc(MessageOutput.format("Unexpected event type",
145                                                          new Object JavaDoc[] {event.getClass()}));
146         }
147     }
148
149     synchronized void handleDisconnectedException() {
150         /*
151          * A VMDisconnectedException has happened while dealing with
152          * another event. We need to flush the event queue, dealing only
153          * with exit events (VMDeath, VMDisconnect) so that we terminate
154          * correctly.
155          */

156         EventQueue queue = Env.vm().eventQueue();
157         while (connected) {
158             try {
159                 EventSet eventSet = queue.remove();
160                 EventIterator iter = eventSet.eventIterator();
161                 while (iter.hasNext()) {
162                     handleExitEvent((Event)iter.next());
163                 }
164             } catch (InterruptedException JavaDoc exc) {
165                 // ignore
166
} catch (InternalError JavaDoc exc) {
167                 // ignore
168
}
169         }
170     }
171
172     private ThreadReference eventThread(Event event) {
173         if (event instanceof ClassPrepareEvent) {
174             return ((ClassPrepareEvent)event).thread();
175         } else if (event instanceof LocatableEvent) {
176             return ((LocatableEvent)event).thread();
177         } else if (event instanceof ThreadStartEvent) {
178             return ((ThreadStartEvent)event).thread();
179         } else if (event instanceof ThreadDeathEvent) {
180             return ((ThreadDeathEvent)event).thread();
181         } else if (event instanceof VMStartEvent) {
182             return ((VMStartEvent)event).thread();
183         } else {
184             return null;
185         }
186     }
187
188     private void setCurrentThread(EventSet set) {
189         ThreadReference thread;
190         if (set.size() > 0) {
191             /*
192              * If any event in the set has a thread associated with it,
193              * they all will, so just grab the first one.
194              */

195             Event event = (Event)set.iterator().next(); // Is there a better way?
196
thread = eventThread(event);
197         } else {
198             thread = null;
199         }
200         setCurrentThread(thread);
201     }
202
203     private void setCurrentThread(ThreadReference thread) {
204         ThreadInfo.invalidateAll();
205         ThreadInfo.setCurrentThread(thread);
206     }
207
208     private boolean vmStartEvent(Event event) {
209         VMStartEvent se = (VMStartEvent)event;
210         notifier.vmStartEvent(se);
211         return stopOnVMStart;
212     }
213
214     private boolean breakpointEvent(Event event) {
215         BreakpointEvent be = (BreakpointEvent)event;
216         notifier.breakpointEvent(be);
217         return true;
218     }
219
220     private boolean methodEntryEvent(Event event) {
221         MethodEntryEvent me = (MethodEntryEvent)event;
222         notifier.methodEntryEvent(me);
223         return true;
224     }
225
226     private boolean methodExitEvent(Event event) {
227         MethodExitEvent me = (MethodExitEvent)event;
228         return notifier.methodExitEvent(me);
229     }
230
231     private boolean fieldWatchEvent(Event event) {
232         WatchpointEvent fwe = (WatchpointEvent)event;
233         notifier.fieldWatchEvent(fwe);
234         return true;
235     }
236
237     private boolean stepEvent(Event event) {
238         StepEvent se = (StepEvent)event;
239         notifier.stepEvent(se);
240         return true;
241     }
242
243     private boolean classPrepareEvent(Event event) {
244         ClassPrepareEvent cle = (ClassPrepareEvent)event;
245         notifier.classPrepareEvent(cle);
246
247         if (!Env.specList.resolve(cle)) {
248             MessageOutput.lnprint("Stopping due to deferred breakpoint errors.");
249             return true;
250         } else {
251             return false;
252         }
253     }
254
255     private boolean classUnloadEvent(Event event) {
256         ClassUnloadEvent cue = (ClassUnloadEvent)event;
257         notifier.classUnloadEvent(cue);
258         return false;
259     }
260
261     private boolean exceptionEvent(Event event) {
262         ExceptionEvent ee = (ExceptionEvent)event;
263         notifier.exceptionEvent(ee);
264         return true;
265     }
266
267     private boolean threadDeathEvent(Event event) {
268         ThreadDeathEvent tee = (ThreadDeathEvent)event;
269         ThreadInfo.removeThread(tee.thread());
270         return false;
271     }
272
273     private boolean threadStartEvent(Event event) {
274         ThreadStartEvent tse = (ThreadStartEvent)event;
275         ThreadInfo.addThread(tse.thread());
276         notifier.threadStartEvent(tse);
277         return false;
278     }
279
280     public boolean vmDeathEvent(Event event) {
281         shutdownMessageKey = "The application exited";
282         notifier.vmDeathEvent((VMDeathEvent)event);
283         return false;
284     }
285
286     public boolean vmDisconnectEvent(Event event) {
287         shutdownMessageKey = "The application has been disconnected";
288         notifier.vmDisconnectEvent((VMDisconnectEvent)event);
289         return false;
290     }
291 }
292
Popular Tags