/**
* Copyright (c) 2005-2013 by Appcelerator, Inc. All Rights Reserved.
* Licensed under the terms of the Eclipse Public License (EPL).
* Please see the license.txt included with this distribution for details.
* Any modifications to this file must keep this entire header intact.
*/
/*
* Author: atotic
* Created on Mar 23, 2004
*/
package org.python.pydev.debug.model.remote;
import org.eclipse.core.runtime.IStatus;
import org.python.pydev.debug.core.PydevDebugPlugin;
import org.python.pydev.debug.model.AbstractDebugTarget;
import org.python.pydev.shared_core.string.FastStringBuffer;
/**
* Superclass of all debugger commands.
*
* Debugger commands know how to interact with pydevd.py.
* See pydevd.py for protocol information.
*
* Command lifecycle:
* cmd = new Command() // creation
* cmd.getSequence() // get the sequence number of the command
* cmd.getOutgoing() // asks command for outgoing message
* cmd.aboutToSend() // called right before we go on wire
* // by default, if command needs response
* // it gets posted to in the response queue
* if (cmd.needsResponse())
* post the command to response queue, otherwise we are done
* when response arrives:
* if response is an error
* cmd.processResponse()
* else
* cmd.processErrorResponse()
*
*/
public abstract class AbstractDebuggerCommand {
static public final int CMD_RUN = 101;
static public final int CMD_LIST_THREADS = 102;
static public final int CMD_THREAD_CREATED = 103;
static public final int CMD_THREAD_KILL = 104;
static public final int CMD_THREAD_SUSPEND = 105;
static public final int CMD_THREAD_RUN = 106;
static public final int CMD_STEP_INTO = 107;
static public final int CMD_STEP_OVER = 108;
static public final int CMD_STEP_RETURN = 109;
static public final int CMD_GET_VARIABLE = 110;
static public final int CMD_SET_BREAK = 111;
static public final int CMD_REMOVE_BREAK = 112;
static public final int CMD_EVALUATE_EXPRESSION = 113;
static public final int CMD_GET_FRAME = 114;
static public final int CMD_EXEC_EXPRESSION = 115;
static public final int CMD_WRITE_TO_CONSOLE = 116;
static public final int CMD_CHANGE_VARIABLE = 117;
static public final int CMD_RUN_TO_LINE = 118;
static public final int CMD_RELOAD_CODE = 119;
static public final int CMD_GET_COMPLETIONS = 120;
static public final int CMD_CONSOLE_EXEC = 121;
static public final int CMD_ADD_EXCEPTION_BREAK = 122;
static public final int CMD_REMOVE_EXCEPTION_BREAK = 123;
static public final int CMD_LOAD_SOURCE = 124;
static public final int CMD_ADD_DJANGO_EXCEPTION_BREAK = 125;
static public final int CMD_REMOVE_DJANGO_EXCEPTION_BREAK = 126;
static public final int CMD_SET_NEXT_STATEMENT = 127;
static public final int CMD_SMART_STEP_INTO = 128;
static public final int CMD_EXIT = 129;
static public final int CMD_SIGNATURE_CALL_TRACE = 130;
static public final int CMD_SET_PY_EXCEPTION = 131;
static public final int CMD_GET_FILE_CONTENTS = 132;
static public final int CMD_SET_PROPERTY_TRACE = 133;
static public final int CMD_EVALUATE_CONSOLE_EXPRESSION = 134;
static public final int CMD_RUN_CUSTOM_OPERATION = 135;
static public final int CMD_GET_BREAKPOINT_EXCEPTION = 136;
static public final int CMD_STEP_CAUGHT_EXCEPTION = 137;
static public final int CMD_SEND_CURR_EXCEPTION_TRACE = 138;
static public final int CMD_SEND_CURR_EXCEPTION_TRACE_PROCEEDED = 139;
static public final int CMD_IGNORE_THROWN_EXCEPTION_AT = 140;
static public final int CMD_ENABLE_DONT_TRACE = 141;
static public final int CMD_SHOW_RETURN_VALUES = 146;
static public final int CMD_INPUT_REQUESTED = 147;
static public final int CMD_PROCESS_CREATED = 149;
static public final int CMD_ERROR = 901;
static public final int CMD_VERSION = 501;
static public final int CMD_RETURN = 502;
protected AbstractDebugTarget target;
protected ICommandResponseListener responseListener;
int sequence;
public AbstractDebuggerCommand(AbstractDebugTarget debugger) {
this.target = debugger;
this.responseListener = null;
sequence = debugger.getNextSequence();
}
public void setCompletionListener(ICommandResponseListener listener) {
this.responseListener = listener;
}
/**
* @return outgoing message
*/
public abstract String getOutgoing();
/**
* Notification right before the command is sent.
* If subclassed, call super()
*/
public void aboutToSend() {
// if we need a response, put me on the waiting queue
if (needResponse()) {
target.addToResponseQueue(this);
}
}
/**
* Does this command require a response?
*
* This is meant to be overriden by subclasses if they need a response.
*/
public boolean needResponse() {
return false;
}
/**
* returns Sequence #
*/
public final int getSequence() {
return sequence;
}
/**
* Called when command completes, if needResponse was true
*/
public final void processResponse(int cmdCode, String payload) {
if (cmdCode / 100 == 9) {
processErrorResponse(cmdCode, payload);
} else {
processOKResponse(cmdCode, payload);
}
if (responseListener != null) {
responseListener.commandComplete(this);
}
}
/**
* notification of the response to the command.
* You'll get either processResponse or processErrorResponse
*/
public void processOKResponse(int cmdCode, String payload) {
PydevDebugPlugin.log(IStatus.ERROR, "Debugger command ignored response " + getClass().toString() + payload,
null);
}
/**
* notification of the response to the command.
* You'll get either processResponse or processErrorResponse
*/
public void processErrorResponse(int cmdCode, String payload) {
PydevDebugPlugin.log(IStatus.ERROR, "Debugger command ignored error response " + getClass().toString()
+ payload, null);
}
public static String makeCommand(int code, int sequence, String payload) {
FastStringBuffer s = new FastStringBuffer(payload.length() + 20);
s.append(code);
s.append("\t");
s.append(sequence);
s.append("\t");
s.append(payload);
return s.toString();
}
}