Fixed problem opening other sources
[phpeclipse.git] / net.sourceforge.phpeclipse.debug.core / src / net / sourceforge / phpdt / internal / debug / core / PHPDBGProxy.java
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
7
8 Contributors:
9         IBM Corporation - Initial implementation
10         Vicente Fernando - www.alfersoft.com.ar
11 **********************************************************************/
12 package net.sourceforge.phpdt.internal.debug.core;
13
14 import java.io.BufferedReader;
15 import java.io.IOException;
16 import java.io.InputStreamReader;
17 import java.io.OutputStream;
18 import java.net.Socket;
19 import java.net.ServerSocket;
20
21 import org.eclipse.core.runtime.CoreException;
22 import org.eclipse.debug.core.DebugPlugin;
23 import org.eclipse.debug.core.DebugException;
24 import org.eclipse.debug.core.model.IBreakpoint;
25 import net.sourceforge.phpdt.internal.debug.core.model.IPHPDebugTarget;
26 import net.sourceforge.phpdt.internal.debug.core.model.PHPStackFrame;
27 import net.sourceforge.phpdt.internal.debug.core.model.PHPThread;
28 import net.sourceforge.phpdt.internal.debug.core.model.PHPVariable;
29 import net.sourceforge.phpdt.internal.debug.core.breakpoints.PHPLineBreakpoint;
30
31 public class PHPDBGProxy {
32
33         private ServerSocket server= null;
34         private Socket socket;
35         private BufferedReader reader= null;
36         private PHPDBGInterface DBGInt= null;
37         private IPHPDebugTarget debugTarget= null;
38         private PHPLoop phpLoop;
39         private PHPThread PHPMainThread;
40         private PHPDBGProxy thisProxy= null;
41         private int port;
42
43         public PHPDBGProxy() {
44                 thisProxy= this;
45         }
46
47         public void start() {
48                 createServerSocket();
49                 this.startPHPLoop();
50         }
51
52         public void stop() {
53                 phpLoop.setShouldStop();
54                 if(DBGInt != null) DBGInt.setShouldStop();
55                 phpLoop.notifyWait();
56         }
57
58         protected ServerSocket getServerSocket() throws IOException {
59                 if (server == null) {
60                         createServerSocket();
61                 }
62                 return server;
63         }
64
65         protected void createServerSocket() {
66                 port = SocketUtil.findUnusedLocalPort("localhost", 10001, 10101);
67                 if (port == -1) {
68                         PHPDebugCorePlugin.log(5, "Cannot find free port!!!!");
69                         return;
70                 }
71                 try {
72                         if (server == null) {
73                                 server = new ServerSocket(port);
74                                 //System.out.println("ServerSocket on port: " + port);
75                         } 
76                 } catch (IOException e) {
77                         // IO Error
78                         PHPDebugCorePlugin.log(e);
79                         stop();
80                 }
81         }
82
83         public Socket getSocket() throws IOException {
84                 return socket;
85         }
86
87         protected void setDBGInterface(PHPDBGInterface DBGInt) {
88                 this.DBGInt= DBGInt;
89         }
90
91         public BufferedReader getReader() throws IOException {
92                 if (reader == null) {                   
93                         reader = new BufferedReader(new InputStreamReader(this.getSocket().getInputStream(), "ISO8859_1"));
94                 }
95                 return reader;
96         }
97
98         public OutputStream getOutputStream() throws IOException {
99                 return this.getSocket().getOutputStream();
100         }
101
102         protected void setBreakPoints() throws IOException, CoreException {
103                 IBreakpoint[] breakpoints = DebugPlugin.getDefault().getBreakpointManager().getBreakpoints();
104                 for (int i = 0; i < breakpoints.length; i++) {
105                         addBreakpoint(breakpoints[i]);
106                 }
107         }
108
109         public void addBreakpoint(IBreakpoint breakpoint) {
110                 if (DBGInt == null) return;
111                 int bpNo= 0;
112                 try {
113                         PHPLineBreakpoint phpLBP;
114                         if(breakpoint.getModelIdentifier() == PHPDebugCorePlugin.getDefault().getDescriptor().getUniqueIdentifier()) {
115                                 phpLBP= (PHPLineBreakpoint)breakpoint;
116                                 bpNo= DBGInt.addBreakpoint(phpLBP.getMarker().getResource().getLocation().toOSString(), phpLBP.getLineNumber());
117                                 phpLBP.setDBGBpNo(bpNo);
118                         }
119                 } catch (IOException e) {
120                         PHPDebugCorePlugin.log(e);
121                         stop();
122                 } catch (CoreException e) {
123                         PHPDebugCorePlugin.log(e);
124                         stop();
125                 }
126         }
127
128         public void removeBreakpoint(IBreakpoint breakpoint) {
129                 if (DBGInt == null) return;
130                 try {
131                         PHPLineBreakpoint phpLBP;
132                         if(breakpoint.getModelIdentifier() == PHPDebugCorePlugin.getDefault().getDescriptor().getUniqueIdentifier()) {
133                                 phpLBP= (PHPLineBreakpoint)breakpoint;
134                                 DBGInt.removeBreakpoint(phpLBP.getMarker().getResource().getLocation().toOSString(), phpLBP.getLineNumber(), phpLBP.getDBGBpNo());
135                         }
136                 } catch (IOException e) {
137                         PHPDebugCorePlugin.log(e);
138                         stop();
139                 } catch (CoreException e) {
140                         PHPDebugCorePlugin.log(e);
141                         stop();
142                 }
143         }
144
145         public void startPHPLoop() {
146                 phpLoop = new PHPLoop();
147                 phpLoop.start();
148         }
149
150         public void resume(PHPThread thread) {
151                 try {
152                         DBGInt.continueExecution();
153                         phpLoop.notifyWait();
154                 } catch (IOException e) {
155                         PHPDebugCorePlugin.log(e);
156                         stop();
157                 }
158         }
159
160         protected IPHPDebugTarget getDebugTarget() {
161                 return debugTarget;
162         }
163
164         public void setDebugTarget(IPHPDebugTarget debugTarget) {
165                 this.debugTarget = debugTarget;
166                 debugTarget.setPHPDBGProxy(this);
167         }
168
169         public PHPVariable[] readVariables(PHPStackFrame frame) {
170                 try {
171                         return DBGInt.getVariables(frame);
172                 } catch (IOException ioex) {
173                         ioex.printStackTrace();
174                         throw new RuntimeException(ioex.getMessage());
175                 } catch (DebugException ex) {
176                         ex.printStackTrace();
177                         throw new RuntimeException(ex.getMessage());
178                 }
179         }
180
181         public PHPVariable[] readInstanceVariables(PHPVariable variable) {
182                 try {
183                         return DBGInt.getInstVars(variable);
184                 } catch (DebugException ex) {
185                         ex.printStackTrace();
186                         throw new RuntimeException(ex.getMessage());
187                 }
188
189         }
190
191         public void readStepOverEnd(PHPStackFrame stackFrame) {
192                 try {
193                         DBGInt.stepOver();
194                         phpLoop.notifyWait();
195                 } catch (Exception e) {
196                         PHPDebugCorePlugin.log(e);
197                 }
198         }
199
200         public void readStepReturnEnd(PHPStackFrame stackFrame) {
201                 try {
202                         DBGInt.stepOut();
203                         phpLoop.notifyWait();
204                 } catch (Exception e) {
205                         PHPDebugCorePlugin.log(e);
206                 }
207         }
208
209         public void readStepIntoEnd(PHPStackFrame stackFrame) {
210                 try {
211                         DBGInt.stepInto();
212                         phpLoop.notifyWait();
213                 } catch (Exception e) {
214                         PHPDebugCorePlugin.log(e);
215                 }
216         }
217
218 /*
219         public PHPStackFrame[] readFrames(PHPThread thread) {
220                 //try {
221                         //this.println("th " + thread.getId() + " ; f ");
222                         //return new FramesReader(getMultiReaderStrategy()).readFrames(thread);
223                         return null;
224                 //} catch (IOException e) {
225                 //      PHPDebugCorePlugin.log(e);
226                 //      return null;
227                 //}
228
229         }
230 */
231         
232         public void closeSocket() throws IOException {
233                 if (socket != null) {
234                         socket.close();
235                 }
236         }
237
238         public void closeServerSocket() throws IOException {
239                 if (server != null) {
240                         server.close();
241                 }
242         }
243
244         public int getPort() {
245                 return port;
246         }
247
248         class PHPLoop extends Thread {
249                 private boolean shouldStop;
250         
251                 public PHPLoop() {
252                         shouldStop = false;
253                         this.setName("PHPDebuggerLoop");
254                 }
255
256                 public synchronized void setShouldStop() {
257                         shouldStop = true;
258                 }
259
260                 public synchronized void notifyWait() {
261                         notify();
262                 }
263
264                 public void run() {
265                         try {
266                                 char[] buf= new char[16];
267                                 int i, pos, timeout;
268                                 long interval= 1000*20;
269                                 String line;
270                                 PHPStackFrame[] StackList;
271                                 
272                                 //System.out.println("Waiting for breakpoints.");                       
273                                 try{
274                                         socket = server.accept();
275                                         //System.out.println("Accepted! : " + socket.toString());
276                                 } catch (IOException e) {
277                                         PHPDebugCorePlugin.log(e);
278                                         return;                 
279                                 }
280                                 
281                                 PHPMainThread= new PHPThread(getDebugTarget(), getPort());
282                                 PHPMainThread.setName("Thread [main]");
283                                 timeout= 0;
284                                 while((getDebugTarget() == null) && (timeout < 100)) {
285                                         sleep(100);
286                                         timeout++;
287                                 }
288                                 // Be sure debug target is set
289                                 PHPMainThread.setDebugTarget(getDebugTarget());
290                                 getDebugTarget().addThread(PHPMainThread);
291                                 setDBGInterface(new PHPDBGInterface(getReader(), getOutputStream(), thisProxy));
292
293                                 DBGInt.waitResponse(1000);
294                                 DBGInt.flushAllPackets();
295
296                                 // Check version and session ID
297                                 setBreakPoints();
298                                 DBGInt.continueExecution();
299
300                                 while (!shouldStop) {
301                                         DBGInt.waitResponse(interval);
302                                         DBGInt.flushAllPackets();
303
304                                         if (DBGInt.BPUnderHit != 0) {
305                                                 StackList= DBGInt.getStackList();
306                                                 if(StackList.length > 0) {
307                                                         for(i=0; i < StackList.length; i++) {
308                                                                 StackList[i].setThread(PHPMainThread);
309                                                                 if(DBGInt.getModByNo(StackList[i].getModNo()).equals("")) {
310                                                                         DBGInt.getSourceTree();
311                                                                 }
312                                                                 StackList[i].setFile(DBGInt.getModByNo(StackList[i].getModNo()));
313                                                         }
314                                                         PHPMainThread.setStackFrames(StackList);
315                                                 }
316                                                 // Fire debug event
317                                                 PHPMainThread.suspend();
318
319                                                 synchronized(this) {
320                                                         wait();
321                                                 }
322                                         }                                       
323                                         if(PHPMainThread.isTerminated() || getDebugTarget().getProcess().isTerminated()) break;
324                                 }
325                         } catch (Exception ex) {
326                                 PHPDebugCorePlugin.log(ex);
327                                 System.out.println(ex);
328                         } finally {
329                                 try {
330                                         getDebugTarget().terminate();
331                                         closeSocket();
332                                         closeServerSocket();
333                                 } catch (IOException e) {
334                                         PHPDebugCorePlugin.log(e);
335                                         return;
336                                 }
337                                 //System.out.println("Socket loop finished.");
338                         }
339                 }
340         }       
341 }