1 /**********************************************************************
2 Copyright (c) 2000, 2002 IBM Corp. and others.
3 All rights reserved. This program and the accompanying materials
4 are made available under the terms of the Common Public License v1.0
5 which accompanies this distribution, and is available at
6 http://www.eclipse.org/legal/cpl-v10.html
9 IBM Corporation - Initial implementation
10 Vicente Fernando - www.alfersoft.com.ar
11 **********************************************************************/
12 package net.sourceforge.phpdt.internal.debug.core.model;
14 import net.sourceforge.phpdt.internal.debug.core.PHPDBGProxy;
15 import net.sourceforge.phpdt.internal.debug.core.PHPDebugCorePlugin;
17 import org.eclipse.core.resources.IMarkerDelta;
18 import org.eclipse.debug.core.DebugEvent;
19 import org.eclipse.debug.core.DebugException;
20 import org.eclipse.debug.core.DebugPlugin;
21 import org.eclipse.debug.core.IBreakpointManager;
22 import org.eclipse.debug.core.IDebugEventSetListener;
23 import org.eclipse.debug.core.ILaunch;
24 import org.eclipse.debug.core.ILaunchListener;
25 import org.eclipse.debug.core.model.IBreakpoint;
26 import org.eclipse.debug.core.model.IDebugTarget;
27 import org.eclipse.debug.core.model.IMemoryBlock;
28 import org.eclipse.debug.core.model.IProcess;
29 import org.eclipse.debug.core.model.IThread;
32 * Debug target for PHP debug model.
34 public class PHPDebugTarget implements IPHPDebugTarget, ILaunchListener, IDebugEventSetListener {
36 private IProcess process;
37 private boolean isTerminated;
38 private boolean isSuspended;
39 private ILaunch launch;
40 private PHPThread[] threads;
41 private PHPDBGProxy phpDBGProxy;
43 public PHPDebugTarget(ILaunch launch, IProcess process) {
44 this.isSuspended = false;
46 this.process = process;
47 this.threads = new PHPThread[0];
48 // TODO XXX remove breakpoint listener at termination to avoid live leak
49 IBreakpointManager manager= DebugPlugin.getDefault().getBreakpointManager();
50 manager.addBreakpointListener(this);
51 DebugPlugin.getDefault().addDebugEventListener(this);
55 protected synchronized void initialize() {
56 DebugEvent ev = new DebugEvent(this, DebugEvent.CREATE);
57 DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[] { ev });
60 public void addThread(PHPThread phpThread) {
62 PHPThread[] updatedThreads = new PHPThread[threads.length + 1];
64 for(i=0; i < threads.length; i++) {
65 updatedThreads[i] = threads[i];
67 updatedThreads[i] = phpThread;
68 threads = updatedThreads;
73 private void fireChangeEvent() {
74 DebugEvent ev = new DebugEvent(this, DebugEvent.CHANGE);
75 DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[] { ev });
78 protected PHPThread getThreadById(int id) {
79 for (int i = 0; i < threads.length; i++) {
80 if (threads[i].getId() == id) {
87 public IThread[] getThreads() {
91 public boolean hasThreads() throws DebugException {
92 return threads.length > 0;
95 public String getName() throws DebugException {
96 return "PHP Debugger at localhost:" + getPHPDBGProxy().getPort();
99 public boolean supportsBreakpoint(IBreakpoint arg0) {
100 if(arg0.getModelIdentifier().equals(PHPDebugCorePlugin.PLUGIN_ID)) {
106 public String getModelIdentifier() {
107 return PHPDebugCorePlugin.PLUGIN_ID;
110 public IDebugTarget getDebugTarget() {
114 public ILaunch getLaunch() {
118 public boolean canTerminate() {
119 return !isTerminated;
122 public boolean isTerminated() {
126 public synchronized void terminate() {
127 // This method is synchronized to control a race condition between the
128 // UI thread that terminates the debugging session, and the slave
129 // thread that executes PHPLoop.run
131 // Avoid terminating twice...
134 this.threads = new PHPThread[0];
139 public boolean canResume() {
140 if(isTerminated) return false;
144 public boolean canSuspend() {
145 if(isTerminated) return false;
149 public boolean isSuspended() {
153 public void resume() throws DebugException {
154 this.getPHPDBGProxy().resume();
158 public void suspend() throws DebugException {
159 this.getPHPDBGProxy().pause();
163 public void breakpointAdded(IBreakpoint breakpoint) {
164 this.getPHPDBGProxy().addBreakpoint(breakpoint) ;
167 public void breakpointRemoved(IBreakpoint breakpoint, IMarkerDelta arg1) {
168 this.getPHPDBGProxy().removeBreakpoint(breakpoint) ;
171 public void breakpointChanged(IBreakpoint breakpoint, IMarkerDelta arg1) {
172 // is called e.g. after a line has been inserted before a breakpoint
173 // but then the debugger is out of sync with the file anyway, so debugging
174 // should be stopped here.
177 public boolean canDisconnect() {
181 public void disconnect() throws DebugException {
184 public boolean isDisconnected() {
188 public boolean supportsStorageRetrieval() {
192 public IMemoryBlock getMemoryBlock(long arg0, long arg1) throws DebugException {
196 public Object getAdapter(Class arg0) {
200 public IProcess getProcess() {
204 public void setProcess(IProcess process) {
205 this.process = process;
208 public PHPDBGProxy getPHPDBGProxy() {
212 public void setPHPDBGProxy(PHPDBGProxy phpDBGProxy) {
213 this.phpDBGProxy = phpDBGProxy;
217 * @see ILaunchListener#launchRemoved(ILaunch)
219 public void launchRemoved(ILaunch launch) {
220 if (!isTerminated()) {
223 if (launch.equals(getLaunch())) {
224 // This target has been deregistered, but it hasn't successfully terminated.
225 // Update internal state to reflect that it is disconnected
231 * @see ILaunchListener#launchAdded(ILaunch)
233 public void launchAdded(ILaunch launch) {
237 * @see ILaunchListener#launchChanged(ILaunch)
239 public void launchChanged(ILaunch launch) {
243 * When a debug target or process terminates, terminate DBG Proxy.
245 * @see IDebugEventSetListener#handleDebugEvents(DebugEvent[])
247 public void handleDebugEvents(DebugEvent[] events) {
248 for (int i = 0; i < events.length; i++) {
249 DebugEvent event = events[i];
250 if (event.getKind() == DebugEvent.TERMINATE) {
251 Object source = event.getSource();
252 if (source instanceof PHPDebugTarget || source instanceof IDebugTarget) {
253 getPHPDBGProxy().stop();
254 } else if(source instanceof IProcess) {
255 if(getDebugTarget().getProcess() == (IProcess)source) {
256 getPHPDBGProxy().stop();
259 } else if (event.getKind() == DebugEvent.SUSPEND) {
260 getPHPDBGProxy().pause();