| /******************************************************************************* |
| * Copyright (c) 2000, 2006 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. |
| * <p> |
| * The following list defines the events generated for each debug |
| * model element. |
| * The <code>getSource()</code> 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. |
| * </p> |
| * <p> |
| * A debug model may define model specific events by specifying a debug event |
| * kind of <code>MODEL_SPECIFIC</code>. 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. |
| * </p> |
| * <p> |
| * The generic <code>CHANGE</code> 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 <code>CHANGE</code> 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:<ul> |
| * <li><code>STATE</code> - 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.</li> |
| * <li><code>CONTENT</code> - 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.</li> |
| * </ul> |
| * </p> |
| * <ul> |
| * <li><code>IProcess</code> |
| * <ul> |
| * <li><code>CREATE</code> - a process has been created and is executing.</li> |
| * <li><code>TERMINATE</code> - a process has terminated.</li> |
| * </ul> |
| * <li><code>IDebugTarget</code> |
| * <ul> |
| * <li><code>CREATE</code> - a debug target has been created and is ready |
| * to begin a debug session.</li> |
| * <li><code>TERMINATE</code> - a debug target has terminated and the debug |
| * session has ended.</li> |
| * <li><code>SUSPEND</code> - a debug target has suspended. Event detail provides |
| * the reason for the suspension:<ul> |
| * <li><code>STEP_END</code> - a request to step has completed</li> |
| * <li><code>BREAKPOINT</code> - a breakpoint has been hit</li> |
| * <li><code>CLIENT_REQUEST</code> - a client request has caused the target to suspend |
| * (i.e. an explicit call to <code>suspend()</code>)</li> |
| * <li><code>UNSPECIFIED</code> - the reason for the suspend is not specified</li> |
| * </ul> |
| * </li> |
| * <li><code>RESUME</code> - a debug target has resumed. Event detail provides |
| * the reason for the resume:<ul> |
| * <li><code>STEP_INTO</code> - a target is being resumed because of a request to step into</li> |
| * <li><code>STEP_OVER</code> - a target is being resumed because of a request to step over</li> |
| * <li><code>STEP_RETURN</code> - a target is being resumed because of a request to step return</li> |
| * <li><code>CLIENT_REQUEST</code> - a client request has caused the target to be resumed |
| * (i.e. an explicit call to <code>resume()</code>)</li> |
| * <li><code>UNSPECIFIED</code> - The reason for the resume is not specified</li> |
| * </ul> |
| * </li> |
| * </ul> |
| * </li> |
| * <li><code>IThread</code> |
| * <ul> |
| * <li><code>CREATE</code> - a thread has been created in a debug target.</li> |
| * <li><code>TERMINATE</code> - a thread has terminated.</li> |
| * <li><code>SUSPEND</code> - a thread has suspended execution. Event detail provides |
| * the reason for the suspension:<ul> |
| * <li><code>STEP_END</code> - a request to step has completed</li> |
| * <li><code>BREAKPOINT</code> - a breakpoint has been hit</li> |
| * <li><code>CLIENT_REQUEST</code> - a client request has caused the thread to suspend |
| * (i.e. an explicit call to <code>suspend()</code>)</li> |
| * <li><code>EVALUATION</code> - an expression evaluation has ended that may |
| * have had side effects in the debug target.</li> |
| * <li><code>EVALUATION_IMPLICIT</code> - an expression evaluation has ended that |
| * had no side effects in the debug target.</li> |
| * <li><code>UNSPECIFIED</code> - the reason for the suspend is not specified</li> |
| * </ul> |
| * </li> |
| * <li><code>RESUME</code> - a thread has resumed execution. Event detail provides |
| * the reason for the resume:<ul> |
| * <li><code>STEP_INTO</code> - a thread is being resumed because of a request to step into</li> |
| * <li><code>STEP_OVER</code> - a thread is being resumed because of a request to step over</li> |
| * <li><code>STEP_RETURN</code> - a thread is being resumed because of a request to step return</li> |
| * <li><code>CLIENT_REQUEST</code> - a client request has caused the thread to be resumed |
| * (i.e. an explicit call to <code>resume()</code>)</li> |
| * <li><code>EVALUATION</code> - an expression evaluation has started that may |
| * have side effects in the debug target.</li> |
| * <li><code>EVALUATION_IMPLICIT</code> - an expression evaluation has started that |
| * will have no side effects in the debug target.</li> |
| * <li><code>UNSPECIFIED</code> - The reason for the resume is not specified</li> |
| * </ul> |
| * </li> |
| * </ul> |
| * </li> |
| * <li><code>IStackFrame</code> - no events are specified for stack frames. |
| * When a thread is suspended, it has stack frames. When a thread resumes, |
| * stack frames are unavailable. |
| * </li> |
| * <li><code>IVariable</code> - no events are specified for variables. |
| * When a thread is suspended, stack frames have variables. When a thread resumes, |
| * variables are unavailable. |
| * </li> |
| * <li><code>IValue</code> - no events are specified for values. |
| * </li> |
| * </ul> |
| * <p> |
| * Clients may instantiate this class. Clients are not intended to subclass this class. |
| * </p> |
| * |
| */ |
| public final class DebugEvent extends EventObject { |
| |
| /** |
| * All objects that can be serialized should have a stable serialVersionUID |
| */ |
| private static final long serialVersionUID = 1L; |
| |
| /** |
| * Resume event kind. |
| */ |
| public static final int RESUME= 0x0001; |
| |
| /** |
| * Suspend event kind. |
| */ |
| public static final int SUSPEND= 0x0002; |
| |
| /** |
| * Create event kind. |
| */ |
| public static final int CREATE= 0x0004; |
| |
| /** |
| * Terminate event kind. |
| */ |
| public static final int TERMINATE= 0x0008; |
| |
| /** |
| * Change event kind. |
| */ |
| public static final int CHANGE= 0x0010; |
| |
| /** |
| * Model specific event kind. The detail codes |
| * for a model specific event are client defined. |
| * |
| * @since 2.1.2 |
| */ |
| public static final int MODEL_SPECIFIC= 0x0020; |
| |
| /** |
| * Step start detail. Indicates a thread was resumed by a step |
| * into action. |
| * @since 2.0 |
| */ |
| public static final int STEP_INTO= 0x0001; |
| |
| /** |
| * Step start detail. Indicates a thread was resumed by a step |
| * over action. |
| * @since 2.0 |
| */ |
| public static final int STEP_OVER= 0x0002; |
| |
| /** |
| * Step start detail. Indicates a thread was resumed by a step |
| * return action. |
| * @since 2.0 |
| */ |
| public static final int STEP_RETURN= 0x0004; |
| |
| /** |
| * Step end detail. Indicates a thread was suspended due |
| * to the completion of a step action. |
| */ |
| public static final int STEP_END= 0x0008; |
| |
| /** |
| * Breakpoint detail. Indicates a thread was suspended by |
| * a breakpoint. |
| */ |
| public static final int BREAKPOINT= 0x0010; |
| |
| /** |
| * Client request detail. Indicates a thread was suspended due |
| * to a client request. |
| */ |
| public static final int CLIENT_REQUEST= 0x0020; |
| |
| /** |
| * Evaluation detail. Indicates that a thread was resumed or |
| * suspended to perform an expression evaluation. |
| * |
| * @since 2.0 |
| */ |
| public static final int EVALUATION = 0x0040; |
| |
| /** |
| * Evaluation detail. Indicates that a thread was resumed or |
| * suspended to perform an implicit expression evaluation. |
| * An implicit evaluation is an evaluation that is performed |
| * as an indirect result of a user action. |
| * Clients may use this detail event to decide whether or not |
| * to alert the user that an evaluation is taking place.. |
| * |
| * @since 2.0 |
| */ |
| public static final int EVALUATION_IMPLICIT = 0x0080; |
| |
| /** |
| * State change detail. Indicates the state of a single |
| * debug element has changed. Only valid for <code>CHANGE</code> |
| * 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 |
| * <code>CHANGE</code> 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 |
| * <code>UNSPECIFIED</code>. |
| * |
| * @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 |
| * <code>UNSPECIFIED</code>, 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 <code>STEP_INTO</code>, <code>STEP_OVER</code>, or |
| * <code>STEP_RETURN</code>. |
| * |
| * @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 <code>EVALUATION</code>, or <code>EVALUATION_IMPLICIT</code>. |
| * |
| * @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 <code>null</code> if none |
| * |
| * @return application defined data, or <code>null</code> 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(); |
| } |
| } |
| |