Merge from mainline.
[official-gcc.git] / libjava / classpath / gnu / classpath / jdwp / event / EventManager.java
blobeb0c3ddb7d254b07d15971aba43eca675da682b6
1 /* EventManager.java -- event management and notification infrastructure
2 Copyright (C) 2005 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)
9 any later version.
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
19 02110-1301 USA.
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
24 combination.
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.VMVirtualMachine;
43 import gnu.classpath.jdwp.exception.InvalidEventTypeException;
44 import gnu.classpath.jdwp.exception.JdwpException;
46 import java.util.Collection;
47 import java.util.Hashtable;
48 import java.util.Iterator;
50 /**
51 * Manages event requests and filters event notifications.
53 * The purpose of this class is actually two-fold:
55 * 1) Maintain a list of event requests from the debugger
56 * 2) Filter event notifications from the VM
58 * If an event request arrives from the debugger, the back-end will
59 * call {@link #requestEvent}, which will first check for a valid event.
60 * If it is valid, <code>EventManager</code> will record the request
61 * internally and register the event with the virtual machine, which may
62 * choose to handle the request itself (as is likely the case with
63 * breakpoints and other execution-related events), or it may decide to
64 * allow the <code>EventManager</code> to handle notifications and all
65 * filtering (which is convenient for other events such as class (un)loading).
67 * @author Keith Seitz (keiths@redhat.com)
69 public class EventManager
71 // Single instance
72 private static EventManager _instance = new EventManager ();
74 // maps event (EVENT_*) to lists of EventRequests
75 private Hashtable _requests = null;
77 /**
78 * Returns an instance of the event manager
80 * @return the event manager
82 public static EventManager getDefault ()
84 return _instance;
87 // Private constructs a new <code>EventManager</code>
88 private EventManager ()
90 _requests = new Hashtable ();
92 // Add lists for all the event types
93 _requests.put (new Byte (EventRequest.EVENT_SINGLE_STEP),
94 new Hashtable ());
95 _requests.put (new Byte (EventRequest.EVENT_BREAKPOINT),
96 new Hashtable ());
97 _requests.put (new Byte (EventRequest.EVENT_FRAME_POP),
98 new Hashtable ());
99 _requests.put (new Byte (EventRequest.EVENT_EXCEPTION),
100 new Hashtable ());
101 _requests.put (new Byte (EventRequest.EVENT_USER_DEFINED),
102 new Hashtable ());
103 _requests.put (new Byte (EventRequest.EVENT_THREAD_START),
104 new Hashtable ());
105 _requests.put (new Byte (EventRequest.EVENT_THREAD_END),
106 new Hashtable ());
107 _requests.put (new Byte (EventRequest.EVENT_CLASS_PREPARE),
108 new Hashtable ());
109 _requests.put (new Byte (EventRequest.EVENT_CLASS_UNLOAD),
110 new Hashtable ());
111 _requests.put (new Byte (EventRequest.EVENT_CLASS_LOAD),
112 new Hashtable ());
113 _requests.put (new Byte (EventRequest.EVENT_FIELD_ACCESS),
114 new Hashtable ());
115 _requests.put (new Byte (EventRequest.EVENT_FIELD_MODIFY),
116 new Hashtable ());
117 _requests.put (new Byte (EventRequest.EVENT_METHOD_ENTRY),
118 new Hashtable ());
119 _requests.put (new Byte (EventRequest.EVENT_METHOD_EXIT),
120 new Hashtable ());
121 _requests.put (new Byte (EventRequest.EVENT_VM_INIT),
122 new Hashtable ());
123 _requests.put (new Byte (EventRequest.EVENT_VM_DEATH),
124 new Hashtable ());
126 // Add auto-generated event notifications
127 // only two: VM_INIT, VM_DEATH
130 requestEvent (new EventRequest (0,
131 EventRequest.EVENT_VM_INIT,
132 EventRequest.SUSPEND_NONE));
133 requestEvent (new EventRequest (0,
134 EventRequest.EVENT_VM_DEATH,
135 EventRequest.SUSPEND_NONE));
137 catch (JdwpException e)
139 // This can't happen
144 * Returns a request for the given event. This method will only
145 * be used if the <code>EventManager</code> is handling event filtering.
147 * @param event the event
148 * @return request that was interested in this event
149 * or <code>null</code> if none (and event should not be sent)
150 * @throws IllegalArgumentException for invalid event kind
152 public EventRequest getEventRequest (Event event)
154 EventRequest interestedRequest = null;
155 Hashtable requests;
156 Byte kind = new Byte (event.getEventKind ());
157 requests = (Hashtable) _requests.get (kind);
158 if (requests == null)
160 // Did not get a valid event type
161 throw new IllegalArgumentException ("invalid event kind: " + kind);
163 boolean match = false;
165 // Loop through the requests. Must look at ALL requests in order
166 // to evaluate all filters (think count filter).
167 // TODO: What if multiple matches? Spec isn't so clear on this.
168 Iterator rIter = requests.values().iterator ();
169 while (rIter.hasNext ())
171 EventRequest request = (EventRequest) rIter.next ();
172 if (request.matches (event))
173 interestedRequest = request;
176 return interestedRequest;
180 * Requests monitoring of an event.
182 * The debugger registers for event notification through
183 * an event filter. If no event filter is specified for an event
184 * in the VM, it is assumed that the debugger is not interested in
185 * receiving notifications of this event.
187 * The virtual machine will be notified of the request.
189 * @param request the request to monitor
190 * @throws InvalidEventTypeException for invalid event kind
191 * @throws JdwpException for other errors involving request
193 public void requestEvent (EventRequest request)
194 throws JdwpException
196 // Add request to request list
197 Hashtable requests;
198 Byte kind = new Byte (request.getEventKind ());
199 requests = (Hashtable) _requests.get (kind);
200 if (requests == null)
202 // Did not get a valid event type
203 throw new InvalidEventTypeException (request.getEventKind ());
206 // Register the event with the VM
207 VMVirtualMachine.registerEvent (request);
208 requests.put (new Integer (request.getId ()), request);
212 * Deletes the given request from the management table
214 * @param kind the event kind
215 * @param id the ID of the request to delete
216 * @throws IllegalArgumentException for invalid event kind
217 * @throws JdwpException for other errors deleting request
219 public void deleteRequest (byte kind, int id)
220 throws JdwpException
222 Hashtable requests;
223 requests = (Hashtable) _requests.get (new Byte (kind));
224 if (requests == null)
226 // Did not get a valid event type
227 throw new IllegalArgumentException ("invalid event kind: " + kind);
230 Integer iid = new Integer (id);
231 EventRequest request = (EventRequest) requests.get (iid);
232 if (request != null)
234 VMVirtualMachine.unregisterEvent (request);
235 requests.remove (iid);
240 * Clears all the requests for a given event
242 * @param kind the event kind
243 * @throws IllegalArgumentException for invalid event kind
244 * @throws JdwpException for error clearing events
246 public void clearRequests (byte kind)
247 throws JdwpException
249 Hashtable requests = (Hashtable) _requests.get (new Byte (kind));
250 if (requests == null)
252 // Did not get a valid event type
253 throw new IllegalArgumentException ("invalid event kind: " + kind);
256 VMVirtualMachine.clearEvents (kind);
257 requests.clear ();
261 * Returns a given event request for an event
263 * @param kind the kind of event for the request
264 * @param id the integer request id to return
265 * @return the request for the given event kind with the given id
266 * (or <code>null</code> if not found)
267 * @throws IllegalArgumentException for invalid event kind
269 public EventRequest getRequest (byte kind, int id)
271 Hashtable requests = (Hashtable) _requests.get (new Byte (kind));
272 if (requests == null)
274 // Did not get a valid event type
275 throw new IllegalArgumentException ("invalid event kind: " + kind);
278 return (EventRequest) requests.get (new Integer (id));
282 * Returns all requests of the given event kind
284 * @param kind the event kind
285 * @returns a <code>Collection</code> of all the registered requests
286 * @throws IllegalArgumentException for invalid event kind
288 public Collection getRequests (byte kind)
290 Hashtable requests = (Hashtable) _requests.get (new Byte (kind));
291 if (requests == null)
293 // Did not get a valid event type
294 throw new IllegalArgumentException ("invalid event kind: " + kind);
297 return requests.values ();