1 /* EventManager.java -- event management and notification infrastructure
2 Copyright (C) 2005, 2006, 2007 Free Software Foundation
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 terms of your choice, provided that you also meet, for each linked
32 independent module, the terms and conditions of the license of that
33 module. An independent module is a module which is not derived from
34 or based on this library. If you modify this library, you may extend
35 this exception to your version of the library, but you are not
36 obligated to do so. If you do not wish to do so, delete this
37 exception statement from your version. */
40 package gnu.classpath.jdwp.event;
42 import gnu.classpath.jdwp.Jdwp;
43 import gnu.classpath.jdwp.VMVirtualMachine;
44 import gnu.classpath.jdwp.exception.InvalidEventTypeException;
45 import gnu.classpath.jdwp.exception.JdwpException;
47 import java.util.Collection;
48 import java.util.Hashtable;
49 import java.util.Iterator;
52 * Manages event requests and filters event notifications.
54 * The purpose of this class is actually two-fold:
56 * 1) Maintain a list of event requests from the debugger
57 * 2) Filter event notifications from the VM
59 * If an event request arrives from the debugger, the back-end will
60 * call {@link #requestEvent}, which will first check for a valid event.
61 * If it is valid, <code>EventManager</code> will record the request
62 * internally and register the event with the virtual machine, which may
63 * choose to handle the request itself (as is likely the case with
64 * breakpoints and other execution-related events), or it may decide to
65 * allow the <code>EventManager</code> to handle notifications and all
66 * filtering (which is convenient for other events such as class (un)loading).
68 * @author Keith Seitz (keiths@redhat.com)
70 public class EventManager
73 private static EventManager _instance = null;
75 // maps event (EVENT_*) to lists of EventRequests
76 private Hashtable _requests = null;
79 * Returns an instance of the event manager
81 * @return the event manager
83 public static EventManager getDefault()
85 if (_instance == null)
86 _instance = new EventManager();
91 // Private constructs a new <code>EventManager</code>
92 private EventManager ()
94 _requests = new Hashtable ();
96 // Add lists for all the event types
97 _requests.put (new Byte (EventRequest.EVENT_SINGLE_STEP),
99 _requests.put (new Byte (EventRequest.EVENT_BREAKPOINT),
101 _requests.put (new Byte (EventRequest.EVENT_FRAME_POP),
103 _requests.put (new Byte (EventRequest.EVENT_EXCEPTION),
105 _requests.put (new Byte (EventRequest.EVENT_USER_DEFINED),
107 _requests.put (new Byte (EventRequest.EVENT_THREAD_START),
109 _requests.put (new Byte (EventRequest.EVENT_THREAD_END),
111 _requests.put (new Byte (EventRequest.EVENT_CLASS_PREPARE),
113 _requests.put (new Byte (EventRequest.EVENT_CLASS_UNLOAD),
115 _requests.put (new Byte (EventRequest.EVENT_CLASS_LOAD),
117 _requests.put (new Byte (EventRequest.EVENT_FIELD_ACCESS),
119 _requests.put (new Byte (EventRequest.EVENT_FIELD_MODIFY),
121 _requests.put (new Byte (EventRequest.EVENT_METHOD_ENTRY),
123 _requests.put (new Byte (EventRequest.EVENT_METHOD_EXIT),
125 _requests.put (new Byte (EventRequest.EVENT_VM_INIT),
127 _requests.put (new Byte (EventRequest.EVENT_VM_DEATH),
130 // Add auto-generated event notifications
131 // only two: VM_INIT, VM_DEATH
134 byte sp = (Jdwp.suspendOnStartup()
135 ? EventRequest.SUSPEND_THREAD : EventRequest.SUSPEND_NONE);
136 requestEvent (new EventRequest (0,
137 EventRequest.EVENT_VM_INIT, sp));
138 requestEvent (new EventRequest (0,
139 EventRequest.EVENT_VM_DEATH,
140 EventRequest.SUSPEND_NONE));
142 catch (JdwpException e)
149 * Returns a request for the given event. This method will only
150 * be used if the <code>EventManager</code> is handling event filtering.
152 * @param event the event
153 * @return request that was interested in this event
154 * or <code>null</code> if none (and event should not be sent)
155 * @throws IllegalArgumentException for invalid event kind
157 public EventRequest getEventRequest (Event event)
159 EventRequest interestedRequest = null;
161 Byte kind = new Byte (event.getEventKind ());
162 requests = (Hashtable) _requests.get (kind);
163 if (requests == null)
165 // Did not get a valid event type
166 throw new IllegalArgumentException ("invalid event kind: " + kind);
168 boolean match = false;
170 // Loop through the requests. Must look at ALL requests in order
171 // to evaluate all filters (think count filter).
172 // TODO: What if multiple matches? Spec isn't so clear on this.
173 Iterator rIter = requests.values().iterator ();
174 while (rIter.hasNext ())
176 EventRequest request = (EventRequest) rIter.next ();
177 if (request.matches (event))
178 interestedRequest = request;
181 return interestedRequest;
185 * Requests monitoring of an event.
187 * The debugger registers for event notification through
188 * an event filter. If no event filter is specified for an event
189 * in the VM, it is assumed that the debugger is not interested in
190 * receiving notifications of this event.
192 * The virtual machine will be notified of the request.
194 * @param request the request to monitor
195 * @throws InvalidEventTypeException for invalid event kind
196 * @throws JdwpException for other errors involving request
198 public void requestEvent (EventRequest request)
201 // Add request to request list
203 Byte kind = new Byte (request.getEventKind ());
204 requests = (Hashtable) _requests.get (kind);
205 if (requests == null)
207 // Did not get a valid event type
208 throw new InvalidEventTypeException (request.getEventKind ());
211 // Register the event with the VM
212 VMVirtualMachine.registerEvent (request);
213 requests.put (new Integer (request.getId ()), request);
217 * Deletes the given request from the management table
219 * @param kind the event kind
220 * @param id the ID of the request to delete
221 * @throws IllegalArgumentException for invalid event kind
222 * @throws JdwpException for other errors deleting request
224 public void deleteRequest (byte kind, int id)
228 requests = (Hashtable) _requests.get (new Byte (kind));
229 if (requests == null)
231 // Did not get a valid event type
232 throw new IllegalArgumentException ("invalid event kind: " + kind);
235 Integer iid = new Integer (id);
236 EventRequest request = (EventRequest) requests.get (iid);
239 VMVirtualMachine.unregisterEvent (request);
240 requests.remove (iid);
245 * Clears all the requests for a given event
247 * @param kind the event kind
248 * @throws IllegalArgumentException for invalid event kind
249 * @throws JdwpException for error clearing events
251 public void clearRequests (byte kind)
254 Hashtable requests = (Hashtable) _requests.get (new Byte (kind));
255 if (requests == null)
257 // Did not get a valid event type
258 throw new IllegalArgumentException ("invalid event kind: " + kind);
261 VMVirtualMachine.clearEvents (kind);
266 * Returns a given event request for an event
268 * @param kind the kind of event for the request
269 * @param id the integer request id to return
270 * @return the request for the given event kind with the given id
271 * (or <code>null</code> if not found)
272 * @throws IllegalArgumentException for invalid event kind
274 public EventRequest getRequest (byte kind, int id)
276 Hashtable requests = (Hashtable) _requests.get (new Byte (kind));
277 if (requests == null)
279 // Did not get a valid event type
280 throw new IllegalArgumentException ("invalid event kind: " + kind);
283 return (EventRequest) requests.get (new Integer (id));
287 * Returns all requests of the given event kind
289 * @param kind the event kind
290 * @returns a <code>Collection</code> of all the registered requests
291 * @throws IllegalArgumentException for invalid event kind
293 public Collection getRequests (byte kind)
295 Hashtable requests = (Hashtable) _requests.get (new Byte (kind));
296 if (requests == null)
298 // Did not get a valid event type
299 throw new IllegalArgumentException ("invalid event kind: " + kind);
302 return requests.values ();