1 /*******************************************************************************
2  * Copyright (c) 2000, 2013 IBM Corporation and others.
3  *
4  * This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * which accompanies this distribution, and is available at
7  * https://www.eclipse.org/legal/epl-2.0/
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors:
12  *     IBM Corporation - initial API and implementation
13  *******************************************************************************/
14 package org.eclipse.debug.core;
15 
16 
17 import java.util.EventObject;
18 
19 import org.eclipse.debug.internal.core.DebugCoreMessages;
20 
21 /**
22  * A debug event describes an event in a program being debugged or in a running
23  * process. Debug models and process implementations are required to generate
24  * debug events as specified by this class.
25  * <p>
26  * The following list defines the events generated for each debug model element.
27  * The <code>getSource()</code> method of a debug event returns the element
28  * associated with the event. Creation events are guaranteed to occur in a top
29  * down order - that is, parents are created before children. Termination events
30  * are guaranteed to occur in a bottom up order - that is, children before
31  * parents. However, termination events are not guaranteed for all elements that
32  * are created. That is, terminate events can be coalesced - a terminate event
33  * for a parent signals that all children have been terminated.
34  * </p>
35  * <p>
36  * A debug model may define model specific events by specifying a debug event
37  * kind of <code>MODEL_SPECIFIC</code>. A model specific event is identified by
38  * the event source (i.e. by the debug model that generated the event). The
39  * detail of a model specific event is client defined. Note that model specific
40  * events are not understood by the debug platform, and are thus ignored.
41  * </p>
42  * <p>
43  * The generic <code>CHANGE</code> event can be fired at any time by any
44  * element. Generally, a client of a debug model, such as as a UI, can get
45  * sufficient information to update by listening/responding to the other event
46  * kinds. However, if a debug model needs to inform clients of a change that is
47  * not specified by create/terminate/suspend/resume, the <code>CHANGE</code>
48  * event may be used. For example, generally, the only way a thread or any of
49  * its children can change state between a suspend and resume operation, is if
50  * the thread or owning debug target is terminated. However, if a debug model
51  * supports some other operation that would allow a debug element to change
52  * state while suspended, the debug model would fire a change event for that
53  * element. The valid detail codes for a change event are:
54  * </p>
55  * <ul>
56  * <li><code>STATE</code> - indicates the state of an element has changed, but
57  * its children are not affected. A client would use a state change event to
58  * update a label of the affected element, but would not update any
59  * children.</li>
60  * <li><code>CONTENT</code> - indicates that a debug element's value or contents
61  * have changed in some way. For example, when the value of a variable is
62  * changed explicitly, the variable should fire a content change event.</li>
63  * </ul>
64  *
65  * <ul>
66  * <li><code>IProcess</code>
67  * <ul>
68  * <li><code>CREATE</code> - a process has been created and is executing.</li>
69  * <li><code>TERMINATE</code> - a process has terminated.</li>
70  * </ul>
71  * <li><code>IDebugTarget</code>
72  * <ul>
73  * <li><code>CREATE</code> - a debug target has been created and is ready to
74  * begin a debug session.</li>
75  * <li><code>TERMINATE</code> - a debug target has terminated and the debug
76  * session has ended.</li>
77  * <li><code>SUSPEND</code> - a debug target has suspended. Event detail
78  * provides the reason for the suspension:
79  * <ul>
80  * <li><code>STEP_END</code> - a request to step has completed</li>
81  * <li><code>BREAKPOINT</code> - a breakpoint has been hit</li>
82  * <li><code>CLIENT_REQUEST</code> - a client request has caused the target to
83  * suspend (i.e. an explicit call to <code>suspend()</code>)</li>
84  * <li><code>UNSPECIFIED</code> - the reason for the suspend is not
85  * specified</li>
86  * </ul>
87  * </li>
88  * <li><code>RESUME</code> - a debug target has resumed. Event detail provides
89  * the reason for the resume:
90  * <ul>
91  * <li><code>STEP_INTO</code> - a target is being resumed because of a request
92  * to step into</li>
93  * <li><code>STEP_OVER</code> - a target is being resumed because of a request
94  * to step over</li>
95  * <li><code>STEP_RETURN</code> - a target is being resumed because of a request
96  * to step return</li>
97  * <li><code>CLIENT_REQUEST</code> - a client request has caused the target to
98  * be resumed (i.e. an explicit call to <code>resume()</code>)</li>
99  * <li><code>UNSPECIFIED</code> - The reason for the resume is not
100  * specified</li>
101  * </ul>
102  * </li>
103  * </ul>
104  * </li>
105  * <li><code>IThread</code>
106  * <ul>
107  * <li><code>CREATE</code> - a thread has been created in a debug target.</li>
108  * <li><code>TERMINATE</code> - a thread has terminated.</li>
109  * <li><code>SUSPEND</code> - a thread has suspended execution. Event detail
110  * provides the reason for the suspension:
111  * <ul>
112  * <li><code>STEP_END</code> - a request to step has completed</li>
113  * <li><code>BREAKPOINT</code> - a breakpoint has been hit</li>
114  * <li><code>CLIENT_REQUEST</code> - a client request has caused the thread to
115  * suspend (i.e. an explicit call to <code>suspend()</code>)</li>
116  * <li><code>EVALUATION</code> - an expression evaluation has ended that may
117  * have had side effects in the debug target.</li>
118  * <li><code>EVALUATION_IMPLICIT</code> - an expression evaluation has ended
119  * that had no side effects in the debug target.</li>
120  * <li><code>UNSPECIFIED</code> - the reason for the suspend is not
121  * specified</li>
122  * </ul>
123  * </li>
124  * <li><code>RESUME</code> - a thread has resumed execution. Event detail
125  * provides the reason for the resume:
126  * <ul>
127  * <li><code>STEP_INTO</code> - a thread is being resumed because of a request
128  * to step into</li>
129  * <li><code>STEP_OVER</code> - a thread is being resumed because of a request
130  * to step over</li>
131  * <li><code>STEP_RETURN</code> - a thread is being resumed because of a request
132  * to step return</li>
133  * <li><code>CLIENT_REQUEST</code> - a client request has caused the thread to
134  * be resumed (i.e. an explicit call to <code>resume()</code>)</li>
135  * <li><code>EVALUATION</code> - an expression evaluation has started that may
136  * have side effects in the debug target.</li>
137  * <li><code>EVALUATION_IMPLICIT</code> - an expression evaluation has started
138  * that will have no side effects in the debug target.</li>
139  * <li><code>UNSPECIFIED</code> - The reason for the resume is not
140  * specified</li>
141  * </ul>
142  * </li>
143  * </ul>
144  * </li>
145  * <li><code>IStackFrame</code> - no events are specified for stack frames. When
146  * a thread is suspended, it has stack frames. When a thread resumes, stack
147  * frames are unavailable.</li>
148  * <li><code>IVariable</code> - no events are specified for variables. When a
149  * thread is suspended, stack frames have variables. When a thread resumes,
150  * variables are unavailable.</li>
151  * <li><code>IValue</code> - no events are specified for values.</li>
152  * </ul>
153  *
154  */
155 public final class DebugEvent extends EventObject {
156 
157 	/**
158 	 * All objects that can be serialized should have a stable serialVersionUID
159 	 */
160 	private static final long serialVersionUID = 1L;
161 
162 	/**
163 	 * Resume event kind.
164 	 */
165 	public static final int RESUME= 0x0001;
166 
167 	/**
168 	 * Suspend event kind.
169 	 */
170 	public static final int SUSPEND= 0x0002;
171 
172 	/**
173 	 * Create event kind.
174 	 */
175 	public static final int CREATE= 0x0004;
176 
177 	/**
178 	 * Terminate event kind.
179 	 */
180 	public static final int TERMINATE= 0x0008;
181 
182 	/**
183 	 * Change event kind.
184 	 */
185 	public static final int CHANGE= 0x0010;
186 
187 	/**
188 	 * Model specific event kind. The detail codes
189 	 * for a model specific event are client defined.
190 	 *
191 	 * @since 2.1.2
192 	 */
193 	public static final int MODEL_SPECIFIC= 0x0020;
194 
195 	/**
196 	 * Step start detail. Indicates a thread was resumed by a step
197 	 * into action.
198 	 * @since 2.0
199 	 */
200 	public static final int STEP_INTO= 0x0001;
201 
202 	/**
203 	 * Step start detail. Indicates a thread was resumed by a step
204 	 * over action.
205 	 * @since 2.0
206 	 */
207 	public static final int STEP_OVER= 0x0002;
208 
209 	/**
210 	 * Step start detail. Indicates a thread was resumed by a step
211 	 * return action.
212 	 * @since 2.0
213 	 */
214 	public static final int STEP_RETURN= 0x0004;
215 
216 	/**
217 	 * Step end detail. Indicates a thread was suspended due
218 	 * to the completion of a step action.
219 	 */
220 	public static final int STEP_END= 0x0008;
221 
222 	/**
223 	 * Breakpoint detail. Indicates a thread was suspended by
224 	 * a breakpoint.
225 	 */
226 	public static final int BREAKPOINT= 0x0010;
227 
228 	/**
229 	 * Client request detail. Indicates a thread was suspended due
230 	 * to a client request.
231 	 */
232 	public static final int CLIENT_REQUEST= 0x0020;
233 
234 	/**
235 	 * Evaluation detail. Indicates that a thread was resumed or
236 	 * suspended to perform an expression evaluation.
237 	 *
238 	 * @since 2.0
239 	 */
240 	public static final int EVALUATION = 0x0040;
241 
242 	/**
243 	 * Evaluation detail. Indicates that a thread was resumed or
244 	 * suspended to perform an implicit expression evaluation.
245 	 * An implicit evaluation is an evaluation that is performed
246 	 * as an indirect result of a user action.
247 	 * Clients may use this detail event to decide whether or not
248 	 * to alert the user that an evaluation is taking place..
249 	 *
250 	 * @since 2.0
251 	 */
252 	public static final int EVALUATION_IMPLICIT = 0x0080;
253 
254 	/**
255 	 * State change detail. Indicates the state of a single
256 	 * debug element has changed. Only valid for <code>CHANGE</code>
257 	 * events.
258 	 *
259 	 * @since 2.0
260 	 */
261 	public static final int STATE = 0x0100;
262 
263 	/**
264 	 * Content change detail. Indicates the content of a debug element
265 	 * (and potentially its children) has changed. Only valid for
266 	 * <code>CHANGE</code> events.
267 	 *
268 	 * @since 2.0
269 	 */
270 	public static final int CONTENT = 0x0200;
271 
272 	/**
273 	 * Constant indicating that the kind or detail of a debug
274 	 * event is unspecified.
275 	 */
276 	public static final int UNSPECIFIED = 0;
277 
278 	/**
279 	 * The kind of event - one of the kind constants defined by
280 	 * this class.
281 	 */
282 	private int fKind= UNSPECIFIED;
283 
284 	/**
285 	 * The detail of the event - one of the detail constants defined by
286 	 * this class.
287 	 */
288 	private int fDetail= UNSPECIFIED;
289 
290 	/**
291 	 * Client defined data field.
292 	 *
293 	 * @since 2.1.2
294 	 */
295 	private Object fData = null;
296 
297 	/**
298 	 * Constructs a new debug event of the given kind with a detail code of
299 	 * <code>UNSPECIFIED</code>.
300 	 *
301 	 * @param eventSource the object associated with the event
302 	 * @param kind the kind of debug event (one of the
303 	 *	kind constants defined by this class)
304 	 */
DebugEvent(Object eventSource, int kind)305 	public DebugEvent(Object eventSource, int kind) {
306 		this(eventSource, kind, UNSPECIFIED);
307 	}
308 
309 	/**
310 	 * Constructs a new debug event of the given kind with the given detail.
311 	 *
312 	 * @param eventSource the object associated with the event
313 	 * @param kind the kind of debug event (one of the
314 	 *	kind constants defined by this class)
315 	 * @param detail extra information about the event (one of the
316 	 *	detail constants defined by this class or a client defined detail if this is a model specific event)
317 	 */
DebugEvent(Object eventSource, int kind, int detail)318 	public DebugEvent(Object eventSource, int kind, int detail) {
319 		super(eventSource);
320 		if ((kind & (RESUME | SUSPEND | CREATE | TERMINATE | CHANGE | MODEL_SPECIFIC)) == 0) {
321 			throw new IllegalArgumentException(DebugCoreMessages.DebugEvent_illegal_kind);
322 		}
323 		if (kind != MODEL_SPECIFIC && detail != UNSPECIFIED && (detail & (STEP_END | STEP_INTO | STEP_OVER | STEP_RETURN | BREAKPOINT | CLIENT_REQUEST |EVALUATION | EVALUATION_IMPLICIT | STATE | CONTENT)) == 0) {
324 			throw new IllegalArgumentException(DebugCoreMessages.DebugEvent_illegal_detail);
325 		}
326 		fKind= kind;
327 		fDetail= detail;
328 	}
329 
330 	/**
331 	 * Returns a constant describing extra detail about the event - either one
332 	 * of the detail constants defined by this class, possibly
333 	 * <code>UNSPECIFIED</code>, or a client defined detail if this is a model specific event.
334 	 *
335 	 * @return the detail code
336 	 */
getDetail()337 	public int getDetail() {
338 		return fDetail;
339 	}
340 
341 	/**
342 	 * Returns this event's kind - one of the kind constants defined by this class.
343 	 *
344 	 * @return the kind code
345 	 */
getKind()346 	public int getKind() {
347 		return fKind;
348 	}
349 
350 	/**
351 	 * Returns whether this event's detail indicates the
352 	 * beginning of a step event. This event's detail is one
353 	 * of <code>STEP_INTO</code>, <code>STEP_OVER</code>, or
354 	 * <code>STEP_RETURN</code>.
355 	 *
356 	 * @return whether this event's detail indicates the beginning
357 	 *  of a step event.
358 	 * @since 2.0
359 	 */
isStepStart()360 	public boolean isStepStart() {
361 		return (getDetail() & (STEP_INTO | STEP_OVER | STEP_RETURN)) > 0;
362 	}
363 
364 	/**
365 	 * Returns whether this event's detail indicates an
366 	 * evaluation. This event's detail is one
367 	 * of <code>EVALUATION</code>, or <code>EVALUATION_IMPLICIT</code>.
368 	 *
369 	 * @return whether this event's detail indicates an evaluation.
370 	 * @since 2.0
371 	 */
isEvaluation()372 	public boolean isEvaluation() {
373 		return (getDetail() & (EVALUATION | EVALUATION_IMPLICIT)) > 0;
374 	}
375 
376 	/**
377 	 * Sets this event's application defined data.
378 	 *
379 	 * @param data application defined data
380 	 * @since 2.1.2
381 	 */
setData(Object data)382 	public void setData(Object data) {
383 		fData = data;
384 	}
385 
386 	/**
387 	 * Returns this event's application defined data, or <code>null</code> if none
388 	 *
389 	 * @return application defined data, or <code>null</code> if none
390 	 * @since 2.1.2
391 	 */
getData()392 	public Object getData() {
393 		return fData;
394 	}
395 
396 	/**
397 	 * @see java.lang.Object#toString()
398 	 */
399 	@Override
toString()400 	public String toString() {
401 		StringBuilder buf = new StringBuilder("DebugEvent["); //$NON-NLS-1$
402 		if (getSource() != null) {
403 			buf.append(getSource().toString());
404 		} else {
405 			buf.append("null"); //$NON-NLS-1$
406 		}
407 		buf.append(", "); //$NON-NLS-1$
408 		switch (getKind()) {
409 			case CREATE:
410 				buf.append("CREATE"); //$NON-NLS-1$
411 				break;
412 			case TERMINATE:
413 				buf.append("TERMINATE"); //$NON-NLS-1$
414 				break;
415 			case RESUME:
416 				buf.append("RESUME"); //$NON-NLS-1$
417 				break;
418 			case SUSPEND:
419 				buf.append("SUSPEND"); //$NON-NLS-1$
420 				break;
421 			case CHANGE:
422 				buf.append("CHANGE"); //$NON-NLS-1$
423 				break;
424 			case UNSPECIFIED:
425 				buf.append("UNSPECIFIED"); //$NON-NLS-1$
426 				break;
427 			case MODEL_SPECIFIC:
428 				buf.append("MODEL_SPECIFIC"); //$NON-NLS-1$
429 				break;
430 			default:
431 				break;
432 		}
433 		buf.append(", "); //$NON-NLS-1$
434 		switch (getDetail()) {
435 			case BREAKPOINT:
436 				buf.append("BREAKPOINT"); //$NON-NLS-1$
437 				break;
438 			case CLIENT_REQUEST:
439 				buf.append("CLIENT_REQUEST"); //$NON-NLS-1$
440 				break;
441 			case STEP_END:
442 				buf.append("STEP_END"); //$NON-NLS-1$
443 				break;
444 			case STEP_INTO:
445 				buf.append("STEP_INTO"); //$NON-NLS-1$
446 				break;
447 			case STEP_OVER:
448 				buf.append("STEP_OVER"); //$NON-NLS-1$
449 				break;
450 			case STEP_RETURN:
451 				buf.append("STEP_RETURN"); //$NON-NLS-1$
452 				break;
453 			case EVALUATION:
454 				buf.append("EVALUATION"); //$NON-NLS-1$
455 				break;
456 			case EVALUATION_IMPLICIT:
457 				buf.append("EVALUATION_IMPLICIT"); //$NON-NLS-1$
458 				break;
459 			case STATE:
460 				buf.append("STATE"); //$NON-NLS-1$
461 				break;
462 			case CONTENT:
463 				buf.append("CONTENT"); //$NON-NLS-1$
464 				break;
465 			case UNSPECIFIED:
466 				buf.append("UNSPECIFIED"); //$NON-NLS-1$
467 				break;
468 			default:
469 				// model specific
470 				buf.append(getDetail());
471 				break;
472 		}
473 		buf.append("]"); //$NON-NLS-1$
474 		return buf.toString();
475 	}
476 }
477 
478