/******************************************************************************* * Copyright (c) 2000, 2008 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.debug.core; import java.util.EventObject; import org.eclipse.debug.internal.core.DebugCoreMessages; /** * A debug event describes an event in a program being debugged or * in a running process. Debug models and process implementations * are required to generate debug events as specified by this class. *
* The following list defines the events generated for each debug
* model element.
* The getSource()
method of a debug event
* returns the element associated with the event.
* Creation events are guaranteed to occur in a top
* down order - that is, parents are created before children.
* Termination events are guaranteed to occur in a bottom up order -
* that is, children before parents. However, termination events are not guaranteed
* for all elements that are created. That is, terminate events can be coalesced - a
* terminate event for a parent signals that all children have been terminated.
*
* A debug model may define model specific events by specifying a debug event
* kind of MODEL_SPECIFIC
. A model specific event is identified by the
* event source (i.e. by the debug model that generated the event). The detail of
* a model specific event is client defined. Note that model specific events are
* not understood by the debug platform, and are thus ignored.
*
* The generic CHANGE
event can be fired at any time by any element.
* Generally, a client of a debug model, such as as a UI, can get sufficient
* information to update by listening/responding to the other event kinds. However,
* if a debug model needs to inform clients of a change that is not specified
* by create/terminate/suspend/resume, the CHANGE
event may be used.
* For example, generally, the only way a thread or any of its children can change
* state between a suspend and resume operation, is if the thread or owning debug
* target is terminated. However, if a debug model supports some other operation
* that would allow a debug element to change state while suspended, the debug model
* would fire a change event for that element. The valid detail codes for a
* change event are:
STATE
- indicates the state of an element has changed, but its
* children are not affected. A client would use a state change event to update
* a label of the affected element, but would not update any children.CONTENT
- indicates that a debug element's value or contents have
* changed in some way. For example, when the value of a variable is changed
* explicitly, the variable should fire a content change event.IProcess
* CREATE
- a process has been created and is executing.TERMINATE
- a process has terminated.IDebugTarget
* CREATE
- a debug target has been created and is ready
* to begin a debug session.TERMINATE
- a debug target has terminated and the debug
* session has ended.SUSPEND
- a debug target has suspended. Event detail provides
* the reason for the suspension:STEP_END
- a request to step has completedBREAKPOINT
- a breakpoint has been hitCLIENT_REQUEST
- a client request has caused the target to suspend
* (i.e. an explicit call to suspend()
)UNSPECIFIED
- the reason for the suspend is not specifiedRESUME
- a debug target has resumed. Event detail provides
* the reason for the resume:STEP_INTO
- a target is being resumed because of a request to step intoSTEP_OVER
- a target is being resumed because of a request to step overSTEP_RETURN
- a target is being resumed because of a request to step returnCLIENT_REQUEST
- a client request has caused the target to be resumed
* (i.e. an explicit call to resume()
)UNSPECIFIED
- The reason for the resume is not specifiedIThread
* CREATE
- a thread has been created in a debug target.TERMINATE
- a thread has terminated.SUSPEND
- a thread has suspended execution. Event detail provides
* the reason for the suspension:STEP_END
- a request to step has completedBREAKPOINT
- a breakpoint has been hitCLIENT_REQUEST
- a client request has caused the thread to suspend
* (i.e. an explicit call to suspend()
)EVALUATION
- an expression evaluation has ended that may
* have had side effects in the debug target.EVALUATION_IMPLICIT
- an expression evaluation has ended that
* had no side effects in the debug target.UNSPECIFIED
- the reason for the suspend is not specifiedRESUME
- a thread has resumed execution. Event detail provides
* the reason for the resume:STEP_INTO
- a thread is being resumed because of a request to step intoSTEP_OVER
- a thread is being resumed because of a request to step overSTEP_RETURN
- a thread is being resumed because of a request to step returnCLIENT_REQUEST
- a client request has caused the thread to be resumed
* (i.e. an explicit call to resume()
)EVALUATION
- an expression evaluation has started that may
* have side effects in the debug target.EVALUATION_IMPLICIT
- an expression evaluation has started that
* will have no side effects in the debug target.UNSPECIFIED
- The reason for the resume is not specifiedIStackFrame
- no events are specified for stack frames.
* When a thread is suspended, it has stack frames. When a thread resumes,
* stack frames are unavailable.
* IVariable
- no events are specified for variables.
* When a thread is suspended, stack frames have variables. When a thread resumes,
* variables are unavailable.
* IValue
- no events are specified for values.
* CHANGE
* events.
*
* @since 2.0
*/
public static final int STATE = 0x0100;
/**
* Content change detail. Indicates the content of a debug element
* (and potentially its children) has changed. Only valid for
* CHANGE
events.
*
* @since 2.0
*/
public static final int CONTENT = 0x0200;
/**
* Constant indicating that the kind or detail of a debug
* event is unspecified.
*/
public static final int UNSPECIFIED = 0;
/**
* The kind of event - one of the kind constants defined by
* this class.
*/
private int fKind= UNSPECIFIED;
/**
* The detail of the event - one of the detail constants defined by
* this class.
*/
private int fDetail= UNSPECIFIED;
/**
* Client defined data field.
*
* @since 2.1.2
*/
private Object fData = null;
/**
* Constructs a new debug event of the given kind with a detail code of
* UNSPECIFIED
.
*
* @param eventSource the object associated with the event
* @param kind the kind of debug event (one of the
* kind constants defined by this class)
*/
public DebugEvent(Object eventSource, int kind) {
this(eventSource, kind, UNSPECIFIED);
}
/**
* Constructs a new debug event of the given kind with the given detail.
*
* @param eventSource the object associated with the event
* @param kind the kind of debug event (one of the
* kind constants defined by this class)
* @param detail extra information about the event (one of the
* detail constants defined by this class or a client defined detail if this is a model specific event)
*/
public DebugEvent(Object eventSource, int kind, int detail) {
super(eventSource);
if ((kind & (RESUME | SUSPEND | CREATE | TERMINATE | CHANGE | MODEL_SPECIFIC)) == 0)
throw new IllegalArgumentException(DebugCoreMessages.DebugEvent_illegal_kind);
if (kind != MODEL_SPECIFIC && detail != UNSPECIFIED && (detail & (STEP_END | STEP_INTO | STEP_OVER | STEP_RETURN | BREAKPOINT | CLIENT_REQUEST |EVALUATION | EVALUATION_IMPLICIT | STATE | CONTENT)) == 0)
throw new IllegalArgumentException(DebugCoreMessages.DebugEvent_illegal_detail);
fKind= kind;
fDetail= detail;
}
/**
* Returns a constant describing extra detail about the event - either one
* of the detail constants defined by this class, possibly
* UNSPECIFIED
, or a client defined detail if this is a model specific event.
*
* @return the detail code
*/
public int getDetail() {
return fDetail;
}
/**
* Returns this event's kind - one of the kind constants defined by this class.
*
* @return the kind code
*/
public int getKind() {
return fKind;
}
/**
* Returns whether this event's detail indicates the
* beginning of a step event. This event's detail is one
* of STEP_INTO
, STEP_OVER
, or
* STEP_RETURN
.
*
* @return whether this event's detail indicates the beginning
* of a step event.
* @since 2.0
*/
public boolean isStepStart() {
return (getDetail() & (STEP_INTO | STEP_OVER | STEP_RETURN)) > 0;
}
/**
* Returns whether this event's detail indicates an
* evaluation. This event's detail is one
* of EVALUATION
, or EVALUATION_IMPLICIT
.
*
* @return whether this event's detail indicates an evaluation.
* @since 2.0
*/
public boolean isEvaluation() {
return (getDetail() & (EVALUATION | EVALUATION_IMPLICIT)) > 0;
}
/**
* Sets this event's application defined data.
*
* @param data application defined data
* @since 2.1.2
*/
public void setData(Object data) {
fData = data;
}
/**
* Returns this event's application defined data, or null
if none
*
* @return application defined data, or null
if none
* @since 2.1.2
*/
public Object getData() {
return fData;
}
/**
* @see java.lang.Object#toString()
*/
public String toString() {
StringBuffer buf = new StringBuffer("DebugEvent["); //$NON-NLS-1$
if (getSource() != null) {
buf.append(getSource().toString());
} else {
buf.append("null"); //$NON-NLS-1$
}
buf.append(", "); //$NON-NLS-1$
switch (getKind()) {
case CREATE:
buf.append("CREATE"); //$NON-NLS-1$
break;
case TERMINATE:
buf.append("TERMINATE"); //$NON-NLS-1$
break;
case RESUME:
buf.append("RESUME"); //$NON-NLS-1$
break;
case SUSPEND:
buf.append("SUSPEND"); //$NON-NLS-1$
break;
case CHANGE:
buf.append("CHANGE"); //$NON-NLS-1$
break;
case UNSPECIFIED:
buf.append("UNSPECIFIED"); //$NON-NLS-1$
break;
case MODEL_SPECIFIC:
buf.append("MODEL_SPECIFIC"); //$NON-NLS-1$
break;
}
buf.append(", "); //$NON-NLS-1$
switch (getDetail()) {
case BREAKPOINT:
buf.append("BREAKPOINT"); //$NON-NLS-1$
break;
case CLIENT_REQUEST:
buf.append("CLIENT_REQUEST"); //$NON-NLS-1$
break;
case STEP_END:
buf.append("STEP_END"); //$NON-NLS-1$
break;
case STEP_INTO:
buf.append("STEP_INTO"); //$NON-NLS-1$
break;
case STEP_OVER:
buf.append("STEP_OVER"); //$NON-NLS-1$
break;
case STEP_RETURN:
buf.append("STEP_RETURN"); //$NON-NLS-1$
break;
case EVALUATION:
buf.append("EVALUATION"); //$NON-NLS-1$
break;
case EVALUATION_IMPLICIT:
buf.append("EVALUATION_IMPLICIT"); //$NON-NLS-1$
break;
case STATE:
buf.append("STATE"); //$NON-NLS-1$
break;
case CONTENT:
buf.append("CONTENT"); //$NON-NLS-1$
break;
case UNSPECIFIED:
buf.append("UNSPECIFIED"); //$NON-NLS-1$
break;
default:
// model specific
buf.append(getDetail());
break;
}
buf.append("]"); //$NON-NLS-1$
return buf.toString();
}
}