/****************************************************************************** * Copyright (C) 2012-2013 Hussain Bohra 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: * Hussain Bohra <hussain.bohra@tavant.com> - initial API and implementation * Fabio Zadrozny <fabiofz@gmail.com> - ongoing maintenance ******************************************************************************/ package org.python.pydev.debug.newconsole; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.CoreException; import org.python.pydev.core.log.Log; import org.python.pydev.debug.model.AbstractDebugTarget; import org.python.pydev.debug.model.PyStackFrame; import org.python.pydev.debug.model.remote.AbstractDebuggerCommand; import org.python.pydev.debug.model.remote.EvaluateConsoleExpressionCommand; import org.python.pydev.debug.model.remote.ICommandResponseListener; import org.python.pydev.shared_core.string.StringUtils; /** * Class to exectute console command in the debugging context * * @author hussain.bohra * @author Fabio Zadrozny */ public class EvaluateDebugConsoleExpression implements ICommandResponseListener { String EMPTY = StringUtils.EMPTY; private String payload; private final PyStackFrame frame; public EvaluateDebugConsoleExpression(PyStackFrame frame) { Assert.isNotNull(frame); this.frame = frame; } /** * This method will get called from AbstractDebugTarget when * output arrives for the posted command */ @Override public void commandComplete(AbstractDebuggerCommand cmd) { try { this.payload = ((EvaluateConsoleExpressionCommand) cmd).getResponse(); } catch (CoreException e) { this.payload = e.getMessage(); } } /** * Execute the line in selected frame context * * @param consoleId * @param command */ public void executeCommand(String command, boolean bufferedOutput) { AbstractDebugTarget target = frame.getTarget(); String locator = getLocator(frame.getThreadId(), frame.getId(), bufferedOutput ? "EVALUATE" : "EVALUATE_UNBUFFERED", command); AbstractDebuggerCommand cmd = new EvaluateConsoleExpressionCommand(target, locator, new ICommandResponseListener() { @Override public void commandComplete(AbstractDebuggerCommand cmd) { frame.forceGetNewVariables(); EvaluateDebugConsoleExpression.this.commandComplete(cmd); } }); target.postCommand(cmd); } /** * Post the completions command * * @param consoleId * @param actTok * @param offset */ public String getCompletions(String actTok, int offset) { AbstractDebugTarget target = frame.getTarget(); String locator = getLocator(frame.getThreadId(), frame.getId(), "GET_COMPLETIONS", actTok); AbstractDebuggerCommand cmd = new EvaluateConsoleExpressionCommand(target, locator, this); target.postCommand(cmd); return waitForCommand(); } /** * Keeps in a loop for 3 seconds or until the completions are found. If no * completions are found in that time, returns an empty array. */ public String waitForCommand() { int timeout = PydevConsoleConstants.CONSOLE_TIMEOUT; // wait up to 3 seconds while (--timeout > 0 && payload == null) { try { Thread.sleep(10); // 10 millis } catch (InterruptedException e) { // ignore } } String temp = this.payload; this.payload = null; if (temp == null) { Log.logInfo("Timeout for waiting for debug completions elapsed (3 seconds)."); return EMPTY; } return temp; } /** * join and return all locators with '\t' * * @param locators * @return */ private String getLocator(String... locators) { return StringUtils.join("\t", locators); } /** * This class represent the console message to be displayed in the debug console. * * @author hussain.bohra * */ public static class PydevDebugConsoleMessage { private boolean more; private StringBuilder outputMessage = new StringBuilder(); private StringBuilder errorMessage = new StringBuilder(); public boolean isMore() { return more; } public void setMore(boolean more) { this.more = more; } public void appendMessage(String output, boolean isError) { if (!isError) { outputMessage.append(output); outputMessage.append("\n"); } else { errorMessage.append(output); errorMessage.append("\n"); } } public StringBuilder getOutputMessage() { return outputMessage; } public StringBuilder getErrorMessage() { return errorMessage; } } }