/**
* Copyright (c) 2005-2011 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;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IPath;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IBreakpointManager;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.model.IProcess;
import org.python.pydev.core.log.Log;
import org.python.pydev.debug.console.ConsoleCompletionsPageParticipant;
import org.python.pydev.debug.model.remote.AbstractRemoteDebugger;
/**
* Debugger class that represents a single python process.
*
* It deals with events from RemoteDebugger.
* Breakpoint updating.
*/
public class PyDebugTarget extends AbstractDebugTarget {
//private ILaunch launch;
public volatile IProcess process;
/**
* TODO consider instead of global access to project, have {@link ConsoleCompletionsPageParticipant#init(org.eclipse.ui.part.IPageBookViewPage, org.eclipse.ui.console.IConsole)
* instead call something like getInterpreterInfo which then PyDebugTargetConsole (which isn't connected to a project)
* has some hope of resolving
*/
public final IProject project;
public volatile boolean finishedInit = false;
public PyDebugTarget(ILaunch launch, IProcess process, IPath[] file, AbstractRemoteDebugger debugger,
IProject project) {
this.launch = launch;
this.process = process;
this.file = file;
this.debugger = debugger;
this.threads = new PyThread[0];
this.project = project;
launch.addDebugTarget(this);
debugger.addTarget(this);
IBreakpointManager breakpointManager = DebugPlugin.getDefault().getBreakpointManager();
breakpointManager.addBreakpointListener(this);
PyExceptionBreakPointManager.getInstance().addListener(this);
PyPropertyTraceManager.getInstance().addListener(this);
// we have to know when we get removed, so that we can shut off the debugger
DebugPlugin.getDefault().getLaunchManager().addLaunchListener(this);
}
public void launchRemoved(ILaunch launch) {
// shut down the remote debugger when parent launch
if (launch == this.launch) {
IBreakpointManager breakpointManager = DebugPlugin.getDefault().getBreakpointManager();
breakpointManager.removeBreakpointListener(this);
PyExceptionBreakPointManager.getInstance().removeListener(this);
PyPropertyTraceManager.getInstance().removeListener(this);
debugger.dispose();
debugger = null;
}
}
public IProcess getProcess() {
return process;
}
public boolean canTerminate() {
if (!finishedInit) {
//We must finish init to terminate
return false;
}
// We can always terminate if it's still not terminated.
return !this.isTerminated();
}
public boolean isTerminated() {
if (!finishedInit) {
//We must finish init to terminate
return false;
}
if (process == null) {
return true;
}
return process.isTerminated();
}
public void terminate() {
if (process != null) {
try {
process.terminate();
} catch (DebugException e) {
Log.log(e);
}
process = null;
}
super.terminate();
}
}